Compare commits

..

75 Commits

Author SHA1 Message Date
Auxilor
0805b48763 Updated to 6.55.2 2023-04-24 22:12:47 +01:00
Auxilor
d737322aaa Merge remote-tracking branch 'origin/master'
# Conflicts:
#	gradle.properties
2023-04-24 22:12:19 +01:00
Auxilor
4ddc150e1c Updated to 6.54.1 2023-04-24 22:11:55 +01:00
Auxilor
0da119d89d Finally reimplemented BlockUtils#getVein 2023-04-24 22:10:42 +01:00
Auxilor
fc0a07d1c5 Config injections now use a ConcurrentHashMap 2023-04-24 22:05:37 +01:00
Auxilor
58316c2a06 Fixed locale bug with Registry 2023-04-20 20:32:07 +01:00
Auxilor
d96ad10960 Added locker to registry 2023-04-20 19:27:52 +01:00
Auxilor
21283b0928 Added ExternalDataStoreObjectAdapter 2023-04-20 19:19:00 +01:00
Auxilor
2797687f01 Cleanup 2023-04-20 17:54:23 +01:00
Auxilor
9c68d1fbc3 Merge branch 'master' into develop
# Conflicts:
#	eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/integrations/customitems/CustomItemsOraxen.kt
2023-04-20 17:45:06 +01:00
Auxilor
9371d9b88d Upstream 2023-04-20 17:44:58 +01:00
Auxilor
14e2ead488 Fixed javadoc, updated Kingdoms 2023-04-20 17:42:46 +01:00
Auxilor
5473bb8ef8 Cleaned up IntegrationRegistry 2023-04-20 17:34:18 +01:00
Auxilor
90c55849ae Isolated integration registration 2023-04-20 17:24:56 +01:00
Auxilor
9809140cf9 Isolated remaining integrations 2023-04-20 17:23:24 +01:00
Auxilor
49a82dc005 Isolated ShopManager 2023-04-20 17:15:18 +01:00
Auxilor
92dec03b9a Added IntegrationRegistry 2023-04-20 17:09:46 +01:00
Auxilor
7453c70b87 Fixed imports 2023-04-20 16:52:49 +01:00
Auxilor
3038ea43d0 Updated to 6.55.0 2023-04-20 16:51:11 +01:00
Auxilor
3c6ddd8255 Added OutdatedEcoVersionError 2023-04-20 16:50:35 +01:00
Auxilor
925ee04cc1 Added Version as a cross-version compatible version of DefaultArtifactVersion 2023-04-20 16:48:20 +01:00
Auxilor
6f7de8716b Added KRegistrable 2023-04-20 16:41:35 +01:00
Auxilor
a17b951a8b Made registry lockable and iterable 2023-04-20 16:40:06 +01:00
Auxilor
f003ed06a8 Fixed imports 2023-04-19 18:00:19 +01:00
Auxilor
f864953da2 Updated to 6.54.1 2023-04-19 17:38:22 +01:00
Auxilor
6ef31444ac Removed Checkstyle CI, cleaned up Oraxen PR 2023-04-19 17:38:09 +01:00
Will FP
99258116de Merge pull request #264 from MCCasper/master
fix oraxen and SNBT
2023-04-19 12:33:14 -04:00
casper
a59c68102e fix SNBT matching the same tag for diff materials 2023-04-19 11:09:26 -05:00
casper
2482525fe2 load oraxen later 2023-04-18 22:23:49 -05:00
Auxilor
acb326c0c8 Updated to 6.54.0 2023-04-13 12:13:32 -04:00
Auxilor
11d947e24b Updated to 6.53.2 2023-04-13 12:09:14 -04:00
Auxilor
3cced3012c Added Prerequisite#HAS_1_19_4 2023-04-13 11:59:04 -04:00
Auxilor
520523e903 Isolated integration loading 2023-04-13 11:57:49 -04:00
Auxilor
ee36cc74f8 Improved lifecycle error logging 2023-04-13 11:50:32 -04:00
Auxilor
55344e0550 Improved lifecycle error handling, isolated tasks 2023-04-13 11:49:43 -04:00
Auxilor
75f6f05c7d Merge branch 'master' into develop 2023-03-30 14:05:09 +01:00
Auxilor
17fa519501 Revert "Fixed ContinuallyAppliedPersistentDataContainer"
This reverts commit 1852ff86ec.
2023-03-30 14:04:43 +01:00
Auxilor
1a72cf3ca9 Revert "Updated to 6.53.2"
This reverts commit d11f355c44.
2023-03-30 14:04:43 +01:00
Auxilor
d11f355c44 Updated to 6.53.2 2023-03-30 12:08:37 +01:00
Auxilor
1852ff86ec Fixed ContinuallyAppliedPersistentDataContainer 2023-03-30 12:08:26 +01:00
Auxilor
ffe9219f45 Changed README to show repo.auxilor.io 2023-03-29 13:33:24 +01:00
Auxilor
f67a5d3b3d Added repo.auxilor.io 2023-03-29 13:30:15 +01:00
Auxilor
bbd541abe0 Added repo.auxilor.io 2023-03-29 13:21:40 +01:00
Auxilor
3de8d0fed9 Updated to 6.53.1 2023-03-28 17:13:04 +01:00
Auxilor
df4abe39eb Fixed tab completion for dynamically registered commands 2023-03-28 17:12:54 +01:00
Auxilor
f5e289966f Fixed tab completion for dynamically registered commands 2023-03-28 17:12:35 +01:00
Auxilor
bcfa4bd82e Added json() extension 2023-03-25 17:48:27 +00:00
Auxilor
229c9e58c3 Merge branch 'develop'
# Conflicts:
#	eco-api/src/main/java/com/willfp/eco/core/config/TransientConfig.java
#	eco-core/core-nms/nms-common/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/common/packet/PacketInjectorListener.kt
#	gradle.properties
2023-03-25 15:34:47 +00:00
Auxilor
4f30a6e04e Removed all forRemoval classes / methods deprecated since before 6.43.0 2023-03-20 12:52:41 +00:00
Auxilor
9ea45ee0d0 Updated EcoPlugin#getID 2023-03-19 22:24:02 +00:00
Auxilor
192316214d Added Items.matchesAny 2023-03-19 22:08:47 +00:00
Auxilor
feb8898a87 Added default values to ExternalDataStore.get 2023-03-19 22:03:21 +00:00
Auxilor
1e64815e47 Added Registry.tryFitPattern 2023-03-19 22:00:42 +00:00
Auxilor
dc10648c25 Fixed DefaultMap and ListMap, adding tasks to lifecycle events, and packet injection 2023-03-19 17:39:20 +00:00
Auxilor
70131a6cae Added logging for invalid registry IDs 2023-03-18 15:22:20 +00:00
Auxilor
6d23cc7141 Fixed Registry#clear 2023-03-18 15:17:41 +00:00
Auxilor
473202527a Fixed EntityDeathByEntityEvent for WildStacker users 2023-03-17 21:23:54 +00:00
Auxilor
bc24aaeb3c Fixed 1.19.4 support
(cherry picked from commit ad47b7898e)
2023-03-15 21:10:33 +00:00
Auxilor
52072bd935 Added 1.19.4 support
(cherry picked from commit cb3ccbb39a)
2023-03-15 21:10:33 +00:00
Auxilor
ad47b7898e Fixed 1.19.4 support 2023-03-15 21:06:02 +00:00
Auxilor
19d6533db6 Updated to 6.52.3 2023-03-15 21:05:15 +00:00
Auxilor
3a37d40271 Fixed missing channel bug 2023-03-15 21:02:05 +00:00
Auxilor
cb3ccbb39a Added 1.19.4 support 2023-03-15 21:02:01 +00:00
Auxilor
5c3bb678b3 Updated backend paper version 2023-03-15 18:20:46 +00:00
Auxilor
4f4ee82e6b Converted remaining groovy buildscripts to kotlin 2023-03-14 19:46:12 +00:00
Auxilor
32d88f55f8 Fixed environment variables 2023-03-14 17:18:05 +00:00
Auxilor
bc8d615079 Added environment variables, moved eco.yml components around, added option to disable reflective reload, moved eco to be a paper plugin 2023-03-14 16:35:30 +00:00
Auxilor
55b7c3c16f Added ExternalDataStore 2023-03-14 12:45:35 +00:00
Auxilor
9535986f59 Fixed EcoPlugin#getID 2023-03-14 12:25:29 +00:00
Auxilor
fb17fc1383 Fixed annotation mismatch 2023-03-13 15:24:51 +00:00
Auxilor
4221368388 Made EcoPlugin registrable 2023-03-13 15:18:21 +00:00
Auxilor
d4432d0cb8 Updated to 6.53.0 2023-03-13 14:31:19 +00:00
Auxilor
f9093c2ed6 Added LifecyclePosition 2023-03-13 14:23:28 +00:00
Auxilor
15f4d5c098 Fixed missing channel bug 2023-03-13 13:35:51 +00:00
Auxilor
dc47bc7995 Updated Placeholder API, added ability to parse placeholders without PAPI installed 2023-03-11 17:08:50 +00:00
143 changed files with 2376 additions and 1493 deletions

View File

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

View File

@@ -28,6 +28,8 @@ jobs:
- name: Publish artifact - name: Publish artifact
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
# The GITHUB_REF tag comes in the format 'refs/tags/xxx'. # The GITHUB_REF tag comes in the format 'refs/tags/xxx'.
# So if we split on '/' and take the 3rd value, we can get the release name. # So if we split on '/' and take the 3rd value, we can get the release name.

View File

@@ -63,7 +63,7 @@ eco comes packed with all the tools you need in your plugins:
# For developers # For developers
## Javadoc ## Javadoc
The 6.49.0 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.49.0/javadoc/) The 6.53.0 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.53.0/javadoc/)
## Plugin Information ## Plugin Information
@@ -75,31 +75,31 @@ depend:
- eco - eco
``` ```
## Get from JitPack: ## Dependency Information:
Gradle: Gradle:
```groovy ```kts
repositories { repositories {
maven { url 'https://jitpack.io' } maven("https://repo.auxilor.io/repository/maven-public/")
} }
``` ```
```groovy ```groovy
dependencies { dependencies {
compileOnly 'com.willfp:eco:Tag' compileOnly("com.willfp:eco:Tag")
} }
``` ```
Replace `Tag` with a release tag for eco, eg `6.49.0`. Replace `Tag` with a release tag for eco, eg `6.53.0`.
Maven: Maven:
```xml ```xml
<repository> <repository>
<id>jitpack.io</id> <id>auxilor</id>
<url>https://jitpack.io</url> <url>https://repo.auxilor.io/repository/maven-public/</url>
</repository> </repository>
``` ```
@@ -112,7 +112,7 @@ Maven:
</dependency> </dependency>
``` ```
Replace `Tag` with a release tag for eco, eg `6.49.0`. Replace `Tag` with a release tag for eco, eg `6.53.0`.
## Build locally: ## Build locally:

View File

@@ -26,6 +26,7 @@ dependencies {
implementation(project(path = ":eco-core:core-nms:v1_18_R2", configuration = "reobf")) implementation(project(path = ":eco-core:core-nms:v1_18_R2", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_19_R1", configuration = "reobf")) implementation(project(path = ":eco-core:core-nms:v1_19_R1", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_19_R2", configuration = "reobf")) implementation(project(path = ":eco-core:core-nms:v1_19_R2", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_19_R3", configuration = "reobf"))
} }
allprojects { allprojects {
@@ -56,7 +57,7 @@ allprojects {
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/") maven("https://repo.extendedclip.com/content/repositories/placeholderapi/")
// ProtocolLib // ProtocolLib
maven("https://repo.dmulloy2.net/nexus/repository/public/") //maven("https://repo.dmulloy2.net/nexus/repository/public/")
// WorldGuard // WorldGuard
maven("https://maven.enginehub.org/repo/") maven("https://maven.enginehub.org/repo/")
@@ -79,6 +80,7 @@ allprojects {
// LibsDisguises // LibsDisguises
maven("https://repo.md-5.net/content/groups/public/") maven("https://repo.md-5.net/content/groups/public/")
// UltraEconomy
maven("https://repo.techscode.com/repository/maven-releases/") maven("https://repo.techscode.com/repository/maven-releases/")
} }

View File

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

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

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

View File

@@ -13,12 +13,16 @@ import com.willfp.eco.core.factory.MetadataValueFactory;
import com.willfp.eco.core.factory.NamespacedKeyFactory; import com.willfp.eco.core.factory.NamespacedKeyFactory;
import com.willfp.eco.core.factory.RunnableFactory; import com.willfp.eco.core.factory.RunnableFactory;
import com.willfp.eco.core.integrations.IntegrationLoader; import com.willfp.eco.core.integrations.IntegrationLoader;
import com.willfp.eco.core.map.ListMap;
import com.willfp.eco.core.packet.PacketListener; import com.willfp.eco.core.packet.PacketListener;
import com.willfp.eco.core.proxy.ProxyFactory; import com.willfp.eco.core.proxy.ProxyFactory;
import com.willfp.eco.core.registry.Registrable;
import com.willfp.eco.core.registry.Registry;
import com.willfp.eco.core.scheduling.Scheduler; import com.willfp.eco.core.scheduling.Scheduler;
import com.willfp.eco.core.version.OutdatedEcoVersionError;
import com.willfp.eco.core.version.Version;
import com.willfp.eco.core.web.UpdateChecker; import com.willfp.eco.core.web.UpdateChecker;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
@@ -35,6 +39,7 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -53,27 +58,12 @@ import java.util.stream.Collectors;
* <b>IMPORTANT: When reloading a plugin, all runnables / tasks will * <b>IMPORTANT: When reloading a plugin, all runnables / tasks will
* be cancelled.</b> * be cancelled.</b>
*/ */
@SuppressWarnings({"unused", "DeprecatedIsStillUsed", "deprecation", "RedundantSuppression"}) @SuppressWarnings({"unused", "DeprecatedIsStillUsed", "deprecation", "RedundantSuppression", "MismatchedQueryAndUpdateOfCollection"})
public abstract class EcoPlugin extends JavaPlugin implements PluginLike { public abstract class EcoPlugin extends JavaPlugin implements PluginLike, Registrable {
/** /**
* The polymart resource ID of the plugin. * The properties (eco.yml).
*/ */
private final int resourceId; private final PluginProps props;
/**
* The bStats resource ID of the plugin.
*/
private final int bStatsId;
/**
* The package where proxy implementations are.
*/
private final String proxyPackage;
/**
* The color of the plugin, used in messages.
*/
private final String color;
/** /**
* Loaded integrations. * Loaded integrations.
@@ -142,11 +132,6 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
*/ */
private boolean outdated = false; private boolean outdated = false;
/**
* If the plugin supports extensions.
*/
private final boolean supportingExtensions;
/** /**
* The proxy factory. * The proxy factory.
*/ */
@@ -156,27 +141,27 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
/** /**
* The tasks to run on enable. * The tasks to run on enable.
*/ */
private final List<Runnable> onEnable = new ArrayList<>(); private final ListMap<LifecyclePosition, Runnable> onEnable = new ListMap<>();
/** /**
* The tasks to run on disable. * The tasks to run on disable.
*/ */
private final List<Runnable> onDisable = new ArrayList<>(); private final ListMap<LifecyclePosition, Runnable> onDisable = new ListMap<>();
/** /**
* The tasks to run on reload. * The tasks to run on reload.
*/ */
private final List<Runnable> onReload = new ArrayList<>(); private final ListMap<LifecyclePosition, Runnable> onReload = new ListMap<>();
/** /**
* The tasks to run on load. * The tasks to run on load.
*/ */
private final List<Runnable> onLoad = new ArrayList<>(); private final ListMap<LifecyclePosition, Runnable> onLoad = new ListMap<>();
/** /**
* The tasks to run after load. * The tasks to run after load.
*/ */
private final List<Runnable> afterLoad = new ArrayList<>(); private final ListMap<LifecyclePosition, Runnable> afterLoad = new ListMap<>();
/** /**
* Create a new plugin. * Create a new plugin.
@@ -193,7 +178,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* Create a new plugin without proxy support, polymart, or bStats. * Create a new plugin without proxy support, polymart, or bStats.
* *
* @param color The color. * @param color The color.
* @deprecated Use eco.yml instead.
*/ */
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(@NotNull final String color) { protected EcoPlugin(@NotNull final String color) {
this("", color); this("", color);
} }
@@ -204,7 +191,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* *
* @param proxyPackage The package where proxy implementations are stored. * @param proxyPackage The package where proxy implementations are stored.
* @param color The color of the plugin (used in messages, using standard formatting) * @param color The color of the plugin (used in messages, using standard formatting)
* @deprecated Use eco.yml instead.
*/ */
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(@NotNull final String proxyPackage, protected EcoPlugin(@NotNull final String proxyPackage,
@NotNull final String color) { @NotNull final String color) {
this(0, 0, proxyPackage, color); this(0, 0, proxyPackage, color);
@@ -216,7 +205,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param resourceId The polymart resource ID for the plugin. * @param resourceId The polymart resource ID for the plugin.
* @param bStatsId The bStats resource ID for the plugin. * @param bStatsId The bStats resource ID for the plugin.
* @param color The color of the plugin (used in messages, using standard formatting) * @param color The color of the plugin (used in messages, using standard formatting)
* @deprecated Use eco.yml instead.
*/ */
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(final int resourceId, protected EcoPlugin(final int resourceId,
final int bStatsId, final int bStatsId,
@NotNull final String color) { @NotNull final String color) {
@@ -230,7 +221,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param bStatsId The bStats resource ID for the plugin. * @param bStatsId The bStats resource ID for the plugin.
* @param color The color of the plugin (used in messages, using standard formatting) * @param color The color of the plugin (used in messages, using standard formatting)
* @param supportingExtensions If the plugin supports extensions. * @param supportingExtensions If the plugin supports extensions.
* @deprecated Use eco.yml instead.
*/ */
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(final int resourceId, protected EcoPlugin(final int resourceId,
final int bStatsId, final int bStatsId,
@NotNull final String color, @NotNull final String color,
@@ -245,7 +238,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param bStatsId The bStats resource ID for the plugin. * @param bStatsId The bStats resource ID for the plugin.
* @param proxyPackage The package where proxy implementations are stored. * @param proxyPackage The package where proxy implementations are stored.
* @param color The color of the plugin (used in messages, using standard formatting) * @param color The color of the plugin (used in messages, using standard formatting)
* @deprecated Use eco.yml instead.
*/ */
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(final int resourceId, protected EcoPlugin(final int resourceId,
final int bStatsId, final int bStatsId,
@NotNull final String proxyPackage, @NotNull final String proxyPackage,
@@ -261,21 +256,15 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param proxyPackage The package where proxy implementations are stored. * @param proxyPackage The package where proxy implementations are stored.
* @param color The color of the plugin (used in messages, using standard formatting) * @param color The color of the plugin (used in messages, using standard formatting)
* @param supportingExtensions If the plugin supports extensions. * @param supportingExtensions If the plugin supports extensions.
* @deprecated Use eco.yml instead.
*/ */
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(final int resourceId, protected EcoPlugin(final int resourceId,
final int bStatsId, final int bStatsId,
@NotNull final String proxyPackage, @NotNull final String proxyPackage,
@NotNull final String color, @NotNull final String color,
final boolean supportingExtensions) { final boolean supportingExtensions) {
this( this(PluginProps.createSimple(resourceId, bStatsId, proxyPackage, color, supportingExtensions));
PluginProps.createSimple(
resourceId,
bStatsId,
proxyPackage,
color,
supportingExtensions
)
);
} }
/** /**
@@ -325,13 +314,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
PluginProps props = this.mutateProps(generatedProps); PluginProps props = this.mutateProps(generatedProps);
props.validate(); props.validate();
this.resourceId = props.getResourceId(); this.props = props;
this.bStatsId = props.getBStatsId();
this.proxyPackage = props.getProxyPackage();
this.color = props.getColor();
this.supportingExtensions = props.isSupportingExtensions();
this.proxyFactory = this.proxyPackage.equalsIgnoreCase("") ? null : Eco.get().createProxyFactory(this); this.proxyFactory = this.props.getProxyPackage().equalsIgnoreCase("") ? null : Eco.get().createProxyFactory(this);
this.logger = Eco.get().createLogger(this); this.logger = Eco.get().createLogger(this);
this.getLogger().info("Initializing " + this.getColor() + this.getName()); this.getLogger().info("Initializing " + this.getColor() + this.getName());
@@ -363,14 +348,14 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
they have an outdated version of eco installed. they have an outdated version of eco installed.
*/ */
DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.get().getEcoPlugin().getDescription().getVersion()); Version runningVersion = new Version(Eco.get().getEcoPlugin().getDescription().getVersion());
DefaultArtifactVersion requiredVersion = new DefaultArtifactVersion(this.getMinimumEcoVersion()); Version requiredVersion = new Version(this.getMinimumEcoVersion());
if (!(runningVersion.compareTo(requiredVersion) > 0 || runningVersion.equals(requiredVersion))) { if (!(runningVersion.compareTo(requiredVersion) > 0 || runningVersion.equals(requiredVersion))) {
this.getLogger().severe("You are running an outdated version of eco!"); this.getLogger().severe("You are running an outdated version of eco!");
this.getLogger().severe("You must be on at least" + this.getMinimumEcoVersion()); this.getLogger().severe("You must be on at least" + this.getMinimumEcoVersion());
this.getLogger().severe("Download the newest version here:"); this.getLogger().severe("Download the newest version here:");
this.getLogger().severe("https://polymart.org/download/773/recent/JSpprMspkuyecf5y1wQ2Jn8OoLQSQ_IW"); this.getLogger().severe("https://polymart.org/download/773/recent/JSpprMspkuyecf5y1wQ2Jn8OoLQSQ_IW");
Bukkit.getPluginManager().disablePlugin(this); throw new OutdatedEcoVersionError("This plugin requires at least eco version " + this.getMinimumEcoVersion() + " to run.");
} }
} }
@@ -386,8 +371,8 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
if (this.getResourceId() != 0 && !Eco.get().getEcoPlugin().getConfigYml().getBool("no-update-checker")) { if (this.getResourceId() != 0 && !Eco.get().getEcoPlugin().getConfigYml().getBool("no-update-checker")) {
new UpdateChecker(this).getVersion(version -> { new UpdateChecker(this).getVersion(version -> {
DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(this.getDescription().getVersion()); Version currentVersion = new Version(this.getDescription().getVersion());
DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version); Version mostRecentVersion = new Version(version);
if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) { if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) {
this.outdated = true; this.outdated = true;
this.getLogger().warning(this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")"); this.getLogger().warning(this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")");
@@ -401,10 +386,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
Eco.get().registerBStats(this); Eco.get().registerBStats(this);
} }
Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins()) Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(Plugin::getName).map(String::toLowerCase).collect(Collectors.toSet());
.map(Plugin::getName)
.map(String::toLowerCase)
.collect(Collectors.toSet());
if (enabledPlugins.contains("PlaceholderAPI".toLowerCase())) { if (enabledPlugins.contains("PlaceholderAPI".toLowerCase())) {
Eco.get().createPAPIIntegration(this); Eco.get().createPAPIIntegration(this);
@@ -412,8 +394,13 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
this.loadIntegrationLoaders().forEach(integrationLoader -> { this.loadIntegrationLoaders().forEach(integrationLoader -> {
if (enabledPlugins.contains(integrationLoader.getPluginName().toLowerCase())) { if (enabledPlugins.contains(integrationLoader.getPluginName().toLowerCase())) {
this.loadedIntegrations.add(integrationLoader.getPluginName()); try {
integrationLoader.load(); integrationLoader.load();
this.loadedIntegrations.add(integrationLoader.getPluginName());
} catch (Exception e) {
this.getLogger().warning("Failed to load integration for " + integrationLoader.getPluginName());
e.printStackTrace();
}
} }
}); });
@@ -449,8 +436,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
} }
} }
this.handleEnable(); this.handleLifecycle(this.onEnable, this::handleEnable);
this.onEnable.forEach(Runnable::run);
this.getLogger().info(""); this.getLogger().info("");
} }
@@ -461,7 +447,18 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param task The task. * @param task The task.
*/ */
public final void onEnable(@NotNull final Runnable task) { public final void onEnable(@NotNull final Runnable task) {
this.onEnable.add(task); this.onEnable(LifecyclePosition.END, task);
}
/**
* Add new task to run on enable.
*
* @param position The position to run the task.
* @param task The task.
*/
public final void onEnable(@NotNull final LifecyclePosition position,
@NotNull final Runnable task) {
this.onEnable.append(position, task);
} }
/** /**
@@ -474,8 +471,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
this.getEventManager().unregisterAllListeners(); this.getEventManager().unregisterAllListeners();
this.getScheduler().cancelAll(); this.getScheduler().cancelAll();
this.handleDisable(); this.handleLifecycle(this.onDisable, this::handleDisable);
this.onDisable.forEach(Runnable::run);
if (this.isSupportingExtensions()) { if (this.isSupportingExtensions()) {
this.getExtensionLoader().unloadExtensions(); this.getExtensionLoader().unloadExtensions();
@@ -491,7 +487,18 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param task The task. * @param task The task.
*/ */
public final void onDisable(@NotNull final Runnable task) { public final void onDisable(@NotNull final Runnable task) {
this.onDisable.add(task); this.onDisable(LifecyclePosition.END, task);
}
/**
* Add new task to run on disable.
*
* @param position The position to run the task.
* @param task The task.
*/
public final void onDisable(@NotNull final LifecyclePosition position,
@NotNull final Runnable task) {
this.onDisable.append(position, task);
} }
/** /**
@@ -501,8 +508,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
public final void onLoad() { public final void onLoad() {
super.onLoad(); super.onLoad();
this.handleLoad(); this.handleLifecycle(this.onLoad, this::handleLoad);
this.onLoad.forEach(Runnable::run);
} }
/** /**
@@ -511,7 +517,18 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param task The task. * @param task The task.
*/ */
public final void onLoad(@NotNull final Runnable task) { public final void onLoad(@NotNull final Runnable task) {
this.onLoad.add(task); this.onLoad(LifecyclePosition.END, task);
}
/**
* Add new task to run on load.
*
* @param position The position to run the task.
* @param task The task.
*/
public final void onLoad(@NotNull final LifecyclePosition position,
@NotNull final Runnable task) {
this.onLoad.append(position, task);
} }
/** /**
@@ -545,8 +562,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
this.getLogger().severe(""); this.getLogger().severe("");
} }
this.handleAfterLoad(); this.handleLifecycle(this.afterLoad, this::handleAfterLoad);
this.afterLoad.forEach(Runnable::run);
this.reload(); this.reload();
@@ -554,7 +570,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
extension.handleAfterLoad(); extension.handleAfterLoad();
} }
this.getLogger().info("Loaded " + this.color + this.getName()); this.getLogger().info("Loaded " + this.props.getColor() + this.getName());
} }
/** /**
@@ -563,7 +579,18 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param task The task. * @param task The task.
*/ */
public final void afterLoad(@NotNull final Runnable task) { public final void afterLoad(@NotNull final Runnable task) {
this.afterLoad.add(task); this.afterLoad(LifecyclePosition.END, task);
}
/**
* Add new task to run after load.
*
* @param position The position to run the task.
* @param task The task.
*/
public final void afterLoad(@NotNull final LifecyclePosition position,
@NotNull final Runnable task) {
this.afterLoad.append(position, task);
} }
/** /**
@@ -576,8 +603,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
this.getConfigHandler().callUpdate(); this.getConfigHandler().callUpdate();
this.getConfigHandler().callUpdate(); // Call twice to fix issues this.getConfigHandler().callUpdate(); // Call twice to fix issues
this.handleReload(); this.handleLifecycle(this.onReload, this::handleReload);
this.onReload.forEach(Runnable::run);
for (Extension extension : this.extensionLoader.getLoadedExtensions()) { for (Extension extension : this.extensionLoader.getLoadedExtensions()) {
extension.handleReload(); extension.handleReload();
@@ -585,12 +611,23 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
} }
/** /**
* Add new task to run on enable. * Add new task to run on reload.
* *
* @param task The task. * @param task The task.
*/ */
public final void onReload(@NotNull final Runnable task) { public final void onReload(@NotNull final Runnable task) {
this.onReload.add(task); this.onReload(LifecyclePosition.END, task);
}
/**
* Add new task to run on reload.
*
* @param position The position to run the task.
* @param task The task.
*/
public final void onReload(@NotNull final LifecyclePosition position,
@NotNull final Runnable task) {
this.onReload.append(position, task);
} }
/** /**
@@ -606,6 +643,43 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
return System.currentTimeMillis() - startTime; return System.currentTimeMillis() - startTime;
} }
/**
* Handle lifecycle.
*
* @param tasks The tasks.
* @param handler The handler.
*/
private void handleLifecycle(@NotNull final ListMap<LifecyclePosition, Runnable> tasks,
@NotNull final Runnable handler) {
for (Runnable task : tasks.get(LifecyclePosition.START)) {
try {
task.run();
} catch (final Exception e) {
this.getLogger().log(Level.SEVERE, "Error while running lifecycle task!");
this.getLogger().log(Level.SEVERE, "The plugin may not function properly");
e.printStackTrace();
}
}
try {
handler.run();
} catch (final Exception e) {
this.getLogger().log(Level.SEVERE, "Error while running lifecycle task!");
this.getLogger().log(Level.SEVERE, "The plugin may not function properly");
e.printStackTrace();
}
for (Runnable task : tasks.get(LifecyclePosition.END)) {
try {
task.run();
} catch (final Exception e) {
this.getLogger().log(Level.SEVERE, "Error while running lifecycle task!");
this.getLogger().log(Level.SEVERE, "The plugin may not function properly");
e.printStackTrace();
}
}
}
/** /**
* The plugin-specific code to be executed on enable. * The plugin-specific code to be executed on enable.
* <p> * <p>
@@ -762,10 +836,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
*/ */
@Nullable @Nullable
protected DisplayModule createDisplayModule() { protected DisplayModule createDisplayModule() {
Validate.isTrue( Validate.isTrue(this.getDisplayModule() == null, "Display module exists!");
this.getDisplayModule() == null,
"Display module exists!"
);
return null; return null;
} }
@@ -879,13 +950,23 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
return new HashSet<>(Eco.get().getLoadedPlugins()); return new HashSet<>(Eco.get().getLoadedPlugins());
} }
/**
* Get the plugin props. (eco.yml).
*
* @return The props.
*/
@NotNull
public PluginProps getProps() {
return this.props;
}
/** /**
* Get the polymart resource ID. * Get the polymart resource ID.
* *
* @return The resource ID. * @return The resource ID.
*/ */
public int getResourceId() { public int getResourceId() {
return this.resourceId; return this.getProps().getResourceId();
} }
/** /**
@@ -894,7 +975,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return The ID. * @return The ID.
*/ */
public int getBStatsId() { public int getBStatsId() {
return this.bStatsId; return this.getProps().getBStatsId();
} }
/** /**
@@ -903,7 +984,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return The package where proxies are contained. * @return The package where proxies are contained.
*/ */
public String getProxyPackage() { public String getProxyPackage() {
return this.proxyPackage; return this.getProps().getProxyPackage();
} }
/** /**
@@ -912,7 +993,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return The color. * @return The color.
*/ */
public String getColor() { public String getColor() {
return this.color; return this.getProps().getColor();
} }
/** /**
@@ -1030,7 +1111,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return If extensions are supported. * @return If extensions are supported.
*/ */
public boolean isSupportingExtensions() { public boolean isSupportingExtensions() {
return this.supportingExtensions; return this.getProps().isSupportingExtensions();
} }
/** /**
@@ -1064,4 +1145,10 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
public FixedMetadataValue createMetadataValue(@NotNull final Object value) { public FixedMetadataValue createMetadataValue(@NotNull final Object value) {
return this.getMetadataValueFactory().create(value); return this.getMetadataValueFactory().create(value);
} }
@Override
@NotNull
public final String getID() {
return Registry.tryFitPattern(this.getName());
}
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -30,16 +30,6 @@ import java.util.Set;
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
public interface Config extends Cloneable, PlaceholderInjectable { public interface Config extends Cloneable, PlaceholderInjectable {
/**
* Clears cache.
* <p>
* Configs no longer have caches as they have in previous versions.
*/
@Deprecated(since = "6.31.1", forRemoval = true)
default void clearCache() {
// Do nothing.
}
/** /**
* Convert the config into readable text. * Convert the config into readable text.
* *

View File

@@ -2,7 +2,6 @@ package com.willfp.eco.core.config.interfaces;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@@ -44,21 +43,6 @@ public interface LoadableConfig extends Config {
*/ */
String getName(); String getName();
/**
* Get bukkit {@link YamlConfiguration}.
* <p>
* This used to represent the underlying config, but since 6.30.0 configs use
* their own implementations internally, without relying on bukkit.
*
* @return The config, or null if config is not yaml-based.
* @deprecated Use toBukkit() instead.
*/
@Nullable
@Deprecated(since = "6.30.0", forRemoval = true)
default YamlConfiguration getBukkitHandle() {
return this.toBukkit();
}
/** /**
* Convert the config to a bukkit {@link YamlConfiguration}. * Convert the config to a bukkit {@link YamlConfiguration}.
*/ */

View File

@@ -38,6 +38,9 @@ import java.lang.annotation.Target;
* <p> * <p>
* By having a plugin as a parameter, you shouldn't really need getInstance() * By having a plugin as a parameter, you shouldn't really need getInstance()
* calls in your code. * calls in your code.
*
* While flexible, this can lead to long initialization times, so this feature
* can be disabled in eco.yml with the uses-reflective-reload option.
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) @Target(ElementType.METHOD)

View File

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

View File

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

View File

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

View File

@@ -82,44 +82,6 @@ public final class PersistentDataKey<T> {
return this.type; return this.type;
} }
/**
* In older eco versions, keys would have to be categorized in order
* to register the columns in the MySQL database. This is no longer needed.
* <p>
* Old description is below:
* <p>
* Categorize key as a server key, will register new column to MySQL
* database immediately rather than waiting for auto-categorization.
* <p>
* This will improve performance.
*
* @return The key.
* @deprecated Not required since the new MySQL data handler was introduced.
*/
@Deprecated(since = "6.40.0", forRemoval = true)
public PersistentDataKey<T> server() {
return this;
}
/**
* In older eco versions, keys would have to be categorized in order
* to register the columns in the MySQL database. This is no longer needed.
* <p>
* Old description is below:
* <p>
* Categorize key as a player key, will register new column to MySQL
* database immediately rather than waiting for auto-categorization.
* <p>
* This will improve performance.
*
* @return The key.
* @deprecated Not required since the new MySQL data handler was introduced.
*/
@Deprecated(since = "6.40.0", forRemoval = true)
public PersistentDataKey<T> player() {
return this;
}
/** /**
* Get all persistent data keys. * Get all persistent data keys.
* *

View File

@@ -22,55 +22,38 @@ public final class PersistentDataKeyType<T> {
/** /**
* String. * String.
*/ */
public static final PersistentDataKeyType<String> STRING = new PersistentDataKeyType<>(String.class, "STRING"); public static final PersistentDataKeyType<String> STRING = new PersistentDataKeyType<>("STRING");
/** /**
* Boolean. * Boolean.
*/ */
public static final PersistentDataKeyType<Boolean> BOOLEAN = new PersistentDataKeyType<>(Boolean.class, "BOOLEAN"); public static final PersistentDataKeyType<Boolean> BOOLEAN = new PersistentDataKeyType<>("BOOLEAN");
/** /**
* Int. * Int.
*/ */
public static final PersistentDataKeyType<Integer> INT = new PersistentDataKeyType<>(Integer.class, "INT"); public static final PersistentDataKeyType<Integer> INT = new PersistentDataKeyType<>("INT");
/** /**
* Double. * Double.
*/ */
public static final PersistentDataKeyType<Double> DOUBLE = new PersistentDataKeyType<>(Double.class, "DOUBLE"); public static final PersistentDataKeyType<Double> DOUBLE = new PersistentDataKeyType<>("DOUBLE");
/** /**
* String List. * String List.
*/ */
public static final PersistentDataKeyType<List<String>> STRING_LIST = new PersistentDataKeyType<>(null, "STRING_LIST"); public static final PersistentDataKeyType<List<String>> STRING_LIST = new PersistentDataKeyType<>("STRING_LIST");
/** /**
* Config. * Config.
*/ */
public static final PersistentDataKeyType<Config> CONFIG = new PersistentDataKeyType<>(Config.class, "CONFIG"); public static final PersistentDataKeyType<Config> CONFIG = new PersistentDataKeyType<>("CONFIG");
/**
* The class of the type.
*/
private final Class<T> typeClass;
/** /**
* The name of the key type. * The name of the key type.
*/ */
private final String name; private final String name;
/**
* Get the class of the type.
*
* @return The class.
* @deprecated String list type will return null.
*/
@Deprecated(since = "6.36.0", forRemoval = true)
@Nullable
public Class<T> getTypeClass() {
return typeClass;
}
/** /**
* Get the name of the key type. * Get the name of the key type.
* *
@@ -83,14 +66,11 @@ public final class PersistentDataKeyType<T> {
/** /**
* Create new PersistentDataKeyType. * Create new PersistentDataKeyType.
* *
* @param typeClass The type class.
* @param name The name. * @param name The name.
*/ */
private PersistentDataKeyType(@Nullable final Class<T> typeClass, private PersistentDataKeyType(@NotNull final String name) {
@NotNull final String name) {
VALUES.add(this); VALUES.add(this);
this.typeClass = typeClass;
this.name = name; this.name = name;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -20,18 +20,6 @@ import java.util.Set;
* FastItemStack contains methods to modify and read items faster than in default bukkit. * FastItemStack contains methods to modify and read items faster than in default bukkit.
*/ */
public interface FastItemStack extends PersistentDataHolder { public interface FastItemStack extends PersistentDataHolder {
/**
* Get all enchantments on an item.
*
* @param checkStored If stored NBT should also be checked.
* @return A map of all enchantments.
* @deprecated Poorly named method. Use getEnchants instead.
*/
@Deprecated(since = "6.24.0", forRemoval = true)
default Map<Enchantment, Integer> getEnchantmentsOnItem(boolean checkStored) {
return getEnchants(checkStored);
}
/** /**
* Get all enchantments on an item. * Get all enchantments on an item.
* Does not account for stored enchants. * Does not account for stored enchants.
@@ -51,33 +39,6 @@ public interface FastItemStack extends PersistentDataHolder {
@NotNull @NotNull
Map<Enchantment, Integer> getEnchants(boolean checkStored); Map<Enchantment, Integer> getEnchants(boolean checkStored);
/**
* Get the level of an enchantment on an item.
*
* @param enchantment The enchantment.
* @return The enchantment level, or 0 if not found.
* @deprecated Poorly named method. Use getEnchantmentLevel instead.
*/
@Deprecated(since = "6.34.0", forRemoval = true)
default int getLevelOnItem(@NotNull Enchantment enchantment) {
return getEnchantmentLevel(enchantment, false);
}
/**
* Get the level of an enchantment on an item.
*
* @param enchantment The enchantment.
* @param checkStored If the stored NBT should also be checked.
* @return The enchantment level, or 0 if not found.
* @deprecated Poorly named method. Use getEnchantmentLevel instead.
*/
@Deprecated(since = "6.34.0", forRemoval = true)
@SuppressWarnings("DeprecatedIsStillUsed")
default int getLevelOnItem(@NotNull Enchantment enchantment,
boolean checkStored) {
return getEnchantmentLevel(enchantment, checkStored);
}
/** /**
* Get the level of an enchantment. * Get the level of an enchantment.
* *
@@ -85,7 +46,7 @@ public interface FastItemStack extends PersistentDataHolder {
* @return The enchantment level, or 0 if not found. * @return The enchantment level, or 0 if not found.
*/ */
default int getEnchantmentLevel(@NotNull Enchantment enchantment) { default int getEnchantmentLevel(@NotNull Enchantment enchantment) {
return getLevelOnItem(enchantment, false); return getEnchantmentLevel(enchantment, false);
} }
/** /**

View File

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

View File

@@ -90,17 +90,4 @@ public abstract class CustomSlot implements Slot {
public final Slot getSlotAt(int row, int column) { public final Slot getSlotAt(int row, int column) {
return Slot.super.getSlotAt(row, column); return Slot.super.getSlotAt(row, column);
} }
/**
* Get the delegate slot.
* <p>
* This is not required to add the slot to a menu, but is instead used internally.
*
* @return The slot.
* @deprecated Replaced with {@link Slot#getActionableSlot(Player, Menu)}
*/
@Deprecated(since = "6.43.0", forRemoval = true)
public Slot getDelegate() {
return this.delegate;
}
} }

View File

@@ -158,27 +158,4 @@ public interface Slot extends GUIComponent {
static SlotBuilder builder(@NotNull final SlotProvider provider) { static SlotBuilder builder(@NotNull final SlotProvider provider) {
return Eco.get().createSlotBuilder(provider); return Eco.get().createSlotBuilder(provider);
} }
/**
* If the slot is not captive for a player.
*
* @param player The player.
* @return If not captive for the player.
* @deprecated Captivity is now reactive, this method can produce incorrect results.
*/
@Deprecated(since = "6.43.0", forRemoval = true)
default boolean isNotCaptiveFor(@NotNull Player player) {
return false;
}
/**
* If the slot is captive. (Can items be placed in it).
*
* @return If captive.
* @deprecated Captivity is now reactive, this method can produce incorrect results.
*/
@Deprecated(since = "6.43.0", forRemoval = true)
default boolean isCaptive() {
return false;
}
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -3,7 +3,6 @@ package com.willfp.eco.core.integrations.placeholder;
import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.placeholder.AdditionalPlayer; import com.willfp.eco.core.placeholder.AdditionalPlayer;
import com.willfp.eco.core.placeholder.DynamicPlaceholder; import com.willfp.eco.core.placeholder.DynamicPlaceholder;
@@ -16,6 +15,7 @@ import com.willfp.eco.core.placeholder.PlayerStaticPlaceholder;
import com.willfp.eco.core.placeholder.PlayerlessPlaceholder; import com.willfp.eco.core.placeholder.PlayerlessPlaceholder;
import com.willfp.eco.core.placeholder.StaticPlaceholder; import com.willfp.eco.core.placeholder.StaticPlaceholder;
import com.willfp.eco.util.StringUtils; import com.willfp.eco.util.StringUtils;
import org.apache.commons.lang.Validate;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -36,7 +36,6 @@ import java.util.regex.Pattern;
/** /**
* Class to handle placeholder integrations. * Class to handle placeholder integrations.
*/ */
@SuppressWarnings("removal")
public final class PlaceholderManager { public final class PlaceholderManager {
/** /**
* All registered placeholders. * All registered placeholders.
@@ -78,6 +77,11 @@ public final class PlaceholderManager {
* Empty injectable object. * Empty injectable object.
*/ */
public static final PlaceholderInjectable EMPTY_INJECTABLE = new PlaceholderInjectable() { public static final PlaceholderInjectable EMPTY_INJECTABLE = new PlaceholderInjectable() {
@Override
public void addInjectablePlaceholder(@NotNull Iterable<InjectablePlaceholder> placeholders) {
// Do nothing.
}
@Override @Override
public void clearInjectedPlaceholders() { public void clearInjectedPlaceholders() {
// Do nothing. // Do nothing.
@@ -110,25 +114,12 @@ public final class PlaceholderManager {
throw new IllegalArgumentException("Static placeholders cannot be registered!"); throw new IllegalArgumentException("Static placeholders cannot be registered!");
} }
EcoPlugin plugin = placeholder.getPlugin() == null ? Eco.get().getEcoPlugin() : placeholder.getPlugin();
Map<Pattern, Placeholder> pluginPlaceholders = REGISTERED_PLACEHOLDERS Map<Pattern, Placeholder> pluginPlaceholders = REGISTERED_PLACEHOLDERS
.getOrDefault(plugin, new HashMap<>()); .getOrDefault(placeholder.getPlugin(), new HashMap<>());
pluginPlaceholders.put(placeholder.getPattern(), placeholder); pluginPlaceholders.put(placeholder.getPattern(), placeholder);
REGISTERED_PLACEHOLDERS.put(plugin, pluginPlaceholders); REGISTERED_PLACEHOLDERS.put(placeholder.getPlugin(), pluginPlaceholders);
}
/**
* Register a placeholder.
*
* @param placeholder The placeholder to register.
* @deprecated Uses old placeholder system.
*/
@Deprecated(since = "6.28.0", forRemoval = true)
public static void registerPlaceholder(@NotNull final PlaceholderEntry placeholder) {
registerPlaceholder(placeholder.toModernPlaceholder());
} }
/** /**
@@ -139,10 +130,11 @@ public final class PlaceholderManager {
* @return The value of the placeholder. * @return The value of the placeholder.
* @deprecated Specify a plugin to get the result from. * @deprecated Specify a plugin to get the result from.
*/ */
@Deprecated @Deprecated(since = "6.52.2", forRemoval = true)
@SuppressWarnings("unused")
public static String getResult(@Nullable final Player player, public static String getResult(@Nullable final Player player,
@NotNull final String identifier) { @NotNull final String identifier) {
return getResult(player, identifier, null); throw new UnsupportedOperationException("Please specify a plugin to get the result from!");
} }
/** /**
@@ -156,34 +148,21 @@ public final class PlaceholderManager {
@NotNull @NotNull
public static String getResult(@Nullable final Player player, public static String getResult(@Nullable final Player player,
@NotNull final String identifier, @NotNull final String identifier,
@Nullable final EcoPlugin plugin) { @NotNull final EcoPlugin plugin) {
Validate.notNull(plugin, "Plugin cannot be null!");
// This is really janky, and it sucks, but it works so? // This is really janky, and it sucks, but it works so?
// Compensating for regex being slow so that's why we get it. // Compensating for regex being slow so that's why we get it.
Placeholder placeholder = PLACEHOLDER_LOOKUP_CACHE.get( Placeholder placeholder = PLACEHOLDER_LOOKUP_CACHE.get(
new PlaceholderLookup(identifier, plugin), new PlaceholderLookup(identifier, plugin),
(it) -> { (it) -> {
EcoPlugin owner = plugin == null ? Eco.get().getEcoPlugin() : plugin;
// I hate the streams API. // I hate the streams API.
Optional<Placeholder> found = REGISTERED_PLACEHOLDERS return REGISTERED_PLACEHOLDERS
.getOrDefault(owner, new HashMap<>()) .getOrDefault(plugin, new HashMap<>())
.entrySet() .entrySet()
.stream().filter(entry -> entry.getKey().matcher(identifier).matches()) .stream().filter(entry -> entry.getKey().matcher(identifier).matches())
.map(Map.Entry::getValue) .map(Map.Entry::getValue)
.findFirst(); .findFirst();
if (found.isEmpty() && plugin != null) {
// Here we go again! Something about legacy support? I don't remember.
// I won't touch it though, I'm scared of the placeholder system.
found = REGISTERED_PLACEHOLDERS
.getOrDefault(Eco.get().getEcoPlugin(), new HashMap<>())
.entrySet()
.stream().filter(entry -> entry.getKey().matcher(identifier).matches())
.map(Map.Entry::getValue)
.findFirst();
}
return found;
} }
).orElse(null); ).orElse(null);
@@ -231,22 +210,6 @@ public final class PlaceholderManager {
return translatePlaceholders(text, player, EMPTY_INJECTABLE); return translatePlaceholders(text, player, EMPTY_INJECTABLE);
} }
/**
* Translate all placeholders with respect to a player.
*
* @param text The text that may contain placeholders to translate.
* @param player The player to translate the placeholders with respect to.
* @param statics Extra static placeholders.
* @return The text, translated.
* @deprecated Use new static system.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public static String translatePlaceholders(@NotNull final String text,
@Nullable final Player player,
@NotNull final List<StaticPlaceholder> statics) {
return translatePlaceholders(text, player, EMPTY_INJECTABLE);
}
/** /**
* Translate all placeholders with respect to a player. * Translate all placeholders with respect to a player.
* *
@@ -326,6 +289,11 @@ public final class PlaceholderManager {
} }
} }
// Only run jank code if there are no integrations.
if (REGISTERED_INTEGRATIONS.isEmpty()) {
processed = setWithoutIntegration(processed, player);
}
for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) { for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) {
processed = integration.translate(processed, player); processed = integration.translate(processed, player);
} }
@@ -350,12 +318,9 @@ public final class PlaceholderManager {
public static List<String> findPlaceholdersIn(@NotNull final String text) { public static List<String> findPlaceholdersIn(@NotNull final String text) {
Set<String> found = new HashSet<>(); Set<String> found = new HashSet<>();
// Mock PAPI for those without it installed Matcher matcher = PATTERN.matcher(text);
if (REGISTERED_INTEGRATIONS.isEmpty()) { while (matcher.find()) {
Matcher matcher = PATTERN.matcher(text); found.add(matcher.group());
while (matcher.find()) {
found.add(matcher.group());
}
} }
for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) { for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) {
@@ -365,6 +330,95 @@ public final class PlaceholderManager {
return new ArrayList<>(found); return new ArrayList<>(found);
} }
/**
* Set placeholders without any integrations.
* <p>
* This is fallback if for some reason you don't have PAPI installed.
* It's a cut-down version of the actual PAPI code, and I don't
* really know how it works.
* <p>
* Original source
* <a href="https://github.com/PlaceholderAPI/PlaceholderAPI/blob/master/src/main/java/me/clip/placeholderapi/replacer/CharsReplacer.java">here</a>.
*
* @param text The text.
* @param player The player.
* @return The text.
*/
private static String setWithoutIntegration(@NotNull final String text,
@Nullable final Player player) {
char[] chars = text.toCharArray();
StringBuilder builder = new StringBuilder(text.length());
StringBuilder identifier = new StringBuilder();
StringBuilder parameters = new StringBuilder();
for (int i = 0; i < chars.length; i++) {
char currentChar = chars[i];
if (currentChar == '%' && i + 1 < chars.length) {
boolean identified = false;
boolean badPlaceholder = true;
boolean hadSpace = false;
while (true) {
i++;
if (i >= chars.length) {
break;
}
char p = chars[i];
if (p == ' ' && !identified) {
hadSpace = true;
break;
}
if (p == '%') {
badPlaceholder = false;
break;
}
if (p == '_' && !identified) {
identified = true;
} else if (identified) {
parameters.append(p);
} else {
identifier.append(p);
}
}
String pluginName = identifier.toString().toLowerCase();
EcoPlugin plugin = EcoPlugin.getPlugin(pluginName);
String placeholderIdentifier = parameters.toString();
identifier.setLength(0);
parameters.setLength(0);
if (badPlaceholder) {
builder.append('%').append(pluginName);
if (identified) {
builder.append('_').append(placeholderIdentifier);
}
if (hadSpace) {
builder.append(' ');
}
} else {
if (plugin == null) {
builder.append('%').append(pluginName);
if (identified) {
builder.append('_');
}
builder.append(placeholderIdentifier).append('%');
} else {
builder.append(getResult(player, placeholderIdentifier, plugin));
}
}
} else {
builder.append(currentChar);
}
}
return builder.toString();
}
private record PlaceholderLookup(@NotNull String identifier, private record PlaceholderLookup(@NotNull String identifier,
@Nullable EcoPlugin plugin) { @Nullable EcoPlugin plugin) {

View File

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

View File

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

View File

@@ -568,6 +568,42 @@ public final class Items {
return EMPTY_TESTABLE_ITEM.matches(itemStack); return EMPTY_TESTABLE_ITEM.matches(itemStack);
} }
/**
* Get if an item matches any items.
*
* @param itemStack The item.
* @param items The items.
* @return If matches any.
*/
public static boolean matchesAny(@Nullable final ItemStack itemStack,
@NotNull final Collection<TestableItem> items) {
for (TestableItem item : items) {
if (item.matches(itemStack)) {
return true;
}
}
return false;
}
/**
* Get if any item matches any item.
*
* @param itemStacks The items.
* @param items The items.
* @return If matches any.
*/
public static boolean matchesAny(@NotNull final Collection<ItemStack> itemStacks,
@NotNull final Collection<TestableItem> items) {
for (ItemStack itemStack : itemStacks) {
if (matchesAny(itemStack, items)) {
return true;
}
}
return false;
}
private Items() { private Items() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
} }

View File

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

View File

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

View File

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

View File

@@ -2,7 +2,6 @@ package com.willfp.eco.core.placeholder;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@@ -16,7 +15,7 @@ public sealed interface Placeholder permits PlayerPlaceholder, PlayerlessPlaceho
* *
* @return The plugin. * @return The plugin.
*/ */
@Nullable @NotNull
EcoPlugin getPlugin(); EcoPlugin getPlugin();
/** /**

View File

@@ -2,7 +2,6 @@ package com.willfp.eco.core.placeholder;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@@ -15,7 +14,7 @@ public interface PlaceholderInjectable {
* @param placeholders The placeholders. * @param placeholders The placeholders.
*/ */
default void injectPlaceholders(@NotNull StaticPlaceholder... placeholders) { default void injectPlaceholders(@NotNull StaticPlaceholder... placeholders) {
this.injectPlaceholders(List.of(placeholders)); this.addInjectablePlaceholder(List.of(placeholders));
} }
/** /**
@@ -27,20 +26,6 @@ public interface PlaceholderInjectable {
this.addInjectablePlaceholder(List.of(placeholders)); this.addInjectablePlaceholder(List.of(placeholders));
} }
/**
* Inject placeholder.
*
* @param placeholders The placeholders.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
default void injectPlaceholders(@NotNull Iterable<StaticPlaceholder> placeholders) {
List<InjectablePlaceholder> toInject = new ArrayList<>();
for (StaticPlaceholder placeholder : placeholders) {
toInject.add(placeholder);
}
this.addInjectablePlaceholder(toInject);
}
/** /**
* Inject placeholders. * Inject placeholders.
* <p> * <p>
@@ -48,41 +33,13 @@ public interface PlaceholderInjectable {
* *
* @param placeholders The placeholders. * @param placeholders The placeholders.
*/ */
default void addInjectablePlaceholder(@NotNull Iterable<InjectablePlaceholder> placeholders) { void addInjectablePlaceholder(@NotNull Iterable<InjectablePlaceholder> placeholders);
List<StaticPlaceholder> toInject = new ArrayList<>();
for (InjectablePlaceholder placeholder : placeholders) {
if (placeholder instanceof StaticPlaceholder staticPlaceholder) {
toInject.add(staticPlaceholder);
}
}
this.injectPlaceholders(toInject);
}
/** /**
* Clear injected placeholders. * Clear injected placeholders.
*/ */
void clearInjectedPlaceholders(); void clearInjectedPlaceholders();
/**
* Get injected placeholders.
*
* @return Injected placeholders.
* @deprecated Use getPlaceholderInjections.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
@NotNull
default List<StaticPlaceholder> getInjectedPlaceholders() {
List<StaticPlaceholder> found = new ArrayList<>();
for (InjectablePlaceholder placeholder : getPlaceholderInjections()) {
if (placeholder instanceof StaticPlaceholder staticPlaceholder) {
found.add(staticPlaceholder);
}
}
return found;
}
/** /**
* Get injected placeholders. * Get injected placeholders.
* <p> * <p>
@@ -91,7 +48,5 @@ public interface PlaceholderInjectable {
* @return Injected placeholders. * @return Injected placeholders.
*/ */
@NotNull @NotNull
default List<InjectablePlaceholder> getPlaceholderInjections() { List<InjectablePlaceholder> getPlaceholderInjections();
return new ArrayList<>(getInjectedPlaceholders());
}
} }

View File

@@ -1,12 +0,0 @@
package com.willfp.eco.core.proxy;
/**
* Prior to 6.17.0, all proxies were required to implement this interface,
* however it produced no functionality and was not even used internally.
*
* @deprecated Unused class, not required. Will be removed in a subsequent release.
*/
@Deprecated(since = "6.17.0", forRemoval = true)
public interface AbstractProxy {
}

View File

@@ -1,21 +0,0 @@
package com.willfp.eco.core.proxy;
import com.willfp.eco.core.EcoPlugin;
import org.jetbrains.annotations.NotNull;
/**
* A cleaner is an internal component to fix classloader errors.
* <p>
* Important to allow for PlugMan/ServerUtils support.
*
* @deprecated No reason for this to be in the API.
*/
@Deprecated(since = "6.43.0", forRemoval = true)
public interface Cleaner {
/**
* Clean up classes left over from plugin.
*
* @param plugin The plugin.
*/
void clean(@NotNull EcoPlugin plugin);
}

View File

@@ -22,7 +22,8 @@ public final class ProxyConstants {
"v1_18_R1", "v1_18_R1",
"v1_18_R2", "v1_18_R2",
"v1_19_R1", "v1_19_R1",
"v1_19_R2" "v1_19_R2",
"v1_19_R3"
); );
private ProxyConstants() { private ProxyConstants() {

View File

@@ -16,15 +16,4 @@ public class ProxyError extends Error {
@NotNull final Throwable cause) { @NotNull final Throwable cause) {
super(message, 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(forRemoval = true)
public ProxyError(@NotNull final String message) {
super(message);
}
} }

View File

@@ -1,31 +0,0 @@
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.
*/
@SuppressWarnings("removal")
@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", forRemoval = true)
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());
}
}

View File

@@ -53,7 +53,11 @@ public final class Recipes {
* @return The match, or null if not found. * @return The match, or null if not found.
*/ */
@Nullable @Nullable
public static CraftingRecipe getMatch(@NotNull final ItemStack[] matrix) { public static CraftingRecipe getMatch(@Nullable final ItemStack[] matrix) {
if (matrix == null) {
return null;
}
return RECIPES_FROM_MATRIX.get(matrix).orElse(null); return RECIPES_FROM_MATRIX.get(matrix).orElse(null);
} }

View File

@@ -20,7 +20,7 @@ public interface CraftingRecipe {
* @param matrix The matrix to check. * @param matrix The matrix to check.
* @return If the recipe matches. * @return If the recipe matches.
*/ */
boolean test(@NotNull ItemStack[] matrix); boolean test(@Nullable ItemStack[] matrix);
/** /**
* Register the recipe. * Register the recipe.

View File

@@ -69,7 +69,11 @@ public final class ShapedCraftingRecipe implements CraftingRecipe {
} }
@Override @Override
public boolean test(@NotNull final ItemStack[] matrix) { public boolean test(@Nullable final ItemStack[] matrix) {
if (matrix == null) {
return false;
}
List<ItemStack> dynamicMatrix = Arrays.asList(matrix); List<ItemStack> dynamicMatrix = Arrays.asList(matrix);
boolean matches = true; boolean matches = true;
for (int i = 0; i < 9; i++) { for (int i = 0; i < 9; i++) {

View File

@@ -80,7 +80,11 @@ public final class ShapelessCraftingRecipe implements CraftingRecipe {
} }
@Override @Override
public boolean test(@NotNull final ItemStack[] matrix) { public boolean test(@Nullable final ItemStack[] matrix) {
if (matrix == null) {
return false;
}
RecipeTest test = newTest(); RecipeTest test = newTest();
for (ItemStack stack : matrix) { for (ItemStack stack : matrix) {

View File

@@ -5,6 +5,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@@ -14,7 +16,7 @@ import java.util.regex.Pattern;
* *
* @param <T> The type of {@link Registrable}. * @param <T> The type of {@link Registrable}.
*/ */
public abstract class Registry<T extends Registrable> { public class Registry<T extends Registrable> implements Iterable<T> {
/** /**
* The ID pattern. * The ID pattern.
*/ */
@@ -25,10 +27,21 @@ public abstract class Registry<T extends Registrable> {
*/ */
private final Map<String, T> registry = new HashMap<>(); private final Map<String, T> registry = new HashMap<>();
/**
* If the registry is locked.
*/
private boolean isLocked = false;
/**
* The locker, used to 'secure' registries and prevent random unlocking.
*/
@Nullable
private Object locker = null;
/** /**
* Instantiate a new registry. * Instantiate a new registry.
*/ */
protected Registry() { public Registry() {
} }
@@ -40,7 +53,11 @@ public abstract class Registry<T extends Registrable> {
*/ */
@NotNull @NotNull
public T register(@NotNull final T element) { public T register(@NotNull final T element) {
Validate.isTrue(ID_PATTERN.matcher(element.getID()).matches(), "ID must match pattern: " + ID_PATTERN.pattern()); if (this.isLocked) {
throw new IllegalStateException("Cannot add to locked registry! (ID: " + element.getID() + ")");
}
Validate.isTrue(ID_PATTERN.matcher(element.getID()).matches(), "ID must match pattern: " + ID_PATTERN.pattern() + " (was " + element.getID() + ")");
registry.put(element.getID(), element); registry.put(element.getID(), element);
@@ -56,6 +73,10 @@ public abstract class Registry<T extends Registrable> {
* @return The element. * @return The element.
*/ */
public T remove(@NotNull final T element) { public T remove(@NotNull final T element) {
if (this.isLocked) {
throw new IllegalStateException("Cannot remove from locked registry! (ID: " + element.getID() + ")");
}
element.onRemove(); element.onRemove();
registry.remove(element.getID()); registry.remove(element.getID());
@@ -71,6 +92,10 @@ public abstract class Registry<T extends Registrable> {
*/ */
@Nullable @Nullable
public T remove(@NotNull final String id) { public T remove(@NotNull final String id) {
if (this.isLocked) {
throw new IllegalStateException("Cannot remove from locked registry! (ID: " + id + ")");
}
T element = registry.get(id); T element = registry.get(id);
if (element != null) { if (element != null) {
@@ -95,7 +120,7 @@ public abstract class Registry<T extends Registrable> {
* Clear the registry. * Clear the registry.
*/ */
public void clear() { public void clear() {
for (T value : registry.values()) { for (T value : Set.copyOf(registry.values())) {
remove(value); remove(value);
} }
} }
@@ -108,4 +133,73 @@ public abstract class Registry<T extends Registrable> {
public Set<T> values() { public Set<T> values() {
return Set.copyOf(registry.values()); return Set.copyOf(registry.values());
} }
/**
* Get if the registry is locked.
*
* @return If the registry is locked.
*/
public boolean isLocked() {
return isLocked;
}
/**
* Lock the registry.
*
* @param locker The locker.
*/
public void lock(@Nullable final Object locker) {
this.locker = locker;
isLocked = true;
}
/**
* Unlock the registry.
*
* @param locker The locker.
*/
public void unlock(@Nullable final Object locker) {
if (this.locker != locker) {
throw new IllegalArgumentException("Cannot unlock registry!");
}
isLocked = false;
}
/**
* Get if the registry is empty.
*
* @return If the registry is empty.
*/
public boolean isEmpty() {
return registry.isEmpty();
}
/**
* Get if the registry is not empty.
*
* @return If the registry is not empty.
*/
public boolean isNotEmpty() {
return !isEmpty();
}
@NotNull
@Override
public Iterator<T> iterator() {
return values().iterator();
}
/**
* Try to fit a string to the ID pattern.
*
* @param string The string.
* @return The string in lowercase, but with all spaces, dots, and dashes replaced with underscores.
*/
@NotNull
public static String tryFitPattern(@NotNull final String string) {
return string.replace(" ", "_")
.replace(".", "_")
.replace("-", "_")
.toLowerCase(Locale.ENGLISH);
}
} }

View File

@@ -0,0 +1,17 @@
package com.willfp.eco.core.version;
import org.jetbrains.annotations.NotNull;
/**
* An error thrown when eco is outdated.
*/
public class OutdatedEcoVersionError extends Error {
/**
* Create a new OutdatedEcoVersionError.
*
* @param message The message.
*/
public OutdatedEcoVersionError(@NotNull final String message) {
super(message);
}
}

View File

@@ -0,0 +1,53 @@
package com.willfp.eco.core.version;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.jetbrains.annotations.NotNull;
/**
* A minimal class to represent a version, uses DefaultArtifactVersion under the hood.
* <p>
* This class exists to resolve issues where 1.17 doesn't include DefaultArtifactVersion.
*/
public class Version implements Comparable<Version> {
/**
* The version.
*/
private final DefaultArtifactVersion version;
/**
* Create a new version.
*
* @param version The version.
*/
public Version(@NotNull final String version) {
this.version = new DefaultArtifactVersion(version);
}
@Override
public int compareTo(@NotNull final Version o) {
return this.version.compareTo(o.version);
}
@Override
public String toString() {
return this.version.toString();
}
@Override
public boolean equals(@NotNull final Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof Version other)) {
return false;
}
return this.version.equals(other.version);
}
@Override
public int hashCode() {
return this.version.hashCode();
}
}

View File

@@ -1,52 +1,22 @@
package com.willfp.eco.util; package com.willfp.eco.util;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.persistence.PersistentDataType; import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Queue;
import java.util.Set; import java.util.Set;
/** /**
* Utilities / API methods for blocks. * Utilities / API methods for blocks.
*/ */
public final class BlockUtils { public final class BlockUtils {
/**
* Max blocks to mine (yes, this is to prevent a stack overflow).
*/
private static final int MAX_BLOCKS = 2500;
private static Set<Block> getNearbyBlocks(@NotNull final Block start,
@NotNull final List<Material> allowedMaterials,
@NotNull final Set<Block> blocks,
final int limit) {
for (BlockFace face : BlockFace.values()) {
Block block = start.getRelative(face);
if (blocks.contains(block)) {
continue;
}
if (allowedMaterials.contains(block.getType())) {
blocks.add(block);
if (blocks.size() > limit || blocks.size() > MAX_BLOCKS) {
return blocks;
}
blocks.addAll(getNearbyBlocks(block, allowedMaterials, blocks, limit));
}
}
return blocks;
}
/** /**
* Get a set of all blocks in contact with each other of a specific type. * Get a set of all blocks in contact with each other of a specific type.
* *
@@ -59,28 +29,32 @@ public final class BlockUtils {
public static Set<Block> getVein(@NotNull final Block start, public static Set<Block> getVein(@NotNull final Block start,
@NotNull final List<Material> allowedMaterials, @NotNull final List<Material> allowedMaterials,
final int limit) { final int limit) {
return getNearbyBlocks(start, allowedMaterials, new HashSet<>(), limit); Set<Block> blocks = new HashSet<>();
} Queue<Block> toProcess = new LinkedList<>();
/** if (allowedMaterials.contains(start.getType())) {
* Break the block as if the player had done it manually. toProcess.add(start);
*
* @param player The player to break the block as.
* @param block The block to break.
* @deprecated Added into spigot API in 1.17.1
*/
@Deprecated(since = "6.26.2", forRemoval = true)
public static void breakBlock(@NotNull final Player player,
@NotNull final Block block) {
Location location = block.getLocation();
World world = location.getWorld();
assert world != null;
if (location.getY() < world.getMinHeight() || location.getY() > world.getMaxHeight()) {
return;
} }
player.breakBlock(block); while (!toProcess.isEmpty() && blocks.size() < limit) {
Block currentBlock = toProcess.poll();
if (blocks.contains(currentBlock)) {
continue;
}
blocks.add(currentBlock);
for (BlockFace face : BlockFace.values()) {
Block adjacentBlock = currentBlock.getRelative(face);
if (!blocks.contains(adjacentBlock) && allowedMaterials.contains(adjacentBlock.getType())) {
toProcess.add(adjacentBlock);
}
}
}
return blocks;
} }
/** /**

View File

@@ -8,7 +8,6 @@ import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerItemBreakEvent; import org.bukkit.event.player.PlayerItemBreakEvent;
import org.bukkit.event.player.PlayerItemDamageEvent; import org.bukkit.event.player.PlayerItemDamageEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -19,25 +18,6 @@ import org.jetbrains.annotations.NotNull;
// Have to suppress casts to ItemMeta because the methods don't exist for some older versions that eco supports. // Have to suppress casts to ItemMeta because the methods don't exist for some older versions that eco supports.
@SuppressWarnings("RedundantCast") @SuppressWarnings("RedundantCast")
public final class DurabilityUtils { public final class DurabilityUtils {
/**
* Damage an item in a player's inventory.
* The slot of a held item can be obtained with {@link PlayerInventory#getHeldItemSlot()}.
* Armor slots are 39 (helmet), 38 (chestplate), 37 (leggings), 36 (boots).
*
* @param player The player.
* @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", forRemoval = true)
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. * Damage an item in a player's inventory.
* *

View File

@@ -2,11 +2,9 @@ package com.willfp.eco.util;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager; import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
import com.willfp.eco.core.placeholder.AdditionalPlayer;
import com.willfp.eco.core.placeholder.InjectablePlaceholder;
import com.willfp.eco.core.math.MathContext; import com.willfp.eco.core.math.MathContext;
import com.willfp.eco.core.placeholder.AdditionalPlayer;
import com.willfp.eco.core.placeholder.PlaceholderInjectable; import com.willfp.eco.core.placeholder.PlaceholderInjectable;
import com.willfp.eco.core.placeholder.StaticPlaceholder;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -14,7 +12,6 @@ import org.jetbrains.annotations.Nullable;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
@@ -89,34 +86,6 @@ public final class NumberUtils {
return (input * k) / (input * k - input + 1); return (input * k) / (input * k - input + 1);
} }
/**
* If value is above maximum, set it to maximum.
*
* @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);
}
/**
* If value is above maximum, set it to maximum.
*
* @param toChange The value to test.
* @param limit The maximum.
* @return The new value.
* @deprecated Pointless method.
*/
@Deprecated(since = "6.19.0", forRemoval = true)
public static double equalIfOver(final double toChange,
final double limit) {
return Math.min(toChange, limit);
}
/** /**
* Get Roman Numeral from number. * Get Roman Numeral from number.
* *
@@ -256,36 +225,6 @@ public final class NumberUtils {
return evaluateExpression(expression, player, PlaceholderManager.EMPTY_INJECTABLE); return evaluateExpression(expression, player, PlaceholderManager.EMPTY_INJECTABLE);
} }
/**
* Evaluate an expression with respect to a player (for placeholders).
*
* @param expression The expression.
* @param player The player.
* @param statics The static placeholders.
* @return The value of the expression, or zero if invalid.
* @deprecated Use new statics system.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public static double evaluateExpression(@NotNull final String expression,
@Nullable final Player player,
@NotNull final Iterable<StaticPlaceholder> statics) {
return evaluateExpression(expression, player, new PlaceholderInjectable() {
@Override
public void clearInjectedPlaceholders() {
// Do nothing.
}
@Override
public @NotNull List<InjectablePlaceholder> getPlaceholderInjections() {
List<InjectablePlaceholder> injections = new ArrayList<>();
for (StaticPlaceholder placeholder : statics) {
injections.add(placeholder);
}
return injections;
}
});
}
/** /**
* Evaluate an expression with respect to a player (for placeholders). * Evaluate an expression with respect to a player (for placeholders).
* *

View File

@@ -426,20 +426,6 @@ public final class StringUtils {
return processedString; return processedString;
} }
/**
* Internal implementation of {@link String#valueOf}.
* Formats collections and doubles better.
*
* @param object The object to convert to string.
* @return The object stringified.
* @deprecated Poorly named method. Use {@link StringUtils#toNiceString(Object)} instead.
*/
@NotNull
@Deprecated(since = "6.26.0", forRemoval = true)
public static String internalToString(@Nullable final Object object) {
return toNiceString(object);
}
/** /**
* Internal implementation of {@link String#valueOf}. * Internal implementation of {@link String#valueOf}.
* Formats collections and doubles better. * Formats collections and doubles better.

View File

@@ -4,24 +4,16 @@ import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap; import com.google.common.collect.HashBiMap;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Team; import org.bukkit.scoreboard.Team;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
/** /**
* Utilities / API methods for teams. * Utilities / API methods for teams.
*/ */
public final class TeamUtils { public final class TeamUtils {
/**
* Ore ChatColors.
*/
private static final Map<Material, ChatColor> MATERIAL_COLORS = new HashMap<>();
/** /**
* All chat color teams. * All chat color teams.
*/ */
@@ -60,44 +52,10 @@ public final class TeamUtils {
return team; return team;
} }
/**
* Get team from material.
* <p>
* For {@link org.bukkit.potion.PotionEffectType#GLOWING}.
*
* @param material The material to find the team from.
* @return The team.
* @deprecated Stupid method.
*/
@NotNull
@Deprecated(since = "6.24.0", forRemoval = true)
public static Team getMaterialColorTeam(@NotNull final Material material) {
return fromChatColor(MATERIAL_COLORS.getOrDefault(material, ChatColor.WHITE));
}
static { static {
for (ChatColor value : ChatColor.values()) { for (ChatColor value : ChatColor.values()) {
fromChatColor(value); fromChatColor(value);
} }
MATERIAL_COLORS.put(Material.COAL_ORE, ChatColor.BLACK);
MATERIAL_COLORS.put(Material.IRON_ORE, ChatColor.GRAY);
MATERIAL_COLORS.put(Material.GOLD_ORE, ChatColor.YELLOW);
MATERIAL_COLORS.put(Material.LAPIS_ORE, ChatColor.BLUE);
MATERIAL_COLORS.put(Material.REDSTONE_ORE, ChatColor.RED);
MATERIAL_COLORS.put(Material.DIAMOND_ORE, ChatColor.AQUA);
MATERIAL_COLORS.put(Material.EMERALD_ORE, ChatColor.GREEN);
MATERIAL_COLORS.put(Material.ANCIENT_DEBRIS, ChatColor.DARK_RED);
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() { private TeamUtils() {

View File

@@ -38,6 +38,15 @@ class DSLConfig internal constructor(type: ConfigType) : GenericConfig(type) {
fun config(type: ConfigType = ConfigType.YAML, builder: DSLConfig.() -> Unit): Config = fun config(type: ConfigType = ConfigType.YAML, builder: DSLConfig.() -> Unit): Config =
DSLConfig(type).apply(builder) DSLConfig(type).apply(builder)
/**
* Helper function to create JSON configs with a kotlin DSL.
*
* @param builder The builder.
* @return The config.
*/
fun json(builder: DSLConfig.() -> Unit): Config =
config(ConfigType.JSON, builder)
/** @see Configs.empty */ /** @see Configs.empty */
fun emptyConfig() = Configs.empty() fun emptyConfig() = Configs.empty()

View File

@@ -0,0 +1,34 @@
@file:JvmName("ExternalDataStoreExtensions")
package com.willfp.eco.core.data
/**
* @see ExternalDataStore.put
*/
fun writeExternalData(
key: String,
value: Any
) = ExternalDataStore.put(key, value)
/**
* @see ExternalDataStore.get
*/
inline fun <reified T> readExternalData(
key: String
): T? = ExternalDataStore.get(key, T::class.java)
/**
* @see ExternalDataStore.get
*/
inline fun <reified T> readExternalData(
key: String,
default: T
): T = ExternalDataStore.get(key, T::class.java) ?: default
/**
* @see ExternalDataStore.get
*/
inline fun <reified T> readExternalData(
key: String,
default: () -> T
): T = readExternalData(key, default())

View File

@@ -39,3 +39,11 @@ fun ItemStack.toSNBT() =
/** @see Items.isEmpty */ /** @see Items.isEmpty */
val ItemStack?.isEmpty: Boolean val ItemStack?.isEmpty: Boolean
get() = Items.isEmpty(this) get() = Items.isEmpty(this)
/** @see Items.matchesAny */
fun Collection<TestableItem>.matches(item: ItemStack): Boolean =
Items.matchesAny(item, this)
/** @see Items.matchesAny */
fun Collection<TestableItem>.matches(items: Collection<ItemStack>): Boolean =
Items.matchesAny(items, this)

View File

@@ -0,0 +1,13 @@
package com.willfp.eco.core.registry
/**
* A registrable that has a string ID, for use with Kotlin.
*/
interface KRegistrable : Registrable {
/**
* The ID of the registrable.
*/
val id: String
override fun getID() = id
}

View File

@@ -0,0 +1,7 @@
@file:JvmName("RegistryExtensions")
package com.willfp.eco.core.registry
/** @see Registry.tryFitPattern */
fun String.tryFitRegistryPattern(): String =
Registry.tryFitPattern(this)

View File

@@ -1,8 +0,0 @@
group 'com.willfp'
version rootProject.version
subprojects {
dependencies {
compileOnly project(":eco-api")
}
}

View File

@@ -0,0 +1,8 @@
group = "com.willfp"
version = rootProject.version
subprojects {
dependencies {
compileOnly(project(":eco-api"))
}
}

View File

@@ -1,15 +0,0 @@
group 'com.willfp'
version rootProject.version
dependencies {
// Libraries
implementation 'org.reflections:reflections:0.9.12'
implementation 'org.objenesis:objenesis:3.2'
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
compileOnly 'me.clip:placeholderapi:2.10.10'
compileOnly 'net.kyori:adventure-text-minimessage:4.10.0'
compileOnly 'net.kyori:adventure-platform-bukkit:4.1.0'
compileOnly 'org.yaml:snakeyaml:1.33'
compileOnly 'com.moandjiezana.toml:toml4j:0.7.2'
}

View File

@@ -0,0 +1,15 @@
group = "com.willfp"
version = rootProject.version
dependencies {
// Libraries
implementation("org.reflections:reflections:0.9.12")
implementation("org.objenesis:objenesis:3.2")
compileOnly("org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT")
compileOnly("me.clip:placeholderapi:2.10.10")
compileOnly("net.kyori:adventure-text-minimessage:4.10.0")
compileOnly("net.kyori:adventure-platform-bukkit:4.1.0")
compileOnly("org.yaml:snakeyaml:1.33")
compileOnly("com.moandjiezana.toml:toml4j:0.7.2")
}

View File

@@ -7,18 +7,39 @@ import com.willfp.eco.core.config.readConfig
object EcoPropsParser : PluginProps.PropsParser<Config> { object EcoPropsParser : PluginProps.PropsParser<Config> {
override fun parseFrom(config: Config): PluginProps { override fun parseFrom(config: Config): PluginProps {
val props = blankProps
if (!config.has("options")) {
parseAndApplyOptions(props, config)
} else {
parseAndApplyOptions(props, config.getSubsection("options"))
}
return props.apply {
for (envConfig in config.getSubsections("environment")) {
val name = envConfig.getStringOrNull("name") ?: continue
val value = envConfig.getStringOrNull("value") ?: continue
this.setEnvironmentVariable(name, value)
}
}
}
private fun parseAndApplyOptions(props: PluginProps, config: Config) {
val resourceId = config.getIntOrNull("resource-id") ?: 0 val resourceId = config.getIntOrNull("resource-id") ?: 0
val bStatsId = config.getIntOrNull("bstats-id") ?: 0 val bStatsId = config.getIntOrNull("bstats-id") ?: 0
val proxyPackage = config.getStringOrNull("proxy-package") ?: "" val proxyPackage = config.getStringOrNull("proxy-package") ?: ""
val color = config.getStringOrNull("color") ?: "&f" val color = config.getStringOrNull("color") ?: "&f"
val supportsExtensions = config.getBoolOrNull("supports-extensions") ?: false val supportsExtensions = config.getBoolOrNull("supports-extensions") ?: false
val usesReflectiveReload = config.getBoolOrNull("uses-reflective-reload") ?: true
return blankProps.apply { props.apply {
this.resourceId = resourceId this.resourceId = resourceId
this.bStatsId = bStatsId this.bStatsId = bStatsId
this.proxyPackage = proxyPackage this.proxyPackage = proxyPackage
this.color = color this.color = color
this.isSupportingExtensions = supportsExtensions this.isSupportingExtensions = supportsExtensions
this.setUsesReflectiveReload(usesReflectiveReload)
} }
} }

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.internal.command package com.willfp.eco.internal.command
import org.bukkit.Location
import org.bukkit.command.Command import org.bukkit.command.Command
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
import org.bukkit.command.PluginIdentifiableCommand import org.bukkit.command.PluginIdentifiableCommand
@@ -21,7 +22,16 @@ class DelegatedBukkitCommand(
label: String, label: String,
args: Array<out String>? args: Array<out String>?
): List<String> { ): List<String> {
return delegate.onTabComplete(sender, this, label, args) ?: emptyList() return delegate.onTabComplete(sender, this, label, args)
}
override fun tabComplete(
sender: CommandSender,
alias: String,
args: Array<out String>?,
location: Location?
): List<String> {
return delegate.onTabComplete(sender, this, alias, args)
} }
override fun getPlugin() = delegate.plugin override fun getPlugin() = delegate.plugin

View File

@@ -50,7 +50,7 @@ abstract class HandledCommand(
command: Command, command: Command,
label: String, label: String,
args: Array<out String>? args: Array<out String>?
): List<String>? { ): List<String> {
return handleTabComplete(sender, args?.toList() ?: listOf()) return handleTabComplete(sender, args?.toList() ?: listOf())
} }

View File

@@ -15,7 +15,7 @@ open class EcoConfig(
private val values = ConcurrentHashMap<String, Any?>() private val values = ConcurrentHashMap<String, Any?>()
@Transient @Transient
var injections = mutableListOf<InjectablePlaceholder>() var injections = ConcurrentHashMap<String, InjectablePlaceholder>()
fun init(values: Map<String, Any?>) { fun init(values: Map<String, Any?>) {
this.values.clear() this.values.clear()
@@ -104,12 +104,12 @@ open class EcoConfig(
} }
override fun getSubsectionOrNull(path: String): Config? { override fun getSubsectionOrNull(path: String): Config? {
return (get(path) as? Config)?.apply { this.addInjectablePlaceholder(injections) } return (get(path) as? Config)?.apply { this.addInjectablePlaceholder(injections.values) }
} }
override fun getSubsectionsOrNull(path: String): List<Config>? { override fun getSubsectionsOrNull(path: String): List<Config>? {
return getList<Config>(path) return getList<Config>(path)
?.map { it.apply { this.addInjectablePlaceholder(injections) } } ?.map { it.apply { this.addInjectablePlaceholder(injections.values) } }
?.toList() ?.toList()
} }
@@ -180,12 +180,13 @@ open class EcoConfig(
} }
override fun addInjectablePlaceholder(placeholders: Iterable<InjectablePlaceholder>) { override fun addInjectablePlaceholder(placeholders: Iterable<InjectablePlaceholder>) {
injections.removeIf { placeholders.any { placeholder -> it.identifier == placeholder.identifier } } for (placeholder in placeholders) {
injections.addAll(placeholders) injections[placeholder.identifier] = placeholder
}
} }
override fun getPlaceholderInjections(): List<InjectablePlaceholder> { override fun getPlaceholderInjections(): List<InjectablePlaceholder> {
return injections.toList() return injections.values.toList()
} }
override fun clearInjectedPlaceholders() { override fun clearInjectedPlaceholders() {

View File

@@ -2,14 +2,15 @@ package com.willfp.eco.internal.config
import com.willfp.eco.core.config.ConfigType import com.willfp.eco.core.config.ConfigType
import com.willfp.eco.core.placeholder.InjectablePlaceholder import com.willfp.eco.core.placeholder.InjectablePlaceholder
import java.util.concurrent.ConcurrentHashMap
class EcoConfigSection( class EcoConfigSection(
type: ConfigType, type: ConfigType,
values: Map<String, Any?> = emptyMap(), values: Map<String, Any?> = emptyMap(),
injections: Collection<InjectablePlaceholder> = emptyList() injections: MutableMap<String, InjectablePlaceholder> = mutableMapOf()
) : EcoConfig(type) { ) : EcoConfig(type) {
init { init {
this.init(values) this.init(values)
this.injections = injections.toMutableList() this.injections = ConcurrentHashMap(injections)
} }
} }

View File

@@ -1,22 +1,18 @@
package com.willfp.eco.internal.config package com.willfp.eco.internal.config.handler
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.config.interfaces.LoadableConfig
import com.willfp.eco.core.config.updating.ConfigHandler
import com.willfp.eco.core.config.updating.ConfigUpdater import com.willfp.eco.core.config.updating.ConfigUpdater
import org.reflections.Reflections import org.reflections.Reflections
import org.reflections.scanners.MethodAnnotationsScanner import org.reflections.scanners.MethodAnnotationsScanner
class EcoConfigHandler( class ReflectiveConfigHandler(
private val plugin: EcoPlugin private val plugin: EcoPlugin
) : ConfigHandler { ) : SimpleConfigHandler() {
private val reflections: Reflections = Reflections( private val reflections: Reflections = Reflections(
this.plugin::class.java.classLoader, this.plugin::class.java.classLoader,
MethodAnnotationsScanner() MethodAnnotationsScanner()
) )
private val configs = mutableListOf<LoadableConfig>()
override fun callUpdate() { override fun callUpdate() {
for (method in reflections.getMethodsAnnotatedWith(ConfigUpdater::class.java)) { for (method in reflections.getMethodsAnnotatedWith(ConfigUpdater::class.java)) {
runCatching { runCatching {
@@ -31,25 +27,6 @@ class EcoConfigHandler(
} }
} }
} }
override fun saveAllConfigs() {
for (config in configs) {
config.save()
}
}
override fun addConfig(config: LoadableConfig) {
configs.add(config)
}
override fun updateConfigs() {
for (config in configs) {
when (config) {
is EcoUpdatableConfig -> config.update()
is EcoLoadableConfig -> config.reloadFromFile()
}
}
}
} }
class InvalidUpdateMethodException(message: String) : RuntimeException(message) class InvalidUpdateMethodException(message: String) : RuntimeException(message)

View File

@@ -0,0 +1,33 @@
package com.willfp.eco.internal.config.handler
import com.willfp.eco.core.config.interfaces.LoadableConfig
import com.willfp.eco.core.config.updating.ConfigHandler
import com.willfp.eco.internal.config.EcoLoadableConfig
import com.willfp.eco.internal.config.EcoUpdatableConfig
open class SimpleConfigHandler : ConfigHandler {
private val configs = mutableListOf<LoadableConfig>()
override fun callUpdate() {
// Do nothing.
}
override fun saveAllConfigs() {
for (config in configs) {
config.save()
}
}
override fun addConfig(config: LoadableConfig) {
configs.add(config)
}
override fun updateConfigs() {
for (config in configs) {
when (config) {
is EcoUpdatableConfig -> config.update()
is EcoLoadableConfig -> config.reloadFromFile()
}
}
}
}

View File

@@ -0,0 +1,27 @@
package com.willfp.eco.internal.data
import com.willfp.eco.core.data.ExternalDataStoreObjectAdapter
import com.willfp.eco.core.version.Version
object VersionToStringAdapter: ExternalDataStoreObjectAdapter<Version, String>(
Version::class.java,
String::class.java
) {
override fun toAccessedObject(obj: String): Version = Version(obj)
override fun toStoredObject(obj: Version): String = obj.toString()
}
class MavenVersionToStringAdapter(
className: String
): ExternalDataStoreObjectAdapter<Any, String>(
Class.forName(className),
String::class.java
) {
private val constructor = Class.forName(className)
.getConstructor(String::class.java)
override fun toAccessedObject(obj: String): Any = constructor.newInstance(obj)
override fun toStoredObject(obj: Any): String = obj.toString()
}

View File

@@ -8,7 +8,7 @@ import java.util.logging.Logger
class EcoLogger(private val plugin: EcoPlugin) : Logger(plugin.name, null as String?) { class EcoLogger(private val plugin: EcoPlugin) : Logger(plugin.name, null as String?) {
override fun info(msg: String) { override fun info(msg: String) {
Bukkit.getConsoleSender().sendMessage("[${plugin.name}] ${StringUtils.format(msg)}") Bukkit.getConsoleSender().sendMessage("[${plugin.name}] ${StringUtils.format(msg, StringUtils.FormatOption.WITHOUT_PLACEHOLDERS)}")
} }
init { init {

View File

@@ -1,3 +1,8 @@
plugins {
id("io.papermc.paperweight.userdev") version "1.5.3" apply false
}
group = "com.willfp" group = "com.willfp"
version = rootProject.version version = rootProject.version
@@ -9,4 +14,4 @@ subprojects {
// libraries.minecraft.net machine broke // libraries.minecraft.net machine broke
compileOnly("com.github.Mojang:brigadier:1.0.18") compileOnly("com.github.Mojang:brigadier:1.0.18")
} }
} }

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