Compare commits
93 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8fa209a981 | ||
|
|
b3a0634ad0 | ||
|
|
97d7acc0a9 | ||
|
|
ebac75b0ee | ||
|
|
02d0fa85b5 | ||
|
|
168915868c | ||
|
|
d62d598fd6 | ||
|
|
06561c5387 | ||
|
|
c9805e91b4 | ||
|
|
e3be95ca4d | ||
|
|
2e6463aed9 | ||
|
|
2501574eeb | ||
|
|
3c237fd856 | ||
|
|
7b3fd1d0c2 | ||
|
|
e599add6de | ||
|
|
1bda970f6b | ||
|
|
eb1f694905 | ||
|
|
efd3403eda | ||
|
|
08b563d528 | ||
|
|
c3f88bf7b0 | ||
|
|
eb6d76e0c6 | ||
|
|
f2d0e8c368 | ||
|
|
5e7b9573a1 | ||
|
|
7d457ea496 | ||
|
|
806bf9a43f | ||
|
|
316f134b71 | ||
|
|
0d363b9fb6 | ||
|
|
2890083eaa | ||
|
|
694646431b | ||
|
|
86d5e9d09e | ||
|
|
8635e5f7a5 | ||
|
|
aa718649eb | ||
|
|
1dc0fa449b | ||
|
|
19e3061a13 | ||
|
|
ecafbd76de | ||
|
|
3728f2fc7a | ||
|
|
56c124dbd2 | ||
|
|
6730697fc5 | ||
|
|
c8e1c83061 | ||
|
|
a9fd5a9418 | ||
|
|
7b1179f402 | ||
|
|
f4907329d9 | ||
|
|
1e23cbaa5e | ||
|
|
863818d2eb | ||
|
|
d35285d0dc | ||
|
|
bc92f8a444 | ||
|
|
2fafef17d7 | ||
|
|
24078a2838 | ||
|
|
73d13277be | ||
|
|
0e4c23d70c | ||
|
|
ddf5094c5a | ||
|
|
925fc56cab | ||
|
|
3208d0328f | ||
|
|
317824ae78 | ||
|
|
41a4b4fc1a | ||
|
|
c528e4cd42 | ||
|
|
2724f21d4e | ||
|
|
5cb14e31b7 | ||
|
|
6b9942f412 | ||
|
|
fbe88ab0fd | ||
|
|
d042211dbe | ||
|
|
5781df011e | ||
|
|
c191ff0767 | ||
|
|
b9cbcbe7a0 | ||
|
|
6009122c48 | ||
|
|
7536794100 | ||
|
|
e80aa5f910 | ||
|
|
b4aeeac570 | ||
|
|
33515aa5f7 | ||
|
|
047b535a40 | ||
|
|
ef8093ec7f | ||
|
|
9d0f95617d | ||
|
|
b4f3988fc7 | ||
|
|
e7e1751acc | ||
|
|
e68d482aa5 | ||
|
|
c0547a7c34 | ||
|
|
183b18c0ec | ||
|
|
e026a767d9 | ||
|
|
d2966aa428 | ||
|
|
9168e68b5a | ||
|
|
51a61b65c6 | ||
|
|
76be236dac | ||
|
|
f1bbac2dd0 | ||
|
|
6e88aef572 | ||
|
|
804f187964 | ||
|
|
623b8a18f4 | ||
|
|
0d4e424582 | ||
|
|
452e499467 | ||
|
|
b2950ab035 | ||
|
|
e47d05ccb2 | ||
|
|
b9e61b8c0d | ||
|
|
0f35d5d16e | ||
|
|
3a7315d728 |
@@ -12,7 +12,7 @@ dependencies {
|
|||||||
implementation(project(":eco-core:core-backend"))
|
implementation(project(":eco-core:core-backend"))
|
||||||
implementation(project(":eco-core:core-nms:v1_16_R3"))
|
implementation(project(":eco-core:core-nms:v1_16_R3"))
|
||||||
implementation(project(path = ":eco-core:core-nms:v1_17_R1", configuration = "reobf"))
|
implementation(project(path = ":eco-core:core-nms:v1_17_R1", configuration = "reobf"))
|
||||||
implementation(project(":eco-core:core-nms:v1_18_R1"))
|
implementation(project(path = ":eco-core:core-nms:v1_18_R1", configuration = "reobf"))
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
@@ -61,6 +61,12 @@ allprojects {
|
|||||||
|
|
||||||
// IridiumSkyblock
|
// IridiumSkyblock
|
||||||
maven("https://nexus.iridiumdevelopment.net/repository/maven-releases/")
|
maven("https://nexus.iridiumdevelopment.net/repository/maven-releases/")
|
||||||
|
|
||||||
|
// MythicMobs
|
||||||
|
maven("https://mvn.lumine.io/repository/maven-public/")
|
||||||
|
|
||||||
|
// Crunch
|
||||||
|
maven("https://redempt.dev")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -88,12 +94,14 @@ allprojects {
|
|||||||
exclude(group = "org.spongepowered", module = "configurate-hocon")
|
exclude(group = "org.spongepowered", module = "configurate-hocon")
|
||||||
exclude(group = "com.darkblade12", module = "particleeffect")
|
exclude(group = "com.darkblade12", module = "particleeffect")
|
||||||
exclude(group = "com.github.cryptomorin", module = "XSeries")
|
exclude(group = "com.github.cryptomorin", module = "XSeries")
|
||||||
|
exclude(group = "org.apache.commons", module = "commons-lang3")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
shadowJar {
|
shadowJar {
|
||||||
relocate("org.bstats", "com.willfp.eco.shaded.bstats")
|
relocate("org.bstats", "com.willfp.eco.shaded.bstats")
|
||||||
relocate("net.kyori.adventure.text.minimessage", "com.willfp.eco.shaded.minimessage")
|
relocate("net.kyori.adventure.text.minimessage", "com.willfp.eco.shaded.minimessage")
|
||||||
|
relocate("redempt.crunch", "com.willfp.eco.shaded.crunch")
|
||||||
}
|
}
|
||||||
|
|
||||||
compileJava {
|
compileJava {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ dependencies {
|
|||||||
compileOnly 'org.apache.maven:maven-artifact:3.8.1'
|
compileOnly 'org.apache.maven:maven-artifact:3.8.1'
|
||||||
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.1-SNAPSHOT'
|
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.1-SNAPSHOT'
|
||||||
compileOnly 'com.google.code.gson:gson:2.8.8'
|
compileOnly 'com.google.code.gson:gson:2.8.8'
|
||||||
|
compileOnly 'org.apache.commons:commons-lang3:3.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
|
|||||||
@@ -327,11 +327,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
|||||||
DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version);
|
DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version);
|
||||||
if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) {
|
if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) {
|
||||||
this.outdated = true;
|
this.outdated = true;
|
||||||
this.getScheduler().runTimer(() -> {
|
this.getLogger().warning("&c" + this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")");
|
||||||
this.getLogger().info("&c " + this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")");
|
this.getLogger().warning("&cThe newest version is &f" + version);
|
||||||
this.getLogger().info("&cThe newest version is &f" + version);
|
this.getLogger().warning("&cDownload the new version!");
|
||||||
this.getLogger().info("&cDownload the new version!");
|
|
||||||
}, 0, 864000);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ import com.willfp.eco.core.proxy.ProxyFactory;
|
|||||||
import com.willfp.eco.core.requirement.RequirementFactory;
|
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.Location;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -232,4 +234,13 @@ public interface Handler {
|
|||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
PlayerProfileHandler getPlayerProfileHandler();
|
PlayerProfileHandler getPlayerProfileHandler();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create dummy entity - never spawned, exists purely in code.
|
||||||
|
*
|
||||||
|
* @param location The location.
|
||||||
|
* @return The entity.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
Entity createDummyEntity(@NotNull Location location);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
package com.willfp.eco.core.config.interfaces;
|
package com.willfp.eco.core.config.interfaces;
|
||||||
|
|
||||||
import com.willfp.eco.core.config.ConfigType;
|
import com.willfp.eco.core.config.ConfigType;
|
||||||
|
import com.willfp.eco.core.config.TransientConfig;
|
||||||
|
import com.willfp.eco.util.NumberUtils;
|
||||||
import com.willfp.eco.util.StringUtils;
|
import com.willfp.eco.util.StringUtils;
|
||||||
|
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.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All configs implement this interface.
|
* All configs implement this interface.
|
||||||
@@ -67,10 +72,12 @@ public interface Config extends Cloneable {
|
|||||||
* Get subsection from config.
|
* Get subsection from config.
|
||||||
*
|
*
|
||||||
* @param path The key to check.
|
* @param path The key to check.
|
||||||
* @return The subsection. Throws NPE if not found.
|
* @return The subsection. Returns an empty section if not found.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
Config getSubsection(@NotNull String path);
|
default Config getSubsection(@NotNull String path) {
|
||||||
|
return Objects.requireNonNullElse(getSubsectionOrNull(path), new TransientConfig());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get subsection from config.
|
* Get subsection from config.
|
||||||
@@ -87,7 +94,44 @@ public interface Config extends Cloneable {
|
|||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @return The found value, or 0 if not found.
|
* @return The found value, or 0 if not found.
|
||||||
*/
|
*/
|
||||||
int getInt(@NotNull String path);
|
default int getInt(@NotNull String path) {
|
||||||
|
return Objects.requireNonNullElse(getIntOrNull(path), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an integer from config with a specified default (not found) value.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @param def The value to default to if not found.
|
||||||
|
* @return The found value, or the default.
|
||||||
|
*/
|
||||||
|
default int getInt(@NotNull String path,
|
||||||
|
int def) {
|
||||||
|
return Objects.requireNonNullElse(getIntOrNull(path), def);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a decimal value via a mathematical expression.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The computed value, or 0 if not found or invalid.
|
||||||
|
*/
|
||||||
|
default int getIntFromExpression(@NotNull String path) {
|
||||||
|
return getIntFromExpression(path, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a decimal value via a mathematical expression.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @param player The player to evaluate placeholders with respect to.
|
||||||
|
* @return The computed value, or 0 if not found or invalid.
|
||||||
|
*/
|
||||||
|
default int getIntFromExpression(@NotNull String path,
|
||||||
|
@Nullable Player player) {
|
||||||
|
return Double.valueOf(getDoubleFromExpression(path, player)).intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an integer from config.
|
* Get an integer from config.
|
||||||
@@ -98,16 +142,6 @@ public interface Config extends Cloneable {
|
|||||||
@Nullable
|
@Nullable
|
||||||
Integer getIntOrNull(@NotNull String path);
|
Integer getIntOrNull(@NotNull String path);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an integer from config with a specified default (not found) value.
|
|
||||||
*
|
|
||||||
* @param path The key to fetch the value from.
|
|
||||||
* @param def The value to default to if not found.
|
|
||||||
* @return The found value, or the default.
|
|
||||||
*/
|
|
||||||
int getInt(@NotNull String path,
|
|
||||||
int def);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of integers from config.
|
* Get a list of integers from config.
|
||||||
*
|
*
|
||||||
@@ -115,7 +149,9 @@ public interface Config extends Cloneable {
|
|||||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
List<Integer> getInts(@NotNull String path);
|
default List<Integer> getInts(@NotNull String path) {
|
||||||
|
return Objects.requireNonNullElse(getIntsOrNull(path), new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of integers from config.
|
* Get a list of integers from config.
|
||||||
@@ -132,7 +168,9 @@ public interface Config extends Cloneable {
|
|||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @return The found value, or false if not found.
|
* @return The found value, or false if not found.
|
||||||
*/
|
*/
|
||||||
boolean getBool(@NotNull String path);
|
default boolean getBool(@NotNull String path) {
|
||||||
|
return Objects.requireNonNullElse(getBoolOrNull(path), false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a boolean from config.
|
* Get a boolean from config.
|
||||||
@@ -150,7 +188,9 @@ public interface Config extends Cloneable {
|
|||||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
List<Boolean> getBools(@NotNull String path);
|
default List<Boolean> getBools(@NotNull String path) {
|
||||||
|
return Objects.requireNonNullElse(getBoolsOrNull(path), new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of booleans from config.
|
* Get a list of booleans from config.
|
||||||
@@ -169,7 +209,7 @@ public interface Config extends Cloneable {
|
|||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
default String getFormattedString(@NotNull String path) {
|
default String getFormattedString(@NotNull String path) {
|
||||||
return getString(path, true);
|
return getString(path, true, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -188,25 +228,25 @@ public interface Config extends Cloneable {
|
|||||||
/**
|
/**
|
||||||
* Get a string from config.
|
* Get a string from config.
|
||||||
* <p>
|
* <p>
|
||||||
* Formatted by default.
|
* Not formatted.
|
||||||
*
|
*
|
||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @return The found value, or an empty string if not found.
|
* @return The found value, or an empty string if not found.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
default String getString(@NotNull String path) {
|
default String getString(@NotNull String path) {
|
||||||
return getString(path, true);
|
return getString(path, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a string from config.
|
* Get a string from config.
|
||||||
* <p>
|
|
||||||
* This will be deprecated when {@link Config#getString(String)} no longer formats by default.
|
|
||||||
*
|
*
|
||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @param format If the string should be formatted.
|
* @param format If the string should be formatted.
|
||||||
* @return The found value, or an empty string if not found.
|
* @return The found value, or an empty string if not found.
|
||||||
|
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "6.18.0")
|
||||||
default String getString(@NotNull String path,
|
default String getString(@NotNull String path,
|
||||||
boolean format) {
|
boolean format) {
|
||||||
return this.getString(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
return this.getString(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||||
@@ -236,9 +276,11 @@ public interface Config extends Cloneable {
|
|||||||
* @return The found value, or an empty string if not found.
|
* @return The found value, or an empty string if not found.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
String getString(@NotNull String path,
|
default String getString(@NotNull String path,
|
||||||
boolean format,
|
boolean format,
|
||||||
@NotNull StringUtils.FormatOption option);
|
@NotNull StringUtils.FormatOption option) {
|
||||||
|
return Objects.requireNonNullElse(getStringOrNull(path, format, option), "");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a formatted string from config.
|
* Get a formatted string from config.
|
||||||
@@ -248,7 +290,7 @@ public interface Config extends Cloneable {
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
default String getFormattedStringOrNull(@NotNull String path) {
|
default String getFormattedStringOrNull(@NotNull String path) {
|
||||||
return getStringOrNull(path, true);
|
return getStringOrNull(path, true, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -274,19 +316,19 @@ public interface Config extends Cloneable {
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
default String getStringOrNull(@NotNull String path) {
|
default String getStringOrNull(@NotNull String path) {
|
||||||
return getStringOrNull(path, true);
|
return getStringOrNull(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a string from config.
|
* Get a string from config.
|
||||||
* <p>
|
|
||||||
* This will be deprecated when {@link Config#getStringOrNull(String)} no longer formats by default.
|
|
||||||
*
|
*
|
||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @param format If the string should be formatted.
|
* @param format If the string should be formatted.
|
||||||
* @return The found value, or null if not found.
|
* @return The found value, or null if not found.
|
||||||
|
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@Deprecated(since = "6.18.0")
|
||||||
default String getStringOrNull(@NotNull String path,
|
default String getStringOrNull(@NotNull String path,
|
||||||
boolean format) {
|
boolean format) {
|
||||||
return this.getStringOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
return this.getStringOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||||
@@ -351,28 +393,26 @@ public interface Config extends Cloneable {
|
|||||||
/**
|
/**
|
||||||
* Get a list of strings from config.
|
* Get a list of strings from config.
|
||||||
* <p>
|
* <p>
|
||||||
* Formatted by default.
|
* Not formatted.
|
||||||
* <p>
|
|
||||||
* This will be changed in newer versions to <b>not</b> format by default.
|
|
||||||
*
|
*
|
||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
default List<String> getStrings(@NotNull String path) {
|
default List<String> getStrings(@NotNull String path) {
|
||||||
return getStrings(path, true);
|
return getStrings(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of strings from config.
|
* Get a list of strings from config.
|
||||||
* <p>
|
|
||||||
* This will be deprecated when {@link Config#getStrings(String)} no longer formats by default.
|
|
||||||
*
|
*
|
||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @param format If the strings should be formatted.
|
* @param format If the strings should be formatted.
|
||||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||||
|
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
|
@Deprecated(since = "6.18.0")
|
||||||
default List<String> getStrings(@NotNull String path,
|
default List<String> getStrings(@NotNull String path,
|
||||||
boolean format) {
|
boolean format) {
|
||||||
return this.getStrings(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
return this.getStrings(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||||
@@ -390,7 +430,7 @@ public interface Config extends Cloneable {
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
default List<String> getStrings(@NotNull String path,
|
default List<String> getStrings(@NotNull String path,
|
||||||
@NotNull StringUtils.FormatOption option) {
|
@NotNull StringUtils.FormatOption option) {
|
||||||
return getStrings(path, true, option);
|
return getStrings(path, false, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -402,14 +442,16 @@ public interface Config extends Cloneable {
|
|||||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
List<String> getStrings(@NotNull String path,
|
default List<String> getStrings(@NotNull String path,
|
||||||
boolean format,
|
boolean format,
|
||||||
@NotNull StringUtils.FormatOption option);
|
@NotNull StringUtils.FormatOption option) {
|
||||||
|
return Objects.requireNonNullElse(getStringsOrNull(path, format, option), new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of strings from config.
|
* Get a list of strings from config.
|
||||||
* <p>
|
* <p>
|
||||||
* Formatted by default.
|
* Formatted.
|
||||||
*
|
*
|
||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @return The found value, or null if not found.
|
* @return The found value, or null if not found.
|
||||||
@@ -422,7 +464,7 @@ public interface Config extends Cloneable {
|
|||||||
/**
|
/**
|
||||||
* Get a list of strings from config.
|
* Get a list of strings from config.
|
||||||
* <p>
|
* <p>
|
||||||
* Formatted by default.
|
* Formatted.
|
||||||
*
|
*
|
||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @param option The format option.
|
* @param option The format option.
|
||||||
@@ -437,7 +479,7 @@ public interface Config extends Cloneable {
|
|||||||
/**
|
/**
|
||||||
* Get a list of strings from config.
|
* Get a list of strings from config.
|
||||||
* <p>
|
* <p>
|
||||||
* Formatted by default.
|
* Not formatted.
|
||||||
* <p>
|
* <p>
|
||||||
* This will be changed in newer versions to <b>not</b> format by default.
|
* This will be changed in newer versions to <b>not</b> format by default.
|
||||||
*
|
*
|
||||||
@@ -446,7 +488,7 @@ public interface Config extends Cloneable {
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
default List<String> getStringsOrNull(@NotNull String path) {
|
default List<String> getStringsOrNull(@NotNull String path) {
|
||||||
return getStringsOrNull(path, true);
|
return getStringsOrNull(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -455,8 +497,10 @@ public interface Config extends Cloneable {
|
|||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @param format If the strings should be formatted.
|
* @param format If the strings should be formatted.
|
||||||
* @return The found value, or null if not found.
|
* @return The found value, or null if not found.
|
||||||
|
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@Deprecated(since = "6.18.0")
|
||||||
default List<String> getStringsOrNull(@NotNull String path,
|
default List<String> getStringsOrNull(@NotNull String path,
|
||||||
boolean format) {
|
boolean format) {
|
||||||
return getStringsOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
return getStringsOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||||
@@ -474,7 +518,7 @@ public interface Config extends Cloneable {
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
default List<String> getStringsOrNull(@NotNull String path,
|
default List<String> getStringsOrNull(@NotNull String path,
|
||||||
@NotNull StringUtils.FormatOption option) {
|
@NotNull StringUtils.FormatOption option) {
|
||||||
return getStringsOrNull(path, true, option);
|
return getStringsOrNull(path, false, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -496,7 +540,31 @@ public interface Config extends Cloneable {
|
|||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @return The found value, or 0 if not found.
|
* @return The found value, or 0 if not found.
|
||||||
*/
|
*/
|
||||||
double getDouble(@NotNull String path);
|
default double getDouble(@NotNull String path) {
|
||||||
|
return Objects.requireNonNullElse(getDoubleOrNull(path), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a decimal value via a mathematical expression.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The computed value, or 0 if not found or invalid.
|
||||||
|
*/
|
||||||
|
default double getDoubleFromExpression(@NotNull String path) {
|
||||||
|
return getDoubleFromExpression(path, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a decimal value via a mathematical expression.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @param player The player to evaluate placeholders with respect to.
|
||||||
|
* @return The computed value, or 0 if not found or invalid.
|
||||||
|
*/
|
||||||
|
default double getDoubleFromExpression(@NotNull String path,
|
||||||
|
@Nullable Player player) {
|
||||||
|
return NumberUtils.evaluateExpression(this.getString(path), player);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a decimal from config.
|
* Get a decimal from config.
|
||||||
@@ -514,7 +582,9 @@ public interface Config extends Cloneable {
|
|||||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
List<Double> getDoubles(@NotNull String path);
|
default List<Double> getDoubles(@NotNull String path) {
|
||||||
|
return Objects.requireNonNullElse(getDoublesOrNull(path), new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of decimals from config.
|
* Get a list of decimals from config.
|
||||||
@@ -532,7 +602,9 @@ public interface Config extends Cloneable {
|
|||||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
List<? extends Config> getSubsections(@NotNull String path);
|
default List<? extends Config> getSubsections(@NotNull String path) {
|
||||||
|
return Objects.requireNonNullElse(getSubsectionsOrNull(path), new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of subsections from config.
|
* Get a list of subsections from config.
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ package com.willfp.eco.core.config.interfaces;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JSON config.
|
* JSON config.
|
||||||
@@ -22,7 +24,9 @@ public interface JSONConfig extends Config {
|
|||||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
List<JSONConfig> getSubsections(@NotNull String path);
|
default List<JSONConfig> getSubsections(@NotNull String path) {
|
||||||
|
return Objects.requireNonNullElse(getSubsectionsOrNull(path), new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of subsections from config.
|
* Get a list of subsections from config.
|
||||||
|
|||||||
@@ -70,70 +70,31 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
|
|||||||
handle.set(path, object);
|
handle.set(path, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull Config getSubsection(@NotNull final String path) {
|
|
||||||
return handle.getSubsection(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable Config getSubsectionOrNull(@NotNull final String path) {
|
public @Nullable Config getSubsectionOrNull(@NotNull final String path) {
|
||||||
return handle.getSubsectionOrNull(path);
|
return handle.getSubsectionOrNull(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getInt(@NotNull final String path) {
|
|
||||||
return handle.getInt(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable Integer getIntOrNull(@NotNull final String path) {
|
public @Nullable Integer getIntOrNull(@NotNull final String path) {
|
||||||
return handle.getIntOrNull(path);
|
return handle.getIntOrNull(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getInt(@NotNull final String path,
|
|
||||||
final int def) {
|
|
||||||
return handle.getInt(path, def);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull List<Integer> getInts(@NotNull final String path) {
|
|
||||||
return handle.getInts(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable List<Integer> getIntsOrNull(@NotNull final String path) {
|
public @Nullable List<Integer> getIntsOrNull(@NotNull final String path) {
|
||||||
return handle.getIntsOrNull(path);
|
return handle.getIntsOrNull(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean getBool(@NotNull final String path) {
|
|
||||||
return handle.getBool(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable Boolean getBoolOrNull(@NotNull final String path) {
|
public @Nullable Boolean getBoolOrNull(@NotNull final String path) {
|
||||||
return handle.getBoolOrNull(path);
|
return handle.getBoolOrNull(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull List<Boolean> getBools(@NotNull final String path) {
|
|
||||||
return handle.getBools(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable List<Boolean> getBoolsOrNull(@NotNull final String path) {
|
public @Nullable List<Boolean> getBoolsOrNull(@NotNull final String path) {
|
||||||
return handle.getBoolsOrNull(path);
|
return handle.getBoolsOrNull(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull String getString(@NotNull final String path,
|
|
||||||
final boolean format,
|
|
||||||
@NotNull final StringUtils.FormatOption option) {
|
|
||||||
return handle.getString(path, format, option);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable String getStringOrNull(@NotNull final String path,
|
public @Nullable String getStringOrNull(@NotNull final String path,
|
||||||
final boolean format,
|
final boolean format,
|
||||||
@@ -141,13 +102,6 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
|
|||||||
return handle.getStringOrNull(path, format, option);
|
return handle.getStringOrNull(path, format, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull List<String> getStrings(@NotNull final String path,
|
|
||||||
final boolean format,
|
|
||||||
@NotNull final StringUtils.FormatOption option) {
|
|
||||||
return handle.getStrings(path, format, option);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable List<String> getStringsOrNull(@NotNull final String path,
|
public @Nullable List<String> getStringsOrNull(@NotNull final String path,
|
||||||
final boolean format,
|
final boolean format,
|
||||||
@@ -155,31 +109,16 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
|
|||||||
return handle.getStringsOrNull(path, format, option);
|
return handle.getStringsOrNull(path, format, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public double getDouble(@NotNull final String path) {
|
|
||||||
return handle.getDouble(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable Double getDoubleOrNull(@NotNull final String path) {
|
public @Nullable Double getDoubleOrNull(@NotNull final String path) {
|
||||||
return handle.getDoubleOrNull(path);
|
return handle.getDoubleOrNull(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull List<Double> getDoubles(@NotNull final String path) {
|
|
||||||
return handle.getDoubles(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable List<Double> getDoublesOrNull(@NotNull final String path) {
|
public @Nullable List<Double> getDoublesOrNull(@NotNull final String path) {
|
||||||
return handle.getDoublesOrNull(path);
|
return handle.getDoublesOrNull(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull List<? extends Config> getSubsections(@NotNull final String path) {
|
|
||||||
return handle.getSubsections(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable List<? extends Config> getSubsectionsOrNull(@NotNull final String path) {
|
public @Nullable List<? extends Config> getSubsectionsOrNull(@NotNull final String path) {
|
||||||
return handle.getSubsectionsOrNull(path);
|
return handle.getSubsectionsOrNull(path);
|
||||||
|
|||||||
@@ -53,15 +53,6 @@ public class PersistentDataKey<T> {
|
|||||||
+ '}';
|
+ '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all persistent data keys.
|
|
||||||
*
|
|
||||||
* @return The keys.
|
|
||||||
*/
|
|
||||||
public static Set<PersistentDataKey<?>> values() {
|
|
||||||
return Eco.getHandler().getKeyRegistry().getRegisteredKeys();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the key.
|
* Get the key.
|
||||||
*
|
*
|
||||||
@@ -88,4 +79,13 @@ public class PersistentDataKey<T> {
|
|||||||
public PersistentDataKeyType getType() {
|
public PersistentDataKeyType getType() {
|
||||||
return this.type;
|
return this.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all persistent data keys.
|
||||||
|
*
|
||||||
|
* @return The keys.
|
||||||
|
*/
|
||||||
|
public static Set<PersistentDataKey<?>> values() {
|
||||||
|
return Eco.getHandler().getKeyRegistry().getRegisteredKeys();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
package com.willfp.eco.core.entities;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A custom entity has 3 components.
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>The key to identify it</li>
|
||||||
|
* <li>The test to check if any entity is this custom entity</li>
|
||||||
|
* <li>The supplier to spawn the custom {@link org.bukkit.entity.Entity}</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public class CustomEntity implements TestableEntity {
|
||||||
|
/**
|
||||||
|
* The key.
|
||||||
|
*/
|
||||||
|
private final NamespacedKey key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The test for Entities to pass.
|
||||||
|
*/
|
||||||
|
private final Predicate<@NotNull Entity> test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The provider to spawn the entity.
|
||||||
|
*/
|
||||||
|
private final Function<Location, Entity> provider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new custom entity.
|
||||||
|
*
|
||||||
|
* @param key The entity key.
|
||||||
|
* @param test The test.
|
||||||
|
* @param provider The provider to spawn the entity.
|
||||||
|
*/
|
||||||
|
public CustomEntity(@NotNull final NamespacedKey key,
|
||||||
|
@NotNull final Predicate<@NotNull Entity> test,
|
||||||
|
@NotNull final Function<Location, Entity> provider) {
|
||||||
|
this.key = key;
|
||||||
|
this.test = test;
|
||||||
|
this.provider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(@Nullable final Entity entity) {
|
||||||
|
if (entity == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return test.test(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Entity spawn(@NotNull final Location location) {
|
||||||
|
Validate.notNull(location.getWorld());
|
||||||
|
|
||||||
|
return provider.apply(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the entity.
|
||||||
|
*/
|
||||||
|
public void register() {
|
||||||
|
Entities.registerCustomEntity(this.getKey(), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the key.
|
||||||
|
*
|
||||||
|
* @return The key.
|
||||||
|
*/
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return this.key;
|
||||||
|
}
|
||||||
|
}
|
||||||
239
eco-api/src/main/java/com/willfp/eco/core/entities/Entities.java
Normal file
239
eco-api/src/main/java/com/willfp/eco/core/entities/Entities.java
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
package com.willfp.eco.core.entities;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParseResult;
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParser;
|
||||||
|
import com.willfp.eco.core.entities.impl.EmptyTestableEntity;
|
||||||
|
import com.willfp.eco.core.entities.impl.ModifiedTestableEntity;
|
||||||
|
import com.willfp.eco.core.entities.impl.SimpleTestableEntity;
|
||||||
|
import com.willfp.eco.util.NamespacedKeyUtils;
|
||||||
|
import com.willfp.eco.util.StringUtils;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to manage all custom and vanilla entities.
|
||||||
|
*/
|
||||||
|
public final class Entities {
|
||||||
|
/**
|
||||||
|
* All entities.
|
||||||
|
*/
|
||||||
|
private static final Map<NamespacedKey, TestableEntity> REGISTRY = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All entity parsers.
|
||||||
|
*/
|
||||||
|
private static final List<EntityArgParser> ARG_PARSERS = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new custom item.
|
||||||
|
*
|
||||||
|
* @param key The key of the item.
|
||||||
|
* @param item The item.
|
||||||
|
*/
|
||||||
|
public static void registerCustomEntity(@NotNull final NamespacedKey key,
|
||||||
|
@NotNull final TestableEntity item) {
|
||||||
|
REGISTRY.put(key, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new arg parser.
|
||||||
|
*
|
||||||
|
* @param parser The parser.
|
||||||
|
*/
|
||||||
|
public static void registerArgParser(@NotNull final EntityArgParser parser) {
|
||||||
|
ARG_PARSERS.add(parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an entity.
|
||||||
|
*
|
||||||
|
* @param key The key of the entity.
|
||||||
|
*/
|
||||||
|
public static void removeCustomEntity(@NotNull final NamespacedKey key) {
|
||||||
|
REGISTRY.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the backbone of the entire eco entity system.
|
||||||
|
* <p>
|
||||||
|
* You can look up a TestableEntity for any type or custom entity,
|
||||||
|
* and it will return it with any modifiers passed as parameters.
|
||||||
|
* <p>
|
||||||
|
* If you want to get an Entity instance from this, then just call
|
||||||
|
* {@link TestableEntity#spawn(Location)}.
|
||||||
|
* <p>
|
||||||
|
* The advantages of the testable entity system are that there is the inbuilt
|
||||||
|
* {@link TestableEntity#matches(Entity)} - this allows to check if any entity
|
||||||
|
* is that testable entity; which may sound negligible, but actually it allows for
|
||||||
|
* much more power and flexibility. For example, you can have an entity with an
|
||||||
|
* extra metadata tag, extra lore lines, different display name - and it
|
||||||
|
* will still work as long as the test passes.
|
||||||
|
*
|
||||||
|
* @param key The lookup string.
|
||||||
|
* @return The testable entity, or an empty testable entity if not found.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static TestableEntity lookup(@NotNull final String key) {
|
||||||
|
if (key.contains("?")) {
|
||||||
|
String[] options = key.split("\\?");
|
||||||
|
for (String option : options) {
|
||||||
|
TestableEntity lookup = lookup(option);
|
||||||
|
if (!(lookup instanceof EmptyTestableEntity)) {
|
||||||
|
return lookup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new EmptyTestableEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] args = StringUtils.parseTokens(key);
|
||||||
|
|
||||||
|
if (args.length == 0) {
|
||||||
|
return new EmptyTestableEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
TestableEntity entity;
|
||||||
|
|
||||||
|
String[] split = args[0].toLowerCase().split(":");
|
||||||
|
|
||||||
|
if (split.length == 1) {
|
||||||
|
EntityType type;
|
||||||
|
try {
|
||||||
|
type = EntityType.valueOf(args[0].toUpperCase());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return new EmptyTestableEntity();
|
||||||
|
}
|
||||||
|
entity = new SimpleTestableEntity(type);
|
||||||
|
} else {
|
||||||
|
String namespace = split[0];
|
||||||
|
String keyID = split[1];
|
||||||
|
NamespacedKey namespacedKey = NamespacedKeyUtils.create(namespace, keyID);
|
||||||
|
|
||||||
|
TestableEntity part = REGISTRY.get(namespacedKey);
|
||||||
|
|
||||||
|
if (part == null) {
|
||||||
|
return new EmptyTestableEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
entity = part;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String[] modifierArgs = Arrays.copyOfRange(args, 1, args.length);
|
||||||
|
|
||||||
|
List<EntityArgParseResult> parseResults = new ArrayList<>();
|
||||||
|
|
||||||
|
for (EntityArgParser argParser : ARG_PARSERS) {
|
||||||
|
EntityArgParseResult result = argParser.parseArguments(modifierArgs);
|
||||||
|
if (result != null) {
|
||||||
|
parseResults.add(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Function<Location, Entity> spawner = entity::spawn;
|
||||||
|
|
||||||
|
if (!parseResults.isEmpty()) {
|
||||||
|
entity = new ModifiedTestableEntity(
|
||||||
|
entity,
|
||||||
|
test -> {
|
||||||
|
for (EntityArgParseResult parseResult : parseResults) {
|
||||||
|
if (!parseResult.test().test(test)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
location -> {
|
||||||
|
Entity spawned = spawner.apply(location);
|
||||||
|
|
||||||
|
for (EntityArgParseResult parseResult : parseResults) {
|
||||||
|
parseResult.modifier().accept(spawned);
|
||||||
|
}
|
||||||
|
|
||||||
|
return spawned;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a Testable Entity from an ItemStack.
|
||||||
|
* <p>
|
||||||
|
* Will search for registered entity first. If there are no matches in the registry,
|
||||||
|
* then it will return a {@link com.willfp.eco.core.entities.impl.SimpleTestableEntity} matching the entity type.
|
||||||
|
* <p>
|
||||||
|
* If the entity is not custom and has unknown type, this will return null.
|
||||||
|
*
|
||||||
|
* @param entity The Entity.
|
||||||
|
* @return The found Testable Entity.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static TestableEntity getEntity(@Nullable final Entity entity) {
|
||||||
|
if (entity == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
TestableEntity customEntity = getEntity(entity);
|
||||||
|
|
||||||
|
if (customEntity != null) {
|
||||||
|
return customEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (TestableEntity known : REGISTRY.values()) {
|
||||||
|
if (known.matches(entity)) {
|
||||||
|
return known;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity.getType() == EntityType.UNKNOWN) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SimpleTestableEntity(entity.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if entity is a custom entity.
|
||||||
|
*
|
||||||
|
* @param entity The entity to check.
|
||||||
|
* @return If is custom.
|
||||||
|
*/
|
||||||
|
public static boolean isCustomEntity(@NotNull final Entity entity) {
|
||||||
|
for (TestableEntity testable : REGISTRY.values()) {
|
||||||
|
if (testable.matches(entity)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all registered custom items.
|
||||||
|
*
|
||||||
|
* @return A set of all items.
|
||||||
|
*/
|
||||||
|
public static Set<TestableEntity> getCustomEntities() {
|
||||||
|
return new HashSet<>(REGISTRY.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Entities() {
|
||||||
|
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.willfp.eco.core.entities;
|
||||||
|
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An item with a test to see if any item is that item.
|
||||||
|
*/
|
||||||
|
public interface TestableEntity {
|
||||||
|
/**
|
||||||
|
* If an Entity matches the test.
|
||||||
|
*
|
||||||
|
* @param entity The entity to test.
|
||||||
|
* @return If the entity matches.
|
||||||
|
*/
|
||||||
|
boolean matches(@Nullable Entity entity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spawn the entity.
|
||||||
|
*
|
||||||
|
* @param location The location.
|
||||||
|
* @return The entity.
|
||||||
|
*/
|
||||||
|
Entity spawn(@NotNull Location location);
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.willfp.eco.core.entities.args;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param test The test for the entity.
|
||||||
|
* @param modifier The modifier to apply to the entity.
|
||||||
|
* @see EntityArgParser
|
||||||
|
*/
|
||||||
|
public record EntityArgParseResult(@NotNull Predicate<Entity> test,
|
||||||
|
@NotNull Consumer<Entity> modifier) {
|
||||||
|
/**
|
||||||
|
* Kotlin destructuring support.
|
||||||
|
*
|
||||||
|
* @return The test.
|
||||||
|
*/
|
||||||
|
public Predicate<Entity> component1() {
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kotlin destructuring support.
|
||||||
|
*
|
||||||
|
* @return The modifier.
|
||||||
|
*/
|
||||||
|
public Consumer<Entity> component2() {
|
||||||
|
return modifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.willfp.eco.core.entities.args;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.TestableEntity;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An argument parser should generate the predicate as well
|
||||||
|
* as modify the Entity for {@link TestableEntity#spawn(Location)}.
|
||||||
|
*/
|
||||||
|
public interface EntityArgParser {
|
||||||
|
/**
|
||||||
|
* Parse the arguments.
|
||||||
|
*
|
||||||
|
* @param args The arguments.
|
||||||
|
* @return The predicate test to apply to the modified entity.
|
||||||
|
*/
|
||||||
|
@Nullable EntityArgParseResult parseArguments(@NotNull String[] args);
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.willfp.eco.core.entities.impl;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.Eco;
|
||||||
|
import com.willfp.eco.core.entities.TestableEntity;
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty entity.
|
||||||
|
*/
|
||||||
|
public class EmptyTestableEntity implements TestableEntity {
|
||||||
|
/**
|
||||||
|
* Create a new empty testable entity.
|
||||||
|
*/
|
||||||
|
public EmptyTestableEntity() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(@Nullable final Entity entity) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Entity spawn(@NotNull final Location location) {
|
||||||
|
Validate.notNull(location.getWorld());
|
||||||
|
|
||||||
|
return Eco.getHandler().createDummyEntity(location);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package com.willfp.eco.core.entities.impl;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.TestableEntity;
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Existing testable entity with an extra filter.
|
||||||
|
*
|
||||||
|
* @see com.willfp.eco.core.entities.CustomEntity
|
||||||
|
*/
|
||||||
|
public class ModifiedTestableEntity implements TestableEntity {
|
||||||
|
/**
|
||||||
|
* The item.
|
||||||
|
*/
|
||||||
|
private final TestableEntity handle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The amount.
|
||||||
|
*/
|
||||||
|
private final Predicate<Entity> test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The provider to spawn the entity.
|
||||||
|
*/
|
||||||
|
private final Function<Location, Entity> provider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new modified testable entity.
|
||||||
|
*
|
||||||
|
* @param entity The base entity.
|
||||||
|
* @param test The test.
|
||||||
|
* @param provider The provider to spawn the entity.
|
||||||
|
*/
|
||||||
|
public ModifiedTestableEntity(@NotNull final TestableEntity entity,
|
||||||
|
@NotNull final Predicate<@NotNull Entity> test,
|
||||||
|
@NotNull final Function<Location, Entity> provider) {
|
||||||
|
this.handle = entity;
|
||||||
|
this.test = test;
|
||||||
|
this.provider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(@Nullable final Entity entity) {
|
||||||
|
return entity != null && handle.matches(entity) && test.test(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Entity spawn(@NotNull final Location location) {
|
||||||
|
Validate.notNull(location.getWorld());
|
||||||
|
|
||||||
|
return provider.apply(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the handle.
|
||||||
|
*
|
||||||
|
* @return The handle.
|
||||||
|
*/
|
||||||
|
public TestableEntity getHandle() {
|
||||||
|
return this.handle;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package com.willfp.eco.core.entities.impl;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.TestableEntity;
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default vanilla entities.
|
||||||
|
*/
|
||||||
|
public class SimpleTestableEntity implements TestableEntity {
|
||||||
|
/**
|
||||||
|
* The entity type.
|
||||||
|
*/
|
||||||
|
private final EntityType type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new simple testable entity.
|
||||||
|
*
|
||||||
|
* @param type The entity type.
|
||||||
|
*/
|
||||||
|
public SimpleTestableEntity(@NotNull final EntityType type) {
|
||||||
|
this.type = type;
|
||||||
|
|
||||||
|
Validate.notNull(type.getEntityClass(), "Entity cannot be of unknown type!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(@Nullable final Entity entity) {
|
||||||
|
return entity != null && entity.getType() == type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Entity spawn(@NotNull final Location location) {
|
||||||
|
Validate.notNull(location.getWorld());
|
||||||
|
|
||||||
|
assert type.getEntityClass() != null;
|
||||||
|
|
||||||
|
return location.getWorld().spawn(location, type.getEntityClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type.
|
||||||
|
*
|
||||||
|
* @return The type.
|
||||||
|
*/
|
||||||
|
public EntityType getType() {
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.willfp.eco.core.integrations.customentities;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to handle custom entity integrations.
|
||||||
|
*/
|
||||||
|
public final class CustomEntitiesManager {
|
||||||
|
/**
|
||||||
|
* A set of all registered integrations.
|
||||||
|
*/
|
||||||
|
private static final Set<CustomEntitiesWrapper> REGISTERED = new HashSet<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new integration.
|
||||||
|
*
|
||||||
|
* @param integration The integration to register.
|
||||||
|
*/
|
||||||
|
public static void register(@NotNull final CustomEntitiesWrapper integration) {
|
||||||
|
REGISTERED.add(integration);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register all the custom entities for a specific plugin into eco.
|
||||||
|
*
|
||||||
|
* @see com.willfp.eco.core.entities.Entities
|
||||||
|
*/
|
||||||
|
public static void registerAllEntities() {
|
||||||
|
for (CustomEntitiesWrapper wrapper : REGISTERED) {
|
||||||
|
wrapper.registerAllEntities();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private CustomEntitiesManager() {
|
||||||
|
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.willfp.eco.core.integrations.customentities;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.integrations.Integration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper class for custom item integrations.
|
||||||
|
*/
|
||||||
|
public interface CustomEntitiesWrapper extends Integration {
|
||||||
|
/**
|
||||||
|
* Register all the custom entities for a specific plugin into eco.
|
||||||
|
*
|
||||||
|
* @see com.willfp.eco.core.entities.Entities
|
||||||
|
*/
|
||||||
|
void registerAllEntities();
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.willfp.eco.core.integrations.placeholder;
|
package com.willfp.eco.core.integrations.placeholder;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -28,12 +29,20 @@ public class PlaceholderEntry {
|
|||||||
*/
|
*/
|
||||||
private final boolean requiresPlayer;
|
private final boolean requiresPlayer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The plugin for the placeholder.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private final EcoPlugin plugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a placeholder entry that doesn't require a player.
|
* Create a placeholder entry that doesn't require a player.
|
||||||
*
|
*
|
||||||
* @param identifier The identifier of the placeholder.
|
* @param identifier The identifier of the placeholder.
|
||||||
* @param function A lambda to get the result of the placeholder given a player.
|
* @param function A lambda to get the result of the placeholder given a player.
|
||||||
|
* @deprecated Specify a plugin.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public PlaceholderEntry(@NotNull final String identifier,
|
public PlaceholderEntry(@NotNull final String identifier,
|
||||||
@NotNull final Function<Player, String> function) {
|
@NotNull final Function<Player, String> function) {
|
||||||
this(identifier, function, false);
|
this(identifier, function, false);
|
||||||
@@ -45,10 +54,41 @@ public class PlaceholderEntry {
|
|||||||
* @param identifier The identifier of the placeholder.
|
* @param identifier The identifier of the placeholder.
|
||||||
* @param function A lambda to get the result of the placeholder.
|
* @param function A lambda to get the result of the placeholder.
|
||||||
* @param requiresPlayer If the placeholder requires a player.
|
* @param requiresPlayer If the placeholder requires a player.
|
||||||
|
* @deprecated Specify a plugin.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public PlaceholderEntry(@NotNull final String identifier,
|
public PlaceholderEntry(@NotNull final String identifier,
|
||||||
@NotNull final Function<Player, String> function,
|
@NotNull final Function<Player, String> function,
|
||||||
final boolean requiresPlayer) {
|
final boolean requiresPlayer) {
|
||||||
|
this(null, identifier, function, requiresPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a placeholder entry that doesn't require a player.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin for the placeholder.
|
||||||
|
* @param identifier The identifier of the placeholder.
|
||||||
|
* @param function A lambda to get the result of the placeholder given a player.
|
||||||
|
*/
|
||||||
|
public PlaceholderEntry(@Nullable final EcoPlugin plugin,
|
||||||
|
@NotNull final String identifier,
|
||||||
|
@NotNull final Function<Player, String> function) {
|
||||||
|
this(plugin, identifier, function, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a placeholder entry that may require a player.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin for the placeholder.
|
||||||
|
* @param identifier The identifier of the placeholder.
|
||||||
|
* @param function A lambda to get the result of the placeholder.
|
||||||
|
* @param requiresPlayer If the placeholder requires a player.
|
||||||
|
*/
|
||||||
|
public PlaceholderEntry(@Nullable final EcoPlugin plugin,
|
||||||
|
@NotNull final String identifier,
|
||||||
|
@NotNull final Function<Player, String> function,
|
||||||
|
final boolean requiresPlayer) {
|
||||||
|
this.plugin = plugin;
|
||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
this.function = function;
|
this.function = function;
|
||||||
this.requiresPlayer = requiresPlayer;
|
this.requiresPlayer = requiresPlayer;
|
||||||
@@ -85,6 +125,16 @@ public class PlaceholderEntry {
|
|||||||
return identifier;
|
return identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the plugin.
|
||||||
|
*
|
||||||
|
* @return The plugin.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public EcoPlugin getPlugin() {
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register the placeholder.
|
* Register the placeholder.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ 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.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper class for placeholder integrations.
|
* Wrapper class for placeholder integrations.
|
||||||
*/
|
*/
|
||||||
@@ -24,4 +27,14 @@ public interface PlaceholderIntegration extends Integration {
|
|||||||
*/
|
*/
|
||||||
String translate(@NotNull String text,
|
String translate(@NotNull String text,
|
||||||
@Nullable Player player);
|
@Nullable Player player);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all placeholders in a given text.
|
||||||
|
*
|
||||||
|
* @param text The text.
|
||||||
|
* @return The placeholders.
|
||||||
|
*/
|
||||||
|
default List<String> findPlaceholdersIn(@NotNull String text) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
package com.willfp.eco.core.integrations.placeholder;
|
package com.willfp.eco.core.integrations.placeholder;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.Eco;
|
||||||
|
import com.willfp.eco.core.EcoPlugin;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@@ -16,7 +20,7 @@ public final class PlaceholderManager {
|
|||||||
/**
|
/**
|
||||||
* All registered placeholders.
|
* All registered placeholders.
|
||||||
*/
|
*/
|
||||||
private static final Map<String, PlaceholderEntry> REGISTERED_PLACEHOLDERS = new HashMap<>();
|
private static final Map<EcoPlugin, Map<String, PlaceholderEntry>> REGISTERED_PLACEHOLDERS = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All registered placeholder integrations.
|
* All registered placeholder integrations.
|
||||||
@@ -39,8 +43,11 @@ public final class PlaceholderManager {
|
|||||||
* @param expansion The {@link PlaceholderEntry} to register.
|
* @param expansion The {@link PlaceholderEntry} to register.
|
||||||
*/
|
*/
|
||||||
public static void registerPlaceholder(@NotNull final PlaceholderEntry expansion) {
|
public static void registerPlaceholder(@NotNull final PlaceholderEntry expansion) {
|
||||||
REGISTERED_PLACEHOLDERS.remove(expansion.getIdentifier());
|
EcoPlugin plugin = expansion.getPlugin() == null ? Eco.getHandler().getEcoPlugin() : expansion.getPlugin();
|
||||||
REGISTERED_PLACEHOLDERS.put(expansion.getIdentifier(), expansion);
|
Map<String, PlaceholderEntry> pluginPlaceholders = REGISTERED_PLACEHOLDERS
|
||||||
|
.getOrDefault(plugin, new HashMap<>());
|
||||||
|
pluginPlaceholders.put(expansion.getIdentifier(), expansion);
|
||||||
|
REGISTERED_PLACEHOLDERS.put(plugin, pluginPlaceholders);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -49,10 +56,36 @@ public final class PlaceholderManager {
|
|||||||
* @param player The player to get the result from.
|
* @param player The player to get the result from.
|
||||||
* @param identifier The placeholder identifier.
|
* @param identifier The placeholder identifier.
|
||||||
* @return The value of the placeholder.
|
* @return The value of the placeholder.
|
||||||
|
* @deprecated Specify a plugin to get the result from.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static String getResult(@Nullable final Player player,
|
public static String getResult(@Nullable final Player player,
|
||||||
@NotNull final String identifier) {
|
@NotNull final String identifier) {
|
||||||
PlaceholderEntry entry = REGISTERED_PLACEHOLDERS.get(identifier.toLowerCase());
|
return getResult(player, identifier, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the result of a placeholder with respect to a player.
|
||||||
|
*
|
||||||
|
* @param player The player to get the result from.
|
||||||
|
* @param identifier The placeholder identifier.
|
||||||
|
* @param plugin The plugin for the placeholder.
|
||||||
|
* @return The value of the placeholder.
|
||||||
|
*/
|
||||||
|
public static String getResult(@Nullable final Player player,
|
||||||
|
@NotNull final String identifier,
|
||||||
|
@Nullable final EcoPlugin plugin) {
|
||||||
|
EcoPlugin owner = player == null ? Eco.getHandler().getEcoPlugin() : plugin;
|
||||||
|
PlaceholderEntry entry = REGISTERED_PLACEHOLDERS.getOrDefault(owner, new HashMap<>()).get(identifier.toLowerCase());
|
||||||
|
|
||||||
|
if (entry == null && plugin != null) {
|
||||||
|
PlaceholderEntry alternate = REGISTERED_PLACEHOLDERS.getOrDefault(Eco.getHandler().getEcoPlugin(), new HashMap<>())
|
||||||
|
.get(identifier.toLowerCase());
|
||||||
|
if (alternate != null) {
|
||||||
|
entry = alternate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (entry == null) {
|
if (entry == null) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -80,6 +113,21 @@ public final class PlaceholderManager {
|
|||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all placeholders in a given text.
|
||||||
|
*
|
||||||
|
* @param text The text.
|
||||||
|
* @return The placeholders.
|
||||||
|
*/
|
||||||
|
public static List<String> findPlaceholdersIn(@NotNull final String text) {
|
||||||
|
List<String> found = new ArrayList<>();
|
||||||
|
for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) {
|
||||||
|
found.addAll(integration.findPlaceholdersIn(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
private PlaceholderManager() {
|
private PlaceholderManager() {
|
||||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ public class CustomItem implements TestableItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack getItem() {
|
public ItemStack getItem() {
|
||||||
return item;
|
return item.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.willfp.eco.core.items;
|
package com.willfp.eco.core.items;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.fast.FastItemStack;
|
||||||
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.items.provider.ItemProvider;
|
||||||
import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
|
import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
|
||||||
@@ -8,10 +9,12 @@ 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 com.willfp.eco.util.NumberUtils;
|
||||||
|
import com.willfp.eco.util.StringUtils;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
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;
|
||||||
|
|
||||||
@@ -33,6 +36,11 @@ public final class Items {
|
|||||||
*/
|
*/
|
||||||
private static final Map<NamespacedKey, TestableItem> REGISTRY = new ConcurrentHashMap<>();
|
private static final Map<NamespacedKey, TestableItem> REGISTRY = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cached custom item lookups, using {@link FastItemStack#hashCode()}.
|
||||||
|
*/
|
||||||
|
private static final Map<Integer, TestableItem> CACHE = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All item providers.
|
* All item providers.
|
||||||
*/
|
*/
|
||||||
@@ -118,7 +126,8 @@ public final class Items {
|
|||||||
return new EmptyTestableItem();
|
return new EmptyTestableItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] args = key.split(" ");
|
String[] args = StringUtils.parseTokens(key);
|
||||||
|
|
||||||
if (args.length == 0) {
|
if (args.length == 0) {
|
||||||
return new EmptyTestableItem();
|
return new EmptyTestableItem();
|
||||||
}
|
}
|
||||||
@@ -274,12 +283,7 @@ public final class Items {
|
|||||||
* @return If is recipe.
|
* @return If is recipe.
|
||||||
*/
|
*/
|
||||||
public static boolean isCustomItem(@NotNull final ItemStack itemStack) {
|
public static boolean isCustomItem(@NotNull final ItemStack itemStack) {
|
||||||
for (TestableItem item : REGISTRY.values()) {
|
return getCustomItem(itemStack) != null;
|
||||||
if (item.matches(itemStack)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -290,12 +294,30 @@ public final class Items {
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public static CustomItem getCustomItem(@NotNull final ItemStack itemStack) {
|
public static CustomItem getCustomItem(@NotNull final ItemStack itemStack) {
|
||||||
|
int hash = FastItemStack.wrap(itemStack).hashCode();
|
||||||
|
TestableItem cached = CACHE.get(hash);
|
||||||
|
if (cached != null) {
|
||||||
|
return getOrWrap(cached);
|
||||||
|
} else {
|
||||||
|
CACHE.remove(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
TestableItem match = null;
|
||||||
|
|
||||||
for (TestableItem item : REGISTRY.values()) {
|
for (TestableItem item : REGISTRY.values()) {
|
||||||
if (item.matches(itemStack)) {
|
if (item.matches(itemStack)) {
|
||||||
return getOrWrap(item);
|
match = item;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
|
if (match == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
CACHE.put(hash, match);
|
||||||
|
|
||||||
|
return getOrWrap(match);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -329,6 +351,14 @@ public final class Items {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the lookup cache.
|
||||||
|
*/
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public static void clearCache() {
|
||||||
|
CACHE.clear();
|
||||||
|
}
|
||||||
|
|
||||||
private Items() {
|
private Items() {
|
||||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
package com.willfp.eco.core.items.args;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse leather armor colors.
|
|
||||||
*
|
|
||||||
* @deprecated Moved to internals.
|
|
||||||
*/
|
|
||||||
@Deprecated(since = "6.16.0", forRemoval = true)
|
|
||||||
public class ColorArgParser implements LookupArgParser {
|
|
||||||
/**
|
|
||||||
* Instantiate arg parser.
|
|
||||||
*/
|
|
||||||
public ColorArgParser() {
|
|
||||||
Bukkit.getLogger().severe("Instantiation of class marked for removal! (" + this.getClass().getName() + "), this will throw an error in a future release!");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
|
|
||||||
@NotNull final ItemMeta meta) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package com.willfp.eco.core.items.args;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse custom model data.
|
|
||||||
*
|
|
||||||
* @deprecated Moved to internals.
|
|
||||||
*/
|
|
||||||
@Deprecated(since = "6.16.0", forRemoval = true)
|
|
||||||
public class CustomModelDataArgParser implements LookupArgParser {
|
|
||||||
/**
|
|
||||||
* Instantiate arg parser.
|
|
||||||
*/
|
|
||||||
public CustomModelDataArgParser() {
|
|
||||||
Bukkit.getLogger().severe("Instantiation of class marked for removal! (" + this.getClass().getName() + "), this will throw an error in a future release!");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
|
|
||||||
@NotNull final ItemMeta meta) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package com.willfp.eco.core.items.args;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses enchantment arguments.
|
|
||||||
*
|
|
||||||
* @deprecated Moved to internals.
|
|
||||||
*/
|
|
||||||
@Deprecated(since = "6.16.0", forRemoval = true)
|
|
||||||
public class EnchantmentArgParser implements LookupArgParser {
|
|
||||||
/**
|
|
||||||
* Instantiate arg parser.
|
|
||||||
*/
|
|
||||||
public EnchantmentArgParser() {
|
|
||||||
Bukkit.getLogger().severe("Instantiation of class marked for removal! (" + this.getClass().getName() + "), this will throw an error in a future release!");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
|
|
||||||
@NotNull final ItemMeta meta) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package com.willfp.eco.core.items.args;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse skull textures.
|
|
||||||
*
|
|
||||||
* @deprecated Moved to internals.
|
|
||||||
*/
|
|
||||||
@Deprecated(since = "6.16.0", forRemoval = true)
|
|
||||||
public class TextureArgParser implements LookupArgParser {
|
|
||||||
/**
|
|
||||||
* Instantiate arg parser.
|
|
||||||
*/
|
|
||||||
public TextureArgParser() {
|
|
||||||
Bukkit.getLogger().severe("Instantiation of class marked for removal! (" + this.getClass().getName() + "), this will throw an error in a future release!");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
|
|
||||||
@NotNull final ItemMeta meta) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -39,7 +39,7 @@ public class EnchantedBookBuilder extends AbstractItemStackBuilder<EnchantmentSt
|
|||||||
* @return The builder.
|
* @return The builder.
|
||||||
*/
|
*/
|
||||||
public EnchantedBookBuilder addStoredEnchantment(@NotNull final Supplier<Enchantment> enchantment,
|
public EnchantedBookBuilder addStoredEnchantment(@NotNull final Supplier<Enchantment> enchantment,
|
||||||
final Supplier<Integer> level) {
|
@NotNull final Supplier<Integer> level) {
|
||||||
return this.addStoredEnchantment(enchantment.get(), level.get());
|
return this.addStoredEnchantment(enchantment.get(), level.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
|
|||||||
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
|
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
|
||||||
assert lore != null;
|
assert lore != null;
|
||||||
lore.add("");
|
lore.add("");
|
||||||
String add = Eco.getHandler().getEcoPlugin().getLangYml().getString("multiple-in-craft");
|
String add = Eco.getHandler().getEcoPlugin().getLangYml().getFormattedString("multiple-in-craft");
|
||||||
add = add.replace("%amount%", String.valueOf(item.getAmount()));
|
add = add.replace("%amount%", String.valueOf(item.getAmount()));
|
||||||
lore.add(add);
|
lore.add(add);
|
||||||
meta.setLore(lore);
|
meta.setLore(lore);
|
||||||
|
|||||||
@@ -92,7 +92,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,6 +91,24 @@ public final class ListUtils {
|
|||||||
return index >= 0 && index < list.size() ? list.get(index) : null;
|
return index >= 0 && index < list.size() ? list.get(index) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if an iterable of strings contains a certain element regardless of case.
|
||||||
|
*
|
||||||
|
* @param list The list.
|
||||||
|
* @param element The element.
|
||||||
|
* @return If contained.
|
||||||
|
*/
|
||||||
|
public static boolean containsIgnoreCase(@NotNull final Iterable<String> list,
|
||||||
|
@NotNull final String element) {
|
||||||
|
for (String s : list) {
|
||||||
|
if (s.equalsIgnoreCase(element)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private ListUtils() {
|
private ListUtils() {
|
||||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
package com.willfp.eco.util;
|
package com.willfp.eco.util;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utilities / API methods for numbers.
|
* Utilities / API methods for numbers.
|
||||||
@@ -16,6 +21,11 @@ public final class NumberUtils {
|
|||||||
*/
|
*/
|
||||||
private static final double[] SIN_LOOKUP = new double[65536];
|
private static final double[] SIN_LOOKUP = new double[65536];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crunch handler.
|
||||||
|
*/
|
||||||
|
private static BiFunction<String, Player, Double> crunch = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of roman numerals to look up.
|
* Set of roman numerals to look up.
|
||||||
*/
|
*/
|
||||||
@@ -83,7 +93,9 @@ public final class NumberUtils {
|
|||||||
* @param toChange The value to test.
|
* @param toChange The value to test.
|
||||||
* @param limit The maximum.
|
* @param limit The maximum.
|
||||||
* @return The new value.
|
* @return The new value.
|
||||||
|
* @deprecated Pointless method.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "6.19.0")
|
||||||
public static int equalIfOver(final int toChange,
|
public static int equalIfOver(final int toChange,
|
||||||
final int limit) {
|
final int limit) {
|
||||||
return Math.min(toChange, limit);
|
return Math.min(toChange, limit);
|
||||||
@@ -95,7 +107,9 @@ public final class NumberUtils {
|
|||||||
* @param toChange The value to test.
|
* @param toChange The value to test.
|
||||||
* @param limit The maximum.
|
* @param limit The maximum.
|
||||||
* @return The new value.
|
* @return The new value.
|
||||||
|
* @deprecated Pointless method.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "6.19.0")
|
||||||
public static double equalIfOver(final double toChange,
|
public static double equalIfOver(final double toChange,
|
||||||
final double limit) {
|
final double limit) {
|
||||||
return Math.min(toChange, limit);
|
return Math.min(toChange, limit);
|
||||||
@@ -185,11 +199,23 @@ public final class NumberUtils {
|
|||||||
/**
|
/**
|
||||||
* Get Log base 2 of a number.
|
* Get Log base 2 of a number.
|
||||||
*
|
*
|
||||||
* @param toLog The number.
|
* @param a The number.
|
||||||
* @return The result.
|
* @return The result.
|
||||||
*/
|
*/
|
||||||
public static int log2(final int toLog) {
|
public static int log2(final int a) {
|
||||||
return (int) (Math.log(toLog) / Math.log(2));
|
return (int) logBase(a, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log with a base.
|
||||||
|
*
|
||||||
|
* @param a The number.
|
||||||
|
* @param base The base.
|
||||||
|
* @return The logarithm.
|
||||||
|
*/
|
||||||
|
public static double logBase(final double a,
|
||||||
|
final double base) {
|
||||||
|
return Math.log(a) / Math.log(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -206,6 +232,39 @@ public final class NumberUtils {
|
|||||||
return formatted.endsWith("00") ? String.valueOf((int) toFormat) : formatted;
|
return formatted.endsWith("00") ? String.valueOf((int) toFormat) : formatted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluate an expression.
|
||||||
|
*
|
||||||
|
* @param expression The expression.
|
||||||
|
* @return The value of the expression, or zero if invalid.
|
||||||
|
*/
|
||||||
|
public static double evaluateExpression(@NotNull final String expression) {
|
||||||
|
return evaluateExpression(expression, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluate an expression with respect to a player (for placeholders).
|
||||||
|
*
|
||||||
|
* @param expression The expression.
|
||||||
|
* @param player The player.
|
||||||
|
* @return The value of the expression, or zero if invalid.
|
||||||
|
*/
|
||||||
|
public static double evaluateExpression(@NotNull final String expression,
|
||||||
|
@Nullable final Player player) {
|
||||||
|
return crunch.apply(expression, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init crunch handler.
|
||||||
|
*
|
||||||
|
* @param handler The handler.
|
||||||
|
*/
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public static void initCrunch(@NotNull final BiFunction<String, Player, Double> handler) {
|
||||||
|
Validate.isTrue(crunch == null, "Already initialized!");
|
||||||
|
crunch = handler;
|
||||||
|
}
|
||||||
|
|
||||||
private NumberUtils() {
|
private NumberUtils() {
|
||||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ 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.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.gson.JsonSyntaxException;
|
||||||
import com.willfp.eco.core.Prerequisite;
|
import com.willfp.eco.core.Prerequisite;
|
||||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
|
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
@@ -58,6 +59,13 @@ public final class StringUtils {
|
|||||||
.hexColors()
|
.hexColors()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GSON serializer.
|
||||||
|
*/
|
||||||
|
private static final GsonComponentSerializer GSON_COMPONENT_SERIALIZER = GsonComponentSerializer.builder()
|
||||||
|
.emitLegacyHoverEvent()
|
||||||
|
.build();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Color map.
|
* Color map.
|
||||||
*/
|
*/
|
||||||
@@ -415,7 +423,7 @@ public final class StringUtils {
|
|||||||
if (legacy == null) {
|
if (legacy == null) {
|
||||||
processed = "";
|
processed = "";
|
||||||
}
|
}
|
||||||
return GsonComponentSerializer.gson().serialize(
|
return GSON_COMPONENT_SERIALIZER.serialize(
|
||||||
Component.empty().decoration(TextDecoration.ITALIC, false).append(
|
Component.empty().decoration(TextDecoration.ITALIC, false).append(
|
||||||
LEGACY_COMPONENT_SERIALIZER.deserialize(processed)
|
LEGACY_COMPONENT_SERIALIZER.deserialize(processed)
|
||||||
)
|
)
|
||||||
@@ -429,10 +437,17 @@ public final class StringUtils {
|
|||||||
* @return The legacy string.
|
* @return The legacy string.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public static String jsonToLegacy(@NotNull final String json) {
|
public static String jsonToLegacy(@Nullable final String json) {
|
||||||
return LEGACY_COMPONENT_SERIALIZER.serialize(
|
if (json == null || json.isEmpty()) {
|
||||||
GsonComponentSerializer.gson().deserialize(json)
|
return "";
|
||||||
);
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Component component = GSON_COMPONENT_SERIALIZER.deserialize(json);
|
||||||
|
return LEGACY_COMPONENT_SERIALIZER.serialize(component);
|
||||||
|
} catch (JsonSyntaxException e) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -462,6 +477,53 @@ public final class StringUtils {
|
|||||||
return LEGACY_COMPONENT_SERIALIZER.serialize(component);
|
return LEGACY_COMPONENT_SERIALIZER.serialize(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse string into tokens.
|
||||||
|
* <p>
|
||||||
|
* Handles quoted strings for names.
|
||||||
|
*
|
||||||
|
* @param lookup The lookup string.
|
||||||
|
* @return An array of tokens to be processed.
|
||||||
|
* @author Shawn (https://stackoverflow.com/questions/70606170/split-a-list-on-spaces-and-group-quoted-characters/70606653#70606653)
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static String[] parseTokens(@NotNull final String lookup) {
|
||||||
|
char[] chars = lookup.toCharArray();
|
||||||
|
List<String> tokens = new ArrayList<>();
|
||||||
|
StringBuilder tokenBuilder = new StringBuilder();
|
||||||
|
for (int i = 0; i < chars.length; i++) {
|
||||||
|
if (chars[i] == ' ') {
|
||||||
|
/*
|
||||||
|
Take the current value of the argument builder, append it to the
|
||||||
|
list of found tokens, and then clear it for the next argument.
|
||||||
|
*/
|
||||||
|
tokens.add(tokenBuilder.toString());
|
||||||
|
tokenBuilder.setLength(0);
|
||||||
|
} else if (chars[i] == '"') {
|
||||||
|
/*
|
||||||
|
Work until the next unescaped quote to handle quotes with
|
||||||
|
spaces in them - assumes the input string is well-formatted
|
||||||
|
*/
|
||||||
|
for (i++; chars[i] != '"'; i++) {
|
||||||
|
/*
|
||||||
|
If the found quote is escaped, ignore it in the parsing
|
||||||
|
*/
|
||||||
|
if (chars[i] == '\\') {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
tokenBuilder.append(chars[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
If it's a regular character, just append it to the current argument.
|
||||||
|
*/
|
||||||
|
tokenBuilder.append(chars[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tokens.add(tokenBuilder.toString()); // Adds the last argument to the tokens.
|
||||||
|
return tokens.toArray(new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Options for formatting.
|
* Options for formatting.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import com.google.gson.GsonBuilder
|
|||||||
import com.willfp.eco.core.config.ConfigType
|
import com.willfp.eco.core.config.ConfigType
|
||||||
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.bukkit.configuration.file.YamlConfiguration
|
|
||||||
import java.util.Objects
|
import java.util.Objects
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
@@ -131,24 +130,18 @@ open class EcoJSONConfigWrapper : JSONConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getSubsection(path: String): JSONConfig {
|
override fun getSubsection(path: String): JSONConfig {
|
||||||
val subsection = getSubsectionOrNull(path)
|
return getSubsectionOrNull(path) ?: EcoJSONConfigSection(mutableMapOf())
|
||||||
return subsection ?: EcoJSONConfigSection(emptyMap())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSubsectionOrNull(path: String): JSONConfig? {
|
override fun getSubsectionOrNull(path: String): JSONConfig? {
|
||||||
return if (values.containsKey(path)) {
|
return if (values.containsKey(path)) {
|
||||||
val subsection = values[path] as Map<String, Any>?
|
val subsection = values[path] as Map<String, Any>
|
||||||
EcoJSONConfigSection(subsection!!)
|
EcoJSONConfigSection(subsection)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSubsections(path: String): List<JSONConfig> {
|
|
||||||
val subsections = getSubsectionsOrNull(path)
|
|
||||||
return subsections ?: mutableListOf()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getSubsectionsOrNull(path: String): List<JSONConfig>? {
|
override fun getSubsectionsOrNull(path: String): List<JSONConfig>? {
|
||||||
val maps = getOfKnownType(path, Any::class.java) as List<Map<String, Any>>?
|
val maps = getOfKnownType(path, Any::class.java) as List<Map<String, Any>>?
|
||||||
?: return null
|
?: return null
|
||||||
@@ -159,74 +152,20 @@ open class EcoJSONConfigWrapper : JSONConfig {
|
|||||||
return configs.toMutableList()
|
return configs.toMutableList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getInt(path: String): Int {
|
|
||||||
return (getOfKnownType(path, Double::class.java) ?: 0.0).toInt()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getIntOrNull(path: String): Int? {
|
override fun getIntOrNull(path: String): Int? {
|
||||||
return if (has(path)) {
|
return getOfKnownType(path, Double::class.java)?.toInt()
|
||||||
getInt(path)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getInt(
|
|
||||||
path: String,
|
|
||||||
def: Int
|
|
||||||
): Int {
|
|
||||||
return Objects.requireNonNullElse(getOfKnownType(path, Int::class.java), def)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getInts(path: String): MutableList<Int> {
|
|
||||||
return (Objects.requireNonNullElse(
|
|
||||||
getOfKnownType(path, Any::class.java),
|
|
||||||
emptyList<Int>()
|
|
||||||
) as List<Int>).toMutableList()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getIntsOrNull(path: String): MutableList<Int>? {
|
override fun getIntsOrNull(path: String): MutableList<Int>? {
|
||||||
return if (has(path)) {
|
return (getOfKnownType(path, Any::class.java) as Collection<Int>?)?.toMutableList()
|
||||||
getInts(path)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getBool(path: String): Boolean {
|
|
||||||
return Objects.requireNonNullElse(getOfKnownType(path, Boolean::class.java), false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getBoolOrNull(path: String): Boolean? {
|
override fun getBoolOrNull(path: String): Boolean? {
|
||||||
return if (has(path)) {
|
return getOfKnownType(path, Boolean::class.java)
|
||||||
getBool(path)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getBools(path: String): MutableList<Boolean> {
|
|
||||||
return (Objects.requireNonNullElse(
|
|
||||||
getOfKnownType(path, Any::class.java),
|
|
||||||
emptyList<Boolean>()
|
|
||||||
) as List<Boolean>).toMutableList()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getBoolsOrNull(path: String): MutableList<Boolean>? {
|
override fun getBoolsOrNull(path: String): MutableList<Boolean>? {
|
||||||
return if (has(path)) {
|
return (getOfKnownType(path, Any::class.java) as Collection<Boolean>?)?.toMutableList()
|
||||||
getBools(path)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getString(
|
|
||||||
path: String,
|
|
||||||
format: Boolean,
|
|
||||||
option: StringUtils.FormatOption
|
|
||||||
): String {
|
|
||||||
val string = getOfKnownType(path, String::class.java) ?: ""
|
|
||||||
return if (format) StringUtils.format(string, option) else string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getStringOrNull(
|
override fun getStringOrNull(
|
||||||
@@ -235,62 +174,36 @@ open class EcoJSONConfigWrapper : JSONConfig {
|
|||||||
option: StringUtils.FormatOption
|
option: StringUtils.FormatOption
|
||||||
): String? {
|
): String? {
|
||||||
return if (has(path)) {
|
return if (has(path)) {
|
||||||
getString(path, format, option)
|
val string = getOfKnownType(path, String::class.java) ?: ""
|
||||||
|
return if (format) StringUtils.format(string, option) else string
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getStrings(
|
|
||||||
path: String,
|
|
||||||
format: Boolean,
|
|
||||||
option: StringUtils.FormatOption
|
|
||||||
): MutableList<String> {
|
|
||||||
val strings =
|
|
||||||
(Objects.requireNonNullElse(
|
|
||||||
getOfKnownType(path, Any::class.java),
|
|
||||||
emptyList<String>()
|
|
||||||
) as List<String>).toMutableList()
|
|
||||||
return if (format) StringUtils.formatList(strings, option) else strings
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getStringsOrNull(
|
override fun getStringsOrNull(
|
||||||
path: String,
|
path: String,
|
||||||
format: Boolean,
|
format: Boolean,
|
||||||
option: StringUtils.FormatOption
|
option: StringUtils.FormatOption
|
||||||
): MutableList<String>? {
|
): MutableList<String>? {
|
||||||
return if (has(path)) {
|
return if (has(path)) {
|
||||||
getStrings(path, format, option)
|
val strings =
|
||||||
|
(Objects.requireNonNullElse(
|
||||||
|
getOfKnownType(path, Any::class.java),
|
||||||
|
emptyList<String>()
|
||||||
|
) as List<String>).toMutableList()
|
||||||
|
return if (format) StringUtils.formatList(strings, option) else strings
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDouble(path: String): Double {
|
|
||||||
return Objects.requireNonNullElse(getOfKnownType(path, Double::class.java), 0.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getDoubleOrNull(path: String): Double? {
|
override fun getDoubleOrNull(path: String): Double? {
|
||||||
return if (has(path)) {
|
return getOfKnownType(path, Double::class.java)
|
||||||
getDouble(path)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getDoubles(path: String): MutableList<Double> {
|
|
||||||
return (Objects.requireNonNullElse(
|
|
||||||
getOfKnownType(path, Any::class.java),
|
|
||||||
emptyList<Double>()
|
|
||||||
) as List<Double>).toMutableList()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDoublesOrNull(path: String): MutableList<Double>? {
|
override fun getDoublesOrNull(path: String): MutableList<Double>? {
|
||||||
return if (has(path)) {
|
return (getOfKnownType(path, Any::class.java) as Collection<Double>?)?.toMutableList()
|
||||||
getDoubles(path)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getType(): ConfigType {
|
override fun getType(): ConfigType {
|
||||||
|
|||||||
@@ -24,11 +24,7 @@ open class EcoLoadableJSONConfig(
|
|||||||
private val name: String = "$configName.json"
|
private val name: String = "$configName.json"
|
||||||
|
|
||||||
fun reloadFromFile() {
|
fun reloadFromFile() {
|
||||||
try {
|
runCatching { init(configFile) }.onFailure { it.printStackTrace() }
|
||||||
init(configFile)
|
|
||||||
} catch (e: IOException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final override fun createFile() {
|
final override fun createFile() {
|
||||||
@@ -94,11 +90,7 @@ open class EcoLoadableJSONConfig(
|
|||||||
createFile()
|
createFile()
|
||||||
}
|
}
|
||||||
configFile = File(directory, name)
|
configFile = File(directory, name)
|
||||||
try {
|
init(configFile)
|
||||||
init(configFile)
|
|
||||||
} catch (e: IOException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
plugin.configHandler.addConfig(this)
|
plugin.configHandler.addConfig(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
package com.willfp.eco.internal.config.json
|
package com.willfp.eco.internal.config.json
|
||||||
|
|
||||||
import com.willfp.eco.core.PluginLike
|
import com.willfp.eco.core.PluginLike
|
||||||
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
|
||||||
import java.io.IOException
|
|
||||||
import java.io.InputStreamReader
|
import java.io.InputStreamReader
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
|
|
||||||
@@ -21,48 +19,36 @@ open class EcoUpdatableJSONConfig(
|
|||||||
|
|
||||||
fun update() {
|
fun update() {
|
||||||
super.clearCache()
|
super.clearCache()
|
||||||
try {
|
this.init(configFile)
|
||||||
this.init(configFile)
|
val newConfig = configInJar ?: return
|
||||||
val newConfig = configInJar
|
if (newConfig.getKeys(true) == this.getKeys(true)) {
|
||||||
if (newConfig.getKeys(true) == this.getKeys(true)) {
|
return
|
||||||
return
|
|
||||||
}
|
|
||||||
newConfig.getKeys(true).forEach { key: String ->
|
|
||||||
if (!this.getKeys(true).contains(key)) {
|
|
||||||
if (updateBlacklist.stream().noneMatch { s: String -> key.contains(s) }) {
|
|
||||||
this.set(key, newConfig[key])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (removeUnused) {
|
|
||||||
this.getKeys(true).forEach { s ->
|
|
||||||
if (!newConfig.getKeys(true).contains(s)) {
|
|
||||||
if (updateBlacklist.stream().noneMatch(s::contains)) {
|
|
||||||
this.set(s, null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.save()
|
|
||||||
} catch (e: IOException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
} catch (e: InvalidConfigurationException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
}
|
||||||
|
newConfig.getKeys(true).forEach { key: String ->
|
||||||
|
if (!this.getKeys(true).contains(key)) {
|
||||||
|
if (updateBlacklist.stream().noneMatch { s: String -> key.contains(s) }) {
|
||||||
|
this.set(key, newConfig[key])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (removeUnused) {
|
||||||
|
this.getKeys(true).forEach { s ->
|
||||||
|
if (!newConfig.getKeys(true).contains(s)) {
|
||||||
|
if (updateBlacklist.stream().noneMatch(s::contains)) {
|
||||||
|
this.set(s, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.save()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val configInJar: YamlConfiguration
|
private val configInJar: YamlConfiguration?
|
||||||
get() {
|
get() {
|
||||||
val newIn = this.source.getResourceAsStream(resourcePath) ?: throw NullPointerException("$name is null?")
|
val newIn = this.source.getResourceAsStream(resourcePath) ?: return null
|
||||||
val reader = BufferedReader(InputStreamReader(newIn, StandardCharsets.UTF_8))
|
val reader = BufferedReader(InputStreamReader(newIn, StandardCharsets.UTF_8))
|
||||||
val newConfig = YamlConfiguration()
|
val newConfig = YamlConfiguration()
|
||||||
try {
|
newConfig.load(reader)
|
||||||
newConfig.load(reader)
|
|
||||||
} catch (e: IOException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
} catch (e: InvalidConfigurationException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
return newConfig
|
return newConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,15 +24,15 @@ class EcoConfigHandler(
|
|||||||
|
|
||||||
override fun callUpdate() {
|
override fun callUpdate() {
|
||||||
for (method in reflections.getMethodsAnnotatedWith(ConfigUpdater::class.java)) {
|
for (method in reflections.getMethodsAnnotatedWith(ConfigUpdater::class.java)) {
|
||||||
try {
|
kotlin.runCatching {
|
||||||
when (method.parameterCount) {
|
when (method.parameterCount) {
|
||||||
0 -> method.invoke(null)
|
0 -> method.invoke(null)
|
||||||
1 -> method.invoke(null, this.plugin)
|
1 -> method.invoke(null, this.plugin)
|
||||||
else -> throw InvalidUpdateMethodException("Update method must have 0 parameters or a plugin parameter.")
|
else -> throw InvalidUpdateMethodException("Update method must have 0 parameters or a plugin parameter.")
|
||||||
}
|
}
|
||||||
} catch (e: ReflectiveOperationException) {
|
}.onFailure {
|
||||||
e.printStackTrace()
|
it.printStackTrace()
|
||||||
throw InvalidUpdateMethodException("Update method generated an exception")
|
plugin.logger.severe("Update method ${method.toGenericString()} generated an exception")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ package com.willfp.eco.internal.config.yaml
|
|||||||
import com.willfp.eco.core.PluginLike
|
import com.willfp.eco.core.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.file.YamlConfiguration
|
import org.bukkit.configuration.file.YamlConfiguration
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
@@ -23,13 +22,7 @@ open class EcoLoadableYamlConfig(
|
|||||||
private val name: String = "$configName.yml"
|
private val name: String = "$configName.yml"
|
||||||
|
|
||||||
fun reloadFromFile() {
|
fun reloadFromFile() {
|
||||||
try {
|
handle.load(getConfigFile())
|
||||||
handle.load(getConfigFile())
|
|
||||||
} catch (e: IOException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
} catch (e: InvalidConfigurationException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final override fun createFile() {
|
final override fun createFile() {
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
package com.willfp.eco.internal.config.yaml
|
package com.willfp.eco.internal.config.yaml
|
||||||
|
|
||||||
import com.willfp.eco.core.PluginLike
|
import com.willfp.eco.core.PluginLike
|
||||||
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
|
||||||
import java.io.IOException
|
|
||||||
import java.io.InputStreamReader
|
import java.io.InputStreamReader
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
|
|
||||||
@@ -21,48 +19,36 @@ class EcoUpdatableYamlConfig(
|
|||||||
|
|
||||||
fun update() {
|
fun update() {
|
||||||
super.clearCache()
|
super.clearCache()
|
||||||
try {
|
this.handle.load(configFile)
|
||||||
this.handle.load(configFile)
|
val newConfig = configInJar ?: return
|
||||||
val newConfig = configInJar
|
if (newConfig.getKeys(true) == this.handle.getKeys(true)) {
|
||||||
if (newConfig.getKeys(true) == this.handle.getKeys(true)) {
|
return
|
||||||
return
|
|
||||||
}
|
|
||||||
newConfig.getKeys(true).forEach { key ->
|
|
||||||
if (!this.handle.getKeys(true).contains(key)) {
|
|
||||||
if (updateBlacklist.stream().noneMatch { key.contains(it) }) {
|
|
||||||
this.handle.set(key, newConfig[key])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (removeUnused) {
|
|
||||||
this.handle.getKeys(true).forEach { s ->
|
|
||||||
if (!newConfig.getKeys(true).contains(s)) {
|
|
||||||
if (updateBlacklist.stream().noneMatch(s::contains)) {
|
|
||||||
this.handle.set(s, null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.handle.save(configFile)
|
|
||||||
} catch (e: IOException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
} catch (e: InvalidConfigurationException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
}
|
||||||
|
newConfig.getKeys(true).forEach { key ->
|
||||||
|
if (!this.handle.getKeys(true).contains(key)) {
|
||||||
|
if (updateBlacklist.stream().noneMatch { key.contains(it) }) {
|
||||||
|
this.handle.set(key, newConfig[key])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (removeUnused) {
|
||||||
|
this.handle.getKeys(true).forEach { s ->
|
||||||
|
if (!newConfig.getKeys(true).contains(s)) {
|
||||||
|
if (updateBlacklist.stream().noneMatch(s::contains)) {
|
||||||
|
this.handle.set(s, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.handle.save(configFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val configInJar: YamlConfiguration
|
private val configInJar: YamlConfiguration?
|
||||||
get() {
|
get() {
|
||||||
val newIn = source.getResourceAsStream(resourcePath) ?: throw NullPointerException("$name is null?")
|
val newIn = source.getResourceAsStream(resourcePath) ?: return null
|
||||||
val reader = BufferedReader(InputStreamReader(newIn, StandardCharsets.UTF_8))
|
val reader = BufferedReader(InputStreamReader(newIn, StandardCharsets.UTF_8))
|
||||||
val newConfig = YamlConfiguration()
|
val newConfig = YamlConfiguration()
|
||||||
try {
|
newConfig.load(reader)
|
||||||
newConfig.load(reader)
|
|
||||||
} catch (e: IOException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
} catch (e: InvalidConfigurationException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
return newConfig
|
return newConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,11 +49,6 @@ open class EcoYamlConfigWrapper<T : ConfigurationSection> : Config {
|
|||||||
handle[path] = obj
|
handle[path] = obj
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSubsection(path: String): Config {
|
|
||||||
val subsection = getSubsectionOrNull(path)
|
|
||||||
return subsection ?: EcoYamlConfigSection(YamlConfiguration())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getSubsectionOrNull(path: String): Config? {
|
override fun getSubsectionOrNull(path: String): Config? {
|
||||||
return if (cache.containsKey(path)) {
|
return if (cache.containsKey(path)) {
|
||||||
cache[path] as Config?
|
cache[path] as Config?
|
||||||
@@ -68,109 +63,55 @@ open class EcoYamlConfigWrapper<T : ConfigurationSection> : Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getInt(path: String): Int {
|
|
||||||
return if (cache.containsKey(path)) {
|
|
||||||
(cache[path] as Number).toInt()
|
|
||||||
} else {
|
|
||||||
cache[path] = handle.getDouble(path, 0.0).toInt()
|
|
||||||
getInt(path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getIntOrNull(path: String): Int? {
|
override fun getIntOrNull(path: String): Int? {
|
||||||
return if (has(path)) {
|
|
||||||
getInt(path)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getInt(
|
|
||||||
path: String,
|
|
||||||
def: Int
|
|
||||||
): Int {
|
|
||||||
return if (cache.containsKey(path)) {
|
return if (cache.containsKey(path)) {
|
||||||
(cache[path] as Number).toInt()
|
(cache[path] as Number).toInt()
|
||||||
} else {
|
} else {
|
||||||
cache[path] = handle.getDouble(path, def.toDouble()).toInt()
|
if (has(path)) {
|
||||||
getInt(path)
|
cache[path] = handle.getDouble(path).toInt()
|
||||||
}
|
} else {
|
||||||
}
|
return null
|
||||||
|
}
|
||||||
override fun getInts(path: String): MutableList<Int> {
|
getIntOrNull(path)
|
||||||
return if (cache.containsKey(path)) {
|
|
||||||
(cache[path] as MutableList<Int>).toMutableList()
|
|
||||||
} else {
|
|
||||||
cache[path] = if (has(path)) ArrayList(handle.getIntegerList(path)) else mutableListOf<Int>()
|
|
||||||
getInts(path)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getIntsOrNull(path: String): MutableList<Int>? {
|
override fun getIntsOrNull(path: String): MutableList<Int>? {
|
||||||
return if (has(path)) {
|
|
||||||
getInts(path)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getBool(path: String): Boolean {
|
|
||||||
return if (cache.containsKey(path)) {
|
return if (cache.containsKey(path)) {
|
||||||
cache[path] as Boolean
|
(cache[path] as Collection<Int>).toMutableList()
|
||||||
} else {
|
} else {
|
||||||
cache[path] = handle.getBoolean(path)
|
if (has(path)) {
|
||||||
getBool(path)
|
cache[path] = handle.getIntegerList(path).toMutableList()
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
getIntsOrNull(path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getBoolOrNull(path: String): Boolean? {
|
override fun getBoolOrNull(path: String): Boolean? {
|
||||||
return if (has(path)) {
|
|
||||||
getBool(path)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getBools(path: String): MutableList<Boolean> {
|
|
||||||
return if (cache.containsKey(path)) {
|
return if (cache.containsKey(path)) {
|
||||||
(cache[path] as MutableList<Boolean>).toMutableList()
|
cache[path] as Boolean
|
||||||
} else {
|
} else {
|
||||||
cache[path] =
|
if (has(path)) {
|
||||||
if (has(path)) ArrayList(handle.getBooleanList(path)) else mutableListOf<Boolean>()
|
cache[path] = handle.getBoolean(path)
|
||||||
getBools(path)
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
getBoolOrNull(path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getBoolsOrNull(path: String): MutableList<Boolean>? {
|
override fun getBoolsOrNull(path: String): MutableList<Boolean>? {
|
||||||
return if (has(path)) {
|
return if (cache.containsKey(path)) {
|
||||||
getBools(path)
|
(cache[path] as Collection<Boolean>).toMutableList()
|
||||||
} else {
|
} else {
|
||||||
null
|
if (has(path)) {
|
||||||
}
|
cache[path] = handle.getBooleanList(path).toMutableList()
|
||||||
}
|
|
||||||
|
|
||||||
override fun getString(
|
|
||||||
path: String,
|
|
||||||
format: Boolean,
|
|
||||||
option: StringUtils.FormatOption
|
|
||||||
): String {
|
|
||||||
if (format && option == StringUtils.FormatOption.WITHOUT_PLACEHOLDERS) {
|
|
||||||
return if (cache.containsKey("$path\$FMT")) {
|
|
||||||
cache["$path\$FMT"] as String
|
|
||||||
} else {
|
} else {
|
||||||
val string: String = handle.getString(path, "")!!
|
return null
|
||||||
cache["$path\$FMT"] = StringUtils.format(string, option)
|
|
||||||
getString(path, format, option)
|
|
||||||
}
|
}
|
||||||
} else {
|
getBoolsOrNull(path)
|
||||||
val string = if (cache.containsKey(path)) {
|
|
||||||
cache[path] as String
|
|
||||||
} else {
|
|
||||||
cache[path] = handle.getString(path, "")!!
|
|
||||||
getString(path, format, option)
|
|
||||||
}
|
|
||||||
|
|
||||||
return if (format) StringUtils.format(string) else string
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,108 +121,105 @@ open class EcoYamlConfigWrapper<T : ConfigurationSection> : Config {
|
|||||||
option: StringUtils.FormatOption
|
option: StringUtils.FormatOption
|
||||||
): String? {
|
): String? {
|
||||||
return if (has(path)) {
|
return if (has(path)) {
|
||||||
getString(path, format, option)
|
if (format && option == StringUtils.FormatOption.WITHOUT_PLACEHOLDERS) {
|
||||||
|
return if (cache.containsKey("$path\$FMT")) {
|
||||||
|
cache["$path\$FMT"] as String
|
||||||
|
} else {
|
||||||
|
val string: String = handle.getString(path, "")!!
|
||||||
|
cache["$path\$FMT"] = StringUtils.format(string, option)
|
||||||
|
getString(path, format, option)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val string = if (cache.containsKey(path)) {
|
||||||
|
cache[path] as String
|
||||||
|
} else {
|
||||||
|
cache[path] = handle.getString(path, "")!!
|
||||||
|
getString(path, format, option)
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (format) StringUtils.format(string) else string
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getStrings(
|
|
||||||
path: String,
|
|
||||||
format: Boolean,
|
|
||||||
option: StringUtils.FormatOption
|
|
||||||
): MutableList<String> {
|
|
||||||
if (format && option == StringUtils.FormatOption.WITHOUT_PLACEHOLDERS) {
|
|
||||||
return if (cache.containsKey("$path\$FMT")) {
|
|
||||||
(cache["$path\$FMT"] as MutableList<String>).toMutableList()
|
|
||||||
} else {
|
|
||||||
val list = if (has(path)) handle.getStringList(path) else mutableListOf<String>()
|
|
||||||
cache["$path\$FMT"] = StringUtils.formatList(list, option)
|
|
||||||
getStrings(path, true, option)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val strings = if (cache.containsKey(path)) {
|
|
||||||
(cache[path] as MutableList<String>).toMutableList()
|
|
||||||
} else {
|
|
||||||
cache[path] =
|
|
||||||
if (has(path)) ArrayList(handle.getStringList(path)) else mutableListOf<String>()
|
|
||||||
getStrings(path, false, option)
|
|
||||||
}
|
|
||||||
|
|
||||||
return if (format) {
|
|
||||||
StringUtils.formatList(strings, StringUtils.FormatOption.WITH_PLACEHOLDERS)
|
|
||||||
} else {
|
|
||||||
strings
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getStringsOrNull(
|
override fun getStringsOrNull(
|
||||||
path: String,
|
path: String,
|
||||||
format: Boolean,
|
format: Boolean,
|
||||||
option: StringUtils.FormatOption
|
option: StringUtils.FormatOption
|
||||||
): MutableList<String>? {
|
): MutableList<String>? {
|
||||||
return if (has(path)) {
|
return if (has(path)) {
|
||||||
getStrings(path, format, option)
|
if (format && option == StringUtils.FormatOption.WITHOUT_PLACEHOLDERS) {
|
||||||
|
return if (cache.containsKey("$path\$FMT")) {
|
||||||
|
(cache["$path\$FMT"] as MutableList<String>).toMutableList()
|
||||||
|
} else {
|
||||||
|
val list = if (has(path)) handle.getStringList(path) else mutableListOf<String>()
|
||||||
|
cache["$path\$FMT"] = StringUtils.formatList(list, option)
|
||||||
|
getStrings(path, true, option)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val strings = if (cache.containsKey(path)) {
|
||||||
|
(cache[path] as MutableList<String>).toMutableList()
|
||||||
|
} else {
|
||||||
|
cache[path] =
|
||||||
|
if (has(path)) ArrayList(handle.getStringList(path)) else mutableListOf<String>()
|
||||||
|
getStrings(path, false, option)
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (format) {
|
||||||
|
StringUtils.formatList(strings, StringUtils.FormatOption.WITH_PLACEHOLDERS)
|
||||||
|
} else {
|
||||||
|
strings
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDouble(path: String): Double {
|
|
||||||
return if (cache.containsKey(path)) {
|
|
||||||
cache[path] as Double
|
|
||||||
} else {
|
|
||||||
cache[path] = handle.getDouble(path)
|
|
||||||
getDouble(path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getDoubleOrNull(path: String): Double? {
|
override fun getDoubleOrNull(path: String): Double? {
|
||||||
return if (has(path)) {
|
|
||||||
getDouble(path)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getDoubles(path: String): MutableList<Double> {
|
|
||||||
return if (cache.containsKey(path)) {
|
return if (cache.containsKey(path)) {
|
||||||
(cache[path] as MutableList<Double>).toMutableList()
|
(cache[path] as Number).toDouble()
|
||||||
} else {
|
} else {
|
||||||
cache[path] = if (has(path)) ArrayList(handle.getDoubleList(path)) else emptyList<Double>()
|
if (has(path)) {
|
||||||
getDoubles(path)
|
cache[path] = handle.getDouble(path)
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
getDoubleOrNull(path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDoublesOrNull(path: String): MutableList<Double>? {
|
override fun getDoublesOrNull(path: String): MutableList<Double>? {
|
||||||
return if (has(path)) {
|
|
||||||
getDoubles(path)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getSubsections(path: String): MutableList<out Config> {
|
|
||||||
return if (cache.containsKey(path)) {
|
return if (cache.containsKey(path)) {
|
||||||
(cache[path] as Collection<Config>).toMutableList()
|
(cache[path] as Collection<Double>).toMutableList()
|
||||||
} else {
|
} else {
|
||||||
val mapList = ArrayList(handle.getMapList(path)) as List<Map<String, Any?>>
|
if (has(path)) {
|
||||||
val configList = mutableListOf<Config>()
|
cache[path] = handle.getDoubleList(path).toMutableList()
|
||||||
for (map in mapList) {
|
} else {
|
||||||
val temp = YamlConfiguration.loadConfiguration(StringReader(""))
|
return null
|
||||||
temp.createSection("a", map)
|
|
||||||
configList.add(EcoYamlConfigSection(temp.getConfigurationSection("a")!!))
|
|
||||||
}
|
}
|
||||||
|
getDoublesOrNull(path)
|
||||||
cache[path] = if (has(path)) configList else emptyList()
|
|
||||||
getSubsections(path)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSubsectionsOrNull(path: String): MutableList<out Config>? {
|
override fun getSubsectionsOrNull(path: String): MutableList<out Config>? {
|
||||||
return if (has(path)) {
|
return if (has(path)) {
|
||||||
getSubsections(path)
|
return if (cache.containsKey(path)) {
|
||||||
|
(cache[path] as Collection<Config>).toMutableList()
|
||||||
|
} else {
|
||||||
|
val mapList = ArrayList(handle.getMapList(path)) as List<Map<String, Any?>>
|
||||||
|
val configList = mutableListOf<Config>()
|
||||||
|
for (map in mapList) {
|
||||||
|
val temp = YamlConfiguration.loadConfiguration(StringReader(""))
|
||||||
|
temp.createSection("a", map)
|
||||||
|
configList.add(EcoYamlConfigSection(temp.getConfigurationSection("a")!!))
|
||||||
|
}
|
||||||
|
|
||||||
|
cache[path] = if (has(path)) configList else emptyList()
|
||||||
|
getSubsections(path)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,12 +73,10 @@ open class EcoDropQueue(val player: Player) : InternalDropQueue {
|
|||||||
world.dropItem(location, drop!!).velocity = Vector()
|
world.dropItem(location, drop!!).velocity = Vector()
|
||||||
}
|
}
|
||||||
if (xp > 0) {
|
if (xp > 0) {
|
||||||
val event = PlayerExpChangeEvent(player, xp)
|
|
||||||
Bukkit.getPluginManager().callEvent(event)
|
|
||||||
val orb =
|
val orb =
|
||||||
world.spawnEntity(player.location.add(0.0, 0.2, 0.0), EntityType.EXPERIENCE_ORB) as ExperienceOrb
|
world.spawnEntity(player.location.add(0.0, 0.2, 0.0), EntityType.EXPERIENCE_ORB) as ExperienceOrb
|
||||||
orb.velocity = Vector(0, 0, 0)
|
orb.velocity = Vector(0, 0, 0)
|
||||||
orb.experience = event.amount
|
orb.experience = xp
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (drop in items) {
|
for (drop in items) {
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.willfp.eco.internal.entities
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParseResult
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParser
|
||||||
|
import org.bukkit.entity.Animals
|
||||||
|
|
||||||
|
class EntityArgParserAdult : EntityArgParser {
|
||||||
|
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
|
||||||
|
var baby = false
|
||||||
|
|
||||||
|
for (arg in args) {
|
||||||
|
if (arg.equals("adult", true)) {
|
||||||
|
baby = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!baby) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return EntityArgParseResult(
|
||||||
|
{
|
||||||
|
if (it !is Animals) {
|
||||||
|
return@EntityArgParseResult false
|
||||||
|
}
|
||||||
|
|
||||||
|
it.isAdult
|
||||||
|
},
|
||||||
|
{
|
||||||
|
(it as? Animals)?.setAdult()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.willfp.eco.internal.entities
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParseResult
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParser
|
||||||
|
import org.bukkit.attribute.Attribute
|
||||||
|
import org.bukkit.entity.LivingEntity
|
||||||
|
|
||||||
|
class EntityArgParserAttackDamage : EntityArgParser {
|
||||||
|
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
|
||||||
|
var attributeValue: Double? = null
|
||||||
|
|
||||||
|
for (arg in args) {
|
||||||
|
val argSplit = arg.split(":")
|
||||||
|
if (!argSplit[0].equals("attack-damage", ignoreCase = true)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (argSplit.size < 2) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
attributeValue = argSplit[1].toDoubleOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
attributeValue ?: return null
|
||||||
|
|
||||||
|
return EntityArgParseResult(
|
||||||
|
{
|
||||||
|
if (it !is LivingEntity) {
|
||||||
|
return@EntityArgParseResult false
|
||||||
|
}
|
||||||
|
|
||||||
|
val inst = it.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE) ?: return@EntityArgParseResult false
|
||||||
|
inst.value >= attributeValue
|
||||||
|
},
|
||||||
|
{
|
||||||
|
if (it !is LivingEntity) {
|
||||||
|
return@EntityArgParseResult
|
||||||
|
}
|
||||||
|
|
||||||
|
it.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE)?.baseValue = attributeValue
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.willfp.eco.internal.entities
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParseResult
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParser
|
||||||
|
import org.bukkit.attribute.Attribute
|
||||||
|
import org.bukkit.entity.LivingEntity
|
||||||
|
|
||||||
|
class EntityArgParserAttackSpeed : EntityArgParser {
|
||||||
|
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
|
||||||
|
var attributeValue: Double? = null
|
||||||
|
|
||||||
|
for (arg in args) {
|
||||||
|
val argSplit = arg.split(":")
|
||||||
|
if (!argSplit[0].equals("attack-speed", ignoreCase = true)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (argSplit.size < 2) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
attributeValue = argSplit[1].toDoubleOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
attributeValue ?: return null
|
||||||
|
|
||||||
|
return EntityArgParseResult(
|
||||||
|
{
|
||||||
|
if (it !is LivingEntity) {
|
||||||
|
return@EntityArgParseResult false
|
||||||
|
}
|
||||||
|
|
||||||
|
val inst = it.getAttribute(Attribute.GENERIC_ATTACK_SPEED) ?: return@EntityArgParseResult false
|
||||||
|
inst.value >= attributeValue
|
||||||
|
},
|
||||||
|
{
|
||||||
|
if (it !is LivingEntity) {
|
||||||
|
return@EntityArgParseResult
|
||||||
|
}
|
||||||
|
|
||||||
|
it.getAttribute(Attribute.GENERIC_ATTACK_SPEED)?.baseValue = attributeValue
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.willfp.eco.internal.entities
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParseResult
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParser
|
||||||
|
import org.bukkit.entity.Animals
|
||||||
|
|
||||||
|
class EntityArgParserBaby : EntityArgParser {
|
||||||
|
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
|
||||||
|
var baby = false
|
||||||
|
|
||||||
|
for (arg in args) {
|
||||||
|
if (arg.equals("baby", true)) {
|
||||||
|
baby = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!baby) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return EntityArgParseResult(
|
||||||
|
{
|
||||||
|
if (it !is Animals) {
|
||||||
|
return@EntityArgParseResult false
|
||||||
|
}
|
||||||
|
|
||||||
|
!it.isAdult
|
||||||
|
},
|
||||||
|
{
|
||||||
|
(it as? Animals)?.setBaby()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.willfp.eco.internal.entities
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParseResult
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParser
|
||||||
|
import org.bukkit.entity.Creeper
|
||||||
|
|
||||||
|
class EntityArgParserCharged : EntityArgParser {
|
||||||
|
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
|
||||||
|
var noAI = false
|
||||||
|
|
||||||
|
for (arg in args) {
|
||||||
|
if (arg.equals("charged", true)) {
|
||||||
|
noAI = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!noAI) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return EntityArgParseResult(
|
||||||
|
{
|
||||||
|
if (it !is Creeper) {
|
||||||
|
return@EntityArgParseResult false
|
||||||
|
}
|
||||||
|
|
||||||
|
it.isPowered
|
||||||
|
},
|
||||||
|
{
|
||||||
|
(it as? Creeper)?.isPowered = true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.willfp.eco.internal.entities
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParseResult
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParser
|
||||||
|
import org.bukkit.entity.Creeper
|
||||||
|
|
||||||
|
class EntityArgParserExplosionRadius : EntityArgParser {
|
||||||
|
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
|
||||||
|
var size: Int? = null
|
||||||
|
|
||||||
|
for (arg in args) {
|
||||||
|
val argSplit = arg.split(":")
|
||||||
|
if (!argSplit[0].equals("explosion-radius", ignoreCase = true)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (argSplit.size < 2) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
size = argSplit[1].toIntOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
size ?: return null
|
||||||
|
|
||||||
|
return EntityArgParseResult(
|
||||||
|
{
|
||||||
|
when (it) {
|
||||||
|
is Creeper -> it.explosionRadius == size
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
when (it) {
|
||||||
|
is Creeper -> it.explosionRadius = size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.willfp.eco.internal.entities
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParseResult
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParser
|
||||||
|
import org.bukkit.attribute.Attribute
|
||||||
|
import org.bukkit.entity.LivingEntity
|
||||||
|
|
||||||
|
class EntityArgParserFlySpeed : EntityArgParser {
|
||||||
|
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
|
||||||
|
var attributeValue: Double? = null
|
||||||
|
|
||||||
|
for (arg in args) {
|
||||||
|
val argSplit = arg.split(":")
|
||||||
|
if (!argSplit[0].equals("fly-speed", ignoreCase = true)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (argSplit.size < 2) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
attributeValue = argSplit[1].toDoubleOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
attributeValue ?: return null
|
||||||
|
|
||||||
|
return EntityArgParseResult(
|
||||||
|
{
|
||||||
|
if (it !is LivingEntity) {
|
||||||
|
return@EntityArgParseResult false
|
||||||
|
}
|
||||||
|
|
||||||
|
val inst = it.getAttribute(Attribute.GENERIC_FLYING_SPEED) ?: return@EntityArgParseResult false
|
||||||
|
inst.value >= attributeValue
|
||||||
|
},
|
||||||
|
{
|
||||||
|
if (it !is LivingEntity) {
|
||||||
|
return@EntityArgParseResult
|
||||||
|
}
|
||||||
|
|
||||||
|
it.getAttribute(Attribute.GENERIC_FLYING_SPEED)?.baseValue = attributeValue
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.willfp.eco.internal.entities
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParseResult
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParser
|
||||||
|
import org.bukkit.attribute.Attribute
|
||||||
|
import org.bukkit.entity.LivingEntity
|
||||||
|
|
||||||
|
class EntityArgParserFollowRange : EntityArgParser {
|
||||||
|
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
|
||||||
|
var attributeValue: Double? = null
|
||||||
|
|
||||||
|
for (arg in args) {
|
||||||
|
val argSplit = arg.split(":")
|
||||||
|
if (!argSplit[0].equals("follow-range", ignoreCase = true)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (argSplit.size < 2) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
attributeValue = argSplit[1].toDoubleOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
attributeValue ?: return null
|
||||||
|
|
||||||
|
return EntityArgParseResult(
|
||||||
|
{
|
||||||
|
if (it !is LivingEntity) {
|
||||||
|
return@EntityArgParseResult false
|
||||||
|
}
|
||||||
|
|
||||||
|
val inst = it.getAttribute(Attribute.GENERIC_FOLLOW_RANGE) ?: return@EntityArgParseResult false
|
||||||
|
inst.value >= attributeValue
|
||||||
|
},
|
||||||
|
{
|
||||||
|
if (it !is LivingEntity) {
|
||||||
|
return@EntityArgParseResult
|
||||||
|
}
|
||||||
|
|
||||||
|
it.getAttribute(Attribute.GENERIC_FOLLOW_RANGE)?.baseValue = attributeValue
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.willfp.eco.internal.entities
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParseResult
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParser
|
||||||
|
import org.bukkit.attribute.Attribute
|
||||||
|
import org.bukkit.entity.LivingEntity
|
||||||
|
|
||||||
|
class EntityArgParserHealth : EntityArgParser {
|
||||||
|
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
|
||||||
|
var health: Double? = null
|
||||||
|
|
||||||
|
for (arg in args) {
|
||||||
|
val argSplit = arg.split(":")
|
||||||
|
if (!argSplit[0].equals("health", ignoreCase = true)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (argSplit.size < 2) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
health = argSplit[1].toDoubleOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
health ?: return null
|
||||||
|
|
||||||
|
return EntityArgParseResult(
|
||||||
|
{
|
||||||
|
if (it !is LivingEntity) {
|
||||||
|
return@EntityArgParseResult false
|
||||||
|
}
|
||||||
|
|
||||||
|
it.health >= health
|
||||||
|
},
|
||||||
|
{
|
||||||
|
if (it !is LivingEntity) {
|
||||||
|
return@EntityArgParseResult
|
||||||
|
}
|
||||||
|
|
||||||
|
it.getAttribute(Attribute.GENERIC_MAX_HEALTH)?.baseValue = health
|
||||||
|
it.health = health
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.willfp.eco.internal.entities
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParseResult
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParser
|
||||||
|
import org.bukkit.attribute.Attribute
|
||||||
|
import org.bukkit.entity.LivingEntity
|
||||||
|
|
||||||
|
class EntityArgParserJumpStrength : EntityArgParser {
|
||||||
|
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
|
||||||
|
var attributeValue: Double? = null
|
||||||
|
|
||||||
|
for (arg in args) {
|
||||||
|
val argSplit = arg.split(":")
|
||||||
|
if (!argSplit[0].equals("jump-strength", ignoreCase = true)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (argSplit.size < 2) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
attributeValue = argSplit[1].toDoubleOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
attributeValue ?: return null
|
||||||
|
|
||||||
|
return EntityArgParseResult(
|
||||||
|
{
|
||||||
|
if (it !is LivingEntity) {
|
||||||
|
return@EntityArgParseResult false
|
||||||
|
}
|
||||||
|
|
||||||
|
val inst = it.getAttribute(Attribute.HORSE_JUMP_STRENGTH) ?: return@EntityArgParseResult false
|
||||||
|
inst.value >= attributeValue
|
||||||
|
},
|
||||||
|
{
|
||||||
|
if (it !is LivingEntity) {
|
||||||
|
return@EntityArgParseResult
|
||||||
|
}
|
||||||
|
|
||||||
|
it.getAttribute(Attribute.HORSE_JUMP_STRENGTH)?.baseValue = attributeValue
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.willfp.eco.internal.entities
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParseResult
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParser
|
||||||
|
import org.bukkit.attribute.Attribute
|
||||||
|
import org.bukkit.entity.LivingEntity
|
||||||
|
|
||||||
|
class EntityArgParserKnockback : EntityArgParser {
|
||||||
|
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
|
||||||
|
var attributeValue: Double? = null
|
||||||
|
|
||||||
|
for (arg in args) {
|
||||||
|
val argSplit = arg.split(":")
|
||||||
|
if (!argSplit[0].equals("knockback", ignoreCase = true)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (argSplit.size < 2) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
attributeValue = argSplit[1].toDoubleOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
attributeValue ?: return null
|
||||||
|
|
||||||
|
return EntityArgParseResult(
|
||||||
|
{
|
||||||
|
if (it !is LivingEntity) {
|
||||||
|
return@EntityArgParseResult false
|
||||||
|
}
|
||||||
|
|
||||||
|
val inst = it.getAttribute(Attribute.GENERIC_ATTACK_KNOCKBACK) ?: return@EntityArgParseResult false
|
||||||
|
inst.value >= attributeValue
|
||||||
|
},
|
||||||
|
{
|
||||||
|
if (it !is LivingEntity) {
|
||||||
|
return@EntityArgParseResult
|
||||||
|
}
|
||||||
|
|
||||||
|
it.getAttribute(Attribute.GENERIC_ATTACK_KNOCKBACK)?.baseValue = attributeValue
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.willfp.eco.internal.entities
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParseResult
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParser
|
||||||
|
import org.bukkit.attribute.Attribute
|
||||||
|
import org.bukkit.entity.LivingEntity
|
||||||
|
|
||||||
|
class EntityArgParserKnockbackResistance : EntityArgParser {
|
||||||
|
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
|
||||||
|
var attributeValue: Double? = null
|
||||||
|
|
||||||
|
for (arg in args) {
|
||||||
|
val argSplit = arg.split(":")
|
||||||
|
if (!argSplit[0].equals("knockback-resistance", ignoreCase = true)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (argSplit.size < 2) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
attributeValue = argSplit[1].toDoubleOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
attributeValue ?: return null
|
||||||
|
|
||||||
|
return EntityArgParseResult(
|
||||||
|
{
|
||||||
|
if (it !is LivingEntity) {
|
||||||
|
return@EntityArgParseResult false
|
||||||
|
}
|
||||||
|
|
||||||
|
val inst = it.getAttribute(Attribute.GENERIC_KNOCKBACK_RESISTANCE) ?: return@EntityArgParseResult false
|
||||||
|
inst.value >= attributeValue
|
||||||
|
},
|
||||||
|
{
|
||||||
|
if (it !is LivingEntity) {
|
||||||
|
return@EntityArgParseResult
|
||||||
|
}
|
||||||
|
|
||||||
|
it.getAttribute(Attribute.GENERIC_KNOCKBACK_RESISTANCE)?.baseValue = attributeValue
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.willfp.eco.internal.entities
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParseResult
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParser
|
||||||
|
import com.willfp.eco.util.StringUtils
|
||||||
|
|
||||||
|
class EntityArgParserName : EntityArgParser {
|
||||||
|
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
|
||||||
|
var name: String? = null
|
||||||
|
|
||||||
|
for (arg in args) {
|
||||||
|
val argSplit = arg.split(":")
|
||||||
|
if (!argSplit[0].equals("name", ignoreCase = true)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (argSplit.size < 2) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
name = argSplit[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
name ?: return null
|
||||||
|
|
||||||
|
val formatted = StringUtils.format(name)
|
||||||
|
|
||||||
|
return EntityArgParseResult(
|
||||||
|
{ it.customName == formatted },
|
||||||
|
{
|
||||||
|
it.isCustomNameVisible = true
|
||||||
|
it.customName = formatted
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.willfp.eco.internal.entities
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParseResult
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParser
|
||||||
|
import org.bukkit.entity.LivingEntity
|
||||||
|
|
||||||
|
class EntityArgParserNoAI : EntityArgParser {
|
||||||
|
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
|
||||||
|
var noAI = false
|
||||||
|
|
||||||
|
for (arg in args) {
|
||||||
|
if (arg.equals("no-ai", true)) {
|
||||||
|
noAI = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!noAI) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return EntityArgParseResult(
|
||||||
|
{
|
||||||
|
if (it !is LivingEntity) {
|
||||||
|
return@EntityArgParseResult false
|
||||||
|
}
|
||||||
|
|
||||||
|
!it.hasAI()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
(it as? LivingEntity)?.setAI(false)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.willfp.eco.internal.entities
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParseResult
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParser
|
||||||
|
import org.bukkit.entity.Phantom
|
||||||
|
import org.bukkit.entity.Slime
|
||||||
|
|
||||||
|
class EntityArgParserSize : EntityArgParser {
|
||||||
|
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
|
||||||
|
var size: Int? = null
|
||||||
|
|
||||||
|
for (arg in args) {
|
||||||
|
val argSplit = arg.split(":")
|
||||||
|
if (!argSplit[0].equals("size", ignoreCase = true)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (argSplit.size < 2) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
size = argSplit[1].toIntOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
size ?: return null
|
||||||
|
|
||||||
|
return EntityArgParseResult(
|
||||||
|
{
|
||||||
|
when (it) {
|
||||||
|
is Slime -> it.size == size
|
||||||
|
is Phantom -> it.size == size
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
when (it) {
|
||||||
|
is Slime -> it.size = size
|
||||||
|
is Phantom -> it.size = size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.willfp.eco.internal.entities
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParseResult
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParser
|
||||||
|
import org.bukkit.attribute.Attribute
|
||||||
|
import org.bukkit.entity.LivingEntity
|
||||||
|
|
||||||
|
class EntityArgParserSpawnReinforcements : EntityArgParser {
|
||||||
|
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
|
||||||
|
var attributeValue: Double? = null
|
||||||
|
|
||||||
|
for (arg in args) {
|
||||||
|
val argSplit = arg.split(":")
|
||||||
|
if (!argSplit[0].equals("spawn-reinforcements", ignoreCase = true)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (argSplit.size < 2) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
attributeValue = argSplit[1].toDoubleOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
attributeValue ?: return null
|
||||||
|
|
||||||
|
return EntityArgParseResult(
|
||||||
|
{
|
||||||
|
if (it !is LivingEntity) {
|
||||||
|
return@EntityArgParseResult false
|
||||||
|
}
|
||||||
|
|
||||||
|
val inst = it.getAttribute(Attribute.ZOMBIE_SPAWN_REINFORCEMENTS) ?: return@EntityArgParseResult false
|
||||||
|
inst.value >= attributeValue
|
||||||
|
},
|
||||||
|
{
|
||||||
|
if (it !is LivingEntity) {
|
||||||
|
return@EntityArgParseResult
|
||||||
|
}
|
||||||
|
|
||||||
|
it.getAttribute(Attribute.ZOMBIE_SPAWN_REINFORCEMENTS)?.baseValue = attributeValue
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.willfp.eco.internal.entities
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParseResult
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParser
|
||||||
|
import org.bukkit.attribute.Attribute
|
||||||
|
import org.bukkit.entity.LivingEntity
|
||||||
|
|
||||||
|
class EntityArgParserSpeed : EntityArgParser {
|
||||||
|
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
|
||||||
|
var attributeValue: Double? = null
|
||||||
|
|
||||||
|
for (arg in args) {
|
||||||
|
val argSplit = arg.split(":")
|
||||||
|
if (!argSplit[0].equals("speed", ignoreCase = true)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (argSplit.size < 2) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
attributeValue = argSplit[1].toDoubleOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
attributeValue ?: return null
|
||||||
|
|
||||||
|
return EntityArgParseResult(
|
||||||
|
{
|
||||||
|
if (it !is LivingEntity) {
|
||||||
|
return@EntityArgParseResult false
|
||||||
|
}
|
||||||
|
|
||||||
|
val inst = it.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED) ?: return@EntityArgParseResult false
|
||||||
|
inst.value >= attributeValue
|
||||||
|
},
|
||||||
|
{
|
||||||
|
if (it !is LivingEntity) {
|
||||||
|
return@EntityArgParseResult
|
||||||
|
}
|
||||||
|
|
||||||
|
it.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED)?.baseValue = attributeValue
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,8 +10,6 @@ import com.willfp.eco.core.extensions.MalformedExtensionException
|
|||||||
import org.bukkit.configuration.file.YamlConfiguration
|
import org.bukkit.configuration.file.YamlConfiguration
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.InputStreamReader
|
import java.io.InputStreamReader
|
||||||
import java.net.MalformedURLException
|
|
||||||
import java.net.URL
|
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
|
|
||||||
class EcoExtensionLoader(
|
class EcoExtensionLoader(
|
||||||
@@ -32,9 +30,7 @@ class EcoExtensionLoader(
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
runCatching { loadExtension(extensionJar) }.onFailure {
|
||||||
loadExtension(extensionJar)
|
|
||||||
} catch (e: MalformedExtensionException) {
|
|
||||||
this.plugin.logger.warning(extensionJar.name + " caused an error!")
|
this.plugin.logger.warning(extensionJar.name + " caused an error!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,13 +38,7 @@ class EcoExtensionLoader(
|
|||||||
|
|
||||||
@Throws(MalformedExtensionException::class)
|
@Throws(MalformedExtensionException::class)
|
||||||
private fun loadExtension(extensionJar: File) {
|
private fun loadExtension(extensionJar: File) {
|
||||||
lateinit var url: URL
|
val url = extensionJar.toURI().toURL()
|
||||||
|
|
||||||
try {
|
|
||||||
url = extensionJar.toURI().toURL()
|
|
||||||
} catch (e: MalformedURLException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
|
|
||||||
val classLoader = URLClassLoader(arrayOf(url), this.plugin::class.java.classLoader)
|
val classLoader = URLClassLoader(arrayOf(url), this.plugin::class.java.classLoader)
|
||||||
val ymlIn = classLoader.getResourceAsStream("extension.yml")
|
val ymlIn = classLoader.getResourceAsStream("extension.yml")
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class PlaceholderIntegrationPAPI(private val plugin: EcoPlugin) : PlaceholderExp
|
|||||||
player: Player?,
|
player: Player?,
|
||||||
identifier: String
|
identifier: String
|
||||||
): String {
|
): String {
|
||||||
return PlaceholderManager.getResult(player, identifier)
|
return PlaceholderManager.getResult(player, identifier, plugin)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun registerIntegration() {
|
override fun registerIntegration() {
|
||||||
@@ -49,4 +49,14 @@ class PlaceholderIntegrationPAPI(private val plugin: EcoPlugin) : PlaceholderExp
|
|||||||
): String {
|
): String {
|
||||||
return PlaceholderAPI.setPlaceholders(player, text)
|
return PlaceholderAPI.setPlaceholders(player, text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun findPlaceholdersIn(text: String): MutableList<String> {
|
||||||
|
val placeholders = mutableListOf<String>()
|
||||||
|
val matcher = PlaceholderAPI.getPlaceholderPattern().matcher(text)
|
||||||
|
while (matcher.find()) {
|
||||||
|
placeholders.add(matcher.group())
|
||||||
|
}
|
||||||
|
|
||||||
|
return placeholders
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -11,12 +11,7 @@ class ArgParserFlag : LookupArgParser {
|
|||||||
val flags = mutableSetOf<ItemFlag>()
|
val flags = mutableSetOf<ItemFlag>()
|
||||||
|
|
||||||
for (arg in args) {
|
for (arg in args) {
|
||||||
val flag = try {
|
val flag = kotlin.runCatching { ItemFlag.valueOf(arg.uppercase()) }.getOrNull() ?: continue
|
||||||
ItemFlag.valueOf(arg.uppercase())
|
|
||||||
} catch (e: Exception) {
|
|
||||||
null
|
|
||||||
} ?: continue
|
|
||||||
|
|
||||||
flags.add(flag)
|
flags.add(flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class ArgParserName : LookupArgParser {
|
|||||||
if (argSplit.size < 2) {
|
if (argSplit.size < 2) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
name = argSplit[1].replace("_", "")
|
name = argSplit[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
name ?: return null
|
name ?: return null
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_16_R3
|
||||||
|
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.DummyEntityProxy
|
||||||
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.craftbukkit.v1_16_R3.CraftWorld
|
||||||
|
import org.bukkit.entity.Entity
|
||||||
|
import org.bukkit.entity.EntityType
|
||||||
|
|
||||||
|
class DummyEntity : DummyEntityProxy {
|
||||||
|
override fun createDummyEntity(location: Location): Entity {
|
||||||
|
val world = location.world as CraftWorld
|
||||||
|
@Suppress("UsePropertyAccessSyntax")
|
||||||
|
return world.createEntity(location, EntityType.ZOMBIE.entityClass).getBukkitEntity()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
package com.willfp.eco.internal.spigot.proxy.v1_16_R3
|
package com.willfp.eco.internal.spigot.proxy.v1_16_R3
|
||||||
|
|
||||||
import com.willfp.eco.core.display.Display
|
import com.willfp.eco.core.display.Display
|
||||||
import com.willfp.eco.internal.spigot.proxy.VillagerTradeProxy
|
import com.willfp.eco.internal.spigot.proxy.VillagerTradeProxy
|
||||||
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftMerchantRecipe
|
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftMerchantRecipe
|
||||||
@@ -30,21 +31,11 @@ class VillagerTrade : VillagerTradeProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getHandle(recipe: CraftMerchantRecipe): net.minecraft.server.v1_16_R3.MerchantRecipe {
|
private fun getHandle(recipe: CraftMerchantRecipe): net.minecraft.server.v1_16_R3.MerchantRecipe {
|
||||||
try {
|
return handle[recipe] as net.minecraft.server.v1_16_R3.MerchantRecipe
|
||||||
return handle[recipe] as net.minecraft.server.v1_16_R3.MerchantRecipe
|
|
||||||
} catch (e: IllegalAccessException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
throw IllegalArgumentException("Not CMR")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
try {
|
handle = CraftMerchantRecipe::class.java.getDeclaredField("handle")
|
||||||
handle = CraftMerchantRecipe::class.java.getDeclaredField("handle")
|
handle.isAccessible = true
|
||||||
handle.isAccessible = true
|
|
||||||
} catch (e: NoSuchFieldException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
throw RuntimeException("Error!")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("io.papermc.paperweight.userdev") version "1.2.0"
|
id("io.papermc.paperweight.userdev") version "1.3.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "com.willfp"
|
group = "com.willfp"
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_17_R1
|
||||||
|
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.DummyEntityProxy
|
||||||
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.craftbukkit.v1_17_R1.CraftWorld
|
||||||
|
import org.bukkit.entity.Entity
|
||||||
|
import org.bukkit.entity.EntityType
|
||||||
|
|
||||||
|
class DummyEntity : DummyEntityProxy {
|
||||||
|
override fun createDummyEntity(location: Location): Entity {
|
||||||
|
val world = location.world as CraftWorld
|
||||||
|
@Suppress("UsePropertyAccessSyntax")
|
||||||
|
return world.createEntity(location, EntityType.ZOMBIE.entityClass).getBukkitEntity()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -87,33 +87,29 @@ class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemS
|
|||||||
|
|
||||||
override fun getLore(): List<String> {
|
override fun getLore(): List<String> {
|
||||||
if (loreCache != null) {
|
if (loreCache != null) {
|
||||||
return loreCache as List<String>
|
return loreCache!!
|
||||||
}
|
|
||||||
|
|
||||||
val lore: MutableList<String> = ArrayList()
|
|
||||||
|
|
||||||
for (s in getLoreJSON()) {
|
|
||||||
lore.add(StringUtils.jsonToLegacy(s))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val lore = this.getLoreJSON().map { StringUtils.jsonToLegacy(it) }
|
||||||
loreCache = lore
|
loreCache = lore
|
||||||
return lore
|
return lore
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getLoreJSON(): List<String> {
|
private fun getLoreJSON(): List<String> {
|
||||||
val displayTag = handle.getTagElement("display") ?: return emptyList()
|
val displayTag = handle.getTagElement("display") ?: return emptyList()
|
||||||
return if (displayTag.contains("Lore")) {
|
|
||||||
val loreTag = displayTag.getList("Lore", CraftMagicNumbers.NBT.TAG_STRING)
|
|
||||||
val lore: MutableList<String> = ArrayList(loreTag.size)
|
|
||||||
|
|
||||||
for (i in loreTag.indices) {
|
if (!displayTag.contains("Lore")) {
|
||||||
lore.add(loreTag.getString(i))
|
return emptyList()
|
||||||
}
|
|
||||||
|
|
||||||
lore
|
|
||||||
} else {
|
|
||||||
emptyList()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val loreTag = displayTag.getList("Lore", CraftMagicNumbers.NBT.TAG_STRING)
|
||||||
|
val lore = mutableListOf<String>()
|
||||||
|
|
||||||
|
for (i in loreTag.indices) {
|
||||||
|
lore.add(loreTag.getString(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
return lore
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addItemFlags(vararg hideFlags: ItemFlag) {
|
override fun addItemFlags(vararg hideFlags: ItemFlag) {
|
||||||
@@ -155,11 +151,11 @@ class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemS
|
|||||||
|
|
||||||
private var flagBits: Int
|
private var flagBits: Int
|
||||||
get() =
|
get() =
|
||||||
if (handle.hasTag() && handle.tag!!.contains(
|
if (handle.hasTag() && handle.tag.contains(
|
||||||
"HideFlags",
|
"HideFlags",
|
||||||
99
|
99
|
||||||
)
|
)
|
||||||
) handle.tag!!.getInt("HideFlags") else 0
|
) handle.tag.getInt("HideFlags") else 0
|
||||||
set(value) =
|
set(value) =
|
||||||
handle.orCreateTag.putInt("HideFlags", value)
|
handle.orCreateTag.putInt("HideFlags", value)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,16 @@
|
|||||||
|
plugins {
|
||||||
|
id("io.papermc.paperweight.userdev") version "1.3.3"
|
||||||
|
}
|
||||||
|
|
||||||
group = "com.willfp"
|
group = "com.willfp"
|
||||||
version = rootProject.version
|
version = rootProject.version
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(files("./impl.jar"))
|
paperDevBundle("1.18.1-R0.1-SNAPSHOT")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
build {
|
||||||
|
dependsOn(reobfJar)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Binary file not shown.
@@ -0,0 +1,15 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
|
||||||
|
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.AutoCraftProxy
|
||||||
|
import net.minecraft.network.protocol.game.ClientboundPlaceGhostRecipePacket
|
||||||
|
import net.minecraft.resources.ResourceLocation
|
||||||
|
|
||||||
|
class AutoCraft : AutoCraftProxy {
|
||||||
|
override fun modifyPacket(packet: Any) {
|
||||||
|
val recipePacket = packet as ClientboundPlaceGhostRecipePacket
|
||||||
|
val fKey = recipePacket.javaClass.getDeclaredField("b")
|
||||||
|
fKey.isAccessible = true
|
||||||
|
val key = fKey[recipePacket] as ResourceLocation
|
||||||
|
fKey[recipePacket] = ResourceLocation(key.namespace, key.path + "_displayed")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
|
||||||
|
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.BlockBreakProxy
|
||||||
|
import org.bukkit.block.Block
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
|
class BlockBreak : BlockBreakProxy {
|
||||||
|
override fun breakBlock(
|
||||||
|
player: Player,
|
||||||
|
block: Block
|
||||||
|
) {
|
||||||
|
player.breakBlock(block)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
|
||||||
|
|
||||||
|
import com.willfp.eco.core.display.Display
|
||||||
|
import com.willfp.eco.internal.spigot.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_18_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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
|
||||||
|
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.DummyEntityProxy
|
||||||
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.CraftWorld
|
||||||
|
import org.bukkit.entity.Entity
|
||||||
|
import org.bukkit.entity.EntityType
|
||||||
|
|
||||||
|
class DummyEntity : DummyEntityProxy {
|
||||||
|
override fun createDummyEntity(location: Location): Entity {
|
||||||
|
val world = location.world as CraftWorld
|
||||||
|
@Suppress("UsePropertyAccessSyntax")
|
||||||
|
return world.createEntity(location, EntityType.ZOMBIE.entityClass).getBukkitEntity()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
|
||||||
|
|
||||||
|
import com.willfp.eco.core.fast.FastItemStack
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.v1_18_R1.fast.NMSFastItemStack
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
|
||||||
|
class FastItemStackFactory : FastItemStackFactoryProxy {
|
||||||
|
override fun create(itemStack: ItemStack): FastItemStack {
|
||||||
|
return NMSFastItemStack(itemStack)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
|
||||||
|
|
||||||
|
import com.mojang.authlib.GameProfile
|
||||||
|
import com.mojang.authlib.properties.Property
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.SkullProxy
|
||||||
|
import org.bukkit.inventory.meta.SkullMeta
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
import java.lang.reflect.Method
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
class Skull : SkullProxy {
|
||||||
|
private lateinit var setProfile: Method
|
||||||
|
private lateinit var profile: Field
|
||||||
|
|
||||||
|
override fun setSkullTexture(
|
||||||
|
meta: SkullMeta,
|
||||||
|
base64: String
|
||||||
|
) {
|
||||||
|
if (!this::setProfile.isInitialized) {
|
||||||
|
setProfile = meta.javaClass.getDeclaredMethod("setProfile", GameProfile::class.java)
|
||||||
|
setProfile.isAccessible = true
|
||||||
|
}
|
||||||
|
val uuid = UUID(
|
||||||
|
base64.substring(base64.length - 20).hashCode().toLong(),
|
||||||
|
base64.substring(base64.length - 10).hashCode().toLong()
|
||||||
|
)
|
||||||
|
val profile = GameProfile(uuid, "eco")
|
||||||
|
profile.properties.put("textures", Property("textures", base64))
|
||||||
|
setProfile.invoke(meta, profile)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSkullTexture(
|
||||||
|
meta: SkullMeta
|
||||||
|
): String? {
|
||||||
|
if (!this::profile.isInitialized) {
|
||||||
|
profile = meta.javaClass.getDeclaredField("profile")
|
||||||
|
profile.isAccessible = true
|
||||||
|
}
|
||||||
|
val profile = profile[meta] as GameProfile? ?: return null
|
||||||
|
val properties = profile.properties ?: return null
|
||||||
|
val prop = properties["textures"] ?: return null
|
||||||
|
return prop.toMutableList().firstOrNull()?.name
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
|
||||||
|
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.TPSProxy
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.CraftServer
|
||||||
|
|
||||||
|
class TPS : TPSProxy {
|
||||||
|
override fun getTPS(): Double {
|
||||||
|
return (Bukkit.getServer() as CraftServer).handle.server.recentTps[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
|
||||||
|
|
||||||
|
import com.willfp.eco.core.display.Display
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.VillagerTradeProxy
|
||||||
|
import net.minecraft.world.item.trading.MerchantOffer
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftMerchantRecipe
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.inventory.MerchantRecipe
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
|
||||||
|
class VillagerTrade : VillagerTradeProxy {
|
||||||
|
private val handle: Field = CraftMerchantRecipe::class.java.getDeclaredField("handle")
|
||||||
|
|
||||||
|
override fun displayTrade(
|
||||||
|
recipe: MerchantRecipe,
|
||||||
|
player: Player
|
||||||
|
): MerchantRecipe {
|
||||||
|
val oldRecipe = recipe as CraftMerchantRecipe
|
||||||
|
val newRecipe = CraftMerchantRecipe(
|
||||||
|
Display.display(recipe.getResult().clone(), player),
|
||||||
|
recipe.getUses(),
|
||||||
|
recipe.getMaxUses(),
|
||||||
|
recipe.hasExperienceReward(),
|
||||||
|
recipe.getVillagerExperience(),
|
||||||
|
recipe.getPriceMultiplier()
|
||||||
|
)
|
||||||
|
for (ingredient in recipe.getIngredients()) {
|
||||||
|
newRecipe.addIngredient(Display.display(ingredient.clone(), player))
|
||||||
|
}
|
||||||
|
getHandle(newRecipe).setSpecialPriceDiff(getHandle(oldRecipe).getSpecialPriceDiff())
|
||||||
|
return newRecipe
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getHandle(recipe: CraftMerchantRecipe): MerchantOffer {
|
||||||
|
return handle[recipe] as MerchantOffer
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
handle.isAccessible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R1.fast
|
||||||
|
|
||||||
|
import org.bukkit.craftbukkit.v1_18_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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,188 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy.v1_18_R1.fast
|
||||||
|
|
||||||
|
import com.willfp.eco.internal.fast.EcoFastItemStack
|
||||||
|
import com.willfp.eco.util.StringUtils
|
||||||
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.minecraft.nbt.ListTag
|
||||||
|
import net.minecraft.nbt.StringTag
|
||||||
|
import net.minecraft.world.item.EnchantedBookItem
|
||||||
|
import net.minecraft.world.item.Item
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import net.minecraft.world.item.Items
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.util.CraftMagicNumbers
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.util.CraftNamespacedKey
|
||||||
|
import org.bukkit.enchantments.Enchantment
|
||||||
|
import org.bukkit.inventory.ItemFlag
|
||||||
|
import kotlin.experimental.and
|
||||||
|
|
||||||
|
@Suppress("UsePropertyAccessSyntax")
|
||||||
|
class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemStack<ItemStack>(
|
||||||
|
itemStack.getNMSStack(), itemStack
|
||||||
|
) {
|
||||||
|
private var loreCache: List<String>? = null
|
||||||
|
|
||||||
|
override fun getEnchantmentsOnItem(checkStored: Boolean): Map<Enchantment, Int> {
|
||||||
|
val enchantmentNBT =
|
||||||
|
if (checkStored && handle.getItem() === Items.ENCHANTED_BOOK) EnchantedBookItem.getEnchantments(
|
||||||
|
handle
|
||||||
|
) else handle.getEnchantmentTags()
|
||||||
|
val foundEnchantments: MutableMap<Enchantment, Int> = HashMap()
|
||||||
|
for (base in enchantmentNBT) {
|
||||||
|
val compound = base as CompoundTag
|
||||||
|
val key = compound.getString("id")
|
||||||
|
val level = ('\uffff'.code.toShort() and compound.getShort("lvl")).toInt()
|
||||||
|
val found = Enchantment.getByKey(CraftNamespacedKey.fromStringOrNull(key))
|
||||||
|
if (found != null) {
|
||||||
|
foundEnchantments[found] = level
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return foundEnchantments
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLevelOnItem(
|
||||||
|
enchantment: Enchantment,
|
||||||
|
checkStored: Boolean
|
||||||
|
): Int {
|
||||||
|
val enchantmentNBT =
|
||||||
|
if (checkStored && handle.getItem() === Items.ENCHANTED_BOOK) EnchantedBookItem.getEnchantments(
|
||||||
|
handle
|
||||||
|
) else handle.getEnchantmentTags()
|
||||||
|
for (base in enchantmentNBT) {
|
||||||
|
val compound = base as CompoundTag
|
||||||
|
val key = compound.getString("id")
|
||||||
|
if (key != enchantment.key.toString()) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return ('\uffff'.code.toShort() and compound.getShort("lvl")).toInt()
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setLore(lore: List<String>?) {
|
||||||
|
loreCache = null
|
||||||
|
val jsonLore: MutableList<String> = ArrayList()
|
||||||
|
|
||||||
|
if (lore != null) {
|
||||||
|
for (s in lore) {
|
||||||
|
jsonLore.add(StringUtils.legacyToJson(s))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val displayTag = handle.getOrCreateTagElement("display")
|
||||||
|
|
||||||
|
if (!displayTag.contains("Lore")) {
|
||||||
|
displayTag.put("Lore", ListTag())
|
||||||
|
}
|
||||||
|
|
||||||
|
val loreTag = displayTag.getList("Lore", CraftMagicNumbers.NBT.TAG_STRING)
|
||||||
|
|
||||||
|
loreTag.clear()
|
||||||
|
|
||||||
|
for (s in jsonLore) {
|
||||||
|
loreTag.add(StringTag.valueOf(s))
|
||||||
|
}
|
||||||
|
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLore(): List<String> {
|
||||||
|
if (loreCache != null) {
|
||||||
|
return loreCache!!
|
||||||
|
}
|
||||||
|
|
||||||
|
val lore = this.getLoreJSON().map { StringUtils.jsonToLegacy(it) }
|
||||||
|
loreCache = lore
|
||||||
|
return lore
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getLoreJSON(): List<String> {
|
||||||
|
val displayTag = handle.getTagElement("display") ?: return emptyList()
|
||||||
|
|
||||||
|
if (!displayTag.contains("Lore")) {
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
val loreTag = displayTag.getList("Lore", CraftMagicNumbers.NBT.TAG_STRING)
|
||||||
|
val lore = ArrayList<String>(loreTag.size)
|
||||||
|
|
||||||
|
for (i in loreTag.indices) {
|
||||||
|
lore.add(loreTag.getString(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
return lore
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addItemFlags(vararg hideFlags: ItemFlag) {
|
||||||
|
for (flag in hideFlags) {
|
||||||
|
this.flagBits = this.flagBits or getBitModifier(flag)
|
||||||
|
}
|
||||||
|
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun removeItemFlags(vararg hideFlags: ItemFlag) {
|
||||||
|
for (flag in hideFlags) {
|
||||||
|
this.flagBits = this.flagBits and getBitModifier(flag)
|
||||||
|
}
|
||||||
|
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemFlags(): MutableSet<ItemFlag> {
|
||||||
|
val flags = mutableSetOf<ItemFlag>()
|
||||||
|
|
||||||
|
var flagArr: Array<ItemFlag>
|
||||||
|
val size = ItemFlag.values().also { flagArr = it }.size
|
||||||
|
|
||||||
|
for (i in 0 until size) {
|
||||||
|
val flag = flagArr[i]
|
||||||
|
if (this.hasItemFlag(flag)) {
|
||||||
|
flags.add(flag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return flags
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hasItemFlag(flag: ItemFlag): Boolean {
|
||||||
|
val bitModifier = getBitModifier(flag)
|
||||||
|
return this.flagBits and bitModifier == bitModifier
|
||||||
|
}
|
||||||
|
|
||||||
|
private var flagBits: Int
|
||||||
|
get() =
|
||||||
|
if (handle.hasTag() && handle.getTag()!!.contains(
|
||||||
|
"HideFlags",
|
||||||
|
99
|
||||||
|
)
|
||||||
|
) handle.getTag()!!.getInt("HideFlags") else 0
|
||||||
|
set(value) =
|
||||||
|
handle.getOrCreateTag().putInt("HideFlags", value)
|
||||||
|
|
||||||
|
override fun getRepairCost(): Int {
|
||||||
|
return handle.getBaseRepairCost()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setRepairCost(cost: Int) {
|
||||||
|
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.getTag()?.hashCode() ?: (0b00010101 * 31 + Item.getId(handle.getItem()))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun apply() {
|
||||||
|
if (bukkit !is CraftItemStack) {
|
||||||
|
bukkit.itemMeta = CraftItemStack.asCraftMirror(handle).itemMeta
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ dependencies {
|
|||||||
implementation('net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT') {
|
implementation('net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT') {
|
||||||
exclude group: 'net.kyori', module: 'adventure-api'
|
exclude group: 'net.kyori', module: 'adventure-api'
|
||||||
}
|
}
|
||||||
|
implementation 'com.github.Redempt:Crunch:1.0'
|
||||||
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
|
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
|
||||||
compileOnly 'org.apache.maven:maven-artifact:3.8.1'
|
compileOnly 'org.apache.maven:maven-artifact:3.8.1'
|
||||||
compileOnly 'com.google.code.gson:gson:2.8.8'
|
compileOnly 'com.google.code.gson:gson:2.8.8'
|
||||||
@@ -25,6 +26,7 @@ dependencies {
|
|||||||
compileOnly 'com.gmail.nossr50.mcMMO:mcMMO:2.1.202'
|
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.github.oraxen:oraxen:bd81ace154'
|
compileOnly 'com.github.oraxen:oraxen:bd81ace154'
|
||||||
|
compileOnly 'com.github.Ssomar-Developement:ExecutableItems:master-SNAPSHOT'
|
||||||
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 'com.arcaniax:HeadDatabase-API:1.3.0'
|
compileOnly 'com.arcaniax:HeadDatabase-API:1.3.0'
|
||||||
@@ -35,14 +37,15 @@ dependencies {
|
|||||||
compileOnly 'com.zaxxer:HikariCP:5.0.0'
|
compileOnly 'com.zaxxer:HikariCP:5.0.0'
|
||||||
compileOnly 'com.gmail.filoghost.holographicdisplays:holographicdisplays-api:2.4.0'
|
compileOnly 'com.gmail.filoghost.holographicdisplays:holographicdisplays-api:2.4.0'
|
||||||
compileOnly 'com.github.EssentialsX:Essentials:2.19.0'
|
compileOnly 'com.github.EssentialsX:Essentials:2.19.0'
|
||||||
compileOnly 'com.bgsoftware:SuperiorSkyblockAPI:latest'
|
compileOnly 'com.bgsoftware:SuperiorSkyblockAPI:1.8.3'
|
||||||
compileOnly 'com.github.MilkBowl:VaultAPI:1.7'
|
compileOnly 'com.github.MilkBowl:VaultAPI:1.7'
|
||||||
compileOnly 'world.bentobox:bentobox:1.17.3-SNAPSHOT'
|
compileOnly 'world.bentobox:bentobox:1.17.3-SNAPSHOT'
|
||||||
compileOnly 'com.google.guava:guava:31.0.1-jre'
|
compileOnly 'com.google.guava:guava:31.0.1-jre'
|
||||||
compileOnly 'com.iridium:IridiumSkyblock:3.1.2'
|
compileOnly 'com.iridium:IridiumSkyblock:3.1.2'
|
||||||
compileOnly 'com.github.WillFP:CrashClaim:1.0.19'
|
compileOnly 'com.github.WhipDevelopment:CrashClaim:f9cd7d92eb'
|
||||||
compileOnly 'com.wolfyscript.wolfyutilities:wolfyutilities:1.7.8.1'
|
compileOnly 'com.wolfyscript.wolfyutilities:wolfyutilities:1.7.8.1'
|
||||||
compileOnly 'com.github.decentsoftware-eu:decentholograms:2.1.2'
|
compileOnly 'com.github.decentsoftware-eu:decentholograms:2.1.2'
|
||||||
|
compileOnly 'io.lumine.xikage:MythicMobs:4.9.1'
|
||||||
|
|
||||||
// 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'
|
||||||
|
|||||||
@@ -25,8 +25,11 @@ import com.willfp.eco.internal.spigot.data.EcoPlayerProfileHandler
|
|||||||
import com.willfp.eco.internal.spigot.data.storage.MySQLDataHandler
|
import com.willfp.eco.internal.spigot.data.storage.MySQLDataHandler
|
||||||
import com.willfp.eco.internal.spigot.data.storage.YamlDataHandler
|
import com.willfp.eco.internal.spigot.data.storage.YamlDataHandler
|
||||||
import com.willfp.eco.internal.spigot.integrations.bstats.MetricHandler
|
import com.willfp.eco.internal.spigot.integrations.bstats.MetricHandler
|
||||||
|
import com.willfp.eco.internal.spigot.proxy.DummyEntityProxy
|
||||||
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
|
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences
|
||||||
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.entity.Entity
|
||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
import java.util.logging.Logger
|
import java.util.logging.Logger
|
||||||
|
|
||||||
@@ -140,4 +143,8 @@ class EcoHandler : EcoSpigotPlugin(), Handler {
|
|||||||
fun setAdventure(adventure: BukkitAudiences) {
|
fun setAdventure(adventure: BukkitAudiences) {
|
||||||
this.adventure = adventure
|
this.adventure = adventure
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun createDummyEntity(location: Location): Entity {
|
||||||
|
return getProxy(DummyEntityProxy::class.java).createDummyEntity(location)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -5,10 +5,12 @@ 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.Prerequisite
|
||||||
import com.willfp.eco.core.display.Display
|
import com.willfp.eco.core.display.Display
|
||||||
|
import com.willfp.eco.core.entities.Entities
|
||||||
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.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.customentities.CustomEntitiesManager
|
||||||
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.economy.EconomyManager
|
||||||
import com.willfp.eco.core.integrations.hologram.HologramManager
|
import com.willfp.eco.core.integrations.hologram.HologramManager
|
||||||
@@ -17,6 +19,23 @@ import com.willfp.eco.core.integrations.shop.ShopManager
|
|||||||
import com.willfp.eco.core.items.Items
|
import com.willfp.eco.core.items.Items
|
||||||
import com.willfp.eco.internal.display.EcoDisplayHandler
|
import com.willfp.eco.internal.display.EcoDisplayHandler
|
||||||
import com.willfp.eco.internal.drops.DropManager
|
import com.willfp.eco.internal.drops.DropManager
|
||||||
|
import com.willfp.eco.internal.entities.EntityArgParserAdult
|
||||||
|
import com.willfp.eco.internal.entities.EntityArgParserAttackDamage
|
||||||
|
import com.willfp.eco.internal.entities.EntityArgParserAttackSpeed
|
||||||
|
import com.willfp.eco.internal.entities.EntityArgParserBaby
|
||||||
|
import com.willfp.eco.internal.entities.EntityArgParserCharged
|
||||||
|
import com.willfp.eco.internal.entities.EntityArgParserExplosionRadius
|
||||||
|
import com.willfp.eco.internal.entities.EntityArgParserFlySpeed
|
||||||
|
import com.willfp.eco.internal.entities.EntityArgParserFollowRange
|
||||||
|
import com.willfp.eco.internal.entities.EntityArgParserHealth
|
||||||
|
import com.willfp.eco.internal.entities.EntityArgParserJumpStrength
|
||||||
|
import com.willfp.eco.internal.entities.EntityArgParserKnockback
|
||||||
|
import com.willfp.eco.internal.entities.EntityArgParserKnockbackResistance
|
||||||
|
import com.willfp.eco.internal.entities.EntityArgParserName
|
||||||
|
import com.willfp.eco.internal.entities.EntityArgParserNoAI
|
||||||
|
import com.willfp.eco.internal.entities.EntityArgParserSize
|
||||||
|
import com.willfp.eco.internal.entities.EntityArgParserSpawnReinforcements
|
||||||
|
import com.willfp.eco.internal.entities.EntityArgParserSpeed
|
||||||
import com.willfp.eco.internal.items.ArgParserColor
|
import com.willfp.eco.internal.items.ArgParserColor
|
||||||
import com.willfp.eco.internal.items.ArgParserCustomModelData
|
import com.willfp.eco.internal.items.ArgParserCustomModelData
|
||||||
import com.willfp.eco.internal.items.ArgParserEnchantment
|
import com.willfp.eco.internal.items.ArgParserEnchantment
|
||||||
@@ -55,7 +74,6 @@ import com.willfp.eco.internal.spigot.integrations.anticheat.AnticheatVulcan
|
|||||||
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefBentoBox
|
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefBentoBox
|
||||||
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefCombatLogXV10
|
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefCombatLogXV10
|
||||||
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefCombatLogXV11
|
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefCombatLogXV11
|
||||||
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefCrashClaim
|
|
||||||
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefDeluxeCombat
|
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefDeluxeCombat
|
||||||
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefFactionsUUID
|
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefFactionsUUID
|
||||||
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefGriefPrevention
|
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefGriefPrevention
|
||||||
@@ -65,6 +83,9 @@ import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefLands
|
|||||||
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefSuperiorSkyblock2
|
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefSuperiorSkyblock2
|
||||||
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefTowny
|
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefTowny
|
||||||
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefWorldGuard
|
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefWorldGuard
|
||||||
|
import com.willfp.eco.internal.spigot.integrations.customentities.CustomEntitiesMythicMobs
|
||||||
|
import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsCustomCrafting
|
||||||
|
import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsExecutableItems
|
||||||
import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsHeadDatabase
|
import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsHeadDatabase
|
||||||
import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsItemsAdder
|
import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsItemsAdder
|
||||||
import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsOraxen
|
import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsOraxen
|
||||||
@@ -75,12 +96,14 @@ import com.willfp.eco.internal.spigot.integrations.hologram.HologramHolographicD
|
|||||||
import com.willfp.eco.internal.spigot.integrations.mcmmo.McmmoIntegrationImpl
|
import com.willfp.eco.internal.spigot.integrations.mcmmo.McmmoIntegrationImpl
|
||||||
import com.willfp.eco.internal.spigot.integrations.multiverseinventories.MultiverseInventoriesIntegration
|
import com.willfp.eco.internal.spigot.integrations.multiverseinventories.MultiverseInventoriesIntegration
|
||||||
import com.willfp.eco.internal.spigot.integrations.shop.ShopShopGuiPlus
|
import com.willfp.eco.internal.spigot.integrations.shop.ShopShopGuiPlus
|
||||||
|
import com.willfp.eco.internal.spigot.math.evaluateExpression
|
||||||
import com.willfp.eco.internal.spigot.proxy.BlockBreakProxy
|
import com.willfp.eco.internal.spigot.proxy.BlockBreakProxy
|
||||||
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
|
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
|
||||||
import com.willfp.eco.internal.spigot.proxy.SkullProxy
|
import com.willfp.eco.internal.spigot.proxy.SkullProxy
|
||||||
import com.willfp.eco.internal.spigot.proxy.TPSProxy
|
import com.willfp.eco.internal.spigot.proxy.TPSProxy
|
||||||
import com.willfp.eco.internal.spigot.recipes.ShapedRecipeListener
|
import com.willfp.eco.internal.spigot.recipes.ShapedRecipeListener
|
||||||
import com.willfp.eco.util.BlockUtils
|
import com.willfp.eco.util.BlockUtils
|
||||||
|
import com.willfp.eco.util.NumberUtils
|
||||||
import com.willfp.eco.util.ServerUtils
|
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
|
||||||
@@ -105,6 +128,24 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
|||||||
Items.registerArgParser(ArgParserUnbreakable())
|
Items.registerArgParser(ArgParserUnbreakable())
|
||||||
Items.registerArgParser(ArgParserName())
|
Items.registerArgParser(ArgParserName())
|
||||||
|
|
||||||
|
Entities.registerArgParser(EntityArgParserName())
|
||||||
|
Entities.registerArgParser(EntityArgParserNoAI())
|
||||||
|
Entities.registerArgParser(EntityArgParserAttackDamage())
|
||||||
|
Entities.registerArgParser(EntityArgParserAttackSpeed())
|
||||||
|
Entities.registerArgParser(EntityArgParserFlySpeed())
|
||||||
|
Entities.registerArgParser(EntityArgParserFollowRange())
|
||||||
|
Entities.registerArgParser(EntityArgParserHealth())
|
||||||
|
Entities.registerArgParser(EntityArgParserJumpStrength())
|
||||||
|
Entities.registerArgParser(EntityArgParserKnockback())
|
||||||
|
Entities.registerArgParser(EntityArgParserKnockbackResistance())
|
||||||
|
Entities.registerArgParser(EntityArgParserSize())
|
||||||
|
Entities.registerArgParser(EntityArgParserSpawnReinforcements())
|
||||||
|
Entities.registerArgParser(EntityArgParserSpeed())
|
||||||
|
Entities.registerArgParser(EntityArgParserBaby())
|
||||||
|
Entities.registerArgParser(EntityArgParserAdult())
|
||||||
|
Entities.registerArgParser(EntityArgParserCharged())
|
||||||
|
Entities.registerArgParser(EntityArgParserExplosionRadius())
|
||||||
|
|
||||||
val skullProxy = getProxy(SkullProxy::class.java)
|
val skullProxy = getProxy(SkullProxy::class.java)
|
||||||
SkullUtils.initialize(
|
SkullUtils.initialize(
|
||||||
{ meta, base64 -> skullProxy.setSkullTexture(meta, base64) },
|
{ meta, base64 -> skullProxy.setSkullTexture(meta, base64) },
|
||||||
@@ -117,6 +158,8 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
|||||||
val tpsProxy = getProxy(TPSProxy::class.java)
|
val tpsProxy = getProxy(TPSProxy::class.java)
|
||||||
ServerUtils.initialize { tpsProxy.getTPS() }
|
ServerUtils.initialize { tpsProxy.getTPS() }
|
||||||
|
|
||||||
|
NumberUtils.initCrunch { exp, player -> evaluateExpression(exp, player) }
|
||||||
|
|
||||||
postInit()
|
postInit()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,6 +192,11 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
|||||||
CollatedRunnable(this)
|
CollatedRunnable(this)
|
||||||
DropManager.update(this)
|
DropManager.update(this)
|
||||||
ProfileSaver(this)
|
ProfileSaver(this)
|
||||||
|
this.scheduler.runTimer(
|
||||||
|
{ Items.clearCache() },
|
||||||
|
this.configYml.getInt("item-cache-ttl").toLong(),
|
||||||
|
this.configYml.getInt("item-cache-ttl").toLong()
|
||||||
|
)
|
||||||
this.scheduler.runTimer(
|
this.scheduler.runTimer(
|
||||||
{ clearFrames() },
|
{ clearFrames() },
|
||||||
this.configYml.getInt("display-frame-ttl").toLong(),
|
this.configYml.getInt("display-frame-ttl").toLong(),
|
||||||
@@ -158,6 +206,7 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
|||||||
|
|
||||||
override fun handleAfterLoad() {
|
override fun handleAfterLoad() {
|
||||||
CustomItemsManager.registerAllItems()
|
CustomItemsManager.registerAllItems()
|
||||||
|
CustomEntitiesManager.registerAllEntities()
|
||||||
ShopManager.registerEcoProvider()
|
ShopManager.registerEcoProvider()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +223,7 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
|||||||
IntegrationLoader("Towny") { AntigriefManager.register(AntigriefTowny()) },
|
IntegrationLoader("Towny") { AntigriefManager.register(AntigriefTowny()) },
|
||||||
IntegrationLoader("Lands") { AntigriefManager.register(AntigriefLands(this)) },
|
IntegrationLoader("Lands") { AntigriefManager.register(AntigriefLands(this)) },
|
||||||
IntegrationLoader("Kingdoms") { AntigriefManager.register(AntigriefKingdoms()) },
|
IntegrationLoader("Kingdoms") { AntigriefManager.register(AntigriefKingdoms()) },
|
||||||
IntegrationLoader("CrashClaim") { AntigriefManager.register(AntigriefCrashClaim()) },
|
//IntegrationLoader("CrashClaim") { AntigriefManager.register(AntigriefCrashClaim()) },
|
||||||
IntegrationLoader("CombatLogX") {
|
IntegrationLoader("CombatLogX") {
|
||||||
val pluginManager = Bukkit.getPluginManager()
|
val pluginManager = Bukkit.getPluginManager()
|
||||||
val combatLogXPlugin = pluginManager.getPlugin("CombatLogX") ?: return@IntegrationLoader
|
val combatLogXPlugin = pluginManager.getPlugin("CombatLogX") ?: return@IntegrationLoader
|
||||||
@@ -195,10 +244,15 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
|||||||
IntegrationLoader("Vulcan") { AnticheatManager.register(this, AnticheatVulcan()) },
|
IntegrationLoader("Vulcan") { AnticheatManager.register(this, AnticheatVulcan()) },
|
||||||
IntegrationLoader("Alice") { AnticheatManager.register(this, AnticheatAlice()) },
|
IntegrationLoader("Alice") { AnticheatManager.register(this, AnticheatAlice()) },
|
||||||
|
|
||||||
|
// Custom Entities
|
||||||
|
IntegrationLoader("MythicMobs") { CustomEntitiesManager.register(CustomEntitiesMythicMobs()) },
|
||||||
|
|
||||||
// Custom Items
|
// Custom Items
|
||||||
IntegrationLoader("Oraxen") { CustomItemsManager.register(CustomItemsOraxen()) },
|
IntegrationLoader("Oraxen") { CustomItemsManager.register(CustomItemsOraxen()) },
|
||||||
IntegrationLoader("ItemsAdder") { CustomItemsManager.register(CustomItemsItemsAdder()) },
|
IntegrationLoader("ItemsAdder") { CustomItemsManager.register(CustomItemsItemsAdder()) },
|
||||||
IntegrationLoader("HeadDatabase") { CustomItemsManager.register(CustomItemsHeadDatabase(this)) },
|
IntegrationLoader("HeadDatabase") { CustomItemsManager.register(CustomItemsHeadDatabase(this)) },
|
||||||
|
IntegrationLoader("ExecutableItems") { CustomItemsManager.register(CustomItemsExecutableItems()) },
|
||||||
|
IntegrationLoader("CustomCrafting") { CustomItemsManager.register(CustomItemsCustomCrafting()) },
|
||||||
|
|
||||||
// Shop
|
// Shop
|
||||||
IntegrationLoader("ShopGUIPlus") { ShopManager.register(ShopShopGuiPlus()) },
|
IntegrationLoader("ShopGUIPlus") { ShopManager.register(ShopShopGuiPlus()) },
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import org.bukkit.event.block.BlockMultiPlaceEvent
|
|||||||
import org.bukkit.event.block.BlockPistonExtendEvent
|
import org.bukkit.event.block.BlockPistonExtendEvent
|
||||||
import org.bukkit.event.block.BlockPistonRetractEvent
|
import org.bukkit.event.block.BlockPistonRetractEvent
|
||||||
import org.bukkit.event.block.BlockPlaceEvent
|
import org.bukkit.event.block.BlockPlaceEvent
|
||||||
|
import org.bukkit.event.world.StructureGrowEvent
|
||||||
import org.bukkit.persistence.PersistentDataType
|
import org.bukkit.persistence.PersistentDataType
|
||||||
|
|
||||||
class PlayerBlockListener(
|
class PlayerBlockListener(
|
||||||
@@ -40,6 +41,15 @@ class PlayerBlockListener(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
fun onGrow(event: StructureGrowEvent) {
|
||||||
|
val block = event.location.block
|
||||||
|
|
||||||
|
this.plugin.scheduler.run {
|
||||||
|
removeKey(block)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
fun onExtend(event: BlockPistonExtendEvent) {
|
fun onExtend(event: BlockPistonExtendEvent) {
|
||||||
val locs = mutableListOf<Location>()
|
val locs = mutableListOf<Location>()
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class MySQLDataHandler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get Exposed to shut the hell up
|
// Get Exposed to shut the hell up
|
||||||
try {
|
runCatching {
|
||||||
exposedLogger::class.java.getDeclaredField("logger").apply { isAccessible = true }
|
exposedLogger::class.java.getDeclaredField("logger").apply { isAccessible = true }
|
||||||
.apply {
|
.apply {
|
||||||
get(exposedLogger).apply {
|
get(exposedLogger).apply {
|
||||||
@@ -63,8 +63,6 @@ class MySQLDataHandler(
|
|||||||
.invoke(this, Level.OFF)
|
.invoke(this, Level.OFF)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
|
||||||
Eco.getHandler().ecoPlugin.logger.warning("Failed to silence Exposed logger! You might get some console spam")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import com.willfp.eco.core.AbstractPacketAdapter
|
|||||||
import com.willfp.eco.core.EcoPlugin
|
import com.willfp.eco.core.EcoPlugin
|
||||||
import com.willfp.eco.internal.spigot.proxy.AutoCraftProxy
|
import com.willfp.eco.internal.spigot.proxy.AutoCraftProxy
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import java.lang.reflect.InvocationTargetException
|
|
||||||
|
|
||||||
class PacketAutoRecipe(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, PacketType.Play.Server.AUTO_RECIPE, false) {
|
class PacketAutoRecipe(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, PacketType.Play.Server.AUTO_RECIPE, false) {
|
||||||
override fun onSend(
|
override fun onSend(
|
||||||
@@ -27,10 +26,6 @@ class PacketAutoRecipe(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, Packet
|
|||||||
getPlugin().getProxy(AutoCraftProxy::class.java).modifyPacket(packet.handle)
|
getPlugin().getProxy(AutoCraftProxy::class.java).modifyPacket(packet.handle)
|
||||||
val newAutoRecipe = PacketContainer(PacketType.Play.Server.AUTO_RECIPE)
|
val newAutoRecipe = PacketContainer(PacketType.Play.Server.AUTO_RECIPE)
|
||||||
newAutoRecipe.minecraftKeys.write(0, packet.minecraftKeys.read(0))
|
newAutoRecipe.minecraftKeys.write(0, packet.minecraftKeys.read(0))
|
||||||
try {
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, newAutoRecipe)
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, newAutoRecipe)
|
|
||||||
} catch (e: InvocationTargetException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,7 @@ 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.google.common.util.concurrent.ThreadFactoryBuilder
|
||||||
import com.willfp.eco.core.AbstractPacketAdapter
|
import com.willfp.eco.core.AbstractPacketAdapter
|
||||||
|
import com.willfp.eco.core.Eco
|
||||||
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.core.fast.FastItemStack
|
||||||
@@ -47,34 +48,35 @@ class PacketWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, Packe
|
|||||||
handleRateLimit(player)
|
handleRateLimit(player)
|
||||||
|
|
||||||
if (usingAsync(player)) {
|
if (usingAsync(player)) {
|
||||||
val newPacket = packet.shallowClone()
|
val newPacket = packet.deepClone()
|
||||||
|
|
||||||
fun modifyAndSend(itemStacks: MutableList<ItemStack>, windowId: Int, player: Player) {
|
|
||||||
modifyWindowItems(itemStacks, windowId, player)
|
|
||||||
|
|
||||||
newPacket.itemListModifier.write(0, itemStacks)
|
|
||||||
|
|
||||||
ignorePacketList.add(player.name)
|
|
||||||
|
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, newPacket)
|
|
||||||
}
|
|
||||||
|
|
||||||
executor.execute {
|
executor.execute {
|
||||||
try {
|
runCatchingWithLogs { modifyAndSend(newPacket, itemStacks, windowId, player) }
|
||||||
modifyAndSend(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. (Remember to disable ratelimit and emergency too)")
|
|
||||||
}
|
|
||||||
|
|
||||||
this.getPlugin().scheduler.run {
|
|
||||||
modifyAndSend(itemStacks, windowId, player)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
packet.itemListModifier.write(0, modifyWindowItems(itemStacks, windowId, player))
|
modifyPacket(packet, itemStacks, windowId, player)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun modifyPacket(
|
||||||
|
packet: PacketContainer,
|
||||||
|
itemStacks: MutableList<ItemStack>,
|
||||||
|
windowId: Int,
|
||||||
|
player: Player
|
||||||
|
) {
|
||||||
|
packet.itemListModifier.write(0, modifyWindowItems(itemStacks, windowId, player))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun modifyAndSend(
|
||||||
|
packet: PacketContainer,
|
||||||
|
itemStacks: MutableList<ItemStack>,
|
||||||
|
windowId: Int,
|
||||||
|
player: Player
|
||||||
|
) {
|
||||||
|
modifyPacket(packet, itemStacks, windowId, player)
|
||||||
|
ignorePacketList.add(player.name)
|
||||||
|
this.getPlugin().scheduler.run {
|
||||||
|
runCatchingWithLogs { ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +102,7 @@ class PacketWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, Packe
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun usingAsync(player: Player): Boolean {
|
private fun usingAsync(player: Player): Boolean {
|
||||||
if (this.getPlugin().configYml.getStrings("async-display.disable-on-types", false)
|
if (this.getPlugin().configYml.getStrings("async-display.disable-on-types")
|
||||||
.map { it.lowercase() }.contains(player.openInventory.type.name.lowercase())
|
.map { it.lowercase() }.contains(player.openInventory.type.name.lowercase())
|
||||||
) {
|
) {
|
||||||
return false
|
return false
|
||||||
@@ -162,3 +164,14 @@ class PacketWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, Packe
|
|||||||
return itemStacks
|
return itemStacks
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private inline fun <T> runCatchingWithLogs(toRun: () -> T): Result<T> {
|
||||||
|
return runCatching { toRun() }.onFailure {
|
||||||
|
if (Eco.getHandler().ecoPlugin.configYml.getBool("async-display.log-errors")) {
|
||||||
|
Eco.getHandler().ecoPlugin.logger.warning(
|
||||||
|
"Error happened in async processing! Disable async display (/plugins/eco/config.yml)" +
|
||||||
|
"if this is a frequent issue. (Remember to disable ratelimit and emergency too)"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class AntigriefCrashClaim : AntigriefWrapper {
|
|||||||
block: Block
|
block: Block
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val api = CrashClaim.getPlugin().api ?: return true
|
val api = CrashClaim.getPlugin().api ?: return true
|
||||||
val claim = api.getClaim(block.location).getNow(null) ?: return true
|
val claim = api.getClaim(block.location) ?: return true
|
||||||
return claim.hasPermission(player.uniqueId, block.location, PermissionRoute.BUILD)
|
return claim.hasPermission(player.uniqueId, block.location, PermissionRoute.BUILD)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ class AntigriefCrashClaim : AntigriefWrapper {
|
|||||||
location: Location
|
location: Location
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val api = CrashClaim.getPlugin().api ?: return true
|
val api = CrashClaim.getPlugin().api ?: return true
|
||||||
val claim = api.getClaim(location).getNow(null) ?: return true
|
val claim = api.getClaim(location) ?: return true
|
||||||
return claim.hasPermission(player.uniqueId, location, PermissionRoute.EXPLOSIONS)
|
return claim.hasPermission(player.uniqueId, location, PermissionRoute.EXPLOSIONS)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ class AntigriefCrashClaim : AntigriefWrapper {
|
|||||||
block: Block
|
block: Block
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val api = CrashClaim.getPlugin().api ?: return true
|
val api = CrashClaim.getPlugin().api ?: return true
|
||||||
val claim = api.getClaim(block.location).getNow(null) ?: return true
|
val claim = api.getClaim(block.location) ?: return true
|
||||||
return claim.hasPermission(player.uniqueId, block.location, PermissionRoute.BUILD)
|
return claim.hasPermission(player.uniqueId, block.location, PermissionRoute.BUILD)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ class AntigriefCrashClaim : AntigriefWrapper {
|
|||||||
victim: LivingEntity
|
victim: LivingEntity
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val api = CrashClaim.getPlugin().api ?: return true
|
val api = CrashClaim.getPlugin().api ?: return true
|
||||||
val claim = api.getClaim(victim.location).getNow(null) ?: return true
|
val claim = api.getClaim(victim.location) ?: return true
|
||||||
return when (victim) {
|
return when (victim) {
|
||||||
is Player -> false
|
is Player -> false
|
||||||
else -> claim.hasPermission(player.uniqueId, victim.location, PermissionRoute.ENTITIES)
|
else -> claim.hasPermission(player.uniqueId, victim.location, PermissionRoute.ENTITIES)
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.integrations.customentities
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.CustomEntity
|
||||||
|
import com.willfp.eco.core.integrations.customentities.CustomEntitiesWrapper
|
||||||
|
import io.lumine.xikage.mythicmobs.MythicMobs
|
||||||
|
import org.bukkit.NamespacedKey
|
||||||
|
|
||||||
|
class CustomEntitiesMythicMobs : CustomEntitiesWrapper {
|
||||||
|
override fun registerAllEntities() {
|
||||||
|
val mobManager = MythicMobs.inst().mobManager
|
||||||
|
val api = MythicMobs.inst().apiHelper
|
||||||
|
|
||||||
|
for (id in mobManager.mobNames) {
|
||||||
|
val key = NamespacedKey.fromString("mythicmobs:${id.lowercase()}")
|
||||||
|
key ?: continue
|
||||||
|
CustomEntity(
|
||||||
|
key,
|
||||||
|
{
|
||||||
|
val entityId = api.getMythicMobInstance(it)?.type?.entityType ?: return@CustomEntity false
|
||||||
|
entityId.equals(id, ignoreCase = true)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
api.spawnMythicMob(id, it)
|
||||||
|
}
|
||||||
|
).register()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPluginName(): String {
|
||||||
|
return "MythicMobs"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.integrations.customitems
|
||||||
|
|
||||||
|
import com.willfp.eco.core.integrations.customitems.CustomItemsWrapper
|
||||||
|
import com.willfp.eco.core.items.CustomItem
|
||||||
|
import com.willfp.eco.core.items.Items
|
||||||
|
import com.willfp.eco.core.items.TestableItem
|
||||||
|
import com.willfp.eco.core.items.provider.ItemProvider
|
||||||
|
import com.willfp.eco.util.NamespacedKeyUtils
|
||||||
|
import me.wolfyscript.utilities.util.NamespacedKey
|
||||||
|
import me.wolfyscript.utilities.util.Registry
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import java.util.function.Predicate
|
||||||
|
class CustomItemsCustomCrafting: CustomItemsWrapper {
|
||||||
|
override fun registerAllItems() {
|
||||||
|
Items.registerItemProvider(CustomCraftingProvider())
|
||||||
|
}
|
||||||
|
override fun getPluginName(): String {
|
||||||
|
return "CustomCrafting"
|
||||||
|
}
|
||||||
|
private class CustomCraftingProvider : ItemProvider("customcrafting") {
|
||||||
|
override fun provideForKey(key: String): TestableItem? {
|
||||||
|
val nKey = key.replace("customcrafting:", "", ignoreCase = true)
|
||||||
|
val itemKey = NamespacedKey("customcrafting", nKey)
|
||||||
|
val item = Registry.CUSTOM_ITEMS.get(itemKey) ?: return null
|
||||||
|
val namespacedKey = NamespacedKeyUtils.create("customcrafting", key)
|
||||||
|
val stack = item.create(1)
|
||||||
|
return CustomItem(
|
||||||
|
namespacedKey,
|
||||||
|
Predicate { test: ItemStack ->
|
||||||
|
val customStack = me.wolfyscript.utilities.api.inventory.custom_items.CustomItem.getByItemStack(test) ?: return@Predicate false
|
||||||
|
val iKey = customStack.namespacedKey ?: return@Predicate false
|
||||||
|
iKey.equals(key)
|
||||||
|
},
|
||||||
|
stack
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.integrations.customitems
|
||||||
|
|
||||||
|
import com.ssomar.score.api.ExecutableItemsAPI
|
||||||
|
import com.willfp.eco.core.integrations.customitems.CustomItemsWrapper
|
||||||
|
import com.willfp.eco.core.items.CustomItem
|
||||||
|
import com.willfp.eco.core.items.Items
|
||||||
|
import com.willfp.eco.core.items.TestableItem
|
||||||
|
import com.willfp.eco.core.items.provider.ItemProvider
|
||||||
|
import com.willfp.eco.util.NamespacedKeyUtils
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import java.util.function.Predicate
|
||||||
|
class CustomItemsExecutableItems: CustomItemsWrapper {
|
||||||
|
override fun registerAllItems() {
|
||||||
|
Items.registerItemProvider(ExecutableItemsProvider())
|
||||||
|
}
|
||||||
|
override fun getPluginName(): String {
|
||||||
|
return "ExecutableItems"
|
||||||
|
}
|
||||||
|
private class ExecutableItemsProvider : ItemProvider("executableitems") {
|
||||||
|
override fun provideForKey(key: String): TestableItem? {
|
||||||
|
val item = ExecutableItemsAPI.getExecutableItem(key) ?: return null
|
||||||
|
val namespacedKey = NamespacedKeyUtils.create("executableitems", key)
|
||||||
|
return CustomItem(
|
||||||
|
namespacedKey,
|
||||||
|
Predicate { test: ItemStack ->
|
||||||
|
val customStack = ExecutableItemsAPI.getExecutableItemConfig(test) ?: return@Predicate false
|
||||||
|
customStack.id.equals(key, ignoreCase = true)
|
||||||
|
},
|
||||||
|
item
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.math
|
||||||
|
|
||||||
|
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import redempt.crunch.CompiledExpression
|
||||||
|
import redempt.crunch.Crunch
|
||||||
|
import redempt.crunch.data.FastNumberParsing
|
||||||
|
import redempt.crunch.functional.EvaluationEnvironment
|
||||||
|
|
||||||
|
private val cache = mutableMapOf<String, CompiledExpression>()
|
||||||
|
private val goToZero = Crunch.compileExpression("0")
|
||||||
|
|
||||||
|
fun evaluateExpression(expression: String, player: Player?): Double {
|
||||||
|
val placeholderValues = PlaceholderManager.findPlaceholdersIn(expression)
|
||||||
|
.map { PlaceholderManager.translatePlaceholders(expression, player) }
|
||||||
|
.map { runCatching { FastNumberParsing.parseDouble(it) }.getOrDefault(0.0) }
|
||||||
|
.toDoubleArray()
|
||||||
|
|
||||||
|
val compiled = generateExpression(expression)
|
||||||
|
return runCatching { compiled.evaluate(*placeholderValues) }.getOrDefault(0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateExpression(expression: String): CompiledExpression {
|
||||||
|
val cached = cache[expression]
|
||||||
|
|
||||||
|
if (cached != null) {
|
||||||
|
return cached
|
||||||
|
}
|
||||||
|
|
||||||
|
val placeholders = PlaceholderManager.findPlaceholdersIn(expression)
|
||||||
|
|
||||||
|
val env = EvaluationEnvironment()
|
||||||
|
env.setVariableNames(*placeholders.toTypedArray())
|
||||||
|
|
||||||
|
val compiled = runCatching { Crunch.compileExpression(expression, env) }.getOrDefault(goToZero)
|
||||||
|
cache[expression] = compiled
|
||||||
|
return compiled
|
||||||
|
}
|
||||||
@@ -41,6 +41,11 @@ use-display-frame: true
|
|||||||
# that display frames will be cleared / deleted.
|
# that display frames will be cleared / deleted.
|
||||||
display-frame-ttl: 17
|
display-frame-ttl: 17
|
||||||
|
|
||||||
|
# Time to live for storing hashes against custom item keys. Increasing this value
|
||||||
|
# can benefit performance under load (e.g. from ShopGUI+ sells) but can increase
|
||||||
|
# memory use.
|
||||||
|
item-cache-ttl: 6000
|
||||||
|
|
||||||
# Window items packets have the option to be run asynchronously. This may cause
|
# Window items packets have the option to be run asynchronously. This may cause
|
||||||
# some bugs and is considered experimental, however it has been tested without
|
# some bugs and is considered experimental, however it has been tested without
|
||||||
# any apparent issues. Enable this if performance is absolutely crucial or if you
|
# any apparent issues. Enable this if performance is absolutely crucial or if you
|
||||||
@@ -64,14 +69,14 @@ async-display:
|
|||||||
# If emergency async should be used.
|
# If emergency async should be used.
|
||||||
enabled: true
|
enabled: true
|
||||||
# Below this TPS value, emergency async display will be used.
|
# Below this TPS value, emergency async display will be used.
|
||||||
cutoff: 18
|
cutoff: 17
|
||||||
|
|
||||||
# If players with a large amount of display packets should have their processing
|
# If players with a large amount of display packets should have their processing
|
||||||
# done asynchronously. This will help if a player is trying to crash the server
|
# done asynchronously. This will help if a player is trying to crash the server
|
||||||
# by overloading the display system.
|
# by overloading the display system.
|
||||||
ratelimit:
|
ratelimit:
|
||||||
# If rate limit async display should be used.
|
# If rate limit async display should be used.
|
||||||
enabled: true
|
enabled: false
|
||||||
# The amount of window items packets per timeframe needed to enable async display
|
# The amount of window items packets per timeframe needed to enable async display
|
||||||
# for a specified player.
|
# for a specified player.
|
||||||
cutoff: 4
|
cutoff: 4
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ softdepend:
|
|||||||
- SuperiorSkyblock2
|
- SuperiorSkyblock2
|
||||||
- CrashClaim
|
- CrashClaim
|
||||||
- DecentHolograms
|
- DecentHolograms
|
||||||
|
- MythicMobs
|
||||||
|
- CustomCrafting
|
||||||
|
- ExecutableItems
|
||||||
libraries:
|
libraries:
|
||||||
- 'org.reflections:reflections:0.9.12'
|
- 'org.reflections:reflections:0.9.12'
|
||||||
- 'org.apache.maven:maven-artifact:3.0.3'
|
- 'org.apache.maven:maven-artifact:3.0.3'
|
||||||
@@ -53,3 +56,4 @@ libraries:
|
|||||||
- 'mysql:mysql-connector-java:8.0.25'
|
- 'mysql:mysql-connector-java:8.0.25'
|
||||||
- 'com.google.guava:guava:31.0.1-jre'
|
- 'com.google.guava:guava:31.0.1-jre'
|
||||||
- 'com.zaxxer:HikariCP:5.0.0'
|
- 'com.zaxxer:HikariCP:5.0.0'
|
||||||
|
- 'org.apache.commons:commons-lang3:3.0'
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.willfp.eco.internal.spigot.proxy
|
||||||
|
|
||||||
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.entity.Entity
|
||||||
|
|
||||||
|
interface DummyEntityProxy {
|
||||||
|
fun createDummyEntity(
|
||||||
|
location: Location
|
||||||
|
): Entity
|
||||||
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
version = 6.17.2
|
version = 6.20.3
|
||||||
plugin-name = eco
|
plugin-name = eco
|
||||||
kotlin.code.style = official
|
kotlin.code.style = official
|
||||||
BIN
lib/SCore-1.6.0.9.jar
Normal file
BIN
lib/SCore-1.6.0.9.jar
Normal file
Binary file not shown.
Reference in New Issue
Block a user