1
0
mirror of https://e.coding.net/circlecloud/BossShop-re.git synced 2025-11-24 21:26:18 +00:00
Files
BossShop-re/src/main/java/cc/util/bossshop/NMSHelper.java
2016-06-25 23:26:56 +08:00

255 lines
12 KiB
Java

package cc.util.bossshop;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
/**
* 一个用于获取NMS类的类
* @author 聪聪
*
*/
public class NMSHelper{
/**
* NMS类
*/
public static final Class<?> clazz_EntityPlayerMP;
public static final Class<?> clazz_EntityPlayer;
public static final Class<?> clazz_NMSItemStack;
public static final Class<?> clazz_NMSWorld;
public static final Class<?> clazz_IInventory;
public static final Class<?> clazz_NBTBase;
public static final Class<?> clazz_NBTTagByte;
public static final Class<?> clazz_NBTTagShort;
public static final Class<?> clazz_NBTTagInt;
public static final Class<?> clazz_NBTTagLong;
public static final Class<?> clazz_NBTTagFloat;
public static final Class<?> clazz_NBTTagDouble;
public static final Class<?> clazz_NBTTagByteArray;
public static final Class<?> clazz_NBTTagString;
public static final Class<?> clazz_NBTTagIntArray;
public static final Class<?> clazz_NBTTagList;
public static final Class<?> clazz_NBTTagCompound;
public static final Method method_CraftItemStack_asNMSCopy;
public static final Method method_CraftItemStack_asCraftMirror;
public static final Method method_CraftPlayer_getHandle;
public static final Method method_NMSItemStack_getTag;
//public static final Method method_NMSItemStack_setTag;//此方法歧义较大不建议启用
public static final Method method_NBTTagCompound_isEmpty;
public static final Method method_NBTTagCompound_clone;
public static final Method method_NBTTagCompound_set;
public static final Method method_NBTTagList_add;
public static final Field field_NBTTagString_value;
public static final Field field_NBTTagByte_value;
public static final Field field_NBTTagShort_value;
public static final Field field_NBTTagInt_value;
public static final Field field_NBTTagFloat_value;
public static final Field field_NBTTagDouble_value;
public static final Field field_NBTTagLong_value;
public static final Field field_NBTTagList_value;
public static final Field field_NBTTagCompound_map;
public static final Field field_NMSItemStack_tag;
/**
* CraftBukkit类
*/
public static final Class<?> clazz_CraftItemStack;
public static final Class<?> clazz_CraftInventory;
public static final Class<?> clazz_CraftPlayer;
static{
String packetPath="";
clazz_CraftItemStack=ClassHelper.getCBTClass("inventory.CraftItemStack");
clazz_CraftInventory=ClassHelper.getCBTClass("inventory.CraftInventory");
Method method_CraftInventory_getInventory=ClassHelper.getMethod(clazz_CraftInventory,"getInventory");
clazz_IInventory=method_CraftInventory_getInventory.getReturnType();
clazz_CraftPlayer=ClassHelper.getCBTClass("entity.CraftPlayer");
method_CraftPlayer_getHandle=ClassHelper.getMethod(clazz_CraftPlayer,"getHandle");
clazz_EntityPlayerMP=method_CraftPlayer_getHandle.getReturnType();
clazz_EntityPlayer=clazz_EntityPlayerMP.getSuperclass();
clazz_NMSWorld=clazz_EntityPlayer.getDeclaredConstructors()[0].getParameterTypes()[0];
//NMS ItemStck
ItemStack tItem=new ItemStack(Material.STONE);
method_CraftItemStack_asNMSCopy=ClassHelper.getMethod(clazz_CraftItemStack,"asNMSCopy",ItemStack.class);
Object tNMSItemStack_mcitem=ClassHelper.invokeStaticMethod(method_CraftItemStack_asNMSCopy,tItem);
clazz_NMSItemStack=tNMSItemStack_mcitem.getClass();
method_NMSItemStack_getTag=ClassHelper.getUnknowMethod(clazz_NMSItemStack,"NBTTagCompound").get(0);
//NBT
clazz_NBTTagCompound=method_NMSItemStack_getTag.getReturnType();
packetPath=NMSHelper.getClassPrefix(clazz_NBTTagCompound.getName());
clazz_NBTBase=ClassHelper.getClass(packetPath+"NBTBase");
clazz_NBTTagByte=ClassHelper.getClass(packetPath+"NBTTagByte");
clazz_NBTTagShort=ClassHelper.getClass(packetPath+"NBTTagShort");
clazz_NBTTagInt=ClassHelper.getClass(packetPath+"NBTTagInt");
clazz_NBTTagLong=ClassHelper.getClass(packetPath+"NBTTagLong");
clazz_NBTTagFloat=ClassHelper.getClass(packetPath+"NBTTagFloat");
clazz_NBTTagDouble=ClassHelper.getClass(packetPath+"NBTTagDouble");
clazz_NBTTagByteArray=ClassHelper.getClass(packetPath+"NBTTagByteArray");
clazz_NBTTagString=ClassHelper.getClass(packetPath+"NBTTagString");
clazz_NBTTagIntArray=ClassHelper.getClass(packetPath+"NBTTagIntArray");
clazz_NBTTagList=ClassHelper.getClass(packetPath+"NBTTagList");
method_NBTTagCompound_isEmpty=ClassHelper.getUnknowMethod(clazz_NBTTagCompound,boolean.class).get(0);
method_NBTTagCompound_clone=ClassHelper.getUnknowMethod(clazz_NBTTagCompound,clazz_NBTBase).get(0);
method_NBTTagCompound_set=ClassHelper.getUnknowMethod(clazz_NBTTagCompound,void.class,new Class<?>[]{String.class,clazz_NBTBase}).get(0);
method_CraftItemStack_asCraftMirror=ClassHelper.getMethod(clazz_CraftItemStack,"asCraftMirror",clazz_NMSItemStack);
method_NBTTagList_add=ClassHelper.getUnknowMethod(clazz_NBTTagList,void.class,clazz_NBTBase).get(0);
field_NBTTagByte_value=ClassHelper.getField(clazz_NBTTagByte,byte.class,-1).get(0);
field_NBTTagShort_value=ClassHelper.getField(clazz_NBTTagShort,short.class,-1).get(0);
field_NBTTagInt_value=ClassHelper.getField(clazz_NBTTagInt,int.class,-1).get(0);
field_NBTTagFloat_value=ClassHelper.getField(clazz_NBTTagFloat,float.class,-1).get(0);
field_NBTTagDouble_value=ClassHelper.getField(clazz_NBTTagDouble,double.class,-1).get(0);
field_NBTTagLong_value=ClassHelper.getField(clazz_NBTTagLong,long.class,-1).get(0);
field_NBTTagString_value=ClassHelper.getField(clazz_NBTTagString,String.class,Modifier.PRIVATE).get(0);
field_NBTTagList_value=ClassHelper.getField(clazz_NBTTagList,List.class,-1).get(0);
field_NBTTagCompound_map=ClassHelper.getField(clazz_NBTTagCompound,Map.class,-1).get(0);
field_NMSItemStack_tag=ClassHelper.getField(clazz_NMSItemStack,clazz_NBTTagCompound,-1).get(0);
}
/**
* 获取类全名的前段字符串
* @param classFullName
* @return
*/
public static String getClassPrefix(String classFullName){
String packetPath="";
int pos=-1;
if((pos=classFullName.lastIndexOf("."))!=-1)
packetPath=classFullName.substring(0,pos+1);
return packetPath;
}
public static Set<String> getNBTFirstDeepNodeList(ItemStack pItem){
Object nbtTag=getNBTTagCompound(pItem);
if(nbtTag==null) return null;
Map<String,Object> tMap=getNBTTagMapFromTag(nbtTag);
Set<String> rSet=new HashSet<>();
for(String skey : tMap.keySet())
rSet.add(skey);
return rSet;
}
/**
* 获取Bukkit物品的NBT标签
* @param pItem Bukkit物品实例
* @return NBTTagCompound实例或者null
*/
public static Object getNBTTagCompound(ItemStack pItem){
Object nmsItem=NMSHelper.getNMSItem(pItem);
if(nmsItem==null) return null;
return ClassHelper.invokeMethod(nmsItem,method_NMSItemStack_getTag);
}
/**
* 获取物品的NBT的的值域Map
* @param pItem 物品,可以为null
* @return 可能为null
*/
public static Map<String,Object> getNBTTagMapFromItem(ItemStack pItem){
return getNBTTagMapFromTag(getNBTTagCompound(pItem));
}
/**
* 获取Bukkit物品对应的MC物品
* @param pItem Bukkit物品实例
* @return NBTTagCompound实例或者null
*/
public static Object getNMSItem(ItemStack pItem){
if(pItem==null||pItem.getType()==Material.AIR) return null;
return ClassHelper.invokeStaticMethod(method_CraftItemStack_asNMSCopy,pItem);
}
/**
* 获取类类型为NBTTagCompound的值域Map
* @param pNBTTagCompound 实例,类型必须为NBTTagCompound,可以为null
* @return 可能为非null
*/
public static Map<String,Object> getNBTTagMapFromTag(Object pNBTTagCompound){
if(pNBTTagCompound==null) return new HashMap<>();
return (Map<String,Object>)ClassHelper.getFieldValue(pNBTTagCompound,field_NBTTagCompound_map);
}
/**
* 从NBTTagCompound实例中移除指定的标签
* @param pNBTTagCompound NBTTagCompound实例
* @param pNBTLabel NBT标签
* @return 移除的值或null
*/
public static Object removeFromNBTTagCompound(Object pNBTTagCompound,String pNBTLabel){
Map<String,Object> tMap=NMSHelper.getNBTTagMapFromTag(pNBTTagCompound);
if(tMap==null) return null;
return tMap.remove(pNBTLabel);
}
/**
* 获取获取物品的Json字符串
*/
public static String getItemJson(ItemStack pItem){
if(pItem==null||pItem.getType()==Material.AIR) return "{}";
String itemJson="{";
itemJson+="id:"+pItem.getTypeId();
itemJson+=",Damage:"+pItem.getDurability();
Object tagNBTTagCompound=getNBTTagCompound(pItem);
if(tagNBTTagCompound!=null) itemJson+=",tag:"+getNBTBaseValue(tagNBTTagCompound);
itemJson+="}";
return itemJson;
}
/**
* 获取NBTBase的子类的Json值
* <p>
* 只对NBTTagString的toString方法重写<br />
* 其他方法不变
* </p>
* @param pNBTBase
* @return json字符串
*/
public static String getNBTBaseValue(Object pNBTBase){
if(pNBTBase==null) return "";
if(NMSHelper.clazz_NBTTagCompound.isInstance(pNBTBase)){
Map<String,Object> tNBTContents=(Map<String,Object>)ClassHelper.getFieldValue(pNBTBase,NMSHelper.field_NBTTagCompound_map);
if(tNBTContents==null||tNBTContents.isEmpty()) return "{}";
String contentJson = "{";
for (String sKey : tNBTContents.keySet()) {
Object tContentNode=tNBTContents.get(sKey);
if(tContentNode==null) continue;
contentJson+=sKey+':'+getNBTBaseValue(tContentNode)+',';
}
if(contentJson.lastIndexOf(",")!=-1)
contentJson=contentJson.substring(0,contentJson.length()-1);
return contentJson + "}";
}else if(NMSHelper.clazz_NBTTagList.isInstance(pNBTBase)){
List<Object> tNBTContents=(List<Object>)ClassHelper.getFieldValue(pNBTBase,NMSHelper.field_NBTTagList_value);
if(tNBTContents==null||tNBTContents.isEmpty()) return "[]";
String contentJson = "[";
int i=0;
for(Object tContentNode : tNBTContents){
if(tContentNode==null) continue;
contentJson+=i+":"+getNBTBaseValue(tContentNode).toString()+',';
i++;
}
if(contentJson.lastIndexOf(",")!=-1)
contentJson=contentJson.substring(0,contentJson.length()-1);
return contentJson+"]";
}else if(NMSHelper.clazz_NBTTagString.isInstance(pNBTBase)){
String value=(String)ClassHelper.getFieldValue(pNBTBase,NMSHelper.field_NBTTagString_value);
value=value.replace("\"","\\\"");
return "\""+value+"\"";
}else return pNBTBase.toString();
}
}