Stage 1 of merging the client and server for MCP.

Results:
Client: 362
Server: 3 (Only due to issues of FF decompilation inconsistancies)
Common: 910

Stage 2: Write runtime transformer to remove annotated fields/methods with invalid side annotation.
This commit is contained in:
LexManos 2012-08-08 05:48:06 -07:00
parent 77f4cc5bea
commit ac8945a4f8
20 changed files with 47254 additions and 27 deletions

View File

@ -10,7 +10,17 @@
def creatergcfg(self, reobf=False, keep_lvt=False, keep_generics=False, rg_update=False): def creatergcfg(self, reobf=False, keep_lvt=False, keep_generics=False, rg_update=False):
"""Create the files necessary for RetroGuard""" """Create the files necessary for RetroGuard"""
@@ -1039,6 +1042,7 @@ @@ -779,7 +782,8 @@
testlk = {CLIENT: self.testclient, SERVER: self.testserver}
if not os.path.exists(os.path.join(srclk[side], os.path.normpath(testlk[side] + '.java'))):
- return False
+ if not os.path.exists(os.path.join(self.srcshared, os.path.normpath(testlk[side] + '.java'))):
+ return False
return True
def checkbins(self, side):
@@ -1039,6 +1043,7 @@
all_files = True all_files = True
append_pattern = False append_pattern = False
pkglist = filterdirs(pathsrclk[side], '*.java', append_pattern=append_pattern, all_files=all_files) pkglist = filterdirs(pathsrclk[side], '*.java', append_pattern=append_pattern, all_files=all_files)
@ -18,7 +28,7 @@
dirs = ' '.join(pkglist) dirs = ' '.join(pkglist)
classpath = os.pathsep.join(cplk[side]) classpath = os.pathsep.join(cplk[side])
forkcmd = self.cmdrecomp.format(classpath=classpath, sourcepath=pathsrclk[side], outpath=pathbinlk[side], forkcmd = self.cmdrecomp.format(classpath=classpath, sourcepath=pathsrclk[side], outpath=pathbinlk[side],
@@ -1195,20 +1199,20 @@ @@ -1195,20 +1200,20 @@
with open(self.csvmethods, 'rb') as fh: with open(self.csvmethods, 'rb') as fh:
methodsreader = csv.DictReader(fh) methodsreader = csv.DictReader(fh)
for row in methodsreader: for row in methodsreader:
@ -42,7 +52,7 @@
names['params'][row['param']] = row['name'] names['params'][row['param']] = row['name']
regexps = { regexps = {
@@ -1238,6 +1242,11 @@ @@ -1238,6 +1243,11 @@
# HINT: We pathwalk the sources # HINT: We pathwalk the sources
for path, _, filelist in os.walk(pathsrclk[side], followlinks=True): for path, _, filelist in os.walk(pathsrclk[side], followlinks=True):
@ -54,7 +64,7 @@
for cur_file in fnmatch.filter(filelist, '*.java'): for cur_file in fnmatch.filter(filelist, '*.java'):
updatefile(os.path.normpath(os.path.join(path, cur_file))) updatefile(os.path.normpath(os.path.join(path, cur_file)))
return True return True
@@ -1320,12 +1329,14 @@ @@ -1320,12 +1330,14 @@
pathsrclk = {CLIENT: self.srcclient, SERVER: self.srcserver} pathsrclk = {CLIENT: self.srcclient, SERVER: self.srcserver}
strip_comments(pathsrclk[side]) strip_comments(pathsrclk[side])
@ -69,7 +79,7 @@
def process_javadoc(self, side): def process_javadoc(self, side):
"""Add CSV descriptions to methods and fields as javadoc""" """Add CSV descriptions to methods and fields as javadoc"""
@@ -1334,6 +1345,21 @@ @@ -1334,6 +1346,21 @@
if not self.has_doc_csv: if not self.has_doc_csv:
self.logger.warning('!! javadoc disabled due to no csvs !!') self.logger.warning('!! javadoc disabled due to no csvs !!')
return False return False
@ -91,7 +101,7 @@
#HINT: We read the relevant CSVs #HINT: We read the relevant CSVs
methodsreader = csv.DictReader(open(self.csvmethods, 'r')) methodsreader = csv.DictReader(open(self.csvmethods, 'r'))
@@ -1342,13 +1368,13 @@ @@ -1342,13 +1369,13 @@
methods = {} methods = {}
for row in methodsreader: for row in methodsreader:
#HINT: Only include methods that have a non-empty description #HINT: Only include methods that have a non-empty description
@ -107,7 +117,7 @@
fields[row['searge']] = row['desc'].replace('*/', '* /') fields[row['searge']] = row['desc'].replace('*/', '* /')
regexps = { regexps = {
@@ -1420,6 +1446,7 @@ @@ -1420,6 +1447,7 @@
# HINT: We create the list of source directories based on the list of packages # HINT: We create the list of source directories based on the list of packages
pkglist = filterdirs(pathsrclk[side], '*.java', append_pattern=True) pkglist = filterdirs(pathsrclk[side], '*.java', append_pattern=True)
@ -115,7 +125,7 @@
dirs = ' '.join(pkglist) dirs = ' '.join(pkglist)
forkcmd = self.cmdastyle.format(classes=dirs, conffile=self.astyleconf) forkcmd = self.cmdastyle.format(classes=dirs, conffile=self.astyleconf)
self.runcmd(forkcmd) self.runcmd(forkcmd)
@@ -1592,6 +1619,9 @@ @@ -1592,6 +1620,9 @@
sys.exit(1) sys.exit(1)
for entry in newfiles: for entry in newfiles:

View File

@ -0,0 +1,14 @@
package cpw.mods.fml.common.asm;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import cpw.mods.fml.common.Side;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR})
public @interface SideOnly
{
public Side side();
}

View File

@ -269,21 +269,7 @@ public class AccessTransformer implements IClassTransformer
System.out.println("Could not find target jar: " + orig); System.out.println("Could not find target jar: " + orig);
return; return;
} }
/*
if (temp.exists())
{
if (orig.exists() && !orig.renameTo(new File(args[0] + (new SimpleDateFormat(".yyyy.MM.dd.HHmmss")).format(new Date()))))
{
System.out.println("Could not backup existing file: " + orig);
return;
}
if (!temp.renameTo(orig))
{
System.out.println("Could not restore backup from previous run: " + temp);
return;
}
}
*/
if (!orig.renameTo(temp)) if (!orig.renameTo(temp))
{ {
System.out.println("Could not rename file: " + orig + " -> " + temp); System.out.println("Could not rename file: " + orig + " -> " + temp);

View File

@ -0,0 +1,514 @@
package cpw.mods.fml.common.asm.transformers;
import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.Map.Entry;
import java.util.zip.*;
import org.objectweb.asm.*;
import org.objectweb.asm.tree.*;
import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.asm.SideOnly;
public class MCPMerger
{
private static Hashtable<String, ClassInfo> clients = new Hashtable<String, ClassInfo>();
private static Hashtable<String, ClassInfo> shared = new Hashtable<String, ClassInfo>();
private static Hashtable<String, ClassInfo> servers = new Hashtable<String, ClassInfo>();
private static HashSet<String> copyToServer = new HashSet<String>();
private static HashSet<String> copyToClient = new HashSet<String>();
public static void main(String[] args)
{
if (args.length != 3)
{
System.out.println("Usage: AccessTransformer <MapFile> <minecraft.jar> <minecraft_server.jar>");
return;
}
File map_file = new File(args[0]);
File client_jar = new File(args[1]);
File server_jar = new File(args[2]);
File client_jar_tmp = new File(args[1] + ".MergeBack");
File server_jar_tmp = new File(args[2] + ".MergeBack");
if (client_jar_tmp.exists() && !client_jar_tmp.delete())
{
System.out.println("Could not delete temp file: " + client_jar_tmp);
}
if (server_jar_tmp.exists() && !server_jar_tmp.delete())
{
System.out.println("Could not delete temp file: " + server_jar_tmp);
}
if (!client_jar.exists())
{
System.out.println("Could not find minecraft.jar: " + client_jar);
return;
}
if (!server_jar.exists())
{
System.out.println("Could not find minecraft_server.jar: " + server_jar);
return;
}
if (!client_jar.renameTo(client_jar_tmp))
{
System.out.println("Could not rename file: " + client_jar + " -> " + client_jar_tmp);
return;
}
if (!server_jar.renameTo(server_jar_tmp))
{
System.out.println("Could not rename file: " + server_jar + " -> " + server_jar_tmp);
return;
}
if (!readMapFile(map_file))
{
System.out.println("Could not read map file: " + map_file);
return;
}
try
{
processJar(client_jar_tmp, server_jar_tmp, client_jar, server_jar);
}
catch (IOException e)
{
e.printStackTrace();
}
if (!client_jar_tmp.delete())
{
System.out.println("Could not delete temp file: " + client_jar_tmp);
}
if (!server_jar_tmp.delete())
{
System.out.println("Could not delete temp file: " + server_jar_tmp);
}
}
private static boolean readMapFile(File mapFile)
{
try
{
FileInputStream fstream = new FileInputStream(mapFile);
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = br.readLine()) != null)
{
boolean toClient = line.charAt(0) == '<';
line = line.substring(1);
if (toClient) copyToClient.add(line);
else copyToServer.add(line);
}
in.close();
return true;
}
catch (Exception e)
{
System.err.println("Error: " + e.getMessage());
return false;
}
}
public static void processJar(File clientInFile, File serverInFile, File clientOutFile, File serverOutFile) throws IOException
{
ZipFile cInJar = null;
ZipFile sInJar = null;
ZipOutputStream cOutJar = null;
ZipOutputStream sOutJar = null;
try
{
try
{
cInJar = new ZipFile(clientInFile);
sInJar = new ZipFile(serverInFile);
}
catch (FileNotFoundException e)
{
throw new FileNotFoundException("Could not open input file: " + e.getMessage());
}
try
{
cOutJar = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(clientOutFile)));
sOutJar = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(serverOutFile)));
}
catch (FileNotFoundException e)
{
throw new FileNotFoundException("Could not open output file: " + e.getMessage());
}
Hashtable<String, ZipEntry> cClasses = getClassEntries(cInJar, cOutJar);
Hashtable<String, ZipEntry> sClasses = getClassEntries(sInJar, sOutJar);
for (Entry<String, ZipEntry> entry : cClasses.entrySet())
{
String name = entry.getKey();
ZipEntry cEntry = entry.getValue();
ZipEntry sEntry = sClasses.get(name);
if (sEntry == null)
{
if (!copyToServer.contains(name))
{
copyEntry(cInJar, cEntry, cOutJar);
}
else
{
System.out.println("Copy class c->s : " + name);
copyClass(cInJar, cEntry, cOutJar, sOutJar, true);
}
continue;
}
sClasses.remove(name);
ClassInfo info = new ClassInfo(name);
shared.put(name, info);
byte[] cData = readEntry(cInJar, entry.getValue());
byte[] sData = readEntry(sInJar, sEntry);
byte[] data = processClass(cData, sData, info);
ZipEntry newEntry = new ZipEntry(cEntry.getName());
cOutJar.putNextEntry(newEntry);
cOutJar.write(data);
sOutJar.putNextEntry(newEntry);
sOutJar.write(data);
}
for (Entry<String, ZipEntry> entry : sClasses.entrySet())
{
if (!copyToClient.contains(entry.getKey()))
{
copyEntry(sInJar, entry.getValue(), sOutJar);
}
else
{
System.out.println("Copy class s->c : " + entry.getKey());
copyClass(sInJar, entry.getValue(), cOutJar, sOutJar, false);
}
}
for (String name : new String[]{SideOnly.class.getName(), Side.class.getName()})
{
byte[] data = getClassBytes(name);
ZipEntry newEntry = new ZipEntry(name.replace(".", "/").concat(".class"));
cOutJar.putNextEntry(newEntry);
cOutJar.write(data);
sOutJar.putNextEntry(newEntry);
sOutJar.write(data);
}
}
finally
{
if (cInJar != null)
{
try { cInJar.close(); } catch (IOException e){}
}
if (sInJar != null)
{
try { sInJar.close(); } catch (IOException e) {}
}
if (cOutJar != null)
{
try { cOutJar.close(); } catch (IOException e){}
}
if (sOutJar != null)
{
try { sOutJar.close(); } catch (IOException e) {}
}
}
}
private static void copyClass(ZipFile inJar, ZipEntry entry, ZipOutputStream outJar, ZipOutputStream outJar2, boolean isClientOnly) throws IOException
{
ClassReader reader = new ClassReader(readEntry(inJar, entry));
ClassNode classNode = new ClassNode();
reader.accept(classNode, 0);
if (classNode.visibleAnnotations == null) classNode.visibleAnnotations = new ArrayList<AnnotationNode>();
classNode.visibleAnnotations.add(getSideAnn(isClientOnly));
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classNode.accept(writer);
byte[] data = writer.toByteArray();
ZipEntry newEntry = new ZipEntry(entry.getName());
outJar.putNextEntry(newEntry);
outJar.write(data);
outJar2.putNextEntry(newEntry);
outJar2.write(data);
}
private static AnnotationNode getSideAnn(boolean isClientOnly)
{
AnnotationNode ann = new AnnotationNode("L" + Type.getInternalName(SideOnly.class) + ";");
ann.values = new ArrayList<Object>();
ann.values.add("side");
ann.values.add(new String[]{ "L" + Type.getInternalName(Side.class) + ";", (isClientOnly ? "CLIENT" : "SERVER")});
return ann;
}
@SuppressWarnings("unchecked")
private static Hashtable<String, ZipEntry> getClassEntries(ZipFile inFile, ZipOutputStream outFile) throws IOException
{
Hashtable<String, ZipEntry> ret = new Hashtable<String, ZipEntry>();
for (ZipEntry entry : Collections.list((Enumeration<ZipEntry>)inFile.entries()))
{
if (entry.isDirectory())
{
outFile.putNextEntry(entry);
continue;
}
String entryName = entry.getName();
if (!entryName.endsWith(".class") || entryName.startsWith("."))
{
copyEntry(inFile, entry, outFile);
}
else
{
ret.put(entryName.replace(".class", ""), entry);
}
}
return ret;
}
private static void copyEntry(ZipFile inFile, ZipEntry entry, ZipOutputStream outFile) throws IOException
{
ZipEntry newEntry = new ZipEntry(entry.getName());
outFile.putNextEntry(newEntry);
outFile.write(readEntry(inFile, entry));
}
private static byte[] readEntry(ZipFile inFile, ZipEntry entry) throws IOException
{
return readFully(inFile.getInputStream(entry));
}
private static byte[] readFully(InputStream stream) throws IOException
{
byte[] data = new byte[4096];
ByteArrayOutputStream entryBuffer = new ByteArrayOutputStream();
int len;
do
{
len = stream.read(data);
if (len > 0)
{
entryBuffer.write(data, 0, len);
}
} while (len != -1);
return entryBuffer.toByteArray();
}
private static class ClassInfo
{
public String name;
public ArrayList<FieldNode> cField = new ArrayList<FieldNode>();
public ArrayList<FieldNode> sField = new ArrayList<FieldNode>();
public ArrayList<MethodNode> cMethods = new ArrayList<MethodNode>();
public ArrayList<MethodNode> sMethods = new ArrayList<MethodNode>();
public ClassInfo(String name){ this.name = name; }
public boolean isSame() { return (cField.size() == 0 && sField.size() == 0 && cMethods.size() == 0 && sMethods.size() == 0); }
}
public static byte[] processClass(byte[] cIn, byte[] sIn, ClassInfo info)
{
ClassNode cClassNode = getClassNode(cIn);
ClassNode sClassNode = getClassNode(sIn);
processFields(cClassNode, sClassNode, info);
processMethods(cClassNode, sClassNode, info);
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cClassNode.accept(writer);
return writer.toByteArray();
}
private static ClassNode getClassNode(byte[] data)
{
ClassReader reader = new ClassReader(data);
ClassNode classNode = new ClassNode();
reader.accept(classNode, 0);
return classNode;
}
@SuppressWarnings("unchecked")
private static void processFields(ClassNode cClass, ClassNode sClass, ClassInfo info)
{
List<FieldNode> cFields = cClass.fields;
List<FieldNode> sFields = sClass.fields;
int sI = 0;
for (int x = 0; x < cFields.size(); x++)
{
FieldNode cF = cFields.get(x);
if (sI < sFields.size())
{
if (!cF.name.equals(sFields.get(sI).name))
{
boolean serverHas = false;
for (int y = sI + 1; y < sFields.size(); y++)
{
if (cF.name.equals(sFields.get(y).name))
{
serverHas = true;
break;
}
}
if (serverHas)
{
boolean clientHas = false;
FieldNode sF = sFields.get(sI);
for (int y = x + 1; y < cFields.size(); y++)
{
if (sF.name.equals(cFields.get(y).name))
{
clientHas = true;
break;
}
}
if (!clientHas)
{
if (sF.visibleAnnotations == null) sF.visibleAnnotations = new ArrayList<AnnotationNode>();
sF.visibleAnnotations.add(getSideAnn(false));
cFields.add(x++, sF);
info.sField.add(sF);
}
}
else
{
if (cF.visibleAnnotations == null) cF.visibleAnnotations = new ArrayList<AnnotationNode>();
cF.visibleAnnotations.add(getSideAnn(true));
sFields.add(sI, cF);
info.cField.add(cF);
}
}
}
else
{
if (cF.visibleAnnotations == null) cF.visibleAnnotations = new ArrayList<AnnotationNode>();
cF.visibleAnnotations.add(getSideAnn(true));
sFields.add(sI, cF);
info.cField.add(cF);
}
sI++;
}
if (sFields.size() != cFields.size())
{
for (int x = cFields.size(); x < sFields.size(); x++)
{
FieldNode sF = sFields.get(x);
if (sF.visibleAnnotations == null) sF.visibleAnnotations = new ArrayList<AnnotationNode>();
sF.visibleAnnotations.add(getSideAnn(true));
cFields.add(x++, sF);
info.sField.add(sF);
}
}
}
@SuppressWarnings("unchecked")
private static void processMethods(ClassNode cClass, ClassNode sClass, ClassInfo info)
{
List<MethodNode> cMethods = (List<MethodNode>)cClass.methods;
List<MethodNode> sMethods = (List<MethodNode>)sClass.methods;
int sI = 0;
for (int x = 0; x < cMethods.size(); x++)
{
MethodNode cM = cMethods.get(x);
if (sI < sMethods.size())
{
if (!cM.name.equals(sMethods.get(sI).name) || (cM.name.equals("<init>") && !cM.desc.equals(sMethods.get(sI).desc)))
{
boolean serverHas = false;
for (int y = sI + 1; y < sMethods.size(); y++)
{
if (cM.name.equals(sMethods.get(y).name) && cM.desc.equals(sMethods.get(y).desc))
{
serverHas = true;
break;
}
}
if (serverHas)
{
boolean clientHas = false;
MethodNode sM = sMethods.get(sI);
for (int y = x + 1; y < cMethods.size(); y++)
{
if (sM.name.equals(cMethods.get(y).name) && sM.desc.equals(cMethods.get(y).desc))
{
clientHas = true;
break;
}
}
if (!clientHas)
{
if (sM.visibleAnnotations == null) sM.visibleAnnotations = new ArrayList<AnnotationNode>();
sM.visibleAnnotations.add(getSideAnn(false));
cMethods.add(x, sM);
info.sMethods.add(sM);
}
}
else
{
if (cM.visibleAnnotations == null) cM.visibleAnnotations = new ArrayList<AnnotationNode>();
cM.visibleAnnotations.add(getSideAnn(true));
sMethods.add(sI, cM);
info.cMethods.add(cM);
}
}
}
else
{
if (cM.visibleAnnotations == null) cM.visibleAnnotations = new ArrayList<AnnotationNode>();
cM.visibleAnnotations.add(getSideAnn(true));
sMethods.add(sI, cM);
info.cMethods.add(cM);
}
sI++;
}
if (sMethods.size() != cMethods.size())
{
for (int x = cMethods.size(); x < sMethods.size(); x++)
{
MethodNode sM = sMethods.get(x);
if (sM.visibleAnnotations == null) sM.visibleAnnotations = new ArrayList<AnnotationNode>();
sM.visibleAnnotations.add(getSideAnn(false));
cMethods.add(x++, sM);
info.sMethods.add(sM);
}
}
}
public static byte[] getClassBytes(String name) throws IOException
{
InputStream classStream = null;
try
{
classStream = MCPMerger.class.getResourceAsStream("/" + name.replace('.', '/').concat(".class"));
return readFully(classStream);
}
finally
{
if (classStream != null)
{
try
{
classStream.close();
}
catch (IOException e){}
}
}
}
}

19
fml/conf/astyle.cfg Normal file
View File

@ -0,0 +1,19 @@
# Artistic Style format configuration
# see http://astyle.sourceforge.net/astyle.html
style=allman
add-brackets
break-closing-brackets
indent-switches
max-instatement-indent=2
pad-oper
pad-header
unpad-paren
break-blocks
delete-empty-lines

3907
fml/conf/fields.csv Normal file

File diff suppressed because it is too large Load Diff

6170
fml/conf/joined.exc Normal file

File diff suppressed because it is too large Load Diff

14363
fml/conf/joined.srg Normal file

File diff suppressed because it is too large Load Diff

155
fml/conf/mcp.cfg Normal file
View File

@ -0,0 +1,155 @@
[DEFAULT]
DirTemp = temp
DirSrc = src
DirLogs = logs
DirBin = bin
DirJars = jars
DirReobf = reobf
DirConf = conf
DirRuntime = runtime
DirLib = lib
DirTempSrc = temp/src
DirTempCls = temp/cls
DirTempBin = temp/bin
DirModSrc = modsrc
DirEclipse = eclipse
[CSV]
Classes = %(DirConf)s/classes.csv
Methods = %(DirConf)s/methods.csv
Fields = %(DirConf)s/fields.csv
Params = %(DirConf)s/params.csv
NewIds = %(DirConf)s/newids.csv
[SRGS]
ConfClient = %(DirConf)s/joined.srg
ConfServer = %(DirConf)s/joined.srg
Client = %(DirTemp)s/client_rg.srg
Server = %(DirTemp)s/server_rg.srg
DeobfClient = %(DirTemp)s/client_deobf.srg
DeobfServer = %(DirTemp)s/server_deobf.srg
ReobfClient = %(DirTemp)s/client_ro.srg
ReobfServer = %(DirTemp)s/server_ro.srg
[JAR]
DirNatives = %(DirJars)s/bin/natives
Client = %(DirJars)s/bin/minecraft.jar
Server = %(DirJars)s/minecraft_server.jar
LWJGL = %(DirJars)s/bin/jinput.jar,%(DirJars)s/bin/lwjgl.jar,%(DirJars)s/bin/lwjgl_util.jar
MD5Client = 266ccbc9798afd2eadf3d6c01b4c562a
MD5Server = f44a3cfe6ec35b1ac3f2b635e73d96fe
[RETROGUARD]
Location = %(DirRuntime)s/bin/retroguard.jar
RetroConf = %(DirTemp)s/retroguard.cfg
RetroReobConf = %(DirTemp)s/retroguard_ro.cfg
ClientConf = %(DirTemp)s/client_rg.cfg
ServerConf = %(DirTemp)s/server_rg.cfg
ClientReobConf = %(DirTemp)s/client_ro.cfg
ServerReobConf = %(DirTemp)s/server_ro.cfg
ClientOut = %(DirTemp)s/minecraft_rg.jar
ServerOut = %(DirTemp)s/minecraft_server_rg.jar
ClientLog = %(DirLogs)s/client_rg.log
ServerLog = %(DirLogs)s/server_rg.log
ClientDeobLog = %(DirLogs)s/client_deob.log
ServerDeobLog = %(DirLogs)s/server_deob.log
NullPkg = net/minecraft/src
[EXCEPTOR]
XClientCfg = %(DirConf)s/joined.exc
XServerCfg = %(DirConf)s/joined.exc
XClientOut = %(DirTemp)s/minecraft_exc.jar
XServerOut = %(DirTemp)s/minecraft_server_exc.jar
XClientLog = %(DirLogs)s/client_exc.log
XServerLog = %(DirLogs)s/server_exc.log
[DECOMPILE]
ClsClientTemp = %(DirTempCls)s/minecraft
ClsServerTemp = %(DirTempCls)s/minecraft_server
SrcClientTemp = %(DirTempSrc)s/minecraft
SrcServerTemp = %(DirTempSrc)s/minecraft_server
FFSource = net
[OUTPUT]
BinClientTemp = %(DirTempBin)s/minecraft
BinServerTemp = %(DirTempBin)s/minecraft_server
SrcClient = %(DirSrc)s/minecraft
SrcServer = %(DirSrc)s/minecraft_server
TestClient = net/minecraft/client/Minecraft
TestServer = net/minecraft/server/MinecraftServer
[PATCHES]
PatchClient = %(DirConf)s/patches/minecraft.patch
PatchServer = %(DirConf)s/patches/minecraft_server.patch
PatchTemp = %(DirTemp)s/temp.patch
FFPatchClient = %(DirConf)s/patches/minecraft_ff.patch
FFPatchServer = %(DirConf)s/patches/minecraft_server_ff.patch
PatchClient_osx = %(DirConf)s/patches/minecraft_osx.patch
PatchServer_osx = %(DirConf)s/patches/minecraft_server_osx.patch
[RECOMPILE]
BinClient = %(DirBin)s/minecraft
BinServer = %(DirBin)s/minecraft_server
LogClient = %(DirLogs)s/client_compile.log
LogServer = %(DirLogs)s/server_compile.log
ClassPathClient = %(DirLib)s/,%(DirLib)s/*,%(DirJars)s/bin/minecraft.jar,%(DirJars)s/bin/jinput.jar,%(DirJars)s/bin/lwjgl.jar,%(DirJars)s/bin/lwjgl_util.jar
ClassPathServer = %(DirLib)s/,%(DirLib)s/*,%(DirJars)s/minecraft_server.jar
ClientFixes = %(DirConf)s/patches
FixStart = Start
IgnorePkg = paulscode,com/jcraft,isom,ibxm,de/matthiasmann/twl,org/xmlpull,javax/xml
[REOBF]
MD5Client = %(DirTemp)s/client.md5
MD5Server = %(DirTemp)s/server.md5
MD5PreReobfClient = %(DirTemp)s/client_reobf.md5
MD5PreReobfServer = %(DirTemp)s/server_reobf.md5
RecompJarClient = %(DirTemp)s/client_recomp.jar
RecompJarServer = %(DirTemp)s/server_recomp.jar
ObfJarClient = %(DirTemp)s/client_reobf.jar
ObfJarServer = %(DirTemp)s/server_reobf.jar
ReobfDirClient = %(DirReobf)s/minecraft
ReobfDirServer = %(DirReobf)s/minecraft_server
ClientRoLog = %(DirLogs)s/client_ro.log
ServerRoLog = %(DirLogs)s/server_ro.log
ReobfClientLog = %(DirLogs)s/client_reob.log
ReobfServerLog = %(DirLogs)s/server_reob.log
[GETMODSOURCE]
OutSRCClient = %(DirModSrc)s/minecraft
OutSRCServer = %(DirModSrc)s/minecraft_server
[MCP]
LogFile = %(DirLogs)s/mcp.log
LogFileErr = %(DirLogs)s/mcperr.log
UpdateUrl =
IgnoreUpdate = %(DirBin)s,%(DirLib)s,%(DirLogs)s,%(DirModSrc)s,%(DirReobf)s,%(DirSrc)s,%(DirTemp)s,%(DirEclipse)s/Client/bin,%(DirEclipse)s/Server/bin,%(DirJars)s/world,%(DirJars)s/saves,%(DirJars)s/resources
RGIndex = 70000
ParamIndex = 3000
[ASTYLE]
AstyleConfig = %(DirConf)s/astyle.cfg
[COMMANDS]
Wine = wine
Patcher_win = %(DirRuntime)s/bin/applydiff.exe
Patcher_linux = patch
Patcher_osx = patch
Jad_win = %(DirRuntime)s/bin/jad.exe
Jad_osx = %(DirRuntime)s/bin/jad-osx
AStyle_win = %(DirRuntime)s/bin/astyle.exe
AStyle_linux = astyle
AStyle_osx = %(DirRuntime)s/bin/astyle-osx
JadRetro = %(DirRuntime)s/bin/jadretro.jar
Fernflower = %(DirRuntime)s/bin/fernflower.jar
Exceptor = %(DirRuntime)s/bin/mcinjector.jar
CmdPatch = %s -p1 -u -i {patchfile} -d {srcdir}
CmdJad = %s -b -d {outdir} -dead -o -r -s .java -stat -ff {classes}
CmdAStyle = %s --suffix=none --quiet --options={conffile} {classes}
CmdRG = %s -cp "{classpath}" RetroGuard -searge {conffile}
CmdRGReobf = %s -cp "{classpath}" RetroGuard -notch {conffile}
CmdJadretro = %s -jar %s {targetdir}
CmdFernflower = %s -jar %s -din=0 -rbr=0 -dgs=1 -asc=1 -log=WARN {indir} {outdir}
CmdExceptor = %s -jar %s {input} {output} {conf} {log}
CmdRecomp = %s -Xlint:-options -deprecation -g -source 1.6 -target 1.6 -classpath "{classpath}" -sourcepath {sourcepath} -d {outpath} {pkgs}
CmdStartSrv = %s -Xincgc -Xms1024M -Xmx1024M -cp "{classpath}" net.minecraft.server.MinecraftServer
CmdStartClt = %s -Xincgc -Xms1024M -Xmx1024M -cp "{classpath}" -Djava.library.path={natives} Start

3509
fml/conf/methods.csv Normal file

File diff suppressed because it is too large Load Diff

8820
fml/conf/newids.csv Normal file

File diff suppressed because it is too large Load Diff

9145
fml/conf/params.csv Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,79 @@
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import net.minecraft.client.Minecraft;
public class Start
{
public static void main(String[] args)
{
try
{
Field f = Minecraft.class.getDeclaredField("field_71463_am");
Field.setAccessible(new Field[] { f }, true);
f.set(null, new File("."));
}
catch (Exception e)
{
e.printStackTrace();
return;
}
if (args.length != 2)
{
Minecraft.main(args);
}
else
{
try {
String parameters = "http://login.minecraft.net/?user=" + URLEncoder.encode(args[0], "UTF-8") +
"&password=" + URLEncoder.encode(args[1], "UTF-8") +
"&version=" + 13;
String result = openUrl(parameters);
if (result == null)
{
System.out.println("Can't connect to minecraft.net");
return;
}
if (!result.contains(":"))
{
System.out.println("Login Failed: " + result);
return;
}
//latestVersion, downloadTicket, userName, sessionId
String[] values = result.split(":");
Minecraft.main(new String[]{values[2].trim(), values[3].trim()});
} catch (Exception e) {
e.printStackTrace();
}
}
}
private static String openUrl(String addr)
{
try {
URL url = new URL(addr);
java.io.InputStream is;
is = url.openConnection().getInputStream();
java.io.BufferedReader reader = new java.io.BufferedReader(new java.io.InputStreamReader(is));
String buf = "";
String line = null;
while((line = reader.readLine() ) != null)
{
buf += "\n" + line;
}
reader.close();
return buf;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,184 @@
diff -r -U 3 minecraft\net\minecraft\client\Minecraft.java minecraft_patched\net\minecraft\client\Minecraft.java
--- minecraft\net\minecraft\client\Minecraft.java Wed Aug 01 18:13:27 2012
+++ minecraft_patched\net\minecraft\client\Minecraft.java Wed Aug 01 18:23:13 2012
@@ -539,9 +539,8 @@
return;
}
- while(true) {
try {
- if(this.field_71425_J) {
+ while(this.field_71425_J) {
if(this.field_71434_R && this.field_71433_S != null) {
this.func_71377_b(this.field_71433_S);
return;
@@ -559,7 +558,6 @@
this.func_71373_a(new GuiMemoryErrorScreen());
System.gc();
}
- continue;
}
} catch (MinecraftError var12) {
;
@@ -577,8 +575,6 @@
this.func_71405_e();
}
- return;
- }
}
private void func_71411_J() {
diff -r -U 3 minecraft\net\minecraft\src\CodecMus.java minecraft_patched\net\minecraft\src\CodecMus.java
--- minecraft\net\minecraft\src\CodecMus.java Wed Aug 01 18:13:28 2012
+++ minecraft_patched\net\minecraft\src\CodecMus.java Wed Aug 01 18:24:06 2012
@@ -1,5 +1,6 @@
package net.minecraft.src;
+import java.io.IOException;
import java.io.InputStream;
import net.minecraft.src.MusInputStream;
import paulscode.sound.codecs.CodecJOrbis;
@@ -7,6 +8,10 @@
public class CodecMus extends CodecJOrbis {
protected InputStream openInputStream() {
+ try {
return new MusInputStream(this, this.url, this.urlConnection.getInputStream());
+ } catch(IOException ex) {
+ return null;
+ }
}
}
diff -r -U 3 minecraft\net\minecraft\src\ComponentStrongholdRightTurn.java minecraft_patched\net\minecraft\src\ComponentStrongholdRightTurn.java
--- minecraft\net\minecraft\src\ComponentStrongholdRightTurn.java Wed Aug 01 18:13:28 2012
+++ minecraft_patched\net\minecraft\src\ComponentStrongholdRightTurn.java Wed Aug 01 18:26:33 2012
@@ -11,6 +11,10 @@
public class ComponentStrongholdRightTurn extends ComponentStrongholdLeftTurn {
+ public ComponentStrongholdRightTurn(int p_i3843_1_, Random p_i3843_2_, StructureBoundingBox p_i3843_3_, int p_i3843_4_) {
+ super(p_i3843_1_, p_i3843_2_, p_i3843_3_, p_i3843_4_);
+ }
+
public void func_74861_a(StructureComponent p_74861_1_, List p_74861_2_, Random p_74861_3_) {
if(this.field_74885_f != 2 && this.field_74885_f != 3) {
this.func_74989_b((ComponentStrongholdStairs2)p_74861_1_, p_74861_2_, p_74861_3_, 1, 1);
diff -r -U 3 minecraft\net\minecraft\src\DedicatedServer.java minecraft_patched\net\minecraft\src\DedicatedServer.java
--- minecraft\net\minecraft\src\DedicatedServer.java Wed Aug 01 18:13:29 2012
+++ minecraft_patched\net\minecraft\src\DedicatedServer.java Wed Aug 01 18:31:22 2012
@@ -183,7 +183,7 @@
}
- protected CrashReport func_71230_b(CrashReport p_71230_1_) {
+ public CrashReport func_71230_b(CrashReport p_71230_1_) {
p_71230_1_.func_71500_a("Type", new CallableType(this));
return super.func_71230_b(p_71230_1_);
}
@@ -192,7 +192,7 @@
System.exit(0);
}
- protected void func_71190_q() {
+ public void func_71190_q() {
super.func_71190_q();
this.func_71333_ah();
}
diff -r -U 3 minecraft\net\minecraft\src\FontRenderer.java minecraft_patched\net\minecraft\src\FontRenderer.java
--- minecraft\net\minecraft\src\FontRenderer.java Thu Aug 02 02:35:41 2012
+++ minecraft_patched\net\minecraft\src\FontRenderer.java Thu Aug 02 02:37:34 2012
@@ -711,8 +711,6 @@
for(boolean var7 = false; var5 < var3; ++var5) {
char var8 = p_78259_1_.charAt(var5);
switch(var8) {
- case 32:
- var6 = var5;
case 167:
if(var5 < var3 - 1) {
++var5;
@@ -726,6 +724,8 @@
}
}
break;
+ case 32:
+ var6 = var5;
default:
var4 += this.func_78263_a(var8);
if(var7) {
diff -r -U 3 minecraft\net\minecraft\src\IntegratedServer.java minecraft_patched\net\minecraft\src\IntegratedServer.java
--- minecraft\net\minecraft\src\IntegratedServer.java Wed Aug 01 18:13:30 2012
+++ minecraft_patched\net\minecraft\src\IntegratedServer.java Wed Aug 01 18:32:27 2012
@@ -97,7 +97,7 @@
return true;
}
- protected void func_71217_p() {
+ public void func_71217_p() {
boolean var1 = this.field_71348_o;
this.field_71348_o = this.field_71347_n.func_71752_f();
if(!var1 && this.field_71348_o) {
@@ -144,7 +144,7 @@
this.field_71349_l.func_71404_a(p_71228_1_);
}
- protected CrashReport func_71230_b(CrashReport p_71230_1_) {
+ public CrashReport func_71230_b(CrashReport p_71230_1_) {
p_71230_1_.func_71500_a("Type", new CallableType3(this));
p_71230_1_.func_71500_a("Is Modded", new CallableIsModded(this));
return super.func_71230_b(p_71230_1_);
diff -r -U 3 minecraft\net\minecraft\src\ItemMap.java minecraft_patched\net\minecraft\src\ItemMap.java
--- minecraft\net\minecraft\src\ItemMap.java Wed Aug 01 18:13:31 2012
+++ minecraft_patched\net\minecraft\src\ItemMap.java Wed Aug 01 18:27:03 2012
@@ -24,7 +24,6 @@
}
public static MapData func_77874_a(short p_77874_0_, World p_77874_1_) {
- "map_" + p_77874_0_;
MapData var3 = (MapData)p_77874_1_.func_72943_a(MapData.class, "map_" + p_77874_0_);
if(var3 == null) {
int var4 = p_77874_1_.func_72841_b("map");
@@ -37,7 +36,6 @@
}
public MapData func_77873_a(ItemStack p_77873_1_, World p_77873_2_) {
- "map_" + p_77873_1_.func_77960_j();
MapData var4 = (MapData)p_77873_2_.func_72943_a(MapData.class, "map_" + p_77873_1_.func_77960_j());
if(var4 == null) {
p_77873_1_.func_77964_b(p_77873_2_.func_72841_b("map"));
diff -r -U 3 minecraft\net\minecraft\src\RenderGlobal.java minecraft_patched\net\minecraft\src\RenderGlobal.java
--- minecraft\net\minecraft\src\RenderGlobal.java Wed Aug 01 18:13:32 2012
+++ minecraft_patched\net\minecraft\src\RenderGlobal.java Wed Aug 01 18:33:03 2012
@@ -1431,7 +1431,7 @@
double var15 = this.field_72777_q.field_71451_h.field_70165_t - p_72726_2_;
double var17 = this.field_72777_q.field_71451_h.field_70163_u - p_72726_4_;
double var19 = this.field_72777_q.field_71451_h.field_70161_v - p_72726_6_;
- Object var21 = null;
+ EntityFX var21 = null;
if(p_72726_1_.equals("hugeexplosion")) {
this.field_72777_q.field_71452_i.func_78873_a(var21 = new EntityHugeExplodeFX(this.field_72769_h, p_72726_2_, p_72726_4_, p_72726_6_, p_72726_8_, p_72726_10_, p_72726_12_));
} else if(p_72726_1_.equals("largeexplode")) {
diff -r -U 3 minecraft\net\minecraft\src\TcpMasterThread.java minecraft_patched\net\minecraft\src\TcpMasterThread.java
--- minecraft\net\minecraft\src\TcpMasterThread.java Wed Aug 01 18:13:32 2012
+++ minecraft_patched\net\minecraft\src\TcpMasterThread.java Wed Aug 01 18:27:42 2012
@@ -11,6 +11,7 @@
this.field_74504_a = p_i3285_1_;
}
+ @SuppressWarnings("deprecation")
public void run() {
try {
Thread.sleep(5000L);
diff -r -U 3 minecraft\net\minecraft\src\ThreadedFileIOBase.java minecraft_patched\net\minecraft\src\ThreadedFileIOBase.java
--- minecraft\net\minecraft\src\ThreadedFileIOBase.java Wed Aug 01 18:13:32 2012
+++ minecraft_patched\net\minecraft\src\ThreadedFileIOBase.java Wed Aug 01 18:28:10 2012
@@ -20,7 +20,9 @@
}
public void run() {
+ while(true) {
this.func_75736_b();
+ }
}
private void func_75736_b() {

View File

@ -0,0 +1,81 @@
diff -r -U 3 minecraft_server\net\minecraft\src\ComponentStrongholdRightTurn.java minecraft_server_patched\net\minecraft\src\ComponentStrongholdRightTurn.java
--- minecraft_server\net\minecraft\src\ComponentStrongholdRightTurn.java Wed Aug 01 18:15:36 2012
+++ minecraft_server_patched\net\minecraft\src\ComponentStrongholdRightTurn.java Wed Aug 01 18:26:32 2012
@@ -11,6 +11,10 @@
public class ComponentStrongholdRightTurn extends ComponentStrongholdLeftTurn {
+ public ComponentStrongholdRightTurn(int p_i3843_1_, Random p_i3843_2_, StructureBoundingBox p_i3843_3_, int p_i3843_4_) {
+ super(p_i3843_1_, p_i3843_2_, p_i3843_3_, p_i3843_4_);
+ }
+
public void func_74861_a(StructureComponent p_74861_1_, List p_74861_2_, Random p_74861_3_) {
if(this.field_74885_f != 2 && this.field_74885_f != 3) {
this.func_74989_b((ComponentStrongholdStairs2)p_74861_1_, p_74861_2_, p_74861_3_, 1, 1);
diff -r -U 3 minecraft_server\net\minecraft\src\DedicatedServer.java minecraft_server_patched\net\minecraft\src\DedicatedServer.java
--- minecraft_server\net\minecraft\src\DedicatedServer.java Wed Aug 01 18:15:36 2012
+++ minecraft_server_patched\net\minecraft\src\DedicatedServer.java Wed Aug 01 18:31:22 2012
@@ -184,7 +184,7 @@
}
- protected CrashReport func_71230_b(CrashReport p_71230_1_) {
+ public CrashReport func_71230_b(CrashReport p_71230_1_) {
p_71230_1_.func_71500_a("Type", new CallableType(this));
return super.func_71230_b(p_71230_1_);
}
@@ -193,7 +193,7 @@
System.exit(0);
}
- protected void func_71190_q() {
+ public void func_71190_q() {
super.func_71190_q();
this.func_71333_ah();
}
diff -r -U 3 minecraft_server\net\minecraft\src\ItemMap.java minecraft_server_patched\net\minecraft\src\ItemMap.java
--- minecraft_server\net\minecraft\src\ItemMap.java Wed Aug 01 18:15:37 2012
+++ minecraft_server_patched\net\minecraft\src\ItemMap.java Wed Aug 01 18:27:23 2012
@@ -24,7 +24,6 @@
}
public MapData func_77873_a(ItemStack p_77873_1_, World p_77873_2_) {
- "map_" + p_77873_1_.func_77960_j();
MapData var4 = (MapData)p_77873_2_.func_72943_a(MapData.class, "map_" + p_77873_1_.func_77960_j());
if(var4 == null) {
p_77873_1_.func_77964_b(p_77873_2_.func_72841_b("map"));
diff -r -U 3 minecraft_server\net\minecraft\src\TcpMasterThread.java minecraft_server_patched\net\minecraft\src\TcpMasterThread.java
--- minecraft_server\net\minecraft\src\TcpMasterThread.java Wed Aug 01 18:15:38 2012
+++ minecraft_server_patched\net\minecraft\src\TcpMasterThread.java Wed Aug 01 18:28:41 2012
@@ -11,6 +11,7 @@
this.field_74504_a = p_i3285_1_;
}
+ @SuppressWarnings("deprecation")
public void run() {
try {
Thread.sleep(5000L);
diff -r -U 3 minecraft_server\net\minecraft\src\ThreadedFileIOBase.java minecraft_server_patched\net\minecraft\src\ThreadedFileIOBase.java
--- minecraft_server\net\minecraft\src\ThreadedFileIOBase.java Wed Aug 01 18:15:38 2012
+++ minecraft_server_patched\net\minecraft\src\ThreadedFileIOBase.java Wed Aug 01 18:28:56 2012
@@ -20,7 +20,9 @@
}
public void run() {
+ while(true) {
this.func_75736_b();
+ }
}
private void func_75736_b() {
diff -r -U 3 minecraft_server\net\minecraft\src\ItemMap.java minecraft_server_patched\net\minecraft\src\ItemMap.java
--- minecraft_server\net\minecraft\src\ItemMap.java Wed Aug 01 18:15:37 2012
+++ minecraft_server_patched\net\minecraft\src\ItemMap.java Wed Aug 01 18:27:23 2012
@@ -24,7 +24,6 @@
}
public static MapData func_77874_a(short p_77874_0_, World p_77874_1_) {
- "map_" + p_77874_0_;
MapData var3 = (MapData)p_77874_1_.func_72943_a(MapData.class, "map_" + p_77874_0_);
if(var3 == null) {
int var4 = p_77874_1_.func_72841_b("map");

4
fml/conf/version.cfg Normal file
View File

@ -0,0 +1,4 @@
[VERSION]
MCPVersion = 7.0a
ClientVersion = 1.3.1
ServerVersion = 1.3.1

View File

@ -6,14 +6,15 @@ import os
if __name__ == '__main__': if __name__ == '__main__':
if not len(sys.argv) == 3: if not len(sys.argv) == 3:
print 'Invalid arguments, must supply mcp folder and fml folder: decompile.y <MCPFolder> <FMLFolder>' print 'Invalid arguments, must supply mcp folder and fml folder: decompile.py <MCPFolder> <FMLFolder>'
else: else:
mcp_dir = os.path.abspath(sys.argv[1]) mcp_dir = os.path.abspath(sys.argv[1])
fml_dir = os.path.abspath(sys.argv[2]) fml_dir = os.path.abspath(sys.argv[2])
dont_gen_conf = '-no_gen_conf' in sys.argv
sys.path.append(os.path.join(fml_dir, 'install')) sys.path.append(os.path.join(fml_dir, 'install'))
from fml import setup_fml, setup_mcp from fml import setup_fml, setup_mcp
setup_mcp(fml_dir, mcp_dir) setup_mcp(fml_dir, mcp_dir, dont_gen_conf)
setup_fml(fml_dir, mcp_dir) setup_fml(fml_dir, mcp_dir)

View File

@ -2,6 +2,7 @@ import os, os.path, sys
import urllib, zipfile import urllib, zipfile
import shutil, glob, fnmatch import shutil, glob, fnmatch
import subprocess, logging, re, shlex import subprocess, logging, re, shlex
import csv
from hashlib import md5 # pylint: disable-msg=E0611 from hashlib import md5 # pylint: disable-msg=E0611
#class flushout(object): #class flushout(object):
@ -162,6 +163,23 @@ def setup_fml(fml_dir, mcp_dir):
#print forkcmd #print forkcmd
self.runcmd(forkcmd) self.runcmd(forkcmd)
#Compile MCPMerger
forkcmd = ('%s -Xlint:-options -deprecation -g -source 1.6 -target 1.6 -classpath "{classpath}" -sourcepath {sourcepath} -d {outpath} {target}' % self.cmdjavac).format(
classpath=os.pathsep.join(['.', os.path.join(mcp_dir, 'lib', '*')]), sourcepath=os.path.join(fml_dir, 'common'), outpath=os.path.join(fml_dir, 'bin'),
target=os.path.join(fml_dir, 'common', 'cpw', 'mods', 'fml', 'common', 'asm', 'transformers', 'MCPMerger.java'))
#print forkcmd
self.runcmd(forkcmd)
#Run MCPMerger
forkcmd = ('%s -classpath "{classpath}" cpw.mods.fml.common.asm.transformers.MCPMerger "{mergecfg}" "{client}" "{server}"' % self.cmdjava).format(
classpath=os.pathsep.join([os.path.join(mcp_dir, 'lib', '*'), binDir]), mergecfg=os.path.join(fml_dir, 'mcp_merge.cfg'), client=jars[CLIENT], server=jars[SERVER])
forge_cfg = os.path.join(mcp_dir, 'forge', 'common', 'forge_at.cfg')
if os.path.isfile(forge_cfg):
forkcmd += ' "%s"' % forge_cfg
self.runcmd(forkcmd)
#Run AccessTransformer #Run AccessTransformer
forkcmd = ('%s -classpath "{classpath}" cpw.mods.fml.common.asm.transformers.AccessTransformer "{jar}" "{fmlconfig}"' % self.cmdjava).format( forkcmd = ('%s -classpath "{classpath}" cpw.mods.fml.common.asm.transformers.AccessTransformer "{jar}" "{fmlconfig}"' % self.cmdjava).format(
classpath=os.pathsep.join([os.path.join(mcp_dir, 'lib', '*'), binDir]), jar=jars[side], fmlconfig=os.path.join(fml_dir, 'common', 'fml_at.cfg')) classpath=os.pathsep.join([os.path.join(mcp_dir, 'lib', '*'), binDir]), jar=jars[side], fmlconfig=os.path.join(fml_dir, 'common', 'fml_at.cfg'))
@ -247,6 +265,9 @@ def merge_client_server(mcp_dir):
shutil.move(f_client, f_shared) shutil.move(f_client, f_shared)
os.remove(f_server) os.remove(f_server)
cleanDirs(server)
cleanDirs(client)
def apply_fml_patches(fml_dir, mcp_dir, src_dir, copy_files=True): def apply_fml_patches(fml_dir, mcp_dir, src_dir, copy_files=True):
has_client = os.path.isdir(os.path.join(src_dir, 'minecraft')) has_client = os.path.isdir(os.path.join(src_dir, 'minecraft'))
has_server = os.path.isdir(os.path.join(src_dir, 'minecraft_server')) has_server = os.path.isdir(os.path.join(src_dir, 'minecraft_server'))
@ -416,6 +437,21 @@ def copytree(src, dst, verbose=0, symlinks=False):
# can't copy file access times on Windows # can't copy file access times on Windows
pass pass
def cleanDirs(path):
if not os.path.isdir(path):
return
files = os.listdir(path)
if len(files):
for f in files:
fullpath = os.path.join(path, f)
if os.path.isdir(fullpath):
cleanDirs(fullpath)
files = os.listdir(path)
if len(files) == 0:
os.rmdir(path)
def merge_tree(root_src_dir, root_dst_dir): def merge_tree(root_src_dir, root_dst_dir):
for src_dir, dirs, files in os.walk(root_src_dir): for src_dir, dirs, files in os.walk(root_src_dir):
dst_dir = src_dir.replace(root_src_dir, root_dst_dir) dst_dir = src_dir.replace(root_src_dir, root_dst_dir)
@ -428,7 +464,7 @@ def merge_tree(root_src_dir, root_dst_dir):
os.remove(dst_file) os.remove(dst_file)
shutil.copy(src_file, dst_dir) shutil.copy(src_file, dst_dir)
def setup_mcp(fml_dir, mcp_dir): def setup_mcp(fml_dir, mcp_dir, dont_gen_conf=True):
backup = os.path.join(mcp_dir, 'runtime', 'commands.py.bck') backup = os.path.join(mcp_dir, 'runtime', 'commands.py.bck')
runtime = os.path.join(mcp_dir, 'runtime', 'commands.py') runtime = os.path.join(mcp_dir, 'runtime', 'commands.py')
patch = os.path.join(fml_dir, 'commands.patch') patch = os.path.join(fml_dir, 'commands.patch')
@ -467,6 +503,217 @@ def setup_mcp(fml_dir, mcp_dir):
if os.path.isfile(temp): if os.path.isfile(temp):
os.remove(temp) os.remove(temp)
mcp_conf = os.path.join(mcp_dir, 'conf')
mcp_conf_bak = os.path.join(mcp_dir, 'conf.bak')
fml_conf = os.path.join(fml_dir, 'conf')
if not dont_gen_conf:
if os.path.isdir(mcp_conf_bak):
print 'Reverting old conf backup folder'
shutil.rmtree(mcp_conf)
os.rename(mcp_conf_bak, mcp_conf)
get_conf_copy(mcp_dir, fml_dir)
print 'Backing up MCP Conf'
os.rename(mcp_conf, mcp_conf_bak)
else:
shutil.rmtree(mcp_conf)
print 'Copying FML conf'
shutil.copytree(fml_conf, mcp_conf)
#update workspace #update workspace
print 'Fixing MCP Workspace' print 'Fixing MCP Workspace'
merge_tree(os.path.join(fml_dir, 'eclipse'), os.path.join(mcp_dir, 'eclipse')) merge_tree(os.path.join(fml_dir, 'eclipse'), os.path.join(mcp_dir, 'eclipse'))
def get_conf_copy(mcp_dir, fml_dir):
#Lets grab the files we dont work on
for file in ['astyle.cfg', 'version.cfg', 'patches/minecraft_ff.patch', 'patches/minecraft_server_ff.patch', 'newids.csv']:
dst_file = os.path.normpath(os.path.join(fml_dir, 'conf', file))
src_file = os.path.normpath(os.path.join(mcp_dir, 'conf', file))
if not os.path.isdir(os.path.dirname(dst_file)):
os.makedirs(os.path.dirname(dst_file))
if os.path.exists(dst_file):
os.remove(dst_file)
shutil.copy(src_file, dst_file)
print 'Grabbing: ' + src_file
ff_server = os.path.normpath(os.path.join(fml_dir, 'conf', 'patches', 'minecraft_server_ff.patch'))
data = []
with open(ff_server) as f: data = f.readlines();
data = data + [
'diff -r -U 3 minecraft_server\\net\\minecraft\\src\\ItemMap.java minecraft_server_patched\\net\\minecraft\\src\\ItemMap.java',
'--- minecraft_server\\net\\minecraft\\src\\ItemMap.java Wed Aug 01 18:15:37 2012',
'+++ minecraft_server_patched\\net\\minecraft\\src\\ItemMap.java Wed Aug 01 18:27:23 2012',
'@@ -24,7 +24,6 @@',
' }',
' ',
' public static MapData func_77874_a(short p_77874_0_, World p_77874_1_) {',
'- "map_" + p_77874_0_;',
' MapData var3 = (MapData)p_77874_1_.func_72943_a(MapData.class, "map_" + p_77874_0_);',
' if(var3 == null) {',
' int var4 = p_77874_1_.func_72841_b("map");'
]
os.remove(ff_server)
with open(ff_server, 'w') as f:
for line in data:
f.write(line.rstrip('\r\n') + '\n')
common_srg = gen_merged_srg(mcp_dir, fml_dir)
common_exc = gen_merged_exc(mcp_dir, fml_dir)
common_map = gen_shared_searge_names(common_srg, common_exc)
#ToDo use common_map to merge the remaining csvs, client taking precidense, setting the common items to side '2' and editing commands.py in FML to have 'if csv_side == side || csv_side == '2''
gen_merged_csv(common_map, os.path.join(mcp_dir, 'conf', 'fields.csv'), os.path.join(fml_dir, 'conf', 'fields.csv'))
gen_merged_csv(common_map, os.path.join(mcp_dir, 'conf', 'methods.csv'), os.path.join(fml_dir, 'conf', 'methods.csv'))
gen_merged_csv(common_map, os.path.join(mcp_dir, 'conf', 'params.csv'), os.path.join(fml_dir, 'conf', 'params.csv'), main_key='param')
def gen_merged_srg(mcp_dir, fml_dir):
print 'Generating merged Retroguard data'
srg_client = os.path.join(mcp_dir, 'conf', 'client.srg')
srg_server = os.path.join(mcp_dir, 'conf', 'server.srg')
if not os.path.isfile(srg_client) or not os.path.isfile(srg_server):
print 'Could not find client and server srg files in "%s"' % mcp_dir
return False
client = {'PK:': {}, 'CL:': {}, 'FD:': {}, 'MD:': {}}
with open(srg_client, 'r') as fh:
for line in fh:
pts = line.rstrip('\r\n').split(' ')
if pts[0] == 'MD:':
client[pts[0]][pts[1] + ' ' + pts[2]] = pts[3] + ' ' + pts[4]
else:
client[pts[0]][pts[1]] = pts[2]
server = {'PK:': {}, 'CL:': {}, 'FD:': {}, 'MD:': {}}
with open(srg_server, 'r') as fh:
for line in fh:
pts = line.rstrip('\r\n').split(' ')
if pts[0] == 'MD:':
server[pts[0]][pts[1] + ' ' + pts[2]] = pts[3] + ' ' + pts[4]
else:
server[pts[0]][pts[1]] = pts[2]
common = {'PK:': {}, 'CL:': {}, 'FD:': {}, 'MD:': {}}
for type in common:
for key, value in client[type].items():
if key in server[type]:
if value == server[type][key]:
client[type].pop(key)
server[type].pop(key)
common[type][key] = value
for type in common:
for key, value in client[type].items():
common[type][key] = value #+ ' #C'
for type in common:
for key, value in server[type].items():
common[type][key] = value #+ ' #S'
#Print joined retroguard files
with open(os.path.join(fml_dir, 'conf', 'joined.srg'), 'w') as f:
for type in ['PK:', 'CL:', 'FD:', 'MD:']:
for key in sorted(common[type]):
f.write('%s %s %s\n' % (type, key, common[type][key]))
return common
def gen_merged_exc(mcp_dir, fml_dir):
print 'Generating merged MCInjector config'
exc_client = os.path.join(mcp_dir, 'conf', 'client.exc')
exc_server = os.path.join(mcp_dir, 'conf', 'server.exc')
client = {}
with open(exc_client, 'r') as fh:
for line in fh:
if not line.startswith('#'):
pts = line.rstrip('\r\n').split('=')
client[pts[0]] = pts[1]
server = {}
with open(exc_server, 'r') as fh:
for line in fh:
if not line.startswith('#'):
pts = line.rstrip('\r\n').split('=')
server[pts[0]] = pts[1]
common = {}
for key, value in client.items():
if key in server:
if value != server[key]:
print 'Error: Exec for shared function does not match client and server:'
print 'Function: ' + key
print 'Client: ' + value
print 'Server: ' + server[value]
if value != '|':
common[key] = value
client.pop(key)
server.pop(key)
else:
if value != '|':
common[key] = value
joined = dict(common.items() + server.items())
#Print joined mcinjector files
with open(os.path.join(fml_dir, 'conf', 'joined.exc'), 'w') as f:
for key in sorted(joined):
f.write('%s=%s\n' % (key, joined[key]))
return common
def gen_shared_searge_names(common_srg, common_exc):
field = re.compile(r'field_[0-9]+_[a-zA-Z_]+$')
method = re.compile(r'func_[0-9]+_[a-zA-Z_]+')
param = re.compile(r'p_[\w]+_\d+_')
print 'Gathering list of common searge names'
searge = []
for key, value in common_srg['FD:'].items():
m = field.search(value)
if not m is None:
if not m.group(0) in searge:
searge.append(m.group(0))
for key, value in common_srg['MD:'].items():
m = method.search(value)
if not m is None and not '#' in value:
if not m.group(0) in searge:
searge.append(m.group(0))
for key, value in common_exc.items():
m = param.findall(value)
if not m is None:
for p in m:
if not p in searge:
searge.append(p)
return searge
def gen_merged_csv(common_map, in_file, out_file, main_key='searge'):
reader = csv.DictReader(open(in_file, 'r'))
print 'Generating merged csv for %s' % os.path.basename(in_file)
sides = {'client': [], 'server': [], 'common': []}
added = []
for row in reader:
side = int(row['side'])
if row[main_key] in common_map:
if not row[main_key] in added:
row['side'] = '2'
sides['common'].append(row)
added.append(row[main_key])
elif side == 0:
sides['client'].append(row)
else:
sides['server'].append(row)
writer = csv.DictWriter(open(out_file, 'wb'), fieldnames=reader.fieldnames)
writer.writeheader()
for key in ['client', 'server', 'common']:
for row in sorted(sides[key], key=lambda row: row[main_key]):
writer.writerow(row)

19
fml/mcp_merge.cfg Normal file
View File

@ -0,0 +1,19 @@
<fz
<fy
<gc
<gd
>akd
<ge
<gf
>aki
<ga
<gb
<gg
>um
>un
<eo
>aeg
>rs
>hl
>hz
>hy

View File

@ -1,2 +1,2 @@
@echo off @echo off
..\runtime\bin\python\python_mcp update_patches.py .. patches ..\runtime\bin\python\python_mcp update_patches.py .. .