Rewrote patch generation and application to no longer need diff, and attempt to apply common patches on decompiles that don't have one side or the other.

This commit is contained in:
LexManos 2012-08-01 06:54:57 -07:00
parent d0036dda00
commit 4fb08f1660
11 changed files with 111 additions and 117 deletions

View File

@ -1,66 +1,14 @@
import sys import os, sys
import os, os.path, shutil
import commands
import fnmatch
import re
import subprocess, shlex
def cmdsplit(args):
if os.sep == '\\':
args = args.replace('\\', '\\\\')
return shlex.split(args)
def main(): def main():
print("Applying patches") fml_dir = os.path.abspath(sys.argv[1])
sys.stdout.flush() work_dir = os.path.normpath(sys.argv[2])
patches = os.path.abspath(sys.argv[1]) mcp_dir = os.path.normpath(sys.argv[3])
work = os.path.normpath(sys.argv[2])
mcp = os.path.normpath(sys.argv[3])
temp = os.path.abspath('temp.patch')
cmd = cmdsplit('patch -p2 -i "%s" ' % temp) sys.path.append(os.path.join(fml_dir, 'install'))
display = True from fml import apply_fml_patches
if os.name == 'nt': apply_fml_patches(fml_dir, mcp_dir, work_dir, False)
mcp = os.path.abspath(os.path.join(mcp, 'runtime', 'bin', 'applydiff.exe'))
cmd = cmdsplit('"%s" -uf -p2 -i "%s"' % (mcp, temp))
display = False
for path, _, filelist in os.walk(patches, followlinks=True):
for cur_file in fnmatch.filter(filelist, '*.patch'):
patch_file = os.path.normpath(os.path.join(patches, path[len(patches)+1:], cur_file))
if display:
print 'patching file %s' % os.path.join(path[len(patches)+1:], cur_file)
normaliselines(patch_file, temp)
process = subprocess.Popen(cmd, cwd=work, bufsize=-1)
process.communicate()
if os.path.isfile(temp):
os.remove(temp)
#Taken from MCP
def normaliselines(in_filename, out_filename=None):
in_filename = os.path.normpath(in_filename)
if out_filename is None:
tmp_filename = in_filename + '.tmp'
else:
out_filename = os.path.normpath(out_filename)
tmp_filename = out_filename
dir_name = os.path.dirname(out_filename)
if dir_name:
if not os.path.exists(dir_name):
os.makedirs(dir_name)
regex_ending = re.compile(r'\r?\n')
with open(in_filename, 'rb') as in_file:
with open(tmp_filename, 'wb') as out_file:
buf = in_file.read()
if os.linesep == '\r\n':
buf = regex_ending.sub(r'\r\n', buf)
else:
buf = buf.replace('\r\n', '\n')
out_file.write(buf)
if out_filename is None:
shutil.move(tmp_filename, in_filename)
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -212,7 +212,7 @@
<target name="patch" depends="buildenvsetup"> <target name="patch" depends="buildenvsetup">
<exec executable="${python.exe}" dir="${basedir}"> <exec executable="${python.exe}" dir="${basedir}">
<arg value="${basedir}/applypatches.py" /> <arg value="${basedir}/applypatches.py" />
<arg value="${patch.src.dir}" /> <arg value="${basedir}" />
<arg value="${mcp.srcdir}" /> <arg value="${mcp.srcdir}" />
<arg value="${mcp.home}" /> <arg value="${mcp.home}" />
</exec> </exec>

Binary file not shown.

View File

@ -4,6 +4,14 @@ import shutil, glob, fnmatch
import subprocess, logging, re import subprocess, logging, re
from hashlib import md5 # pylint: disable-msg=E0611 from hashlib import md5 # pylint: disable-msg=E0611
#class flushout(object):
# def __init__(self, f):
# self.f = f
# def write(self, x):
# self.f.write(x)
# self.f.flush()
#sys.stdout = flushout(sys.stdout)
def download_deps(mcp_path): def download_deps(mcp_path):
bin_path = os.path.normpath(os.path.join(mcp_path, 'runtime', 'bin')) bin_path = os.path.normpath(os.path.join(mcp_path, 'runtime', 'bin'))
ff_path = os.path.normpath(os.path.join(bin_path, 'fernflower.jar')) ff_path = os.path.normpath(os.path.join(bin_path, 'fernflower.jar'))
@ -196,6 +204,9 @@ def merge_client_server(mcp_dir):
server = os.path.join(mcp_dir, 'src', 'minecraft_server') server = os.path.join(mcp_dir, 'src', 'minecraft_server')
shared = os.path.join(mcp_dir, 'src', 'common') shared = os.path.join(mcp_dir, 'src', 'common')
if not os.path.isdir(shared):
os.makedirs(shared)
if not os.path.isdir(client) or not os.path.isdir(server): if not os.path.isdir(client) or not os.path.isdir(server):
return return
@ -228,34 +239,39 @@ 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)
def apply_fml_patches(fml_dir, mcp_dir): def apply_fml_patches(fml_dir, mcp_dir, src_dir, copy_files=True):
sys.path.append(mcp_dir) sys.path.append(mcp_dir)
from runtime.updatemd5 import updatemd5 from runtime.updatemd5 import updatemd5
has_client = os.path.isdir(os.path.join(mcp_dir, 'src', 'minecraft')) has_client = os.path.isdir(os.path.join(src_dir, 'minecraft'))
has_server = os.path.isdir(os.path.join(mcp_dir, 'src', 'minecraft_server')) has_server = os.path.isdir(os.path.join(src_dir, 'minecraft_server'))
#patch files #patch files
print 'Applying Forge ModLoader patches' print 'Applying Forge ModLoader patches'
sys.stdout.flush()
if has_client: if has_client:
if os.path.isdir(os.path.join(fml_dir, 'patches', 'minecraft')): if os.path.isdir(os.path.join(fml_dir, 'patches', 'minecraft')):
apply_patches(mcp_dir, os.path.join(fml_dir, 'patches', 'minecraft'), src_dir) apply_patches(mcp_dir, os.path.join(fml_dir, 'patches', 'minecraft'), src_dir)
if os.path.isdir(os.path.join(fml_dir, 'src', 'minecraft')): if os.path.isdir(os.path.join(fml_dir, 'patches', 'common')):
apply_patches(mcp_dir, os.path.join(fml_dir, 'patches', 'common'), src_dir, '/common/', '/minecraft/')
if copy_files and os.path.isdir(os.path.join(fml_dir, 'src', 'minecraft')):
copytree(os.path.join(fml_dir, 'src', 'minecraft'), os.path.join(src_dir, 'minecraft')) copytree(os.path.join(fml_dir, 'src', 'minecraft'), os.path.join(src_dir, 'minecraft'))
#delete argo #delete argo
shutil.rmtree(os.path.join(src_dir, 'minecraft', 'argo')) if os.path.isdir(os.path.join(src_dir, 'minecraft', 'argo')):
shutil.rmtree(os.path.join(src_dir, 'minecraft', 'argo'))
if has_server: if has_server:
if os.path.isdir(os.path.join(fml_dir, 'patches', 'minecraft_server')): if os.path.isdir(os.path.join(fml_dir, 'patches', 'minecraft_server')):
apply_patches(mcp_dir, os.path.join(fml_dir, 'patches', 'minecraft_server'), src_dir) apply_patches(mcp_dir, os.path.join(fml_dir, 'patches', 'minecraft_server'), src_dir)
if os.path.isdir(os.path.join(fml_dir, 'src', 'minecraft_server')): if os.path.isdir(os.path.join(fml_dir, 'patches', 'common')):
apply_patches(mcp_dir, os.path.join(fml_dir, 'patches', 'common'), src_dir, '/common/', '/minecraft_server/')
if copy_files and os.path.isdir(os.path.join(fml_dir, 'src', 'minecraft_server')):
copytree(os.path.join(fml_dir, 'src', 'minecraft_server'), os.path.join(src_dir, 'minecraft_server')) copytree(os.path.join(fml_dir, 'src', 'minecraft_server'), os.path.join(src_dir, 'minecraft_server'))
#updatemd5 -f if os.path.isdir(os.path.join(fml_dir, 'patches', 'common')):
os.chdir(mcp_dir) apply_patches(mcp_dir, os.path.join(fml_dir, 'patches', 'common'), src_dir)
updatemd5(None, True) if copy_files and os.path.isdir(os.path.join(fml_dir, 'src', 'common')):
reset_logger() copytree(os.path.join(fml_dir, 'src', 'common'), os.path.join(src_dir, 'common'))
os.chdir(fml_dir)
def finish_setup_fml(fml_dir, mcp_dir): def finish_setup_fml(fml_dir, mcp_dir):
sys.path.append(mcp_dir) sys.path.append(mcp_dir)
@ -276,9 +292,8 @@ def finish_setup_fml(fml_dir, mcp_dir):
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 apply_patches(mcp_dir, patch_dir, target_dir): def apply_patches(mcp_dir, patch_dir, target_dir, find=None, rep=None):
sys.path.append(mcp_dir) sys.path.append(mcp_dir)
from runtime.pylibs.normlines import normaliselines
from runtime.commands import cmdsplit from runtime.commands import cmdsplit
temp = os.path.abspath('temp.patch') temp = os.path.abspath('temp.patch')
@ -293,15 +308,47 @@ def apply_patches(mcp_dir, patch_dir, target_dir):
for path, _, filelist in os.walk(patch_dir, followlinks=True): for path, _, filelist in os.walk(patch_dir, followlinks=True):
for cur_file in fnmatch.filter(filelist, '*.patch'): for cur_file in fnmatch.filter(filelist, '*.patch'):
patch_file = os.path.normpath(os.path.join(patch_dir, path[len(patch_dir)+1:], cur_file)) patch_file = os.path.normpath(os.path.join(patch_dir, path[len(patch_dir)+1:], cur_file))
if display: target_file = os.path.join(target_dir, fix_patch(patch_file, temp, find, rep))
print 'patching file %s' % os.path.join(path[len(patch_dir)+1:], cur_file) if os.path.isfile(target_file):
normaliselines(patch_file, temp) if display:
process = subprocess.Popen(cmd, cwd=target_dir, bufsize=-1) print 'patching file %s' % os.path.normpath(target_file)
process.communicate() process = subprocess.Popen(cmd, cwd=target_dir, bufsize=-1)
process.communicate()
if os.path.isfile(temp): if os.path.isfile(temp):
os.remove(temp) os.remove(temp)
def fix_patch(in_file, out_file, find=None, rep=None):
in_file = os.path.normpath(in_file)
if out_file is None:
tmp_filename = in_file + '.tmp'
else:
out_file = os.path.normpath(out_file)
tmp_file = out_file
dir_name = os.path.dirname(out_file)
if dir_name:
if not os.path.exists(dir_name):
os.makedirs(dir_name)
file = 'not found'
with open(in_file, 'rb') as inpatch:
with open(tmp_file, 'wb') as outpatch:
for line in inpatch:
line = line.rstrip('\r\n')
if line[:3] in ['+++', '---', 'Onl', 'dif']:
if not find == None and not replace == None:
line = line.replace('\\', '/').replace(find, rep).replace('/', os.sep)
else:
line = line.replace('\\', '/').replace('/', os.sep)
outpatch.write(line + os.linesep)
else:
outpatch.write(line + os.linesep)
if line[:3] == '---':
file = line[line.find(os.sep, line.find(os.sep)+1)+1:]
if out_file is None:
shutil.move(tmp_file, in_file)
return file
#Taken from: http://stackoverflow.com/questions/7545299/distutil-shutil-copytree #Taken from: http://stackoverflow.com/questions/7545299/distutil-shutil-copytree
def _mkdir(newdir): def _mkdir(newdir):
"""works the way a good mkdir should :) """works the way a good mkdir should :)

View File

@ -8,7 +8,7 @@ from fml import setup_fml, finish_setup_fml, apply_fml_patches
def main(): def main():
print '================ Forge ModLoader Setup Start ===================' print '================ Forge ModLoader Setup Start ==================='
setup_fml(fml_dir, mcp_dir) setup_fml(fml_dir, mcp_dir)
apply_fml_patches(fml_dir, mcp_sir) apply_fml_patches(fml_dir, mcp_sir, os.path.join(mcp_dir, 'src'))
finish_setup_fml(fml_dir, mcp_dir) finish_setup_fml(fml_dir, mcp_dir)
print '================ Forge ModLoader Setup End ===================' print '================ Forge ModLoader Setup End ==================='

View File

@ -1,5 +1,5 @@
--- ../src-base/minecraft/net/minecraft/client/ClientBrandRetriever.java 0000-00-00 00:00:00.000000000 -0000 --- ../src-base/minecraft/net/minecraft/client/ClientBrandRetriever.java
+++ ../src-work/minecraft/net/minecraft/client/ClientBrandRetriever.java 0000-00-00 00:00:00.000000000 -0000 +++ ../src-work/minecraft/net/minecraft/client/ClientBrandRetriever.java
@@ -4,6 +4,6 @@ @@ -4,6 +4,6 @@
{ {
public static String getClientModName() public static String getClientModName()

View File

@ -1,5 +1,5 @@
--- ../src-base/minecraft/net/minecraft/client/Minecraft.java 0000-00-00 00:00:00.000000000 -0000 --- ../src-base/minecraft/net/minecraft/client/Minecraft.java
+++ ../src-work/minecraft/net/minecraft/client/Minecraft.java 0000-00-00 00:00:00.000000000 -0000 +++ ../src-work/minecraft/net/minecraft/client/Minecraft.java
@@ -126,6 +126,10 @@ @@ -126,6 +126,10 @@
import org.lwjgl.opengl.PixelFormat; import org.lwjgl.opengl.PixelFormat;
import org.lwjgl.util.glu.GLU; import org.lwjgl.util.glu.GLU;

View File

@ -1,5 +1,5 @@
--- ../src-base/minecraft/net/minecraft/client/MinecraftApplet.java 0000-00-00 00:00:00.000000000 -0000 --- ../src-base/minecraft/net/minecraft/client/MinecraftApplet.java
+++ ../src-work/minecraft/net/minecraft/client/MinecraftApplet.java 0000-00-00 00:00:00.000000000 -0000 +++ ../src-work/minecraft/net/minecraft/client/MinecraftApplet.java
@@ -3,6 +3,8 @@ @@ -3,6 +3,8 @@
import java.applet.Applet; import java.applet.Applet;
import java.awt.BorderLayout; import java.awt.BorderLayout;
@ -9,18 +9,18 @@
import net.minecraft.src.CanvasMinecraftApplet; import net.minecraft.src.CanvasMinecraftApplet;
import net.minecraft.src.MinecraftAppletImpl; import net.minecraft.src.MinecraftAppletImpl;
import net.minecraft.src.Session; import net.minecraft.src.Session;
@@ -15,6 +17,11 @@ @@ -14,6 +16,11 @@
private Thread field_71482_c = null;
public void init() public void init()
{ + {
+ FMLEmbeddingRelauncher.appletEntry(this); + FMLEmbeddingRelauncher.appletEntry(this);
+ } + }
+ +
+ public void fmlInitReentry() + public void fmlInitReentry()
+ { {
this.field_71483_a = new CanvasMinecraftApplet(this); this.field_71483_a = new CanvasMinecraftApplet(this);
boolean var1 = "true".equalsIgnoreCase(this.getParameter("fullscreen")); boolean var1 = "true".equalsIgnoreCase(this.getParameter("fullscreen"));
this.field_71481_b = new MinecraftAppletImpl(this, this.field_71483_a, this, this.getWidth(), this.getHeight(), var1);
@@ -60,6 +67,11 @@ @@ -60,6 +67,11 @@
public void start() public void start()

View File

@ -1,6 +1,6 @@
--- ../src-base/minecraft/net/minecraft/src/GuiMainMenu.java 0000-00-00 00:00:00.000000000 -0000 --- ../src-base/minecraft/net/minecraft/src/GuiMainMenu.java
+++ ../src-work/minecraft/net/minecraft/src/GuiMainMenu.java 0000-00-00 00:00:00.000000000 -0000 +++ ../src-work/minecraft/net/minecraft/src/GuiMainMenu.java
@@ -8,11 +8,18 @@ @@ -8,10 +8,17 @@
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
@ -9,16 +9,15 @@
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU; import org.lwjgl.util.glu.GLU;
+
+import com.google.common.base.Strings; +import com.google.common.base.Strings;
+import com.google.common.collect.Lists; +import com.google.common.collect.Lists;
+ +
+import cpw.mods.fml.client.GuiModList; +import cpw.mods.fml.client.GuiModList;
+import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.FMLCommonHandler;
+
public class GuiMainMenu extends GuiScreen public class GuiMainMenu extends GuiScreen
{ {
private static final Random field_73976_a = new Random();
@@ -118,7 +125,8 @@ @@ -118,7 +125,8 @@
this.func_73969_a(var4, 24, var2); this.func_73969_a(var4, 24, var2);
} }
@ -29,18 +28,18 @@
if (this.field_73882_e.field_71448_m) if (this.field_73882_e.field_71448_m)
{ {
@@ -184,6 +192,11 @@ @@ -182,6 +190,11 @@
if (p_73875_1_.field_73741_f == 4)
{
this.field_73882_e.func_71400_g(); this.field_73882_e.func_71400_g();
} + }
+
+ if (p_73875_1_.field_73741_f == 6) + if (p_73875_1_.field_73741_f == 6)
+ { + {
+ this.field_73882_e.func_71373_a(new GuiModList(this)); + this.field_73882_e.func_71373_a(new GuiModList(this));
+ } }
+
if (p_73875_1_.field_73741_f == 11) if (p_73875_1_.field_73741_f == 11)
{
this.field_73882_e.func_71371_a("Demo_World", "Demo_World", DemoWorldServer.field_73071_a);
@@ -400,7 +413,14 @@ @@ -400,7 +413,14 @@
var9 = var9 + " Demo"; var9 = var9 + " Demo";
} }

View File

@ -1,5 +1,5 @@
--- ../src-base/minecraft/net/minecraft/src/StatFileWriter.java 0000-00-00 00:00:00.000000000 -0000 --- ../src-base/minecraft/net/minecraft/src/StatFileWriter.java
+++ ../src-work/minecraft/net/minecraft/src/StatFileWriter.java 0000-00-00 00:00:00.000000000 -0000 +++ ../src-work/minecraft/net/minecraft/src/StatFileWriter.java
@@ -124,17 +124,17 @@ @@ -124,17 +124,17 @@
{ {
String var2 = "local"; String var2 = "local";

View File

@ -5,6 +5,8 @@ import fnmatch
import re import re
import subprocess, shlex import subprocess, shlex
import difflib, time
def cmdsplit(args): def cmdsplit(args):
if os.sep == '\\': if os.sep == '\\':
args = args.replace('\\', '\\\\') args = args.replace('\\', '\\\\')
@ -27,27 +29,25 @@ def cleanDirs(path):
def main(): def main():
print("Creating patches") print("Creating patches")
mcp = sys.argv[1] mcp = os.path.normpath(sys.argv[1])
patchd = os.path.normpath(sys.argv[2])
base = os.path.normpath(os.path.join(mcp, 'src-base')) base = os.path.normpath(os.path.join(mcp, 'src-base'))
work = os.path.normpath(os.path.join(mcp, 'src-work')) work = os.path.normpath(os.path.join(mcp, 'src-work'))
timestamp = re.compile(r'[0-9-]* [0-9:\.]* [+-][0-9]*\r?\n')
mcpath = re.compile(mcp)
for path, _, filelist in os.walk(work, followlinks=True): for path, _, filelist in os.walk(work, followlinks=True):
for cur_file in fnmatch.filter(filelist, '*.java'): for cur_file in fnmatch.filter(filelist, '*.java'):
file_base = os.path.normpath(os.path.join(base, path[len(work)+1:], cur_file)).replace(os.path.sep, '/') file_base = os.path.normpath(os.path.join(base, path[len(work)+1:], cur_file)).replace(os.path.sep, '/')
file_work = os.path.normpath(os.path.join(work, path[len(work)+1:], cur_file)).replace(os.path.sep, '/') file_work = os.path.normpath(os.path.join(work, path[len(work)+1:], cur_file)).replace(os.path.sep, '/')
patch = ''
cmd = 'diff -u %s %s -r --strip-trailing-cr --new-file' % (file_base, file_work) fromlines = open(file_base, 'U').readlines()
process = subprocess.Popen(cmdsplit(cmd), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=-1) tolines = open(file_work, 'U').readlines()
patch, _ = process.communicate()
patch_dir = os.path.join(sys.argv[2], path[len(work)+1:]) patch = ''.join(difflib.unified_diff(fromlines, tolines, '../' + file_base[len(mcp)+1:], '../' + file_work[len(mcp)+1:], '', '', n=3))
patch_dir = os.path.join(patchd, path[len(work)+1:])
patch_file = os.path.join(patch_dir, cur_file + '.patch') patch_file = os.path.join(patch_dir, cur_file + '.patch')
if len(patch) > 0: if len(patch) > 0:
print patch_file print patch_file[len(patchd)+1:]
patch = timestamp.sub("0000-00-00 00:00:00.000000000 -0000\n", patch)
patch = mcpath.sub('..',patch)
patch = patch.replace('\r\n', '\n') patch = patch.replace('\r\n', '\n')
if not os.path.exists(patch_dir): if not os.path.exists(patch_dir):
@ -60,7 +60,7 @@ def main():
os.remove(patch_file) os.remove(patch_file)
cleanDirs('patches') cleanDirs(patchd)
if __name__ == '__main__': if __name__ == '__main__':
main() main()