From debf09437e1f9b9b5f30ac7958d48696547432b2 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sun, 13 Feb 2022 15:54:19 -0500 Subject: [PATCH] Add UUID support to trade and protection signs (#4713) --- .../com/earth2me/essentials/Essentials.java | 14 +++++- .../com/earth2me/essentials/IEssentials.java | 5 ++- .../java/com/earth2me/essentials/User.java | 4 ++ .../essentials/signs/EssentialsSign.java | 40 +++++++++++++++-- .../essentials/signs/SignProtection.java | 3 +- .../earth2me/essentials/signs/SignTrade.java | 37 ++++++++-------- .../net/ess3/provider/SignDataProvider.java | 9 ++++ .../providers/ModernSignDataProvider.java | 43 +++++++++++++++++++ 8 files changed, 127 insertions(+), 28 deletions(-) create mode 100644 providers/BaseProviders/src/main/java/net/ess3/provider/SignDataProvider.java create mode 100644 providers/BaseProviders/src/main/java/net/ess3/provider/providers/ModernSignDataProvider.java diff --git a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java index a17f10239..9ab438975 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java @@ -66,6 +66,7 @@ import net.ess3.provider.PotionMetaProvider; import net.ess3.provider.ProviderListener; import net.ess3.provider.SerializationProvider; import net.ess3.provider.ServerStateProvider; +import net.ess3.provider.SignDataProvider; import net.ess3.provider.SpawnEggProvider; import net.ess3.provider.SpawnerBlockProvider; import net.ess3.provider.SpawnerItemProvider; @@ -80,9 +81,10 @@ import net.ess3.provider.providers.FlatSpawnEggProvider; import net.ess3.provider.providers.LegacyItemUnbreakableProvider; import net.ess3.provider.providers.LegacyPotionMetaProvider; import net.ess3.provider.providers.LegacySpawnEggProvider; +import net.ess3.provider.providers.ModernDataWorldInfoProvider; import net.ess3.provider.providers.ModernItemUnbreakableProvider; import net.ess3.provider.providers.ModernPersistentDataProvider; -import net.ess3.provider.providers.ModernDataWorldInfoProvider; +import net.ess3.provider.providers.ModernSignDataProvider; import net.ess3.provider.providers.PaperContainerProvider; import net.ess3.provider.providers.PaperKnownCommandsProvider; import net.ess3.provider.providers.PaperMaterialTagProvider; @@ -175,6 +177,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { private transient ReflOnlineModeProvider onlineModeProvider; private transient ItemUnbreakableProvider unbreakableProvider; private transient WorldInfoProvider worldInfoProvider; + private transient SignDataProvider signDataProvider; private transient Kits kits; private transient RandomTeleport randomTeleport; private transient UpdateChecker updateChecker; @@ -432,6 +435,10 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { worldInfoProvider = new FixedHeightWorldInfoProvider(); } + if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_14_4_R01)) { + signDataProvider = new ModernSignDataProvider(this); + } + execTimer.mark("Init(Providers)"); reload(); @@ -1306,6 +1313,11 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { return worldInfoProvider; } + @Override + public SignDataProvider getSignDataProvider() { + return signDataProvider; + } + @Override public PluginCommand getPluginCommand(final String cmd) { return this.getCommand(cmd); diff --git a/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java b/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java index cb3df386f..464fec918 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java @@ -14,8 +14,9 @@ import net.ess3.provider.ItemUnbreakableProvider; import net.ess3.provider.KnownCommandsProvider; import net.ess3.provider.MaterialTagProvider; import net.ess3.provider.PersistentDataProvider; -import net.ess3.provider.ServerStateProvider; import net.ess3.provider.SerializationProvider; +import net.ess3.provider.ServerStateProvider; +import net.ess3.provider.SignDataProvider; import net.ess3.provider.SpawnerBlockProvider; import net.ess3.provider.SpawnerItemProvider; import net.ess3.provider.SyncCommandsProvider; @@ -165,5 +166,7 @@ public interface IEssentials extends Plugin { WorldInfoProvider getWorldInfoProvider(); + SignDataProvider getSignDataProvider(); + PluginCommand getPluginCommand(String cmd); } diff --git a/Essentials/src/main/java/com/earth2me/essentials/User.java b/Essentials/src/main/java/com/earth2me/essentials/User.java index 596268dc4..12952aff9 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/User.java +++ b/Essentials/src/main/java/com/earth2me/essentials/User.java @@ -110,6 +110,10 @@ public class User extends UserData implements Comparable, IMessageRecipien setBase(base); } + public IEssentials getEssentials() { + return ess; + } + @Override public boolean isAuthorized(final IEssentialsCommand cmd) { return isAuthorized(cmd, "essentials."); diff --git a/Essentials/src/main/java/com/earth2me/essentials/signs/EssentialsSign.java b/Essentials/src/main/java/com/earth2me/essentials/signs/EssentialsSign.java index c380596a7..8df9f5524 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/signs/EssentialsSign.java +++ b/Essentials/src/main/java/com/earth2me/essentials/signs/EssentialsSign.java @@ -5,6 +5,7 @@ import com.earth2me.essentials.CommandSource; import com.earth2me.essentials.MetaItemStack; import com.earth2me.essentials.Trade; import com.earth2me.essentials.User; +import com.earth2me.essentials.utils.FormatUtil; import com.earth2me.essentials.utils.MaterialUtil; import com.earth2me.essentials.utils.NumberUtil; import net.ess3.api.IEssentials; @@ -60,15 +61,15 @@ public class EssentialsSign { } /** - * @deprecated, use {@link #isValidSign(IEssentials, ISign)} if possible + * @deprecated use {@link #isValidSign(IEssentials, ISign)} if possible */ @Deprecated public static boolean isValidSign(final ISign sign) { - return sign.getLine(0).matches("§1\\[.*\\]"); + return sign.getLine(0).matches("§1\\[.*]"); } public static boolean isValidSign(final IEssentials ess, final ISign sign) { - if (!sign.getLine(0).matches("§1\\[.*\\]")) + if (!sign.getLine(0).matches("§1\\[.*]")) return false; // Validate that the sign is actually an essentials sign @@ -119,6 +120,7 @@ public class EssentialsSign { } catch (final ChargeException | SignException ex) { showError(ess, user.getSource(), ex, signName); } + setOwnerData(ess, user, sign); // Return true, so the player sees the wrong sign. return true; } @@ -154,6 +156,35 @@ public class EssentialsSign { return user.getName().substring(0, Math.min(user.getName().length(), 13)); } + public void setOwner(final IEssentials ess, final User user, final ISign signProvider, final int nameIndex, final String namePrefix) { + setOwnerData(ess, user, signProvider); + signProvider.setLine(nameIndex, namePrefix + getUsername(user)); + } + + public void setOwnerData(final IEssentials ess, final User user, final ISign signProvider) { + if (ess.getSignDataProvider() == null) { + return; + } + final Sign sign = (Sign) signProvider.getBlock().getState(); + ess.getSignDataProvider().setSignData(sign, "owner", user.getUUID().toString()); + } + + public boolean isOwner(final IEssentials ess, final User user, final ISign signProvider, final int nameIndex, final String namePrefix) { + final Sign sign = (Sign) signProvider.getBlock().getState(); + if (ess.getSignDataProvider() == null || ess.getSignDataProvider().getSignData(sign, "owner") == null) { + if (ess.getSignDataProvider() != null) { + ess.getSignDataProvider().setSignData(sign, "owner", user.getUUID().toString()); + } + return FormatUtil.stripFormat(signProvider.getLine(nameIndex)).equalsIgnoreCase(getUsername(user)); + } + + if (user.getUUID().toString().equals(ess.getSignDataProvider().getSignData(sign, "owner"))) { + signProvider.setLine(nameIndex, namePrefix + getUsername(user)); + return true; + } + return false; + } + protected final boolean onSignInteract(final Block block, final Player player, final IEssentials ess) { final ISign sign = new BlockSign(block); final User user = ess.getUser(player); @@ -392,7 +423,7 @@ public class EssentialsSign { } protected final BigDecimal getMoney(final String line, final IEssentials ess) throws SignException { - final boolean isMoney = line.matches("^[^0-9-\\.]?[\\.0-9]+[^0-9-\\.]?$"); + final boolean isMoney = line.matches("^[^0-9-.]?[.0-9]+[^0-9-.]?$"); return isMoney ? getBigDecimalPositive(line, ess) : null; } @@ -531,6 +562,7 @@ public class EssentialsSign { @Override public final void setLine(final int index, final String text) { sign.setLine(index, text); + updateSign(); } @Override diff --git a/Essentials/src/main/java/com/earth2me/essentials/signs/SignProtection.java b/Essentials/src/main/java/com/earth2me/essentials/signs/SignProtection.java index cbb69dda8..bd2f27bcd 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/signs/SignProtection.java +++ b/Essentials/src/main/java/com/earth2me/essentials/signs/SignProtection.java @@ -5,7 +5,6 @@ import com.earth2me.essentials.Trade; import com.earth2me.essentials.Trade.OverflowType; import com.earth2me.essentials.User; import com.earth2me.essentials.utils.EnumUtil; -import com.earth2me.essentials.utils.FormatUtil; import com.earth2me.essentials.utils.MaterialUtil; import net.ess3.api.IEssentials; import net.ess3.api.MaxMoneyException; @@ -123,7 +122,7 @@ public class SignProtection extends EssentialsSign { if (user.isAuthorized("essentials.signs.protection.override")) { return SignProtectionState.OWNER; } - if (FormatUtil.stripFormat(sign.getLine(3)).equalsIgnoreCase(username)) { + if (isOwner(user.getEssentials(), user, sign, 3, "§1")) { return SignProtectionState.OWNER; } for (int i = 1; i <= 2; i++) { diff --git a/Essentials/src/main/java/com/earth2me/essentials/signs/SignTrade.java b/Essentials/src/main/java/com/earth2me/essentials/signs/SignTrade.java index 1308f0999..33989fcff 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/signs/SignTrade.java +++ b/Essentials/src/main/java/com/earth2me/essentials/signs/SignTrade.java @@ -19,7 +19,7 @@ import static com.earth2me.essentials.I18n.tl; //TODO: TL exceptions public class SignTrade extends EssentialsSign { - private static int MAX_STOCK_LINE_LENGTH = 15; + private static final int MAX_STOCK_LINE_LENGTH = 15; public SignTrade() { super("Trade"); @@ -35,7 +35,7 @@ public class SignTrade extends EssentialsSign { throw new SignException("You cannot trade for the same item type."); } trade.isAffordableFor(player); - sign.setLine(3, "§8" + username); + setOwner(ess, player, sign, 3, "§8"); trade.charge(player); Trade.log("Sign", "Trade", "Create", username, trade, username, null, sign.getBlock().getLocation(), player.getMoney(), ess); return true; @@ -43,7 +43,7 @@ public class SignTrade extends EssentialsSign { @Override protected boolean onSignInteract(final ISign sign, final User player, final String username, final IEssentials ess) throws SignException, ChargeException, MaxMoneyException { - if (sign.getLine(3).substring(2).equalsIgnoreCase(username)) { + if (isOwner(ess, player, sign, 3, "§8")) { final Trade store = rechargeSign(sign, ess, player); final Trade stored; try { @@ -102,7 +102,7 @@ public class SignTrade extends EssentialsSign { protected boolean onSignBreak(final ISign sign, final User player, final String username, final IEssentials ess) throws SignException, MaxMoneyException { final String signOwner = sign.getLine(3); - final boolean isOwner = signOwner.length() > 3 && signOwner.substring(2).equalsIgnoreCase(username); + final boolean isOwner = isOwner(ess, player, sign, 3, "§8"); final boolean canBreak = isOwner || player.isAuthorized("essentials.signs.trade.override"); final boolean canCollect = isOwner || player.isAuthorized("essentials.signs.trade.override.collect"); @@ -238,27 +238,26 @@ public class SignTrade extends EssentialsSign { } if (split.length == 3) { + final int stackAmount = getIntegerPositive(split[0]); if (split[1].equalsIgnoreCase("exp") || split[1].equalsIgnoreCase("xp")) { - final int stackamount = getIntegerPositive(split[0]); int amount = getInteger(split[2]); if (amountType == AmountType.ROUNDED) { - amount -= amount % stackamount; + amount -= amount % stackAmount; } - if (notEmpty && (amount < 1 || stackamount < 1)) { + if (notEmpty && (amount < 1 || stackAmount < 1)) { throw new SignException(tl("tradeSignEmpty")); } - return new Trade(amountType == AmountType.COST ? stackamount : amount, ess); + return new Trade(amountType == AmountType.COST ? stackAmount : amount, ess); } else { - final int stackamount = getIntegerPositive(split[0]); - final ItemStack item = getItemStack(split[1], stackamount, allowId, ess); + final ItemStack item = getItemStack(split[1], stackAmount, allowId, ess); int amount = getInteger(split[2]); if (amountType == AmountType.ROUNDED) { - amount -= amount % stackamount; + amount -= amount % stackAmount; } - if (notEmpty && (amount < 1 || stackamount < 1 || item.getType() == Material.AIR || amount < stackamount)) { + if (notEmpty && (amount < 1 || stackAmount < 1 || item.getType() == Material.AIR || amount < stackAmount)) { throw new SignException(tl("tradeSignEmpty")); } - item.setAmount(amountType == AmountType.COST ? stackamount : amount); + item.setAmount(amountType == AmountType.COST ? stackAmount : amount); return new Trade(item, ess); } } @@ -337,20 +336,18 @@ public class SignTrade extends EssentialsSign { } if (split.length == 3) { + final int stackAmount = getIntegerPositive(split[0]); if (split[1].equalsIgnoreCase("exp") || split[1].equalsIgnoreCase("xp")) { - final int stackamount = getIntegerPositive(split[0]); - final String newline = stackamount + " " + split[1] + ":" + value.intValueExact(); + final String newline = stackAmount + " " + split[1] + ":" + value.intValueExact(); validateSignLength(newline); sign.setLine(index, newline); - return; } else { - final int stackamount = getIntegerPositive(split[0]); - getItemStack(split[1], stackamount, ess); - final String newline = stackamount + " " + split[1] + ":" + value.intValueExact(); + getItemStack(split[1], stackAmount, ess); + final String newline = stackAmount + " " + split[1] + ":" + value.intValueExact(); validateSignLength(newline); sign.setLine(index, newline); - return; } + return; } throw new SignException(tl("invalidSignLine", index + 1)); } diff --git a/providers/BaseProviders/src/main/java/net/ess3/provider/SignDataProvider.java b/providers/BaseProviders/src/main/java/net/ess3/provider/SignDataProvider.java new file mode 100644 index 000000000..f84c85144 --- /dev/null +++ b/providers/BaseProviders/src/main/java/net/ess3/provider/SignDataProvider.java @@ -0,0 +1,9 @@ +package net.ess3.provider; + +import org.bukkit.block.Sign; + +public interface SignDataProvider extends Provider { + void setSignData(Sign sign, String key, String value); + + String getSignData(Sign sign, String key); +} diff --git a/providers/BaseProviders/src/main/java/net/ess3/provider/providers/ModernSignDataProvider.java b/providers/BaseProviders/src/main/java/net/ess3/provider/providers/ModernSignDataProvider.java new file mode 100644 index 000000000..84687c0ed --- /dev/null +++ b/providers/BaseProviders/src/main/java/net/ess3/provider/providers/ModernSignDataProvider.java @@ -0,0 +1,43 @@ +package net.ess3.provider.providers; + +import net.ess3.provider.SignDataProvider; +import org.bukkit.NamespacedKey; +import org.bukkit.block.Sign; +import org.bukkit.persistence.PersistentDataType; +import org.bukkit.plugin.Plugin; + +public class ModernSignDataProvider implements SignDataProvider { + private final Plugin plugin; + + public ModernSignDataProvider(Plugin plugin) { + this.plugin = plugin; + } + + @Override + public void setSignData(Sign sign, String key, String value) { + if (sign == null || key == null || value == null) { + return; + } + + sign.getPersistentDataContainer().set(new NamespacedKey(plugin, key), PersistentDataType.STRING, value); + sign.update(); + } + + @Override + public String getSignData(Sign sign, String key) { + if (sign == null || key == null) { + return null; + } + + try { + return sign.getPersistentDataContainer().get(new NamespacedKey(plugin, key), PersistentDataType.STRING); + } catch (IllegalArgumentException ignored) { + return null; + } + } + + @Override + public String getDescription() { + return "1.14+ Persistent Data Sign Provider"; + } +}