fix book tool on 1.14.4
This commit is contained in:
		@@ -36,7 +36,7 @@ public class TInjectAsm implements TabooLibLoader.Loader {
 | 
			
		||||
                declaredField.setAccessible(true);
 | 
			
		||||
                declaredField.set(instance, SimpleVersionControl.createNMS(annotation.asm()).useCache().translate(plugin).newInstance());
 | 
			
		||||
            } catch (Throwable t) {
 | 
			
		||||
                t.printStackTrace();
 | 
			
		||||
                TLogger.getGlobalLogger().warn("Cannot translate class \"" + declaredField.getType().getName() + "\": " + t.getMessage());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,8 @@ public abstract class NMS {
 | 
			
		||||
        return impl;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    abstract public void openBook(Player player, ItemStack book);
 | 
			
		||||
 | 
			
		||||
    abstract public boolean isRunning();
 | 
			
		||||
 | 
			
		||||
    abstract public Object toPacketPlayOutWorldParticles(Particle var1, boolean var2, float var3, float var4, float var5, float var6, float var7, float var8, float var9, int var10, Object var11);
 | 
			
		||||
 
 | 
			
		||||
@@ -9,12 +9,14 @@ import net.minecraft.server.v1_12_R1.ChatMessageType;
 | 
			
		||||
import net.minecraft.server.v1_12_R1.EntityVillager;
 | 
			
		||||
import net.minecraft.server.v1_12_R1.MinecraftServer;
 | 
			
		||||
import net.minecraft.server.v1_12_R1.NBTTagCompound;
 | 
			
		||||
import net.minecraft.server.v1_13_R2.EnumHand;
 | 
			
		||||
import net.minecraft.server.v1_13_R2.IRegistry;
 | 
			
		||||
import net.minecraft.server.v1_8_R3.*;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.Particle;
 | 
			
		||||
import org.bukkit.craftbukkit.v1_12_R1.CraftParticle;
 | 
			
		||||
import org.bukkit.craftbukkit.v1_13_R2.CraftServer;
 | 
			
		||||
import org.bukkit.craftbukkit.v1_13_R2.entity.CraftPlayer;
 | 
			
		||||
import org.bukkit.craftbukkit.v1_13_R2.entity.CraftVillager;
 | 
			
		||||
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack;
 | 
			
		||||
import org.bukkit.entity.Entity;
 | 
			
		||||
@@ -62,6 +64,20 @@ public class NMSImpl extends NMS {
 | 
			
		||||
        SimpleReflection.saveField(MinecraftServer.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void openBook(Player player, ItemStack book) {
 | 
			
		||||
        // 你妈 1.14.3 的 a() 到 1.14.4 的 openBook() 不改 nms 版本号?都是 1_14_R1?神经病吧
 | 
			
		||||
        Object bookItem = org.bukkit.craftbukkit.v1_13_R2.inventory.CraftItemStack.asNMSCopy(book);
 | 
			
		||||
        try {
 | 
			
		||||
            ((CraftPlayer) player).getHandle().a((net.minecraft.server.v1_13_R2.ItemStack) bookItem, EnumHand.MAIN_HAND);
 | 
			
		||||
        } catch (Throwable ignored) {
 | 
			
		||||
            try {
 | 
			
		||||
                ((org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer) player).getHandle().openBook((net.minecraft.server.v1_14_R1.ItemStack) bookItem, net.minecraft.server.v1_14_R1.EnumHand.MAIN_HAND);
 | 
			
		||||
            } catch (Throwable ignored2) {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean isRunning() {
 | 
			
		||||
        return !SimpleReflection.getFieldValue(MinecraftServer.class, ((CraftServer) Bukkit.getServer()).getServer(), "hasStopped", false);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,63 +0,0 @@
 | 
			
		||||
package io.izzel.taboolib.util.book;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.Achievement;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
 | 
			
		||||
import static org.bukkit.Achievement.*;
 | 
			
		||||
 | 
			
		||||
public final class BookAchievement {
 | 
			
		||||
 | 
			
		||||
    private static final HashMap<Achievement, String> achievements = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
        achievements.put(OPEN_INVENTORY, "openInventory");
 | 
			
		||||
        achievements.put(MINE_WOOD, "mineWood");
 | 
			
		||||
        achievements.put(BUILD_WORKBENCH, "buildWorkBench");
 | 
			
		||||
        achievements.put(BUILD_PICKAXE, "buildPickaxe");
 | 
			
		||||
        achievements.put(BUILD_FURNACE, "buildFurnace");
 | 
			
		||||
        achievements.put(ACQUIRE_IRON, "aquireIron");
 | 
			
		||||
        achievements.put(BUILD_HOE, "buildHoe");
 | 
			
		||||
        achievements.put(MAKE_BREAD, "makeBread");
 | 
			
		||||
        achievements.put(BAKE_CAKE, "bakeCake");
 | 
			
		||||
        achievements.put(BUILD_BETTER_PICKAXE, "buildBetterPickaxe");
 | 
			
		||||
        achievements.put(COOK_FISH, "cookFish");
 | 
			
		||||
        achievements.put(ON_A_RAIL, "onARail");
 | 
			
		||||
        achievements.put(BUILD_SWORD, "buildSword");
 | 
			
		||||
        achievements.put(KILL_ENEMY, "killEnemy");
 | 
			
		||||
        achievements.put(KILL_COW, "killCow");
 | 
			
		||||
        achievements.put(FLY_PIG, "flyPig");
 | 
			
		||||
        achievements.put(SNIPE_SKELETON, "snipeSkeleton");
 | 
			
		||||
        achievements.put(GET_DIAMONDS, "diamonds");
 | 
			
		||||
        achievements.put(NETHER_PORTAL, "portal");
 | 
			
		||||
        achievements.put(GHAST_RETURN, "ghast");
 | 
			
		||||
        achievements.put(GET_BLAZE_ROD, "blazerod");
 | 
			
		||||
        achievements.put(BREW_POTION, "potion");
 | 
			
		||||
        achievements.put(END_PORTAL, "thEnd");
 | 
			
		||||
        achievements.put(THE_END, "theEnd2");
 | 
			
		||||
        achievements.put(ENCHANTMENTS, "enchantments");
 | 
			
		||||
        achievements.put(OVERKILL, "overkill");
 | 
			
		||||
        achievements.put(BOOKCASE, "bookacase");
 | 
			
		||||
        achievements.put(EXPLORE_ALL_BIOMES, "exploreAllBiomes");
 | 
			
		||||
        achievements.put(SPAWN_WITHER, "spawnWither");
 | 
			
		||||
        achievements.put(KILL_WITHER, "killWither");
 | 
			
		||||
        achievements.put(FULL_BEACON, "fullBeacon");
 | 
			
		||||
        achievements.put(BREED_COW, "breedCow");
 | 
			
		||||
        achievements.put(DIAMONDS_TO_YOU, "diamondsToYou");
 | 
			
		||||
        achievements.put(OVERPOWERED, "overpowered");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private BookAchievement() {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the json id from the bukkit achievement passed as argument
 | 
			
		||||
     *
 | 
			
		||||
     * @param achievement the achievement
 | 
			
		||||
     * @return the achievement's id or null if not found
 | 
			
		||||
     */
 | 
			
		||||
    public static String toId(Achievement achievement) {
 | 
			
		||||
        return achievements.get(achievement);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								src/main/scala/io/izzel/taboolib/util/book/BookAsm.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/main/scala/io/izzel/taboolib/util/book/BookAsm.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
package io.izzel.taboolib.util.book;
 | 
			
		||||
 | 
			
		||||
import io.izzel.taboolib.module.inject.TInject;
 | 
			
		||||
import io.izzel.taboolib.util.chat.BaseComponent;
 | 
			
		||||
import org.bukkit.inventory.meta.BookMeta;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2019-08-18 16:44
 | 
			
		||||
 */
 | 
			
		||||
public abstract class BookAsm {
 | 
			
		||||
 | 
			
		||||
    @TInject(asm = "io.izzel.taboolib.util.book.BookAsmImpl")
 | 
			
		||||
    private static BookAsm handle;
 | 
			
		||||
 | 
			
		||||
    public static BookAsm getHandle() {
 | 
			
		||||
        return handle;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    abstract public void setPages(BookMeta bookmeta, BaseComponent[]... pages);
 | 
			
		||||
 | 
			
		||||
    abstract public void addPages(BookMeta bookmeta, BaseComponent[]... pages);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								src/main/scala/io/izzel/taboolib/util/book/BookAsmImpl.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/main/scala/io/izzel/taboolib/util/book/BookAsmImpl.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
package io.izzel.taboolib.util.book;
 | 
			
		||||
 | 
			
		||||
import io.izzel.taboolib.util.chat.BaseComponent;
 | 
			
		||||
import io.izzel.taboolib.util.chat.ComponentSerializer;
 | 
			
		||||
import net.minecraft.server.v1_14_R1.IChatBaseComponent;
 | 
			
		||||
import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftMetaBook;
 | 
			
		||||
import org.bukkit.inventory.meta.BookMeta;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2019-08-18 16:46
 | 
			
		||||
 */
 | 
			
		||||
public class BookAsmImpl extends BookAsm {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setPages(BookMeta bookmeta, BaseComponent[]... pages) {
 | 
			
		||||
        ((CraftMetaBook) bookmeta).pages.clear();
 | 
			
		||||
        addPages(bookmeta, pages);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void addPages(BookMeta bookmeta, BaseComponent[]... pages) {
 | 
			
		||||
        for (BaseComponent[] components : pages) {
 | 
			
		||||
            ((CraftMetaBook) bookmeta).pages.add(IChatBaseComponent.ChatSerializer.a(ComponentSerializer.toString(components)));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,45 +1,33 @@
 | 
			
		||||
package io.izzel.taboolib.util.book;
 | 
			
		||||
 | 
			
		||||
import io.izzel.taboolib.module.nms.NMS;
 | 
			
		||||
import io.izzel.taboolib.util.book.builder.BookBuilder;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
 | 
			
		||||
@SuppressWarnings("deprecation")
 | 
			
		||||
public final class BookFormatter {
 | 
			
		||||
/**
 | 
			
		||||
 * @author unknown
 | 
			
		||||
 * @recode 2019-8-18 16:40:16
 | 
			
		||||
 */
 | 
			
		||||
public class BookFormatter {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Opens a book GUI to the player
 | 
			
		||||
     * @param p the player
 | 
			
		||||
     * @param book the book to be opened
 | 
			
		||||
     */
 | 
			
		||||
    public static void forceOpen(Player p, ItemStack book) {
 | 
			
		||||
    	//Close inventory currently
 | 
			
		||||
        p.closeInventory();
 | 
			
		||||
        //Store the previous item
 | 
			
		||||
        ItemStack hand = p.getItemInHand();
 | 
			
		||||
        p.setItemInHand(book);
 | 
			
		||||
 | 
			
		||||
        //Opening the GUI
 | 
			
		||||
        BookReflection.openBook(p, book, false);
 | 
			
		||||
 | 
			
		||||
        //Returning whatever was on hand.
 | 
			
		||||
        p.setItemInHand(hand);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a BookBuilder instance with a written book as the Itemstack's type
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public static BookBuilder writtenBook() {
 | 
			
		||||
        return new BookBuilder(new ItemStack(Material.WRITTEN_BOOK));
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a BookBuilder instance with a written book as the Itemstack's type
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    public static BookBuilder writtenBook(String title, String author) {
 | 
			
		||||
        return new BookBuilder(new ItemStack(Material.WRITTEN_BOOK), title, author);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void forceOpen(Player player, ItemStack book) {
 | 
			
		||||
        ItemStack hand = player.getItemInHand();
 | 
			
		||||
        player.setItemInHand(book);
 | 
			
		||||
        try {
 | 
			
		||||
            NMS.handle().openBook(player, book);
 | 
			
		||||
        } catch (Throwable t) {
 | 
			
		||||
            t.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        player.setItemInHand(hand);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,322 +0,0 @@
 | 
			
		||||
package io.izzel.taboolib.util.book;
 | 
			
		||||
 | 
			
		||||
import io.izzel.taboolib.util.chat.BaseComponent;
 | 
			
		||||
import io.izzel.taboolib.util.chat.TextComponent;
 | 
			
		||||
import io.izzel.taboolib.util.chat.ComponentSerializer;
 | 
			
		||||
import io.izzel.taboolib.module.locale.logger.TLogger;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
import org.bukkit.inventory.meta.BookMeta;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Constructor;
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.lang.reflect.InvocationTargetException;
 | 
			
		||||
import java.lang.reflect.Method;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.regex.Matcher;
 | 
			
		||||
import java.util.regex.Pattern;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The NMS helper for all the Book-API
 | 
			
		||||
 */
 | 
			
		||||
@SuppressWarnings({"ALL", "AliControlFlowStatementWithoutBraces"})
 | 
			
		||||
public final class BookReflection {
 | 
			
		||||
 | 
			
		||||
    private static final String version;
 | 
			
		||||
    private static final boolean doubleHands;
 | 
			
		||||
 | 
			
		||||
    private static final Class<?> craftMetaBookClass;
 | 
			
		||||
    private static final Field craftMetaBookField;
 | 
			
		||||
    private static final Method chatSerializerA;
 | 
			
		||||
 | 
			
		||||
    private static final Method craftPlayerGetHandle;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    This method takes an enum that represents the player's hand only in versions >= 1.9
 | 
			
		||||
    In the other versions it only takes the nms item
 | 
			
		||||
    */
 | 
			
		||||
    private static final Method entityPlayerOpenBook;
 | 
			
		||||
 | 
			
		||||
    // only version >= 1.9
 | 
			
		||||
    private static final Object[] hands;
 | 
			
		||||
 | 
			
		||||
    //Older versions
 | 
			
		||||
    /*private static final Field entityHumanPlayerConnection;
 | 
			
		||||
    private static final Method playerConnectionSendPacket;
 | 
			
		||||
 | 
			
		||||
    private static final Constructor<?> packetPlayOutCustomPayloadConstructor;
 | 
			
		||||
    private static final Constructor<?> packetDataSerializerConstructor;*/
 | 
			
		||||
 | 
			
		||||
    private static final Method nmsItemStackSave;
 | 
			
		||||
    private static final Constructor<?> nbtTagCompoundConstructor;
 | 
			
		||||
 | 
			
		||||
    private static final Method craftItemStackAsNMSCopy;
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
        version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
 | 
			
		||||
        final int major, minor;
 | 
			
		||||
        Pattern pattern = Pattern.compile("v([0-9]+)_([0-9]+)");
 | 
			
		||||
        Matcher m = pattern.matcher(version);
 | 
			
		||||
        if (m.find()) {
 | 
			
		||||
            major = Integer.parseInt(m.group(1));
 | 
			
		||||
            minor = Integer.parseInt(m.group(2));
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new IllegalStateException("Cannot parse version \"" + version + "\", make sure it follows \"v<major>_<minor>...\"");
 | 
			
		||||
        }
 | 
			
		||||
        doubleHands = major <= 1 && minor >= 9;
 | 
			
		||||
        try {
 | 
			
		||||
            craftMetaBookClass = getCraftClass("inventory.CraftMetaBook");
 | 
			
		||||
            craftMetaBookField = craftMetaBookClass.getDeclaredField("pages");
 | 
			
		||||
            craftMetaBookField.setAccessible(true);
 | 
			
		||||
            Class<?> chatSerializer = getNmsClass("IChatBaseComponent$ChatSerializer", false);
 | 
			
		||||
            //noinspection AliControlFlowStatementWithoutBraces
 | 
			
		||||
            if (chatSerializer == null) {
 | 
			
		||||
                chatSerializer = getNmsClass("ChatSerializer");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            chatSerializerA = chatSerializer.getDeclaredMethod("a", String.class);
 | 
			
		||||
 | 
			
		||||
            final Class<?> craftPlayerClass = getCraftClass("entity.CraftPlayer");
 | 
			
		||||
            craftPlayerGetHandle = craftPlayerClass.getMethod("getHandle");
 | 
			
		||||
 | 
			
		||||
            final Class<?> entityPlayerClass = getNmsClass("EntityPlayer");
 | 
			
		||||
            final Class<?> itemStackClass = getNmsClass("ItemStack");
 | 
			
		||||
            if (doubleHands) {
 | 
			
		||||
                final Class<?> enumHandClass = getNmsClass("EnumHand");
 | 
			
		||||
                entityPlayerOpenBook = entityPlayerClass.getMethod("a", itemStackClass, enumHandClass);
 | 
			
		||||
                hands = enumHandClass.getEnumConstants();
 | 
			
		||||
            } else {
 | 
			
		||||
                entityPlayerOpenBook = entityPlayerClass.getMethod("openBook", itemStackClass);
 | 
			
		||||
                hands = null;
 | 
			
		||||
            }
 | 
			
		||||
            //Older versions
 | 
			
		||||
            /*entityHumanPlayerConnection = entityPlayerClass.getField("playerConnection");
 | 
			
		||||
            final Class<?> playerConnectionClass = getNmsClass("PlayerConnection");
 | 
			
		||||
            playerConnectionSendPacket = playerConnectionClass.getMethod("sendPacket", getNmsClass("Packet"));
 | 
			
		||||
 | 
			
		||||
            final Class<?> packetDataSerializerClasss = getNmsClass("PacketDataSerializer");
 | 
			
		||||
            packetPlayOutCustomPayloadConstructor = getNmsClass("PacketPlayOutCustomPayload").getConstructor(String.class, packetDataSerializerClasss);
 | 
			
		||||
            packetDataSerializerConstructor = packetDataSerializerClasss.getConstructor(ByteBuf.class);*/
 | 
			
		||||
 | 
			
		||||
            final Class<?> craftItemStackClass = getCraftClass("inventory.CraftItemStack");
 | 
			
		||||
            craftItemStackAsNMSCopy = craftItemStackClass.getMethod("asNMSCopy", ItemStack.class);
 | 
			
		||||
            Class<?> nmsItemStackClazz = getNmsClass("ItemStack");
 | 
			
		||||
            Class<?> nbtTagCompoundClazz = getNmsClass("NBTTagCompound");
 | 
			
		||||
            nmsItemStackSave = nmsItemStackClazz.getMethod("save", nbtTagCompoundClazz);
 | 
			
		||||
            nbtTagCompoundConstructor = nbtTagCompoundClazz.getConstructor();
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            throw new IllegalStateException("Cannot initiate reflections for " + version, e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the pages of the book to the components json equivalent
 | 
			
		||||
     *
 | 
			
		||||
     * @param meta       the book meta to change
 | 
			
		||||
     * @param components the pages of the book
 | 
			
		||||
     */
 | 
			
		||||
    public static void setPages(BookMeta meta, BaseComponent[]... components) {
 | 
			
		||||
        List<Object> pages = null;
 | 
			
		||||
        try {
 | 
			
		||||
            pages = (List<Object>) craftMetaBookField.get(meta);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            TLogger.getGlobalLogger().error("Error while executing reflections, failed to get bookmeta (version: " + BookReflection.version + ")");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        pages.clear();
 | 
			
		||||
        for (BaseComponent[] c : components) {
 | 
			
		||||
            try {
 | 
			
		||||
                pages.add(chatSerializerA.invoke(null, ComponentSerializer.toString(c)));
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                TLogger.getGlobalLogger().error("Error while executing reflections, submit to developers the following log (version: " + BookReflection.version + ")");
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Append the pages of the book to the components json equivalent
 | 
			
		||||
     *
 | 
			
		||||
     * @param meta       the book meta to change
 | 
			
		||||
     * @param components the pages of the book
 | 
			
		||||
     */
 | 
			
		||||
    public static void addPages(BookMeta meta, BaseComponent[]... components) {
 | 
			
		||||
        List<Object> pages = null;
 | 
			
		||||
        try {
 | 
			
		||||
            pages = (List<Object>) craftMetaBookField.get(meta);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            TLogger.getGlobalLogger().error("Error while executing reflections, failed to get bookmeta (version: " + BookReflection.version + ")");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        for (BaseComponent[] c : components) {
 | 
			
		||||
            try {
 | 
			
		||||
                pages.add(chatSerializerA.invoke(null, ComponentSerializer.toString(c)));
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                TLogger.getGlobalLogger().error("Error while executing reflections, submit to developers the following log (version: " + BookReflection.version + ")");
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Opens the book to a player (the player needs to have the book in one of his hands)
 | 
			
		||||
     *
 | 
			
		||||
     * @param player  the player
 | 
			
		||||
     * @param book    the book to open
 | 
			
		||||
     * @param offHand false if the book is in the right hand, true otherwise
 | 
			
		||||
     */
 | 
			
		||||
    public static void openBook(Player player, ItemStack book, boolean offHand) {
 | 
			
		||||
        //nms(player).openBook(nms(player), nms(book), hand);
 | 
			
		||||
        try {
 | 
			
		||||
            //Older versions:
 | 
			
		||||
            /*playerConnectionSendPacket.invoke(
 | 
			
		||||
                    entityHumanPlayerConnection.get(toNms(player)),
 | 
			
		||||
                    createBookOpenPacket()
 | 
			
		||||
            );*/
 | 
			
		||||
            if (doubleHands) {
 | 
			
		||||
                entityPlayerOpenBook.invoke(
 | 
			
		||||
                        toNms(player),
 | 
			
		||||
                        nmsCopy(book),
 | 
			
		||||
                        hands[offHand ? 1 : 0]
 | 
			
		||||
                );
 | 
			
		||||
            } else {
 | 
			
		||||
                entityPlayerOpenBook.invoke(
 | 
			
		||||
                        toNms(player),
 | 
			
		||||
                        nmsCopy(book)
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            throw new UnsupportedVersionException(e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //Older versions
 | 
			
		||||
    /*public static Object createBookOpenPacket() {
 | 
			
		||||
        //new PacketPlayOutCustomPayload("MC|BOpen", new PacketDataSerializer(Unpooled.buffer())));
 | 
			
		||||
        try {
 | 
			
		||||
            return packetPlayOutCustomPayloadConstructor.newInstance(
 | 
			
		||||
                    "MC|BOpen",
 | 
			
		||||
                    packetDataSerializerConstructor.newInstance(Unpooled.buffer())
 | 
			
		||||
            );
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            throw new UnsupportedVersionException(e);
 | 
			
		||||
        }
 | 
			
		||||
    }*/
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Translates an ItemStack to his Chat-Component equivalent
 | 
			
		||||
     *
 | 
			
		||||
     * @param item the item to be converted
 | 
			
		||||
     * @return a Chat-Component equivalent of the parameter
 | 
			
		||||
     */
 | 
			
		||||
    public static BaseComponent[] itemToComponents(ItemStack item) {
 | 
			
		||||
        return jsonToComponents(itemToJson(item));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Translates a json string to his Chat-Component equivalent
 | 
			
		||||
     *
 | 
			
		||||
     * @param json the json string to be converted
 | 
			
		||||
     * @return a Chat-Component equivalent of the parameter
 | 
			
		||||
     */
 | 
			
		||||
    public static BaseComponent[] jsonToComponents(String json) {
 | 
			
		||||
        return new BaseComponent[]{new TextComponent(json)};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Translates an ItemStack to his json equivalent
 | 
			
		||||
     *
 | 
			
		||||
     * @param item the item to be converted
 | 
			
		||||
     * @return a json equivalent of the parameter
 | 
			
		||||
     */
 | 
			
		||||
    private static String itemToJson(ItemStack item) {
 | 
			
		||||
        try {
 | 
			
		||||
            //net.minecraft.server.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
 | 
			
		||||
            Object nmsItemStack = nmsCopy(item);
 | 
			
		||||
 | 
			
		||||
            //net.minecraft.server.NBTTagCompound compound = new NBTTagCompound();
 | 
			
		||||
            //compound = nmsItemStack.save(compound);
 | 
			
		||||
            Object emptyTag = nbtTagCompoundConstructor.newInstance();
 | 
			
		||||
            Object json = nmsItemStackSave.invoke(nmsItemStack, emptyTag);
 | 
			
		||||
            return json.toString();
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            throw new UnsupportedVersionException(e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the EntityPlayer handled by the argument
 | 
			
		||||
     *
 | 
			
		||||
     * @param player the Player handler
 | 
			
		||||
     * @return the handled class
 | 
			
		||||
     * @throws InvocationTargetException when some problems are found with the reflection
 | 
			
		||||
     * @throws IllegalAccessException    when some problems are found with the reflection
 | 
			
		||||
     */
 | 
			
		||||
    public static Object toNms(Player player) throws InvocationTargetException, IllegalAccessException {
 | 
			
		||||
        return craftPlayerGetHandle.invoke(player);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a NMS copy of the parameter
 | 
			
		||||
     *
 | 
			
		||||
     * @param item the ItemStack to be nms-copied
 | 
			
		||||
     * @return a NMS-ItemStack that is the equivalent of the one passed as argument
 | 
			
		||||
     * @throws InvocationTargetException when some problems are found with the reflection
 | 
			
		||||
     * @throws IllegalAccessException    when some problems are found with the reflection
 | 
			
		||||
     */
 | 
			
		||||
    public static Object nmsCopy(ItemStack item) throws InvocationTargetException, IllegalAccessException {
 | 
			
		||||
        return craftItemStackAsNMSCopy.invoke(null, item);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressWarnings("AliControlFlowStatementWithoutBraces")
 | 
			
		||||
    public static Class<?> getNmsClass(String className, boolean log) {
 | 
			
		||||
        try {
 | 
			
		||||
            return Class.forName("net.minecraft.server." + version + "." + className);
 | 
			
		||||
        } catch (ClassNotFoundException e) {
 | 
			
		||||
            //noinspection AliControlFlowStatementWithoutBraces
 | 
			
		||||
            if (log) {
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
            }
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static Class<?> getCraftClass(String path) {
 | 
			
		||||
        try {
 | 
			
		||||
            return Class.forName("org.bukkit.craftbukkit." + version + "." + path);
 | 
			
		||||
        } catch (ClassNotFoundException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Class<?> getNmsClass(String className) {
 | 
			
		||||
        return getNmsClass(className, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * An error thrown when this NMS-helper class doesn't support the running MC version
 | 
			
		||||
     */
 | 
			
		||||
    public static class UnsupportedVersionException extends RuntimeException {
 | 
			
		||||
        /**
 | 
			
		||||
         * serialVersionUID
 | 
			
		||||
         */
 | 
			
		||||
        private static final long serialVersionUID = 6835583513394319946L;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * The current running version
 | 
			
		||||
         */
 | 
			
		||||
        private final String version = BookReflection.version;
 | 
			
		||||
 | 
			
		||||
        public UnsupportedVersionException(Exception e) {
 | 
			
		||||
            super("Error while executing reflections, submit to developers the following log (version: " + BookReflection.version + ")", e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getVersion() {
 | 
			
		||||
            return version;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +1,9 @@
 | 
			
		||||
package io.izzel.taboolib.util.book.action;
 | 
			
		||||
 | 
			
		||||
import io.izzel.taboolib.module.tellraw.TellrawCreator;
 | 
			
		||||
import io.izzel.taboolib.util.chat.BaseComponent;
 | 
			
		||||
import io.izzel.taboolib.util.chat.HoverEvent;
 | 
			
		||||
import io.izzel.taboolib.util.chat.TextComponent;
 | 
			
		||||
import io.izzel.taboolib.util.book.BookAchievement;
 | 
			
		||||
import io.izzel.taboolib.util.book.BookReflection;
 | 
			
		||||
import org.bukkit.Achievement;
 | 
			
		||||
import org.bukkit.entity.Entity;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
 | 
			
		||||
@@ -55,7 +53,7 @@ public interface HoverAction {
 | 
			
		||||
     * @return a new HoverAction instance
 | 
			
		||||
     */
 | 
			
		||||
    static HoverAction showItem(ItemStack item) {
 | 
			
		||||
        return new SimpleHoverAction(HoverEvent.Action.SHOW_ITEM, io.izzel.taboolib.util.book.BookReflection.itemToComponents(item));
 | 
			
		||||
        return new SimpleHoverAction(HoverEvent.Action.SHOW_ITEM, new TextComponent(TellrawCreator.getAbstractTellraw().getItemComponent(item)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -77,11 +75,7 @@ public interface HoverAction {
 | 
			
		||||
     * @return a new HoverAction instance
 | 
			
		||||
     */
 | 
			
		||||
    static HoverAction showEntity(UUID uuid, String type, String name) {
 | 
			
		||||
        return new SimpleHoverAction(HoverEvent.Action.SHOW_ENTITY,
 | 
			
		||||
                BookReflection.jsonToComponents(
 | 
			
		||||
                        "{id:\"" + uuid + "\",type:\"" + type + "\"name:\"" + name + "\"}"
 | 
			
		||||
                )
 | 
			
		||||
        );
 | 
			
		||||
        return new SimpleHoverAction(HoverEvent.Action.SHOW_ENTITY, new TextComponent("{id:\"" + uuid + "\",type:\"" + type + "\"name:\"" + name + "\"}"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -104,16 +98,6 @@ public interface HoverAction {
 | 
			
		||||
        return new SimpleHoverAction(HoverEvent.Action.SHOW_ACHIEVEMENT, new TextComponent("achievement." + achievementId));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a show_achievement action: when the component is hovered the achievement information will be displayed
 | 
			
		||||
     *
 | 
			
		||||
     * @param achievement the achievement to display
 | 
			
		||||
     * @return a new HoverAction instance
 | 
			
		||||
     */
 | 
			
		||||
    static HoverAction showAchievement(Achievement achievement) {
 | 
			
		||||
        return showAchievement(BookAchievement.toId(achievement));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a show_achievement action: when the component is hovered the statistic information will be displayed
 | 
			
		||||
     *
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
package io.izzel.taboolib.util.book.builder;
 | 
			
		||||
 | 
			
		||||
import io.izzel.taboolib.util.book.BookAsm;
 | 
			
		||||
import io.izzel.taboolib.util.chat.BaseComponent;
 | 
			
		||||
import io.izzel.taboolib.util.book.BookReflection;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
import org.bukkit.inventory.meta.BookMeta;
 | 
			
		||||
 | 
			
		||||
@@ -93,7 +93,7 @@ public class BookBuilder {
 | 
			
		||||
     * @return the BookBuilder's calling instance
 | 
			
		||||
     */
 | 
			
		||||
    public BookBuilder pages(BaseComponent[]... pages) {
 | 
			
		||||
        io.izzel.taboolib.util.book.BookReflection.setPages(meta, pages);
 | 
			
		||||
        BookAsm.getHandle().setPages(meta, pages);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -103,7 +103,7 @@ public class BookBuilder {
 | 
			
		||||
     * @return the BookBuilder's calling instance
 | 
			
		||||
     */
 | 
			
		||||
    public BookBuilder pages(List<BaseComponent[]> pages) {
 | 
			
		||||
        io.izzel.taboolib.util.book.BookReflection.setPages(meta, pages.toArray(new BaseComponent[0][]));
 | 
			
		||||
        BookAsm.getHandle().setPages(meta, pages.toArray(new BaseComponent[0][]));
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
@@ -113,7 +113,7 @@ public class BookBuilder {
 | 
			
		||||
     * @return the BookBuilder's calling instance
 | 
			
		||||
     */
 | 
			
		||||
    public BookBuilder addPages(BaseComponent[]... pages) {
 | 
			
		||||
    	BookReflection.addPages(meta, pages);
 | 
			
		||||
        BookAsm.getHandle().addPages(meta, pages);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -126,13 +126,6 @@ public class BookBuilder {
 | 
			
		||||
        return book;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // *********************************
 | 
			
		||||
    //
 | 
			
		||||
    //        Getter and Setter
 | 
			
		||||
    //
 | 
			
		||||
    // *********************************
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public BookMeta getMeta() {
 | 
			
		||||
        return meta;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -9,11 +9,12 @@ import io.izzel.taboolib.util.chat.TextComponent;
 | 
			
		||||
 * @since 2018-03-08 22:36:58
 | 
			
		||||
 */
 | 
			
		||||
public class PageBuilder {
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
    private BaseComponent[] text = TextComponent.fromLegacyText("");
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a simple black-colored text to the page
 | 
			
		||||
     *
 | 
			
		||||
     * @param text the text to add
 | 
			
		||||
     * @return the PageBuilder's calling instance
 | 
			
		||||
     */
 | 
			
		||||
@@ -24,6 +25,7 @@ public class PageBuilder {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a component to the page
 | 
			
		||||
     *
 | 
			
		||||
     * @param component the component to add
 | 
			
		||||
     * @return the PageBuilder's calling instance
 | 
			
		||||
     */
 | 
			
		||||
@@ -34,6 +36,7 @@ public class PageBuilder {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds one or more components to the page
 | 
			
		||||
     *
 | 
			
		||||
     * @param components the components to add
 | 
			
		||||
     * @return the PageBuilder's calling instance
 | 
			
		||||
     */
 | 
			
		||||
@@ -44,14 +47,16 @@ public class PageBuilder {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a newline to the page (equivalent of adding \n to the previous component)
 | 
			
		||||
     *
 | 
			
		||||
     * @return the PageBuilder's calling instance
 | 
			
		||||
     */
 | 
			
		||||
    public PageBuilder newLine() {
 | 
			
		||||
        return add("\n");
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Another way of newLine(), better resolution (equivalent of adding \n to the previous component)
 | 
			
		||||
     *
 | 
			
		||||
     * @return the PageBuilder's calling instance
 | 
			
		||||
     */
 | 
			
		||||
    public PageBuilder endLine() {
 | 
			
		||||
@@ -60,6 +65,7 @@ public class PageBuilder {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Builds the page
 | 
			
		||||
     *
 | 
			
		||||
     * @return an array of BaseComponents representing the page
 | 
			
		||||
     */
 | 
			
		||||
    public BaseComponent[] build() {
 | 
			
		||||
@@ -68,6 +74,7 @@ public class PageBuilder {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new PageBuilder instance wih the parameter as the initial text
 | 
			
		||||
     *
 | 
			
		||||
     * @param text the initial text of the page
 | 
			
		||||
     * @return a new PageBuilder with the parameter as the initial text
 | 
			
		||||
     */
 | 
			
		||||
@@ -77,6 +84,7 @@ public class PageBuilder {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new PageBuilder instance wih the parameter as the initial component
 | 
			
		||||
     *
 | 
			
		||||
     * @param text the initial component of the page
 | 
			
		||||
     * @return a new PageBuilder with the parameter as the initial component
 | 
			
		||||
     */
 | 
			
		||||
@@ -86,12 +94,13 @@ public class PageBuilder {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new PageBuilder instance wih the parameter as the initial components
 | 
			
		||||
     *
 | 
			
		||||
     * @param text the initial components of the page
 | 
			
		||||
     * @return a new PageBuilder with the parameter as the initial components
 | 
			
		||||
     */
 | 
			
		||||
    public static PageBuilder of(BaseComponent... text) {
 | 
			
		||||
        PageBuilder res = new PageBuilder();
 | 
			
		||||
        for(BaseComponent b : text) {
 | 
			
		||||
        for (BaseComponent b : text) {
 | 
			
		||||
            res.add(b);
 | 
			
		||||
        }
 | 
			
		||||
        return res;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user