Skip to content

Commit 907d55d

Browse files
Add general parameter naming
1 parent 18c9023 commit 907d55d

File tree

5 files changed

+174
-107
lines changed

5 files changed

+174
-107
lines changed

src/main/java/de/oceanlabs/mcp/mcinjector/MCInjector.java

+24-7
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ public class MCInjector
3030
private Path fileIn, fileOut;
3131
private Path excIn, excOut;
3232
private Path accIn, accOut;
33-
private Path ctrIn, ctrOut;
33+
private Path ctrIn;
34+
private Path prmIn, prmOut;
3435
private LVTNaming lvt;
3536

3637
public MCInjector(Path fileIn, Path fileOut)
@@ -104,9 +105,15 @@ public MCInjector constructors(Path ctrs)
104105
return this;
105106
}
106107

107-
public MCInjector constructorsOut(Path out)
108+
public MCInjector parameters(Path ctrs)
108109
{
109-
this.ctrOut = out;
110+
this.prmIn = ctrs;
111+
return this;
112+
}
113+
114+
public MCInjector parametersOut(Path out)
115+
{
116+
this.prmOut = out;
110117
return this;
111118
}
112119

@@ -121,8 +128,9 @@ public void process() throws IOException
121128
{
122129
MCInjectorImpl.process(fileIn, fileOut,
123130
accIn, accOut,
124-
ctrIn, ctrOut,
131+
ctrIn,
125132
excIn, excOut,
133+
prmIn, prmOut,
126134
lvt);
127135
}
128136

@@ -174,7 +182,9 @@ public static void main(String[] args) throws Exception
174182
OptionSpec<Path> acc = parser.accepts("acc") .withRequiredArg().withValuesConvertedBy(PATH_ARG);
175183
OptionSpec<Path> accOut = parser.accepts("accOut").withRequiredArg().withValuesConvertedBy(PATH_ARG);
176184
OptionSpec<Path> ctr = parser.accepts("ctr") .withRequiredArg().withValuesConvertedBy(PATH_ARG);
177-
OptionSpec<Path> ctrOut = parser.accepts("ctrOut").withRequiredArg().withValuesConvertedBy(PATH_ARG);
185+
OptionSpec<Path> ctrOut = parser.accepts("ctrOut").withRequiredArg().withValuesConvertedBy(PATH_ARG); //legacy
186+
OptionSpec<Path> prm = parser.accepts("prm") .withRequiredArg().withValuesConvertedBy(PATH_ARG);
187+
OptionSpec<Path> prmOut = parser.accepts("prmOut").withRequiredArg().withValuesConvertedBy(PATH_ARG);
178188
OptionSpec<Level> logLvl = parser.accepts("level") .withRequiredArg().withValuesConvertedBy(LEVEL_ARG).defaultsTo(Level.INFO);
179189
OptionSpec<LVTNaming> lvt = parser.accepts("lvt").withRequiredArg().ofType(LVTNaming.class).defaultsTo(LVTNaming.STRIP);
180190

@@ -192,6 +202,11 @@ else if (o.has(ver))
192202
System.out.println(VERSION);
193203
return;
194204
}
205+
else if (o.has(ctrOut))
206+
{
207+
System.out.println("ctrOut is using the legacy format and is no longer supported!");
208+
return;
209+
}
195210

196211
MCInjector.LOG.setUseParentHandlers(false);
197212
MCInjector.LOG.setLevel(o.valueOf(logLvl));
@@ -205,7 +220,8 @@ else if (o.has(ver))
205220
LOG.info("Access: " + o.valueOf(acc));
206221
LOG.info(" " + o.valueOf(accOut));
207222
LOG.info("Constructors: " + o.valueOf(ctr));
208-
LOG.info(" " + o.valueOf(ctrOut));
223+
LOG.info("Extra Params: " + o.valueOf(prm));
224+
LOG.info(" " + o.valueOf(prmOut));
209225
LOG.info("LVT: " + o.valueOf(lvt));
210226

211227
try
@@ -219,7 +235,8 @@ else if (o.has(ver))
219235
.access(o.valueOf(acc))
220236
.accessOut(o.valueOf(accOut))
221237
.constructors(o.valueOf(ctr))
222-
.constructorsOut(o.valueOf(ctrOut))
238+
.parameters(o.valueOf(prm))
239+
.parametersOut(o.valueOf(prmOut))
223240
.process();
224241
}
225242
catch (Exception e)

src/main/java/de/oceanlabs/mcp/mcinjector/MCInjectorImpl.java

+8-5
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
import de.oceanlabs.mcp.mcinjector.adaptors.InnerClassInitAdder;
3333
import de.oceanlabs.mcp.mcinjector.adaptors.ParameterAnnotationFixer;
3434
import de.oceanlabs.mcp.mcinjector.data.Access;
35-
import de.oceanlabs.mcp.mcinjector.data.Constructors;
35+
import de.oceanlabs.mcp.mcinjector.data.Parameters;
3636
import de.oceanlabs.mcp.mcinjector.data.Exceptions;
3737
import de.oceanlabs.mcp.mcinjector.lvt.LVTFernflower;
3838
import de.oceanlabs.mcp.mcinjector.lvt.LVTLvt;
@@ -47,15 +47,18 @@ public class MCInjectorImpl
4747
static void process(
4848
Path in, Path out,
4949
Path accIn, Path accOut,
50-
Path ctrIn, Path ctrOut,
50+
Path ctrIn,
5151
Path excIn, Path excOut,
52+
Path prmIn, Path prmOut,
5253
LVTNaming naming)
5354
throws IOException
5455
{
5556
if (accIn != null)
5657
Access.INSTANCE.load(accIn);
58+
if (prmIn != null)
59+
Parameters.INSTANCE.load(prmIn);
5760
if (ctrIn != null)
58-
Constructors.INSTANCE.load(ctrIn);
61+
Parameters.INSTANCE.loadLegacy(ctrIn);
5962
if (excIn != null)
6063
Exceptions.INSTANCE.load(excIn);
6164

@@ -69,8 +72,8 @@ static void process(
6972

7073
if (accOut != null)
7174
Access.INSTANCE.dump(accOut);
72-
if (ctrOut != null)
73-
Constructors.INSTANCE.dump(ctrOut);
75+
if (prmOut != null)
76+
Parameters.INSTANCE.dump(prmOut);
7477
if (excOut != null)
7578
Exceptions.INSTANCE.dump(excOut);
7679

src/main/java/de/oceanlabs/mcp/mcinjector/adaptors/ApplyMap.java

+6-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.util.Set;
1111
import java.util.logging.Level;
1212

13+
import de.oceanlabs.mcp.mcinjector.data.Parameters;
1314
import org.objectweb.asm.ClassVisitor;
1415
import org.objectweb.asm.MethodVisitor;
1516
import org.objectweb.asm.Opcodes;
@@ -21,7 +22,6 @@
2122

2223
import de.oceanlabs.mcp.mcinjector.MCInjector;
2324
import de.oceanlabs.mcp.mcinjector.MCInjectorImpl;
24-
import de.oceanlabs.mcp.mcinjector.data.Constructors;
2525
import de.oceanlabs.mcp.mcinjector.data.Exceptions;
2626

2727
public class ApplyMap extends ClassVisitor
@@ -95,9 +95,11 @@ private void processLVT(String cls, String name, String desc, MethodNode mn)
9595
{
9696
List<String> params = new ArrayList<>();
9797
List<Type> types = new ArrayList<>();
98+
boolean isStatic = false;
9899

99100
if ((mn.access & Opcodes.ACC_STATIC) == 0)
100101
{
102+
isStatic = true;
101103
types.add(Type.getType("L" + cls + ";"));
102104
params.add(0, "this");
103105
}
@@ -109,11 +111,11 @@ private void processLVT(String cls, String name, String desc, MethodNode mn)
109111
return;
110112

111113
MCInjector.LOG.fine(" Generating map:");
112-
String nameFormat = "p_" + name + "_%d_";
114+
String nameFormat = null;
113115
if (name.matches("func_\\d+_.+")) // A srg name method params are just p_MethodID_ParamIndex_
114116
nameFormat = "p_" + name.substring(5, name.indexOf('_', 5)) + "_%s_";
115-
else if (name.equals("<init>")) // Every constructor is given a unique ID, try to load the ID from the map, if none is found assign a new one
116-
nameFormat = "p_i" + Constructors.INSTANCE.getID(className, desc, types.size() > 1) + "_%s_";
117+
else
118+
nameFormat = "p_" + Parameters.INSTANCE.getName(className, name, desc, types.size() > params.size(), isStatic) + "_%s_"; //assign new name only if there are names remaining
117119

118120
for (int x = params.size(), y = x; x < types.size(); x++)
119121
{

src/main/java/de/oceanlabs/mcp/mcinjector/data/Constructors.java

-91
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
package de.oceanlabs.mcp.mcinjector.data;
2+
3+
import de.oceanlabs.mcp.mcinjector.MCInjector;
4+
5+
import java.io.IOException;
6+
import java.nio.charset.StandardCharsets;
7+
import java.nio.file.Files;
8+
import java.nio.file.Path;
9+
import java.nio.file.StandardOpenOption;
10+
import java.util.HashMap;
11+
import java.util.List;
12+
import java.util.Map;
13+
import java.util.stream.Collectors;
14+
15+
public enum Parameters
16+
{
17+
INSTANCE;
18+
19+
private Map<String, String> fromDesc = new HashMap<>();
20+
private Map<String, String> fromID = new HashMap<>();
21+
private int maxID = 0;
22+
23+
public boolean load(Path file)
24+
{
25+
this.fromDesc.clear();
26+
this.fromID.clear();
27+
try
28+
{
29+
MCInjector.LOG.fine("Loading Parameters from: " + file);
30+
Files.readAllLines(file).forEach(line ->
31+
{
32+
line = line.trim();
33+
if (line.isEmpty() || line.startsWith("#"))
34+
return;
35+
36+
String[] parts = line.split(" " );
37+
int id = Integer.parseInt(parts[0].substring(1));
38+
char prefix = parts[0].charAt(0);
39+
MCInjector.LOG.fine(" Method parameter ID loaded " + prefix + id + " " + parts[0] + " " + parts[1] + " " + parts[3]);
40+
this.setName(parts[1], parts[2], parts[3], id, prefix);
41+
});
42+
}
43+
catch (IOException e)
44+
{
45+
e.printStackTrace();
46+
MCInjector.LOG.warning("Could not load Parameters list: " + e.toString());
47+
return false;
48+
}
49+
return true;
50+
}
51+
52+
public boolean loadLegacy(Path file)
53+
{
54+
try {
55+
MCInjector.LOG.fine("Loading Constructors from: " + file);
56+
Files.readAllLines(file).forEach(line ->
57+
{
58+
line = line.trim();
59+
if (line.isEmpty() || line.startsWith("#"))
60+
return;
61+
62+
String[] parts = line.split(" " );
63+
int id = Integer.parseInt(parts[0]);
64+
MCInjector.LOG.fine(" Constructor ID loaded " + id + " " + parts[0] + " " + parts[1]);
65+
this.setName(parts[1], "<init>", parts[2], id, 'i');
66+
});
67+
return true;
68+
}
69+
catch (IOException e)
70+
{
71+
e.printStackTrace();
72+
MCInjector.LOG.warning("Could not import Constructors list: " + e.toString());
73+
return false;
74+
}
75+
}
76+
77+
public boolean dump(Path file)
78+
{
79+
try
80+
{
81+
List<String> ret = this.fromID.entrySet().stream()
82+
.sorted((e1, e2) -> e1.getKey().compareTo(e2.getKey()))
83+
.map(e -> e.getKey() + " " + e.getValue())
84+
.collect(Collectors.toList());
85+
Files.write(file, String.join("\n", ret).getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE_NEW);
86+
}
87+
catch (IOException e)
88+
{
89+
e.printStackTrace();
90+
MCInjector.LOG.warning("Could not dump Parameters list: " + e.toString());
91+
return false;
92+
}
93+
return true;
94+
}
95+
96+
public void setName(String cls, String method, String desc, int id, char prefix)
97+
{
98+
if (id < 0)
99+
throw new IllegalArgumentException("ID must be positive: " + id);
100+
this.maxID = Math.max(this.maxID, id);
101+
this.fromDesc.put(cls + " " + method + " " + desc, prefix + "" + id);
102+
this.fromID .put(prefix + "" + id, cls + " " + method + " " + desc);
103+
}
104+
105+
public String getName(String cls, String method, String desc, boolean generate, boolean isStatic)
106+
{
107+
String id = this.fromDesc.get(cls + " " + method + " " + desc);
108+
if (id == null)
109+
{
110+
if (!generate)
111+
return method; //if we are not generating new names we will return the old parameter format, _p_funcname_x_
112+
char prefix = getPrefix(method, isStatic);
113+
int newId = ++maxID;
114+
this.setName(cls, method, desc, newId, prefix);
115+
return prefix + "" + newId;
116+
}
117+
if(id.charAt(0) != getPrefix(method, isStatic))
118+
{
119+
String num = id.substring(1);
120+
char prefix = getPrefix(method, isStatic);
121+
this.setName(cls, method, desc, Integer.parseInt(num), prefix);
122+
String newID = prefix + "" + num;
123+
MCInjector.LOG.info("Method " + cls + "." + method + desc + " has wrong name attribute, updating: " + id + " -> " + newID);
124+
return newID;
125+
}
126+
return id;
127+
}
128+
129+
public char getPrefix(String name, boolean isStatic){
130+
if(name.equals("<init>")) //this ensures constructors will still have the _p_i12345_x_ format
131+
return 'i';
132+
if(isStatic) //since the static map does not cover these methods we encode it in the param prefix (s=static)
133+
return 's';
134+
return 'e'; //while new methods named will use the _p_e12345_x_ format
135+
}
136+
}

0 commit comments

Comments
 (0)