From 4ca63717e59b2f50c166a8e2725513bd7bc8ee86 Mon Sep 17 00:00:00 2001 From: LexManos Date: Wed, 1 Aug 2012 03:25:45 -0700 Subject: [PATCH] Modified the decompiler stage to: Compile and run AccessTransformer during the pre-RG stage of decompilation. Merge resulting sources that are identical to src/common ToDo: Finish the common intergration: -update_patches - Add common folder support -apply_patches: --patch each side, also patch all common patches to each side incase they are not merged, only if file exists. --- fml/build.xml | 21 ++++--- fml/decompile.py | 18 ++++++ fml/install/.gitignore | 1 + fml/install/fml.py | 121 +++++++++++++++++++++++++++++++++++------ fml/install/install.py | 3 +- 5 files changed, 135 insertions(+), 29 deletions(-) create mode 100644 fml/decompile.py create mode 100644 fml/install/.gitignore diff --git a/fml/build.xml b/fml/build.xml index e1aef8712..7add9a410 100644 --- a/fml/build.xml +++ b/fml/build.xml @@ -226,28 +226,27 @@ You have decided not to continue. This script will stop now. Preparing the MCP environment at ${mcp.home} - + - - - - - + + + + - + + Moving old patched sources at ${patch.mcp.srcdir} out of the way diff --git a/fml/decompile.py b/fml/decompile.py new file mode 100644 index 000000000..3a4ab6f64 --- /dev/null +++ b/fml/decompile.py @@ -0,0 +1,18 @@ +import urllib +import zipfile +import sys +import os + + +if __name__ == '__main__': + if not len(sys.argv) == 3: + print 'Invalid arguments, must supply mcp folder and fml folder: decompile.y ' + else: + mcp_dir = os.path.abspath(sys.argv[1]) + fml_dir = os.path.abspath(sys.argv[2]) + + sys.path.append(os.path.join(fml_dir, 'install')) + + from fml import setup_fml + + setup_fml(fml_dir, mcp_dir) diff --git a/fml/install/.gitignore b/fml/install/.gitignore new file mode 100644 index 000000000..a74b07aee --- /dev/null +++ b/fml/install/.gitignore @@ -0,0 +1 @@ +/*.pyc diff --git a/fml/install/fml.py b/fml/install/fml.py index 839ae95a5..b2057d9e2 100644 --- a/fml/install/fml.py +++ b/fml/install/fml.py @@ -2,6 +2,7 @@ import os, os.path, sys import urllib, zipfile import shutil, glob, fnmatch import subprocess, logging, re +from hashlib import md5 # pylint: disable-msg=E0611 def download_deps(mcp_path): bin_path = os.path.normpath(os.path.join(mcp_path, 'runtime', 'bin')) @@ -20,38 +21,50 @@ def download_deps(mcp_path): print "Downloading Fernflower failed download manually from http://goo.gl/PnJHp" ret = False - for lib in ["argo-2.25.jar", "guava-12.0.jar", "asm-all-4.0.jar"]: - target = os.path.normpath(os.path.join(mcp_path, 'lib', lib)) + for lib in ['argo-2.25.jar', 'guava-12.0.jar', 'asm-all-4.0.jar']: + libF = os.path.join(mcp_path, 'lib') + if not os.path.isdir(libF): + os.makedirs(libF) + + target = os.path.normpath(os.path.join(libF, lib)) + if not os.path.isfile(target): try: urllib.urlretrieve('http://cloud.github.com/downloads/cpw/FML/' + lib, target) print 'Downloaded %s successfully' % lib except: - print 'Download %s failed, download manually from http://cloud.github.com/downloads/cpw/FML/%s and place in MCP/libs' % (lib, lib) + print 'Download %s failed, download manually from http://cloud.github.com/downloads/cpw/FML/%s and place in MCP/lib' % (lib, lib) ret = False return ret def pre_decompile(mcp_dir, fml_dir): - bin_dir = os.path.join(mcp_dir, 'jars', 'bin') - back_jar = os.path.join(bin_dir, 'minecraft.jar.backup') - src_jar = os.path.join(bin_dir, 'minecraft.jar') + file_backup(os.path.join(mcp_dir, 'jars', 'bin'), 'minecraft.jar') + file_backup(os.path.join(mcp_dir, 'jars'), 'minecraft_server.jar') + +def file_backup(base, file): + back_jar = os.path.join(base, file + '.backup') + src_jar = os.path.join(base, file) + + if not os.path.isfile(src_jar): + return if os.path.isfile(back_jar): if os.path.isfile(src_jar): os.remove(src_jar) - shutil.move(back_jar, src_jar) + shutil.copy(back_jar, src_jar) + else: + shutil.copy(src_jar, back_jar) def post_decompile(mcp_dir, fml_dir): - print 'Stripping META-INF from minecraft.jar' bin_dir = os.path.join(mcp_dir, 'jars', 'bin') back_jar = os.path.join(bin_dir, 'minecraft.jar.backup') src_jar = os.path.join(bin_dir, 'minecraft.jar') - if os.path.isfile(back_jar): - os.remove(back_jar) - - shutil.move(src_jar, back_jar) + if not os.path.isfile(src_jar): + return + + print 'Stripping META-INF from minecraft.jar' zip_in = zipfile.ZipFile(back_jar, mode='a') zip_out = zipfile.ZipFile(src_jar, 'w', zipfile.ZIP_DEFLATED) @@ -102,8 +115,9 @@ def cleanup_source(path): def setup_fml(fml_dir, mcp_dir): sys.path.append(mcp_dir) from runtime.decompile import decompile - from runtime.updatemd5 import updatemd5 from runtime.cleanup import cleanup + from runtime.commands import Commands, CLIENT, SERVER + from runtime.mcp import decompile_side src_dir = os.path.join(mcp_dir, 'src') @@ -122,10 +136,40 @@ def setup_fml(fml_dir, mcp_dir): if not download_deps(mcp_dir): sys.exit(1) + def applyrg_shunt(self, side, reobf=False, applyrg_real = Commands.applyrg): + jars = {CLIENT: self.jarclient, SERVER: self.jarserver} + #print "==================================SHUNT %s============================" % side + #print "Java: %s" % self.cmdjava + #print "Javac: %s" % self.cmdjavac + #print "Jar: %s" % jars[side] + + binDir = os.path.join(fml_dir, 'bin') + if not os.path.isdir(binDir): + os.makedirs(binDir) + + #Compile AccessTransformer + forkcmd = ('%s -Xlint:-options -deprecation -g -source 1.6 -target 1.6 -classpath "{classpath};." -sourcepath {sourcepath} -d {outpath} {target}' % self.cmdjavac).format( + classpath=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, 'transformers', 'cpw', 'mods', 'fml', 'common', 'asm', 'transformers', 'AccessTransformer.java')) + self.runcmd(forkcmd) + + #Run AccessTransformer + 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')) + + 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) + + applyrg_real(self, side, reobf) + try: pre_decompile(mcp_dir, fml_dir) os.chdir(mcp_dir) + Commands.applyrg = applyrg_shunt #decompile -d -n -r # Conf JAD CSV -r -d -a -n -p -o -l -g decompile(None, False, False, True, True, False, True, False, False, False, False) @@ -145,6 +189,49 @@ def setup_fml(fml_dir, mcp_dir): #cleanup_source cleanup_source(src_dir) + merge_client_server(mcp_dir) + +def merge_client_server(mcp_dir): + client = os.path.join(mcp_dir, 'src', 'minecraft') + server = os.path.join(mcp_dir, 'src', 'minecraft_server') + shared = os.path.join(mcp_dir, 'src', 'common') + + if not os.path.isdir(client) or not os.path.isdir(server): + return + + if not os.path.isdir(shared): + os.makedirs(shared) + + for path, _, filelist in os.walk(client, followlinks=True): + for cur_file in filelist: + f_client = os.path.normpath(os.path.join(client, path[len(client)+1:], cur_file)).replace(os.path.sep, '/') + f_server = os.path.normpath(os.path.join(server, path[len(client)+1:], cur_file)).replace(os.path.sep, '/') + f_shared = os.path.normpath(os.path.join(shared, path[len(client)+1:], cur_file)).replace(os.path.sep, '/') + + if not os.path.isfile(f_client) or not os.path.isfile(f_server): + continue + + md5_c = "" + md5_s = "" + with open(f_client, 'rb') as fh: + md5_c = md5(fh.read()).hexdigest() + with open(f_server, 'rb') as fh: + md5_s = md5(fh.read()).hexdigest() + + if md5_c != md5_s: + continue + + new_dir = os.path.join(shared, path[len(client)+1:]) + if not os.path.isdir(new_dir): + os.makedirs(new_dir) + + shutil.move(f_client, f_shared) + os.remove(f_server) + +def apply_fml_patches(fml_dir, mcp_dir): + sys.path.append(mcp_dir) + from runtime.updatemd5 import updatemd5 + has_client = os.path.isdir(os.path.join(mcp_dir, 'src', 'minecraft')) has_server = os.path.isdir(os.path.join(mcp_dir, 'src', 'minecraft_server')) @@ -169,10 +256,6 @@ def setup_fml(fml_dir, mcp_dir): updatemd5(None, True) reset_logger() os.chdir(fml_dir) - - #update workspace - print 'Fixing MCP Workspace' - merge_tree(os.path.join(fml_dir, 'eclipse'), os.path.join(mcp_dir, 'eclipse')) def finish_setup_fml(fml_dir, mcp_dir): sys.path.append(mcp_dir) @@ -188,6 +271,10 @@ def finish_setup_fml(fml_dir, mcp_dir): updatemd5(None, True) reset_logger() os.chdir(fml_dir) + + #update workspace + print 'Fixing MCP Workspace' + merge_tree(os.path.join(fml_dir, 'eclipse'), os.path.join(mcp_dir, 'eclipse')) def apply_patches(mcp_dir, patch_dir, target_dir): sys.path.append(mcp_dir) diff --git a/fml/install/install.py b/fml/install/install.py index 323e47036..ac3f1b4df 100644 --- a/fml/install/install.py +++ b/fml/install/install.py @@ -3,11 +3,12 @@ import os, os.path, sys fml_dir = os.path.dirname(os.path.abspath(__file__)) mcp_dir = os.path.abspath('..') -from fml import setup_fml, finish_setup_fml +from fml import setup_fml, finish_setup_fml, apply_fml_patches def main(): print '================ Forge ModLoader Setup Start ===================' setup_fml(fml_dir, mcp_dir) + apply_fml_patches(fml_dir, mcp_sir) finish_setup_fml(fml_dir, mcp_dir) print '================ Forge ModLoader Setup End ==================='