net.minecraftforge.gradle.tasks.GenSrgTask Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of CelestiGradle Show documentation
Show all versions of CelestiGradle Show documentation
Gradle plugin for building Celestibytes projects. ForgeGradle included.
package net.minecraftforge.gradle.tasks;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import net.minecraftforge.gradle.delayed.DelayedFile;
import net.minecraftforge.gradle.tasks.abstractutil.CachedTask;
import net.minecraftforge.srg2source.rangeapplier.MethodData;
import net.minecraftforge.srg2source.rangeapplier.SrgContainer;
import org.gradle.api.file.FileCollection;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;
import au.com.bytecode.opencsv.CSVReader;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
public class GenSrgTask extends CachedTask
{
@InputFile
private DelayedFile inSrg;
@InputFile
private DelayedFile inExc;
@InputFiles
private final LinkedList extraExcs = new LinkedList();
@InputFiles
private final LinkedList extraSrgs = new LinkedList();
@InputFile
private DelayedFile methodsCsv;
@InputFile
private DelayedFile fieldsCsv;
@Cached
@OutputFile
private DelayedFile notchToSrg;
@Cached
@OutputFile
private DelayedFile notchToMcp;
@Cached
@OutputFile
private DelayedFile mcpToNotch;
@Cached
@OutputFile
private DelayedFile mcpToSrg;
@Cached
@OutputFile
private DelayedFile srgExc;
@Cached
@OutputFile
private DelayedFile mcpExc;
@TaskAction
public void doTask() throws IOException
{
// csv data. SRG -> MCP
HashMap methods = new HashMap();
HashMap fields = new HashMap();
readCSVs(getMethodsCsv(), getFieldsCsv(), methods, fields);
// Do SRG stuff
SrgContainer inSrg = new SrgContainer().readSrg(getInSrg());
Map excRemap = readExtraSrgs(getExtraSrgs(), inSrg);
writeOutSrgs(inSrg, methods, fields);
// do EXC stuff
writeOutExcs(excRemap, methods);
}
private static void readCSVs(File methodCsv, File fieldCsv, Map methodMap, Map fieldMap) throws IOException
{
// read methods
CSVReader csvReader = RemapSourcesTask.getReader(methodCsv);
for (String[] s : csvReader.readAll())
{
methodMap.put(s[0], s[1]);
}
// read fields
csvReader = RemapSourcesTask.getReader(fieldCsv);
for (String[] s : csvReader.readAll())
{
fieldMap.put(s[0], s[1]);
}
}
private static Map readExtraSrgs(FileCollection extras, SrgContainer inSrg)
{
SrgContainer extraSrg = new SrgContainer().readSrgs(extras);
// Need to convert these to Notch-SRG names. and add them to the other one.
HashMap excRemap = new HashMap(extraSrg.methodMap.size());
// SRG -> notch map
Map classMap = inSrg.classMap.inverse();
Map methodMap = inSrg.methodMap.inverse();
// rename methods
for (Entry e : extraSrg.methodMap.entrySet())
{
String notchName = remapMethodName(e.getValue().name, methodMap);
String notchSig = remapSig(e.getValue().sig, classMap);
inSrg.methodMap.put(new MethodData(notchName, notchSig), e.getValue());
excRemap.put(e.getKey().name, e.getValue().name);
}
return excRemap;
}
private void writeOutSrgs(SrgContainer inSrg, Map methods, Map fields) throws IOException
{
// ensure folders exist
Files.createParentDirs(getNotchToSrg());
Files.createParentDirs(getNotchToMcp());
Files.createParentDirs(getMcpToSrg());
Files.createParentDirs(getMcpToNotch());
// create streams
BufferedWriter notch2Srg = Files.newWriter(getNotchToSrg(), Charsets.UTF_8);
BufferedWriter notch2Mcp = Files.newWriter(getNotchToMcp(), Charsets.UTF_8);
BufferedWriter mcpToSrg = Files.newWriter(getMcpToSrg(), Charsets.UTF_8);
BufferedWriter mcpToNotch = Files.newWriter(getMcpToNotch(), Charsets.UTF_8);
String line, temp, mcpName;
// packages
for (Entry e : inSrg.packageMap.entrySet())
{
line = "PK: "+e.getKey()+" "+e.getValue();
// nobody cares about the packages.
notch2Srg.write(line);
notch2Srg.newLine();
notch2Mcp.write(line);
notch2Mcp.newLine();
mcpToSrg.write(line);
mcpToSrg.newLine();
mcpToNotch.write(line);
mcpToNotch.newLine();
}
// classes
for (Entry e : inSrg.classMap.entrySet())
{
line = "CL: "+e.getKey()+" "+e.getValue();
// same...
notch2Srg.write(line);
notch2Srg.newLine();
// SRG and MCP have the same class names
notch2Mcp.write(line);
notch2Mcp.newLine();
line = "CL: "+e.getValue()+" "+e.getValue();
// reobf: same classes on both sides.
mcpToSrg.write("CL: "+e.getValue()+" "+e.getValue());
mcpToSrg.newLine();
// output is notch
mcpToNotch.write("CL: "+e.getValue()+" "+e.getKey());
mcpToNotch.newLine();
}
// fields
for (Entry e : inSrg.fieldMap.entrySet())
{
line = "FD: "+e.getKey()+" "+e.getValue();
// same...
notch2Srg.write("FD: "+e.getKey()+" "+e.getValue());
notch2Srg.newLine();
temp = e.getValue().substring(e.getValue().lastIndexOf('/')+1);
mcpName = e.getValue();
if (fields.containsKey(temp))
mcpName = mcpName.replace(temp, fields.get(temp));
// SRG and MCP have the same class names
notch2Mcp.write("FD: "+e.getKey()+" "+mcpName);
notch2Mcp.newLine();
// reobf: same classes on both sides.
mcpToSrg.write("FD: "+mcpName+" "+e.getValue());
mcpToSrg.newLine();
// output is notch
mcpToNotch.write("FD: "+mcpName+" "+e.getKey());
mcpToNotch.newLine();
}
// methods
for (Entry e : inSrg.methodMap.entrySet())
{
line = "MD: "+e.getKey()+" "+e.getValue();
// same...
notch2Srg.write("MD: "+e.getKey()+" "+e.getValue());
notch2Srg.newLine();
temp = e.getValue().name.substring(e.getValue().name.lastIndexOf('/')+1);
mcpName = e.getValue().toString();
if (methods.containsKey(temp))
mcpName = mcpName.replace(temp, methods.get(temp));
// SRG and MCP have the same class names
notch2Mcp.write("MD: "+e.getKey()+" "+mcpName);
notch2Mcp.newLine();
// reobf: same classes on both sides.
mcpToSrg.write("MD: "+mcpName+" "+e.getValue());
mcpToSrg.newLine();
// output is notch
mcpToNotch.write("MD: "+mcpName+" "+e.getKey());
mcpToNotch.newLine();
}
notch2Srg.flush();
notch2Srg.close();
notch2Mcp.flush();
notch2Mcp.close();
mcpToSrg.flush();
mcpToSrg.close();
mcpToNotch.flush();
mcpToNotch.close();
}
private void writeOutExcs(Map excRemap, Map methods) throws IOException
{
// ensure folders exist
Files.createParentDirs(getSrgExc());
Files.createParentDirs(getMcpExc());
// create streams
BufferedWriter srgOut = Files.newWriter(getSrgExc(), Charsets.UTF_8);
BufferedWriter mcpOut = Files.newWriter(getMcpExc(), Charsets.UTF_8);
// read and write existing lines
List excLines = Files.readLines(getInExc(), Charsets.UTF_8);
String[] split;
for (String line : excLines)
{
// its already in SRG names.
srgOut.write(line);
srgOut.newLine();
// remap MCP.
// split line up
split = line.split("=");
int sigIndex = split[0].indexOf('(');
int dotIndex = split[0].indexOf('.');
// not a method? wut?
if (sigIndex == -1 || dotIndex == -1)
{
mcpOut.write(line);
mcpOut.newLine();
continue;
}
// get new name
String name = split[0].substring(dotIndex+1, sigIndex);
if (methods.containsKey(name))
name = methods.get(name);
// write remapped line
mcpOut.write(split[0].substring(0, dotIndex) + name + split[0].substring(sigIndex) + "=" + split[1]);
mcpOut.newLine();
}
for (File f : getExtraExcs())
{
List lines = Files.readLines(f, Charsets.UTF_8);
for (String line : lines)
{
// these are in MCP names
mcpOut.write(line);
mcpOut.newLine();
// remap SRG
// split line up
split = line.split("=");
int sigIndex = split[0].indexOf('(');
int dotIndex = split[0].indexOf('.');
// not a method? wut?
if (sigIndex == -1 || dotIndex == -1)
{
srgOut.write(line);
srgOut.newLine();
continue;
}
// get new name
String name = split[0].substring(dotIndex+1, sigIndex);
if (excRemap.containsKey(name))
name = excRemap.get(name);
// write remapped line
srgOut.write(split[0].substring(0, dotIndex) + name + split[0].substring(sigIndex) + "=" + split[1]);
srgOut.newLine();
}
}
srgOut.flush();
srgOut.close();
mcpOut.flush();
mcpOut.close();
}
/**
*
* @param name
* @param methodMap SRG -> notch names.
* @return
*/
private static String remapMethodName(String name, Map methodMap)
{
MethodData key = null;
for (MethodData data : methodMap.keySet())
{
if (data.name.equals(name))
{
key = data;
break;
}
}
if (key == null)
return name; // no mapping found.
else
return methodMap.get(key).name;
}
private static String remapSig(String sig, Map classMap)
{
StringBuilder newSig = new StringBuilder(sig.length()).append("(");
String[] params = sig.substring(1, sig.lastIndexOf(')')).split(";");
for (String param : params)
newSig.append(remap(param, classMap)).append(';');
newSig.append(')').append(remap(sig.substring(sig.lastIndexOf(')') + 1), classMap));
return newSig.toString();
}
private static String remap(String thing, Map map)
{
if (map.containsKey(thing))
return map.get(thing);
else
return thing;
}
public File getInSrg()
{
return inSrg.call();
}
public void setInSrg(DelayedFile inSrg)
{
this.inSrg = inSrg;
}
public File getInExc()
{
return inExc.call();
}
public void setInExc(DelayedFile inSrg)
{
this.inExc = inSrg;
}
public File getMethodsCsv()
{
return methodsCsv.call();
}
public void setMethodsCsv(DelayedFile methodsCsv)
{
this.methodsCsv = methodsCsv;
}
public File getFieldsCsv()
{
return fieldsCsv.call();
}
public void setFieldsCsv(DelayedFile fieldsCsv)
{
this.fieldsCsv = fieldsCsv;
}
public File getNotchToSrg()
{
return notchToSrg.call();
}
public void setNotchToSrg(DelayedFile deobfSrg)
{
this.notchToSrg = deobfSrg;
}
public File getNotchToMcp()
{
return notchToMcp.call();
}
public void setNotchToMcp(DelayedFile deobfSrg)
{
this.notchToMcp = deobfSrg;
}
public File getMcpToSrg()
{
return mcpToSrg.call();
}
public void setMcpToSrg(DelayedFile reobfSrg)
{
this.mcpToSrg = reobfSrg;
}
public File getMcpToNotch()
{
return mcpToNotch.call();
}
public void setMcpToNotch(DelayedFile reobfSrg)
{
this.mcpToNotch = reobfSrg;
}
public File getSrgExc()
{
return srgExc.call();
}
public void setSrgExc(DelayedFile inSrg)
{
this.srgExc = inSrg;
}
public File getMcpExc()
{
return mcpExc.call();
}
public void setMcpExc(DelayedFile inSrg)
{
this.mcpExc = inSrg;
}
public FileCollection getExtraExcs()
{
return getProject().files(extraExcs);
}
public void addExtraExc(File file)
{
extraExcs.add(file);
}
public FileCollection getExtraSrgs()
{
return getProject().files(extraSrgs);
}
public void addExtraSrg(File file)
{
extraSrgs.add(file);
}
}