Compare commits

..

37 Commits
3.3.2 ... 3.8.0

Author SHA1 Message Date
Auxilor
d1307e35db Minor code issues 2021-02-16 19:48:20 +00:00
Auxilor
0a6b197a97 Cleaned various internals 2021-02-16 19:44:34 +00:00
Auxilor
8d6512886c Removed redundant PluginDependentFactory.java 2021-02-16 19:37:55 +00:00
Auxilor
5c0c0f3e2a Refactored Scheduler.java 2021-02-16 19:35:55 +00:00
Auxilor
e2c2fc776a Moved break blocks into block utils 2021-02-16 19:34:26 +00:00
Auxilor
576050b31e Updated to 3.8.0 2021-02-16 19:22:20 +00:00
Auxilor
f9a43bd336 Added trident util initializatoin 2021-02-16 19:17:59 +00:00
Auxilor
203f2f599a Added trident utils 2021-02-16 19:16:48 +00:00
Auxilor
baa5d37744 Added PlayerUtils 2021-02-16 19:11:02 +00:00
Auxilor
17f6af2a70 Added Skull texture setter 2021-02-16 18:07:47 +00:00
Auxilor
eae213f58e More refactoring, splitting api and internal 2021-02-14 16:31:16 +00:00
Auxilor
3a6a133560 Added caching to AbstractConfig 2021-02-14 15:32:10 +00:00
Auxilor
57cf144c57 Refactoring to remove internal components from API 2021-02-14 15:23:42 +00:00
Auxilor
5c29859d49 Updated to 3.7.0 2021-02-10 10:50:46 +00:00
Auxilor
02510127d1 Added getParts to EcoShapedRecipe 2021-02-10 10:50:31 +00:00
Auxilor
f6b5c8f7e0 Updated to eco 3.6.1 2021-02-09 09:30:29 +00:00
Auxilor
dbfef3094b Fixed villager trade being finalized 2021-02-09 09:30:08 +00:00
Auxilor
b5c3af752c Fixed bugs with new config system 2021-02-07 20:18:00 +00:00
Auxilor
d0366b39e2 Updated to 3.6.0 2021-02-07 20:03:46 +00:00
Auxilor
ed5390d2b5 Reworked config system (again) 2021-02-07 20:03:31 +00:00
Auxilor
e31857a15d Merge remote-tracking branch 'origin/master' into master
# Conflicts:
#	gradle.properties
2021-02-07 19:29:52 +00:00
Auxilor
32e119d187 Updated to 3.5.0 2021-02-07 19:29:32 +00:00
Auxilor
5690eccd14 Refactored config system and added update blacklist 2021-02-07 19:29:05 +00:00
Auxilor
2faf3732df Updated to 3.4.4 2021-02-07 15:00:52 +00:00
Auxilor
8670fb36e0 Changed ItemStats to StatTrackers 2021-02-07 15:00:36 +00:00
Auxilor
7c001c4809 Updated to 3.4.3 2021-02-03 09:14:20 +00:00
Auxilor
bce1dd9fee Fixed finalize issues 2021-02-03 09:13:45 +00:00
Auxilor
412c2e1e3c Updated to 3.4.2 2021-02-01 16:04:28 +00:00
Auxilor
dd7ffac974 Cleaned up DurabilityUtils and added edge case 2021-02-01 16:04:17 +00:00
Auxilor
7ad59e0166 Updated to 3.4.1 2021-02-01 08:54:30 +00:00
Auxilor
2f2bdbb9f5 Prevented dropping empty dropqueue or air 2021-02-01 08:54:17 +00:00
Auxilor
d23dc10bc5 Improved finalization (again) 2021-01-30 14:48:14 +00:00
Auxilor
46c2e3f90a Updated to 3.4.0 2021-01-30 14:31:51 +00:00
Auxilor
1776b668a4 Improved Display system 2021-01-30 14:31:31 +00:00
Auxilor
10dccd0f38 Updated to 3.3.3 2021-01-28 13:13:21 +00:00
Auxilor
f1918eb1ec Stopped removing final modifier on villager trades 2021-01-28 13:13:02 +00:00
Auxilor
436b33fde2 Fixed lands 2021-01-27 10:33:08 +00:00
73 changed files with 1497 additions and 636 deletions

View File

@@ -0,0 +1,16 @@
package com.willfp.eco.proxy.v1_15_R1;
import com.willfp.eco.proxy.proxies.BlockBreakProxy;
import net.minecraft.server.v1_15_R1.BlockPosition;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public final class BlockBreak implements BlockBreakProxy {
@Override
public void breakBlock(@NotNull final Player player,
@NotNull final Block block) {
((CraftPlayer) player).getHandle().playerInteractManager.breakBlock(new BlockPosition(block.getX(), block.getY(), block.getZ()));
}
}

View File

@@ -0,0 +1,15 @@
package com.willfp.eco.proxy.v1_15_R1;
import com.willfp.eco.proxy.proxies.CooldownProxy;
import net.minecraft.server.v1_15_R1.EntityHuman;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public final class Cooldown implements CooldownProxy {
@Override
public double getAttackCooldown(@NotNull final Player player) {
EntityHuman entityHuman = ((CraftPlayer) player).getHandle();
return entityHuman.s(0);
}
}

View File

@@ -0,0 +1,41 @@
package com.willfp.eco.proxy.v1_15_R1;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import com.willfp.eco.proxy.proxies.SkullProxy;
import org.bukkit.inventory.meta.SkullMeta;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.UUID;
public final class Skull implements SkullProxy {
/**
* Cached method to set the gameProfile.
*/
private Method setProfile = null;
@Override
public void setSkullTexture(@NotNull final SkullMeta meta,
@NotNull final String base64) {
try {
if (setProfile == null) {
setProfile = meta.getClass().getDeclaredMethod("setProfile", GameProfile.class);
setProfile.setAccessible(true);
}
UUID uuid = new UUID(
base64.substring(base64.length() - 20).hashCode(),
base64.substring(base64.length() - 10).hashCode()
);
GameProfile profile = new GameProfile(uuid, "talismans");
profile.getProperties().put("textures", new Property("textures", base64));
setProfile.invoke(meta, profile);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,17 @@
package com.willfp.eco.proxy.v1_15_R1;
import com.willfp.eco.proxy.proxies.TridentStackProxy;
import net.minecraft.server.v1_15_R1.EntityThrownTrident;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftTrident;
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack;
import org.bukkit.entity.Trident;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
public final class TridentStack implements TridentStackProxy {
@Override
public ItemStack getTridentStack(@NotNull final Trident trident) {
EntityThrownTrident t = ((CraftTrident) trident).getHandle();
return CraftItemStack.asBukkitCopy(t.trident);
}
}

View File

@@ -9,36 +9,29 @@ import org.bukkit.inventory.MerchantRecipe;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public final class VillagerTrade implements VillagerTradeProxy {
@Override
public void displayTrade(@NotNull final MerchantRecipe merchantRecipe) {
try {
// Enables removing final modifier
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
// Bukkit MerchantRecipe result
Field fResult = MerchantRecipe.class.getDeclaredField("result");
fResult.setAccessible(true);
ItemStack result = merchantRecipe.getResult();
Display.displayAndFinalize(result);
Display.display(result);
fResult.set(merchantRecipe, result);
// Get NMS MerchantRecipe from CraftMerchantRecipe
Field fHandle = CraftMerchantRecipe.class.getDeclaredField("handle");
fHandle.setAccessible(true);
net.minecraft.server.v1_15_R1.MerchantRecipe handle = (net.minecraft.server.v1_15_R1.MerchantRecipe) fHandle.get(merchantRecipe); // NMS Recipe
modifiersField.setInt(fHandle, fHandle.getModifiers() & ~Modifier.FINAL); // Remove final
Field fSelling = net.minecraft.server.v1_15_R1.MerchantRecipe.class.getDeclaredField("sellingItem");
fSelling.setAccessible(true);
modifiersField.setInt(fSelling, fSelling.getModifiers() & ~Modifier.FINAL);
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
Display.displayAndFinalize(selling);
Display.display(selling);
fSelling.set(handle, CraftItemStack.asNMSCopy(selling));
} catch (IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();

View File

@@ -0,0 +1,16 @@
package com.willfp.eco.proxy.v1_16_R1;
import com.willfp.eco.proxy.proxies.BlockBreakProxy;
import net.minecraft.server.v1_16_R1.BlockPosition;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public final class BlockBreak implements BlockBreakProxy {
@Override
public void breakBlock(@NotNull final Player player,
@NotNull final Block block) {
((CraftPlayer) player).getHandle().playerInteractManager.breakBlock(new BlockPosition(block.getX(), block.getY(), block.getZ()));
}
}

View File

@@ -0,0 +1,41 @@
package com.willfp.eco.proxy.v1_16_R1;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import com.willfp.eco.proxy.proxies.SkullProxy;
import org.bukkit.inventory.meta.SkullMeta;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.UUID;
public final class Skull implements SkullProxy {
/**
* Cached method to set the gameProfile.
*/
private Method setProfile = null;
@Override
public void setSkullTexture(@NotNull final SkullMeta meta,
@NotNull final String base64) {
try {
if (setProfile == null) {
setProfile = meta.getClass().getDeclaredMethod("setProfile", GameProfile.class);
setProfile.setAccessible(true);
}
UUID uuid = new UUID(
base64.substring(base64.length() - 20).hashCode(),
base64.substring(base64.length() - 10).hashCode()
);
GameProfile profile = new GameProfile(uuid, "talismans");
profile.getProperties().put("textures", new Property("textures", base64));
setProfile.invoke(meta, profile);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,17 @@
package com.willfp.eco.proxy.v1_16_R1;
import com.willfp.eco.proxy.proxies.TridentStackProxy;
import net.minecraft.server.v1_16_R1.EntityThrownTrident;
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftTrident;
import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack;
import org.bukkit.entity.Trident;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
public final class TridentStack implements TridentStackProxy {
@Override
public ItemStack getTridentStack(@NotNull final Trident trident) {
EntityThrownTrident t = ((CraftTrident) trident).getHandle();
return CraftItemStack.asBukkitCopy(t.trident);
}
}

View File

@@ -9,35 +9,28 @@ import org.bukkit.inventory.MerchantRecipe;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public final class VillagerTrade implements VillagerTradeProxy {
@Override
public void displayTrade(@NotNull final MerchantRecipe merchantRecipe) {
try {
// Enables removing final modifier
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
// Bukkit MerchantRecipe result
Field fResult = MerchantRecipe.class.getDeclaredField("result");
fResult.setAccessible(true);
ItemStack result = merchantRecipe.getResult();
Display.displayAndFinalize(result);
Display.display(result);
fResult.set(merchantRecipe, result);
// Get NMS MerchantRecipe from CraftMerchantRecipe
Field fHandle = CraftMerchantRecipe.class.getDeclaredField("handle");
fHandle.setAccessible(true);
net.minecraft.server.v1_16_R1.MerchantRecipe handle = (net.minecraft.server.v1_16_R1.MerchantRecipe) fHandle.get(merchantRecipe); // NMS Recipe
modifiersField.setInt(fHandle, fHandle.getModifiers() & ~Modifier.FINAL); // Remove final
Field fSelling = net.minecraft.server.v1_16_R1.MerchantRecipe.class.getDeclaredField("sellingItem");
fSelling.setAccessible(true);
modifiersField.setInt(fSelling, fSelling.getModifiers() & ~Modifier.FINAL);
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
Display.displayAndFinalize(selling);
Display.display(selling);
fSelling.set(handle, CraftItemStack.asNMSCopy(selling));
} catch (IllegalAccessException | NoSuchFieldException e) {

View File

@@ -0,0 +1,16 @@
package com.willfp.eco.proxy.v1_16_R2;
import com.willfp.eco.proxy.proxies.BlockBreakProxy;
import net.minecraft.server.v1_16_R2.BlockPosition;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public final class BlockBreak implements BlockBreakProxy {
@Override
public void breakBlock(@NotNull final Player player,
@NotNull final Block block) {
((CraftPlayer) player).getHandle().playerInteractManager.breakBlock(new BlockPosition(block.getX(), block.getY(), block.getZ()));
}
}

View File

@@ -0,0 +1,41 @@
package com.willfp.eco.proxy.v1_16_R2;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import com.willfp.eco.proxy.proxies.SkullProxy;
import org.bukkit.inventory.meta.SkullMeta;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.UUID;
public final class Skull implements SkullProxy {
/**
* Cached method to set the gameProfile.
*/
private Method setProfile = null;
@Override
public void setSkullTexture(@NotNull final SkullMeta meta,
@NotNull final String base64) {
try {
if (setProfile == null) {
setProfile = meta.getClass().getDeclaredMethod("setProfile", GameProfile.class);
setProfile.setAccessible(true);
}
UUID uuid = new UUID(
base64.substring(base64.length() - 20).hashCode(),
base64.substring(base64.length() - 10).hashCode()
);
GameProfile profile = new GameProfile(uuid, "talismans");
profile.getProperties().put("textures", new Property("textures", base64));
setProfile.invoke(meta, profile);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,17 @@
package com.willfp.eco.proxy.v1_16_R2;
import com.willfp.eco.proxy.proxies.TridentStackProxy;
import net.minecraft.server.v1_16_R2.EntityThrownTrident;
import org.bukkit.craftbukkit.v1_16_R2.entity.CraftTrident;
import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftItemStack;
import org.bukkit.entity.Trident;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
public final class TridentStack implements TridentStackProxy {
@Override
public ItemStack getTridentStack(@NotNull final Trident trident) {
EntityThrownTrident t = ((CraftTrident) trident).getHandle();
return CraftItemStack.asBukkitCopy(t.trident);
}
}

View File

@@ -9,35 +9,28 @@ import org.bukkit.inventory.MerchantRecipe;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public final class VillagerTrade implements VillagerTradeProxy {
@Override
public void displayTrade(@NotNull final MerchantRecipe merchantRecipe) {
try {
// Enables removing final modifier
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
// Bukkit MerchantRecipe result
Field fResult = MerchantRecipe.class.getDeclaredField("result");
fResult.setAccessible(true);
ItemStack result = merchantRecipe.getResult();
Display.displayAndFinalize(result);
Display.display(result);
fResult.set(merchantRecipe, result);
// Get NMS MerchantRecipe from CraftMerchantRecipe
Field fHandle = CraftMerchantRecipe.class.getDeclaredField("handle");
fHandle.setAccessible(true);
net.minecraft.server.v1_16_R2.MerchantRecipe handle = (net.minecraft.server.v1_16_R2.MerchantRecipe) fHandle.get(merchantRecipe); // NMS Recipe
modifiersField.setInt(fHandle, fHandle.getModifiers() & ~Modifier.FINAL); // Remove final
Field fSelling = net.minecraft.server.v1_16_R2.MerchantRecipe.class.getDeclaredField("sellingItem");
fSelling.setAccessible(true);
modifiersField.setInt(fSelling, fSelling.getModifiers() & ~Modifier.FINAL);
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
Display.displayAndFinalize(selling);
Display.display(selling);
fSelling.set(handle, CraftItemStack.asNMSCopy(selling));
} catch (IllegalAccessException | NoSuchFieldException e) {

View File

@@ -0,0 +1,16 @@
package com.willfp.eco.proxy.v1_16_R3;
import com.willfp.eco.proxy.proxies.BlockBreakProxy;
import net.minecraft.server.v1_16_R3.BlockPosition;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public final class BlockBreak implements BlockBreakProxy {
@Override
public void breakBlock(@NotNull final Player player,
@NotNull final Block block) {
((CraftPlayer) player).getHandle().playerInteractManager.breakBlock(new BlockPosition(block.getX(), block.getY(), block.getZ()));
}
}

View File

@@ -0,0 +1,41 @@
package com.willfp.eco.proxy.v1_16_R3;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import com.willfp.eco.proxy.proxies.SkullProxy;
import org.bukkit.inventory.meta.SkullMeta;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.UUID;
public final class Skull implements SkullProxy {
/**
* Cached method to set the gameProfile.
*/
private Method setProfile = null;
@Override
public void setSkullTexture(@NotNull final SkullMeta meta,
@NotNull final String base64) {
try {
if (setProfile == null) {
setProfile = meta.getClass().getDeclaredMethod("setProfile", GameProfile.class);
setProfile.setAccessible(true);
}
UUID uuid = new UUID(
base64.substring(base64.length() - 20).hashCode(),
base64.substring(base64.length() - 10).hashCode()
);
GameProfile profile = new GameProfile(uuid, "talismans");
profile.getProperties().put("textures", new Property("textures", base64));
setProfile.invoke(meta, profile);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,17 @@
package com.willfp.eco.proxy.v1_16_R3;
import com.willfp.eco.proxy.proxies.TridentStackProxy;
import net.minecraft.server.v1_16_R3.EntityThrownTrident;
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftTrident;
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
import org.bukkit.entity.Trident;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
public final class TridentStack implements TridentStackProxy {
@Override
public ItemStack getTridentStack(@NotNull final Trident trident) {
EntityThrownTrident t = ((CraftTrident) trident).getHandle();
return CraftItemStack.asBukkitCopy(t.trident);
}
}

View File

@@ -9,35 +9,28 @@ import org.bukkit.inventory.MerchantRecipe;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public final class VillagerTrade implements VillagerTradeProxy {
@Override
public void displayTrade(@NotNull final MerchantRecipe merchantRecipe) {
try {
// Enables removing final modifier
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
// Bukkit MerchantRecipe result
Field fResult = MerchantRecipe.class.getDeclaredField("result");
fResult.setAccessible(true);
ItemStack result = merchantRecipe.getResult();
Display.displayAndFinalize(result);
Display.display(result);
fResult.set(merchantRecipe, result);
// Get NMS MerchantRecipe from CraftMerchantRecipe
Field fHandle = CraftMerchantRecipe.class.getDeclaredField("handle");
fHandle.setAccessible(true);
net.minecraft.server.v1_16_R3.MerchantRecipe handle = (net.minecraft.server.v1_16_R3.MerchantRecipe) fHandle.get(merchantRecipe); // NMS Recipe
modifiersField.setInt(fHandle, fHandle.getModifiers() & ~Modifier.FINAL); // Remove final
net.minecraft.server.v1_16_R3.MerchantRecipe handle = (net.minecraft.server.v1_16_R3.MerchantRecipe) fHandle.get(merchantRecipe); // NMS RecipeR
Field fSelling = net.minecraft.server.v1_16_R3.MerchantRecipe.class.getDeclaredField("sellingItem");
fSelling.setAccessible(true);
modifiersField.setInt(fSelling, fSelling.getModifiers() & ~Modifier.FINAL);
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
Display.displayAndFinalize(selling);
Display.display(selling);
fSelling.set(handle, CraftItemStack.asNMSCopy(selling));
} catch (IllegalAccessException | NoSuchFieldException e) {

View File

@@ -1,11 +1,18 @@
package com.willfp.eco.spigot;
import com.willfp.eco.spigot.display.packets.PacketAutoRecipe;
import com.willfp.eco.spigot.display.packets.PacketChat;
import com.willfp.eco.spigot.display.packets.PacketOpenWindowMerchant;
import com.willfp.eco.spigot.display.packets.PacketSetCreativeSlot;
import com.willfp.eco.spigot.display.packets.PacketSetSlot;
import com.willfp.eco.spigot.display.packets.PacketWindowItems;
import com.willfp.eco.proxy.proxies.BlockBreakProxy;
import com.willfp.eco.proxy.proxies.CooldownProxy;
import com.willfp.eco.proxy.proxies.SkullProxy;
import com.willfp.eco.proxy.proxies.TridentStackProxy;
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.drops.CollatedRunnable;
import com.willfp.eco.spigot.eventlisteners.EntityDeathByEntityListeners;
import com.willfp.eco.spigot.eventlisteners.NaturalExpGainListeners;
import com.willfp.eco.spigot.integrations.anticheat.AnticheatAAC;
import com.willfp.eco.spigot.integrations.anticheat.AnticheatMatrix;
import com.willfp.eco.spigot.integrations.anticheat.AnticheatNCP;
@@ -16,12 +23,14 @@ import com.willfp.eco.spigot.integrations.antigrief.AntigriefLands;
import com.willfp.eco.spigot.integrations.antigrief.AntigriefTowny;
import com.willfp.eco.spigot.integrations.antigrief.AntigriefWorldGuard;
import com.willfp.eco.spigot.integrations.mcmmo.McmmoIntegrationImpl;
import com.willfp.eco.util.BlockUtils;
import com.willfp.eco.util.PlayerUtils;
import com.willfp.eco.util.SkullUtils;
import com.willfp.eco.util.TridentUtils;
import com.willfp.eco.util.command.AbstractCommand;
import com.willfp.eco.util.drops.internal.FastCollatedDropQueue;
import com.willfp.eco.util.display.Display;
import com.willfp.eco.util.events.armorequip.ArmorListener;
import com.willfp.eco.util.events.armorequip.DispenserArmorListener;
import com.willfp.eco.util.events.entitydeathbyentity.EntityDeathByEntityListeners;
import com.willfp.eco.util.events.naturalexpgainevent.NaturalExpGainListeners;
import com.willfp.eco.util.integrations.IntegrationLoader;
import com.willfp.eco.util.integrations.anticheat.AnticheatManager;
import com.willfp.eco.util.integrations.antigrief.AntigriefManager;
@@ -48,11 +57,16 @@ public class EcoPlugin extends AbstractEcoPlugin {
public EcoPlugin() {
super("eco", 87955, 10043, "com.willfp.eco.proxy", "&a");
instance = this;
Display.setFinalizeKey(this.getNamespacedKeyFactory().create("finalized"));
SkullUtils.initialize((skullMeta, base64) -> InternalProxyUtils.getProxy(SkullProxy.class).setSkullTexture(skullMeta, base64));
BlockUtils.initialize(((player, block) -> InternalProxyUtils.getProxy(BlockBreakProxy.class).breakBlock(player, block)));
PlayerUtils.initialize(((player) -> InternalProxyUtils.getProxy(CooldownProxy.class).getAttackCooldown(player)));
TridentUtils.initialize(((trident) -> InternalProxyUtils.getProxy(TridentStackProxy.class).getTridentStack(trident)));
}
@Override
public void enable() {
new FastCollatedDropQueue.CollatedRunnable(this);
new CollatedRunnable(this);
this.getEventManager().registerListener(new NaturalExpGainListeners());
this.getEventManager().registerListener(new ArmorListener());
this.getEventManager().registerListener(new DispenserArmorListener());
@@ -71,7 +85,7 @@ public class EcoPlugin extends AbstractEcoPlugin {
@Override
public void onReload() {
new FastCollatedDropQueue.CollatedRunnable(this);
new CollatedRunnable(this);
}
@Override

View File

@@ -1,4 +1,4 @@
package com.willfp.eco.spigot.display.packets;
package com.willfp.eco.spigot.display;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;

View File

@@ -1,4 +1,4 @@
package com.willfp.eco.spigot.display.packets;
package com.willfp.eco.spigot.display;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.ListenerPriority;

View File

@@ -1,4 +1,4 @@
package com.willfp.eco.spigot.display.packets;
package com.willfp.eco.spigot.display;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.PacketContainer;

View File

@@ -1,4 +1,4 @@
package com.willfp.eco.spigot.display.packets;
package com.willfp.eco.spigot.display;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.PacketContainer;

View File

@@ -1,4 +1,4 @@
package com.willfp.eco.spigot.display.packets;
package com.willfp.eco.spigot.display;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.PacketContainer;

View File

@@ -1,4 +1,4 @@
package com.willfp.eco.spigot.display.packets;
package com.willfp.eco.spigot.display;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.PacketContainer;

View File

@@ -0,0 +1,39 @@
package com.willfp.eco.spigot.drops;
import com.willfp.eco.internal.drops.impl.FastCollatedDropQueue;
import com.willfp.eco.internal.drops.impl.InternalDropQueue;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import lombok.Getter;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
public class CollatedRunnable {
/**
* The {@link BukkitTask} that the runnable represents.
*/
@Getter
private final BukkitTask runnableTask;
/**
* Create and run a new runnable to process collated drops.
*
* @param plugin The {@link AbstractEcoPlugin} that manages the processing.
*/
public CollatedRunnable(@NotNull final AbstractEcoPlugin plugin) {
runnableTask = plugin.getScheduler().runTimer(() -> {
for (Map.Entry<Player, FastCollatedDropQueue.CollatedDrops> entry : FastCollatedDropQueue.COLLATED_MAP.entrySet()) {
new InternalDropQueue(entry.getKey())
.setLocation(entry.getValue().getLocation())
.addItems(entry.getValue().getDrops())
.addXP(entry.getValue().getXp())
.push();
FastCollatedDropQueue.COLLATED_MAP.remove(entry.getKey());
}
FastCollatedDropQueue.COLLATED_MAP.clear();
}, 0, 1);
}
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.util.events.entitydeathbyentity;
package com.willfp.eco.spigot.eventlisteners;
import com.willfp.eco.util.events.entitydeathbyentity.EntityDeathByEntityEvent;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang.Validate;

View File

@@ -1,4 +1,4 @@
package com.willfp.eco.util.events.entitydeathbyentity;
package com.willfp.eco.spigot.eventlisteners;
import com.willfp.eco.util.internal.PluginDependent;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.util.events.naturalexpgainevent;
package com.willfp.eco.spigot.eventlisteners;
import com.willfp.eco.util.events.naturalexpgainevent.NaturalExpGainEvent;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang.Validate;

View File

@@ -1,4 +1,4 @@
package com.willfp.eco.util.events.naturalexpgainevent;
package com.willfp.eco.spigot.eventlisteners;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -7,6 +7,7 @@ import org.bukkit.event.player.PlayerExpChangeEvent;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
public class NaturalExpGainListeners implements Listener {
@@ -28,9 +29,10 @@ public class NaturalExpGainListeners implements Listener {
NaturalExpGainBuilder toRemove = null;
for (NaturalExpGainBuilder searchBuilder : events) {
if (!searchBuilder.getLocation().getWorld().equals(event.getPlayer().getLocation().getWorld())) {
if (!Objects.equals(searchBuilder.getLocation().getWorld(), event.getPlayer().getLocation().getWorld())) {
continue;
}
if (searchBuilder.getReason().equals(NaturalExpGainBuilder.BuildReason.BOTTLE) && searchBuilder.getLocation().distanceSquared(event.getPlayer().getLocation()) > 52) {
toRemove = searchBuilder;
}

View File

@@ -29,6 +29,10 @@ public class AntigriefKingdoms implements AntigriefWrapper {
Land land = Land.getLand(block);
if (land == null) {
return true;
}
DefaultKingdomPermission permission = land.isNexusLand() ? DefaultKingdomPermission.NEXUS_BUILD : DefaultKingdomPermission.BUILD;
if (!kp.hasPermission(permission)) {
return false;

View File

@@ -7,7 +7,7 @@ website: willfp.com
loadbefore:
- EcoEnchants
- Talismans
- ItemStats
- StatTrackers
- EcoArmor
- Illusioner
depend:

View File

@@ -0,0 +1,17 @@
package com.willfp.eco.proxy.proxies;
import com.willfp.eco.util.proxy.AbstractProxy;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public interface BlockBreakProxy extends AbstractProxy {
/**
* Break the block as if the player had done it manually.
*
* @param player The player to break the block as.
* @param block The block to break.
*/
void breakBlock(@NotNull Player player,
@NotNull Block block);
}

View File

@@ -0,0 +1,15 @@
package com.willfp.eco.proxy.proxies;
import com.willfp.eco.util.proxy.AbstractProxy;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public interface CooldownProxy extends AbstractProxy {
/**
* Get the attack cooldown for a player.
*
* @param player The player's attack cooldown.
* @return A value between 0 and 1, with 1 representing full power.
*/
double getAttackCooldown(@NotNull Player player);
}

View File

@@ -0,0 +1,16 @@
package com.willfp.eco.proxy.proxies;
import com.willfp.eco.util.proxy.AbstractProxy;
import org.bukkit.inventory.meta.SkullMeta;
import org.jetbrains.annotations.NotNull;
public interface SkullProxy extends AbstractProxy {
/**
* Set the texture of a skull from base64.
*
* @param meta The meta to modify.
* @param base64 The base64 texture.
*/
void setSkullTexture(@NotNull SkullMeta meta,
@NotNull String base64);
}

View File

@@ -0,0 +1,16 @@
package com.willfp.eco.proxy.proxies;
import com.willfp.eco.util.proxy.AbstractProxy;
import org.bukkit.entity.Trident;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
public interface TridentStackProxy extends AbstractProxy {
/**
* Get a trident's ItemStack.
*
* @param trident The trident to query.
* @return The trident's ItemStack.
*/
ItemStack getTridentStack(@NotNull Trident trident);
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.util.bukkit.events;
package com.willfp.eco.internal.bukkit.events;
import com.willfp.eco.util.bukkit.events.EventManager;
import com.willfp.eco.util.internal.PluginDependent;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.bukkit.Bukkit;

View File

@@ -1,6 +1,7 @@
package com.willfp.eco.util.bukkit.logging;
package com.willfp.eco.internal.bukkit.logging;
import com.willfp.eco.util.StringUtils;
import com.willfp.eco.util.bukkit.logging.Logger;
import com.willfp.eco.util.internal.PluginDependent;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.jetbrains.annotations.NotNull;

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.util.bukkit.scheduling;
package com.willfp.eco.internal.bukkit.scheduling;
import com.willfp.eco.util.bukkit.scheduling.Scheduler;
import com.willfp.eco.util.internal.PluginDependent;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.bukkit.Bukkit;

View File

@@ -1,4 +1,4 @@
package com.willfp.eco.util.drops.internal;
package com.willfp.eco.internal.drops;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;

View File

@@ -1,4 +1,4 @@
package com.willfp.eco.util.drops.internal;
package com.willfp.eco.internal.drops;
import lombok.Getter;
import lombok.experimental.UtilityClass;

View File

@@ -1,4 +1,4 @@
package com.willfp.eco.util.drops.internal;
package com.willfp.eco.internal.drops;
public enum DropQueueType {
/**

View File

@@ -1,6 +1,6 @@
package com.willfp.eco.util.drops.internal;
package com.willfp.eco.internal.drops.impl;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import com.willfp.eco.internal.drops.AbstractDropQueue;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@@ -8,8 +8,6 @@ import lombok.experimental.Accessors;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitTask;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -22,7 +20,7 @@ public class FastCollatedDropQueue extends InternalDropQueue {
* <p>
* Cleared and updated every tick.
*/
private static final Map<Player, CollatedDrops> COLLATED_MAP = new ConcurrentHashMap<>();
public static final Map<Player, CollatedDrops> COLLATED_MAP = new ConcurrentHashMap<>();
/**
* Backend implementation of {@link AbstractDropQueue}
@@ -37,7 +35,7 @@ public class FastCollatedDropQueue extends InternalDropQueue {
}
/**
* Queues the drops to be managed by the {@link CollatedRunnable}.
* Queues the drops to be managed by the runnable.
*/
@Override
public void push() {
@@ -50,7 +48,7 @@ public class FastCollatedDropQueue extends InternalDropQueue {
* The items, location, and xp linked to a player's drops.
*/
@ToString
private static final class CollatedDrops {
public static final class CollatedDrops {
/**
* A collection of all ItemStacks to be dropped at the end of the tick.
*/
@@ -101,32 +99,4 @@ public class FastCollatedDropQueue extends InternalDropQueue {
return this;
}
}
public static class CollatedRunnable {
/**
* The {@link BukkitTask} that the runnable represents.
*/
@Getter
private final BukkitTask runnableTask;
/**
* Create and run a new runnable to process collated drops.
*
* @param plugin The {@link AbstractEcoPlugin} that manages the processing.
*/
@ApiStatus.Internal
public CollatedRunnable(@NotNull final AbstractEcoPlugin plugin) {
runnableTask = plugin.getScheduler().runTimer(() -> {
for (Map.Entry<Player, CollatedDrops> entry : COLLATED_MAP.entrySet()) {
new InternalDropQueue(entry.getKey())
.setLocation(entry.getValue().getLocation())
.addItems(entry.getValue().getDrops())
.addXP(entry.getValue().getXp())
.push();
COLLATED_MAP.remove(entry.getKey());
}
COLLATED_MAP.clear();
}, 0, 1);
}
}
}

View File

@@ -1,10 +1,12 @@
package com.willfp.eco.util.drops.internal;
package com.willfp.eco.internal.drops.impl;
import com.willfp.eco.internal.drops.AbstractDropQueue;
import com.willfp.eco.util.drops.telekinesis.TelekinesisUtils;
import lombok.AccessLevel;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.ExperienceOrb;
@@ -133,6 +135,11 @@ public class InternalDropQueue implements AbstractDropQueue {
assert world != null;
loc = loc.add(0.5, 0.5, 0.5);
items.removeIf(itemStack -> itemStack.getType() == Material.AIR);
if (items.isEmpty()) {
return;
}
if (hasTelekinesis) {
HashMap<Integer, ItemStack> leftover = player.getInventory().addItem(items.toArray(new ItemStack[0]));
for (ItemStack drop : leftover.values()) {

View File

@@ -1,10 +1,12 @@
package com.willfp.eco.util.extensions.loader;
package com.willfp.eco.internal.extensions;
import com.willfp.eco.util.extensions.Extension;
import com.willfp.eco.util.extensions.MalformedExtensionException;
import com.willfp.eco.util.extensions.loader.ExtensionLoader;
import com.willfp.eco.util.internal.PluginDependent;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
@@ -94,6 +96,9 @@ public class EcoExtensionLoader extends PluginDependent implements ExtensionLoad
String mainClass = extensionYml.getString("main");
String name = extensionYml.getString("name");
String version = extensionYml.getString("version");
Validate.notNull(name, "Name is missing!");
Validate.notNull(version, "Version is missing!");
Extension.ExtensionMetadata metadata = new Extension.ExtensionMetadata(version, name);
Class<?> cls;

View File

@@ -1,20 +1,33 @@
package com.willfp.eco.util;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;
@UtilityClass
public class BlockUtils {
public class BlockUtils {
/**
* If the meta set function has been set.
*/
private boolean initialized = false;
/**
* The block break function.
*/
private BiConsumer<Player, Block> blockBreakConsumer = null;
private Set<Block> getNearbyBlocks(@NotNull final Block start,
@NotNull final List<Material> allowedMaterials,
@NotNull final HashSet<Block> blocks,
@NotNull final Set<Block> blocks,
final int limit) {
for (BlockFace face : BlockFace.values()) {
Block block = start.getRelative(face);
@@ -29,7 +42,6 @@ public class BlockUtils {
return blocks;
}
/**
* Get a set of all blocks in contact with each other of a specific type.
*
@@ -44,4 +56,31 @@ public class BlockUtils {
final int limit) {
return getNearbyBlocks(start, allowedMaterials, new HashSet<>(), limit);
}
/**
* Break the block as if the player had done it manually.
*
* @param player The player to break the block as.
* @param block The block to break.
*/
public void breakBlock(@NotNull final Player player,
@NotNull final Block block) {
Validate.isTrue(initialized, "Must be initialized!");
Validate.notNull(blockBreakConsumer, "Must be initialized!");
blockBreakConsumer.accept(player, block);
}
/**
* Initialize the block break function.
*
* @param function The function.
*/
public void initialize(@NotNull final BiConsumer<Player, Block> function) {
Validate.isTrue(!initialized, "Already initialized!");
blockBreakConsumer = function;
initialized = true;
}
}

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.util;
import lombok.experimental.UtilityClass;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.SoundCategory;
import org.bukkit.entity.Player;
@@ -37,25 +38,32 @@ public class DurabilityUtils {
return;
}
if (!(item.getItemMeta() instanceof Damageable)) {
return;
}
// Special edge case
if (item.getType() == Material.CARVED_PUMPKIN || item.getType() == Material.PLAYER_HEAD) {
return;
}
PlayerItemDamageEvent event3 = new PlayerItemDamageEvent(player, item, damage);
Bukkit.getPluginManager().callEvent(event3);
if (!event3.isCancelled()) {
int damage2 = event3.getDamage();
if (item.getItemMeta() instanceof Damageable) {
Damageable meta = (Damageable) item.getItemMeta();
meta.setDamage(meta.getDamage() + damage2);
Damageable meta = (Damageable) item.getItemMeta();
meta.setDamage(meta.getDamage() + damage2);
if (meta.getDamage() >= item.getType().getMaxDurability()) {
meta.setDamage(item.getType().getMaxDurability());
item.setItemMeta((ItemMeta) meta);
PlayerItemBreakEvent event = new PlayerItemBreakEvent(player, item);
Bukkit.getPluginManager().callEvent(event);
player.getInventory().clear(slot);
player.playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, SoundCategory.BLOCKS, 1, 1);
} else {
item.setItemMeta((ItemMeta) meta);
}
if (meta.getDamage() >= item.getType().getMaxDurability()) {
meta.setDamage(item.getType().getMaxDurability());
item.setItemMeta((ItemMeta) meta);
PlayerItemBreakEvent event = new PlayerItemBreakEvent(player, item);
Bukkit.getPluginManager().callEvent(event);
player.getInventory().clear(slot);
player.playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, SoundCategory.BLOCKS, 1, 1);
} else {
item.setItemMeta((ItemMeta) meta);
}
}
}
@@ -78,20 +86,22 @@ public class DurabilityUtils {
return;
}
if (!(item.getItemMeta() instanceof Damageable)) {
return;
}
PlayerItemDamageEvent event3 = new PlayerItemDamageEvent(player, item, damage);
Bukkit.getPluginManager().callEvent(event3);
if (!event3.isCancelled()) {
int damage2 = event3.getDamage();
if (item.getItemMeta() instanceof Damageable) {
Damageable meta = (Damageable) item.getItemMeta();
meta.setDamage(meta.getDamage() + damage2);
Damageable meta = (Damageable) item.getItemMeta();
meta.setDamage(meta.getDamage() + damage2);
if (meta.getDamage() >= item.getType().getMaxDurability()) {
meta.setDamage(item.getType().getMaxDurability() - 1);
}
item.setItemMeta((ItemMeta) meta);
if (meta.getDamage() >= item.getType().getMaxDurability()) {
meta.setDamage(item.getType().getMaxDurability() - 1);
}
item.setItemMeta((ItemMeta) meta);
}
}

View File

@@ -0,0 +1,52 @@
package com.willfp.eco.util;
import com.willfp.eco.util.optional.Prerequisite;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang.Validate;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.function.Function;
@UtilityClass
public class PlayerUtils {
/**
* If the meta set function has been set.
*/
private boolean initialized = false;
/**
* The cooldown function.
*/
private Function<Player, Double> cooldownFunction = null;
/**
* Get the attack cooldown for a player.
*
* @param player The player's attack cooldown.
* @return A value between 0 and 1, with 1 representing full power.
*/
public double getAttackCooldown(@NotNull final Player player) {
Validate.isTrue(initialized, "Must be initialized!");
Validate.notNull(cooldownFunction, "Must be initialized!");
if (Prerequisite.MINIMUM_1_16.isMet()) {
return player.getAttackCooldown();
}
return cooldownFunction.apply(player);
}
/**
* Initialize the cooldown function.
*
* @param function The function.
*/
public void initialize(@NotNull final Function<Player, Double> function) {
Validate.isTrue(!initialized, "Already initialized!");
cooldownFunction = function;
initialized = true;
}
}

View File

@@ -0,0 +1,47 @@
package com.willfp.eco.util;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang.Validate;
import org.bukkit.inventory.meta.SkullMeta;
import org.jetbrains.annotations.NotNull;
import java.util.function.BiConsumer;
@UtilityClass
public class SkullUtils {
/**
* If the meta set function has been set.
*/
private boolean initialized = false;
/**
* The meta set function.
*/
private BiConsumer<SkullMeta, String> metaSetConsumer = null;
/**
* Set the texture of a skull from base64.
*
* @param meta The meta to modify.
* @param base64 The base64 texture.
*/
public void setSkullTexture(@NotNull final SkullMeta meta,
@NotNull final String base64) {
Validate.isTrue(initialized, "Must be initialized!");
Validate.notNull(metaSetConsumer, "Must be initialized!");
metaSetConsumer.accept(meta, base64);
}
/**
* Initialize the skull texture function.
*
* @param function The function.
*/
public void initialize(@NotNull final BiConsumer<SkullMeta, String> function) {
Validate.isTrue(!initialized, "Already initialized!");
metaSetConsumer = function;
initialized = true;
}
}

View File

@@ -0,0 +1,47 @@
package com.willfp.eco.util;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang.Validate;
import org.bukkit.entity.Trident;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.function.Function;
@UtilityClass
public class TridentUtils {
/**
* If the meta set function has been set.
*/
private boolean initialized = false;
/**
* The meta set function.
*/
private Function<Trident, ItemStack> tridentFunction = null;
/**
* Get a trident's ItemStack.
*
* @param trident The trident to query.
* @return The trident's ItemStack.
*/
public ItemStack getItemStack(@NotNull final Trident trident) {
Validate.isTrue(initialized, "Must be initialized!");
Validate.notNull(tridentFunction, "Must be initialized!");
return tridentFunction.apply(trident);
}
/**
* Initialize the trident function.
*
* @param function The function.
*/
public void initialize(@NotNull final Function<Trident, ItemStack> function) {
Validate.isTrue(!initialized, "Already initialized!");
tridentFunction = function;
initialized = true;
}
}

View File

@@ -1,11 +1,11 @@
package com.willfp.eco.util.bukkit.keys;
import com.willfp.eco.util.internal.PluginDependentFactory;
import com.willfp.eco.util.internal.PluginDependent;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.bukkit.NamespacedKey;
import org.jetbrains.annotations.NotNull;
public class NamespacedKeyFactory extends PluginDependentFactory {
public class NamespacedKeyFactory extends PluginDependent {
/**
* Factory class to produce {@link NamespacedKey}s associated with an {@link AbstractEcoPlugin}.
*

View File

@@ -1,11 +1,11 @@
package com.willfp.eco.util.bukkit.meta;
import com.willfp.eco.util.internal.PluginDependentFactory;
import com.willfp.eco.util.internal.PluginDependent;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.bukkit.metadata.FixedMetadataValue;
import org.jetbrains.annotations.NotNull;
public class MetadataValueFactory extends PluginDependentFactory {
public class MetadataValueFactory extends PluginDependent {
/**
* Factory class to produce {@link FixedMetadataValue}s associated with an {@link AbstractEcoPlugin}.
*

View File

@@ -1,12 +1,12 @@
package com.willfp.eco.util.bukkit.scheduling;
import com.willfp.eco.util.internal.PluginDependentFactory;
import com.willfp.eco.util.internal.PluginDependent;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.jetbrains.annotations.NotNull;
import java.util.function.Consumer;
public class RunnableFactory extends PluginDependentFactory {
public class RunnableFactory extends PluginDependent {
/**
* Factory class to produce {@link EcoBukkitRunnable}s associated with an {@link AbstractEcoPlugin}.
*

View File

@@ -12,7 +12,8 @@ public interface Scheduler {
* @param ticksLater The amount of ticks to wait before execution.
* @return The created {@link BukkitTask}.
*/
BukkitTask runLater(@NotNull Runnable runnable, long ticksLater);
BukkitTask runLater(@NotNull Runnable runnable,
long ticksLater);
/**
* Run the task repeatedly on a timer.
@@ -22,7 +23,9 @@ public interface Scheduler {
* @param repeat The amount of ticks to wait between executions.
* @return The created {@link BukkitTask}.
*/
BukkitTask runTimer(@NotNull Runnable runnable, long delay, long repeat);
BukkitTask runTimer(@NotNull Runnable runnable,
long delay,
long repeat);
/**
* Run the task repeatedly and asynchronously on a timer.
@@ -32,7 +35,9 @@ public interface Scheduler {
* @param repeat The amount of ticks to wait between executions.
* @return The created {@link BukkitTask}.
*/
BukkitTask runAsyncTimer(@NotNull Runnable runnable, long delay, long repeat);
BukkitTask runAsyncTimer(@NotNull Runnable runnable,
long delay,
long repeat);
/**
* Run the task.
@@ -58,7 +63,9 @@ public interface Scheduler {
* @param repeat The amount of ticks to wait between executions.
* @return The id of the task.
*/
int syncRepeating(@NotNull Runnable runnable, long delay, long repeat);
int syncRepeating(@NotNull Runnable runnable,
long delay,
long repeat);
/**
* Cancel all running tasks from the linked {@link AbstractEcoPlugin}.

View File

@@ -1,221 +1,40 @@
package com.willfp.eco.util.config;
import com.willfp.eco.util.StringUtils;
import com.willfp.eco.util.internal.PluginDependent;
import com.willfp.eco.util.config.internal.AbstractUpdatableConfig;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import lombok.AccessLevel;
import lombok.Getter;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;
public abstract class BaseConfig extends PluginDependent implements ValueGetter {
/**
* The linked {@link YamlConfiguration} where values are physically stored.
*/
@Getter(AccessLevel.PUBLIC)
private final YamlConfiguration config;
/**
* The physical config file, as stored on disk.
*/
@Getter(AccessLevel.PROTECTED)
private final File configFile;
/**
* The full name of the config file (eg config.yml).
*/
private final String name;
/**
* Whether keys not in the base config should be removed on update.
*/
private final boolean removeUnused;
public abstract class BaseConfig extends AbstractUpdatableConfig {
/**
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
* <p>
* Automatically updates.
*
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
*/
protected BaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final AbstractEcoPlugin plugin,
@NotNull final String... updateBlacklist) {
super(configName, plugin, "", plugin.getClass(), removeUnused, updateBlacklist);
}
/**
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
* <p>
* Automatically updates.
*
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
*/
protected BaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final AbstractEcoPlugin plugin) {
super(plugin);
this.name = configName + ".yml";
this.removeUnused = removeUnused;
if (!new File(this.getPlugin().getDataFolder(), this.name).exists()) {
createFile();
}
this.configFile = new File(this.getPlugin().getDataFolder(), this.name);
this.config = YamlConfiguration.loadConfiguration(configFile);
update();
}
private void createFile() {
this.getPlugin().saveResource(name, false);
}
/**
* Update the config.
* <p>
* Writes missing values, however removes comments due to how configs are stored internally in bukkit.
*/
public void update() {
try {
config.load(configFile);
InputStream newIn = this.getPlugin().getResource(name);
if (newIn == null) {
this.getPlugin().getLog().error(name + " is null?");
return;
}
BufferedReader reader = new BufferedReader(new InputStreamReader(newIn, StandardCharsets.UTF_8));
YamlConfiguration newConfig = new YamlConfiguration();
newConfig.load(reader);
if (newConfig.getKeys(true).equals(config.getKeys(true))) {
return;
}
newConfig.getKeys(true).forEach((s -> {
if (!config.getKeys(true).contains(s)) {
config.set(s, newConfig.get(s));
}
}));
if (this.removeUnused) {
config.getKeys(true).forEach((s -> {
if (!newConfig.getKeys(true).contains(s)) {
config.set(s, null);
}
}));
}
config.save(configFile);
} catch (IOException | InvalidConfigurationException e) {
e.printStackTrace();
}
}
/**
* Get an integer from config.
*
* @param path The key to fetch the value from.
* @return The found value, or 0 if not found.
*/
@Override
public int getInt(@NotNull final String path) {
return config.getInt(path, 0);
}
/**
* Get an integer from config with a specified default (not found) value.
*
* @param path The key to fetch the value from.
* @param def The value to default to if not found.
* @return The found value, or the default.
*/
@Override
public int getInt(@NotNull final String path,
final int def) {
return config.getInt(path, def);
}
/**
* Get a list of integers from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@Override
@NotNull
public List<Integer> getInts(@NotNull final String path) {
return config.getIntegerList(path);
}
/**
* Get a boolean from config.
*
* @param path The key to fetch the value from.
* @return The found value, or false if not found.
*/
@Override
public boolean getBool(@NotNull final String path) {
return config.getBoolean(path, false);
}
/**
* Get a list of booleans from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@Override
@NotNull
public List<Boolean> getBools(@NotNull final String path) {
return config.getBooleanList(path);
}
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @return The found value, or an empty string if not found.
*/
@Override
@NotNull
public String getString(@NotNull final String path) {
return StringUtils.translate(Objects.requireNonNull(config.getString(path, "")));
}
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@Override
@NotNull
public List<String> getStrings(@NotNull final String path) {
return config.getStringList(path);
}
/**
* Get a decimal from config.
*
* @param path The key to fetch the value from.
* @return The found value, or 0 if not found.
*/
@Override
public double getDouble(@NotNull final String path) {
return config.getDouble(path, 0);
}
/**
* Get a list of decimals from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@Override
@NotNull
public List<Double> getDoubles(@NotNull final String path) {
return config.getDoubleList(path);
super(configName, plugin, "", plugin.getClass(), removeUnused, "");
}
}

View File

@@ -0,0 +1,28 @@
package com.willfp.eco.util.config;
import com.willfp.eco.util.config.internal.AbstractUpdatableConfig;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.jetbrains.annotations.NotNull;
public abstract class ExtendableConfig extends AbstractUpdatableConfig {
/**
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
* <p>
* Automatically updates.
*
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
*/
protected ExtendableConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final AbstractEcoPlugin plugin,
@NotNull final Class<?> source,
@NotNull final String subDirectoryPath,
@NotNull final String... updateBlacklist) {
super(configName, plugin, subDirectoryPath, source, removeUnused, updateBlacklist);
}
}

View File

@@ -1,163 +1,20 @@
package com.willfp.eco.util.config;
import com.willfp.eco.util.StringUtils;
import com.willfp.eco.util.internal.PluginDependent;
import com.willfp.eco.util.config.internal.AbstractConfig;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import lombok.AccessLevel;
import lombok.Getter;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.List;
import java.util.Objects;
public abstract class StaticBaseConfig extends PluginDependent implements ValueGetter {
/**
* The linked {@link YamlConfiguration} where values are physically stored.
*/
@Getter(AccessLevel.PUBLIC)
private final YamlConfiguration config;
/**
* The physical config file, as stored on disk.
*/
@Getter(AccessLevel.PROTECTED)
private final File configFile;
/**
* The full name of the config file (eg config.yml).
*/
private final String name;
public abstract class StaticBaseConfig extends AbstractConfig {
/**
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
* <p>
* Does not automatically update.
*
* @param configName The name of the config
* @param plugin The plugin.
* @param configName The name of the config
* @param plugin The plugin.
*/
protected StaticBaseConfig(@NotNull final String configName,
@NotNull final AbstractEcoPlugin plugin) {
super(plugin);
this.name = configName + ".yml";
if (!new File(this.getPlugin().getDataFolder(), this.name).exists()) {
createFile();
}
this.configFile = new File(this.getPlugin().getDataFolder(), this.name);
this.config = YamlConfiguration.loadConfiguration(configFile);
}
private void createFile() {
this.getPlugin().saveResource(name, false);
}
/**
* Get an integer from config.
*
* @param path The key to fetch the value from.
* @return The found value, or 0 if not found.
*/
@Override
public int getInt(@NotNull final String path) {
return config.getInt(path, 0);
}
/**
* Get an integer from config with a specified default (not found) value.
*
* @param path The key to fetch the value from.
* @param def The value to default to if not found.
* @return The found value, or the default.
*/
@Override
public int getInt(@NotNull final String path,
final int def) {
return config.getInt(path, def);
}
/**
* Get a list of integers from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@Override
@NotNull
public List<Integer> getInts(@NotNull final String path) {
return config.getIntegerList(path);
}
/**
* Get a boolean from config.
*
* @param path The key to fetch the value from.
* @return The found value, or false if not found.
*/
@Override
public boolean getBool(@NotNull final String path) {
return config.getBoolean(path, false);
}
/**
* Get a list of booleans from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@Override
@NotNull
public List<Boolean> getBools(@NotNull final String path) {
return config.getBooleanList(path);
}
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @return The found value, or an empty string if not found.
*/
@Override
@NotNull
public String getString(@NotNull final String path) {
return StringUtils.translate(Objects.requireNonNull(config.getString(path, "")));
}
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@Override
@NotNull
public List<String> getStrings(@NotNull final String path) {
return config.getStringList(path);
}
/**
* Get a decimal from config.
*
* @param path The key to fetch the value from.
* @return The found value, or 0 if not found.
*/
@Override
public double getDouble(@NotNull final String path) {
return config.getDouble(path, 0);
}
/**
* Get a list of decimals from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@Override
@NotNull
public List<Double> getDoubles(@NotNull final String path) {
return config.getDoubleList(path);
super(configName, plugin, "", plugin.getClass());
}
}

View File

@@ -1,87 +1,5 @@
package com.willfp.eco.util.config;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@SuppressWarnings("unused")
@Deprecated
public interface ValueGetter {
/**
* Get an integer from config.
*
* @param path The key to fetch the value from.
* @return The found value, or 0 if not found.
*/
int getInt(@NotNull String path);
/**
* Get an integer from config with a specified default (not found) value.
*
* @param path The key to fetch the value from.
* @param def The value to default to if not found.
* @return The found value, or the default.
*/
int getInt(@NotNull String path,
int def);
/**
* Get a list of integers from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@NotNull
List<Integer> getInts(@NotNull String path);
/**
* Get a boolean from config.
*
* @param path The key to fetch the value from.
* @return The found value, or false if not found.
*/
boolean getBool(@NotNull String path);
/**
* Get a list of booleans from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@NotNull
List<Boolean> getBools(@NotNull String path);
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @return The found value, or an empty string if not found.
*/
@NotNull
String getString(@NotNull String path);
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@NotNull
List<String> getStrings(@NotNull String path);
/**
* Get a decimal from config.
*
* @param path The key to fetch the value from.
* @return The found value, or 0 if not found.
*/
double getDouble(@NotNull String path);
/**
* Get a list of decimals from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@NotNull
List<Double> getDoubles(@NotNull String path);
}

View File

@@ -1,6 +1,5 @@
package com.willfp.eco.util.config.configs;
import com.willfp.eco.util.StringUtils;
import com.willfp.eco.util.config.BaseConfig;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.jetbrains.annotations.NotNull;
@@ -21,7 +20,7 @@ public class Lang extends BaseConfig {
* @return The prefix.
*/
public String getPrefix() {
return StringUtils.translate(this.getConfig().getString("messages.prefix"));
return this.getString("messages.prefix");
}
/**
@@ -30,7 +29,7 @@ public class Lang extends BaseConfig {
* @return The message.
*/
public String getNoPermission() {
return getPrefix() + StringUtils.translate(this.getConfig().getString("messages.no-permission"));
return getPrefix() + this.getString("messages.no-permission");
}
/**
@@ -40,6 +39,6 @@ public class Lang extends BaseConfig {
* @return The message with a prefix appended.
*/
public String getMessage(@NotNull final String message) {
return getPrefix() + StringUtils.translate(this.getConfig().getString("messages." + message));
return getPrefix() + this.getString("messages." + message);
}
}

View File

@@ -0,0 +1,472 @@
package com.willfp.eco.util.config.internal;
import com.willfp.eco.util.StringUtils;
import com.willfp.eco.util.internal.PluginDependent;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import lombok.AccessLevel;
import lombok.Getter;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@SuppressWarnings("unchecked")
public abstract class AbstractConfig extends PluginDependent {
/**
* The linked {@link YamlConfiguration} where values are physically stored.
*/
@Getter(AccessLevel.PUBLIC)
protected final YamlConfiguration config;
/**
* The physical config file, as stored on disk.
*/
@Getter(AccessLevel.PROTECTED)
private final File configFile;
/**
* The full name of the config file (eg config.yml).
*/
@Getter(AccessLevel.PROTECTED)
private final String name;
/**
* The subdirectory path.
*/
@Getter(AccessLevel.PROTECTED)
private final String subDirectoryPath;
/**
* The provider of the config.
*/
@Getter(AccessLevel.PROTECTED)
private final Class<?> source;
/**
* Cached values for faster reading.
*/
private final Map<String, Object> cache = new HashMap<>();
/**
* Abstract config.
*
* @param configName The name of the config
* @param plugin The plugin.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
*/
protected AbstractConfig(@NotNull final String configName,
@NotNull final AbstractEcoPlugin plugin,
@NotNull final String subDirectoryPath,
@NotNull final Class<?> source) {
super(plugin);
this.source = source;
this.subDirectoryPath = subDirectoryPath;
this.name = configName + ".yml";
File directory = new File(this.getPlugin().getDataFolder(), subDirectoryPath);
if (!directory.exists()) {
directory.mkdirs();
}
if (!new File(directory, this.name).exists()) {
createFile();
}
this.configFile = new File(directory, this.name);
this.config = YamlConfiguration.loadConfiguration(configFile);
}
private void createFile() {
String resourcePath = getResourcePath();
InputStream in = source.getResourceAsStream(resourcePath);
File outFile = new File(this.getPlugin().getDataFolder(), resourcePath);
int lastIndex = resourcePath.lastIndexOf('/');
File outDir = new File(this.getPlugin().getDataFolder(), resourcePath.substring(0, Math.max(lastIndex, 0)));
if (!outDir.exists()) {
outDir.mkdirs();
}
try {
if (!outFile.exists()) {
OutputStream out = new FileOutputStream(outFile);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.close();
in.close();
}
} catch (IOException ignored) {
}
}
/**
* Get resource path as relative to base directory.
*
* @return The resource path.
*/
protected String getResourcePath() {
String resourcePath;
if (subDirectoryPath.isEmpty()) {
resourcePath = name;
} else {
resourcePath = subDirectoryPath + name;
}
return "/" + resourcePath;
}
/**
* Get YamlConfiguration as found in jar.
*
* @return The YamlConfiguration.
*/
protected YamlConfiguration getConfigInJar() {
InputStream newIn = source.getResourceAsStream(getResourcePath());
if (newIn == null) {
throw new NullPointerException(this.getName() + " is null?");
}
BufferedReader reader = new BufferedReader(new InputStreamReader(newIn, StandardCharsets.UTF_8));
YamlConfiguration newConfig = new YamlConfiguration();
try {
newConfig.load(reader);
} catch (IOException | InvalidConfigurationException e) {
e.printStackTrace();
}
return newConfig;
}
/**
* Clears cache.
*/
public final void clearCache() {
cache.clear();
}
/**
* Get if the config contains a key.
*
* @param path The key to check.
* @return If contained.
*/
public boolean has(@NotNull final String path) {
return config.contains(path);
}
/**
* Get configuration section from config.
*
* @param path The key to check.
* @return The configuration section. Throws NPE if not found.
*/
@NotNull
public ConfigurationSection getSection(@NotNull final String path) {
ConfigurationSection section = getSectionOrNull(path);
if (section == null) {
throw new NullPointerException("Section cannot be null!");
} else {
return section;
}
}
/**
* Get configuration section from config.
*
* @param path The key to check.
* @return The configuration section, or null if not found.
*/
@Nullable
public ConfigurationSection getSectionOrNull(@NotNull final String path) {
if (cache.containsKey(path)) {
return (ConfigurationSection) cache.get(path);
} else {
cache.put(path, config.getConfigurationSection(path));
return getSectionOrNull(path);
}
}
/**
* Get an integer from config.
*
* @param path The key to fetch the value from.
* @return The found value, or 0 if not found.
*/
public int getInt(@NotNull final String path) {
if (cache.containsKey(path)) {
return (int) cache.get(path);
} else {
cache.put(path, config.getInt(path, 0));
return getInt(path);
}
}
/**
* Get an integer from config.
*
* @param path The key to fetch the value from.
* @return The found value, or null if not found.
*/
@Nullable
public Integer getIntOrNull(@NotNull final String path) {
if (has(path)) {
return getInt(path);
} else {
return null;
}
}
/**
* Get an integer from config with a specified default (not found) value.
*
* @param path The key to fetch the value from.
* @param def The value to default to if not found.
* @return The found value, or the default.
*/
public int getInt(@NotNull final String path,
final int def) {
if (cache.containsKey(path)) {
return (int) cache.get(path);
} else {
cache.put(path, config.getInt(path, def));
return getInt(path);
}
}
/**
* Get a list of integers from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@NotNull
public List<Integer> getInts(@NotNull final String path) {
if (cache.containsKey(path)) {
return (List<Integer>) cache.get(path);
} else {
cache.put(path, config.getIntegerList(path));
return getInts(path);
}
}
/**
* Get a list of integers from config.
*
* @param path The key to fetch the value from.
* @return The found value, or null if not found.
*/
@Nullable
public List<Integer> getIntsOrNull(@NotNull final String path) {
if (has(path)) {
return getInts(path);
} else {
return null;
}
}
/**
* Get a boolean from config.
*
* @param path The key to fetch the value from.
* @return The found value, or false if not found.
*/
public boolean getBool(@NotNull final String path) {
if (cache.containsKey(path)) {
return (boolean) cache.get(path);
} else {
cache.put(path, config.getBoolean(path));
return getBool(path);
}
}
/**
* Get a boolean from config.
*
* @param path The key to fetch the value from.
* @return The found value, or null if not found.
*/
@Nullable
public Boolean getBoolOrNull(@NotNull final String path) {
if (has(path)) {
return getBool(path);
} else {
return null;
}
}
/**
* Get a list of booleans from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@NotNull
public List<Boolean> getBools(@NotNull final String path) {
if (cache.containsKey(path)) {
return (List<Boolean>) cache.get(path);
} else {
cache.put(path, config.getBooleanList(path));
return getBools(path);
}
}
/**
* Get a list of booleans from config.
*
* @param path The key to fetch the value from.
* @return The found value, or null if not found.
*/
@Nullable
public List<Boolean> getBoolsOrNull(@NotNull final String path) {
if (has(path)) {
return getBools(path);
} else {
return null;
}
}
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @return The found value, or an empty string if not found.
*/
@NotNull
public String getString(@NotNull final String path) {
if (cache.containsKey(path)) {
return (String) cache.get(path);
} else {
cache.put(path, StringUtils.translate(Objects.requireNonNull(config.getString(path, ""))));
return getString(path);
}
}
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @return The found value, or null if not found.
*/
@Nullable
public String getStringOrNull(@NotNull final String path) {
if (has(path)) {
return getString(path);
} else {
return null;
}
}
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@NotNull
public List<String> getStrings(@NotNull final String path) {
if (cache.containsKey(path)) {
return (List<String>) cache.get(path);
} else {
cache.put(path, config.getStringList(path));
return getStrings(path);
}
}
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @return The found value, or null if not found.
*/
@Nullable
public List<String> getStringsOrNull(@NotNull final String path) {
if (has(path)) {
return getStrings(path);
} else {
return null;
}
}
/**
* Get a decimal from config.
*
* @param path The key to fetch the value from.
* @return The found value, or 0 if not found.
*/
public double getDouble(@NotNull final String path) {
if (cache.containsKey(path)) {
return (double) cache.get(path);
} else {
cache.put(path, config.getDouble(path));
return getDouble(path);
}
}
/**
* Get a decimal from config.
*
* @param path The key to fetch the value from.
* @return The found value, or null if not found.
*/
@Nullable
public Double getDoubleOrNull(@NotNull final String path) {
if (has(path)) {
return getDouble(path);
} else {
return null;
}
}
/**
* Get a list of decimals from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@NotNull
public List<Double> getDoubles(@NotNull final String path) {
if (cache.containsKey(path)) {
return (List<Double>) cache.get(path);
} else {
cache.put(path, config.getDoubleList(path));
return getDoubles(path);
}
}
/**
* Get a list of decimals from config.
*
* @param path The key to fetch the value from.
* @return The found value, or null if not found.
*/
@Nullable
public List<Double> getDoublesOrNull(@NotNull final String path) {
if (has(path)) {
return getDoubles(path);
} else {
return null;
}
}
}

View File

@@ -0,0 +1,87 @@
package com.willfp.eco.util.config.internal;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public abstract class AbstractUpdatableConfig extends AbstractConfig {
/**
* Whether keys not in the base config should be removed on update.
*/
private final boolean removeUnused;
/**
* List of blacklisted update keys.
*/
private final List<String> updateBlacklist;
/**
* Updatable config.
*
* @param configName The name of the config
* @param plugin The plugin.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param updateBlacklist Substring of keys to not add/remove keys for.
*/
protected AbstractUpdatableConfig(@NotNull final String configName,
@NotNull final AbstractEcoPlugin plugin,
@NotNull final String subDirectoryPath,
@NotNull final Class<?> source,
final boolean removeUnused,
@NotNull final String... updateBlacklist) {
super(configName, plugin, subDirectoryPath, source);
this.removeUnused = removeUnused;
this.updateBlacklist = new ArrayList<>(Arrays.asList(updateBlacklist));
this.updateBlacklist.removeIf(String::isEmpty);
update();
}
/**
* Update the config.
* <p>
* Writes missing values, however removes comments due to how configs are stored internally in bukkit.
*/
public void update() {
super.clearCache();
try {
config.load(this.getConfigFile());
YamlConfiguration newConfig = this.getConfigInJar();
if (newConfig.getKeys(true).equals(config.getKeys(true))) {
return;
}
newConfig.getKeys(true).forEach((s -> {
if (!config.getKeys(true).contains(s)) {
if (updateBlacklist.stream().noneMatch(s::contains)) {
config.set(s, newConfig.get(s));
}
}
}));
if (this.removeUnused) {
config.getKeys(true).forEach((s -> {
if (!newConfig.getKeys(true).contains(s)) {
if (updateBlacklist.stream().noneMatch(s::contains)) {
config.set(s, null);
}
}
}));
}
config.save(this.getConfigFile());
} catch (IOException | InvalidConfigurationException e) {
e.printStackTrace();
}
}
}

View File

@@ -1,7 +1,13 @@
package com.willfp.eco.util.display;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang.Validate;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -24,15 +30,9 @@ public class Display {
private static final List<Function<ItemStack, ItemStack>> REVERT_FUNCTIONS = new ArrayList<>();
/**
* Registered finalize functions.
* NamespacedKey for finalizing.
*/
public static final List<Function<ItemStack, ItemStack>> FINALIZE_FUNCTIONS = new ArrayList<>();
/**
* Registered finalize test functions.
*/
public static final List<Predicate<ItemStack>> FINALIZE_TEST_FUNCTIONS = new ArrayList<>();
private static NamespacedKey finalizeKey;
/**
* Register display module.
@@ -66,24 +66,6 @@ public class Display {
REVERT_FUNCTIONS.add(function);
}
/**
* Register finalize function.
*
* @param function The function.
*/
public void registerFinalizeModule(@NotNull final Function<ItemStack, ItemStack> function) {
FINALIZE_FUNCTIONS.add(function);
}
/**
* Register finalize test function.
*
* @param function The function.
*/
public void registerFinalizeTestModule(@NotNull final Predicate<ItemStack> function) {
FINALIZE_TEST_FUNCTIONS.add(function);
}
/**
* Display on ItemStacks.
*
@@ -91,6 +73,13 @@ public class Display {
* @return The itemstack.
*/
public ItemStack display(@NotNull final ItemStack itemStack) {
if (isFinalized(itemStack)) {
unfinalize(itemStack);
return itemStack;
}
revert(itemStack);
for (Map<String, Function<ItemStack, ItemStack>> displayFunctions : DISPLAY_FUNCTIONS) {
if (displayFunctions == null) {
continue;
@@ -121,9 +110,15 @@ public class Display {
* @return The itemstack.
*/
public ItemStack revert(@NotNull final ItemStack itemStack) {
if (isFinalized(itemStack)) {
unfinalize(itemStack);
return itemStack;
}
for (Function<ItemStack, ItemStack> displayFunction : REVERT_FUNCTIONS) {
displayFunction.apply(itemStack);
}
return itemStack;
}
@@ -134,26 +129,85 @@ public class Display {
* @return The itemstack.
*/
public ItemStack finalize(@NotNull final ItemStack itemStack) {
for (Function<ItemStack, ItemStack> function : FINALIZE_FUNCTIONS) {
function.apply(itemStack);
Validate.notNull(finalizeKey, "Key cannot be null!");
if (itemStack.getType().getMaxStackSize() > 1) {
return itemStack;
}
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
return itemStack;
}
PersistentDataContainer container = meta.getPersistentDataContainer();
container.set(finalizeKey, PersistentDataType.INTEGER, 1);
itemStack.setItemMeta(meta);
return itemStack;
}
/**
* Finalize an ItemStacks.
* Unfinalize an ItemStacks.
*
* @param itemStack The item.
* @return The itemstack.
*/
public ItemStack unfinalize(@NotNull final ItemStack itemStack) {
Validate.notNull(finalizeKey, "Key cannot be null!");
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
return itemStack;
}
PersistentDataContainer container = meta.getPersistentDataContainer();
container.remove(finalizeKey);
itemStack.setItemMeta(meta);
return itemStack;
}
/**
* If an item is finalized.
*
* @param itemStack The item.
* @return If finalized.
*/
public boolean isFinalized(@NotNull final ItemStack itemStack) {
for (Predicate<ItemStack> function : FINALIZE_TEST_FUNCTIONS) {
if (function.test(itemStack)) {
return true;
}
Validate.notNull(finalizeKey, "Key cannot be null!");
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
return false;
}
PersistentDataContainer container = meta.getPersistentDataContainer();
return container.has(finalizeKey, PersistentDataType.INTEGER);
}
return false;
/**
* Register finalize function.
*
* @param function The function.
* @deprecated Not needed.
*/
@Deprecated
public void registerFinalizeModule(@NotNull final Function<ItemStack, ItemStack> function) {
// This function is not needed.
}
/**
* Register finalize test function.
*
* @param function The function.
* @deprecated Not needed.
*/
@Deprecated
public void registerFinalizeTestModule(@NotNull final Predicate<ItemStack> function) {
// This isn't needed.
}
/**
* Set key to be used for finalization.
*
* @param finalizeKey The key.
*/
@ApiStatus.Internal
public static void setFinalizeKey(@NotNull final NamespacedKey finalizeKey) {
Display.finalizeKey = finalizeKey;
}
static {

View File

@@ -1,10 +1,10 @@
package com.willfp.eco.util.drops;
import com.willfp.eco.util.drops.internal.AbstractDropQueue;
import com.willfp.eco.util.drops.internal.DropManager;
import com.willfp.eco.util.drops.internal.DropQueueType;
import com.willfp.eco.util.drops.internal.FastCollatedDropQueue;
import com.willfp.eco.util.drops.internal.InternalDropQueue;
import com.willfp.eco.internal.drops.AbstractDropQueue;
import com.willfp.eco.internal.drops.DropManager;
import com.willfp.eco.internal.drops.DropQueueType;
import com.willfp.eco.internal.drops.impl.FastCollatedDropQueue;
import com.willfp.eco.internal.drops.impl.InternalDropQueue;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;

View File

@@ -122,6 +122,6 @@ public class ArmorEquipEvent extends PlayerEvent implements Cancellable {
/**
* When you die causing all armor to unequip
*/
DEATH;
DEATH
}
}

View File

@@ -1,12 +0,0 @@
package com.willfp.eco.util.internal;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
@ApiStatus.Internal
public abstract class PluginDependentFactory extends PluginDependent {
protected PluginDependentFactory(@NotNull final AbstractEcoPlugin plugin) {
super(plugin);
}
}

View File

@@ -1,8 +1,8 @@
package com.willfp.eco.util.optional;
import com.willfp.eco.util.ClassUtils;
import com.willfp.eco.util.proxy.ProxyConstants;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -20,7 +20,7 @@ public class Prerequisite {
* Requires the server to be running minecraft version 1.16 or higher.
*/
public static final Prerequisite MINIMUM_1_16 = new Prerequisite(
() -> !Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3].contains("15"),
() -> !ProxyConstants.NMS_VERSION.contains("15"),
"Requires minimum server version of 1.16"
);

View File

@@ -1,21 +1,21 @@
package com.willfp.eco.util.plugin;
import com.willfp.eco.internal.bukkit.events.EcoEventManager;
import com.willfp.eco.internal.bukkit.logging.EcoLogger;
import com.willfp.eco.internal.bukkit.scheduling.EcoScheduler;
import com.willfp.eco.util.ClassUtils;
import com.willfp.eco.util.arrows.ArrowDataListener;
import com.willfp.eco.util.bukkit.events.EcoEventManager;
import com.willfp.eco.util.bukkit.events.EventManager;
import com.willfp.eco.util.bukkit.keys.NamespacedKeyFactory;
import com.willfp.eco.util.bukkit.logging.EcoLogger;
import com.willfp.eco.util.bukkit.logging.Logger;
import com.willfp.eco.util.bukkit.meta.MetadataValueFactory;
import com.willfp.eco.util.bukkit.scheduling.EcoScheduler;
import com.willfp.eco.util.bukkit.scheduling.RunnableFactory;
import com.willfp.eco.util.bukkit.scheduling.Scheduler;
import com.willfp.eco.util.command.AbstractCommand;
import com.willfp.eco.util.config.configs.Config;
import com.willfp.eco.util.config.configs.Lang;
import com.willfp.eco.util.config.updating.ConfigHandler;
import com.willfp.eco.util.extensions.loader.EcoExtensionLoader;
import com.willfp.eco.internal.extensions.EcoExtensionLoader;
import com.willfp.eco.util.extensions.loader.ExtensionLoader;
import com.willfp.eco.util.integrations.IntegrationLoader;
import com.willfp.eco.util.integrations.placeholder.PlaceholderManager;
@@ -41,7 +41,6 @@ import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@SuppressWarnings("unchecked")
public abstract class AbstractEcoPlugin extends JavaPlugin {
/**
* Loaded eco plugins.

View File

@@ -16,6 +16,7 @@ public final class EcoShapedRecipe extends PluginDependent implements Registerab
/**
* Recipe parts.
*/
@Getter
private final RecipePart[] parts;
/**

View File

@@ -14,7 +14,7 @@ import java.util.function.Function;
@UtilityClass
public final class RecipePartUtils {
/**
* Set of tests that return if the player is telekinetic.
* All recipes.
*/
private static final Map<String, Function<String, RecipePart>> TESTS = new HashMap<>();

View File

@@ -0,0 +1,17 @@
package com.willfp.eco.util.tuples;
import org.jetbrains.annotations.Nullable;
@SuppressWarnings("deprecation")
public class Pair<A, B> extends com.willfp.eco.util.tuplets.Pair<A, B> {
/**
* Create a pair of values.
*
* @param first The first item in the pair.
* @param second The second item in the pair.
*/
public Pair(@Nullable final A first,
@Nullable final B second) {
super(first, second);
}
}

View File

@@ -0,0 +1,19 @@
package com.willfp.eco.util.tuples;
import org.jetbrains.annotations.Nullable;
@SuppressWarnings("deprecation")
public class Triplet<A, B, C> extends com.willfp.eco.util.tuplets.Triplet<A, B, C> {
/**
* Create a triple of values.
*
* @param first The first item in the pair.
* @param second The second item in the pair.
* @param third The third item in the pair.
*/
public Triplet(@Nullable final A first,
@Nullable final B second,
@Nullable final C third) {
super(first, second, third);
}
}

View File

@@ -5,7 +5,9 @@ import lombok.Setter;
import lombok.ToString;
import org.jetbrains.annotations.Nullable;
@SuppressWarnings("DeprecatedIsStillUsed")
@ToString
@Deprecated
public class Pair<A, B> {
/**
* The first value in the pair.
@@ -25,6 +27,8 @@ public class Pair<A, B> {
/**
* Create a pair of values.
* <p>
* This is deprecated because I forgot how to spell Tuples before putting this into production.
*
* @param first The first item in the pair.
* @param second The second item in the pair.

View File

@@ -5,7 +5,9 @@ import lombok.Setter;
import lombok.ToString;
import org.jetbrains.annotations.Nullable;
@SuppressWarnings("DeprecatedIsStillUsed")
@ToString
@Deprecated
public class Triplet<A, B, C> {
/**
* The first item in the triplet.
@@ -33,6 +35,8 @@ public class Triplet<A, B, C> {
/**
* Create a triplet.
* <p>
* This is deprecated because I forgot how to spell Tuples before putting this into production.
*
* @param first The first item in the triplet.
* @param second The second item in the triplet.

View File

@@ -1,2 +1,2 @@
version = 3.3.2
version = 3.8.0
plugin-name = eco