AsmClassTransformer
This commit is contained in:
		
							
								
								
									
										1
									
								
								.idea/dictionaries/csh20.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1
									
								
								.idea/dictionaries/csh20.xml
									
									
									
										generated
									
									
									
								
							@@ -2,6 +2,7 @@
 | 
			
		||||
  <dictionary name="csh20">
 | 
			
		||||
    <words>
 | 
			
		||||
      <w>autoload</w>
 | 
			
		||||
      <w>craftbukkit</w>
 | 
			
		||||
      <w>mvdw</w>
 | 
			
		||||
      <w>papi</w>
 | 
			
		||||
      <w>sendable</w>
 | 
			
		||||
 
 | 
			
		||||
@@ -66,6 +66,21 @@ public class TConfigInjector {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void reloadConfig(Plugin plugin, Object object) {
 | 
			
		||||
        try {
 | 
			
		||||
            Config config = object.getClass().getAnnotation(Config.class);
 | 
			
		||||
            Validate.notNull(config);
 | 
			
		||||
            File file = new File(plugin.getDataFolder(), config.name());
 | 
			
		||||
            Map<String, Object> map = ConfigUtils.confToMap(ConfigUtils.loadYaml(plugin, file));
 | 
			
		||||
            Object obj = ConfigUtils.mapToObj(map, object);
 | 
			
		||||
            if (!config.readOnly()) saveConfig(plugin, obj);
 | 
			
		||||
        } catch (NullPointerException e) {
 | 
			
		||||
            TLocale.Logger.warn("CONFIG.LOAD-FAIL-NO-ANNOTATION", plugin.toString(), object.getClass().getSimpleName());
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            TLocale.Logger.warn("CONFIG.LOAD-FAIL", plugin.toString(), object.getClass().getSimpleName());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Object unserialize(Plugin plugin, Class<?> clazz) {
 | 
			
		||||
        try {
 | 
			
		||||
            Config config = clazz.getAnnotation(Config.class);
 | 
			
		||||
 
 | 
			
		||||
@@ -72,11 +72,7 @@ public class TDependencyInjector {
 | 
			
		||||
                                    obj,
 | 
			
		||||
                                    object -> {
 | 
			
		||||
                                        try {
 | 
			
		||||
                                            Object newObj = TConfigInjector.loadConfig(plugin, object.getClass());
 | 
			
		||||
                                            for (Field f : newObj.getClass().getDeclaredFields()) {
 | 
			
		||||
                                                f.setAccessible(true);
 | 
			
		||||
                                                f.set(obj, f.get(newObj));
 | 
			
		||||
                                            }
 | 
			
		||||
                                            TConfigInjector.reloadConfig(plugin, object);
 | 
			
		||||
                                            TLocale.Logger.info("CONFIG.RELOAD-SUCCESS", plugin.toString(), config.name());
 | 
			
		||||
                                        } catch (Exception ignored) {
 | 
			
		||||
                                            TLocale.Logger.warn("CONFIG.RELOAD-FAIL", plugin.toString(), config.name());
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										50
									
								
								src/main/java/com/ilummc/tlib/nms/ActionBar.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/main/java/com/ilummc/tlib/nms/ActionBar.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
package com.ilummc.tlib.nms;
 | 
			
		||||
 | 
			
		||||
import com.ilummc.tlib.util.asm.AsmClassTransformer;
 | 
			
		||||
import me.skymc.taboolib.TabooLib;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
public abstract class ActionBar {
 | 
			
		||||
 | 
			
		||||
    private static ActionBar instance;
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
        if (TabooLib.getVerint() > 11100) {
 | 
			
		||||
            instance = (ActionBar) AsmClassTransformer.builder().from(Impl_1_12.class).fromVersion("v1_12_R1")
 | 
			
		||||
                    .toVersion(Bukkit.getServer().getClass().getName().split("\\.")[3]).build().transform();
 | 
			
		||||
        } else {
 | 
			
		||||
            instance = (ActionBar) AsmClassTransformer.builder().from(Impl_1_8.class).fromVersion("v1_8_R3")
 | 
			
		||||
                    .toVersion(Bukkit.getServer().getClass().getName().split("\\.")[3]).build().transform();
 | 
			
		||||
        }
 | 
			
		||||
        System.out.println(instance.getClass());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void sendActionBar(Player player, String text) {
 | 
			
		||||
        instance.send(player, text);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public abstract void send(Player player, String text);
 | 
			
		||||
 | 
			
		||||
    public static class Impl_1_8 extends ActionBar {
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void send(Player player, String text) {
 | 
			
		||||
            net.minecraft.server.v1_8_R3.ChatComponentText component = new net.minecraft.server.v1_8_R3.ChatComponentText(text);
 | 
			
		||||
            net.minecraft.server.v1_8_R3.PacketPlayOutChat packet = new net.minecraft.server.v1_8_R3.PacketPlayOutChat(component, (byte) 2);
 | 
			
		||||
            ((org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class Impl_1_12 extends ActionBar {
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void send(Player player, String text) {
 | 
			
		||||
            net.minecraft.server.v1_12_R1.ChatComponentText component = new net.minecraft.server.v1_12_R1.ChatComponentText(text);
 | 
			
		||||
            net.minecraft.server.v1_12_R1.PacketPlayOutChat packet = new net.minecraft.server.v1_12_R1.PacketPlayOutChat(component,
 | 
			
		||||
                    net.minecraft.server.v1_12_R1.ChatMessageType.a((byte) 2));
 | 
			
		||||
            ((org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -72,6 +72,8 @@ public class TLocaleLoader {
 | 
			
		||||
                    TLocaleInstance localeInstance = new TLocaleInstance(plugin);
 | 
			
		||||
                    localeInstance.load(configuration);
 | 
			
		||||
                    map.put(plugin.getName(), localeInstance);
 | 
			
		||||
                    TLib.getTLib().getLogger().info(Strings.replaceWithOrder(TLib.getTLib().getInternalLang().getString("SUCCESS-LOADING-LANG"),
 | 
			
		||||
                            plugin.getName(), lang, String.valueOf(localeInstance.size())));
 | 
			
		||||
                }
 | 
			
		||||
                File finalFile = file;
 | 
			
		||||
                String finalLang = lang;
 | 
			
		||||
@@ -84,7 +86,6 @@ public class TLocaleLoader {
 | 
			
		||||
                    TLib.getTLib().getLogger().info(Strings.replaceWithOrder(TLib.getTLib().getInternalLang().getString("SUCCESS-LOADING-LANG"),
 | 
			
		||||
                            plugin.getName(), finalLang, String.valueOf(localeInstance.size())));
 | 
			
		||||
                });
 | 
			
		||||
                TLib.getTLib().getLogger().info(Strings.replaceWithOrder(TLib.getTLib().getInternalLang().getString("SUCCESS-LOADING-LANG"), plugin.getName(), lang));
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            TLib.getTLib().getLogger().error(Strings.replaceWithOrder(TLib.getTLib().getInternalLang().getString("ERROR-LOADING-LANG"),
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								src/main/java/com/ilummc/tlib/util/asm/AsmClassLoader.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/main/java/com/ilummc/tlib/util/asm/AsmClassLoader.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
package com.ilummc.tlib.util.asm;
 | 
			
		||||
 | 
			
		||||
public class AsmClassLoader extends ClassLoader {
 | 
			
		||||
 | 
			
		||||
    public AsmClassLoader() {
 | 
			
		||||
        super(AsmClassLoader.class.getClassLoader());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Class<?> createNewClass(String name, byte[] arr) {
 | 
			
		||||
        return defineClass(name, arr, 0, arr.length, AsmClassLoader.class.getProtectionDomain());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,153 @@
 | 
			
		||||
package com.ilummc.tlib.util.asm;
 | 
			
		||||
 | 
			
		||||
public class AsmClassTransformer {
 | 
			
		||||
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.objectweb.asm.*;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.lang.reflect.Constructor;
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.lang.reflect.InvocationTargetException;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
public class AsmClassTransformer extends ClassVisitor implements Opcodes {
 | 
			
		||||
 | 
			
		||||
    private final Class<?> from;
 | 
			
		||||
 | 
			
		||||
    private final String fromVer, toVer;
 | 
			
		||||
 | 
			
		||||
    private final ClassWriter writer;
 | 
			
		||||
 | 
			
		||||
    private String newClassName, prevName;
 | 
			
		||||
 | 
			
		||||
    private AsmClassTransformer(Class<?> from, String fromVer, String toVer, ClassWriter classWriter) {
 | 
			
		||||
        super(Opcodes.ASM6, classWriter);
 | 
			
		||||
        writer = classWriter;
 | 
			
		||||
        this.from = from;
 | 
			
		||||
        this.fromVer = fromVer;
 | 
			
		||||
        this.toVer = toVer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Builder builder() {
 | 
			
		||||
        return new Builder().toVersion(Bukkit.getServer().getClass().getName().split("\\.")[3]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Object transform() {
 | 
			
		||||
        try {
 | 
			
		||||
            ClassReader classReader = new ClassReader(from.getResourceAsStream("/" + from.getName().replace('.', '/') + ".class"));
 | 
			
		||||
            newClassName = from.getName() + "_TabooLibRemap_" + this.hashCode() + "_" + toVer;
 | 
			
		||||
            prevName = from.getName().replace('.', '/');
 | 
			
		||||
            classReader.accept(this, ClassReader.SKIP_DEBUG);
 | 
			
		||||
            Class<?> clazz = new AsmClassLoader().createNewClass(newClassName, writer.toByteArray());
 | 
			
		||||
            Field field = from.getClassLoader().getClass().getDeclaredField("classes");
 | 
			
		||||
            field.setAccessible(true);
 | 
			
		||||
            ((Map<String, Class<?>>) field.get(from.getClassLoader())).put(newClassName, clazz);
 | 
			
		||||
            Constructor<?> constructor = clazz.getDeclaredConstructor();
 | 
			
		||||
            constructor.setAccessible(true);
 | 
			
		||||
            return constructor.newInstance();
 | 
			
		||||
        } catch (IOException | NoSuchFieldException | IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
 | 
			
		||||
        super.visit(version, access, newClassName.replace('.', '/'), replace(signature),
 | 
			
		||||
                prevName, replace(interfaces));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
 | 
			
		||||
        MethodVisitor visitor = super.visitMethod(access, name, replace(descriptor), replace(signature), replace(exceptions));
 | 
			
		||||
        return new AsmMethodTransformer(visitor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
 | 
			
		||||
        return super.visitField(access, name, replace(descriptor), replace(signature), value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void visitInnerClass(String name, String outerName, String innerName, int access) {
 | 
			
		||||
        super.visitInnerClass(replace(name), outerName, replace(name).substring(outerName.length() + 1), access);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String replace(String text) {
 | 
			
		||||
        if (text != null)
 | 
			
		||||
            return text.replace("net/minecraft/server/" + fromVer, "net/minecraft/server/" + toVer)
 | 
			
		||||
                    .replace("org/bukkit/craftbukkit/" + fromVer, "org/bukkit/craftbukkit/" + toVer)
 | 
			
		||||
                    .replace(prevName, newClassName.replace('.', '/'));
 | 
			
		||||
        else return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String[] replace(String[] text) {
 | 
			
		||||
        if (text != null) {
 | 
			
		||||
            for (int i = 0; i < text.length; i++) {
 | 
			
		||||
                text[i] = replace(text[i]);
 | 
			
		||||
            }
 | 
			
		||||
            return text;
 | 
			
		||||
        } else return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class Builder {
 | 
			
		||||
 | 
			
		||||
        private Class<?> from;
 | 
			
		||||
 | 
			
		||||
        private String fromVersion, toVersion;
 | 
			
		||||
 | 
			
		||||
        public Builder from(Class<?> clazz) {
 | 
			
		||||
            this.from = clazz;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Builder fromVersion(String ver) {
 | 
			
		||||
            fromVersion = ver;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Builder toVersion(String ver) {
 | 
			
		||||
            toVersion = ver;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public AsmClassTransformer build() {
 | 
			
		||||
            return new AsmClassTransformer(from, fromVersion, toVersion, new ClassWriter(ClassWriter.COMPUTE_MAXS));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private class AsmMethodTransformer extends MethodVisitor {
 | 
			
		||||
 | 
			
		||||
        AsmMethodTransformer(MethodVisitor visitor) {
 | 
			
		||||
            super(Opcodes.ASM6, visitor);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
 | 
			
		||||
            super.visitMethodInsn(opcode, replace(owner), name, replace(descriptor), isInterface);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void visitLdcInsn(Object value) {
 | 
			
		||||
            if (value instanceof String)
 | 
			
		||||
                super.visitLdcInsn(replace((String) value));
 | 
			
		||||
            else super.visitLdcInsn(value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void visitTypeInsn(int opcode, String type) {
 | 
			
		||||
            super.visitTypeInsn(opcode, replace(type));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void visitFieldInsn(int opcode, String owner, String name, String descriptor) {
 | 
			
		||||
            super.visitFieldInsn(opcode, replace(owner), name, replace(descriptor));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) {
 | 
			
		||||
            super.visitLocalVariable(name, replace(descriptor), replace(signature), start, end, index);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,52 +1,20 @@
 | 
			
		||||
package me.skymc.taboolib.display;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Constructor;
 | 
			
		||||
 | 
			
		||||
import com.ilummc.tlib.nms.ActionBar;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import me.skymc.taboolib.TabooLib;
 | 
			
		||||
import me.skymc.taboolib.nms.NMSUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Bkm016
 | 
			
		||||
 * @since 2018-04-26
 | 
			
		||||
 */
 | 
			
		||||
public class ActionUtils {
 | 
			
		||||
 | 
			
		||||
	private static Class<?> Packet = NMSUtils.getNMSClass("Packet");
 | 
			
		||||
	private static Class<?> ChatComponentText = NMSUtils.getNMSClass("ChatComponentText");
 | 
			
		||||
	private static Class<?> ChatMessageType = NMSUtils.getNMSClass("ChatMessageType");
 | 
			
		||||
	private static Class<?> PacketPlayOutChat = NMSUtils.getNMSClass("PacketPlayOutChat");
 | 
			
		||||
	private static Class<?> IChatBaseComponent = NMSUtils.getNMSClass("IChatBaseComponent");
 | 
			
		||||
	
 | 
			
		||||
    public static void send(Player player, String action) {
 | 
			
		||||
        if (player == null) {
 | 
			
		||||
        if (player == null)
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            Object ab = ChatComponentText.getConstructor(String.class).newInstance(action);
 | 
			
		||||
            Constructor<?> ac = null;
 | 
			
		||||
            Object abPacket = null;
 | 
			
		||||
            if (TabooLib.getVerint() > 11100) {
 | 
			
		||||
            	ac = PacketPlayOutChat.getConstructor(IChatBaseComponent, ChatMessageType);
 | 
			
		||||
            	abPacket = ac.newInstance(ab, ChatMessageType.getMethod("a", Byte.TYPE).invoke(null, (byte) 2));
 | 
			
		||||
            } else {
 | 
			
		||||
            	ac = PacketPlayOutChat.getConstructor(IChatBaseComponent, Byte.TYPE);
 | 
			
		||||
                abPacket = ac.newInstance(ab, (byte) 2);
 | 
			
		||||
            }
 | 
			
		||||
            sendPacket(player, abPacket);
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ignored) {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    private static void sendPacket(Player player, Object packet) {
 | 
			
		||||
        try {
 | 
			
		||||
            Object handle = player.getClass().getMethod("getHandle", new Class[0]).invoke(player);
 | 
			
		||||
            Object playerConnection = handle.getClass().getField("playerConnection").get(handle);
 | 
			
		||||
            playerConnection.getClass().getMethod("sendPacket", Packet).invoke(playerConnection, packet);
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ignored) {
 | 
			
		||||
            ActionBar.sendActionBar(player, action);
 | 
			
		||||
        } catch (Throwable ignored) {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,9 @@
 | 
			
		||||
package me.skymc.taboolib.display;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Constructor;
 | 
			
		||||
import java.lang.reflect.Method;
 | 
			
		||||
 | 
			
		||||
import me.skymc.taboolib.nms.NMSUtils;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import me.skymc.taboolib.nms.NMSUtils;
 | 
			
		||||
import java.lang.reflect.Constructor;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Bkm016
 | 
			
		||||
@@ -13,20 +11,20 @@ import me.skymc.taboolib.nms.NMSUtils;
 | 
			
		||||
 */
 | 
			
		||||
public class TitleUtils {
 | 
			
		||||
 | 
			
		||||
	private static Class<?> Packet = NMSUtils.getNMSClass("Packet");
 | 
			
		||||
	private static Class<?> PacketPlayOutTitle = NMSUtils.getNMSClass("PacketPlayOutTitle");
 | 
			
		||||
	private static Class<?> IChatBaseComponent = NMSUtils.getNMSClass("IChatBaseComponent");
 | 
			
		||||
	private static Class<?> EnumTitleAction = PacketPlayOutTitle.getDeclaredClasses()[0];
 | 
			
		||||
    private static Class<?> Packet = NMSUtils.getNMSClass("Packet");
 | 
			
		||||
    private static Class<?> PacketPlayOutTitle = NMSUtils.getNMSClass("PacketPlayOutTitle");
 | 
			
		||||
    private static Class<?> IChatBaseComponent = NMSUtils.getNMSClass("IChatBaseComponent");
 | 
			
		||||
    private static Class<?> EnumTitleAction = PacketPlayOutTitle.getDeclaredClasses()[0];
 | 
			
		||||
 | 
			
		||||
    public static void sendTitle(Player p, String title, String subtitle, int fadein, int stay, int fadeout) {
 | 
			
		||||
    	sendTitle(p, title, fadein, stay, fadeout, subtitle, fadein, stay, fadeout);
 | 
			
		||||
        sendTitle(p, title, fadein, stay, fadeout, subtitle, fadein, stay, fadeout);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void sendTitle(Player p, String title, int fadeint, int stayt, int fadeoutt, String subtitle, int fadeinst, int stayst, int fadeoutst) {
 | 
			
		||||
    	if (p == null) {
 | 
			
		||||
    		return;
 | 
			
		||||
    	}
 | 
			
		||||
    	try {
 | 
			
		||||
        if (p == null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            if (title != null) {
 | 
			
		||||
                Object times = EnumTitleAction.getField("TIMES").get(null);
 | 
			
		||||
                Object chatTitle = IChatBaseComponent.getDeclaredClasses()[0].getMethod("a", String.class).invoke(null, "{\"text\":\"" + title + "\"}");
 | 
			
		||||
@@ -53,8 +51,7 @@ public class TitleUtils {
 | 
			
		||||
                subtitlePacket = subtitleConstructor.newInstance(times, chatSubtitle, fadeinst, stayst, fadeoutst);
 | 
			
		||||
                sendPacket(p, subtitlePacket);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ignored) {
 | 
			
		||||
        } catch (Exception ignored) {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ package me.skymc.taboolib.fileutils;
 | 
			
		||||
import com.google.common.collect.Maps;
 | 
			
		||||
import com.google.common.io.Files;
 | 
			
		||||
import com.ilummc.tlib.TLib;
 | 
			
		||||
import com.ilummc.tlib.bean.Property;
 | 
			
		||||
import com.ilummc.tlib.util.Ref;
 | 
			
		||||
import org.bukkit.configuration.ConfigurationSection;
 | 
			
		||||
import org.bukkit.configuration.MemoryConfiguration;
 | 
			
		||||
@@ -86,13 +87,20 @@ public class ConfigUtils {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressWarnings("unchecked")
 | 
			
		||||
    public static <T> T mapToObj(Map<String, Object> map, T obj) {
 | 
			
		||||
        Class<?> clazz = obj.getClass();
 | 
			
		||||
        map.forEach((string, value) -> Ref.getFieldBySerializedName(clazz, string).ifPresent(field -> {
 | 
			
		||||
            if (!field.isAccessible())
 | 
			
		||||
                field.setAccessible(true);
 | 
			
		||||
            try {
 | 
			
		||||
                field.set(obj, value);
 | 
			
		||||
                if (Property.class.isAssignableFrom(field.getType())) {
 | 
			
		||||
                    Property<Object> property = (Property) field.get(obj);
 | 
			
		||||
                    if (property != null) property.set(value);
 | 
			
		||||
                    else field.set(obj, Property.of(value));
 | 
			
		||||
                } else {
 | 
			
		||||
                    field.set(obj, value);
 | 
			
		||||
                }
 | 
			
		||||
            } catch (IllegalAccessException ignored) {
 | 
			
		||||
            }
 | 
			
		||||
        }));
 | 
			
		||||
@@ -108,7 +116,9 @@ public class ConfigUtils {
 | 
			
		||||
        for (Field field : Ref.getDeclaredFields(object.getClass(), excludedModifiers, false)) {
 | 
			
		||||
            try {
 | 
			
		||||
                if (!field.isAccessible()) field.setAccessible(true);
 | 
			
		||||
                map.put(Ref.getSerializedName(field), field.get(object));
 | 
			
		||||
                Object obj = field.get(object);
 | 
			
		||||
                if (obj instanceof Property) obj = ((Property) obj).get();
 | 
			
		||||
                map.put(Ref.getSerializedName(field), obj);
 | 
			
		||||
            } catch (IllegalAccessException ignored) {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,22 +1,14 @@
 | 
			
		||||
package me.skymc.taboolib.fileutils;
 | 
			
		||||
 | 
			
		||||
import java.io.BufferedInputStream;
 | 
			
		||||
import java.io.BufferedReader;
 | 
			
		||||
import java.io.ByteArrayOutputStream;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.InputStreamReader;
 | 
			
		||||
import ch.njol.util.Closeable;
 | 
			
		||||
import me.skymc.taboolib.message.MsgUtils;
 | 
			
		||||
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.net.HttpURLConnection;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.net.URLConnection;
 | 
			
		||||
import java.nio.channels.FileChannel;
 | 
			
		||||
 | 
			
		||||
import ch.njol.util.Closeable;
 | 
			
		||||
import me.skymc.taboolib.message.MsgUtils;
 | 
			
		||||
 | 
			
		||||
public class FileUtils {
 | 
			
		||||
	
 | 
			
		||||
	public static String ip() {  
 | 
			
		||||
@@ -248,6 +240,11 @@ public class FileUtils {
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static String getStringFromURL(String url, String def) {
 | 
			
		||||
		String s = getStringFromURL(url, 1024);
 | 
			
		||||
		return s == null ? def : s;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
    /**
 | 
			
		||||
     * 下载文件
 | 
			
		||||
     * 
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,12 @@
 | 
			
		||||
package me.skymc.taboolib.update;
 | 
			
		||||
 | 
			
		||||
import java.util.regex.Matcher;
 | 
			
		||||
import java.util.regex.Pattern;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.scheduler.BukkitRunnable;
 | 
			
		||||
 | 
			
		||||
import com.google.gson.JsonObject;
 | 
			
		||||
import com.google.gson.JsonParser;
 | 
			
		||||
import me.skymc.taboolib.Main;
 | 
			
		||||
import me.skymc.taboolib.TabooLib;
 | 
			
		||||
import me.skymc.taboolib.fileutils.FileUtils;
 | 
			
		||||
import me.skymc.taboolib.message.MsgUtils;
 | 
			
		||||
import org.bukkit.scheduler.BukkitRunnable;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author sky
 | 
			
		||||
@@ -16,6 +14,8 @@ import me.skymc.taboolib.message.MsgUtils;
 | 
			
		||||
 */
 | 
			
		||||
public class UpdateTask {
 | 
			
		||||
 | 
			
		||||
	private static final String API = "https://api.github.com/repos/Bkm016/TabooLib/releases/latest";
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * 检测更新
 | 
			
		||||
	 */
 | 
			
		||||
@@ -27,14 +27,10 @@ public class UpdateTask {
 | 
			
		||||
				if (!Main.getInst().getConfig().getBoolean("UPDATE-CHECK")) {
 | 
			
		||||
					return;
 | 
			
		||||
				}
 | 
			
		||||
				String value = FileUtils.getStringFromURL("https://github.com/Bkm016/TabooLib/releases", 1024);
 | 
			
		||||
				if (value == null) {
 | 
			
		||||
					return;
 | 
			
		||||
				}
 | 
			
		||||
				Pattern pattern = Pattern.compile("<a href=\"/Bkm016/TabooLib/releases/tag/(\\S+)\">");
 | 
			
		||||
				Matcher matcher = pattern.matcher(value);
 | 
			
		||||
				if (matcher.find()) {
 | 
			
		||||
					double newVersion = Double.valueOf(matcher.group(1));
 | 
			
		||||
				String value = FileUtils.getStringFromURL(API, "{}");
 | 
			
		||||
				JsonObject json = new JsonParser().parse(value).getAsJsonObject();
 | 
			
		||||
				if (json.entrySet().size() > 0) {
 | 
			
		||||
					double newVersion = Double.parseDouble(json.get("tag_name").getAsString());
 | 
			
		||||
					if (TabooLib.getPluginVersion() >= newVersion) {
 | 
			
		||||
						MsgUtils.send("插件已是最新版, 无需更新!");
 | 
			
		||||
					}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user