Compare commits
204 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08c14f4def | ||
|
|
0fa6f972c0 | ||
|
|
8837fecfa0 | ||
|
|
af1841770e | ||
|
|
1d85dbf08d | ||
|
|
ba9812534a | ||
|
|
1f95a33385 | ||
|
|
bc652a8154 | ||
|
|
0c2e1f0cae | ||
|
|
39d6eb7f9a | ||
|
|
61bae6de55 | ||
|
|
aa4ac4c6d1 | ||
|
|
7141b12e95 | ||
|
|
2382548629 | ||
|
|
0c4bd182f7 | ||
|
|
e90e053b45 | ||
|
|
742c1abb00 | ||
|
|
c0686ca386 | ||
|
|
db2ea7daa9 | ||
|
|
ed4f0b2ab6 | ||
|
|
6decc68d1b | ||
|
|
1e061313a4 | ||
|
|
4762004e94 | ||
|
|
0d9889ef43 | ||
|
|
b2a23e80a1 | ||
|
|
0e439db7b3 | ||
|
|
f615006b23 | ||
|
|
d952dbc61b | ||
|
|
d95a96f4c6 | ||
|
|
33940f5778 | ||
|
|
173d04595f | ||
|
|
c7c4ca3777 | ||
|
|
cbf7316db9 | ||
|
|
601cadd582 | ||
|
|
877647db03 | ||
|
|
81196bb132 | ||
|
|
ef701f1f86 | ||
|
|
58d8f72cf5 | ||
|
|
3abf916f18 | ||
|
|
b459a746e3 | ||
|
|
30c37078a2 | ||
|
|
36ccfb5fc6 | ||
|
|
c84f1a060a | ||
|
|
d8d5609f6b | ||
|
|
462abd46c6 | ||
|
|
e89008cf97 | ||
|
|
d34e43797d | ||
|
|
63ee83c795 | ||
|
|
2eec17698e | ||
|
|
ad52c2a086 | ||
|
|
6e482cccda | ||
|
|
899b4297f7 | ||
|
|
ceb95e20b5 | ||
|
|
bdfeb9a0ab | ||
|
|
e0707e2afa | ||
|
|
e8048f5a0a | ||
|
|
a36018e31a | ||
|
|
a34c63161d | ||
|
|
2eb350977c | ||
|
|
8a89a63c5f | ||
|
|
5c26e6e782 | ||
|
|
f88b914fa6 | ||
|
|
15ff6b3ea3 | ||
|
|
b14eed696c | ||
|
|
cffae33c87 | ||
|
|
adf6d1c800 | ||
|
|
2b7c8962e7 | ||
|
|
b60cbfce2c | ||
|
|
910ad18703 | ||
|
|
8a4a71ebc1 | ||
|
|
2e748b1723 | ||
|
|
cb28726bc3 | ||
|
|
c0c20d63bb | ||
|
|
3b11610c45 | ||
|
|
232048022e | ||
|
|
9abfe0ab01 | ||
|
|
e7ac05278c | ||
|
|
85ba40c279 | ||
|
|
1acf86492e | ||
|
|
4609d38389 | ||
|
|
2d6836cc93 | ||
|
|
8e21617345 | ||
|
|
2f99a17d02 | ||
|
|
34edf1d7b4 | ||
|
|
be85ba5706 | ||
|
|
b817b00ca4 | ||
|
|
ee02528abc | ||
|
|
794948c8f9 | ||
|
|
7c70dec2e7 | ||
|
|
d1f20b7111 | ||
|
|
595751a094 | ||
|
|
8231afdcbf | ||
|
|
4f55d66096 | ||
|
|
d350febbdc | ||
|
|
78755b0e9a | ||
|
|
63d7bdab6b | ||
|
|
344032b7e3 | ||
|
|
3ae5c8a72c | ||
|
|
e4f2bc2e39 | ||
|
|
90ba0a0391 | ||
|
|
801a3cd4f9 | ||
|
|
ce9cada75a | ||
|
|
ae551dd0f7 | ||
|
|
1b3dd53fb8 | ||
|
|
dda4224e6e | ||
|
|
6e14265655 | ||
|
|
77fd99d215 | ||
|
|
cf05efc2ff | ||
|
|
0e8c759a4c | ||
|
|
ba7bfb828b | ||
|
|
8dd1239b99 | ||
|
|
edada09966 | ||
|
|
19c300bbf3 | ||
|
|
4fc9c21034 | ||
|
|
2366dcd293 | ||
|
|
054e6a53c0 | ||
|
|
46f590fe3e | ||
|
|
b46aaf547f | ||
|
|
0f7125e1c8 | ||
|
|
6cb99819f3 | ||
|
|
a018a1fca5 | ||
|
|
8a7b8f2b03 | ||
|
|
abf3dc1e9e | ||
|
|
e92cc41be6 | ||
|
|
49570c841b | ||
|
|
9aa465844d | ||
|
|
a692fbee01 | ||
|
|
4223e8f17a | ||
|
|
5f26b23a53 | ||
|
|
c8c179981c | ||
|
|
4bb8bb62f9 | ||
|
|
c1b3bec67c | ||
|
|
f2535ce75c | ||
|
|
049d64821e | ||
|
|
bf5766e61c | ||
|
|
38da5fe6d1 | ||
|
|
e16649873b | ||
|
|
a3b0b4f847 | ||
|
|
d9f1ddd188 | ||
|
|
14a4d9291b | ||
|
|
6630044546 | ||
|
|
1043981fe4 | ||
|
|
fb0b7c52cf | ||
|
|
74e5464f7d | ||
|
|
2ad1ff4cdb | ||
|
|
2d47c18be6 | ||
|
|
69e67be436 | ||
|
|
c144723d5b | ||
|
|
108375f545 | ||
|
|
83d5b3e96e | ||
|
|
37e09a470e | ||
|
|
1f064110b7 | ||
|
|
94a0b4de5d | ||
|
|
8a68666f86 | ||
|
|
2c218d1088 | ||
|
|
3fa95d82a6 | ||
|
|
9648b42c4d | ||
|
|
66887f0a3a | ||
|
|
410cdfe7e3 | ||
|
|
bbffdc7e23 | ||
|
|
0d267e2bec | ||
|
|
578256f89b | ||
|
|
90ecbfce00 | ||
|
|
9945704338 | ||
|
|
5c7a7876d8 | ||
|
|
94df0e67a6 | ||
|
|
92c4e62709 | ||
|
|
e094a1e934 | ||
|
|
26c07a20e7 | ||
|
|
ad68e1efef | ||
|
|
d8c3a3befa | ||
|
|
aa52dcdf94 | ||
|
|
9d3ba7ea88 | ||
|
|
e2b417af74 | ||
|
|
77394d3038 | ||
|
|
fcc7f82b38 | ||
|
|
396f4dac44 | ||
|
|
3341093735 | ||
|
|
714d04e48f | ||
|
|
73b7ccea3a | ||
|
|
606bf8fcd2 | ||
|
|
fbbf893d64 | ||
|
|
36001373eb | ||
|
|
9ac34288eb | ||
|
|
6345d1fe92 | ||
|
|
a7fa0ecf26 | ||
|
|
a65f16cfac | ||
|
|
49965c091b | ||
|
|
f9bc2aba99 | ||
|
|
5627582bd5 | ||
|
|
ab8065d06e | ||
|
|
444764e481 | ||
|
|
c240e94a6b | ||
|
|
9da28a1dff | ||
|
|
cf3c1f8394 | ||
|
|
f98befbdce | ||
|
|
d0d8ea07e4 | ||
|
|
109347a601 | ||
|
|
43bef762bf | ||
|
|
69a2e0e247 | ||
|
|
874a9b4f32 | ||
|
|
5690221c27 | ||
|
|
f19b143804 | ||
|
|
bbbf19c041 |
11
.github/dependabot.yml
vendored
Normal file
11
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "gradle" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "daily"
|
||||
@@ -1,6 +1,6 @@
|
||||
<h1 align="center">
|
||||
<br>
|
||||
<img src="https://i.imgur.com/p5uR2Qp.png" alt="eco logo" width="256">
|
||||
<img src="https://i.imgur.com/kU3ejCt.png" alt="eco logo" width="256">
|
||||
<br>
|
||||
</h1>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# Information for development
|
||||
|
||||
## Javadoc
|
||||
The 6.0.0 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.0.0/javadoc/)
|
||||
The 6.8.0 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.8.0/javadoc/)
|
||||
|
||||
## Plugin Information
|
||||
|
||||
@@ -31,7 +31,6 @@ depend:
|
||||
eco is available from any of these places:
|
||||
|
||||
- [GitHub](https://github.com/Auxilor/eco/releases)
|
||||
- [Spigot](https://www.spigotmc.org/resources/eco.87955/)
|
||||
- [Polymart](https://polymart.org/resource/eco.773)
|
||||
- [Build it locally](https://github.com/Auxilor/eco#build-locally).
|
||||
|
||||
@@ -72,7 +71,7 @@ Maven:
|
||||
</dependency>
|
||||
```
|
||||
|
||||
Replace `Tag` with a release tag for eco, eg `6.0.0`.
|
||||
Replace `Tag` with a release tag for eco, eg `6.8.0`.
|
||||
|
||||
## Build locally:
|
||||
|
||||
@@ -158,7 +157,7 @@ Here's a list of some (not all) of the features of eco:
|
||||
|
||||
<h1 align="center">
|
||||
<br>
|
||||
<a href="http://gamersupps.gg/discount/Auxilor?afmc=Auxilor" target="_blank">
|
||||
<a href="https://gamersupps.gg/discount/Auxilor?afmc=Auxilor" target="_blank">
|
||||
<img src="https://i.imgur.com/uFDpBAC.png" alt="supps banner">
|
||||
</a>
|
||||
<a href="https://dedimc.promo/Auxilor" target="_blank">
|
||||
|
||||
15
build.gradle
15
build.gradle
@@ -25,11 +25,14 @@ allprojects {
|
||||
mavenLocal()
|
||||
maven { url 'https://jitpack.io' }
|
||||
|
||||
// SuperiorSkyblock2
|
||||
maven { url 'https://repo.bg-software.com/repository/api/' }
|
||||
|
||||
// NMS (for jitpack compilation)
|
||||
maven { url 'https://repo.codemc.org/repository/nms/' }
|
||||
|
||||
// bStats, mcMMO
|
||||
maven { url 'https://repo.codemc.org/repository/maven-public' }
|
||||
// bStats, mcMMO, BentoBox
|
||||
maven { url 'https://repo.codemc.org/repository/maven-public/' }
|
||||
|
||||
// Spigot API
|
||||
maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' }
|
||||
@@ -51,23 +54,20 @@ allprojects {
|
||||
|
||||
// CombatLogX
|
||||
maven { url 'https://nexus.sirblobman.xyz/repository/public/' }
|
||||
|
||||
// Head Database
|
||||
maven { url 'https://mvn.intellectualsites.com/content/groups/public/' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly 'org.jetbrains:annotations:19.0.0'
|
||||
|
||||
// Lombok
|
||||
compileOnly 'org.projectlombok:lombok:1.18.20'
|
||||
compileOnly 'org.projectlombok:lombok:1.18.22'
|
||||
annotationProcessor 'org.projectlombok:lombok:1.18.20'
|
||||
testCompileOnly 'org.projectlombok:lombok:1.18.20'
|
||||
testAnnotationProcessor 'org.projectlombok:lombok:1.18.20'
|
||||
|
||||
// Test
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
|
||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1'
|
||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
@@ -87,6 +87,7 @@ allprojects {
|
||||
|
||||
shadowJar {
|
||||
relocate('org.bstats', 'com.willfp.eco.shaded.bstats')
|
||||
relocate('net.kyori.adventure.text.minimessage', 'com.willfp.eco.shaded.minimessage')
|
||||
}
|
||||
|
||||
jar {
|
||||
|
||||
@@ -6,12 +6,18 @@ group 'com.willfp'
|
||||
version rootProject.version
|
||||
|
||||
dependencies {
|
||||
compileOnly 'org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT'
|
||||
compileOnly 'org.apache.maven:maven-artifact:3.0.3'
|
||||
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.0-SNAPSHOT'
|
||||
compileOnly 'com.google.code.gson:gson:2.8.7'
|
||||
compileOnly 'net.kyori:adventure-text-serializer-gson:4.8.1'
|
||||
compileOnly 'net.kyori:adventure-text-serializer-legacy:4.8.1'
|
||||
// Adventure
|
||||
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
|
||||
compileOnly 'net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT'
|
||||
compileOnly 'net.kyori:adventure-api:4.9.2'
|
||||
compileOnly 'net.kyori:adventure-text-serializer-gson:4.9.2'
|
||||
compileOnly 'net.kyori:adventure-text-serializer-legacy:4.9.2'
|
||||
|
||||
// Other
|
||||
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
|
||||
compileOnly 'org.apache.maven:maven-artifact:3.8.1'
|
||||
compileOnly 'com.comphenix.protocol:ProtocolLib:4.7.1-SNAPSHOT'
|
||||
compileOnly 'com.google.code.gson:gson:2.8.8'
|
||||
}
|
||||
|
||||
java {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.willfp.eco.core;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -15,20 +14,12 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class Eco {
|
||||
/**
|
||||
* Instance of eco handler.
|
||||
* <p>
|
||||
* The handler is, in essence, a way to interface between the eco-api
|
||||
* frontend module, and the eco-backend implementations.
|
||||
* <p>
|
||||
* There shouldn't really be any reason to ever use the handler
|
||||
* in your own plugins, but if you want to then you can - it's
|
||||
* just a part of the API like any other.
|
||||
*/
|
||||
@Getter
|
||||
@ApiStatus.Internal
|
||||
private Handler handler;
|
||||
|
||||
/**
|
||||
* Set the handler.
|
||||
*
|
||||
* @param handler The handler.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@@ -37,4 +28,25 @@ public class Eco {
|
||||
|
||||
Eco.handler = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the instance of the eco handler.
|
||||
* <p>
|
||||
* The handler is, in essence, a way to interface between the eco-api
|
||||
* frontend module, and the eco-backend implementations.
|
||||
* <p>
|
||||
* There shouldn't really be any reason to ever use the handler
|
||||
* in your own plugins, and you are likely to break things. All parts of
|
||||
* the handler are abstracted into logically named parts of the API.
|
||||
* <p>
|
||||
* In versions of eco before 6.12.0, the handler was considered part of
|
||||
* the eco API, however it has since been moved into an internal component
|
||||
* that shouldn't be used in your plugins.
|
||||
*
|
||||
* @return The handler.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public Handler getHandler() {
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,9 +52,9 @@ import java.util.stream.Collectors;
|
||||
* be cancelled.</b>
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public abstract class EcoPlugin extends JavaPlugin {
|
||||
public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
/**
|
||||
* The spigot resource ID of the plugin.
|
||||
* The polymart resource ID of the plugin.
|
||||
*/
|
||||
@Getter
|
||||
private final int resourceId;
|
||||
@@ -169,14 +169,14 @@ public abstract class EcoPlugin extends JavaPlugin {
|
||||
private final ProxyFactory proxyFactory;
|
||||
|
||||
/**
|
||||
* Create a new plugin without a specified color, proxy support, spigot, or bStats.
|
||||
* Create a new plugin without a specified color, proxy support, polymart, or bStats.
|
||||
*/
|
||||
protected EcoPlugin() {
|
||||
this("&f");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new plugin without proxy support, spigot, or bStats.
|
||||
* Create a new plugin without proxy support, polymart, or bStats.
|
||||
*
|
||||
* @param color The color.
|
||||
*/
|
||||
@@ -186,7 +186,7 @@ public abstract class EcoPlugin extends JavaPlugin {
|
||||
|
||||
|
||||
/**
|
||||
* Create a new plugin unlinked to spigot and bStats.
|
||||
* Create a new plugin unlinked to polymart and bStats.
|
||||
*
|
||||
* @param proxyPackage The package where proxy implementations are stored.
|
||||
* @param color The color of the plugin (used in messages, using standard formatting)
|
||||
@@ -199,7 +199,7 @@ public abstract class EcoPlugin extends JavaPlugin {
|
||||
/**
|
||||
* Create a new plugin without proxy or extension support.
|
||||
*
|
||||
* @param resourceId The spigot resource ID for the plugin.
|
||||
* @param resourceId The polymart resource ID for the plugin.
|
||||
* @param bStatsId The bStats resource ID for the plugin.
|
||||
* @param color The color of the plugin (used in messages, using standard formatting)
|
||||
*/
|
||||
@@ -212,7 +212,7 @@ public abstract class EcoPlugin extends JavaPlugin {
|
||||
/**
|
||||
* Create a new plugin without proxy support.
|
||||
*
|
||||
* @param resourceId The spigot resource ID for the plugin.
|
||||
* @param resourceId The polymart resource ID for the plugin.
|
||||
* @param bStatsId The bStats resource ID for the plugin.
|
||||
* @param color The color of the plugin (used in messages, using standard formatting)
|
||||
* @param supportingExtensions If the plugin supports extensions.
|
||||
@@ -227,7 +227,7 @@ public abstract class EcoPlugin extends JavaPlugin {
|
||||
/**
|
||||
* Create a new plugin without extension support.
|
||||
*
|
||||
* @param resourceId The spigot resource ID for the plugin.
|
||||
* @param resourceId The polymart resource ID for the plugin.
|
||||
* @param bStatsId The bStats resource ID for the plugin.
|
||||
* @param proxyPackage The package where proxy implementations are stored.
|
||||
* @param color The color of the plugin (used in messages, using standard formatting)
|
||||
@@ -242,7 +242,7 @@ public abstract class EcoPlugin extends JavaPlugin {
|
||||
/**
|
||||
* Create a new plugin.
|
||||
*
|
||||
* @param resourceId The spigot resource ID for the plugin.
|
||||
* @param resourceId The polymart resource ID for the plugin.
|
||||
* @param bStatsId The bStats resource ID for the plugin.
|
||||
* @param proxyPackage The package where proxy implementations are stored.
|
||||
* @param color The color of the plugin (used in messages, using standard formatting)
|
||||
@@ -357,15 +357,18 @@ public abstract class EcoPlugin extends JavaPlugin {
|
||||
Eco.getHandler().registerBStats(this);
|
||||
}
|
||||
|
||||
Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(Plugin::getName).collect(Collectors.toSet());
|
||||
Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins())
|
||||
.map(Plugin::getName)
|
||||
.map(String::toLowerCase)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (enabledPlugins.contains("PlaceholderAPI")) {
|
||||
if (enabledPlugins.contains("PlaceholderAPI".toLowerCase())) {
|
||||
this.loadedIntegrations.add("PlaceholderAPI");
|
||||
PlaceholderManager.addIntegration(Eco.getHandler().createPAPIIntegration(this));
|
||||
}
|
||||
|
||||
this.loadIntegrationLoaders().forEach((integrationLoader -> {
|
||||
if (enabledPlugins.contains(integrationLoader.getPluginName())) {
|
||||
if (enabledPlugins.contains(integrationLoader.getPluginName().toLowerCase())) {
|
||||
this.loadedIntegrations.add(integrationLoader.getPluginName());
|
||||
integrationLoader.load();
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.willfp.eco.core;
|
||||
|
||||
import com.willfp.eco.core.config.updating.ConfigHandler;
|
||||
import com.willfp.eco.core.config.wrapper.ConfigFactory;
|
||||
import com.willfp.eco.core.data.keys.KeyRegistry;
|
||||
import com.willfp.eco.core.data.PlayerProfileHandler;
|
||||
import com.willfp.eco.core.drops.DropQueueFactory;
|
||||
import com.willfp.eco.core.events.EventManager;
|
||||
import com.willfp.eco.core.extensions.ExtensionLoader;
|
||||
@@ -13,8 +15,11 @@ import com.willfp.eco.core.gui.GUIFactory;
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration;
|
||||
import com.willfp.eco.core.proxy.Cleaner;
|
||||
import com.willfp.eco.core.proxy.ProxyFactory;
|
||||
import com.willfp.eco.core.requirement.RequirementFactory;
|
||||
import com.willfp.eco.core.scheduling.Scheduler;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -22,8 +27,9 @@ import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* @see Eco
|
||||
* @see Eco#getHandler()
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public interface Handler {
|
||||
/**
|
||||
* Create a scheduler.
|
||||
@@ -194,4 +200,35 @@ public interface Handler {
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
void registerBStats(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Get the requirement factory.
|
||||
*
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
RequirementFactory getRequirementFactory();
|
||||
|
||||
/**
|
||||
* Get Adventure audiences.
|
||||
*
|
||||
* @return The audiences.
|
||||
*/
|
||||
@Nullable
|
||||
BukkitAudiences getAdventure();
|
||||
|
||||
/**
|
||||
* Get the key registry.
|
||||
*
|
||||
* @return The registry.
|
||||
*/
|
||||
@NotNull
|
||||
KeyRegistry getKeyRegistry();
|
||||
|
||||
/**
|
||||
* Get the PlayerProfile handler.
|
||||
*
|
||||
* @return The handler.
|
||||
*/
|
||||
PlayerProfileHandler getPlayerProfileHandler();
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
*
|
||||
* @param <T> The eco plugin type.
|
||||
*/
|
||||
public abstract class PluginDependent<@NotNull T extends EcoPlugin> {
|
||||
public abstract class PluginDependent<T extends EcoPlugin> {
|
||||
/**
|
||||
* The {@link EcoPlugin} that is stored.
|
||||
*/
|
||||
|
||||
29
eco-api/src/main/java/com/willfp/eco/core/PluginLike.java
Normal file
29
eco-api/src/main/java/com/willfp/eco/core/PluginLike.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package com.willfp.eco.core;
|
||||
|
||||
import com.willfp.eco.core.config.updating.ConfigHandler;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Represents any class that acts like a plugin, for example {@link EcoPlugin}
|
||||
* or {@link com.willfp.eco.core.extensions.Extension}. This exists to create
|
||||
* things such as extension base configs rather than needing to pass an instance
|
||||
* of the owning plugin.
|
||||
*/
|
||||
public interface PluginLike {
|
||||
/**
|
||||
* Get the data folder of the object.
|
||||
* <p>
|
||||
* Returns the plugin data folder for a plugin, or the extension's parent plugin's folder
|
||||
*
|
||||
* @return The data folder.
|
||||
*/
|
||||
File getDataFolder();
|
||||
|
||||
/**
|
||||
* Get the handler class for updatable classes.
|
||||
*
|
||||
* @return The config handler.
|
||||
*/
|
||||
ConfigHandler getConfigHandler();
|
||||
}
|
||||
@@ -34,7 +34,7 @@ public interface LoadableConfig {
|
||||
File getConfigFile();
|
||||
|
||||
/**
|
||||
* Get the config name (including extension)
|
||||
* Get the config name (including extension).
|
||||
*
|
||||
* @return The name.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.willfp.eco.core.config.json;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Config implementation for configs present in the plugin's base directory (eg config.json).
|
||||
* <p>
|
||||
* Automatically updates.
|
||||
*/
|
||||
public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||
*/
|
||||
protected JSONBaseConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final PluginLike plugin,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
super(
|
||||
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
|
||||
configName,
|
||||
plugin,
|
||||
"",
|
||||
plugin.getClass(),
|
||||
removeUnused, updateBlacklist
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
protected JSONBaseConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final PluginLike plugin) {
|
||||
super(
|
||||
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
|
||||
configName,
|
||||
plugin,
|
||||
"",
|
||||
plugin.getClass(),
|
||||
removeUnused
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||
*/
|
||||
protected JSONBaseConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final EcoPlugin plugin,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
this(configName, removeUnused, (PluginLike) plugin, updateBlacklist);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
protected JSONBaseConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final EcoPlugin plugin) {
|
||||
this(configName, removeUnused, (PluginLike) plugin);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.willfp.eco.core.config.json;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Config implementation for configs present in one of two places:
|
||||
* <ul>
|
||||
* <li>Plugin base directory (eg config.yml, lang.yml)</li>
|
||||
* <li>Other extension's configs</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Automatically updates.
|
||||
*/
|
||||
public abstract class JSONExtendableConfig extends LoadableJSONConfigWrapper {
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||
* @param subDirectoryPath The subdirectory path.
|
||||
* @param source The class that owns the resource.
|
||||
*/
|
||||
protected JSONExtendableConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final PluginLike plugin,
|
||||
@NotNull final Class<?> source,
|
||||
@NotNull final String subDirectoryPath,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
super(
|
||||
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
|
||||
configName,
|
||||
plugin,
|
||||
subDirectoryPath,
|
||||
source,
|
||||
removeUnused,
|
||||
updateBlacklist
|
||||
)
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||
* @param subDirectoryPath The subdirectory path.
|
||||
* @param source The class that owns the resource.
|
||||
*/
|
||||
protected JSONExtendableConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final EcoPlugin plugin,
|
||||
@NotNull final Class<?> source,
|
||||
@NotNull final String subDirectoryPath,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
this(configName, removeUnused, (PluginLike) plugin, source, subDirectoryPath, updateBlacklist);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.willfp.eco.core.config.json;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -18,7 +19,20 @@ public abstract class JSONStaticBaseConfig extends LoadableJSONConfigWrapper {
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
protected JSONStaticBaseConfig(@NotNull final String configName,
|
||||
@NotNull final EcoPlugin plugin) {
|
||||
@NotNull final PluginLike plugin) {
|
||||
super(Eco.getHandler().getConfigFactory().createLoadableJSONConfig(configName, plugin, "", plugin.getClass()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Config implementation for configs present in the plugin's base directory (eg config.json, lang.json).
|
||||
* <p>
|
||||
* Does not automatically update.
|
||||
*
|
||||
* @param configName The name of the config
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
protected JSONStaticBaseConfig(@NotNull final String configName,
|
||||
@NotNull final EcoPlugin plugin) {
|
||||
this(configName, (PluginLike) plugin);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import com.willfp.eco.core.config.interfaces.LoadableConfig;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Every {@link com.willfp.eco.core.EcoPlugin} has a config handler.
|
||||
* Every {@link com.willfp.eco.core.PluginLike} has a config handler.
|
||||
* <p>
|
||||
* Handles updating and saving configs.
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.willfp.eco.core.config.wrapper;
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.interfaces.Config;
|
||||
import com.willfp.eco.core.config.interfaces.JSONConfig;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
@@ -24,7 +24,25 @@ public interface ConfigFactory {
|
||||
* @return The config implementation.
|
||||
*/
|
||||
Config createUpdatableYamlConfig(@NotNull String configName,
|
||||
@NotNull EcoPlugin plugin,
|
||||
@NotNull PluginLike plugin,
|
||||
@NotNull String subDirectoryPath,
|
||||
@NotNull Class<?> source,
|
||||
boolean removeUnused,
|
||||
@NotNull String... updateBlacklist);
|
||||
|
||||
/**
|
||||
* Updatable config.
|
||||
*
|
||||
* @param configName The name of the config
|
||||
* @param plugin The plugin.
|
||||
* @param subDirectoryPath The subdirectory path.
|
||||
* @param source The class that owns the resource.
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||
* @return The config implementation.
|
||||
*/
|
||||
JSONConfig createUpdatableJSONConfig(@NotNull String configName,
|
||||
@NotNull PluginLike plugin,
|
||||
@NotNull String subDirectoryPath,
|
||||
@NotNull Class<?> source,
|
||||
boolean removeUnused,
|
||||
@@ -40,7 +58,7 @@ public interface ConfigFactory {
|
||||
* @return The config implementation.
|
||||
*/
|
||||
JSONConfig createLoadableJSONConfig(@NotNull String configName,
|
||||
@NotNull EcoPlugin plugin,
|
||||
@NotNull PluginLike plugin,
|
||||
@NotNull String subDirectoryPath,
|
||||
@NotNull Class<?> source);
|
||||
|
||||
@@ -54,7 +72,7 @@ public interface ConfigFactory {
|
||||
* @return The config implementation.
|
||||
*/
|
||||
Config createLoadableYamlConfig(@NotNull String configName,
|
||||
@NotNull EcoPlugin plugin,
|
||||
@NotNull PluginLike plugin,
|
||||
@NotNull String subDirectoryPath,
|
||||
@NotNull Class<?> source);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.willfp.eco.core.config.yaml;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -19,7 +20,7 @@ public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
|
||||
*/
|
||||
protected YamlBaseConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final EcoPlugin plugin,
|
||||
@NotNull final PluginLike plugin,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
super(
|
||||
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig(
|
||||
@@ -39,7 +40,7 @@ public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
|
||||
*/
|
||||
protected YamlBaseConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final EcoPlugin plugin) {
|
||||
@NotNull final PluginLike plugin) {
|
||||
super(
|
||||
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig(
|
||||
configName,
|
||||
@@ -50,4 +51,28 @@ public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||
*/
|
||||
protected YamlBaseConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final EcoPlugin plugin,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
this(configName, removeUnused, (PluginLike) plugin, updateBlacklist);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
protected YamlBaseConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final EcoPlugin plugin) {
|
||||
this(configName, removeUnused, (PluginLike) plugin);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.willfp.eco.core.config.yaml;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -25,7 +26,7 @@ public abstract class YamlExtendableConfig extends LoadableYamlConfigWrapper {
|
||||
*/
|
||||
protected YamlExtendableConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final EcoPlugin plugin,
|
||||
@NotNull final PluginLike plugin,
|
||||
@NotNull final Class<?> source,
|
||||
@NotNull final String subDirectoryPath,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
@@ -40,4 +41,20 @@ public abstract class YamlExtendableConfig extends LoadableYamlConfigWrapper {
|
||||
)
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||
* @param subDirectoryPath The subdirectory path.
|
||||
* @param source The class that owns the resource.
|
||||
*/
|
||||
protected YamlExtendableConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final EcoPlugin plugin,
|
||||
@NotNull final Class<?> source,
|
||||
@NotNull final String subDirectoryPath,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
this(configName, removeUnused, (PluginLike) plugin, source, subDirectoryPath, updateBlacklist);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.willfp.eco.core.config.yaml;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -18,7 +19,20 @@ public abstract class YamlStaticBaseConfig extends LoadableYamlConfigWrapper {
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
protected YamlStaticBaseConfig(@NotNull final String configName,
|
||||
@NotNull final EcoPlugin plugin) {
|
||||
@NotNull final PluginLike plugin) {
|
||||
super(Eco.getHandler().getConfigFactory().createLoadableYamlConfig(configName, plugin, "", plugin.getClass()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
|
||||
* <p>
|
||||
* Does not automatically update.
|
||||
*
|
||||
* @param configName The name of the config
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
protected YamlStaticBaseConfig(@NotNull final String configName,
|
||||
@NotNull final EcoPlugin plugin) {
|
||||
this(configName, (PluginLike) plugin);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.willfp.eco.core.data;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Persistent data storage interface for players.
|
||||
* <p>
|
||||
* Profiles save automatically, so there is no need to save after changes.
|
||||
*/
|
||||
public interface PlayerProfile {
|
||||
/**
|
||||
* Write a key to a player's persistent data.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param value The value.
|
||||
* @param <T> The type of the key.
|
||||
*/
|
||||
<T> void write(@NotNull PersistentDataKey<T> key,
|
||||
@NotNull T value);
|
||||
|
||||
/**
|
||||
* Read a key from a player's persistent data.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param <T> The type of the key.
|
||||
* @return The value, or the default value if not found.
|
||||
*/
|
||||
<T> @NotNull T read(@NotNull PersistentDataKey<T> key);
|
||||
|
||||
/**
|
||||
* Load a player profile.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return The profile.
|
||||
*/
|
||||
@NotNull
|
||||
static PlayerProfile load(@NotNull final OfflinePlayer player) {
|
||||
return load(player.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a player profile.
|
||||
*
|
||||
* @param uuid The player's UUID.
|
||||
* @return The profile.
|
||||
*/
|
||||
@NotNull
|
||||
static PlayerProfile load(@NotNull final UUID uuid) {
|
||||
return Eco.getHandler().getPlayerProfileHandler().load(uuid);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.willfp.eco.core.data;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* API to handle player profiles.
|
||||
*/
|
||||
public interface PlayerProfileHandler {
|
||||
/**
|
||||
* Load a player profile.
|
||||
*
|
||||
* @param uuid The UUID.
|
||||
* @return The profile.
|
||||
*/
|
||||
PlayerProfile load(@NotNull UUID uuid);
|
||||
|
||||
/**
|
||||
* Save a player profile.
|
||||
*
|
||||
* @param uuid The uuid.
|
||||
*/
|
||||
void savePlayer(@NotNull UUID uuid);
|
||||
|
||||
/**
|
||||
* Save all player data.
|
||||
*
|
||||
* @param async If the saving should be done asynchronously.
|
||||
*/
|
||||
void saveAll(boolean async);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.willfp.eco.core.data.keys;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* API to register persistent data keys.
|
||||
*/
|
||||
public interface KeyRegistry {
|
||||
/**
|
||||
* Register a persistent data key to be stored.
|
||||
*
|
||||
* @param key The key.
|
||||
*/
|
||||
void registerKey(@NotNull PersistentDataKey<?> key);
|
||||
|
||||
/**
|
||||
* Get all registered keys.
|
||||
*
|
||||
* @return The keys.
|
||||
*/
|
||||
Set<PersistentDataKey<?>> getRegisteredKeys();
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.willfp.eco.core.data.keys;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A persistent data key is a key with a type that can be stored about an offline player.
|
||||
*
|
||||
* @param <T> The type of the data.
|
||||
*/
|
||||
public class PersistentDataKey<T> {
|
||||
/**
|
||||
* The key of the persistent data value.
|
||||
*/
|
||||
@Getter
|
||||
private final NamespacedKey key;
|
||||
|
||||
/**
|
||||
* The default value for the key.
|
||||
*/
|
||||
@Getter
|
||||
private final T defaultValue;
|
||||
|
||||
/**
|
||||
* The persistent data key type.
|
||||
*/
|
||||
@Getter
|
||||
private final PersistentDataKeyType type;
|
||||
|
||||
/**
|
||||
* Create a new Persistent Data Key.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param type The data type.
|
||||
* @param defaultValue The default value.
|
||||
*/
|
||||
public PersistentDataKey(@NotNull final NamespacedKey key,
|
||||
@NotNull final PersistentDataKeyType type,
|
||||
@NotNull final T defaultValue) {
|
||||
this.key = key;
|
||||
this.defaultValue = defaultValue;
|
||||
this.type = type;
|
||||
|
||||
Eco.getHandler().getKeyRegistry().registerKey(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PersistentDataKey{"
|
||||
+ "key=" + key
|
||||
+ ", defaultValue=" + defaultValue
|
||||
+ ", type=" + type
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.willfp.eco.core.data.keys;
|
||||
|
||||
/**
|
||||
* All storable data key types.
|
||||
*/
|
||||
public enum PersistentDataKeyType {
|
||||
/**
|
||||
* String.
|
||||
*/
|
||||
STRING,
|
||||
|
||||
/**
|
||||
* Boolean.
|
||||
*/
|
||||
BOOLEAN,
|
||||
|
||||
/**
|
||||
* Integer.
|
||||
*/
|
||||
INT,
|
||||
|
||||
/**
|
||||
* Double.
|
||||
*/
|
||||
DOUBLE
|
||||
}
|
||||
@@ -1,22 +1,12 @@
|
||||
package com.willfp.eco.core.display;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Utility class to manage client-side item display.
|
||||
*/
|
||||
@@ -28,29 +18,9 @@ public class Display {
|
||||
public static final String PREFIX = "§z";
|
||||
|
||||
/**
|
||||
* All registered display modules.
|
||||
* The display handler.
|
||||
*/
|
||||
private static final Map<DisplayPriority, List<DisplayModule>> MODULES = new HashMap<>();
|
||||
|
||||
/**
|
||||
* NamespacedKey for finalizing.
|
||||
*/
|
||||
private static NamespacedKey finalizeKey = null;
|
||||
|
||||
/**
|
||||
* Register display module.
|
||||
*
|
||||
* @param module The module.
|
||||
*/
|
||||
public void registerDisplayModule(@NotNull final DisplayModule module) {
|
||||
List<DisplayModule> modules = MODULES.get(module.getPriority());
|
||||
|
||||
modules.removeIf(module1 -> module1.getPluginName().equalsIgnoreCase(module.getPluginName()));
|
||||
|
||||
modules.add(module);
|
||||
|
||||
MODULES.put(module.getPriority(), modules);
|
||||
}
|
||||
private static DisplayHandler handler = null;
|
||||
|
||||
/**
|
||||
* Display on ItemStacks.
|
||||
@@ -71,35 +41,7 @@ public class Display {
|
||||
*/
|
||||
public ItemStack display(@NotNull final ItemStack itemStack,
|
||||
@Nullable final Player player) {
|
||||
Map<String, Object[]> pluginVarArgs = new HashMap<>();
|
||||
|
||||
for (DisplayPriority priority : DisplayPriority.values()) {
|
||||
List<DisplayModule> modules = MODULES.get(priority);
|
||||
for (DisplayModule module : modules) {
|
||||
pluginVarArgs.put(module.getPluginName(), module.generateVarArgs(itemStack));
|
||||
}
|
||||
}
|
||||
|
||||
revert(itemStack);
|
||||
|
||||
ItemMeta meta = itemStack.getItemMeta();
|
||||
|
||||
if (meta == null) {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
for (DisplayPriority priority : DisplayPriority.values()) {
|
||||
List<DisplayModule> modules = MODULES.get(priority);
|
||||
for (DisplayModule module : modules) {
|
||||
Object[] varargs = pluginVarArgs.get(module.getPluginName());
|
||||
module.display(itemStack, varargs);
|
||||
if (player != null) {
|
||||
module.display(itemStack, player, varargs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return itemStack;
|
||||
return handler.display(itemStack, player);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,31 +73,7 @@ public class Display {
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
public ItemStack revert(@NotNull final ItemStack itemStack) {
|
||||
if (Display.isFinalized(itemStack)) {
|
||||
unfinalize(itemStack);
|
||||
}
|
||||
|
||||
ItemMeta meta = itemStack.getItemMeta();
|
||||
|
||||
if (meta == null) {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
List<String> lore = meta.getLore();
|
||||
|
||||
if (lore != null && lore.removeIf(line -> line.startsWith(Display.PREFIX))) { // only apply lore modification if needed
|
||||
meta.setLore(lore);
|
||||
itemStack.setItemMeta(meta);
|
||||
}
|
||||
|
||||
for (DisplayPriority priority : DisplayPriority.values()) {
|
||||
List<DisplayModule> modules = MODULES.get(priority);
|
||||
for (DisplayModule module : modules) {
|
||||
module.revert(itemStack);
|
||||
}
|
||||
}
|
||||
|
||||
return itemStack;
|
||||
return handler.revert(itemStack);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,21 +83,7 @@ public class Display {
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
public ItemStack finalize(@NotNull final ItemStack itemStack) {
|
||||
Validate.notNull(finalizeKey, "Key cannot be null!");
|
||||
|
||||
if (itemStack.getType().getMaxStackSize() > 1) {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
ItemMeta meta = itemStack.getItemMeta();
|
||||
if (meta == null) {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||
container.set(finalizeKey, PersistentDataType.INTEGER, 1);
|
||||
itemStack.setItemMeta(meta);
|
||||
return itemStack;
|
||||
return handler.finalize(itemStack);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,18 +93,7 @@ public class Display {
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
public ItemStack unfinalize(@NotNull final ItemStack itemStack) {
|
||||
Validate.notNull(finalizeKey, "Key cannot be null!");
|
||||
|
||||
ItemMeta meta = itemStack.getItemMeta();
|
||||
|
||||
if (meta == null) {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||
container.remove(finalizeKey);
|
||||
itemStack.setItemMeta(meta);
|
||||
return itemStack;
|
||||
return handler.unfinalize(itemStack);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,31 +103,77 @@ public class Display {
|
||||
* @return If finalized.
|
||||
*/
|
||||
public boolean isFinalized(@NotNull final ItemStack itemStack) {
|
||||
Validate.notNull(finalizeKey, "Key cannot be null!");
|
||||
|
||||
ItemMeta meta = itemStack.getItemMeta();
|
||||
|
||||
if (meta == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||
return container.has(finalizeKey, PersistentDataType.INTEGER);
|
||||
return handler.isFinalized(itemStack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set key to be used for finalization.
|
||||
* Register a new display module.
|
||||
*
|
||||
* @param finalizeKey The key.
|
||||
* @param module The module.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public static void setFinalizeKey(@NotNull final NamespacedKey finalizeKey) {
|
||||
Display.finalizeKey = finalizeKey;
|
||||
public void registerDisplayModule(@NotNull final DisplayModule module) {
|
||||
handler.registerDisplayModule(module);
|
||||
}
|
||||
|
||||
static {
|
||||
for (DisplayPriority priority : DisplayPriority.values()) {
|
||||
MODULES.put(priority, new ArrayList<>());
|
||||
/**
|
||||
* Initialize the display system.
|
||||
*
|
||||
* @param handler The handler.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public static void init(@NotNull final DisplayHandler handler) {
|
||||
if (Display.handler != null) {
|
||||
throw new IllegalArgumentException("Already Initialized!");
|
||||
}
|
||||
Display.handler = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extremely janky method - also internal, so don't use it. <b>This method is
|
||||
* NOT part of the API and may be removed at any time!</b>
|
||||
* <p>
|
||||
* This calls a display module with the specified parameters, now
|
||||
* you might ask why I need a static java method when the DisplayHandler
|
||||
* implementation could just call it itself? Well, kotlin doesn't really
|
||||
* like dealing with vararg ambiguity, and so while kotlin can't figure out
|
||||
* what is and isn't a vararg when I call display with a player, java can.
|
||||
* <p>
|
||||
* Because of this, I need to have this part of the code in java.
|
||||
*
|
||||
* <b>Don't call this method as part of your plugins!</b>
|
||||
* <p>
|
||||
* No, seriously - don't. This skips a bunch of checks and you'll almost
|
||||
* definitely break something.
|
||||
*
|
||||
* @param module The display module.
|
||||
* @param itemStack The ItemStack.
|
||||
* @param player The player.
|
||||
* @param args The args.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public static void callDisplayModule(@NotNull final DisplayModule module,
|
||||
@NotNull final ItemStack itemStack,
|
||||
@Nullable final Player player,
|
||||
@NotNull final Object... args) {
|
||||
module.display(itemStack, args);
|
||||
if (player != null) {
|
||||
module.display(itemStack, player, args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the display handler.
|
||||
* <p>
|
||||
* Internal API component, you will cause bugs if you create your own handler.
|
||||
*
|
||||
* @param handler The handler.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public static void setHandler(@NotNull final DisplayHandler handler) {
|
||||
if (Display.handler != null) {
|
||||
throw new IllegalStateException("Display already initialized!");
|
||||
}
|
||||
|
||||
Display.handler = handler;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.willfp.eco.core.display;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Interface for display implementations.
|
||||
*/
|
||||
public interface DisplayHandler {
|
||||
/**
|
||||
* Register display module.
|
||||
*
|
||||
* @param module The module.
|
||||
*/
|
||||
void registerDisplayModule(@NotNull DisplayModule module);
|
||||
|
||||
/**
|
||||
* Display on ItemStacks.
|
||||
*
|
||||
* @param itemStack The item.
|
||||
* @param player The player.
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
ItemStack display(@NotNull ItemStack itemStack,
|
||||
@Nullable Player player);
|
||||
|
||||
/**
|
||||
* Revert on ItemStacks.
|
||||
*
|
||||
* @param itemStack The item.
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
ItemStack revert(@NotNull ItemStack itemStack);
|
||||
|
||||
/**
|
||||
* Finalize an ItemStacks.
|
||||
*
|
||||
* @param itemStack The item.
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
ItemStack finalize(@NotNull ItemStack itemStack);
|
||||
|
||||
/**
|
||||
* Unfinalize an ItemStacks.
|
||||
*
|
||||
* @param itemStack The item.
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
ItemStack unfinalize(@NotNull ItemStack itemStack);
|
||||
|
||||
/**
|
||||
* If an item is finalized.
|
||||
*
|
||||
* @param itemStack The item.
|
||||
* @return If finalized.
|
||||
*/
|
||||
boolean isFinalized(@NotNull ItemStack itemStack);
|
||||
}
|
||||
@@ -36,7 +36,7 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
|
||||
* @param itemStack The item.
|
||||
* @param args Optional args for display.
|
||||
*/
|
||||
protected void display(@NotNull final ItemStack itemStack,
|
||||
public void display(@NotNull final ItemStack itemStack,
|
||||
@NotNull final Object... args) {
|
||||
// Technically optional.
|
||||
}
|
||||
@@ -48,7 +48,7 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
|
||||
* @param player The player.
|
||||
* @param args Optional args for display.
|
||||
*/
|
||||
protected void display(@NotNull final ItemStack itemStack,
|
||||
public void display(@NotNull final ItemStack itemStack,
|
||||
@Nullable final Player player,
|
||||
@NotNull final Object... args) {
|
||||
// Technically optional.
|
||||
@@ -59,7 +59,7 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
|
||||
*
|
||||
* @param itemStack The item.
|
||||
*/
|
||||
protected void revert(@NotNull final ItemStack itemStack) {
|
||||
public void revert(@NotNull final ItemStack itemStack) {
|
||||
// Technically optional.
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
|
||||
* @param itemStack The itemStack.
|
||||
* @return The plugin-specific varargs.
|
||||
*/
|
||||
protected Object[] generateVarArgs(@NotNull final ItemStack itemStack) {
|
||||
public Object[] generateVarArgs(@NotNull final ItemStack itemStack) {
|
||||
return new Object[0];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
package com.willfp.eco.core.extensions;
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.updating.ConfigHandler;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* An extension is a separate jar file that hooks into the base plugin jar.
|
||||
* <p>
|
||||
@@ -15,9 +19,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
* Syntactically, extensions are very similar to plugins in their own right, except that
|
||||
* they are loaded by another plugin.
|
||||
*
|
||||
* @see <a href="https://ecoenchants.polymart.org">EcoEnchants extension examples.</a>
|
||||
* @see <a href="https://auxilor.polymart.org">Extension examples.</a>
|
||||
*/
|
||||
public abstract class Extension {
|
||||
public abstract class Extension implements PluginLike {
|
||||
/**
|
||||
* The {@link EcoPlugin} that this extension is for.
|
||||
*/
|
||||
@@ -103,4 +107,14 @@ public abstract class Extension {
|
||||
Validate.notNull(metadata, "Metadata cannot be null!");
|
||||
return this.metadata.version();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getDataFolder() {
|
||||
return this.plugin.getDataFolder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigHandler getConfigHandler() {
|
||||
return this.plugin.getConfigHandler();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ public interface FastItemStack {
|
||||
* @param itemStack The ItemStack.
|
||||
* @return The FastItemStack.
|
||||
*/
|
||||
static FastItemStack wrap(final ItemStack itemStack) {
|
||||
static FastItemStack wrap(@Nullable final ItemStack itemStack) {
|
||||
return Eco.getHandler().createFastItemStack(Objects.requireNonNullElseGet(itemStack, () -> new ItemStack(Material.AIR)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.willfp.eco.core.integrations.afk;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Class to handle afk integrations.
|
||||
*/
|
||||
@UtilityClass
|
||||
public class AFKManager {
|
||||
/**
|
||||
* A set of all registered integrations.
|
||||
*/
|
||||
private final Set<AFKWrapper> registered = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Register a new integration.
|
||||
*
|
||||
* @param integration The integration to register.
|
||||
*/
|
||||
public void register(@NotNull final AFKWrapper integration) {
|
||||
registered.add(integration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if a player is afk.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return If afk.
|
||||
*/
|
||||
public boolean isAfk(@NotNull final Player player) {
|
||||
for (AFKWrapper afkWrapper : registered) {
|
||||
if (afkWrapper.isAfk(player)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.willfp.eco.core.integrations.afk;
|
||||
|
||||
import com.willfp.eco.core.integrations.Integration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Wrapper class for afk integrations.
|
||||
*/
|
||||
public interface AFKWrapper extends Integration {
|
||||
/**
|
||||
* Get if a player is afk.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return If afk.
|
||||
*/
|
||||
boolean isAfk(@NotNull Player player);
|
||||
}
|
||||
@@ -29,6 +29,16 @@ public class AntigriefManager {
|
||||
registered.add(antigrief);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister an AntiGrief/Land Management integration.
|
||||
*
|
||||
* @param antigrief The integration to unregister.
|
||||
*/
|
||||
public void unregister(@NotNull final AntigriefWrapper antigrief) {
|
||||
registered.removeIf(it -> it.getPluginName().equalsIgnoreCase(antigrief.getPluginName()));
|
||||
registered.remove(antigrief);
|
||||
}
|
||||
|
||||
/**
|
||||
* Can player break block.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.willfp.eco.core.integrations.economy;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Class to handle economy.
|
||||
*/
|
||||
@UtilityClass
|
||||
public class EconomyManager {
|
||||
/**
|
||||
* A set of all registered integrations.
|
||||
*/
|
||||
private final Set<EconomyWrapper> registered = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Register a new integration.
|
||||
*
|
||||
* @param integration The integration to register.
|
||||
*/
|
||||
public void register(@NotNull final EconomyWrapper integration) {
|
||||
registered.add(integration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if any economy registrations are registered.
|
||||
*
|
||||
* @return If any economy.
|
||||
*/
|
||||
public boolean hasRegistrations() {
|
||||
return !registered.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if a player has a certain amount.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param amount The amount.
|
||||
* @return If the player has the amount.
|
||||
*/
|
||||
public boolean hasAmount(@NotNull final OfflinePlayer player,
|
||||
final double amount) {
|
||||
for (EconomyWrapper wrapper : registered) {
|
||||
return wrapper.hasAmount(player, amount);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Give money to a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param amount The amount to give.
|
||||
* @return If the transaction was a success.
|
||||
*/
|
||||
public boolean giveMoney(@NotNull final OfflinePlayer player,
|
||||
final double amount) {
|
||||
for (EconomyWrapper wrapper : registered) {
|
||||
return wrapper.giveMoney(player, amount);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove money from a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param amount The amount to remove.
|
||||
* @return If the transaction was a success.
|
||||
*/
|
||||
public boolean removeMoney(@NotNull final OfflinePlayer player,
|
||||
final double amount) {
|
||||
for (EconomyWrapper wrapper : registered) {
|
||||
return wrapper.removeMoney(player, amount);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the balance of a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return The balance.
|
||||
*/
|
||||
public double getBalance(@NotNull final OfflinePlayer player) {
|
||||
for (EconomyWrapper wrapper : registered) {
|
||||
return wrapper.getBalance(player);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.willfp.eco.core.integrations.economy;
|
||||
|
||||
import com.willfp.eco.core.integrations.Integration;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Wrapper class for economy integrations.
|
||||
*/
|
||||
public interface EconomyWrapper extends Integration {
|
||||
/**
|
||||
* Get if a player has a certain amount.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param amount The amount.
|
||||
* @return If the player has the amount.
|
||||
*/
|
||||
boolean hasAmount(@NotNull OfflinePlayer player,
|
||||
double amount);
|
||||
|
||||
/**
|
||||
* Give money to a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param amount The amount to give.
|
||||
* @return If the transaction was a success.
|
||||
*/
|
||||
boolean giveMoney(@NotNull OfflinePlayer player,
|
||||
double amount);
|
||||
|
||||
/**
|
||||
* Remove money from a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param amount The amount to remove.
|
||||
* @return If the transaction was a success.
|
||||
*/
|
||||
boolean removeMoney(@NotNull OfflinePlayer player,
|
||||
double amount);
|
||||
|
||||
/**
|
||||
* Get the balance of a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return The balance.
|
||||
*/
|
||||
double getBalance(@NotNull OfflinePlayer player);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.willfp.eco.core.integrations.hologram;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Dummy hologram, created if no integrations are present on the server.
|
||||
*/
|
||||
class DummyHologram implements Hologram {
|
||||
@Override
|
||||
public void remove() {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContents(@NotNull final List<String> contents) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.willfp.eco.core.integrations.hologram;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Wrapper class for plugin-specific holograms.
|
||||
*/
|
||||
public interface Hologram {
|
||||
/**
|
||||
* Remove the hologram.
|
||||
*/
|
||||
void remove();
|
||||
|
||||
/**
|
||||
* Set the hologram contents.
|
||||
*
|
||||
* @param contents The contents.
|
||||
*/
|
||||
void setContents(@NotNull List<String> contents);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.willfp.eco.core.integrations.hologram;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
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.
|
||||
*/
|
||||
@UtilityClass
|
||||
public class HologramManager {
|
||||
/**
|
||||
* A set of all registered integrations.
|
||||
*/
|
||||
private final Set<HologramWrapper> registered = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Register a new integration.
|
||||
*
|
||||
* @param integration The integration to register.
|
||||
*/
|
||||
public void register(@NotNull final HologramWrapper integration) {
|
||||
registered.add(integration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create hologram.
|
||||
*
|
||||
* @param location The location.
|
||||
* @param contents The contents for the hologram.
|
||||
* @return The hologram.
|
||||
*/
|
||||
public Hologram createHologram(@NotNull final Location location,
|
||||
@NotNull final List<String> contents) {
|
||||
for (HologramWrapper wrapper : registered) {
|
||||
return wrapper.createHologram(location, contents);
|
||||
}
|
||||
|
||||
return new DummyHologram();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.willfp.eco.core.integrations.hologram;
|
||||
|
||||
import com.willfp.eco.core.integrations.Integration;
|
||||
import org.bukkit.Location;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Wrapper class for hologram integrations.
|
||||
*/
|
||||
public interface HologramWrapper extends Integration {
|
||||
/**
|
||||
* Create hologram.
|
||||
*
|
||||
* @param location The location.
|
||||
* @param contents The contents for the hologram.
|
||||
* @return The hologram.
|
||||
*/
|
||||
Hologram createHologram(@NotNull Location location,
|
||||
@NotNull List<String> contents);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.willfp.eco.core.integrations.mcmmo;
|
||||
|
||||
import com.willfp.eco.core.integrations.Integration;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.Event;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -7,7 +8,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* Wrapper class for mcmmo integrations.
|
||||
*/
|
||||
public interface McmmoWrapper {
|
||||
public interface McmmoWrapper extends Integration {
|
||||
/**
|
||||
* Get bonus drop count of block.
|
||||
*
|
||||
|
||||
@@ -8,9 +8,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* Class to handle placeholder integrations.
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.willfp.eco.core.integrations.shop;
|
||||
|
||||
import com.willfp.eco.core.integrations.Integration;
|
||||
|
||||
/**
|
||||
* Wrapper class for shop integrations.
|
||||
*/
|
||||
public interface ShopWrapper {
|
||||
public interface ShopWrapper extends Integration {
|
||||
/**
|
||||
* Register eco item provider for shop plugins.
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.willfp.eco.core.items;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -9,7 +11,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* A custom item has 3 components:
|
||||
* A custom item has 3 components.
|
||||
*
|
||||
* <ul>
|
||||
* <li>The key to identify it</li>
|
||||
@@ -47,6 +49,12 @@ public class CustomItem implements TestableItem {
|
||||
this.key = key;
|
||||
this.test = test;
|
||||
this.item = item;
|
||||
|
||||
Eco.getHandler().getEcoPlugin().getScheduler().runLater(() -> {
|
||||
if (!matches(getItem())) {
|
||||
Bukkit.getLogger().severe("Item with key " + key + " is invalid!");
|
||||
}
|
||||
}, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package com.willfp.eco.core.items;
|
||||
|
||||
import com.willfp.eco.core.items.args.LookupArgParser;
|
||||
import com.willfp.eco.core.items.provider.ItemProvider;
|
||||
import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
|
||||
import com.willfp.eco.core.recipe.parts.MaterialTestableItem;
|
||||
import com.willfp.eco.core.recipe.parts.ModifiedTestableItem;
|
||||
import com.willfp.eco.core.recipe.parts.TestableStack;
|
||||
import com.willfp.eco.util.NamespacedKeyUtils;
|
||||
import com.willfp.eco.util.NumberUtils;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
@@ -16,12 +18,12 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Class to manage all custom and vanilla items.
|
||||
@@ -31,7 +33,12 @@ public final class Items {
|
||||
/**
|
||||
* All recipe parts.
|
||||
*/
|
||||
private static final Map<NamespacedKey, CustomItem> REGISTRY = new ConcurrentHashMap<>();
|
||||
private static final Map<NamespacedKey, TestableItem> REGISTRY = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* All item providers.
|
||||
*/
|
||||
private static final Map<String, ItemProvider> PROVIDERS = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* All recipe parts.
|
||||
@@ -42,11 +49,20 @@ public final class Items {
|
||||
* Register a new custom item.
|
||||
*
|
||||
* @param key The key of the item.
|
||||
* @param part The item.
|
||||
* @param item The item.
|
||||
*/
|
||||
public void registerCustomItem(@NotNull final NamespacedKey key,
|
||||
@NotNull final CustomItem part) {
|
||||
REGISTRY.put(key, part);
|
||||
@NotNull final TestableItem item) {
|
||||
REGISTRY.put(key, item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new item provider.
|
||||
*
|
||||
* @param provider The provider.
|
||||
*/
|
||||
public void registerItemProvider(@NotNull final ItemProvider provider) {
|
||||
PROVIDERS.put(provider.getNamespace(), provider);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,7 +139,20 @@ public final class Items {
|
||||
}
|
||||
|
||||
if (split.length == 2) {
|
||||
CustomItem part = REGISTRY.get(NamespacedKeyUtils.create(split[0], split[1]));
|
||||
String namespace = split[0];
|
||||
String keyID = split[1];
|
||||
NamespacedKey namespacedKey = NamespacedKeyUtils.create(namespace, keyID);
|
||||
|
||||
TestableItem part = REGISTRY.get(namespacedKey);
|
||||
|
||||
if (part == null && PROVIDERS.containsKey(namespace)) {
|
||||
ItemProvider provider = PROVIDERS.get(namespace);
|
||||
item = provider.provideForKey(keyID);
|
||||
if (item instanceof EmptyTestableItem || item == null) {
|
||||
return new EmptyTestableItem();
|
||||
}
|
||||
registerCustomItem(namespacedKey, item);
|
||||
}
|
||||
|
||||
/*
|
||||
Legacy id:amount format
|
||||
@@ -146,7 +175,7 @@ public final class Items {
|
||||
This has been superseded by namespace:id amount
|
||||
*/
|
||||
if (split.length == 3) {
|
||||
CustomItem part = REGISTRY.get(NamespacedKeyUtils.create(split[0], split[1]));
|
||||
TestableItem part = REGISTRY.get(NamespacedKeyUtils.create(split[0], split[1]));
|
||||
if (part == null) {
|
||||
return new EmptyTestableItem();
|
||||
}
|
||||
@@ -178,8 +207,11 @@ public final class Items {
|
||||
List<Predicate<ItemStack>> predicates = new ArrayList<>();
|
||||
|
||||
for (LookupArgParser argParser : ARG_PARSERS) {
|
||||
Predicate<ItemStack> predicate = argParser.parseArguments(modifierArgs, meta);
|
||||
if (predicate != null) {
|
||||
predicates.add(argParser.parseArguments(modifierArgs, meta));
|
||||
}
|
||||
}
|
||||
|
||||
example.setItemMeta(meta);
|
||||
if (!predicates.isEmpty()) {
|
||||
@@ -212,7 +244,7 @@ public final class Items {
|
||||
* @return If is recipe.
|
||||
*/
|
||||
public boolean isCustomItem(@NotNull final ItemStack itemStack) {
|
||||
for (CustomItem item : REGISTRY.values()) {
|
||||
for (TestableItem item : REGISTRY.values()) {
|
||||
if (item.matches(itemStack)) {
|
||||
return true;
|
||||
}
|
||||
@@ -228,9 +260,9 @@ public final class Items {
|
||||
*/
|
||||
@Nullable
|
||||
public CustomItem getCustomItem(@NotNull final ItemStack itemStack) {
|
||||
for (CustomItem item : REGISTRY.values()) {
|
||||
for (TestableItem item : REGISTRY.values()) {
|
||||
if (item.matches(itemStack)) {
|
||||
return item;
|
||||
return getOrWrap(item);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -242,6 +274,27 @@ public final class Items {
|
||||
* @return A set of all items.
|
||||
*/
|
||||
public Set<CustomItem> getCustomItems() {
|
||||
return new HashSet<>(REGISTRY.values());
|
||||
return REGISTRY.values().stream().map(Items::getOrWrap).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a CustomItem instance for a given TestableItem.
|
||||
* <p>
|
||||
* Used internally since 6.10.0 when the registration moved from {@link CustomItem}
|
||||
* to {@link TestableItem} for added flexibility.
|
||||
*
|
||||
* @param item The item.
|
||||
* @return The CustomItem.
|
||||
*/
|
||||
public CustomItem getOrWrap(@NotNull final TestableItem item) {
|
||||
if (item instanceof CustomItem) {
|
||||
return (CustomItem) item;
|
||||
} else {
|
||||
return new CustomItem(
|
||||
NamespacedKeyUtils.createEcoKey("wrapped_" + NumberUtils.randInt(0, 100000)),
|
||||
item::matches,
|
||||
item.getItem()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -16,7 +17,7 @@ import java.util.function.Predicate;
|
||||
*/
|
||||
public class EnchantmentArgParser implements LookupArgParser {
|
||||
@Override
|
||||
public Predicate<ItemStack> parseArguments(@NotNull final String[] args,
|
||||
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
|
||||
@NotNull final ItemMeta meta) {
|
||||
Map<Enchantment, Integer> requiredEnchantments = new HashMap<>();
|
||||
|
||||
@@ -37,6 +38,10 @@ public class EnchantmentArgParser implements LookupArgParser {
|
||||
requiredEnchantments.put(enchantment, level);
|
||||
}
|
||||
|
||||
if (requiredEnchantments.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (meta instanceof EnchantmentStorageMeta storageMeta) {
|
||||
requiredEnchantments.forEach((enchantment, integer) -> storageMeta.addStoredEnchant(enchantment, integer, true));
|
||||
} else {
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.willfp.eco.core.items.TestableItem;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@@ -19,6 +20,6 @@ public interface LookupArgParser {
|
||||
* @param meta The ItemMeta to modify.
|
||||
* @return The predicate test to apply to the modified item.
|
||||
*/
|
||||
Predicate<ItemStack> parseArguments(@NotNull String[] args,
|
||||
@Nullable Predicate<ItemStack> parseArguments(@NotNull String[] args,
|
||||
@NotNull ItemMeta meta);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@@ -13,7 +14,7 @@ import java.util.function.Predicate;
|
||||
*/
|
||||
public class TextureArgParser implements LookupArgParser {
|
||||
@Override
|
||||
public Predicate<ItemStack> parseArguments(@NotNull final String[] args,
|
||||
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
|
||||
@NotNull final ItemMeta meta) {
|
||||
String skullTexture = null;
|
||||
|
||||
@@ -34,6 +35,10 @@ public class TextureArgParser implements LookupArgParser {
|
||||
SkullUtils.setSkullTexture(skullMeta, skullTexture);
|
||||
}
|
||||
|
||||
if (skullTexture == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String finalSkullTexture = skullTexture;
|
||||
return test -> {
|
||||
if (!test.hasItemMeta()) {
|
||||
@@ -44,7 +49,7 @@ public class TextureArgParser implements LookupArgParser {
|
||||
|
||||
assert testMeta != null;
|
||||
|
||||
if (testMeta instanceof SkullMeta skullMeta && finalSkullTexture != null) {
|
||||
if (testMeta instanceof SkullMeta skullMeta) {
|
||||
return finalSkullTexture.equalsIgnoreCase(SkullUtils.getSkullTexture(skullMeta));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.willfp.eco.core.items.provider;
|
||||
|
||||
import com.willfp.eco.core.items.TestableItem;
|
||||
import lombok.Getter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Item providers are call-site registrations for items. In other words,
|
||||
* they only register their items when a request is made. This is marginally
|
||||
* slower, however it is required for certain plugins, and fixes bugs related to
|
||||
* loading orders.
|
||||
*
|
||||
* @see TestableItem
|
||||
*/
|
||||
public abstract class ItemProvider {
|
||||
/**
|
||||
* The namespace.
|
||||
*/
|
||||
@Getter
|
||||
private final String namespace;
|
||||
|
||||
/**
|
||||
* Create a new ItemProvider for a specific namespace.
|
||||
*
|
||||
* @param namespace The namespace.
|
||||
*/
|
||||
protected ItemProvider(@NotNull final String namespace) {
|
||||
this.namespace = namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a TestableItem for a given key.
|
||||
*
|
||||
* @param key The item ID.
|
||||
* @return The TestableItem, or null if not found.
|
||||
*/
|
||||
@Nullable
|
||||
public abstract TestableItem provideForKey(@NotNull String key);
|
||||
}
|
||||
@@ -82,6 +82,10 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
|
||||
ShapedRecipe shapedRecipe = new ShapedRecipe(this.getKey(), this.getOutput());
|
||||
shapedRecipe.shape("012", "345", "678");
|
||||
for (int i = 0; i < 9; i++) {
|
||||
if (parts.get(i) instanceof EmptyTestableItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
char character = String.valueOf(i).toCharArray()[0];
|
||||
shapedRecipe.setIngredient(character, parts.get(i).getItem().getType());
|
||||
}
|
||||
@@ -89,6 +93,10 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
|
||||
ShapedRecipe displayedRecipe = new ShapedRecipe(this.getDisplayedKey(), this.getOutput());
|
||||
displayedRecipe.shape("012", "345", "678");
|
||||
for (int i = 0; i < 9; i++) {
|
||||
if (parts.get(i) instanceof EmptyTestableItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
char character = String.valueOf(i).toCharArray()[0];
|
||||
ItemStack item = parts.get(i).getItem();
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.willfp.eco.core.requirement;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A requirement is a defined goal that a player must meet.
|
||||
*/
|
||||
public abstract class Requirement {
|
||||
/**
|
||||
* Create a new requirement.
|
||||
*/
|
||||
protected Requirement() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the player meets the requirement.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param args The arguments.
|
||||
* @return The requirement.
|
||||
*/
|
||||
public abstract boolean doesPlayerMeet(@NotNull Player player,
|
||||
@NotNull List<String> args);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.willfp.eco.core.requirement;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Interface for internal requirement factory implementations.
|
||||
*/
|
||||
public interface RequirementFactory {
|
||||
/**
|
||||
* Create a requirement.
|
||||
*
|
||||
* @param name The name.
|
||||
* @return The requirement returned for the name.
|
||||
* Will return a requirement that is always true if not found.
|
||||
*/
|
||||
Requirement create(@NotNull String name);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.willfp.eco.core.requirement;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Contains methods and fields pertaining to requirements.
|
||||
*/
|
||||
@UtilityClass
|
||||
public class Requirements {
|
||||
/**
|
||||
* Requires a player to have a permission.
|
||||
*/
|
||||
public static final Requirement HAS_PERMISSION = Eco.getHandler().getRequirementFactory().create("has-permission");
|
||||
|
||||
/**
|
||||
* Placeholder equals value.
|
||||
*/
|
||||
public static final Requirement PLACEHOLDER_EQUALS = Eco.getHandler().getRequirementFactory().create("placeholder-equals");
|
||||
|
||||
/**
|
||||
* Numeric placeholder greater than value.
|
||||
*/
|
||||
public static final Requirement PLACEHOLDER_GREATER_THAN = Eco.getHandler().getRequirementFactory().create("placeholder-greater-than");
|
||||
|
||||
/**
|
||||
* Numeric placeholder less than value.
|
||||
*/
|
||||
public static final Requirement PLACEHOLDER_LESS_THAN = Eco.getHandler().getRequirementFactory().create("placeholder-less-than");
|
||||
|
||||
/**
|
||||
* Get Requirements matching ID.
|
||||
*
|
||||
* @param name The ID to search for.
|
||||
* @return The matching Requirements.
|
||||
*/
|
||||
public static Requirement getByID(@NotNull final String name) {
|
||||
return Eco.getHandler().getRequirementFactory().create(name);
|
||||
}
|
||||
}
|
||||
@@ -38,4 +38,26 @@ public class Pair<A, B> {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
/**
|
||||
* component1 exists to allow a pair to be destructured by kotlin.
|
||||
* The default kotlin pair already has this, however there is no default
|
||||
* pair in java so this exists for parity.
|
||||
*
|
||||
* @return First.
|
||||
*/
|
||||
public A component1() {
|
||||
return first;
|
||||
}
|
||||
|
||||
/**
|
||||
* component2 exists to allow a pair to be destructured by kotlin.
|
||||
* The default kotlin pair already has this, however there is no default
|
||||
* pair in java so this exists for parity.
|
||||
*
|
||||
* @return First.
|
||||
*/
|
||||
public B component2() {
|
||||
return second;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,4 +34,15 @@ public class Triplet<A, B, C> extends Pair<A, B> {
|
||||
|
||||
this.third = third;
|
||||
}
|
||||
|
||||
/**
|
||||
* component3 exists to allow a pair to be destructured by kotlin.
|
||||
* The default kotlin pair already has this, however there is no default
|
||||
* pair in java so this exists for parity.
|
||||
*
|
||||
* @return First.
|
||||
*/
|
||||
public C component3() {
|
||||
return third;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.willfp.eco.core.Eco;
|
||||
import lombok.Getter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -11,7 +12,6 @@ import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@@ -40,45 +40,42 @@ public class Paste {
|
||||
* <p>
|
||||
* Runs asynchronously to avoid hangups.
|
||||
*
|
||||
* @param responseHandler The consumer to accept the response token.
|
||||
* @param callback The consumer to accept the response token.
|
||||
*/
|
||||
public void getHastebinToken(@NotNull final Consumer<String> responseHandler) {
|
||||
public void getHastebinToken(@NotNull final Consumer<String> callback) {
|
||||
Eco.getHandler().getEcoPlugin().getScheduler().runAsync(() -> {
|
||||
try {
|
||||
String url = "https://hastebin.com/documents";
|
||||
URL obj = new URL(url);
|
||||
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
|
||||
byte[] postData = contents.getBytes(StandardCharsets.UTF_8);
|
||||
int postDataLength = postData.length;
|
||||
|
||||
con.setRequestMethod("POST");
|
||||
con.setRequestProperty("Content-Type", "application/json");
|
||||
String requestURL = "https://hastebin.com/documents";
|
||||
URL url = new URL(requestURL);
|
||||
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
|
||||
conn.setDoOutput(true);
|
||||
conn.setInstanceFollowRedirects(false);
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setRequestProperty("User-Agent", "eco-Hastebin");
|
||||
conn.setRequestProperty("Content-Length", Integer.toString(postDataLength));
|
||||
conn.setUseCaches(false);
|
||||
|
||||
con.setDoOutput(true);
|
||||
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
|
||||
wr.writeBytes(URLEncoder.encode(contents, StandardCharsets.UTF_8));
|
||||
wr.flush();
|
||||
wr.close();
|
||||
String response;
|
||||
DataOutputStream wr;
|
||||
|
||||
BufferedReader iny = new BufferedReader(
|
||||
new InputStreamReader(con.getInputStream()));
|
||||
String output;
|
||||
StringBuilder responseBuilder = new StringBuilder();
|
||||
wr = new DataOutputStream(conn.getOutputStream());
|
||||
wr.write(postData);
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
response = reader.readLine();
|
||||
|
||||
while ((output = iny.readLine()) != null) {
|
||||
responseBuilder.append(output);
|
||||
assert response != null;
|
||||
|
||||
if (response.contains("\"key\"")) {
|
||||
response = response.substring(response.indexOf(":") + 2, response.length() - 2);
|
||||
|
||||
callback.accept(response);
|
||||
}
|
||||
iny.close();
|
||||
|
||||
String responseString = responseBuilder.toString();
|
||||
|
||||
responseString = responseString.replace("{\"key\":\"", "");
|
||||
responseString = responseString.replace("\"}", "");
|
||||
|
||||
responseHandler.accept(responseString);
|
||||
} catch (IOException e) {
|
||||
responseHandler.accept(e.getMessage());
|
||||
callback.accept(e.getMessage());
|
||||
}
|
||||
|
||||
responseHandler.accept("");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -26,16 +26,18 @@ public class UpdateChecker extends PluginDependent<EcoPlugin> {
|
||||
/**
|
||||
* Get the latest version of the plugin.
|
||||
*
|
||||
* @param consumer The process to run after checking.
|
||||
* @param callback The process to run after checking.
|
||||
*/
|
||||
public void getVersion(@NotNull final Consumer<? super String> consumer) {
|
||||
public void getVersion(@NotNull final Consumer<? super String> callback) {
|
||||
this.getPlugin().getScheduler().runAsync(() -> {
|
||||
try {
|
||||
InputStream inputStream = new URL("https://api.spigotmc.org/legacy/update.php?resource=" + this.getPlugin().getResourceId()).openStream();
|
||||
InputStream inputStream = new URL(
|
||||
"https://api.polymart.org/v1/getResourceInfoSimple?key=version&resource_id=" + this.getPlugin().getResourceId()
|
||||
).openStream();
|
||||
Scanner scanner = new Scanner(inputStream);
|
||||
|
||||
if (scanner.hasNext()) {
|
||||
consumer.accept(scanner.next());
|
||||
callback.accept(scanner.next());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
this.getPlugin().getLogger().warning("Failed to check for updates: " + e.getMessage());
|
||||
|
||||
@@ -2,12 +2,14 @@ package com.willfp.eco.util;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.apache.commons.lang.Validate;
|
||||
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.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -92,6 +94,21 @@ public class BlockUtils {
|
||||
blockBreakConsumer.accept(player, block);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if a block was placed by a player.
|
||||
*
|
||||
* @param block The block.
|
||||
* @return If placed by a player.
|
||||
*/
|
||||
public boolean isPlayerPlaced(@NotNull final Block block) {
|
||||
Chunk chunk = block.getChunk();
|
||||
|
||||
return chunk.getPersistentDataContainer().has(
|
||||
NamespacedKeyUtils.createEcoKey(Integer.toString(block.getLocation().hashCode(), 16)),
|
||||
PersistentDataType.INTEGER
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the block break function.
|
||||
*
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.willfp.eco.util;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -10,18 +11,37 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
@UtilityClass
|
||||
public class LightningUtils {
|
||||
|
||||
/**
|
||||
* Strike lightning on player without fire.
|
||||
*
|
||||
* @param victim The entity to smite.
|
||||
* @param damage The damage to deal.
|
||||
* @param silent If the lightning sound should be played locally
|
||||
*/
|
||||
public void strike(@NotNull final LivingEntity victim,
|
||||
final double damage,
|
||||
final boolean silent) {
|
||||
Location loc = victim.getLocation();
|
||||
|
||||
if (silent) {
|
||||
victim.getWorld().spigot().strikeLightningEffect(loc, true);
|
||||
victim.getWorld().playSound(loc, Sound.ENTITY_LIGHTNING_BOLT_IMPACT, 1, 1);
|
||||
} else {
|
||||
victim.getWorld().strikeLightningEffect(loc);
|
||||
}
|
||||
|
||||
victim.damage(damage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strike lightning on a victim without fire.
|
||||
*
|
||||
* @param victim The entity to smite.
|
||||
* @param damage The damage to deal.
|
||||
*/
|
||||
public void strike(@NotNull final LivingEntity victim,
|
||||
final double damage) {
|
||||
Location loc = victim.getLocation();
|
||||
|
||||
victim.getWorld().strikeLightningEffect(loc);
|
||||
|
||||
victim.damage(damage);
|
||||
strike(victim, damage, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,9 @@ 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;
|
||||
|
||||
/**
|
||||
* Utilities / API methods for lists.
|
||||
@@ -21,7 +23,7 @@ public class ListUtils {
|
||||
* @return The list, filled will null objects.
|
||||
*/
|
||||
@NotNull
|
||||
public <@Nullable T> List<List<T>> create2DList(final int rows,
|
||||
public static <@Nullable T> List<List<T>> create2DList(final int rows,
|
||||
final int columns) {
|
||||
List<List<T>> list = new ArrayList<>(rows);
|
||||
while (list.size() < rows) {
|
||||
@@ -34,4 +36,25 @@ public class ListUtils {
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a list potentially containing duplicates to a map where the value is the frequency of the key.
|
||||
*
|
||||
* @param list The list.
|
||||
* @param <T> The type parameter of the list.
|
||||
* @return The frequency map.
|
||||
*/
|
||||
@NotNull
|
||||
public static <T> Map<T, Integer> listToFrequencyMap(@NotNull final List<T> list) {
|
||||
Map<T, Integer> frequencyMap = new HashMap<>();
|
||||
for (T object : list) {
|
||||
if (frequencyMap.containsKey(object)) {
|
||||
frequencyMap.put(object, frequencyMap.get(object) + 1);
|
||||
} else {
|
||||
frequencyMap.put(object, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return frequencyMap;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.willfp.eco.util;
|
||||
|
||||
import lombok.experimental.NonFinal;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
105
eco-api/src/main/java/com/willfp/eco/util/PlayerUtils.java
Normal file
105
eco-api/src/main/java/com/willfp/eco/util/PlayerUtils.java
Normal file
@@ -0,0 +1,105 @@
|
||||
package com.willfp.eco.util;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.Prerequisite;
|
||||
import com.willfp.eco.core.data.PlayerProfile;
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey;
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKeyType;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Utilities / API methods for players.
|
||||
*/
|
||||
@UtilityClass
|
||||
public class PlayerUtils {
|
||||
/**
|
||||
* The data key for saved player names.
|
||||
*/
|
||||
private static final PersistentDataKey<String> PLAYER_NAME_KEY = new PersistentDataKey<>(
|
||||
NamespacedKeyUtils.createEcoKey("player_name"),
|
||||
PersistentDataKeyType.STRING,
|
||||
"Unknown Player"
|
||||
);
|
||||
|
||||
/**
|
||||
* Get the audience from a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return The audience.
|
||||
*/
|
||||
@NotNull
|
||||
public Audience getAudience(@NotNull final Player player) {
|
||||
BukkitAudiences adventure = Eco.getHandler().getAdventure();
|
||||
|
||||
if (Prerequisite.HAS_PAPER.isMet()) {
|
||||
if (player instanceof Audience) {
|
||||
return (Audience) player;
|
||||
} else {
|
||||
return Audience.empty();
|
||||
}
|
||||
} else {
|
||||
if (adventure == null) {
|
||||
return Audience.empty();
|
||||
} else {
|
||||
return adventure.player(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the audience from a command sender.
|
||||
*
|
||||
* @param sender The command sender.
|
||||
* @return The audience.
|
||||
*/
|
||||
@NotNull
|
||||
public Audience getAudience(@NotNull final CommandSender sender) {
|
||||
BukkitAudiences adventure = Eco.getHandler().getAdventure();
|
||||
|
||||
if (Prerequisite.HAS_PAPER.isMet()) {
|
||||
if (sender instanceof Audience) {
|
||||
return (Audience) sender;
|
||||
} else {
|
||||
return Audience.empty();
|
||||
}
|
||||
} else {
|
||||
if (adventure == null) {
|
||||
return Audience.empty();
|
||||
} else {
|
||||
return adventure.sender(sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get saved display name for an offline player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return The player name.
|
||||
*/
|
||||
public String getSavedDisplayName(@NotNull final OfflinePlayer player) {
|
||||
PlayerProfile profile = PlayerProfile.load(player);
|
||||
|
||||
if (player instanceof Player onlinePlayer) {
|
||||
profile.write(PLAYER_NAME_KEY, onlinePlayer.getDisplayName());
|
||||
}
|
||||
|
||||
return profile.read(PLAYER_NAME_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the saved display name for a player.
|
||||
*
|
||||
* @param player The player.
|
||||
*/
|
||||
public void updateSavedDisplayName(@NotNull final Player player) {
|
||||
PlayerProfile profile = PlayerProfile.load(player);
|
||||
profile.write(PLAYER_NAME_KEY, player.getDisplayName());
|
||||
}
|
||||
}
|
||||
47
eco-api/src/main/java/com/willfp/eco/util/PotionUtils.java
Normal file
47
eco-api/src/main/java/com/willfp/eco/util/PotionUtils.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package com.willfp.eco.util;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.potion.PotionData;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Utilities / API methods for potions.
|
||||
*/
|
||||
@UtilityClass
|
||||
public class PotionUtils {
|
||||
/**
|
||||
* Get the duration (in ticks) for potion data.
|
||||
*
|
||||
* @param data The data.
|
||||
* @return The duration.
|
||||
*/
|
||||
public int getDuration(@NotNull final PotionData data) {
|
||||
if (data.isExtended()) {
|
||||
return switch (data.getType()) {
|
||||
case INSTANT_DAMAGE, INSTANT_HEAL: yield 0;
|
||||
case POISON, REGEN: yield 1800;
|
||||
case SLOW_FALLING, WEAKNESS, SLOWNESS: yield 4800;
|
||||
case TURTLE_MASTER: yield 800;
|
||||
default: yield 9600;
|
||||
};
|
||||
}
|
||||
|
||||
if (data.isUpgraded()) {
|
||||
return switch (data.getType()) {
|
||||
case INSTANT_DAMAGE, INSTANT_HEAL: yield 0;
|
||||
case POISON, REGEN: yield 420;
|
||||
case SLOW_FALLING, WEAKNESS, SLOWNESS: yield 440;
|
||||
case TURTLE_MASTER: yield 400;
|
||||
default: yield 1800;
|
||||
};
|
||||
}
|
||||
|
||||
return switch (data.getType()) {
|
||||
case INSTANT_DAMAGE, INSTANT_HEAL: yield 0;
|
||||
case POISON, REGEN: yield 900;
|
||||
case SLOW_FALLING, WEAKNESS, SLOWNESS: yield 400;
|
||||
case TURTLE_MASTER: yield 1800;
|
||||
default: yield 3600;
|
||||
};
|
||||
}
|
||||
}
|
||||
48
eco-api/src/main/java/com/willfp/eco/util/ServerUtils.java
Normal file
48
eco-api/src/main/java/com/willfp/eco/util/ServerUtils.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package com.willfp.eco.util;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Utilities / API methods for the server.
|
||||
*/
|
||||
@UtilityClass
|
||||
public class ServerUtils {
|
||||
/**
|
||||
* The TPS supplier.
|
||||
*/
|
||||
private Supplier<Double> tpsSupplier = null;
|
||||
|
||||
/**
|
||||
* Get the current server TPS.
|
||||
*
|
||||
* @return The TPS.
|
||||
*/
|
||||
public double getTps() {
|
||||
Validate.notNull(tpsSupplier, "Not initialized!");
|
||||
|
||||
double tps = tpsSupplier.get();
|
||||
|
||||
if (tps > 20) {
|
||||
return 20;
|
||||
} else {
|
||||
return tps;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the tps supplier function.
|
||||
*
|
||||
* @param function The function.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public void initialize(@NotNull final Supplier<Double> function) {
|
||||
Validate.isTrue(tpsSupplier == null, "Already initialized!");
|
||||
|
||||
tpsSupplier = function;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,14 @@
|
||||
package com.willfp.eco.util;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.willfp.eco.core.Prerequisite;
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.TextDecoration;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.markdown.DiscordFlavor;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
@@ -16,11 +20,17 @@ import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static net.md_5.bungee.api.ChatColor.BOLD;
|
||||
import static net.md_5.bungee.api.ChatColor.COLOR_CHAR;
|
||||
import static net.md_5.bungee.api.ChatColor.ITALIC;
|
||||
import static net.md_5.bungee.api.ChatColor.MAGIC;
|
||||
import static net.md_5.bungee.api.ChatColor.STRIKETHROUGH;
|
||||
import static net.md_5.bungee.api.ChatColor.UNDERLINE;
|
||||
|
||||
/**
|
||||
* Utilities / API methods for strings.
|
||||
@@ -34,6 +44,8 @@ public class StringUtils {
|
||||
.add(Pattern.compile("<GRADIENT:([0-9A-Fa-f]{6})>(.*?)</GRADIENT:([0-9A-Fa-f]{6})>", Pattern.CASE_INSENSITIVE))
|
||||
.add(Pattern.compile("<GRADIENT:#([0-9A-Fa-f]{6})>(.*?)</GRADIENT:#([0-9A-Fa-f]{6})>", Pattern.CASE_INSENSITIVE))
|
||||
.add(Pattern.compile("<G:([0-9A-Fa-f]{6})>(.*?)</G:([0-9A-Fa-f]{6})>", Pattern.CASE_INSENSITIVE))
|
||||
.add(Pattern.compile("<G:#([0-9A-Fa-f]{6})>(.*?)</G:#([0-9A-Fa-f]{6})>", Pattern.CASE_INSENSITIVE))
|
||||
.add(Pattern.compile("<G#([0-9A-Fa-f]{6})>(.*?)</G#([0-9A-Fa-f]{6})>", Pattern.CASE_INSENSITIVE))
|
||||
.add(Pattern.compile("<#:([0-9A-Fa-f]{6})>(.*?)</#:([0-9A-Fa-f]{6})>"))
|
||||
.add(Pattern.compile("\\{#:([0-9A-Fa-f]{6})}(.*?)\\{/#:([0-9A-Fa-f]{6})}"))
|
||||
.build();
|
||||
@@ -56,6 +68,22 @@ public class StringUtils {
|
||||
.hexColors()
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Color map.
|
||||
*/
|
||||
private static final Map<String, ChatColor> COLOR_MAP = new ImmutableMap.Builder<String, ChatColor>()
|
||||
.put("&l", BOLD)
|
||||
.put("&o", ITALIC)
|
||||
.put("&n", UNDERLINE)
|
||||
.put("&m", STRIKETHROUGH)
|
||||
.put("&k", MAGIC)
|
||||
.put("§l", BOLD)
|
||||
.put("§o", ITALIC)
|
||||
.put("§n", UNDERLINE)
|
||||
.put("§m", STRIKETHROUGH)
|
||||
.put("§k", MAGIC)
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Format a list of strings.
|
||||
* <p>
|
||||
@@ -166,6 +194,68 @@ public class StringUtils {
|
||||
return format(message, null, option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a string to a component.
|
||||
* <p>
|
||||
* Converts color codes and placeholders.
|
||||
*
|
||||
* @param message The message to translate.
|
||||
* @return The message, formatted, as a component.
|
||||
* @see StringUtils#format(String, Player)
|
||||
*/
|
||||
@NotNull
|
||||
public Component formatToComponent(@NotNull final String message) {
|
||||
return formatToComponent(message, (Player) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a string.
|
||||
* <p>
|
||||
* Converts color codes and placeholders for a player.
|
||||
*
|
||||
* @param message The message to format.
|
||||
* @param player The player to translate placeholders with respect to.
|
||||
* @return The message, formatted.
|
||||
*/
|
||||
@NotNull
|
||||
public Component formatToComponent(@NotNull final String message,
|
||||
@Nullable final Player player) {
|
||||
return formatToComponent(message, player, FormatOption.WITH_PLACEHOLDERS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a string to a component.
|
||||
* <p>
|
||||
* Converts color codes and placeholders if specified.
|
||||
*
|
||||
* @param message The message to translate.
|
||||
* @param option The format option.
|
||||
* @return The message, formatted, as a component.
|
||||
* @see StringUtils#format(String, Player)
|
||||
*/
|
||||
@NotNull
|
||||
public Component formatToComponent(@NotNull final String message,
|
||||
@NotNull final FormatOption option) {
|
||||
return formatToComponent(message, null, option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a string to a component.
|
||||
* <p>
|
||||
* Coverts color codes and placeholders for a player if specified.
|
||||
*
|
||||
* @param message The message to format.
|
||||
* @param player The player to translate placeholders with respect to.
|
||||
* @param option The format options.
|
||||
* @return The message, formatted, as a component.
|
||||
*/
|
||||
@NotNull
|
||||
public Component formatToComponent(@NotNull final String message,
|
||||
@Nullable final Player player,
|
||||
@NotNull final FormatOption option) {
|
||||
return toComponent(format(message, player, option));
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a string.
|
||||
* <p>
|
||||
@@ -181,15 +271,22 @@ public class StringUtils {
|
||||
@Nullable final Player player,
|
||||
@NotNull final FormatOption option) {
|
||||
String processedMessage = message;
|
||||
processedMessage = translateGradients(processedMessage);
|
||||
if (option == FormatOption.WITH_PLACEHOLDERS) {
|
||||
processedMessage = PlaceholderManager.translatePlaceholders(processedMessage, player);
|
||||
}
|
||||
processedMessage = translateHexColorCodes(processedMessage);
|
||||
processedMessage = ChatColor.translateAlternateColorCodes('&', processedMessage);
|
||||
processedMessage = translateGradients(processedMessage);
|
||||
processedMessage = translateHexColorCodes(processedMessage);
|
||||
if (Prerequisite.HAS_PAPER.isMet()) {
|
||||
processedMessage = translateMiniMessage(processedMessage);
|
||||
}
|
||||
return processedMessage;
|
||||
}
|
||||
|
||||
private static String translateMiniMessage(@NotNull final String message) {
|
||||
return LEGACY_COMPONENT_SERIALIZER.serialize(MiniMessage.withMarkdownFlavor(DiscordFlavor.get()).parse(message));
|
||||
}
|
||||
|
||||
private static String translateHexColorCodes(@NotNull final String message) {
|
||||
String processedMessage = message;
|
||||
for (Pattern pattern : HEX_PATTERNS) {
|
||||
@@ -219,26 +316,12 @@ public class StringUtils {
|
||||
@NotNull final Color end) {
|
||||
String processedString = string;
|
||||
List<ChatColor> modifiers = new ArrayList<>();
|
||||
if (processedString.contains("&l")) {
|
||||
modifiers.add(ChatColor.BOLD);
|
||||
for (Map.Entry<String, ChatColor> entry : COLOR_MAP.entrySet()) {
|
||||
if (processedString.contains(entry.getKey())) {
|
||||
modifiers.add(entry.getValue());
|
||||
}
|
||||
if (processedString.contains("&o")) {
|
||||
modifiers.add(ChatColor.ITALIC);
|
||||
processedString = processedString.replace(entry.getKey(), "");
|
||||
}
|
||||
if (processedString.contains("&n")) {
|
||||
modifiers.add(ChatColor.UNDERLINE);
|
||||
}
|
||||
if (processedString.contains("&m")) {
|
||||
modifiers.add(ChatColor.STRIKETHROUGH);
|
||||
}
|
||||
if (processedString.contains("&k")) {
|
||||
modifiers.add(ChatColor.MAGIC);
|
||||
}
|
||||
processedString = processedString.replace("&l", "");
|
||||
processedString = processedString.replace("&o", "");
|
||||
processedString = processedString.replace("&n", "");
|
||||
processedString = processedString.replace("&k", "");
|
||||
processedString = processedString.replace("&m", "");
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
ChatColor[] colors = getGradientColors(start, end, processedString.length());
|
||||
@@ -255,6 +338,9 @@ public class StringUtils {
|
||||
@NotNull final Color end,
|
||||
final int step) {
|
||||
ChatColor[] colors = new ChatColor[step];
|
||||
if (step <= 1) {
|
||||
return colors;
|
||||
}
|
||||
int stepR = Math.abs(start.getRed() - end.getRed()) / (step - 1);
|
||||
int stepG = Math.abs(start.getGreen() - end.getGreen()) / (step - 1);
|
||||
int stepB = Math.abs(start.getBlue() - end.getBlue()) / (step - 1);
|
||||
@@ -334,10 +420,14 @@ public class StringUtils {
|
||||
* @return The JSON String.
|
||||
*/
|
||||
@NotNull
|
||||
public String legacyToJson(@NotNull final String legacy) {
|
||||
public String legacyToJson(@Nullable final String legacy) {
|
||||
String processed = legacy;
|
||||
if (legacy == null) {
|
||||
processed = "";
|
||||
}
|
||||
return GsonComponentSerializer.gson().serialize(
|
||||
Component.empty().decoration(TextDecoration.ITALIC, false).append(
|
||||
LEGACY_COMPONENT_SERIALIZER.deserialize(legacy)
|
||||
LEGACY_COMPONENT_SERIALIZER.deserialize(processed)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -355,6 +445,33 @@ public class StringUtils {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert legacy (bukkit) text to Component.
|
||||
*
|
||||
* @param legacy The legacy text.
|
||||
* @return The component.
|
||||
*/
|
||||
@NotNull
|
||||
public Component toComponent(@Nullable final String legacy) {
|
||||
String processed = legacy;
|
||||
if (legacy == null) {
|
||||
processed = "";
|
||||
}
|
||||
|
||||
return LEGACY_COMPONENT_SERIALIZER.deserialize(processed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Component to legacy (bukkit) text.
|
||||
*
|
||||
* @param component The component.
|
||||
* @return The legacy text.
|
||||
*/
|
||||
@NotNull
|
||||
public String toLegacy(@NotNull final Component component) {
|
||||
return LEGACY_COMPONENT_SERIALIZER.serialize(component);
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for formatting.
|
||||
*/
|
||||
|
||||
@@ -4,7 +4,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21"
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,14 @@ subprojects {
|
||||
|
||||
dependencies {
|
||||
compileOnly project(":eco-api")
|
||||
compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:1.5.21'
|
||||
compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:1.5.31'
|
||||
}
|
||||
|
||||
compileKotlin {
|
||||
kotlinOptions {
|
||||
jvmTarget = "16"
|
||||
}
|
||||
targetCompatibility = JavaVersion.VERSION_16
|
||||
sourceCompatibility = JavaVersion.VERSION_16
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,10 @@ group 'com.willfp'
|
||||
version rootProject.version
|
||||
|
||||
dependencies {
|
||||
compileOnly 'org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT'
|
||||
compileOnly 'me.clip:placeholderapi:2.10.9'
|
||||
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
|
||||
compileOnly 'me.clip:placeholderapi:2.10.10'
|
||||
compileOnly 'org.reflections:reflections:0.9.12'
|
||||
compileOnly 'net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT'
|
||||
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
|
||||
compileOnly 'com.google.guava:guava:31.0.1-jre'
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
package com.willfp.eco.internal.config
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.PluginLike
|
||||
import com.willfp.eco.core.config.interfaces.Config
|
||||
import com.willfp.eco.core.config.interfaces.JSONConfig
|
||||
import com.willfp.eco.core.config.wrapper.ConfigFactory
|
||||
import com.willfp.eco.internal.config.json.EcoJSONConfigSection
|
||||
import com.willfp.eco.internal.config.json.EcoLoadableJSONConfig
|
||||
import com.willfp.eco.internal.config.json.EcoUpdatableJSONConfig
|
||||
import com.willfp.eco.internal.config.yaml.EcoLoadableYamlConfig
|
||||
import com.willfp.eco.internal.config.yaml.EcoUpdatableYamlConfig
|
||||
import com.willfp.eco.internal.config.yaml.EcoYamlConfigSection
|
||||
@@ -14,7 +15,7 @@ import org.bukkit.configuration.file.YamlConfiguration
|
||||
class EcoConfigFactory : ConfigFactory {
|
||||
override fun createUpdatableYamlConfig(
|
||||
configName: String,
|
||||
plugin: EcoPlugin,
|
||||
plugin: PluginLike,
|
||||
subDirectoryPath: String,
|
||||
source: Class<*>,
|
||||
removeUnused: Boolean,
|
||||
@@ -30,9 +31,27 @@ class EcoConfigFactory : ConfigFactory {
|
||||
)
|
||||
}
|
||||
|
||||
override fun createUpdatableJSONConfig(
|
||||
configName: String,
|
||||
plugin: PluginLike,
|
||||
subDirectoryPath: String,
|
||||
source: Class<*>,
|
||||
removeUnused: Boolean,
|
||||
vararg updateBlacklist: String
|
||||
): JSONConfig {
|
||||
return EcoUpdatableJSONConfig(
|
||||
configName,
|
||||
plugin,
|
||||
subDirectoryPath,
|
||||
source,
|
||||
removeUnused,
|
||||
*updateBlacklist
|
||||
)
|
||||
}
|
||||
|
||||
override fun createLoadableJSONConfig(
|
||||
configName: String,
|
||||
plugin: EcoPlugin,
|
||||
plugin: PluginLike,
|
||||
subDirectoryPath: String,
|
||||
source: Class<*>
|
||||
): JSONConfig {
|
||||
@@ -46,7 +65,7 @@ class EcoConfigFactory : ConfigFactory {
|
||||
|
||||
override fun createLoadableYamlConfig(
|
||||
configName: String,
|
||||
plugin: EcoPlugin,
|
||||
plugin: PluginLike,
|
||||
subDirectoryPath: String,
|
||||
source: Class<*>
|
||||
): Config {
|
||||
|
||||
@@ -4,16 +4,16 @@ import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.willfp.eco.core.config.interfaces.JSONConfig
|
||||
import com.willfp.eco.util.StringUtils
|
||||
import org.apache.commons.lang.Validate
|
||||
import java.util.*
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
open class EcoJSONConfigWrapper : JSONConfig {
|
||||
val handle: Gson = GsonBuilder().setPrettyPrinting().create()
|
||||
|
||||
val values = mutableMapOf<String, Any?>()
|
||||
val values = ConcurrentHashMap<String, Any?>()
|
||||
|
||||
private val cache = mutableMapOf<String, Any>()
|
||||
private val cache = ConcurrentHashMap<String, Any>()
|
||||
|
||||
fun init(values: Map<String, Any?>) {
|
||||
this.values.clear()
|
||||
@@ -123,8 +123,7 @@ open class EcoJSONConfigWrapper : JSONConfig {
|
||||
|
||||
override fun getSubsection(path: String): JSONConfig {
|
||||
val subsection = getSubsectionOrNull(path)
|
||||
Validate.notNull(subsection)
|
||||
return subsection!!
|
||||
return subsection ?: EcoJSONConfigSection(emptyMap())
|
||||
}
|
||||
|
||||
override fun getSubsectionOrNull(path: String): JSONConfig? {
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
package com.willfp.eco.internal.config.json
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.PluginLike
|
||||
import com.willfp.eco.core.config.interfaces.LoadableConfig
|
||||
import org.jetbrains.annotations.NotNull
|
||||
import java.io.*
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.FileOutputStream
|
||||
import java.io.FileReader
|
||||
import java.io.IOException
|
||||
import java.io.OutputStream
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.StandardOpenOption
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class EcoLoadableJSONConfig(
|
||||
open class EcoLoadableJSONConfig(
|
||||
configName: String,
|
||||
private val plugin: EcoPlugin,
|
||||
private val plugin: PluginLike,
|
||||
private val subDirectoryPath: String,
|
||||
private val source: Class<*>
|
||||
val source: Class<*>
|
||||
) : EcoJSONConfigWrapper(), LoadableConfig {
|
||||
|
||||
private val configFile: File
|
||||
@@ -65,7 +69,7 @@ class EcoLoadableJSONConfig(
|
||||
|
||||
@Throws(FileNotFoundException::class)
|
||||
fun init(file: File) {
|
||||
super.init(handle.fromJson(FileReader(file), Map::class.java) as @NotNull MutableMap<String, Any>)
|
||||
super.init(handle.fromJson(FileReader(file), Map::class.java) as MutableMap<String, Any>)
|
||||
}
|
||||
|
||||
override fun getName(): String {
|
||||
@@ -77,7 +81,7 @@ class EcoLoadableJSONConfig(
|
||||
}
|
||||
|
||||
init {
|
||||
val directory: File = File(this.plugin.dataFolder, subDirectoryPath)
|
||||
val directory = File(this.plugin.dataFolder, subDirectoryPath)
|
||||
if (!directory.exists()) {
|
||||
directory.mkdirs()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.willfp.eco.internal.config.json
|
||||
|
||||
import com.willfp.eco.core.PluginLike
|
||||
import org.bukkit.configuration.InvalidConfigurationException
|
||||
import org.bukkit.configuration.file.YamlConfiguration
|
||||
import java.io.BufferedReader
|
||||
import java.io.IOException
|
||||
import java.io.InputStreamReader
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
open class EcoUpdatableJSONConfig(
|
||||
configName: String,
|
||||
plugin: PluginLike,
|
||||
subDirectoryPath: String,
|
||||
source: Class<*>,
|
||||
private val removeUnused: Boolean,
|
||||
vararg updateBlacklist: String
|
||||
) : EcoLoadableJSONConfig(configName, plugin, subDirectoryPath, source) {
|
||||
|
||||
private val updateBlacklist: MutableList<String> = mutableListOf(*updateBlacklist)
|
||||
|
||||
fun update() {
|
||||
super.clearCache()
|
||||
try {
|
||||
this.init(configFile)
|
||||
val newConfig = configInJar
|
||||
if (newConfig.getKeys(true) == this.getKeys(true)) {
|
||||
return
|
||||
}
|
||||
newConfig.getKeys(true).forEach { key: String ->
|
||||
if (!this.getKeys(true).contains(key)) {
|
||||
if (updateBlacklist.stream().noneMatch { s: String -> key.contains(s) }) {
|
||||
this.set(key, newConfig[key])
|
||||
}
|
||||
}
|
||||
}
|
||||
if (removeUnused) {
|
||||
this.getKeys(true).forEach { s ->
|
||||
if (!newConfig.getKeys(true).contains(s)) {
|
||||
if (updateBlacklist.stream().noneMatch(s::contains)) {
|
||||
this.set(s, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.save()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
} catch (e: InvalidConfigurationException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private val configInJar: YamlConfiguration
|
||||
get() {
|
||||
val newIn = this.source.getResourceAsStream(resourcePath) ?: throw NullPointerException("$name is null?")
|
||||
val reader = BufferedReader(InputStreamReader(newIn, StandardCharsets.UTF_8))
|
||||
val newConfig = YamlConfiguration()
|
||||
try {
|
||||
newConfig.load(reader)
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
} catch (e: InvalidConfigurationException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return newConfig
|
||||
}
|
||||
|
||||
init {
|
||||
this.updateBlacklist.removeIf { obj: String -> obj.isEmpty() }
|
||||
plugin.configHandler.addConfig(this)
|
||||
update()
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,12 @@ import com.willfp.eco.core.config.interfaces.LoadableConfig
|
||||
import com.willfp.eco.core.config.updating.ConfigHandler
|
||||
import com.willfp.eco.core.config.updating.ConfigUpdater
|
||||
import com.willfp.eco.internal.config.json.EcoLoadableJSONConfig
|
||||
import com.willfp.eco.internal.config.json.EcoUpdatableJSONConfig
|
||||
import com.willfp.eco.internal.config.updating.exceptions.InvalidUpdateMethodException
|
||||
import com.willfp.eco.internal.config.yaml.EcoLoadableYamlConfig
|
||||
import com.willfp.eco.internal.config.yaml.EcoUpdatableYamlConfig
|
||||
import org.reflections.Reflections
|
||||
import org.reflections.scanners.MethodAnnotationsScanner
|
||||
import java.lang.reflect.Modifier
|
||||
|
||||
class EcoConfigHandler(
|
||||
private val plugin: EcoPlugin
|
||||
@@ -24,10 +24,6 @@ class EcoConfigHandler(
|
||||
|
||||
override fun callUpdate() {
|
||||
for (method in reflections.getMethodsAnnotatedWith(ConfigUpdater::class.java)) {
|
||||
if (!Modifier.isStatic(method.modifiers)) {
|
||||
throw InvalidUpdateMethodException("Update method in ${method.declaringClass.name} must be static.")
|
||||
}
|
||||
|
||||
try {
|
||||
when (method.parameterCount) {
|
||||
0 -> method.invoke(null)
|
||||
@@ -55,6 +51,7 @@ class EcoConfigHandler(
|
||||
for (config in configs) {
|
||||
when (config) {
|
||||
is EcoUpdatableYamlConfig -> config.update()
|
||||
is EcoUpdatableJSONConfig -> config.update()
|
||||
is EcoLoadableYamlConfig -> config.reloadFromFile()
|
||||
is EcoLoadableJSONConfig -> config.reloadFromFile()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.willfp.eco.internal.config.yaml
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.PluginLike
|
||||
import com.willfp.eco.core.config.interfaces.LoadableConfig
|
||||
import com.willfp.eco.core.config.interfaces.WrappedYamlConfiguration
|
||||
import org.bukkit.configuration.InvalidConfigurationException
|
||||
@@ -12,7 +12,7 @@ import java.io.OutputStream
|
||||
|
||||
open class EcoLoadableYamlConfig(
|
||||
configName: String,
|
||||
private val plugin: EcoPlugin,
|
||||
private val plugin: PluginLike,
|
||||
private val subDirectoryPath: String,
|
||||
val source: Class<*>
|
||||
) : EcoYamlConfigWrapper<YamlConfiguration>(), WrappedYamlConfiguration, LoadableConfig {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.willfp.eco.internal.config.yaml
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.PluginLike
|
||||
import org.bukkit.configuration.InvalidConfigurationException
|
||||
import org.bukkit.configuration.file.YamlConfiguration
|
||||
import java.io.BufferedReader
|
||||
@@ -10,7 +10,7 @@ import java.nio.charset.StandardCharsets
|
||||
|
||||
class EcoUpdatableYamlConfig(
|
||||
configName: String,
|
||||
plugin: EcoPlugin,
|
||||
plugin: PluginLike,
|
||||
subDirectoryPath: String,
|
||||
source: Class<*>,
|
||||
private val removeUnused: Boolean,
|
||||
@@ -27,9 +27,9 @@ class EcoUpdatableYamlConfig(
|
||||
if (newConfig.getKeys(true) == this.handle.getKeys(true)) {
|
||||
return
|
||||
}
|
||||
newConfig.getKeys(true).forEach { key: String ->
|
||||
newConfig.getKeys(true).forEach { key ->
|
||||
if (!this.handle.getKeys(true).contains(key)) {
|
||||
if (updateBlacklist.stream().noneMatch { s: String -> key.contains(s) }) {
|
||||
if (updateBlacklist.stream().noneMatch { key.contains(it) }) {
|
||||
this.handle.set(key, newConfig[key])
|
||||
}
|
||||
}
|
||||
@@ -67,7 +67,7 @@ class EcoUpdatableYamlConfig(
|
||||
}
|
||||
|
||||
init {
|
||||
this.updateBlacklist.removeIf { obj: String -> obj.isEmpty() }
|
||||
this.updateBlacklist.removeIf { it.isEmpty() }
|
||||
plugin.configHandler.addConfig(this)
|
||||
update()
|
||||
}
|
||||
|
||||
@@ -2,15 +2,15 @@ package com.willfp.eco.internal.config.yaml
|
||||
|
||||
import com.willfp.eco.core.config.interfaces.Config
|
||||
import com.willfp.eco.util.StringUtils
|
||||
import org.apache.commons.lang.Validate
|
||||
import org.bukkit.configuration.ConfigurationSection
|
||||
import org.bukkit.configuration.file.YamlConfiguration
|
||||
import java.io.StringReader
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
open class EcoYamlConfigWrapper<T : ConfigurationSection> : Config {
|
||||
lateinit var handle: T
|
||||
private val cache = mutableMapOf<String, Any?>()
|
||||
private val cache = ConcurrentHashMap<String, Any?>()
|
||||
|
||||
protected fun init(config: T): Config {
|
||||
handle = config
|
||||
@@ -51,8 +51,7 @@ open class EcoYamlConfigWrapper<T : ConfigurationSection> : Config {
|
||||
|
||||
override fun getSubsection(path: String): Config {
|
||||
val subsection = getSubsectionOrNull(path)
|
||||
Validate.notNull(subsection)
|
||||
return subsection!!
|
||||
return subsection ?: EcoYamlConfigSection(YamlConfiguration())
|
||||
}
|
||||
|
||||
override fun getSubsectionOrNull(path: String): Config? {
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.willfp.eco.internal.data
|
||||
|
||||
import com.willfp.eco.core.data.PlayerProfile
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||
|
||||
class EcoPlayerProfile(
|
||||
val data: MutableMap<PersistentDataKey<*>, Any>
|
||||
) : PlayerProfile {
|
||||
override fun <T : Any> write(key: PersistentDataKey<T>, value: T) {
|
||||
this.data[key] = value
|
||||
}
|
||||
|
||||
override fun <T : Any> read(key: PersistentDataKey<T>): T {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return this.data[key] as T? ?: key.defaultValue
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package com.willfp.eco.internal.display
|
||||
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.display.Display
|
||||
import com.willfp.eco.core.display.DisplayHandler
|
||||
import com.willfp.eco.core.display.DisplayModule
|
||||
import com.willfp.eco.core.display.DisplayPriority
|
||||
import com.willfp.eco.core.fast.FastItemStack
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
import java.util.concurrent.ExecutorService
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
class EcoDisplayHandler(plugin: EcoPlugin) : DisplayHandler {
|
||||
private val registeredModules = mutableMapOf<DisplayPriority, MutableList<DisplayModule>>()
|
||||
private val finalizeKey: NamespacedKey = plugin.namespacedKeyFactory.create("finalized")
|
||||
|
||||
init {
|
||||
for (priority in DisplayPriority.values()) {
|
||||
registeredModules[priority] = mutableListOf()
|
||||
}
|
||||
}
|
||||
|
||||
override fun registerDisplayModule(module: DisplayModule) {
|
||||
val modules = registeredModules[module.priority] ?: return
|
||||
modules.removeIf { module1: DisplayModule ->
|
||||
module1.pluginName.equals(module.pluginName, ignoreCase = true)
|
||||
}
|
||||
modules.add(module)
|
||||
registeredModules[module.priority] = modules
|
||||
}
|
||||
|
||||
override fun display(itemStack: ItemStack, player: Player?): ItemStack {
|
||||
val pluginVarArgs = mutableMapOf<String, Array<Any>>()
|
||||
|
||||
for (priority in DisplayPriority.values()) {
|
||||
val modules = registeredModules[priority] ?: continue
|
||||
for (module in modules) {
|
||||
pluginVarArgs[module.pluginName] = module.generateVarArgs(itemStack)
|
||||
}
|
||||
}
|
||||
|
||||
Display.revert(itemStack)
|
||||
|
||||
itemStack.itemMeta ?: return itemStack
|
||||
|
||||
for (priority in DisplayPriority.values()) {
|
||||
val modules = registeredModules[priority] ?: continue
|
||||
for (module in modules) {
|
||||
val varargs = pluginVarArgs[module.pluginName] ?: continue
|
||||
Display.callDisplayModule(module, itemStack, player, *varargs)
|
||||
}
|
||||
}
|
||||
|
||||
return itemStack
|
||||
}
|
||||
|
||||
override fun revert(itemStack: ItemStack): ItemStack {
|
||||
if (Display.isFinalized(itemStack)) {
|
||||
Display.unfinalize(itemStack)
|
||||
}
|
||||
|
||||
val fast = FastItemStack.wrap(itemStack)
|
||||
val lore = fast.lore
|
||||
|
||||
if (lore.isNotEmpty() && lore.removeIf { line: String ->
|
||||
line.startsWith(
|
||||
Display.PREFIX
|
||||
)
|
||||
}) { // Only modify lore if needed.
|
||||
fast.lore = lore
|
||||
}
|
||||
|
||||
for (priority in DisplayPriority.values()) {
|
||||
val modules = registeredModules[priority] ?: continue
|
||||
for (module in modules) {
|
||||
module.revert(itemStack)
|
||||
}
|
||||
}
|
||||
|
||||
return itemStack
|
||||
}
|
||||
|
||||
override fun finalize(itemStack: ItemStack): ItemStack {
|
||||
if (itemStack.type.maxStackSize > 1) {
|
||||
return itemStack
|
||||
}
|
||||
|
||||
val meta = itemStack.itemMeta ?: return itemStack
|
||||
|
||||
val container = meta.persistentDataContainer
|
||||
container.set(finalizeKey, PersistentDataType.INTEGER, 1)
|
||||
itemStack.itemMeta = meta
|
||||
return itemStack
|
||||
}
|
||||
|
||||
override fun unfinalize(itemStack: ItemStack): ItemStack {
|
||||
val meta = itemStack.itemMeta ?: return itemStack
|
||||
|
||||
val container = meta.persistentDataContainer
|
||||
container.remove(finalizeKey)
|
||||
itemStack.itemMeta = meta
|
||||
return itemStack
|
||||
}
|
||||
|
||||
override fun isFinalized(itemStack: ItemStack): Boolean {
|
||||
val meta = itemStack.itemMeta ?: return false
|
||||
|
||||
val container = meta.persistentDataContainer
|
||||
return container.has(finalizeKey, PersistentDataType.INTEGER)
|
||||
}
|
||||
}
|
||||
@@ -12,10 +12,9 @@ import org.bukkit.event.player.PlayerExpChangeEvent
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.util.Vector
|
||||
|
||||
open class EcoDropQueue(player: Player) : InternalDropQueue {
|
||||
open class EcoDropQueue(val player: Player) : InternalDropQueue {
|
||||
val items = mutableListOf<ItemStack>()
|
||||
var xp: Int = 0
|
||||
val player: Player
|
||||
var loc: Location
|
||||
var hasTelekinesis = false
|
||||
|
||||
@@ -79,7 +78,6 @@ open class EcoDropQueue(player: Player) : InternalDropQueue {
|
||||
}
|
||||
|
||||
init {
|
||||
this.player = player
|
||||
loc = player.location
|
||||
}
|
||||
}
|
||||
@@ -22,11 +22,11 @@ class EcoMenu(
|
||||
): Menu {
|
||||
override fun getSlot(row: Int, column: Int): Slot {
|
||||
if (row < 1 || row > this.rows) {
|
||||
throw IllegalArgumentException("Invalid row number!")
|
||||
return slots[0][0]
|
||||
}
|
||||
|
||||
if (column < 1 || column > 9) {
|
||||
throw IllegalArgumentException("Invalid column number!")
|
||||
return slots[0][0]
|
||||
}
|
||||
|
||||
return slots[row - 1][column - 1]
|
||||
|
||||
@@ -18,9 +18,7 @@ class ExtendedInventory(
|
||||
fun refresh(player: Player) {
|
||||
captiveItems.clear()
|
||||
for (i in 0 until inventory.size) {
|
||||
val pair = MenuUtils.convertSlotToRowColumn(i)
|
||||
val row = pair.first!!
|
||||
val column = pair.second!!
|
||||
val (row, column) = MenuUtils.convertSlotToRowColumn(i)
|
||||
val slot = menu.getSlot(row, column)
|
||||
if (slot is EcoCaptivatorSlot) {
|
||||
val defaultItem = slot.getItemStack(player)
|
||||
|
||||
@@ -2,10 +2,11 @@ package com.willfp.eco.internal.gui.menu
|
||||
|
||||
import com.willfp.eco.core.gui.menu.Menu
|
||||
import org.bukkit.inventory.Inventory
|
||||
import java.util.*
|
||||
|
||||
object MenuHandler {
|
||||
private val menus = mutableMapOf<ExtendedInventory, EcoMenu>()
|
||||
private val inventories = mutableMapOf<Inventory, ExtendedInventory>()
|
||||
private val menus = WeakHashMap<ExtendedInventory, EcoMenu>()
|
||||
private val inventories = WeakHashMap<Inventory, ExtendedInventory>()
|
||||
|
||||
fun registerMenu(
|
||||
inventory: Inventory,
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.willfp.eco.internal.requirement
|
||||
|
||||
import com.willfp.eco.core.requirement.Requirement
|
||||
import com.willfp.eco.core.requirement.RequirementFactory
|
||||
import com.willfp.eco.internal.requirement.requirements.*
|
||||
|
||||
class EcoRequirementFactory: RequirementFactory {
|
||||
override fun create(name: String): Requirement {
|
||||
return when (name.lowercase()) {
|
||||
"has-permission" -> RequirementHasPermission()
|
||||
"placeholder-equals" -> RequirementPlaceholderEquals()
|
||||
"placeholder-greater-than" -> RequirementPlaceholderGreaterThan()
|
||||
"placeholder-less-than" -> RequirementPlaceholderLessThan()
|
||||
else -> RequirementTrue()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.willfp.eco.internal.requirement.requirements
|
||||
|
||||
import com.willfp.eco.core.requirement.Requirement
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class RequirementHasPermission : Requirement() {
|
||||
override fun doesPlayerMeet(
|
||||
player: Player,
|
||||
args: List<String>
|
||||
): Boolean {
|
||||
if (args.isEmpty()) {
|
||||
return false
|
||||
}
|
||||
|
||||
val permission = args[0]
|
||||
return player.hasPermission(permission)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.willfp.eco.internal.requirement.requirements
|
||||
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager
|
||||
import com.willfp.eco.core.requirement.Requirement
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class RequirementPlaceholderEquals : Requirement() {
|
||||
override fun doesPlayerMeet(
|
||||
player: Player,
|
||||
args: List<String>
|
||||
): Boolean {
|
||||
if (args.size < 2) {
|
||||
return false
|
||||
}
|
||||
|
||||
val placeholder = args[0]
|
||||
val equals = args[1]
|
||||
return PlaceholderManager.translatePlaceholders(placeholder, player).equals(equals, ignoreCase = true)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.willfp.eco.internal.requirement.requirements
|
||||
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager
|
||||
import com.willfp.eco.core.requirement.Requirement
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class RequirementPlaceholderGreaterThan : Requirement() {
|
||||
override fun doesPlayerMeet(
|
||||
player: Player,
|
||||
args: List<String>
|
||||
): Boolean {
|
||||
if (args.size < 2) {
|
||||
return false
|
||||
}
|
||||
|
||||
val placeholder = args[0]
|
||||
val equals = args[1].toDoubleOrNull() ?: return false
|
||||
return PlaceholderManager.translatePlaceholders(placeholder, player).toDoubleOrNull() ?: 0.0 >= equals
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.willfp.eco.internal.requirement.requirements
|
||||
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager
|
||||
import com.willfp.eco.core.requirement.Requirement
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class RequirementPlaceholderLessThan : Requirement() {
|
||||
override fun doesPlayerMeet(
|
||||
player: Player,
|
||||
args: List<String>
|
||||
): Boolean {
|
||||
if (args.size < 2) {
|
||||
return false
|
||||
}
|
||||
|
||||
val placeholder = args[0]
|
||||
val equals = args[1].toDoubleOrNull() ?: return false
|
||||
return PlaceholderManager.translatePlaceholders(placeholder, player).toDoubleOrNull() ?: 0.0 < equals
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.willfp.eco.internal.requirement.requirements
|
||||
|
||||
import com.willfp.eco.core.requirement.Requirement
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class RequirementTrue : Requirement() {
|
||||
override fun doesPlayerMeet(
|
||||
player: Player,
|
||||
args: List<String>
|
||||
): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -3,4 +3,6 @@ version rootProject.version
|
||||
|
||||
dependencies {
|
||||
compileOnly 'org.spigotmc:spigot:1.16.5-R0.1-SNAPSHOT'
|
||||
compileOnly 'net.kyori:adventure-api:4.9.1'
|
||||
compileOnly 'net.kyori:adventure-text-serializer-gson:4.8.1'
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
package com.willfp.eco.proxy.v1_16_R3;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.willfp.eco.core.display.Display;
|
||||
import com.willfp.eco.proxy.ChatComponentProxy;
|
||||
import net.minecraft.server.v1_16_R3.ChatBaseComponent;
|
||||
import net.minecraft.server.v1_16_R3.ChatHoverable;
|
||||
import net.minecraft.server.v1_16_R3.ChatMessage;
|
||||
import net.minecraft.server.v1_16_R3.ChatModifier;
|
||||
import net.minecraft.server.v1_16_R3.IChatBaseComponent;
|
||||
import net.minecraft.server.v1_16_R3.MojangsonParser;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public final class ChatComponent implements ChatComponentProxy {
|
||||
@Override
|
||||
public Object modifyComponent(@NotNull final Object obj,
|
||||
@NotNull final Player player) {
|
||||
if (!(obj instanceof IChatBaseComponent chatComponent)) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
for (IChatBaseComponent iChatBaseComponent : chatComponent) {
|
||||
if (iChatBaseComponent == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
modifyBaseComponent(iChatBaseComponent, player);
|
||||
}
|
||||
|
||||
return chatComponent;
|
||||
}
|
||||
|
||||
private void modifyBaseComponent(@NotNull final IChatBaseComponent component,
|
||||
@NotNull final Player player) {
|
||||
for (IChatBaseComponent sibling : component.getSiblings()) {
|
||||
if (sibling == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
modifyBaseComponent(sibling, player);
|
||||
}
|
||||
if (component instanceof ChatMessage) {
|
||||
Arrays.stream(((ChatMessage) component).getArgs())
|
||||
.filter(o -> o instanceof IChatBaseComponent)
|
||||
.map(o -> (IChatBaseComponent) o)
|
||||
.forEach(o -> this.modifyBaseComponent(o, player));
|
||||
}
|
||||
|
||||
ChatHoverable hoverable = component.getChatModifier().getHoverEvent();
|
||||
|
||||
if (hoverable == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
JsonObject jsonObject = hoverable.b();
|
||||
JsonElement json = hoverable.b().get("contents");
|
||||
if (json.getAsJsonObject().get("id") == null) {
|
||||
return;
|
||||
}
|
||||
if (json.getAsJsonObject().get("tag") == null) {
|
||||
return;
|
||||
}
|
||||
String id = json.getAsJsonObject().get("id").toString();
|
||||
String tag = json.getAsJsonObject().get("tag").toString();
|
||||
ItemStack itemStack = getFromTag(tag, id);
|
||||
|
||||
Display.displayAndFinalize(itemStack, player);
|
||||
|
||||
json.getAsJsonObject().remove("tag");
|
||||
String newTag = toJson(itemStack);
|
||||
json.getAsJsonObject().add("tag", new JsonPrimitive(newTag));
|
||||
|
||||
jsonObject.remove("contents");
|
||||
jsonObject.add("contents", json);
|
||||
ChatHoverable newHoverable = ChatHoverable.a(jsonObject);
|
||||
ChatModifier modifier = component.getChatModifier();
|
||||
modifier = modifier.setChatHoverable(newHoverable);
|
||||
|
||||
((ChatBaseComponent) component).setChatModifier(modifier);
|
||||
}
|
||||
|
||||
private static ItemStack getFromTag(@NotNull final String jsonTag,
|
||||
@NotNull final String id) {
|
||||
String processedId = id;
|
||||
String processedJsonTag = jsonTag;
|
||||
processedId = processedId.replace("minecraft:", "");
|
||||
processedId = processedId.toUpperCase();
|
||||
processedId = processedId.replace("\"", "");
|
||||
processedJsonTag = processedJsonTag.substring(1, processedJsonTag.length() - 1);
|
||||
processedJsonTag = processedJsonTag.replace("id:", "\"id\":");
|
||||
processedJsonTag = processedJsonTag.replace("\\", "");
|
||||
Material material = Material.getMaterial(processedId);
|
||||
|
||||
assert material != null;
|
||||
ItemStack itemStack = new ItemStack(material);
|
||||
net.minecraft.server.v1_16_R3.ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
|
||||
|
||||
try {
|
||||
nmsStack.setTag(MojangsonParser.parse(processedJsonTag));
|
||||
} catch (CommandSyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return CraftItemStack.asBukkitCopy(nmsStack);
|
||||
}
|
||||
|
||||
private static String toJson(@NotNull final ItemStack itemStack) {
|
||||
return CraftItemStack.asNMSCopy(itemStack).getOrCreateTag().toString();
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package com.willfp.eco.proxy.v1_16_R3;
|
||||
|
||||
import org.bukkit.craftbukkit.libs.org.apache.commons.lang3.Validate;
|
||||
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class FastItemStackUtils {
|
||||
private static final Field FIELD;
|
||||
|
||||
public static net.minecraft.server.v1_16_R3.ItemStack getNMSStack(@NotNull final ItemStack itemStack) {
|
||||
if (!(itemStack instanceof CraftItemStack)) {
|
||||
return CraftItemStack.asNMSCopy(itemStack);
|
||||
} else {
|
||||
try {
|
||||
net.minecraft.server.v1_16_R3.ItemStack nms = (net.minecraft.server.v1_16_R3.ItemStack) FIELD.get(itemStack);
|
||||
return nms == null ? CraftItemStack.asNMSCopy(itemStack) : nms;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
e.printStackTrace();
|
||||
return net.minecraft.server.v1_16_R3.ItemStack.b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
Field temp = null;
|
||||
|
||||
try {
|
||||
Field handleField = CraftItemStack.class.getDeclaredField("handle");
|
||||
handleField.setAccessible(true);
|
||||
temp = handleField;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
assert temp != null;
|
||||
Validate.notNull(temp, "Error occurred in initialization!");
|
||||
|
||||
FIELD = temp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.willfp.eco.proxy.v1_16_R3
|
||||
|
||||
import com.willfp.eco.core.display.Display
|
||||
import com.willfp.eco.proxy.ChatComponentProxy
|
||||
import net.kyori.adventure.nbt.api.BinaryTagHolder
|
||||
import net.kyori.adventure.text.BuildableComponent
|
||||
import net.kyori.adventure.text.Component
|
||||
import net.kyori.adventure.text.TranslatableComponent
|
||||
import net.kyori.adventure.text.event.HoverEvent
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer
|
||||
import net.minecraft.server.v1_16_R3.IChatBaseComponent
|
||||
import net.minecraft.server.v1_16_R3.MojangsonParser
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class ChatComponent : ChatComponentProxy {
|
||||
private val gsonComponentSerializer = GsonComponentSerializer.gson()
|
||||
|
||||
override fun modifyComponent(obj: Any, player: Player): Any {
|
||||
if (obj !is IChatBaseComponent) {
|
||||
return obj
|
||||
}
|
||||
|
||||
val component = gsonComponentSerializer.deserialize(
|
||||
IChatBaseComponent.ChatSerializer.a(
|
||||
obj
|
||||
)
|
||||
).asComponent() as BuildableComponent<*, *>
|
||||
|
||||
val newComponent = modifyBaseComponent(component, player)
|
||||
|
||||
return IChatBaseComponent.ChatSerializer.a(
|
||||
gsonComponentSerializer.serialize(newComponent.asComponent())
|
||||
) ?: obj
|
||||
}
|
||||
|
||||
private fun modifyBaseComponent(baseComponent: Component, player: Player): Component {
|
||||
var component = baseComponent
|
||||
|
||||
if (component is TranslatableComponent) {
|
||||
val args = mutableListOf<Component>()
|
||||
for (arg in component.args()) {
|
||||
args.add(modifyBaseComponent(arg, player))
|
||||
}
|
||||
component = component.args(args)
|
||||
}
|
||||
|
||||
val children = mutableListOf<Component>()
|
||||
for (child in component.children()) {
|
||||
children.add(modifyBaseComponent(child, player))
|
||||
}
|
||||
component = component.children(children)
|
||||
|
||||
val hoverEvent: HoverEvent<Any> = component.style().hoverEvent() as HoverEvent<Any>? ?: return component
|
||||
|
||||
val showItem = hoverEvent.value()
|
||||
|
||||
if (showItem !is HoverEvent.ShowItem) {
|
||||
return component
|
||||
}
|
||||
|
||||
val newShowItem = showItem.nbt(
|
||||
BinaryTagHolder.of(
|
||||
CraftItemStack.asNMSCopy(
|
||||
Display.display(
|
||||
CraftItemStack.asBukkitCopy(
|
||||
CraftItemStack.asNMSCopy(
|
||||
org.bukkit.inventory.ItemStack(
|
||||
Material.matchMaterial(
|
||||
showItem.item()
|
||||
.toString()
|
||||
) ?: return component,
|
||||
showItem.count()
|
||||
)
|
||||
).apply {
|
||||
this.tag = MojangsonParser.parse(
|
||||
showItem.nbt()?.string() ?: return component
|
||||
) ?: return component
|
||||
}
|
||||
),
|
||||
player
|
||||
)
|
||||
).orCreateTag.toString()
|
||||
)
|
||||
)
|
||||
|
||||
val newHover = hoverEvent.value(newShowItem)
|
||||
val style = component.style().hoverEvent(newHover)
|
||||
return component.style(style)
|
||||
}
|
||||
}
|
||||
@@ -36,8 +36,9 @@ class Skull : SkullProxy {
|
||||
profile = meta.javaClass.getDeclaredField("profile")
|
||||
profile.isAccessible = true
|
||||
}
|
||||
val profile = profile[meta] as GameProfile?
|
||||
val property = profile?.properties?.get("textures") as Property?
|
||||
return property?.value
|
||||
val profile = profile[meta] as GameProfile? ?: return null
|
||||
val properties = profile.properties ?: return null
|
||||
val prop = properties["textures"] ?: return null
|
||||
return prop.toMutableList().firstOrNull()?.name
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.willfp.eco.proxy.v1_16_R3
|
||||
|
||||
import com.willfp.eco.proxy.TPSProxy
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.craftbukkit.v1_16_R3.CraftServer
|
||||
|
||||
class TPS : TPSProxy {
|
||||
override fun getTPS(): Double {
|
||||
return (Bukkit.getServer() as CraftServer).handle.server.recentTps[0]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.willfp.eco.proxy.v1_16_R3.fast
|
||||
|
||||
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import java.lang.reflect.Field
|
||||
|
||||
private val field: Field = CraftItemStack::class.java.getDeclaredField("handle").apply {
|
||||
isAccessible = true
|
||||
}
|
||||
|
||||
fun ItemStack.getNMSStack(): net.minecraft.server.v1_16_R3.ItemStack {
|
||||
return if (this !is CraftItemStack) {
|
||||
CraftItemStack.asNMSCopy(this)
|
||||
} else {
|
||||
field[this] as net.minecraft.server.v1_16_R3.ItemStack? ?: CraftItemStack.asNMSCopy(this)
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.willfp.eco.proxy.v1_16_R3.fast
|
||||
|
||||
import com.willfp.eco.internal.fast.EcoFastItemStack
|
||||
import com.willfp.eco.proxy.v1_16_R3.FastItemStackUtils
|
||||
import com.willfp.eco.util.StringUtils
|
||||
import net.minecraft.server.v1_16_R3.*
|
||||
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack
|
||||
@@ -12,7 +11,7 @@ import org.bukkit.inventory.ItemFlag
|
||||
import kotlin.experimental.and
|
||||
|
||||
class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemStack<ItemStack>(
|
||||
FastItemStackUtils.getNMSStack(itemStack), itemStack
|
||||
itemStack.getNMSStack(), itemStack
|
||||
) {
|
||||
private var loreCache: List<String>? = null
|
||||
override fun getEnchantmentsOnItem(checkStored: Boolean): Map<Enchantment, Int> {
|
||||
@@ -151,6 +150,18 @@ class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemS
|
||||
handle.repairCost = cost
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is NMSFastItemStack) {
|
||||
return false
|
||||
}
|
||||
|
||||
return other.hashCode() == this.hashCode()
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return handle.tag.hashCode() * 31 + Item.getId(handle.item)
|
||||
}
|
||||
|
||||
private fun apply() {
|
||||
if (bukkit !is CraftItemStack) {
|
||||
bukkit.itemMeta = CraftItemStack.asCraftMirror(handle).itemMeta
|
||||
|
||||
@@ -7,6 +7,8 @@ version rootProject.version
|
||||
|
||||
dependencies {
|
||||
compileOnly 'org.spigotmc:spigot:1.17.1-R0.1-SNAPSHOT:remapped-mojang'
|
||||
compileOnly 'net.kyori:adventure-api:4.9.1'
|
||||
compileOnly 'net.kyori:adventure-text-serializer-gson:4.8.1'
|
||||
}
|
||||
|
||||
specialGradle {
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
package com.willfp.eco.proxy.v1_17_R1;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.willfp.eco.core.display.Display;
|
||||
import net.minecraft.nbt.TagParser;
|
||||
import net.minecraft.network.chat.BaseComponent;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.HoverEvent;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import com.willfp.eco.proxy.ChatComponentProxy;
|
||||
|
||||
public final class ChatComponent implements ChatComponentProxy {
|
||||
@Override
|
||||
public Object modifyComponent(@NotNull final Object obj,
|
||||
@NotNull final Player player) {
|
||||
if (!(obj instanceof Component chatComponent)) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
for (Component iChatBaseComponent : chatComponent) {
|
||||
if (iChatBaseComponent == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
modifyBaseComponent(iChatBaseComponent, player);
|
||||
}
|
||||
|
||||
return chatComponent;
|
||||
}
|
||||
|
||||
private void modifyBaseComponent(@NotNull final Component component,
|
||||
@NotNull final Player player) {
|
||||
for (Component sibling : component.getSiblings()) {
|
||||
if (sibling == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
modifyBaseComponent(sibling, player);
|
||||
}
|
||||
|
||||
if (component instanceof TranslatableComponent baseComponent) {
|
||||
for (Object arg : baseComponent.getArgs()) {
|
||||
if (arg instanceof Component) {
|
||||
modifyBaseComponent((Component) arg, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HoverEvent hoverable = component.getStyle().getHoverEvent();
|
||||
|
||||
if (hoverable == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
JsonObject jsonObject = hoverable.serialize();
|
||||
JsonElement json = jsonObject.get("contents");
|
||||
if (json.getAsJsonObject().get("id") == null) {
|
||||
return;
|
||||
}
|
||||
if (json.getAsJsonObject().get("tag") == null) {
|
||||
return;
|
||||
}
|
||||
String id = json.getAsJsonObject().get("id").toString();
|
||||
String tag = json.getAsJsonObject().get("tag").toString();
|
||||
ItemStack itemStack = getFromTag(tag, id);
|
||||
|
||||
Display.displayAndFinalize(itemStack, player);
|
||||
|
||||
json.getAsJsonObject().remove("tag");
|
||||
String newTag = toJson(itemStack);
|
||||
json.getAsJsonObject().add("tag", new JsonPrimitive(newTag));
|
||||
|
||||
jsonObject.remove("contents");
|
||||
jsonObject.add("contents", json);
|
||||
HoverEvent newHoverable = HoverEvent.deserialize(jsonObject);
|
||||
Style modifier = component.getStyle();
|
||||
modifier = modifier.withHoverEvent(newHoverable);
|
||||
|
||||
((BaseComponent) component).setStyle(modifier);
|
||||
}
|
||||
|
||||
private static ItemStack getFromTag(@NotNull final String jsonTag,
|
||||
@NotNull final String id) {
|
||||
String processedId = id;
|
||||
String processedJsonTag = jsonTag;
|
||||
processedId = processedId.replace("minecraft:", "");
|
||||
processedId = processedId.toUpperCase();
|
||||
processedId = processedId.replace("\"", "");
|
||||
processedJsonTag = processedJsonTag.substring(1, processedJsonTag.length() - 1);
|
||||
processedJsonTag = processedJsonTag.replace("id:", "\"id\":");
|
||||
processedJsonTag = processedJsonTag.replace("\\", "");
|
||||
Material material = Material.getMaterial(processedId);
|
||||
|
||||
assert material != null;
|
||||
ItemStack itemStack = new ItemStack(material);
|
||||
net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
|
||||
|
||||
try {
|
||||
nmsStack.setTag(TagParser.parseTag(processedJsonTag));
|
||||
} catch (CommandSyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return CraftItemStack.asBukkitCopy(nmsStack);
|
||||
}
|
||||
|
||||
private static String toJson(@NotNull final ItemStack itemStack) {
|
||||
return CraftItemStack.asNMSCopy(itemStack).getOrCreateTag().toString();
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package com.willfp.eco.proxy.v1_17_R1;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.craftbukkit.libs.org.apache.commons.lang3.Validate;
|
||||
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
@UtilityClass
|
||||
public class FastItemStackUtils {
|
||||
private static final Field FIELD;
|
||||
|
||||
public static net.minecraft.world.item.ItemStack getNMSStack(@NotNull final ItemStack itemStack) {
|
||||
if (!(itemStack instanceof CraftItemStack)) {
|
||||
return CraftItemStack.asNMSCopy(itemStack);
|
||||
} else {
|
||||
try {
|
||||
net.minecraft.world.item.ItemStack nms = (net.minecraft.world.item.ItemStack) FIELD.get(itemStack);
|
||||
return nms == null ? CraftItemStack.asNMSCopy(itemStack) : nms;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
e.printStackTrace();
|
||||
return net.minecraft.world.item.ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
Field temp = null;
|
||||
|
||||
try {
|
||||
Field handleField = CraftItemStack.class.getDeclaredField("handle");
|
||||
handleField.setAccessible(true);
|
||||
temp = handleField;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
assert temp != null;
|
||||
Validate.notNull(temp, "Error occurred in initialization!");
|
||||
|
||||
FIELD = temp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.willfp.eco.proxy.v1_17_R1
|
||||
|
||||
import com.willfp.eco.core.display.Display
|
||||
import com.willfp.eco.proxy.ChatComponentProxy
|
||||
import net.kyori.adventure.nbt.api.BinaryTagHolder
|
||||
import net.kyori.adventure.text.BuildableComponent
|
||||
import net.kyori.adventure.text.Component
|
||||
import net.kyori.adventure.text.TranslatableComponent
|
||||
import net.kyori.adventure.text.event.HoverEvent
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer
|
||||
import net.minecraft.nbt.TagParser
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class ChatComponent : ChatComponentProxy {
|
||||
private val gsonComponentSerializer = GsonComponentSerializer.gson()
|
||||
|
||||
override fun modifyComponent(obj: Any, player: Player): Any {
|
||||
if (obj !is net.minecraft.network.chat.Component) {
|
||||
return obj
|
||||
}
|
||||
|
||||
val component = gsonComponentSerializer.deserialize(
|
||||
net.minecraft.network.chat.Component.Serializer.toJson(
|
||||
obj
|
||||
)
|
||||
).asComponent() as BuildableComponent<*, *>
|
||||
|
||||
val newComponent = modifyBaseComponent(component, player)
|
||||
|
||||
return net.minecraft.network.chat.Component.Serializer.fromJson(
|
||||
gsonComponentSerializer.serialize(newComponent.asComponent())
|
||||
) ?: obj
|
||||
}
|
||||
|
||||
private fun modifyBaseComponent(baseComponent: Component, player: Player): Component {
|
||||
var component = baseComponent
|
||||
|
||||
if (component is TranslatableComponent) {
|
||||
val args = mutableListOf<Component>()
|
||||
for (arg in component.args()) {
|
||||
args.add(modifyBaseComponent(arg, player))
|
||||
}
|
||||
component = component.args(args)
|
||||
}
|
||||
|
||||
val children = mutableListOf<Component>()
|
||||
for (child in component.children()) {
|
||||
children.add(modifyBaseComponent(child, player))
|
||||
}
|
||||
component = component.children(children)
|
||||
|
||||
val hoverEvent: HoverEvent<Any> = component.style().hoverEvent() as HoverEvent<Any>? ?: return component
|
||||
|
||||
val showItem = hoverEvent.value()
|
||||
|
||||
if (showItem !is HoverEvent.ShowItem) {
|
||||
return component
|
||||
}
|
||||
|
||||
val newShowItem = showItem.nbt(
|
||||
BinaryTagHolder.of(
|
||||
CraftItemStack.asNMSCopy(
|
||||
Display.display(
|
||||
CraftItemStack.asBukkitCopy(
|
||||
CraftItemStack.asNMSCopy(
|
||||
ItemStack(
|
||||
Material.matchMaterial(
|
||||
showItem.item()
|
||||
.toString()
|
||||
) ?: return component,
|
||||
showItem.count()
|
||||
)
|
||||
).apply {
|
||||
this.tag = TagParser.parseTag(
|
||||
showItem.nbt()?.string() ?: return component
|
||||
) ?: return component
|
||||
}
|
||||
),
|
||||
player
|
||||
)
|
||||
).orCreateTag.toString()
|
||||
)
|
||||
)
|
||||
|
||||
val newHover = hoverEvent.value(newShowItem)
|
||||
val style = component.style().hoverEvent(newHover)
|
||||
return component.style(style)
|
||||
}
|
||||
}
|
||||
@@ -36,8 +36,9 @@ class Skull : SkullProxy {
|
||||
profile = meta.javaClass.getDeclaredField("profile")
|
||||
profile.isAccessible = true
|
||||
}
|
||||
val profile = profile[meta] as GameProfile?
|
||||
val property = profile?.properties?.get("textures") as Property?
|
||||
return property?.value
|
||||
val profile = profile[meta] as GameProfile? ?: return null
|
||||
val properties = profile.properties ?: return null
|
||||
val prop = properties["textures"] ?: return null
|
||||
return prop.toMutableList().firstOrNull()?.name
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.willfp.eco.proxy.v1_17_R1
|
||||
|
||||
import com.willfp.eco.proxy.TPSProxy
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.craftbukkit.v1_17_R1.CraftServer
|
||||
|
||||
class TPS : TPSProxy {
|
||||
override fun getTPS(): Double {
|
||||
return (Bukkit.getServer() as CraftServer).handle.server.recentTps[0]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.willfp.eco.proxy.v1_17_R1.fast
|
||||
|
||||
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import java.lang.reflect.Field
|
||||
|
||||
private val field: Field = CraftItemStack::class.java.getDeclaredField("handle").apply {
|
||||
isAccessible = true
|
||||
}
|
||||
|
||||
fun ItemStack.getNMSStack(): net.minecraft.world.item.ItemStack {
|
||||
return if (this !is CraftItemStack) {
|
||||
CraftItemStack.asNMSCopy(this)
|
||||
} else {
|
||||
field[this] as net.minecraft.world.item.ItemStack? ?: CraftItemStack.asNMSCopy(this)
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
package com.willfp.eco.proxy.v1_17_R1.fast
|
||||
|
||||
import com.willfp.eco.internal.fast.EcoFastItemStack
|
||||
import com.willfp.eco.proxy.v1_17_R1.FastItemStackUtils
|
||||
import com.willfp.eco.util.StringUtils
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.ListTag
|
||||
import net.minecraft.nbt.StringTag
|
||||
import net.minecraft.world.item.EnchantedBookItem
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.Items
|
||||
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack
|
||||
@@ -17,7 +17,7 @@ import org.bukkit.inventory.ItemFlag
|
||||
import kotlin.experimental.and
|
||||
|
||||
class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemStack<ItemStack>(
|
||||
FastItemStackUtils.getNMSStack(itemStack), itemStack
|
||||
itemStack.getNMSStack(), itemStack
|
||||
) {
|
||||
private var loreCache: List<String>? = null
|
||||
|
||||
@@ -171,6 +171,18 @@ class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemS
|
||||
handle.setRepairCost(cost)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is NMSFastItemStack) {
|
||||
return false
|
||||
}
|
||||
|
||||
return other.hashCode() == this.hashCode()
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return handle.tag.hashCode() * 31 + Item.getId(handle.item)
|
||||
}
|
||||
|
||||
private fun apply() {
|
||||
if (bukkit !is CraftItemStack) {
|
||||
bukkit.itemMeta = CraftItemStack.asCraftMirror(handle).itemMeta
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user