Compare commits

...

63 Commits
3.8.0 ... 4.3.0

Author SHA1 Message Date
Auxilor
9565ab0641 Fixed StaticOptionalConfig 2021-04-02 12:26:56 +01:00
Auxilor
45c53b96dc Updated to 4.3.0 2021-04-02 12:24:49 +01:00
Auxilor
861325ac3f Added serialization system 2021-04-02 12:24:38 +01:00
Auxilor
70c015c1f0 Updated to 4.2.9 2021-03-29 20:15:58 +01:00
Auxilor
8f3755b130 Fixed NCP integration 2021-03-29 20:15:45 +01:00
Auxilor
697ff0ccbb Updated to 4.2.8 2021-03-29 08:54:46 +01:00
Auxilor
f117847fc3 Fixed towny again 2021-03-29 08:54:36 +01:00
Auxilor
bd88d40309 Updated to 4.2.7 2021-03-28 21:39:44 +01:00
Auxilor
2fd8aab230 Fixed towny integration 2021-03-28 21:39:15 +01:00
Auxilor
5ec10ec617 Fixed ComabatLogX integration 2021-03-27 19:57:43 +00:00
Auxilor
270270d015 Added support for CombatLogX NewbieHelper and UltimateLands 2021-03-27 19:53:51 +00:00
Auxilor
3364b01c9d Added combatlogx integration 2021-03-27 19:37:30 +00:00
Auxilor
4beda35adf Updated to 4.2.6 2021-03-27 19:16:34 +00:00
Auxilor
fd3e79378b Fixed display occuring twice 2021-03-27 19:15:51 +00:00
Auxilor
4d0068e551 Fixed varargs breaking plugins using new display system 2021-03-27 19:15:40 +00:00
Auxilor
6933c0e5ef Added backend for future dependencies 2021-03-27 19:15:07 +00:00
Auxilor
839b3724e7 Updated to 4.2.5 2021-03-24 18:31:57 +00:00
Auxilor
6006865358 Merge remote-tracking branch 'origin/master' into master 2021-03-24 18:30:46 +00:00
Auxilor
4907b4b6e6 Updated to 4.2.4 2021-03-24 18:30:31 +00:00
Auxilor
29735cdf83 Fixed mcMMO Integration when running an old version 2021-03-24 18:30:08 +00:00
Auxilor
ae4b2ce0d0 Updated to 4.2.4 2021-03-21 16:26:06 +00:00
Auxilor
786cbbcd7d Added CMI hex code support 2021-03-21 16:21:50 +00:00
Auxilor
6d3f2fc5dc Improved consistency of config list getters 2021-03-18 18:55:50 +00:00
Auxilor
6697cc412e Updated to 4.2.3 2021-03-12 22:33:19 +00:00
Auxilor
17a877a89a Merge remote-tracking branch 'origin/master' into master 2021-03-12 22:32:36 +00:00
Auxilor
9d4149c58f Switched illusioner with ecobosses 2021-03-12 22:32:26 +00:00
Auxilor
123ac79918 Updated to 4.2.2 2021-03-06 18:03:50 +00:00
Auxilor
1670c8b3fb Merge pull request #5 from PaulBGD/master 2021-03-06 17:15:42 +00:00
Paul Sauve
6125044e4c Do less work with displaying items 2021-03-06 11:07:18 -06:00
Auxilor
492439470c Updated to 4.2.1 2021-02-26 10:12:33 +00:00
Auxilor
e9e39345ed Reworked finalize system 2021-02-26 10:12:22 +00:00
Auxilor
cf29df7bce Updated to 4.2.0 2021-02-25 17:56:03 +00:00
Auxilor
c259cb5a45 Changed display to allow varargs 2021-02-25 17:55:49 +00:00
Auxilor
4148f55bb5 Updated to 4.1.3 2021-02-25 17:20:32 +00:00
Auxilor
b63791c14b Prevented overriding getPluginName() metod 2021-02-25 17:20:20 +00:00
Auxilor
294dfabd54 Removed duplicate display modules 2021-02-25 17:20:01 +00:00
Auxilor
d7f7cad863 Updated to 4.1.2 2021-02-23 18:53:53 +00:00
Auxilor
afd8df5b48 Fixed WorldGuard integration 2021-02-23 18:53:38 +00:00
Auxilor
b9d1f36604 Getters breaking 2021-02-18 15:02:48 +00:00
Auxilor
403a7a7da8 Fixed Configs again 2021-02-18 14:57:36 +00:00
Auxilor
f6fb5bcf66 Updated to 4.1.1 2021-02-18 14:55:22 +00:00
Auxilor
194eb8b5f5 Fixed configs 2021-02-18 14:55:07 +00:00
Auxilor
853aaca071 Updated to 4.1.0 2021-02-18 14:26:48 +00:00
Auxilor
18dabd6bcf Added StaticOptionalConfig 2021-02-18 14:26:37 +00:00
Auxilor
bb42505d66 Hopeful fix 2021-02-17 16:07:08 +00:00
Auxilor
b4d59077e3 Fixed load order again 2021-02-17 15:55:39 +00:00
Auxilor
104d55c11b Changed load order again 2021-02-17 15:49:51 +00:00
Auxilor
b5af17cf08 Changed load order 2021-02-17 15:45:33 +00:00
Auxilor
78ae662ced Fixed RecipeParts 2021-02-17 15:20:39 +00:00
Auxilor
32e48db3ce Removed @Nullable because it's annoying 2021-02-17 15:02:52 +00:00
Auxilor
8a27e75c02 Fixed EcoPlugin 2021-02-17 14:55:34 +00:00
Auxilor
bf55e9b189 Constructor change 2021-02-17 14:54:28 +00:00
Auxilor
bfbaa3d033 Removed redundant check 2021-02-17 14:42:03 +00:00
Auxilor
64f87d5741 Cleaned up recipes 2021-02-17 13:54:02 +00:00
Auxilor
cb3441286c Removed redundant Registerable interface 2021-02-17 13:39:32 +00:00
Auxilor
5e97a0f894 Refactored ArrowDataListener 2021-02-17 13:35:32 +00:00
Auxilor
de2166dfdb Reworked tuples 2021-02-17 13:33:57 +00:00
Auxilor
abd361f4b5 Refactored config internals 2021-02-17 13:30:06 +00:00
Auxilor
422f8ead23 Removed RecipeListener from api 2021-02-17 13:27:28 +00:00
Auxilor
7c05dd7457 Reworked recipes 2021-02-17 13:20:34 +00:00
Auxilor
3ef7622c6f Updated to 4.0.0 2021-02-17 12:50:16 +00:00
Auxilor
8207d62b1f Reworked display system. 2021-02-17 12:50:01 +00:00
Auxilor
75a0b1dd0d Added @Internal annotations 2021-02-17 12:05:14 +00:00
57 changed files with 1748 additions and 965 deletions

View File

@@ -45,6 +45,9 @@ allprojects {
// NoCheatPlus // NoCheatPlus
maven { url 'https://repo.md-5.net/content/repositories/snapshots/' } maven { url 'https://repo.md-5.net/content/repositories/snapshots/' }
// CombatLogX
maven { url 'https://nexus.sirblobman.xyz/repository/public/' }
} }
dependencies { dependencies {

View File

@@ -19,7 +19,7 @@ public final class VillagerTrade implements VillagerTradeProxy {
fResult.setAccessible(true); fResult.setAccessible(true);
ItemStack result = merchantRecipe.getResult(); ItemStack result = merchantRecipe.getResult();
Display.display(result); Display.displayAndFinalize(result);
fResult.set(merchantRecipe, result); fResult.set(merchantRecipe, result);
// Get NMS MerchantRecipe from CraftMerchantRecipe // Get NMS MerchantRecipe from CraftMerchantRecipe
@@ -31,7 +31,7 @@ public final class VillagerTrade implements VillagerTradeProxy {
fSelling.setAccessible(true); fSelling.setAccessible(true);
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem); ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
Display.display(selling); Display.displayAndFinalize(selling);
fSelling.set(handle, CraftItemStack.asNMSCopy(selling)); fSelling.set(handle, CraftItemStack.asNMSCopy(selling));
} catch (IllegalAccessException | NoSuchFieldException e) { } catch (IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace(); e.printStackTrace();

View File

@@ -18,7 +18,7 @@ public final class VillagerTrade implements VillagerTradeProxy {
Field fResult = MerchantRecipe.class.getDeclaredField("result"); Field fResult = MerchantRecipe.class.getDeclaredField("result");
fResult.setAccessible(true); fResult.setAccessible(true);
ItemStack result = merchantRecipe.getResult(); ItemStack result = merchantRecipe.getResult();
Display.display(result); Display.displayAndFinalize(result);
fResult.set(merchantRecipe, result); fResult.set(merchantRecipe, result);
// Get NMS MerchantRecipe from CraftMerchantRecipe // Get NMS MerchantRecipe from CraftMerchantRecipe
@@ -30,7 +30,7 @@ public final class VillagerTrade implements VillagerTradeProxy {
fSelling.setAccessible(true); fSelling.setAccessible(true);
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem); ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
Display.display(selling); Display.displayAndFinalize(selling);
fSelling.set(handle, CraftItemStack.asNMSCopy(selling)); fSelling.set(handle, CraftItemStack.asNMSCopy(selling));
} catch (IllegalAccessException | NoSuchFieldException e) { } catch (IllegalAccessException | NoSuchFieldException e) {

View File

@@ -18,7 +18,7 @@ public final class VillagerTrade implements VillagerTradeProxy {
Field fResult = MerchantRecipe.class.getDeclaredField("result"); Field fResult = MerchantRecipe.class.getDeclaredField("result");
fResult.setAccessible(true); fResult.setAccessible(true);
ItemStack result = merchantRecipe.getResult(); ItemStack result = merchantRecipe.getResult();
Display.display(result); Display.displayAndFinalize(result);
fResult.set(merchantRecipe, result); fResult.set(merchantRecipe, result);
// Get NMS MerchantRecipe from CraftMerchantRecipe // Get NMS MerchantRecipe from CraftMerchantRecipe
@@ -30,7 +30,7 @@ public final class VillagerTrade implements VillagerTradeProxy {
fSelling.setAccessible(true); fSelling.setAccessible(true);
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem); ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
Display.display(selling); Display.displayAndFinalize(selling);
fSelling.set(handle, CraftItemStack.asNMSCopy(selling)); fSelling.set(handle, CraftItemStack.asNMSCopy(selling));
} catch (IllegalAccessException | NoSuchFieldException e) { } catch (IllegalAccessException | NoSuchFieldException e) {

View File

@@ -18,7 +18,7 @@ public final class VillagerTrade implements VillagerTradeProxy {
Field fResult = MerchantRecipe.class.getDeclaredField("result"); Field fResult = MerchantRecipe.class.getDeclaredField("result");
fResult.setAccessible(true); fResult.setAccessible(true);
ItemStack result = merchantRecipe.getResult(); ItemStack result = merchantRecipe.getResult();
Display.display(result); Display.displayAndFinalize(result);
fResult.set(merchantRecipe, result); fResult.set(merchantRecipe, result);
// Get NMS MerchantRecipe from CraftMerchantRecipe // Get NMS MerchantRecipe from CraftMerchantRecipe
@@ -30,7 +30,7 @@ public final class VillagerTrade implements VillagerTradeProxy {
fSelling.setAccessible(true); fSelling.setAccessible(true);
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem); ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
Display.display(selling); Display.displayAndFinalize(selling);
fSelling.set(handle, CraftItemStack.asNMSCopy(selling)); fSelling.set(handle, CraftItemStack.asNMSCopy(selling));
} catch (IllegalAccessException | NoSuchFieldException e) { } catch (IllegalAccessException | NoSuchFieldException e) {

View File

@@ -16,19 +16,23 @@ import com.willfp.eco.spigot.eventlisteners.NaturalExpGainListeners;
import com.willfp.eco.spigot.integrations.anticheat.AnticheatAAC; import com.willfp.eco.spigot.integrations.anticheat.AnticheatAAC;
import com.willfp.eco.spigot.integrations.anticheat.AnticheatMatrix; import com.willfp.eco.spigot.integrations.anticheat.AnticheatMatrix;
import com.willfp.eco.spigot.integrations.anticheat.AnticheatNCP; import com.willfp.eco.spigot.integrations.anticheat.AnticheatNCP;
import com.willfp.eco.spigot.integrations.antigrief.AntigriefCombatLogX;
import com.willfp.eco.spigot.integrations.antigrief.AntigriefFactionsUUID; import com.willfp.eco.spigot.integrations.antigrief.AntigriefFactionsUUID;
import com.willfp.eco.spigot.integrations.antigrief.AntigriefGriefPrevention; import com.willfp.eco.spigot.integrations.antigrief.AntigriefGriefPrevention;
import com.willfp.eco.spigot.integrations.antigrief.AntigriefKingdoms; import com.willfp.eco.spigot.integrations.antigrief.AntigriefKingdoms;
import com.willfp.eco.spigot.integrations.antigrief.AntigriefLands; import com.willfp.eco.spigot.integrations.antigrief.AntigriefLands;
import com.willfp.eco.spigot.integrations.antigrief.AntigriefTowny; import com.willfp.eco.spigot.integrations.antigrief.AntigriefTowny;
import com.willfp.eco.spigot.integrations.antigrief.AntigriefUltimateLands;
import com.willfp.eco.spigot.integrations.antigrief.AntigriefWorldGuard; import com.willfp.eco.spigot.integrations.antigrief.AntigriefWorldGuard;
import com.willfp.eco.spigot.integrations.mcmmo.McmmoIntegrationImpl; import com.willfp.eco.spigot.integrations.mcmmo.McmmoIntegrationImpl;
import com.willfp.eco.spigot.recipes.RecipeListener;
import com.willfp.eco.util.BlockUtils; import com.willfp.eco.util.BlockUtils;
import com.willfp.eco.util.PlayerUtils; import com.willfp.eco.util.PlayerUtils;
import com.willfp.eco.util.SkullUtils; import com.willfp.eco.util.SkullUtils;
import com.willfp.eco.util.TridentUtils; import com.willfp.eco.util.TridentUtils;
import com.willfp.eco.util.command.AbstractCommand; import com.willfp.eco.util.command.AbstractCommand;
import com.willfp.eco.util.display.Display; import com.willfp.eco.util.display.Display;
import com.willfp.eco.util.display.DisplayModule;
import com.willfp.eco.util.events.armorequip.ArmorListener; import com.willfp.eco.util.events.armorequip.ArmorListener;
import com.willfp.eco.util.events.armorequip.DispenserArmorListener; import com.willfp.eco.util.events.armorequip.DispenserArmorListener;
import com.willfp.eco.util.integrations.IntegrationLoader; import com.willfp.eco.util.integrations.IntegrationLoader;
@@ -39,6 +43,7 @@ import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import com.willfp.eco.util.protocollib.AbstractPacketAdapter; import com.willfp.eco.util.protocollib.AbstractPacketAdapter;
import lombok.Getter; import lombok.Getter;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@@ -71,6 +76,7 @@ public class EcoPlugin extends AbstractEcoPlugin {
this.getEventManager().registerListener(new ArmorListener()); this.getEventManager().registerListener(new ArmorListener());
this.getEventManager().registerListener(new DispenserArmorListener()); this.getEventManager().registerListener(new DispenserArmorListener());
this.getEventManager().registerListener(new EntityDeathByEntityListeners(this)); this.getEventManager().registerListener(new EntityDeathByEntityListeners(this));
this.getEventManager().registerListener(new RecipeListener());
} }
@Override @Override
@@ -103,6 +109,8 @@ public class EcoPlugin extends AbstractEcoPlugin {
new IntegrationLoader("Towny", () -> AntigriefManager.register(new AntigriefTowny())), new IntegrationLoader("Towny", () -> AntigriefManager.register(new AntigriefTowny())),
new IntegrationLoader("Lands", () -> AntigriefManager.register(new AntigriefLands(this))), new IntegrationLoader("Lands", () -> AntigriefManager.register(new AntigriefLands(this))),
new IntegrationLoader("Kingdoms", () -> AntigriefManager.register(new AntigriefKingdoms())), new IntegrationLoader("Kingdoms", () -> AntigriefManager.register(new AntigriefKingdoms())),
new IntegrationLoader("ULands", () -> AntigriefManager.register(new AntigriefUltimateLands())),
new IntegrationLoader("CombatLogX", () -> AntigriefManager.register(new AntigriefCombatLogX())),
// Anticheat // Anticheat
new IntegrationLoader("AAC5", () -> AnticheatManager.register(this, new AnticheatAAC())), new IntegrationLoader("AAC5", () -> AnticheatManager.register(this, new AnticheatAAC())),
@@ -140,4 +148,10 @@ public class EcoPlugin extends AbstractEcoPlugin {
public List<Class<?>> getUpdatableClasses() { public List<Class<?>> getUpdatableClasses() {
return new ArrayList<>(); return new ArrayList<>();
} }
@Override
@Nullable
protected DisplayModule createDisplayModule() {
return null;
}
} }

View File

@@ -23,7 +23,7 @@ public class AnticheatNCP implements AnticheatWrapper {
@Override @Override
public void exempt(@NotNull final Player player) { public void exempt(@NotNull final Player player) {
if (!NCPExemptionManager.isExempted(player, CheckType.ALL)) { if (NCPExemptionManager.isExempted(player, CheckType.ALL)) {
return; return;
} }

View File

@@ -0,0 +1,76 @@
package com.willfp.eco.spigot.integrations.antigrief;
import com.SirBlobman.combatlogx.api.ICombatLogX;
import com.SirBlobman.combatlogx.api.expansion.Expansion;
import com.SirBlobman.combatlogx.expansion.newbie.helper.NewbieHelper;
import com.SirBlobman.combatlogx.expansion.newbie.helper.listener.ListenerPVP;
import com.willfp.eco.spigot.EcoPlugin;
import com.willfp.eco.util.integrations.antigrief.AntigriefWrapper;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class AntigriefCombatLogX implements AntigriefWrapper {
/**
* Instance of CombatLogX.
*/
private final ICombatLogX instance = (ICombatLogX) Bukkit.getPluginManager().getPlugin("CombatLogX");
/**
* PVPManager for CombatLogX NewbieHelper.
*/
private ListenerPVP pvp = null;
/**
* Create new CombatLogX antigrief.
*/
public AntigriefCombatLogX() {
assert instance != null;
EcoPlugin.getInstance().getScheduler().runLater(() -> {
Expansion expansionUncast = instance.getExpansionManager().getExpansionByName("NewbieHelper").orElse(null);
if (expansionUncast instanceof NewbieHelper) {
pvp = ((NewbieHelper) expansionUncast).getPVPListener();
}
}, 3);
}
@Override
public boolean canBreakBlock(@NotNull final Player player,
@NotNull final Block block) {
return true;
}
@Override
public boolean canCreateExplosion(@NotNull final Player player,
@NotNull final Location location) {
return true;
}
@Override
public boolean canPlaceBlock(@NotNull final Player player,
@NotNull final Block block) {
return true;
}
@Override
public boolean canInjure(@NotNull final Player player,
@NotNull final LivingEntity victim) {
if (!(victim instanceof Player)) {
return true;
}
if (pvp == null) {
return true;
}
return (pvp.isPVPEnabled(player) && pvp.isPVPEnabled((Player) victim));
}
@Override
public String getPluginName() {
return "CombatLogX";
}
}

View File

@@ -1,7 +1,10 @@
package com.willfp.eco.spigot.integrations.antigrief; package com.willfp.eco.spigot.integrations.antigrief;
import com.palmergames.bukkit.towny.TownyAPI;
import com.palmergames.bukkit.towny.TownyUniverse;
import com.palmergames.bukkit.towny.object.Town; import com.palmergames.bukkit.towny.object.Town;
import com.palmergames.bukkit.towny.object.TownyPermission; import com.palmergames.bukkit.towny.object.TownyPermission;
import com.palmergames.bukkit.towny.object.TownyWorld;
import com.palmergames.bukkit.towny.object.WorldCoord; import com.palmergames.bukkit.towny.object.WorldCoord;
import com.palmergames.bukkit.towny.utils.PlayerCacheUtil; import com.palmergames.bukkit.towny.utils.PlayerCacheUtil;
import com.willfp.eco.util.integrations.antigrief.AntigriefWrapper; import com.willfp.eco.util.integrations.antigrief.AntigriefWrapper;
@@ -16,24 +19,57 @@ public class AntigriefTowny implements AntigriefWrapper {
@Override @Override
public boolean canBreakBlock(@NotNull final Player player, public boolean canBreakBlock(@NotNull final Player player,
@NotNull final Block block) { @NotNull final Block block) {
return PlayerCacheUtil.getCachePermission(player, block.getLocation(), block.getType(), TownyPermission.ActionType.DESTROY); TownyWorld world = TownyUniverse.getInstance().getWorldMap().get(block.getLocation().getWorld().getName());
if (world == null) {
return true;
}
if (TownyAPI.getInstance().isWilderness(block)) {
return true;
}
return PlayerCacheUtil.getCachePermission(player, block.getLocation(), block.getType(), TownyPermission.ActionType.DESTROY)
|| PlayerCacheUtil.getCachePermission(player, block.getLocation(), block.getType(), TownyPermission.ActionType.BUILD);
} }
@Override @Override
public boolean canCreateExplosion(@NotNull final Player player, public boolean canCreateExplosion(@NotNull final Player player,
@NotNull final Location location) { @NotNull final Location location) {
TownyWorld world = TownyUniverse.getInstance().getWorldMap().get(location.getWorld().getName());
if (world == null) {
return true;
}
if (TownyAPI.getInstance().isWilderness(location)) {
return true;
}
return PlayerCacheUtil.getCachePermission(player, location, Material.TNT, TownyPermission.ActionType.ITEM_USE); return PlayerCacheUtil.getCachePermission(player, location, Material.TNT, TownyPermission.ActionType.ITEM_USE);
} }
@Override @Override
public boolean canPlaceBlock(@NotNull final Player player, public boolean canPlaceBlock(@NotNull final Player player,
@NotNull final Block block) { @NotNull final Block block) {
TownyWorld world = TownyUniverse.getInstance().getWorldMap().get(block.getLocation().getWorld().getName());
if (world == null) {
return true;
}
if (TownyAPI.getInstance().isWilderness(block)) {
return true;
}
return PlayerCacheUtil.getCachePermission(player, block.getLocation(), block.getType(), TownyPermission.ActionType.BUILD); return PlayerCacheUtil.getCachePermission(player, block.getLocation(), block.getType(), TownyPermission.ActionType.BUILD);
} }
@Override @Override
public boolean canInjure(@NotNull final Player player, public boolean canInjure(@NotNull final Player player,
@NotNull final LivingEntity victim) { @NotNull final LivingEntity victim) {
TownyWorld world = TownyUniverse.getInstance().getWorldMap().get(victim.getLocation().getWorld().getName());
if (world == null) {
return true;
}
if (TownyAPI.getInstance().isWilderness(victim.getLocation())) {
if (victim instanceof Player) {
return world.isPVP();
} else {
return true;
}
}
if (victim instanceof Player) { if (victim instanceof Player) {
try { try {
Town town = WorldCoord.parseWorldCoord(victim.getLocation()).getTownBlock().getTown(); Town town = WorldCoord.parseWorldCoord(victim.getLocation()).getTownBlock().getTown();

View File

@@ -0,0 +1,40 @@
package com.willfp.eco.spigot.integrations.antigrief;
import com.willfp.eco.util.integrations.antigrief.AntigriefWrapper;
import me.ulrich.lands.api.LandsAPI;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class AntigriefUltimateLands implements AntigriefWrapper {
@Override
public boolean canBreakBlock(@NotNull final Player player,
@NotNull final Block block) {
return LandsAPI.getInstance().isOwnerOfChunk(player.getName(), block.getChunk()) || LandsAPI.getInstance().isMemberOfChunk(block.getChunk(), player);
}
@Override
public boolean canCreateExplosion(@NotNull final Player player,
@NotNull final Location location) {
return LandsAPI.getInstance().isOwnerOfChunk(player.getName(), location.getChunk()) || LandsAPI.getInstance().isMemberOfChunk(location.getChunk(), player);
}
@Override
public boolean canPlaceBlock(@NotNull final Player player,
@NotNull final Block block) {
return LandsAPI.getInstance().isOwnerOfChunk(player.getName(), block.getChunk()) || LandsAPI.getInstance().isMemberOfChunk(block.getChunk(), player);
}
@Override
public boolean canInjure(@NotNull final Player player,
@NotNull final LivingEntity victim) {
return LandsAPI.getInstance().isOwnerOfChunk(player.getName(), victim.getLocation().getChunk()) || LandsAPI.getInstance().isMemberOfChunk(victim.getLocation().getChunk(), player);
}
@Override
public String getPluginName() {
return "ULands";
}
}

View File

@@ -5,7 +5,6 @@ import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard; import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.flags.Flags; import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.flags.StateFlag;
import com.sk89q.worldguard.protection.regions.RegionContainer; import com.sk89q.worldguard.protection.regions.RegionContainer;
import com.sk89q.worldguard.protection.regions.RegionQuery; import com.sk89q.worldguard.protection.regions.RegionQuery;
import com.willfp.eco.util.integrations.antigrief.AntigriefWrapper; import com.willfp.eco.util.integrations.antigrief.AntigriefWrapper;
@@ -25,7 +24,7 @@ public class AntigriefWorldGuard implements AntigriefWrapper {
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionQuery query = container.createQuery(); RegionQuery query = container.createQuery();
if (query.queryState(BukkitAdapter.adapt(block.getLocation()), localPlayer, Flags.BUILD) == StateFlag.State.DENY) { if (!query.testBuild(BukkitAdapter.adapt(block.getLocation()), localPlayer, Flags.BLOCK_BREAK)) {
return WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, BukkitAdapter.adapt(block.getWorld())); return WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, BukkitAdapter.adapt(block.getWorld()));
} }
return true; return true;
@@ -40,7 +39,7 @@ public class AntigriefWorldGuard implements AntigriefWrapper {
World world = location.getWorld(); World world = location.getWorld();
Validate.notNull(world, "World cannot be null!"); Validate.notNull(world, "World cannot be null!");
if (query.queryState(BukkitAdapter.adapt(location), localPlayer, Flags.OTHER_EXPLOSION) == StateFlag.State.DENY) { if (!query.testBuild(BukkitAdapter.adapt(location), localPlayer, Flags.TNT)) {
return WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, BukkitAdapter.adapt(world)); return WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, BukkitAdapter.adapt(world));
} }
return true; return true;
@@ -53,7 +52,7 @@ public class AntigriefWorldGuard implements AntigriefWrapper {
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionQuery query = container.createQuery(); RegionQuery query = container.createQuery();
if (query.queryState(BukkitAdapter.adapt(block.getLocation()), localPlayer, Flags.BLOCK_PLACE) == StateFlag.State.DENY) { if (!query.testBuild(BukkitAdapter.adapt(block.getLocation()), localPlayer, Flags.BLOCK_PLACE)) {
return WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, BukkitAdapter.adapt(block.getWorld())); return WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, BukkitAdapter.adapt(block.getWorld()));
} }
return true; return true;
@@ -67,11 +66,11 @@ public class AntigriefWorldGuard implements AntigriefWrapper {
RegionQuery query = container.createQuery(); RegionQuery query = container.createQuery();
if (victim instanceof Player) { if (victim instanceof Player) {
if (query.queryState(BukkitAdapter.adapt(victim.getLocation()), localPlayer, Flags.PVP) == StateFlag.State.DENY) { if (!query.testBuild(BukkitAdapter.adapt(victim.getLocation()), localPlayer, Flags.PVP)) {
return WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, BukkitAdapter.adapt(player.getWorld())); return WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, BukkitAdapter.adapt(player.getWorld()));
} }
} else { } else {
if (query.queryState(BukkitAdapter.adapt(victim.getLocation()), localPlayer, Flags.DAMAGE_ANIMALS) == StateFlag.State.DENY) { if (!query.testBuild(BukkitAdapter.adapt(victim.getLocation()), localPlayer, Flags.DAMAGE_ANIMALS)) {
return WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, BukkitAdapter.adapt(player.getWorld())); return WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, BukkitAdapter.adapt(player.getWorld()));
} }
} }

View File

@@ -3,14 +3,33 @@ package com.willfp.eco.spigot.integrations.mcmmo;
import com.gmail.nossr50.datatypes.meta.BonusDropMeta; import com.gmail.nossr50.datatypes.meta.BonusDropMeta;
import com.gmail.nossr50.events.fake.FakeEvent; import com.gmail.nossr50.events.fake.FakeEvent;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.willfp.eco.util.ClassUtils;
import com.willfp.eco.util.integrations.mcmmo.McmmoWrapper; import com.willfp.eco.util.integrations.mcmmo.McmmoWrapper;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class McmmoIntegrationImpl implements McmmoWrapper { public class McmmoIntegrationImpl implements McmmoWrapper {
/**
* Disabled if mcmmo is outdated or missing classes.
*/
boolean disabled = false;
/**
* Initialize mcMMO integration.
*/
public McmmoIntegrationImpl() {
if (!ClassUtils.exists("com.gmail.nossr50.events.fake.FakeEvent")) {
disabled = true;
}
}
@Override @Override
public int getBonusDropCount(@NotNull final Block block) { public int getBonusDropCount(@NotNull final Block block) {
if (disabled) {
return 0;
}
if (block.getMetadata(mcMMO.BONUS_DROPS_METAKEY).size() > 0) { if (block.getMetadata(mcMMO.BONUS_DROPS_METAKEY).size() > 0) {
BonusDropMeta bonusDropMeta = (BonusDropMeta) block.getMetadata(mcMMO.BONUS_DROPS_METAKEY).get(0); BonusDropMeta bonusDropMeta = (BonusDropMeta) block.getMetadata(mcMMO.BONUS_DROPS_METAKEY).get(0);
return bonusDropMeta.asInt(); return bonusDropMeta.asInt();
@@ -21,6 +40,10 @@ public class McmmoIntegrationImpl implements McmmoWrapper {
@Override @Override
public boolean isFake(@NotNull final Event event) { public boolean isFake(@NotNull final Event event) {
if (disabled) {
return false;
}
return event instanceof FakeEvent; return event instanceof FakeEvent;
} }
} }

View File

@@ -0,0 +1,220 @@
package com.willfp.eco.spigot.recipes;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import com.willfp.eco.util.recipe.RecipeParts;
import com.willfp.eco.util.recipe.Recipes;
import com.willfp.eco.util.recipe.parts.RecipePart;
import com.willfp.eco.util.recipe.parts.SimpleRecipePart;
import com.willfp.eco.util.recipe.recipes.EcoShapedRecipe;
import org.bukkit.Material;
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.CraftItemEvent;
import org.bukkit.event.inventory.PrepareItemCraftEvent;
import org.bukkit.event.player.PlayerRecipeDiscoverEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.ShapedRecipe;
import org.jetbrains.annotations.NotNull;
public class RecipeListener implements Listener {
/**
* Called on item craft.
*
* @param event The event to listen for.
*/
@EventHandler
public void complexRecipeListener(@NotNull final PrepareItemCraftEvent event) {
if (!(event.getRecipe() instanceof ShapedRecipe)) {
return;
}
ShapedRecipe recipe = (ShapedRecipe) event.getRecipe();
if (!AbstractEcoPlugin.LOADED_ECO_PLUGINS.contains(recipe.getKey().getNamespace())) {
return;
}
ItemStack[] matrix = event.getInventory().getMatrix();
EcoShapedRecipe matched = Recipes.getMatch(matrix);
if (matched == null) {
event.getInventory().setResult(new ItemStack(Material.AIR));
return;
}
if (matched.test(matrix)) {
event.getInventory().setResult(matched.getOutput());
} else {
event.getInventory().setResult(new ItemStack(Material.AIR));
}
}
/**
* Called on item craft.
*
* @param event The event to listen for.
*/
@EventHandler
public void complexRecipeListener(@NotNull final CraftItemEvent event) {
if (!(event.getRecipe() instanceof ShapedRecipe)) {
return;
}
ShapedRecipe recipe = (ShapedRecipe) event.getRecipe();
if (!AbstractEcoPlugin.LOADED_ECO_PLUGINS.contains(recipe.getKey().getNamespace())) {
return;
}
ItemStack[] matrix = event.getInventory().getMatrix();
EcoShapedRecipe matched = Recipes.getMatch(matrix);
if (matched == null) {
event.getInventory().setResult(new ItemStack(Material.AIR));
event.setResult(Event.Result.DENY);
event.setCancelled(true);
return;
}
if (matched.test(matrix)) {
event.getInventory().setResult(matched.getOutput());
} else {
event.getInventory().setResult(new ItemStack(Material.AIR));
event.setResult(Event.Result.DENY);
event.setCancelled(true);
}
}
/**
* Called on item craft.
*
* @param event The event to listen for.
*/
@EventHandler
public void preventUsingComplexPartInEcoRecipe(@NotNull final PrepareItemCraftEvent event) {
if (!(event.getRecipe() instanceof ShapedRecipe)) {
return;
}
ShapedRecipe recipe = (ShapedRecipe) event.getRecipe();
EcoShapedRecipe ecoShapedRecipe = Recipes.getShapedRecipe(recipe.getKey());
if (ecoShapedRecipe == null) {
return;
}
for (int i = 0; i < 9; i++) {
ItemStack itemStack = event.getInventory().getMatrix()[i];
RecipePart part = ecoShapedRecipe.getParts()[i];
if (part instanceof SimpleRecipePart) {
if (RecipeParts.isRecipePart(itemStack)) {
event.getInventory().setResult(new ItemStack(Material.AIR));
return;
}
}
}
}
/**
* Called on item craft.
*
* @param event The event to listen for.
*/
@EventHandler
public void preventUsingComplexPartInEcoRecipe(@NotNull final CraftItemEvent event) {
if (!(event.getRecipe() instanceof ShapedRecipe)) {
return;
}
ShapedRecipe recipe = (ShapedRecipe) event.getRecipe();
EcoShapedRecipe ecoShapedRecipe = Recipes.getShapedRecipe(recipe.getKey());
if (ecoShapedRecipe == null) {
return;
}
for (int i = 0; i < 9; i++) {
ItemStack itemStack = event.getInventory().getMatrix()[i];
RecipePart part = ecoShapedRecipe.getParts()[i];
if (part instanceof SimpleRecipePart) {
if (RecipeParts.isRecipePart(itemStack)) {
event.getInventory().setResult(new ItemStack(Material.AIR));
event.setResult(Event.Result.DENY);
event.setCancelled(true);
return;
}
}
}
}
/**
* Prevents using talismans in recipes.
*
* @param event The event to listen for.
*/
@EventHandler
public void preventUsingComplexPartInVanillaRecipe(@NotNull final PrepareItemCraftEvent event) {
if (!(event.getRecipe() instanceof ShapedRecipe)) {
return;
}
ShapedRecipe recipe = (ShapedRecipe) event.getRecipe();
if (AbstractEcoPlugin.LOADED_ECO_PLUGINS.contains(recipe.getKey().getNamespace())) {
return;
}
for (ItemStack itemStack : event.getInventory().getMatrix()) {
if (RecipeParts.isRecipePart(itemStack)) {
event.getInventory().setResult(new ItemStack(Material.AIR));
return;
}
}
}
/**
* Prevents using talismans in recipes.
*
* @param event The event to listen for.
*/
@EventHandler
public void preventUsingComplexPartInVanillaRecipe(@NotNull final CraftItemEvent event) {
if (!(event.getRecipe() instanceof ShapedRecipe)) {
return;
}
ShapedRecipe recipe = (ShapedRecipe) event.getRecipe();
if (AbstractEcoPlugin.LOADED_ECO_PLUGINS.contains(recipe.getKey().getNamespace())) {
return;
}
for (ItemStack itemStack : event.getInventory().getMatrix()) {
if (RecipeParts.isRecipePart(itemStack)) {
event.getInventory().setResult(new ItemStack(Material.AIR));
event.setResult(Event.Result.DENY);
event.setCancelled(true);
return;
}
}
}
/**
* Prevents learning displayed recipes.
*
* @param event The event to listen for.
*/
@EventHandler
public void preventLearningDisplayedRecipes(@NotNull final PlayerRecipeDiscoverEvent event) {
if (!AbstractEcoPlugin.LOADED_ECO_PLUGINS.contains(event.getRecipe().getNamespace())) {
return;
}
if (event.getRecipe().getKey().contains("_displayed")) {
event.setCancelled(true);
}
}
}

View File

@@ -9,7 +9,7 @@ loadbefore:
- Talismans - Talismans
- StatTrackers - StatTrackers
- EcoArmor - EcoArmor
- Illusioner - EcoBosses
depend: depend:
- ProtocolLib - ProtocolLib
softdepend: softdepend:
@@ -25,3 +25,5 @@ softdepend:
- Spartan - Spartan
- PlaceholderAPI - PlaceholderAPI
- mcMMO - mcMMO
- ULands
- CombatLogX

View File

@@ -1,4 +1,4 @@
package com.willfp.eco.util.arrows; package com.willfp.eco.internal.arrows;
import com.willfp.eco.util.internal.PluginDependent; import com.willfp.eco.util.internal.PluginDependent;
import com.willfp.eco.util.plugin.AbstractEcoPlugin; import com.willfp.eco.util.plugin.AbstractEcoPlugin;

View File

@@ -0,0 +1,148 @@
package com.willfp.eco.internal.config;
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.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
public abstract class AbstractConfig extends AbstractUndefinedConfig<YamlConfiguration> {
/**
* The physical config file, as stored on disk.
*/
@Getter(AccessLevel.PROTECTED)
private final File configFile;
/**
* Plugin handle.
*/
@Getter(AccessLevel.PROTECTED)
private final AbstractEcoPlugin plugin;
/**
* The full name of the config file (eg config.yml).
*/
@Getter
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;
/**
* 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(configName);
this.plugin = plugin;
this.name = configName + ".yml";
this.source = source;
this.subDirectoryPath = subDirectoryPath;
File directory = new File(this.getPlugin().getDataFolder(), subDirectoryPath);
if (!directory.exists()) {
directory.mkdirs();
}
if (!new File(directory, this.name).exists()) {
createFile();
}
this.configFile = new File(directory, this.name);
init(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(name + " 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;
}
}

View File

@@ -0,0 +1,323 @@
package com.willfp.eco.internal.config;
import com.willfp.eco.util.SerializationUtils;
import com.willfp.eco.util.StringUtils;
import com.willfp.eco.util.config.Config;
import com.willfp.eco.util.serialization.EcoSerializable;
import lombok.AccessLevel;
import lombok.Getter;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.MemorySection;
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;
import java.util.Objects;
@SuppressWarnings({"unchecked", "unused", "DeprecatedIsStillUsed"})
public abstract class AbstractUndefinedConfig<T extends ConfigurationSection> implements Config {
/**
* The linked {@link MemorySection} where values are physically stored.
*/
@Getter(AccessLevel.PUBLIC)
protected T config = null;
/**
* Cached values for faster reading.
*/
private final Map<String, Object> cache = new HashMap<>();
/**
* Abstract config.
*
* @param configName The name of the config
*/
protected AbstractUndefinedConfig(@NotNull final String configName) {
}
protected Config init(@NotNull final T config) {
this.config = config;
return this;
}
@Override
public final void clearCache() {
cache.clear();
}
@Override
public boolean has(@NotNull final String path) {
return config.contains(path);
}
@NotNull
@Override
public List<String> getKeys(final boolean deep) {
return new ArrayList<>(config.getKeys(deep));
}
@Override
public void set(@NotNull final String path,
@NotNull final EcoSerializable<?> object) {
Config serializedConfig = object.serialize();
for (String key : serializedConfig.getKeys(true)) {
Object raw = serializedConfig.getRaw(key);
config.set(path + "." + key, raw);
cache.put(path + "." + key, raw);
}
}
@Override
@Nullable
public Object getRaw(@NotNull final String path) {
return config.get(path);
}
@Override
@NotNull
public <T extends EcoSerializable<T>> T get(@NotNull final String path,
@NotNull final Class<T> clazz) {
T object = getOrNull(path, clazz);
if (object == null) {
throw new NullPointerException("Object cannot be null!");
} else {
return object;
}
}
@Override
@Nullable
public <T extends EcoSerializable<T>> T getOrNull(@NotNull final String path,
@NotNull final Class<T> clazz) {
if (cache.containsKey(path)) {
return (T) cache.get(path);
} else {
Config section = getSubsectionOrNull(path);
if (section == null) {
return null;
}
cache.put(path, SerializationUtils.deserialize(section, clazz));
return getOrNull(path, clazz);
}
}
@Override
@NotNull
@Deprecated
public ConfigurationSection getSection(@NotNull final String path) {
ConfigurationSection section = getSectionOrNull(path);
if (section == null) {
throw new NullPointerException("Section cannot be null!");
} else {
return section;
}
}
@Override
@Nullable
@Deprecated
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);
}
}
@Override
@NotNull
public Config getSubsection(@NotNull final String path) {
return new ConfigSection(this.getSection(path));
}
@Override
@Nullable
public Config getSubsectionOrNull(@NotNull final String path) {
ConfigurationSection section = this.getSectionOrNull(path);
if (section == null) {
return null;
}
return new ConfigSection(section);
}
@Override
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);
}
}
@Override
@Nullable
public Integer getIntOrNull(@NotNull final String path) {
if (has(path)) {
return getInt(path);
} else {
return null;
}
}
@Override
public int getInt(@NotNull final String path,
final int def) {
if (cache.containsKey(path)) {
return (int) cache.get(path);
} else {
cache.put(path, config.getInt(path, def));
return getInt(path);
}
}
@Override
@NotNull
public List<Integer> getInts(@NotNull final String path) {
if (cache.containsKey(path)) {
return (List<Integer>) cache.get(path);
} else {
cache.put(path, has(path) ? new ArrayList<>(config.getIntegerList(path)) : new ArrayList<>());
return getInts(path);
}
}
@Override
@Nullable
public List<Integer> getIntsOrNull(@NotNull final String path) {
if (has(path)) {
return getInts(path);
} else {
return null;
}
}
@Override
public boolean getBool(@NotNull final String path) {
if (cache.containsKey(path)) {
return (boolean) cache.get(path);
} else {
cache.put(path, config.getBoolean(path));
return getBool(path);
}
}
@Override
@Nullable
public Boolean getBoolOrNull(@NotNull final String path) {
if (has(path)) {
return getBool(path);
} else {
return null;
}
}
@Override
@NotNull
public List<Boolean> getBools(@NotNull final String path) {
if (cache.containsKey(path)) {
return (List<Boolean>) cache.get(path);
} else {
cache.put(path, has(path) ? new ArrayList<>(config.getBooleanList(path)) : new ArrayList<>());
return getBools(path);
}
}
@Override
@Nullable
public List<Boolean> getBoolsOrNull(@NotNull final String path) {
if (has(path)) {
return getBools(path);
} else {
return null;
}
}
@Override
@NotNull
public String getString(@NotNull final String path) {
if (cache.containsKey(path)) {
return (String) cache.get(path);
} else {
cache.put(path, StringUtils.translate(Objects.requireNonNull(config.getString(path, ""))));
return getString(path);
}
}
@Override
@Nullable
public String getStringOrNull(@NotNull final String path) {
if (has(path)) {
return getString(path);
} else {
return null;
}
}
@Override
@NotNull
public List<String> getStrings(@NotNull final String path) {
if (cache.containsKey(path)) {
return (List<String>) cache.get(path);
} else {
cache.put(path, has(path) ? new ArrayList<>(config.getStringList(path)) : new ArrayList<>());
return getStrings(path);
}
}
@Override
@Nullable
public List<String> getStringsOrNull(@NotNull final String path) {
if (has(path)) {
return getStrings(path);
} else {
return null;
}
}
@Override
public 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);
}
}
@Override
@Nullable
public Double getDoubleOrNull(@NotNull final String path) {
if (has(path)) {
return getDouble(path);
} else {
return null;
}
}
@Override
@NotNull
public List<Double> getDoubles(@NotNull final String path) {
if (cache.containsKey(path)) {
return (List<Double>) cache.get(path);
} else {
cache.put(path, has(path) ? new ArrayList<>(config.getDoubleList(path)) : new ArrayList<>());
return getDoubles(path);
}
}
@Override
@Nullable
public List<Double> getDoublesOrNull(@NotNull final String path) {
if (has(path)) {
return getDoubles(path);
} else {
return null;
}
}
}

View File

@@ -1,4 +1,4 @@
package com.willfp.eco.util.config.internal; package com.willfp.eco.internal.config;
import com.willfp.eco.util.plugin.AbstractEcoPlugin; import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.InvalidConfigurationException;

View File

@@ -0,0 +1,16 @@
package com.willfp.eco.internal.config;
import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.NotNull;
public class ConfigSection extends AbstractUndefinedConfig<ConfigurationSection> {
/**
* Config section.
*
* @param section The section.
*/
protected ConfigSection(@NotNull final ConfigurationSection section) {
super("subsection");
this.init(section);
}
}

View File

@@ -6,6 +6,7 @@ import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashSet; import java.util.HashSet;
@@ -76,6 +77,7 @@ public class BlockUtils {
* *
* @param function The function. * @param function The function.
*/ */
@ApiStatus.Internal
public void initialize(@NotNull final BiConsumer<Player, Block> function) { public void initialize(@NotNull final BiConsumer<Player, Block> function) {
Validate.isTrue(!initialized, "Already initialized!"); Validate.isTrue(!initialized, "Already initialized!");

View File

@@ -4,6 +4,7 @@ import com.willfp.eco.util.optional.Prerequisite;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.function.Function; import java.util.function.Function;
@@ -42,6 +43,7 @@ public class PlayerUtils {
* *
* @param function The function. * @param function The function.
*/ */
@ApiStatus.Internal
public void initialize(@NotNull final Function<Player, Double> function) { public void initialize(@NotNull final Function<Player, Double> function) {
Validate.isTrue(!initialized, "Already initialized!"); Validate.isTrue(!initialized, "Already initialized!");

View File

@@ -0,0 +1,49 @@
package com.willfp.eco.util;
import com.willfp.eco.util.config.Config;
import com.willfp.eco.util.serialization.Deserializer;
import com.willfp.eco.util.serialization.EcoSerializable;
import com.willfp.eco.util.serialization.NoRegisteredDeserializerException;
import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
@UtilityClass
public class SerializationUtils {
/**
* All registered deserializers.
*/
private static final Map<String, Deserializer<?>> REGISTRY = new HashMap<>();
/**
* Register deserializer.
*
* @param clazz The serializable class.
* @param deserializer The deserializer.
* @param <T> The object type.
*/
public <T extends EcoSerializable<T>> void registerDeserializer(@NotNull final Class<T> clazz,
@NotNull final Deserializer<T> deserializer) {
REGISTRY.put(clazz.getName(), deserializer);
}
/**
* Deserialize object.
*
* @param config The config.
* @param clazz The class.
* @param <T> The object type.
*/
@SneakyThrows
public <T extends EcoSerializable<T>> T deserialize(@NotNull final Config config,
@NotNull final Class<T> clazz) {
if (!REGISTRY.containsKey(clazz.getName())) {
throw new NoRegisteredDeserializerException("No deserializer registered for " + clazz.getName());
}
return clazz.cast(REGISTRY.get(clazz.getName()).deserialize(config));
}
}

View File

@@ -3,6 +3,7 @@ package com.willfp.eco.util;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.inventory.meta.SkullMeta;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
@@ -38,6 +39,7 @@ public class SkullUtils {
* *
* @param function The function. * @param function The function.
*/ */
@ApiStatus.Internal
public void initialize(@NotNull final BiConsumer<SkullMeta, String> function) { public void initialize(@NotNull final BiConsumer<SkullMeta, String> function) {
Validate.isTrue(!initialized, "Already initialized!"); Validate.isTrue(!initialized, "Already initialized!");

View File

@@ -30,6 +30,11 @@ public class StringUtils {
*/ */
private static final Pattern HEX_PATTERN = Pattern.compile("&#" + "([A-Fa-f0-9]{6})" + ""); private static final Pattern HEX_PATTERN = Pattern.compile("&#" + "([A-Fa-f0-9]{6})" + "");
/**
* Regex for hex codes.
*/
private static final Pattern ALT_HEX_PATTERN = Pattern.compile("\\{#" + "([A-Fa-f0-9]{6})" + "}");
/** /**
* Translate a string - converts Placeholders and Color codes. * Translate a string - converts Placeholders and Color codes.
* *
@@ -61,7 +66,22 @@ public class StringUtils {
} }
private static String translateHexColorCodes(@NotNull final String message) { private static String translateHexColorCodes(@NotNull final String message) {
Matcher matcher = HEX_PATTERN.matcher(message); String processedMessage = message;
for (HexParseMode parseMode : HexParseMode.values()) {
processedMessage = translateHexColorCodes(processedMessage, parseMode);
}
return processedMessage;
}
private static String translateHexColorCodes(@NotNull final String message,
@NotNull final HexParseMode mode) {
Matcher matcher;
if (mode == HexParseMode.CMI) {
matcher = ALT_HEX_PATTERN.matcher(message);
} else {
matcher = HEX_PATTERN.matcher(message);
}
StringBuffer buffer = new StringBuffer(message.length() + 4 * 8); StringBuffer buffer = new StringBuffer(message.length() + 4 * 8);
while (matcher.find()) { while (matcher.find()) {
String group = matcher.group(1); String group = matcher.group(1);
@@ -201,4 +221,9 @@ public class StringUtils {
} }
return string; return string;
} }
private enum HexParseMode {
CMI,
NORMAL
}
} }

View File

@@ -4,6 +4,7 @@ import lombok.experimental.UtilityClass;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.entity.Trident; import org.bukkit.entity.Trident;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.function.Function; import java.util.function.Function;
@@ -38,6 +39,7 @@ public class TridentUtils {
* *
* @param function The function. * @param function The function.
*/ */
@ApiStatus.Internal
public void initialize(@NotNull final Function<Trident, ItemStack> function) { public void initialize(@NotNull final Function<Trident, ItemStack> function) {
Validate.isTrue(!initialized, "Already initialized!"); Validate.isTrue(!initialized, "Already initialized!");

View File

@@ -0,0 +1,11 @@
package com.willfp.eco.util.bukkit.scheduling;
public interface TimedRunnable extends Runnable {
/**
* The TimedRunnable interface is generally used for repeating tasks.
* This method is to retrieve the ticks between repetitions.
*
* @return The ticks between repetitions.
*/
long getTime();
}

View File

@@ -1,7 +1,6 @@
package com.willfp.eco.util.command; package com.willfp.eco.util.command;
import com.willfp.eco.util.internal.PluginDependent; import com.willfp.eco.util.internal.PluginDependent;
import com.willfp.eco.util.interfaces.Registerable;
import com.willfp.eco.util.plugin.AbstractEcoPlugin; import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.Command; import org.bukkit.command.Command;
@@ -15,7 +14,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
public abstract class AbstractCommand extends PluginDependent implements CommandExecutor, Registerable { public abstract class AbstractCommand extends PluginDependent implements CommandExecutor {
/** /**
* The name of the command * The name of the command
* <p> * <p>
@@ -130,7 +129,6 @@ public abstract class AbstractCommand extends PluginDependent implements Command
* <p> * <p>
* Requires the command name to exist, defined in plugin.yml. * Requires the command name to exist, defined in plugin.yml.
*/ */
@Override
public final void register() { public final void register() {
PluginCommand command = Bukkit.getPluginCommand(name); PluginCommand command = Bukkit.getPluginCommand(name);
assert command != null; assert command != null;

View File

@@ -1,6 +1,6 @@
package com.willfp.eco.util.config; package com.willfp.eco.util.config;
import com.willfp.eco.util.config.internal.AbstractUpdatableConfig; import com.willfp.eco.internal.config.AbstractUpdatableConfig;
import com.willfp.eco.util.plugin.AbstractEcoPlugin; import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;

View File

@@ -0,0 +1,262 @@
package com.willfp.eco.util.config;
import com.willfp.eco.util.serialization.EcoSerializable;
import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public interface Config {
/**
* Clears cache.
*/
void clearCache();
/**
* Get if the config contains a key.
*
* @param path The key to check.
* @return If contained.
*/
boolean has(@NotNull String path);
/**
* Get config keys.
*
* @param deep If keys from subsections should be fetched too.
* @return A list of keys.
*/
@NotNull
List<String> getKeys(boolean deep);
/**
* Set an object in config.
*
* @param path The path.
* @param object The object.
*/
void set(@NotNull String path,
@NotNull EcoSerializable<?> object);
/**
* Get an object from config.
* Default implementations call {@link org.bukkit.configuration.file.YamlConfiguration#get(String)}.
*
* @param path The path.
* @return The object.
*/
@Nullable
Object getRaw(@NotNull String path);
/**
* Get an object from config.
*
* @param path The path.
* @param clazz The class of the object.
* @param <T> The type of the object.
* @return The object.
*/
@NotNull <T extends EcoSerializable<T>> T get(@NotNull String path,
@NotNull Class<T> clazz);
/**
* Get an object from config.
*
* @param path The path.
* @param clazz The class of the object.
* @param <T> The type of the object.
* @return The object, or null if not found.
*/
@Nullable <T extends EcoSerializable<T>> T getOrNull(@NotNull String path,
@NotNull Class<T> clazz);
/**
* Get bukkit configuration section from config.
*
* @param path The key to check.
* @return The configuration section. Throws NPE if not found.
*/
@NotNull
@Deprecated
ConfigurationSection getSection(@NotNull String path);
/**
* Get bukkit configuration section from config.
*
* @param path The key to check.
* @return The configuration section, or null if not found.
*/
@Nullable
@Deprecated
ConfigurationSection getSectionOrNull(@NotNull String path);
/**
* Get subsection from config.
*
* @param path The key to check.
* @return The subsection. Throws NPE if not found.
*/
@NotNull
Config getSubsection(@NotNull String path);
/**
* Get subsection from config.
*
* @param path The key to check.
* @return The subsection, or null if not found.
*/
@Nullable
Config getSubsectionOrNull(@NotNull String path);
/**
* 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.
*
* @param path The key to fetch the value from.
* @return The found value, or null if not found.
*/
@Nullable
Integer getIntOrNull(@NotNull String path);
/**
* Get an integer from config with a specified default (not found) value.
*
* @param path The key to fetch the value from.
* @param def The value to default to if not found.
* @return The found value, or the default.
*/
int getInt(@NotNull String path,
int def);
/**
* Get a list of integers from config.
*
* @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 list of integers from config.
*
* @param path The key to fetch the value from.
* @return The found value, or null if not found.
*/
@Nullable
List<Integer> getIntsOrNull(@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 boolean from config.
*
* @param path The key to fetch the value from.
* @return The found value, or null if not found.
*/
@Nullable
Boolean getBoolOrNull(@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 list of booleans from config.
*
* @param path The key to fetch the value from.
* @return The found value, or null if not found.
*/
@Nullable
List<Boolean> getBoolsOrNull(@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 string from config.
*
* @param path The key to fetch the value from.
* @return The found value, or null if not found.
*/
@Nullable
String getStringOrNull(@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 list of strings from config.
*
* @param path The key to fetch the value from.
* @return The found value, or null if not found.
*/
@Nullable
List<String> getStringsOrNull(@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 decimal from config.
*
* @param path The key to fetch the value from.
* @return The found value, or null if not found.
*/
@Nullable
Double getDoubleOrNull(@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);
/**
* 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
List<Double> getDoublesOrNull(@NotNull String path);
}

View File

@@ -1,6 +1,6 @@
package com.willfp.eco.util.config; package com.willfp.eco.util.config;
import com.willfp.eco.util.config.internal.AbstractUpdatableConfig; import com.willfp.eco.internal.config.AbstractUpdatableConfig;
import com.willfp.eco.util.plugin.AbstractEcoPlugin; import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;

View File

@@ -1,6 +1,6 @@
package com.willfp.eco.util.config; package com.willfp.eco.util.config;
import com.willfp.eco.util.config.internal.AbstractConfig; import com.willfp.eco.internal.config.AbstractConfig;
import com.willfp.eco.util.plugin.AbstractEcoPlugin; import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;

View File

@@ -0,0 +1,40 @@
package com.willfp.eco.util.config;
import com.willfp.eco.internal.config.AbstractUndefinedConfig;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
public abstract class StaticOptionalConfig extends AbstractUndefinedConfig<YamlConfiguration> {
/**
* Config implementation for passing YamlConfigurations.
* <p>
* Does not automatically update.
*
* @param configName The name of the config
* @param plugin The plugin.
* @param config The YamlConfiguration handle.
* @deprecated Plugin not required.
*/
@Deprecated
public StaticOptionalConfig(@NotNull final String configName,
@NotNull final AbstractEcoPlugin plugin,
@NotNull final YamlConfiguration config) {
this(configName, config);
}
/**
* Config implementation for passing YamlConfigurations.
* <p>
* Does not automatically update.
*
* @param configName The name of the config
* @param config The YamlConfiguration handle.
*/
public StaticOptionalConfig(@NotNull final String configName,
@NotNull final YamlConfiguration config) {
super(configName);
init(config);
}
}

View File

@@ -1,5 +0,0 @@
package com.willfp.eco.util.config;
@Deprecated
public interface ValueGetter {
}

View File

@@ -1,472 +0,0 @@
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

@@ -14,25 +14,24 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
import java.util.function.Predicate;
@UtilityClass @UtilityClass
@SuppressWarnings("deprecation")
public class Display { public class Display {
/** /**
* Registered display functions. * The prefix for lore lines.
*/ */
private static final List<Map<String, Function<ItemStack, ItemStack>>> DISPLAY_FUNCTIONS = new ArrayList<>(10000); public static final String PREFIX = "§z";
/** /**
* Registered revert functions. * All registered display modules.
*/ */
private static final List<Function<ItemStack, ItemStack>> REVERT_FUNCTIONS = new ArrayList<>(); private static final Map<DisplayPriority, List<DisplayModule>> MODULES = new HashMap<>();
/** /**
* NamespacedKey for finalizing. * NamespacedKey for finalizing.
*/ */
private static NamespacedKey finalizeKey; private static NamespacedKey finalizeKey = null;
/** /**
* Register display module. * Register display module.
@@ -40,30 +39,13 @@ public class Display {
* @param module The module. * @param module The module.
*/ */
public void registerDisplayModule(@NotNull final DisplayModule module) { public void registerDisplayModule(@NotNull final DisplayModule module) {
int priority = module.getPriority(); List<DisplayModule> modules = MODULES.get(module.getPriority());
if (priority > 9999) {
priority = 9999;
}
Function<ItemStack, ItemStack> function = module.getFunction();
Map<String, Function<ItemStack, ItemStack>> functions = DISPLAY_FUNCTIONS.get(priority); modules.removeIf(module1 -> module1.getPluginName().equalsIgnoreCase(module.getPluginName()));
if (functions == null) {
functions = new HashMap<>();
}
functions.remove(module.getId()); modules.add(module);
functions.put(module.getId(), function);
DISPLAY_FUNCTIONS.set(priority, functions); MODULES.put(module.getPriority(), modules);
}
/**
* Register revert function.
*
* @param function The function.
*/
public void registerRevertModule(@NotNull final Function<ItemStack, ItemStack> function) {
REVERT_FUNCTIONS.add(function);
} }
/** /**
@@ -73,20 +55,33 @@ public class Display {
* @return The itemstack. * @return The itemstack.
*/ */
public ItemStack display(@NotNull final ItemStack itemStack) { public ItemStack display(@NotNull final ItemStack itemStack) {
if (isFinalized(itemStack)) { if (!itemStack.hasItemMeta()) {
unfinalize(itemStack); return itemStack; // return early if there's no customization of the item
return itemStack; }
Map<String, Object[]> pluginVarArgs = new HashMap<>();
for (DisplayPriority priority : DisplayPriority.values()) {
List<DisplayModule> modules = MODULES.get(priority);
for (DisplayModule module : modules) {
pluginVarArgs.put(module.getPluginName(), module.generateVarArgs(itemStack));
}
} }
revert(itemStack); revert(itemStack);
for (Map<String, Function<ItemStack, ItemStack>> displayFunctions : DISPLAY_FUNCTIONS) { ItemMeta meta = itemStack.getItemMeta();
if (displayFunctions == null) {
continue;
}
for (Function<ItemStack, ItemStack> displayFunction : displayFunctions.values()) { if (meta == null) {
displayFunction.apply(itemStack); return itemStack;
}
for (DisplayPriority priority : DisplayPriority.values()) {
List<DisplayModule> modules = MODULES.get(priority);
for (DisplayModule module : modules) {
Object[] varargs = pluginVarArgs.get(module.getPluginName());
module.display(itemStack);
module.display(itemStack, varargs);
} }
} }
@@ -110,13 +105,32 @@ public class Display {
* @return The itemstack. * @return The itemstack.
*/ */
public ItemStack revert(@NotNull final ItemStack itemStack) { public ItemStack revert(@NotNull final ItemStack itemStack) {
if (isFinalized(itemStack)) { if (Display.isFinalized(itemStack)) {
unfinalize(itemStack); unfinalize(itemStack);
}
if (!itemStack.hasItemMeta()) {
return itemStack; return itemStack;
} }
for (Function<ItemStack, ItemStack> displayFunction : REVERT_FUNCTIONS) { ItemMeta meta = itemStack.getItemMeta();
displayFunction.apply(itemStack);
if (meta == null) {
return itemStack;
}
List<String> lore = meta.getLore();
if (lore != null && lore.removeIf(line -> line.startsWith(Display.PREFIX))) { // only apply lore modification if needed
meta.setLore(lore);
itemStack.setItemMeta(meta);
}
for (DisplayPriority priority : DisplayPriority.values()) {
List<DisplayModule> modules = MODULES.get(priority);
for (DisplayModule module : modules) {
module.revert(itemStack);
}
} }
return itemStack; return itemStack;
@@ -130,13 +144,16 @@ public class Display {
*/ */
public ItemStack finalize(@NotNull final ItemStack itemStack) { public ItemStack finalize(@NotNull final ItemStack itemStack) {
Validate.notNull(finalizeKey, "Key cannot be null!"); Validate.notNull(finalizeKey, "Key cannot be null!");
if (itemStack.getType().getMaxStackSize() > 1) { if (itemStack.getType().getMaxStackSize() > 1) {
return itemStack; return itemStack;
} }
ItemMeta meta = itemStack.getItemMeta(); ItemMeta meta = itemStack.getItemMeta();
if (meta == null) { if (meta == null) {
return itemStack; return itemStack;
} }
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
container.set(finalizeKey, PersistentDataType.INTEGER, 1); container.set(finalizeKey, PersistentDataType.INTEGER, 1);
itemStack.setItemMeta(meta); itemStack.setItemMeta(meta);
@@ -151,10 +168,13 @@ public class Display {
*/ */
public ItemStack unfinalize(@NotNull final ItemStack itemStack) { public ItemStack unfinalize(@NotNull final ItemStack itemStack) {
Validate.notNull(finalizeKey, "Key cannot be null!"); Validate.notNull(finalizeKey, "Key cannot be null!");
ItemMeta meta = itemStack.getItemMeta(); ItemMeta meta = itemStack.getItemMeta();
if (meta == null) { if (meta == null) {
return itemStack; return itemStack;
} }
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
container.remove(finalizeKey); container.remove(finalizeKey);
itemStack.setItemMeta(meta); itemStack.setItemMeta(meta);
@@ -169,37 +189,17 @@ public class Display {
*/ */
public boolean isFinalized(@NotNull final ItemStack itemStack) { public boolean isFinalized(@NotNull final ItemStack itemStack) {
Validate.notNull(finalizeKey, "Key cannot be null!"); Validate.notNull(finalizeKey, "Key cannot be null!");
ItemMeta meta = itemStack.getItemMeta(); ItemMeta meta = itemStack.getItemMeta();
if (meta == null) { if (meta == null) {
return false; return false;
} }
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
return container.has(finalizeKey, PersistentDataType.INTEGER); return container.has(finalizeKey, PersistentDataType.INTEGER);
} }
/**
* 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. * Set key to be used for finalization.
* *
@@ -211,8 +211,8 @@ public class Display {
} }
static { static {
for (int i = 0; i < 10000; i++) { for (DisplayPriority priority : DisplayPriority.values()) {
DISPLAY_FUNCTIONS.add(null); MODULES.put(priority, new ArrayList<>());
} }
} }
} }

View File

@@ -1,42 +1,79 @@
package com.willfp.eco.util.display; package com.willfp.eco.util.display;
import com.willfp.eco.util.internal.PluginDependent;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import lombok.Getter; import lombok.Getter;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.function.Function; public abstract class DisplayModule extends PluginDependent {
public class DisplayModule {
/** /**
* Priority of the display module, where lower numbers are executed sooner. * The priority of the module.
*/ */
@Getter @Getter
private final int priority; private final DisplayPriority priority;
/** /**
* The function executed on display. * Create a new display module.
*/
@Getter
private final Function<ItemStack, ItemStack> function;
/**
* Function id for unregistration.
*/
@Getter
private final String id;
/**
* Create new display module.
* *
* @param function The function. * @param plugin The plugin that the display is for.
* @param priority The priority. * @param priority The priority of the module.
* @param id The id.
*/ */
public DisplayModule(@NotNull final Function<ItemStack, ItemStack> function, protected DisplayModule(@NotNull final AbstractEcoPlugin plugin,
final int priority, @NotNull final DisplayPriority priority) {
@NotNull final String id) { super(plugin);
this.function = function;
this.priority = priority; this.priority = priority;
this.id = id; }
/**
* Display an item.
*
* @param itemStack The item.
* @param args Optional args for display.
*/
protected void display(@NotNull final ItemStack itemStack,
@NotNull final Object... args) {
// Technically optional.
}
/**
* Display an item.
* <p>
* This method exists for parity with older plugins that don't include the varargs.
*
* @param itemStack The item.
* @deprecated Use {@link this#display(ItemStack, Object...)} instead.
*/
@Deprecated
protected void display(@NotNull final ItemStack itemStack) {
// Technically optional.
}
/**
* Revert an item.
*
* @param itemStack The item.
*/
protected void revert(@NotNull final ItemStack itemStack) {
// Technically optoinal.
}
/**
* Create varargs to pass back to itemstack after reverting, but before display.
*
* @param itemStack The itemStack.
* @return The plugin-specific varargs.
*/
protected Object[] generateVarArgs(@NotNull final ItemStack itemStack) {
return new Object[0];
}
/**
* Get name of plugin.
*
* @return The plugin name.
*/
final String getPluginName() {
return super.getPlugin().getPluginName();
} }
} }

View File

@@ -0,0 +1,23 @@
package com.willfp.eco.util.display;
public enum DisplayPriority {
/**
* Ran first.
*/
LOWEST,
/**
* Ran second.
*/
LOW,
/**
* Ran third.
*/
HIGH,
/**
* Ran last.
*/
HIGHEST
}

View File

@@ -1,11 +0,0 @@
package com.willfp.eco.util.interfaces;
public interface EcoRunnable extends Runnable {
/**
* The EcoRunnable interface is generally used for repeating tasks.
* This method is to retrieve the ticks between repetitions.
*
* @return The ticks between repetitions.
*/
long getTime();
}

View File

@@ -1,8 +0,0 @@
package com.willfp.eco.util.interfaces;
public interface Registerable {
/**
* Register an object with its respective registry.
*/
void register();
}

View File

@@ -1,10 +1,10 @@
package com.willfp.eco.util.plugin; package com.willfp.eco.util.plugin;
import com.willfp.eco.internal.arrows.ArrowDataListener;
import com.willfp.eco.internal.bukkit.events.EcoEventManager; import com.willfp.eco.internal.bukkit.events.EcoEventManager;
import com.willfp.eco.internal.bukkit.logging.EcoLogger; import com.willfp.eco.internal.bukkit.logging.EcoLogger;
import com.willfp.eco.internal.bukkit.scheduling.EcoScheduler; import com.willfp.eco.internal.bukkit.scheduling.EcoScheduler;
import com.willfp.eco.util.ClassUtils; import com.willfp.eco.internal.extensions.EcoExtensionLoader;
import com.willfp.eco.util.arrows.ArrowDataListener;
import com.willfp.eco.util.bukkit.events.EventManager; import com.willfp.eco.util.bukkit.events.EventManager;
import com.willfp.eco.util.bukkit.keys.NamespacedKeyFactory; import com.willfp.eco.util.bukkit.keys.NamespacedKeyFactory;
import com.willfp.eco.util.bukkit.logging.Logger; import com.willfp.eco.util.bukkit.logging.Logger;
@@ -15,15 +15,14 @@ import com.willfp.eco.util.command.AbstractCommand;
import com.willfp.eco.util.config.configs.Config; import com.willfp.eco.util.config.configs.Config;
import com.willfp.eco.util.config.configs.Lang; import com.willfp.eco.util.config.configs.Lang;
import com.willfp.eco.util.config.updating.ConfigHandler; import com.willfp.eco.util.config.updating.ConfigHandler;
import com.willfp.eco.internal.extensions.EcoExtensionLoader; import com.willfp.eco.util.display.Display;
import com.willfp.eco.util.display.DisplayModule;
import com.willfp.eco.util.extensions.loader.ExtensionLoader; import com.willfp.eco.util.extensions.loader.ExtensionLoader;
import com.willfp.eco.util.integrations.IntegrationLoader; import com.willfp.eco.util.integrations.IntegrationLoader;
import com.willfp.eco.util.integrations.placeholder.PlaceholderManager; import com.willfp.eco.util.integrations.placeholder.PlaceholderManager;
import com.willfp.eco.util.integrations.placeholder.plugins.PlaceholderIntegrationPAPI; import com.willfp.eco.util.integrations.placeholder.plugins.PlaceholderIntegrationPAPI;
import com.willfp.eco.util.optional.Prerequisite; import com.willfp.eco.util.optional.Prerequisite;
import com.willfp.eco.util.protocollib.AbstractPacketAdapter; import com.willfp.eco.util.protocollib.AbstractPacketAdapter;
import com.willfp.eco.util.recipe.RecipeListener;
import com.willfp.eco.util.recipe.RecipeManager;
import com.willfp.eco.util.updater.UpdateChecker; import com.willfp.eco.util.updater.UpdateChecker;
import lombok.Getter; import lombok.Getter;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
@@ -33,6 +32,7 @@ import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@@ -141,12 +141,6 @@ public abstract class AbstractEcoPlugin extends JavaPlugin {
@Getter @Getter
private final RunnableFactory runnableFactory; private final RunnableFactory runnableFactory;
/**
* Recipe handler for crafting recipes.
*/
@Getter
private final RecipeManager recipeManager;
/** /**
* The loader for all plugin extensions. * The loader for all plugin extensions.
* *
@@ -161,6 +155,12 @@ public abstract class AbstractEcoPlugin extends JavaPlugin {
@Getter @Getter
private final ConfigHandler configHandler; private final ConfigHandler configHandler;
/**
* The display module for the plugin.
*/
@Getter
private DisplayModule displayModule;
/** /**
* If the server is running an outdated version of the plugin. * If the server is running an outdated version of the plugin.
*/ */
@@ -195,7 +195,6 @@ public abstract class AbstractEcoPlugin extends JavaPlugin {
this.runnableFactory = new RunnableFactory(this); this.runnableFactory = new RunnableFactory(this);
this.extensionLoader = new EcoExtensionLoader(this); this.extensionLoader = new EcoExtensionLoader(this);
this.configHandler = new ConfigHandler(this); this.configHandler = new ConfigHandler(this);
this.recipeManager = new RecipeManager(this);
this.langYml = new Lang(this); this.langYml = new Lang(this);
this.configYml = new Config(this); this.configYml = new Config(this);
@@ -214,7 +213,6 @@ public abstract class AbstractEcoPlugin extends JavaPlugin {
this.getLog().info("Loading " + this.color + this.pluginName); this.getLog().info("Loading " + this.color + this.pluginName);
this.getEventManager().registerListener(new ArrowDataListener(this)); this.getEventManager().registerListener(new ArrowDataListener(this));
this.getEventManager().registerListener(new RecipeListener(this));
new UpdateChecker(this).getVersion(version -> { new UpdateChecker(this).getVersion(version -> {
DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(this.getDescription().getVersion()); DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(this.getDescription().getVersion());
@@ -297,14 +295,18 @@ public abstract class AbstractEcoPlugin extends JavaPlugin {
* Default code to be executed after the server is up. * Default code to be executed after the server is up.
*/ */
public final void afterLoad() { public final void afterLoad() {
if (ClassUtils.exists("com.comphenix.protocol.events.PacketAdapter")) { this.displayModule = createDisplayModule();
this.getPacketAdapters().forEach(abstractPacketAdapter -> {
if (abstractPacketAdapter.isPostLoad()) { if (this.getDisplayModule() != null) {
abstractPacketAdapter.register(); Display.registerDisplayModule(this.getDisplayModule());
}
});
} }
this.getPacketAdapters().forEach(abstractPacketAdapter -> {
if (abstractPacketAdapter.isPostLoad()) {
abstractPacketAdapter.register();
}
});
if (!Prerequisite.HAS_PAPER.isMet()) { if (!Prerequisite.HAS_PAPER.isMet()) {
this.getLog().error(""); this.getLog().error("");
this.getLog().error("----------------------------"); this.getLog().error("----------------------------");
@@ -400,4 +402,12 @@ public abstract class AbstractEcoPlugin extends JavaPlugin {
* @return A list of all updatable classes. * @return A list of all updatable classes.
*/ */
public abstract List<Class<?>> getUpdatableClasses(); public abstract List<Class<?>> getUpdatableClasses();
/**
* Create the display module for the plugin.
*
* @return The display module, or null.
*/
@Nullable
protected abstract DisplayModule createDisplayModule();
} }

View File

@@ -1,89 +0,0 @@
package com.willfp.eco.util.recipe;
import com.willfp.eco.util.internal.PluginDependent;
import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.CraftItemEvent;
import org.bukkit.event.inventory.PrepareItemCraftEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.ShapedRecipe;
import org.jetbrains.annotations.NotNull;
public class RecipeListener extends PluginDependent implements Listener {
/**
* Pass an {@link AbstractEcoPlugin} in order to interface with it.
*
* @param plugin The plugin to manage.
*/
public RecipeListener(@NotNull final AbstractEcoPlugin plugin) {
super(plugin);
}
/**
* Called on item craft.
*
* @param event The event to listen for.
*/
@EventHandler
public void prepareCraftListener(@NotNull final PrepareItemCraftEvent event) {
if (!(event.getRecipe() instanceof ShapedRecipe)) {
return;
}
ShapedRecipe recipe = (ShapedRecipe) event.getRecipe();
if (!recipe.getKey().getNamespace().equals(this.getPlugin().getPluginName().toLowerCase())) {
return;
}
ItemStack[] matrix = event.getInventory().getMatrix();
EcoShapedRecipe matched = this.getPlugin().getRecipeManager().getMatch(matrix);
if (matched == null) {
event.getInventory().setResult(new ItemStack(Material.AIR));
return;
}
if (matched.test(matrix)) {
event.getInventory().setResult(matched.getOutput());
} else {
event.getInventory().setResult(new ItemStack(Material.AIR));
}
}
/**
* Called on item craft.
*
* @param event The event to listen for.
*/
@EventHandler
public void craftListener(@NotNull final CraftItemEvent event) {
if (!(event.getRecipe() instanceof ShapedRecipe)) {
return;
}
ShapedRecipe recipe = (ShapedRecipe) event.getRecipe();
if (!recipe.getKey().getNamespace().equals(this.getPlugin().getPluginName().toLowerCase())) {
return;
}
ItemStack[] matrix = event.getInventory().getMatrix();
EcoShapedRecipe matched = this.getPlugin().getRecipeManager().getMatch(matrix);
if (matched == null) {
event.getInventory().setResult(new ItemStack(Material.AIR));
event.setCancelled(true);
return;
}
if (matched.test(matrix)) {
event.getInventory().setResult(matched.getOutput());
} else {
event.getInventory().setResult(new ItemStack(Material.AIR));
event.setCancelled(true);
}
}
}

View File

@@ -0,0 +1,63 @@
package com.willfp.eco.util.recipe;
import com.willfp.eco.util.recipe.parts.EmptyRecipePart;
import com.willfp.eco.util.recipe.parts.RecipePart;
import com.willfp.eco.util.recipe.parts.SimpleRecipePart;
import lombok.experimental.UtilityClass;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
@UtilityClass
@SuppressWarnings("deprecation")
public final class RecipeParts {
/**
* All recipe parts.
*/
private static final Map<NamespacedKey, RecipePart> PARTS = new HashMap<>();
/**
* Register a new recipe part.
*
* @param key The key of the recipe part.
* @param part The recipe part.
*/
public void registerRecipePart(@NotNull final NamespacedKey key,
@NotNull final RecipePart part) {
PARTS.put(key, part);
}
/**
* Lookup recipe part from string.
*
* @param key The string to test.
* @return The found recipe part, or null if not found.
*/
public RecipePart lookup(@NotNull final String key) {
String[] split = key.toLowerCase().split(":");
if (split.length == 1) {
Material material = Material.getMaterial(key.toUpperCase());
if (material == null || material == Material.AIR) {
return new EmptyRecipePart();
}
return new SimpleRecipePart(material);
}
RecipePart part = PARTS.get(new NamespacedKey(split[0], split[1]));
return part == null ? new EmptyRecipePart() : part;
}
/**
* Get if itemStack is a recipe part (used to check for custom items).
*
* @param itemStack The itemStack to check.
* @return If is recipe.
*/
public boolean isRecipePart(@NotNull final ItemStack itemStack) {
return PARTS.values().stream().anyMatch(recipePart -> recipePart.matches(itemStack));
}
}

View File

@@ -2,8 +2,8 @@ package com.willfp.eco.util.recipe;
import com.google.common.collect.BiMap; import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap; import com.google.common.collect.HashBiMap;
import com.willfp.eco.util.internal.PluginDependent; import com.willfp.eco.util.recipe.recipes.EcoShapedRecipe;
import com.willfp.eco.util.plugin.AbstractEcoPlugin; import lombok.experimental.UtilityClass;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@@ -12,40 +12,34 @@ import org.bukkit.inventory.ShapedRecipe;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@UtilityClass
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public class RecipeManager extends PluginDependent { public class Recipes {
/** /**
* Registry of all recipes. * Registry of all recipes.
*/ */
private final BiMap<String, EcoShapedRecipe> registry = HashBiMap.create(); private static final BiMap<NamespacedKey, EcoShapedRecipe> RECIPES = HashBiMap.create();
/** /**
* Pass an {@link AbstractEcoPlugin} in order to interface with it. * Register a recipe.
* *
* @param plugin The plugin to manage. * @param recipe The recipe.
*/ */
public RecipeManager(@NotNull final AbstractEcoPlugin plugin) { public void register(@NotNull final EcoShapedRecipe recipe) {
super(plugin); RECIPES.forcePut(recipe.getKey(), recipe);
}
void register(@NotNull final EcoShapedRecipe recipe) { Bukkit.getServer().removeRecipe(recipe.getKey());
String key = recipe.getKey(); Bukkit.getServer().removeRecipe(recipe.getDisplayedKey());
registry.forcePut(key, recipe);
NamespacedKey baseKey = this.getPlugin().getNamespacedKeyFactory().create(key); ShapedRecipe shapedRecipe = new ShapedRecipe(recipe.getKey(), recipe.getOutput());
Bukkit.getServer().removeRecipe(baseKey);
NamespacedKey displayedKey = this.getPlugin().getNamespacedKeyFactory().create(key + "_displayed");
Bukkit.getServer().removeRecipe(displayedKey);
ShapedRecipe shapedRecipe = new ShapedRecipe(baseKey, recipe.getOutput());
shapedRecipe.shape("012", "345", "678"); shapedRecipe.shape("012", "345", "678");
for (int i = 0; i < 9; i++) { for (int i = 0; i < 9; i++) {
char character = String.valueOf(i).toCharArray()[0]; char character = String.valueOf(i).toCharArray()[0];
shapedRecipe.setIngredient(character, recipe.getMaterialAtIndex(i)); shapedRecipe.setIngredient(character, recipe.getMaterialAtIndex(i));
} }
ShapedRecipe displayedRecipe = new ShapedRecipe(displayedKey, recipe.getOutput()); ShapedRecipe displayedRecipe = new ShapedRecipe(recipe.getDisplayedKey(), recipe.getOutput());
displayedRecipe.shape("012", "345", "678"); displayedRecipe.shape("012", "345", "678");
for (int i = 0; i < 9; i++) { for (int i = 0; i < 9; i++) {
char character = String.valueOf(i).toCharArray()[0]; char character = String.valueOf(i).toCharArray()[0];
@@ -64,7 +58,7 @@ public class RecipeManager extends PluginDependent {
*/ */
@Nullable @Nullable
public EcoShapedRecipe getMatch(@NotNull final ItemStack[] matrix) { public EcoShapedRecipe getMatch(@NotNull final ItemStack[] matrix) {
return registry.values().stream().filter(recipe -> recipe.test(matrix)).findFirst().orElse(null); return RECIPES.values().stream().filter(recipe -> recipe.test(matrix)).findFirst().orElse(null);
} }
/** /**
@@ -74,7 +68,18 @@ public class RecipeManager extends PluginDependent {
* @return The shaped recipe, or null if not found. * @return The shaped recipe, or null if not found.
*/ */
@Nullable @Nullable
public EcoShapedRecipe getShapedRecipe(@NotNull final String key) { public EcoShapedRecipe getShapedRecipe(@NotNull final NamespacedKey key) {
return registry.get(key); EcoShapedRecipe recipe = RECIPES.get(key);
if (recipe != null) {
return recipe;
}
if (key.getKey().contains("_displayed")) {
NamespacedKey otherKey = new NamespacedKey(key.getNamespace(), key.getKey().replace("_displayed", ""));
return RECIPES.get(otherKey);
}
return null;
} }
} }

View File

@@ -1,51 +0,0 @@
package com.willfp.eco.util.recipe.lookup;
import com.willfp.eco.util.recipe.parts.EmptyRecipePart;
import com.willfp.eco.util.recipe.parts.RecipePart;
import com.willfp.eco.util.recipe.parts.SimpleRecipePart;
import lombok.experimental.UtilityClass;
import org.bukkit.Material;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
@UtilityClass
public final class RecipePartUtils {
/**
* All recipes.
*/
private static final Map<String, Function<String, RecipePart>> TESTS = new HashMap<>();
/**
* Register a new lookup.
*
* @param key The key of the lookup.
* @param lookupFunction The lookup to register, where the output is the recipe part generated.
*/
public void registerLookup(@NotNull final String key,
@NotNull final Function<String, RecipePart> lookupFunction) {
TESTS.put(key, lookupFunction);
}
/**
* Lookup recipe part from string.
*
* @param key The string to test.
* @return The generated recipe part, or null if invalid.
*/
public RecipePart lookup(@NotNull final String key) {
Function<String, RecipePart> lookup = TESTS.get(key);
if (lookup == null) {
Material material = Material.getMaterial(key.toUpperCase());
if (material == null || material == Material.AIR) {
return new EmptyRecipePart();
}
return new SimpleRecipePart(material);
}
return lookup.apply(key);
}
}

View File

@@ -1,18 +1,19 @@
package com.willfp.eco.util.recipe; package com.willfp.eco.util.recipe.recipes;
import com.willfp.eco.util.interfaces.Registerable;
import com.willfp.eco.util.internal.PluginDependent; import com.willfp.eco.util.internal.PluginDependent;
import com.willfp.eco.util.plugin.AbstractEcoPlugin; import com.willfp.eco.util.plugin.AbstractEcoPlugin;
import com.willfp.eco.util.recipe.Recipes;
import com.willfp.eco.util.recipe.parts.EmptyRecipePart; import com.willfp.eco.util.recipe.parts.EmptyRecipePart;
import com.willfp.eco.util.recipe.parts.RecipePart; import com.willfp.eco.util.recipe.parts.RecipePart;
import lombok.Getter; import lombok.Getter;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Arrays; import java.util.Arrays;
public final class EcoShapedRecipe extends PluginDependent implements Registerable { public final class EcoShapedRecipe extends PluginDependent {
/** /**
* Recipe parts. * Recipe parts.
*/ */
@@ -23,7 +24,13 @@ public final class EcoShapedRecipe extends PluginDependent implements Registerab
* The key of the recipe. * The key of the recipe.
*/ */
@Getter @Getter
private final String key; private final NamespacedKey key;
/**
* The key of the displayed recipe.
*/
@Getter
private final NamespacedKey displayedKey;
/** /**
* The recipe's output. * The recipe's output.
@@ -38,7 +45,8 @@ public final class EcoShapedRecipe extends PluginDependent implements Registerab
super(plugin); super(plugin);
this.parts = parts; this.parts = parts;
this.key = key; this.key = plugin.getNamespacedKeyFactory().create(key);
this.displayedKey = plugin.getNamespacedKeyFactory().create(key + "_displayed");
this.output = output; this.output = output;
} }
@@ -82,9 +90,8 @@ public final class EcoShapedRecipe extends PluginDependent implements Registerab
/** /**
* Register the recipe. * Register the recipe.
*/ */
@Override
public void register() { public void register() {
this.getPlugin().getRecipeManager().register(this); Recipes.register(this);
} }
@Override @Override
@@ -193,66 +200,4 @@ public final class EcoShapedRecipe extends PluginDependent implements Registerab
return new EcoShapedRecipe(plugin, key.toLowerCase(), recipeParts, output); return new EcoShapedRecipe(plugin, key.toLowerCase(), recipeParts, output);
} }
} }
public enum RecipePosition {
/**
* Top left of matrix.
*/
TOP_LEFT(0),
/**
* Top middle of matrix.
*/
TOP_MIDDLE(1),
/**
* Top right of matrix.
*/
TOP_RIGHT(2),
/**
* Middle left of matrix.
*/
MIDDLE_LEFT(3),
/**
* Middle of matrix.
*/
MIDDLE(4),
/**
* Middle right of matrix.
*/
MIDDLE_RIGHT(5),
/**
* Bottom left of matrix.
*/
BOTTOM_LEFT(6),
/**
* Bottom middle of matrix.
*/
BOTTOM_MIDDLE(7),
/**
* Bottom right of matrix.
*/
BOTTOM_RIGHT(8);
/**
* The index within a crafting table matrix.
*/
@Getter
private final int index;
/**
* Recipe position with crafting table index.
*
* @param index The index.
*/
RecipePosition(final int index) {
this.index = index;
}
}
} }

View File

@@ -0,0 +1,65 @@
package com.willfp.eco.util.recipe.recipes;
import lombok.Getter;
public enum RecipePosition {
/**
* Top left of matrix.
*/
TOP_LEFT(0),
/**
* Top middle of matrix.
*/
TOP_MIDDLE(1),
/**
* Top right of matrix.
*/
TOP_RIGHT(2),
/**
* Middle left of matrix.
*/
MIDDLE_LEFT(3),
/**
* Middle of matrix.
*/
MIDDLE(4),
/**
* Middle right of matrix.
*/
MIDDLE_RIGHT(5),
/**
* Bottom left of matrix.
*/
BOTTOM_LEFT(6),
/**
* Bottom middle of matrix.
*/
BOTTOM_MIDDLE(7),
/**
* Bottom right of matrix.
*/
BOTTOM_RIGHT(8);
/**
* The index within a crafting table matrix.
*/
@Getter
private final int index;
/**
* Recipe position with crafting table index.
*
* @param index The index.
*/
RecipePosition(final int index) {
this.index = index;
}
}

View File

@@ -0,0 +1,14 @@
package com.willfp.eco.util.serialization;
import com.willfp.eco.util.config.Config;
import org.jetbrains.annotations.NotNull;
public abstract class Deserializer<T extends EcoSerializable<T>> {
/**
* Deserialize a config into an object.
*
* @param config The config.
* @return The object.
*/
public abstract T deserialize(@NotNull Config config);
}

View File

@@ -0,0 +1,14 @@
package com.willfp.eco.util.serialization;
import com.willfp.eco.util.config.Config;
import org.jetbrains.annotations.NotNull;
public interface EcoSerializable<T> {
/**
* Serialize an object into a config.
*
* @return The config.
*/
@NotNull
Config serialize();
}

View File

@@ -0,0 +1,14 @@
package com.willfp.eco.util.serialization;
import org.jetbrains.annotations.NotNull;
public class NoRegisteredDeserializerException extends Exception {
/**
* Create new NoRegisteredDeserializerException.
*
* @param message The message.
*/
public NoRegisteredDeserializerException(@NotNull final String message) {
super(message);
}
}

View File

@@ -1,9 +1,26 @@
package com.willfp.eco.util.tuples; package com.willfp.eco.util.tuples;
import lombok.Getter;
import lombok.Setter;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@SuppressWarnings("deprecation") public class Pair<A, B> {
public class Pair<A, B> extends com.willfp.eco.util.tuplets.Pair<A, B> { /**
* The first item in the tuple.
*/
@Getter
@Setter
@Nullable
private A first;
/**
* The second item in the tuple.
*/
@Getter
@Setter
@Nullable
private B second;
/** /**
* Create a pair of values. * Create a pair of values.
* *
@@ -12,6 +29,7 @@ public class Pair<A, B> extends com.willfp.eco.util.tuplets.Pair<A, B> {
*/ */
public Pair(@Nullable final A first, public Pair(@Nullable final A first,
@Nullable final B second) { @Nullable final B second) {
super(first, second); this.first = first;
this.second = second;
} }
} }

View File

@@ -1,9 +1,18 @@
package com.willfp.eco.util.tuples; package com.willfp.eco.util.tuples;
import lombok.Getter;
import lombok.Setter;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@SuppressWarnings("deprecation") public class Triplet<A, B, C> extends Pair<A, B> {
public class Triplet<A, B, C> extends com.willfp.eco.util.tuplets.Triplet<A, B, C> { /**
* The third item in the tuple.
*/
@Getter
@Setter
@Nullable
private C third;
/** /**
* Create a triple of values. * Create a triple of values.
* *
@@ -14,6 +23,8 @@ public class Triplet<A, B, C> extends com.willfp.eco.util.tuplets.Triplet<A, B,
public Triplet(@Nullable final A first, public Triplet(@Nullable final A first,
@Nullable final B second, @Nullable final B second,
@Nullable final C third) { @Nullable final C third) {
super(first, second, third); super(first, second);
this.third = third;
} }
} }

View File

@@ -1,41 +0,0 @@
package com.willfp.eco.util.tuplets;
import lombok.Getter;
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.
*/
@Getter
@Setter
@Nullable
private A first;
/**
* The second value in the pair.
*/
@Getter
@Setter
@Nullable
private B second;
/**
* 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.
*/
public Pair(@Nullable final A first,
@Nullable final B second) {
this.first = first;
this.second = second;
}
}

View File

@@ -1,52 +0,0 @@
package com.willfp.eco.util.tuplets;
import lombok.Getter;
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.
*/
@Getter
@Setter
@Nullable
private A first;
/**
* The second item in the triplet.
*/
@Getter
@Setter
@Nullable
private B second;
/**
* The third item in the triplet.
*/
@Getter
@Setter
@Nullable
private C third;
/**
* 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.
* @param third The third item in the triplet.
*/
public Triplet(@Nullable final A first,
@Nullable final B second,
@Nullable final C third) {
this.first = first;
this.second = second;
this.third = third;
}
}

View File

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

BIN
lib/CombatLogX.jar Normal file

Binary file not shown.

BIN
lib/Newbie Helper.jar Normal file

Binary file not shown.

BIN
lib/ULands-Addon-2.8.7.jar Normal file

Binary file not shown.