Changes the Anvil GUI for SongodaCore's ChatPrompt. Also moves the redeem logic from the interact listener to the voucher to avoid duplicate code.

Adds support for custom player textures. You can get them from https://minecraft-heads.com. Copying the value or the Minecraft URL value works.

Changes the checks for a voucher for a very simple NBT check. Should also fix the random lore issue not working.
This commit is contained in:
Fernando Pettinelli 2020-09-14 17:17:21 -03:00
parent 97fc3ea793
commit 7f9018a034
11 changed files with 154 additions and 60 deletions

View File

@ -92,8 +92,10 @@ public class EpicVouchers extends SongodaPlugin {
guiManager.init();
manager.registerEvents(new PlayerInteractListener(this), this);
manager.registerEvents(new PlayerCommandListener(), this);
}
@Override
public void onDataLoad() {
if (!new File(this.getDataFolder(), "vouchers.yml").exists())
saveResource("vouchers.yml", false);
vouchersConfig.load();
@ -128,6 +130,7 @@ public class EpicVouchers extends SongodaPlugin {
.setData((short) cs.getInt("data", 0))
.setName(cs.getString("name", "default"))
.setLore(cs.getStringList("lore"))
.setTexture(cs.getString("texture", ""))
.setGlow(cs.getBoolean("glow", false))
.setConfirm(cs.getBoolean("confirm", true))
.setUnbreakable(cs.getBoolean("unbreakable", false))
@ -171,6 +174,7 @@ public class EpicVouchers extends SongodaPlugin {
vouchersConfig.set(prefix + "data", voucher.getData());
vouchersConfig.set(prefix + "name", voucher.getName());
vouchersConfig.set(prefix + "lore", voucher.getLore());
vouchersConfig.set(prefix + "texture", voucher.getTexture());
vouchersConfig.set(prefix + "glow", voucher.isGlow());
vouchersConfig.set(prefix + "confirm", voucher.isConfirm());
vouchersConfig.set(prefix + "unbreakable", voucher.isUnbreakable());

View File

@ -1,9 +1,10 @@
package com.songoda.epicvouchers.libraries.inventory.icons;
import com.songoda.core.gui.AnvilGui;
import com.songoda.core.input.ChatPrompt;
import com.songoda.epicvouchers.EpicVouchers;
import com.songoda.epicvouchers.libraries.ItemBuilder;
import com.songoda.epicvouchers.utils.Pair;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
@ -21,13 +22,9 @@ public class ListEntryIcon extends Icon {
onRemove.accept(event.getPlayer(), entry);
return;
}
AnvilGui gui = new AnvilGui(event.getPlayer());
gui.setTitle("Current: " + entry);
gui.setAction(aevent -> onEdit.accept(event.getPlayer(), new Pair<>(entry, gui.getInputText().trim())));
instance.getGuiManager().showGUI(event.getPlayer(), gui);
ChatPrompt.showPrompt(instance, event.getPlayer(), aevent -> {
Bukkit.getScheduler().runTaskLater(instance, () -> onEdit.accept(event.getPlayer(), new Pair<>(entry, aevent.getMessage().trim())), 1L);
});
}
});
}
}

View File

@ -1,10 +1,11 @@
package com.songoda.epicvouchers.libraries.inventory.icons;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.gui.AnvilGui;
import com.songoda.core.input.ChatPrompt;
import com.songoda.core.utils.TextUtils;
import com.songoda.epicvouchers.EpicVouchers;
import com.songoda.epicvouchers.libraries.ItemBuilder;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
@ -48,18 +49,15 @@ public class StringIcon extends Icon {
consumer.accept(event.getPlayer(), "");
event.getPlayer().sendMessage(TextUtils.formatText("&7Successfully cleared&7."));
} else {
AnvilGui gui = new AnvilGui(event.getPlayer());
gui.setTitle("current:" + current);
gui.setAction(aevent -> {
final String msg = gui.getInputText().trim();
ChatPrompt.showPrompt(instance, event.getPlayer(), TextUtils.formatText("&7Enter a new value. Current: &r" + current), aevent -> {
final String msg = aevent.getMessage().trim();
if (!predicate.test(msg)) {
event.getPlayer().sendMessage(TextUtils.formatText("&cFailed to set value to: " + msg));
return;
}
consumer.accept(event.getPlayer(), msg);
event.getPlayer().sendMessage(TextUtils.formatText("&7Successfully set to &r" + msg + "&7."));
});
instance.getGuiManager().showGUI(event.getPlayer(), gui);
Bukkit.getScheduler().runTaskLater(instance, () -> consumer.accept(event.getPlayer(), msg), 1L);
});
}
});

View File

@ -1,11 +1,10 @@
package com.songoda.epicvouchers.listeners;
import com.songoda.core.nms.NmsManager;
import com.songoda.core.nms.nbt.NBTItem;
import com.songoda.epicvouchers.EpicVouchers;
import com.songoda.epicvouchers.menus.ConfirmMenu;
import com.songoda.epicvouchers.voucher.Voucher;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
@ -13,8 +12,6 @@ import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.UUID;
public class PlayerInteractListener implements Listener {
private final EpicVouchers instance;
@ -28,10 +25,20 @@ public class PlayerInteractListener implements Listener {
final ItemStack item = event.getItem();
if (item == null || (event.getAction() != Action.RIGHT_CLICK_AIR && event.getAction() != Action.RIGHT_CLICK_BLOCK))
return;
final Player player = event.getPlayer();
final NBTItem itemNbt = NmsManager.getNbt().of(item);
for (Voucher voucher : instance.getVoucherManager().getVouchers()) {
final ItemStack voucherItem = voucher.toItemStack();
// Check voucher NBT.
if (itemNbt.has("epicvouchers:voucher") && itemNbt.getNBTObject("epicvouchers:voucher").asString().equals(voucher.getKey())) {
event.setCancelled(true);
voucher.redeemVoucher(event);
continue;
}
// Legacy crap.
// does the item they're holding match this voucher?
if (voucherItem != null && !voucherItem.isSimilar(item)) continue;
@ -46,32 +53,7 @@ public class PlayerInteractListener implements Listener {
}
event.setCancelled(true);
// does the player have permission to redeem this voucher?
if (!voucher.getPermission().isEmpty() && !player.hasPermission(voucher.getPermission())) {
// todo: probably should send a message to the player...
return;
}
UUID uuid = player.getUniqueId();
if (instance.getCoolDowns().isOnCoolDown(uuid)) {
instance.getLocale().getMessage("event.general.cooldown")
.processPlaceholder("time", instance.getCoolDowns().getTime(uuid))
.processPlaceholder("voucher", voucher.getName(true))
.sendPrefixedMessage(player);
return;
}
if (voucher.isConfirm()) {
new ConfirmMenu(instance,
() -> instance.getVoucherExecutor().redeemVoucher(player, voucher, item, true, event),
() -> {
})
.open(player);
} else {
instance.getVoucherExecutor().redeemVoucher(player, voucher, item, true, event);
}
voucher.redeemVoucher(event);
}
}
}

View File

@ -1,5 +1,7 @@
package com.songoda.epicvouchers.menus;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.utils.ItemUtils;
import com.songoda.epicvouchers.EpicVouchers;
import com.songoda.epicvouchers.libraries.ItemBuilder;
import com.songoda.epicvouchers.libraries.inventory.IconInv;
@ -13,6 +15,7 @@ import com.songoda.epicvouchers.menus.sub.editor.SoundsMenu;
import com.songoda.epicvouchers.menus.sub.editor.TitlesMenu;
import com.songoda.epicvouchers.voucher.Voucher;
import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
@ -87,6 +90,13 @@ public class VoucherEditorMenu extends IconInv {
reopen(player);
}));
addIcon(13, new StringIcon(instance, new ItemBuilder(voucher.getTexture() == null ? CompatibleMaterial.PLAYER_HEAD.getItem() : ItemUtils.getCustomHead(voucher.getTexture()))
.name(ChatColor.YELLOW + "Skull Texture")
.lore(GRAY + "Right click to edit", GRAY + "Left click to clear").build(), voucher.getTexture(), (player, editString) -> {
voucher.setTexture(editString);
reopen(player);
}));
// Sections
addIcon(18, new StringListIcon(instance, voucher.getCommands(), "Commands", voucher));

View File

@ -41,6 +41,7 @@ public class VoucherMenu extends IconInv {
Voucher voucher = new Voucher(msg, instance);
voucher.setMaterial(PAPER);
voucher.setName("&f" + msg);
voucher.setTexture("");
instance.getVoucherManager().addVoucher(voucher);
event.getPlayer().sendMessage(TextUtils.formatText("&7Successfully created voucher with id &r" + msg + "&7."));

View File

@ -1,12 +1,14 @@
package com.songoda.epicvouchers.menus.sub.editor;
import com.songoda.core.gui.AnvilGui;
import com.songoda.core.input.ChatPrompt;
import com.songoda.core.utils.TextUtils;
import com.songoda.epicvouchers.EpicVouchers;
import com.songoda.epicvouchers.libraries.ItemBuilder;
import com.songoda.epicvouchers.libraries.inventory.IconInv;
import com.songoda.epicvouchers.libraries.inventory.icons.ListEntryIcon;
import com.songoda.epicvouchers.menus.VoucherEditorMenu;
import com.songoda.epicvouchers.voucher.Voucher;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import java.util.List;
@ -32,13 +34,12 @@ public class StringListMenu extends IconInv {
.build());
addIcon(size - 1, new ItemBuilder(PAPER).name(GREEN + "Add to list").build(), event -> {
AnvilGui gui = new AnvilGui(event.getPlayer());
gui.setAction(aevent -> {
list.add(gui.getInputText().trim());
voucher.saveSetting(key.toLowerCase(), list);
new StringListMenu(instance, key, list, toEdit, voucher).open(event.getPlayer());
ChatPrompt.showPrompt(instance, event.getPlayer(), TextUtils.formatText("Enter a new value."), aevent -> {
list.add(aevent.getMessage().trim());
voucher.saveSetting(key.toLowerCase(), list);
Bukkit.getScheduler().runTaskLater(instance, () -> new StringListMenu(instance, key, list, toEdit, voucher).open(event.getPlayer()), 1L);
});
instance.getGuiManager().showGUI(event.getPlayer(), gui);
});
for (int i = 0; i < list.size(); i++) {

View File

@ -0,0 +1,47 @@
package com.songoda.epicvouchers.utils;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import com.songoda.core.compatibility.ServerVersion;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.UUID;
public class SkullUtils {
/*
* Custom skull texture. Should probably be moved to SongodaCore.
*/
public static ItemStack customTexture(ItemStack itemStack, String texture) {
if (ServerVersion.isServerVersionBelow(ServerVersion.V1_8)) {
return itemStack;
}
if (texture == null || texture.isEmpty()) {
return itemStack;
}
SkullMeta skullMeta = (SkullMeta)itemStack.getItemMeta();
GameProfile gameProfile = new GameProfile(UUID.nameUUIDFromBytes(texture.getBytes()), "CustomHead");
if (texture.endsWith("=")) {
gameProfile.getProperties().put("textures", new Property("texture", texture.replaceAll("=", "")));
} else {
byte[] encodedData = Base64.getEncoder().encode(String.format("{textures:{SKIN:{url:\"http://textures.minecraft.net/texture/%s\"}}}", texture).getBytes());
gameProfile.getProperties().put("textures", new Property("textures", new String(encodedData)));
}
try {
Field profileField = skullMeta.getClass().getDeclaredField("profile");
profileField.setAccessible(true);
profileField.set(skullMeta, gameProfile);
itemStack.setItemMeta(skullMeta);
return itemStack;
} catch (IllegalAccessException | NoSuchFieldException ex) {
throw new RuntimeException("Reflection error while setting head texture", ex);
}
}
}

View File

@ -4,11 +4,12 @@ import com.songoda.epicvouchers.EpicVouchers;
import org.bukkit.Bukkit;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class CoolDownManager {
private final HashMap<UUID, Long> entries = new HashMap<>();
private final Map<UUID, Long> entries = new HashMap<>();
private final EpicVouchers instance;
public CoolDownManager(EpicVouchers instance) {

View File

@ -1,5 +1,6 @@
package com.songoda.epicvouchers.voucher;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.nms.NmsManager;
import com.songoda.core.nms.nbt.NBTItem;
@ -7,18 +8,22 @@ import com.songoda.core.utils.TextUtils;
import com.songoda.epicvouchers.EpicVouchers;
import com.songoda.epicvouchers.events.ForceRedeemEvent;
import com.songoda.epicvouchers.events.VoucherReceiveEvent;
import com.songoda.epicvouchers.menus.ConfirmMenu;
import com.songoda.epicvouchers.utils.SkullUtils;
import lombok.experimental.Accessors;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import static org.bukkit.Material.PAPER;
@ -34,6 +39,7 @@ public class Voucher {
private int coolDown = 0;
private String name;
private List<String> lore = new ArrayList<>();
private String texture;
private boolean glow = true;
private boolean confirm = true;
private boolean unbreakable = false;
@ -113,7 +119,15 @@ public class Voucher {
item = nbtItem.finish();
}
}
return item;
if (texture != null && !texture.isEmpty() && CompatibleMaterial.PLAYER_HEAD.getMaterial() == material) {
item = SkullUtils.customTexture(itemStack, texture);
}
NBTItem nbtItem = NmsManager.getNbt().of(item);
nbtItem.set("epicvouchers:voucher", key);
return nbtItem.finish();
}
public String getName(boolean applyFormatting) {
@ -200,6 +214,40 @@ public class Voucher {
}
}
public void redeemVoucher(PlayerInteractEvent event) {
Player player = event.getPlayer();
// does the player have permission to redeem this voucher?
if (!permission.isEmpty() && !player.hasPermission(permission)) {
player.sendMessage(instance.getLocale().getMessage("event.general.nopermission").getPrefixedMessage());
return;
}
UUID uuid = player.getUniqueId();
if (instance.getCoolDowns().isOnCoolDown(uuid)) {
instance.getLocale().getMessage("event.general.cooldown")
.processPlaceholder("time", instance.getCoolDowns().getTime(uuid))
.processPlaceholder("voucher", getName(true))
.sendPrefixedMessage(player);
return;
}
if (confirm) {
new ConfirmMenu(instance,
() -> instance.getVoucherExecutor().redeemVoucher(player, this, event.getItem(), true, event),
() -> {
})
.open(player);
} else {
instance.getVoucherExecutor().redeemVoucher(player, this, event.getItem(), true, event);
}
}
public String getTexture() {
return texture;
}
public String getActionBar() {
return TextUtils.formatText(actionBar);
}
@ -417,6 +465,11 @@ public class Voucher {
return this;
}
public Voucher setTexture(String texture) {
this.texture = texture;
return this;
}
public Voucher setActionBar(String actionBar) {
this.actionBar = actionBar;
return this;

View File

@ -5,10 +5,10 @@ import com.songoda.epicvouchers.EpicVouchers;
import com.songoda.epicvouchers.events.VoucherRedeemEvent;
import com.songoda.epicvouchers.libraries.BountifulAPI;
import com.songoda.epicvouchers.listeners.PlayerCommandListener;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.Sound;
import org.bukkit.craftbukkit.libs.org.apache.commons.lang3.StringUtils;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;