LibsDisguises/plugin/src/main/java/me/libraryaddict/disguise/utilities/reflection/ClassMappings.java

158 lines
6.3 KiB
Java

package me.libraryaddict.disguise.utilities.reflection;
import me.libraryaddict.disguise.LibsDisguises;
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
import org.bukkit.Bukkit;
import org.bukkit.scheduler.BukkitRunnable;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class ClassMappings {
private static final HashMap<String, String> classLocations = new HashMap<>();
private static final String[] packages = getPackages();
private static boolean updatingCache = false;
public static String getClass(String packageHint, String className) {
String key = packageHint + "." + className;
String location = classLocations.get(key);
if (location != null) {
return location;
}
location = "???";
for (String pack : packages) {
if (!pack.startsWith(packageHint)) {
continue;
}
String toTry = pack + "." + className;
try {
Class.forName(toTry);
location = toTry;
break;
} catch (Throwable ignored) {
}
}
classLocations.put(key, location);
synchronized (classLocations) {
if (!updatingCache && LibsDisguises.getInstance() != null && LibsDisguises.getInstance().isEnabled()) {
// Run 10 seconds later
updatingCache = true;
new BukkitRunnable() {
@Override
public void run() {
ClassMappings.saveMappingsCache(LibsDisguises.getInstance().getDataFolder());
}
}.runTaskLater(LibsDisguises.getInstance(), 10 * 20);
}
}
return location;
}
private static String[] getPackages() {
String[] s = {"net.minecraft.server.$version$", "net.minecraft.core", "net.minecraft.core.particles", "net.minecraft.nbt",
"net.minecraft.network.chat", "net.minecraft.network.protocol.game", "net.minecraft.network.syncher", "net.minecraft.resources",
"net.minecraft.server.level", "net.minecraft.server", "net.minecraft.server.network", "net.minecraft.sounds",
"net.minecraft.world.damagesource", "net.minecraft.world.effect", "net.minecraft.world.entity.ambient",
"net.minecraft.world.entity.animal.axolotl", "net.minecraft.world.entity.animal", "net.minecraft.world.entity.animal.goat",
"net.minecraft.world.entity.animal.horse", "net.minecraft.world.entity.boss.enderdragon",
"net.minecraft.world.entity.boss.wither", "net.minecraft.world.entity.decoration", "net.minecraft.world.entity",
"net.minecraft.world.entity.item", "net.minecraft.world.entity.monster", "net.minecraft.world.entity.monster.hoglin",
"net.minecraft.world.entity.monster.piglin", "net.minecraft.world.entity.npc", "net.minecraft.world.entity.player",
"net.minecraft.world.entity.projectile", "net.minecraft.world.entity.vehicle", "net.minecraft.world.inventory",
"net.minecraft.world.item", "net.minecraft.world.level.block", "net.minecraft.world.level.block.state",
"net.minecraft.world.level", "net.minecraft.world.phys", "org.bukkit.craftbukkit.$version$.block.data",
"org.bukkit.craftbukkit.$version$", "org.bukkit.craftbukkit.$version$.entity", "org.bukkit.craftbukkit.$version$.inventory",
"org.bukkit.craftbukkit.$version$.util"};
String replaceStr = "$version$";
String version = ReflectionManager.getNmsPackage();
// If there is no nms package, then replace the . as well so we don't have a "org.bukkit..server" package name situation
if (version.isEmpty()) {
replaceStr = "." + replaceStr;
}
for (int i = 0; i < s.length; i++) {
s[i] = s[i].replace(replaceStr, version);
}
return s;
}
private static String getVersion() {
return "Built for: " + Bukkit.getVersion() + "\t" + LibsDisguises.getInstance().getDescription().getVersion();
}
public static void saveMappingsCache(File dataFolder) {
synchronized (classLocations) {
if (!updatingCache) {
return;
}
updatingCache = false;
}
File mappingsCache = new File(dataFolder, "mappings_cache");
try (BufferedWriter writer = new BufferedWriter(new FileWriter(mappingsCache))) {
writer.write(getVersion() + "\n");
for (Map.Entry<String, String> entry : classLocations.entrySet()) {
writer.write(entry.getKey() + " " + entry.getValue() + "\n");
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void loadMappingsCache(File dataFolder) {
File mappingsCache = new File(dataFolder, "mappings_cache");
if (!mappingsCache.exists()) {
return;
}
try (BufferedReader reader = new BufferedReader(new FileReader(mappingsCache))) {
String line = reader.readLine();
// Not the correct version
if (line == null || !line.equals(getVersion())) {
DisguiseUtilities.getLogger().info("Outdated mappings cache, will rebuild.");
return;
}
while ((line = reader.readLine()) != null) {
String[] parts = line.split(" ", 2);
if (parts.length != 2) {
continue;
}
try {
// Check if class name is still valid
if (parts[1].contains(".")) {
Class.forName(parts[1]);
}
classLocations.put(parts[0], parts[1]);
} catch (ClassNotFoundException e) {
// silently discard, something went wrong though
}
}
} catch (FileNotFoundException e) {
// silently discard, it doesn't matter if the cache doesn't exist, we will just create it later
} catch (IOException e) {
e.printStackTrace();
}
}
}