package net.fybertech.dynamicmappings;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import net.minecraft.launchwrapper.Launch;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;
public class AccessUtil
{
public static final int allAccess = Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE;
public List<String> accessTransformerFields = new ArrayList<>();
public List<String> accessTransformerMethods = new ArrayList<>();
public List<String> accessTransformerClasses = new ArrayList<>(); // TODO
private boolean debug = false;
public void readAllTransformerConfigs()
{
System.out.println("Discovering access transformers...");
Enumeration<URL> urls = null;
try {
urls = AccessUtil.class.getClassLoader().getResources("accesstransformer.cfg");
} catch (IOException e) {
e.printStackTrace();
}
if (urls == null) return;
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
System.out.println("Processing access transformer at " + url);
String line = null;
while ((line = reader.readLine()) != null) {
// Ignore commented or short lines
if (line.startsWith("#") || line.length() < 1) continue;
String[] split = line.split(" ", 2);
if (split.length < 2) continue;
String mode = split[0].toUpperCase();
String ac = split[1];
if (mode.equals("F")) accessTransformerFields.add(ac);
else if (mode.equals("M")) accessTransformerMethods.add(ac);
else if (mode.equals("C")) accessTransformerClasses.add(ac);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void transformDeobfuscatedClass(ClassNode cn)
{
for (String transformer : accessTransformerFields) {
String[] split = transformer.split(" ");
if (split.length != 4) continue;
String className = split[0];
String fieldName = split[1];
String fieldDesc = split[2];
int access = 0;
try {
access = Integer.parseInt(split[3]);
}
catch (NumberFormatException e) {}
if (access < 1) continue;
if (!cn.name.equals(className)) continue;
boolean wildcardName = fieldName.equals("*");
boolean wildcardDesc = fieldDesc.equals("*");
for (FieldNode field : cn.fields) {
if (!field.name.equals(fieldName) && !wildcardName) continue;
if (!field.desc.equals(fieldDesc) && !wildcardDesc) continue;
field.access = (field.access & ~allAccess) | access;
if (debug) System.out.println("Modifying access of " + className + " " + field.name + " " + field.desc);
}
}
for (String transformer : accessTransformerMethods) {
String[] split = transformer.split(" ");
if (split.length != 4) continue;
String className = split[0];
String methodName = split[1];
String methodDesc = split[2];
int access = 0;
try {
access = Integer.parseInt(split[3]);
}
catch (NumberFormatException e) {}
if (access < 1) continue;
if (!cn.name.equals(className)) continue;
boolean wildcardName = methodName.equals("*");
boolean wildcardDesc = methodDesc.equals("*");
for (MethodNode method : cn.methods) {
if (!method.name.equals(methodName) && !wildcardName) continue;
if (!method.desc.equals(methodDesc) && !wildcardDesc) continue;
method.access = (method.access & ~allAccess) | access;
if (debug) System.out.println("Modifying access of " + className + " " + method.name + " " + method.desc);
}
}
}
}