mirror of
https://e.coding.net/circlecloud/BossShop-re.git
synced 2025-11-24 21:26:18 +00:00
255 lines
12 KiB
Java
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();
|
|
}
|
|
|
|
}
|