Compare commits

..

90 Commits

Author SHA1 Message Date
Auxilor
d96ad10960 Added locker to registry 2023-04-20 19:27:52 +01:00
Auxilor
21283b0928 Added ExternalDataStoreObjectAdapter 2023-04-20 19:19:00 +01:00
Auxilor
2797687f01 Cleanup 2023-04-20 17:54:23 +01:00
Auxilor
9c68d1fbc3 Merge branch 'master' into develop
# Conflicts:
#	eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/integrations/customitems/CustomItemsOraxen.kt
2023-04-20 17:45:06 +01:00
Auxilor
9371d9b88d Upstream 2023-04-20 17:44:58 +01:00
Auxilor
14e2ead488 Fixed javadoc, updated Kingdoms 2023-04-20 17:42:46 +01:00
Auxilor
5473bb8ef8 Cleaned up IntegrationRegistry 2023-04-20 17:34:18 +01:00
Auxilor
90c55849ae Isolated integration registration 2023-04-20 17:24:56 +01:00
Auxilor
9809140cf9 Isolated remaining integrations 2023-04-20 17:23:24 +01:00
Auxilor
49a82dc005 Isolated ShopManager 2023-04-20 17:15:18 +01:00
Auxilor
92dec03b9a Added IntegrationRegistry 2023-04-20 17:09:46 +01:00
Auxilor
7453c70b87 Fixed imports 2023-04-20 16:52:49 +01:00
Auxilor
3038ea43d0 Updated to 6.55.0 2023-04-20 16:51:11 +01:00
Auxilor
3c6ddd8255 Added OutdatedEcoVersionError 2023-04-20 16:50:35 +01:00
Auxilor
925ee04cc1 Added Version as a cross-version compatible version of DefaultArtifactVersion 2023-04-20 16:48:20 +01:00
Auxilor
6f7de8716b Added KRegistrable 2023-04-20 16:41:35 +01:00
Auxilor
a17b951a8b Made registry lockable and iterable 2023-04-20 16:40:06 +01:00
Auxilor
f003ed06a8 Fixed imports 2023-04-19 18:00:19 +01:00
Auxilor
f864953da2 Updated to 6.54.1 2023-04-19 17:38:22 +01:00
Auxilor
6ef31444ac Removed Checkstyle CI, cleaned up Oraxen PR 2023-04-19 17:38:09 +01:00
Will FP
99258116de Merge pull request #264 from MCCasper/master
fix oraxen and SNBT
2023-04-19 12:33:14 -04:00
casper
a59c68102e fix SNBT matching the same tag for diff materials 2023-04-19 11:09:26 -05:00
casper
2482525fe2 load oraxen later 2023-04-18 22:23:49 -05:00
Auxilor
acb326c0c8 Updated to 6.54.0 2023-04-13 12:13:32 -04:00
Auxilor
11d947e24b Updated to 6.53.2 2023-04-13 12:09:14 -04:00
Auxilor
3cced3012c Added Prerequisite#HAS_1_19_4 2023-04-13 11:59:04 -04:00
Auxilor
520523e903 Isolated integration loading 2023-04-13 11:57:49 -04:00
Auxilor
ee36cc74f8 Improved lifecycle error logging 2023-04-13 11:50:32 -04:00
Auxilor
55344e0550 Improved lifecycle error handling, isolated tasks 2023-04-13 11:49:43 -04:00
Auxilor
75f6f05c7d Merge branch 'master' into develop 2023-03-30 14:05:09 +01:00
Auxilor
17fa519501 Revert "Fixed ContinuallyAppliedPersistentDataContainer"
This reverts commit 1852ff86ec.
2023-03-30 14:04:43 +01:00
Auxilor
1a72cf3ca9 Revert "Updated to 6.53.2"
This reverts commit d11f355c44.
2023-03-30 14:04:43 +01:00
Auxilor
d11f355c44 Updated to 6.53.2 2023-03-30 12:08:37 +01:00
Auxilor
1852ff86ec Fixed ContinuallyAppliedPersistentDataContainer 2023-03-30 12:08:26 +01:00
Auxilor
ffe9219f45 Changed README to show repo.auxilor.io 2023-03-29 13:33:24 +01:00
Auxilor
f67a5d3b3d Added repo.auxilor.io 2023-03-29 13:30:15 +01:00
Auxilor
bbd541abe0 Added repo.auxilor.io 2023-03-29 13:21:40 +01:00
Auxilor
3de8d0fed9 Updated to 6.53.1 2023-03-28 17:13:04 +01:00
Auxilor
df4abe39eb Fixed tab completion for dynamically registered commands 2023-03-28 17:12:54 +01:00
Auxilor
f5e289966f Fixed tab completion for dynamically registered commands 2023-03-28 17:12:35 +01:00
Auxilor
bcfa4bd82e Added json() extension 2023-03-25 17:48:27 +00:00
Auxilor
229c9e58c3 Merge branch 'develop'
# Conflicts:
#	eco-api/src/main/java/com/willfp/eco/core/config/TransientConfig.java
#	eco-core/core-nms/nms-common/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/common/packet/PacketInjectorListener.kt
#	gradle.properties
2023-03-25 15:34:47 +00:00
Auxilor
4f30a6e04e Removed all forRemoval classes / methods deprecated since before 6.43.0 2023-03-20 12:52:41 +00:00
Auxilor
9ea45ee0d0 Updated EcoPlugin#getID 2023-03-19 22:24:02 +00:00
Auxilor
192316214d Added Items.matchesAny 2023-03-19 22:08:47 +00:00
Auxilor
feb8898a87 Added default values to ExternalDataStore.get 2023-03-19 22:03:21 +00:00
Auxilor
1e64815e47 Added Registry.tryFitPattern 2023-03-19 22:00:42 +00:00
Auxilor
dc10648c25 Fixed DefaultMap and ListMap, adding tasks to lifecycle events, and packet injection 2023-03-19 17:39:20 +00:00
Auxilor
70131a6cae Added logging for invalid registry IDs 2023-03-18 15:22:20 +00:00
Auxilor
6d23cc7141 Fixed Registry#clear 2023-03-18 15:17:41 +00:00
Auxilor
473202527a Fixed EntityDeathByEntityEvent for WildStacker users 2023-03-17 21:23:54 +00:00
Auxilor
bc24aaeb3c Fixed 1.19.4 support
(cherry picked from commit ad47b7898e)
2023-03-15 21:10:33 +00:00
Auxilor
52072bd935 Added 1.19.4 support
(cherry picked from commit cb3ccbb39a)
2023-03-15 21:10:33 +00:00
Auxilor
ad47b7898e Fixed 1.19.4 support 2023-03-15 21:06:02 +00:00
Auxilor
19d6533db6 Updated to 6.52.3 2023-03-15 21:05:15 +00:00
Auxilor
3a37d40271 Fixed missing channel bug 2023-03-15 21:02:05 +00:00
Auxilor
cb3ccbb39a Added 1.19.4 support 2023-03-15 21:02:01 +00:00
Auxilor
5c3bb678b3 Updated backend paper version 2023-03-15 18:20:46 +00:00
Auxilor
4f4ee82e6b Converted remaining groovy buildscripts to kotlin 2023-03-14 19:46:12 +00:00
Auxilor
32d88f55f8 Fixed environment variables 2023-03-14 17:18:05 +00:00
Auxilor
bc8d615079 Added environment variables, moved eco.yml components around, added option to disable reflective reload, moved eco to be a paper plugin 2023-03-14 16:35:30 +00:00
Auxilor
55b7c3c16f Added ExternalDataStore 2023-03-14 12:45:35 +00:00
Auxilor
9535986f59 Fixed EcoPlugin#getID 2023-03-14 12:25:29 +00:00
Auxilor
fb17fc1383 Fixed annotation mismatch 2023-03-13 15:24:51 +00:00
Auxilor
4221368388 Made EcoPlugin registrable 2023-03-13 15:18:21 +00:00
Auxilor
d4432d0cb8 Updated to 6.53.0 2023-03-13 14:31:19 +00:00
Auxilor
f9093c2ed6 Added LifecyclePosition 2023-03-13 14:23:28 +00:00
Auxilor
15f4d5c098 Fixed missing channel bug 2023-03-13 13:35:51 +00:00
Auxilor
dc47bc7995 Updated Placeholder API, added ability to parse placeholders without PAPI installed 2023-03-11 17:08:50 +00:00
Auxilor
29ce0deb1b Merge remote-tracking branch 'origin/develop' into develop 2023-02-27 19:19:21 +00:00
Auxilor
fd78402bf5 Updated to 6.52.2 2023-02-27 19:19:18 +00:00
Will FP
5f65e3f520 Merge pull request #248
Yet another economyshopgui fix
2023-02-27 19:19:06 +00:00
0ft3n
ceaf4d34a5 Yet another economyshopgui fix 2023-02-27 22:13:02 +03:00
Auxilor
2d2e5f8150 Updated to 6.52.1 2023-02-27 17:00:24 +00:00
Auxilor
323a4aefef Fixed ListMap overload resolution ambiguity for kotlin 2023-02-27 17:00:15 +00:00
Auxilor
af486580c1 Updated to 6.52.0 2023-02-27 16:31:19 +00:00
Auxilor
7955a94f14 Added missing annotations 2023-02-25 19:03:18 +00:00
Auxilor
c99a1bd50a loadListeners is no longer abstract 2023-02-25 19:02:14 +00:00
Auxilor
93364247de Merge branch 'master' into develop 2023-02-25 14:49:15 +00:00
Auxilor
49612eddcb Updated to 6.51.4 2023-02-24 14:02:16 +00:00
Auxilor
834c29f843 Fixed placeholder bug with additional players, prevented NaN being evaluated by crunch 2023-02-24 14:02:04 +00:00
Auxilor
a806ac039d Added regex validation for Ids 2023-02-23 21:15:12 +00:00
Auxilor
0ca2651af0 Added ListMap#append 2023-02-23 21:07:04 +00:00
Auxilor
6157fdcfa1 Improved DefaultMap 2023-02-23 21:04:01 +00:00
Auxilor
36cfcd24c2 Added DefaultMap 2023-02-23 20:51:21 +00:00
Auxilor
d4558db40c Added registry 2023-02-23 18:33:28 +00:00
Auxilor
3f8448fee1 Updated to 6.51.3 2023-02-18 12:26:39 +00:00
Auxilor
8b6e15457c Fixed clearing entity goals on 1.19+ 2023-02-18 12:26:32 +00:00
Auxilor
b99e822db3 Updated to 6.51.2 2023-02-16 16:16:08 +00:00
Auxilor
02f8d33a81 Hot'fix' 2023-02-16 16:16:01 +00:00
152 changed files with 2940 additions and 1481 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
env:
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'.
# 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
## 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
@@ -75,31 +75,31 @@ depend:
- eco
```
## Get from JitPack:
## Dependency Information:
Gradle:
```groovy
```kts
repositories {
maven { url 'https://jitpack.io' }
maven("https://repo.auxilor.io/repository/maven-public/")
}
```
```groovy
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:
```xml
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
<id>auxilor</id>
<url>https://repo.auxilor.io/repository/maven-public/</url>
</repository>
```
@@ -112,7 +112,7 @@ Maven:
</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:

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_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_R3", configuration = "reobf"))
}
allprojects {
@@ -56,7 +57,7 @@ allprojects {
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/")
// ProtocolLib
maven("https://repo.dmulloy2.net/nexus/repository/public/")
//maven("https://repo.dmulloy2.net/nexus/repository/public/")
// WorldGuard
maven("https://maven.enginehub.org/repo/")
@@ -79,6 +80,7 @@ allprojects {
// LibsDisguises
maven("https://repo.md-5.net/content/groups/public/")
// UltraEconomy
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.RunnableFactory;
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.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.version.OutdatedEcoVersionError;
import com.willfp.eco.core.version.Version;
import com.willfp.eco.core.web.UpdateChecker;
import org.apache.commons.lang.Validate;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.file.FileConfiguration;
@@ -35,6 +39,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
@@ -53,27 +58,12 @@ import java.util.stream.Collectors;
* <b>IMPORTANT: When reloading a plugin, all runnables / tasks will
* be cancelled.</b>
*/
@SuppressWarnings({"unused", "DeprecatedIsStillUsed", "deprecation", "RedundantSuppression"})
public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
@SuppressWarnings({"unused", "DeprecatedIsStillUsed", "deprecation", "RedundantSuppression", "MismatchedQueryAndUpdateOfCollection"})
public abstract class EcoPlugin extends JavaPlugin implements PluginLike, Registrable {
/**
* The polymart resource ID of the plugin.
* The properties (eco.yml).
*/
private final int resourceId;
/**
* 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;
private final PluginProps props;
/**
* Loaded integrations.
@@ -142,11 +132,6 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
*/
private boolean outdated = false;
/**
* If the plugin supports extensions.
*/
private final boolean supportingExtensions;
/**
* The proxy factory.
*/
@@ -156,27 +141,27 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
/**
* 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.
*/
private final List<Runnable> onDisable = new ArrayList<>();
private final ListMap<LifecyclePosition, Runnable> onDisable = new ListMap<>();
/**
* 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.
*/
private final List<Runnable> onLoad = new ArrayList<>();
private final ListMap<LifecyclePosition, Runnable> onLoad = new ListMap<>();
/**
* 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.
@@ -193,7 +178,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* Create a new plugin without proxy support, polymart, or bStats.
*
* @param color The color.
* @deprecated Use eco.yml instead.
*/
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(@NotNull final String 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 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,
@NotNull final String 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 bStatsId The bStats resource ID for the plugin.
* @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,
final int bStatsId,
@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 color The color of the plugin (used in messages, using standard formatting)
* @param supportingExtensions If the plugin supports extensions.
* @deprecated Use eco.yml instead.
*/
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(final int resourceId,
final int bStatsId,
@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 proxyPackage The package where proxy implementations are stored.
* @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,
final int bStatsId,
@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 color The color of the plugin (used in messages, using standard formatting)
* @param supportingExtensions If the plugin supports extensions.
* @deprecated Use eco.yml instead.
*/
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(final int resourceId,
final int bStatsId,
@NotNull final String proxyPackage,
@NotNull final String color,
final boolean supportingExtensions) {
this(
PluginProps.createSimple(
resourceId,
bStatsId,
proxyPackage,
color,
supportingExtensions
)
);
this(PluginProps.createSimple(resourceId, bStatsId, proxyPackage, color, supportingExtensions));
}
/**
@@ -325,13 +314,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
PluginProps props = this.mutateProps(generatedProps);
props.validate();
this.resourceId = props.getResourceId();
this.bStatsId = props.getBStatsId();
this.proxyPackage = props.getProxyPackage();
this.color = props.getColor();
this.supportingExtensions = props.isSupportingExtensions();
this.props = props;
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.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.
*/
DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.get().getEcoPlugin().getDescription().getVersion());
DefaultArtifactVersion requiredVersion = new DefaultArtifactVersion(this.getMinimumEcoVersion());
Version runningVersion = new Version(Eco.get().getEcoPlugin().getDescription().getVersion());
Version requiredVersion = new Version(this.getMinimumEcoVersion());
if (!(runningVersion.compareTo(requiredVersion) > 0 || runningVersion.equals(requiredVersion))) {
this.getLogger().severe("You are running an outdated version of eco!");
this.getLogger().severe("You must be on at least" + this.getMinimumEcoVersion());
this.getLogger().severe("Download the newest version here:");
this.getLogger().severe("https://polymart.org/download/773/recent/JSpprMspkuyecf5y1wQ2Jn8OoLQSQ_IW");
Bukkit.getPluginManager().disablePlugin(this);
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")) {
new UpdateChecker(this).getVersion(version -> {
DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(this.getDescription().getVersion());
DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version);
Version currentVersion = new Version(this.getDescription().getVersion());
Version mostRecentVersion = new Version(version);
if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) {
this.outdated = true;
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);
}
Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins())
.map(Plugin::getName)
.map(String::toLowerCase)
.collect(Collectors.toSet());
Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(Plugin::getName).map(String::toLowerCase).collect(Collectors.toSet());
if (enabledPlugins.contains("PlaceholderAPI".toLowerCase())) {
Eco.get().createPAPIIntegration(this);
@@ -412,8 +394,13 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
this.loadIntegrationLoaders().forEach(integrationLoader -> {
if (enabledPlugins.contains(integrationLoader.getPluginName().toLowerCase())) {
this.loadedIntegrations.add(integrationLoader.getPluginName());
integrationLoader.load();
try {
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.onEnable.forEach(Runnable::run);
this.handleLifecycle(this.onEnable, this::handleEnable);
this.getLogger().info("");
}
@@ -461,7 +447,18 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param task The 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.getScheduler().cancelAll();
this.handleDisable();
this.onDisable.forEach(Runnable::run);
this.handleLifecycle(this.onDisable, this::handleDisable);
if (this.isSupportingExtensions()) {
this.getExtensionLoader().unloadExtensions();
@@ -491,7 +487,18 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param task The 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() {
super.onLoad();
this.handleLoad();
this.onLoad.forEach(Runnable::run);
this.handleLifecycle(this.onLoad, this::handleLoad);
}
/**
@@ -511,7 +517,18 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param task The 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.handleAfterLoad();
this.afterLoad.forEach(Runnable::run);
this.handleLifecycle(this.afterLoad, this::handleAfterLoad);
this.reload();
@@ -554,7 +570,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
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.
*/
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(); // Call twice to fix issues
this.handleReload();
this.onReload.forEach(Runnable::run);
this.handleLifecycle(this.onReload, this::handleReload);
for (Extension extension : this.extensionLoader.getLoadedExtensions()) {
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.
*/
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;
}
/**
* 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.
* <p>
@@ -713,7 +787,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
*
* @return A list of all listeners.
*/
protected abstract List<Listener> loadListeners();
protected List<Listener> loadListeners() {
return new ArrayList<>();
}
/**
* Useful for custom LangYml implementations.
@@ -760,10 +836,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
*/
@Nullable
protected DisplayModule createDisplayModule() {
Validate.isTrue(
this.getDisplayModule() == null,
"Display module exists!"
);
Validate.isTrue(this.getDisplayModule() == null, "Display module exists!");
return null;
}
@@ -862,6 +935,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param pluginName The name.
* @return The plugin.
*/
@Nullable
public static EcoPlugin getPlugin(@NotNull final String pluginName) {
return Eco.get().getPluginByName(pluginName);
}
@@ -871,17 +945,28 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
*
* @return The set of names.
*/
@NotNull
public static Set<String> getPluginNames() {
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.
*
* @return The resource ID.
*/
public int getResourceId() {
return this.resourceId;
return this.getProps().getResourceId();
}
/**
@@ -890,7 +975,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return The ID.
*/
public int getBStatsId() {
return this.bStatsId;
return this.getProps().getBStatsId();
}
/**
@@ -899,7 +984,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return The package where proxies are contained.
*/
public String getProxyPackage() {
return this.proxyPackage;
return this.getProps().getProxyPackage();
}
/**
@@ -908,7 +993,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return The color.
*/
public String getColor() {
return this.color;
return this.getProps().getColor();
}
/**
@@ -1026,7 +1111,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return If extensions are supported.
*/
public boolean isSupportingExtensions() {
return this.supportingExtensions;
return this.getProps().isSupportingExtensions();
}
/**
@@ -1060,4 +1145,10 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
public FixedMetadataValue createMetadataValue(@NotNull final Object 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
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.
*/
@@ -153,6 +163,46 @@ public final class PluginProps {
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.
*/
@@ -232,7 +282,9 @@ public final class PluginProps {
* @param color The primary color of the plugin.
* @param supportsExtensions If the plugin should attempt to look for extensions.
* @return The props.
* @deprecated Moving to force the usage of eco.yml.
*/
@Deprecated(since = "6.53.0")
static PluginProps createSimple(final int resourceId,
final int bStatsId,
@NotNull final String proxyPackage,

View File

@@ -1,6 +1,5 @@
package com.willfp.eco.core;
import com.willfp.eco.core.integrations.economy.EconomyManager;
import com.willfp.eco.core.proxy.ProxyConstants;
import com.willfp.eco.util.ClassUtils;
import org.jetbrains.annotations.NotNull;
@@ -39,14 +38,11 @@ public class Prerequisite {
);
/**
* Requires the server to have vault installed.
*
* @deprecated Use {@link EconomyManager#hasRegistrations()} instead.
* Requires the server to be running 1.19.4.
*/
@Deprecated(forRemoval = true)
public static final Prerequisite HAS_VAULT = new Prerequisite(
() -> ClassUtils.exists("net.milkbowl.vault.economy.Economy"),
"Requires server to have vault"
public static final Prerequisite HAS_1_19_4 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("19_R3"),
"Requires server to be running 1.19.4+"
);
/**
@@ -65,17 +61,6 @@ public class Prerequisite {
"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.
*

View File

@@ -14,7 +14,7 @@ import java.util.List;
*
* @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 {
/**
* The delegate command.

View File

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

View File

@@ -26,6 +26,8 @@ import java.util.Map;
@Deprecated(since = "6.44.0", forRemoval = true)
public class TransientConfig extends ConfigWrapper<Config> {
/**
* Create new transient config from bukkit config.
*
* @param config The ConfigurationSection handle.
*/
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.
*/
public TransientConfig(@Nullable final InputStream stream) {
@@ -51,15 +55,8 @@ public class TransientConfig extends ConfigWrapper<Config> {
}
/**
* @param file The File.
* @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);
}
/**
* Load a file to a config.
*
* @param file The file.
* @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 type The config type.
*/

View File

@@ -30,16 +30,6 @@ import java.util.Set;
*/
@SuppressWarnings("unused")
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.
*

View File

@@ -2,7 +2,6 @@ package com.willfp.eco.core.config.interfaces;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
@@ -44,21 +43,6 @@ public interface LoadableConfig extends Config {
*/
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}.
*/

View File

@@ -38,6 +38,9 @@ import java.lang.annotation.Target;
* <p>
* By having a plugin as a parameter, you shouldn't really need getInstance()
* 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)
@Target(ElementType.METHOD)

View File

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

View File

@@ -22,55 +22,38 @@ public final class PersistentDataKeyType<T> {
/**
* String.
*/
public static final PersistentDataKeyType<String> STRING = new PersistentDataKeyType<>(String.class, "STRING");
public static final PersistentDataKeyType<String> STRING = new PersistentDataKeyType<>("STRING");
/**
* Boolean.
*/
public static final PersistentDataKeyType<Boolean> BOOLEAN = new PersistentDataKeyType<>(Boolean.class, "BOOLEAN");
public static final PersistentDataKeyType<Boolean> BOOLEAN = new PersistentDataKeyType<>("BOOLEAN");
/**
* Int.
*/
public static final PersistentDataKeyType<Integer> INT = new PersistentDataKeyType<>(Integer.class, "INT");
public static final PersistentDataKeyType<Integer> INT = new PersistentDataKeyType<>("INT");
/**
* Double.
*/
public static final PersistentDataKeyType<Double> DOUBLE = new PersistentDataKeyType<>(Double.class, "DOUBLE");
public static final PersistentDataKeyType<Double> DOUBLE = new PersistentDataKeyType<>("DOUBLE");
/**
* 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.
*/
public static final PersistentDataKeyType<Config> CONFIG = new PersistentDataKeyType<>(Config.class, "CONFIG");
/**
* The class of the type.
*/
private final Class<T> typeClass;
public static final PersistentDataKeyType<Config> CONFIG = new PersistentDataKeyType<>("CONFIG");
/**
* The name of the key type.
*/
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.
*
@@ -83,14 +66,11 @@ public final class PersistentDataKeyType<T> {
/**
* Create new PersistentDataKeyType.
*
* @param typeClass The type class.
* @param name The name.
*/
private PersistentDataKeyType(@Nullable final Class<T> typeClass,
@NotNull final String name) {
private PersistentDataKeyType(@NotNull final String name) {
VALUES.add(this);
this.typeClass = typeClass;
this.name = name;
}

View File

@@ -112,23 +112,6 @@ public abstract class DisplayModule {
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.
*

View File

@@ -6,7 +6,10 @@ package com.willfp.eco.core.display;
public enum DisplayPriority {
/**
* Custom weight.
*
* @deprecated Will never be used.
*/
@Deprecated(since = "6.53.0", forRemoval = true)
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);
/**
* Create a new custom goal.
*/
protected CustomGoal() {
}
/**
* Initialize the goal with a mob.
* <p>

View File

@@ -28,6 +28,8 @@ public record EntityGoalTempt(
boolean canBeScared
) implements EntityGoal<Mob> {
/**
* Create a new entity goal.
*
* @param speed The speed at which the entity follows the item.
* @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.

View File

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

View File

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

View File

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

View File

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

View File

@@ -7,6 +7,8 @@ import java.util.function.Consumer;
import java.util.function.Predicate;
/**
* The result of an arg parses.
*
* @param test The test for the entity.
* @param modifier The modifier to apply to the entity.
* @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.
*/
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.
* Does not account for stored enchants.
@@ -51,33 +39,6 @@ public interface FastItemStack extends PersistentDataHolder {
@NotNull
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.
*
@@ -85,7 +46,7 @@ public interface FastItemStack extends PersistentDataHolder {
* @return The enchantment level, or 0 if not found.
*/
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.gui.page.Page;
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.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
/**
* GUI version of {@link Inventory}.
@@ -240,58 +235,6 @@ public interface Menu {
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.
*

View File

@@ -90,17 +90,4 @@ public abstract class CustomSlot implements Slot {
public final Slot getSlotAt(int row, int 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) {
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;
import com.willfp.eco.core.registry.Registrable;
import com.willfp.eco.core.registry.Registry;
import org.jetbrains.annotations.NotNull;
/**
* Abstract class for integrations.
*/
public interface Integration {
public interface Integration extends Registrable {
/**
* Get the name of integration.
*
* @return The name.
*/
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;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
/**
* Class to handle afk integrations.
*/
@@ -13,7 +11,7 @@ public final class AFKManager {
/**
* 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.
@@ -21,8 +19,7 @@ public final class AFKManager {
* @param integration The integration to register.
*/
public static void register(@NotNull final AFKIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration);
REGISTRY.register(integration);
}
/**
@@ -32,13 +29,7 @@ public final class AFKManager {
* @return If afk.
*/
public static boolean isAfk(@NotNull final Player player) {
for (AFKIntegration integration : REGISTERED) {
if (integration.isAfk(player)) {
return true;
}
}
return false;
return REGISTRY.anySafely(integration -> integration.isAfk(player));
}
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;
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.event.Listener;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
/**
* Class to handle anticheat integrations.
*/
@@ -16,20 +13,7 @@ public final class AnticheatManager {
/**
* A set of all registered anticheats.
*/
private static final Set<AnticheatIntegration> ANTICHEATS = new HashSet<>();
/**
* 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);
}
private static final IntegrationRegistry<AnticheatIntegration> REGISTRY = new IntegrationRegistry<>();
/**
* Register a new anticheat.
@@ -40,8 +24,7 @@ public final class AnticheatManager {
if (anticheat instanceof Listener) {
Eco.get().getEcoPlugin().getEventManager().registerListener((Listener) anticheat);
}
ANTICHEATS.removeIf(it -> it.getPluginName().equalsIgnoreCase(anticheat.getPluginName()));
ANTICHEATS.add(anticheat);
REGISTRY.register(anticheat);
}
/**
@@ -50,17 +33,16 @@ public final class AnticheatManager {
* @param player The player to exempt.
*/
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.
* 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.
*/
public static void unexemptPlayer(@NotNull final Player player) {
ANTICHEATS.forEach(anticheat -> anticheat.unexempt(player));
REGISTRY.forEachSafely(anticheat -> anticheat.unexempt(player));
}
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;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
@@ -16,7 +17,7 @@ public final class AntigriefManager {
/**
* 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.
@@ -24,8 +25,7 @@ public final class AntigriefManager {
* @param antigrief The integration to register.
*/
public static void register(@NotNull final AntigriefIntegration antigrief) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(antigrief.getPluginName()));
REGISTERED.add(antigrief);
REGISTRY.register(antigrief);
}
/**
@@ -34,8 +34,7 @@ public final class AntigriefManager {
* @param antigrief The integration to unregister.
*/
public static void unregister(@NotNull final AntigriefIntegration antigrief) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(antigrief.getPluginName()));
REGISTERED.remove(antigrief);
REGISTRY.remove(antigrief);
}
/**
@@ -47,7 +46,7 @@ public final class AntigriefManager {
*/
public static boolean canPickupItem(@NotNull final Player player,
@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,
@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,
@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,
@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,
@NotNull final LivingEntity victim) {
return REGISTERED.stream().allMatch(antigriefIntegration -> antigriefIntegration.canInjure(player, victim));
return REGISTRY.allSafely(integration -> integration.canInjure(player, victim));
}
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;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
/**
* Class to handle custom entity integrations.
*/
@@ -12,7 +10,7 @@ public final class CustomEntitiesManager {
/**
* 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.
@@ -20,8 +18,7 @@ public final class CustomEntitiesManager {
* @param integration The integration to register.
*/
public static void register(@NotNull final CustomEntitiesIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration);
REGISTRY.register(integration);
}
/**
@@ -30,9 +27,7 @@ public final class CustomEntitiesManager {
* @see com.willfp.eco.core.entities.Entities
*/
public static void registerAllEntities() {
for (CustomEntitiesIntegration integration : REGISTERED) {
integration.registerAllEntities();
}
REGISTRY.forEachSafely(CustomEntitiesIntegration::registerAllEntities);
}
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;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
@@ -12,7 +13,7 @@ public final class CustomItemsManager {
/**
* 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.
@@ -20,8 +21,7 @@ public final class CustomItemsManager {
* @param integration The integration to register.
*/
public static void register(@NotNull final CustomItemsIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration);
REGISTRY.register(integration);
}
/**
@@ -30,9 +30,7 @@ public final class CustomItemsManager {
* @see com.willfp.eco.core.items.Items
*/
public static void registerAllItems() {
for (CustomItemsIntegration customItemsIntegration : REGISTERED) {
customItemsIntegration.registerAllItems();
}
REGISTRY.forEachSafely(CustomItemsIntegration::registerAllItems);
}
/**
@@ -41,9 +39,7 @@ public final class CustomItemsManager {
* @see com.willfp.eco.core.items.Items
*/
public static void registerProviders() {
for (CustomItemsIntegration customItemsIntegration : REGISTERED) {
customItemsIntegration.registerProvider();
}
REGISTRY.forEachSafely(CustomItemsIntegration::registerProvider);
}
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;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Set;
/**
* Class to handle economy.
@@ -14,7 +13,7 @@ public final class EconomyManager {
/**
* 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.
@@ -22,8 +21,7 @@ public final class EconomyManager {
* @param integration The integration to register.
*/
public static void register(@NotNull final EconomyIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration);
REGISTRY.register(integration);
}
/**
@@ -32,7 +30,7 @@ public final class EconomyManager {
* @return If any economy.
*/
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,
final BigDecimal amount) {
for (EconomyIntegration integration : REGISTERED) {
return integration.hasAmount(player, amount);
}
return false;
return REGISTRY.firstSafely(
integration -> integration.hasAmount(player, amount),
false
);
}
/**
@@ -84,11 +81,10 @@ public final class EconomyManager {
*/
public static boolean giveMoney(@NotNull final OfflinePlayer player,
@NotNull final BigDecimal amount) {
for (EconomyIntegration integration : REGISTERED) {
return integration.giveMoney(player, amount);
}
return false;
return REGISTRY.firstSafely(
integration -> integration.giveMoney(player, amount),
false
);
}
/**
@@ -112,11 +108,10 @@ public final class EconomyManager {
*/
public static boolean removeMoney(@NotNull final OfflinePlayer player,
@NotNull final BigDecimal amount) {
for (EconomyIntegration integration : REGISTERED) {
return integration.removeMoney(player, amount);
}
return false;
return REGISTRY.firstSafely(
integration -> integration.removeMoney(player, amount),
false
);
}
/**
@@ -136,11 +131,10 @@ public final class EconomyManager {
* @return The balance.
*/
public static BigDecimal getExactBalance(@NotNull final OfflinePlayer player) {
for (EconomyIntegration integration : REGISTERED) {
return integration.getExactBalance(player);
}
return BigDecimal.ZERO;
return REGISTRY.firstSafely(
integration -> integration.getExactBalance(player),
BigDecimal.ZERO
);
}
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;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import com.willfp.eco.util.MenuUtils;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
/**
* Class to handle GUI detection.
*/
@@ -14,7 +12,7 @@ public final class GUIDetectionManager {
/**
* 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.
@@ -22,8 +20,7 @@ public final class GUIDetectionManager {
* @param integration The integration to register.
*/
public static void register(@NotNull final GUIDetectionIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration);
REGISTRY.register(integration);
}
/**
@@ -37,13 +34,7 @@ public final class GUIDetectionManager {
return true;
}
for (GUIDetectionIntegration integration : REGISTERED) {
if (integration.hasGUIOpen(player)) {
return true;
}
}
return false;
return REGISTRY.anySafely(integration -> integration.hasGUIOpen(player));
}
private GUIDetectionManager() {

View File

@@ -1,11 +1,10 @@
package com.willfp.eco.core.integrations.hologram;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Class to handle hologram integrations.
@@ -14,7 +13,7 @@ public final class HologramManager {
/**
* 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.
@@ -22,8 +21,7 @@ public final class HologramManager {
* @param integration The integration to register.
*/
public static void register(@NotNull final HologramIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration);
REGISTRY.register(integration);
}
/**
@@ -35,11 +33,10 @@ public final class HologramManager {
*/
public static Hologram createHologram(@NotNull final Location location,
@NotNull final List<String> contents) {
for (HologramIntegration integration : REGISTERED) {
return integration.createHologram(location, contents);
}
return new DummyHologram();
return REGISTRY.firstSafely(
integration -> integration.createHologram(location, contents),
new DummyHologram()
);
}
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;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.bukkit.block.Block;
import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull;
@@ -14,7 +15,7 @@ public final class McmmoManager {
/**
* 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.
@@ -22,8 +23,7 @@ public final class McmmoManager {
* @param integration The integration to register.
*/
public static void register(@NotNull final McmmoIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration);
REGISTERED.register(integration);
}
/**
@@ -34,13 +34,11 @@ public final class McmmoManager {
*/
public static int getBonusDropCount(@NotNull final Block block) {
int finalValue = 0;
for (McmmoIntegration mcmmoIntegration : REGISTERED) {
finalValue += mcmmoIntegration.getBonusDropCount(block);
}
return finalValue;
}
@@ -51,13 +49,7 @@ public final class McmmoManager {
* @return If the event is fake.
*/
public static boolean isFake(@NotNull final Event event) {
for (McmmoIntegration mcmmoIntegration : REGISTERED) {
if (mcmmoIntegration.isFake(event)) {
return true;
}
}
return false;
return REGISTERED.anySafely(integration -> integration.isFake(event));
}
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.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.placeholder.AdditionalPlayer;
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.StaticPlaceholder;
import com.willfp.eco.util.StringUtils;
import org.apache.commons.lang.Validate;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -36,7 +36,6 @@ import java.util.regex.Pattern;
/**
* Class to handle placeholder integrations.
*/
@SuppressWarnings("removal")
public final class PlaceholderManager {
/**
* All registered placeholders.
@@ -78,6 +77,11 @@ public final class PlaceholderManager {
* Empty injectable object.
*/
public static final PlaceholderInjectable EMPTY_INJECTABLE = new PlaceholderInjectable() {
@Override
public void addInjectablePlaceholder(@NotNull Iterable<InjectablePlaceholder> placeholders) {
// Do nothing.
}
@Override
public void clearInjectedPlaceholders() {
// Do nothing.
@@ -110,25 +114,12 @@ public final class PlaceholderManager {
throw new IllegalArgumentException("Static placeholders cannot be registered!");
}
EcoPlugin plugin = placeholder.getPlugin() == null ? Eco.get().getEcoPlugin() : placeholder.getPlugin();
Map<Pattern, Placeholder> pluginPlaceholders = REGISTERED_PLACEHOLDERS
.getOrDefault(plugin, new HashMap<>());
.getOrDefault(placeholder.getPlugin(), new HashMap<>());
pluginPlaceholders.put(placeholder.getPattern(), placeholder);
REGISTERED_PLACEHOLDERS.put(plugin, 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());
REGISTERED_PLACEHOLDERS.put(placeholder.getPlugin(), pluginPlaceholders);
}
/**
@@ -139,10 +130,11 @@ public final class PlaceholderManager {
* @return The value of the placeholder.
* @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,
@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
public static String getResult(@Nullable final Player player,
@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?
// Compensating for regex being slow so that's why we get it.
Placeholder placeholder = PLACEHOLDER_LOOKUP_CACHE.get(
new PlaceholderLookup(identifier, plugin),
(it) -> {
EcoPlugin owner = plugin == null ? Eco.get().getEcoPlugin() : plugin;
// I hate the streams API.
Optional<Placeholder> found = REGISTERED_PLACEHOLDERS
.getOrDefault(owner, new HashMap<>())
return REGISTERED_PLACEHOLDERS
.getOrDefault(plugin, new HashMap<>())
.entrySet()
.stream().filter(entry -> entry.getKey().matcher(identifier).matches())
.map(Map.Entry::getValue)
.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);
@@ -231,22 +210,6 @@ public final class PlaceholderManager {
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.
*
@@ -276,6 +239,35 @@ public final class PlaceholderManager {
@NotNull final Collection<AdditionalPlayer> additionalPlayers) {
String processed = text;
/*
Why am I doing statics at the start, but player statics at the end?
Additional players let you use something like victim as a player to parse in relation to,
for example doing %victim_player_health%, which would parse the health of the victim.
However, something like libreforge will also inject %victim_max_health%, which is unrelated
to additional players, and instead holds a constant value. So, eco saw this, smartly thought
"ah, it's an additional player, let's parse it", and then tried to parse %max_health% with
relation to the victim, which resolved to zero. So, we have to parse statics and player statics
that might include a prefix first, then additional players, then player statics with the support
of additional players.
This was a massive headache and took so many reports before I clocked what was going on.
Oh well, at least it's fixed now.
*/
for (InjectablePlaceholder injection : context.getPlaceholderInjections()) {
if (injection instanceof StaticPlaceholder placeholder) {
processed = processed.replace("%" + placeholder.getIdentifier() + "%", placeholder.getValue());
} else if (injection instanceof PlayerStaticPlaceholder placeholder && player != null) {
processed = processed.replace("%" + placeholder.getIdentifier() + "%", placeholder.getValue(player));
}
}
// Prevent running 2 scans if there are no additional players.
if (!additionalPlayers.isEmpty()) {
List<String> found = findPlaceholdersIn(text);
@@ -297,19 +289,23 @@ 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) {
processed = integration.translate(processed, player);
}
// DON'T REMOVE THIS, IT'S NOT DUPLICATE CODE.
for (InjectablePlaceholder injection : context.getPlaceholderInjections()) {
// Do I know this is a bad way of doing this? Yes.
// I know it's deprecated, but it's fast.
if (injection instanceof StaticPlaceholder placeholder) {
processed = processed.replace("%" + placeholder.getIdentifier() + "%", placeholder.getValue());
} else if (injection instanceof PlayerStaticPlaceholder placeholder && player != null) {
if (injection instanceof PlayerStaticPlaceholder placeholder && player != null) {
processed = processed.replace("%" + placeholder.getIdentifier() + "%", placeholder.getValue(player));
}
}
return processed;
}
@@ -322,12 +318,9 @@ public final class PlaceholderManager {
public static List<String> findPlaceholdersIn(@NotNull final String text) {
Set<String> found = new HashSet<>();
// Mock PAPI for those without it installed
if (REGISTERED_INTEGRATIONS.isEmpty()) {
Matcher matcher = PATTERN.matcher(text);
while (matcher.find()) {
found.add(matcher.group());
}
Matcher matcher = PATTERN.matcher(text);
while (matcher.find()) {
found.add(matcher.group());
}
for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) {
@@ -337,6 +330,95 @@ public final class PlaceholderManager {
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,
@Nullable EcoPlugin plugin) {

View File

@@ -1,5 +1,6 @@
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.impl.PriceFree;
import org.bukkit.entity.Player;
@@ -13,11 +14,12 @@ import java.util.Set;
/**
* Class to handle shop integrations.
*/
@SuppressWarnings("DeprecatedIsStillUsed")
public final class ShopManager {
/**
* 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.
@@ -25,17 +27,14 @@ public final class ShopManager {
* @param integration The integration to register.
*/
public static void register(@NotNull final ShopIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration);
REGISTRY.register(integration);
}
/**
* Register eco item provider for shop plugins.
*/
public static void registerEcoProvider() {
for (ShopIntegration shopIntegration : REGISTERED) {
shopIntegration.registerEcoProvider();
}
REGISTRY.forEachSafely(ShopIntegration::registerEcoProvider);
}
/**
@@ -51,11 +50,7 @@ public final class ShopManager {
return false;
}
for (ShopIntegration integration : REGISTERED) {
return integration.isSellable(itemStack, player);
}
return false;
return REGISTRY.anySafely(integration -> integration.isSellable(itemStack, player));
}
/**
@@ -74,11 +69,10 @@ public final class ShopManager {
return new PriceFree();
}
for (ShopIntegration integration : REGISTERED) {
return integration.getUnitValue(itemStack, player);
}
return new PriceFree();
return REGISTRY.firstSafely(
integration -> integration.getUnitValue(itemStack, player),
new PriceFree()
);
}
/**
@@ -108,11 +102,10 @@ public final class ShopManager {
return 0.0;
}
for (ShopIntegration shopIntegration : REGISTERED) {
return shopIntegration.getUnitValue(itemStack, player).getValue(player, itemStack.getAmount());
}
return 0.0;
return REGISTRY.firstSafely(
integration -> integration.getUnitValue(itemStack, player).getValue(player, itemStack.getAmount()),
0.0
);
}
/**
@@ -121,7 +114,7 @@ public final class ShopManager {
* @return The integrations.
*/
public static Set<ShopIntegration> getRegisteredIntegrations() {
return new HashSet<>(REGISTERED);
return new HashSet<>(REGISTRY.values());
}
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);
}
/**
* 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() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}

View File

@@ -0,0 +1,168 @@
package com.willfp.eco.core.map;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
/**
* A map with a default value.
*
* @param <K> The key type.
* @param <V> The value type.
*/
public class DefaultMap<K, V> implements Map<K, V> {
/**
* The map.
*/
private final Map<K, V> map;
/**
* The default value.
*/
private final Supplier<V> defaultValue;
/**
* Create a new default map.
*
* @param defaultValue The default value.
*/
public DefaultMap(@NotNull final V defaultValue) {
this(() -> defaultValue);
}
/**
* Create a new default map.
*
* @param defaultValue The default value.
*/
public DefaultMap(@NotNull final Supplier<V> defaultValue) {
this(new HashMap<>(), 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 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.defaultValue = defaultValue;
}
@Override
@NotNull
@SuppressWarnings("unchecked")
public V get(@Nullable final Object key) {
if (key == null) {
return defaultValue.get();
}
if (map.get(key) == null) {
map.put((K) key, defaultValue.get());
}
return map.get(key);
}
@Override
public int size() {
return map.size();
}
@Override
public boolean isEmpty() {
return map.isEmpty();
}
@Override
public boolean containsKey(@Nullable final Object key) {
return map.containsKey(key);
}
@Override
public boolean containsValue(@Nullable final Object value) {
return map.containsValue(value);
}
@Override
public V put(@NotNull final K key, @Nullable final V value) {
return map.put(key, value);
}
@Override
public V remove(@NotNull final Object key) {
return map.remove(key);
}
@Override
public void putAll(@NotNull final Map<? extends K, ? extends V> m) {
map.putAll(m);
}
@Override
public void clear() {
map.clear();
}
@NotNull
@Override
public Set<K> keySet() {
return map.keySet();
}
@NotNull
@Override
public Collection<V> values() {
return map.values();
}
@NotNull
@Override
public Set<Entry<K, V>> entrySet() {
return map.entrySet();
}
/**
* Create a new nested map.
*
* @param <K> The key type.
* @param <K1> The nested key type.
* @param <V> The value type.
* @return The nested map.
*/
@NotNull
public static <K, K1, V> DefaultMap<K, Map<K1, V>> createNestedMap() {
return new DefaultMap<>(new HashMap<>());
}
/**
* Create a new nested list map.
*
* @param <K> The key type.
* @param <K1> The nested key type.
* @param <V> The value type.
* @return The nested list map.
*/
@NotNull
public static <K, K1, V> DefaultMap<K, ListMap<K1, V>> createNestedListMap() {
return new DefaultMap<>(new ListMap<>());
}
}

View File

@@ -0,0 +1,32 @@
package com.willfp.eco.core.map;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* Maps keys to lists of values.
*
* @param <K> The key type.
* @param <V> The value type.
*/
public class ListMap<K, V> extends DefaultMap<K, List<V>> {
/**
* Create a new list map.
*/
public ListMap() {
super(ArrayList::new);
}
/**
* Append a value to a key.
*
* @param key The key.
* @param value The value.
*/
public void append(@NotNull final K key,
@NotNull final V 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.
*/
public final class EmptyParticle implements SpawnableParticle {
/**
* Instantiate a new empty particle.
*/
public EmptyParticle() {
}
@Override
public void spawn(@NotNull final Location location,
final int amount) {

View File

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

View File

@@ -2,7 +2,6 @@ package com.willfp.eco.core.placeholder;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
@@ -15,7 +14,7 @@ public interface PlaceholderInjectable {
* @param placeholders The 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));
}
/**
* 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.
* <p>
@@ -48,41 +33,13 @@ public interface PlaceholderInjectable {
*
* @param placeholders The placeholders.
*/
default 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);
}
void addInjectablePlaceholder(@NotNull Iterable<InjectablePlaceholder> placeholders);
/**
* Clear injected placeholders.
*/
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.
* <p>
@@ -91,7 +48,5 @@ public interface PlaceholderInjectable {
* @return Injected placeholders.
*/
@NotNull
default List<InjectablePlaceholder> getPlaceholderInjections() {
return new ArrayList<>(getInjectedPlaceholders());
}
List<InjectablePlaceholder> getPlaceholderInjections();
}

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_R2",
"v1_19_R1",
"v1_19_R2"
"v1_19_R2",
"v1_19_R3"
);
private ProxyConstants() {

View File

@@ -16,15 +16,4 @@ public class ProxyError extends Error {
@NotNull final Throwable cause) {
super(message, cause);
}
/**
* Thrown if there is an error getting a proxy.
*
* @param message The message to send.
* @deprecated Proxy Errors should include a cause.
*/
@Deprecated(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.
*/
@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);
}

View File

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

View File

@@ -69,7 +69,11 @@ public final class ShapedCraftingRecipe implements CraftingRecipe {
}
@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);
boolean matches = true;
for (int i = 0; i < 9; i++) {

View File

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

View File

@@ -0,0 +1,36 @@
package com.willfp.eco.core.registry;
import org.jetbrains.annotations.NotNull;
/**
* An object that can be registered.
*
* @see Registry
*/
public interface Registrable {
/**
* Get the ID of the element.
*
* @return The ID.
*/
@NotNull
String getID();
/**
* Called when the element is registered.
* <p>
* This is called after registration.
*/
default void onRegister() {
// Do nothing by default.
}
/**
* Called when the element is removed.
* <p>
* This is called before removal.
*/
default void onRemove() {
// Do nothing by default.
}
}

View File

@@ -0,0 +1,204 @@
package com.willfp.eco.core.registry;
import org.apache.commons.lang.Validate;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
/**
* A registry for {@link Registrable}s.
*
* @param <T> The type of {@link Registrable}.
*/
public class Registry<T extends Registrable> implements Iterable<T> {
/**
* The ID pattern.
*/
private static final Pattern ID_PATTERN = Pattern.compile("[a-z0-9_]{1,100}");
/**
* The registry.
*/
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.
*/
public Registry() {
}
/**
* Register a new element.
*
* @param element The element to register.
* @return The element.
*/
@NotNull
public T register(@NotNull final T element) {
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);
element.onRegister();
return element;
}
/**
* Remove an element.
*
* @param element The element.
* @return The element.
*/
public T remove(@NotNull final T element) {
if (this.isLocked) {
throw new IllegalStateException("Cannot remove from locked registry! (ID: " + element.getID() + ")");
}
element.onRemove();
registry.remove(element.getID());
return element;
}
/**
* Remove an element by ID.
*
* @param id The ID.
* @return The element.
*/
@Nullable
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);
if (element != null) {
element.onRemove();
}
return registry.remove(id);
}
/**
* Get an element by ID.
*
* @param id The ID.
* @return The element, or null if not found.
*/
@Nullable
public T get(@NotNull final String id) {
return registry.get(id);
}
/**
* Clear the registry.
*/
public void clear() {
for (T value : Set.copyOf(registry.values())) {
remove(value);
}
}
/**
* Get all elements.
*
* @return All elements.
*/
public Set<T> 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();
}
}

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,12 +1,9 @@
package com.willfp.eco.util;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
@@ -62,27 +59,6 @@ public final class BlockUtils {
return getNearbyBlocks(start, allowedMaterials, new HashSet<>(), limit);
}
/**
* Break the block as if the player had done it manually.
*
* @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);
}
/**
* Get if a block was placed by a player.
*

View File

@@ -8,7 +8,6 @@ import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerItemBreakEvent;
import org.bukkit.event.player.PlayerItemDamageEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
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.
@SuppressWarnings("RedundantCast")
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.
*

View File

@@ -2,11 +2,9 @@ package com.willfp.eco.util;
import com.willfp.eco.core.Eco;
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.placeholder.AdditionalPlayer;
import com.willfp.eco.core.placeholder.PlaceholderInjectable;
import com.willfp.eco.core.placeholder.StaticPlaceholder;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -14,7 +12,6 @@ import org.jetbrains.annotations.Nullable;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ThreadLocalRandom;
@@ -89,34 +86,6 @@ public final class NumberUtils {
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.
*
@@ -256,36 +225,6 @@ public final class NumberUtils {
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).
*

View File

@@ -426,20 +426,6 @@ public final class StringUtils {
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}.
* Formats collections and doubles better.

View File

@@ -4,24 +4,16 @@ import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Team;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* Utilities / API methods for teams.
*/
public final class TeamUtils {
/**
* Ore ChatColors.
*/
private static final Map<Material, ChatColor> MATERIAL_COLORS = new HashMap<>();
/**
* All chat color teams.
*/
@@ -60,44 +52,10 @@ public final class TeamUtils {
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 {
for (ChatColor value : ChatColor.values()) {
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() {

View File

@@ -38,6 +38,15 @@ class DSLConfig internal constructor(type: ConfigType) : GenericConfig(type) {
fun config(type: ConfigType = ConfigType.YAML, builder: DSLConfig.() -> Unit): Config =
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 */
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 */
val ItemStack?.isEmpty: Boolean
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,48 @@
@file:JvmName("DefaultMapExtensions")
package com.willfp.eco.core.map
/**
* Required to avoid type ambiguity.
*
* @see ListMap
*/
@Suppress("RedundantOverride")
class MutableListMap<K : Any, V : Any> : ListMap<K, V>() {
/**
* Override with enforced MutableList type.
*/
override fun get(key: K?): MutableList<V> =
super.get(key)
/**
* Override with enforced MutableList type.
*/
override fun getOrDefault(key: K, defaultValue: MutableList<V>?): MutableList<V> {
return super.getOrDefault(key, defaultValue)
}
}
/**
* @see DefaultMap
*/
fun <K : Any, V : Any> defaultMap(defaultValue: V) =
DefaultMap<K, V>(defaultValue)
/**
* @see ListMap
*/
fun <K : Any, V : Any> listMap() =
MutableListMap<K, V>()
/**
* @see DefaultMap.createNestedMap
*/
fun <K : Any, K1 : Any, V : Any> nestedMap() =
DefaultMap.createNestedMap<K, K1, V>()
/**
* @see DefaultMap.createNestedListMap
*/
fun <K : Any, K1 : Any, V : Any> nestedListMap() =
DefaultMap<K, MutableListMap<K1, V>>(MutableListMap())

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> {
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 bStatsId = config.getIntOrNull("bstats-id") ?: 0
val proxyPackage = config.getStringOrNull("proxy-package") ?: ""
val color = config.getStringOrNull("color") ?: "&f"
val supportsExtensions = config.getBoolOrNull("supports-extensions") ?: false
val usesReflectiveReload = config.getBoolOrNull("uses-reflective-reload") ?: true
return blankProps.apply {
props.apply {
this.resourceId = resourceId
this.bStatsId = bStatsId
this.proxyPackage = proxyPackage
this.color = color
this.isSupportingExtensions = supportsExtensions
this.setUsesReflectiveReload(usesReflectiveReload)
}
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.internal.command
import org.bukkit.Location
import org.bukkit.command.Command
import org.bukkit.command.CommandSender
import org.bukkit.command.PluginIdentifiableCommand
@@ -21,7 +22,16 @@ class DelegatedBukkitCommand(
label: String,
args: Array<out 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

View File

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

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.config.interfaces.LoadableConfig
import com.willfp.eco.core.config.updating.ConfigHandler
import com.willfp.eco.core.config.updating.ConfigUpdater
import org.reflections.Reflections
import org.reflections.scanners.MethodAnnotationsScanner
class EcoConfigHandler(
class ReflectiveConfigHandler(
private val plugin: EcoPlugin
) : ConfigHandler {
) : SimpleConfigHandler() {
private val reflections: Reflections = Reflections(
this.plugin::class.java.classLoader,
MethodAnnotationsScanner()
)
private val configs = mutableListOf<LoadableConfig>()
override fun callUpdate() {
for (method in reflections.getMethodsAnnotatedWith(ConfigUpdater::class.java)) {
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)

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?) {
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 {

View File

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

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