Compare commits
79 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a408e3436a | ||
|
|
3df977c1bc | ||
|
|
136f1841b4 | ||
|
|
1086a59a6a | ||
|
|
d9147f9918 | ||
|
|
d144df4048 | ||
|
|
061f77e911 | ||
|
|
5cebe2fce8 | ||
|
|
1e712dcae6 | ||
|
|
09d444da58 | ||
|
|
09f45c0ab5 | ||
|
|
f64d69f084 | ||
|
|
86a948738f | ||
|
|
8f9c5e7ed8 | ||
|
|
ae897b7493 | ||
|
|
f1a7c9d50e | ||
|
|
83ee8fe4cd | ||
|
|
465f885e22 | ||
|
|
d4141735a9 | ||
|
|
b9b4ce1937 | ||
|
|
56234e6c83 | ||
|
|
2dda34097e | ||
|
|
155a349569 | ||
|
|
ce231934a3 | ||
|
|
5cbb7bfe47 | ||
|
|
06e0ec0295 | ||
|
|
02ed583674 | ||
|
|
8e4cbdd1aa | ||
|
|
8828f8e45d | ||
|
|
d15524ee9e | ||
|
|
d45e66d71e | ||
|
|
6b1dde7540 | ||
|
|
abf2964c48 | ||
|
|
db51c4c761 | ||
|
|
cbb574acec | ||
|
|
93c044ef09 | ||
|
|
1cc39fe40a | ||
|
|
edfd561fcd | ||
|
|
bd7f22cb02 | ||
|
|
3233bad307 | ||
|
|
3cefcbe0bb | ||
|
|
49bce53724 | ||
|
|
2b86159b30 | ||
|
|
d028511a48 | ||
|
|
5ad1ef33b8 | ||
|
|
634d6194d6 | ||
|
|
7f7eb4f45a | ||
|
|
bd90ae996b | ||
|
|
1bc57dec08 | ||
|
|
ce44d40f0f | ||
|
|
68824fb4d0 | ||
|
|
fd96b0d2cf | ||
|
|
2669569e81 | ||
|
|
067f740bcc | ||
|
|
2ce96ab0b1 | ||
|
|
027f9be194 | ||
|
|
a09018d1f0 | ||
|
|
a1da83173d | ||
|
|
8ac30283f8 | ||
|
|
6099b5d64d | ||
|
|
19d2e0788b | ||
|
|
1b223b3736 | ||
|
|
d6d1f01704 | ||
|
|
51231939c0 | ||
|
|
72fb20ecd9 | ||
|
|
58a386922c | ||
|
|
12824c7f6c | ||
|
|
b5236b8db6 | ||
|
|
3ffbb861d1 | ||
|
|
f8fad15f0b | ||
|
|
a0e96fca35 | ||
|
|
6cf9a53a65 | ||
|
|
a4909453d7 | ||
|
|
a10666f792 | ||
|
|
a845cda9ed | ||
|
|
ed5f1ccb5e | ||
|
|
c6e59e1d62 | ||
|
|
ed24b6278e | ||
|
|
3aea7b4077 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -14,6 +14,7 @@ bin/
|
|||||||
# Gradle
|
# Gradle
|
||||||
.gradle
|
.gradle
|
||||||
**/build/
|
**/build/
|
||||||
|
**/out/
|
||||||
!eco-api/src/**/build/
|
!eco-api/src/**/build/
|
||||||
.gradletasknamecache
|
.gradletasknamecache
|
||||||
!gradle-wrapper.jar
|
!gradle-wrapper.jar
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ Here's a list of some (not all) of the features of eco:
|
|||||||
- ArmorEquipEvent
|
- ArmorEquipEvent
|
||||||
- EntityDeathByEntityEvent
|
- EntityDeathByEntityEvent
|
||||||
- NaturalExpGainEvent
|
- NaturalExpGainEvent
|
||||||
- Plugin extensions (Plugins for plugins)
|
- Plugin extensions (com.willfp.eco.internal.Plugins for plugins)
|
||||||
- GUI System
|
- GUI System
|
||||||
- Integration system for external plugins
|
- Integration system for external plugins
|
||||||
- Anticheat support
|
- Anticheat support
|
||||||
|
|||||||
24
build.gradle
24
build.gradle
@@ -7,7 +7,11 @@ plugins {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation project(":eco-api")
|
implementation project(":eco-api")
|
||||||
implementation project(":eco-core").getSubprojects()
|
implementation project(":eco-core:core-plugin")
|
||||||
|
implementation project(":eco-core:core-proxy")
|
||||||
|
implementation project(":eco-core:core-backend")
|
||||||
|
implementation project(":eco-core:core-nms:v1_16_R3")
|
||||||
|
implementation project(path: ":eco-core:core-nms:v1_17_R1", configuration: 'mapped')
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
@@ -57,6 +61,10 @@ allprojects {
|
|||||||
annotationProcessor 'org.projectlombok:lombok:1.18.20'
|
annotationProcessor 'org.projectlombok:lombok:1.18.20'
|
||||||
testCompileOnly 'org.projectlombok:lombok:1.18.20'
|
testCompileOnly 'org.projectlombok:lombok:1.18.20'
|
||||||
testAnnotationProcessor 'org.projectlombok:lombok:1.18.20'
|
testAnnotationProcessor 'org.projectlombok:lombok:1.18.20'
|
||||||
|
|
||||||
|
// Test
|
||||||
|
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
|
||||||
|
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1'
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType(JavaCompile) {
|
tasks.withType(JavaCompile) {
|
||||||
@@ -75,7 +83,7 @@ allprojects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
shadowJar {
|
shadowJar {
|
||||||
relocate('org.bstats.bukkit', 'com.willfp.eco.shaded.bstats')
|
relocate('org.bstats', 'com.willfp.eco.shaded.bstats')
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
@@ -92,6 +100,18 @@ allprojects {
|
|||||||
withSourcesJar()
|
withSourcesJar()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
|
||||||
|
// Always run tests, even when nothing changed.
|
||||||
|
dependsOn cleanTest
|
||||||
|
|
||||||
|
// Show test results.
|
||||||
|
testLogging {
|
||||||
|
events "passed", "skipped", "failed"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
compileJava.options.encoding = 'UTF-8'
|
compileJava.options.encoding = 'UTF-8'
|
||||||
compileJava.dependsOn clean
|
compileJava.dependsOn clean
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
-->
|
-->
|
||||||
<property name="severity" value="error"/>
|
<property name="severity" value="error"/>
|
||||||
|
|
||||||
<property name="fileExtensions" value="java, properties, xml"/>
|
<property name="fileExtensions" value="java, properties, xml, kt"/>
|
||||||
|
|
||||||
<!-- Excludes all 'module-info.java' files -->
|
<!-- Excludes all 'module-info.java' files -->
|
||||||
<!-- See https://checkstyle.org/config_filefilters.html -->
|
<!-- See https://checkstyle.org/config_filefilters.html -->
|
||||||
@@ -66,6 +66,7 @@
|
|||||||
<module name="FileLength"/>
|
<module name="FileLength"/>
|
||||||
<module name="LineLength">
|
<module name="LineLength">
|
||||||
<property name="fileExtensions" value="java"/>
|
<property name="fileExtensions" value="java"/>
|
||||||
|
<property name="fileExtensions" value="kt"/>
|
||||||
<property name="max" value="200"/>
|
<property name="max" value="200"/>
|
||||||
</module>
|
</module>
|
||||||
|
|
||||||
|
|||||||
@@ -8,17 +8,16 @@ version rootProject.version
|
|||||||
dependencies {
|
dependencies {
|
||||||
compileOnly 'org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT'
|
compileOnly 'org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT'
|
||||||
compileOnly 'org.apache.maven:maven-artifact:3.0.3'
|
compileOnly 'org.apache.maven:maven-artifact:3.0.3'
|
||||||
compileOnly 'org.bstats:bstats-bukkit:1.7'
|
|
||||||
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.0-SNAPSHOT'
|
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.0-SNAPSHOT'
|
||||||
compileOnly 'com.google.code.gson:gson:2.8.7'
|
compileOnly 'com.google.code.gson:gson:2.8.7'
|
||||||
|
compileOnly 'net.kyori:adventure-text-serializer-gson:4.8.1'
|
||||||
|
compileOnly 'net.kyori:adventure-text-serializer-legacy:4.8.1'
|
||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
withJavadocJar()
|
withJavadocJar()
|
||||||
}
|
}
|
||||||
|
|
||||||
compileJava.options.encoding = 'UTF-8'
|
|
||||||
compileJava.dependsOn clean
|
|
||||||
|
|
||||||
build.dependsOn publishToMavenLocal
|
build.dependsOn publishToMavenLocal
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import com.willfp.eco.core.web.UpdateChecker;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
|
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
|
||||||
import org.bstats.bukkit.Metrics;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
@@ -348,7 +347,7 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.getBStatsId() != 0) {
|
if (this.getBStatsId() != 0) {
|
||||||
new Metrics(this, this.getBStatsId());
|
Eco.getHandler().registerBStats(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(Plugin::getName).collect(Collectors.toSet());
|
Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(Plugin::getName).collect(Collectors.toSet());
|
||||||
@@ -406,7 +405,6 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
|
|
||||||
this.getEventManager().unregisterAllListeners();
|
this.getEventManager().unregisterAllListeners();
|
||||||
this.getScheduler().cancelAll();
|
this.getScheduler().cancelAll();
|
||||||
this.getConfigHandler().saveAllConfigs();
|
|
||||||
|
|
||||||
this.handleDisable();
|
this.handleDisable();
|
||||||
|
|
||||||
@@ -615,7 +613,7 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
* @param <T> The proxy type.
|
* @param <T> The proxy type.
|
||||||
* @return The proxy.
|
* @return The proxy.
|
||||||
*/
|
*/
|
||||||
public <T extends AbstractProxy> T getProxy(@NotNull final Class<T> proxyClass) {
|
public final <T extends AbstractProxy> T getProxy(@NotNull final Class<T> proxyClass) {
|
||||||
Validate.notNull(proxyFactory, "Plugin does not support proxy!");
|
Validate.notNull(proxyFactory, "Plugin does not support proxy!");
|
||||||
|
|
||||||
return proxyFactory.getProxy(proxyClass);
|
return proxyFactory.getProxy(proxyClass);
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ import com.willfp.eco.core.extensions.ExtensionLoader;
|
|||||||
import com.willfp.eco.core.factory.MetadataValueFactory;
|
import com.willfp.eco.core.factory.MetadataValueFactory;
|
||||||
import com.willfp.eco.core.factory.NamespacedKeyFactory;
|
import com.willfp.eco.core.factory.NamespacedKeyFactory;
|
||||||
import com.willfp.eco.core.factory.RunnableFactory;
|
import com.willfp.eco.core.factory.RunnableFactory;
|
||||||
|
import com.willfp.eco.core.fast.FastItemStack;
|
||||||
import com.willfp.eco.core.gui.GUIFactory;
|
import com.willfp.eco.core.gui.GUIFactory;
|
||||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration;
|
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration;
|
||||||
import com.willfp.eco.core.proxy.Cleaner;
|
import com.willfp.eco.core.proxy.Cleaner;
|
||||||
import com.willfp.eco.core.proxy.ProxyFactory;
|
import com.willfp.eco.core.proxy.ProxyFactory;
|
||||||
import com.willfp.eco.core.scheduling.Scheduler;
|
import com.willfp.eco.core.scheduling.Scheduler;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -158,4 +160,19 @@ public interface Handler {
|
|||||||
* @return A list of plugin names in lowercase.
|
* @return A list of plugin names in lowercase.
|
||||||
*/
|
*/
|
||||||
List<String> getLoadedPlugins();
|
List<String> getLoadedPlugins();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a FastItemStack.
|
||||||
|
*
|
||||||
|
* @param itemStack The base ItemStack.
|
||||||
|
* @return The FastItemStack.
|
||||||
|
*/
|
||||||
|
FastItemStack createFastItemStack(@NotNull ItemStack itemStack);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register bStats metrics.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin.
|
||||||
|
*/
|
||||||
|
void registerBStats(@NotNull EcoPlugin plugin);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,14 @@ public class Prerequisite {
|
|||||||
"Requires server to be running paper (or a fork)"
|
"Requires server to be running paper (or a fork)"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requires the server to be running an implementation of paper.
|
||||||
|
*/
|
||||||
|
public static final Prerequisite HAS_VAULT = new Prerequisite(
|
||||||
|
() -> ClassUtils.exists("net.milkbowl.vault.economy.Economy"),
|
||||||
|
"Requires server to have vault"
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requires the server to be running 1.17.
|
* Requires the server to be running 1.17.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import lombok.Getter;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for all plugin-specific client-side item display modules.
|
* Class for all plugin-specific client-side item display modules.
|
||||||
@@ -48,7 +49,7 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
|
|||||||
* @param args Optional args for display.
|
* @param args Optional args for display.
|
||||||
*/
|
*/
|
||||||
protected void display(@NotNull final ItemStack itemStack,
|
protected void display(@NotNull final ItemStack itemStack,
|
||||||
@NotNull final Player player,
|
@Nullable final Player player,
|
||||||
@NotNull final Object... args) {
|
@NotNull final Object... args) {
|
||||||
// Technically optional.
|
// Technically optional.
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,10 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* <p>
|
* <p>
|
||||||
* The event is called before the player's inventory actually updates,
|
* The event is called before the player's inventory actually updates,
|
||||||
* so you can check a tick later to see the new contents.
|
* so you can check a tick later to see the new contents.
|
||||||
|
*
|
||||||
|
* @see ArmorChangeEvent
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class ArmorEquipEvent extends PlayerEvent {
|
public class ArmorEquipEvent extends PlayerEvent {
|
||||||
/**
|
/**
|
||||||
* Bukkit parity.
|
* Bukkit parity.
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package com.willfp.eco.core.fast;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.Eco;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FastItemStack contains methods to modify and read items faster than in default bukkit.
|
||||||
|
*/
|
||||||
|
public interface FastItemStack {
|
||||||
|
/**
|
||||||
|
* Get all enchantments on an item.
|
||||||
|
*
|
||||||
|
* @param checkStored If stored NBT should also be checked.
|
||||||
|
* @return A map of all enchantments.
|
||||||
|
*/
|
||||||
|
Map<Enchantment, Integer> getEnchantmentsOnItem(boolean checkStored);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the level of an enchantment on an item.
|
||||||
|
*
|
||||||
|
* @param enchantment The enchantment.
|
||||||
|
* @param checkStored If the stored NBT should also be checked.
|
||||||
|
* @return The enchantment level, or 0 if not found.
|
||||||
|
*/
|
||||||
|
int getLevelOnItem(@NotNull Enchantment enchantment,
|
||||||
|
boolean checkStored);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the item lore.
|
||||||
|
*
|
||||||
|
* @param lore The lore.
|
||||||
|
*/
|
||||||
|
void setLore(@Nullable List<String> lore);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the item lore.
|
||||||
|
*
|
||||||
|
* @return The lore.
|
||||||
|
*/
|
||||||
|
List<String> getLore();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Bukkit ItemStack again.
|
||||||
|
*
|
||||||
|
* @return The ItemStack.
|
||||||
|
*/
|
||||||
|
ItemStack unwrap();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap an ItemStack to create a FastItemStack.
|
||||||
|
*
|
||||||
|
* @param itemStack The ItemStack.
|
||||||
|
* @return The FastItemStack.
|
||||||
|
*/
|
||||||
|
static FastItemStack wrap(@NotNull final ItemStack itemStack) {
|
||||||
|
return Eco.getHandler().createFastItemStack(itemStack);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -77,4 +77,11 @@ public class PlaceholderEntry {
|
|||||||
public boolean requiresPlayer() {
|
public boolean requiresPlayer() {
|
||||||
return requiresPlayer;
|
return requiresPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the placeholder.
|
||||||
|
*/
|
||||||
|
public void register() {
|
||||||
|
PlaceholderManager.registerPlaceholder(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public class CustomItem implements TestableItem {
|
|||||||
/**
|
/**
|
||||||
* The test for ItemStacks to pass.
|
* The test for ItemStacks to pass.
|
||||||
*/
|
*/
|
||||||
private final Predicate<ItemStack> test;
|
private final Predicate<@NotNull ItemStack> test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Example Item: what the user should see.
|
* Example Item: what the user should see.
|
||||||
@@ -42,7 +42,7 @@ public class CustomItem implements TestableItem {
|
|||||||
* @param item The example ItemStacks.
|
* @param item The example ItemStacks.
|
||||||
*/
|
*/
|
||||||
public CustomItem(@NotNull final NamespacedKey key,
|
public CustomItem(@NotNull final NamespacedKey key,
|
||||||
@NotNull final Predicate<ItemStack> test,
|
@NotNull final Predicate<@NotNull ItemStack> test,
|
||||||
@NotNull final ItemStack item) {
|
@NotNull final ItemStack item) {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.test = test;
|
this.test = test;
|
||||||
@@ -51,6 +51,10 @@ public class CustomItem implements TestableItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(@Nullable final ItemStack itemStack) {
|
public boolean matches(@Nullable final ItemStack itemStack) {
|
||||||
|
if (itemStack == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return test.test(itemStack);
|
return test.test(itemStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.willfp.eco.util;
|
package com.willfp.eco.util;
|
||||||
|
|
||||||
import com.willfp.eco.core.tuples.Pair;
|
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@@ -32,12 +31,10 @@ public class BlockUtils {
|
|||||||
*/
|
*/
|
||||||
private BiConsumer<Player, Block> blockBreakConsumer = null;
|
private BiConsumer<Player, Block> blockBreakConsumer = null;
|
||||||
|
|
||||||
private Pair<Block, Set<Block>> getNearbyBlocksRecursively(@NotNull final Block start,
|
private Set<Block> getNearbyBlocks(@NotNull final Block start,
|
||||||
@NotNull final List<Material> allowedMaterials,
|
@NotNull final List<Material> allowedMaterials,
|
||||||
@NotNull final Set<Block> blocks,
|
@NotNull final Set<Block> blocks,
|
||||||
final int limit) {
|
final int limit) {
|
||||||
Block last = start;
|
|
||||||
|
|
||||||
for (BlockFace face : BlockFace.values()) {
|
for (BlockFace face : BlockFace.values()) {
|
||||||
Block block = start.getRelative(face);
|
Block block = start.getRelative(face);
|
||||||
if (blocks.contains(block)) {
|
if (blocks.contains(block)) {
|
||||||
@@ -46,46 +43,15 @@ public class BlockUtils {
|
|||||||
|
|
||||||
if (allowedMaterials.contains(block.getType())) {
|
if (allowedMaterials.contains(block.getType())) {
|
||||||
blocks.add(block);
|
blocks.add(block);
|
||||||
last = block;
|
|
||||||
|
|
||||||
if (blocks.size() > limit) {
|
if (blocks.size() > limit || blocks.size() > 2500) {
|
||||||
return new Pair<>(last, blocks);
|
return blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pair<Block, Set<Block>> pair = getNearbyBlocksRecursively(last, allowedMaterials, blocks, limit);
|
blocks.addAll(getNearbyBlocks(block, allowedMaterials, blocks, limit));
|
||||||
assert pair.getSecond() != null;
|
|
||||||
|
|
||||||
blocks.addAll(pair.getSecond());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Pair<>(last, blocks);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Set<Block> getNearbyBlocks(@NotNull final Block start,
|
|
||||||
@NotNull final List<Material> allowedMaterials,
|
|
||||||
@NotNull final Set<Block> blocks,
|
|
||||||
final int limit) {
|
|
||||||
/*
|
|
||||||
Prevent stack overflow.
|
|
||||||
*/
|
|
||||||
int cycles = (int) Math.ceil(limit / 1024D);
|
|
||||||
|
|
||||||
int cap = limit;
|
|
||||||
Block iterStart = start;
|
|
||||||
|
|
||||||
for (int i = 0; i < cycles; i++) {
|
|
||||||
assert iterStart != null;
|
|
||||||
|
|
||||||
Pair<Block, Set<Block>> pair = getNearbyBlocksRecursively(iterStart, allowedMaterials, blocks, cap);
|
|
||||||
assert pair.getSecond() != null;
|
|
||||||
iterStart = pair.getFirst();
|
|
||||||
|
|
||||||
blocks.addAll(pair.getSecond());
|
|
||||||
|
|
||||||
cap -= 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
return blocks;
|
return blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ public class NumberUtils {
|
|||||||
if (numeral.isEmpty()) {
|
if (numeral.isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
for (Map.Entry<Integer, String> entry : NUMERALS.entrySet()) {
|
for (Map.Entry<Integer, String> entry : NUMERALS.descendingMap().entrySet()) {
|
||||||
if (numeral.startsWith(entry.getValue())) {
|
if (numeral.startsWith(entry.getValue())) {
|
||||||
return entry.getKey() + fromNumeral(numeral.substring(entry.getValue().length()));
|
return entry.getKey() + fromNumeral(numeral.substring(entry.getValue().length()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,10 @@ package com.willfp.eco.util;
|
|||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
|
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.format.TextDecoration;
|
||||||
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -27,9 +31,9 @@ public class StringUtils {
|
|||||||
* Regexes for gradients.
|
* Regexes for gradients.
|
||||||
*/
|
*/
|
||||||
private static final List<Pattern> GRADIENT_PATTERNS = new ImmutableList.Builder<Pattern>()
|
private static final List<Pattern> GRADIENT_PATTERNS = new ImmutableList.Builder<Pattern>()
|
||||||
.add(Pattern.compile("<GRADIENT:([0-9A-Fa-f]{6})>(.*?)</GRADIENT:([0-9A-Fa-f]{6})>"))
|
.add(Pattern.compile("<GRADIENT:([0-9A-Fa-f]{6})>(.*?)</GRADIENT:([0-9A-Fa-f]{6})>", Pattern.CASE_INSENSITIVE))
|
||||||
.add(Pattern.compile("<gradient:([0-9A-Fa-f]{6})>(.*?)</gradient:([0-9A-Fa-f]{6})>"))
|
.add(Pattern.compile("<GRADIENT:#([0-9A-Fa-f]{6})>(.*?)</GRADIENT:#([0-9A-Fa-f]{6})>", Pattern.CASE_INSENSITIVE))
|
||||||
.add(Pattern.compile("<G:([0-9A-Fa-f]{6})>(.*?)</G:([0-9A-Fa-f]{6})>"))
|
.add(Pattern.compile("<G:([0-9A-Fa-f]{6})>(.*?)</G:([0-9A-Fa-f]{6})>", Pattern.CASE_INSENSITIVE))
|
||||||
.add(Pattern.compile("<#:([0-9A-Fa-f]{6})>(.*?)</#:([0-9A-Fa-f]{6})>"))
|
.add(Pattern.compile("<#:([0-9A-Fa-f]{6})>(.*?)</#:([0-9A-Fa-f]{6})>"))
|
||||||
.add(Pattern.compile("\\{#:([0-9A-Fa-f]{6})}(.*?)\\{/#:([0-9A-Fa-f]{6})}"))
|
.add(Pattern.compile("\\{#:([0-9A-Fa-f]{6})}(.*?)\\{/#:([0-9A-Fa-f]{6})}"))
|
||||||
.build();
|
.build();
|
||||||
@@ -122,14 +126,6 @@ public class StringUtils {
|
|||||||
return matcher.appendTail(builder).toString();
|
return matcher.appendTail(builder).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Colors a string with a gradient.
|
|
||||||
*
|
|
||||||
* @param string The string to color.
|
|
||||||
* @param start The start color.
|
|
||||||
* @param end The end color.
|
|
||||||
* @return The string, colored.
|
|
||||||
*/
|
|
||||||
private static String processGradients(@NotNull final String string,
|
private static String processGradients(@NotNull final String string,
|
||||||
@NotNull final Color start,
|
@NotNull final Color start,
|
||||||
@NotNull final Color end) {
|
@NotNull final Color end) {
|
||||||
@@ -167,14 +163,6 @@ public class StringUtils {
|
|||||||
return stringBuilder.toString();
|
return stringBuilder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates chatColors for gradients.
|
|
||||||
*
|
|
||||||
* @param start The start color.
|
|
||||||
* @param end The end color.
|
|
||||||
* @param step How many colors are returned.
|
|
||||||
* @return Array of chat colors.
|
|
||||||
*/
|
|
||||||
private static ChatColor[] getGradientColors(@NotNull final Color start,
|
private static ChatColor[] getGradientColors(@NotNull final Color start,
|
||||||
@NotNull final Color end,
|
@NotNull final Color end,
|
||||||
final int step) {
|
final int step) {
|
||||||
@@ -195,12 +183,6 @@ public class StringUtils {
|
|||||||
return colors;
|
return colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add gradients to a string.
|
|
||||||
*
|
|
||||||
* @param string The string.
|
|
||||||
* @return The string, colorized.
|
|
||||||
*/
|
|
||||||
private static String translateGradients(@NotNull final String string) {
|
private static String translateGradients(@NotNull final String string) {
|
||||||
String processedString = string;
|
String processedString = string;
|
||||||
for (Pattern pattern : GRADIENT_PATTERNS) {
|
for (Pattern pattern : GRADIENT_PATTERNS) {
|
||||||
@@ -254,4 +236,30 @@ public class StringUtils {
|
|||||||
}
|
}
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert legacy string to JSON.
|
||||||
|
*
|
||||||
|
* @param legacy The legacy string.
|
||||||
|
* @return The JSON String.
|
||||||
|
*/
|
||||||
|
public String legacyToJson(@NotNull final String legacy) {
|
||||||
|
return GsonComponentSerializer.gson().serialize(
|
||||||
|
Component.empty().decoration(TextDecoration.ITALIC, false).append(
|
||||||
|
LegacyComponentSerializer.legacySection().deserialize(legacy)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert JSON string to legacy.
|
||||||
|
*
|
||||||
|
* @param json The JSON string.
|
||||||
|
* @return The legacy string.
|
||||||
|
*/
|
||||||
|
public String jsonToLegacy(@NotNull final String json) {
|
||||||
|
return LegacyComponentSerializer.legacySection().serialize(
|
||||||
|
GsonComponentSerializer.gson().deserialize(json)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
24
eco-api/src/test/java/NumberUtilsTest.java
Normal file
24
eco-api/src/test/java/NumberUtilsTest.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import com.willfp.eco.util.NumberUtils;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class NumberUtilsTest {
|
||||||
|
@Test
|
||||||
|
public void testFormatDouble() {
|
||||||
|
Assertions.assertEquals("3", NumberUtils.format(3.0D));
|
||||||
|
Assertions.assertEquals("3.20", NumberUtils.format(3.2D));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLog2() {
|
||||||
|
Assertions.assertEquals(1, NumberUtils.log2(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNumerals() {
|
||||||
|
Assertions.assertEquals(4, NumberUtils.fromNumeral("IV"));
|
||||||
|
Assertions.assertEquals(9, NumberUtils.fromNumeral("IX"));
|
||||||
|
Assertions.assertEquals("XIV", NumberUtils.toNumeral(14));
|
||||||
|
Assertions.assertEquals("XXI", NumberUtils.toNumeral(21));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,21 @@
|
|||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
group 'com.willfp'
|
group 'com.willfp'
|
||||||
version rootProject.version
|
version rootProject.version
|
||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
|
apply plugin: "kotlin"
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly project(":eco-api")
|
compileOnly project(":eco-api")
|
||||||
|
compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:1.5.21'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
package com.willfp.eco.internal;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.items.CustomItem;
|
|
||||||
import com.willfp.eco.core.items.Items;
|
|
||||||
import com.willfp.eco.core.proxy.Cleaner;
|
|
||||||
import com.willfp.eco.internal.proxy.EcoProxyFactory;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URLClassLoader;
|
|
||||||
|
|
||||||
public class EcoCleaner implements Cleaner {
|
|
||||||
@Override
|
|
||||||
public void clean(@NotNull final EcoPlugin plugin) {
|
|
||||||
if (!plugin.getProxyPackage().equalsIgnoreCase("")) {
|
|
||||||
EcoProxyFactory factory = (EcoProxyFactory) plugin.getProxyFactory();
|
|
||||||
factory.clean();
|
|
||||||
}
|
|
||||||
|
|
||||||
Plugins.LOADED_ECO_PLUGINS.remove(plugin.getName().toLowerCase());
|
|
||||||
|
|
||||||
for (CustomItem customItem : Items.getCustomItems()) {
|
|
||||||
if (customItem.getKey().getNamespace().equalsIgnoreCase(plugin.getName().toLowerCase())) {
|
|
||||||
Items.removeCustomItem(customItem.getKey());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plugin.getClass().getClassLoader() instanceof URLClassLoader urlClassLoader) {
|
|
||||||
try {
|
|
||||||
urlClassLoader.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
System.gc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
package com.willfp.eco.internal;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@UtilityClass
|
|
||||||
public class Plugins {
|
|
||||||
public static final Map<String, EcoPlugin> LOADED_ECO_PLUGINS = new HashMap<>();
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
package com.willfp.eco.internal.config;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.config.interfaces.Config;
|
|
||||||
import com.willfp.eco.core.config.interfaces.JSONConfig;
|
|
||||||
import com.willfp.eco.core.config.wrapper.ConfigFactory;
|
|
||||||
import com.willfp.eco.internal.config.json.EcoJSONConfigSection;
|
|
||||||
import com.willfp.eco.internal.config.json.EcoLoadableJSONConfig;
|
|
||||||
import com.willfp.eco.internal.config.yaml.EcoLoadableYamlConfig;
|
|
||||||
import com.willfp.eco.internal.config.yaml.EcoUpdatableYamlConfig;
|
|
||||||
import com.willfp.eco.internal.config.yaml.EcoYamlConfigSection;
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class EcoConfigFactory implements ConfigFactory {
|
|
||||||
@Override
|
|
||||||
public Config createUpdatableYamlConfig(@NotNull final String configName,
|
|
||||||
@NotNull final EcoPlugin plugin,
|
|
||||||
@NotNull final String subDirectoryPath,
|
|
||||||
@NotNull final Class<?> source,
|
|
||||||
final boolean removeUnused,
|
|
||||||
@NotNull final String... updateBlacklist) {
|
|
||||||
return new EcoUpdatableYamlConfig(
|
|
||||||
configName,
|
|
||||||
plugin,
|
|
||||||
subDirectoryPath,
|
|
||||||
source,
|
|
||||||
removeUnused,
|
|
||||||
updateBlacklist
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JSONConfig createLoadableJSONConfig(@NotNull final String configName,
|
|
||||||
@NotNull final EcoPlugin plugin,
|
|
||||||
@NotNull final String subDirectoryPath,
|
|
||||||
@NotNull final Class<?> source) {
|
|
||||||
return new EcoLoadableJSONConfig(
|
|
||||||
configName,
|
|
||||||
plugin,
|
|
||||||
subDirectoryPath,
|
|
||||||
source
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Config createLoadableYamlConfig(@NotNull final String configName,
|
|
||||||
@NotNull final EcoPlugin plugin,
|
|
||||||
@NotNull final String subDirectoryPath,
|
|
||||||
@NotNull final Class<?> source) {
|
|
||||||
return new EcoLoadableYamlConfig(
|
|
||||||
configName,
|
|
||||||
plugin,
|
|
||||||
subDirectoryPath,
|
|
||||||
source
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Config createYamlConfig(@NotNull final YamlConfiguration config) {
|
|
||||||
return new EcoYamlConfigSection(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JSONConfig createJSONConfig(@NotNull final Map<String, Object> values) {
|
|
||||||
return new EcoJSONConfigSection(values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package com.willfp.eco.internal.config.json;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class EcoJSONConfigSection extends EcoJSONConfigWrapper {
|
|
||||||
public EcoJSONConfigSection(@NotNull final Map<String, Object> values) {
|
|
||||||
this.init(values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,368 +0,0 @@
|
|||||||
package com.willfp.eco.internal.config.json;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.willfp.eco.core.config.interfaces.JSONConfig;
|
|
||||||
import com.willfp.eco.util.StringUtils;
|
|
||||||
import lombok.Getter;
|
|
||||||
import org.apache.commons.lang.Validate;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "unused"})
|
|
||||||
public class EcoJSONConfigWrapper implements JSONConfig {
|
|
||||||
@Getter
|
|
||||||
private final Gson handle = new GsonBuilder().setPrettyPrinting().create();
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private final Map<String, Object> values = new HashMap<>();
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private final Map<String, Object> cache = new HashMap<>();
|
|
||||||
|
|
||||||
public EcoJSONConfigWrapper() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void init(@NotNull final Map<String, Object> values) {
|
|
||||||
this.values.clear();
|
|
||||||
this.values.putAll(values);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void clearCache() {
|
|
||||||
cache.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toPlaintext() {
|
|
||||||
return this.getHandle().toJson(this.getValues());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean has(@NotNull final String path) {
|
|
||||||
return getOfKnownType(path, Object.class) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
protected <T> T getOfKnownType(@NotNull final String path,
|
|
||||||
@NotNull final Class<T> clazz) {
|
|
||||||
return getOfKnownType(path, clazz, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
protected <T> T getOfKnownType(@NotNull final String path,
|
|
||||||
@NotNull final Class<T> clazz,
|
|
||||||
final boolean isBase) {
|
|
||||||
String closestPath = path;
|
|
||||||
|
|
||||||
if (cache.containsKey(path) && isBase) {
|
|
||||||
return (T) cache.get(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path.contains(".")) {
|
|
||||||
String[] split = path.split("\\.");
|
|
||||||
closestPath = split[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (values.get(closestPath) instanceof Map && !path.equals(closestPath)) {
|
|
||||||
EcoJSONConfigSection section = new EcoJSONConfigSection((Map<String, Object>) values.get(closestPath));
|
|
||||||
return section.getOfKnownType(path.substring(closestPath.length() + 1), clazz, false);
|
|
||||||
} else {
|
|
||||||
if (values.containsKey(closestPath)) {
|
|
||||||
return (T) values.get(closestPath);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public List<String> getKeys(final boolean deep) {
|
|
||||||
if (deep) {
|
|
||||||
return new ArrayList<>(getDeepKeys(new HashSet<>(), ""));
|
|
||||||
} else {
|
|
||||||
return new ArrayList<>(values.keySet());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Set<String> getDeepKeys(@NotNull final Set<String> list,
|
|
||||||
@NotNull final String root) {
|
|
||||||
for (String key : values.keySet()) {
|
|
||||||
list.add(root + key);
|
|
||||||
|
|
||||||
if (values.get(key) instanceof Map) {
|
|
||||||
EcoJSONConfigSection section = new EcoJSONConfigSection((Map<String, Object>) values.get(key));
|
|
||||||
list.addAll(section.getDeepKeys(list, root + key + "."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public Object get(@NotNull final String path) {
|
|
||||||
return getOfKnownType(path, Object.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void set(@NotNull final String path,
|
|
||||||
@Nullable final Object object) {
|
|
||||||
setRecursively(path, object, true);
|
|
||||||
clearCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setRecursively(@NotNull final String path,
|
|
||||||
@Nullable final Object object,
|
|
||||||
final boolean isBase) {
|
|
||||||
String closestPath = path;
|
|
||||||
|
|
||||||
if (path.contains(".")) {
|
|
||||||
String[] split = path.split("\\.");
|
|
||||||
closestPath = split[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (values.get(closestPath) instanceof Map && !path.equals(closestPath)) {
|
|
||||||
EcoJSONConfigSection section = new EcoJSONConfigSection((Map<String, Object>) values.get(closestPath));
|
|
||||||
section.setRecursively(path.substring(closestPath.length() + 1), object, false);
|
|
||||||
values.put(closestPath, section.getValues());
|
|
||||||
} else {
|
|
||||||
Object obj = object;
|
|
||||||
|
|
||||||
if (object instanceof JSONConfig) {
|
|
||||||
obj = ((EcoJSONConfigWrapper) object).getValues();
|
|
||||||
}
|
|
||||||
|
|
||||||
values.put(path, obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public JSONConfig getSubsection(@NotNull final String path) {
|
|
||||||
JSONConfig subsection = getSubsectionOrNull(path);
|
|
||||||
Validate.notNull(subsection);
|
|
||||||
return subsection;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public JSONConfig getSubsectionOrNull(@NotNull final String path) {
|
|
||||||
if (values.containsKey(path)) {
|
|
||||||
Map<String, Object> subsection = (Map<String, Object>) values.get(path);
|
|
||||||
return new EcoJSONConfigSection(subsection);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public List<JSONConfig> getSubsections(@NotNull final String path) {
|
|
||||||
List<JSONConfig> subsections = getSubsectionsOrNull(path);
|
|
||||||
return subsections == null ? new ArrayList<>() : subsections;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public List<JSONConfig> getSubsectionsOrNull(@NotNull final String path) {
|
|
||||||
List<Map<String, Object>> maps = (List<Map<String, Object>>) getOfKnownType(path, Object.class);
|
|
||||||
|
|
||||||
if (maps == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<JSONConfig> configs = new ArrayList<>();
|
|
||||||
|
|
||||||
for (Map<String, Object> map : maps) {
|
|
||||||
configs.add(new EcoJSONConfigSection(map));
|
|
||||||
}
|
|
||||||
|
|
||||||
return configs;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getInt(@NotNull final String path) {
|
|
||||||
// ew
|
|
||||||
return Objects.requireNonNullElse(getOfKnownType(path, Double.class), 0D).intValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public Integer getIntOrNull(@NotNull final String path) {
|
|
||||||
if (has(path)) {
|
|
||||||
return getInt(path);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getInt(@NotNull final String path,
|
|
||||||
final int def) {
|
|
||||||
return Objects.requireNonNullElse(getOfKnownType(path, Integer.class), def);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public List<Integer> getInts(@NotNull final String path) {
|
|
||||||
return (List<Integer>) Objects.requireNonNullElse(getOfKnownType(path, Object.class), new ArrayList<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public List<Integer> getIntsOrNull(@NotNull final String path) {
|
|
||||||
if (has(path)) {
|
|
||||||
return getInts(path);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean getBool(@NotNull final String path) {
|
|
||||||
return Objects.requireNonNullElse(getOfKnownType(path, Boolean.class), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public Boolean getBoolOrNull(@NotNull final String path) {
|
|
||||||
if (has(path)) {
|
|
||||||
return getBool(path);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public List<Boolean> getBools(@NotNull final String path) {
|
|
||||||
return (List<Boolean>) Objects.requireNonNullElse(getOfKnownType(path, Object.class), new ArrayList<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public List<Boolean> getBoolsOrNull(@NotNull final String path) {
|
|
||||||
if (has(path)) {
|
|
||||||
return getBools(path);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public String getString(@NotNull final String path) {
|
|
||||||
return getString(path, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public String getString(@NotNull final String path,
|
|
||||||
final boolean format) {
|
|
||||||
String string = Objects.requireNonNullElse(getOfKnownType(path, String.class), "");
|
|
||||||
return format ? StringUtils.format(string) : string;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public String getStringOrNull(@NotNull final String path) {
|
|
||||||
if (has(path)) {
|
|
||||||
return getString(path);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public String getStringOrNull(@NotNull final String path,
|
|
||||||
final boolean format) {
|
|
||||||
if (has(path)) {
|
|
||||||
return getString(path, format);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public List<String> getStrings(@NotNull final String path) {
|
|
||||||
return getStrings(path, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public List<String> getStrings(@NotNull final String path,
|
|
||||||
final boolean format) {
|
|
||||||
List<String> strings = (List<String>) Objects.requireNonNullElse(getOfKnownType(path, Object.class), new ArrayList<>());
|
|
||||||
|
|
||||||
return format ? StringUtils.formatList(strings) : strings;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public List<String> getStringsOrNull(@NotNull final String path) {
|
|
||||||
if (has(path)) {
|
|
||||||
return getStrings(path);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable List<String> getStringsOrNull(@NotNull final String path,
|
|
||||||
final boolean format) {
|
|
||||||
if (has(path)) {
|
|
||||||
return getStrings(path, format);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double getDouble(@NotNull final String path) {
|
|
||||||
return Objects.requireNonNullElse(getOfKnownType(path, Double.class), 0D);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public Double getDoubleOrNull(@NotNull final String path) {
|
|
||||||
if (has(path)) {
|
|
||||||
return getDouble(path);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public List<Double> getDoubles(@NotNull final String path) {
|
|
||||||
return (List<Double>) Objects.requireNonNullElse(getOfKnownType(path, Object.class), new ArrayList<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public List<Double> getDoublesOrNull(@NotNull final String path) {
|
|
||||||
if (has(path)) {
|
|
||||||
return getDoubles(path);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JSONConfig clone() {
|
|
||||||
return new EcoJSONConfigSection(new HashMap<>(this.getValues()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
package com.willfp.eco.internal.config.json;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.config.interfaces.LoadableConfig;
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.StandardOpenOption;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "unused"})
|
|
||||||
public class EcoLoadableJSONConfig extends EcoJSONConfigWrapper implements LoadableConfig {
|
|
||||||
@Getter
|
|
||||||
private final File configFile;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PROTECTED)
|
|
||||||
private final EcoPlugin plugin;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PROTECTED)
|
|
||||||
private final String subDirectoryPath;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PROTECTED)
|
|
||||||
private final Class<?> source;
|
|
||||||
|
|
||||||
public EcoLoadableJSONConfig(@NotNull final String configName,
|
|
||||||
@NotNull final EcoPlugin plugin,
|
|
||||||
@NotNull final String subDirectoryPath,
|
|
||||||
@NotNull final Class<?> source) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
this.name = configName + ".json";
|
|
||||||
this.source = source;
|
|
||||||
this.subDirectoryPath = subDirectoryPath;
|
|
||||||
|
|
||||||
File directory = new File(this.getPlugin().getDataFolder(), subDirectoryPath);
|
|
||||||
if (!directory.exists()) {
|
|
||||||
directory.mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!new File(directory, this.name).exists()) {
|
|
||||||
createFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.configFile = new File(directory, this.name);
|
|
||||||
|
|
||||||
try {
|
|
||||||
init(this.configFile);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
plugin.getConfigHandler().addConfig(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reloadFromFile() {
|
|
||||||
try {
|
|
||||||
init(this.configFile);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void createFile() {
|
|
||||||
String resourcePath = getResourcePath();
|
|
||||||
InputStream in = source.getResourceAsStream(resourcePath);
|
|
||||||
|
|
||||||
File outFile = new File(this.getPlugin().getDataFolder(), resourcePath);
|
|
||||||
int lastIndex = resourcePath.lastIndexOf('/');
|
|
||||||
File outDir = new File(this.getPlugin().getDataFolder(), resourcePath.substring(0, Math.max(lastIndex, 0)));
|
|
||||||
|
|
||||||
if (!outDir.exists()) {
|
|
||||||
outDir.mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!outFile.exists()) {
|
|
||||||
OutputStream out = new FileOutputStream(outFile);
|
|
||||||
byte[] buf = new byte[1024];
|
|
||||||
int len;
|
|
||||||
while ((len = in.read(buf)) > 0) {
|
|
||||||
out.write(buf, 0, len);
|
|
||||||
}
|
|
||||||
out.close();
|
|
||||||
in.close();
|
|
||||||
}
|
|
||||||
} catch (IOException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getResourcePath() {
|
|
||||||
String resourcePath;
|
|
||||||
|
|
||||||
if (subDirectoryPath.isEmpty()) {
|
|
||||||
resourcePath = name;
|
|
||||||
} else {
|
|
||||||
resourcePath = subDirectoryPath + name;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "/" + resourcePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void save() throws IOException {
|
|
||||||
if (configFile.delete()) {
|
|
||||||
Files.write(configFile.toPath(), this.toPlaintext().getBytes(), StandardOpenOption.CREATE, StandardOpenOption.WRITE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void init(@NotNull final File file) throws FileNotFoundException {
|
|
||||||
super.init(this.getHandle().fromJson(new FileReader(file), HashMap.class));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
package com.willfp.eco.internal.config.updating;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.PluginDependent;
|
|
||||||
import com.willfp.eco.core.config.interfaces.LoadableConfig;
|
|
||||||
import com.willfp.eco.core.config.updating.ConfigHandler;
|
|
||||||
import com.willfp.eco.core.config.updating.ConfigUpdater;
|
|
||||||
import com.willfp.eco.internal.config.json.EcoLoadableJSONConfig;
|
|
||||||
import com.willfp.eco.internal.config.updating.exceptions.InvalidUpdateMethodException;
|
|
||||||
import com.willfp.eco.internal.config.yaml.EcoLoadableYamlConfig;
|
|
||||||
import com.willfp.eco.internal.config.yaml.EcoUpdatableYamlConfig;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.reflections.Reflections;
|
|
||||||
import org.reflections.scanners.MethodAnnotationsScanner;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class EcoConfigHandler extends PluginDependent<EcoPlugin> implements ConfigHandler {
|
|
||||||
private final List<LoadableConfig> configs = new ArrayList<>();
|
|
||||||
|
|
||||||
private final Reflections reflections;
|
|
||||||
|
|
||||||
public EcoConfigHandler(@NotNull final EcoPlugin plugin) {
|
|
||||||
super(plugin);
|
|
||||||
|
|
||||||
this.reflections = new Reflections(
|
|
||||||
this.getPlugin().getClass().getClassLoader(),
|
|
||||||
new MethodAnnotationsScanner()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void callUpdate() {
|
|
||||||
for (Method method : reflections.getMethodsAnnotatedWith(ConfigUpdater.class)) {
|
|
||||||
if (!Modifier.isStatic(method.getModifiers())) {
|
|
||||||
throw new InvalidUpdateMethodException("Update method must be static.");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (method.getParameterCount() == 0) {
|
|
||||||
method.invoke(null);
|
|
||||||
} else if (method.getParameterCount() == 1) {
|
|
||||||
method.invoke(null, this.getPlugin());
|
|
||||||
} else {
|
|
||||||
throw new InvalidUpdateMethodException("Update method must have 0 parameters or a plugin parameter.");
|
|
||||||
}
|
|
||||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw new InvalidUpdateMethodException("Update method generated an exception.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveAllConfigs() {
|
|
||||||
try {
|
|
||||||
for (LoadableConfig config : configs) {
|
|
||||||
config.save();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addConfig(@NotNull final LoadableConfig config) {
|
|
||||||
configs.add(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateConfigs() {
|
|
||||||
for (LoadableConfig config : configs) {
|
|
||||||
if (config instanceof EcoUpdatableYamlConfig updatableYamlConfig) {
|
|
||||||
updatableYamlConfig.update();
|
|
||||||
}
|
|
||||||
if (config instanceof EcoLoadableYamlConfig ecoLoadableYamlConfig) {
|
|
||||||
ecoLoadableYamlConfig.reloadFromFile();
|
|
||||||
}
|
|
||||||
if (config instanceof EcoLoadableJSONConfig ecoLoadableJSONConfig) {
|
|
||||||
ecoLoadableJSONConfig.reloadFromFile();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package com.willfp.eco.internal.config.updating.exceptions;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class InvalidUpdateMethodException extends RuntimeException {
|
|
||||||
public InvalidUpdateMethodException(@NotNull final String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
package com.willfp.eco.internal.config.yaml;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.config.interfaces.LoadableConfig;
|
|
||||||
import com.willfp.eco.core.config.interfaces.WrappedYamlConfiguration;
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
|
||||||
import org.bukkit.configuration.InvalidConfigurationException;
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public class EcoLoadableYamlConfig extends EcoYamlConfigWrapper<YamlConfiguration> implements WrappedYamlConfiguration, LoadableConfig {
|
|
||||||
@Getter
|
|
||||||
private final File configFile;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PROTECTED)
|
|
||||||
private final EcoPlugin plugin;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PROTECTED)
|
|
||||||
private final String subDirectoryPath;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PROTECTED)
|
|
||||||
private final Class<?> source;
|
|
||||||
|
|
||||||
public EcoLoadableYamlConfig(@NotNull final String configName,
|
|
||||||
@NotNull final EcoPlugin plugin,
|
|
||||||
@NotNull final String subDirectoryPath,
|
|
||||||
@NotNull final Class<?> source) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
this.name = configName + ".yml";
|
|
||||||
this.source = source;
|
|
||||||
this.subDirectoryPath = subDirectoryPath;
|
|
||||||
|
|
||||||
File directory = new File(this.getPlugin().getDataFolder(), subDirectoryPath);
|
|
||||||
if (!directory.exists()) {
|
|
||||||
directory.mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!new File(directory, this.name).exists()) {
|
|
||||||
createFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.configFile = new File(directory, this.name);
|
|
||||||
|
|
||||||
this.getPlugin().getConfigHandler().addConfig(this);
|
|
||||||
init(YamlConfiguration.loadConfiguration(configFile));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reloadFromFile() {
|
|
||||||
try {
|
|
||||||
this.getHandle().load(this.getConfigFile());
|
|
||||||
} catch (IOException | InvalidConfigurationException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void createFile() {
|
|
||||||
String resourcePath = getResourcePath();
|
|
||||||
InputStream in = source.getResourceAsStream(resourcePath);
|
|
||||||
|
|
||||||
File outFile = new File(this.getPlugin().getDataFolder(), resourcePath);
|
|
||||||
int lastIndex = resourcePath.lastIndexOf('/');
|
|
||||||
File outDir = new File(this.getPlugin().getDataFolder(), resourcePath.substring(0, Math.max(lastIndex, 0)));
|
|
||||||
|
|
||||||
if (!outDir.exists()) {
|
|
||||||
outDir.mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!outFile.exists()) {
|
|
||||||
OutputStream out = new FileOutputStream(outFile);
|
|
||||||
byte[] buf = new byte[1024];
|
|
||||||
int len;
|
|
||||||
while ((len = in.read(buf)) > 0) {
|
|
||||||
out.write(buf, 0, len);
|
|
||||||
}
|
|
||||||
out.close();
|
|
||||||
in.close();
|
|
||||||
}
|
|
||||||
} catch (IOException ignored) {
|
|
||||||
}
|
|
||||||
|
|
||||||
plugin.getConfigHandler().addConfig(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getResourcePath() {
|
|
||||||
String resourcePath;
|
|
||||||
|
|
||||||
if (subDirectoryPath.isEmpty()) {
|
|
||||||
resourcePath = name;
|
|
||||||
} else {
|
|
||||||
resourcePath = subDirectoryPath + name;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "/" + resourcePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void save() throws IOException {
|
|
||||||
this.getHandle().save(this.getConfigFile());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public YamlConfiguration getBukkitHandle() {
|
|
||||||
return this.getHandle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
package com.willfp.eco.internal.config.yaml;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import org.bukkit.configuration.InvalidConfigurationException;
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class EcoUpdatableYamlConfig extends EcoLoadableYamlConfig {
|
|
||||||
private final boolean removeUnused;
|
|
||||||
|
|
||||||
private final List<String> updateBlacklist;
|
|
||||||
|
|
||||||
public EcoUpdatableYamlConfig(@NotNull final String configName,
|
|
||||||
@NotNull final EcoPlugin plugin,
|
|
||||||
@NotNull final String subDirectoryPath,
|
|
||||||
@NotNull final Class<?> source,
|
|
||||||
final boolean removeUnused,
|
|
||||||
@NotNull final String... updateBlacklist) {
|
|
||||||
super(configName, plugin, subDirectoryPath, source);
|
|
||||||
this.removeUnused = removeUnused;
|
|
||||||
this.updateBlacklist = new ArrayList<>(Arrays.asList(updateBlacklist));
|
|
||||||
this.updateBlacklist.removeIf(String::isEmpty);
|
|
||||||
|
|
||||||
plugin.getConfigHandler().addConfig(this);
|
|
||||||
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update() {
|
|
||||||
super.clearCache();
|
|
||||||
try {
|
|
||||||
this.getHandle().load(this.getConfigFile());
|
|
||||||
|
|
||||||
YamlConfiguration newConfig = this.getConfigInJar();
|
|
||||||
|
|
||||||
if (newConfig.getKeys(true).equals(this.getHandle().getKeys(true))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
newConfig.getKeys(true).forEach((s -> {
|
|
||||||
if (!this.getHandle().getKeys(true).contains(s)) {
|
|
||||||
if (updateBlacklist.stream().noneMatch(s::contains)) {
|
|
||||||
this.getHandle().set(s, newConfig.get(s));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (this.removeUnused) {
|
|
||||||
this.getHandle().getKeys(true).forEach((s -> {
|
|
||||||
if (!newConfig.getKeys(true).contains(s)) {
|
|
||||||
if (updateBlacklist.stream().noneMatch(s::contains)) {
|
|
||||||
this.getHandle().set(s, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.getHandle().save(this.getConfigFile());
|
|
||||||
} catch (IOException | InvalidConfigurationException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public YamlConfiguration getConfigInJar() {
|
|
||||||
InputStream newIn = this.getSource().getResourceAsStream(getResourcePath());
|
|
||||||
|
|
||||||
if (newIn == null) {
|
|
||||||
throw new NullPointerException(this.getName() + " is null?");
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(newIn, StandardCharsets.UTF_8));
|
|
||||||
YamlConfiguration newConfig = new YamlConfiguration();
|
|
||||||
|
|
||||||
try {
|
|
||||||
newConfig.load(reader);
|
|
||||||
} catch (IOException | InvalidConfigurationException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return newConfig;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package com.willfp.eco.internal.config.yaml;
|
|
||||||
|
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class EcoYamlConfigSection extends EcoYamlConfigWrapper<ConfigurationSection> {
|
|
||||||
public EcoYamlConfigSection(@NotNull final ConfigurationSection section) {
|
|
||||||
this.init(section);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,316 +0,0 @@
|
|||||||
package com.willfp.eco.internal.config.yaml;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.config.interfaces.Config;
|
|
||||||
import com.willfp.eco.util.StringUtils;
|
|
||||||
import lombok.Getter;
|
|
||||||
import org.apache.commons.lang.Validate;
|
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.io.StringReader;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "unused"})
|
|
||||||
public class EcoYamlConfigWrapper<T extends ConfigurationSection> implements Config {
|
|
||||||
@Getter
|
|
||||||
private T handle = null;
|
|
||||||
|
|
||||||
private final Map<String, Object> cache = new HashMap<>();
|
|
||||||
|
|
||||||
public EcoYamlConfigWrapper() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Config init(@NotNull final T config) {
|
|
||||||
this.handle = config;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toPlaintext() {
|
|
||||||
YamlConfiguration temp = new YamlConfiguration();
|
|
||||||
for (String key : handle.getKeys(true)) {
|
|
||||||
temp.set(key, handle.get(key));
|
|
||||||
}
|
|
||||||
return temp.saveToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void clearCache() {
|
|
||||||
cache.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean has(@NotNull final String path) {
|
|
||||||
return handle.contains(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public List<String> getKeys(final boolean deep) {
|
|
||||||
return new ArrayList<>(handle.getKeys(deep));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public Object get(@NotNull final String path) {
|
|
||||||
return handle.get(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void set(@NotNull final String path,
|
|
||||||
@Nullable final Object object) {
|
|
||||||
cache.remove(path);
|
|
||||||
handle.set(path, object);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public Config getSubsection(@NotNull final String path) {
|
|
||||||
Config subsection = getSubsectionOrNull(path);
|
|
||||||
Validate.notNull(subsection);
|
|
||||||
return subsection;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public Config getSubsectionOrNull(@NotNull final String path) {
|
|
||||||
if (cache.containsKey(path)) {
|
|
||||||
return (Config) cache.get(path);
|
|
||||||
} else {
|
|
||||||
ConfigurationSection raw = handle.getConfigurationSection(path);
|
|
||||||
if (raw == null) {
|
|
||||||
cache.put(path, null);
|
|
||||||
} else {
|
|
||||||
cache.put(path, new EcoYamlConfigSection(raw));
|
|
||||||
}
|
|
||||||
return getSubsectionOrNull(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getInt(@NotNull final String path) {
|
|
||||||
if (cache.containsKey(path)) {
|
|
||||||
return (int) cache.get(path);
|
|
||||||
} else {
|
|
||||||
cache.put(path, handle.getInt(path, 0));
|
|
||||||
return getInt(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public Integer getIntOrNull(@NotNull final String path) {
|
|
||||||
if (has(path)) {
|
|
||||||
return getInt(path);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getInt(@NotNull final String path,
|
|
||||||
final int def) {
|
|
||||||
if (cache.containsKey(path)) {
|
|
||||||
return (int) cache.get(path);
|
|
||||||
} else {
|
|
||||||
cache.put(path, handle.getInt(path, def));
|
|
||||||
return getInt(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public List<Integer> getInts(@NotNull final String path) {
|
|
||||||
if (cache.containsKey(path)) {
|
|
||||||
return (List<Integer>) cache.get(path);
|
|
||||||
} else {
|
|
||||||
cache.put(path, has(path) ? new ArrayList<>(handle.getIntegerList(path)) : new ArrayList<>());
|
|
||||||
return getInts(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public List<Integer> getIntsOrNull(@NotNull final String path) {
|
|
||||||
if (has(path)) {
|
|
||||||
return getInts(path);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean getBool(@NotNull final String path) {
|
|
||||||
if (cache.containsKey(path)) {
|
|
||||||
return (boolean) cache.get(path);
|
|
||||||
} else {
|
|
||||||
cache.put(path, handle.getBoolean(path));
|
|
||||||
return getBool(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public Boolean getBoolOrNull(@NotNull final String path) {
|
|
||||||
if (has(path)) {
|
|
||||||
return getBool(path);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public List<Boolean> getBools(@NotNull final String path) {
|
|
||||||
if (cache.containsKey(path)) {
|
|
||||||
return (List<Boolean>) cache.get(path);
|
|
||||||
} else {
|
|
||||||
cache.put(path, has(path) ? new ArrayList<>(handle.getBooleanList(path)) : new ArrayList<>());
|
|
||||||
return getBools(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public List<Boolean> getBoolsOrNull(@NotNull final String path) {
|
|
||||||
if (has(path)) {
|
|
||||||
return getBools(path);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public String getString(@NotNull final String path) {
|
|
||||||
if (cache.containsKey(path)) {
|
|
||||||
return (String) cache.get(path);
|
|
||||||
} else {
|
|
||||||
cache.put(path, StringUtils.format(Objects.requireNonNull(handle.getString(path, ""))));
|
|
||||||
return getString(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull String getString(@NotNull final String path,
|
|
||||||
final boolean format) {
|
|
||||||
if (cache.containsKey(path)) {
|
|
||||||
return (String) cache.get(path);
|
|
||||||
} else {
|
|
||||||
String string = Objects.requireNonNull(handle.getString(path, ""));
|
|
||||||
cache.put(path, format ? StringUtils.format(string) : string);
|
|
||||||
return getString(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public String getStringOrNull(@NotNull final String path) {
|
|
||||||
if (has(path)) {
|
|
||||||
return getString(path);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable String getStringOrNull(@NotNull final String path,
|
|
||||||
final boolean format) {
|
|
||||||
if (has(path)) {
|
|
||||||
return getString(path, format);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public List<String> getStrings(@NotNull final String path) {
|
|
||||||
return getStrings(path, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public List<String> getStrings(@NotNull final String path,
|
|
||||||
final boolean format) {
|
|
||||||
if (cache.containsKey(path)) {
|
|
||||||
return format ? StringUtils.formatList((List<String>) cache.get(path)) : (List<String>) cache.get(path);
|
|
||||||
} else {
|
|
||||||
cache.put(path, has(path) ? new ArrayList<>(handle.getStringList(path)) : new ArrayList<>());
|
|
||||||
return getStrings(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public List<String> getStringsOrNull(@NotNull final String path) {
|
|
||||||
if (has(path)) {
|
|
||||||
return getStrings(path);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable List<String> getStringsOrNull(@NotNull final String path,
|
|
||||||
final boolean format) {
|
|
||||||
if (has(path)) {
|
|
||||||
return getStrings(path, format);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double getDouble(@NotNull final String path) {
|
|
||||||
if (cache.containsKey(path)) {
|
|
||||||
return (double) cache.get(path);
|
|
||||||
} else {
|
|
||||||
cache.put(path, handle.getDouble(path));
|
|
||||||
return getDouble(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public Double getDoubleOrNull(@NotNull final String path) {
|
|
||||||
if (has(path)) {
|
|
||||||
return getDouble(path);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public List<Double> getDoubles(@NotNull final String path) {
|
|
||||||
if (cache.containsKey(path)) {
|
|
||||||
return (List<Double>) cache.get(path);
|
|
||||||
} else {
|
|
||||||
cache.put(path, has(path) ? new ArrayList<>(handle.getDoubleList(path)) : new ArrayList<>());
|
|
||||||
return getDoubles(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public List<Double> getDoublesOrNull(@NotNull final String path) {
|
|
||||||
if (has(path)) {
|
|
||||||
return getDoubles(path);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Config clone() {
|
|
||||||
return new EcoYamlConfigSection(YamlConfiguration.loadConfiguration(new StringReader(this.toPlaintext())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package com.willfp.eco.internal.drops;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.config.updating.ConfigUpdater;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
@UtilityClass
|
|
||||||
public final class DropManager {
|
|
||||||
@Getter
|
|
||||||
private DropQueueType type = DropQueueType.COLLATED;
|
|
||||||
|
|
||||||
@ConfigUpdater
|
|
||||||
public static void update(@NotNull final EcoPlugin plugin) {
|
|
||||||
type = plugin.getConfigYml().getBool("use-fast-collated-drops") ? DropQueueType.COLLATED : DropQueueType.STANDARD;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
package com.willfp.eco.internal.drops;
|
|
||||||
|
|
||||||
public enum DropQueueType {
|
|
||||||
STANDARD,
|
|
||||||
COLLATED
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package com.willfp.eco.internal.drops;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.drops.DropQueueFactory;
|
|
||||||
import com.willfp.eco.core.drops.InternalDropQueue;
|
|
||||||
import com.willfp.eco.internal.drops.impl.EcoDropQueue;
|
|
||||||
import com.willfp.eco.internal.drops.impl.EcoFastCollatedDropQueue;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class EcoDropQueueFactory implements DropQueueFactory {
|
|
||||||
@Override
|
|
||||||
public InternalDropQueue create(@NotNull final Player player) {
|
|
||||||
return DropManager.getType() == DropQueueType.COLLATED ? new EcoFastCollatedDropQueue(player) : new EcoDropQueue(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
package com.willfp.eco.internal.drops.impl;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.drops.InternalDropQueue;
|
|
||||||
import com.willfp.eco.util.TelekinesisUtils;
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
import org.bukkit.entity.ExperienceOrb;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.player.PlayerExpChangeEvent;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class EcoDropQueue implements InternalDropQueue {
|
|
||||||
@Getter(AccessLevel.PROTECTED)
|
|
||||||
private final List<ItemStack> items;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PROTECTED)
|
|
||||||
private int xp;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PROTECTED)
|
|
||||||
private final Player player;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PROTECTED)
|
|
||||||
private Location loc;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PROTECTED)
|
|
||||||
private boolean hasTelekinesis = false;
|
|
||||||
|
|
||||||
public EcoDropQueue(@NotNull final Player player) {
|
|
||||||
this.items = new ArrayList<>();
|
|
||||||
this.xp = 0;
|
|
||||||
this.player = player;
|
|
||||||
this.loc = player.getLocation();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InternalDropQueue addItem(@NotNull final ItemStack item) {
|
|
||||||
this.items.add(item);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InternalDropQueue addItems(@NotNull final Collection<ItemStack> itemStacks) {
|
|
||||||
this.items.addAll(itemStacks);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InternalDropQueue addXP(final int amount) {
|
|
||||||
this.xp += amount;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InternalDropQueue setLocation(@NotNull final Location location) {
|
|
||||||
this.loc = location;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InternalDropQueue forceTelekinesis() {
|
|
||||||
this.hasTelekinesis = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void push() {
|
|
||||||
if (!hasTelekinesis) {
|
|
||||||
hasTelekinesis = TelekinesisUtils.testPlayer(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
World world = loc.getWorld();
|
|
||||||
assert world != null;
|
|
||||||
loc = loc.add(0.5, 0.5, 0.5);
|
|
||||||
|
|
||||||
items.removeIf(itemStack -> itemStack.getType() == Material.AIR);
|
|
||||||
if (items.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasTelekinesis) {
|
|
||||||
HashMap<Integer, ItemStack> leftover = player.getInventory().addItem(items.toArray(new ItemStack[0]));
|
|
||||||
for (ItemStack drop : leftover.values()) {
|
|
||||||
world.dropItem(loc, drop).setVelocity(new Vector());
|
|
||||||
}
|
|
||||||
if (xp > 0) {
|
|
||||||
PlayerExpChangeEvent event = new PlayerExpChangeEvent(player, xp);
|
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
|
||||||
ExperienceOrb orb = (ExperienceOrb) world.spawnEntity(player.getLocation().add(0, 0.2, 0), EntityType.EXPERIENCE_ORB);
|
|
||||||
orb.setVelocity(new Vector(0, 0, 0));
|
|
||||||
orb.setExperience(event.getAmount());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (ItemStack drop : items) {
|
|
||||||
world.dropItem(loc, drop).setVelocity(new Vector());
|
|
||||||
}
|
|
||||||
if (xp > 0) {
|
|
||||||
ExperienceOrb orb = (ExperienceOrb) world.spawnEntity(loc, EntityType.EXPERIENCE_ORB);
|
|
||||||
orb.setExperience(xp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
package com.willfp.eco.internal.drops.impl;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.ToString;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
public class EcoFastCollatedDropQueue extends EcoDropQueue {
|
|
||||||
public static final Map<Player, CollatedDrops> COLLATED_MAP = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
public EcoFastCollatedDropQueue(@NotNull final Player player) {
|
|
||||||
super(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void push() {
|
|
||||||
CollatedDrops fetched = COLLATED_MAP.get(getPlayer());
|
|
||||||
CollatedDrops collatedDrops = fetched == null ? new CollatedDrops(getItems(), getLoc(), getXp()) : fetched.addDrops(getItems()).setLocation(getLoc()).addXp(getXp());
|
|
||||||
COLLATED_MAP.put(this.getPlayer(), collatedDrops);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ToString
|
|
||||||
public static final class CollatedDrops {
|
|
||||||
@Getter
|
|
||||||
private final List<ItemStack> drops;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Accessors(chain = true)
|
|
||||||
private Location location;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private int xp;
|
|
||||||
|
|
||||||
private CollatedDrops(@NotNull final List<ItemStack> drops,
|
|
||||||
@NotNull final Location location,
|
|
||||||
final int xp) {
|
|
||||||
this.drops = drops;
|
|
||||||
this.location = location;
|
|
||||||
this.xp = xp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CollatedDrops addDrops(@NotNull final List<ItemStack> toAdd) {
|
|
||||||
drops.addAll(toAdd);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CollatedDrops addXp(final int xp) {
|
|
||||||
this.xp += xp;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
package com.willfp.eco.internal.events;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.PluginDependent;
|
|
||||||
import com.willfp.eco.core.events.EventManager;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.event.HandlerList;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class EcoEventManager extends PluginDependent<EcoPlugin> implements EventManager {
|
|
||||||
@ApiStatus.Internal
|
|
||||||
public EcoEventManager(@NotNull final EcoPlugin plugin) {
|
|
||||||
super(plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void registerListener(@NotNull final Listener listener) {
|
|
||||||
Bukkit.getPluginManager().registerEvents(listener, this.getPlugin());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unregisterListener(@NotNull final Listener listener) {
|
|
||||||
HandlerList.unregisterAll(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unregisterAllListeners() {
|
|
||||||
HandlerList.unregisterAll(this.getPlugin());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
package com.willfp.eco.internal.extensions;
|
|
||||||
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.PluginDependent;
|
|
||||||
import com.willfp.eco.core.config.interfaces.Config;
|
|
||||||
import com.willfp.eco.core.config.yaml.YamlTransientConfig;
|
|
||||||
import com.willfp.eco.core.extensions.Extension;
|
|
||||||
import com.willfp.eco.core.extensions.ExtensionLoader;
|
|
||||||
import com.willfp.eco.core.extensions.ExtensionMetadata;
|
|
||||||
import com.willfp.eco.core.extensions.MalformedExtensionException;
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLClassLoader;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class EcoExtensionLoader extends PluginDependent<EcoPlugin> implements ExtensionLoader {
|
|
||||||
private final Map<Extension, ClassLoader> extensions = new HashMap<>();
|
|
||||||
|
|
||||||
public EcoExtensionLoader(@NotNull final EcoPlugin plugin) {
|
|
||||||
super(plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadExtensions() {
|
|
||||||
File dir = new File(this.getPlugin().getDataFolder(), "/extensions");
|
|
||||||
if (!dir.exists()) {
|
|
||||||
dir.mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
File[] extensionJars = dir.listFiles();
|
|
||||||
|
|
||||||
if (extensionJars == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (File extensionJar : extensionJars) {
|
|
||||||
if (!extensionJar.isFile()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
loadExtension(extensionJar);
|
|
||||||
} catch (MalformedExtensionException e) {
|
|
||||||
this.getPlugin().getLogger().warning(extensionJar.getName() + " caused an error!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadExtension(@NotNull final File extensionJar) throws MalformedExtensionException {
|
|
||||||
URL url = null;
|
|
||||||
try {
|
|
||||||
url = extensionJar.toURI().toURL();
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
ClassLoader classLoader = new URLClassLoader(new URL[]{url}, this.getPlugin().getClass().getClassLoader());
|
|
||||||
|
|
||||||
InputStream ymlIn = classLoader.getResourceAsStream("extension.yml");
|
|
||||||
|
|
||||||
if (ymlIn == null) {
|
|
||||||
throw new MalformedExtensionException("No extension.yml found in " + extensionJar.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
Config extensionYml = new YamlTransientConfig(YamlConfiguration.loadConfiguration(new InputStreamReader(ymlIn)));
|
|
||||||
|
|
||||||
String mainClass = extensionYml.getStringOrNull("main");
|
|
||||||
String name = extensionYml.getStringOrNull("name");
|
|
||||||
String version = extensionYml.getStringOrNull("version");
|
|
||||||
String author = extensionYml.getStringOrNull("author");
|
|
||||||
|
|
||||||
if (mainClass == null) {
|
|
||||||
throw new MalformedExtensionException("Invalid extension.yml found in " + extensionJar.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name == null) {
|
|
||||||
this.getPlugin().getLogger().warning(extensionJar.getName() + " doesn't have a name!");
|
|
||||||
name = "Unnamed Extension " + extensionJar.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (version == null) {
|
|
||||||
this.getPlugin().getLogger().warning(extensionJar.getName() + " doesn't have a version!");
|
|
||||||
version = "1.0.0";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (author == null) {
|
|
||||||
this.getPlugin().getLogger().warning(extensionJar.getName() + " doesn't have an author!");
|
|
||||||
author = "Unnamed Author";
|
|
||||||
}
|
|
||||||
|
|
||||||
ExtensionMetadata metadata = new ExtensionMetadata(version, name, author);
|
|
||||||
|
|
||||||
Class<?> cls;
|
|
||||||
Object object = null;
|
|
||||||
try {
|
|
||||||
cls = classLoader.loadClass(mainClass);
|
|
||||||
object = cls.getConstructor(EcoPlugin.class).newInstance(this.getPlugin());
|
|
||||||
} catch (ReflectiveOperationException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(object instanceof Extension extension)) {
|
|
||||||
throw new MalformedExtensionException(extensionJar.getName() + " is invalid");
|
|
||||||
}
|
|
||||||
|
|
||||||
extension.setMetadata(metadata);
|
|
||||||
extension.enable();
|
|
||||||
extensions.put(extension, classLoader);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unloadExtensions() {
|
|
||||||
extensions.keySet().forEach(Extension::disable);
|
|
||||||
for (ClassLoader loader : extensions.values()) {
|
|
||||||
try {
|
|
||||||
((URLClassLoader) loader).close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
extensions.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<Extension> getLoadedExtensions() {
|
|
||||||
return extensions.keySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package com.willfp.eco.internal.factory;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.PluginDependent;
|
|
||||||
import com.willfp.eco.core.factory.MetadataValueFactory;
|
|
||||||
import org.bukkit.metadata.FixedMetadataValue;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class EcoMetadataValueFactory extends PluginDependent<EcoPlugin> implements MetadataValueFactory {
|
|
||||||
public EcoMetadataValueFactory(@NotNull final EcoPlugin plugin) {
|
|
||||||
super(plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FixedMetadataValue create(@NotNull final Object value) {
|
|
||||||
return new FixedMetadataValue(this.getPlugin(), value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package com.willfp.eco.internal.factory;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.PluginDependent;
|
|
||||||
import com.willfp.eco.core.factory.NamespacedKeyFactory;
|
|
||||||
import org.bukkit.NamespacedKey;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class EcoNamespacedKeyFactory extends PluginDependent<EcoPlugin> implements NamespacedKeyFactory {
|
|
||||||
public EcoNamespacedKeyFactory(@NotNull final EcoPlugin plugin) {
|
|
||||||
super(plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NamespacedKey create(@NotNull final String key) {
|
|
||||||
return new NamespacedKey(this.getPlugin(), key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
package com.willfp.eco.internal.factory;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.PluginDependent;
|
|
||||||
import com.willfp.eco.core.factory.RunnableFactory;
|
|
||||||
import com.willfp.eco.core.scheduling.RunnableTask;
|
|
||||||
import com.willfp.eco.internal.scheduling.EcoRunnableTask;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public class EcoRunnableFactory extends PluginDependent<EcoPlugin> implements RunnableFactory {
|
|
||||||
public EcoRunnableFactory(@NotNull final EcoPlugin plugin) {
|
|
||||||
super(plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RunnableTask create(@NotNull final Consumer<RunnableTask> consumer) {
|
|
||||||
return new EcoRunnableTask(this.getPlugin()) {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
consumer.accept(this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package com.willfp.eco.internal.gui;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.gui.GUIFactory;
|
|
||||||
import com.willfp.eco.core.gui.menu.MenuBuilder;
|
|
||||||
import com.willfp.eco.core.gui.slot.SlotBuilder;
|
|
||||||
import com.willfp.eco.internal.gui.menu.EcoMenuBuilder;
|
|
||||||
import com.willfp.eco.internal.gui.slot.EcoSlotBuilder;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
public class EcoGUIFactory implements GUIFactory {
|
|
||||||
@Override
|
|
||||||
public SlotBuilder createSlotBuilder(@NotNull final Function<Player, ItemStack> provider) {
|
|
||||||
return new EcoSlotBuilder(provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MenuBuilder createMenuBuilder(final int rows) {
|
|
||||||
return new EcoMenuBuilder(rows);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
package com.willfp.eco.internal.gui.menu;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.gui.menu.Menu;
|
|
||||||
import com.willfp.eco.core.gui.slot.FillerSlot;
|
|
||||||
import com.willfp.eco.core.gui.slot.Slot;
|
|
||||||
import com.willfp.eco.internal.gui.slot.EcoFillerSlot;
|
|
||||||
import com.willfp.eco.util.StringUtils;
|
|
||||||
import lombok.Getter;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
|
||||||
import org.bukkit.inventory.Inventory;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public class EcoMenu implements Menu {
|
|
||||||
@Getter
|
|
||||||
private final int rows;
|
|
||||||
|
|
||||||
private final List<List<Slot>> slots;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private final String title;
|
|
||||||
|
|
||||||
private final Consumer<InventoryCloseEvent> onClose;
|
|
||||||
|
|
||||||
public EcoMenu(final int rows,
|
|
||||||
@NotNull final List<List<Slot>> slots,
|
|
||||||
@NotNull final String title,
|
|
||||||
@NotNull final Consumer<InventoryCloseEvent> onClose) {
|
|
||||||
this.rows = rows;
|
|
||||||
this.slots = slots;
|
|
||||||
this.title = title;
|
|
||||||
this.onClose = onClose;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Slot getSlot(final int row,
|
|
||||||
final int column) {
|
|
||||||
if (row < 1 || row > this.rows) {
|
|
||||||
throw new IllegalArgumentException("Invalid row number!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (column < 1 || column > 9) {
|
|
||||||
throw new IllegalArgumentException("Invalid column number!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Slot slot = slots.get(row - 1).get(column - 1);
|
|
||||||
if (slot instanceof FillerSlot fillerSlot) {
|
|
||||||
slots.get(row - 1).set(
|
|
||||||
column - 1,
|
|
||||||
new EcoFillerSlot(fillerSlot.getItemStack())
|
|
||||||
);
|
|
||||||
|
|
||||||
return getSlot(row, column);
|
|
||||||
}
|
|
||||||
|
|
||||||
return slots.get(row - 1).get(column - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Inventory open(@NotNull final Player player) {
|
|
||||||
Inventory inventory = Bukkit.createInventory(null, rows * 9, title);
|
|
||||||
int i = 0;
|
|
||||||
for (List<Slot> row : slots) {
|
|
||||||
for (Slot item : row) {
|
|
||||||
if (i == rows * 9) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ItemStack slotItem = item.getItemStack(player);
|
|
||||||
ItemMeta meta = slotItem.getItemMeta();
|
|
||||||
if (meta != null) {
|
|
||||||
List<String> lore = meta.getLore();
|
|
||||||
if (lore != null) {
|
|
||||||
lore.replaceAll(s -> StringUtils.format(s, player));
|
|
||||||
meta.setLore(lore);
|
|
||||||
}
|
|
||||||
slotItem.setItemMeta(meta);
|
|
||||||
}
|
|
||||||
inventory.setItem(i, slotItem);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
player.openInventory(inventory);
|
|
||||||
MenuHandler.registerMenu(inventory, this);
|
|
||||||
return inventory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleClose(@NotNull final InventoryCloseEvent event) {
|
|
||||||
onClose.accept(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
package com.willfp.eco.internal.gui.menu;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.gui.menu.Menu;
|
|
||||||
import com.willfp.eco.core.gui.menu.MenuBuilder;
|
|
||||||
import com.willfp.eco.core.gui.slot.FillerMask;
|
|
||||||
import com.willfp.eco.core.gui.slot.Slot;
|
|
||||||
import com.willfp.eco.internal.gui.slot.EcoFillerSlot;
|
|
||||||
import com.willfp.eco.util.ListUtils;
|
|
||||||
import com.willfp.eco.util.StringUtils;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public class EcoMenuBuilder implements MenuBuilder {
|
|
||||||
private final int rows;
|
|
||||||
|
|
||||||
private String title = "Menu";
|
|
||||||
|
|
||||||
private List<List<Slot>> maskSlots;
|
|
||||||
|
|
||||||
private final List<List<Slot>> slots;
|
|
||||||
|
|
||||||
private Consumer<InventoryCloseEvent> onClose = (event) -> {
|
|
||||||
};
|
|
||||||
|
|
||||||
public EcoMenuBuilder(final int rows) {
|
|
||||||
this.rows = rows;
|
|
||||||
this.slots = ListUtils.create2DList(rows, 9);
|
|
||||||
this.maskSlots = ListUtils.create2DList(rows, 9);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MenuBuilder setTitle(@NotNull final String title) {
|
|
||||||
this.title = StringUtils.format(title);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MenuBuilder setSlot(final int row,
|
|
||||||
final int column,
|
|
||||||
@NotNull final Slot slot) {
|
|
||||||
if (row < 1 || row > this.rows) {
|
|
||||||
throw new IllegalArgumentException("Invalid row number!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (column < 1 || column > 9) {
|
|
||||||
throw new IllegalArgumentException("Invalid column number!");
|
|
||||||
}
|
|
||||||
|
|
||||||
slots.get(row - 1).set(column - 1, slot);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MenuBuilder setMask(@NotNull final FillerMask mask) {
|
|
||||||
this.maskSlots = mask.getMask();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MenuBuilder onClose(@NotNull final Consumer<InventoryCloseEvent> action) {
|
|
||||||
this.onClose = action;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Menu build() {
|
|
||||||
List<List<Slot>> finalSlots = maskSlots;
|
|
||||||
for (int i = 0; i < slots.size(); i++) {
|
|
||||||
for (int j = 0; j < slots.get(i).size(); j++) {
|
|
||||||
Slot slot = slots.get(i).get(j);
|
|
||||||
if (slot != null) {
|
|
||||||
finalSlots.get(i).set(j, slot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (List<Slot> finalSlot : finalSlots) {
|
|
||||||
for (int j = 0; j < finalSlot.size(); j++) {
|
|
||||||
if (finalSlot.get(j) == null) {
|
|
||||||
finalSlot.set(j, new EcoFillerSlot(new ItemStack(Material.AIR)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new EcoMenu(rows, finalSlots, title, onClose);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
package com.willfp.eco.internal.gui.menu;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.gui.menu.Menu;
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
import org.bukkit.inventory.Inventory;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@UtilityClass
|
|
||||||
public class MenuHandler {
|
|
||||||
private static final Map<Inventory, Menu> MENUS = new HashMap<>();
|
|
||||||
|
|
||||||
public void registerMenu(@NotNull final Inventory inventory,
|
|
||||||
@NotNull final Menu menu) {
|
|
||||||
MENUS.put(inventory, menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unregisterMenu(@NotNull final Inventory inventory) {
|
|
||||||
MENUS.remove(inventory);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public Menu getMenu(@NotNull final Inventory inventory) {
|
|
||||||
return MENUS.get(inventory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package com.willfp.eco.internal.gui.slot;
|
|
||||||
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class EcoFillerSlot extends EcoSlot {
|
|
||||||
public EcoFillerSlot(@NotNull final ItemStack itemStack) {
|
|
||||||
super((player) -> itemStack, null, null, null, null, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
package com.willfp.eco.internal.gui.slot;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.gui.slot.Slot;
|
|
||||||
import lombok.Getter;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
public class EcoSlot implements Slot {
|
|
||||||
@Getter
|
|
||||||
private final Function<Player, ItemStack> provider;
|
|
||||||
|
|
||||||
private final BiConsumer<InventoryClickEvent, Slot> onLeftClick;
|
|
||||||
|
|
||||||
private final BiConsumer<InventoryClickEvent, Slot> onRightClick;
|
|
||||||
|
|
||||||
private final BiConsumer<InventoryClickEvent, Slot> onShiftLeftClick;
|
|
||||||
|
|
||||||
private final BiConsumer<InventoryClickEvent, Slot> onShiftRightClick;
|
|
||||||
|
|
||||||
private final BiConsumer<InventoryClickEvent, Slot> onMiddleClick;
|
|
||||||
|
|
||||||
public EcoSlot(@NotNull final Function<Player, ItemStack> provider,
|
|
||||||
@Nullable final BiConsumer<InventoryClickEvent, Slot> onLeftClick,
|
|
||||||
@Nullable final BiConsumer<InventoryClickEvent, Slot> onRightClick,
|
|
||||||
@Nullable final BiConsumer<InventoryClickEvent, Slot> onShiftLeftClick,
|
|
||||||
@Nullable final BiConsumer<InventoryClickEvent, Slot> onShiftRightClick,
|
|
||||||
@Nullable final BiConsumer<InventoryClickEvent, Slot> onMiddleClick) {
|
|
||||||
this.provider = provider;
|
|
||||||
this.onLeftClick = onLeftClick == null ? ((event, slot) -> {
|
|
||||||
}) : onLeftClick;
|
|
||||||
this.onRightClick = onRightClick == null ? ((event, slot) -> {
|
|
||||||
}) : onRightClick;
|
|
||||||
this.onShiftLeftClick = onShiftLeftClick == null ? ((event, slot) -> {
|
|
||||||
}) : onShiftLeftClick;
|
|
||||||
this.onShiftRightClick = onShiftRightClick == null ? ((event, slot) -> {
|
|
||||||
}) : onShiftRightClick;
|
|
||||||
this.onMiddleClick = onMiddleClick == null ? ((event, slot) -> {
|
|
||||||
}) : onMiddleClick;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleInventoryClick(@NotNull final InventoryClickEvent event) {
|
|
||||||
switch (event.getClick()) {
|
|
||||||
case LEFT -> this.onLeftClick.accept(event, this);
|
|
||||||
case RIGHT -> this.onRightClick.accept(event, this);
|
|
||||||
case SHIFT_LEFT -> this.onShiftLeftClick.accept(event, this);
|
|
||||||
case SHIFT_RIGHT -> this.onShiftRightClick.accept(event, this);
|
|
||||||
case MIDDLE -> this.onMiddleClick.accept(event, this);
|
|
||||||
default -> {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemStack getItemStack(@NotNull final Player player) {
|
|
||||||
return provider.apply(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
package com.willfp.eco.internal.gui.slot;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.gui.slot.Slot;
|
|
||||||
import com.willfp.eco.core.gui.slot.SlotBuilder;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
public class EcoSlotBuilder implements SlotBuilder {
|
|
||||||
private final Function<Player, ItemStack> provider;
|
|
||||||
|
|
||||||
private BiConsumer<InventoryClickEvent, Slot> onLeftClick = null;
|
|
||||||
|
|
||||||
private BiConsumer<InventoryClickEvent, Slot> onRightClick = null;
|
|
||||||
|
|
||||||
private BiConsumer<InventoryClickEvent, Slot> onShiftLeftClick = null;
|
|
||||||
|
|
||||||
private BiConsumer<InventoryClickEvent, Slot> onShiftRightClick = null;
|
|
||||||
|
|
||||||
private BiConsumer<InventoryClickEvent, Slot> onMiddleClick = null;
|
|
||||||
|
|
||||||
public EcoSlotBuilder(@NotNull final Function<Player, ItemStack> provider) {
|
|
||||||
this.provider = provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SlotBuilder onLeftClick(@NotNull final BiConsumer<InventoryClickEvent, Slot> action) {
|
|
||||||
this.onLeftClick = action;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SlotBuilder onRightClick(@NotNull final BiConsumer<InventoryClickEvent, Slot> action) {
|
|
||||||
this.onRightClick = action;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SlotBuilder onShiftLeftClick(@NotNull final BiConsumer<InventoryClickEvent, Slot> action) {
|
|
||||||
this.onShiftLeftClick = action;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SlotBuilder onShiftRightClick(@NotNull final BiConsumer<InventoryClickEvent, Slot> action) {
|
|
||||||
this.onShiftRightClick = action;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SlotBuilder onMiddleClick(@NotNull final BiConsumer<InventoryClickEvent, Slot> action) {
|
|
||||||
this.onMiddleClick = action;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Slot build() {
|
|
||||||
return new EcoSlot(provider, onLeftClick, onRightClick, onShiftLeftClick, onShiftRightClick, onMiddleClick);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
package com.willfp.eco.internal.integrations;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration;
|
|
||||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPI;
|
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
public class PlaceholderIntegrationPAPI extends PlaceholderExpansion implements PlaceholderIntegration {
|
|
||||||
private final EcoPlugin plugin;
|
|
||||||
|
|
||||||
public PlaceholderIntegrationPAPI(@NotNull final EcoPlugin plugin) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean persist() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canRegister() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull String getAuthor() {
|
|
||||||
return String.join(", ", plugin.getDescription().getAuthors());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull String getIdentifier() {
|
|
||||||
return plugin.getDescription().getName().toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull String getVersion() {
|
|
||||||
return plugin.getDescription().getVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String onPlaceholderRequest(@Nullable final Player player,
|
|
||||||
@NotNull final String identifier) {
|
|
||||||
return PlaceholderManager.getResult(player, identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void registerIntegration() {
|
|
||||||
this.register();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getPluginName() {
|
|
||||||
return "PlaceholderAPI";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String translate(@NotNull final String text,
|
|
||||||
@Nullable final Player player) {
|
|
||||||
return PlaceholderAPI.setPlaceholders(player, text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
package com.willfp.eco.internal.logging;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.util.StringUtils;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
public class EcoLogger extends Logger {
|
|
||||||
public EcoLogger(@NotNull final EcoPlugin plugin) {
|
|
||||||
super(plugin.getName(), (String) null);
|
|
||||||
String prefix = plugin.getDescription().getPrefix();
|
|
||||||
this.setParent(plugin.getServer().getLogger());
|
|
||||||
this.setLevel(Level.ALL);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void info(@NotNull final String msg) {
|
|
||||||
super.info(StringUtils.format(msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void warning(@NotNull final String msg) {
|
|
||||||
super.warning(StringUtils.format(msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void severe(@NotNull final String msg) {
|
|
||||||
super.severe(StringUtils.format(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
package com.willfp.eco.internal.proxy;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.PluginDependent;
|
|
||||||
import com.willfp.eco.core.proxy.AbstractProxy;
|
|
||||||
import com.willfp.eco.core.proxy.ProxyConstants;
|
|
||||||
import com.willfp.eco.core.proxy.ProxyFactory;
|
|
||||||
import com.willfp.eco.core.proxy.exceptions.ProxyError;
|
|
||||||
import com.willfp.eco.core.proxy.exceptions.UnsupportedVersionException;
|
|
||||||
import org.apache.commons.lang.Validate;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URLClassLoader;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.IdentityHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class EcoProxyFactory extends PluginDependent<EcoPlugin> implements ProxyFactory {
|
|
||||||
private static final List<String> SUPPORTED_VERSIONS = Arrays.asList(
|
|
||||||
"v1_16_R3",
|
|
||||||
"v1_17_R1"
|
|
||||||
);
|
|
||||||
|
|
||||||
private final ClassLoader proxyClassLoader;
|
|
||||||
|
|
||||||
private final Map<Class<? extends AbstractProxy>, AbstractProxy> cache = new IdentityHashMap<>();
|
|
||||||
|
|
||||||
public EcoProxyFactory(@NotNull final EcoPlugin plugin) {
|
|
||||||
super(plugin);
|
|
||||||
|
|
||||||
Validate.isTrue(
|
|
||||||
!plugin.getProxyPackage().equalsIgnoreCase(""),
|
|
||||||
"Specified plugin has no proxy support!"
|
|
||||||
);
|
|
||||||
|
|
||||||
this.proxyClassLoader = plugin.getClass().getClassLoader();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T extends AbstractProxy> @NotNull T getProxy(@NotNull final Class<T> proxyClass) {
|
|
||||||
try {
|
|
||||||
T cachedProxy = attemptCache(proxyClass);
|
|
||||||
if (cachedProxy != null) {
|
|
||||||
return cachedProxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
String className = this.getPlugin().getProxyPackage() + "." + ProxyConstants.NMS_VERSION + "." + proxyClass.getSimpleName().replace("Proxy", "");
|
|
||||||
Class<?> clazz = this.getPlugin().getClass().getClassLoader().loadClass(className);
|
|
||||||
Object instance = clazz.getDeclaredConstructor().newInstance();
|
|
||||||
if (proxyClass.isAssignableFrom(clazz) && proxyClass.isInstance(instance)) {
|
|
||||||
T proxy = proxyClass.cast(instance);
|
|
||||||
cache.put(proxyClass, proxy);
|
|
||||||
return proxy;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
throwError(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
throwError(new IllegalArgumentException());
|
|
||||||
|
|
||||||
throw new RuntimeException("Something went wrong.");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void throwError(@Nullable final Exception e) {
|
|
||||||
if (e != null) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SUPPORTED_VERSIONS.contains(ProxyConstants.NMS_VERSION)) {
|
|
||||||
throw new UnsupportedVersionException("You're running an unsupported server version: " + ProxyConstants.NMS_VERSION);
|
|
||||||
} else {
|
|
||||||
throw new ProxyError("Error with proxies - here's a stacktrace. Only god can help you now.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T extends AbstractProxy> T attemptCache(@NotNull final Class<T> proxyClass) {
|
|
||||||
Object proxy = cache.get(proxyClass);
|
|
||||||
if (proxy == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (proxyClass.isInstance(proxy)) {
|
|
||||||
return proxyClass.cast(proxy);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clean() {
|
|
||||||
try {
|
|
||||||
if (proxyClassLoader instanceof URLClassLoader urlClassLoader) {
|
|
||||||
urlClassLoader.close();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
cache.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
package com.willfp.eco.internal.scheduling;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.scheduling.RunnableTask;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public abstract class EcoRunnableTask extends BukkitRunnable implements RunnableTask {
|
|
||||||
private final EcoPlugin plugin;
|
|
||||||
|
|
||||||
@ApiStatus.Internal
|
|
||||||
public EcoRunnableTask(@NotNull final EcoPlugin plugin) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final EcoPlugin getPlugin() {
|
|
||||||
return this.plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public final synchronized BukkitTask runTask() {
|
|
||||||
return super.runTask(plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public final synchronized BukkitTask runTaskAsynchronously() {
|
|
||||||
return super.runTaskAsynchronously(plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public final synchronized BukkitTask runTaskLater(final long delay) {
|
|
||||||
return super.runTaskLater(plugin, delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public final synchronized BukkitTask runTaskLaterAsynchronously(final long delay) {
|
|
||||||
return super.runTaskLaterAsynchronously(plugin, delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public final synchronized BukkitTask runTaskTimer(final long delay, final long period) {
|
|
||||||
return super.runTaskTimer(plugin, delay, period);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public final synchronized BukkitTask runTaskTimerAsynchronously(final long delay, final long period) {
|
|
||||||
return super.runTaskTimerAsynchronously(plugin, delay, period);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
package com.willfp.eco.internal.scheduling;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.PluginDependent;
|
|
||||||
import com.willfp.eco.core.scheduling.Scheduler;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class EcoScheduler extends PluginDependent<EcoPlugin> implements Scheduler {
|
|
||||||
@ApiStatus.Internal
|
|
||||||
public EcoScheduler(@NotNull final EcoPlugin plugin) {
|
|
||||||
super(plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BukkitTask runLater(@NotNull final Runnable runnable,
|
|
||||||
final long ticksLater) {
|
|
||||||
return Bukkit.getScheduler().runTaskLater(this.getPlugin(), runnable, ticksLater);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BukkitTask runTimer(@NotNull final Runnable runnable,
|
|
||||||
final long delay,
|
|
||||||
final long repeat) {
|
|
||||||
return Bukkit.getScheduler().runTaskTimer(this.getPlugin(), runnable, delay, repeat);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BukkitTask runAsyncTimer(@NotNull final Runnable runnable,
|
|
||||||
final long delay,
|
|
||||||
final long repeat) {
|
|
||||||
return Bukkit.getScheduler().runTaskTimerAsynchronously(this.getPlugin(), runnable, delay, repeat);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BukkitTask run(@NotNull final Runnable runnable) {
|
|
||||||
return Bukkit.getScheduler().runTask(this.getPlugin(), runnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BukkitTask runAsync(@NotNull final Runnable runnable) {
|
|
||||||
return Bukkit.getScheduler().runTaskAsynchronously(this.getPlugin(), runnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int syncRepeating(@NotNull final Runnable runnable,
|
|
||||||
final long delay,
|
|
||||||
final long repeat) {
|
|
||||||
return Bukkit.getScheduler().scheduleSyncRepeatingTask(this.getPlugin(), runnable, delay, repeat);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cancelAll() {
|
|
||||||
Bukkit.getScheduler().cancelTasks(this.getPlugin());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package com.willfp.eco.internal
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.items.Items
|
||||||
|
import com.willfp.eco.core.proxy.Cleaner
|
||||||
|
import com.willfp.eco.internal.proxy.EcoProxyFactory
|
||||||
|
import java.net.URLClassLoader
|
||||||
|
|
||||||
|
class EcoCleaner: Cleaner {
|
||||||
|
override fun clean(plugin: EcoPlugin) {
|
||||||
|
if (plugin.proxyPackage.isNotEmpty()) {
|
||||||
|
val factory = plugin.proxyFactory as EcoProxyFactory
|
||||||
|
factory.clean()
|
||||||
|
}
|
||||||
|
|
||||||
|
Plugins.LOADED_ECO_PLUGINS.remove(plugin.name.lowercase())
|
||||||
|
|
||||||
|
for (customItem in Items.getCustomItems()) {
|
||||||
|
if (customItem.key.namespace.equals(plugin.name.lowercase(), ignoreCase = true)) {
|
||||||
|
Items.removeCustomItem(customItem.key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val classLoader = plugin::class.java.classLoader
|
||||||
|
|
||||||
|
if (classLoader is URLClassLoader) {
|
||||||
|
classLoader.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
System.gc()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.willfp.eco.internal
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
|
||||||
|
object Plugins {
|
||||||
|
val LOADED_ECO_PLUGINS = HashMap<String, EcoPlugin>()
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package com.willfp.eco.internal.config
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config
|
||||||
|
import com.willfp.eco.core.config.interfaces.JSONConfig
|
||||||
|
import com.willfp.eco.core.config.wrapper.ConfigFactory
|
||||||
|
import com.willfp.eco.internal.config.json.EcoJSONConfigSection
|
||||||
|
import com.willfp.eco.internal.config.json.EcoLoadableJSONConfig
|
||||||
|
import com.willfp.eco.internal.config.yaml.EcoLoadableYamlConfig
|
||||||
|
import com.willfp.eco.internal.config.yaml.EcoUpdatableYamlConfig
|
||||||
|
import com.willfp.eco.internal.config.yaml.EcoYamlConfigSection
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration
|
||||||
|
|
||||||
|
class EcoConfigFactory : ConfigFactory {
|
||||||
|
override fun createUpdatableYamlConfig(
|
||||||
|
configName: String,
|
||||||
|
plugin: EcoPlugin,
|
||||||
|
subDirectoryPath: String,
|
||||||
|
source: Class<*>,
|
||||||
|
removeUnused: Boolean,
|
||||||
|
vararg updateBlacklist: String
|
||||||
|
): Config {
|
||||||
|
return EcoUpdatableYamlConfig(
|
||||||
|
configName,
|
||||||
|
plugin,
|
||||||
|
subDirectoryPath,
|
||||||
|
source,
|
||||||
|
removeUnused,
|
||||||
|
*updateBlacklist
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createLoadableJSONConfig(
|
||||||
|
configName: String,
|
||||||
|
plugin: EcoPlugin,
|
||||||
|
subDirectoryPath: String,
|
||||||
|
source: Class<*>
|
||||||
|
): JSONConfig {
|
||||||
|
return EcoLoadableJSONConfig(
|
||||||
|
configName,
|
||||||
|
plugin,
|
||||||
|
subDirectoryPath,
|
||||||
|
source
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createLoadableYamlConfig(
|
||||||
|
configName: String,
|
||||||
|
plugin: EcoPlugin,
|
||||||
|
subDirectoryPath: String,
|
||||||
|
source: Class<*>
|
||||||
|
): Config {
|
||||||
|
return EcoLoadableYamlConfig(
|
||||||
|
configName,
|
||||||
|
plugin,
|
||||||
|
subDirectoryPath,
|
||||||
|
source
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createYamlConfig(config: YamlConfiguration): Config {
|
||||||
|
return EcoYamlConfigSection(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createJSONConfig(values: Map<String, Any>): JSONConfig {
|
||||||
|
return EcoJSONConfigSection(values)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.willfp.eco.internal.config.json
|
||||||
|
|
||||||
|
class EcoJSONConfigSection(values: Map<String, Any?>) : EcoJSONConfigWrapper() {
|
||||||
|
init {
|
||||||
|
init(values)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,299 @@
|
|||||||
|
package com.willfp.eco.internal.config.json
|
||||||
|
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.google.gson.GsonBuilder
|
||||||
|
import com.willfp.eco.core.config.interfaces.JSONConfig
|
||||||
|
import com.willfp.eco.util.StringUtils
|
||||||
|
import org.apache.commons.lang.Validate
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
open class EcoJSONConfigWrapper : JSONConfig {
|
||||||
|
val handle: Gson = GsonBuilder().setPrettyPrinting().create()
|
||||||
|
|
||||||
|
val values: MutableMap<String, Any?> = HashMap()
|
||||||
|
|
||||||
|
private val cache: MutableMap<String, Any> = HashMap()
|
||||||
|
|
||||||
|
fun init(values: Map<String, Any?>) {
|
||||||
|
this.values.clear()
|
||||||
|
this.values.putAll(values)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun clearCache() {
|
||||||
|
cache.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toPlaintext(): String {
|
||||||
|
return this.handle.toJson(this.values)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun has(path: String): Boolean {
|
||||||
|
return getOfKnownType(path, Any::class.java) != null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T: Any?> getOfKnownType(
|
||||||
|
path: String,
|
||||||
|
clazz: Class<T>
|
||||||
|
): T? {
|
||||||
|
return getOfKnownType(path, clazz, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun <T> getOfKnownType(
|
||||||
|
path: String,
|
||||||
|
clazz: Class<T>,
|
||||||
|
isBase: Boolean
|
||||||
|
): T? {
|
||||||
|
var closestPath = path
|
||||||
|
if (cache.containsKey(path) && isBase) {
|
||||||
|
return cache[path] as T?
|
||||||
|
}
|
||||||
|
if (path.contains(".")) {
|
||||||
|
val split = path.split("\\.".toRegex()).toTypedArray()
|
||||||
|
closestPath = split[0]
|
||||||
|
}
|
||||||
|
return if (values[closestPath] is Map<*, *> && path != closestPath) {
|
||||||
|
val section =
|
||||||
|
EcoJSONConfigSection((values[closestPath] as Map<String, Any?>?)!!)
|
||||||
|
section.getOfKnownType(path.substring(closestPath.length + 1), clazz, false)
|
||||||
|
} else {
|
||||||
|
if (values.containsKey(closestPath)) {
|
||||||
|
values[closestPath] as T?
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getKeys(deep: Boolean): List<String> {
|
||||||
|
return if (deep) {
|
||||||
|
ArrayList(getDeepKeys(HashSet(), ""))
|
||||||
|
} else {
|
||||||
|
ArrayList(values.keys)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun getDeepKeys(
|
||||||
|
list: MutableSet<String>,
|
||||||
|
root: String
|
||||||
|
): Set<String> {
|
||||||
|
for (key in values.keys) {
|
||||||
|
list.add(root + key)
|
||||||
|
if (values[key] is Map<*, *>) {
|
||||||
|
val section = EcoJSONConfigSection((values[key] as Map<String, Any?>?)!!)
|
||||||
|
list.addAll(section.getDeepKeys(list, "$root$key."))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun get(path: String): Any? {
|
||||||
|
return getOfKnownType(path, Any::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun set(
|
||||||
|
path: String,
|
||||||
|
`object`: Any?
|
||||||
|
) {
|
||||||
|
setRecursively(path, `object`)
|
||||||
|
clearCache()
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun setRecursively(
|
||||||
|
path: String,
|
||||||
|
obj: Any?
|
||||||
|
) {
|
||||||
|
var closestPath = path
|
||||||
|
if (path.contains(".")) {
|
||||||
|
val split = path.split("\\.".toRegex()).toTypedArray()
|
||||||
|
closestPath = split[0]
|
||||||
|
}
|
||||||
|
if (values[closestPath] is Map<*, *> && path != closestPath) {
|
||||||
|
val section = EcoJSONConfigSection((values[closestPath] as Map<String, Any?>?)!!)
|
||||||
|
section.setRecursively(path.substring(closestPath.length + 1), obj)
|
||||||
|
values[closestPath] = section.values
|
||||||
|
} else {
|
||||||
|
var ob = obj
|
||||||
|
if (ob is JSONConfig) {
|
||||||
|
ob = (obj as EcoJSONConfigWrapper).values
|
||||||
|
}
|
||||||
|
values[path] = ob
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSubsection(path: String): JSONConfig {
|
||||||
|
val subsection = getSubsectionOrNull(path)
|
||||||
|
Validate.notNull(subsection)
|
||||||
|
return subsection!!
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSubsectionOrNull(path: String): JSONConfig? {
|
||||||
|
return if (values.containsKey(path)) {
|
||||||
|
val subsection = values[path] as Map<String, Any>?
|
||||||
|
EcoJSONConfigSection(subsection!!)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSubsections(path: String): List<JSONConfig> {
|
||||||
|
val subsections = getSubsectionsOrNull(path)
|
||||||
|
return subsections ?: ArrayList()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSubsectionsOrNull(path: String): List<JSONConfig>? {
|
||||||
|
val maps = getOfKnownType(path, Any::class.java) as List<Map<String, Any>>?
|
||||||
|
?: return null
|
||||||
|
val configs: MutableList<JSONConfig> = ArrayList()
|
||||||
|
for (map in maps) {
|
||||||
|
configs.add(EcoJSONConfigSection(map))
|
||||||
|
}
|
||||||
|
return configs
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getInt(path: String): Int {
|
||||||
|
return (getOfKnownType(path, Double::class.java) ?: 0.0).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getIntOrNull(path: String): Int? {
|
||||||
|
return if (has(path)) {
|
||||||
|
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): List<Int> {
|
||||||
|
return Objects.requireNonNullElse(getOfKnownType(path, Any::class.java), ArrayList<Any>()) as List<Int>
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getIntsOrNull(path: String): List<Int>? {
|
||||||
|
return if (has(path)) {
|
||||||
|
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? {
|
||||||
|
return if (has(path)) {
|
||||||
|
getBool(path)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getBools(path: String): List<Boolean> {
|
||||||
|
return Objects.requireNonNullElse(getOfKnownType(path, Any::class.java), ArrayList<Any>()) as List<Boolean>
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getBoolsOrNull(path: String): List<Boolean>? {
|
||||||
|
return if (has(path)) {
|
||||||
|
getBools(path)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getString(path: String): String {
|
||||||
|
return getString(path, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getString(
|
||||||
|
path: String,
|
||||||
|
format: Boolean
|
||||||
|
): String {
|
||||||
|
val string = getOfKnownType(path, String::class.java) ?: ""
|
||||||
|
return if (format) StringUtils.format(string) else string
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStringOrNull(path: String): String? {
|
||||||
|
return if (has(path)) {
|
||||||
|
getString(path)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStringOrNull(
|
||||||
|
path: String,
|
||||||
|
format: Boolean
|
||||||
|
): String? {
|
||||||
|
return if (has(path)) {
|
||||||
|
getString(path, format)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStrings(path: String): List<String> {
|
||||||
|
return getStrings(path, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStrings(
|
||||||
|
path: String,
|
||||||
|
format: Boolean
|
||||||
|
): List<String> {
|
||||||
|
val strings =
|
||||||
|
Objects.requireNonNullElse(getOfKnownType(path, Any::class.java), ArrayList<Any>()) as List<String>
|
||||||
|
return if (format) StringUtils.formatList(strings) else strings
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStringsOrNull(path: String): List<String>? {
|
||||||
|
return if (has(path)) {
|
||||||
|
getStrings(path)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStringsOrNull(
|
||||||
|
path: String,
|
||||||
|
format: Boolean
|
||||||
|
): List<String>? {
|
||||||
|
return if (has(path)) {
|
||||||
|
getStrings(path, format)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDouble(path: String): Double {
|
||||||
|
return Objects.requireNonNullElse(getOfKnownType(path, Double::class.java), 0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDoubleOrNull(path: String): Double? {
|
||||||
|
return if (has(path)) {
|
||||||
|
getDouble(path)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDoubles(path: String): List<Double> {
|
||||||
|
return Objects.requireNonNullElse(getOfKnownType(path, Any::class.java), ArrayList<Any>()) as List<Double>
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDoublesOrNull(path: String): List<Double>? {
|
||||||
|
return if (has(path)) {
|
||||||
|
getDoubles(path)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun clone(): JSONConfig {
|
||||||
|
return EcoJSONConfigSection(HashMap<String, Any>(this.values))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
package com.willfp.eco.internal.config.json
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.config.interfaces.LoadableConfig
|
||||||
|
import org.jetbrains.annotations.NotNull
|
||||||
|
import java.io.*
|
||||||
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.StandardOpenOption
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
class EcoLoadableJSONConfig(
|
||||||
|
configName: String,
|
||||||
|
private val plugin: EcoPlugin,
|
||||||
|
private val subDirectoryPath: String,
|
||||||
|
private val source: Class<*>
|
||||||
|
) : EcoJSONConfigWrapper(), LoadableConfig {
|
||||||
|
|
||||||
|
private val configFile: File
|
||||||
|
private val name: String = "$configName.json"
|
||||||
|
|
||||||
|
fun reloadFromFile() {
|
||||||
|
try {
|
||||||
|
init(configFile)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createFile() {
|
||||||
|
val resourcePath = resourcePath
|
||||||
|
val inputStream = source.getResourceAsStream(resourcePath)!!
|
||||||
|
val outFile = File(this.plugin.dataFolder, resourcePath)
|
||||||
|
val lastIndex = resourcePath.lastIndexOf('/')
|
||||||
|
val outDir = File(this.plugin.dataFolder, resourcePath.substring(0, lastIndex.coerceAtLeast(0)))
|
||||||
|
if (!outDir.exists()) {
|
||||||
|
outDir.mkdirs()
|
||||||
|
}
|
||||||
|
if (!outFile.exists()) {
|
||||||
|
val out: OutputStream = FileOutputStream(outFile)
|
||||||
|
val buf = ByteArray(1024)
|
||||||
|
var len: Int
|
||||||
|
while (inputStream.read(buf).also { len = it } > 0) {
|
||||||
|
out.write(buf, 0, len)
|
||||||
|
}
|
||||||
|
out.close()
|
||||||
|
inputStream.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getResourcePath(): String {
|
||||||
|
val resourcePath: String = if (subDirectoryPath.isEmpty()) {
|
||||||
|
name
|
||||||
|
} else {
|
||||||
|
subDirectoryPath + name
|
||||||
|
}
|
||||||
|
return "/$resourcePath"
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun save() {
|
||||||
|
if (configFile.delete()) {
|
||||||
|
Files.write(
|
||||||
|
configFile.toPath(),
|
||||||
|
toPlaintext().toByteArray(),
|
||||||
|
StandardOpenOption.CREATE,
|
||||||
|
StandardOpenOption.WRITE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(FileNotFoundException::class)
|
||||||
|
fun init(file: File) {
|
||||||
|
super.init(handle.fromJson(FileReader(file), Map::class.java) as @NotNull MutableMap<String, Any>)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getName(): String {
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getConfigFile(): File {
|
||||||
|
return configFile
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
val directory: File = File(this.plugin.dataFolder, subDirectoryPath)
|
||||||
|
if (!directory.exists()) {
|
||||||
|
directory.mkdirs()
|
||||||
|
}
|
||||||
|
if (!File(directory, name).exists()) {
|
||||||
|
createFile()
|
||||||
|
}
|
||||||
|
configFile = File(directory, name)
|
||||||
|
try {
|
||||||
|
init(configFile)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
plugin.configHandler.addConfig(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package com.willfp.eco.internal.config.updating
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.PluginDependent
|
||||||
|
import com.willfp.eco.core.config.interfaces.LoadableConfig
|
||||||
|
import com.willfp.eco.core.config.updating.ConfigHandler
|
||||||
|
import com.willfp.eco.core.config.updating.ConfigUpdater
|
||||||
|
import com.willfp.eco.internal.config.json.EcoLoadableJSONConfig
|
||||||
|
import com.willfp.eco.internal.config.updating.exceptions.InvalidUpdateMethodException
|
||||||
|
import com.willfp.eco.internal.config.yaml.EcoLoadableYamlConfig
|
||||||
|
import com.willfp.eco.internal.config.yaml.EcoUpdatableYamlConfig
|
||||||
|
import org.reflections.Reflections
|
||||||
|
import org.reflections.scanners.MethodAnnotationsScanner
|
||||||
|
import java.lang.reflect.Modifier
|
||||||
|
|
||||||
|
class EcoConfigHandler(
|
||||||
|
plugin: EcoPlugin
|
||||||
|
) : PluginDependent<EcoPlugin>(plugin), ConfigHandler {
|
||||||
|
private val reflections: Reflections = Reflections(
|
||||||
|
this.plugin::class.java.classLoader,
|
||||||
|
MethodAnnotationsScanner()
|
||||||
|
)
|
||||||
|
|
||||||
|
private val configs: MutableList<LoadableConfig> = ArrayList()
|
||||||
|
|
||||||
|
override fun callUpdate() {
|
||||||
|
for (method in reflections.getMethodsAnnotatedWith(ConfigUpdater::class.java)) {
|
||||||
|
if (!Modifier.isStatic(method.modifiers)) {
|
||||||
|
throw InvalidUpdateMethodException("Update method in ${method.declaringClass.name} must be static.")
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
when (method.parameterCount) {
|
||||||
|
0 -> method.invoke(null)
|
||||||
|
1 -> method.invoke(null, this.plugin)
|
||||||
|
else -> throw InvalidUpdateMethodException("Update method must have 0 parameters or a plugin parameter.")
|
||||||
|
}
|
||||||
|
} catch (e: ReflectiveOperationException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
throw InvalidUpdateMethodException("Update method generated an exception")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun saveAllConfigs() {
|
||||||
|
for (config in configs) {
|
||||||
|
config.save()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addConfig(config: LoadableConfig) {
|
||||||
|
configs.add(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateConfigs() {
|
||||||
|
for (config in configs) {
|
||||||
|
when (config) {
|
||||||
|
is EcoUpdatableYamlConfig -> config.update()
|
||||||
|
is EcoLoadableYamlConfig -> config.reloadFromFile()
|
||||||
|
is EcoLoadableJSONConfig -> config.reloadFromFile()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package com.willfp.eco.internal.config.updating.exceptions
|
||||||
|
|
||||||
|
class InvalidUpdateMethodException(message: String) : RuntimeException(message)
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
package com.willfp.eco.internal.config.yaml
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.config.interfaces.LoadableConfig
|
||||||
|
import com.willfp.eco.core.config.interfaces.WrappedYamlConfiguration
|
||||||
|
import org.bukkit.configuration.InvalidConfigurationException
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileOutputStream
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.OutputStream
|
||||||
|
|
||||||
|
open class EcoLoadableYamlConfig(
|
||||||
|
configName: String,
|
||||||
|
private val plugin: EcoPlugin,
|
||||||
|
private val subDirectoryPath: String,
|
||||||
|
val source: Class<*>
|
||||||
|
) : EcoYamlConfigWrapper<YamlConfiguration>(), WrappedYamlConfiguration, LoadableConfig {
|
||||||
|
|
||||||
|
private val configFile: File
|
||||||
|
private val name: String = "$configName.yml"
|
||||||
|
|
||||||
|
fun reloadFromFile() {
|
||||||
|
try {
|
||||||
|
handle.load(getConfigFile())
|
||||||
|
} catch (e: IOException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
} catch (e: InvalidConfigurationException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final override fun createFile() {
|
||||||
|
val resourcePath = resourcePath
|
||||||
|
val inputStream = source.getResourceAsStream(resourcePath)!!
|
||||||
|
val outFile = File(this.plugin.dataFolder, resourcePath)
|
||||||
|
val lastIndex = resourcePath.lastIndexOf('/')
|
||||||
|
val outDir = File(this.plugin.dataFolder, resourcePath.substring(0, lastIndex.coerceAtLeast(0)))
|
||||||
|
if (!outDir.exists()) {
|
||||||
|
outDir.mkdirs()
|
||||||
|
}
|
||||||
|
if (!outFile.exists()) {
|
||||||
|
val out: OutputStream = FileOutputStream(outFile)
|
||||||
|
val buf = ByteArray(1024)
|
||||||
|
var len: Int
|
||||||
|
while (inputStream.read(buf).also { len = it } > 0) {
|
||||||
|
out.write(buf, 0, len)
|
||||||
|
}
|
||||||
|
out.close()
|
||||||
|
inputStream.close()
|
||||||
|
}
|
||||||
|
plugin.configHandler.addConfig(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getResourcePath(): String {
|
||||||
|
val resourcePath: String = if (subDirectoryPath.isEmpty()) {
|
||||||
|
name
|
||||||
|
} else {
|
||||||
|
subDirectoryPath + name
|
||||||
|
}
|
||||||
|
return "/$resourcePath"
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun save() {
|
||||||
|
handle.save(getConfigFile())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getBukkitHandle(): YamlConfiguration {
|
||||||
|
return handle
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getName(): String {
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getConfigFile(): File {
|
||||||
|
return configFile
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
val directory = File(this.plugin.dataFolder, subDirectoryPath)
|
||||||
|
if (!directory.exists()) {
|
||||||
|
directory.mkdirs()
|
||||||
|
}
|
||||||
|
if (!File(directory, name).exists()) {
|
||||||
|
createFile()
|
||||||
|
}
|
||||||
|
configFile = File(directory, name)
|
||||||
|
this.plugin.configHandler.addConfig(this)
|
||||||
|
init(YamlConfiguration.loadConfiguration(configFile))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package com.willfp.eco.internal.config.yaml
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import org.bukkit.configuration.InvalidConfigurationException
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration
|
||||||
|
import java.io.BufferedReader
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.InputStreamReader
|
||||||
|
import java.nio.charset.StandardCharsets
|
||||||
|
|
||||||
|
class EcoUpdatableYamlConfig(
|
||||||
|
configName: String,
|
||||||
|
plugin: EcoPlugin,
|
||||||
|
subDirectoryPath: String,
|
||||||
|
source: Class<*>,
|
||||||
|
private val removeUnused: Boolean,
|
||||||
|
vararg updateBlacklist: String
|
||||||
|
) : EcoLoadableYamlConfig(configName, plugin, subDirectoryPath, source) {
|
||||||
|
|
||||||
|
private val updateBlacklist: MutableList<String> = mutableListOf(*updateBlacklist)
|
||||||
|
|
||||||
|
fun update() {
|
||||||
|
super.clearCache()
|
||||||
|
try {
|
||||||
|
this.handle.load(configFile)
|
||||||
|
val newConfig = configInJar
|
||||||
|
if (newConfig.getKeys(true) == this.handle.getKeys(true)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
newConfig.getKeys(true).forEach { key: String ->
|
||||||
|
if (!this.handle.getKeys(true).contains(key)) {
|
||||||
|
if (updateBlacklist.stream().noneMatch { s: String -> key.contains(s) }) {
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val configInJar: YamlConfiguration
|
||||||
|
get() {
|
||||||
|
val newIn = source.getResourceAsStream(resourcePath) ?: throw NullPointerException("$name is null?")
|
||||||
|
val reader = BufferedReader(InputStreamReader(newIn, StandardCharsets.UTF_8))
|
||||||
|
val newConfig = YamlConfiguration()
|
||||||
|
try {
|
||||||
|
newConfig.load(reader)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
} catch (e: InvalidConfigurationException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
return newConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
this.updateBlacklist.removeIf { obj: String -> obj.isEmpty() }
|
||||||
|
plugin.configHandler.addConfig(this)
|
||||||
|
update()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.willfp.eco.internal.config.yaml
|
||||||
|
|
||||||
|
import org.bukkit.configuration.ConfigurationSection
|
||||||
|
|
||||||
|
class EcoYamlConfigSection(section: ConfigurationSection) : EcoYamlConfigWrapper<ConfigurationSection>() {
|
||||||
|
init {
|
||||||
|
init(section)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,286 @@
|
|||||||
|
package com.willfp.eco.internal.config.yaml
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config
|
||||||
|
import com.willfp.eco.util.StringUtils
|
||||||
|
import org.apache.commons.lang.Validate
|
||||||
|
import org.bukkit.configuration.ConfigurationSection
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration
|
||||||
|
import java.io.StringReader
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
open class EcoYamlConfigWrapper<T : ConfigurationSection> : Config {
|
||||||
|
lateinit var handle: T
|
||||||
|
private val cache: MutableMap<String, Any?> = HashMap()
|
||||||
|
|
||||||
|
protected fun init(config: T): Config {
|
||||||
|
handle = config
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toPlaintext(): String {
|
||||||
|
val temp = YamlConfiguration()
|
||||||
|
for (key in handle.getKeys(true)) {
|
||||||
|
temp[key] = handle[key]
|
||||||
|
}
|
||||||
|
return temp.saveToString()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun clearCache() {
|
||||||
|
cache.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun has(path: String): Boolean {
|
||||||
|
return handle.contains(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getKeys(deep: Boolean): List<String> {
|
||||||
|
return ArrayList(handle.getKeys(deep))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun get(path: String): Any? {
|
||||||
|
return handle[path]
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun set(
|
||||||
|
path: String,
|
||||||
|
obj: Any?
|
||||||
|
) {
|
||||||
|
cache.remove(path)
|
||||||
|
handle[path] = obj
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSubsection(path: String): Config {
|
||||||
|
val subsection = getSubsectionOrNull(path)
|
||||||
|
Validate.notNull(subsection)
|
||||||
|
return subsection!!
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSubsectionOrNull(path: String): Config? {
|
||||||
|
return if (cache.containsKey(path)) {
|
||||||
|
cache[path] as Config?
|
||||||
|
} else {
|
||||||
|
val raw = handle.getConfigurationSection(path)
|
||||||
|
if (raw == null) {
|
||||||
|
cache[path] = null
|
||||||
|
} else {
|
||||||
|
cache[path] = EcoYamlConfigSection(raw)
|
||||||
|
}
|
||||||
|
getSubsectionOrNull(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getInt(path: String): Int {
|
||||||
|
return if (cache.containsKey(path)) {
|
||||||
|
cache[path] as Int
|
||||||
|
} else {
|
||||||
|
cache[path] = handle.getInt(path, 0)
|
||||||
|
getInt(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
cache[path] as Int
|
||||||
|
} else {
|
||||||
|
cache[path] = handle.getInt(path, def)
|
||||||
|
getInt(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getInts(path: String): List<Int> {
|
||||||
|
return if (cache.containsKey(path)) {
|
||||||
|
cache[path] as List<Int>
|
||||||
|
} else {
|
||||||
|
cache[path] = if (has(path)) ArrayList(handle.getIntegerList(path)) else ArrayList<Any>()
|
||||||
|
getInts(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getIntsOrNull(path: String): List<Int>? {
|
||||||
|
return if (has(path)) {
|
||||||
|
getInts(path)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getBool(path: String): Boolean {
|
||||||
|
return if (cache.containsKey(path)) {
|
||||||
|
cache[path] as Boolean
|
||||||
|
} else {
|
||||||
|
cache[path] = handle.getBoolean(path)
|
||||||
|
getBool(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getBoolOrNull(path: String): Boolean? {
|
||||||
|
return if (has(path)) {
|
||||||
|
getBool(path)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getBools(path: String): List<Boolean> {
|
||||||
|
return if (cache.containsKey(path)) {
|
||||||
|
cache[path] as List<Boolean>
|
||||||
|
} else {
|
||||||
|
cache[path] =
|
||||||
|
if (has(path)) ArrayList(handle.getBooleanList(path)) else ArrayList<Any>()
|
||||||
|
getBools(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getBoolsOrNull(path: String): List<Boolean>? {
|
||||||
|
return if (has(path)) {
|
||||||
|
getBools(path)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getString(path: String): String {
|
||||||
|
return getString(path, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getString(
|
||||||
|
path: String,
|
||||||
|
format: Boolean
|
||||||
|
): String {
|
||||||
|
if (format) {
|
||||||
|
return if (cache.containsKey("$path\$FMT")) {
|
||||||
|
cache["$path\$FMT"] as String
|
||||||
|
} else {
|
||||||
|
val string: String = handle.getString(path, "")!!
|
||||||
|
cache["$path\$FMT"] = StringUtils.format(string)
|
||||||
|
getString(path, format)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return if (cache.containsKey(path)) {
|
||||||
|
cache[path] as String
|
||||||
|
} else {
|
||||||
|
cache[path] = handle.getString(path, "")!!
|
||||||
|
getString(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStringOrNull(path: String): String? {
|
||||||
|
return if (has(path)) {
|
||||||
|
getString(path)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStringOrNull(
|
||||||
|
path: String,
|
||||||
|
format: Boolean
|
||||||
|
): String? {
|
||||||
|
return if (has(path)) {
|
||||||
|
getString(path, format)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStrings(path: String): List<String> {
|
||||||
|
return getStrings(path, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStrings(
|
||||||
|
path: String,
|
||||||
|
format: Boolean
|
||||||
|
): List<String> {
|
||||||
|
if (format) {
|
||||||
|
return if (cache.containsKey("$path\$FMT")) {
|
||||||
|
cache["$path\$FMT"] as List<String>
|
||||||
|
} else {
|
||||||
|
cache["$path\$FMT"] = StringUtils.formatList(if (has(path)) ArrayList(handle.getStringList(path)) else ArrayList<String>())
|
||||||
|
getStrings(path, true)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return if (cache.containsKey(path)) {
|
||||||
|
cache[path] as List<String>
|
||||||
|
} else {
|
||||||
|
cache[path] =
|
||||||
|
if (has(path)) ArrayList(handle.getStringList(path)) else ArrayList<Any>()
|
||||||
|
getStrings(path, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStringsOrNull(path: String): List<String>? {
|
||||||
|
return if (has(path)) {
|
||||||
|
getStrings(path)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStringsOrNull(
|
||||||
|
path: String,
|
||||||
|
format: Boolean
|
||||||
|
): List<String>? {
|
||||||
|
return if (has(path)) {
|
||||||
|
getStrings(path, format)
|
||||||
|
} else {
|
||||||
|
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? {
|
||||||
|
return if (has(path)) {
|
||||||
|
getDouble(path)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDoubles(path: String): List<Double> {
|
||||||
|
return if (cache.containsKey(path)) {
|
||||||
|
cache[path] as List<Double>
|
||||||
|
} else {
|
||||||
|
cache[path] = if (has(path)) ArrayList(handle.getDoubleList(path)) else ArrayList<Any>()
|
||||||
|
getDoubles(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDoublesOrNull(path: String): List<Double>? {
|
||||||
|
return if (has(path)) {
|
||||||
|
getDoubles(path)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun clone(): Config {
|
||||||
|
return EcoYamlConfigSection(
|
||||||
|
YamlConfiguration.loadConfiguration(
|
||||||
|
StringReader(
|
||||||
|
toPlaintext()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.willfp.eco.internal.drops
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
|
||||||
|
object DropManager {
|
||||||
|
var type = DropQueueType.COLLATED
|
||||||
|
|
||||||
|
fun update(plugin: EcoPlugin) {
|
||||||
|
type = if (plugin.configYml.getBool("use-fast-collated-drops")) DropQueueType.COLLATED else DropQueueType.STANDARD
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.willfp.eco.internal.drops
|
||||||
|
|
||||||
|
enum class DropQueueType {
|
||||||
|
STANDARD, COLLATED
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.willfp.eco.internal.drops
|
||||||
|
|
||||||
|
import com.willfp.eco.core.drops.DropQueueFactory
|
||||||
|
import com.willfp.eco.core.drops.InternalDropQueue
|
||||||
|
import com.willfp.eco.internal.drops.impl.EcoDropQueue
|
||||||
|
import com.willfp.eco.internal.drops.impl.EcoFastCollatedDropQueue
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
|
class EcoDropQueueFactory : DropQueueFactory {
|
||||||
|
override fun create(player: Player): InternalDropQueue {
|
||||||
|
return if (DropManager.type == DropQueueType.COLLATED) EcoFastCollatedDropQueue(player) else EcoDropQueue(
|
||||||
|
player
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package com.willfp.eco.internal.drops.impl
|
||||||
|
|
||||||
|
import com.willfp.eco.core.drops.InternalDropQueue
|
||||||
|
import com.willfp.eco.util.TelekinesisUtils
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.Material
|
||||||
|
import org.bukkit.entity.EntityType
|
||||||
|
import org.bukkit.entity.ExperienceOrb
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.player.PlayerExpChangeEvent
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import org.bukkit.util.Vector
|
||||||
|
|
||||||
|
open class EcoDropQueue(player: Player) : InternalDropQueue {
|
||||||
|
val items: MutableList<ItemStack>
|
||||||
|
var xp: Int
|
||||||
|
val player: Player
|
||||||
|
var loc: Location
|
||||||
|
|
||||||
|
private var hasTelekinesis = false
|
||||||
|
override fun addItem(item: ItemStack): InternalDropQueue {
|
||||||
|
items.add(item)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addItems(itemStacks: Collection<ItemStack>): InternalDropQueue {
|
||||||
|
items.addAll(itemStacks)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addXP(amount: Int): InternalDropQueue {
|
||||||
|
xp += amount
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setLocation(location: Location): InternalDropQueue {
|
||||||
|
loc = location
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun forceTelekinesis(): InternalDropQueue {
|
||||||
|
hasTelekinesis = true
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun push() {
|
||||||
|
if (!hasTelekinesis) {
|
||||||
|
hasTelekinesis = TelekinesisUtils.testPlayer(player)
|
||||||
|
}
|
||||||
|
val world = loc.world!!
|
||||||
|
loc = loc.add(0.5, 0.5, 0.5)
|
||||||
|
items.removeIf { itemStack: ItemStack -> itemStack.type == Material.AIR }
|
||||||
|
if (items.isEmpty()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (hasTelekinesis) {
|
||||||
|
val leftover = player.inventory.addItem(*items.toTypedArray())
|
||||||
|
for (drop in leftover.values) {
|
||||||
|
world.dropItem(loc, drop!!).velocity = Vector()
|
||||||
|
}
|
||||||
|
if (xp > 0) {
|
||||||
|
val event = PlayerExpChangeEvent(player, xp)
|
||||||
|
Bukkit.getPluginManager().callEvent(event)
|
||||||
|
val orb =
|
||||||
|
world.spawnEntity(player.location.add(0.0, 0.2, 0.0), EntityType.EXPERIENCE_ORB) as ExperienceOrb
|
||||||
|
orb.velocity = Vector(0, 0, 0)
|
||||||
|
orb.experience = event.amount
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (drop in items) {
|
||||||
|
world.dropItem(loc, drop).velocity = Vector()
|
||||||
|
}
|
||||||
|
if (xp > 0) {
|
||||||
|
val orb = world.spawnEntity(loc, EntityType.EXPERIENCE_ORB) as ExperienceOrb
|
||||||
|
orb.experience = xp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
items = ArrayList()
|
||||||
|
xp = 0
|
||||||
|
this.player = player
|
||||||
|
loc = player.location
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package com.willfp.eco.internal.drops.impl
|
||||||
|
|
||||||
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
|
class EcoFastCollatedDropQueue(player: Player) : EcoDropQueue(player) {
|
||||||
|
override fun push() {
|
||||||
|
val fetched = COLLATED_MAP[player]
|
||||||
|
|
||||||
|
if (fetched == null) {
|
||||||
|
COLLATED_MAP[player] = CollatedDrops(items, loc, xp)
|
||||||
|
} else {
|
||||||
|
fetched.addDrops(items)
|
||||||
|
fetched.location = loc
|
||||||
|
fetched.addXp(xp)
|
||||||
|
|
||||||
|
COLLATED_MAP[player] = fetched
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CollatedDrops(
|
||||||
|
val drops: MutableList<ItemStack>,
|
||||||
|
var location: Location,
|
||||||
|
var xp: Int
|
||||||
|
) {
|
||||||
|
fun addDrops(toAdd: List<ItemStack>): CollatedDrops {
|
||||||
|
drops.addAll(toAdd)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addXp(xp: Int): CollatedDrops {
|
||||||
|
this.xp += xp
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val COLLATED_MAP: MutableMap<Player, CollatedDrops> = ConcurrentHashMap()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.willfp.eco.internal.events
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.PluginDependent
|
||||||
|
import com.willfp.eco.core.events.EventManager
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.event.HandlerList
|
||||||
|
import org.bukkit.event.Listener
|
||||||
|
|
||||||
|
class EcoEventManager constructor(plugin: EcoPlugin) : PluginDependent<EcoPlugin>(plugin), EventManager {
|
||||||
|
override fun registerListener(listener: Listener) {
|
||||||
|
Bukkit.getPluginManager().registerEvents(listener, plugin)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unregisterListener(listener: Listener) {
|
||||||
|
HandlerList.unregisterAll(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unregisterAllListeners() {
|
||||||
|
HandlerList.unregisterAll(plugin)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
package com.willfp.eco.internal.extensions
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.PluginDependent
|
||||||
|
import com.willfp.eco.core.config.yaml.YamlTransientConfig
|
||||||
|
import com.willfp.eco.core.extensions.Extension
|
||||||
|
import com.willfp.eco.core.extensions.ExtensionLoader
|
||||||
|
import com.willfp.eco.core.extensions.ExtensionMetadata
|
||||||
|
import com.willfp.eco.core.extensions.MalformedExtensionException
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration
|
||||||
|
import java.io.File
|
||||||
|
import java.io.InputStreamReader
|
||||||
|
import java.net.MalformedURLException
|
||||||
|
import java.net.URL
|
||||||
|
import java.net.URLClassLoader
|
||||||
|
|
||||||
|
class EcoExtensionLoader(
|
||||||
|
plugin: EcoPlugin
|
||||||
|
) : PluginDependent<EcoPlugin>(plugin), ExtensionLoader {
|
||||||
|
private val extensions: MutableMap<Extension, URLClassLoader> = HashMap()
|
||||||
|
|
||||||
|
override fun loadExtensions() {
|
||||||
|
val dir = File(this.plugin.dataFolder, "/extensions")
|
||||||
|
if (!dir.exists()) {
|
||||||
|
dir.mkdirs()
|
||||||
|
}
|
||||||
|
|
||||||
|
val extensionJars = dir.listFiles() ?: return
|
||||||
|
|
||||||
|
for (extensionJar in extensionJars) {
|
||||||
|
if (!extensionJar.isFile) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
loadExtension(extensionJar)
|
||||||
|
} catch (e: MalformedExtensionException) {
|
||||||
|
this.plugin.logger.warning(extensionJar.name + " caused an error!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(MalformedExtensionException::class)
|
||||||
|
private fun loadExtension(extensionJar: File) {
|
||||||
|
lateinit var url : URL
|
||||||
|
|
||||||
|
try {
|
||||||
|
url = extensionJar.toURI().toURL()
|
||||||
|
} catch (e: MalformedURLException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
val classLoader = URLClassLoader(arrayOf(url), this.plugin::class.java.classLoader)
|
||||||
|
val ymlIn = classLoader.getResourceAsStream("extension.yml")
|
||||||
|
?: throw MalformedExtensionException ("No extension.yml found in " + extensionJar.name)
|
||||||
|
|
||||||
|
val extensionYml = YamlTransientConfig(YamlConfiguration.loadConfiguration(InputStreamReader(ymlIn)))
|
||||||
|
|
||||||
|
val mainClass = extensionYml.getStringOrNull("main")
|
||||||
|
var name = extensionYml.getStringOrNull("name")
|
||||||
|
var version = extensionYml.getStringOrNull("version")
|
||||||
|
var author = extensionYml.getStringOrNull("author")
|
||||||
|
|
||||||
|
|
||||||
|
if (mainClass == null) {
|
||||||
|
throw MalformedExtensionException ("Invalid extension.yml found in " + extensionJar.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name == null) {
|
||||||
|
this.plugin.logger.warning(extensionJar.name + " doesn't have a name!")
|
||||||
|
name = "Unnamed Extension " + extensionJar.name
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version == null) {
|
||||||
|
this.plugin.logger.warning(extensionJar.name + " doesn't have a version!")
|
||||||
|
version = "1.0.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (author == null) {
|
||||||
|
this.plugin.logger.warning(extensionJar.name + " doesn't have an author!")
|
||||||
|
author = "Unnamed Author"
|
||||||
|
}
|
||||||
|
|
||||||
|
val metadata = ExtensionMetadata(version, name, author)
|
||||||
|
|
||||||
|
val cls: Class<*> = classLoader.loadClass(mainClass)
|
||||||
|
val extension: Extension = cls.getConstructor(EcoPlugin::class.java).newInstance(this.plugin) as Extension
|
||||||
|
|
||||||
|
extension.setMetadata(metadata)
|
||||||
|
extension.enable()
|
||||||
|
extensions[extension] = classLoader
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLoadedExtensions(): MutableSet<Extension> {
|
||||||
|
return ImmutableSet.copyOf(extensions.keys)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unloadExtensions() {
|
||||||
|
extensions.keys.forEach { e -> e.disable() }
|
||||||
|
for (urlClassLoader in extensions.values) {
|
||||||
|
urlClassLoader.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
extensions.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.willfp.eco.internal.factory
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.PluginDependent
|
||||||
|
import com.willfp.eco.core.factory.MetadataValueFactory
|
||||||
|
import org.bukkit.metadata.FixedMetadataValue
|
||||||
|
|
||||||
|
class EcoMetadataValueFactory(plugin: EcoPlugin) : PluginDependent<EcoPlugin>(plugin), MetadataValueFactory {
|
||||||
|
override fun create(value: Any): FixedMetadataValue {
|
||||||
|
return FixedMetadataValue(plugin, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.willfp.eco.internal.factory
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.PluginDependent
|
||||||
|
import com.willfp.eco.core.factory.NamespacedKeyFactory
|
||||||
|
import org.bukkit.NamespacedKey
|
||||||
|
|
||||||
|
class EcoNamespacedKeyFactory(plugin: EcoPlugin) : PluginDependent<EcoPlugin>(plugin), NamespacedKeyFactory {
|
||||||
|
override fun create(key: String): NamespacedKey {
|
||||||
|
return NamespacedKey(plugin, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.willfp.eco.internal.factory
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.PluginDependent
|
||||||
|
import com.willfp.eco.core.factory.RunnableFactory
|
||||||
|
import com.willfp.eco.core.scheduling.RunnableTask
|
||||||
|
import com.willfp.eco.internal.scheduling.EcoRunnableTask
|
||||||
|
import java.util.function.Consumer
|
||||||
|
|
||||||
|
class EcoRunnableFactory(plugin: EcoPlugin) : PluginDependent<EcoPlugin>(plugin), RunnableFactory {
|
||||||
|
override fun create(consumer: Consumer<RunnableTask>): RunnableTask {
|
||||||
|
return object : EcoRunnableTask(plugin) {
|
||||||
|
override fun run() {
|
||||||
|
consumer.accept(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.willfp.eco.internal.fast
|
||||||
|
|
||||||
|
import com.willfp.eco.core.fast.FastItemStack
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
|
||||||
|
abstract class EcoFastItemStack<T: Any>(
|
||||||
|
val handle: T,
|
||||||
|
val bukkit: ItemStack
|
||||||
|
) : FastItemStack {
|
||||||
|
override fun unwrap(): ItemStack {
|
||||||
|
return bukkit
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.willfp.eco.internal.gui
|
||||||
|
|
||||||
|
import com.willfp.eco.core.gui.GUIFactory
|
||||||
|
import com.willfp.eco.core.gui.menu.MenuBuilder
|
||||||
|
import com.willfp.eco.core.gui.slot.SlotBuilder
|
||||||
|
import com.willfp.eco.internal.gui.menu.EcoMenuBuilder
|
||||||
|
import com.willfp.eco.internal.gui.slot.EcoSlotBuilder
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import java.util.function.Function
|
||||||
|
|
||||||
|
class EcoGUIFactory : GUIFactory {
|
||||||
|
override fun createSlotBuilder(provider: Function<Player, ItemStack>): SlotBuilder {
|
||||||
|
return EcoSlotBuilder(provider)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createMenuBuilder(rows: Int): MenuBuilder {
|
||||||
|
return EcoMenuBuilder(rows)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package com.willfp.eco.internal.gui.menu
|
||||||
|
|
||||||
|
import com.willfp.eco.core.gui.menu.Menu
|
||||||
|
import com.willfp.eco.core.gui.slot.FillerSlot
|
||||||
|
import com.willfp.eco.core.gui.slot.Slot
|
||||||
|
import com.willfp.eco.internal.gui.slot.EcoFillerSlot
|
||||||
|
import com.willfp.eco.util.StringUtils
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.inventory.InventoryCloseEvent
|
||||||
|
import org.bukkit.inventory.Inventory
|
||||||
|
import java.util.function.Consumer
|
||||||
|
|
||||||
|
class EcoMenu(
|
||||||
|
private val rows: Int,
|
||||||
|
private val slots: List<MutableList<Slot>>,
|
||||||
|
private val title: String,
|
||||||
|
private val onClose: Consumer<InventoryCloseEvent>
|
||||||
|
): Menu {
|
||||||
|
|
||||||
|
override fun getSlot(row: Int, column: Int): Slot {
|
||||||
|
if (row < 1 || row > this.rows) {
|
||||||
|
throw IllegalArgumentException("Invalid row number!")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (column < 1 || column > 9) {
|
||||||
|
throw IllegalArgumentException("Invalid column number!")
|
||||||
|
}
|
||||||
|
|
||||||
|
val slot = slots[row - 1][column - 1]
|
||||||
|
if (slot is FillerSlot) {
|
||||||
|
slots[row - 1][column - 1] = EcoFillerSlot(slot.itemStack)
|
||||||
|
|
||||||
|
return getSlot(row, column)
|
||||||
|
}
|
||||||
|
|
||||||
|
return slot
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun open(player: Player): Inventory {
|
||||||
|
val inventory = Bukkit.createInventory(null, rows * 9, title)
|
||||||
|
|
||||||
|
var i = 0
|
||||||
|
for (row in slots) {
|
||||||
|
for (item in row) {
|
||||||
|
if (i == rows * 9) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
val slotItem = item.getItemStack(player)
|
||||||
|
val meta = slotItem.itemMeta
|
||||||
|
if (meta != null) {
|
||||||
|
val lore = meta.lore
|
||||||
|
if (lore != null) {
|
||||||
|
lore.replaceAll{ s -> StringUtils.format(s, player) }
|
||||||
|
meta.lore = lore
|
||||||
|
}
|
||||||
|
slotItem.itemMeta = meta
|
||||||
|
}
|
||||||
|
inventory.setItem(i, slotItem)
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
player.openInventory(inventory)
|
||||||
|
MenuHandler.registerMenu(inventory, this)
|
||||||
|
return inventory
|
||||||
|
}
|
||||||
|
|
||||||
|
fun handleClose(event: InventoryCloseEvent) {
|
||||||
|
onClose.accept(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getRows(): Int {
|
||||||
|
return rows
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getTitle(): String {
|
||||||
|
return title
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package com.willfp.eco.internal.gui.menu
|
||||||
|
|
||||||
|
import com.willfp.eco.core.gui.menu.Menu
|
||||||
|
import com.willfp.eco.core.gui.menu.MenuBuilder
|
||||||
|
import com.willfp.eco.core.gui.slot.FillerMask
|
||||||
|
import com.willfp.eco.core.gui.slot.Slot
|
||||||
|
import com.willfp.eco.internal.gui.slot.EcoFillerSlot
|
||||||
|
import com.willfp.eco.util.ListUtils
|
||||||
|
import com.willfp.eco.util.StringUtils
|
||||||
|
import org.bukkit.Material
|
||||||
|
import org.bukkit.event.inventory.InventoryCloseEvent
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import java.util.function.Consumer
|
||||||
|
|
||||||
|
class EcoMenuBuilder(private val rows: Int) : MenuBuilder {
|
||||||
|
private var title = "Menu"
|
||||||
|
private var maskSlots: List<MutableList<Slot?>>
|
||||||
|
private val slots: List<MutableList<Slot>> = ListUtils.create2DList(rows, 9)
|
||||||
|
private var onClose = Consumer { _: InventoryCloseEvent -> }
|
||||||
|
|
||||||
|
override fun setTitle(title: String): MenuBuilder {
|
||||||
|
this.title = StringUtils.format(title)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setSlot(
|
||||||
|
row: Int,
|
||||||
|
column: Int,
|
||||||
|
slot: Slot
|
||||||
|
): MenuBuilder {
|
||||||
|
require(!(row < 1 || row > rows)) { "Invalid row number!" }
|
||||||
|
require(!(column < 1 || column > 9)) { "Invalid column number!" }
|
||||||
|
slots[row - 1][column - 1] = slot
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setMask(mask: FillerMask): MenuBuilder {
|
||||||
|
maskSlots = mask.mask
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClose(action: Consumer<InventoryCloseEvent>): MenuBuilder {
|
||||||
|
onClose = action
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun build(): Menu {
|
||||||
|
val finalSlots: MutableList<MutableList<Slot>> = ArrayList()
|
||||||
|
|
||||||
|
for (maskRow in maskSlots) {
|
||||||
|
val row = ArrayList<Slot>()
|
||||||
|
for (slot in maskRow) {
|
||||||
|
row.add(slot ?: EcoFillerSlot(ItemStack(Material.AIR)))
|
||||||
|
}
|
||||||
|
finalSlots.add(ArrayList())
|
||||||
|
finalSlots.add(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i in slots.indices) {
|
||||||
|
for (j in slots[i].indices) {
|
||||||
|
val slot = slots[i][j]
|
||||||
|
finalSlots[i][j] = slot
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EcoMenu(rows, finalSlots, title, onClose)
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
maskSlots = ListUtils.create2DList(rows, 9)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.willfp.eco.internal.gui.menu
|
||||||
|
|
||||||
|
import com.willfp.eco.core.gui.menu.Menu
|
||||||
|
import org.bukkit.inventory.Inventory
|
||||||
|
|
||||||
|
object MenuHandler {
|
||||||
|
private val MENUS: MutableMap<Inventory, Menu> = HashMap()
|
||||||
|
|
||||||
|
fun registerMenu(
|
||||||
|
inventory: Inventory,
|
||||||
|
menu: Menu
|
||||||
|
) {
|
||||||
|
MENUS[inventory] = menu
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unregisterMenu(inventory: Inventory) {
|
||||||
|
MENUS.remove(inventory)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getMenu(inventory: Inventory): Menu? {
|
||||||
|
return MENUS[inventory]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.willfp.eco.internal.gui.slot
|
||||||
|
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import java.util.function.Function
|
||||||
|
|
||||||
|
class EcoFillerSlot(itemStack: ItemStack) : EcoSlot(
|
||||||
|
Function { itemStack },
|
||||||
|
{ _, _ -> },
|
||||||
|
{ _, _ -> },
|
||||||
|
{ _, _ -> },
|
||||||
|
{ _, _ -> },
|
||||||
|
{ _, _ -> }
|
||||||
|
)
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.willfp.eco.internal.gui.slot
|
||||||
|
|
||||||
|
import com.willfp.eco.core.gui.slot.Slot
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.inventory.ClickType
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import java.util.function.BiConsumer
|
||||||
|
import java.util.function.Function
|
||||||
|
|
||||||
|
open class EcoSlot(
|
||||||
|
private val provider: Function<Player, ItemStack>,
|
||||||
|
private val onLeftClick: BiConsumer<InventoryClickEvent, Slot>,
|
||||||
|
private val onRightClick: BiConsumer<InventoryClickEvent, Slot>,
|
||||||
|
private val onShiftLeftClick: BiConsumer<InventoryClickEvent, Slot>,
|
||||||
|
private val onShiftRightClick: BiConsumer<InventoryClickEvent, Slot>,
|
||||||
|
private val onMiddleClick: BiConsumer<InventoryClickEvent, Slot>
|
||||||
|
) : Slot {
|
||||||
|
|
||||||
|
fun handleInventoryClick(event: InventoryClickEvent) {
|
||||||
|
when (event.click) {
|
||||||
|
ClickType.LEFT -> this.onLeftClick.accept(event, this)
|
||||||
|
ClickType.RIGHT -> this.onRightClick.accept(event, this)
|
||||||
|
ClickType.SHIFT_LEFT -> this.onShiftLeftClick.accept(event, this)
|
||||||
|
ClickType.SHIFT_RIGHT -> this.onShiftRightClick.accept(event, this)
|
||||||
|
ClickType.MIDDLE -> this.onMiddleClick.accept(event, this)
|
||||||
|
else -> { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemStack(player: Player): ItemStack {
|
||||||
|
return provider.apply(player)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package com.willfp.eco.internal.gui.slot
|
||||||
|
|
||||||
|
import com.willfp.eco.core.gui.slot.Slot
|
||||||
|
import com.willfp.eco.core.gui.slot.SlotBuilder
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import java.util.function.BiConsumer
|
||||||
|
import java.util.function.Function
|
||||||
|
|
||||||
|
class EcoSlotBuilder(private val provider: Function<Player, ItemStack>) : SlotBuilder {
|
||||||
|
private var onLeftClick: BiConsumer<InventoryClickEvent, Slot> = BiConsumer { _, _ -> run { } }
|
||||||
|
private var onRightClick: BiConsumer<InventoryClickEvent, Slot> = BiConsumer { _, _ -> run { } }
|
||||||
|
private var onShiftLeftClick: BiConsumer<InventoryClickEvent, Slot> = BiConsumer { _, _ -> run { } }
|
||||||
|
private var onShiftRightClick: BiConsumer<InventoryClickEvent, Slot> = BiConsumer { _, _ -> run { } }
|
||||||
|
private var onMiddleClick: BiConsumer<InventoryClickEvent, Slot> = BiConsumer { _, _ -> run { } }
|
||||||
|
|
||||||
|
override fun onLeftClick(action: BiConsumer<InventoryClickEvent, Slot>): SlotBuilder {
|
||||||
|
onLeftClick = action
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRightClick(action: BiConsumer<InventoryClickEvent, Slot>): SlotBuilder {
|
||||||
|
onRightClick = action
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onShiftLeftClick(action: BiConsumer<InventoryClickEvent, Slot>): SlotBuilder {
|
||||||
|
onShiftLeftClick = action
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onShiftRightClick(action: BiConsumer<InventoryClickEvent, Slot>): SlotBuilder {
|
||||||
|
onShiftRightClick = action
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMiddleClick(action: BiConsumer<InventoryClickEvent, Slot>): SlotBuilder {
|
||||||
|
onMiddleClick = action
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun build(): Slot {
|
||||||
|
return EcoSlot(provider, onLeftClick, onRightClick, onShiftLeftClick, onShiftRightClick, onMiddleClick)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package com.willfp.eco.internal.integrations
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration
|
||||||
|
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager
|
||||||
|
import me.clip.placeholderapi.PlaceholderAPI
|
||||||
|
import me.clip.placeholderapi.expansion.PlaceholderExpansion
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
|
class PlaceholderIntegrationPAPI(private val plugin: EcoPlugin) : PlaceholderExpansion(), PlaceholderIntegration {
|
||||||
|
override fun persist(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun canRegister(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getAuthor(): String {
|
||||||
|
return java.lang.String.join(", ", plugin.description.authors)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getIdentifier(): String {
|
||||||
|
return plugin.description.name.lowercase()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getVersion(): String {
|
||||||
|
return plugin.description.version
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPlaceholderRequest(
|
||||||
|
player: Player?,
|
||||||
|
identifier: String
|
||||||
|
): String {
|
||||||
|
return PlaceholderManager.getResult(player, identifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun registerIntegration() {
|
||||||
|
register()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPluginName(): String {
|
||||||
|
return "PlaceholderAPI"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun translate(
|
||||||
|
text: String,
|
||||||
|
player: Player?
|
||||||
|
): String {
|
||||||
|
return PlaceholderAPI.setPlaceholders(player, text)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.willfp.eco.internal.logging
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.util.StringUtils
|
||||||
|
import java.util.logging.Level
|
||||||
|
import java.util.logging.Logger
|
||||||
|
|
||||||
|
class EcoLogger(plugin: EcoPlugin) : Logger(plugin.name, null as String?) {
|
||||||
|
override fun info(msg: String) {
|
||||||
|
super.info(StringUtils.format(msg))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun warning(msg: String) {
|
||||||
|
super.warning(StringUtils.format(msg))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun severe(msg: String) {
|
||||||
|
super.severe(StringUtils.format(msg))
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
parent = plugin.server.logger
|
||||||
|
this.level = Level.ALL
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package com.willfp.eco.internal.proxy;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.PluginDependent
|
||||||
|
import com.willfp.eco.core.proxy.AbstractProxy
|
||||||
|
import com.willfp.eco.core.proxy.ProxyConstants
|
||||||
|
import com.willfp.eco.core.proxy.ProxyFactory
|
||||||
|
import com.willfp.eco.core.proxy.exceptions.ProxyError
|
||||||
|
import com.willfp.eco.core.proxy.exceptions.UnsupportedVersionException
|
||||||
|
import java.net.URLClassLoader
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class EcoProxyFactory(
|
||||||
|
plugin: EcoPlugin
|
||||||
|
) : PluginDependent<EcoPlugin>(plugin), ProxyFactory {
|
||||||
|
private val proxyClassLoader: ClassLoader = plugin::class.java.classLoader
|
||||||
|
private val cache: MutableMap<Class<out AbstractProxy>, AbstractProxy> = IdentityHashMap()
|
||||||
|
|
||||||
|
override fun <T : AbstractProxy> getProxy(proxyClass: Class<T>): T {
|
||||||
|
try {
|
||||||
|
val cachedProxy: T? = attemptCache(proxyClass)
|
||||||
|
if (cachedProxy != null) {
|
||||||
|
return cachedProxy
|
||||||
|
}
|
||||||
|
|
||||||
|
val className =
|
||||||
|
this.plugin.proxyPackage + "." + ProxyConstants.NMS_VERSION + "." + proxyClass.simpleName.replace(
|
||||||
|
"Proxy",
|
||||||
|
""
|
||||||
|
)
|
||||||
|
val clazz = this.plugin::class.java.classLoader.loadClass(className)
|
||||||
|
val instance = clazz.getDeclaredConstructor().newInstance()
|
||||||
|
if (proxyClass.isAssignableFrom(clazz) && proxyClass.isInstance(instance)) {
|
||||||
|
val proxy = proxyClass.cast(instance)
|
||||||
|
cache[proxyClass] = proxy
|
||||||
|
return proxy
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
throwError(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
throwError(IllegalArgumentException())
|
||||||
|
|
||||||
|
throw RuntimeException("Something went wrong.")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun throwError(e: Exception?) {
|
||||||
|
e?.printStackTrace()
|
||||||
|
|
||||||
|
if (!SUPPORTED_VERSIONS.contains(ProxyConstants.NMS_VERSION)) {
|
||||||
|
throw UnsupportedVersionException("You're running an unsupported server version: " + ProxyConstants.NMS_VERSION)
|
||||||
|
} else {
|
||||||
|
throw ProxyError("Error with proxies - here's a stacktrace. Only god can help you now.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T : AbstractProxy> attemptCache(proxyClass: Class<T>): T? {
|
||||||
|
val proxy = cache[proxyClass] ?: return null
|
||||||
|
|
||||||
|
if (proxyClass.isInstance(proxy)) {
|
||||||
|
return proxyClass.cast(proxy)
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clean() {
|
||||||
|
if (proxyClassLoader is URLClassLoader) {
|
||||||
|
proxyClassLoader.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
cache.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val SUPPORTED_VERSIONS = listOf(
|
||||||
|
"v1_16_R3",
|
||||||
|
"v1_17_R1"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.willfp.eco.internal.scheduling
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.scheduling.RunnableTask
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable
|
||||||
|
import org.bukkit.scheduler.BukkitTask
|
||||||
|
|
||||||
|
abstract class EcoRunnableTask(protected val plugin: EcoPlugin) : BukkitRunnable(), RunnableTask {
|
||||||
|
@Synchronized
|
||||||
|
override fun runTask(): BukkitTask {
|
||||||
|
return super.runTask(plugin)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
override fun runTaskAsynchronously(): BukkitTask {
|
||||||
|
return super.runTaskAsynchronously(plugin)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
override fun runTaskLater(delay: Long): BukkitTask {
|
||||||
|
return super.runTaskLater(plugin, delay)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
override fun runTaskLaterAsynchronously(delay: Long): BukkitTask {
|
||||||
|
return super.runTaskLaterAsynchronously(plugin, delay)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
override fun runTaskTimer(delay: Long, period: Long): BukkitTask {
|
||||||
|
return super.runTaskTimer(plugin, delay, period)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
override fun runTaskTimerAsynchronously(delay: Long, period: Long): BukkitTask {
|
||||||
|
return super.runTaskTimerAsynchronously(plugin, delay, period)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package com.willfp.eco.internal.scheduling
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.PluginDependent
|
||||||
|
import com.willfp.eco.core.scheduling.Scheduler
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.scheduler.BukkitTask
|
||||||
|
|
||||||
|
class EcoScheduler(plugin: EcoPlugin) : PluginDependent<EcoPlugin>(plugin), Scheduler {
|
||||||
|
override fun runLater(
|
||||||
|
runnable: Runnable,
|
||||||
|
ticksLater: Long
|
||||||
|
): BukkitTask {
|
||||||
|
return Bukkit.getScheduler().runTaskLater(plugin, runnable, ticksLater)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun runTimer(
|
||||||
|
runnable: Runnable,
|
||||||
|
delay: Long,
|
||||||
|
repeat: Long
|
||||||
|
): BukkitTask {
|
||||||
|
return Bukkit.getScheduler().runTaskTimer(plugin, runnable, delay, repeat)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun runAsyncTimer(
|
||||||
|
runnable: Runnable,
|
||||||
|
delay: Long,
|
||||||
|
repeat: Long
|
||||||
|
): BukkitTask {
|
||||||
|
return Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, runnable, delay, repeat)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun run(runnable: Runnable): BukkitTask {
|
||||||
|
return Bukkit.getScheduler().runTask(plugin, runnable)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun runAsync(runnable: Runnable): BukkitTask {
|
||||||
|
return Bukkit.getScheduler().runTaskAsynchronously(plugin, runnable)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun syncRepeating(
|
||||||
|
runnable: Runnable,
|
||||||
|
delay: Long,
|
||||||
|
repeat: Long
|
||||||
|
): Int {
|
||||||
|
return Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, runnable, delay, repeat)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun cancelAll() {
|
||||||
|
Bukkit.getScheduler().cancelTasks(plugin)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,5 +5,6 @@ subprojects {
|
|||||||
dependencies {
|
dependencies {
|
||||||
compileOnly project(':eco-core:core-proxy')
|
compileOnly project(':eco-core:core-proxy')
|
||||||
compileOnly project(':eco-core:core-plugin')
|
compileOnly project(':eco-core:core-plugin')
|
||||||
|
compileOnly project(':eco-core:core-backend')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
package com.willfp.eco.proxy.v1_16_R3;
|
|
||||||
|
|
||||||
import com.willfp.eco.proxy.AutoCraftProxy;
|
|
||||||
import net.minecraft.server.v1_16_R3.MinecraftKey;
|
|
||||||
import net.minecraft.server.v1_16_R3.PacketPlayOutAutoRecipe;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
|
|
||||||
public final class AutoCraft implements AutoCraftProxy {
|
|
||||||
@Override
|
|
||||||
public void modifyPacket(@NotNull final Object packet) throws NoSuchFieldException, IllegalAccessException {
|
|
||||||
PacketPlayOutAutoRecipe recipePacket = (PacketPlayOutAutoRecipe) packet;
|
|
||||||
Field fKey = recipePacket.getClass().getDeclaredField("b");
|
|
||||||
fKey.setAccessible(true);
|
|
||||||
MinecraftKey key = (MinecraftKey) fKey.get(recipePacket);
|
|
||||||
fKey.set(recipePacket, new MinecraftKey(key.getNamespace(), key.getKey() + "_displayed"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package com.willfp.eco.proxy.v1_16_R3;
|
|
||||||
|
|
||||||
import com.willfp.eco.proxy.BlockBreakProxy;
|
|
||||||
import net.minecraft.server.v1_16_R3.BlockPosition;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public final class BlockBreak implements BlockBreakProxy {
|
|
||||||
@Override
|
|
||||||
public void breakBlock(@NotNull final Player player,
|
|
||||||
@NotNull final Block block) {
|
|
||||||
if (!(player instanceof CraftPlayer)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
((CraftPlayer) player).getHandle().playerInteractManager.breakBlock(new BlockPosition(block.getX(), block.getY(), block.getZ()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -22,10 +22,10 @@ import java.util.Arrays;
|
|||||||
|
|
||||||
public final class ChatComponent implements ChatComponentProxy {
|
public final class ChatComponent implements ChatComponentProxy {
|
||||||
@Override
|
@Override
|
||||||
public Object modifyComponent(@NotNull final Object object,
|
public Object modifyComponent(@NotNull final Object obj,
|
||||||
@NotNull final Player player) {
|
@NotNull final Player player) {
|
||||||
if (!(object instanceof IChatBaseComponent chatComponent)) {
|
if (!(obj instanceof IChatBaseComponent chatComponent)) {
|
||||||
return object;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (IChatBaseComponent iChatBaseComponent : chatComponent) {
|
for (IChatBaseComponent iChatBaseComponent : chatComponent) {
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
package com.willfp.eco.proxy.v1_16_R3;
|
|
||||||
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
import com.mojang.authlib.properties.Property;
|
|
||||||
import com.willfp.eco.proxy.SkullProxy;
|
|
||||||
import org.bukkit.inventory.meta.SkullMeta;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public final class Skull implements SkullProxy {
|
|
||||||
private Method setProfile = null;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSkullTexture(@NotNull final SkullMeta meta,
|
|
||||||
@NotNull final String base64) {
|
|
||||||
try {
|
|
||||||
if (setProfile == null) {
|
|
||||||
setProfile = meta.getClass().getDeclaredMethod("setProfile", GameProfile.class);
|
|
||||||
setProfile.setAccessible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
UUID uuid = new UUID(
|
|
||||||
base64.substring(base64.length() - 20).hashCode(),
|
|
||||||
base64.substring(base64.length() - 10).hashCode()
|
|
||||||
);
|
|
||||||
|
|
||||||
GameProfile profile = new GameProfile(uuid, "talismans");
|
|
||||||
profile.getProperties().put("textures", new Property("textures", base64));
|
|
||||||
|
|
||||||
setProfile.invoke(meta, profile);
|
|
||||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
package com.willfp.eco.proxy.v1_16_R3;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.display.Display;
|
|
||||||
import com.willfp.eco.proxy.VillagerTradeProxy;
|
|
||||||
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftMerchantRecipe;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.MerchantRecipe;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
|
|
||||||
public final class VillagerTrade implements VillagerTradeProxy {
|
|
||||||
private final Field handle;
|
|
||||||
|
|
||||||
public VillagerTrade() {
|
|
||||||
try {
|
|
||||||
handle = CraftMerchantRecipe.class.getDeclaredField("handle");
|
|
||||||
handle.setAccessible(true);
|
|
||||||
return;
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new RuntimeException("Error!");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MerchantRecipe displayTrade(@NotNull final MerchantRecipe recipe,
|
|
||||||
@NotNull final Player player) {
|
|
||||||
CraftMerchantRecipe oldRecipe = (CraftMerchantRecipe) recipe;
|
|
||||||
|
|
||||||
CraftMerchantRecipe newRecipe = new CraftMerchantRecipe(
|
|
||||||
Display.display(recipe.getResult().clone()),
|
|
||||||
recipe.getUses(),
|
|
||||||
recipe.getMaxUses(),
|
|
||||||
recipe.hasExperienceReward(),
|
|
||||||
recipe.getVillagerExperience(),
|
|
||||||
recipe.getPriceMultiplier()
|
|
||||||
);
|
|
||||||
|
|
||||||
for (ItemStack ingredient : recipe.getIngredients()) {
|
|
||||||
newRecipe.addIngredient(Display.display(ingredient.clone(), player));
|
|
||||||
}
|
|
||||||
|
|
||||||
getHandle(newRecipe).setSpecialPrice(getHandle(oldRecipe).getSpecialPrice());
|
|
||||||
|
|
||||||
return newRecipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private net.minecraft.server.v1_16_R3.MerchantRecipe getHandle(@NotNull final CraftMerchantRecipe recipe) {
|
|
||||||
try {
|
|
||||||
return (net.minecraft.server.v1_16_R3.MerchantRecipe) handle.get(recipe);
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalArgumentException("Not CMR");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.willfp.eco.proxy.v1_16_R3
|
||||||
|
import com.willfp.eco.proxy.AutoCraftProxy
|
||||||
|
import net.minecraft.server.v1_16_R3.MinecraftKey
|
||||||
|
import net.minecraft.server.v1_16_R3.PacketPlayOutAutoRecipe
|
||||||
|
|
||||||
|
class AutoCraft : AutoCraftProxy {
|
||||||
|
@Throws(NoSuchFieldException::class, IllegalAccessException::class)
|
||||||
|
override fun modifyPacket(packet: Any) {
|
||||||
|
val recipePacket = packet as PacketPlayOutAutoRecipe
|
||||||
|
val fKey = recipePacket.javaClass.getDeclaredField("b")
|
||||||
|
fKey.isAccessible = true
|
||||||
|
val key = fKey[recipePacket] as MinecraftKey
|
||||||
|
fKey[recipePacket] = MinecraftKey(key.namespace, key.key + "_displayed")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.willfp.eco.proxy.v1_16_R3
|
||||||
|
import com.willfp.eco.proxy.BlockBreakProxy
|
||||||
|
import net.minecraft.server.v1_16_R3.BlockPosition
|
||||||
|
import org.bukkit.block.Block
|
||||||
|
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
|
class BlockBreak : BlockBreakProxy {
|
||||||
|
override fun breakBlock(
|
||||||
|
player: Player,
|
||||||
|
block: Block
|
||||||
|
) {
|
||||||
|
if (player !is CraftPlayer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
player.handle.playerInteractManager.breakBlock(BlockPosition(block.x, block.y, block.z))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.willfp.eco.proxy.v1_16_R3
|
||||||
|
import com.willfp.eco.core.fast.FastItemStack
|
||||||
|
import com.willfp.eco.proxy.FastItemStackFactoryProxy
|
||||||
|
import com.willfp.eco.proxy.v1_16_R3.fast.NMSFastItemStack
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
|
||||||
|
class FastItemStackFactory : FastItemStackFactoryProxy {
|
||||||
|
override fun create(itemStack: ItemStack): FastItemStack {
|
||||||
|
return NMSFastItemStack(itemStack)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package com.willfp.eco.proxy.v1_16_R3
|
||||||
|
import com.mojang.authlib.GameProfile
|
||||||
|
import com.mojang.authlib.properties.Property
|
||||||
|
import org.bukkit.inventory.meta.SkullMeta
|
||||||
|
import com.willfp.eco.proxy.SkullProxy
|
||||||
|
import java.lang.reflect.Method
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class Skull : SkullProxy {
|
||||||
|
private lateinit var setProfile: Method
|
||||||
|
|
||||||
|
override fun setSkullTexture(
|
||||||
|
meta: SkullMeta,
|
||||||
|
base64: String
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
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)
|
||||||
|
} catch (e: ReflectiveOperationException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package com.willfp.eco.proxy.v1_16_R3
|
||||||
|
import com.willfp.eco.core.display.Display
|
||||||
|
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftMerchantRecipe
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.inventory.MerchantRecipe
|
||||||
|
import com.willfp.eco.proxy.VillagerTradeProxy
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
|
||||||
|
class VillagerTrade : VillagerTradeProxy {
|
||||||
|
private var handle: Field
|
||||||
|
|
||||||
|
override fun displayTrade(
|
||||||
|
recipe: MerchantRecipe,
|
||||||
|
player: Player
|
||||||
|
): MerchantRecipe {
|
||||||
|
val oldRecipe = recipe as CraftMerchantRecipe
|
||||||
|
val newRecipe = CraftMerchantRecipe(
|
||||||
|
Display.display(recipe.getResult().clone()),
|
||||||
|
recipe.getUses(),
|
||||||
|
recipe.getMaxUses(),
|
||||||
|
recipe.hasExperienceReward(),
|
||||||
|
recipe.getVillagerExperience(),
|
||||||
|
recipe.getPriceMultiplier()
|
||||||
|
)
|
||||||
|
for (ingredient in recipe.getIngredients()) {
|
||||||
|
newRecipe.addIngredient(Display.display(ingredient.clone(), player))
|
||||||
|
}
|
||||||
|
getHandle(newRecipe).specialPrice = getHandle(oldRecipe).specialPrice
|
||||||
|
return newRecipe
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getHandle(recipe: CraftMerchantRecipe): net.minecraft.server.v1_16_R3.MerchantRecipe {
|
||||||
|
try {
|
||||||
|
return handle[recipe] as net.minecraft.server.v1_16_R3.MerchantRecipe
|
||||||
|
} catch (e: IllegalAccessException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
throw IllegalArgumentException("Not CMR")
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
try {
|
||||||
|
handle = CraftMerchantRecipe::class.java.getDeclaredField("handle")
|
||||||
|
handle.isAccessible = true
|
||||||
|
} catch (e: NoSuchFieldException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
throw RuntimeException("Error!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
package com.willfp.eco.proxy.v1_16_R3.fast
|
||||||
|
|
||||||
|
import com.willfp.eco.internal.fast.EcoFastItemStack
|
||||||
|
import com.willfp.eco.util.StringUtils
|
||||||
|
import net.minecraft.server.v1_16_R3.*
|
||||||
|
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack
|
||||||
|
import org.bukkit.craftbukkit.v1_16_R3.util.CraftMagicNumbers
|
||||||
|
import org.bukkit.craftbukkit.v1_16_R3.util.CraftNamespacedKey
|
||||||
|
import org.bukkit.enchantments.Enchantment
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
import kotlin.experimental.and
|
||||||
|
|
||||||
|
class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemStack<ItemStack>(
|
||||||
|
getNMSStack(itemStack), itemStack
|
||||||
|
) {
|
||||||
|
private var loreCache: List<String>? = null
|
||||||
|
override fun getEnchantmentsOnItem(checkStored: Boolean): Map<Enchantment, Int> {
|
||||||
|
val enchantmentNBT = if (checkStored && handle.item === Items.ENCHANTED_BOOK) ItemEnchantedBook.d(
|
||||||
|
handle
|
||||||
|
) else handle.enchantments
|
||||||
|
val foundEnchantments: MutableMap<Enchantment, Int> = HashMap()
|
||||||
|
for (base in enchantmentNBT) {
|
||||||
|
val compound = base as NBTTagCompound
|
||||||
|
val key = compound.getString("id")
|
||||||
|
val level: Int = ('\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.item === Items.ENCHANTED_BOOK) ItemEnchantedBook.d(
|
||||||
|
handle
|
||||||
|
) else handle.enchantments
|
||||||
|
for (base in enchantmentNBT) {
|
||||||
|
val compound = base as NBTTagCompound
|
||||||
|
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.a("display")
|
||||||
|
if (!displayTag.hasKey("Lore")) {
|
||||||
|
displayTag["Lore"] = NBTTagList()
|
||||||
|
}
|
||||||
|
val loreTag = displayTag.getList("Lore", CraftMagicNumbers.NBT.TAG_STRING)
|
||||||
|
loreTag.clear()
|
||||||
|
for (s in jsonLore) {
|
||||||
|
loreTag.add(NBTTagString.a(s))
|
||||||
|
}
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLore(): List<String> {
|
||||||
|
if (loreCache != null) {
|
||||||
|
return loreCache as List<String>
|
||||||
|
}
|
||||||
|
val lore: MutableList<String> = ArrayList()
|
||||||
|
for (s in getLoreJSON()) {
|
||||||
|
lore.add(StringUtils.jsonToLegacy(s))
|
||||||
|
}
|
||||||
|
loreCache = lore
|
||||||
|
return lore
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getLoreJSON(): List<String> {
|
||||||
|
val displayTag = handle.a("display")
|
||||||
|
return if (displayTag.hasKey("Lore")) {
|
||||||
|
val loreTag = displayTag.getList("Lore", CraftMagicNumbers.NBT.TAG_STRING)
|
||||||
|
val lore: MutableList<String> = ArrayList(loreTag.size)
|
||||||
|
for (i in loreTag.indices) {
|
||||||
|
lore.add(loreTag.getString(i))
|
||||||
|
}
|
||||||
|
lore
|
||||||
|
} else {
|
||||||
|
ArrayList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun apply() {
|
||||||
|
if (bukkit !is CraftItemStack) {
|
||||||
|
bukkit.itemMeta = CraftItemStack.asCraftMirror(handle).itemMeta
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private var field: Field
|
||||||
|
|
||||||
|
init {
|
||||||
|
lateinit var temp: Field
|
||||||
|
try {
|
||||||
|
val handleField = CraftItemStack::class.java.getDeclaredField("handle")
|
||||||
|
handleField.isAccessible = true
|
||||||
|
temp = handleField
|
||||||
|
} catch (e: ReflectiveOperationException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
field = temp
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getNMSStack(itemStack: org.bukkit.inventory.ItemStack): ItemStack {
|
||||||
|
return if (itemStack !is CraftItemStack) {
|
||||||
|
CraftItemStack.asNMSCopy(itemStack)
|
||||||
|
} else {
|
||||||
|
field[itemStack] as ItemStack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,29 @@
|
|||||||
|
plugins {
|
||||||
|
id 'xyz.jpenilla.special-gradle' version '1.0.0-SNAPSHOT'
|
||||||
|
}
|
||||||
|
|
||||||
group 'com.willfp'
|
group 'com.willfp'
|
||||||
version rootProject.version
|
version rootProject.version
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly 'org.spigotmc:spigot:1.17-R0.1-SNAPSHOT'
|
compileOnly 'org.spigotmc:spigot:1.17.1-R0.1-SNAPSHOT:remapped-mojang'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
specialGradle {
|
||||||
|
minecraftVersion.set("1.17")
|
||||||
|
specialSourceVersion.set("1.10.0")
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTools {
|
||||||
|
quiet.set(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
configurations.create('mapped')
|
||||||
|
|
||||||
|
artifacts {
|
||||||
|
mapped jar.outputs.files.files.toArray()[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
productionMappedJar.mustRunAfter(clean)
|
||||||
|
productionMappedJar.mustRunAfter(compileKotlin)
|
||||||
|
build.dependsOn productionMappedJar
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user