If you replace the ClassNameDeobfuscator with the following, you can also get it to move the classes out of the default package automatically (classes in the default package are a problem, as you cannot import them).
Code:
package alterrs.jbct.ref;
import static alterrs.asm.Opcodes.ACC_INTERFACE;
import static alterrs.asm.Opcodes.ACC_NATIVE;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import alterrs.asm.tree.AbstractInsnNode;
import alterrs.asm.tree.ClassNode;
import alterrs.asm.tree.LdcInsnNode;
import alterrs.asm.tree.MethodNode;
import alterrs.commons.LoggingUtil;
import alterrs.jbct.JBCT;
import alterrs.jbct.utility.AbstractTransformer;
import alterrs.jbct.utility.ClassCollection;
import alterrs.jbct.utility.ID;
/**
* @author Lazaro Brito
*/
public class ClassNameDeobfuscator extends AbstractTransformer {
private static final Logger logger = LoggingUtil.log();
private int interfaceId = 1;
private Map<ID, Integer> classIds = new HashMap<ID, Integer>();
private int cCount = 0;
private static final String DEFAULT_PACKAGE_REPLACEMENT = "rs2/client/";
public ClassNameDeobfuscator() {
super(true);
JBCT.ctx.atr.set("ignoredClasses", new HashSet<ID>());
}
@Override
public void transform(ClassCollection cc) {
for (int level = 0; level < 32; level++) {
classLoop: for (ClassNode c : cc.getClasses().values()) {
if (cc.getLevel(c) == level) {
String cName = c.name.substring(
c.name.lastIndexOf("/") + 1, c.name.length());
boolean isDefaultPackage = (c.name.indexOf("/") == -1);
if (cName.length() <= 3
&& !containsNativeMethods(c)
&& JBCT.ctx.module.getRefactorer().getClass(
new ID(c)) == null) {
String name;
if ((c.access & ACC_INTERFACE) != 0) {
name = "Interface" + interfaceId++;
} else {
name = name(c);
cCount++;
}
if (isDefaultPackage) {
JBCT.ctx.module.getRefactorer().refactorClass(
new ID(c), DEFAULT_PACKAGE_REPLACEMENT+name);
} else {
JBCT.ctx.module.getRefactorer().refactorClass(
new ID(c), c.name.substring(0,
c.name.lastIndexOf("/") + 1)+name);
}
} else {
if (isDefaultPackage) {
JBCT.ctx.module.getRefactorer().refactorClass(
new ID(c), DEFAULT_PACKAGE_REPLACEMENT+cName);
}
for (Object mo : c.methods) {
MethodNode m = (MethodNode) mo;
if (m.name.equals("<init>")) {
for (AbstractInsnNode n : m.instructions.toArray()) {
if (n instanceof LdcInsnNode) {
if (((LdcInsnNode) n).cst
.equals("sw3d")) {
JBCT.ctx.atr.<Set<ID>> get(
"ignoredClasses").add(
new ID(c));
continue classLoop;
}
}
}
}
}
}
}
}
}
}
@Override
public void onFinish() {
logger.info("Refactored " + cCount + " classes and "
+ (interfaceId - 1) + " interfaces!");
}
private int id(ClassNode c) {
if (c.superName == null) {
return 1;
} else {
Integer i = classIds.get(new ID(c.superName));
if (i == null) {
i = 0;
}
i++;
classIds.put(new ID(c.superName), i);
return i;
}
}
private String name(ClassNode c) {
int id = id(c);
int level = JBCT.ctx.module.getLevel(c);
if (level == 1) {
return "Class" + id;
} else {
StringBuilder name = new StringBuilder();
String superName = JBCT.ctx.module.getRefactorer().getClass(
new ID(c.superName));
if (superName != null) {
name.append(superName.substring(superName.lastIndexOf("/") + 1, superName.length()));
} else {
name.append(c.superName.substring(
c.superName.lastIndexOf("/") + 1, c.superName.length()));
}
name.append("_Sub").append(id);
return name.toString();
}
}
private boolean containsNativeMethods(ClassNode c) {
for (Object mo : c.methods) {
MethodNode m = (MethodNode) mo;
if ((m.access & ACC_NATIVE) != 0) {
return true;
}
}
return false;
}
}
If anyone knows the proper way to move classes out of the default package using the alterrs tools, feel free to share. But this way does work, and it's easier than manually moving over 1000 classes after the deobfuscation has finished.