Add UUID support to trade and protection signs (#4713)

This commit is contained in:
Josh Roy 2022-02-13 15:54:19 -05:00 committed by GitHub
parent a9e5f079a9
commit debf09437e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 127 additions and 28 deletions

View file

@ -66,6 +66,7 @@ import net.ess3.provider.PotionMetaProvider;
import net.ess3.provider.ProviderListener; import net.ess3.provider.ProviderListener;
import net.ess3.provider.SerializationProvider; import net.ess3.provider.SerializationProvider;
import net.ess3.provider.ServerStateProvider; import net.ess3.provider.ServerStateProvider;
import net.ess3.provider.SignDataProvider;
import net.ess3.provider.SpawnEggProvider; import net.ess3.provider.SpawnEggProvider;
import net.ess3.provider.SpawnerBlockProvider; import net.ess3.provider.SpawnerBlockProvider;
import net.ess3.provider.SpawnerItemProvider; 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.LegacyItemUnbreakableProvider;
import net.ess3.provider.providers.LegacyPotionMetaProvider; import net.ess3.provider.providers.LegacyPotionMetaProvider;
import net.ess3.provider.providers.LegacySpawnEggProvider; import net.ess3.provider.providers.LegacySpawnEggProvider;
import net.ess3.provider.providers.ModernDataWorldInfoProvider;
import net.ess3.provider.providers.ModernItemUnbreakableProvider; import net.ess3.provider.providers.ModernItemUnbreakableProvider;
import net.ess3.provider.providers.ModernPersistentDataProvider; 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.PaperContainerProvider;
import net.ess3.provider.providers.PaperKnownCommandsProvider; import net.ess3.provider.providers.PaperKnownCommandsProvider;
import net.ess3.provider.providers.PaperMaterialTagProvider; 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 ReflOnlineModeProvider onlineModeProvider;
private transient ItemUnbreakableProvider unbreakableProvider; private transient ItemUnbreakableProvider unbreakableProvider;
private transient WorldInfoProvider worldInfoProvider; private transient WorldInfoProvider worldInfoProvider;
private transient SignDataProvider signDataProvider;
private transient Kits kits; private transient Kits kits;
private transient RandomTeleport randomTeleport; private transient RandomTeleport randomTeleport;
private transient UpdateChecker updateChecker; private transient UpdateChecker updateChecker;
@ -432,6 +435,10 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
worldInfoProvider = new FixedHeightWorldInfoProvider(); worldInfoProvider = new FixedHeightWorldInfoProvider();
} }
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_14_4_R01)) {
signDataProvider = new ModernSignDataProvider(this);
}
execTimer.mark("Init(Providers)"); execTimer.mark("Init(Providers)");
reload(); reload();
@ -1306,6 +1313,11 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
return worldInfoProvider; return worldInfoProvider;
} }
@Override
public SignDataProvider getSignDataProvider() {
return signDataProvider;
}
@Override @Override
public PluginCommand getPluginCommand(final String cmd) { public PluginCommand getPluginCommand(final String cmd) {
return this.getCommand(cmd); return this.getCommand(cmd);

View file

@ -14,8 +14,9 @@ import net.ess3.provider.ItemUnbreakableProvider;
import net.ess3.provider.KnownCommandsProvider; import net.ess3.provider.KnownCommandsProvider;
import net.ess3.provider.MaterialTagProvider; import net.ess3.provider.MaterialTagProvider;
import net.ess3.provider.PersistentDataProvider; import net.ess3.provider.PersistentDataProvider;
import net.ess3.provider.ServerStateProvider;
import net.ess3.provider.SerializationProvider; import net.ess3.provider.SerializationProvider;
import net.ess3.provider.ServerStateProvider;
import net.ess3.provider.SignDataProvider;
import net.ess3.provider.SpawnerBlockProvider; import net.ess3.provider.SpawnerBlockProvider;
import net.ess3.provider.SpawnerItemProvider; import net.ess3.provider.SpawnerItemProvider;
import net.ess3.provider.SyncCommandsProvider; import net.ess3.provider.SyncCommandsProvider;
@ -165,5 +166,7 @@ public interface IEssentials extends Plugin {
WorldInfoProvider getWorldInfoProvider(); WorldInfoProvider getWorldInfoProvider();
SignDataProvider getSignDataProvider();
PluginCommand getPluginCommand(String cmd); PluginCommand getPluginCommand(String cmd);
} }

View file

@ -110,6 +110,10 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
setBase(base); setBase(base);
} }
public IEssentials getEssentials() {
return ess;
}
@Override @Override
public boolean isAuthorized(final IEssentialsCommand cmd) { public boolean isAuthorized(final IEssentialsCommand cmd) {
return isAuthorized(cmd, "essentials."); return isAuthorized(cmd, "essentials.");

View file

@ -5,6 +5,7 @@ import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.MetaItemStack; import com.earth2me.essentials.MetaItemStack;
import com.earth2me.essentials.Trade; import com.earth2me.essentials.Trade;
import com.earth2me.essentials.User; import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.FormatUtil;
import com.earth2me.essentials.utils.MaterialUtil; import com.earth2me.essentials.utils.MaterialUtil;
import com.earth2me.essentials.utils.NumberUtil; import com.earth2me.essentials.utils.NumberUtil;
import net.ess3.api.IEssentials; 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 @Deprecated
public static boolean isValidSign(final ISign sign) { 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) { public static boolean isValidSign(final IEssentials ess, final ISign sign) {
if (!sign.getLine(0).matches("§1\\[.*\\]")) if (!sign.getLine(0).matches("§1\\[.*]"))
return false; return false;
// Validate that the sign is actually an essentials sign // Validate that the sign is actually an essentials sign
@ -119,6 +120,7 @@ public class EssentialsSign {
} catch (final ChargeException | SignException ex) { } catch (final ChargeException | SignException ex) {
showError(ess, user.getSource(), ex, signName); showError(ess, user.getSource(), ex, signName);
} }
setOwnerData(ess, user, sign);
// Return true, so the player sees the wrong sign. // Return true, so the player sees the wrong sign.
return true; return true;
} }
@ -154,6 +156,35 @@ public class EssentialsSign {
return user.getName().substring(0, Math.min(user.getName().length(), 13)); 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) { protected final boolean onSignInteract(final Block block, final Player player, final IEssentials ess) {
final ISign sign = new BlockSign(block); final ISign sign = new BlockSign(block);
final User user = ess.getUser(player); 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 { 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; return isMoney ? getBigDecimalPositive(line, ess) : null;
} }
@ -531,6 +562,7 @@ public class EssentialsSign {
@Override @Override
public final void setLine(final int index, final String text) { public final void setLine(final int index, final String text) {
sign.setLine(index, text); sign.setLine(index, text);
updateSign();
} }
@Override @Override

View file

@ -5,7 +5,6 @@ import com.earth2me.essentials.Trade;
import com.earth2me.essentials.Trade.OverflowType; import com.earth2me.essentials.Trade.OverflowType;
import com.earth2me.essentials.User; import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.EnumUtil; import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.FormatUtil;
import com.earth2me.essentials.utils.MaterialUtil; import com.earth2me.essentials.utils.MaterialUtil;
import net.ess3.api.IEssentials; import net.ess3.api.IEssentials;
import net.ess3.api.MaxMoneyException; import net.ess3.api.MaxMoneyException;
@ -123,7 +122,7 @@ public class SignProtection extends EssentialsSign {
if (user.isAuthorized("essentials.signs.protection.override")) { if (user.isAuthorized("essentials.signs.protection.override")) {
return SignProtectionState.OWNER; return SignProtectionState.OWNER;
} }
if (FormatUtil.stripFormat(sign.getLine(3)).equalsIgnoreCase(username)) { if (isOwner(user.getEssentials(), user, sign, 3, "§1")) {
return SignProtectionState.OWNER; return SignProtectionState.OWNER;
} }
for (int i = 1; i <= 2; i++) { for (int i = 1; i <= 2; i++) {

View file

@ -19,7 +19,7 @@ import static com.earth2me.essentials.I18n.tl;
//TODO: TL exceptions //TODO: TL exceptions
public class SignTrade extends EssentialsSign { public class SignTrade extends EssentialsSign {
private static int MAX_STOCK_LINE_LENGTH = 15; private static final int MAX_STOCK_LINE_LENGTH = 15;
public SignTrade() { public SignTrade() {
super("Trade"); super("Trade");
@ -35,7 +35,7 @@ public class SignTrade extends EssentialsSign {
throw new SignException("You cannot trade for the same item type."); throw new SignException("You cannot trade for the same item type.");
} }
trade.isAffordableFor(player); trade.isAffordableFor(player);
sign.setLine(3, "§8" + username); setOwner(ess, player, sign, 3, "§8");
trade.charge(player); trade.charge(player);
Trade.log("Sign", "Trade", "Create", username, trade, username, null, sign.getBlock().getLocation(), player.getMoney(), ess); Trade.log("Sign", "Trade", "Create", username, trade, username, null, sign.getBlock().getLocation(), player.getMoney(), ess);
return true; return true;
@ -43,7 +43,7 @@ public class SignTrade extends EssentialsSign {
@Override @Override
protected boolean onSignInteract(final ISign sign, final User player, final String username, final IEssentials ess) throws SignException, ChargeException, MaxMoneyException { 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 store = rechargeSign(sign, ess, player);
final Trade stored; final Trade stored;
try { 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 { 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 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 canBreak = isOwner || player.isAuthorized("essentials.signs.trade.override");
final boolean canCollect = isOwner || player.isAuthorized("essentials.signs.trade.override.collect"); final boolean canCollect = isOwner || player.isAuthorized("essentials.signs.trade.override.collect");
@ -238,27 +238,26 @@ public class SignTrade extends EssentialsSign {
} }
if (split.length == 3) { if (split.length == 3) {
final int stackAmount = getIntegerPositive(split[0]);
if (split[1].equalsIgnoreCase("exp") || split[1].equalsIgnoreCase("xp")) { if (split[1].equalsIgnoreCase("exp") || split[1].equalsIgnoreCase("xp")) {
final int stackamount = getIntegerPositive(split[0]);
int amount = getInteger(split[2]); int amount = getInteger(split[2]);
if (amountType == AmountType.ROUNDED) { 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")); throw new SignException(tl("tradeSignEmpty"));
} }
return new Trade(amountType == AmountType.COST ? stackamount : amount, ess); return new Trade(amountType == AmountType.COST ? stackAmount : amount, ess);
} else { } 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]); int amount = getInteger(split[2]);
if (amountType == AmountType.ROUNDED) { 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")); throw new SignException(tl("tradeSignEmpty"));
} }
item.setAmount(amountType == AmountType.COST ? stackamount : amount); item.setAmount(amountType == AmountType.COST ? stackAmount : amount);
return new Trade(item, ess); return new Trade(item, ess);
} }
} }
@ -337,20 +336,18 @@ public class SignTrade extends EssentialsSign {
} }
if (split.length == 3) { if (split.length == 3) {
final int stackAmount = getIntegerPositive(split[0]);
if (split[1].equalsIgnoreCase("exp") || split[1].equalsIgnoreCase("xp")) { 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); validateSignLength(newline);
sign.setLine(index, newline); sign.setLine(index, newline);
return;
} else { } else {
final int stackamount = getIntegerPositive(split[0]); getItemStack(split[1], stackAmount, ess);
getItemStack(split[1], stackamount, ess); final String newline = stackAmount + " " + split[1] + ":" + value.intValueExact();
final String newline = stackamount + " " + split[1] + ":" + value.intValueExact();
validateSignLength(newline); validateSignLength(newline);
sign.setLine(index, newline); sign.setLine(index, newline);
return;
} }
return;
} }
throw new SignException(tl("invalidSignLine", index + 1)); throw new SignException(tl("invalidSignLine", index + 1));
} }

View file

@ -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);
}

View file

@ -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";
}
}