Taboolib 5.0 fully refactored & Not a plugin now.

This commit is contained in:
坏黑
2019-07-06 00:17:54 +08:00
parent dfae3001ef
commit ab3ed6bebe
335 changed files with 4225 additions and 12881 deletions

View File

@@ -0,0 +1,61 @@
package io.izzel.taboolib.module.lite;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.stream.IntStream;
/**
* 我不信 ClassNotFoundException 的邪,自己写了一个发现还是一样。。。
*
* @Author sky
* @Since 2018-09-19 21:17
*/
public class SimpleClassVisitor extends ClassVisitor {
private final SimpleVersionControl simpleVersionControl;
public SimpleClassVisitor(SimpleVersionControl simpleVersionControl, ClassVisitor classVisitor) {
super(Opcodes.ASM5, classVisitor);
this.simpleVersionControl = simpleVersionControl;
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
super.visit(version, access, translate(name), translate(signature), translate(superName), translate(interfaces));
}
@Override
public void visitInnerClass(String name, String outerName, String innerName, int access) {
super.visitInnerClass(translate(name), translate(outerName), translate(innerName), access);
}
@Override
public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
return super.visitField(access, translate(name), translate(descriptor), translate(signature), value instanceof String ? translate((String) value) : value);
}
@Override
public void visitOuterClass(String owner, String name, String descriptor) {
super.visitOuterClass(translate(owner), translate(name), translate(descriptor));
}
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
return new SimpleMethodVisitor(simpleVersionControl, super.visitMethod(access, translate(name), translate(descriptor), translate(signature), translate(exceptions)));
}
private String translate(String target) {
return target == null ? null : simpleVersionControl.replace(target);
}
private String[] translate(String[] target) {
if (target == null) {
return target;
}
IntStream.range(0, target.length).forEach(i -> target[i] = translate(target[i]));
return target;
}
}

View File

@@ -0,0 +1,40 @@
package io.izzel.taboolib.module.lite;
/**
* @Author sky
* @Since 2018-09-25 15:21
*/
public class SimpleCounter {
private int timer;
private int limit;
private boolean ignoredFirst;
private boolean counterFirst;
public SimpleCounter(int limit) {
this(limit, false);
}
public SimpleCounter(int limit, boolean ignoredFirst) {
this.timer = 0;
this.limit = limit;
this.ignoredFirst = ignoredFirst;
this.counterFirst = true;
}
public boolean next() {
if (--timer <= 0) {
timer = limit;
if (ignoredFirst && counterFirst) {
counterFirst = false;
} else {
return true;
}
}
return false;
}
public void reset() {
timer = 0;
}
}

View File

@@ -0,0 +1,78 @@
package io.izzel.taboolib.module.lite;
import com.google.common.collect.Maps;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import java.util.Arrays;
import java.util.Map;
/**
* @Author 坏黑
* @Since 2019-04-25 22:01
*/
public enum SimpleEquip {
HAND(EquipmentSlot.HAND, -1),
OFF_HAND(EquipmentSlot.OFF_HAND, 40),
FEET(EquipmentSlot.FEET, 36),
LEGS(EquipmentSlot.LEGS, 37),
CHEST(EquipmentSlot.CHEST, 38),
HEAD(EquipmentSlot.HEAD, 39);
private EquipmentSlot bukkit;
private int slot;
SimpleEquip(EquipmentSlot bukkit, int slot) {
this.bukkit = bukkit;
this.slot = slot;
}
public void setItem(Player player, ItemStack item) {
if (this != HAND) {
player.getInventory().setItem(slot, item);
} else {
player.setItemInHand(item);
}
}
public ItemStack getItem(Player player) {
if (this != HAND) {
return player.getInventory().getItem(slot);
} else {
return player.getItemInHand();
}
}
public static SimpleEquip fromBukkit(EquipmentSlot bukkit) {
return Arrays.stream(values()).filter(tEquipment -> tEquipment.bukkit == bukkit).findFirst().orElse(null);
}
public static Map<SimpleEquip, ItemStack> getItems(Player player) {
Map<SimpleEquip, ItemStack> map = Maps.newHashMap();
for (SimpleEquip equipment : values()) {
map.put(equipment, equipment.getItem(player));
}
return map;
}
// *********************************
//
// Getter and Setter
//
// *********************************
public EquipmentSlot getBukkit() {
return bukkit;
}
public int getSlot() {
return slot;
}
}

View File

@@ -0,0 +1,101 @@
package io.izzel.taboolib.module.lite;
import io.izzel.taboolib.TabooLib;
import io.izzel.taboolib.Version;
import io.izzel.taboolib.locale.TLocaleLoader;
import io.izzel.taboolib.module.inject.TFunction;
import io.izzel.taboolib.module.nms.NMSHandler;
import io.izzel.taboolib.module.nms.nbt.NBTCompound;
import io.izzel.taboolib.util.Files;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Entity;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SpawnEggMeta;
import org.bukkit.plugin.Plugin;
import java.io.File;
import java.util.Optional;
/**
* @Author 坏黑
* @Since 2019-05-22 1:16
*/
@TFunction(enable = "init")
public class SimpleI18n {
private static FileConfiguration lang;
private static boolean released;
static void init() {
File localeFile = getLocaleFile(TabooLib.getPlugin());
if (localeFile == null) {
lang = new YamlConfiguration();
} else {
lang = Files.load(TabooLib.getPlugin(), localeFile);
}
if (lang.getInt("version") < 3 && !released) {
released = true;
Files.deepDelete(new File(TabooLib.getPlugin().getDataFolder(), "simpleI18n"));
init();
}
}
public static String getCustomName(Entity entity) {
return entity != null ? Optional.ofNullable(entity.getCustomName()).orElse(getName(entity)) : getName(entity);
}
public static String getCustomName(ItemStack item) {
if (item != null) {
ItemMeta itemMeta = item.getItemMeta();
return itemMeta != null && itemMeta.hasDisplayName() ? itemMeta.getDisplayName() : getName(item);
}
return getName(item);
}
public static String getName(Entity entity) {
return entity == null ? "-" : lang.getString(NMSHandler.getHandler().getName(entity).replace(".", "_"), entity.getName());
}
public static String getName(ItemStack item) {
if (item == null) {
return "-";
}
ItemMeta itemMeta = item.getItemMeta();
if (itemMeta instanceof BookMeta && ((BookMeta) itemMeta).getTitle() != null) {
return ((BookMeta) itemMeta).getTitle();
}
if (!Version.isAfter(Version.v1_11)) {
if (item.getType().name().equals("MONSTER_EGG")) {
NBTCompound nbtCompound = NMSHandler.getHandler().loadNBT(item);
if (nbtCompound.containsKey("EntityTag")) {
return lang.getString("item_monsterPlacer_name") + " " + lang.getString("entity_" + nbtCompound.get("EntityTag").asCompound().get("id").asString() + "_name");
}
return lang.getString("item_monsterPlacer_name");
}
} else if (!Version.isAfter(Version.v1_13)) {
if (itemMeta instanceof SpawnEggMeta) {
String spawnEggType = lang.getString("entity_" + ((SpawnEggMeta) itemMeta).getSpawnedType().getEntityClass().getSimpleName().replace(".", "_") + "_name");
if (spawnEggType != null) {
return lang.getString(NMSHandler.getHandler().getName(item).replace(".", "_"), item.getType().name().toLowerCase().replace("_", "")) + " " + spawnEggType;
}
}
}
return lang.getString(NMSHandler.getHandler().getName(item).replace(".", "_"), item.getType().name().toLowerCase().replace("_", ""));
}
private static void releaseLocales(Plugin plugin) {
TLocaleLoader.getLocalePriority().stream().filter(localeName -> !new File("plugins/TabooLib/simpleI18n/" + getVersion() + "/" + localeName + ".yml").exists() && plugin.getResource("simpleI18n/" + getVersion() + "/" + localeName + ".yml") != null).forEach(localeName -> plugin.saveResource("simpleI18n/" + getVersion() + "/" + localeName + ".yml", true));
}
private static File getLocaleFile(Plugin plugin) {
releaseLocales(plugin);
return TLocaleLoader.getLocalePriority().stream().map(localeName -> new File("plugins/TabooLib/simpleI18n/" + getVersion() + "/" + localeName + ".yml")).filter(File::exists).findFirst().orElse(null);
}
private static String getVersion() {
return Version.isAfter(Version.v1_13) ? "high" : "low";
}
}

View File

@@ -0,0 +1,51 @@
package io.izzel.taboolib.module.lite;
import com.google.common.collect.Lists;
import java.util.List;
import java.util.Map;
/**
* @Author sky
* @Since 2018-10-01 16:19
*/
public class SimpleIterator {
private final Object container;
public SimpleIterator(Object container) {
this.container = container;
}
public List<Map.Entry> mapIterator(int start, int end) {
List<Map.Entry> iterator = Lists.newArrayList();
Map container = (Map) this.container;
int loop = 0;
for (Object entry : container.entrySet()) {
if (loop++ >= start) {
if (loop <= end) {
iterator.add((Map.Entry) entry);
} else {
break;
}
}
}
return iterator;
}
public List listIterator(int start, int end) {
List iterator = Lists.newArrayList();
List container = (List) this.container;
int loop = 0;
for (Object entry : container) {
if (loop++ >= start) {
if (loop <= end) {
iterator.add(entry);
} else {
break;
}
}
}
return iterator;
}
}

View File

@@ -0,0 +1,77 @@
package io.izzel.taboolib.module.lite;
import org.objectweb.asm.*;
import java.util.stream.IntStream;
/**
* 我不信 ClassNotFound 的邪,自己写了一个发现还是一样。。。
*
* @Author sky
* @Since 2018-9-19 21:33
*/
public class SimpleMethodVisitor extends MethodVisitor {
private final SimpleVersionControl simpleVersionControl;
public SimpleMethodVisitor(SimpleVersionControl simpleVersionControl, MethodVisitor methodVisitor) {
super(Opcodes.ASM5, methodVisitor);
this.simpleVersionControl = simpleVersionControl;
}
@Override
public void visitParameter(String name, int access) {
super.visitParameter(translate(name), access);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String descriptor) {
super.visitMethodInsn(opcode, translate(owner), translate(name), translate(descriptor));
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
super.visitMethodInsn(opcode, translate(owner), translate(name), translate(descriptor), isInterface);
}
@Override
public void visitLdcInsn(Object value) {
if (value instanceof Type) {
super.visitLdcInsn(Type.getType(translate(((Type) value).getDescriptor())));
} else {
super.visitLdcInsn(value);
}
}
@Override
public void visitTypeInsn(int opcode, String type) {
super.visitTypeInsn(opcode, translate(type));
}
@Override
public void visitFieldInsn(int opcode, String owner, String name, String descriptor) {
super.visitFieldInsn(opcode, translate(owner), translate(name), translate(descriptor));
}
@Override
public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) {
super.visitLocalVariable(translate(name), translate(descriptor), translate(signature), start, end, index);
}
@Override
public void visitInvokeDynamicInsn(String name, String descriptor, Handle bootstrapMethodHandle, Object... bootstrapMethodArguments) {
super.visitInvokeDynamicInsn(translate(name), translate(descriptor), bootstrapMethodHandle, bootstrapMethodArguments);
}
private String translate(String target) {
return target == null ? null : simpleVersionControl.replace(target);
}
private String[] translate(String[] target) {
if (target == null) {
return target;
}
IntStream.range(0, target.length).forEach(i -> target[i] = translate(target[i]));
return target;
}
}

View File

@@ -0,0 +1,133 @@
package io.izzel.taboolib.module.lite;
import com.google.common.collect.Maps;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Map;
/**
* @Author 坏黑
* @Since 2018-10-25 22:51
*/
public class SimpleReflection {
private static Map<String, Map<String, Field>> fieldCached = Maps.newHashMap();
public static boolean isExists(Class<?> nmsClass) {
return fieldCached.containsKey(nmsClass.getName());
}
public static Map<String, Field> getFields(Class<?> nmsClass) {
return fieldCached.getOrDefault(nmsClass.getName(), Maps.newHashMap());
}
public static Field getField(Class<?> nmsClass, String fieldName) {
return fieldCached.getOrDefault(nmsClass.getName(), Maps.newHashMap()).get(fieldName);
}
public static void checkAndSave(Class<?> nmsClass) {
if (!isExists(nmsClass)) {
saveField(nmsClass);
}
}
public static void saveField(Class<?> nmsClass) {
try {
Arrays.stream(nmsClass.getDeclaredFields()).forEach(declaredField -> saveField(nmsClass, declaredField.getName()));
} catch (Exception e) {
e.printStackTrace();
}
}
public static void saveField(Class<?> nmsClass, String fieldName) {
try {
Field declaredField = nmsClass.getDeclaredField(fieldName);
declaredField.setAccessible(true);
fieldCached.computeIfAbsent(nmsClass.getName(), name -> Maps.newHashMap()).put(fieldName, declaredField);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void setFieldValue(Class<?> nmsClass, Object instance, String fieldName, Object value) {
try {
Map<String, Field> fields = fieldCached.get(nmsClass.getName());
if (fields == null) {
return;
}
Field field = fields.get(fieldName);
if (value == null) {
return;
}
field.set(instance, value);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Object getFieldValue(Class<?> nmsClass, Object instance, String fieldName) {
try {
Map<String, Field> fields = fieldCached.get(nmsClass.getName());
if (fields == null) {
return null;
}
Field field = fields.get(fieldName);
if (field == null) {
return null;
}
return field.get(instance);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static <T> T getFieldValue(Class<?> nmsClass, Object instance, String fieldName, T def) {
try {
Map<String, Field> fields = fieldCached.get(nmsClass.getName());
if (fields == null) {
return def;
}
Field field = fields.get(fieldName);
if (field == null) {
return def;
}
return (T) field.get(instance);
} catch (Exception e) {
e.printStackTrace();
}
return def;
}
public static Class getListType(Field field) {
Type genericType = field.getGenericType();
try {
if (ParameterizedType.class.isAssignableFrom(genericType.getClass())) {
for (Type actualTypeArgument : ((ParameterizedType) genericType).getActualTypeArguments()) {
return Class.forName(actualTypeArgument.getTypeName());
}
}
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
public static Class[] getMapType(Field field) {
Class[] mapType = new Class[2];
try {
Type genericType = field.getGenericType();
if (ParameterizedType.class.isAssignableFrom(genericType.getClass())) {
for (Type actualTypeArgument : ((ParameterizedType) genericType).getActualTypeArguments()) {
mapType[mapType[0] == null ? 0 : 1] = Class.forName(actualTypeArgument.getTypeName());
}
}
} catch (Throwable t) {
t.printStackTrace();
}
return mapType[1] == null ? null : mapType ;
}
}

View File

@@ -0,0 +1,156 @@
package io.izzel.taboolib.module.lite;
import com.google.common.collect.Lists;
import io.izzel.taboolib.TabooLib;
import io.izzel.taboolib.Version;
import io.izzel.taboolib.util.Files;
import io.izzel.taboolib.util.asm.AsmClassLoader;
import org.bukkit.plugin.Plugin;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author sky
* @Since 2018-09-19 21:05
*/
public class SimpleVersionControl {
private static Map<String, Class<?>> cacheClasses = new HashMap<>();
private String target;
private String to;
private List<String> from = Lists.newArrayList();
private Plugin plugin;
private boolean useCache;
private boolean useNMS;
SimpleVersionControl() {
useCache = false;
}
public static SimpleVersionControl create() {
return new SimpleVersionControl().to(Version.getBukkitVersion()).plugin(TabooLib.getPlugin());
}
public static SimpleVersionControl create(String toVersion) {
return new SimpleVersionControl().to(toVersion).plugin(TabooLib.getPlugin());
}
public static SimpleVersionControl createSimple(String target, String... from) {
return create().target(target).from(from);
}
public static SimpleVersionControl createNMS(String target) {
return create().target(target).useNMS();
}
/**
* 设置转换类地址写法如me.skymc.taboolib.packet.InternalPacket
*/
public SimpleVersionControl target(String target) {
this.target = target;
return this;
}
/**
* 设置原版本写法如v1_8_R3
*/
public SimpleVersionControl from(String from) {
this.from.add(from.startsWith("v") ? from : "v" + from);
return this;
}
/**
* 设置原版本写法如v1_8_R3, v1_12_R1
*/
public SimpleVersionControl from(String... from) {
Arrays.stream(from).forEach(v -> this.from.add(v.startsWith("v") ? v : "v" + v));
return this;
}
/**
* 设置目标版本
*/
public SimpleVersionControl to(String to) {
this.to = to.startsWith("v") ? to : "v" + to;
return this;
}
/**
* 设置插件,不填默认指向 TabooLib
*/
public SimpleVersionControl plugin(Plugin plugin) {
this.plugin = plugin;
return this;
}
/**
* 转换类将会保存在 TabooLib 中,防止出现 NoClassDefFoundError 异常
*/
public SimpleVersionControl useCache() {
this.useCache = true;
return this;
}
/**
* 自动转换所有使用到的 NMS 或 OBC 方法
*/
public SimpleVersionControl useNMS() {
this.useNMS = true;
return this;
}
public Class<?> translate() throws IOException {
return translate(plugin);
}
public Class<?> translate(Plugin plugin) throws IOException {
if (useCache && cacheClasses.containsKey(target)) {
return cacheClasses.get(target);
}
ClassReader classReader = new ClassReader(Files.getResource(plugin, target.replace(".", "/") + ".class"));
ClassWriter classWriter = new ClassWriter(0);
ClassVisitor classVisitor = new SimpleClassVisitor(this, classWriter);
classReader.accept(classVisitor, ClassReader.EXPAND_FRAMES);
classWriter.visitEnd();
classVisitor.visitEnd();
Class<?> newClass = AsmClassLoader.createNewClass(target, classWriter.toByteArray());
if (useCache) {
cacheClasses.put(target, newClass);
}
return newClass;
}
// *********************************
//
// Getter and Setter
//
// *********************************
public String getTarget() {
return target;
}
public List<String> getFrom() {
return from;
}
public String getTo() {
return to;
}
public String replace(String origin) {
if (useNMS) {
origin = origin.replaceAll("net/minecraft/server/.*?/", "net/minecraft/server/" + to + "/").replaceAll("org/bukkit/craftbukkit/.*?/", "org/bukkit/craftbukkit/" + to + "/");
}
for (String from : from) {
origin = origin.replace("/" + from + "/", "/" + to + "/");
}
return origin;
}
}