Compare commits
131 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 |
@@ -1,6 +1,6 @@
|
|||||||
<h1 align="center">
|
<h1 align="center">
|
||||||
<br>
|
<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>
|
<br>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ Here's a list of some (not all) of the features of eco:
|
|||||||
|
|
||||||
<h1 align="center">
|
<h1 align="center">
|
||||||
<br>
|
<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">
|
<img src="https://i.imgur.com/uFDpBAC.png" alt="supps banner">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://dedimc.promo/Auxilor" target="_blank">
|
<a href="https://dedimc.promo/Auxilor" target="_blank">
|
||||||
|
|||||||
16
build.gradle
16
build.gradle
@@ -25,11 +25,14 @@ allprojects {
|
|||||||
mavenLocal()
|
mavenLocal()
|
||||||
maven { url 'https://jitpack.io' }
|
maven { url 'https://jitpack.io' }
|
||||||
|
|
||||||
|
// SuperiorSkyblock2
|
||||||
|
maven { url 'https://repo.bg-software.com/repository/api/' }
|
||||||
|
|
||||||
// NMS (for jitpack compilation)
|
// NMS (for jitpack compilation)
|
||||||
maven { url 'https://repo.codemc.org/repository/nms/' }
|
maven { url 'https://repo.codemc.org/repository/nms/' }
|
||||||
|
|
||||||
// bStats, mcMMO
|
// bStats, mcMMO, BentoBox
|
||||||
maven { url 'https://repo.codemc.org/repository/maven-public' }
|
maven { url 'https://repo.codemc.org/repository/maven-public/' }
|
||||||
|
|
||||||
// Spigot API
|
// Spigot API
|
||||||
maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' }
|
maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' }
|
||||||
@@ -51,23 +54,20 @@ allprojects {
|
|||||||
|
|
||||||
// CombatLogX
|
// CombatLogX
|
||||||
maven { url 'https://nexus.sirblobman.xyz/repository/public/' }
|
maven { url 'https://nexus.sirblobman.xyz/repository/public/' }
|
||||||
|
|
||||||
// Head Database
|
|
||||||
maven { url 'https://mvn.intellectualsites.com/content/groups/public/' }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly 'org.jetbrains:annotations:19.0.0'
|
compileOnly 'org.jetbrains:annotations:19.0.0'
|
||||||
|
|
||||||
// Lombok
|
// Lombok
|
||||||
compileOnly 'org.projectlombok:lombok:1.18.20'
|
compileOnly 'org.projectlombok:lombok:1.18.22'
|
||||||
annotationProcessor 'org.projectlombok:lombok:1.18.20'
|
annotationProcessor 'org.projectlombok:lombok:1.18.20'
|
||||||
testCompileOnly 'org.projectlombok:lombok:1.18.20'
|
testCompileOnly 'org.projectlombok:lombok:1.18.20'
|
||||||
testAnnotationProcessor 'org.projectlombok:lombok:1.18.20'
|
testAnnotationProcessor 'org.projectlombok:lombok:1.18.20'
|
||||||
|
|
||||||
// Test
|
// Test
|
||||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
|
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) {
|
tasks.withType(JavaCompile) {
|
||||||
@@ -87,7 +87,7 @@ allprojects {
|
|||||||
|
|
||||||
shadowJar {
|
shadowJar {
|
||||||
relocate('org.bstats', 'com.willfp.eco.shaded.bstats')
|
relocate('org.bstats', 'com.willfp.eco.shaded.bstats')
|
||||||
relocate('net.kyori.adventure', 'com.willfp.eco.shaded.adventure')
|
relocate('net.kyori.adventure.text.minimessage', 'com.willfp.eco.shaded.minimessage')
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
|
|||||||
@@ -6,14 +6,18 @@ group 'com.willfp'
|
|||||||
version rootProject.version
|
version rootProject.version
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
|
// Adventure
|
||||||
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'
|
|
||||||
compileOnly 'net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT'
|
|
||||||
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
|
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 {
|
java {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.willfp.eco.core;
|
package com.willfp.eco.core;
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
@@ -15,20 +14,12 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
public class Eco {
|
public class Eco {
|
||||||
/**
|
/**
|
||||||
* Instance of eco handler.
|
* 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;
|
private Handler handler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the handler.
|
* Set the handler.
|
||||||
*
|
|
||||||
* @param handler The handler.
|
* @param handler The handler.
|
||||||
*/
|
*/
|
||||||
@ApiStatus.Internal
|
@ApiStatus.Internal
|
||||||
@@ -37,4 +28,25 @@ public class Eco {
|
|||||||
|
|
||||||
Eco.handler = handler;
|
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,7 +52,7 @@ import java.util.stream.Collectors;
|
|||||||
* be cancelled.</b>
|
* be cancelled.</b>
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public abstract class EcoPlugin extends JavaPlugin {
|
public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||||
/**
|
/**
|
||||||
* The polymart resource ID of the plugin.
|
* The polymart resource ID of the plugin.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package com.willfp.eco.core;
|
|||||||
|
|
||||||
import com.willfp.eco.core.config.updating.ConfigHandler;
|
import com.willfp.eco.core.config.updating.ConfigHandler;
|
||||||
import com.willfp.eco.core.config.wrapper.ConfigFactory;
|
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.drops.DropQueueFactory;
|
||||||
import com.willfp.eco.core.events.EventManager;
|
import com.willfp.eco.core.events.EventManager;
|
||||||
import com.willfp.eco.core.extensions.ExtensionLoader;
|
import com.willfp.eco.core.extensions.ExtensionLoader;
|
||||||
@@ -17,6 +19,7 @@ import com.willfp.eco.core.requirement.RequirementFactory;
|
|||||||
import com.willfp.eco.core.scheduling.Scheduler;
|
import com.willfp.eco.core.scheduling.Scheduler;
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -24,8 +27,9 @@ import java.util.List;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Eco
|
* @see Eco#getHandler()
|
||||||
*/
|
*/
|
||||||
|
@ApiStatus.Internal
|
||||||
public interface Handler {
|
public interface Handler {
|
||||||
/**
|
/**
|
||||||
* Create a scheduler.
|
* Create a scheduler.
|
||||||
@@ -210,6 +214,21 @@ public interface Handler {
|
|||||||
*
|
*
|
||||||
* @return The audiences.
|
* @return The audiences.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@Nullable
|
||||||
BukkitAudiences getAdventure();
|
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.
|
* @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.
|
* 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();
|
File getConfigFile();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the config name (including extension)
|
* Get the config name (including extension).
|
||||||
*
|
*
|
||||||
* @return The name.
|
* @return The name.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ package com.willfp.eco.core.config.json;
|
|||||||
|
|
||||||
import com.willfp.eco.core.Eco;
|
import com.willfp.eco.core.Eco;
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
import com.willfp.eco.core.EcoPlugin;
|
||||||
|
import com.willfp.eco.core.PluginLike;
|
||||||
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
|
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
|
||||||
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -20,7 +20,7 @@ public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
|
|||||||
*/
|
*/
|
||||||
protected JSONBaseConfig(@NotNull final String configName,
|
protected JSONBaseConfig(@NotNull final String configName,
|
||||||
final boolean removeUnused,
|
final boolean removeUnused,
|
||||||
@NotNull final EcoPlugin plugin,
|
@NotNull final PluginLike plugin,
|
||||||
@NotNull final String... updateBlacklist) {
|
@NotNull final String... updateBlacklist) {
|
||||||
super(
|
super(
|
||||||
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
|
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
|
||||||
@@ -40,7 +40,7 @@ public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
|
|||||||
*/
|
*/
|
||||||
protected JSONBaseConfig(@NotNull final String configName,
|
protected JSONBaseConfig(@NotNull final String configName,
|
||||||
final boolean removeUnused,
|
final boolean removeUnused,
|
||||||
@NotNull final EcoPlugin plugin) {
|
@NotNull final PluginLike plugin) {
|
||||||
super(
|
super(
|
||||||
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
|
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
|
||||||
configName,
|
configName,
|
||||||
@@ -51,4 +51,28 @@ 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 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ package com.willfp.eco.core.config.json;
|
|||||||
|
|
||||||
import com.willfp.eco.core.Eco;
|
import com.willfp.eco.core.Eco;
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
import com.willfp.eco.core.EcoPlugin;
|
||||||
|
import com.willfp.eco.core.PluginLike;
|
||||||
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
|
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
|
||||||
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -26,7 +26,7 @@ public abstract class JSONExtendableConfig extends LoadableJSONConfigWrapper {
|
|||||||
*/
|
*/
|
||||||
protected JSONExtendableConfig(@NotNull final String configName,
|
protected JSONExtendableConfig(@NotNull final String configName,
|
||||||
final boolean removeUnused,
|
final boolean removeUnused,
|
||||||
@NotNull final EcoPlugin plugin,
|
@NotNull final PluginLike plugin,
|
||||||
@NotNull final Class<?> source,
|
@NotNull final Class<?> source,
|
||||||
@NotNull final String subDirectoryPath,
|
@NotNull final String subDirectoryPath,
|
||||||
@NotNull final String... updateBlacklist) {
|
@NotNull final String... updateBlacklist) {
|
||||||
@@ -41,4 +41,20 @@ 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 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.Eco;
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
import com.willfp.eco.core.EcoPlugin;
|
||||||
|
import com.willfp.eco.core.PluginLike;
|
||||||
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
|
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@@ -18,7 +19,20 @@ public abstract class JSONStaticBaseConfig extends LoadableJSONConfigWrapper {
|
|||||||
* @param plugin The plugin.
|
* @param plugin The plugin.
|
||||||
*/
|
*/
|
||||||
protected JSONStaticBaseConfig(@NotNull final String configName,
|
protected JSONStaticBaseConfig(@NotNull final String configName,
|
||||||
@NotNull final EcoPlugin plugin) {
|
@NotNull final PluginLike plugin) {
|
||||||
super(Eco.getHandler().getConfigFactory().createLoadableJSONConfig(configName, plugin, "", plugin.getClass()));
|
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;
|
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>
|
* <p>
|
||||||
* Handles updating and saving configs.
|
* Handles updating and saving configs.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.willfp.eco.core.config.wrapper;
|
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.Config;
|
||||||
import com.willfp.eco.core.config.interfaces.JSONConfig;
|
import com.willfp.eco.core.config.interfaces.JSONConfig;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
@@ -24,7 +24,7 @@ public interface ConfigFactory {
|
|||||||
* @return The config implementation.
|
* @return The config implementation.
|
||||||
*/
|
*/
|
||||||
Config createUpdatableYamlConfig(@NotNull String configName,
|
Config createUpdatableYamlConfig(@NotNull String configName,
|
||||||
@NotNull EcoPlugin plugin,
|
@NotNull PluginLike plugin,
|
||||||
@NotNull String subDirectoryPath,
|
@NotNull String subDirectoryPath,
|
||||||
@NotNull Class<?> source,
|
@NotNull Class<?> source,
|
||||||
boolean removeUnused,
|
boolean removeUnused,
|
||||||
@@ -42,7 +42,7 @@ public interface ConfigFactory {
|
|||||||
* @return The config implementation.
|
* @return The config implementation.
|
||||||
*/
|
*/
|
||||||
JSONConfig createUpdatableJSONConfig(@NotNull String configName,
|
JSONConfig createUpdatableJSONConfig(@NotNull String configName,
|
||||||
@NotNull EcoPlugin plugin,
|
@NotNull PluginLike plugin,
|
||||||
@NotNull String subDirectoryPath,
|
@NotNull String subDirectoryPath,
|
||||||
@NotNull Class<?> source,
|
@NotNull Class<?> source,
|
||||||
boolean removeUnused,
|
boolean removeUnused,
|
||||||
@@ -58,7 +58,7 @@ public interface ConfigFactory {
|
|||||||
* @return The config implementation.
|
* @return The config implementation.
|
||||||
*/
|
*/
|
||||||
JSONConfig createLoadableJSONConfig(@NotNull String configName,
|
JSONConfig createLoadableJSONConfig(@NotNull String configName,
|
||||||
@NotNull EcoPlugin plugin,
|
@NotNull PluginLike plugin,
|
||||||
@NotNull String subDirectoryPath,
|
@NotNull String subDirectoryPath,
|
||||||
@NotNull Class<?> source);
|
@NotNull Class<?> source);
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ public interface ConfigFactory {
|
|||||||
* @return The config implementation.
|
* @return The config implementation.
|
||||||
*/
|
*/
|
||||||
Config createLoadableYamlConfig(@NotNull String configName,
|
Config createLoadableYamlConfig(@NotNull String configName,
|
||||||
@NotNull EcoPlugin plugin,
|
@NotNull PluginLike plugin,
|
||||||
@NotNull String subDirectoryPath,
|
@NotNull String subDirectoryPath,
|
||||||
@NotNull Class<?> source);
|
@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.Eco;
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
import com.willfp.eco.core.EcoPlugin;
|
||||||
|
import com.willfp.eco.core.PluginLike;
|
||||||
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
|
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@@ -19,7 +20,7 @@ public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
|
|||||||
*/
|
*/
|
||||||
protected YamlBaseConfig(@NotNull final String configName,
|
protected YamlBaseConfig(@NotNull final String configName,
|
||||||
final boolean removeUnused,
|
final boolean removeUnused,
|
||||||
@NotNull final EcoPlugin plugin,
|
@NotNull final PluginLike plugin,
|
||||||
@NotNull final String... updateBlacklist) {
|
@NotNull final String... updateBlacklist) {
|
||||||
super(
|
super(
|
||||||
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig(
|
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig(
|
||||||
@@ -39,7 +40,7 @@ public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
|
|||||||
*/
|
*/
|
||||||
protected YamlBaseConfig(@NotNull final String configName,
|
protected YamlBaseConfig(@NotNull final String configName,
|
||||||
final boolean removeUnused,
|
final boolean removeUnused,
|
||||||
@NotNull final EcoPlugin plugin) {
|
@NotNull final PluginLike plugin) {
|
||||||
super(
|
super(
|
||||||
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig(
|
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig(
|
||||||
configName,
|
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.Eco;
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
import com.willfp.eco.core.EcoPlugin;
|
||||||
|
import com.willfp.eco.core.PluginLike;
|
||||||
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
|
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@@ -25,7 +26,7 @@ public abstract class YamlExtendableConfig extends LoadableYamlConfigWrapper {
|
|||||||
*/
|
*/
|
||||||
protected YamlExtendableConfig(@NotNull final String configName,
|
protected YamlExtendableConfig(@NotNull final String configName,
|
||||||
final boolean removeUnused,
|
final boolean removeUnused,
|
||||||
@NotNull final EcoPlugin plugin,
|
@NotNull final PluginLike plugin,
|
||||||
@NotNull final Class<?> source,
|
@NotNull final Class<?> source,
|
||||||
@NotNull final String subDirectoryPath,
|
@NotNull final String subDirectoryPath,
|
||||||
@NotNull final String... updateBlacklist) {
|
@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.Eco;
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
import com.willfp.eco.core.EcoPlugin;
|
||||||
|
import com.willfp.eco.core.PluginLike;
|
||||||
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
|
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@@ -18,7 +19,20 @@ public abstract class YamlStaticBaseConfig extends LoadableYamlConfigWrapper {
|
|||||||
* @param plugin The plugin.
|
* @param plugin The plugin.
|
||||||
*/
|
*/
|
||||||
protected YamlStaticBaseConfig(@NotNull final String configName,
|
protected YamlStaticBaseConfig(@NotNull final String configName,
|
||||||
@NotNull final EcoPlugin plugin) {
|
@NotNull final PluginLike plugin) {
|
||||||
super(Eco.getHandler().getConfigFactory().createLoadableYamlConfig(configName, plugin, "", plugin.getClass()));
|
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
|
||||||
|
}
|
||||||
@@ -20,7 +20,7 @@ public class Display {
|
|||||||
/**
|
/**
|
||||||
* The display handler.
|
* The display handler.
|
||||||
*/
|
*/
|
||||||
public static DisplayHandler handler = null;
|
private static DisplayHandler handler = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display on ItemStacks.
|
* Display on ItemStacks.
|
||||||
@@ -160,4 +160,20 @@ public class Display {
|
|||||||
module.display(itemStack, player, args);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ public interface DisplayHandler {
|
|||||||
* @param player The player.
|
* @param player The player.
|
||||||
* @return The ItemStack.
|
* @return The ItemStack.
|
||||||
*/
|
*/
|
||||||
ItemStack display(@NotNull final ItemStack itemStack,
|
ItemStack display(@NotNull ItemStack itemStack,
|
||||||
@Nullable final Player player);
|
@Nullable Player player);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Revert on ItemStacks.
|
* Revert on ItemStacks.
|
||||||
@@ -32,7 +32,7 @@ public interface DisplayHandler {
|
|||||||
* @param itemStack The item.
|
* @param itemStack The item.
|
||||||
* @return The ItemStack.
|
* @return The ItemStack.
|
||||||
*/
|
*/
|
||||||
ItemStack revert(@NotNull final ItemStack itemStack);
|
ItemStack revert(@NotNull ItemStack itemStack);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finalize an ItemStacks.
|
* Finalize an ItemStacks.
|
||||||
@@ -40,7 +40,7 @@ public interface DisplayHandler {
|
|||||||
* @param itemStack The item.
|
* @param itemStack The item.
|
||||||
* @return The ItemStack.
|
* @return The ItemStack.
|
||||||
*/
|
*/
|
||||||
ItemStack finalize(@NotNull final ItemStack itemStack);
|
ItemStack finalize(@NotNull ItemStack itemStack);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unfinalize an ItemStacks.
|
* Unfinalize an ItemStacks.
|
||||||
@@ -48,7 +48,7 @@ public interface DisplayHandler {
|
|||||||
* @param itemStack The item.
|
* @param itemStack The item.
|
||||||
* @return The ItemStack.
|
* @return The ItemStack.
|
||||||
*/
|
*/
|
||||||
ItemStack unfinalize(@NotNull final ItemStack itemStack);
|
ItemStack unfinalize(@NotNull ItemStack itemStack);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If an item is finalized.
|
* If an item is finalized.
|
||||||
@@ -56,5 +56,5 @@ public interface DisplayHandler {
|
|||||||
* @param itemStack The item.
|
* @param itemStack The item.
|
||||||
* @return If finalized.
|
* @return If finalized.
|
||||||
*/
|
*/
|
||||||
boolean isFinalized(@NotNull final ItemStack itemStack);
|
boolean isFinalized(@NotNull ItemStack itemStack);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
package com.willfp.eco.core.extensions;
|
package com.willfp.eco.core.extensions;
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
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.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An extension is a separate jar file that hooks into the base plugin jar.
|
* An extension is a separate jar file that hooks into the base plugin jar.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -15,9 +19,9 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* Syntactically, extensions are very similar to plugins in their own right, except that
|
* Syntactically, extensions are very similar to plugins in their own right, except that
|
||||||
* they are loaded by another plugin.
|
* 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.
|
* The {@link EcoPlugin} that this extension is for.
|
||||||
*/
|
*/
|
||||||
@@ -103,4 +107,14 @@ public abstract class Extension {
|
|||||||
Validate.notNull(metadata, "Metadata cannot be null!");
|
Validate.notNull(metadata, "Metadata cannot be null!");
|
||||||
return this.metadata.version();
|
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.
|
* @param itemStack The ItemStack.
|
||||||
* @return The FastItemStack.
|
* @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)));
|
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);
|
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.
|
* 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;
|
package com.willfp.eco.core.integrations.mcmmo;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.integrations.Integration;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.Event;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -7,7 +8,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
/**
|
/**
|
||||||
* Wrapper class for mcmmo integrations.
|
* Wrapper class for mcmmo integrations.
|
||||||
*/
|
*/
|
||||||
public interface McmmoWrapper {
|
public interface McmmoWrapper extends Integration {
|
||||||
/**
|
/**
|
||||||
* Get bonus drop count of block.
|
* Get bonus drop count of block.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -8,9 +8,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to handle placeholder integrations.
|
* Class to handle placeholder integrations.
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package com.willfp.eco.core.items;
|
|||||||
|
|
||||||
import com.willfp.eco.core.Eco;
|
import com.willfp.eco.core.Eco;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.apache.commons.lang.Validate;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
@@ -12,7 +11,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A custom item has 3 components:
|
* A custom item has 3 components.
|
||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>The key to identify it</li>
|
* <li>The key to identify it</li>
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
package com.willfp.eco.core.items;
|
package com.willfp.eco.core.items;
|
||||||
|
|
||||||
import com.willfp.eco.core.items.args.LookupArgParser;
|
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.EmptyTestableItem;
|
||||||
import com.willfp.eco.core.recipe.parts.MaterialTestableItem;
|
import com.willfp.eco.core.recipe.parts.MaterialTestableItem;
|
||||||
import com.willfp.eco.core.recipe.parts.ModifiedTestableItem;
|
import com.willfp.eco.core.recipe.parts.ModifiedTestableItem;
|
||||||
import com.willfp.eco.core.recipe.parts.TestableStack;
|
import com.willfp.eco.core.recipe.parts.TestableStack;
|
||||||
import com.willfp.eco.util.NamespacedKeyUtils;
|
import com.willfp.eco.util.NamespacedKeyUtils;
|
||||||
|
import com.willfp.eco.util.NumberUtils;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
@@ -16,12 +18,12 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to manage all custom and vanilla items.
|
* Class to manage all custom and vanilla items.
|
||||||
@@ -31,7 +33,12 @@ public final class Items {
|
|||||||
/**
|
/**
|
||||||
* All recipe parts.
|
* 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.
|
* All recipe parts.
|
||||||
@@ -42,11 +49,20 @@ public final class Items {
|
|||||||
* Register a new custom item.
|
* Register a new custom item.
|
||||||
*
|
*
|
||||||
* @param key The key of the item.
|
* @param key The key of the item.
|
||||||
* @param part The item.
|
* @param item The item.
|
||||||
*/
|
*/
|
||||||
public void registerCustomItem(@NotNull final NamespacedKey key,
|
public void registerCustomItem(@NotNull final NamespacedKey key,
|
||||||
@NotNull final CustomItem part) {
|
@NotNull final TestableItem item) {
|
||||||
REGISTRY.put(key, part);
|
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) {
|
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
|
Legacy id:amount format
|
||||||
@@ -146,7 +175,7 @@ public final class Items {
|
|||||||
This has been superseded by namespace:id amount
|
This has been superseded by namespace:id amount
|
||||||
*/
|
*/
|
||||||
if (split.length == 3) {
|
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) {
|
if (part == null) {
|
||||||
return new EmptyTestableItem();
|
return new EmptyTestableItem();
|
||||||
}
|
}
|
||||||
@@ -215,7 +244,7 @@ public final class Items {
|
|||||||
* @return If is recipe.
|
* @return If is recipe.
|
||||||
*/
|
*/
|
||||||
public boolean isCustomItem(@NotNull final ItemStack itemStack) {
|
public boolean isCustomItem(@NotNull final ItemStack itemStack) {
|
||||||
for (CustomItem item : REGISTRY.values()) {
|
for (TestableItem item : REGISTRY.values()) {
|
||||||
if (item.matches(itemStack)) {
|
if (item.matches(itemStack)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -231,9 +260,9 @@ public final class Items {
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public CustomItem getCustomItem(@NotNull final ItemStack itemStack) {
|
public CustomItem getCustomItem(@NotNull final ItemStack itemStack) {
|
||||||
for (CustomItem item : REGISTRY.values()) {
|
for (TestableItem item : REGISTRY.values()) {
|
||||||
if (item.matches(itemStack)) {
|
if (item.matches(itemStack)) {
|
||||||
return item;
|
return getOrWrap(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -245,6 +274,27 @@ public final class Items {
|
|||||||
* @return A set of all items.
|
* @return A set of all items.
|
||||||
*/
|
*/
|
||||||
public Set<CustomItem> getCustomItems() {
|
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()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public class TextureArgParser implements LookupArgParser {
|
|||||||
|
|
||||||
assert testMeta != null;
|
assert testMeta != null;
|
||||||
|
|
||||||
if (testMeta instanceof SkullMeta skullMeta && finalSkullTexture != null) {
|
if (testMeta instanceof SkullMeta skullMeta) {
|
||||||
return finalSkullTexture.equalsIgnoreCase(SkullUtils.getSkullTexture(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);
|
||||||
|
}
|
||||||
@@ -2,7 +2,6 @@ package com.willfp.eco.core.recipe.parts;
|
|||||||
|
|
||||||
import com.willfp.eco.core.items.TestableItem;
|
import com.willfp.eco.core.items.TestableItem;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.apache.commons.lang.Validate;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.willfp.eco.core.Eco;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -11,7 +12,6 @@ import java.io.InputStreamReader;
|
|||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@@ -40,45 +40,42 @@ public class Paste {
|
|||||||
* <p>
|
* <p>
|
||||||
* Runs asynchronously to avoid hangups.
|
* 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(() -> {
|
Eco.getHandler().getEcoPlugin().getScheduler().runAsync(() -> {
|
||||||
try {
|
try {
|
||||||
String url = "https://hastebin.com/documents";
|
byte[] postData = contents.getBytes(StandardCharsets.UTF_8);
|
||||||
URL obj = new URL(url);
|
int postDataLength = postData.length;
|
||||||
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
|
|
||||||
|
|
||||||
con.setRequestMethod("POST");
|
String requestURL = "https://hastebin.com/documents";
|
||||||
con.setRequestProperty("Content-Type", "application/json");
|
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);
|
String response;
|
||||||
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
|
DataOutputStream wr;
|
||||||
wr.writeBytes(URLEncoder.encode(contents, StandardCharsets.UTF_8));
|
|
||||||
wr.flush();
|
|
||||||
wr.close();
|
|
||||||
|
|
||||||
BufferedReader iny = new BufferedReader(
|
wr = new DataOutputStream(conn.getOutputStream());
|
||||||
new InputStreamReader(con.getInputStream()));
|
wr.write(postData);
|
||||||
String output;
|
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||||
StringBuilder responseBuilder = new StringBuilder();
|
response = reader.readLine();
|
||||||
|
|
||||||
while ((output = iny.readLine()) != null) {
|
assert response != null;
|
||||||
responseBuilder.append(output);
|
|
||||||
|
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) {
|
} catch (IOException e) {
|
||||||
responseHandler.accept(e.getMessage());
|
callback.accept(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
responseHandler.accept("");
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +93,7 @@ public class Paste {
|
|||||||
conn.setRequestMethod("GET");
|
conn.setRequestMethod("GET");
|
||||||
try (var reader = new BufferedReader(
|
try (var reader = new BufferedReader(
|
||||||
new InputStreamReader(conn.getInputStream()))) {
|
new InputStreamReader(conn.getInputStream()))) {
|
||||||
for (String line; (line = reader.readLine()) != null; ) {
|
for (String line; (line = reader.readLine()) != null;) {
|
||||||
result.append(line);
|
result.append(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ public class UpdateChecker extends PluginDependent<EcoPlugin> {
|
|||||||
/**
|
/**
|
||||||
* Get the latest version of the plugin.
|
* 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(() -> {
|
this.getPlugin().getScheduler().runAsync(() -> {
|
||||||
try {
|
try {
|
||||||
InputStream inputStream = new URL(
|
InputStream inputStream = new URL(
|
||||||
@@ -37,7 +37,7 @@ public class UpdateChecker extends PluginDependent<EcoPlugin> {
|
|||||||
Scanner scanner = new Scanner(inputStream);
|
Scanner scanner = new Scanner(inputStream);
|
||||||
|
|
||||||
if (scanner.hasNext()) {
|
if (scanner.hasNext()) {
|
||||||
consumer.accept(scanner.next());
|
callback.accept(scanner.next());
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
this.getPlugin().getLogger().warning("Failed to check for updates: " + e.getMessage());
|
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 lombok.experimental.UtilityClass;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@@ -92,6 +94,21 @@ public class BlockUtils {
|
|||||||
blockBreakConsumer.accept(player, block);
|
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.
|
* Initialize the block break function.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utilities / API methods for lists.
|
* Utilities / API methods for lists.
|
||||||
@@ -21,8 +23,8 @@ public class ListUtils {
|
|||||||
* @return The list, filled will null objects.
|
* @return The list, filled will null objects.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@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) {
|
final int columns) {
|
||||||
List<List<T>> list = new ArrayList<>(rows);
|
List<List<T>> list = new ArrayList<>(rows);
|
||||||
while (list.size() < rows) {
|
while (list.size() < rows) {
|
||||||
List<T> row = new ArrayList<>(columns);
|
List<T> row = new ArrayList<>(columns);
|
||||||
@@ -34,4 +36,25 @@ public class ListUtils {
|
|||||||
|
|
||||||
return list;
|
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;
|
package com.willfp.eco.util;
|
||||||
|
|
||||||
import lombok.experimental.NonFinal;
|
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
package com.willfp.eco.util;
|
package com.willfp.eco.util;
|
||||||
|
|
||||||
import com.willfp.eco.core.Eco;
|
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 lombok.experimental.UtilityClass;
|
||||||
import net.kyori.adventure.audience.Audience;
|
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.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -12,6 +18,15 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
*/
|
*/
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class PlayerUtils {
|
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.
|
* Get the audience from a player.
|
||||||
*
|
*
|
||||||
@@ -20,7 +35,21 @@ public class PlayerUtils {
|
|||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public Audience getAudience(@NotNull final Player player) {
|
public Audience getAudience(@NotNull final Player player) {
|
||||||
return Eco.getHandler().getAdventure().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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,6 +60,46 @@ public class PlayerUtils {
|
|||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public Audience getAudience(@NotNull final CommandSender sender) {
|
public Audience getAudience(@NotNull final CommandSender sender) {
|
||||||
return Eco.getHandler().getAdventure().sender(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,6 +1,8 @@
|
|||||||
package com.willfp.eco.util;
|
package com.willfp.eco.util;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
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 com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
@@ -14,15 +16,21 @@ import org.bukkit.entity.Player;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.Color;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
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.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.
|
* Utilities / API methods for strings.
|
||||||
@@ -60,6 +68,22 @@ public class StringUtils {
|
|||||||
.hexColors()
|
.hexColors()
|
||||||
.build();
|
.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.
|
* Format a list of strings.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -250,10 +274,12 @@ public class StringUtils {
|
|||||||
if (option == FormatOption.WITH_PLACEHOLDERS) {
|
if (option == FormatOption.WITH_PLACEHOLDERS) {
|
||||||
processedMessage = PlaceholderManager.translatePlaceholders(processedMessage, player);
|
processedMessage = PlaceholderManager.translatePlaceholders(processedMessage, player);
|
||||||
}
|
}
|
||||||
processedMessage = translateGradients(processedMessage);
|
|
||||||
processedMessage = translateMiniMessage(processedMessage);
|
|
||||||
processedMessage = translateHexColorCodes(processedMessage);
|
|
||||||
processedMessage = ChatColor.translateAlternateColorCodes('&', processedMessage);
|
processedMessage = ChatColor.translateAlternateColorCodes('&', processedMessage);
|
||||||
|
processedMessage = translateGradients(processedMessage);
|
||||||
|
processedMessage = translateHexColorCodes(processedMessage);
|
||||||
|
if (Prerequisite.HAS_PAPER.isMet()) {
|
||||||
|
processedMessage = translateMiniMessage(processedMessage);
|
||||||
|
}
|
||||||
return processedMessage;
|
return processedMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,26 +316,12 @@ public class StringUtils {
|
|||||||
@NotNull final Color end) {
|
@NotNull final Color end) {
|
||||||
String processedString = string;
|
String processedString = string;
|
||||||
List<ChatColor> modifiers = new ArrayList<>();
|
List<ChatColor> modifiers = new ArrayList<>();
|
||||||
if (processedString.contains("&l")) {
|
for (Map.Entry<String, ChatColor> entry : COLOR_MAP.entrySet()) {
|
||||||
modifiers.add(ChatColor.BOLD);
|
if (processedString.contains(entry.getKey())) {
|
||||||
|
modifiers.add(entry.getValue());
|
||||||
|
}
|
||||||
|
processedString = processedString.replace(entry.getKey(), "");
|
||||||
}
|
}
|
||||||
if (processedString.contains("&o")) {
|
|
||||||
modifiers.add(ChatColor.ITALIC);
|
|
||||||
}
|
|
||||||
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();
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
ChatColor[] colors = getGradientColors(start, end, processedString.length());
|
ChatColor[] colors = getGradientColors(start, end, processedString.length());
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ buildscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,4 +18,12 @@ subprojects {
|
|||||||
compileOnly project(":eco-api")
|
compileOnly project(":eco-api")
|
||||||
compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:1.5.31'
|
compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:1.5.31'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compileKotlin {
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "16"
|
||||||
|
}
|
||||||
|
targetCompatibility = JavaVersion.VERSION_16
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_16
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -7,4 +7,5 @@ dependencies {
|
|||||||
compileOnly 'org.reflections:reflections:0.9.12'
|
compileOnly 'org.reflections:reflections:0.9.12'
|
||||||
compileOnly 'net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT'
|
compileOnly 'net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT'
|
||||||
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
|
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
|
||||||
|
compileOnly 'com.google.guava:guava:31.0.1-jre'
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.willfp.eco.internal.config
|
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.Config
|
||||||
import com.willfp.eco.core.config.interfaces.JSONConfig
|
import com.willfp.eco.core.config.interfaces.JSONConfig
|
||||||
import com.willfp.eco.core.config.wrapper.ConfigFactory
|
import com.willfp.eco.core.config.wrapper.ConfigFactory
|
||||||
@@ -15,7 +15,7 @@ import org.bukkit.configuration.file.YamlConfiguration
|
|||||||
class EcoConfigFactory : ConfigFactory {
|
class EcoConfigFactory : ConfigFactory {
|
||||||
override fun createUpdatableYamlConfig(
|
override fun createUpdatableYamlConfig(
|
||||||
configName: String,
|
configName: String,
|
||||||
plugin: EcoPlugin,
|
plugin: PluginLike,
|
||||||
subDirectoryPath: String,
|
subDirectoryPath: String,
|
||||||
source: Class<*>,
|
source: Class<*>,
|
||||||
removeUnused: Boolean,
|
removeUnused: Boolean,
|
||||||
@@ -33,7 +33,7 @@ class EcoConfigFactory : ConfigFactory {
|
|||||||
|
|
||||||
override fun createUpdatableJSONConfig(
|
override fun createUpdatableJSONConfig(
|
||||||
configName: String,
|
configName: String,
|
||||||
plugin: EcoPlugin,
|
plugin: PluginLike,
|
||||||
subDirectoryPath: String,
|
subDirectoryPath: String,
|
||||||
source: Class<*>,
|
source: Class<*>,
|
||||||
removeUnused: Boolean,
|
removeUnused: Boolean,
|
||||||
@@ -51,7 +51,7 @@ class EcoConfigFactory : ConfigFactory {
|
|||||||
|
|
||||||
override fun createLoadableJSONConfig(
|
override fun createLoadableJSONConfig(
|
||||||
configName: String,
|
configName: String,
|
||||||
plugin: EcoPlugin,
|
plugin: PluginLike,
|
||||||
subDirectoryPath: String,
|
subDirectoryPath: String,
|
||||||
source: Class<*>
|
source: Class<*>
|
||||||
): JSONConfig {
|
): JSONConfig {
|
||||||
@@ -65,7 +65,7 @@ class EcoConfigFactory : ConfigFactory {
|
|||||||
|
|
||||||
override fun createLoadableYamlConfig(
|
override fun createLoadableYamlConfig(
|
||||||
configName: String,
|
configName: String,
|
||||||
plugin: EcoPlugin,
|
plugin: PluginLike,
|
||||||
subDirectoryPath: String,
|
subDirectoryPath: String,
|
||||||
source: Class<*>
|
source: Class<*>
|
||||||
): Config {
|
): Config {
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import com.google.gson.Gson
|
|||||||
import com.google.gson.GsonBuilder
|
import com.google.gson.GsonBuilder
|
||||||
import com.willfp.eco.core.config.interfaces.JSONConfig
|
import com.willfp.eco.core.config.interfaces.JSONConfig
|
||||||
import com.willfp.eco.util.StringUtils
|
import com.willfp.eco.util.StringUtils
|
||||||
import org.apache.commons.lang.Validate
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
@@ -124,8 +123,7 @@ open class EcoJSONConfigWrapper : JSONConfig {
|
|||||||
|
|
||||||
override fun getSubsection(path: String): JSONConfig {
|
override fun getSubsection(path: String): JSONConfig {
|
||||||
val subsection = getSubsectionOrNull(path)
|
val subsection = getSubsectionOrNull(path)
|
||||||
Validate.notNull(subsection)
|
return subsection ?: EcoJSONConfigSection(emptyMap())
|
||||||
return subsection!!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSubsectionOrNull(path: String): JSONConfig? {
|
override fun getSubsectionOrNull(path: String): JSONConfig? {
|
||||||
|
|||||||
@@ -1,16 +1,20 @@
|
|||||||
package com.willfp.eco.internal.config.json
|
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 com.willfp.eco.core.config.interfaces.LoadableConfig
|
||||||
import org.jetbrains.annotations.NotNull
|
import java.io.File
|
||||||
import java.io.*
|
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.Files
|
||||||
import java.nio.file.StandardOpenOption
|
import java.nio.file.StandardOpenOption
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
open class EcoLoadableJSONConfig(
|
open class EcoLoadableJSONConfig(
|
||||||
configName: String,
|
configName: String,
|
||||||
private val plugin: EcoPlugin,
|
private val plugin: PluginLike,
|
||||||
private val subDirectoryPath: String,
|
private val subDirectoryPath: String,
|
||||||
val source: Class<*>
|
val source: Class<*>
|
||||||
) : EcoJSONConfigWrapper(), LoadableConfig {
|
) : EcoJSONConfigWrapper(), LoadableConfig {
|
||||||
@@ -77,7 +81,7 @@ open class EcoLoadableJSONConfig(
|
|||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val directory: File = File(this.plugin.dataFolder, subDirectoryPath)
|
val directory = File(this.plugin.dataFolder, subDirectoryPath)
|
||||||
if (!directory.exists()) {
|
if (!directory.exists()) {
|
||||||
directory.mkdirs()
|
directory.mkdirs()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.willfp.eco.internal.config.json
|
package com.willfp.eco.internal.config.json
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin
|
import com.willfp.eco.core.PluginLike
|
||||||
import org.bukkit.configuration.InvalidConfigurationException
|
import org.bukkit.configuration.InvalidConfigurationException
|
||||||
import org.bukkit.configuration.file.YamlConfiguration
|
import org.bukkit.configuration.file.YamlConfiguration
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
@@ -10,7 +10,7 @@ import java.nio.charset.StandardCharsets
|
|||||||
|
|
||||||
open class EcoUpdatableJSONConfig(
|
open class EcoUpdatableJSONConfig(
|
||||||
configName: String,
|
configName: String,
|
||||||
plugin: EcoPlugin,
|
plugin: PluginLike,
|
||||||
subDirectoryPath: String,
|
subDirectoryPath: String,
|
||||||
source: Class<*>,
|
source: Class<*>,
|
||||||
private val removeUnused: Boolean,
|
private val removeUnused: Boolean,
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import com.willfp.eco.internal.config.yaml.EcoLoadableYamlConfig
|
|||||||
import com.willfp.eco.internal.config.yaml.EcoUpdatableYamlConfig
|
import com.willfp.eco.internal.config.yaml.EcoUpdatableYamlConfig
|
||||||
import org.reflections.Reflections
|
import org.reflections.Reflections
|
||||||
import org.reflections.scanners.MethodAnnotationsScanner
|
import org.reflections.scanners.MethodAnnotationsScanner
|
||||||
import java.lang.reflect.Modifier
|
|
||||||
|
|
||||||
class EcoConfigHandler(
|
class EcoConfigHandler(
|
||||||
private val plugin: EcoPlugin
|
private val plugin: EcoPlugin
|
||||||
@@ -25,10 +24,6 @@ class EcoConfigHandler(
|
|||||||
|
|
||||||
override fun callUpdate() {
|
override fun callUpdate() {
|
||||||
for (method in reflections.getMethodsAnnotatedWith(ConfigUpdater::class.java)) {
|
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 {
|
try {
|
||||||
when (method.parameterCount) {
|
when (method.parameterCount) {
|
||||||
0 -> method.invoke(null)
|
0 -> method.invoke(null)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.willfp.eco.internal.config.yaml
|
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.LoadableConfig
|
||||||
import com.willfp.eco.core.config.interfaces.WrappedYamlConfiguration
|
import com.willfp.eco.core.config.interfaces.WrappedYamlConfiguration
|
||||||
import org.bukkit.configuration.InvalidConfigurationException
|
import org.bukkit.configuration.InvalidConfigurationException
|
||||||
@@ -12,7 +12,7 @@ import java.io.OutputStream
|
|||||||
|
|
||||||
open class EcoLoadableYamlConfig(
|
open class EcoLoadableYamlConfig(
|
||||||
configName: String,
|
configName: String,
|
||||||
private val plugin: EcoPlugin,
|
private val plugin: PluginLike,
|
||||||
private val subDirectoryPath: String,
|
private val subDirectoryPath: String,
|
||||||
val source: Class<*>
|
val source: Class<*>
|
||||||
) : EcoYamlConfigWrapper<YamlConfiguration>(), WrappedYamlConfiguration, LoadableConfig {
|
) : EcoYamlConfigWrapper<YamlConfiguration>(), WrappedYamlConfiguration, LoadableConfig {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.willfp.eco.internal.config.yaml
|
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.InvalidConfigurationException
|
||||||
import org.bukkit.configuration.file.YamlConfiguration
|
import org.bukkit.configuration.file.YamlConfiguration
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
@@ -10,7 +10,7 @@ import java.nio.charset.StandardCharsets
|
|||||||
|
|
||||||
class EcoUpdatableYamlConfig(
|
class EcoUpdatableYamlConfig(
|
||||||
configName: String,
|
configName: String,
|
||||||
plugin: EcoPlugin,
|
plugin: PluginLike,
|
||||||
subDirectoryPath: String,
|
subDirectoryPath: String,
|
||||||
source: Class<*>,
|
source: Class<*>,
|
||||||
private val removeUnused: Boolean,
|
private val removeUnused: Boolean,
|
||||||
@@ -27,9 +27,9 @@ class EcoUpdatableYamlConfig(
|
|||||||
if (newConfig.getKeys(true) == this.handle.getKeys(true)) {
|
if (newConfig.getKeys(true) == this.handle.getKeys(true)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
newConfig.getKeys(true).forEach { key: String ->
|
newConfig.getKeys(true).forEach { key ->
|
||||||
if (!this.handle.getKeys(true).contains(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])
|
this.handle.set(key, newConfig[key])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ class EcoUpdatableYamlConfig(
|
|||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
this.updateBlacklist.removeIf { obj: String -> obj.isEmpty() }
|
this.updateBlacklist.removeIf { it.isEmpty() }
|
||||||
plugin.configHandler.addConfig(this)
|
plugin.configHandler.addConfig(this)
|
||||||
update()
|
update()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package com.willfp.eco.internal.config.yaml
|
|||||||
|
|
||||||
import com.willfp.eco.core.config.interfaces.Config
|
import com.willfp.eco.core.config.interfaces.Config
|
||||||
import com.willfp.eco.util.StringUtils
|
import com.willfp.eco.util.StringUtils
|
||||||
import org.apache.commons.lang.Validate
|
|
||||||
import org.bukkit.configuration.ConfigurationSection
|
import org.bukkit.configuration.ConfigurationSection
|
||||||
import org.bukkit.configuration.file.YamlConfiguration
|
import org.bukkit.configuration.file.YamlConfiguration
|
||||||
import java.io.StringReader
|
import java.io.StringReader
|
||||||
@@ -52,8 +51,7 @@ open class EcoYamlConfigWrapper<T : ConfigurationSection> : Config {
|
|||||||
|
|
||||||
override fun getSubsection(path: String): Config {
|
override fun getSubsection(path: String): Config {
|
||||||
val subsection = getSubsectionOrNull(path)
|
val subsection = getSubsectionOrNull(path)
|
||||||
Validate.notNull(subsection)
|
return subsection ?: EcoYamlConfigSection(YamlConfiguration())
|
||||||
return subsection!!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSubsectionOrNull(path: String): Config? {
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.willfp.eco.internal.display
|
package com.willfp.eco.internal.display
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.ThreadFactoryBuilder
|
||||||
import com.willfp.eco.core.EcoPlugin
|
import com.willfp.eco.core.EcoPlugin
|
||||||
import com.willfp.eco.core.display.Display
|
import com.willfp.eco.core.display.Display
|
||||||
import com.willfp.eco.core.display.DisplayHandler
|
import com.willfp.eco.core.display.DisplayHandler
|
||||||
@@ -10,16 +11,11 @@ import org.bukkit.NamespacedKey
|
|||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
import org.bukkit.persistence.PersistentDataType
|
import org.bukkit.persistence.PersistentDataType
|
||||||
|
import java.util.concurrent.ExecutorService
|
||||||
|
import java.util.concurrent.Executors
|
||||||
|
|
||||||
class EcoDisplayHandler(plugin: EcoPlugin) : DisplayHandler {
|
class EcoDisplayHandler(plugin: EcoPlugin) : DisplayHandler {
|
||||||
/**
|
|
||||||
* All registered display modules.
|
|
||||||
*/
|
|
||||||
private val registeredModules = mutableMapOf<DisplayPriority, MutableList<DisplayModule>>()
|
private val registeredModules = mutableMapOf<DisplayPriority, MutableList<DisplayModule>>()
|
||||||
|
|
||||||
/**
|
|
||||||
* NamespacedKey for finalizing.
|
|
||||||
*/
|
|
||||||
private val finalizeKey: NamespacedKey = plugin.namespacedKeyFactory.create("finalized")
|
private val finalizeKey: NamespacedKey = plugin.namespacedKeyFactory.create("finalized")
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|||||||
@@ -12,10 +12,9 @@ import org.bukkit.event.player.PlayerExpChangeEvent
|
|||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
import org.bukkit.util.Vector
|
import org.bukkit.util.Vector
|
||||||
|
|
||||||
open class EcoDropQueue(player: Player) : InternalDropQueue {
|
open class EcoDropQueue(val player: Player) : InternalDropQueue {
|
||||||
val items = mutableListOf<ItemStack>()
|
val items = mutableListOf<ItemStack>()
|
||||||
var xp: Int = 0
|
var xp: Int = 0
|
||||||
val player: Player
|
|
||||||
var loc: Location
|
var loc: Location
|
||||||
var hasTelekinesis = false
|
var hasTelekinesis = false
|
||||||
|
|
||||||
@@ -79,7 +78,6 @@ open class EcoDropQueue(player: Player) : InternalDropQueue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
this.player = player
|
|
||||||
loc = player.location
|
loc = player.location
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,4 +3,6 @@ version rootProject.version
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly 'org.spigotmc:spigot:1.16.5-R0.1-SNAPSHOT'
|
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 = meta.javaClass.getDeclaredField("profile")
|
||||||
profile.isAccessible = true
|
profile.isAccessible = true
|
||||||
}
|
}
|
||||||
val profile = profile[meta] as GameProfile?
|
val profile = profile[meta] as GameProfile? ?: return null
|
||||||
val property = profile?.properties?.get("textures") as Property?
|
val properties = profile.properties ?: return null
|
||||||
return property?.value
|
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
|
package com.willfp.eco.proxy.v1_16_R3.fast
|
||||||
|
|
||||||
import com.willfp.eco.internal.fast.EcoFastItemStack
|
import com.willfp.eco.internal.fast.EcoFastItemStack
|
||||||
import com.willfp.eco.proxy.v1_16_R3.FastItemStackUtils
|
|
||||||
import com.willfp.eco.util.StringUtils
|
import com.willfp.eco.util.StringUtils
|
||||||
import net.minecraft.server.v1_16_R3.*
|
import net.minecraft.server.v1_16_R3.*
|
||||||
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack
|
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack
|
||||||
@@ -12,7 +11,7 @@ import org.bukkit.inventory.ItemFlag
|
|||||||
import kotlin.experimental.and
|
import kotlin.experimental.and
|
||||||
|
|
||||||
class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemStack<ItemStack>(
|
class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemStack<ItemStack>(
|
||||||
FastItemStackUtils.getNMSStack(itemStack), itemStack
|
itemStack.getNMSStack(), itemStack
|
||||||
) {
|
) {
|
||||||
private var loreCache: List<String>? = null
|
private var loreCache: List<String>? = null
|
||||||
override fun getEnchantmentsOnItem(checkStored: Boolean): Map<Enchantment, Int> {
|
override fun getEnchantmentsOnItem(checkStored: Boolean): Map<Enchantment, Int> {
|
||||||
@@ -151,6 +150,18 @@ class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemS
|
|||||||
handle.repairCost = cost
|
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() {
|
private fun apply() {
|
||||||
if (bukkit !is CraftItemStack) {
|
if (bukkit !is CraftItemStack) {
|
||||||
bukkit.itemMeta = CraftItemStack.asCraftMirror(handle).itemMeta
|
bukkit.itemMeta = CraftItemStack.asCraftMirror(handle).itemMeta
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ version rootProject.version
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly 'org.spigotmc:spigot:1.17.1-R0.1-SNAPSHOT:remapped-mojang'
|
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 {
|
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 = meta.javaClass.getDeclaredField("profile")
|
||||||
profile.isAccessible = true
|
profile.isAccessible = true
|
||||||
}
|
}
|
||||||
val profile = profile[meta] as GameProfile?
|
val profile = profile[meta] as GameProfile? ?: return null
|
||||||
val property = profile?.properties?.get("textures") as Property?
|
val properties = profile.properties ?: return null
|
||||||
return property?.value
|
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
|
package com.willfp.eco.proxy.v1_17_R1.fast
|
||||||
|
|
||||||
import com.willfp.eco.internal.fast.EcoFastItemStack
|
import com.willfp.eco.internal.fast.EcoFastItemStack
|
||||||
import com.willfp.eco.proxy.v1_17_R1.FastItemStackUtils
|
|
||||||
import com.willfp.eco.util.StringUtils
|
import com.willfp.eco.util.StringUtils
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.nbt.ListTag
|
import net.minecraft.nbt.ListTag
|
||||||
import net.minecraft.nbt.StringTag
|
import net.minecraft.nbt.StringTag
|
||||||
import net.minecraft.world.item.EnchantedBookItem
|
import net.minecraft.world.item.EnchantedBookItem
|
||||||
|
import net.minecraft.world.item.Item
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.item.Items
|
import net.minecraft.world.item.Items
|
||||||
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack
|
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack
|
||||||
@@ -17,7 +17,7 @@ import org.bukkit.inventory.ItemFlag
|
|||||||
import kotlin.experimental.and
|
import kotlin.experimental.and
|
||||||
|
|
||||||
class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemStack<ItemStack>(
|
class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemStack<ItemStack>(
|
||||||
FastItemStackUtils.getNMSStack(itemStack), itemStack
|
itemStack.getNMSStack(), itemStack
|
||||||
) {
|
) {
|
||||||
private var loreCache: List<String>? = null
|
private var loreCache: List<String>? = null
|
||||||
|
|
||||||
@@ -171,6 +171,18 @@ class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemS
|
|||||||
handle.setRepairCost(cost)
|
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() {
|
private fun apply() {
|
||||||
if (bukkit !is CraftItemStack) {
|
if (bukkit !is CraftItemStack) {
|
||||||
bukkit.itemMeta = CraftItemStack.asCraftMirror(handle).itemMeta
|
bukkit.itemMeta = CraftItemStack.asCraftMirror(handle).itemMeta
|
||||||
|
|||||||
@@ -3,32 +3,43 @@ version rootProject.version
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'org.bstats:bstats-bukkit:1.7'
|
implementation 'org.bstats:bstats-bukkit:1.7'
|
||||||
implementation 'net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT'
|
implementation('net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT') {
|
||||||
implementation 'net.kyori:adventure-platform-bukkit:4.0.0'
|
exclude group: 'net.kyori', module: 'adventure-api'
|
||||||
implementation 'net.kyori:adventure-api:4.9.1'
|
}
|
||||||
implementation 'net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT'
|
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
|
||||||
implementation 'net.kyori:adventure-text-serializer-gson:4.8.1'
|
compileOnly 'net.kyori:adventure-api:4.9.2'
|
||||||
implementation 'net.kyori:adventure-text-serializer-legacy:4.8.1'
|
compileOnly 'net.kyori:adventure-text-serializer-gson:4.9.2'
|
||||||
compileOnly 'org.apache.maven:maven-artifact:3.0.3'
|
compileOnly 'net.kyori:adventure-text-serializer-legacy:4.9.2'
|
||||||
compileOnly 'com.google.code.gson:gson:2.8.7'
|
compileOnly 'org.apache.maven:maven-artifact:3.8.1'
|
||||||
|
compileOnly 'com.google.code.gson:gson:2.8.8'
|
||||||
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
|
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
|
||||||
compileOnly project(":eco-core:core-proxy")
|
compileOnly project(":eco-core:core-proxy")
|
||||||
compileOnly project(":eco-core:core-backend")
|
compileOnly project(":eco-core:core-backend")
|
||||||
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.0-SNAPSHOT'
|
compileOnly 'com.comphenix.protocol:ProtocolLib:4.7.1-SNAPSHOT'
|
||||||
compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.4-SNAPSHOT'
|
compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.7-SNAPSHOT'
|
||||||
compileOnly 'com.github.TechFortress:GriefPrevention:16.17.1'
|
compileOnly 'com.github.TechFortress:GriefPrevention:16.17.1'
|
||||||
compileOnly 'com.massivecraft:Factions:1.6.9.5-U0.5.10'
|
compileOnly 'com.massivecraft:Factions:1.6.9.5-U0.5.10'
|
||||||
compileOnly 'com.github.cryptomorin:kingdoms:1.10.14'
|
compileOnly 'com.github.cryptomorin:kingdoms:1.11.9'
|
||||||
compileOnly 'com.github.TownyAdvanced:Towny:0.97.1.0'
|
compileOnly 'com.github.TownyAdvanced:Towny:0.97.2.6'
|
||||||
compileOnly 'com.github.angeschossen:LandsAPI:4.7.3'
|
compileOnly 'com.github.angeschossen:LandsAPI:5.15.2'
|
||||||
compileOnly 'fr.neatmonster:nocheatplus:3.16.1-SNAPSHOT'
|
compileOnly 'fr.neatmonster:nocheatplus:3.16.1-SNAPSHOT'
|
||||||
compileOnly 'com.github.jiangdashao:matrix-api-repo:317d4635fd'
|
compileOnly 'com.github.jiangdashao:matrix-api-repo:317d4635fd'
|
||||||
compileOnly 'com.gmail.nossr50.mcMMO:mcMMO:2.1.157'
|
compileOnly 'com.gmail.nossr50.mcMMO:mcMMO:2.1.202'
|
||||||
compileOnly 'me.clip:placeholderapi:2.10.10'
|
compileOnly 'me.clip:placeholderapi:2.10.10'
|
||||||
compileOnly 'com.willfp:Oraxen:e1f4003d8d'
|
compileOnly 'com.github.oraxen:oraxen:bd81ace154'
|
||||||
compileOnly 'com.github.brcdev-minecraft:shopgui-api:2.2.0'
|
compileOnly 'com.github.brcdev-minecraft:shopgui-api:2.2.0'
|
||||||
compileOnly 'com.github.LoneDev6:API-ItemsAdder:2.4.7'
|
compileOnly 'com.github.LoneDev6:API-ItemsAdder:2.4.7'
|
||||||
compileOnly 'me.arcaniax:HeadDatabase-API:1.2.0'
|
compileOnly 'com.arcaniax:HeadDatabase-API:1.3.0'
|
||||||
|
compileOnly 'org.jetbrains.exposed:exposed-core:0.35.1'
|
||||||
|
compileOnly 'org.jetbrains.exposed:exposed-dao:0.35.1'
|
||||||
|
compileOnly 'org.jetbrains.exposed:exposed-jdbc:0.35.1'
|
||||||
|
compileOnly 'mysql:mysql-connector-java:8.0.25'
|
||||||
|
compileOnly 'com.gmail.filoghost.holographicdisplays:holographicdisplays-api:2.4.0'
|
||||||
|
compileOnly 'net.essentialsx:EssentialsX:2.19.0'
|
||||||
|
compileOnly 'com.bgsoftware:SuperiorSkyblockAPI:latest'
|
||||||
|
compileOnly 'com.github.MilkBowl:VaultAPI:1.7'
|
||||||
|
compileOnly 'world.bentobox:bentobox:1.17.3-SNAPSHOT'
|
||||||
|
compileOnly 'com.google.guava:guava:31.0.1-jre'
|
||||||
|
|
||||||
// CombatLogX V10 + NewbieHelper Expansion
|
// CombatLogX V10 + NewbieHelper Expansion
|
||||||
compileOnly 'com.SirBlobman.combatlogx:CombatLogX-API:10.0.0.0-SNAPSHOT'
|
compileOnly 'com.SirBlobman.combatlogx:CombatLogX-API:10.0.0.0-SNAPSHOT'
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
package com.willfp.eco.spigot.eventlisteners;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.PluginDependent;
|
|
||||||
import com.willfp.eco.core.events.ArmorChangeEvent;
|
|
||||||
import com.willfp.eco.core.events.ArmorEquipEvent;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public class ArmorChangeEventListeners extends PluginDependent<EcoPlugin> implements Listener {
|
|
||||||
/**
|
|
||||||
* Pass an {@link EcoPlugin} in order to interface with it.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin to manage.
|
|
||||||
*/
|
|
||||||
public ArmorChangeEventListeners(@NotNull final EcoPlugin plugin) {
|
|
||||||
super(plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onArmorChange(@NotNull final ArmorEquipEvent event) {
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
|
|
||||||
List<ItemStack> before = new ArrayList<>(Arrays.asList(player.getInventory().getArmorContents()));
|
|
||||||
|
|
||||||
this.getPlugin().getScheduler().runLater(() -> {
|
|
||||||
List<ItemStack> after = new ArrayList<>(Arrays.asList(player.getInventory().getArmorContents()));
|
|
||||||
|
|
||||||
ArmorChangeEvent armorChangeEvent = new ArmorChangeEvent(player, before, after);
|
|
||||||
Bukkit.getPluginManager().callEvent(armorChangeEvent);
|
|
||||||
}, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,187 +0,0 @@
|
|||||||
package com.willfp.eco.spigot.eventlisteners;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.events.ArmorEquipEvent;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.Event.Result;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.block.Action;
|
|
||||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
|
||||||
import org.bukkit.event.inventory.ClickType;
|
|
||||||
import org.bukkit.event.inventory.InventoryAction;
|
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
|
||||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
|
||||||
import org.bukkit.event.inventory.InventoryType;
|
|
||||||
import org.bukkit.event.inventory.InventoryType.SlotType;
|
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
|
||||||
import org.bukkit.event.player.PlayerItemBreakEvent;
|
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
|
||||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public class ArmorListener implements Listener {
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public final void inventoryClick(@NotNull final InventoryClickEvent event) {
|
|
||||||
boolean shift = false;
|
|
||||||
boolean numberkey = false;
|
|
||||||
if (event.isCancelled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (event.getAction() == InventoryAction.NOTHING) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (event.getClick().equals(ClickType.SHIFT_LEFT) || event.getClick().equals(ClickType.SHIFT_RIGHT)) {
|
|
||||||
shift = true;
|
|
||||||
}
|
|
||||||
if (event.getClick().equals(ClickType.NUMBER_KEY)) {
|
|
||||||
numberkey = true;
|
|
||||||
}
|
|
||||||
if (event.getSlotType() != SlotType.ARMOR && event.getSlotType() != SlotType.QUICKBAR && event.getSlotType() != SlotType.CONTAINER) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (event.getClickedInventory() != null && !event.getClickedInventory().getType().equals(InventoryType.PLAYER)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!event.getInventory().getType().equals(InventoryType.CRAFTING) && !event.getInventory().getType().equals(InventoryType.PLAYER)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!(event.getWhoClicked() instanceof Player)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ArmorType newArmorType = ArmorType.matchType(shift ? event.getCurrentItem() : event.getCursor());
|
|
||||||
if (!shift && newArmorType != null && event.getRawSlot() != newArmorType.getSlot()) {
|
|
||||||
// Used for drag and drop checking to make sure you aren't trying to place a helmet in the boots slot.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (shift) {
|
|
||||||
newArmorType = ArmorType.matchType(event.getCurrentItem());
|
|
||||||
if (newArmorType != null) {
|
|
||||||
boolean equipping = true;
|
|
||||||
if (event.getRawSlot() == newArmorType.getSlot()) {
|
|
||||||
equipping = false;
|
|
||||||
}
|
|
||||||
if (newArmorType.equals(ArmorType.HELMET)
|
|
||||||
&& (equipping == isAirOrNull(event.getWhoClicked().getInventory().getHelmet()))
|
|
||||||
|| newArmorType.equals(ArmorType.CHESTPLATE)
|
|
||||||
&& (equipping == isAirOrNull(event.getWhoClicked().getInventory().getChestplate()))
|
|
||||||
|| newArmorType.equals(ArmorType.LEGGINGS)
|
|
||||||
&& (equipping == isAirOrNull(event.getWhoClicked().getInventory().getLeggings()))
|
|
||||||
|| newArmorType.equals(ArmorType.BOOTS)
|
|
||||||
&& (equipping == isAirOrNull(event.getWhoClicked().getInventory().getBoots()))) {
|
|
||||||
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(
|
|
||||||
(Player) event.getWhoClicked()
|
|
||||||
);
|
|
||||||
Bukkit.getPluginManager().callEvent(armorEquipEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (numberkey) {
|
|
||||||
if (event.getClickedInventory().getType().equals(InventoryType.PLAYER)) {
|
|
||||||
ItemStack hotbarItem = event.getClickedInventory().getItem(event.getHotbarButton());
|
|
||||||
if (!isAirOrNull(hotbarItem)) {
|
|
||||||
newArmorType = ArmorType.matchType(hotbarItem);
|
|
||||||
} else {
|
|
||||||
newArmorType = ArmorType.matchType(!isAirOrNull(event.getCurrentItem()) ? event.getCurrentItem() : event.getCursor());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (isAirOrNull(event.getCursor()) && !isAirOrNull(event.getCurrentItem())) {
|
|
||||||
newArmorType = ArmorType.matchType(event.getCurrentItem());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (newArmorType != null && event.getRawSlot() == newArmorType.getSlot()) {
|
|
||||||
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) event.getWhoClicked());
|
|
||||||
Bukkit.getPluginManager().callEvent(armorEquipEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST)
|
|
||||||
public void playerInteractEvent(@NotNull final PlayerInteractEvent e) {
|
|
||||||
if (e.useItemInHand().equals(Result.DENY)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (e.getAction() == Action.PHYSICAL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
|
||||||
Player player = e.getPlayer();
|
|
||||||
if (!e.useInteractedBlock().equals(Result.DENY)) {
|
|
||||||
if (e.getClickedBlock() != null && e.getAction() == Action.RIGHT_CLICK_BLOCK && !player.isSneaking()) {
|
|
||||||
Material mat = e.getClickedBlock().getType();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ArmorType newArmorType = ArmorType.matchType(e.getItem());
|
|
||||||
if (newArmorType != null) {
|
|
||||||
if (newArmorType.equals(ArmorType.HELMET)
|
|
||||||
&& isAirOrNull(e.getPlayer().getInventory().getHelmet())
|
|
||||||
|| newArmorType.equals(ArmorType.CHESTPLATE)
|
|
||||||
&& isAirOrNull(e.getPlayer().getInventory().getChestplate())
|
|
||||||
|| newArmorType.equals(ArmorType.LEGGINGS)
|
|
||||||
&& isAirOrNull(e.getPlayer().getInventory().getLeggings())
|
|
||||||
|| newArmorType.equals(ArmorType.BOOTS)
|
|
||||||
&& isAirOrNull(e.getPlayer().getInventory().getBoots())) {
|
|
||||||
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(e.getPlayer());
|
|
||||||
Bukkit.getPluginManager().callEvent(armorEquipEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void inventoryDrag(@NotNull final InventoryDragEvent event) {
|
|
||||||
ArmorType type = ArmorType.matchType(event.getOldCursor());
|
|
||||||
if (event.getRawSlots().isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (type != null && type.getSlot() == event.getRawSlots().stream().findFirst().orElse(0)) {
|
|
||||||
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) event.getWhoClicked());
|
|
||||||
Bukkit.getPluginManager().callEvent(armorEquipEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void playerJoinEvent(@NotNull final PlayerJoinEvent event) {
|
|
||||||
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(event.getPlayer());
|
|
||||||
Bukkit.getPluginManager().callEvent(armorEquipEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void playerRespawnEvent(@NotNull final PlayerRespawnEvent event) {
|
|
||||||
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(event.getPlayer());
|
|
||||||
Bukkit.getPluginManager().callEvent(armorEquipEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void itemBreakEvent(@NotNull final PlayerItemBreakEvent event) {
|
|
||||||
ArmorType type = ArmorType.matchType(event.getBrokenItem());
|
|
||||||
if (type != null) {
|
|
||||||
Player p = event.getPlayer();
|
|
||||||
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(p);
|
|
||||||
Bukkit.getPluginManager().callEvent(armorEquipEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void playerDeathEvent(@NotNull final PlayerDeathEvent event) {
|
|
||||||
Player p = event.getEntity();
|
|
||||||
if (event.getKeepInventory()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (ItemStack i : p.getInventory().getArmorContents()) {
|
|
||||||
if (!isAirOrNull(i)) {
|
|
||||||
Bukkit.getPluginManager().callEvent(new ArmorEquipEvent(p));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isAirOrNull(@Nullable final ItemStack item) {
|
|
||||||
return item == null || item.getType().equals(Material.AIR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package com.willfp.eco.spigot.eventlisteners;
|
|
||||||
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
public enum ArmorType {
|
|
||||||
HELMET(5),
|
|
||||||
CHESTPLATE(6),
|
|
||||||
LEGGINGS(7),
|
|
||||||
BOOTS(8);
|
|
||||||
|
|
||||||
private final int slot;
|
|
||||||
|
|
||||||
ArmorType(final int slot) {
|
|
||||||
this.slot = slot;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ArmorType matchType(final ItemStack itemStack) {
|
|
||||||
if (ArmorListener.isAirOrNull(itemStack)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
String type = itemStack.getType().name();
|
|
||||||
if (type.endsWith("_HELMET") || type.endsWith("_SKULL") || type.endsWith("PLAYER_HEAD")) {
|
|
||||||
return HELMET;
|
|
||||||
} else if (type.endsWith("_CHESTPLATE") || type.endsWith("ELYTRA")) {
|
|
||||||
return CHESTPLATE;
|
|
||||||
} else if (type.endsWith("_LEGGINGS")) {
|
|
||||||
return LEGGINGS;
|
|
||||||
} else if (type.endsWith("_BOOTS")) {
|
|
||||||
return BOOTS;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSlot() {
|
|
||||||
return slot;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package com.willfp.eco.spigot.eventlisteners;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.events.ArmorEquipEvent;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.block.BlockDispenseArmorEvent;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public class DispenserArmorListener implements Listener {
|
|
||||||
@EventHandler
|
|
||||||
public void dispenseArmorEvent(@NotNull final BlockDispenseArmorEvent event) {
|
|
||||||
ArmorType type = ArmorType.matchType(event.getItem());
|
|
||||||
if (type != null && event.getTargetEntity() instanceof Player p) {
|
|
||||||
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(p);
|
|
||||||
Bukkit.getPluginManager().callEvent(armorEquipEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,6 +4,8 @@ import com.willfp.eco.core.EcoPlugin
|
|||||||
import com.willfp.eco.core.Handler
|
import com.willfp.eco.core.Handler
|
||||||
import com.willfp.eco.core.config.updating.ConfigHandler
|
import com.willfp.eco.core.config.updating.ConfigHandler
|
||||||
import com.willfp.eco.core.config.wrapper.ConfigFactory
|
import com.willfp.eco.core.config.wrapper.ConfigFactory
|
||||||
|
import com.willfp.eco.core.data.PlayerProfileHandler
|
||||||
|
import com.willfp.eco.core.data.keys.KeyRegistry
|
||||||
import com.willfp.eco.core.drops.DropQueueFactory
|
import com.willfp.eco.core.drops.DropQueueFactory
|
||||||
import com.willfp.eco.core.events.EventManager
|
import com.willfp.eco.core.events.EventManager
|
||||||
import com.willfp.eco.core.extensions.ExtensionLoader
|
import com.willfp.eco.core.extensions.ExtensionLoader
|
||||||
@@ -34,6 +36,8 @@ import com.willfp.eco.internal.proxy.EcoProxyFactory
|
|||||||
import com.willfp.eco.internal.requirement.EcoRequirementFactory
|
import com.willfp.eco.internal.requirement.EcoRequirementFactory
|
||||||
import com.willfp.eco.internal.scheduling.EcoScheduler
|
import com.willfp.eco.internal.scheduling.EcoScheduler
|
||||||
import com.willfp.eco.proxy.FastItemStackFactoryProxy
|
import com.willfp.eco.proxy.FastItemStackFactoryProxy
|
||||||
|
import com.willfp.eco.spigot.data.EcoKeyRegistry
|
||||||
|
import com.willfp.eco.spigot.data.EcoPlayerProfileHandler
|
||||||
import com.willfp.eco.spigot.integrations.bstats.MetricHandler
|
import com.willfp.eco.spigot.integrations.bstats.MetricHandler
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences
|
||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
@@ -43,7 +47,9 @@ import java.util.logging.Logger
|
|||||||
class EcoHandler : EcoSpigotPlugin(), Handler {
|
class EcoHandler : EcoSpigotPlugin(), Handler {
|
||||||
private val cleaner = EcoCleaner()
|
private val cleaner = EcoCleaner()
|
||||||
private val requirementFactory = EcoRequirementFactory()
|
private val requirementFactory = EcoRequirementFactory()
|
||||||
private lateinit var adventure: BukkitAudiences
|
private var adventure: BukkitAudiences? = null
|
||||||
|
private val keyRegistry = EcoKeyRegistry(this)
|
||||||
|
private val playerProfileHandler = EcoPlayerProfileHandler(this)
|
||||||
|
|
||||||
override fun createScheduler(plugin: EcoPlugin): Scheduler {
|
override fun createScheduler(plugin: EcoPlugin): Scheduler {
|
||||||
return EcoScheduler(plugin)
|
return EcoScheduler(plugin)
|
||||||
@@ -129,10 +135,18 @@ class EcoHandler : EcoSpigotPlugin(), Handler {
|
|||||||
return requirementFactory
|
return requirementFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getAdventure(): BukkitAudiences {
|
override fun getAdventure(): BukkitAudiences? {
|
||||||
return adventure
|
return adventure
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getKeyRegistry(): KeyRegistry {
|
||||||
|
return keyRegistry
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPlayerProfileHandler(): PlayerProfileHandler {
|
||||||
|
return playerProfileHandler
|
||||||
|
}
|
||||||
|
|
||||||
fun setAdventure(adventure: BukkitAudiences) {
|
fun setAdventure(adventure: BukkitAudiences) {
|
||||||
this.adventure = adventure
|
this.adventure = adventure
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,15 @@ package com.willfp.eco.spigot
|
|||||||
import com.willfp.eco.core.AbstractPacketAdapter
|
import com.willfp.eco.core.AbstractPacketAdapter
|
||||||
import com.willfp.eco.core.Eco
|
import com.willfp.eco.core.Eco
|
||||||
import com.willfp.eco.core.EcoPlugin
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.Prerequisite
|
||||||
import com.willfp.eco.core.display.Display
|
import com.willfp.eco.core.display.Display
|
||||||
import com.willfp.eco.core.integrations.IntegrationLoader
|
import com.willfp.eco.core.integrations.IntegrationLoader
|
||||||
|
import com.willfp.eco.core.integrations.afk.AFKManager
|
||||||
import com.willfp.eco.core.integrations.anticheat.AnticheatManager
|
import com.willfp.eco.core.integrations.anticheat.AnticheatManager
|
||||||
import com.willfp.eco.core.integrations.antigrief.AntigriefManager
|
import com.willfp.eco.core.integrations.antigrief.AntigriefManager
|
||||||
import com.willfp.eco.core.integrations.customitems.CustomItemsManager
|
import com.willfp.eco.core.integrations.customitems.CustomItemsManager
|
||||||
|
import com.willfp.eco.core.integrations.economy.EconomyManager
|
||||||
|
import com.willfp.eco.core.integrations.hologram.HologramManager
|
||||||
import com.willfp.eco.core.integrations.mcmmo.McmmoManager
|
import com.willfp.eco.core.integrations.mcmmo.McmmoManager
|
||||||
import com.willfp.eco.core.integrations.shop.ShopManager
|
import com.willfp.eco.core.integrations.shop.ShopManager
|
||||||
import com.willfp.eco.core.items.Items
|
import com.willfp.eco.core.items.Items
|
||||||
@@ -18,28 +22,66 @@ import com.willfp.eco.internal.drops.DropManager
|
|||||||
import com.willfp.eco.proxy.BlockBreakProxy
|
import com.willfp.eco.proxy.BlockBreakProxy
|
||||||
import com.willfp.eco.proxy.FastItemStackFactoryProxy
|
import com.willfp.eco.proxy.FastItemStackFactoryProxy
|
||||||
import com.willfp.eco.proxy.SkullProxy
|
import com.willfp.eco.proxy.SkullProxy
|
||||||
|
import com.willfp.eco.proxy.TPSProxy
|
||||||
import com.willfp.eco.spigot.arrows.ArrowDataListener
|
import com.willfp.eco.spigot.arrows.ArrowDataListener
|
||||||
import com.willfp.eco.spigot.display.*
|
import com.willfp.eco.spigot.data.DataListener
|
||||||
|
import com.willfp.eco.spigot.data.EcoPlayerProfileHandler
|
||||||
|
import com.willfp.eco.spigot.data.PlayerBlockListener
|
||||||
|
import com.willfp.eco.spigot.data.storage.DataHandler
|
||||||
|
import com.willfp.eco.spigot.data.storage.MySQLDataHandler
|
||||||
|
import com.willfp.eco.spigot.data.storage.YamlDataHandler
|
||||||
|
import com.willfp.eco.spigot.display.PacketAutoRecipe
|
||||||
|
import com.willfp.eco.spigot.display.PacketChat
|
||||||
|
import com.willfp.eco.spigot.display.PacketOpenWindowMerchant
|
||||||
|
import com.willfp.eco.spigot.display.PacketSetCreativeSlot
|
||||||
|
import com.willfp.eco.spigot.display.PacketSetSlot
|
||||||
|
import com.willfp.eco.spigot.display.PacketWindowItems
|
||||||
|
import com.willfp.eco.spigot.display.frame.clearFrames
|
||||||
import com.willfp.eco.spigot.drops.CollatedRunnable
|
import com.willfp.eco.spigot.drops.CollatedRunnable
|
||||||
import com.willfp.eco.spigot.eventlisteners.*
|
import com.willfp.eco.spigot.eventlisteners.EntityDeathByEntityListeners
|
||||||
|
import com.willfp.eco.spigot.eventlisteners.NaturalExpGainListeners
|
||||||
|
import com.willfp.eco.spigot.eventlisteners.PlayerJumpListeners
|
||||||
|
import com.willfp.eco.spigot.eventlisteners.armor.ArmorChangeEventListeners
|
||||||
|
import com.willfp.eco.spigot.eventlisteners.armor.ArmorListener
|
||||||
import com.willfp.eco.spigot.gui.GUIListener
|
import com.willfp.eco.spigot.gui.GUIListener
|
||||||
import com.willfp.eco.spigot.integrations.anticheat.*
|
import com.willfp.eco.spigot.integrations.afk.AFKIntegrationCMI
|
||||||
import com.willfp.eco.spigot.integrations.antigrief.*
|
import com.willfp.eco.spigot.integrations.afk.AFKIntegrationEssentials
|
||||||
|
import com.willfp.eco.spigot.integrations.anticheat.AnticheatAAC
|
||||||
|
import com.willfp.eco.spigot.integrations.anticheat.AnticheatAlice
|
||||||
|
import com.willfp.eco.spigot.integrations.anticheat.AnticheatMatrix
|
||||||
|
import com.willfp.eco.spigot.integrations.anticheat.AnticheatNCP
|
||||||
|
import com.willfp.eco.spigot.integrations.anticheat.AnticheatSpartan
|
||||||
|
import com.willfp.eco.spigot.integrations.anticheat.AnticheatVulcan
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.AntigriefBentoBox
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.AntigriefCombatLogXV10
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.AntigriefCombatLogXV11
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.AntigriefFactionsUUID
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.AntigriefGriefPrevention
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.AntigriefKingdoms
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.AntigriefLands
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.AntigriefSuperiorSkyblock2
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.AntigriefTowny
|
||||||
|
import com.willfp.eco.spigot.integrations.antigrief.AntigriefWorldGuard
|
||||||
|
import com.willfp.eco.spigot.integrations.customitems.CustomItemsHeadDatabase
|
||||||
import com.willfp.eco.spigot.integrations.customitems.CustomItemsItemsAdder
|
import com.willfp.eco.spigot.integrations.customitems.CustomItemsItemsAdder
|
||||||
import com.willfp.eco.spigot.integrations.customitems.CustomItemsOraxen
|
import com.willfp.eco.spigot.integrations.customitems.CustomItemsOraxen
|
||||||
|
import com.willfp.eco.spigot.integrations.economy.EconomyVault
|
||||||
|
import com.willfp.eco.spigot.integrations.hologram.HologramCMI
|
||||||
|
import com.willfp.eco.spigot.integrations.hologram.HologramGHolo
|
||||||
|
import com.willfp.eco.spigot.integrations.hologram.HologramHolographicDisplays
|
||||||
import com.willfp.eco.spigot.integrations.mcmmo.McmmoIntegrationImpl
|
import com.willfp.eco.spigot.integrations.mcmmo.McmmoIntegrationImpl
|
||||||
|
import com.willfp.eco.spigot.integrations.multiverseinventories.MultiverseInventoriesIntegration
|
||||||
import com.willfp.eco.spigot.integrations.shop.ShopShopGuiPlus
|
import com.willfp.eco.spigot.integrations.shop.ShopShopGuiPlus
|
||||||
import com.willfp.eco.spigot.recipes.ShapedRecipeListener
|
import com.willfp.eco.spigot.recipes.ShapedRecipeListener
|
||||||
import com.willfp.eco.util.BlockUtils
|
import com.willfp.eco.util.BlockUtils
|
||||||
|
import com.willfp.eco.util.ServerUtils
|
||||||
import com.willfp.eco.util.SkullUtils
|
import com.willfp.eco.util.SkullUtils
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences
|
||||||
|
import net.milkbowl.vault.economy.Economy
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
import org.bukkit.Material
|
import org.bukkit.Material
|
||||||
import org.bukkit.block.Block
|
|
||||||
import org.bukkit.entity.Player
|
|
||||||
import org.bukkit.event.Listener
|
import org.bukkit.event.Listener
|
||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
import org.bukkit.inventory.meta.SkullMeta
|
|
||||||
|
|
||||||
abstract class EcoSpigotPlugin : EcoPlugin(
|
abstract class EcoSpigotPlugin : EcoPlugin(
|
||||||
773,
|
773,
|
||||||
@@ -47,29 +89,40 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
|||||||
"com.willfp.eco.proxy",
|
"com.willfp.eco.proxy",
|
||||||
"&a"
|
"&a"
|
||||||
) {
|
) {
|
||||||
|
lateinit var dataHandler: DataHandler
|
||||||
|
|
||||||
init {
|
init {
|
||||||
Items.registerArgParser(EnchantmentArgParser())
|
Items.registerArgParser(EnchantmentArgParser())
|
||||||
Items.registerArgParser(TextureArgParser())
|
Items.registerArgParser(TextureArgParser())
|
||||||
|
|
||||||
val skullProxy = getProxy(SkullProxy::class.java)
|
val skullProxy = getProxy(SkullProxy::class.java)
|
||||||
SkullUtils.initialize(
|
SkullUtils.initialize(
|
||||||
{ meta: SkullMeta, base64: String -> skullProxy.setSkullTexture(meta, base64) },
|
{ meta, base64 -> skullProxy.setSkullTexture(meta, base64) },
|
||||||
{ meta: SkullMeta -> skullProxy.getSkullTexture(meta) }
|
{ meta -> skullProxy.getSkullTexture(meta) }
|
||||||
)
|
)
|
||||||
|
|
||||||
val blockBreakProxy = getProxy(BlockBreakProxy::class.java)
|
val blockBreakProxy = getProxy(BlockBreakProxy::class.java)
|
||||||
BlockUtils.initialize { player: Player, block: Block -> blockBreakProxy.breakBlock(player, block) }
|
BlockUtils.initialize { player, block -> blockBreakProxy.breakBlock(player, block) }
|
||||||
|
|
||||||
|
val tpsProxy = getProxy(TPSProxy::class.java)
|
||||||
|
ServerUtils.initialize { tpsProxy.getTPS() }
|
||||||
|
|
||||||
postInit()
|
postInit()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun postInit() {
|
private fun postInit() {
|
||||||
Display.handler = EcoDisplayHandler(this)
|
Display.setHandler(EcoDisplayHandler(this))
|
||||||
|
|
||||||
|
this.dataHandler = if (this.configYml.getBool("mysql.enabled"))
|
||||||
|
MySQLDataHandler(this) else YamlDataHandler(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleEnable() {
|
override fun handleEnable() {
|
||||||
CollatedRunnable(this)
|
CollatedRunnable(this)
|
||||||
(Eco.getHandler() as EcoHandler).adventure = BukkitAudiences.create(this)
|
|
||||||
|
if (!Prerequisite.HAS_PAPER.isMet) {
|
||||||
|
(Eco.getHandler() as EcoHandler).setAdventure(BukkitAudiences.create(this))
|
||||||
|
}
|
||||||
|
|
||||||
this.logger.info("Ignore messages about deprecated events!")
|
this.logger.info("Ignore messages about deprecated events!")
|
||||||
|
|
||||||
@@ -91,12 +144,25 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun handleDisable() {
|
override fun handleDisable() {
|
||||||
Eco.getHandler().adventure.close()
|
Eco.getHandler().adventure?.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleReload() {
|
override fun handleReload() {
|
||||||
CollatedRunnable(this)
|
CollatedRunnable(this)
|
||||||
DropManager.update(this)
|
DropManager.update(this)
|
||||||
|
this.scheduler.runTimer(
|
||||||
|
{ clearFrames() },
|
||||||
|
this.configYml.getInt("display-frame-ttl").toLong(),
|
||||||
|
this.configYml.getInt("display-frame-ttl").toLong()
|
||||||
|
)
|
||||||
|
this.scheduler.runTimer(
|
||||||
|
{
|
||||||
|
(Eco.getHandler().playerProfileHandler as EcoPlayerProfileHandler)
|
||||||
|
.autosave(this.configYml.getBool("autosave.async"))
|
||||||
|
},
|
||||||
|
this.configYml.getInt("autosave.ticks").toLong(),
|
||||||
|
this.configYml.getInt("autosave.ticks").toLong()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleAfterLoad() {
|
override fun handleAfterLoad() {
|
||||||
@@ -107,9 +173,10 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
|||||||
override fun loadIntegrationLoaders(): List<IntegrationLoader> {
|
override fun loadIntegrationLoaders(): List<IntegrationLoader> {
|
||||||
return listOf(
|
return listOf(
|
||||||
// AntiGrief
|
// AntiGrief
|
||||||
|
IntegrationLoader("SuperiorSkyblock2") { AntigriefManager.register(AntigriefSuperiorSkyblock2()) },
|
||||||
|
IntegrationLoader("BentoBox") { AntigriefManager.register(AntigriefBentoBox()) },
|
||||||
IntegrationLoader("WorldGuard") { AntigriefManager.register(AntigriefWorldGuard()) },
|
IntegrationLoader("WorldGuard") { AntigriefManager.register(AntigriefWorldGuard()) },
|
||||||
IntegrationLoader("GriefPrevention") { AntigriefManager.register(AntigriefGriefPrevention()) },
|
IntegrationLoader("GriefPrevention") { AntigriefManager.register(AntigriefGriefPrevention()) },
|
||||||
IntegrationLoader("GriefDefender") { AntigriefManager.register(AntigriefGriefDefender()) },
|
|
||||||
IntegrationLoader("FactionsUUID") { AntigriefManager.register(AntigriefFactionsUUID()) },
|
IntegrationLoader("FactionsUUID") { AntigriefManager.register(AntigriefFactionsUUID()) },
|
||||||
IntegrationLoader("Towny") { AntigriefManager.register(AntigriefTowny()) },
|
IntegrationLoader("Towny") { AntigriefManager.register(AntigriefTowny()) },
|
||||||
IntegrationLoader("Lands") { AntigriefManager.register(AntigriefLands(this)) },
|
IntegrationLoader("Lands") { AntigriefManager.register(AntigriefLands(this)) },
|
||||||
@@ -132,16 +199,40 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
|||||||
IntegrationLoader("NoCheatPlus") { AnticheatManager.register(this, AnticheatNCP()) },
|
IntegrationLoader("NoCheatPlus") { AnticheatManager.register(this, AnticheatNCP()) },
|
||||||
IntegrationLoader("Spartan") { AnticheatManager.register(this, AnticheatSpartan()) },
|
IntegrationLoader("Spartan") { AnticheatManager.register(this, AnticheatSpartan()) },
|
||||||
IntegrationLoader("Vulcan") { AnticheatManager.register(this, AnticheatVulcan()) },
|
IntegrationLoader("Vulcan") { AnticheatManager.register(this, AnticheatVulcan()) },
|
||||||
|
IntegrationLoader("Alice") { AnticheatManager.register(this, AnticheatAlice()) },
|
||||||
|
|
||||||
// Custom Items
|
// Custom Items
|
||||||
IntegrationLoader("Oraxen") { CustomItemsManager.register(CustomItemsOraxen()) },
|
IntegrationLoader("Oraxen") { CustomItemsManager.register(CustomItemsOraxen()) },
|
||||||
IntegrationLoader("ItemsAdder") { CustomItemsManager.register(CustomItemsItemsAdder(this)) },
|
IntegrationLoader("ItemsAdder") { CustomItemsManager.register(CustomItemsItemsAdder()) },
|
||||||
|
IntegrationLoader("HeadDatabase") { CustomItemsManager.register(CustomItemsHeadDatabase(this)) },
|
||||||
|
|
||||||
// Shop
|
// Shop
|
||||||
IntegrationLoader("ShopGUIPlus") { ShopManager.register(ShopShopGuiPlus()) },
|
IntegrationLoader("ShopGUIPlus") { ShopManager.register(ShopShopGuiPlus()) },
|
||||||
|
|
||||||
|
// Hologram
|
||||||
|
IntegrationLoader("HolographicDisplays") { HologramManager.register(HologramHolographicDisplays(this)) },
|
||||||
|
IntegrationLoader("CMI") { HologramManager.register(HologramCMI()) },
|
||||||
|
IntegrationLoader("GHolo") { HologramManager.register(HologramGHolo()) },
|
||||||
|
|
||||||
|
// AFK
|
||||||
|
IntegrationLoader("Essentials") { AFKManager.register(AFKIntegrationEssentials()) },
|
||||||
|
IntegrationLoader("CMI") { AFKManager.register(AFKIntegrationCMI()) },
|
||||||
|
|
||||||
|
// Economy
|
||||||
|
IntegrationLoader("Vault") {
|
||||||
|
val rsp = Bukkit.getServer().servicesManager.getRegistration(Economy::class.java)
|
||||||
|
if (rsp != null) {
|
||||||
|
EconomyManager.register(EconomyVault(rsp.provider))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
IntegrationLoader("mcMMO") { McmmoManager.register(McmmoIntegrationImpl()) }
|
IntegrationLoader("mcMMO") { McmmoManager.register(McmmoIntegrationImpl()) },
|
||||||
|
IntegrationLoader("Multiverse-Inventories") {
|
||||||
|
this.eventManager.registerListener(
|
||||||
|
MultiverseInventoriesIntegration(this)
|
||||||
|
)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,13 +251,14 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
|||||||
return listOf(
|
return listOf(
|
||||||
NaturalExpGainListeners(),
|
NaturalExpGainListeners(),
|
||||||
ArmorListener(),
|
ArmorListener(),
|
||||||
DispenserArmorListener(),
|
|
||||||
EntityDeathByEntityListeners(this),
|
EntityDeathByEntityListeners(this),
|
||||||
ShapedRecipeListener(this),
|
ShapedRecipeListener(this),
|
||||||
PlayerJumpListeners(),
|
PlayerJumpListeners(),
|
||||||
GUIListener(this),
|
GUIListener(this),
|
||||||
ArrowDataListener(this),
|
ArrowDataListener(this),
|
||||||
ArmorChangeEventListeners(this)
|
ArmorChangeEventListeners(this),
|
||||||
|
DataListener(),
|
||||||
|
PlayerBlockListener(this)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.willfp.eco.spigot.data
|
||||||
|
|
||||||
|
import com.willfp.eco.core.Eco
|
||||||
|
import com.willfp.eco.util.PlayerUtils
|
||||||
|
import org.bukkit.event.EventHandler
|
||||||
|
import org.bukkit.event.Listener
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent
|
||||||
|
|
||||||
|
class DataListener : Listener {
|
||||||
|
@EventHandler
|
||||||
|
fun onLeave(event: PlayerQuitEvent) {
|
||||||
|
PlayerUtils.updateSavedDisplayName(event.player)
|
||||||
|
Eco.getHandler().playerProfileHandler.savePlayer(event.player.uniqueId)
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
fun onJoin(event: PlayerJoinEvent) {
|
||||||
|
PlayerUtils.updateSavedDisplayName(event.player)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.willfp.eco.spigot.data
|
||||||
|
|
||||||
|
import com.willfp.eco.core.data.keys.KeyRegistry
|
||||||
|
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||||
|
import com.willfp.eco.core.data.keys.PersistentDataKeyType
|
||||||
|
import com.willfp.eco.spigot.EcoSpigotPlugin
|
||||||
|
import org.bukkit.NamespacedKey
|
||||||
|
|
||||||
|
class EcoKeyRegistry(
|
||||||
|
private val plugin: EcoSpigotPlugin
|
||||||
|
) : KeyRegistry {
|
||||||
|
private val registry = mutableMapOf<NamespacedKey, PersistentDataKey<*>>()
|
||||||
|
|
||||||
|
override fun registerKey(key: PersistentDataKey<*>) {
|
||||||
|
if (this.registry.containsKey(key.key)) {
|
||||||
|
this.registry.remove(key.key)
|
||||||
|
}
|
||||||
|
|
||||||
|
validateKey(key)
|
||||||
|
|
||||||
|
this.registry[key.key] = key
|
||||||
|
|
||||||
|
plugin.dataHandler.updateKeys()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getRegisteredKeys(): MutableSet<PersistentDataKey<*>> {
|
||||||
|
return registry.values.toMutableSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T> validateKey(key: PersistentDataKey<T>) {
|
||||||
|
when (key.type) {
|
||||||
|
PersistentDataKeyType.INT -> if (key.defaultValue !is Int) {
|
||||||
|
throw IllegalArgumentException("Invalid Data Type! Should be Int")
|
||||||
|
}
|
||||||
|
PersistentDataKeyType.DOUBLE -> if (key.defaultValue !is Double) {
|
||||||
|
throw IllegalArgumentException("Invalid Data Type! Should be Double")
|
||||||
|
}
|
||||||
|
PersistentDataKeyType.BOOLEAN -> if (key.defaultValue !is Boolean) {
|
||||||
|
throw IllegalArgumentException("Invalid Data Type! Should be Boolean")
|
||||||
|
}
|
||||||
|
PersistentDataKeyType.STRING -> if (key.defaultValue !is String) {
|
||||||
|
throw IllegalArgumentException("Invalid Data Type! Should be String")
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> throw NullPointerException("Null value found!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package com.willfp.eco.spigot.data
|
||||||
|
|
||||||
|
import com.willfp.eco.core.Eco
|
||||||
|
import com.willfp.eco.core.data.PlayerProfile
|
||||||
|
import com.willfp.eco.core.data.PlayerProfileHandler
|
||||||
|
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||||
|
import com.willfp.eco.internal.data.EcoPlayerProfile
|
||||||
|
import com.willfp.eco.spigot.EcoSpigotPlugin
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class EcoPlayerProfileHandler(
|
||||||
|
private val plugin: EcoSpigotPlugin
|
||||||
|
) : PlayerProfileHandler {
|
||||||
|
private val loaded = mutableMapOf<UUID, PlayerProfile>()
|
||||||
|
private val handler = plugin.dataHandler
|
||||||
|
|
||||||
|
override fun load(uuid: UUID): PlayerProfile {
|
||||||
|
val found = loaded[uuid]
|
||||||
|
if (found != null) {
|
||||||
|
return found
|
||||||
|
}
|
||||||
|
|
||||||
|
val data = mutableMapOf<PersistentDataKey<*>, Any>()
|
||||||
|
|
||||||
|
for (key in Eco.getHandler().keyRegistry.registeredKeys) {
|
||||||
|
data[key] = handler.read(uuid, key.key) ?: key.defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
|
val profile = EcoPlayerProfile(data)
|
||||||
|
loaded[uuid] = profile
|
||||||
|
return profile
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun savePlayer(uuid: UUID) {
|
||||||
|
writeToHandler(uuid)
|
||||||
|
saveToHandler()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun writeToHandler(uuid: UUID) {
|
||||||
|
val profile = load(uuid)
|
||||||
|
|
||||||
|
for (key in Eco.getHandler().keyRegistry.registeredKeys) {
|
||||||
|
handler.write(uuid, key.key, profile.read(key) ?: key.defaultValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun saveToHandler() {
|
||||||
|
handler.save()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun saveAll(async: Boolean) {
|
||||||
|
val saver = {
|
||||||
|
for ((uuid, _) in loaded) {
|
||||||
|
writeToHandler(uuid)
|
||||||
|
}
|
||||||
|
|
||||||
|
saveToHandler()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (async) {
|
||||||
|
plugin.scheduler.runAsync(saver)
|
||||||
|
} else {
|
||||||
|
saver.invoke()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun autosave(async: Boolean) {
|
||||||
|
if (Bukkit.getOnlinePlayers().isEmpty()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plugin.configYml.getBool("autosave.log")) {
|
||||||
|
plugin.logger.info("Auto-Saving player data!")
|
||||||
|
}
|
||||||
|
|
||||||
|
saveAll(async)
|
||||||
|
|
||||||
|
if (plugin.configYml.getBool("autosave.log")) {
|
||||||
|
plugin.logger.info("Saved player data!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package com.willfp.eco.spigot.data
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.util.NamespacedKeyUtils
|
||||||
|
import org.bukkit.block.Block
|
||||||
|
import org.bukkit.event.EventHandler
|
||||||
|
import org.bukkit.event.EventPriority
|
||||||
|
import org.bukkit.event.Listener
|
||||||
|
import org.bukkit.event.block.BlockBreakEvent
|
||||||
|
import org.bukkit.event.block.BlockMultiPlaceEvent
|
||||||
|
import org.bukkit.event.block.BlockPlaceEvent
|
||||||
|
import org.bukkit.persistence.PersistentDataType
|
||||||
|
|
||||||
|
class PlayerBlockListener(
|
||||||
|
private val plugin: EcoPlugin
|
||||||
|
) : Listener {
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
fun onPlace(event: BlockPlaceEvent) {
|
||||||
|
val block = event.blockPlaced
|
||||||
|
|
||||||
|
writeKey(block)
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
fun onPlace(event: BlockMultiPlaceEvent) {
|
||||||
|
val block = event.blockPlaced
|
||||||
|
|
||||||
|
writeKey(block)
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
fun onBreak(event: BlockBreakEvent) {
|
||||||
|
val block = event.block
|
||||||
|
|
||||||
|
this.plugin.scheduler.run {
|
||||||
|
removeKey(block)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun writeKey(block: Block) {
|
||||||
|
val loc = block.location.hashCode().toString(16)
|
||||||
|
block.chunk.persistentDataContainer.set(
|
||||||
|
plugin.namespacedKeyFactory.create(loc.lowercase()),
|
||||||
|
PersistentDataType.INTEGER,
|
||||||
|
1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun removeKey(block: Block) {
|
||||||
|
val loc = block.location.hashCode().toString(16)
|
||||||
|
block.chunk.persistentDataContainer.remove(plugin.namespacedKeyFactory.create(loc.lowercase()))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.willfp.eco.spigot.data.storage
|
||||||
|
|
||||||
|
import org.bukkit.NamespacedKey
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
interface DataHandler {
|
||||||
|
fun save()
|
||||||
|
|
||||||
|
fun <T> write(uuid: UUID, key: NamespacedKey, value: T)
|
||||||
|
fun <T> read(uuid: UUID, key: NamespacedKey): T?
|
||||||
|
|
||||||
|
fun updateKeys()
|
||||||
|
}
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
package com.willfp.eco.spigot.data.storage
|
||||||
|
|
||||||
|
import com.willfp.eco.core.Eco
|
||||||
|
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||||
|
import com.willfp.eco.core.data.keys.PersistentDataKeyType
|
||||||
|
import com.willfp.eco.spigot.EcoSpigotPlugin
|
||||||
|
import org.bukkit.NamespacedKey
|
||||||
|
import org.jetbrains.exposed.dao.id.UUIDTable
|
||||||
|
import org.jetbrains.exposed.sql.BooleanColumnType
|
||||||
|
import org.jetbrains.exposed.sql.Column
|
||||||
|
import org.jetbrains.exposed.sql.Database
|
||||||
|
import org.jetbrains.exposed.sql.DoubleColumnType
|
||||||
|
import org.jetbrains.exposed.sql.IntegerColumnType
|
||||||
|
import org.jetbrains.exposed.sql.ResultRow
|
||||||
|
import org.jetbrains.exposed.sql.SchemaUtils
|
||||||
|
import org.jetbrains.exposed.sql.VarCharColumnType
|
||||||
|
import org.jetbrains.exposed.sql.insert
|
||||||
|
import org.jetbrains.exposed.sql.select
|
||||||
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
import org.jetbrains.exposed.sql.update
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
class MySQLDataHandler(
|
||||||
|
plugin: EcoSpigotPlugin
|
||||||
|
) : DataHandler {
|
||||||
|
private val columns = mutableMapOf<String, Column<*>>()
|
||||||
|
|
||||||
|
init {
|
||||||
|
Database.connect(
|
||||||
|
"jdbc:mysql://" +
|
||||||
|
"${plugin.configYml.getString("mysql.host")}:" +
|
||||||
|
"${plugin.configYml.getString("mysql.port")}/" +
|
||||||
|
plugin.configYml.getString("mysql.database"),
|
||||||
|
driver = "com.mysql.cj.jdbc.Driver",
|
||||||
|
user = plugin.configYml.getString("mysql.user"),
|
||||||
|
password = plugin.configYml.getString("mysql.password")
|
||||||
|
)
|
||||||
|
|
||||||
|
transaction {
|
||||||
|
SchemaUtils.create(Players)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateKeys() {
|
||||||
|
transaction {
|
||||||
|
for (key in Eco.getHandler().keyRegistry.registeredKeys) {
|
||||||
|
registerColumn(key, Players)
|
||||||
|
}
|
||||||
|
|
||||||
|
SchemaUtils.createMissingTablesAndColumns(Players)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun save() {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T> write(uuid: UUID, key: NamespacedKey, value: T) {
|
||||||
|
transaction {
|
||||||
|
getPlayer(uuid)
|
||||||
|
val column: Column<T> = getColumn(key.toString()) as Column<T>
|
||||||
|
|
||||||
|
Players.update({ Players.id eq uuid }) {
|
||||||
|
it[column] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T> read(uuid: UUID, key: NamespacedKey): T? {
|
||||||
|
var value: T? = null
|
||||||
|
transaction {
|
||||||
|
val player = getPlayer(uuid)
|
||||||
|
value = player[getColumn(key.toString())] as T?
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
object Players : UUIDTable("eco_players") {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T> registerColumn(key: PersistentDataKey<T>, table: UUIDTable) {
|
||||||
|
table.apply {
|
||||||
|
if (this.columns.stream().anyMatch { it.name == key.key.toString() }) {
|
||||||
|
return@apply
|
||||||
|
}
|
||||||
|
|
||||||
|
when (key.type) {
|
||||||
|
PersistentDataKeyType.INT -> registerColumn<Int>(key.key.toString(), IntegerColumnType())
|
||||||
|
.default(key.defaultValue as Int)
|
||||||
|
PersistentDataKeyType.DOUBLE -> registerColumn<Double>(key.key.toString(), DoubleColumnType())
|
||||||
|
.default(key.defaultValue as Double)
|
||||||
|
PersistentDataKeyType.BOOLEAN -> registerColumn<Boolean>(key.key.toString(), BooleanColumnType())
|
||||||
|
.default(key.defaultValue as Boolean)
|
||||||
|
PersistentDataKeyType.STRING -> registerColumn<String>(key.key.toString(), VarCharColumnType(512))
|
||||||
|
.default(key.defaultValue as String)
|
||||||
|
|
||||||
|
else -> throw NullPointerException("Null value found!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getColumn(name: String): Column<*> {
|
||||||
|
val cached = columns[name]
|
||||||
|
if (cached != null) {
|
||||||
|
return cached
|
||||||
|
}
|
||||||
|
|
||||||
|
columns[name] = Players.columns.stream().filter { it.name == name }.findFirst().get()
|
||||||
|
return getColumn(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getPlayer(uuid: UUID): ResultRow {
|
||||||
|
Players.select { Players.id eq uuid }.firstOrNull() ?: run {
|
||||||
|
Players.insert {
|
||||||
|
it[id] = uuid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Players.select { Players.id eq uuid }.first()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.willfp.eco.spigot.data.storage
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.yaml.YamlBaseConfig
|
||||||
|
import com.willfp.eco.spigot.EcoSpigotPlugin
|
||||||
|
import org.bukkit.NamespacedKey
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
class YamlDataHandler(
|
||||||
|
plugin: EcoSpigotPlugin
|
||||||
|
) : DataHandler {
|
||||||
|
private val dataYml = DataYml(plugin)
|
||||||
|
|
||||||
|
override fun save() {
|
||||||
|
dataYml.save()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateKeys() {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T> write(uuid: UUID, key: NamespacedKey, value: T) {
|
||||||
|
dataYml.set("player.$uuid.$key", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T> read(uuid: UUID, key: NamespacedKey): T? {
|
||||||
|
return dataYml.get("player.$uuid.$key") as T?
|
||||||
|
}
|
||||||
|
|
||||||
|
class DataYml(
|
||||||
|
plugin: EcoSpigotPlugin
|
||||||
|
) : YamlBaseConfig(
|
||||||
|
"data",
|
||||||
|
false,
|
||||||
|
plugin
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@ import org.bukkit.entity.Player
|
|||||||
class PacketChat(plugin: EcoPlugin) :
|
class PacketChat(plugin: EcoPlugin) :
|
||||||
AbstractPacketAdapter(plugin,
|
AbstractPacketAdapter(plugin,
|
||||||
PacketType.Play.Server.CHAT,
|
PacketType.Play.Server.CHAT,
|
||||||
if (plugin.configYml.getBool("use-lower-protocollib-priority")) ListenerPriority.NORMAL else ListenerPriority.MONITOR,
|
if (plugin.configYml.getBool("use-lower-protocollib-priority")) ListenerPriority.NORMAL else ListenerPriority.HIGHEST,
|
||||||
true) {
|
true) {
|
||||||
override fun onSend(
|
override fun onSend(
|
||||||
packet: PacketContainer,
|
packet: PacketContainer,
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import com.comphenix.protocol.events.PacketEvent
|
|||||||
import com.willfp.eco.core.AbstractPacketAdapter
|
import com.willfp.eco.core.AbstractPacketAdapter
|
||||||
import com.willfp.eco.core.EcoPlugin
|
import com.willfp.eco.core.EcoPlugin
|
||||||
import com.willfp.eco.core.display.Display
|
import com.willfp.eco.core.display.Display
|
||||||
|
import com.willfp.eco.spigot.display.frame.DisplayFrame
|
||||||
|
import com.willfp.eco.spigot.display.frame.lastDisplayFrame
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
|
|
||||||
@@ -21,5 +23,7 @@ class PacketSetCreativeSlot(plugin: EcoPlugin) :
|
|||||||
itemStack!!
|
itemStack!!
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
player.lastDisplayFrame = DisplayFrame.EMPTY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,8 @@ import com.comphenix.protocol.events.PacketEvent
|
|||||||
import com.willfp.eco.core.AbstractPacketAdapter
|
import com.willfp.eco.core.AbstractPacketAdapter
|
||||||
import com.willfp.eco.core.EcoPlugin
|
import com.willfp.eco.core.EcoPlugin
|
||||||
import com.willfp.eco.core.display.Display
|
import com.willfp.eco.core.display.Display
|
||||||
|
import com.willfp.eco.spigot.display.frame.DisplayFrame
|
||||||
|
import com.willfp.eco.spigot.display.frame.lastDisplayFrame
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
|
|
||||||
@@ -20,5 +22,7 @@ class PacketSetSlot(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, PacketTyp
|
|||||||
item!!, player
|
item!!, player
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
player.lastDisplayFrame = DisplayFrame.EMPTY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,31 +1,148 @@
|
|||||||
package com.willfp.eco.spigot.display
|
package com.willfp.eco.spigot.display
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType
|
import com.comphenix.protocol.PacketType
|
||||||
|
import com.comphenix.protocol.ProtocolLibrary
|
||||||
import com.comphenix.protocol.events.PacketContainer
|
import com.comphenix.protocol.events.PacketContainer
|
||||||
import com.comphenix.protocol.events.PacketEvent
|
import com.comphenix.protocol.events.PacketEvent
|
||||||
|
import com.google.common.util.concurrent.ThreadFactoryBuilder
|
||||||
import com.willfp.eco.core.AbstractPacketAdapter
|
import com.willfp.eco.core.AbstractPacketAdapter
|
||||||
import com.willfp.eco.core.EcoPlugin
|
import com.willfp.eco.core.EcoPlugin
|
||||||
import com.willfp.eco.core.display.Display
|
import com.willfp.eco.core.display.Display
|
||||||
|
import com.willfp.eco.core.fast.FastItemStack
|
||||||
|
import com.willfp.eco.spigot.display.frame.DisplayFrame
|
||||||
|
import com.willfp.eco.spigot.display.frame.HashedItem
|
||||||
|
import com.willfp.eco.spigot.display.frame.lastDisplayFrame
|
||||||
|
import com.willfp.eco.util.ServerUtils
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
import java.util.function.Consumer
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
import java.util.concurrent.Executors
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class PacketWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, PacketType.Play.Server.WINDOW_ITEMS, false) {
|
class PacketWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, PacketType.Play.Server.WINDOW_ITEMS, false) {
|
||||||
|
private val ignorePacketList = ConcurrentHashMap.newKeySet<String>()
|
||||||
|
private val playerRates = ConcurrentHashMap<String, Int>()
|
||||||
|
private val threadFactory = ThreadFactoryBuilder().setNameFormat("eco-display-thread-%d").build()
|
||||||
|
private val executor = Executors.newCachedThreadPool(threadFactory)
|
||||||
|
private val scheduledExecutor = Executors.newSingleThreadScheduledExecutor(threadFactory)
|
||||||
|
|
||||||
override fun onSend(
|
override fun onSend(
|
||||||
packet: PacketContainer,
|
packet: PacketContainer,
|
||||||
player: Player,
|
player: Player,
|
||||||
event: PacketEvent
|
event: PacketEvent
|
||||||
) {
|
) {
|
||||||
packet.itemListModifier.modify(0) { itemStacks: List<ItemStack>? ->
|
if (ignorePacketList.contains(player.name)) {
|
||||||
if (itemStacks == null) {
|
ignorePacketList.remove(player.name)
|
||||||
return@modify null
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val windowId = packet.integers.read(0)
|
||||||
|
|
||||||
|
if (windowId != 0) {
|
||||||
|
player.lastDisplayFrame = DisplayFrame.EMPTY
|
||||||
|
}
|
||||||
|
|
||||||
|
val itemStacks = packet.itemListModifier.read(0) ?: return
|
||||||
|
|
||||||
|
handleRateLimit(player)
|
||||||
|
|
||||||
|
if (usingAsync(player)) {
|
||||||
|
executor.execute {
|
||||||
|
try {
|
||||||
|
modifyWindowItems(itemStacks, windowId, player)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
if (this.getPlugin().configYml.getBool("async-display.log-errors")) {
|
||||||
|
this.getPlugin().logger.warning("Error happened in async processing! Disable async display (/plugins/eco/config.yml) if this is a frequent issue")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val newPacket = packet.deepClone()
|
||||||
|
newPacket.itemListModifier.write(0, itemStacks)
|
||||||
|
|
||||||
|
ignorePacketList.add(player.name)
|
||||||
|
|
||||||
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, newPacket)
|
||||||
}
|
}
|
||||||
itemStacks.forEach(Consumer { item: ItemStack ->
|
} else {
|
||||||
Display.display(
|
packet.itemListModifier.write(0, modifyWindowItems(itemStacks, windowId, player))
|
||||||
item, player
|
|
||||||
)
|
|
||||||
})
|
|
||||||
itemStacks
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun handleRateLimit(player: Player) {
|
||||||
|
fun modifyRateValueBy(player: Player, amount: Int) {
|
||||||
|
val name = player.name
|
||||||
|
val current = playerRates[name] ?: 0
|
||||||
|
val new = current + amount
|
||||||
|
if (new <= 0) {
|
||||||
|
playerRates.remove(name)
|
||||||
|
} else {
|
||||||
|
playerRates[name] = new
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modifyRateValueBy(player, 1)
|
||||||
|
|
||||||
|
scheduledExecutor.schedule(
|
||||||
|
{ modifyRateValueBy(player, -1) },
|
||||||
|
this.getPlugin().configYml.getInt("async-display.ratelimit.timeframe").toLong(),
|
||||||
|
TimeUnit.SECONDS
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun usingAsync(player: Player): Boolean {
|
||||||
|
if (this.getPlugin().configYml.getBool("async-display.enabled")) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.getPlugin().configYml.getBool("async-display.emergency.enabled")
|
||||||
|
&& ServerUtils.getTps() <= this.getPlugin().configYml.getDouble("async-display.emergency.cutoff")
|
||||||
|
) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.getPlugin().configYml.getBool("async-display.ratelimit.enabled")
|
||||||
|
&& (playerRates[player.name] ?: 0) >= this.getPlugin().configYml.getInt("async-display.ratelimit.cutoff")
|
||||||
|
) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun modifyWindowItems(
|
||||||
|
itemStacks: MutableList<ItemStack>,
|
||||||
|
windowId: Int,
|
||||||
|
player: Player
|
||||||
|
): MutableList<ItemStack> {
|
||||||
|
if (this.getPlugin().configYml.getBool("use-display-frame") && windowId == 0) {
|
||||||
|
val frameMap = mutableMapOf<Byte, HashedItem>()
|
||||||
|
|
||||||
|
for (index in itemStacks.indices) {
|
||||||
|
frameMap[index.toByte()] =
|
||||||
|
HashedItem(FastItemStack.wrap(itemStacks[index]).hashCode(), itemStacks[index])
|
||||||
|
}
|
||||||
|
|
||||||
|
val newFrame = DisplayFrame(frameMap)
|
||||||
|
|
||||||
|
val lastFrame = player.lastDisplayFrame
|
||||||
|
|
||||||
|
player.lastDisplayFrame = newFrame
|
||||||
|
|
||||||
|
val changes = lastFrame.getChangedSlots(newFrame)
|
||||||
|
|
||||||
|
for (index in changes) {
|
||||||
|
Display.display(itemStacks[index.toInt()], player)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (index in (itemStacks.indices subtract changes.toSet())) {
|
||||||
|
itemStacks[index.toInt()] = lastFrame.getItem(index.toByte()) ?: itemStacks[index.toInt()]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
itemStacks.forEach { Display.display(it, player) }
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemStacks
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.willfp.eco.spigot.display.frame
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import java.util.*
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
|
data class HashedItem(val hash: Int, val item: ItemStack)
|
||||||
|
|
||||||
|
data class DisplayFrame(val items: Map<Byte, HashedItem>) {
|
||||||
|
fun getChangedSlots(newFrame: DisplayFrame): List<Byte> {
|
||||||
|
val changes = mutableListOf<Byte>()
|
||||||
|
|
||||||
|
for ((slot, data) in newFrame.items) {
|
||||||
|
if (items[slot]?.hash != data.hash) {
|
||||||
|
changes.add(slot)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return changes
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getItem(slot: Byte): ItemStack? {
|
||||||
|
return items[slot]?.item
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val EMPTY = DisplayFrame(emptyMap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val frames = ConcurrentHashMap<UUID, DisplayFrame>()
|
||||||
|
|
||||||
|
var Player.lastDisplayFrame: DisplayFrame
|
||||||
|
get() {
|
||||||
|
return frames[this.uniqueId] ?: DisplayFrame.EMPTY
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
frames[this.uniqueId] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clearFrames() {
|
||||||
|
frames.clear()
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.willfp.eco.spigot.eventlisteners.armor
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.events.ArmorChangeEvent
|
||||||
|
import com.willfp.eco.core.events.ArmorEquipEvent
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.EventHandler
|
||||||
|
import org.bukkit.event.Listener
|
||||||
|
import org.bukkit.event.block.BlockDispenseArmorEvent
|
||||||
|
|
||||||
|
class ArmorChangeEventListeners(
|
||||||
|
private val plugin: EcoPlugin
|
||||||
|
) : Listener {
|
||||||
|
@EventHandler
|
||||||
|
fun onArmorChange(event: ArmorEquipEvent) {
|
||||||
|
val player = event.player
|
||||||
|
val before = player.inventory.armorContents.toMutableList()
|
||||||
|
plugin.scheduler.run {
|
||||||
|
val after = player.inventory.armorContents.toMutableList()
|
||||||
|
val armorChangeEvent = ArmorChangeEvent(player, before, after)
|
||||||
|
Bukkit.getPluginManager().callEvent(armorChangeEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
fun dispenseArmorEvent(event: BlockDispenseArmorEvent) {
|
||||||
|
val type = ArmorType.matchType(event.item)
|
||||||
|
if (type != null && event.targetEntity is Player) {
|
||||||
|
Bukkit.getPluginManager().callEvent(ArmorEquipEvent(event.targetEntity as Player))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user