update 5.03
This commit is contained in:
		@@ -5,7 +5,7 @@ plugins {
 | 
			
		||||
    id 'com.github.johnrengelman.shadow' version '4.0.4'
 | 
			
		||||
}
 | 
			
		||||
group = 'me.skymc'
 | 
			
		||||
version = '5.02'
 | 
			
		||||
version = '5.03'
 | 
			
		||||
 | 
			
		||||
sourceCompatibility = 1.8
 | 
			
		||||
targetCompatibility = 1.8
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@ public abstract class PluginLoader {
 | 
			
		||||
                // 读取插件类
 | 
			
		||||
                TabooLibLoader.setupClasses(plugin);
 | 
			
		||||
                // 加载插件类
 | 
			
		||||
                TabooLibLoader.getPluginClassSafely(plugin).forEach(c -> TabooLibLoader.preLoadClass(plugin, c));
 | 
			
		||||
                TabooLibLoader.preLoadClass(plugin, TabooLibLoader.getPluginClassSafely(plugin));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
@@ -48,7 +48,7 @@ public abstract class PluginLoader {
 | 
			
		||||
                // 加载监听器
 | 
			
		||||
                TListenerHandler.setupListener(plugin);
 | 
			
		||||
                // 加载插件类
 | 
			
		||||
                TabooLibLoader.getPluginClassSafely(plugin).forEach(c -> TabooLibLoader.postLoadClass(plugin, c));
 | 
			
		||||
                TabooLibLoader.postLoadClass(plugin, TabooLibLoader.getPluginClassSafely(plugin));
 | 
			
		||||
                // 注册插件命令
 | 
			
		||||
                TCommandHandler.registerCommand(plugin);
 | 
			
		||||
            }
 | 
			
		||||
@@ -57,6 +57,8 @@ public abstract class PluginLoader {
 | 
			
		||||
            public void onActivated(Plugin plugin) {
 | 
			
		||||
                // 注册监听器
 | 
			
		||||
                TListenerHandler.registerListener(plugin);
 | 
			
		||||
                // 加载插件类
 | 
			
		||||
                TabooLibLoader.activeLoadClass(plugin, TabooLibLoader.getPluginClassSafely(plugin));
 | 
			
		||||
                // 注册调度器
 | 
			
		||||
                TScheduleLoader.run(plugin);
 | 
			
		||||
            }
 | 
			
		||||
@@ -71,7 +73,7 @@ public abstract class PluginLoader {
 | 
			
		||||
                // 注销监听器
 | 
			
		||||
                TListenerHandler.cancelListener(plugin);
 | 
			
		||||
                // 注销插件类
 | 
			
		||||
                TabooLibLoader.getPluginClassSafely(plugin).forEach(c -> TabooLibLoader.unloadClass(plugin, c));
 | 
			
		||||
                TabooLibLoader.unloadClass(plugin, TabooLibLoader.getPluginClassSafely(plugin));
 | 
			
		||||
                // 释放文检读取
 | 
			
		||||
                Optional.ofNullable(TConfig.getFiles().remove(plugin.getName())).ifPresent(files -> files.forEach(file -> TConfigWatcher.getInst().removeListener(file)));
 | 
			
		||||
                // 注销数据库连接
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,8 @@ public class TabooLibLoader {
 | 
			
		||||
 | 
			
		||||
    static Map<String, List<Class>> pluginClasses = Maps.newHashMap();
 | 
			
		||||
    static List<Loader> loaders = Lists.newArrayList();
 | 
			
		||||
    static List<Runnable> runnables = Lists.newArrayList();
 | 
			
		||||
    static boolean started;
 | 
			
		||||
 | 
			
		||||
    static void init() {
 | 
			
		||||
        // 加载依赖
 | 
			
		||||
@@ -58,6 +60,14 @@ public class TabooLibLoader {
 | 
			
		||||
        return classes == null ? new ArrayList<>() : new ArrayList<>(classes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void runTask(Runnable runnable) {
 | 
			
		||||
        if (started) {
 | 
			
		||||
            runnable.run();
 | 
			
		||||
        } else {
 | 
			
		||||
            runnables.add(runnable);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static boolean isLoader(Class pluginClass) {
 | 
			
		||||
        return !Loader.class.equals(pluginClass) && Loader.class.isAssignableFrom(pluginClass);
 | 
			
		||||
    }
 | 
			
		||||
@@ -71,6 +81,15 @@ public class TabooLibLoader {
 | 
			
		||||
        }
 | 
			
		||||
        // 通讯网络客户端
 | 
			
		||||
        TabooLibClient.init();
 | 
			
		||||
        // 执行动作
 | 
			
		||||
        for (Runnable runnable : runnables) {
 | 
			
		||||
            try {
 | 
			
		||||
                runnable.run();
 | 
			
		||||
            } catch (Throwable t) {
 | 
			
		||||
                t.printStackTrace();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        started = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void setupClasses(Plugin plugin) {
 | 
			
		||||
@@ -92,48 +111,70 @@ public class TabooLibLoader {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void preLoadClass(Plugin plugin, Class<?> loadClass) {
 | 
			
		||||
    static void preLoadClass(Plugin plugin, List<Class> loadClass) {
 | 
			
		||||
        loaders.forEach(loader -> {
 | 
			
		||||
            try {
 | 
			
		||||
                loader.preLoad(plugin, loadClass);
 | 
			
		||||
            } catch (NoClassDefFoundError ignore) {
 | 
			
		||||
            } catch (Throwable e) {
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
            for (Class pluginClass : loadClass) {
 | 
			
		||||
                try {
 | 
			
		||||
                    loader.preLoad(plugin, pluginClass);
 | 
			
		||||
                } catch (NoClassDefFoundError ignore) {
 | 
			
		||||
                } catch (Throwable e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void postLoadClass(Plugin plugin, Class<?> loadClass) {
 | 
			
		||||
    static void postLoadClass(Plugin plugin, List<Class> loadClass) {
 | 
			
		||||
        loaders.forEach(loader -> {
 | 
			
		||||
            try {
 | 
			
		||||
                loader.postLoad(plugin, loadClass);
 | 
			
		||||
            } catch (NoClassDefFoundError ignore) {
 | 
			
		||||
            } catch (Throwable e) {
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
            for (Class pluginClass : loadClass) {
 | 
			
		||||
                try {
 | 
			
		||||
                    loader.postLoad(plugin, pluginClass);
 | 
			
		||||
                } catch (NoClassDefFoundError ignore) {
 | 
			
		||||
                } catch (Throwable e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void unloadClass(Plugin plugin, Class<?> loadClass) {
 | 
			
		||||
    static void activeLoadClass(Plugin plugin, List<Class> loadClass) {
 | 
			
		||||
        loaders.forEach(loader -> {
 | 
			
		||||
            try {
 | 
			
		||||
                loader.unload(plugin, loadClass);
 | 
			
		||||
            } catch (NoClassDefFoundError ignore) {
 | 
			
		||||
            } catch (Throwable e) {
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
            for (Class pluginClass : loadClass) {
 | 
			
		||||
                try {
 | 
			
		||||
                    loader.activeLoad(plugin, pluginClass);
 | 
			
		||||
                } catch (NoClassDefFoundError ignore) {
 | 
			
		||||
                } catch (Throwable e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void unloadClass(Plugin plugin, List<Class> loadClass) {
 | 
			
		||||
        loaders.forEach(loader -> {
 | 
			
		||||
            for (Class pluginClass : loadClass) {
 | 
			
		||||
                try {
 | 
			
		||||
                    loader.unload(plugin, pluginClass);
 | 
			
		||||
                } catch (NoClassDefFoundError ignore) {
 | 
			
		||||
                } catch (Throwable e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public interface Loader {
 | 
			
		||||
 | 
			
		||||
        default void preLoad(org.bukkit.plugin.Plugin plugin, Class<?> loadClass) {
 | 
			
		||||
        default void preLoad(org.bukkit.plugin.Plugin plugin, Class<?> pluginClass) {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        default void postLoad(org.bukkit.plugin.Plugin plugin, Class<?> loadClass) {
 | 
			
		||||
        default void postLoad(org.bukkit.plugin.Plugin plugin, Class<?> pluginClass) {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        default void unload(Plugin plugin, Class<?> cancelClass) {
 | 
			
		||||
        default void activeLoad(org.bukkit.plugin.Plugin plugin, Class<?> pluginClass) {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        default void unload(Plugin plugin, Class<?> pluginClass) {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        default int priority() {
 | 
			
		||||
 
 | 
			
		||||
@@ -66,6 +66,10 @@ public abstract class InternalPluginBridge {
 | 
			
		||||
 | 
			
		||||
    abstract public boolean worldguardHooked();
 | 
			
		||||
 | 
			
		||||
    abstract public boolean isPlaceholderExpansion(Class pluginClass);
 | 
			
		||||
 | 
			
		||||
    abstract public void registerExpansion(Class pluginClass);
 | 
			
		||||
 | 
			
		||||
    abstract public Map<String, Object> taboolibTLocaleSerialize(Object in);
 | 
			
		||||
 | 
			
		||||
    abstract public FileConfiguration taboolibGetPlayerData(String username);
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@ import com.sk89q.worldguard.protection.regions.ProtectedRegion;
 | 
			
		||||
import io.izzel.taboolib.common.plugin.InternalPluginBridge;
 | 
			
		||||
import io.izzel.taboolib.util.Reflection;
 | 
			
		||||
import me.clip.placeholderapi.PlaceholderAPI;
 | 
			
		||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
 | 
			
		||||
import me.skymc.taboolib.database.PlayerDataManager;
 | 
			
		||||
import me.skymc.taboolib.sound.SoundPack;
 | 
			
		||||
import net.milkbowl.vault.economy.Economy;
 | 
			
		||||
@@ -161,6 +162,20 @@ public class BridgeImpl extends InternalPluginBridge {
 | 
			
		||||
        return worldguard;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean isPlaceholderExpansion(Class pluginClass) {
 | 
			
		||||
        return PlaceholderExpansion.class.isAssignableFrom(pluginClass);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void registerExpansion(Class pluginClass) {
 | 
			
		||||
        try {
 | 
			
		||||
            ((PlaceholderExpansion) pluginClass.newInstance()).register();
 | 
			
		||||
        } catch (Throwable t) {
 | 
			
		||||
            t.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Map<String, Object> taboolibTLocaleSerialize(Object in) {
 | 
			
		||||
        switch (in.getClass().getSimpleName()) {
 | 
			
		||||
 
 | 
			
		||||
@@ -30,10 +30,18 @@ public class CronusUtils {
 | 
			
		||||
        return player.getItemInHand().getType() == material ? player.getItemInHand() : player.getInventory().getItemInOffHand();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Object parseInt(double in) {
 | 
			
		||||
        return isInt(in) ? (int) in : in;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean next(int page, int size, int entry) {
 | 
			
		||||
        return size / (double) entry > page + 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean isInt(double in) {
 | 
			
		||||
        return NumberConversions.toInt(in) == in;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean isInt(String in) {
 | 
			
		||||
        try {
 | 
			
		||||
            Integer.parseInt(in);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
package io.izzel.taboolib.cronus.util;
 | 
			
		||||
 | 
			
		||||
import io.izzel.taboolib.cronus.CronusUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author 坏黑
 | 
			
		||||
 * @Since 2019-05-29 21:43
 | 
			
		||||
@@ -23,30 +25,21 @@ public class StringNumber {
 | 
			
		||||
    public StringNumber(String source) {
 | 
			
		||||
        this.source = source;
 | 
			
		||||
        try {
 | 
			
		||||
            number = Long.valueOf(source);
 | 
			
		||||
            type = NumberType.INT;
 | 
			
		||||
            this.number = Double.parseDouble(this.source);
 | 
			
		||||
            this.type = CronusUtils.isInt(this.number.doubleValue()) ? NumberType.INT : NumberType.DOUBLE;
 | 
			
		||||
        } catch (Throwable ignored) {
 | 
			
		||||
            try {
 | 
			
		||||
                number = Double.valueOf(source);
 | 
			
		||||
                type = NumberType.DOUBLE;
 | 
			
		||||
            } catch (Throwable ignored2) {
 | 
			
		||||
                type = NumberType.STRING;
 | 
			
		||||
            }
 | 
			
		||||
            this.type = NumberType.STRING;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public StringNumber add(String v) {
 | 
			
		||||
        StringNumber numberFormat = new StringNumber(v);
 | 
			
		||||
        if (isNumber() && numberFormat.isNumber()) {
 | 
			
		||||
            if (type == NumberType.INT && numberFormat.getType() == NumberType.INT) {
 | 
			
		||||
                number = number.longValue() + numberFormat.getNumber().longValue();
 | 
			
		||||
            } else {
 | 
			
		||||
                number = number.doubleValue() + numberFormat.getNumber().doubleValue();
 | 
			
		||||
                type = NumberType.DOUBLE;
 | 
			
		||||
            }
 | 
			
		||||
            this.number = this.number.doubleValue() + numberFormat.getNumber().doubleValue();
 | 
			
		||||
            this.type = CronusUtils.isInt(this.number.doubleValue()) ? NumberType.INT : NumberType.DOUBLE;
 | 
			
		||||
        } else {
 | 
			
		||||
            source += numberFormat.getSource();
 | 
			
		||||
            type = NumberType.STRING;
 | 
			
		||||
            this.source += numberFormat.getSource();
 | 
			
		||||
            this.type = NumberType.STRING;
 | 
			
		||||
        }
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
@@ -54,39 +47,8 @@ public class StringNumber {
 | 
			
		||||
    public StringNumber subtract(String v) {
 | 
			
		||||
        StringNumber numberFormat = new StringNumber(v);
 | 
			
		||||
        if (isNumber() && numberFormat.isNumber()) {
 | 
			
		||||
            if (type == NumberType.INT && numberFormat.getType() == NumberType.INT) {
 | 
			
		||||
                number = number.longValue() - numberFormat.getNumber().longValue();
 | 
			
		||||
            } else {
 | 
			
		||||
                number = number.doubleValue() - numberFormat.getNumber().doubleValue();
 | 
			
		||||
                type = NumberType.DOUBLE;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public StringNumber multiply(String v) {
 | 
			
		||||
        StringNumber numberFormat = new StringNumber(v);
 | 
			
		||||
        if (isNumber() && numberFormat.isNumber()) {
 | 
			
		||||
            if (type == NumberType.INT && numberFormat.getType() == NumberType.INT) {
 | 
			
		||||
                number = number.longValue() * numberFormat.getNumber().longValue();
 | 
			
		||||
            } else {
 | 
			
		||||
                number = number.doubleValue() * numberFormat.getNumber().doubleValue();
 | 
			
		||||
                type = NumberType.DOUBLE;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public StringNumber division(String v) {
 | 
			
		||||
        StringNumber numberFormat = new StringNumber(v);
 | 
			
		||||
        if (isNumber() && numberFormat.isNumber()) {
 | 
			
		||||
            if (type == NumberType.INT && numberFormat.getType() == NumberType.INT) {
 | 
			
		||||
                number = number.longValue() / numberFormat.getNumber().longValue();
 | 
			
		||||
            } else {
 | 
			
		||||
                number = number.doubleValue() / numberFormat.getNumber().doubleValue();
 | 
			
		||||
                type = NumberType.DOUBLE;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.number = this.number.doubleValue() - numberFormat.getNumber().doubleValue();
 | 
			
		||||
            this.type = CronusUtils.isInt(this.number.doubleValue()) ? NumberType.INT : NumberType.DOUBLE;
 | 
			
		||||
        }
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
@@ -121,7 +83,6 @@ public class StringNumber {
 | 
			
		||||
    public enum NumberType {
 | 
			
		||||
 | 
			
		||||
        DOUBLE, INT, STRING
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -81,6 +81,14 @@ public class TConfig extends YamlConfiguration {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void saveToFile() {
 | 
			
		||||
        try {
 | 
			
		||||
            save(file);
 | 
			
		||||
        } catch (Throwable t) {
 | 
			
		||||
            t.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // *********************************
 | 
			
		||||
    //
 | 
			
		||||
    //        Getter and Setter
 | 
			
		||||
@@ -91,6 +99,10 @@ public class TConfig extends YamlConfiguration {
 | 
			
		||||
        return file;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Runnable getListener() {
 | 
			
		||||
        return runnable;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public TConfig listener(Runnable runnable) {
 | 
			
		||||
        this.runnable = runnable;
 | 
			
		||||
        return this;
 | 
			
		||||
 
 | 
			
		||||
@@ -14,8 +14,8 @@ import java.lang.reflect.Modifier;
 | 
			
		||||
public class LocalLoader implements TabooLibLoader.Loader {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void preLoad(Plugin plugin, Class<?> loadClass) {
 | 
			
		||||
        for (Field field : loadClass.getDeclaredFields()) {
 | 
			
		||||
    public void preLoad(Plugin plugin, Class<?> pluginClass) {
 | 
			
		||||
        for (Field field : pluginClass.getDeclaredFields()) {
 | 
			
		||||
            LocalFile annotation = field.getAnnotation(LocalFile.class);
 | 
			
		||||
            if (annotation == null) {
 | 
			
		||||
                continue;
 | 
			
		||||
@@ -24,10 +24,10 @@ public class LocalLoader implements TabooLibLoader.Loader {
 | 
			
		||||
            // 如果是非静态类型
 | 
			
		||||
            if (!Modifier.isStatic(field.getModifiers())) {
 | 
			
		||||
                // 是否为主类
 | 
			
		||||
                if (loadClass.equals(plugin.getClass())) {
 | 
			
		||||
                if (pluginClass.equals(plugin.getClass())) {
 | 
			
		||||
                    instance = plugin;
 | 
			
		||||
                } else {
 | 
			
		||||
                    TLogger.getGlobalLogger().error(field.getName() + " is not a static field. (" + loadClass.getName() + ")");
 | 
			
		||||
                    TLogger.getGlobalLogger().error(field.getName() + " is not a static field. (" + pluginClass.getName() + ")");
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@ public class PlayerContainerLoader implements Listener, TabooLibLoader.Loader {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void unload(Plugin plugin, Class<?> cancelClass) {
 | 
			
		||||
    public void unload(Plugin plugin, Class<?> pluginClass) {
 | 
			
		||||
        pluginContainer.remove(plugin.getName());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								src/main/scala/io/izzel/taboolib/module/inject/THook.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/main/scala/io/izzel/taboolib/module/inject/THook.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
package io.izzel.taboolib.module.inject;
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.ElementType;
 | 
			
		||||
import java.lang.annotation.Retention;
 | 
			
		||||
import java.lang.annotation.RetentionPolicy;
 | 
			
		||||
import java.lang.annotation.Target;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2018-08-22 13:41
 | 
			
		||||
 */
 | 
			
		||||
@Target(ElementType.TYPE)
 | 
			
		||||
@Retention(RetentionPolicy.RUNTIME)
 | 
			
		||||
public @interface THook {
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,22 @@
 | 
			
		||||
package io.izzel.taboolib.module.inject;
 | 
			
		||||
 | 
			
		||||
import io.izzel.taboolib.TabooLibAPI;
 | 
			
		||||
import io.izzel.taboolib.TabooLibLoader;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2019-08-17 22:32
 | 
			
		||||
 */
 | 
			
		||||
public class THookLoader implements TabooLibLoader.Loader {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void activeLoad(Plugin plugin, Class<?> pluginClass) {
 | 
			
		||||
        if (pluginClass.isAnnotationPresent(THook.class)) {
 | 
			
		||||
            // PlaceholderAPI
 | 
			
		||||
            if (TabooLibAPI.getPluginBridge().placeholderHooked() && TabooLibAPI.getPluginBridge().isPlaceholderExpansion(pluginClass)) {
 | 
			
		||||
                TabooLibAPI.getPluginBridge().registerExpansion(pluginClass);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -15,4 +15,22 @@ public @interface TInject {
 | 
			
		||||
 | 
			
		||||
    String[] value() default {};
 | 
			
		||||
 | 
			
		||||
    String asm() default "";
 | 
			
		||||
 | 
			
		||||
    String load() default "";
 | 
			
		||||
 | 
			
		||||
    String init() default "";
 | 
			
		||||
 | 
			
		||||
    String active() default "";
 | 
			
		||||
 | 
			
		||||
    String cancel() default "";
 | 
			
		||||
 | 
			
		||||
    String reload() default "";
 | 
			
		||||
 | 
			
		||||
    State state() default State.NONE;
 | 
			
		||||
 | 
			
		||||
    enum State {
 | 
			
		||||
 | 
			
		||||
        LOADING, STARTING, ACTIVATED, NONE
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,156 @@
 | 
			
		||||
package io.izzel.taboolib.module.inject;
 | 
			
		||||
 | 
			
		||||
import com.google.common.collect.Maps;
 | 
			
		||||
import io.izzel.taboolib.TabooLibLoader;
 | 
			
		||||
import io.izzel.taboolib.module.locale.logger.TLogger;
 | 
			
		||||
import io.izzel.taboolib.util.Reflection;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.lang.reflect.Modifier;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2019-08-17 22:50
 | 
			
		||||
 */
 | 
			
		||||
public class TInjectCreator implements TabooLibLoader.Loader {
 | 
			
		||||
 | 
			
		||||
    private static Map<ClassData, InstanceData> instanceMap = Maps.newHashMap();
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int priority() {
 | 
			
		||||
        return 999;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void preLoad(Plugin plugin, Class<?> pluginClass) {
 | 
			
		||||
        instance(plugin, pluginClass, TInject.State.LOADING);
 | 
			
		||||
        eval(pluginClass, TInjectHelper.State.PRE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void postLoad(Plugin plugin, Class<?> pluginClass) {
 | 
			
		||||
        instance(plugin, pluginClass, TInject.State.STARTING);
 | 
			
		||||
        eval(pluginClass, TInjectHelper.State.POST);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void activeLoad(Plugin plugin, Class<?> pluginClass) {
 | 
			
		||||
        instance(plugin, pluginClass, TInject.State.ACTIVATED);
 | 
			
		||||
        eval(pluginClass, TInjectHelper.State.ACTIVE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void unload(Plugin plugin, Class<?> pluginClass) {
 | 
			
		||||
        eval(pluginClass, TInjectHelper.State.CANCEL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void instance(Plugin plugin, Class<?> loadClass, TInject.State state) {
 | 
			
		||||
        for (Field declaredField : loadClass.getDeclaredFields()) {
 | 
			
		||||
            TInject annotation = declaredField.getAnnotation(TInject.class);
 | 
			
		||||
            if (annotation == null || annotation.state() != state) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            ClassData classData = new ClassData(loadClass, declaredField.getType());
 | 
			
		||||
            Object instance = null;
 | 
			
		||||
            // 非静态类型
 | 
			
		||||
            if (!Modifier.isStatic(declaredField.getModifiers())) {
 | 
			
		||||
                // 在插件主类
 | 
			
		||||
                if (loadClass.equals(plugin.getClass())) {
 | 
			
		||||
                    instance = plugin;
 | 
			
		||||
                }
 | 
			
		||||
                // 判断 pluginCLass 是否为 TInject 创建
 | 
			
		||||
                else if (instanceMap.containsKey(classData)) {
 | 
			
		||||
                    instance = instanceMap.get(classData).getInstance();
 | 
			
		||||
                } else {
 | 
			
		||||
                    TLogger.getGlobalLogger().error(declaredField.getName() + " is not a static field. (" + loadClass.getName() + ")");
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            declaredField.setAccessible(true);
 | 
			
		||||
            try {
 | 
			
		||||
                InstanceData instanceData = new InstanceData(declaredField.getType().newInstance(), annotation);
 | 
			
		||||
                declaredField.set(instance, instanceData.getInstance());
 | 
			
		||||
                instanceMap.put(classData, instanceData);
 | 
			
		||||
            } catch (Throwable t) {
 | 
			
		||||
                TLogger.getGlobalLogger().error(declaredField.getName() + " instantiation failed: " + t.getMessage());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void eval(Class<?> loadClass, TInjectHelper.State state) {
 | 
			
		||||
        for (Map.Entry<ClassData, InstanceData> entry : instanceMap.entrySet()) {
 | 
			
		||||
            if (entry.getKey().getParent().equals(loadClass) && !TInjectHelper.fromState(entry.getValue().getInject(), state).isEmpty()) {
 | 
			
		||||
                try {
 | 
			
		||||
                    Reflection.invokeMethod(entry.getValue().getInstance(), TInjectHelper.fromState(entry.getValue().getInject(), state));
 | 
			
		||||
                } catch (Throwable t) {
 | 
			
		||||
                    t.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Map<ClassData, InstanceData> getInstanceMap() {
 | 
			
		||||
        return instanceMap;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 用于防止多个类使用同一个类型
 | 
			
		||||
     */
 | 
			
		||||
    public class ClassData {
 | 
			
		||||
 | 
			
		||||
        private Class parent;
 | 
			
		||||
        private Class type;
 | 
			
		||||
 | 
			
		||||
        public ClassData(Class parent, Class type) {
 | 
			
		||||
            this.parent = parent;
 | 
			
		||||
            this.type = type;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Class getParent() {
 | 
			
		||||
            return parent;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Class getType() {
 | 
			
		||||
            return type;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public boolean equals(Object o) {
 | 
			
		||||
            if (this == o) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            if (!(o instanceof ClassData)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            ClassData classData = (ClassData) o;
 | 
			
		||||
            return Objects.equals(getParent(), classData.getParent()) && Objects.equals(getType(), classData.getType());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public int hashCode() {
 | 
			
		||||
            return Objects.hash(getParent(), getType());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class InstanceData {
 | 
			
		||||
 | 
			
		||||
        private Object instance;
 | 
			
		||||
        private TInject inject;
 | 
			
		||||
 | 
			
		||||
        public InstanceData(Object instance, TInject inject) {
 | 
			
		||||
            this.instance = instance;
 | 
			
		||||
            this.inject = inject;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Object getInstance() {
 | 
			
		||||
            return instance;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public TInject getInject() {
 | 
			
		||||
            return inject;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,26 @@
 | 
			
		||||
package io.izzel.taboolib.module.inject;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author sky
 | 
			
		||||
 * @Since 2019-08-17 23:22
 | 
			
		||||
 */
 | 
			
		||||
public class TInjectHelper {
 | 
			
		||||
 | 
			
		||||
    enum State {
 | 
			
		||||
 | 
			
		||||
        PRE, POST, ACTIVE, CANCEL
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String fromState(TInject inject, State state) {
 | 
			
		||||
        switch (state) {
 | 
			
		||||
            case PRE:
 | 
			
		||||
                return inject.load();
 | 
			
		||||
            case POST:
 | 
			
		||||
                return inject.init();
 | 
			
		||||
            case ACTIVE:
 | 
			
		||||
                return inject.active();
 | 
			
		||||
            default:
 | 
			
		||||
                return inject.cancel();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -13,6 +13,7 @@ import io.izzel.taboolib.util.lite.cooldown.Cooldowns;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.lang.reflect.Method;
 | 
			
		||||
import java.lang.reflect.Modifier;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
@@ -26,7 +27,7 @@ public class TInjectLoader implements TabooLibLoader.Loader {
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
        // Instance Inject
 | 
			
		||||
        injectTypes.put(Plugin.class, (plugin, field, args, instance) -> {
 | 
			
		||||
        injectTypes.put(Plugin.class, (plugin, field, args, pluginClass, instance) -> {
 | 
			
		||||
            try {
 | 
			
		||||
                field.set(instance, plugin);
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
@@ -34,15 +35,15 @@ public class TInjectLoader implements TabooLibLoader.Loader {
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        // TLogger Inject
 | 
			
		||||
        injectTypes.put(TLogger.class, (plugin, field, args, instance) -> {
 | 
			
		||||
        injectTypes.put(TLogger.class, (plugin, field, args, pluginClass, instance) -> {
 | 
			
		||||
            try {
 | 
			
		||||
                field.set(instance, args.length == 0 ? TLogger.getUnformatted(plugin) : TLogger.getUnformatted(args[0]));
 | 
			
		||||
                field.set(instance, args.value().length == 0 ? TLogger.getUnformatted(plugin) : TLogger.getUnformatted(args.value()[0]));
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        // TPacketListener Inject
 | 
			
		||||
        injectTypes.put(TPacketListener.class, (plugin, field, args, instance) -> {
 | 
			
		||||
        injectTypes.put(TPacketListener.class, (plugin, field, args, pluginClass, instance) -> {
 | 
			
		||||
            try {
 | 
			
		||||
                TPacketHandler.addListener(plugin, ((TPacketListener) field.get(instance)));
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
@@ -50,20 +51,35 @@ public class TInjectLoader implements TabooLibLoader.Loader {
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        // TConfiguration Inject
 | 
			
		||||
        injectTypes.put(TConfig.class, (plugin, field, args, instance) -> {
 | 
			
		||||
        injectTypes.put(TConfig.class, (plugin, field, args, pluginClass, instance) -> {
 | 
			
		||||
            try {
 | 
			
		||||
                field.set(instance, TConfig.create(plugin, args.length == 0 ? "config.yml" : args[0]));
 | 
			
		||||
                TConfig config = TConfig.create(plugin, args.value().length == 0 ? "config.yml" : args.value()[0]);
 | 
			
		||||
                if (!args.reload().isEmpty()) {
 | 
			
		||||
                    try {
 | 
			
		||||
                        Method declaredMethod = pluginClass.getDeclaredMethod(args.reload());
 | 
			
		||||
                        declaredMethod.setAccessible(true);
 | 
			
		||||
                        config.listener(() -> {
 | 
			
		||||
                            try {
 | 
			
		||||
                                declaredMethod.invoke(null);
 | 
			
		||||
                            } catch (Throwable t) {
 | 
			
		||||
                                t.printStackTrace();
 | 
			
		||||
                            }
 | 
			
		||||
                        });
 | 
			
		||||
                        TabooLibLoader.runTask(config::runListener);
 | 
			
		||||
                    } catch (Throwable t) {
 | 
			
		||||
                        t.printStackTrace();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                field.set(instance, config);
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        // SimpleCommandBuilder Inject
 | 
			
		||||
        injectTypes.put(CommandBuilder.class, (plugin, field, args, instance) -> {
 | 
			
		||||
        injectTypes.put(CommandBuilder.class, (plugin, field, args, pluginClass, instance) -> {
 | 
			
		||||
            try {
 | 
			
		||||
                CommandBuilder builder = (CommandBuilder) field.get(instance);
 | 
			
		||||
                if (builder.isBuild()) {
 | 
			
		||||
                    TLogger.getGlobalLogger().error("Command was registered.  (" + field.getType().getName() + ")");
 | 
			
		||||
                } else {
 | 
			
		||||
                if (!builder.isBuild()) {
 | 
			
		||||
                    if (builder.getPlugin() == null) {
 | 
			
		||||
                        builder.plugin(plugin);
 | 
			
		||||
                    }
 | 
			
		||||
@@ -74,12 +90,12 @@ public class TInjectLoader implements TabooLibLoader.Loader {
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        // CooldownPack Inject
 | 
			
		||||
        injectTypes.put(Cooldown.class, (plugin, field, args, instance) -> {
 | 
			
		||||
           try {
 | 
			
		||||
               Cooldowns.register((Cooldown) field.get(instance), plugin);
 | 
			
		||||
           } catch (Throwable t) {
 | 
			
		||||
               t.printStackTrace();
 | 
			
		||||
           }
 | 
			
		||||
        injectTypes.put(Cooldown.class, (plugin, field, args, pluginClass, instance) -> {
 | 
			
		||||
            try {
 | 
			
		||||
                Cooldowns.register((Cooldown) field.get(instance), plugin);
 | 
			
		||||
            } catch (Throwable t) {
 | 
			
		||||
                t.printStackTrace();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -107,7 +123,7 @@ public class TInjectLoader implements TabooLibLoader.Loader {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            inject(plugin, declaredField, instance, annotation, injectTypes.get(Plugin.class));
 | 
			
		||||
            inject(plugin, declaredField, instance, annotation, injectTypes.get(Plugin.class), pluginClass);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -131,17 +147,17 @@ public class TInjectLoader implements TabooLibLoader.Loader {
 | 
			
		||||
            }
 | 
			
		||||
            TInjectTask tInjectTask = injectTypes.get(declaredField.getType());
 | 
			
		||||
            if (tInjectTask != null) {
 | 
			
		||||
                inject(plugin, declaredField, instance, annotation, tInjectTask);
 | 
			
		||||
            } else {
 | 
			
		||||
                inject(plugin, declaredField, instance, annotation, tInjectTask, pluginClass);
 | 
			
		||||
            } else if (annotation.state() == TInject.State.NONE) {
 | 
			
		||||
                TLogger.getGlobalLogger().error(declaredField.getName() + " is an invalid inject type. (" + pluginClass.getName() + ")");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void inject(Plugin plugin, Field field, Object instance, TInject annotation, TInjectTask injectTask) {
 | 
			
		||||
    public void inject(Plugin plugin, Field field, Object instance, TInject annotation, TInjectTask injectTask, Class pluginClass) {
 | 
			
		||||
        try {
 | 
			
		||||
            field.setAccessible(true);
 | 
			
		||||
            injectTask.run(plugin, field, annotation.value(), instance);
 | 
			
		||||
            injectTask.run(plugin, field, annotation, pluginClass, instance);
 | 
			
		||||
            TabooLibAPI.debug(field.getName() + " injected. (" + field.getType().getName() + ")");
 | 
			
		||||
        } catch (Throwable e) {
 | 
			
		||||
            TLogger.getGlobalLogger().error(field.getName() + " inject failed: " + e.getMessage() + " (" + field.getType().getName() + ")");
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,6 @@ import java.lang.reflect.Field;
 | 
			
		||||
 */
 | 
			
		||||
public interface TInjectTask {
 | 
			
		||||
 | 
			
		||||
    void run(Plugin plugin, Field field, String[] args, Object instance);
 | 
			
		||||
    void run(Plugin plugin, Field field, TInject inject, Class pluginClass, Object instance);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -37,13 +37,13 @@ public class TScheduleLoader implements TabooLibLoader.Loader {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void postLoad(Plugin plugin, Class<?> loadClass) {
 | 
			
		||||
        for (Method method : loadClass.getDeclaredMethods()) {
 | 
			
		||||
    public void postLoad(Plugin plugin, Class<?> pluginClass) {
 | 
			
		||||
        for (Method method : pluginClass.getDeclaredMethods()) {
 | 
			
		||||
            TSchedule annotation = method.getAnnotation(TSchedule.class);
 | 
			
		||||
            if (annotation == null) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            Object instance = loadClass.equals(plugin.getClass()) ? plugin : null;
 | 
			
		||||
            Object instance = pluginClass.equals(plugin.getClass()) ? plugin : null;
 | 
			
		||||
            // 如果是非静态类型
 | 
			
		||||
            if (!Modifier.isStatic(method.getModifiers()) && instance == null) {
 | 
			
		||||
                // 是否为主类
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,7 @@ import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
@@ -27,6 +28,10 @@ public class TLocale {
 | 
			
		||||
        throw new AssertionError();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static String[] toArray(Object... obj) {
 | 
			
		||||
        return Arrays.stream(obj).map(String::valueOf).toArray(String[]::new);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void sendTo(String path, CommandSender sender, String[] args, Class<?> callerClass) {
 | 
			
		||||
        TLocaleLoader.sendTo(Ref.getCallerPlugin(callerClass), path, sender, args);
 | 
			
		||||
    }
 | 
			
		||||
@@ -39,18 +44,40 @@ public class TLocale {
 | 
			
		||||
        return TLocaleLoader.asStringList(Ref.getCallerPlugin(callerClass), path, args);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void sendTo(CommandSender sender, String path, Object... args) {
 | 
			
		||||
        Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, sender, toArray(args), clazz));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void sendTo(CommandSender sender, String path, String... args) {
 | 
			
		||||
        Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, sender, args, clazz));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void sendToConsole(String path, Object... args) {
 | 
			
		||||
        Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, Bukkit.getConsoleSender(), toArray(args), clazz));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void sendToConsole(String path, String... args) {
 | 
			
		||||
        Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, Bukkit.getConsoleSender(), args, clazz));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void broadcast(String path, Object... args) {
 | 
			
		||||
        Ref.getCallerClass(3).ifPresent(clazz -> Bukkit.getOnlinePlayers().forEach(player -> sendTo(path, player, toArray(args), clazz)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void broadcast(String path, String... args) {
 | 
			
		||||
        Ref.getCallerClass(3).ifPresent(clazz -> Bukkit.getOnlinePlayers().forEach(player -> sendTo(path, player, args, clazz)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String asString(String path, Object... args) {
 | 
			
		||||
        try {
 | 
			
		||||
            return asString(path, Ref.getCallerClass(3).orElse(TabooLib.class), toArray(args));
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            TabooLib.getLogger().error(Strings.replaceWithOrder(TabooLib.getInst().getInternal().getString("FETCH-LOCALE-ERROR"), path));
 | 
			
		||||
            TabooLib.getLogger().error(Strings.replaceWithOrder(TabooLib.getInst().getInternal().getString("LOCALE-ERROR-REASON"), e.getMessage()));
 | 
			
		||||
            return "§4<" + path + "§4>";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String asString(String path, String... args) {
 | 
			
		||||
        try {
 | 
			
		||||
            return asString(path, Ref.getCallerClass(3).orElse(TabooLib.class), args);
 | 
			
		||||
@@ -61,10 +88,21 @@ public class TLocale {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static List<String> asStringList(String path, Object... args) {
 | 
			
		||||
        try {
 | 
			
		||||
            return asStringList(path, Ref.getCallerClass(3).orElse(TabooLib.class), toArray(args));
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            TabooLib.getLogger().error(Strings.replaceWithOrder(TabooLib.getInst().getInternal().getString("FETCH-LOCALE-ERROR"), path));
 | 
			
		||||
            TabooLib.getLogger().error(Strings.replaceWithOrder(TabooLib.getInst().getInternal().getString("LOCALE-ERROR-REASON"), e.getMessage()));
 | 
			
		||||
            return Collections.singletonList("§4<" + path + "§4>");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static List<String> asStringList(String path, String... args) {
 | 
			
		||||
        try {
 | 
			
		||||
            return asStringList(path, Ref.getCallerClass(3).orElse(TabooLib.class), args);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            TabooLib.getLogger().error(Strings.replaceWithOrder(TabooLib.getInst().getInternal().getString("FETCH-LOCALE-ERROR"), path));
 | 
			
		||||
            TabooLib.getLogger().error(Strings.replaceWithOrder(TabooLib.getInst().getInternal().getString("LOCALE-ERROR-REASON"), e.getMessage()));
 | 
			
		||||
            return Collections.singletonList("§4<" + path + "§4>");
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1582
									
								
								src/main/scala/io/izzel/taboolib/util/lite/Materials.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1582
									
								
								src/main/scala/io/izzel/taboolib/util/lite/Materials.java
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										86
									
								
								src/main/scala/io/izzel/taboolib/util/lite/Vectors.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								src/main/scala/io/izzel/taboolib/util/lite/Vectors.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
package io.izzel.taboolib.util.lite;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.Location;
 | 
			
		||||
import org.bukkit.entity.Entity;
 | 
			
		||||
import org.bukkit.entity.Item;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
import org.bukkit.util.Vector;
 | 
			
		||||
 | 
			
		||||
import java.util.stream.IntStream;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @Author 坏黑
 | 
			
		||||
 * @Since 2019-07-20 13:42
 | 
			
		||||
 */
 | 
			
		||||
public class Vectors {
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
        double yaw = Math.toRadians((double)(-player.getLocation().getYaw() - 90.0F));
 | 
			
		||||
        double pitch = Math.toRadians((double)(-player.getLocation().getPitch()));
 | 
			
		||||
        double x;
 | 
			
		||||
        double y;
 | 
			
		||||
        double z;
 | 
			
		||||
        if (bulletSpread > 0.0D) {
 | 
			
		||||
            double[] spread = new double[]{1.0D, 1.0D, 1.0D};
 | 
			
		||||
            IntStream.range(0, 3).forEach((t) -> {
 | 
			
		||||
                spread[t] = (Numbers.getRandom().nextDouble() - Numbers.getRandom().nextDouble()) * bulletSpread * 0.1D;
 | 
			
		||||
            });
 | 
			
		||||
            x = Math.cos(pitch) * Math.cos(yaw) + spread[0];
 | 
			
		||||
            y = Math.sin(pitch) + spread[1];
 | 
			
		||||
            z = -Math.sin(yaw) * Math.cos(pitch) + spread[2];
 | 
			
		||||
        } else {
 | 
			
		||||
            x = Math.cos(pitch) * Math.cos(yaw);
 | 
			
		||||
            y = Math.sin(pitch);
 | 
			
		||||
            z = -Math.sin(yaw) * Math.cos(pitch);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Vector dirVel = new Vector(x, y, z);
 | 
			
		||||
        item.setVelocity(dirVel.normalize().multiply(radius));
 | 
			
		||||
        return item;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void entityPush(Entity entity, Location to, double velocity) {
 | 
			
		||||
        Location from = entity.getLocation();
 | 
			
		||||
        Vector test = to.clone().subtract(from).toVector();
 | 
			
		||||
        double elevation = test.getY();
 | 
			
		||||
        Double launchAngle = calculateLaunchAngle(from, to, velocity, elevation, 20.0D);
 | 
			
		||||
        double distance = Math.sqrt(Math.pow(test.getX(), 2.0D) + Math.pow(test.getZ(), 2.0D));
 | 
			
		||||
        if (distance != 0.0D) {
 | 
			
		||||
            if (launchAngle == null) {
 | 
			
		||||
                launchAngle = Math.atan((40.0D * elevation + Math.pow(velocity, 2.0D)) / (40.0D * elevation + 2.0D * Math.pow(velocity, 2.0D)));
 | 
			
		||||
            }
 | 
			
		||||
            double hangTime = calculateHangTime(launchAngle, velocity, elevation, 20.0D);
 | 
			
		||||
            test.setY(Math.tan(launchAngle) * distance);
 | 
			
		||||
            test = normalizeVector(test);
 | 
			
		||||
            Vector noise = Vector.getRandom();
 | 
			
		||||
            noise = noise.multiply(0.1D);
 | 
			
		||||
            test.add(noise);
 | 
			
		||||
            velocity = velocity + 1.188D * Math.pow(hangTime, 2.0D) + (Numbers.getRandom().nextDouble() - 0.8D) / 2.0D;
 | 
			
		||||
            test = test.multiply(velocity / 20.0D);
 | 
			
		||||
            entity.setVelocity(test);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static double calculateHangTime(double launchAngle, double v, double elev, double g) {
 | 
			
		||||
        double a = v * Math.sin(launchAngle);
 | 
			
		||||
        double b = -2.0D * g * elev;
 | 
			
		||||
        return Math.pow(a, 2.0D) + b < 0.0D ? 0.0D : (a + Math.sqrt(Math.pow(a, 2.0D) + b)) / g;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static Vector normalizeVector(Vector victor) {
 | 
			
		||||
        double mag = Math.sqrt(Math.pow(victor.getX(), 2.0D) + Math.pow(victor.getY(), 2.0D) + Math.pow(victor.getZ(), 2.0D));
 | 
			
		||||
        return mag != 0.0D ? victor.multiply(1.0D / mag) : victor.multiply(0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static Double calculateLaunchAngle(Location from, Location to, double v, double elevation, double g) {
 | 
			
		||||
        Vector vector = from.clone().subtract(to).toVector();
 | 
			
		||||
        double distance = Math.sqrt(Math.pow(vector.getX(), 2.0D) + Math.pow(vector.getZ(), 2.0D));
 | 
			
		||||
        double v2 = Math.pow(v, 2.0D);
 | 
			
		||||
        double v4 = Math.pow(v, 4.0D);
 | 
			
		||||
        double check = g * (g * Math.pow(distance, 2.0D) + 2.0D * elevation * v2);
 | 
			
		||||
        return v4 < check ? null : Math.atan((v2 - Math.sqrt(v4 - check)) / (g * distance));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user