Compare commits
58 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08c14f4def | ||
|
|
0fa6f972c0 | ||
|
|
8837fecfa0 | ||
|
|
af1841770e | ||
|
|
1d85dbf08d | ||
|
|
ba9812534a | ||
|
|
1f95a33385 | ||
|
|
bc652a8154 | ||
|
|
0c2e1f0cae | ||
|
|
39d6eb7f9a | ||
|
|
61bae6de55 | ||
|
|
aa4ac4c6d1 | ||
|
|
7141b12e95 | ||
|
|
2382548629 | ||
|
|
0c4bd182f7 | ||
|
|
e90e053b45 | ||
|
|
742c1abb00 | ||
|
|
c0686ca386 | ||
|
|
db2ea7daa9 | ||
|
|
ed4f0b2ab6 | ||
|
|
6decc68d1b | ||
|
|
1e061313a4 | ||
|
|
4762004e94 | ||
|
|
0d9889ef43 | ||
|
|
b2a23e80a1 | ||
|
|
0e439db7b3 | ||
|
|
f615006b23 | ||
|
|
d952dbc61b | ||
|
|
d95a96f4c6 | ||
|
|
33940f5778 | ||
|
|
173d04595f | ||
|
|
c7c4ca3777 | ||
|
|
cbf7316db9 | ||
|
|
601cadd582 | ||
|
|
877647db03 | ||
|
|
81196bb132 | ||
|
|
ef701f1f86 | ||
|
|
58d8f72cf5 | ||
|
|
3abf916f18 | ||
|
|
b459a746e3 | ||
|
|
30c37078a2 | ||
|
|
36ccfb5fc6 | ||
|
|
c84f1a060a | ||
|
|
d8d5609f6b | ||
|
|
462abd46c6 | ||
|
|
e89008cf97 | ||
|
|
d34e43797d | ||
|
|
63ee83c795 | ||
|
|
2eec17698e | ||
|
|
ad52c2a086 | ||
|
|
6e482cccda | ||
|
|
899b4297f7 | ||
|
|
ceb95e20b5 | ||
|
|
bdfeb9a0ab | ||
|
|
e0707e2afa | ||
|
|
e8048f5a0a | ||
|
|
a36018e31a | ||
|
|
a34c63161d |
@@ -157,7 +157,7 @@ Here's a list of some (not all) of the features of eco:
|
||||
|
||||
<h1 align="center">
|
||||
<br>
|
||||
<a href="http://gamersupps.gg/discount/Auxilor?afmc=Auxilor" target="_blank">
|
||||
<a href="https://gamersupps.gg/discount/Auxilor?afmc=Auxilor" target="_blank">
|
||||
<img src="https://i.imgur.com/uFDpBAC.png" alt="supps banner">
|
||||
</a>
|
||||
<a href="https://dedimc.promo/Auxilor" target="_blank">
|
||||
|
||||
@@ -25,11 +25,14 @@ allprojects {
|
||||
mavenLocal()
|
||||
maven { url 'https://jitpack.io' }
|
||||
|
||||
// SuperiorSkyblock2
|
||||
maven { url 'https://repo.bg-software.com/repository/api/' }
|
||||
|
||||
// NMS (for jitpack compilation)
|
||||
maven { url 'https://repo.codemc.org/repository/nms/' }
|
||||
|
||||
// bStats, mcMMO
|
||||
maven { url 'https://repo.codemc.org/repository/maven-public' }
|
||||
// bStats, mcMMO, BentoBox
|
||||
maven { url 'https://repo.codemc.org/repository/maven-public/' }
|
||||
|
||||
// Spigot API
|
||||
maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' }
|
||||
|
||||
@@ -9,15 +9,15 @@ dependencies {
|
||||
// Adventure
|
||||
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
|
||||
compileOnly 'net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT'
|
||||
compileOnly 'net.kyori:adventure-api:4.9.1'
|
||||
compileOnly 'net.kyori:adventure-api:4.9.2'
|
||||
compileOnly 'net.kyori:adventure-text-serializer-gson:4.9.2'
|
||||
compileOnly 'net.kyori:adventure-text-serializer-legacy:4.8.1'
|
||||
compileOnly 'net.kyori:adventure-text-serializer-legacy:4.9.2'
|
||||
|
||||
// Other
|
||||
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
|
||||
compileOnly 'org.apache.maven:maven-artifact:3.0.3'
|
||||
compileOnly 'org.apache.maven:maven-artifact:3.8.1'
|
||||
compileOnly 'com.comphenix.protocol:ProtocolLib:4.7.1-SNAPSHOT'
|
||||
compileOnly 'com.google.code.gson:gson:2.8.7'
|
||||
compileOnly 'com.google.code.gson:gson:2.8.8'
|
||||
}
|
||||
|
||||
java {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.willfp.eco.core;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -15,20 +14,12 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class Eco {
|
||||
/**
|
||||
* Instance of eco handler.
|
||||
* <p>
|
||||
* The handler is, in essence, a way to interface between the eco-api
|
||||
* frontend module, and the eco-backend implementations.
|
||||
* <p>
|
||||
* There shouldn't really be any reason to ever use the handler
|
||||
* in your own plugins, but if you want to then you can - it's
|
||||
* just a part of the API like any other.
|
||||
*/
|
||||
@Getter
|
||||
@ApiStatus.Internal
|
||||
private Handler handler;
|
||||
|
||||
/**
|
||||
* Set the handler.
|
||||
*
|
||||
* @param handler The handler.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@@ -37,4 +28,25 @@ public class Eco {
|
||||
|
||||
Eco.handler = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the instance of the eco handler.
|
||||
* <p>
|
||||
* The handler is, in essence, a way to interface between the eco-api
|
||||
* frontend module, and the eco-backend implementations.
|
||||
* <p>
|
||||
* There shouldn't really be any reason to ever use the handler
|
||||
* in your own plugins, and you are likely to break things. All parts of
|
||||
* the handler are abstracted into logically named parts of the API.
|
||||
* <p>
|
||||
* In versions of eco before 6.12.0, the handler was considered part of
|
||||
* the eco API, however it has since been moved into an internal component
|
||||
* that shouldn't be used in your plugins.
|
||||
*
|
||||
* @return The handler.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public Handler getHandler() {
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.willfp.eco.core;
|
||||
|
||||
import com.willfp.eco.core.config.updating.ConfigHandler;
|
||||
import com.willfp.eco.core.config.wrapper.ConfigFactory;
|
||||
import com.willfp.eco.core.data.keys.KeyRegistry;
|
||||
import com.willfp.eco.core.data.PlayerProfileHandler;
|
||||
import com.willfp.eco.core.drops.DropQueueFactory;
|
||||
import com.willfp.eco.core.events.EventManager;
|
||||
import com.willfp.eco.core.extensions.ExtensionLoader;
|
||||
@@ -17,6 +19,7 @@ import com.willfp.eco.core.requirement.RequirementFactory;
|
||||
import com.willfp.eco.core.scheduling.Scheduler;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -24,8 +27,9 @@ import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* @see Eco
|
||||
* @see Eco#getHandler()
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public interface Handler {
|
||||
/**
|
||||
* Create a scheduler.
|
||||
@@ -212,4 +216,19 @@ public interface Handler {
|
||||
*/
|
||||
@Nullable
|
||||
BukkitAudiences getAdventure();
|
||||
|
||||
/**
|
||||
* Get the key registry.
|
||||
*
|
||||
* @return The registry.
|
||||
*/
|
||||
@NotNull
|
||||
KeyRegistry getKeyRegistry();
|
||||
|
||||
/**
|
||||
* Get the PlayerProfile handler.
|
||||
*
|
||||
* @return The handler.
|
||||
*/
|
||||
PlayerProfileHandler getPlayerProfileHandler();
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
*
|
||||
* @param <T> The eco plugin type.
|
||||
*/
|
||||
public abstract class PluginDependent<@NotNull T extends EcoPlugin> {
|
||||
public abstract class PluginDependent<T extends EcoPlugin> {
|
||||
/**
|
||||
* The {@link EcoPlugin} that is stored.
|
||||
*/
|
||||
|
||||
@@ -34,7 +34,7 @@ public interface LoadableConfig {
|
||||
File getConfigFile();
|
||||
|
||||
/**
|
||||
* Get the config name (including extension)
|
||||
* Get the config name (including extension).
|
||||
*
|
||||
* @return The name.
|
||||
*/
|
||||
|
||||
@@ -75,4 +75,4 @@ public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
|
||||
@NotNull final EcoPlugin plugin) {
|
||||
this(configName, removeUnused, (PluginLike) plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.willfp.eco.core.data;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Persistent data storage interface for players.
|
||||
* <p>
|
||||
* Profiles save automatically, so there is no need to save after changes.
|
||||
*/
|
||||
public interface PlayerProfile {
|
||||
/**
|
||||
* Write a key to a player's persistent data.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param value The value.
|
||||
* @param <T> The type of the key.
|
||||
*/
|
||||
<T> void write(@NotNull PersistentDataKey<T> key,
|
||||
@NotNull T value);
|
||||
|
||||
/**
|
||||
* Read a key from a player's persistent data.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param <T> The type of the key.
|
||||
* @return The value, or the default value if not found.
|
||||
*/
|
||||
<T> @NotNull T read(@NotNull PersistentDataKey<T> key);
|
||||
|
||||
/**
|
||||
* Load a player profile.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return The profile.
|
||||
*/
|
||||
@NotNull
|
||||
static PlayerProfile load(@NotNull final OfflinePlayer player) {
|
||||
return load(player.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a player profile.
|
||||
*
|
||||
* @param uuid The player's UUID.
|
||||
* @return The profile.
|
||||
*/
|
||||
@NotNull
|
||||
static PlayerProfile load(@NotNull final UUID uuid) {
|
||||
return Eco.getHandler().getPlayerProfileHandler().load(uuid);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.willfp.eco.core.data;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* API to handle player profiles.
|
||||
*/
|
||||
public interface PlayerProfileHandler {
|
||||
/**
|
||||
* Load a player profile.
|
||||
*
|
||||
* @param uuid The UUID.
|
||||
* @return The profile.
|
||||
*/
|
||||
PlayerProfile load(@NotNull UUID uuid);
|
||||
|
||||
/**
|
||||
* Save a player profile.
|
||||
*
|
||||
* @param uuid The uuid.
|
||||
*/
|
||||
void savePlayer(@NotNull UUID uuid);
|
||||
|
||||
/**
|
||||
* Save all player data.
|
||||
*
|
||||
* @param async If the saving should be done asynchronously.
|
||||
*/
|
||||
void saveAll(boolean async);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.willfp.eco.core.data.keys;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* API to register persistent data keys.
|
||||
*/
|
||||
public interface KeyRegistry {
|
||||
/**
|
||||
* Register a persistent data key to be stored.
|
||||
*
|
||||
* @param key The key.
|
||||
*/
|
||||
void registerKey(@NotNull PersistentDataKey<?> key);
|
||||
|
||||
/**
|
||||
* Get all registered keys.
|
||||
*
|
||||
* @return The keys.
|
||||
*/
|
||||
Set<PersistentDataKey<?>> getRegisteredKeys();
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.willfp.eco.core.data.keys;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A persistent data key is a key with a type that can be stored about an offline player.
|
||||
*
|
||||
* @param <T> The type of the data.
|
||||
*/
|
||||
public class PersistentDataKey<T> {
|
||||
/**
|
||||
* The key of the persistent data value.
|
||||
*/
|
||||
@Getter
|
||||
private final NamespacedKey key;
|
||||
|
||||
/**
|
||||
* The default value for the key.
|
||||
*/
|
||||
@Getter
|
||||
private final T defaultValue;
|
||||
|
||||
/**
|
||||
* The persistent data key type.
|
||||
*/
|
||||
@Getter
|
||||
private final PersistentDataKeyType type;
|
||||
|
||||
/**
|
||||
* Create a new Persistent Data Key.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param type The data type.
|
||||
* @param defaultValue The default value.
|
||||
*/
|
||||
public PersistentDataKey(@NotNull final NamespacedKey key,
|
||||
@NotNull final PersistentDataKeyType type,
|
||||
@NotNull final T defaultValue) {
|
||||
this.key = key;
|
||||
this.defaultValue = defaultValue;
|
||||
this.type = type;
|
||||
|
||||
Eco.getHandler().getKeyRegistry().registerKey(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PersistentDataKey{"
|
||||
+ "key=" + key
|
||||
+ ", defaultValue=" + defaultValue
|
||||
+ ", type=" + type
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.willfp.eco.core.data.keys;
|
||||
|
||||
/**
|
||||
* All storable data key types.
|
||||
*/
|
||||
public enum PersistentDataKeyType {
|
||||
/**
|
||||
* String.
|
||||
*/
|
||||
STRING,
|
||||
|
||||
/**
|
||||
* Boolean.
|
||||
*/
|
||||
BOOLEAN,
|
||||
|
||||
/**
|
||||
* Integer.
|
||||
*/
|
||||
INT,
|
||||
|
||||
/**
|
||||
* Double.
|
||||
*/
|
||||
DOUBLE
|
||||
}
|
||||
@@ -20,7 +20,7 @@ public class Display {
|
||||
/**
|
||||
* The display handler.
|
||||
*/
|
||||
public static DisplayHandler handler = null;
|
||||
private static DisplayHandler handler = null;
|
||||
|
||||
/**
|
||||
* Display on ItemStacks.
|
||||
@@ -160,4 +160,20 @@ public class Display {
|
||||
module.display(itemStack, player, args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the display handler.
|
||||
* <p>
|
||||
* Internal API component, you will cause bugs if you create your own handler.
|
||||
*
|
||||
* @param handler The handler.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public static void setHandler(@NotNull final DisplayHandler handler) {
|
||||
if (Display.handler != null) {
|
||||
throw new IllegalStateException("Display already initialized!");
|
||||
}
|
||||
|
||||
Display.handler = handler;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ public interface DisplayHandler {
|
||||
* @param player The player.
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
ItemStack display(@NotNull final ItemStack itemStack,
|
||||
@Nullable final Player player);
|
||||
ItemStack display(@NotNull ItemStack itemStack,
|
||||
@Nullable Player player);
|
||||
|
||||
/**
|
||||
* Revert on ItemStacks.
|
||||
@@ -32,7 +32,7 @@ public interface DisplayHandler {
|
||||
* @param itemStack The item.
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
ItemStack revert(@NotNull final ItemStack itemStack);
|
||||
ItemStack revert(@NotNull ItemStack itemStack);
|
||||
|
||||
/**
|
||||
* Finalize an ItemStacks.
|
||||
@@ -40,7 +40,7 @@ public interface DisplayHandler {
|
||||
* @param itemStack The item.
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
ItemStack finalize(@NotNull final ItemStack itemStack);
|
||||
ItemStack finalize(@NotNull ItemStack itemStack);
|
||||
|
||||
/**
|
||||
* Unfinalize an ItemStacks.
|
||||
@@ -48,7 +48,7 @@ public interface DisplayHandler {
|
||||
* @param itemStack The item.
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
ItemStack unfinalize(@NotNull final ItemStack itemStack);
|
||||
ItemStack unfinalize(@NotNull ItemStack itemStack);
|
||||
|
||||
/**
|
||||
* If an item is finalized.
|
||||
@@ -56,5 +56,5 @@ public interface DisplayHandler {
|
||||
* @param itemStack The item.
|
||||
* @return If finalized.
|
||||
*/
|
||||
boolean isFinalized(@NotNull final ItemStack itemStack);
|
||||
boolean isFinalized(@NotNull ItemStack itemStack);
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ public interface FastItemStack {
|
||||
* @param itemStack The ItemStack.
|
||||
* @return The FastItemStack.
|
||||
*/
|
||||
static FastItemStack wrap(final ItemStack itemStack) {
|
||||
static FastItemStack wrap(@Nullable final ItemStack itemStack) {
|
||||
return Eco.getHandler().createFastItemStack(Objects.requireNonNullElseGet(itemStack, () -> new ItemStack(Material.AIR)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.willfp.eco.core.integrations.afk;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Class to handle afk integrations.
|
||||
*/
|
||||
@UtilityClass
|
||||
public class AFKManager {
|
||||
/**
|
||||
* A set of all registered integrations.
|
||||
*/
|
||||
private final Set<AFKWrapper> registered = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Register a new integration.
|
||||
*
|
||||
* @param integration The integration to register.
|
||||
*/
|
||||
public void register(@NotNull final AFKWrapper integration) {
|
||||
registered.add(integration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if a player is afk.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return If afk.
|
||||
*/
|
||||
public boolean isAfk(@NotNull final Player player) {
|
||||
for (AFKWrapper afkWrapper : registered) {
|
||||
if (afkWrapper.isAfk(player)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.willfp.eco.core.integrations.afk;
|
||||
|
||||
import com.willfp.eco.core.integrations.Integration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Wrapper class for afk integrations.
|
||||
*/
|
||||
public interface AFKWrapper extends Integration {
|
||||
/**
|
||||
* Get if a player is afk.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return If afk.
|
||||
*/
|
||||
boolean isAfk(@NotNull Player player);
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.willfp.eco.core.integrations.economy;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Class to handle economy.
|
||||
*/
|
||||
@UtilityClass
|
||||
public class EconomyManager {
|
||||
/**
|
||||
* A set of all registered integrations.
|
||||
*/
|
||||
private final Set<EconomyWrapper> registered = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Register a new integration.
|
||||
*
|
||||
* @param integration The integration to register.
|
||||
*/
|
||||
public void register(@NotNull final EconomyWrapper integration) {
|
||||
registered.add(integration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if any economy registrations are registered.
|
||||
*
|
||||
* @return If any economy.
|
||||
*/
|
||||
public boolean hasRegistrations() {
|
||||
return !registered.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if a player has a certain amount.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param amount The amount.
|
||||
* @return If the player has the amount.
|
||||
*/
|
||||
public boolean hasAmount(@NotNull final OfflinePlayer player,
|
||||
final double amount) {
|
||||
for (EconomyWrapper wrapper : registered) {
|
||||
return wrapper.hasAmount(player, amount);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Give money to a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param amount The amount to give.
|
||||
* @return If the transaction was a success.
|
||||
*/
|
||||
public boolean giveMoney(@NotNull final OfflinePlayer player,
|
||||
final double amount) {
|
||||
for (EconomyWrapper wrapper : registered) {
|
||||
return wrapper.giveMoney(player, amount);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove money from a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param amount The amount to remove.
|
||||
* @return If the transaction was a success.
|
||||
*/
|
||||
public boolean removeMoney(@NotNull final OfflinePlayer player,
|
||||
final double amount) {
|
||||
for (EconomyWrapper wrapper : registered) {
|
||||
return wrapper.removeMoney(player, amount);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the balance of a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return The balance.
|
||||
*/
|
||||
public double getBalance(@NotNull final OfflinePlayer player) {
|
||||
for (EconomyWrapper wrapper : registered) {
|
||||
return wrapper.getBalance(player);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.willfp.eco.core.integrations.economy;
|
||||
|
||||
import com.willfp.eco.core.integrations.Integration;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Wrapper class for economy integrations.
|
||||
*/
|
||||
public interface EconomyWrapper extends Integration {
|
||||
/**
|
||||
* Get if a player has a certain amount.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param amount The amount.
|
||||
* @return If the player has the amount.
|
||||
*/
|
||||
boolean hasAmount(@NotNull OfflinePlayer player,
|
||||
double amount);
|
||||
|
||||
/**
|
||||
* Give money to a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param amount The amount to give.
|
||||
* @return If the transaction was a success.
|
||||
*/
|
||||
boolean giveMoney(@NotNull OfflinePlayer player,
|
||||
double amount);
|
||||
|
||||
/**
|
||||
* Remove money from a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param amount The amount to remove.
|
||||
* @return If the transaction was a success.
|
||||
*/
|
||||
boolean removeMoney(@NotNull OfflinePlayer player,
|
||||
double amount);
|
||||
|
||||
/**
|
||||
* Get the balance of a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return The balance.
|
||||
*/
|
||||
double getBalance(@NotNull OfflinePlayer player);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.willfp.eco.core.integrations.hologram;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Dummy hologram, created if no integrations are present on the server.
|
||||
*/
|
||||
class DummyHologram implements Hologram {
|
||||
@Override
|
||||
public void remove() {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContents(@NotNull final List<String> contents) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.willfp.eco.core.integrations.hologram;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Wrapper class for plugin-specific holograms.
|
||||
*/
|
||||
public interface Hologram {
|
||||
/**
|
||||
* Remove the hologram.
|
||||
*/
|
||||
void remove();
|
||||
|
||||
/**
|
||||
* Set the hologram contents.
|
||||
*
|
||||
* @param contents The contents.
|
||||
*/
|
||||
void setContents(@NotNull List<String> contents);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.willfp.eco.core.integrations.hologram;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Location;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Class to handle hologram integrations.
|
||||
*/
|
||||
@UtilityClass
|
||||
public class HologramManager {
|
||||
/**
|
||||
* A set of all registered integrations.
|
||||
*/
|
||||
private final Set<HologramWrapper> registered = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Register a new integration.
|
||||
*
|
||||
* @param integration The integration to register.
|
||||
*/
|
||||
public void register(@NotNull final HologramWrapper integration) {
|
||||
registered.add(integration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create hologram.
|
||||
*
|
||||
* @param location The location.
|
||||
* @param contents The contents for the hologram.
|
||||
* @return The hologram.
|
||||
*/
|
||||
public Hologram createHologram(@NotNull final Location location,
|
||||
@NotNull final List<String> contents) {
|
||||
for (HologramWrapper wrapper : registered) {
|
||||
return wrapper.createHologram(location, contents);
|
||||
}
|
||||
|
||||
return new DummyHologram();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.willfp.eco.core.integrations.hologram;
|
||||
|
||||
import com.willfp.eco.core.integrations.Integration;
|
||||
import org.bukkit.Location;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Wrapper class for hologram integrations.
|
||||
*/
|
||||
public interface HologramWrapper extends Integration {
|
||||
/**
|
||||
* Create hologram.
|
||||
*
|
||||
* @param location The location.
|
||||
* @param contents The contents for the hologram.
|
||||
* @return The hologram.
|
||||
*/
|
||||
Hologram createHologram(@NotNull Location location,
|
||||
@NotNull List<String> contents);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.willfp.eco.core.integrations.mcmmo;
|
||||
|
||||
import com.willfp.eco.core.integrations.Integration;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.Event;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -7,7 +8,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* Wrapper class for mcmmo integrations.
|
||||
*/
|
||||
public interface McmmoWrapper {
|
||||
public interface McmmoWrapper extends Integration {
|
||||
/**
|
||||
* Get bonus drop count of block.
|
||||
*
|
||||
|
||||
@@ -8,9 +8,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* Class to handle placeholder integrations.
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.willfp.eco.core.items;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -12,7 +11,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* A custom item has 3 components:
|
||||
* A custom item has 3 components.
|
||||
*
|
||||
* <ul>
|
||||
* <li>The key to identify it</li>
|
||||
|
||||
@@ -49,7 +49,7 @@ public class TextureArgParser implements LookupArgParser {
|
||||
|
||||
assert testMeta != null;
|
||||
|
||||
if (testMeta instanceof SkullMeta skullMeta && finalSkullTexture != null) {
|
||||
if (testMeta instanceof SkullMeta skullMeta) {
|
||||
return finalSkullTexture.equalsIgnoreCase(SkullUtils.getSkullTexture(skullMeta));
|
||||
}
|
||||
|
||||
|
||||
@@ -36,5 +36,5 @@ public abstract class ItemProvider {
|
||||
* @return The TestableItem, or null if not found.
|
||||
*/
|
||||
@Nullable
|
||||
public abstract TestableItem provideForKey(@NotNull final String key);
|
||||
public abstract TestableItem provideForKey(@NotNull String key);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.willfp.eco.core.recipe.parts;
|
||||
|
||||
import com.willfp.eco.core.items.TestableItem;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.willfp.eco.core.Eco;
|
||||
import lombok.Getter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -11,7 +12,6 @@ import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@@ -40,45 +40,42 @@ public class Paste {
|
||||
* <p>
|
||||
* Runs asynchronously to avoid hangups.
|
||||
*
|
||||
* @param responseHandler The consumer to accept the response token.
|
||||
* @param callback The consumer to accept the response token.
|
||||
*/
|
||||
public void getHastebinToken(@NotNull final Consumer<String> responseHandler) {
|
||||
public void getHastebinToken(@NotNull final Consumer<String> callback) {
|
||||
Eco.getHandler().getEcoPlugin().getScheduler().runAsync(() -> {
|
||||
try {
|
||||
String url = "https://hastebin.com/documents";
|
||||
URL obj = new URL(url);
|
||||
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
|
||||
byte[] postData = contents.getBytes(StandardCharsets.UTF_8);
|
||||
int postDataLength = postData.length;
|
||||
|
||||
con.setRequestMethod("POST");
|
||||
con.setRequestProperty("Content-Type", "application/json");
|
||||
String requestURL = "https://hastebin.com/documents";
|
||||
URL url = new URL(requestURL);
|
||||
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
|
||||
conn.setDoOutput(true);
|
||||
conn.setInstanceFollowRedirects(false);
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setRequestProperty("User-Agent", "eco-Hastebin");
|
||||
conn.setRequestProperty("Content-Length", Integer.toString(postDataLength));
|
||||
conn.setUseCaches(false);
|
||||
|
||||
con.setDoOutput(true);
|
||||
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
|
||||
wr.writeBytes(URLEncoder.encode(contents, StandardCharsets.UTF_8));
|
||||
wr.flush();
|
||||
wr.close();
|
||||
String response;
|
||||
DataOutputStream wr;
|
||||
|
||||
BufferedReader iny = new BufferedReader(
|
||||
new InputStreamReader(con.getInputStream()));
|
||||
String output;
|
||||
StringBuilder responseBuilder = new StringBuilder();
|
||||
wr = new DataOutputStream(conn.getOutputStream());
|
||||
wr.write(postData);
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
response = reader.readLine();
|
||||
|
||||
while ((output = iny.readLine()) != null) {
|
||||
responseBuilder.append(output);
|
||||
assert response != null;
|
||||
|
||||
if (response.contains("\"key\"")) {
|
||||
response = response.substring(response.indexOf(":") + 2, response.length() - 2);
|
||||
|
||||
callback.accept(response);
|
||||
}
|
||||
iny.close();
|
||||
|
||||
String responseString = responseBuilder.toString();
|
||||
|
||||
responseString = responseString.replace("{\"key\":\"", "");
|
||||
responseString = responseString.replace("\"}", "");
|
||||
|
||||
responseHandler.accept(responseString);
|
||||
} catch (IOException e) {
|
||||
responseHandler.accept(e.getMessage());
|
||||
callback.accept(e.getMessage());
|
||||
}
|
||||
|
||||
responseHandler.accept("");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -96,7 +93,7 @@ public class Paste {
|
||||
conn.setRequestMethod("GET");
|
||||
try (var reader = new BufferedReader(
|
||||
new InputStreamReader(conn.getInputStream()))) {
|
||||
for (String line; (line = reader.readLine()) != null; ) {
|
||||
for (String line; (line = reader.readLine()) != null;) {
|
||||
result.append(line);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,9 +26,9 @@ public class UpdateChecker extends PluginDependent<EcoPlugin> {
|
||||
/**
|
||||
* Get the latest version of the plugin.
|
||||
*
|
||||
* @param consumer The process to run after checking.
|
||||
* @param callback The process to run after checking.
|
||||
*/
|
||||
public void getVersion(@NotNull final Consumer<? super String> consumer) {
|
||||
public void getVersion(@NotNull final Consumer<? super String> callback) {
|
||||
this.getPlugin().getScheduler().runAsync(() -> {
|
||||
try {
|
||||
InputStream inputStream = new URL(
|
||||
@@ -37,7 +37,7 @@ public class UpdateChecker extends PluginDependent<EcoPlugin> {
|
||||
Scanner scanner = new Scanner(inputStream);
|
||||
|
||||
if (scanner.hasNext()) {
|
||||
consumer.accept(scanner.next());
|
||||
callback.accept(scanner.next());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
this.getPlugin().getLogger().warning("Failed to check for updates: " + e.getMessage());
|
||||
|
||||
@@ -2,12 +2,14 @@ package com.willfp.eco.util;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -92,6 +94,21 @@ public class BlockUtils {
|
||||
blockBreakConsumer.accept(player, block);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if a block was placed by a player.
|
||||
*
|
||||
* @param block The block.
|
||||
* @return If placed by a player.
|
||||
*/
|
||||
public boolean isPlayerPlaced(@NotNull final Block block) {
|
||||
Chunk chunk = block.getChunk();
|
||||
|
||||
return chunk.getPersistentDataContainer().has(
|
||||
NamespacedKeyUtils.createEcoKey(Integer.toString(block.getLocation().hashCode(), 16)),
|
||||
PersistentDataType.INTEGER
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the block break function.
|
||||
*
|
||||
|
||||
@@ -5,7 +5,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Utilities / API methods for lists.
|
||||
@@ -21,8 +23,8 @@ public class ListUtils {
|
||||
* @return The list, filled will null objects.
|
||||
*/
|
||||
@NotNull
|
||||
public <@Nullable T> List<List<T>> create2DList(final int rows,
|
||||
final int columns) {
|
||||
public static <@Nullable T> List<List<T>> create2DList(final int rows,
|
||||
final int columns) {
|
||||
List<List<T>> list = new ArrayList<>(rows);
|
||||
while (list.size() < rows) {
|
||||
List<T> row = new ArrayList<>(columns);
|
||||
@@ -34,4 +36,25 @@ public class ListUtils {
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a list potentially containing duplicates to a map where the value is the frequency of the key.
|
||||
*
|
||||
* @param list The list.
|
||||
* @param <T> The type parameter of the list.
|
||||
* @return The frequency map.
|
||||
*/
|
||||
@NotNull
|
||||
public static <T> Map<T, Integer> listToFrequencyMap(@NotNull final List<T> list) {
|
||||
Map<T, Integer> frequencyMap = new HashMap<>();
|
||||
for (T object : list) {
|
||||
if (frequencyMap.containsKey(object)) {
|
||||
frequencyMap.put(object, frequencyMap.get(object) + 1);
|
||||
} else {
|
||||
frequencyMap.put(object, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return frequencyMap;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.willfp.eco.util;
|
||||
|
||||
import lombok.experimental.NonFinal;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
@@ -2,9 +2,13 @@ package com.willfp.eco.util;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.Prerequisite;
|
||||
import com.willfp.eco.core.data.PlayerProfile;
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey;
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKeyType;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -14,6 +18,15 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
@UtilityClass
|
||||
public class PlayerUtils {
|
||||
/**
|
||||
* The data key for saved player names.
|
||||
*/
|
||||
private static final PersistentDataKey<String> PLAYER_NAME_KEY = new PersistentDataKey<>(
|
||||
NamespacedKeyUtils.createEcoKey("player_name"),
|
||||
PersistentDataKeyType.STRING,
|
||||
"Unknown Player"
|
||||
);
|
||||
|
||||
/**
|
||||
* Get the audience from a player.
|
||||
*
|
||||
@@ -63,4 +76,30 @@ public class PlayerUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get saved display name for an offline player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return The player name.
|
||||
*/
|
||||
public String getSavedDisplayName(@NotNull final OfflinePlayer player) {
|
||||
PlayerProfile profile = PlayerProfile.load(player);
|
||||
|
||||
if (player instanceof Player onlinePlayer) {
|
||||
profile.write(PLAYER_NAME_KEY, onlinePlayer.getDisplayName());
|
||||
}
|
||||
|
||||
return profile.read(PLAYER_NAME_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the saved display name for a player.
|
||||
*
|
||||
* @param player The player.
|
||||
*/
|
||||
public void updateSavedDisplayName(@NotNull final Player player) {
|
||||
PlayerProfile profile = PlayerProfile.load(player);
|
||||
profile.write(PLAYER_NAME_KEY, player.getDisplayName());
|
||||
}
|
||||
}
|
||||
|
||||
47
eco-api/src/main/java/com/willfp/eco/util/PotionUtils.java
Normal file
47
eco-api/src/main/java/com/willfp/eco/util/PotionUtils.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package com.willfp.eco.util;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.potion.PotionData;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Utilities / API methods for potions.
|
||||
*/
|
||||
@UtilityClass
|
||||
public class PotionUtils {
|
||||
/**
|
||||
* Get the duration (in ticks) for potion data.
|
||||
*
|
||||
* @param data The data.
|
||||
* @return The duration.
|
||||
*/
|
||||
public int getDuration(@NotNull final PotionData data) {
|
||||
if (data.isExtended()) {
|
||||
return switch (data.getType()) {
|
||||
case INSTANT_DAMAGE, INSTANT_HEAL: yield 0;
|
||||
case POISON, REGEN: yield 1800;
|
||||
case SLOW_FALLING, WEAKNESS, SLOWNESS: yield 4800;
|
||||
case TURTLE_MASTER: yield 800;
|
||||
default: yield 9600;
|
||||
};
|
||||
}
|
||||
|
||||
if (data.isUpgraded()) {
|
||||
return switch (data.getType()) {
|
||||
case INSTANT_DAMAGE, INSTANT_HEAL: yield 0;
|
||||
case POISON, REGEN: yield 420;
|
||||
case SLOW_FALLING, WEAKNESS, SLOWNESS: yield 440;
|
||||
case TURTLE_MASTER: yield 400;
|
||||
default: yield 1800;
|
||||
};
|
||||
}
|
||||
|
||||
return switch (data.getType()) {
|
||||
case INSTANT_DAMAGE, INSTANT_HEAL: yield 0;
|
||||
case POISON, REGEN: yield 900;
|
||||
case SLOW_FALLING, WEAKNESS, SLOWNESS: yield 400;
|
||||
case TURTLE_MASTER: yield 1800;
|
||||
default: yield 3600;
|
||||
};
|
||||
}
|
||||
}
|
||||
48
eco-api/src/main/java/com/willfp/eco/util/ServerUtils.java
Normal file
48
eco-api/src/main/java/com/willfp/eco/util/ServerUtils.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package com.willfp.eco.util;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Utilities / API methods for the server.
|
||||
*/
|
||||
@UtilityClass
|
||||
public class ServerUtils {
|
||||
/**
|
||||
* The TPS supplier.
|
||||
*/
|
||||
private Supplier<Double> tpsSupplier = null;
|
||||
|
||||
/**
|
||||
* Get the current server TPS.
|
||||
*
|
||||
* @return The TPS.
|
||||
*/
|
||||
public double getTps() {
|
||||
Validate.notNull(tpsSupplier, "Not initialized!");
|
||||
|
||||
double tps = tpsSupplier.get();
|
||||
|
||||
if (tps > 20) {
|
||||
return 20;
|
||||
} else {
|
||||
return tps;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the tps supplier function.
|
||||
*
|
||||
* @param function The function.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public void initialize(@NotNull final Supplier<Double> function) {
|
||||
Validate.isTrue(tpsSupplier == null, "Already initialized!");
|
||||
|
||||
tpsSupplier = function;
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@@ -7,4 +7,5 @@ dependencies {
|
||||
compileOnly 'org.reflections:reflections:0.9.12'
|
||||
compileOnly 'net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT'
|
||||
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
|
||||
compileOnly 'com.google.guava:guava:31.0.1-jre'
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.willfp.eco.internal.config
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.PluginLike
|
||||
import com.willfp.eco.core.config.interfaces.Config
|
||||
import com.willfp.eco.core.config.interfaces.JSONConfig
|
||||
|
||||
@@ -2,7 +2,12 @@ package com.willfp.eco.internal.config.json
|
||||
|
||||
import com.willfp.eco.core.PluginLike
|
||||
import com.willfp.eco.core.config.interfaces.LoadableConfig
|
||||
import java.io.*
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.FileOutputStream
|
||||
import java.io.FileReader
|
||||
import java.io.IOException
|
||||
import java.io.OutputStream
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.StandardOpenOption
|
||||
|
||||
@@ -76,7 +81,7 @@ open class EcoLoadableJSONConfig(
|
||||
}
|
||||
|
||||
init {
|
||||
val directory: File = File(this.plugin.dataFolder, subDirectoryPath)
|
||||
val directory = File(this.plugin.dataFolder, subDirectoryPath)
|
||||
if (!directory.exists()) {
|
||||
directory.mkdirs()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.willfp.eco.internal.data
|
||||
|
||||
import com.willfp.eco.core.data.PlayerProfile
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||
|
||||
class EcoPlayerProfile(
|
||||
val data: MutableMap<PersistentDataKey<*>, Any>
|
||||
) : PlayerProfile {
|
||||
override fun <T : Any> write(key: PersistentDataKey<T>, value: T) {
|
||||
this.data[key] = value
|
||||
}
|
||||
|
||||
override fun <T : Any> read(key: PersistentDataKey<T>): T {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return this.data[key] as T? ?: key.defaultValue
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.willfp.eco.internal.display
|
||||
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.display.Display
|
||||
import com.willfp.eco.core.display.DisplayHandler
|
||||
@@ -10,16 +11,11 @@ import org.bukkit.NamespacedKey
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
import java.util.concurrent.ExecutorService
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
class EcoDisplayHandler(plugin: EcoPlugin) : DisplayHandler {
|
||||
/**
|
||||
* All registered display modules.
|
||||
*/
|
||||
private val registeredModules = mutableMapOf<DisplayPriority, MutableList<DisplayModule>>()
|
||||
|
||||
/**
|
||||
* NamespacedKey for finalizing.
|
||||
*/
|
||||
private val finalizeKey: NamespacedKey = plugin.namespacedKeyFactory.create("finalized")
|
||||
|
||||
init {
|
||||
|
||||
@@ -12,10 +12,9 @@ import org.bukkit.event.player.PlayerExpChangeEvent
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.util.Vector
|
||||
|
||||
open class EcoDropQueue(player: Player) : InternalDropQueue {
|
||||
open class EcoDropQueue(val player: Player) : InternalDropQueue {
|
||||
val items = mutableListOf<ItemStack>()
|
||||
var xp: Int = 0
|
||||
val player: Player
|
||||
var loc: Location
|
||||
var hasTelekinesis = false
|
||||
|
||||
@@ -79,7 +78,6 @@ open class EcoDropQueue(player: Player) : InternalDropQueue {
|
||||
}
|
||||
|
||||
init {
|
||||
this.player = player
|
||||
loc = player.location
|
||||
}
|
||||
}
|
||||
@@ -36,8 +36,9 @@ class Skull : SkullProxy {
|
||||
profile = meta.javaClass.getDeclaredField("profile")
|
||||
profile.isAccessible = true
|
||||
}
|
||||
val profile = profile[meta] as GameProfile?
|
||||
val property = profile?.properties?.get("textures") as Property?
|
||||
return property?.value
|
||||
val profile = profile[meta] as GameProfile? ?: return null
|
||||
val properties = profile.properties ?: return null
|
||||
val prop = properties["textures"] ?: return null
|
||||
return prop.toMutableList().firstOrNull()?.name
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.willfp.eco.proxy.v1_16_R3
|
||||
|
||||
import com.willfp.eco.proxy.TPSProxy
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.craftbukkit.v1_16_R3.CraftServer
|
||||
|
||||
class TPS : TPSProxy {
|
||||
override fun getTPS(): Double {
|
||||
return (Bukkit.getServer() as CraftServer).handle.server.recentTps[0]
|
||||
}
|
||||
}
|
||||
@@ -36,8 +36,9 @@ class Skull : SkullProxy {
|
||||
profile = meta.javaClass.getDeclaredField("profile")
|
||||
profile.isAccessible = true
|
||||
}
|
||||
val profile = profile[meta] as GameProfile?
|
||||
val property = profile?.properties?.get("textures") as Property?
|
||||
return property?.value
|
||||
val profile = profile[meta] as GameProfile? ?: return null
|
||||
val properties = profile.properties ?: return null
|
||||
val prop = properties["textures"] ?: return null
|
||||
return prop.toMutableList().firstOrNull()?.name
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.willfp.eco.proxy.v1_17_R1
|
||||
|
||||
import com.willfp.eco.proxy.TPSProxy
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.craftbukkit.v1_17_R1.CraftServer
|
||||
|
||||
class TPS : TPSProxy {
|
||||
override fun getTPS(): Double {
|
||||
return (Bukkit.getServer() as CraftServer).handle.server.recentTps[0]
|
||||
}
|
||||
}
|
||||
@@ -7,11 +7,11 @@ dependencies {
|
||||
exclude group: 'net.kyori', module: 'adventure-api'
|
||||
}
|
||||
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
|
||||
compileOnly 'net.kyori:adventure-api:4.9.1'
|
||||
compileOnly 'net.kyori:adventure-api:4.9.2'
|
||||
compileOnly 'net.kyori:adventure-text-serializer-gson:4.9.2'
|
||||
compileOnly 'net.kyori:adventure-text-serializer-legacy:4.8.1'
|
||||
compileOnly 'org.apache.maven:maven-artifact:3.0.3'
|
||||
compileOnly 'com.google.code.gson:gson:2.8.7'
|
||||
compileOnly 'net.kyori:adventure-text-serializer-legacy:4.9.2'
|
||||
compileOnly 'org.apache.maven:maven-artifact:3.8.1'
|
||||
compileOnly 'com.google.code.gson:gson:2.8.8'
|
||||
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
|
||||
compileOnly project(":eco-core:core-proxy")
|
||||
compileOnly project(":eco-core:core-backend")
|
||||
@@ -19,7 +19,7 @@ dependencies {
|
||||
compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.7-SNAPSHOT'
|
||||
compileOnly 'com.github.TechFortress:GriefPrevention:16.17.1'
|
||||
compileOnly 'com.massivecraft:Factions:1.6.9.5-U0.5.10'
|
||||
compileOnly 'com.github.cryptomorin:kingdoms:1.10.14'
|
||||
compileOnly 'com.github.cryptomorin:kingdoms:1.11.9'
|
||||
compileOnly 'com.github.TownyAdvanced:Towny:0.97.2.6'
|
||||
compileOnly 'com.github.angeschossen:LandsAPI:5.15.2'
|
||||
compileOnly 'fr.neatmonster:nocheatplus:3.16.1-SNAPSHOT'
|
||||
@@ -30,6 +30,16 @@ dependencies {
|
||||
compileOnly 'com.github.brcdev-minecraft:shopgui-api:2.2.0'
|
||||
compileOnly 'com.github.LoneDev6:API-ItemsAdder:2.4.7'
|
||||
compileOnly 'com.arcaniax:HeadDatabase-API:1.3.0'
|
||||
compileOnly 'org.jetbrains.exposed:exposed-core:0.35.1'
|
||||
compileOnly 'org.jetbrains.exposed:exposed-dao:0.35.1'
|
||||
compileOnly 'org.jetbrains.exposed:exposed-jdbc:0.35.1'
|
||||
compileOnly 'mysql:mysql-connector-java:8.0.25'
|
||||
compileOnly 'com.gmail.filoghost.holographicdisplays:holographicdisplays-api:2.4.0'
|
||||
compileOnly 'net.essentialsx:EssentialsX:2.19.0'
|
||||
compileOnly 'com.bgsoftware:SuperiorSkyblockAPI:latest'
|
||||
compileOnly 'com.github.MilkBowl:VaultAPI:1.7'
|
||||
compileOnly 'world.bentobox:bentobox:1.17.3-SNAPSHOT'
|
||||
compileOnly 'com.google.guava:guava:31.0.1-jre'
|
||||
|
||||
// CombatLogX V10 + NewbieHelper Expansion
|
||||
compileOnly 'com.SirBlobman.combatlogx:CombatLogX-API:10.0.0.0-SNAPSHOT'
|
||||
|
||||
@@ -4,6 +4,8 @@ import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.Handler
|
||||
import com.willfp.eco.core.config.updating.ConfigHandler
|
||||
import com.willfp.eco.core.config.wrapper.ConfigFactory
|
||||
import com.willfp.eco.core.data.PlayerProfileHandler
|
||||
import com.willfp.eco.core.data.keys.KeyRegistry
|
||||
import com.willfp.eco.core.drops.DropQueueFactory
|
||||
import com.willfp.eco.core.events.EventManager
|
||||
import com.willfp.eco.core.extensions.ExtensionLoader
|
||||
@@ -34,6 +36,8 @@ import com.willfp.eco.internal.proxy.EcoProxyFactory
|
||||
import com.willfp.eco.internal.requirement.EcoRequirementFactory
|
||||
import com.willfp.eco.internal.scheduling.EcoScheduler
|
||||
import com.willfp.eco.proxy.FastItemStackFactoryProxy
|
||||
import com.willfp.eco.spigot.data.EcoKeyRegistry
|
||||
import com.willfp.eco.spigot.data.EcoPlayerProfileHandler
|
||||
import com.willfp.eco.spigot.integrations.bstats.MetricHandler
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences
|
||||
import org.bukkit.inventory.ItemStack
|
||||
@@ -44,6 +48,8 @@ class EcoHandler : EcoSpigotPlugin(), Handler {
|
||||
private val cleaner = EcoCleaner()
|
||||
private val requirementFactory = EcoRequirementFactory()
|
||||
private var adventure: BukkitAudiences? = null
|
||||
private val keyRegistry = EcoKeyRegistry(this)
|
||||
private val playerProfileHandler = EcoPlayerProfileHandler(this)
|
||||
|
||||
override fun createScheduler(plugin: EcoPlugin): Scheduler {
|
||||
return EcoScheduler(plugin)
|
||||
@@ -133,6 +139,14 @@ class EcoHandler : EcoSpigotPlugin(), Handler {
|
||||
return adventure
|
||||
}
|
||||
|
||||
override fun getKeyRegistry(): KeyRegistry {
|
||||
return keyRegistry
|
||||
}
|
||||
|
||||
override fun getPlayerProfileHandler(): PlayerProfileHandler {
|
||||
return playerProfileHandler
|
||||
}
|
||||
|
||||
fun setAdventure(adventure: BukkitAudiences) {
|
||||
this.adventure = adventure
|
||||
}
|
||||
|
||||
@@ -6,9 +6,12 @@ import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.Prerequisite
|
||||
import com.willfp.eco.core.display.Display
|
||||
import com.willfp.eco.core.integrations.IntegrationLoader
|
||||
import com.willfp.eco.core.integrations.afk.AFKManager
|
||||
import com.willfp.eco.core.integrations.anticheat.AnticheatManager
|
||||
import com.willfp.eco.core.integrations.antigrief.AntigriefManager
|
||||
import com.willfp.eco.core.integrations.customitems.CustomItemsManager
|
||||
import com.willfp.eco.core.integrations.economy.EconomyManager
|
||||
import com.willfp.eco.core.integrations.hologram.HologramManager
|
||||
import com.willfp.eco.core.integrations.mcmmo.McmmoManager
|
||||
import com.willfp.eco.core.integrations.shop.ShopManager
|
||||
import com.willfp.eco.core.items.Items
|
||||
@@ -19,8 +22,20 @@ import com.willfp.eco.internal.drops.DropManager
|
||||
import com.willfp.eco.proxy.BlockBreakProxy
|
||||
import com.willfp.eco.proxy.FastItemStackFactoryProxy
|
||||
import com.willfp.eco.proxy.SkullProxy
|
||||
import com.willfp.eco.proxy.TPSProxy
|
||||
import com.willfp.eco.spigot.arrows.ArrowDataListener
|
||||
import com.willfp.eco.spigot.display.*
|
||||
import com.willfp.eco.spigot.data.DataListener
|
||||
import com.willfp.eco.spigot.data.EcoPlayerProfileHandler
|
||||
import com.willfp.eco.spigot.data.PlayerBlockListener
|
||||
import com.willfp.eco.spigot.data.storage.DataHandler
|
||||
import com.willfp.eco.spigot.data.storage.MySQLDataHandler
|
||||
import com.willfp.eco.spigot.data.storage.YamlDataHandler
|
||||
import com.willfp.eco.spigot.display.PacketAutoRecipe
|
||||
import com.willfp.eco.spigot.display.PacketChat
|
||||
import com.willfp.eco.spigot.display.PacketOpenWindowMerchant
|
||||
import com.willfp.eco.spigot.display.PacketSetCreativeSlot
|
||||
import com.willfp.eco.spigot.display.PacketSetSlot
|
||||
import com.willfp.eco.spigot.display.PacketWindowItems
|
||||
import com.willfp.eco.spigot.display.frame.clearFrames
|
||||
import com.willfp.eco.spigot.drops.CollatedRunnable
|
||||
import com.willfp.eco.spigot.eventlisteners.EntityDeathByEntityListeners
|
||||
@@ -29,25 +44,44 @@ import com.willfp.eco.spigot.eventlisteners.PlayerJumpListeners
|
||||
import com.willfp.eco.spigot.eventlisteners.armor.ArmorChangeEventListeners
|
||||
import com.willfp.eco.spigot.eventlisteners.armor.ArmorListener
|
||||
import com.willfp.eco.spigot.gui.GUIListener
|
||||
import com.willfp.eco.spigot.integrations.anticheat.*
|
||||
import com.willfp.eco.spigot.integrations.antigrief.*
|
||||
import com.willfp.eco.spigot.integrations.afk.AFKIntegrationCMI
|
||||
import com.willfp.eco.spigot.integrations.afk.AFKIntegrationEssentials
|
||||
import com.willfp.eco.spigot.integrations.anticheat.AnticheatAAC
|
||||
import com.willfp.eco.spigot.integrations.anticheat.AnticheatAlice
|
||||
import com.willfp.eco.spigot.integrations.anticheat.AnticheatMatrix
|
||||
import com.willfp.eco.spigot.integrations.anticheat.AnticheatNCP
|
||||
import com.willfp.eco.spigot.integrations.anticheat.AnticheatSpartan
|
||||
import com.willfp.eco.spigot.integrations.anticheat.AnticheatVulcan
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefBentoBox
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefCombatLogXV10
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefCombatLogXV11
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefFactionsUUID
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefGriefPrevention
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefKingdoms
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefLands
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefSuperiorSkyblock2
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefTowny
|
||||
import com.willfp.eco.spigot.integrations.antigrief.AntigriefWorldGuard
|
||||
import com.willfp.eco.spigot.integrations.customitems.CustomItemsHeadDatabase
|
||||
import com.willfp.eco.spigot.integrations.customitems.CustomItemsItemsAdder
|
||||
import com.willfp.eco.spigot.integrations.customitems.CustomItemsOraxen
|
||||
import com.willfp.eco.spigot.integrations.economy.EconomyVault
|
||||
import com.willfp.eco.spigot.integrations.hologram.HologramCMI
|
||||
import com.willfp.eco.spigot.integrations.hologram.HologramGHolo
|
||||
import com.willfp.eco.spigot.integrations.hologram.HologramHolographicDisplays
|
||||
import com.willfp.eco.spigot.integrations.mcmmo.McmmoIntegrationImpl
|
||||
import com.willfp.eco.spigot.integrations.multiverseinventories.MultiverseInventoriesIntegration
|
||||
import com.willfp.eco.spigot.integrations.shop.ShopShopGuiPlus
|
||||
import com.willfp.eco.spigot.recipes.ShapedRecipeListener
|
||||
import com.willfp.eco.util.BlockUtils
|
||||
import com.willfp.eco.util.ServerUtils
|
||||
import com.willfp.eco.util.SkullUtils
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences
|
||||
import net.milkbowl.vault.economy.Economy
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.block.Block
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.meta.SkullMeta
|
||||
|
||||
abstract class EcoSpigotPlugin : EcoPlugin(
|
||||
773,
|
||||
@@ -55,24 +89,32 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
||||
"com.willfp.eco.proxy",
|
||||
"&a"
|
||||
) {
|
||||
lateinit var dataHandler: DataHandler
|
||||
|
||||
init {
|
||||
Items.registerArgParser(EnchantmentArgParser())
|
||||
Items.registerArgParser(TextureArgParser())
|
||||
|
||||
val skullProxy = getProxy(SkullProxy::class.java)
|
||||
SkullUtils.initialize(
|
||||
{ meta: SkullMeta, base64: String -> skullProxy.setSkullTexture(meta, base64) },
|
||||
{ meta: SkullMeta -> skullProxy.getSkullTexture(meta) }
|
||||
{ meta, base64 -> skullProxy.setSkullTexture(meta, base64) },
|
||||
{ meta -> skullProxy.getSkullTexture(meta) }
|
||||
)
|
||||
|
||||
val blockBreakProxy = getProxy(BlockBreakProxy::class.java)
|
||||
BlockUtils.initialize { player: Player, block: Block -> blockBreakProxy.breakBlock(player, block) }
|
||||
BlockUtils.initialize { player, block -> blockBreakProxy.breakBlock(player, block) }
|
||||
|
||||
val tpsProxy = getProxy(TPSProxy::class.java)
|
||||
ServerUtils.initialize { tpsProxy.getTPS() }
|
||||
|
||||
postInit()
|
||||
}
|
||||
|
||||
private fun postInit() {
|
||||
Display.handler = EcoDisplayHandler(this)
|
||||
Display.setHandler(EcoDisplayHandler(this))
|
||||
|
||||
this.dataHandler = if (this.configYml.getBool("mysql.enabled"))
|
||||
MySQLDataHandler(this) else YamlDataHandler(this)
|
||||
}
|
||||
|
||||
override fun handleEnable() {
|
||||
@@ -113,6 +155,14 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
||||
this.configYml.getInt("display-frame-ttl").toLong(),
|
||||
this.configYml.getInt("display-frame-ttl").toLong()
|
||||
)
|
||||
this.scheduler.runTimer(
|
||||
{
|
||||
(Eco.getHandler().playerProfileHandler as EcoPlayerProfileHandler)
|
||||
.autosave(this.configYml.getBool("autosave.async"))
|
||||
},
|
||||
this.configYml.getInt("autosave.ticks").toLong(),
|
||||
this.configYml.getInt("autosave.ticks").toLong()
|
||||
)
|
||||
}
|
||||
|
||||
override fun handleAfterLoad() {
|
||||
@@ -123,6 +173,8 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
||||
override fun loadIntegrationLoaders(): List<IntegrationLoader> {
|
||||
return listOf(
|
||||
// AntiGrief
|
||||
IntegrationLoader("SuperiorSkyblock2") { AntigriefManager.register(AntigriefSuperiorSkyblock2()) },
|
||||
IntegrationLoader("BentoBox") { AntigriefManager.register(AntigriefBentoBox()) },
|
||||
IntegrationLoader("WorldGuard") { AntigriefManager.register(AntigriefWorldGuard()) },
|
||||
IntegrationLoader("GriefPrevention") { AntigriefManager.register(AntigriefGriefPrevention()) },
|
||||
IntegrationLoader("FactionsUUID") { AntigriefManager.register(AntigriefFactionsUUID()) },
|
||||
@@ -157,9 +209,30 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
||||
// Shop
|
||||
IntegrationLoader("ShopGUIPlus") { ShopManager.register(ShopShopGuiPlus()) },
|
||||
|
||||
// Hologram
|
||||
IntegrationLoader("HolographicDisplays") { HologramManager.register(HologramHolographicDisplays(this)) },
|
||||
IntegrationLoader("CMI") { HologramManager.register(HologramCMI()) },
|
||||
IntegrationLoader("GHolo") { HologramManager.register(HologramGHolo()) },
|
||||
|
||||
// AFK
|
||||
IntegrationLoader("Essentials") { AFKManager.register(AFKIntegrationEssentials()) },
|
||||
IntegrationLoader("CMI") { AFKManager.register(AFKIntegrationCMI()) },
|
||||
|
||||
// Economy
|
||||
IntegrationLoader("Vault") {
|
||||
val rsp = Bukkit.getServer().servicesManager.getRegistration(Economy::class.java)
|
||||
if (rsp != null) {
|
||||
EconomyManager.register(EconomyVault(rsp.provider))
|
||||
}
|
||||
},
|
||||
|
||||
// Misc
|
||||
IntegrationLoader("mcMMO") { McmmoManager.register(McmmoIntegrationImpl()) },
|
||||
IntegrationLoader("Multiverse-Inventories") { this.eventManager.registerListener(MultiverseInventoriesIntegration(this)) }
|
||||
IntegrationLoader("Multiverse-Inventories") {
|
||||
this.eventManager.registerListener(
|
||||
MultiverseInventoriesIntegration(this)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -183,7 +256,9 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
||||
PlayerJumpListeners(),
|
||||
GUIListener(this),
|
||||
ArrowDataListener(this),
|
||||
ArmorChangeEventListeners(this)
|
||||
ArmorChangeEventListeners(this),
|
||||
DataListener(),
|
||||
PlayerBlockListener(this)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.willfp.eco.spigot.data
|
||||
|
||||
import com.willfp.eco.core.Eco
|
||||
import com.willfp.eco.util.PlayerUtils
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.player.PlayerJoinEvent
|
||||
import org.bukkit.event.player.PlayerQuitEvent
|
||||
|
||||
class DataListener : Listener {
|
||||
@EventHandler
|
||||
fun onLeave(event: PlayerQuitEvent) {
|
||||
PlayerUtils.updateSavedDisplayName(event.player)
|
||||
Eco.getHandler().playerProfileHandler.savePlayer(event.player.uniqueId)
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onJoin(event: PlayerJoinEvent) {
|
||||
PlayerUtils.updateSavedDisplayName(event.player)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.willfp.eco.spigot.data
|
||||
|
||||
import com.willfp.eco.core.data.keys.KeyRegistry
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKeyType
|
||||
import com.willfp.eco.spigot.EcoSpigotPlugin
|
||||
import org.bukkit.NamespacedKey
|
||||
|
||||
class EcoKeyRegistry(
|
||||
private val plugin: EcoSpigotPlugin
|
||||
) : KeyRegistry {
|
||||
private val registry = mutableMapOf<NamespacedKey, PersistentDataKey<*>>()
|
||||
|
||||
override fun registerKey(key: PersistentDataKey<*>) {
|
||||
if (this.registry.containsKey(key.key)) {
|
||||
this.registry.remove(key.key)
|
||||
}
|
||||
|
||||
validateKey(key)
|
||||
|
||||
this.registry[key.key] = key
|
||||
|
||||
plugin.dataHandler.updateKeys()
|
||||
}
|
||||
|
||||
override fun getRegisteredKeys(): MutableSet<PersistentDataKey<*>> {
|
||||
return registry.values.toMutableSet()
|
||||
}
|
||||
|
||||
private fun <T> validateKey(key: PersistentDataKey<T>) {
|
||||
when (key.type) {
|
||||
PersistentDataKeyType.INT -> if (key.defaultValue !is Int) {
|
||||
throw IllegalArgumentException("Invalid Data Type! Should be Int")
|
||||
}
|
||||
PersistentDataKeyType.DOUBLE -> if (key.defaultValue !is Double) {
|
||||
throw IllegalArgumentException("Invalid Data Type! Should be Double")
|
||||
}
|
||||
PersistentDataKeyType.BOOLEAN -> if (key.defaultValue !is Boolean) {
|
||||
throw IllegalArgumentException("Invalid Data Type! Should be Boolean")
|
||||
}
|
||||
PersistentDataKeyType.STRING -> if (key.defaultValue !is String) {
|
||||
throw IllegalArgumentException("Invalid Data Type! Should be String")
|
||||
}
|
||||
|
||||
else -> throw NullPointerException("Null value found!")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.willfp.eco.spigot.data
|
||||
|
||||
import com.willfp.eco.core.Eco
|
||||
import com.willfp.eco.core.data.PlayerProfile
|
||||
import com.willfp.eco.core.data.PlayerProfileHandler
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||
import com.willfp.eco.internal.data.EcoPlayerProfile
|
||||
import com.willfp.eco.spigot.EcoSpigotPlugin
|
||||
import org.bukkit.Bukkit
|
||||
import java.util.*
|
||||
|
||||
class EcoPlayerProfileHandler(
|
||||
private val plugin: EcoSpigotPlugin
|
||||
) : PlayerProfileHandler {
|
||||
private val loaded = mutableMapOf<UUID, PlayerProfile>()
|
||||
private val handler = plugin.dataHandler
|
||||
|
||||
override fun load(uuid: UUID): PlayerProfile {
|
||||
val found = loaded[uuid]
|
||||
if (found != null) {
|
||||
return found
|
||||
}
|
||||
|
||||
val data = mutableMapOf<PersistentDataKey<*>, Any>()
|
||||
|
||||
for (key in Eco.getHandler().keyRegistry.registeredKeys) {
|
||||
data[key] = handler.read(uuid, key.key) ?: key.defaultValue
|
||||
}
|
||||
|
||||
val profile = EcoPlayerProfile(data)
|
||||
loaded[uuid] = profile
|
||||
return profile
|
||||
}
|
||||
|
||||
override fun savePlayer(uuid: UUID) {
|
||||
writeToHandler(uuid)
|
||||
saveToHandler()
|
||||
}
|
||||
|
||||
private fun writeToHandler(uuid: UUID) {
|
||||
val profile = load(uuid)
|
||||
|
||||
for (key in Eco.getHandler().keyRegistry.registeredKeys) {
|
||||
handler.write(uuid, key.key, profile.read(key) ?: key.defaultValue)
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveToHandler() {
|
||||
handler.save()
|
||||
}
|
||||
|
||||
override fun saveAll(async: Boolean) {
|
||||
val saver = {
|
||||
for ((uuid, _) in loaded) {
|
||||
writeToHandler(uuid)
|
||||
}
|
||||
|
||||
saveToHandler()
|
||||
}
|
||||
|
||||
if (async) {
|
||||
plugin.scheduler.runAsync(saver)
|
||||
} else {
|
||||
saver.invoke()
|
||||
}
|
||||
}
|
||||
|
||||
fun autosave(async: Boolean) {
|
||||
if (Bukkit.getOnlinePlayers().isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
if (plugin.configYml.getBool("autosave.log")) {
|
||||
plugin.logger.info("Auto-Saving player data!")
|
||||
}
|
||||
|
||||
saveAll(async)
|
||||
|
||||
if (plugin.configYml.getBool("autosave.log")) {
|
||||
plugin.logger.info("Saved player data!")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.willfp.eco.spigot.data
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.util.NamespacedKeyUtils
|
||||
import org.bukkit.block.Block
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.EventPriority
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.block.BlockBreakEvent
|
||||
import org.bukkit.event.block.BlockMultiPlaceEvent
|
||||
import org.bukkit.event.block.BlockPlaceEvent
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
|
||||
class PlayerBlockListener(
|
||||
private val plugin: EcoPlugin
|
||||
) : Listener {
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
fun onPlace(event: BlockPlaceEvent) {
|
||||
val block = event.blockPlaced
|
||||
|
||||
writeKey(block)
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
fun onPlace(event: BlockMultiPlaceEvent) {
|
||||
val block = event.blockPlaced
|
||||
|
||||
writeKey(block)
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
fun onBreak(event: BlockBreakEvent) {
|
||||
val block = event.block
|
||||
|
||||
this.plugin.scheduler.run {
|
||||
removeKey(block)
|
||||
}
|
||||
}
|
||||
|
||||
private fun writeKey(block: Block) {
|
||||
val loc = block.location.hashCode().toString(16)
|
||||
block.chunk.persistentDataContainer.set(
|
||||
plugin.namespacedKeyFactory.create(loc.lowercase()),
|
||||
PersistentDataType.INTEGER,
|
||||
1
|
||||
)
|
||||
}
|
||||
|
||||
private fun removeKey(block: Block) {
|
||||
val loc = block.location.hashCode().toString(16)
|
||||
block.chunk.persistentDataContainer.remove(plugin.namespacedKeyFactory.create(loc.lowercase()))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.willfp.eco.spigot.data.storage
|
||||
|
||||
import org.bukkit.NamespacedKey
|
||||
import java.util.*
|
||||
|
||||
interface DataHandler {
|
||||
fun save()
|
||||
|
||||
fun <T> write(uuid: UUID, key: NamespacedKey, value: T)
|
||||
fun <T> read(uuid: UUID, key: NamespacedKey): T?
|
||||
|
||||
fun updateKeys()
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package com.willfp.eco.spigot.data.storage
|
||||
|
||||
import com.willfp.eco.core.Eco
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKeyType
|
||||
import com.willfp.eco.spigot.EcoSpigotPlugin
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.jetbrains.exposed.dao.id.UUIDTable
|
||||
import org.jetbrains.exposed.sql.BooleanColumnType
|
||||
import org.jetbrains.exposed.sql.Column
|
||||
import org.jetbrains.exposed.sql.Database
|
||||
import org.jetbrains.exposed.sql.DoubleColumnType
|
||||
import org.jetbrains.exposed.sql.IntegerColumnType
|
||||
import org.jetbrains.exposed.sql.ResultRow
|
||||
import org.jetbrains.exposed.sql.SchemaUtils
|
||||
import org.jetbrains.exposed.sql.VarCharColumnType
|
||||
import org.jetbrains.exposed.sql.insert
|
||||
import org.jetbrains.exposed.sql.select
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import org.jetbrains.exposed.sql.update
|
||||
import java.util.UUID
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class MySQLDataHandler(
|
||||
plugin: EcoSpigotPlugin
|
||||
) : DataHandler {
|
||||
private val columns = mutableMapOf<String, Column<*>>()
|
||||
|
||||
init {
|
||||
Database.connect(
|
||||
"jdbc:mysql://" +
|
||||
"${plugin.configYml.getString("mysql.host")}:" +
|
||||
"${plugin.configYml.getString("mysql.port")}/" +
|
||||
plugin.configYml.getString("mysql.database"),
|
||||
driver = "com.mysql.cj.jdbc.Driver",
|
||||
user = plugin.configYml.getString("mysql.user"),
|
||||
password = plugin.configYml.getString("mysql.password")
|
||||
)
|
||||
|
||||
transaction {
|
||||
SchemaUtils.create(Players)
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateKeys() {
|
||||
transaction {
|
||||
for (key in Eco.getHandler().keyRegistry.registeredKeys) {
|
||||
registerColumn(key, Players)
|
||||
}
|
||||
|
||||
SchemaUtils.createMissingTablesAndColumns(Players)
|
||||
}
|
||||
}
|
||||
|
||||
override fun save() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
override fun <T> write(uuid: UUID, key: NamespacedKey, value: T) {
|
||||
transaction {
|
||||
getPlayer(uuid)
|
||||
val column: Column<T> = getColumn(key.toString()) as Column<T>
|
||||
|
||||
Players.update({ Players.id eq uuid }) {
|
||||
it[column] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun <T> read(uuid: UUID, key: NamespacedKey): T? {
|
||||
var value: T? = null
|
||||
transaction {
|
||||
val player = getPlayer(uuid)
|
||||
value = player[getColumn(key.toString())] as T?
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
object Players : UUIDTable("eco_players") {
|
||||
|
||||
}
|
||||
|
||||
private fun <T> registerColumn(key: PersistentDataKey<T>, table: UUIDTable) {
|
||||
table.apply {
|
||||
if (this.columns.stream().anyMatch { it.name == key.key.toString() }) {
|
||||
return@apply
|
||||
}
|
||||
|
||||
when (key.type) {
|
||||
PersistentDataKeyType.INT -> registerColumn<Int>(key.key.toString(), IntegerColumnType())
|
||||
.default(key.defaultValue as Int)
|
||||
PersistentDataKeyType.DOUBLE -> registerColumn<Double>(key.key.toString(), DoubleColumnType())
|
||||
.default(key.defaultValue as Double)
|
||||
PersistentDataKeyType.BOOLEAN -> registerColumn<Boolean>(key.key.toString(), BooleanColumnType())
|
||||
.default(key.defaultValue as Boolean)
|
||||
PersistentDataKeyType.STRING -> registerColumn<String>(key.key.toString(), VarCharColumnType(512))
|
||||
.default(key.defaultValue as String)
|
||||
|
||||
else -> throw NullPointerException("Null value found!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getColumn(name: String): Column<*> {
|
||||
val cached = columns[name]
|
||||
if (cached != null) {
|
||||
return cached
|
||||
}
|
||||
|
||||
columns[name] = Players.columns.stream().filter { it.name == name }.findFirst().get()
|
||||
return getColumn(name)
|
||||
}
|
||||
|
||||
private fun getPlayer(uuid: UUID): ResultRow {
|
||||
Players.select { Players.id eq uuid }.firstOrNull() ?: run {
|
||||
Players.insert {
|
||||
it[id] = uuid
|
||||
}
|
||||
}
|
||||
|
||||
return Players.select { Players.id eq uuid }.first()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.willfp.eco.spigot.data.storage
|
||||
|
||||
import com.willfp.eco.core.config.yaml.YamlBaseConfig
|
||||
import com.willfp.eco.spigot.EcoSpigotPlugin
|
||||
import org.bukkit.NamespacedKey
|
||||
import java.util.*
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class YamlDataHandler(
|
||||
plugin: EcoSpigotPlugin
|
||||
) : DataHandler {
|
||||
private val dataYml = DataYml(plugin)
|
||||
|
||||
override fun save() {
|
||||
dataYml.save()
|
||||
}
|
||||
|
||||
override fun updateKeys() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
override fun <T> write(uuid: UUID, key: NamespacedKey, value: T) {
|
||||
dataYml.set("player.$uuid.$key", value)
|
||||
}
|
||||
|
||||
override fun <T> read(uuid: UUID, key: NamespacedKey): T? {
|
||||
return dataYml.get("player.$uuid.$key") as T?
|
||||
}
|
||||
|
||||
class DataYml(
|
||||
plugin: EcoSpigotPlugin
|
||||
) : YamlBaseConfig(
|
||||
"data",
|
||||
false,
|
||||
plugin
|
||||
)
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.willfp.eco.spigot.display
|
||||
|
||||
import com.comphenix.protocol.PacketType
|
||||
import com.comphenix.protocol.ProtocolLibrary
|
||||
import com.comphenix.protocol.events.PacketContainer
|
||||
import com.comphenix.protocol.events.PacketEvent
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder
|
||||
import com.willfp.eco.core.AbstractPacketAdapter
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.display.Display
|
||||
@@ -10,53 +12,137 @@ import com.willfp.eco.core.fast.FastItemStack
|
||||
import com.willfp.eco.spigot.display.frame.DisplayFrame
|
||||
import com.willfp.eco.spigot.display.frame.HashedItem
|
||||
import com.willfp.eco.spigot.display.frame.lastDisplayFrame
|
||||
import com.willfp.eco.util.ServerUtils
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class PacketWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, PacketType.Play.Server.WINDOW_ITEMS, false) {
|
||||
private val ignorePacketList = ConcurrentHashMap.newKeySet<String>()
|
||||
private val playerRates = ConcurrentHashMap<String, Int>()
|
||||
private val threadFactory = ThreadFactoryBuilder().setNameFormat("eco-display-thread-%d").build()
|
||||
private val executor = Executors.newCachedThreadPool(threadFactory)
|
||||
private val scheduledExecutor = Executors.newSingleThreadScheduledExecutor(threadFactory)
|
||||
|
||||
override fun onSend(
|
||||
packet: PacketContainer,
|
||||
player: Player,
|
||||
event: PacketEvent
|
||||
) {
|
||||
if (ignorePacketList.contains(player.name)) {
|
||||
ignorePacketList.remove(player.name)
|
||||
return
|
||||
}
|
||||
|
||||
val windowId = packet.integers.read(0)
|
||||
|
||||
if (windowId != 0) {
|
||||
player.lastDisplayFrame = DisplayFrame.EMPTY
|
||||
}
|
||||
|
||||
packet.itemListModifier.modify(0) { itemStacks: MutableList<ItemStack>? ->
|
||||
if (itemStacks == null) {
|
||||
return@modify null
|
||||
val itemStacks = packet.itemListModifier.read(0) ?: return
|
||||
|
||||
handleRateLimit(player)
|
||||
|
||||
if (usingAsync(player)) {
|
||||
executor.execute {
|
||||
try {
|
||||
modifyWindowItems(itemStacks, windowId, player)
|
||||
} catch (e: Exception) {
|
||||
if (this.getPlugin().configYml.getBool("async-display.log-errors")) {
|
||||
this.getPlugin().logger.warning("Error happened in async processing! Disable async display (/plugins/eco/config.yml) if this is a frequent issue")
|
||||
}
|
||||
}
|
||||
|
||||
val newPacket = packet.deepClone()
|
||||
newPacket.itemListModifier.write(0, itemStacks)
|
||||
|
||||
ignorePacketList.add(player.name)
|
||||
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, newPacket)
|
||||
}
|
||||
|
||||
if (this.getPlugin().configYml.getBool("use-display-frame") && windowId == 0) {
|
||||
val frameMap = mutableMapOf<Byte, HashedItem>()
|
||||
|
||||
for (index in itemStacks.indices) {
|
||||
frameMap[index.toByte()] =
|
||||
HashedItem(FastItemStack.wrap(itemStacks[index]).hashCode(), itemStacks[index])
|
||||
}
|
||||
|
||||
val newFrame = DisplayFrame(frameMap)
|
||||
|
||||
val lastFrame = player.lastDisplayFrame
|
||||
|
||||
player.lastDisplayFrame = newFrame
|
||||
|
||||
val changes = lastFrame.getChangedSlots(newFrame)
|
||||
|
||||
for (index in changes) {
|
||||
Display.display(itemStacks[index.toInt()], player)
|
||||
}
|
||||
|
||||
for (index in (itemStacks.indices subtract changes)) {
|
||||
itemStacks[index.toInt()] = lastFrame.getItem(index.toByte()) ?: itemStacks[index.toInt()]
|
||||
}
|
||||
} else {
|
||||
itemStacks.forEach { Display.display(it, player) }
|
||||
}
|
||||
itemStacks
|
||||
} else {
|
||||
packet.itemListModifier.write(0, modifyWindowItems(itemStacks, windowId, player))
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleRateLimit(player: Player) {
|
||||
fun modifyRateValueBy(player: Player, amount: Int) {
|
||||
val name = player.name
|
||||
val current = playerRates[name] ?: 0
|
||||
val new = current + amount
|
||||
if (new <= 0) {
|
||||
playerRates.remove(name)
|
||||
} else {
|
||||
playerRates[name] = new
|
||||
}
|
||||
}
|
||||
|
||||
modifyRateValueBy(player, 1)
|
||||
|
||||
scheduledExecutor.schedule(
|
||||
{ modifyRateValueBy(player, -1) },
|
||||
this.getPlugin().configYml.getInt("async-display.ratelimit.timeframe").toLong(),
|
||||
TimeUnit.SECONDS
|
||||
)
|
||||
}
|
||||
|
||||
private fun usingAsync(player: Player): Boolean {
|
||||
if (this.getPlugin().configYml.getBool("async-display.enabled")) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (
|
||||
this.getPlugin().configYml.getBool("async-display.emergency.enabled")
|
||||
&& ServerUtils.getTps() <= this.getPlugin().configYml.getDouble("async-display.emergency.cutoff")
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (
|
||||
this.getPlugin().configYml.getBool("async-display.ratelimit.enabled")
|
||||
&& (playerRates[player.name] ?: 0) >= this.getPlugin().configYml.getInt("async-display.ratelimit.cutoff")
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun modifyWindowItems(
|
||||
itemStacks: MutableList<ItemStack>,
|
||||
windowId: Int,
|
||||
player: Player
|
||||
): MutableList<ItemStack> {
|
||||
if (this.getPlugin().configYml.getBool("use-display-frame") && windowId == 0) {
|
||||
val frameMap = mutableMapOf<Byte, HashedItem>()
|
||||
|
||||
for (index in itemStacks.indices) {
|
||||
frameMap[index.toByte()] =
|
||||
HashedItem(FastItemStack.wrap(itemStacks[index]).hashCode(), itemStacks[index])
|
||||
}
|
||||
|
||||
val newFrame = DisplayFrame(frameMap)
|
||||
|
||||
val lastFrame = player.lastDisplayFrame
|
||||
|
||||
player.lastDisplayFrame = newFrame
|
||||
|
||||
val changes = lastFrame.getChangedSlots(newFrame)
|
||||
|
||||
for (index in changes) {
|
||||
Display.display(itemStacks[index.toInt()], player)
|
||||
}
|
||||
|
||||
for (index in (itemStacks.indices subtract changes.toSet())) {
|
||||
itemStacks[index.toInt()] = lastFrame.getItem(index.toByte()) ?: itemStacks[index.toInt()]
|
||||
}
|
||||
} else {
|
||||
itemStacks.forEach { Display.display(it, player) }
|
||||
}
|
||||
|
||||
return itemStacks
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.willfp.eco.spigot.integrations.afk
|
||||
|
||||
import com.Zrips.CMI.CMI
|
||||
import com.willfp.eco.core.integrations.afk.AFKWrapper
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class AFKIntegrationCMI : AFKWrapper {
|
||||
override fun isAfk(player: Player): Boolean {
|
||||
return CMI.getInstance().playerManager.getUser(player)?.isAfk ?: false
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "CMI"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.willfp.eco.spigot.integrations.afk
|
||||
|
||||
import com.earth2me.essentials.Essentials
|
||||
import com.willfp.eco.core.integrations.afk.AFKWrapper
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
class AFKIntegrationEssentials : AFKWrapper {
|
||||
private val ess = JavaPlugin.getPlugin(Essentials::class.java)
|
||||
|
||||
override fun isAfk(player: Player): Boolean {
|
||||
return ess.getUser(player) != null && ess.getUser(player).isAfk
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "Essentials"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.willfp.eco.spigot.integrations.antigrief
|
||||
|
||||
import com.willfp.eco.core.integrations.antigrief.AntigriefWrapper
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.World
|
||||
import org.bukkit.block.Block
|
||||
import org.bukkit.entity.LivingEntity
|
||||
import org.bukkit.entity.Monster
|
||||
import org.bukkit.entity.Player
|
||||
import world.bentobox.bentobox.BentoBox
|
||||
import world.bentobox.bentobox.api.user.User
|
||||
import world.bentobox.bentobox.lists.Flags
|
||||
|
||||
class AntigriefBentoBox : AntigriefWrapper {
|
||||
override fun canBreakBlock(
|
||||
player: Player,
|
||||
block: Block
|
||||
): Boolean {
|
||||
val island = BentoBox.getInstance().islandsManager.getIslandAt(block.location).orElse(null) ?: return true
|
||||
return island.isAllowed(User.getInstance(player), Flags.BREAK_BLOCKS)
|
||||
}
|
||||
|
||||
override fun canCreateExplosion(
|
||||
player: Player,
|
||||
location: Location
|
||||
): Boolean {
|
||||
val island = BentoBox.getInstance().islandsManager.getIslandAt(location).orElse(null) ?: return true
|
||||
return island.isAllowed(User.getInstance(player), Flags.TNT_DAMAGE)
|
||||
}
|
||||
|
||||
override fun canPlaceBlock(
|
||||
player: Player,
|
||||
block: Block
|
||||
): Boolean {
|
||||
val island = BentoBox.getInstance().islandsManager.getIslandAt(block.location).orElse(null) ?: return true
|
||||
return island.isAllowed(User.getInstance(player), Flags.PLACE_BLOCKS)
|
||||
}
|
||||
|
||||
override fun canInjure(
|
||||
player: Player,
|
||||
victim: LivingEntity
|
||||
): Boolean {
|
||||
val island = BentoBox.getInstance().islandsManager.getIslandAt(victim.location).orElse(null) ?: return true
|
||||
return when (victim) {
|
||||
is Player -> {
|
||||
island.isAllowed(
|
||||
User.getInstance(player), when (victim.world.environment) {
|
||||
World.Environment.NORMAL -> Flags.PVP_OVERWORLD
|
||||
World.Environment.NETHER -> Flags.PVP_NETHER
|
||||
World.Environment.THE_END -> Flags.PVP_END
|
||||
else -> Flags.PVP_OVERWORLD
|
||||
}
|
||||
)
|
||||
}
|
||||
is Monster -> island.isAllowed(User.getInstance(player), Flags.HURT_MONSTERS)
|
||||
else -> island.isAllowed(User.getInstance(player), Flags.HURT_ANIMALS)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "BentoBox"
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is AntigriefWrapper) {
|
||||
return false
|
||||
}
|
||||
|
||||
return other.pluginName == this.pluginName
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return this.pluginName.hashCode()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.willfp.eco.spigot.integrations.antigrief
|
||||
|
||||
import com.bgsoftware.superiorskyblock.api.SuperiorSkyblockAPI
|
||||
import com.bgsoftware.superiorskyblock.api.enums.HitActionResult
|
||||
import com.bgsoftware.superiorskyblock.api.island.IslandPrivilege
|
||||
import com.willfp.eco.core.integrations.antigrief.AntigriefWrapper
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.block.Block
|
||||
import org.bukkit.entity.Animals
|
||||
import org.bukkit.entity.LivingEntity
|
||||
import org.bukkit.entity.Monster
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class AntigriefSuperiorSkyblock2 : AntigriefWrapper {
|
||||
override fun getPluginName(): String {
|
||||
return "SuperiorSkyblock2"
|
||||
}
|
||||
|
||||
override fun canBreakBlock(player: Player, block: Block): Boolean {
|
||||
if (SuperiorSkyblockAPI.getPlayer(player).hasBypassModeEnabled()) return true
|
||||
return SuperiorSkyblockAPI.getPlayer(player).hasPermission(IslandPrivilege.getByName("Break"))
|
||||
|| SuperiorSkyblockAPI.getPlayer(player).hasPermission(IslandPrivilege.getByName("BREAK"))
|
||||
}
|
||||
|
||||
override fun canCreateExplosion(player: Player, location: Location): Boolean {
|
||||
if (SuperiorSkyblockAPI.getPlayer(player).hasBypassModeEnabled()) return true
|
||||
return SuperiorSkyblockAPI.getIslandAt(location)?.isMember(SuperiorSkyblockAPI.getPlayer(player)) ?: true
|
||||
}
|
||||
|
||||
override fun canPlaceBlock(player: Player, block: Block): Boolean {
|
||||
if (SuperiorSkyblockAPI.getPlayer(player).hasBypassModeEnabled()) return true
|
||||
return SuperiorSkyblockAPI.getPlayer(player).hasPermission(IslandPrivilege.getByName("Place"))
|
||||
|| SuperiorSkyblockAPI.getPlayer(player).hasPermission(IslandPrivilege.getByName("PLACE"))
|
||||
}
|
||||
|
||||
override fun canInjure(player: Player, victim: LivingEntity): Boolean {
|
||||
if (SuperiorSkyblockAPI.getPlayer(player).hasBypassModeEnabled()) return true
|
||||
return when (victim) {
|
||||
is Player -> SuperiorSkyblockAPI.getPlayer(player).canHit(SuperiorSkyblockAPI.getPlayer(victim)).equals(HitActionResult.SUCCESS)
|
||||
is Animals -> {
|
||||
return SuperiorSkyblockAPI.getPlayer(player).hasPermission(IslandPrivilege.getByName("ANIMAL_DAMAGE"))
|
||||
}
|
||||
is Monster -> {
|
||||
return SuperiorSkyblockAPI.getPlayer(player).hasPermission(IslandPrivilege.getByName("MONSTER_DAMAGE"))
|
||||
}
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.willfp.eco.spigot.integrations.economy
|
||||
|
||||
import com.willfp.eco.core.integrations.economy.EconomyWrapper
|
||||
import net.milkbowl.vault.economy.Economy
|
||||
import org.bukkit.OfflinePlayer
|
||||
|
||||
class EconomyVault(
|
||||
private val vault: Economy
|
||||
): EconomyWrapper {
|
||||
override fun hasAmount(player: OfflinePlayer, amount: Double): Boolean {
|
||||
return vault.has(player, amount)
|
||||
}
|
||||
|
||||
override fun giveMoney(player: OfflinePlayer, amount: Double): Boolean {
|
||||
return vault.depositPlayer(player, amount).transactionSuccess()
|
||||
}
|
||||
|
||||
override fun removeMoney(player: OfflinePlayer, amount: Double): Boolean {
|
||||
return vault.withdrawPlayer(player, amount).transactionSuccess()
|
||||
}
|
||||
|
||||
override fun getBalance(player: OfflinePlayer): Double {
|
||||
return vault.getBalance(player)
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "Vault"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.willfp.eco.spigot.integrations.hologram
|
||||
|
||||
import com.Zrips.CMI.CMI
|
||||
import com.Zrips.CMI.Modules.Holograms.CMIHologram
|
||||
import com.willfp.eco.core.integrations.hologram.Hologram
|
||||
import com.willfp.eco.core.integrations.hologram.HologramWrapper
|
||||
import net.Zrips.CMILib.Container.CMILocation
|
||||
import org.bukkit.Location
|
||||
import java.util.UUID
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
class HologramCMI : HologramWrapper {
|
||||
override fun createHologram(location: Location, contents: MutableList<String>): Hologram {
|
||||
val cmiHolo = CMIHologram(UUID.randomUUID().toString(), CMILocation(location))
|
||||
CMI.getInstance().hologramManager.addHologram(cmiHolo)
|
||||
|
||||
val holo = HologramImplCMI(cmiHolo)
|
||||
holo.setContents(contents)
|
||||
|
||||
cmiHolo.enable()
|
||||
|
||||
return holo
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "CMI"
|
||||
}
|
||||
|
||||
class HologramImplCMI(
|
||||
private val handle: CMIHologram
|
||||
) : Hologram {
|
||||
override fun remove() {
|
||||
CMI.getInstance().hologramManager.removeHolo(handle)
|
||||
}
|
||||
|
||||
override fun setContents(contents: MutableList<String>) {
|
||||
handle.lines = contents
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.willfp.eco.spigot.integrations.hologram
|
||||
|
||||
import com.willfp.eco.core.integrations.hologram.Hologram
|
||||
import com.willfp.eco.core.integrations.hologram.HologramWrapper
|
||||
import me.gholo.api.GHoloAPI
|
||||
import org.bukkit.Location
|
||||
import java.util.*
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
class HologramGHolo : HologramWrapper {
|
||||
companion object {
|
||||
private val api = GHoloAPI()
|
||||
}
|
||||
|
||||
override fun createHologram(location: Location, contents: MutableList<String>): Hologram {
|
||||
val id = UUID.randomUUID().toString()
|
||||
|
||||
api.insertHolo(id, location, contents)
|
||||
|
||||
return HologramImplGHolo(id)
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "GHolo"
|
||||
}
|
||||
|
||||
class HologramImplGHolo(
|
||||
private val id: String
|
||||
) : Hologram {
|
||||
override fun remove() {
|
||||
api.removeHolo(id)
|
||||
}
|
||||
|
||||
override fun setContents(contents: MutableList<String>) {
|
||||
api.getHolo(id)?.content = contents
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.willfp.eco.spigot.integrations.hologram
|
||||
|
||||
import com.gmail.filoghost.holographicdisplays.api.HologramsAPI
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.integrations.hologram.Hologram
|
||||
import com.willfp.eco.core.integrations.hologram.HologramWrapper
|
||||
import org.bukkit.Location
|
||||
|
||||
class HologramHolographicDisplays(
|
||||
private val plugin: EcoPlugin
|
||||
) : HologramWrapper {
|
||||
|
||||
override fun createHologram(location: Location, contents: MutableList<String>): Hologram {
|
||||
val hologram = HologramImplHolographicDisplays(
|
||||
HologramsAPI.createHologram(plugin, location)
|
||||
)
|
||||
|
||||
hologram.setContents(contents)
|
||||
|
||||
return hologram
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "HolographicDisplays"
|
||||
}
|
||||
|
||||
class HologramImplHolographicDisplays(
|
||||
private val handle: com.gmail.filoghost.holographicdisplays.api.Hologram
|
||||
) : Hologram {
|
||||
override fun remove() {
|
||||
handle.delete()
|
||||
}
|
||||
|
||||
override fun setContents(contents: MutableList<String>) {
|
||||
handle.clearLines()
|
||||
for (line in contents) {
|
||||
handle.appendTextLine(line)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,10 @@ class McmmoIntegrationImpl : McmmoWrapper {
|
||||
} else event is FakeEvent
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "mcMMO"
|
||||
}
|
||||
|
||||
init {
|
||||
if (!ClassUtils.exists("com.gmail.nossr50.events.fake.FakeEvent")) {
|
||||
disabled = true
|
||||
|
||||
@@ -3,6 +3,19 @@
|
||||
# by Auxilor
|
||||
#
|
||||
|
||||
mysql:
|
||||
enabled: false # Set to false, data.yml will be used instead.
|
||||
host: localhost
|
||||
port: 3306
|
||||
database: database
|
||||
user: username
|
||||
password: passy
|
||||
|
||||
autosave:
|
||||
ticks: 20000 # The amount of ticks between autosaves
|
||||
log: false # If auto-save messages should be sent to console
|
||||
async: false # If saves should be performed asynchronously. May cause bugs without MySQL
|
||||
|
||||
|
||||
# Options to fix villager bugs left behind from old (buggy) versions.
|
||||
villager-display-fix: false
|
||||
@@ -17,7 +30,7 @@ use-fast-collated-drops: true
|
||||
enable-bstats: true
|
||||
|
||||
# Some plugins use their own item display systems (eg Triton)
|
||||
# And must be ran after eco. Don't enable this unless you run a conflicting plugin
|
||||
# And must be run after eco. Don't enable this unless you run a conflicting plugin
|
||||
# and have been told to enable it.
|
||||
use-lower-protocollib-priority: false
|
||||
|
||||
@@ -28,4 +41,38 @@ use-display-frame: true
|
||||
|
||||
# Time to live for a display frame. In other words, this is how frequent (in ticks)
|
||||
# that display frames will be cleared / deleted.
|
||||
display-frame-ttl: 17
|
||||
display-frame-ttl: 17
|
||||
|
||||
# Window items packets have the option to be run asynchronously. This may cause
|
||||
# some bugs and is considered experimental, however it has been tested without
|
||||
# any apparent issues. Enable this if performance is absolutely crucial or if you
|
||||
# are experiencing severe display lag.
|
||||
async-display:
|
||||
# If async display should always be used.
|
||||
enabled: false
|
||||
|
||||
# Log errors that occur in async processing.
|
||||
log-errors: true
|
||||
|
||||
# If the server is running under heavy load (below a certain TPS value), enable
|
||||
# async display automatically. This can prevent some server crashes under load.
|
||||
emergency:
|
||||
# If emergency async should be used.
|
||||
enabled: true
|
||||
# Below this TPS value, emergency async display will be used.
|
||||
cutoff: 18
|
||||
|
||||
# If players with a large amount of display packets should have their processing
|
||||
# done asynchronously. This will help if a player is trying to crash the server
|
||||
# by overloading the display system.
|
||||
ratelimit:
|
||||
# If rate limit async display should be used.
|
||||
enabled: true
|
||||
# The amount of window items packets per timeframe needed to enable async display
|
||||
# for a specified player.
|
||||
cutoff: 4
|
||||
# The length of the timeframe in seconds.
|
||||
# Cutoff 5, Timeframe 1 means that if there are more than 5 window items packets
|
||||
# being sent per second for a player, then that player should have their packets
|
||||
# handled asynchronously.
|
||||
timeframe: 1
|
||||
1
eco-core/core-plugin/src/main/resources/data.yml
Normal file
1
eco-core/core-plugin/src/main/resources/data.yml
Normal file
@@ -0,0 +1 @@
|
||||
# For internal storage use only, do not modify.
|
||||
@@ -2,7 +2,7 @@ name: eco
|
||||
version: ${projectVersion}
|
||||
main: com.willfp.eco.spigot.EcoHandler
|
||||
api-version: 1.16
|
||||
authors: [Auxilor]
|
||||
authors: [ Auxilor ]
|
||||
website: willfp.com
|
||||
load: STARTUP
|
||||
depend:
|
||||
@@ -27,11 +27,23 @@ softdepend:
|
||||
- HeadDatabase
|
||||
- Multiverse-Inventories
|
||||
- Alice
|
||||
- HolographicDisplays
|
||||
- GHolo
|
||||
- CMI
|
||||
- Essentials
|
||||
- Vault
|
||||
- BentoBox
|
||||
libraries:
|
||||
- 'org.reflections:reflections:0.9.12'
|
||||
- 'org.apache.maven:maven-artifact:3.0.3'
|
||||
- 'org.jetbrains.kotlin:kotlin-stdlib:1.5.31'
|
||||
- 'net.kyori:adventure-platform-bukkit:4.0.0'
|
||||
- 'net.kyori:adventure-api:4.9.1'
|
||||
- 'net.kyori:adventure-api:4.9.2'
|
||||
- 'net.kyori:adventure-text-serializer-gson:4.9.2'
|
||||
- 'net.kyori:adventure-text-serializer-legacy:4.8.1'
|
||||
- 'net.kyori:adventure-text-serializer-legacy:4.9.2'
|
||||
- 'org.jetbrains.kotlin:kotlin-stdlib:1.5.21'
|
||||
- 'org.jetbrains.exposed:exposed-core:0.35.1'
|
||||
- 'org.jetbrains.exposed:exposed-dao:0.35.1'
|
||||
- 'org.jetbrains.exposed:exposed-jdbc:0.35.1'
|
||||
- 'mysql:mysql-connector-java:8.0.25'
|
||||
- 'com.google.guava:guava:31.0.1-jre'
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.willfp.eco.proxy
|
||||
|
||||
import com.willfp.eco.core.proxy.AbstractProxy
|
||||
|
||||
interface TPSProxy : AbstractProxy {
|
||||
fun getTPS(): Double
|
||||
}
|
||||
@@ -1,2 +1,2 @@
|
||||
version = 6.11.2
|
||||
version = 6.13.0
|
||||
plugin-name = eco
|
||||
BIN
lib/CMIAPI8.7.8.2.jar
Normal file
BIN
lib/CMIAPI8.7.8.2.jar
Normal file
Binary file not shown.
BIN
lib/CMILib1.0.4.1.jar
Normal file
BIN
lib/CMILib1.0.4.1.jar
Normal file
Binary file not shown.
BIN
lib/GHolo.jar
Normal file
BIN
lib/GHolo.jar
Normal file
Binary file not shown.
Reference in New Issue
Block a user