PlayerKitsF/src/main/java/pk/ajneb97/versions/NMSManager.java
2023-09-30 15:17:09 -03:00

354 lines
20 KiB
Java

package pk.ajneb97.versions;
import org.bukkit.inventory.ItemStack;
import pk.ajneb97.PlayerKits2;
import pk.ajneb97.utils.ServerVersion;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class NMSManager {
private Version version;
private ServerVersion serverVersion;
public NMSManager(){
this.version = new Version();
this.serverVersion = PlayerKits2.serverVersion;
try {
//Classes
version.addClass("CraftItemStack",Class.forName("org.bukkit.craftbukkit."+serverVersion+".inventory.CraftItemStack"));
if(!serverVersionGreaterEqualThan(ServerVersion.v1_13_R1)) {
//1.12 or lower
version.addClass("NBTTagList",Class.forName("net.minecraft.server."+serverVersion+".NBTTagList"));
}
if(serverVersionGreaterEqualThan(ServerVersion.v1_17_R1)){
//1.17 or greater
version.addClass("ItemStackNMS",Class.forName("net.minecraft.world.item.ItemStack"));
version.addClass("NBTTagCompound",Class.forName("net.minecraft.nbt.NBTTagCompound"));
version.addClass("MojangsonParser",Class.forName("net.minecraft.nbt.MojangsonParser"));
version.addClass("NBTBase",Class.forName("net.minecraft.nbt.NBTBase"));
}else{
//1.16 or lower
version.addClass("ItemStackNMS",Class.forName("net.minecraft.server."+serverVersion+".ItemStack"));
version.addClass("NBTTagCompound",Class.forName("net.minecraft.server."+serverVersion+".NBTTagCompound"));
version.addClass("MojangsonParser",Class.forName("net.minecraft.server."+serverVersion+".MojangsonParser"));
version.addClass("NBTBase",Class.forName("net.minecraft.server."+serverVersion+".NBTBase"));
}
//Methods
version.addMethod("asNMSCopy",version.getClassRef("CraftItemStack").getMethod("asNMSCopy",ItemStack.class));
version.addMethod("asBukkitCopy",version.getClassRef("CraftItemStack").getMethod("asBukkitCopy",version.getClassRef("ItemStackNMS")));
if(!serverVersionGreaterEqualThan(ServerVersion.v1_13_R1)){
//1.12 or lower
version.addMethod("getList",version.getClassRef("NBTTagCompound").getMethod("getList",String.class,int.class));
version.addMethod("listSize",version.getClassRef("NBTTagList").getMethod("size"));
version.addMethod("listGet",version.getClassRef("NBTTagList").getMethod("get",int.class));
version.addMethod("listAdd",version.getClassRef("NBTTagList").getMethod("add",version.getClassRef("NBTBase")));
}
if(!serverVersionGreaterEqualThan(ServerVersion.v1_18_R1)){
//1.17 or lower
version.addMethod("hasTag",version.getClassRef("ItemStackNMS").getMethod("hasTag"));
version.addMethod("getTag",version.getClassRef("ItemStackNMS").getMethod("getTag"));
version.addMethod("setTag",version.getClassRef("ItemStackNMS").getMethod("setTag",version.getClassRef("NBTTagCompound")));
version.addMethod("setString",version.getClassRef("NBTTagCompound").getMethod("setString",String.class,String.class));
version.addMethod("setBoolean",version.getClassRef("NBTTagCompound").getMethod("setBoolean",String.class,boolean.class));
version.addMethod("setDouble",version.getClassRef("NBTTagCompound").getMethod("setDouble",String.class,double.class));
version.addMethod("setInt",version.getClassRef("NBTTagCompound").getMethod("setInt",String.class,int.class));
version.addMethod("set",version.getClassRef("NBTTagCompound").getMethod("set",String.class,version.getClassRef("NBTBase")));
version.addMethod("hasKey",version.getClassRef("NBTTagCompound").getMethod("hasKey",String.class));
version.addMethod("getString",version.getClassRef("NBTTagCompound").getMethod("getString",String.class));
version.addMethod("getBoolean",version.getClassRef("NBTTagCompound").getMethod("getBoolean",String.class));
version.addMethod("getInt",version.getClassRef("NBTTagCompound").getMethod("getInt",String.class));
version.addMethod("getDouble",version.getClassRef("NBTTagCompound").getMethod("getDouble",String.class));
version.addMethod("getCompound",version.getClassRef("NBTTagCompound").getMethod("getCompound",String.class));
version.addMethod("get",version.getClassRef("NBTTagCompound").getMethod("get",String.class));
version.addMethod("remove",version.getClassRef("NBTTagCompound").getMethod("remove",String.class));
if(serverVersionGreaterEqualThan(ServerVersion.v1_13_R1)){
version.addMethod("getKeys",version.getClassRef("NBTTagCompound").getMethod("getKeys"));
}else{
version.addMethod("getKeys",version.getClassRef("NBTTagCompound").getMethod("c"));
}
version.addMethod("hasKeyOfType",version.getClassRef("NBTTagCompound").getMethod("hasKeyOfType",String.class,int.class));
version.addMethod("parse",version.getClassRef("MojangsonParser").getMethod("parse",String.class));
}else{
//1.18 or greater
String methodName = null;
switch(serverVersion){
case v1_18_R1: methodName = "r"; break;
case v1_18_R2: methodName = "s"; break;
case v1_19_R1:
case v1_19_R2:
case v1_19_R3: methodName = "t"; break;
case v1_20_R1:
case v1_20_R2: methodName = "u"; break;
}
version.addMethod("hasTag",version.getClassRef("ItemStackNMS").getMethod(methodName));
methodName = null;
switch(serverVersion){
case v1_18_R1: methodName = "s"; break;
case v1_18_R2: methodName = "t"; break;
case v1_19_R1:
case v1_19_R2:
case v1_19_R3: methodName = "u"; break;
case v1_20_R1:
case v1_20_R2: methodName = "v"; break;
}
version.addMethod("getTag",version.getClassRef("ItemStackNMS").getMethod(methodName));
version.addMethod("setTag",version.getClassRef("ItemStackNMS").getMethod("c",version.getClassRef("NBTTagCompound")));
version.addMethod("setString",version.getClassRef("NBTTagCompound").getMethod("a",String.class,String.class));
version.addMethod("setBoolean",version.getClassRef("NBTTagCompound").getMethod("a",String.class,boolean.class));
version.addMethod("setDouble",version.getClassRef("NBTTagCompound").getMethod("a",String.class,double.class));
version.addMethod("setInt",version.getClassRef("NBTTagCompound").getMethod("a",String.class,int.class));
version.addMethod("set",version.getClassRef("NBTTagCompound").getMethod("a",String.class,version.getClassRef("NBTBase")));
version.addMethod("hasKey",version.getClassRef("NBTTagCompound").getMethod("e",String.class));
version.addMethod("getString",version.getClassRef("NBTTagCompound").getMethod("l",String.class));
version.addMethod("getBoolean",version.getClassRef("NBTTagCompound").getMethod("q",String.class));
version.addMethod("getInt",version.getClassRef("NBTTagCompound").getMethod("h",String.class));
version.addMethod("getDouble",version.getClassRef("NBTTagCompound").getMethod("k",String.class));
version.addMethod("getCompound",version.getClassRef("NBTTagCompound").getMethod("p",String.class));
version.addMethod("get",version.getClassRef("NBTTagCompound").getMethod("c",String.class));
version.addMethod("remove",version.getClassRef("NBTTagCompound").getMethod("r",String.class));
methodName = null;
switch(serverVersion){
case v1_18_R1:
case v1_18_R2:
case v1_19_R1: methodName = "d"; break;
case v1_19_R2:
case v1_19_R3:
case v1_20_R1:
case v1_20_R2: methodName = "e"; break;
}
version.addMethod("getKeys",version.getClassRef("NBTTagCompound").getMethod(methodName));
version.addMethod("hasKeyOfType",version.getClassRef("NBTTagCompound").getMethod("b",String.class,int.class));
version.addMethod("parse",version.getClassRef("MojangsonParser").getMethod("a",String.class));
}
} catch (ClassNotFoundException | NoSuchMethodException e) {
e.printStackTrace();
}
}
public ItemStack setTagStringItem(ItemStack item, String key, String value) {
try {
Object newItem = version.getMethodRef("asNMSCopy").invoke(null,item); //ItemStackNMS
Object compound = getNBTCompound(newItem);
version.getMethodRef("setString").invoke(compound,key,value);
version.getMethodRef("setTag").invoke(newItem,compound);
return (ItemStack)version.getMethodRef("asBukkitCopy").invoke(null,newItem);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return item;
}
public String getTagStringItem(ItemStack item,String key) {
try {
Object newItem = version.getMethodRef("asNMSCopy").invoke(null,item); //ItemStackNMS
Object compound = getNBTCompound(newItem);
if((boolean)version.getMethodRef("hasKey").invoke(compound,key)){
return (String)version.getMethodRef("getString").invoke(compound,key);
}
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
public ItemStack removeTagItem(ItemStack item, String key) {
try {
Object newItem = version.getMethodRef("asNMSCopy").invoke(null,item); //ItemStackNMS
Object compound = getNBTCompound(newItem);
version.getMethodRef("remove").invoke(compound,key);
version.getMethodRef("setTag").invoke(newItem,compound);
return (ItemStack)version.getMethodRef("asBukkitCopy").invoke(null,newItem);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return item;
}
public List<String> getNBT(ItemStack item){
List<String> nbtList = new ArrayList<>();
try {
Object newItem = version.getMethodRef("asNMSCopy").invoke(null,item); //ItemStackNMS
if((boolean)version.getMethodRef("hasTag").invoke(newItem,null)){
Object compound = version.getMethodRef("getTag").invoke(newItem,null);
Set<String> tags = (Set<String>) version.getMethodRef("getKeys").invoke(compound,null);
for(String t : tags) {
if(!t.equals("ench") && !t.equals("HideFlags") && !t.equals("display")
&& !t.equals("SkullOwner") && !t.equals("AttributeModifiers")
&& !t.equals("Enchantments") && !t.equals("Damage") && !t.equals("CustomModelData") && !t.equals("Potion")
&& !t.equals("StoredEnchantments") && !t.equals("CustomPotionColor") && !t.equals("CustomPotionEffects") && !t.equals("Fireworks")
&& !t.equals("Explosion")&& !t.equals("pages") && !t.equals("title") && !t.equals("author") && !t.equals("resolved")
&& !t.equals("generation") && !t.equals("Trim")) {
if(t.equals("BlockEntityTag") && !item.getType().name().contains("SHULKER")){
continue;
}
if((boolean)version.getMethodRef("hasKeyOfType").invoke(compound,t,1)) {
//boolean
nbtList.add(t+"|"+version.getMethodRef("getBoolean").invoke(compound,t)+"|boolean");
}else if((boolean)version.getMethodRef("hasKeyOfType").invoke(compound,t,3)) {
//int
nbtList.add(t+"|"+version.getMethodRef("getInt").invoke(compound,t)+"|int");
}else if((boolean)version.getMethodRef("hasKeyOfType").invoke(compound,t,6)) {
//double
nbtList.add(t+"|"+version.getMethodRef("getDouble").invoke(compound,t)+"|double");
}else if((boolean)version.getMethodRef("hasKeyOfType").invoke(compound,t,10)){
//Compound
nbtList.add(t+"|"+version.getMethodRef("getCompound").invoke(compound,t)+"|compound");
}else if((boolean)version.getMethodRef("hasKeyOfType").invoke(compound,t,8)) {
//String
nbtList.add(t+"|"+version.getMethodRef("getString").invoke(compound,t));
}else {
//Other
nbtList.add(t+"|"+version.getMethodRef("get").invoke(compound,t));
}
}
}
}
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return nbtList;
}
public ItemStack setNBT(ItemStack item, List<String> nbtList) {
if(nbtList == null || nbtList.isEmpty()) {
return item;
}
try {
Object newItem = version.getMethodRef("asNMSCopy").invoke(null,item); //ItemStackNMS
Object compound = getNBTCompound(newItem);
for(int i=0;i<nbtList.size();i++) {
String nbt = nbtList.get(i);
String[] sep = nbtList.get(i).split("\\|");
String id = sep[0];
String type = sep[sep.length-1];
if(type.equals("boolean")) {
version.getMethodRef("setBoolean").invoke(compound,sep[0],Boolean.parseBoolean(sep[1]));
}else if(type.equals("double")) {
version.getMethodRef("setDouble").invoke(compound,sep[0],Double.parseDouble(sep[1]));
}else if(type.equals("int")) {
version.getMethodRef("setInt").invoke(compound,sep[0],Integer.parseInt(sep[1]));
}else if(type.equals("compound")) {
String finalNBT = nbt.replace(id+"|", "").replace("|compound", "");
Object compoundNew = version.getMethodRef("parse").invoke(null,finalNBT);
version.getMethodRef("set").invoke(compound,sep[0],compoundNew);
}else {
version.getMethodRef("setString").invoke(compound,sep[0],nbt.replace(id+"|", ""));
}
}
version.getMethodRef("setTag").invoke(newItem,compound);
return (ItemStack)version.getMethodRef("asBukkitCopy").invoke(null,newItem);
}catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException | SecurityException e) {
e.printStackTrace();
}
return null;
}
public List<String> getAttributes(ItemStack item) {
try {
Object newItem = version.getMethodRef("asNMSCopy").invoke(null,item); //ItemStackNMS
if((boolean)version.getMethodRef("hasTag").invoke(newItem,null)) {
Object compound = version.getMethodRef("getTag").invoke(newItem, null);
if((boolean)version.getMethodRef("hasKey").invoke(compound,"AttributeModifiers")){
List<String> attributeList = new ArrayList<>();
Object attributes = version.getMethodRef("getList").invoke(compound,"AttributeModifiers",10); //NBTTagList
for(int i=0;i<(int)version.getMethodRef("listSize").invoke(attributes);i++){
Object compoundI = version.getMethodRef("listGet").invoke(attributes,i);
String attributeName = (String)version.getMethodRef("getString").invoke(compoundI,"AttributeName");
String name = (String)version.getMethodRef("getString").invoke(compoundI,"Name");
double amount = (double)version.getMethodRef("getDouble").invoke(compoundI,"Amount");
int operation = (int)version.getMethodRef("getInt").invoke(compoundI,"Operation");
int uuidLeast = (int)version.getMethodRef("getInt").invoke(compoundI,"UUIDLeast");
int uuidMost = (int)version.getMethodRef("getInt").invoke(compoundI,"UUIDMost");
String all = attributeName+";"+name+";"+amount+";"+operation+";"+uuidLeast+";"+uuidMost;
if((boolean)version.getMethodRef("hasKey").invoke(compoundI,"Slot")) {
all = all+";"+version.getMethodRef("getString").invoke(compoundI,"Slot");
}
attributeList.add(all);
}
return attributeList;
}
}
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
public ItemStack setAttributes(ItemStack item, List<String> attributeList) {
try{
Object newItem = version.getMethodRef("asNMSCopy").invoke(null,item); //ItemStackNMS
Object compound = getNBTCompound(newItem);
Object attributesList = version.getClassRef("NBTTagList").newInstance();
for(int i=0;i<attributeList.size();i++){
Object attributeCompound = version.getClassRef("NBTTagCompound").newInstance();
String[] data = attributeList.get(i).split(";");
String attributeName = data[0];
String name = data[1];
double amount = Double.valueOf(data[2]);
int operation = Integer.valueOf(data[3]);
int uuidLeast = Integer.valueOf(data[4]);
int uuidMost = Integer.valueOf(data[5]);
version.getMethodRef("setString").invoke(attributeCompound,"AttributeName",attributeName);
version.getMethodRef("setString").invoke(attributeCompound,"Name",name);
version.getMethodRef("setDouble").invoke(attributeCompound,"Amount",amount);
version.getMethodRef("setInt").invoke(attributeCompound,"Operation",operation);
version.getMethodRef("setInt").invoke(attributeCompound,"UUIDLeast",uuidLeast);
version.getMethodRef("setInt").invoke(attributeCompound,"UUIDMost",uuidMost);
if(data.length >= 7) {
String slot = data[6];
version.getMethodRef("setString").invoke(attributeCompound,"Slot",slot);
}
version.getMethodRef("listAdd").invoke(attributesList,attributeCompound);
}
version.getMethodRef("set").invoke(compound,"AttributeModifiers",attributesList);
version.getMethodRef("setTag").invoke(newItem,compound);
return (ItemStack)version.getMethodRef("asBukkitCopy").invoke(null,newItem);
} catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
e.printStackTrace();
}
return null;
}
private Object getNBTCompound(Object newItem){
try {
boolean hasTag = (boolean)version.getMethodRef("hasTag").invoke(newItem,null);
Object compound = hasTag ? version.getMethodRef("getTag").invoke(newItem,null) :
version.getClassRef("NBTTagCompound").newInstance();
return compound;
} catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
e.printStackTrace();
}
return null;
}
private boolean serverVersionGreaterEqualThan(ServerVersion version){
return serverVersion.ordinal() >= version.ordinal();
}
}