diff --git a/build.gradle b/build.gradle index b457a17..b3d7bda 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ plugins { } group = 'me.skymc' -version = '5.08' +version = '5.09' sourceCompatibility = 1.8 targetCompatibility = 1.8 diff --git a/src/main/scala/io/izzel/taboolib/common/event/PlayerJumpEvent.java b/src/main/scala/io/izzel/taboolib/common/event/PlayerJumpEvent.java index ca6fed1..fac0484 100644 --- a/src/main/scala/io/izzel/taboolib/common/event/PlayerJumpEvent.java +++ b/src/main/scala/io/izzel/taboolib/common/event/PlayerJumpEvent.java @@ -1,46 +1,17 @@ package io.izzel.taboolib.common.event; -import org.bukkit.Bukkit; +import io.izzel.taboolib.module.event.EventCancellable; import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; -public class PlayerJumpEvent extends Event implements Cancellable { +public class PlayerJumpEvent extends EventCancellable { - private static final HandlerList handlers = new HandlerList(); - private boolean isCancelled; private Player player; public PlayerJumpEvent(Player player) { this.player = player; } - public static HandlerList getHandlerList() { - return handlers; - } - public Player getPlayer() { return this.player; } - - public PlayerJumpEvent call() { - Bukkit.getPluginManager().callEvent(this); - return this; - } - - @Override - public boolean isCancelled() { - return this.isCancelled; - } - - @Override - public void setCancelled(boolean e) { - this.isCancelled = e; - } - - @Override - public HandlerList getHandlers() { - return handlers; - } } diff --git a/src/main/scala/io/izzel/taboolib/common/listener/ListenerPlayerJump.java b/src/main/scala/io/izzel/taboolib/common/listener/ListenerPlayerJump.java index 18aa56b..83b354c 100644 --- a/src/main/scala/io/izzel/taboolib/common/listener/ListenerPlayerJump.java +++ b/src/main/scala/io/izzel/taboolib/common/listener/ListenerPlayerJump.java @@ -28,13 +28,12 @@ public class ListenerPlayerJump implements Listener { // 不在冷却 && !cooldown.isCooldown(e.getPlayer().getName())) { - PlayerJumpEvent event = new PlayerJumpEvent(e.getPlayer()).call(); - if (event.isCancelled()) { + new PlayerJumpEvent(e.getPlayer()).call().ifCancelled(() -> { // 返回位置 e.setTo(e.getFrom()); // 重置冷却 cooldown.reset(e.getPlayer().getName()); - } + }); } } } diff --git a/src/main/scala/io/izzel/taboolib/module/command/base/BaseMainCommand.java b/src/main/scala/io/izzel/taboolib/module/command/base/BaseMainCommand.java index 5cc388c..596957f 100644 --- a/src/main/scala/io/izzel/taboolib/module/command/base/BaseMainCommand.java +++ b/src/main/scala/io/izzel/taboolib/module/command/base/BaseMainCommand.java @@ -110,7 +110,9 @@ public abstract class BaseMainCommand implements CommandExecutor, TabExecutor { sender.sendMessage(getEmptyLine()); } - abstract public String getCommandTitle(); + public String getCommandTitle() { + return "§e§l----- §6§l" + registerCommand.getPlugin().getName() + " Commands §e§l-----"; + } @Override public List onTabComplete(CommandSender commandSender, Command command, String s, String[] args) { diff --git a/src/main/scala/io/izzel/taboolib/module/event/EventCancellable.java b/src/main/scala/io/izzel/taboolib/module/event/EventCancellable.java new file mode 100644 index 0000000..ae03a1a --- /dev/null +++ b/src/main/scala/io/izzel/taboolib/module/event/EventCancellable.java @@ -0,0 +1,53 @@ +package io.izzel.taboolib.module.event; + +import org.bukkit.event.Cancellable; + +/** + * @Author sky + * @Since 2019-10-22 10:41 + */ +public abstract class EventCancellable extends EventNormal implements Cancellable { + + private boolean cancelled; + + public T nonCancelled(Runnable runnable) { + if (nonCancelled()) { + try { + runnable.run(); + } catch (Throwable t) { + t.printStackTrace(); + } + } + return (T) this; + } + + public T ifCancelled(Runnable runnable) { + if (isCancelled()) { + try { + runnable.run(); + } catch (Throwable t) { + t.printStackTrace(); + } + } + return (T) this; + } + + @Override + public T call() { + return (T) super.call(); + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + public boolean nonCancelled() { + return !cancelled; + } +} diff --git a/src/main/scala/io/izzel/taboolib/module/event/EventNormal.java b/src/main/scala/io/izzel/taboolib/module/event/EventNormal.java new file mode 100644 index 0000000..814217e --- /dev/null +++ b/src/main/scala/io/izzel/taboolib/module/event/EventNormal.java @@ -0,0 +1,47 @@ +package io.izzel.taboolib.module.event; + +import io.izzel.taboolib.util.Ref; +import io.izzel.taboolib.util.Reflection; +import org.bukkit.Bukkit; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import java.lang.reflect.Field; + +/** + * @Author sky + * @Since 2019-10-22 10:25 + */ +public abstract class EventNormal extends Event { + + protected static final HandlerList handlers = new HandlerList(); + + protected static HandlerList getHandlerList() { + return handlers; + } + + public T call() { + try { + Bukkit.getPluginManager().callEvent(this); + } catch (Throwable t) { + t.printStackTrace(); + } + return (T) this; + } + + public T async(boolean value) { + try { + Field asyncField = Reflection.getField(Event.class, true, "async"); + Ref.forcedAccess(asyncField); + asyncField.setBoolean(this, value); + } catch (Throwable t) { + t.printStackTrace(); + } + return (T) this; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } +} diff --git a/src/main/scala/io/izzel/taboolib/module/lite/SimpleEquip.java b/src/main/scala/io/izzel/taboolib/module/lite/SimpleEquip.java index e6d16d0..fa71c3d 100644 --- a/src/main/scala/io/izzel/taboolib/module/lite/SimpleEquip.java +++ b/src/main/scala/io/izzel/taboolib/module/lite/SimpleEquip.java @@ -1,12 +1,12 @@ package io.izzel.taboolib.module.lite; -import com.google.common.collect.Maps; import org.bukkit.entity.Player; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; import java.util.Arrays; import java.util.Map; +import java.util.stream.Collectors; /** * @Author 坏黑 @@ -14,23 +14,25 @@ import java.util.Map; */ public enum SimpleEquip { - HAND(EquipmentSlot.HAND, -1), + HAND(EquipmentSlot.HAND, "mainhand", -1), - OFF_HAND(EquipmentSlot.OFF_HAND, 40), + OFF_HAND(EquipmentSlot.OFF_HAND, "offhand", 40), - FEET(EquipmentSlot.FEET, 36), + FEET(EquipmentSlot.FEET, "feet", 36), - LEGS(EquipmentSlot.LEGS, 37), + LEGS(EquipmentSlot.LEGS, "legs", 37), - CHEST(EquipmentSlot.CHEST, 38), + CHEST(EquipmentSlot.CHEST, "chest", 38), - HEAD(EquipmentSlot.HEAD, 39); + HEAD(EquipmentSlot.HEAD, "head", 39); private EquipmentSlot bukkit; + private String nms; private int slot; - SimpleEquip(EquipmentSlot bukkit, int slot) { + SimpleEquip(EquipmentSlot bukkit, String nms, int slot) { this.bukkit = bukkit; + this.nms = nms; this.slot = slot; } @@ -50,16 +52,16 @@ public enum SimpleEquip { } } + public static SimpleEquip fromNMS(String nms) { + return Arrays.stream(values()).filter(tEquipment -> tEquipment.nms.equalsIgnoreCase(nms)).findFirst().orElse(null); + } + public static SimpleEquip fromBukkit(EquipmentSlot bukkit) { return Arrays.stream(values()).filter(tEquipment -> tEquipment.bukkit == bukkit).findFirst().orElse(null); } public static Map getItems(Player player) { - Map map = Maps.newHashMap(); - for (SimpleEquip equipment : values()) { - map.put(equipment, equipment.getItem(player)); - } - return map; + return Arrays.stream(values()).collect(Collectors.toMap(equipment -> equipment, equipment -> equipment.getItem(player), (a, b) -> b)); } // ********************************* @@ -72,6 +74,10 @@ public enum SimpleEquip { return bukkit; } + public String getNMS() { + return nms; + } + public int getSlot() { return slot; } diff --git a/src/main/scala/io/izzel/taboolib/module/nms/NMS.java b/src/main/scala/io/izzel/taboolib/module/nms/NMS.java index e70c66a..fc0c315 100644 --- a/src/main/scala/io/izzel/taboolib/module/nms/NMS.java +++ b/src/main/scala/io/izzel/taboolib/module/nms/NMS.java @@ -1,12 +1,19 @@ package io.izzel.taboolib.module.nms; +import com.google.common.collect.Lists; import io.izzel.taboolib.module.inject.TInject; +import io.izzel.taboolib.module.nms.nbt.NBTAttribute; import io.izzel.taboolib.module.nms.nbt.NBTCompound; +import io.izzel.taboolib.module.nms.nbt.NBTList; import org.bukkit.Particle; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.stream.Collectors; + /** * @Author 坏黑 * @Since 2018-11-09 14:38 @@ -47,4 +54,17 @@ public abstract class NMS { public ItemStack saveNBT(ItemStack itemStack, NBTCompound compound) { return _NBT(itemStack, compound); } + + public List getAttribute(ItemStack item) { + NBTCompound nbt = loadNBT(item); + return !nbt.containsKey("AttributeModifiers") ? Lists.newCopyOnWriteArrayList() : nbt.get("AttributeModifiers").asList().stream().map(element -> NBTAttribute.fromNBT(element.asCompound())).collect(Collectors.toCollection(CopyOnWriteArrayList::new)); + } + + public ItemStack setAttribute(ItemStack item, List attributes) { + NBTCompound nbt = loadNBT(item); + nbt.put("AttributeModifiers", attributes.stream().map(NBTAttribute::toNBT).collect(Collectors.toCollection(NBTList::new))); + return saveNBT(item, nbt); + } + + abstract public List getBaseAttribute(ItemStack item); } diff --git a/src/main/scala/io/izzel/taboolib/module/nms/NMSImpl.java b/src/main/scala/io/izzel/taboolib/module/nms/NMSImpl.java index a5a089e..d177872 100644 --- a/src/main/scala/io/izzel/taboolib/module/nms/NMSImpl.java +++ b/src/main/scala/io/izzel/taboolib/module/nms/NMSImpl.java @@ -1,9 +1,13 @@ package io.izzel.taboolib.module.nms; +import com.google.common.collect.Lists; +import com.google.common.collect.Multimap; import io.izzel.taboolib.Version; import io.izzel.taboolib.module.lite.SimpleReflection; +import io.izzel.taboolib.module.nms.nbt.NBTAttribute; import io.izzel.taboolib.module.nms.nbt.NBTCompound; import io.izzel.taboolib.module.nms.nbt.NBTList; +import io.izzel.taboolib.module.nms.nbt.NBTOperation; import io.izzel.taboolib.module.packet.TPacketHandler; import net.minecraft.server.v1_12_R1.ChatMessageType; import net.minecraft.server.v1_12_R1.EntityVillager; @@ -28,6 +32,7 @@ import org.bukkit.inventory.meta.PotionMeta; import java.lang.reflect.Field; import java.util.List; import java.util.Map; +import java.util.UUID; /** * @Author 坏黑 @@ -235,6 +240,29 @@ public class NMSImpl extends NMS { return new NBTCompound(); } + @Override + public List getBaseAttribute(ItemStack item) { + List list = Lists.newArrayList(); + Object nmsItem = CraftItemStack.asNMSCopy(item); + Object attr; + if (Version.isAfter(Version.v1_9)) { + attr = ((net.minecraft.server.v1_12_R1.ItemStack) nmsItem).getItem().a(net.minecraft.server.v1_12_R1.EnumItemSlot.MAINHAND); + } else { + attr = ((net.minecraft.server.v1_8_R3.ItemStack) nmsItem).getItem().i(); + } + ((Multimap) attr).forEach((k, v) -> { + Object nbt = net.minecraft.server.v1_12_R1.GenericAttributes.a((net.minecraft.server.v1_12_R1.AttributeModifier) v); + list.add(new NBTAttribute( + new UUID(((NBTTagCompound) nbt).getLong("UUIDMost"), ((NBTTagCompound) nbt).getLong("UUIDLeast")), + String.valueOf(k), + ((NBTTagCompound) nbt).getString("Name"), + ((NBTTagCompound) nbt).getDouble("Amount"), + NBTOperation.fromIndex(((NBTTagCompound) nbt).getInt("Operation")) + )); + }); + return list; + } + private Object toNBTBase(io.izzel.taboolib.module.nms.nbt.NBTBase base) { switch (base.getType().getId()) { case 1: diff --git a/src/main/scala/io/izzel/taboolib/module/nms/nbt/NBTAttribute.java b/src/main/scala/io/izzel/taboolib/module/nms/nbt/NBTAttribute.java new file mode 100644 index 0000000..09d7ee3 --- /dev/null +++ b/src/main/scala/io/izzel/taboolib/module/nms/nbt/NBTAttribute.java @@ -0,0 +1,168 @@ +package io.izzel.taboolib.module.nms.nbt; + +import io.izzel.taboolib.module.lite.SimpleEquip; +import io.izzel.taboolib.util.item.Items; + +import java.util.Objects; +import java.util.UUID; + +/** + * @Author sky + * @Since 2019-10-22 11:38 + */ +public class NBTAttribute { + + private UUID id; + private String name; + private String description; + private double amount; + private SimpleEquip slot; + private NBTOperation operation; + + public NBTAttribute(String name, String description, double amount, NBTOperation operation) { + this(UUID.randomUUID(), name, description, amount, null, operation); + } + + public NBTAttribute(String name, String description, double amount, SimpleEquip slot, NBTOperation operation) { + this(UUID.randomUUID(), name, description, amount, slot, operation); + } + + public NBTAttribute(UUID id, String name, String description, double amount, NBTOperation operation) { + this(id, name, description, amount, null, operation); + } + + public NBTAttribute(UUID id, String name, String description, double amount, SimpleEquip slot, NBTOperation operation) { + this.id = id; + this.name = name; + this.description = description; + this.amount = amount; + this.slot = slot; + this.operation = operation; + } + + public NBTCompound toNBT() { + NBTCompound nbt = new NBTCompound(); + nbt.put("UUIDMost", new NBTBase(id.getMostSignificantBits())); + nbt.put("UUIDLeast", new NBTBase(id.getLeastSignificantBits())); + nbt.put("AttributeName", new NBTBase(name)); + nbt.put("Name", new NBTBase(description)); + nbt.put("Amount", new NBTBase(amount)); + nbt.put("Operation", new NBTBase(operation.ordinal())); + if (slot != null) { + nbt.put("Slot", new NBTBase(slot.getNMS())); + } + return nbt; + } + + public static NBTAttribute fromNBT(NBTCompound nbt) { + NBTAttribute attribute = new NBTAttribute( + new UUID(nbt.get("UUIDMost").asLong(), nbt.get("UUIDLeast").asLong()), + nbt.get("AttributeName").asString(), + nbt.get("Name").asString(), + nbt.get("Amount").asDouble(), + NBTOperation.fromIndex(nbt.get("Operation").asInt()) + ); + if (nbt.containsKey("Slot")) { + attribute.slot(SimpleEquip.fromNMS(nbt.get("Slot").asString())); + } + return attribute; + } + + public static NBTAttribute create() { + return new NBTAttribute(Items.asAttribute("damage"), "TabooLib Modifiers", 0, NBTOperation.ADD_NUMBER); + } + + // ********************************* + // + // Getter and Setter + // + // ********************************* + + public UUID getId() { + return id; + } + + public NBTAttribute id(UUID id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public NBTAttribute name(String name) { + this.name = name; + return this; + } + + public String getDescription() { + return description; + } + + public NBTAttribute description(String description) { + this.description = description; + return this; + } + + public double getAmount() { + return amount; + } + + public NBTAttribute amount(double amount) { + this.amount = amount; + return this; + } + + public SimpleEquip getSlot() { + return slot; + } + + public NBTAttribute slot(SimpleEquip slot) { + this.slot = slot; + return this; + } + + public NBTOperation getOperation() { + return operation; + } + + public NBTAttribute operation(NBTOperation operation) { + this.operation = operation; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof NBTAttribute)) { + return false; + } + NBTAttribute that = (NBTAttribute) o; + return Double.compare(that.getAmount(), getAmount()) == 0 && + Objects.equals(getId(), that.getId()) && + Objects.equals(getName(), that.getName()) && + Objects.equals(getDescription(), that.getDescription()) && + getSlot() == that.getSlot() && + getOperation() == that.getOperation(); + } + + @Override + public int hashCode() { + return Objects.hash(getId(), getName(), getDescription(), getAmount(), getSlot(), getOperation()); + } + + @Override + public String toString() { + return "NBTAttribute{" + + "id=" + id + + ", name='" + name + '\'' + + ", description='" + description + '\'' + + ", amount=" + amount + + ", slot=" + slot + + ", operation=" + operation + + '}'; + } +} diff --git a/src/main/scala/io/izzel/taboolib/module/nms/nbt/NBTBase.java b/src/main/scala/io/izzel/taboolib/module/nms/nbt/NBTBase.java index d76f69b..7e3de18 100644 --- a/src/main/scala/io/izzel/taboolib/module/nms/nbt/NBTBase.java +++ b/src/main/scala/io/izzel/taboolib/module/nms/nbt/NBTBase.java @@ -1,7 +1,13 @@ package io.izzel.taboolib.module.nms.nbt; +import io.izzel.taboolib.TabooLib; +import org.bukkit.configuration.ConfigurationSection; + import java.util.Arrays; +import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.regex.Pattern; /** * @Author 坏黑 @@ -9,6 +15,7 @@ import java.util.Objects; */ public class NBTBase { + protected static final Pattern SHORT_PATTERN = Pattern.compile("\\d+s"); protected NBTType type; protected Object data; @@ -115,6 +122,65 @@ public class NBTBase { return type; } + public static NBTBase formNBTBase(Object obj) { + if (obj instanceof String) { + if (SHORT_PATTERN.matcher(obj.toString()).matches()) { + return formNBTBase(Short.valueOf(obj.toString().substring(0, obj.toString().length() - 1))); + } + return new NBTBase((String) obj); + } else if (obj instanceof Integer) { + return new NBTBase((int) obj); + } else if (obj instanceof Double) { + return new NBTBase((double) obj); + } else if (obj instanceof Float) { + return new NBTBase((float) obj); + } else if (obj instanceof Short) { + return new NBTBase((short) obj); + } else if (obj instanceof Long) { + return new NBTBase((long) obj); + } else if (obj instanceof Byte) { + return new NBTBase((byte) obj); + } else if (obj instanceof List) { + return translateList(new NBTList(), (List) obj); + } else if (obj instanceof Map) { + NBTCompound nbtCompound = new NBTCompound(); + ((Map) obj).forEach((key, value) -> nbtCompound.put(key.toString(), formNBTBase(value))); + return nbtCompound; + } else if (obj instanceof ConfigurationSection) { + NBTCompound nbtCompound = new NBTCompound(); + ((ConfigurationSection) obj).getValues(false).forEach((key, value) -> nbtCompound.put(key, formNBTBase(value))); + return nbtCompound; + } + return new NBTBase("error: " + obj); + } + + public static NBTList translateList(NBTList nbtListBase, List list) { + for (Object obj : list) { + NBTBase base = formNBTBase(obj); + if (base == null) { + TabooLib.getLogger().warn("Invalid Type: " + obj + " [" + obj.getClass().getSimpleName() + "]"); + continue; + } + nbtListBase.add(base); + } + return nbtListBase; + } + + public static NBTCompound translateSection(NBTCompound nbt, ConfigurationSection section) { + for (String key : section.getKeys(false)) { + Object obj = section.get(key); + NBTBase base; + if (obj instanceof ConfigurationSection) { + base = translateSection(new NBTCompound(), section.getConfigurationSection(key)); + } else if ((base = formNBTBase(obj)) == null) { + TabooLib.getLogger().warn("Invalid Type: " + obj + " [" + obj.getClass().getSimpleName() + "]"); + continue; + } + nbt.put(key, base); + } + return nbt; + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/src/main/scala/io/izzel/taboolib/module/nms/nbt/NBTCompound.java b/src/main/scala/io/izzel/taboolib/module/nms/nbt/NBTCompound.java index f475678..b94d4cb 100644 --- a/src/main/scala/io/izzel/taboolib/module/nms/nbt/NBTCompound.java +++ b/src/main/scala/io/izzel/taboolib/module/nms/nbt/NBTCompound.java @@ -49,11 +49,37 @@ public class NBTCompound extends NBTBase implements Map { return value.get(key); } + public NBTBase getDeep(String key) { + NBTBase value = this; + for (String keyStr : key.split("\\.")) { + if ((value = value.asCompound().get(keyStr)) == null) { + return null; + } + } + return value; + } + @Override public NBTBase put(String key, NBTBase value) { return this.value.put(key, value); } + public NBTBase putDeep(String key, NBTBase value) { + NBTBase compound = this, temp; + String[] keySplit = key.split("\\."); + for (String keyStr : keySplit) { + if (keyStr.equalsIgnoreCase(keySplit[keySplit.length - 1])) { + return ((NBTCompound) compound).put(keyStr, value); + } + if ((temp = compound.asCompound().get(keyStr)) == null) { + temp = new NBTCompound(); + compound.asCompound().put(keyStr, temp); + } + compound = temp; + } + return null; + } + @Override public NBTBase remove(Object key) { return value.remove(key); diff --git a/src/main/scala/io/izzel/taboolib/module/nms/nbt/NBTOperation.java b/src/main/scala/io/izzel/taboolib/module/nms/nbt/NBTOperation.java new file mode 100644 index 0000000..2c61dfd --- /dev/null +++ b/src/main/scala/io/izzel/taboolib/module/nms/nbt/NBTOperation.java @@ -0,0 +1,27 @@ +package io.izzel.taboolib.module.nms.nbt; + +import io.izzel.taboolib.util.KV; +import org.bukkit.util.NumberConversions; + +import java.util.Arrays; + +/** + * @Author sky + * @Since 2019-10-22 12:06 + */ +public enum NBTOperation { + + ADD_NUMBER, ADD_SCALAR, MULTIPLY_SCALAR_1; + + public static NBTOperation fromIndex(int index) { + return Arrays.stream(values()).filter(operation -> operation.ordinal() == index).findFirst().orElse(ADD_NUMBER); + } + + public static KV fromSimple(String in) { + if (in.endsWith("%")) { + return new KV(NumberConversions.toDouble(in.substring(0, in.length() - 1)), ADD_SCALAR); + } else { + return new KV(NumberConversions.toDouble(in), ADD_NUMBER); + } + } +} diff --git a/src/main/scala/io/izzel/taboolib/util/Strings.java b/src/main/scala/io/izzel/taboolib/util/Strings.java index 8530124..29c5a9f 100644 --- a/src/main/scala/io/izzel/taboolib/util/Strings.java +++ b/src/main/scala/io/izzel/taboolib/util/Strings.java @@ -7,10 +7,18 @@ import java.security.NoSuchAlgorithmException; public class Strings { + public static boolean nonBlack(String var) { + return !isBlank(var); + } + public static boolean isBlank(String var) { return var == null || var.trim().isEmpty(); } + public static boolean nonEmpty(CharSequence var) { + return !isEmpty(var); + } + public static boolean isEmpty(CharSequence var) { return var == null || var.length() == 0; } @@ -90,13 +98,13 @@ public class Strings { } private static String removeSign(String str) { - StringBuffer sb = new StringBuffer(); + StringBuilder builder = new StringBuilder(); for (char item : str.toCharArray()) { if (charReg(item)){ - sb.append(item); + builder.append(item); } } - return sb.toString(); + return builder.toString(); } private static boolean charReg(char charValue) { diff --git a/src/main/scala/io/izzel/taboolib/util/item/Items.java b/src/main/scala/io/izzel/taboolib/util/item/Items.java index 491016d..58c88f3 100644 --- a/src/main/scala/io/izzel/taboolib/util/item/Items.java +++ b/src/main/scala/io/izzel/taboolib/util/item/Items.java @@ -2,13 +2,13 @@ package io.izzel.taboolib.util.item; import com.google.common.collect.ImmutableMap; import io.izzel.taboolib.Version; +import io.izzel.taboolib.module.lite.SimpleEquip; import io.izzel.taboolib.module.lite.SimpleI18n; import io.izzel.taboolib.module.locale.TLocale; import io.izzel.taboolib.module.nms.NMS; import io.izzel.taboolib.module.nms.nbt.NBTBase; import io.izzel.taboolib.module.nms.nbt.NBTCompound; import io.izzel.taboolib.module.nms.nbt.NBTList; -import io.izzel.taboolib.util.lite.Numbers; import org.bukkit.Color; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; @@ -26,6 +26,8 @@ import org.bukkit.util.NumberConversions; import java.util.List; import java.util.Map; +import java.util.Optional; +import java.util.UUID; /** * @Author 坏黑 @@ -48,6 +50,10 @@ public class Items { return item == null || item.getType().equals(Material.AIR); } + public static boolean nonNull(ItemStack item) { + return !isNull(item); + } + public static boolean hasLore(ItemStack i, String a) { return hasLore(i) && i.getItemMeta().getLore().toString().contains(a); } @@ -210,11 +216,11 @@ public class Items { return section.getItemStack("bukkit"); } // 材质 - ItemStack item = new ItemStack(asMaterial(section.getString("material"))); + ItemStack item = new ItemStack(asMaterial(section.contains("material") ? section.getString("material") : section.getString("type"))); // 数量 - item.setAmount(section.contains("amount") ? section.getInt("amount") : 1); + item.setAmount(section.contains("amount") ? section.getInt("amount") : section.getInt("count", 1)); // 耐久 - item.setDurability((short) section.getInt("data")); + item.setDurability((short) (section.contains("data") ? section.getInt("data") : section.getInt("damage"))); // 元数据 ItemMeta meta = item.getItemMeta(); // 展示名 @@ -272,18 +278,7 @@ public class Items { NBTCompound nbt = NMS.handle().loadNBT(item); // 物品标签 if (section.contains("nbt")) { - for (String name : section.getConfigurationSection("nbt").getKeys(false)) { - Object obj = section.get("nbt." + name); - if (obj instanceof String) { - nbt.put(name, new NBTBase(obj.toString())); - } else if (obj instanceof Double) { - nbt.put(name, new NBTBase(NumberConversions.toDouble(obj))); - } else if (obj instanceof Integer) { - nbt.put(name, new NBTBase(NumberConversions.toInt(obj))); - } else if (obj instanceof Long) { - nbt.put(name, new NBTBase(NumberConversions.toLong(obj))); - } - } + NBTBase.translateSection(nbt, section.getConfigurationSection("nbt")); } // 物品属性 if (section.contains("attributes")) { @@ -292,6 +287,7 @@ public class Items { for (String name : section.getConfigurationSection("attributes." + hand).getKeys(false)) { if (asAttribute(name) != null) { try { + UUID uuid = UUID.randomUUID(); NBTCompound a = new NBTCompound(); String num = section.getString("attributes." + hand + "." + name); if (num.endsWith("%")) { @@ -302,11 +298,11 @@ public class Items { a.put("Operation", new NBTBase(0)); } a.put("AttributeName", new NBTBase(asAttribute(name))); - a.put("UUIDMost", new NBTBase(Numbers.getRandom().nextInt(Integer.MAX_VALUE))); - a.put("UUIDLeast", new NBTBase(Numbers.getRandom().nextInt(Integer.MAX_VALUE))); + a.put("UUIDMost", new NBTBase(uuid.getMostSignificantBits())); + a.put("UUIDLeast", new NBTBase(uuid.getLeastSignificantBits())); a.put("Name", new NBTBase(asAttribute(name))); if (!hand.equals("all")) { - a.put("Slot", new NBTBase(hand)); + Optional.ofNullable(SimpleEquip.fromNMS(hand)).ifPresent(e -> a.put("Slot", new NBTBase(e.getNMS()))); } attr.add(a); } catch (Exception ignored) { diff --git a/src/main/scala/io/izzel/taboolib/util/item/inventory/ClickListener.java b/src/main/scala/io/izzel/taboolib/util/item/inventory/ClickListener.java index 3aab994..65b1aab 100644 --- a/src/main/scala/io/izzel/taboolib/util/item/inventory/ClickListener.java +++ b/src/main/scala/io/izzel/taboolib/util/item/inventory/ClickListener.java @@ -1,8 +1,13 @@ package io.izzel.taboolib.util.item.inventory; +import io.izzel.taboolib.TabooLib; import io.izzel.taboolib.module.inject.TListener; +import io.izzel.taboolib.util.item.Items; +import io.izzel.taboolib.util.lite.Vectors; import org.bukkit.Bukkit; import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.inventory.InventoryClickEvent; @@ -11,6 +16,7 @@ import org.bukkit.event.inventory.InventoryDragEvent; import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerItemHeldEvent; import org.bukkit.event.server.PluginDisableEvent; +import org.bukkit.metadata.FixedMetadataValue; import java.util.Optional; @@ -22,43 +28,68 @@ import java.util.Optional; class ClickListener implements Listener { @EventHandler - public void onDisable(PluginDisableEvent e) { + public void e(PluginDisableEvent e) { Bukkit.getOnlinePlayers().stream().filter(player -> player.getOpenInventory().getTopInventory().getHolder() instanceof MenuHolder && e.getPlugin().equals(((MenuHolder) player.getOpenInventory().getTopInventory().getHolder()).getBuilder().getPlugin())).forEach(HumanEntity::closeInventory); } @EventHandler - public void onClick(InventoryClickEvent e) { + public void e(InventoryClickEvent e) { if (e.getInventory().getHolder() instanceof MenuHolder) { + // lock hand if (((MenuHolder) e.getInventory().getHolder()).getBuilder().isLockHand() && (e.getRawSlot() - e.getInventory().getSize() - 27 == e.getWhoClicked().getInventory().getHeldItemSlot() || (e.getClick() == org.bukkit.event.inventory.ClickType.NUMBER_KEY && e.getHotbarButton() == e.getWhoClicked().getInventory().getHeldItemSlot()))) { e.setCancelled(true); } Optional.ofNullable(((MenuHolder) e.getInventory().getHolder()).getBuilder().getClickTask()).ifPresent(t -> t.run(new ClickEvent(ClickType.CLICK, e, ((MenuHolder) e.getInventory().getHolder()).getBuilder().getSlot(e.getRawSlot())))); + // drop on empty area + if (!e.isCancelled() && Items.nonNull(e.getCurrentItem()) && e.getClick() == org.bukkit.event.inventory.ClickType.DROP) { + Item item = Vectors.itemDrop((Player) e.getWhoClicked(), e.getCurrentItem()); + item.setPickupDelay(20); + item.setMetadata("internal-drop", new FixedMetadataValue(TabooLib.getPlugin(), true)); + PlayerDropItemEvent event = new PlayerDropItemEvent((Player) e.getWhoClicked(), item); + if (event.isCancelled()) { + event.getItemDrop().remove(); + } else { + e.setCurrentItem(null); + } + } + // drop by keyboard + else if (!e.isCancelled() && Items.nonNull(e.getCursor()) && e.getRawSlot() == -999) { + Item item = Vectors.itemDrop((Player) e.getWhoClicked(), e.getCursor()); + item.setPickupDelay(20); + item.setMetadata("internal-drop", new FixedMetadataValue(TabooLib.getPlugin(), true)); + PlayerDropItemEvent event = new PlayerDropItemEvent((Player) e.getWhoClicked(), item); + if (event.isCancelled()) { + event.getItemDrop().remove(); + } else { + e.getView().setCursor(null); + } + } } } @EventHandler - public void onDrag(InventoryDragEvent e) { + public void e(InventoryDragEvent e) { if (e.getInventory().getHolder() instanceof MenuHolder) { Optional.ofNullable(((MenuHolder) e.getInventory().getHolder()).getBuilder().getClickTask()).ifPresent(t -> t.run(new ClickEvent(ClickType.DRAG, e, ' '))); } } @EventHandler - public void onDrag(InventoryCloseEvent e) { + public void e(InventoryCloseEvent e) { if (e.getInventory().getHolder() instanceof MenuHolder) { Optional.ofNullable(((MenuHolder) e.getInventory().getHolder()).getBuilder().getCloseTask()).ifPresent(t -> t.run(e)); } } @EventHandler - public void onDrop(PlayerDropItemEvent e) { - if (e.getPlayer().getOpenInventory().getTopInventory().getHolder() instanceof MenuHolder && ((MenuHolder) e.getPlayer().getOpenInventory().getTopInventory().getHolder()).getBuilder().isLockHand()) { + public void e(PlayerDropItemEvent e) { + if (e.getPlayer().getOpenInventory().getTopInventory().getHolder() instanceof MenuHolder && ((MenuHolder) e.getPlayer().getOpenInventory().getTopInventory().getHolder()).getBuilder().isLockHand() && !e.getItemDrop().hasMetadata("internal-drop")) { e.setCancelled(true); } } @EventHandler - public void onHeld(PlayerItemHeldEvent e) { + public void e(PlayerItemHeldEvent e) { if (e.getPlayer().getOpenInventory().getTopInventory().getHolder() instanceof MenuHolder && ((MenuHolder) e.getPlayer().getOpenInventory().getTopInventory().getHolder()).getBuilder().isLockHand()) { e.setCancelled(true); } diff --git a/src/main/scala/io/izzel/taboolib/util/lite/Vectors.java b/src/main/scala/io/izzel/taboolib/util/lite/Vectors.java index c1e0b67..56abc16 100644 --- a/src/main/scala/io/izzel/taboolib/util/lite/Vectors.java +++ b/src/main/scala/io/izzel/taboolib/util/lite/Vectors.java @@ -15,6 +15,10 @@ import java.util.stream.IntStream; */ public class Vectors { + public static Item itemDrop(Player player, ItemStack itemStack) { + return itemDrop(player, itemStack, 0.0, 0.4); + } + public static Item itemDrop(Player player, ItemStack itemStack, double bulletSpread, double radius) { Location location = player.getLocation().add(0.0D, 1.5D, 0.0D); Item item = player.getWorld().dropItem(location, itemStack);