mirror of
https://github.com/SuspiciousActivity/ByteEdit.git
synced 2026-08-13 17:56:17 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
30c9c81d38 | ||
|
|
65235c6b5b | ||
|
|
d8096a4ec5 | ||
|
|
add82951e6 |
No files matched your search
@@ -137,7 +137,7 @@ public class GlobalSearchBox extends JFrame {
|
||||
openBox.model.clear();
|
||||
Set<Info> set = new HashSet<>();
|
||||
if (!txtString.getText().isEmpty()) {
|
||||
String str = UnicodeUtils.unescape(txtString.getText());
|
||||
String str = UnicodeUtils.unescape(null, txtString.getText(), true);
|
||||
if (ignoreCase) {
|
||||
str = str.toLowerCase();
|
||||
}
|
||||
@@ -157,11 +157,11 @@ public class GlobalSearchBox extends JFrame {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String owner = UnicodeUtils.unescape(txtOwner.getText());
|
||||
String owner = UnicodeUtils.unescape(null, txtOwner.getText(), true);
|
||||
boolean wildCardOwner = owner.isEmpty();
|
||||
String name = UnicodeUtils.unescape(txtName.getText());
|
||||
String name = UnicodeUtils.unescape(null, txtName.getText(), true);
|
||||
boolean wildCardName = name.isEmpty();
|
||||
String desc = UnicodeUtils.unescape(txtDesc.getText());
|
||||
String desc = UnicodeUtils.unescape(null, txtDesc.getText(), true);
|
||||
boolean wildCardDesc = desc.isEmpty();
|
||||
for (ClassNode cn : Main.classNodes.values()) {
|
||||
for (MethodNode mn : cn.methods) {
|
||||
|
||||
@@ -84,8 +84,8 @@ public class RenameBox extends JFrame {
|
||||
JOptionPane.showMessageDialog(null, "ClassNode not found!", "Error!", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
String newName = UnicodeUtils.unescape(txtName.getText());
|
||||
String newDesc = UnicodeUtils.unescape(txtDesc.getText());
|
||||
String newName = UnicodeUtils.unescape(null, txtName.getText(), true);
|
||||
String newDesc = UnicodeUtils.unescape(null, txtDesc.getText(), true);
|
||||
if (ClassUtil.isObjectClassMethod(newName, newDesc, true)) {
|
||||
JOptionPane.showMessageDialog(null, "Invalid name!", "Error!", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
|
||||
@@ -76,7 +76,7 @@ public class TypeOpenBox extends JFrame {
|
||||
if (txtSearch.getText().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String search = UnicodeUtils.unescape(txtSearch.getText()).toLowerCase();
|
||||
String search = UnicodeUtils.unescape(null, txtSearch.getText(), true).toLowerCase();
|
||||
if (search.contains("/")) {
|
||||
for (String s : Main.classNodes.keySet()) {
|
||||
String className = s.substring(0, s.length() - 6);
|
||||
|
||||
@@ -36,7 +36,7 @@ public class UnicodeBox extends JFrame {
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
try {
|
||||
textArea.setText(UnicodeUtils.escape(textArea.getText()));
|
||||
textArea.setText(UnicodeUtils.escape(null, textArea.getText(), true));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
Main.showError(ex.getMessage());
|
||||
}
|
||||
@@ -50,7 +50,7 @@ public class UnicodeBox extends JFrame {
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
try {
|
||||
textArea.setText(UnicodeUtils.unescape(textArea.getText()));
|
||||
textArea.setText(UnicodeUtils.unescape(null, textArea.getText(), true));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
Main.showError(ex.getMessage());
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package me.ByteEdit.edit;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.StringReader;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
@@ -9,6 +10,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.swing.text.BadLocationException;
|
||||
|
||||
@@ -51,30 +53,47 @@ import me.ByteEdit.utils.UnicodeUtils;
|
||||
|
||||
public class Assembler {
|
||||
|
||||
public static final Pattern SPACE = Pattern.compile(" ");
|
||||
|
||||
public static ClassNode assemble(String input) {
|
||||
Main.txtByteEditView.removeAllLineHighlights();
|
||||
CustomBufferedReader read = null;
|
||||
try {
|
||||
ClassNode clazz = new ClassNode();
|
||||
HugeStringsRev hsr = new HugeStringsRev();
|
||||
try (BufferedReader reader = new BufferedReader(new StringReader(input))) {
|
||||
String s;
|
||||
while (!(s = reader.readLine()).startsWith("// #SourceFile: ")) {
|
||||
}
|
||||
while (!(s = reader.readLine()).equals("// #Fields")) {
|
||||
if (s.startsWith("#")) {
|
||||
String[] split = SPACE.split(s, 2);
|
||||
hsr.add(Integer.parseInt(split[0].substring(1, split[0].length() - 1)),
|
||||
UnicodeUtils.unescape(null, split[1], true));
|
||||
}
|
||||
}
|
||||
}
|
||||
read = new CustomBufferedReader(new StringReader(input));
|
||||
String s;
|
||||
while (!(s = read.readLine()).startsWith("// #Class v:")) {
|
||||
if (clazz.visibleAnnotations == null) {
|
||||
clazz.visibleAnnotations = new ArrayList<>();
|
||||
}
|
||||
clazz.visibleAnnotations.add(parseAnnotation(s));
|
||||
clazz.visibleAnnotations.add(parseAnnotation(hsr, s));
|
||||
}
|
||||
clazz.version = Integer.parseInt(s.substring(12));
|
||||
while ((s = read.readLine()).startsWith("// ")) {
|
||||
if (s.startsWith("// #Signature: ")) {
|
||||
clazz.signature = s.substring(15).equals("null") ? null : UnicodeUtils.unescape(s.substring(15));
|
||||
clazz.signature = s.substring(15).equals("null") ? null
|
||||
: UnicodeUtils.unescape(hsr, s.substring(15));
|
||||
} else if (s.startsWith("// #OuterClass: ")) {
|
||||
clazz.outerClass = s.substring(16).equals("null") ? null : UnicodeUtils.unescape(s.substring(16));
|
||||
clazz.outerClass = s.substring(16).equals("null") ? null
|
||||
: UnicodeUtils.unescape(hsr, s.substring(16));
|
||||
} else if (s.startsWith("// #OuterMethod: ")) {
|
||||
String[] split = s.split(" ");
|
||||
if (split.length > 3) {
|
||||
clazz.outerMethod = UnicodeUtils.unescape(split[2]);
|
||||
clazz.outerMethodDesc = UnicodeUtils.unescape(split[3]);
|
||||
clazz.outerMethod = UnicodeUtils.unescape(hsr, split[2]);
|
||||
clazz.outerMethodDesc = UnicodeUtils.unescape(hsr, split[3]);
|
||||
}
|
||||
} else if (s.equals("// #InnerClasses:")) {
|
||||
clazz.innerClasses = new ArrayList<>();
|
||||
@@ -137,9 +156,9 @@ public class Assembler {
|
||||
access ^= ClassUtil.ACC_MANDATED;
|
||||
}
|
||||
}
|
||||
clazz.innerClasses.add(new InnerClassNode(UnicodeUtils.unescape(split[1]),
|
||||
split[2].equals("null") ? null : UnicodeUtils.unescape(split[2]),
|
||||
split[3].equals("null") ? null : UnicodeUtils.unescape(split[3]), access));
|
||||
clazz.innerClasses.add(new InnerClassNode(UnicodeUtils.unescape(hsr, split[1]),
|
||||
split[2].equals("null") ? null : UnicodeUtils.unescape(hsr, split[2]),
|
||||
split[3].equals("null") ? null : UnicodeUtils.unescape(hsr, split[3]), access));
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -148,14 +167,14 @@ public class Assembler {
|
||||
String interfaces = s.substring(s.lastIndexOf(" implements ") + 12);
|
||||
clazz.interfaces = new ArrayList<>();
|
||||
for (String interf : interfaces.split(", ")) {
|
||||
clazz.interfaces.add(UnicodeUtils.unescape(interf));
|
||||
clazz.interfaces.add(UnicodeUtils.unescape(hsr, interf));
|
||||
}
|
||||
s = s.substring(0, s.lastIndexOf(" implements "));
|
||||
}
|
||||
clazz.superName = UnicodeUtils.unescape(s.substring(s.lastIndexOf(" extends ") + 9));
|
||||
clazz.superName = UnicodeUtils.unescape(hsr, s.substring(s.lastIndexOf(" extends ") + 9));
|
||||
s = s.substring(0, s.lastIndexOf(" extends "));
|
||||
String[] split = s.split(" ");
|
||||
clazz.name = UnicodeUtils.unescape(split[split.length - 1]);
|
||||
clazz.name = UnicodeUtils.unescape(hsr, split[split.length - 1]);
|
||||
clazz.access = ClassUtil.ACC_SUPER;
|
||||
switch (split[split.length - 2]) {
|
||||
case "class":
|
||||
@@ -192,7 +211,7 @@ public class Assembler {
|
||||
}
|
||||
}
|
||||
s = read.readLine();
|
||||
clazz.sourceFile = s.substring(16).equals("null") ? null : UnicodeUtils.unescape(s.substring(16));
|
||||
clazz.sourceFile = s.substring(16).equals("null") ? null : UnicodeUtils.unescape(hsr, s.substring(16));
|
||||
while (!(s = read.readLine()).equals("// #Fields")) {
|
||||
}
|
||||
clazz.fields = new ArrayList<>();
|
||||
@@ -207,7 +226,7 @@ public class Assembler {
|
||||
annotationsForNext.add(s);
|
||||
} else {
|
||||
if (s.startsWith("// #Signature: ")) {
|
||||
signature = UnicodeUtils.unescape(s.substring(15));
|
||||
signature = UnicodeUtils.unescape(hsr, s.substring(15));
|
||||
} else {
|
||||
String[] split = s.split(" ");
|
||||
boolean hasValue = false;
|
||||
@@ -218,9 +237,9 @@ public class Assembler {
|
||||
if (hasValue) {
|
||||
split = s.substring(0, s.indexOf(" = ")).split(" ");
|
||||
}
|
||||
String name = UnicodeUtils.unescape(split[split.length - 1]);
|
||||
String desc = UnicodeUtils.unescape(split[split.length - 2]);
|
||||
value = getValue((String) value, desc);
|
||||
String name = UnicodeUtils.unescape(hsr, split[split.length - 1]);
|
||||
String desc = UnicodeUtils.unescape(hsr, split[split.length - 2]);
|
||||
value = getValue(hsr, (String) value, desc);
|
||||
int access = 0;
|
||||
if (split.length > 2) {
|
||||
String cons = consolidateStrings(split, 0, split.length - 2);
|
||||
@@ -283,7 +302,7 @@ public class Assembler {
|
||||
node.visibleAnnotations = new ArrayList<>();
|
||||
}
|
||||
for (String anno : annotationsForNext) {
|
||||
node.visibleAnnotations.add(parseAnnotation(anno));
|
||||
node.visibleAnnotations.add(parseAnnotation(hsr, anno));
|
||||
}
|
||||
annotationsForNext.clear();
|
||||
}
|
||||
@@ -319,7 +338,7 @@ public class Assembler {
|
||||
tryCatchBlocksToParse.clear();
|
||||
stage = 0;
|
||||
} else if (s.startsWith("// #Signature: ")) {
|
||||
node.signature = UnicodeUtils.unescape(s.substring(15));
|
||||
node.signature = UnicodeUtils.unescape(hsr, s.substring(15));
|
||||
} else if (s.equals("// #TryCatch:")) {
|
||||
stage = 1;
|
||||
} else if (s.equals("// #LocalVars:")) {
|
||||
@@ -337,7 +356,7 @@ public class Assembler {
|
||||
node.visibleAnnotations = new ArrayList<>();
|
||||
}
|
||||
for (String anno : annotationsForNext) {
|
||||
node.visibleAnnotations.add(parseAnnotation(anno));
|
||||
node.visibleAnnotations.add(parseAnnotation(hsr, anno));
|
||||
}
|
||||
annotationsForNext.clear();
|
||||
}
|
||||
@@ -345,7 +364,7 @@ public class Assembler {
|
||||
String[] sp = st.split(":");
|
||||
int start = Integer.parseInt(sp[3].substring(0, sp[3].length() - 2));
|
||||
int end = Integer.parseInt(sp[4].substring(0, sp[4].length() - 4));
|
||||
String signat = sp[5].equals("null") ? null : UnicodeUtils.unescape(sp[5]);
|
||||
String signat = sp[5].equals("null") ? null : UnicodeUtils.unescape(hsr, sp[5]);
|
||||
LabelNode _start = null;
|
||||
LabelNode _end = null;
|
||||
for (Entry<LabelNode, Integer> entry : methodLabelMap.entrySet()) {
|
||||
@@ -356,9 +375,9 @@ public class Assembler {
|
||||
_end = entry.getKey();
|
||||
}
|
||||
}
|
||||
node.localVariables.add(new LocalVariableNode(UnicodeUtils.unescape(sp[0]),
|
||||
UnicodeUtils.unescape(sp[1].substring(1, sp[1].length() - 2)), signat, _start, _end,
|
||||
Integer.parseInt(sp[2].substring(0, sp[2].length() - 2))));
|
||||
node.localVariables.add(new LocalVariableNode(UnicodeUtils.unescape(hsr, sp[0]),
|
||||
UnicodeUtils.unescape(hsr, sp[1].substring(1, sp[1].length() - 2)), signat, _start,
|
||||
_end, Integer.parseInt(sp[2].substring(0, sp[2].length() - 2))));
|
||||
}
|
||||
for (String st : tryCatchBlocksToParse) {
|
||||
String[] sp = st.split(" ");
|
||||
@@ -380,7 +399,7 @@ public class Assembler {
|
||||
}
|
||||
}
|
||||
node.tryCatchBlocks.add(new TryCatchBlockNode(_start, _end, _handler,
|
||||
sp[0].equals("null") ? null : UnicodeUtils.unescape(sp[0])));
|
||||
sp[0].equals("null") ? null : UnicodeUtils.unescape(hsr, sp[0])));
|
||||
}
|
||||
clazz.methods.add(node);
|
||||
} else if (!s.startsWith("\t")) {
|
||||
@@ -388,13 +407,13 @@ public class Assembler {
|
||||
if (s.contains(" throws ")) {
|
||||
String exceptions = s.substring(s.lastIndexOf(" throws ") + 8);
|
||||
for (String excp : exceptions.split(", ")) {
|
||||
node.exceptions.add(UnicodeUtils.unescape(excp));
|
||||
node.exceptions.add(UnicodeUtils.unescape(hsr, excp));
|
||||
}
|
||||
s = s.substring(0, s.lastIndexOf(" throws "));
|
||||
}
|
||||
String[] split = s.split(" ");
|
||||
node.desc = UnicodeUtils.unescape(split[split.length - 1]);
|
||||
node.name = UnicodeUtils.unescape(split[split.length - 2]);
|
||||
node.desc = UnicodeUtils.unescape(hsr, split[split.length - 1]);
|
||||
node.name = UnicodeUtils.unescape(hsr, split[split.length - 2]);
|
||||
int access = 0;
|
||||
if (split.length > 2) {
|
||||
String cons = consolidateStrings(split, 0, split.length - 2);
|
||||
@@ -458,7 +477,7 @@ public class Assembler {
|
||||
if (!temp.isEmpty()) {
|
||||
if (s.equals("]")) {
|
||||
temp += s;
|
||||
node.instructions.add(getNode(temp, methodLabelMap));
|
||||
node.instructions.add(getNode(hsr, temp, methodLabelMap));
|
||||
temp = "";
|
||||
} else {
|
||||
temp += s + "\n";
|
||||
@@ -467,7 +486,7 @@ public class Assembler {
|
||||
if (s.endsWith("[")) {
|
||||
temp += s + "\n";
|
||||
} else {
|
||||
node.instructions.add(getNode(s, methodLabelMap));
|
||||
node.instructions.add(getNode(hsr, s, methodLabelMap));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -496,31 +515,37 @@ public class Assembler {
|
||||
ArrayList<String> ret = new ArrayList<>();
|
||||
String[] split = s.split(", ");
|
||||
String building = null;
|
||||
boolean inString = false;
|
||||
|
||||
for (int i = 0; i < split.length; i++) {
|
||||
if (split[i].startsWith("(")) {
|
||||
ret.add(split[i]);
|
||||
} else if (split[i].endsWith("\"")) {
|
||||
} else if (split[i].startsWith("\"") && split[i].endsWith("\"")) {
|
||||
ret.add(split[i]);
|
||||
} else if (split[i].endsWith("\"") && inString) {
|
||||
if (building == null)
|
||||
ret.add(split[i]);
|
||||
else
|
||||
ret.add(building + ", " + split[i]);
|
||||
building = null;
|
||||
} else {
|
||||
} else if (inString || split[i].startsWith("\"")) {
|
||||
inString = true;
|
||||
if (building == null)
|
||||
building = split[i];
|
||||
else
|
||||
building += ", " + split[i];
|
||||
} else {
|
||||
ret.add(split[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return ret.toArray(new String[0]);
|
||||
}
|
||||
|
||||
private static AnnotationNode parseAnnotation(String s) {
|
||||
private static AnnotationNode parseAnnotation(HugeStringsRev hsr, String s) {
|
||||
s = s.substring(1);
|
||||
String[] split = s.split(" ");
|
||||
AnnotationNode node = new AnnotationNode(UnicodeUtils.unescape(split[0]));
|
||||
AnnotationNode node = new AnnotationNode(UnicodeUtils.unescape(hsr, split[0]));
|
||||
if (split.length > 1) {
|
||||
if (node.values == null) {
|
||||
node.values = new ArrayList<>();
|
||||
@@ -538,7 +563,7 @@ public class Assembler {
|
||||
String split3[] = splitWithStrings(value.substring(2, value.length() - 2));
|
||||
List<Object> list = new ArrayList<>();
|
||||
for (String rofl : split3) {
|
||||
rofl = UnicodeUtils.unescape(rofl);
|
||||
rofl = UnicodeUtils.unescape(hsr, rofl);
|
||||
if (rofl.startsWith("\"")) {
|
||||
int index = rofl.lastIndexOf("\"");
|
||||
list.add(rofl.substring(1, index));
|
||||
@@ -552,7 +577,7 @@ public class Assembler {
|
||||
}
|
||||
node.values.add(list);
|
||||
} else {
|
||||
value = UnicodeUtils.unescape(value);
|
||||
value = UnicodeUtils.unescape(hsr, value);
|
||||
if (value.startsWith("\"")) {
|
||||
int index = value.lastIndexOf("\"");
|
||||
node.values.add(value.substring(1, index));
|
||||
@@ -596,7 +621,7 @@ public class Assembler {
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static Object getValue(String s, String to) {
|
||||
private static Object getValue(HugeStringsRev hsr, String s, String to) {
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -618,14 +643,15 @@ public class Assembler {
|
||||
case "S":
|
||||
return Short.parseShort(s);
|
||||
case "Ljava/lang/String;":
|
||||
return UnicodeUtils.unescape(s.substring(1, s.length() - 1));
|
||||
return UnicodeUtils.unescape(hsr, s.substring(1, s.length() - 1));
|
||||
default: {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static AbstractInsnNode getNode(String s, HashMap<LabelNode, Integer> labels) throws Exception {
|
||||
private static AbstractInsnNode getNode(HugeStringsRev hsr, String s, HashMap<LabelNode, Integer> labels)
|
||||
throws Exception {
|
||||
if (s.startsWith("// label ")) {
|
||||
int labelNr = Integer.parseInt(s.substring(9));
|
||||
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||
@@ -665,11 +691,8 @@ public class Assembler {
|
||||
int frameType = ClassUtil.getFrameTypeByName(asd);
|
||||
if (frameType != -1)
|
||||
arr.add(new Integer(frameType));
|
||||
else {
|
||||
String frame = UnicodeUtils.unescape(asd);
|
||||
frame = frame.substring(1, frame.length() - 1);
|
||||
arr.add(frame);
|
||||
}
|
||||
else
|
||||
arr.add(UnicodeUtils.unescape(hsr, asd.substring(1, asd.length() - 1)));
|
||||
} else {
|
||||
if (asd.startsWith("(label) ")) {
|
||||
int labelNr = Integer.parseInt(asd.split(" ")[1]);
|
||||
@@ -711,11 +734,8 @@ public class Assembler {
|
||||
int frameType = ClassUtil.getFrameTypeByName(asd);
|
||||
if (frameType != -1)
|
||||
arr.add(new Integer(frameType));
|
||||
else {
|
||||
String frame = UnicodeUtils.unescape(asd);
|
||||
frame = frame.substring(1, frame.length() - 1);
|
||||
arr.add(frame);
|
||||
}
|
||||
else
|
||||
arr.add(UnicodeUtils.unescape(hsr, asd.substring(1, asd.length() - 1)));
|
||||
} else {
|
||||
if (asd.startsWith("(label) ")) {
|
||||
int labelNr = Integer.parseInt(asd.split(" ")[1]);
|
||||
@@ -818,10 +838,12 @@ public class Assembler {
|
||||
String type = split2[0].substring(7);
|
||||
// Reflection
|
||||
val = new Type(ClassUtil.getIDFromClassNameForType(type),
|
||||
UnicodeUtils.unescape(split2[3].substring(6, split2[3].length() - 1)),
|
||||
UnicodeUtils.unescape(hsr, split2[3].substring(6, split2[3].length() - 1)),
|
||||
Integer.parseInt(split2[1].substring(7)), Integer.parseInt(split2[2].substring(5)));
|
||||
} else if (str.startsWith("\"") && str.endsWith("\"")) {
|
||||
val = UnicodeUtils.unescape(str.substring(1, str.length() - 1));
|
||||
val = UnicodeUtils.unescape(hsr, str.substring(1, str.length() - 1), true);
|
||||
} else if (str.startsWith("#")) {
|
||||
val = UnicodeUtils.unescape(hsr, str);
|
||||
} else if (str.endsWith("l")) {
|
||||
val = Long.parseLong(str.substring(0, str.length() - 1));
|
||||
} else if (str.endsWith("f")) {
|
||||
@@ -1437,50 +1459,54 @@ public class Assembler {
|
||||
case "getstatic": {
|
||||
String target = split[2];
|
||||
int index = target.lastIndexOf("/");
|
||||
return new FieldInsnNode(178, UnicodeUtils.unescape(target.substring(0, index)),
|
||||
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]));
|
||||
return new FieldInsnNode(178, UnicodeUtils.unescape(hsr, target.substring(0, index)),
|
||||
UnicodeUtils.unescape(hsr, target.substring(index + 1)), UnicodeUtils.unescape(hsr, split[1]));
|
||||
}
|
||||
case "putstatic": {
|
||||
String target = split[2];
|
||||
int index = target.lastIndexOf("/");
|
||||
return new FieldInsnNode(179, UnicodeUtils.unescape(target.substring(0, index)),
|
||||
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]));
|
||||
return new FieldInsnNode(179, UnicodeUtils.unescape(hsr, target.substring(0, index)),
|
||||
UnicodeUtils.unescape(hsr, target.substring(index + 1)), UnicodeUtils.unescape(hsr, split[1]));
|
||||
}
|
||||
case "getfield": {
|
||||
String target = split[2];
|
||||
int index = target.lastIndexOf("/");
|
||||
return new FieldInsnNode(180, UnicodeUtils.unescape(target.substring(0, index)),
|
||||
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]));
|
||||
return new FieldInsnNode(180, UnicodeUtils.unescape(hsr, target.substring(0, index)),
|
||||
UnicodeUtils.unescape(hsr, target.substring(index + 1)), UnicodeUtils.unescape(hsr, split[1]));
|
||||
}
|
||||
case "putfield": {
|
||||
String target = split[2];
|
||||
int index = target.lastIndexOf("/");
|
||||
return new FieldInsnNode(181, UnicodeUtils.unescape(target.substring(0, index)),
|
||||
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]));
|
||||
return new FieldInsnNode(181, UnicodeUtils.unescape(hsr, target.substring(0, index)),
|
||||
UnicodeUtils.unescape(hsr, target.substring(index + 1)), UnicodeUtils.unescape(hsr, split[1]));
|
||||
}
|
||||
case "invokevirtual": {
|
||||
String target = split[2];
|
||||
int index = target.lastIndexOf("/");
|
||||
return new MethodInsnNode(182, UnicodeUtils.unescape(target.substring(0, index)),
|
||||
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]), false);
|
||||
return new MethodInsnNode(182, UnicodeUtils.unescape(hsr, target.substring(0, index)),
|
||||
UnicodeUtils.unescape(hsr, target.substring(index + 1)), UnicodeUtils.unescape(hsr, split[1]),
|
||||
false);
|
||||
}
|
||||
case "invokespecial": {
|
||||
String target = split[2];
|
||||
int index = target.lastIndexOf("/");
|
||||
return new MethodInsnNode(183, UnicodeUtils.unescape(target.substring(0, index)),
|
||||
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]), false);
|
||||
return new MethodInsnNode(183, UnicodeUtils.unescape(hsr, target.substring(0, index)),
|
||||
UnicodeUtils.unescape(hsr, target.substring(index + 1)), UnicodeUtils.unescape(hsr, split[1]),
|
||||
false);
|
||||
}
|
||||
case "invokestatic": {
|
||||
String target = split[2];
|
||||
int index = target.lastIndexOf("/");
|
||||
return new MethodInsnNode(184, UnicodeUtils.unescape(target.substring(0, index)),
|
||||
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]), false);
|
||||
return new MethodInsnNode(184, UnicodeUtils.unescape(hsr, target.substring(0, index)),
|
||||
UnicodeUtils.unescape(hsr, target.substring(index + 1)), UnicodeUtils.unescape(hsr, split[1]),
|
||||
false);
|
||||
}
|
||||
case "invokeinterface": {
|
||||
String target = split[2];
|
||||
int index = target.lastIndexOf("/");
|
||||
return new MethodInsnNode(185, UnicodeUtils.unescape(target.substring(0, index)),
|
||||
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]), true);
|
||||
return new MethodInsnNode(185, UnicodeUtils.unescape(hsr, target.substring(0, index)),
|
||||
UnicodeUtils.unescape(hsr, target.substring(index + 1)), UnicodeUtils.unescape(hsr, split[1]),
|
||||
true);
|
||||
}
|
||||
case "invokedynamic": {
|
||||
String str = s.substring(16, s.length() - 2).replace("", "");
|
||||
@@ -1495,7 +1521,7 @@ public class Assembler {
|
||||
try {
|
||||
// Reflection
|
||||
args.add(new Type(ClassUtil.getIDFromClassNameForType(vals.get(0).substring(6)),
|
||||
UnicodeUtils.unescape(vals.get(3).substring(6, vals.get(3).length() - 1)),
|
||||
UnicodeUtils.unescape(hsr, vals.get(3).substring(6, vals.get(3).length() - 1)),
|
||||
Integer.parseInt(vals.get(1).substring(7)),
|
||||
Integer.parseInt(vals.get(2).substring(5))));
|
||||
} catch (Exception e) {
|
||||
@@ -1503,9 +1529,9 @@ public class Assembler {
|
||||
}
|
||||
} else if (stage == 2) {
|
||||
args.add(new Handle(OpcodesReverse.getHandleOpcode(vals.get(4).substring(5)),
|
||||
UnicodeUtils.unescape(vals.get(1).substring(7)),
|
||||
UnicodeUtils.unescape(vals.get(0).substring(6)),
|
||||
UnicodeUtils.unescape(vals.get(2).substring(6)),
|
||||
UnicodeUtils.unescape(hsr, vals.get(1).substring(7)),
|
||||
UnicodeUtils.unescape(hsr, vals.get(0).substring(6)),
|
||||
UnicodeUtils.unescape(hsr, vals.get(2).substring(6)),
|
||||
Boolean.parseBoolean(vals.get(3).substring(13))));
|
||||
vals.clear();
|
||||
}
|
||||
@@ -1523,7 +1549,7 @@ public class Assembler {
|
||||
vals.add(st);
|
||||
} else if (stage == 0) {
|
||||
if (st.startsWith("\"") && st.endsWith("\"")) {
|
||||
args.add(UnicodeUtils.unescape(st.substring(1, st.length() - 1)));
|
||||
args.add(UnicodeUtils.unescape(hsr, st.substring(1, st.length() - 1)));
|
||||
} else if (st.endsWith("l")) {
|
||||
args.add(Long.parseLong(st.substring(0, st.length() - 1)));
|
||||
} else if (st.endsWith("f")) {
|
||||
@@ -1541,21 +1567,23 @@ public class Assembler {
|
||||
_args[stage] = o;
|
||||
stage++;
|
||||
}
|
||||
return new InvokeDynamicInsnNode(UnicodeUtils.unescape(sp[0].substring(7)),
|
||||
UnicodeUtils.unescape(sp[1].substring(6)),
|
||||
return new InvokeDynamicInsnNode(UnicodeUtils.unescape(hsr, sp[0].substring(7)),
|
||||
UnicodeUtils.unescape(hsr, sp[1].substring(6)),
|
||||
new Handle(OpcodesReverse.getHandleOpcode(sp[7].substring(6)),
|
||||
UnicodeUtils.unescape(sp[4].substring(8)), UnicodeUtils.unescape(sp[3].substring(7)),
|
||||
UnicodeUtils.unescape(sp[5].substring(7)), Boolean.parseBoolean(sp[6].substring(14))),
|
||||
UnicodeUtils.unescape(hsr, sp[4].substring(8)),
|
||||
UnicodeUtils.unescape(hsr, sp[3].substring(7)),
|
||||
UnicodeUtils.unescape(hsr, sp[5].substring(7)),
|
||||
Boolean.parseBoolean(sp[6].substring(14))),
|
||||
_args);
|
||||
}
|
||||
case "new": {
|
||||
return new TypeInsnNode(187, UnicodeUtils.unescape(split[1]));
|
||||
return new TypeInsnNode(187, UnicodeUtils.unescape(hsr, split[1]));
|
||||
}
|
||||
case "newarray": {
|
||||
return new IntInsnNode(188, ClassUtil.getArrayIDByType(split[1]));
|
||||
}
|
||||
case "anewarray": {
|
||||
return new TypeInsnNode(189, UnicodeUtils.unescape(split[1]));
|
||||
return new TypeInsnNode(189, UnicodeUtils.unescape(hsr, split[1]));
|
||||
}
|
||||
case "arraylength": {
|
||||
return new InsnNode(190);
|
||||
@@ -1564,10 +1592,10 @@ public class Assembler {
|
||||
return new InsnNode(191);
|
||||
}
|
||||
case "checkcast": {
|
||||
return new TypeInsnNode(192, UnicodeUtils.unescape(split[1]));
|
||||
return new TypeInsnNode(192, UnicodeUtils.unescape(hsr, split[1]));
|
||||
}
|
||||
case "instanceof": {
|
||||
return new TypeInsnNode(193, UnicodeUtils.unescape(split[1]));
|
||||
return new TypeInsnNode(193, UnicodeUtils.unescape(hsr, split[1]));
|
||||
}
|
||||
case "monitorenter": {
|
||||
return new InsnNode(194);
|
||||
@@ -1576,7 +1604,7 @@ public class Assembler {
|
||||
return new InsnNode(195);
|
||||
}
|
||||
case "multianewarray": {
|
||||
return new MultiANewArrayInsnNode(UnicodeUtils.unescape(split[1]), Integer.parseInt(split[2]));
|
||||
return new MultiANewArrayInsnNode(UnicodeUtils.unescape(hsr, split[1]), Integer.parseInt(split[2]));
|
||||
}
|
||||
case "ifnull": {
|
||||
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.objectweb.asm.Handle;
|
||||
@@ -40,6 +41,7 @@ import org.objectweb.asm.tree.TryCatchBlockNode;
|
||||
import org.objectweb.asm.tree.TypeInsnNode;
|
||||
import org.objectweb.asm.tree.VarInsnNode;
|
||||
|
||||
import me.ByteEdit.main.Main;
|
||||
import me.ByteEdit.utils.ClassUtil;
|
||||
import me.ByteEdit.utils.OpcodesReverse;
|
||||
import me.ByteEdit.utils.UnicodeUtils;
|
||||
@@ -83,53 +85,60 @@ public class Disassembler {
|
||||
return new DisassembleTuple("ClassNode is null! This is not a valid java class file!");
|
||||
}
|
||||
try {
|
||||
HugeStrings hs = new HugeStrings();
|
||||
AtomicInteger lineFound = new AtomicInteger(-1);
|
||||
StringContext ctx = new StringContext(16);
|
||||
StringContext ctx = new StringContext(18);
|
||||
ctx.next("// #Annotations:\n");
|
||||
ctx.next(doAnnotations(classNode.visibleAnnotations));
|
||||
ctx.next(doAnnotations(classNode.visibleAnnotations, hs));
|
||||
ctx.next("// #Class v:" + classNode.version + "\n");
|
||||
if (classNode.signature != null)
|
||||
ctx.next("// #Signature: " + UnicodeUtils.escapeWithSpaces(classNode.signature) + "\n");
|
||||
ctx.next("// #Signature: " + UnicodeUtils.escapeWithSpaces(hs, classNode.signature) + "\n");
|
||||
if (classNode.outerMethod != null)
|
||||
ctx.next("// #OuterMethod: " + (classNode.outerMethod == null ? "null"
|
||||
: (UnicodeUtils.escapeWithSpaces(classNode.outerMethod) + " "
|
||||
+ UnicodeUtils.escapeWithSpaces(classNode.outerMethodDesc)))
|
||||
+ "\n");
|
||||
ctx.next(
|
||||
"// #OuterMethod: "
|
||||
+ (classNode.outerMethod == null ? "null"
|
||||
: (UnicodeUtils.escapeWithSpaces(hs, classNode.outerMethod) + " "
|
||||
+ UnicodeUtils.escapeWithSpaces(hs, classNode.outerMethodDesc)))
|
||||
+ "\n");
|
||||
if (classNode.outerClass != null)
|
||||
ctx.next("// #OuterClass: " + UnicodeUtils.escapeWithSpaces(classNode.outerClass) + "\n");
|
||||
ctx.next("// #OuterClass: " + UnicodeUtils.escapeWithSpaces(hs, classNode.outerClass) + "\n");
|
||||
ctx.next("// #InnerClasses:\n");
|
||||
if (classNode.innerClasses != null) {
|
||||
String ics = "";
|
||||
for (InnerClassNode icn : classNode.innerClasses) {
|
||||
ics += "// " + UnicodeUtils.escapeWithSpaces(icn.name) + " "
|
||||
+ UnicodeUtils.escapeWithSpaces(icn.outerName) + " "
|
||||
+ UnicodeUtils.escapeWithSpaces(icn.innerName)
|
||||
ics += "// " + UnicodeUtils.escapeWithSpaces(hs, icn.name) + " "
|
||||
+ UnicodeUtils.escapeWithSpaces(hs, icn.outerName) + " "
|
||||
+ UnicodeUtils.escapeWithSpaces(hs, icn.innerName)
|
||||
+ (icn.access == 0 ? "" : " " + ClassUtil.getAccessFlagsFull(icn.access).trim()) + "\n";
|
||||
}
|
||||
ctx.next(ics);
|
||||
}
|
||||
ctx.next(ClassUtil.getAccessFlagsClass(classNode.access) + UnicodeUtils.escapeWithSpaces(classNode.name)
|
||||
ctx.next(ClassUtil.getAccessFlagsClass(classNode.access) + UnicodeUtils.escapeWithSpaces(hs, classNode.name)
|
||||
+ " ");
|
||||
ctx.next("extends " + UnicodeUtils.escapeWithSpaces(classNode.superName) + " ");
|
||||
ctx.next("extends " + UnicodeUtils.escapeWithSpaces(hs, classNode.superName) + " ");
|
||||
if (classNode.interfaces != null && !classNode.interfaces.isEmpty()) {
|
||||
String interfaceStr = "";
|
||||
for (String interfc : classNode.interfaces) {
|
||||
if (interfaceStr.isEmpty()) {
|
||||
interfaceStr += UnicodeUtils.escapeWithSpaces(interfc);
|
||||
interfaceStr += UnicodeUtils.escapeWithSpaces(hs, interfc);
|
||||
} else {
|
||||
interfaceStr += ", " + UnicodeUtils.escapeWithSpaces(interfc);
|
||||
interfaceStr += ", " + UnicodeUtils.escapeWithSpaces(hs, interfc);
|
||||
}
|
||||
}
|
||||
if (!interfaceStr.isEmpty())
|
||||
ctx.next("implements " + interfaceStr + " ");
|
||||
}
|
||||
ctx.next("{\n// #SourceFile: "
|
||||
+ (classNode.sourceFile == null ? "null" : UnicodeUtils.escape(classNode.sourceFile))
|
||||
+ "\n\n// #Fields\n");
|
||||
ctx.next(doFields(classNode.fields, nodeToFind, lineFound));
|
||||
+ (classNode.sourceFile == null ? "null" : UnicodeUtils.escape(hs, classNode.sourceFile)) + "\n");
|
||||
int hugeIdx = ctx.next("");
|
||||
ctx.next("\n// #Fields\n");
|
||||
ctx.next(doFields(classNode.fields, nodeToFind, lineFound, hs));
|
||||
ctx.next("\n// #Methods\n");
|
||||
ctx.next(doMethods(classNode.methods, classNode.name, nodeToFind, lineFound));
|
||||
ctx.next(doMethods(classNode.methods, classNode.name, nodeToFind, lineFound, hs));
|
||||
ctx.next("}\n");
|
||||
|
||||
if (!hs.isEmpty())
|
||||
ctx.set(hugeIdx, hs.makeStringsList());
|
||||
return new DisassembleTuple(ctx.finish(), lineFound.get());
|
||||
} catch (Throwable e) {
|
||||
return new DisassembleTuple("Class couldn't be decompiled:\n" + e.getClass().getName() + ": "
|
||||
@@ -139,12 +148,12 @@ public class Disassembler {
|
||||
}
|
||||
}
|
||||
|
||||
private static String doAnnotations(List<AnnotationNode> annotations) {
|
||||
private static String doAnnotations(List<AnnotationNode> annotations, HugeStrings hs) {
|
||||
if (annotations == null)
|
||||
return "";
|
||||
StringContext ctx = new StringContext(annotations.size());
|
||||
for (AnnotationNode annotationNode : annotations) {
|
||||
String s = "@" + UnicodeUtils.escapeWithSpaces(annotationNode.desc);
|
||||
String s = "@" + UnicodeUtils.escapeWithSpaces(hs, annotationNode.desc);
|
||||
if (annotationNode.values != null && !annotationNode.values.isEmpty()) {
|
||||
s += " (";
|
||||
boolean valBefore = true;
|
||||
@@ -159,10 +168,10 @@ public class Disassembler {
|
||||
boolean w8ing = false;
|
||||
for (String rofl : arr) {
|
||||
if (!w8ing) {
|
||||
s += UnicodeUtils.escapeWithSpaces(rofl) + "/";
|
||||
s += UnicodeUtils.escapeWithSpaces(hs, rofl) + "/";
|
||||
w8ing = true;
|
||||
} else {
|
||||
s += UnicodeUtils.escapeWithSpaces(rofl) + "]";
|
||||
s += UnicodeUtils.escapeWithSpaces(hs, rofl) + "]";
|
||||
}
|
||||
}
|
||||
s += ", ";
|
||||
@@ -175,21 +184,21 @@ public class Disassembler {
|
||||
boolean w8ing = false;
|
||||
for (String rofl : arr) {
|
||||
if (!w8ing) {
|
||||
s += UnicodeUtils.escapeWithSpaces(rofl) + "/";
|
||||
s += UnicodeUtils.escapeWithSpaces(hs, rofl) + "/";
|
||||
w8ing = true;
|
||||
} else {
|
||||
s += UnicodeUtils.escapeWithSpaces(rofl);
|
||||
s += UnicodeUtils.escapeWithSpaces(hs, rofl);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s += "\"" + UnicodeUtils.escape(String.valueOf(obj)) + "\"";
|
||||
s += "\"" + UnicodeUtils.escape(hs, String.valueOf(obj)) + "\"";
|
||||
}
|
||||
s += ", ";
|
||||
}
|
||||
s = s.substring(0, s.length() - 2);
|
||||
s += " }]";
|
||||
} else if (o instanceof String) {
|
||||
s += "\"" + UnicodeUtils.escapeWithSpaces((String) o) + "\"], ";
|
||||
s += "\"" + UnicodeUtils.escapeWithSpaces(hs, (String) o) + "\"], ";
|
||||
} else {
|
||||
s += "(" + o.getClass().getName().replace(".", "/") + ") " + o + "], ";
|
||||
}
|
||||
@@ -207,19 +216,20 @@ public class Disassembler {
|
||||
}
|
||||
|
||||
private static String doMethods(List<MethodNode> methods, String className, Object nodeToFind,
|
||||
AtomicInteger lineFound) throws InterruptedException, ExecutionException {
|
||||
AtomicInteger lineFound, HugeStrings hs) throws InterruptedException, ExecutionException {
|
||||
boolean multithreaded = Main.INSTANCE.mntmMultithreaded.isSelected();
|
||||
Future<String>[] futures = new Future[methods.size()];
|
||||
for (int i = 0; i < futures.length; i++) {
|
||||
MethodNode mn = methods.get(i);
|
||||
futures[i] = exec.submit(new Callable<String>() {
|
||||
Callable<String> callable = new Callable<String>() {
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
String ms = "";
|
||||
try {
|
||||
ms += "\t// #Max: l:" + mn.maxLocals + " s:" + mn.maxStack + "\n";
|
||||
if (mn.signature != null)
|
||||
ms += "\t// #Signature: " + UnicodeUtils.escapeWithSpaces(mn.signature) + "\n";
|
||||
String[] dis = disassembleMethod(className, mn);
|
||||
ms += "\t// #Signature: " + UnicodeUtils.escapeWithSpaces(hs, mn.signature) + "\n";
|
||||
String[] dis = disassembleMethod(className, mn, hs);
|
||||
ms += dis[2];
|
||||
ms += dis[1];
|
||||
if (mn.visibleAnnotations != null && !mn.visibleAnnotations.isEmpty()) {
|
||||
@@ -239,10 +249,10 @@ public class Disassembler {
|
||||
boolean w8ing = false;
|
||||
for (String rofl : arr) {
|
||||
if (!w8ing) {
|
||||
ms += UnicodeUtils.escapeWithSpaces(rofl) + "/";
|
||||
ms += UnicodeUtils.escapeWithSpaces(hs, rofl) + "/";
|
||||
w8ing = true;
|
||||
} else {
|
||||
ms += UnicodeUtils.escapeWithSpaces(rofl) + "]";
|
||||
ms += UnicodeUtils.escapeWithSpaces(hs, rofl) + "]";
|
||||
}
|
||||
}
|
||||
ms += ", ";
|
||||
@@ -255,14 +265,15 @@ public class Disassembler {
|
||||
boolean w8ing = false;
|
||||
for (String rofl : arr) {
|
||||
if (!w8ing) {
|
||||
ms += UnicodeUtils.escapeWithSpaces(rofl) + "/";
|
||||
ms += UnicodeUtils.escapeWithSpaces(hs, rofl) + "/";
|
||||
w8ing = true;
|
||||
} else {
|
||||
ms += UnicodeUtils.escapeWithSpaces(rofl);
|
||||
ms += UnicodeUtils.escapeWithSpaces(hs, rofl);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ms += "\"" + UnicodeUtils.escape(String.valueOf(obj)) + "\"";
|
||||
ms += "\"" + UnicodeUtils.escape(hs, String.valueOf(obj))
|
||||
+ "\"";
|
||||
}
|
||||
ms += ", ";
|
||||
}
|
||||
@@ -284,15 +295,16 @@ public class Disassembler {
|
||||
if (mn.equals(nodeToFind)) {
|
||||
lineFound.set(ms.split("\\n").length);
|
||||
}
|
||||
ms += "\t" + ClassUtil.getAccessFlagsFull(mn.access) + UnicodeUtils.escapeWithSpaces(mn.name)
|
||||
+ " " + UnicodeUtils.escapeWithSpaces(mn.desc) + " ";
|
||||
ms += "\t" + ClassUtil.getAccessFlagsFull(mn.access)
|
||||
+ UnicodeUtils.escapeWithSpaces(hs, mn.name) + " "
|
||||
+ UnicodeUtils.escapeWithSpaces(hs, mn.desc) + " ";
|
||||
if (mn.exceptions != null && !mn.exceptions.isEmpty()) {
|
||||
String exceptionStr = "";
|
||||
for (String exc : mn.exceptions) {
|
||||
if (exceptionStr.isEmpty()) {
|
||||
exceptionStr += UnicodeUtils.escapeWithSpaces(exc);
|
||||
exceptionStr += UnicodeUtils.escapeWithSpaces(hs, exc);
|
||||
} else {
|
||||
exceptionStr += ", " + UnicodeUtils.escapeWithSpaces(exc);
|
||||
exceptionStr += ", " + UnicodeUtils.escapeWithSpaces(hs, exc);
|
||||
}
|
||||
}
|
||||
if (!exceptionStr.isEmpty())
|
||||
@@ -309,10 +321,13 @@ public class Disassembler {
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
});
|
||||
};
|
||||
futures[i] = multithreaded ? exec.submit(callable) : new FutureTask<>(callable);
|
||||
}
|
||||
StringContext ctx = new StringContext(futures.length);
|
||||
for (Future<String> f : futures) {
|
||||
if (f instanceof FutureTask)
|
||||
((FutureTask) f).run();
|
||||
ctx.next(f.get());
|
||||
}
|
||||
String s = ctx.finish();
|
||||
@@ -321,15 +336,15 @@ public class Disassembler {
|
||||
return s;
|
||||
}
|
||||
|
||||
private static String doFields(List<FieldNode> fields, Object nodeToFind, AtomicInteger lineFound) {
|
||||
private static String doFields(List<FieldNode> fields, Object nodeToFind, AtomicInteger lineFound, HugeStrings hs) {
|
||||
StringContext ctx = new StringContext(fields.size());
|
||||
for (FieldNode fn : fields) {
|
||||
String s = "";
|
||||
if (fn.signature != null)
|
||||
s += "\t// #Signature: " + UnicodeUtils.escapeWithSpaces(fn.signature) + "\n";
|
||||
s += "\t// #Signature: " + UnicodeUtils.escapeWithSpaces(hs, fn.signature) + "\n";
|
||||
if (fn.visibleAnnotations != null && !fn.visibleAnnotations.isEmpty()) {
|
||||
for (AnnotationNode annotationNode : fn.visibleAnnotations) {
|
||||
s += "\t@" + UnicodeUtils.escapeWithSpaces(annotationNode.desc);
|
||||
s += "\t@" + UnicodeUtils.escapeWithSpaces(hs, annotationNode.desc);
|
||||
if (annotationNode.values != null && !annotationNode.values.isEmpty()) {
|
||||
s += " (";
|
||||
boolean valBefore = true;
|
||||
@@ -344,10 +359,10 @@ public class Disassembler {
|
||||
boolean w8ing = false;
|
||||
for (String rofl : arr) {
|
||||
if (!w8ing) {
|
||||
s += UnicodeUtils.escapeWithSpaces(rofl) + "/";
|
||||
s += UnicodeUtils.escapeWithSpaces(hs, rofl) + "/";
|
||||
w8ing = true;
|
||||
} else {
|
||||
s += UnicodeUtils.escapeWithSpaces(rofl) + "]";
|
||||
s += UnicodeUtils.escapeWithSpaces(hs, rofl) + "]";
|
||||
}
|
||||
}
|
||||
s += ", ";
|
||||
@@ -360,14 +375,14 @@ public class Disassembler {
|
||||
boolean w8ing = false;
|
||||
for (String rofl : arr) {
|
||||
if (!w8ing) {
|
||||
s += UnicodeUtils.escapeWithSpaces(rofl) + "/";
|
||||
s += UnicodeUtils.escapeWithSpaces(hs, rofl) + "/";
|
||||
w8ing = true;
|
||||
} else {
|
||||
s += UnicodeUtils.escapeWithSpaces(rofl);
|
||||
s += UnicodeUtils.escapeWithSpaces(hs, rofl);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s += "\"" + UnicodeUtils.escape(String.valueOf(obj)) + "\"";
|
||||
s += "\"" + UnicodeUtils.escape(hs, String.valueOf(obj)) + "\"";
|
||||
}
|
||||
s += ", ";
|
||||
}
|
||||
@@ -390,9 +405,9 @@ public class Disassembler {
|
||||
lineFound.set(s.split("\\n").length);
|
||||
}
|
||||
s += "\t" + ClassUtil.getAccessFlagsFull(fn.access).replace("varargs", "transient")
|
||||
+ UnicodeUtils.escapeWithSpaces(fn.desc) + " " + UnicodeUtils.escapeWithSpaces(fn.name);
|
||||
+ UnicodeUtils.escapeWithSpaces(hs, fn.desc) + " " + UnicodeUtils.escapeWithSpaces(hs, fn.name);
|
||||
if (fn.value != null) {
|
||||
s += " = " + ClassUtil.getDecompiledValue(fn.value, fn.desc, true);
|
||||
s += " = " + ClassUtil.getDecompiledValue(fn.value, fn.desc, true, hs);
|
||||
}
|
||||
s += "\n";
|
||||
ctx.next(s);
|
||||
@@ -400,7 +415,7 @@ public class Disassembler {
|
||||
return ctx.finish();
|
||||
}
|
||||
|
||||
private static String[] disassembleMethod(String className, MethodNode mn) {
|
||||
private static String[] disassembleMethod(String className, MethodNode mn, HugeStrings hs) {
|
||||
HashMap<Label, Integer> labels = new HashMap<Label, Integer>();
|
||||
String localVarTable;
|
||||
String tryCatchTable;
|
||||
@@ -414,10 +429,10 @@ public class Disassembler {
|
||||
StringContext ctx = new StringContext(list.size() + 1);
|
||||
ctx.next("\t// #LocalVars:\n");
|
||||
for (LocalVariableNode lvn : list) {
|
||||
ctx.next("\t// " + UnicodeUtils.escapeWithSpaces(lvn.name) + ": "
|
||||
+ UnicodeUtils.escapeWithSpaces(lvn.desc) + " i:" + lvn.index + " s:"
|
||||
ctx.next("\t// " + UnicodeUtils.escapeWithSpaces(hs, lvn.name) + ": "
|
||||
+ UnicodeUtils.escapeWithSpaces(hs, lvn.desc) + " i:" + lvn.index + " s:"
|
||||
+ labels.get(lvn.start.getLabel()) + " e:" + labels.get(lvn.end.getLabel()) + " sig:"
|
||||
+ UnicodeUtils.escapeWithSpaces(lvn.signature) + "\n");
|
||||
+ UnicodeUtils.escapeWithSpaces(hs, lvn.signature) + "\n");
|
||||
}
|
||||
localVarTable = ctx.finish();
|
||||
} else
|
||||
@@ -427,8 +442,9 @@ public class Disassembler {
|
||||
StringContext ctx = new StringContext(list.size() + 1);
|
||||
ctx.next("\t// #TryCatch:\n");
|
||||
for (TryCatchBlockNode tcbn : mn.tryCatchBlocks) {
|
||||
ctx.next("\t// " + UnicodeUtils.escapeWithSpaces(tcbn.type) + " s:" + labels.get(tcbn.start.getLabel())
|
||||
+ " e:" + labels.get(tcbn.end.getLabel()) + " h:" + labels.get(tcbn.handler.getLabel()) + "\n");
|
||||
ctx.next("\t// " + UnicodeUtils.escapeWithSpaces(hs, tcbn.type) + " s:"
|
||||
+ labels.get(tcbn.start.getLabel()) + " e:" + labels.get(tcbn.end.getLabel()) + " h:"
|
||||
+ labels.get(tcbn.handler.getLabel()) + "\n");
|
||||
}
|
||||
tryCatchTable = ctx.finish();
|
||||
} else
|
||||
@@ -436,7 +452,7 @@ public class Disassembler {
|
||||
AbstractInsnNode[] insns = mn.instructions.toArray();
|
||||
StringContext ctx = new StringContext(insns.length);
|
||||
for (AbstractInsnNode n : insns) {
|
||||
ctx.next(disassembleInstruction(n, labels));
|
||||
ctx.next(disassembleInstruction(n, labels, hs));
|
||||
}
|
||||
return new String[] { ctx.finish(), localVarTable, tryCatchTable };
|
||||
}
|
||||
@@ -444,17 +460,17 @@ public class Disassembler {
|
||||
public static final HashMap<Class, InstructionInterface> iiMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
iiMap.put(FieldInsnNode.class, (n, labels) -> {
|
||||
iiMap.put(FieldInsnNode.class, (n, labels, hs) -> {
|
||||
FieldInsnNode node = (FieldInsnNode) n;
|
||||
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
|
||||
+ UnicodeUtils.escapeWithSpaces(node.desc) + " " + UnicodeUtils.escapeWithSpaces(node.owner) + "/"
|
||||
+ UnicodeUtils.escapeWithSpaces(node.name).replace("/", "\\u002F") + "\n";
|
||||
+ UnicodeUtils.escapeWithSpaces(hs, node.desc) + " " + UnicodeUtils.escapeWithSpaces(hs, node.owner)
|
||||
+ "/" + UnicodeUtils.escapeWithSpaces(hs, node.name).replace("/", "\\u002F") + "\n";
|
||||
});
|
||||
iiMap.put(LabelNode.class, (n, labels) -> {
|
||||
iiMap.put(LabelNode.class, (n, labels, hs) -> {
|
||||
LabelNode node = (LabelNode) n;
|
||||
return "\t\t// label " + labels.get(node.getLabel()) + "\n";
|
||||
});
|
||||
iiMap.put(FrameNode.class, (n, labels) -> {
|
||||
iiMap.put(FrameNode.class, (n, labels, hs) -> {
|
||||
FrameNode node = (FrameNode) n;
|
||||
String type = "";
|
||||
switch (node.type) {
|
||||
@@ -485,7 +501,7 @@ public class Disassembler {
|
||||
arr.add(null);
|
||||
} else {
|
||||
if (o instanceof String) {
|
||||
arr.add("\"" + UnicodeUtils.escapeWithSpaces((String) o) + "\"");
|
||||
arr.add("\"" + UnicodeUtils.escapeWithSpaces(hs, (String) o) + "\"");
|
||||
} else if (o instanceof LabelNode) {
|
||||
arr.add("(label) " + labels.get(((LabelNode) o).getLabel()));
|
||||
} else if (o instanceof Integer) {
|
||||
@@ -511,7 +527,7 @@ public class Disassembler {
|
||||
arr.add(null);
|
||||
} else {
|
||||
if (o instanceof String) {
|
||||
arr.add("\"" + UnicodeUtils.escapeWithSpaces((String) o) + "\"");
|
||||
arr.add("\"" + UnicodeUtils.escapeWithSpaces(hs, (String) o) + "\"");
|
||||
} else if (o instanceof LabelNode) {
|
||||
arr.add("(label) " + labels.get(((LabelNode) o).getLabel()));
|
||||
} else if (o instanceof Integer) {
|
||||
@@ -532,18 +548,18 @@ public class Disassembler {
|
||||
s += "\n";
|
||||
return s;
|
||||
});
|
||||
iiMap.put(LineNumberNode.class, (n, labels) -> {
|
||||
iiMap.put(LineNumberNode.class, (n, labels, hs) -> {
|
||||
LineNumberNode node = (LineNumberNode) n;
|
||||
return "\t\t// line " + node.line + " " + labels.get(node.start.getLabel()) + "\n";
|
||||
});
|
||||
iiMap.put(InvokeDynamicInsnNode.class, (n, labels) -> {
|
||||
iiMap.put(InvokeDynamicInsnNode.class, (n, labels, hs) -> {
|
||||
InvokeDynamicInsnNode node = (InvokeDynamicInsnNode) n;
|
||||
String s = "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " [\n\t\t\tname: "
|
||||
+ UnicodeUtils.escapeWithSpaces(node.name).replace("/", "\\u002F") + "\n\t\t\tdesc: "
|
||||
+ UnicodeUtils.escapeWithSpaces(node.desc) + "\n\t\t\tHandle: [\n\t\t\t\tname: "
|
||||
+ UnicodeUtils.escapeWithSpaces(node.bsm.getName()) + "\n\t\t\t\towner: "
|
||||
+ UnicodeUtils.escapeWithSpaces(node.bsm.getOwner()) + "\n\t\t\t\tdesc: "
|
||||
+ UnicodeUtils.escapeWithSpaces(node.bsm.getDesc()) + "\n\t\t\t\tisInterface: "
|
||||
+ UnicodeUtils.escapeWithSpaces(hs, node.name).replace("/", "\\u002F") + "\n\t\t\tdesc: "
|
||||
+ UnicodeUtils.escapeWithSpaces(hs, node.desc) + "\n\t\t\tHandle: [\n\t\t\t\tname: "
|
||||
+ UnicodeUtils.escapeWithSpaces(hs, node.bsm.getName()) + "\n\t\t\t\towner: "
|
||||
+ UnicodeUtils.escapeWithSpaces(hs, node.bsm.getOwner()) + "\n\t\t\t\tdesc: "
|
||||
+ UnicodeUtils.escapeWithSpaces(hs, node.bsm.getDesc()) + "\n\t\t\t\tisInterface: "
|
||||
+ node.bsm.isInterface() + "\n\t\t\t\ttag: " + OpcodesReverse.reverseHandleOpcode(node.bsm.getTag())
|
||||
+ "\n\t\t\t]\n\t\t\targs: [\n";
|
||||
for (Object l : node.bsmArgs) {
|
||||
@@ -555,40 +571,41 @@ public class Disassembler {
|
||||
// Reflection
|
||||
s += "\t\t\t\tType: [\n\t\t\t\t\ttype: " + ClassUtil.getClassNameFromType(type)
|
||||
+ "\n\t\t\t\t\tstart: " + valueBegin + "\n\t\t\t\t\tend: " + valueEnd + "\n\t\t\t\t\tbuf: "
|
||||
+ ClassUtil.getDecompiledValue(buf, "");
|
||||
+ ClassUtil.getDecompiledValue(buf, "", hs);
|
||||
s += "\n\t\t\t\t]\n";
|
||||
} else if (l instanceof Handle) {
|
||||
Handle h = (Handle) l;
|
||||
s += "\t\t\t\tHandle: [\n\t\t\t\t\tname: "
|
||||
+ UnicodeUtils.escapeWithSpaces(h.getName()).replace("/", "\\u002F") + "\n\t\t\t\t\towner: "
|
||||
+ UnicodeUtils.escapeWithSpaces(h.getOwner()) + "\n\t\t\t\t\tdesc: "
|
||||
+ UnicodeUtils.escapeWithSpaces(h.getDesc()) + "\n\t\t\t\t\tisInterface: " + h.isInterface()
|
||||
+ "\n\t\t\t\t\ttag: " + OpcodesReverse.reverseHandleOpcode(h.getTag());
|
||||
+ UnicodeUtils.escapeWithSpaces(hs, h.getName()).replace("/", "\\u002F")
|
||||
+ "\n\t\t\t\t\towner: " + UnicodeUtils.escapeWithSpaces(hs, h.getOwner())
|
||||
+ "\n\t\t\t\t\tdesc: " + UnicodeUtils.escapeWithSpaces(hs, h.getDesc())
|
||||
+ "\n\t\t\t\t\tisInterface: " + h.isInterface() + "\n\t\t\t\t\ttag: "
|
||||
+ OpcodesReverse.reverseHandleOpcode(h.getTag());
|
||||
s += "\n\t\t\t\t]\n";
|
||||
} else {
|
||||
s += "\t\t\t\t" + ClassUtil.getDecompiledValue(l, "") + "\n";
|
||||
s += "\t\t\t\t" + ClassUtil.getDecompiledValue(l, "", hs) + "\n";
|
||||
}
|
||||
}
|
||||
s += "\t\t\t]\n\t\t]\n";
|
||||
return s;
|
||||
});
|
||||
iiMap.put(MethodInsnNode.class, (n, labels) -> {
|
||||
iiMap.put(MethodInsnNode.class, (n, labels, hs) -> {
|
||||
MethodInsnNode node = (MethodInsnNode) n;
|
||||
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
|
||||
+ UnicodeUtils.escapeWithSpaces(node.desc) + " " + UnicodeUtils.escapeWithSpaces(node.owner) + "/"
|
||||
+ UnicodeUtils.escapeWithSpaces(node.name).replace("/", "\\u002F") + "\n";
|
||||
+ UnicodeUtils.escapeWithSpaces(hs, node.desc) + " " + UnicodeUtils.escapeWithSpaces(hs, node.owner)
|
||||
+ "/" + UnicodeUtils.escapeWithSpaces(hs, node.name).replace("/", "\\u002F") + "\n";
|
||||
});
|
||||
iiMap.put(TypeInsnNode.class, (n, labels) -> {
|
||||
iiMap.put(TypeInsnNode.class, (n, labels, hs) -> {
|
||||
TypeInsnNode node = (TypeInsnNode) n;
|
||||
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
|
||||
+ UnicodeUtils.escapeWithSpaces(node.desc) + "\n";
|
||||
+ UnicodeUtils.escapeWithSpaces(hs, node.desc) + "\n";
|
||||
});
|
||||
iiMap.put(MultiANewArrayInsnNode.class, (n, labels) -> {
|
||||
iiMap.put(MultiANewArrayInsnNode.class, (n, labels, hs) -> {
|
||||
MultiANewArrayInsnNode node = (MultiANewArrayInsnNode) n;
|
||||
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
|
||||
+ UnicodeUtils.escapeWithSpaces(node.desc) + " " + node.dims + "\n";
|
||||
+ UnicodeUtils.escapeWithSpaces(hs, node.desc) + " " + node.dims + "\n";
|
||||
});
|
||||
iiMap.put(LdcInsnNode.class, (n, labels) -> {
|
||||
iiMap.put(LdcInsnNode.class, (n, labels, hs) -> {
|
||||
LdcInsnNode node = (LdcInsnNode) n;
|
||||
if (node.cst instanceof Type) {
|
||||
Type type = (Type) node.cst;
|
||||
@@ -598,23 +615,29 @@ public class Disassembler {
|
||||
// Reflection
|
||||
String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " Type: [\n\t\t\ttype: "
|
||||
+ ClassUtil.getClassNameFromType(type) + "\n\t\t\tstart: " + valueBegin + "\n\t\t\tend: "
|
||||
+ valueEnd + "\n\t\t\tbuf: " + ClassUtil.getDecompiledValue(buf, "");
|
||||
+ valueEnd + "\n\t\t\tbuf: " + ClassUtil.getDecompiledValue(buf, "", hs);
|
||||
s += "\n\t\t]\n";
|
||||
return s;
|
||||
} else {
|
||||
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
|
||||
+ ClassUtil.getDecompiledValue(node.cst, "") + "\n";
|
||||
String decomp = ClassUtil.getDecompiledValue(node.cst, "", hs);
|
||||
if (node.cst instanceof String) {
|
||||
if (decomp.startsWith("\"#") && decomp.endsWith("\""))
|
||||
decomp = decomp.substring(1, decomp.length() - 1);
|
||||
else if (decomp.startsWith("\"\\u0023"))
|
||||
decomp = "\"#" + decomp.substring(7);
|
||||
}
|
||||
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + decomp + "\n";
|
||||
}
|
||||
});
|
||||
iiMap.put(VarInsnNode.class, (n, labels) -> {
|
||||
iiMap.put(VarInsnNode.class, (n, labels, hs) -> {
|
||||
VarInsnNode node = (VarInsnNode) n;
|
||||
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.var + "\n";
|
||||
});
|
||||
iiMap.put(InsnNode.class, (n, labels) -> {
|
||||
iiMap.put(InsnNode.class, (n, labels, hs) -> {
|
||||
InsnNode node = (InsnNode) n;
|
||||
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + "\n";
|
||||
});
|
||||
iiMap.put(IntInsnNode.class, (n, labels) -> {
|
||||
iiMap.put(IntInsnNode.class, (n, labels, hs) -> {
|
||||
IntInsnNode node = (IntInsnNode) n;
|
||||
if (n.getOpcode() == Opcodes.NEWARRAY) {
|
||||
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " "
|
||||
@@ -623,12 +646,12 @@ public class Disassembler {
|
||||
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.operand + "\n";
|
||||
}
|
||||
});
|
||||
iiMap.put(JumpInsnNode.class, (n, labels) -> {
|
||||
iiMap.put(JumpInsnNode.class, (n, labels, hs) -> {
|
||||
JumpInsnNode node = (JumpInsnNode) n;
|
||||
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + labels.get(node.label.getLabel())
|
||||
+ "\n";
|
||||
});
|
||||
iiMap.put(TableSwitchInsnNode.class, (n, labels) -> {
|
||||
iiMap.put(TableSwitchInsnNode.class, (n, labels, hs) -> {
|
||||
TableSwitchInsnNode node = (TableSwitchInsnNode) n;
|
||||
String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " [\n\t\t\tmin: " + node.min
|
||||
+ "\n\t\t\tmax: " + node.max + "\n\t\t\tdefault: " + labels.get(node.dflt.getLabel())
|
||||
@@ -639,7 +662,7 @@ public class Disassembler {
|
||||
s += "\t\t\t]\n\t\t]\n";
|
||||
return s;
|
||||
});
|
||||
iiMap.put(LookupSwitchInsnNode.class, (n, labels) -> {
|
||||
iiMap.put(LookupSwitchInsnNode.class, (n, labels, hs) -> {
|
||||
LookupSwitchInsnNode node = (LookupSwitchInsnNode) n;
|
||||
String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " [\n\t\t\tdefault: "
|
||||
+ labels.get(node.dflt.getLabel()) + "\n\t\t\tkeys: [\n";
|
||||
@@ -653,20 +676,20 @@ public class Disassembler {
|
||||
s += "\t\t\t]\n\t\t]\n";
|
||||
return s;
|
||||
});
|
||||
iiMap.put(IincInsnNode.class, (n, labels) -> {
|
||||
iiMap.put(IincInsnNode.class, (n, labels, hs) -> {
|
||||
IincInsnNode node = (IincInsnNode) n;
|
||||
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.var + " " + node.incr + "\n";
|
||||
});
|
||||
}
|
||||
|
||||
static interface InstructionInterface {
|
||||
String apply(AbstractInsnNode n, HashMap<Label, Integer> labels);
|
||||
String apply(AbstractInsnNode n, HashMap<Label, Integer> labels, HugeStrings hs);
|
||||
}
|
||||
|
||||
public static String disassembleInstruction(AbstractInsnNode n, HashMap<Label, Integer> labels) {
|
||||
public static String disassembleInstruction(AbstractInsnNode n, HashMap<Label, Integer> labels, HugeStrings hs) {
|
||||
InstructionInterface ii = iiMap.get(n.getClass());
|
||||
if (ii != null)
|
||||
return ii.apply(n, labels);
|
||||
return ii.apply(n, labels, hs);
|
||||
else
|
||||
return "\t\tNOT HANDLED! " + OpcodesReverse.reverseOpcode(n.getOpcode()) + " "
|
||||
+ n.getClass().getSimpleName() + "\n";
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package me.ByteEdit.edit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import me.ByteEdit.utils.UnicodeUtils;
|
||||
|
||||
public class HugeStrings {
|
||||
|
||||
public static int THRESHOLD = 1000;
|
||||
private final HashMap<String, HugeData> map = new HashMap<>();
|
||||
|
||||
public String onString(String s) {
|
||||
synchronized (map) {
|
||||
HugeData i = map.get(s);
|
||||
if (i == null)
|
||||
map.put(s, i = new HugeData(map.size(), UnicodeUtils.escape(this, s, true)));
|
||||
return "#" + Integer.toString(i.id);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return map.isEmpty();
|
||||
}
|
||||
|
||||
public String makeStringsList() {
|
||||
StringContext ctx = new StringContext(map.size());
|
||||
List<HugeData> list = new ArrayList<>(map.values());
|
||||
list.sort((o1, o2) -> Integer.compare(o1.id, o2.id));
|
||||
for (HugeData hd : list) {
|
||||
StringBuilder sb = new StringBuilder(20 + hd.escaped.length());
|
||||
sb.append('#');
|
||||
sb.append(Integer.toString(hd.id));
|
||||
sb.append(": ");
|
||||
sb.append(hd.escaped);
|
||||
sb.append('\n');
|
||||
ctx.next(sb.toString());
|
||||
}
|
||||
return ctx.finish();
|
||||
}
|
||||
|
||||
private static class HugeData {
|
||||
int id;
|
||||
String escaped;
|
||||
|
||||
public HugeData(int id, String escaped) {
|
||||
this.id = id;
|
||||
this.escaped = escaped;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package me.ByteEdit.edit;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class HugeStringsRev {
|
||||
|
||||
private final HashMap<Integer, String> map = new HashMap<>();
|
||||
|
||||
public void add(int i, String s) {
|
||||
map.put(Integer.valueOf(i), s);
|
||||
}
|
||||
|
||||
public String get(int i) {
|
||||
String s = map.get(Integer.valueOf(i));
|
||||
if (s == null)
|
||||
s = "#" + Integer.toString(i);
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,8 +16,16 @@ public class StringContext {
|
||||
arrs = new String[amt];
|
||||
}
|
||||
|
||||
public void next(String s) {
|
||||
public int next(String s) {
|
||||
int i = idx;
|
||||
len += (arrs[idx++] = s).length();
|
||||
return i;
|
||||
}
|
||||
|
||||
public void set(int i, String s) {
|
||||
if (arrs[i] != null)
|
||||
len -= arrs[i].length();
|
||||
len += (arrs[i] = s).length();
|
||||
}
|
||||
|
||||
public String finish() {
|
||||
|
||||
+177
-36
@@ -17,11 +17,14 @@ import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -37,6 +40,8 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.swing.ButtonGroup;
|
||||
import javax.swing.JCheckBoxMenuItem;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFileChooser;
|
||||
@@ -46,6 +51,7 @@ import javax.swing.JMenuBar;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JRadioButtonMenuItem;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.JTree;
|
||||
@@ -72,7 +78,9 @@ import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
|
||||
import org.fife.ui.rsyntaxtextarea.folding.CurlyFoldParser;
|
||||
import org.fife.ui.rsyntaxtextarea.folding.FoldParserManager;
|
||||
import org.fife.ui.rtextarea.RTextArea;
|
||||
import org.fife.ui.rtextarea.RTextScrollPane;
|
||||
import org.fife.ui.rtextarea.ToolTipSupplier;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
@@ -81,7 +89,6 @@ import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import me.ByteEdit.boxes.CompilationBox;
|
||||
import me.ByteEdit.boxes.GlobalSearchBox;
|
||||
import me.ByteEdit.boxes.OptionBox;
|
||||
import me.ByteEdit.boxes.RenameBox;
|
||||
import me.ByteEdit.boxes.SearchBox;
|
||||
import me.ByteEdit.boxes.ThemeBox;
|
||||
@@ -90,6 +97,7 @@ import me.ByteEdit.boxes.UnicodeBox;
|
||||
import me.ByteEdit.edit.Assembler;
|
||||
import me.ByteEdit.edit.Disassembler;
|
||||
import me.ByteEdit.edit.Disassembler.DisassembleTuple;
|
||||
import me.ByteEdit.edit.HugeStrings;
|
||||
import me.ByteEdit.utils.ClassUtil;
|
||||
import me.ByteEdit.utils.OpcodesReverse;
|
||||
import me.ByteEdit.utils.UnicodeUtils;
|
||||
@@ -107,7 +115,6 @@ public class Main extends JFrame {
|
||||
public static GlobalSearchBox globalSearchBox;
|
||||
public static SearchBox searchBox;
|
||||
public static TypeOpenBox typeOpenBox;
|
||||
public static OptionBox optionBox;
|
||||
public static UnicodeBox unicodeBox;
|
||||
public static RenameBox renameBox;
|
||||
public static CompilationBox compilationBox;
|
||||
@@ -116,6 +123,32 @@ public class Main extends JFrame {
|
||||
public static RTextScrollPane scrollPane_ByteEdit;
|
||||
public static File saveFolder;
|
||||
|
||||
private static final Pattern SLASH = Pattern.compile("/");
|
||||
private JMenuBar menuBar;
|
||||
private JMenu mnFile;
|
||||
private JMenuItem mntmOpenJar;
|
||||
private JMenuItem mntmSaveBytecode;
|
||||
private JMenuItem mntmSaveJar;
|
||||
private JMenu mnWindow;
|
||||
private JMenuItem mntmThemes;
|
||||
private JMenuItem mntmSearchMembers;
|
||||
private JMenuItem mntmSearch;
|
||||
private JMenuItem mntmOpenType;
|
||||
private JMenuItem mntmUnicode;
|
||||
private JMenuItem mntmCompiler;
|
||||
private JMenu mnSearch;
|
||||
private JMenu mnOptions;
|
||||
private JCheckBoxMenuItem mntmComputeFrames;
|
||||
private JCheckBoxMenuItem mntmComputeMax;
|
||||
private JMenu mnStringLimit;
|
||||
private JRadioButtonMenuItem rdbtnmntm0;
|
||||
private JMenuItem rdbtnmntm100;
|
||||
private JMenuItem rdbtnmntm1000;
|
||||
private JMenuItem rdbtnmntm500;
|
||||
private JMenuItem rdbtnmntm5000;
|
||||
private JMenuItem rdbtnmntm10000;
|
||||
public JCheckBoxMenuItem mntmMultithreaded;
|
||||
|
||||
public static final Object treeLock = new Object();
|
||||
|
||||
/**
|
||||
@@ -209,7 +242,6 @@ public class Main extends JFrame {
|
||||
globalSearchBox = new GlobalSearchBox();
|
||||
searchBox = new SearchBox();
|
||||
typeOpenBox = new TypeOpenBox();
|
||||
optionBox = new OptionBox();
|
||||
unicodeBox = new UnicodeBox();
|
||||
renameBox = new RenameBox();
|
||||
compilationBox = new CompilationBox();
|
||||
@@ -217,7 +249,6 @@ public class Main extends JFrame {
|
||||
ThemeManager.registerFrames(globalSearchBox);
|
||||
ThemeManager.registerFrames(searchBox);
|
||||
ThemeManager.registerFrames(typeOpenBox);
|
||||
ThemeManager.registerFrames(optionBox);
|
||||
ThemeManager.registerFrames(unicodeBox);
|
||||
ThemeManager.registerFrames(renameBox);
|
||||
ThemeManager.registerFrames(compilationBox);
|
||||
@@ -278,7 +309,6 @@ public class Main extends JFrame {
|
||||
globalSearchBox.setVisible(false);
|
||||
searchBox.setVisible(false);
|
||||
typeOpenBox.setVisible(false);
|
||||
optionBox.setVisible(false);
|
||||
unicodeBox.setVisible(false);
|
||||
renameBox.setVisible(false);
|
||||
compilationBox.setVisible(false);
|
||||
@@ -336,6 +366,56 @@ public class Main extends JFrame {
|
||||
mntmCompiler = new JMenuItem("Compiler");
|
||||
mntmCompiler.addActionListener(e -> compilationBox.setVisible(true));
|
||||
mnWindow.add(mntmCompiler);
|
||||
|
||||
mnOptions = new JMenu("Options");
|
||||
menuBar.add(mnOptions);
|
||||
|
||||
mntmComputeFrames = new JCheckBoxMenuItem("Compute Frames");
|
||||
mnOptions.add(mntmComputeFrames);
|
||||
|
||||
mntmComputeMax = new JCheckBoxMenuItem("Compute Max");
|
||||
mnOptions.add(mntmComputeMax);
|
||||
|
||||
mntmMultithreaded = new JCheckBoxMenuItem("Multithreaded");
|
||||
mntmMultithreaded.setSelected(true);
|
||||
mnOptions.add(mntmMultithreaded);
|
||||
|
||||
mnStringLimit = new JMenu("Huge String Limit");
|
||||
mnOptions.add(mnStringLimit);
|
||||
|
||||
rdbtnmntm0 = new JRadioButtonMenuItem("0");
|
||||
rdbtnmntm0.addActionListener(e -> HugeStrings.THRESHOLD = 0);
|
||||
mnStringLimit.add(rdbtnmntm0);
|
||||
|
||||
rdbtnmntm100 = new JRadioButtonMenuItem("100");
|
||||
rdbtnmntm100.addActionListener(e -> HugeStrings.THRESHOLD = 100);
|
||||
mnStringLimit.add(rdbtnmntm100);
|
||||
|
||||
rdbtnmntm500 = new JRadioButtonMenuItem("500");
|
||||
rdbtnmntm500.addActionListener(e -> HugeStrings.THRESHOLD = 500);
|
||||
mnStringLimit.add(rdbtnmntm500);
|
||||
|
||||
rdbtnmntm1000 = new JRadioButtonMenuItem("1000");
|
||||
rdbtnmntm1000.addActionListener(e -> HugeStrings.THRESHOLD = 1000);
|
||||
rdbtnmntm1000.setSelected(true);
|
||||
mnStringLimit.add(rdbtnmntm1000);
|
||||
|
||||
rdbtnmntm5000 = new JRadioButtonMenuItem("5000");
|
||||
rdbtnmntm5000.addActionListener(e -> HugeStrings.THRESHOLD = 5000);
|
||||
mnStringLimit.add(rdbtnmntm5000);
|
||||
|
||||
rdbtnmntm10000 = new JRadioButtonMenuItem("10000");
|
||||
rdbtnmntm10000.addActionListener(e -> HugeStrings.THRESHOLD = 10000);
|
||||
mnStringLimit.add(rdbtnmntm10000);
|
||||
|
||||
ButtonGroup group = new ButtonGroup();
|
||||
group.add(rdbtnmntm0);
|
||||
group.add(rdbtnmntm100);
|
||||
group.add(rdbtnmntm500);
|
||||
group.add(rdbtnmntm1000);
|
||||
group.add(rdbtnmntm5000);
|
||||
group.add(rdbtnmntm10000);
|
||||
|
||||
contentPane = new JPanel();
|
||||
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||
setContentPane(contentPane);
|
||||
@@ -472,7 +552,6 @@ public class Main extends JFrame {
|
||||
globalSearchBox.setVisible(false);
|
||||
searchBox.setVisible(false);
|
||||
typeOpenBox.setVisible(false);
|
||||
optionBox.setVisible(false);
|
||||
unicodeBox.setVisible(false);
|
||||
renameBox.setVisible(false);
|
||||
compilationBox.setVisible(false);
|
||||
@@ -520,6 +599,84 @@ public class Main extends JFrame {
|
||||
txtByteEditView = new RSyntaxTextArea();
|
||||
ac.install(txtByteEditView);
|
||||
txtByteEditView.setCodeFoldingEnabled(true);
|
||||
// ToolTips for HugeStrings
|
||||
txtByteEditView.setToolTipSupplier(new ToolTipSupplier() {
|
||||
|
||||
@Override
|
||||
public String getToolTipText(RTextArea textArea, MouseEvent e) {
|
||||
int idx = textArea.viewToModel(e.getPoint());
|
||||
if (idx < 0)
|
||||
return null;
|
||||
int subIdx = Math.max(idx - 15, 0);
|
||||
int subLen = Math.min(30, textArea.getDocument().getLength() - subIdx);
|
||||
if (subLen <= 0)
|
||||
return null;
|
||||
try {
|
||||
String cut = textArea.getText(subIdx, subLen);
|
||||
int hashIdx = -1;
|
||||
for (int off = idx - subIdx; off >= 0; off--) {
|
||||
if (cut.charAt(off) == '#') {
|
||||
hashIdx = off;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hashIdx < 0) {
|
||||
for (int off = idx - subIdx; off < cut.length(); off++) {
|
||||
if (cut.charAt(off) == '#') {
|
||||
hashIdx = off;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hashIdx < 0)
|
||||
return null;
|
||||
if (hashIdx >= 5 && cut.substring(hashIdx - 5, hashIdx).equals("ldc \"")) // ldc "#..."
|
||||
return null;
|
||||
int numLen = 1;
|
||||
for (int i = hashIdx + 1; i < cut.length(); i++) {
|
||||
if (!(cut.charAt(i) - '0' >= 0 && cut.charAt(i) - '0' <= 9)) {
|
||||
break;
|
||||
}
|
||||
numLen++;
|
||||
}
|
||||
if (numLen < 2 || hashIdx > idx - subIdx || idx - subIdx - numLen >= hashIdx)
|
||||
return null;
|
||||
String hashNum = cut.substring(hashIdx, hashIdx + numLen);
|
||||
|
||||
String txt = txtByteEditView.getText();
|
||||
int len = 0;
|
||||
for (String asm : txt.split("\\/\\/ #Annotations:\n")) {
|
||||
len += 19; // "\\/\\/ #Annotations:\n".length()
|
||||
if (asm.isEmpty())
|
||||
continue;
|
||||
if (idx >= len && idx < len + asm.length()) {
|
||||
try (BufferedReader reader = new BufferedReader(new StringReader(asm))) {
|
||||
String s;
|
||||
while (!(s = reader.readLine()).startsWith("// #SourceFile: ")) {
|
||||
}
|
||||
while (!(s = reader.readLine()).equals("// #Fields")) {
|
||||
if (s.startsWith("#")) {
|
||||
String[] split = Assembler.SPACE.split(s, 2);
|
||||
if (hashNum.equals(split[0].substring(0, split[0].length() - 1))) {
|
||||
String toolTip = split[1];
|
||||
if (toolTip.length() > 500)
|
||||
toolTip = toolTip.substring(0, 500) + "...";
|
||||
return toolTip;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e1) {
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
len += asm.length();
|
||||
}
|
||||
}
|
||||
} catch (BadLocationException e1) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
txtByteEditView.addKeyListener(new KeyAdapter() {
|
||||
|
||||
@Override
|
||||
@@ -551,7 +708,6 @@ public class Main extends JFrame {
|
||||
KeyStroke ctrlT = KeyStroke.getKeyStroke(KeyEvent.VK_T, KeyEvent.CTRL_DOWN_MASK);
|
||||
KeyStroke ctrlS = KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_DOWN_MASK);
|
||||
KeyStroke ctrlG = KeyStroke.getKeyStroke(KeyEvent.VK_G, KeyEvent.CTRL_DOWN_MASK);
|
||||
KeyStroke ctrlO = KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_DOWN_MASK);
|
||||
KeyStroke ctrlU = KeyStroke.getKeyStroke(KeyEvent.VK_U, KeyEvent.CTRL_DOWN_MASK);
|
||||
KeyStroke ctrlR = KeyStroke.getKeyStroke(KeyEvent.VK_R, KeyEvent.CTRL_DOWN_MASK);
|
||||
KeyStroke ctrlE = KeyStroke.getKeyStroke(KeyEvent.VK_E, KeyEvent.CTRL_DOWN_MASK);
|
||||
@@ -574,8 +730,6 @@ public class Main extends JFrame {
|
||||
typeOpenBox.txtSearch.requestFocusInWindow();
|
||||
typeOpenBox.txtSearch.select(0, typeOpenBox.txtSearch.getText().length());
|
||||
}, ctrlT, JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
txtByteEditView.registerKeyboardAction(e -> optionBox.setVisible(true), ctrlO,
|
||||
JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
txtByteEditView.registerKeyboardAction(e -> unicodeBox.setVisible(true), ctrlU,
|
||||
JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
txtByteEditView.registerKeyboardAction(e -> compilationBox.setVisible(true), ctrlE,
|
||||
@@ -621,11 +775,11 @@ public class Main extends JFrame {
|
||||
line = line.substring(2);
|
||||
if (line.startsWith("invoke")) {
|
||||
String[] split = line.split(" ");
|
||||
String desc = UnicodeUtils.unescape(split[1]);
|
||||
String desc = UnicodeUtils.unescape(null, split[1], true);
|
||||
String target = split[2];
|
||||
int index = target.lastIndexOf("/");
|
||||
String className = UnicodeUtils.unescape(target.substring(0, index));
|
||||
String methodName = UnicodeUtils.unescape(target.substring(index + 1));
|
||||
String className = UnicodeUtils.unescape(null, target.substring(0, index), true);
|
||||
String methodName = UnicodeUtils.unescape(null, target.substring(index + 1), true);
|
||||
ClassNode classNode = classNodes.get(getFullName(className));
|
||||
if (classNode == null) {
|
||||
return;
|
||||
@@ -644,7 +798,7 @@ public class Main extends JFrame {
|
||||
}
|
||||
} else if (line.startsWith("new ")) {
|
||||
String[] split = line.split(" ");
|
||||
String className = UnicodeUtils.unescape(split[1]);
|
||||
String className = UnicodeUtils.unescape(null, split[1], true);
|
||||
ClassNode classNode = classNodes.get(getFullName(className));
|
||||
if (classNode == null) {
|
||||
return;
|
||||
@@ -653,11 +807,11 @@ public class Main extends JFrame {
|
||||
} else if (line.startsWith("getstatic ") || line.startsWith("putstatic ") || line.startsWith("getfield ")
|
||||
|| line.startsWith("putfield ")) {
|
||||
String[] split = line.split(" ");
|
||||
String desc = UnicodeUtils.unescape(split[1]);
|
||||
String desc = UnicodeUtils.unescape(null, split[1], true);
|
||||
String target = split[2];
|
||||
int index = target.lastIndexOf("/");
|
||||
String className = UnicodeUtils.unescape(target.substring(0, index));
|
||||
String fieldName = UnicodeUtils.unescape(target.substring(index + 1));
|
||||
String className = UnicodeUtils.unescape(null, target.substring(0, index), true);
|
||||
String fieldName = UnicodeUtils.unescape(null, target.substring(index + 1), true);
|
||||
ClassNode classNode = classNodes.get(getFullName(className));
|
||||
if (classNode == null) {
|
||||
return;
|
||||
@@ -721,10 +875,12 @@ public class Main extends JFrame {
|
||||
if (s.contains(" extends "))
|
||||
s = s.substring(0, s.lastIndexOf(" extends "));
|
||||
String[] split = s.split(" ");
|
||||
String className = UnicodeUtils.unescape(split[split.length - 1]);
|
||||
String className = UnicodeUtils.unescape(null, split[split.length - 1], true);
|
||||
renameBox.className = className;
|
||||
String name = UnicodeUtils.unescape(m.pattern() == renameableFieldPattern ? m.group(2) : m.group(1));
|
||||
String desc = UnicodeUtils.unescape(m.pattern() == renameableFieldPattern ? m.group(1) : m.group(2));
|
||||
String name = UnicodeUtils.unescape(null, m.pattern() == renameableFieldPattern ? m.group(2) : m.group(1),
|
||||
true);
|
||||
String desc = UnicodeUtils.unescape(null, m.pattern() == renameableFieldPattern ? m.group(1) : m.group(2),
|
||||
true);
|
||||
renameBox.name = name;
|
||||
renameBox.desc = desc;
|
||||
renameBox.txtName.setText(name);
|
||||
@@ -899,10 +1055,10 @@ public class Main extends JFrame {
|
||||
output.closeEntry();
|
||||
}
|
||||
int computeFlags = 0;
|
||||
if (optionBox.chckbxComputeFrames.isSelected()) {
|
||||
if (mntmComputeFrames.isSelected()) {
|
||||
computeFlags |= ClassWriter.COMPUTE_FRAMES;
|
||||
}
|
||||
if (optionBox.chckbxComputeMax.isSelected()) {
|
||||
if (mntmComputeMax.isSelected()) {
|
||||
computeFlags |= ClassWriter.COMPUTE_MAXS;
|
||||
}
|
||||
for (ClassNode node : classes) {
|
||||
@@ -939,21 +1095,6 @@ public class Main extends JFrame {
|
||||
return s + ".class";
|
||||
}
|
||||
|
||||
private static final Pattern SLASH = Pattern.compile("/");
|
||||
private JMenuBar menuBar;
|
||||
private JMenu mnFile;
|
||||
private JMenuItem mntmOpenJar;
|
||||
private JMenuItem mntmSaveBytecode;
|
||||
private JMenuItem mntmSaveJar;
|
||||
private JMenu mnWindow;
|
||||
private JMenuItem mntmThemes;
|
||||
private JMenuItem mntmSearchMembers;
|
||||
private JMenuItem mntmSearch;
|
||||
private JMenuItem mntmOpenType;
|
||||
private JMenuItem mntmUnicode;
|
||||
private JMenuItem mntmCompiler;
|
||||
private JMenu mnSearch;
|
||||
|
||||
class ArchiveTreeModel extends DefaultTreeModel {
|
||||
|
||||
public ArrayList<String> paths = new ArrayList<>();
|
||||
|
||||
@@ -6,6 +6,8 @@ import java.util.HashSet;
|
||||
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import me.ByteEdit.edit.HugeStrings;
|
||||
|
||||
public class ClassUtil {
|
||||
|
||||
public static final int ACC_PUBLIC = 0x0001;
|
||||
@@ -525,28 +527,29 @@ public class ClassUtil {
|
||||
public static final HashMap<Class, DecompilationInterface> diMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
diMap.put(String.class, (o, desc, escapeSpaces) -> "\""
|
||||
+ (escapeSpaces ? UnicodeUtils.escapeWithSpaces((String) o) : UnicodeUtils.escape((String) o)) + "\"");
|
||||
diMap.put(String.class, (o, desc, escapeSpaces, hs) -> "\""
|
||||
+ (escapeSpaces ? UnicodeUtils.escapeWithSpaces(hs, (String) o) : UnicodeUtils.escape(hs, (String) o))
|
||||
+ "\"");
|
||||
diMap.put(Integer.class,
|
||||
(o, desc, escape) -> desc.equals("Z") ? (((int) o) == 0 ? "false" : "true") : o.toString());
|
||||
diMap.put(Long.class, (o, desc, escape) -> o.toString() + "l");
|
||||
diMap.put(Float.class, (o, desc, escape) -> o.toString() + "f");
|
||||
(o, desc, escape, hs) -> desc.equals("Z") ? (((int) o) == 0 ? "false" : "true") : o.toString());
|
||||
diMap.put(Long.class, (o, desc, escape, hs) -> o.toString() + "l");
|
||||
diMap.put(Float.class, (o, desc, escape, hs) -> o.toString() + "f");
|
||||
}
|
||||
|
||||
static interface DecompilationInterface {
|
||||
String apply(Object o, String desc, boolean escape);
|
||||
String apply(Object o, String desc, boolean escape, HugeStrings hs);
|
||||
}
|
||||
|
||||
public static String getDecompiledValue(Object o, String desc, boolean escapeSpaces) {
|
||||
public static String getDecompiledValue(Object o, String desc, boolean escapeSpaces, HugeStrings hs) {
|
||||
DecompilationInterface di = diMap.get(o.getClass());
|
||||
if (di != null)
|
||||
return di.apply(o, desc, escapeSpaces);
|
||||
return di.apply(o, desc, escapeSpaces, hs);
|
||||
else
|
||||
return o.toString();
|
||||
}
|
||||
|
||||
public static String getDecompiledValue(Object o, String desc) {
|
||||
return getDecompiledValue(o, desc, false);
|
||||
public static String getDecompiledValue(Object o, String desc, HugeStrings hs) {
|
||||
return getDecompiledValue(o, desc, false, hs);
|
||||
}
|
||||
|
||||
public static Object getCastedValue(String o, String className) {
|
||||
|
||||
@@ -1,11 +1,26 @@
|
||||
package me.ByteEdit.utils;
|
||||
|
||||
import me.ByteEdit.edit.HugeStrings;
|
||||
import me.ByteEdit.edit.HugeStringsRev;
|
||||
|
||||
public class UnicodeUtils {
|
||||
|
||||
public static String unescape(String s) {
|
||||
public static String unescape(HugeStringsRev hsr, String s) {
|
||||
return unescape(hsr, s, false);
|
||||
}
|
||||
|
||||
public static String unescape(HugeStringsRev hsr, String s, boolean force) {
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
if (!force && !s.isEmpty() && s.charAt(0) == '#' && s.length() < 12) {
|
||||
try {
|
||||
int id = Integer.parseInt(s.substring(1));
|
||||
return hsr.get(id);
|
||||
} catch (NumberFormatException ex) {
|
||||
// Doesn't seem like a HugeString
|
||||
}
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
char unicodeBuffer = 0;
|
||||
int stage = 0;
|
||||
@@ -78,10 +93,13 @@ public class UnicodeUtils {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String escapeWithSpaces(String s) {
|
||||
public static String escapeWithSpaces(HugeStrings hs, String s) {
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
if (s.length() > HugeStrings.THRESHOLD) {
|
||||
return hs.onString(s);
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
char[] arr = s.toCharArray();
|
||||
int i = 0;
|
||||
@@ -92,6 +110,9 @@ public class UnicodeUtils {
|
||||
if (arr[0] == '/') {
|
||||
sb.append("\\u002F");
|
||||
i++;
|
||||
} else if (arr[0] == '#') {
|
||||
sb.append("\\u0023");
|
||||
i++;
|
||||
}
|
||||
if (arr[len - 1] == '/') {
|
||||
addSlash = true;
|
||||
@@ -158,12 +179,26 @@ public class UnicodeUtils {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String escape(String s) {
|
||||
public static String escape(HugeStrings hs, String s) {
|
||||
return escape(hs, s, false);
|
||||
}
|
||||
|
||||
public static String escape(HugeStrings hs, String s, boolean force) {
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (char c : s.toCharArray()) {
|
||||
if (!force && s.length() > HugeStrings.THRESHOLD) {
|
||||
return hs.onString(s);
|
||||
}
|
||||
char[] arr = s.toCharArray();
|
||||
StringBuilder sb = new StringBuilder(arr.length);
|
||||
int i = 0;
|
||||
if (arr.length > 0 && arr[0] == '#') {
|
||||
sb.append("\\u0023");
|
||||
i++;
|
||||
}
|
||||
for (; i < arr.length; i++) {
|
||||
char c = arr[i];
|
||||
switch (c) {
|
||||
case 'Ä':
|
||||
case 'ä':
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user