All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.minecraftforge.gradle.tasks.GenSrgTask Maven / Gradle / Ivy

There is a newer version: 3.2.0
Show newest version
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);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy