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, 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)
import os, sys
def main():
print("Applying patches")
sys.stdout.flush()
patches = os.path.abspath(sys.argv[1])
work = os.path.normpath(sys.argv[2])
mcp = os.path.normpath(sys.argv[3])
temp = os.path.abspath('temp.patch')
fml_dir = os.path.abspath(sys.argv[1])
work_dir = os.path.normpath(sys.argv[2])
mcp_dir = os.path.normpath(sys.argv[3])
cmd = cmdsplit('patch -p2 -i "%s" ' % temp)
display = True
sys.path.append(os.path.join(fml_dir, 'install'))
from fml import apply_fml_patches
if os.name == 'nt':
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)
apply_fml_patches(fml_dir, mcp_dir, work_dir, False)
if __name__ == '__main__':
main()

View File

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

Binary file not shown.

View File

@ -4,6 +4,14 @@ import shutil, glob, fnmatch
import subprocess, logging, re
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):
bin_path = os.path.normpath(os.path.join(mcp_path, 'runtime', 'bin'))
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')
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):
return
@ -227,35 +238,40 @@ def merge_client_server(mcp_dir):
shutil.move(f_client, f_shared)
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)
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'))
has_client = os.path.isdir(os.path.join(src_dir, 'minecraft'))
has_server = os.path.isdir(os.path.join(src_dir, 'minecraft_server'))
#patch files
print 'Applying Forge ModLoader patches'
sys.stdout.flush()
if has_client:
if os.path.isdir(os.path.join(fml_dir, 'patches', 'minecraft')):
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'))
#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 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)
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'))
#updatemd5 -f
os.chdir(mcp_dir)
updatemd5(None, True)
reset_logger()
os.chdir(fml_dir)
if os.path.isdir(os.path.join(fml_dir, 'patches', 'common')):
apply_patches(mcp_dir, os.path.join(fml_dir, 'patches', 'common'), src_dir)
if copy_files and os.path.isdir(os.path.join(fml_dir, 'src', 'common')):
copytree(os.path.join(fml_dir, 'src', 'common'), os.path.join(src_dir, 'common'))
def finish_setup_fml(fml_dir, mcp_dir):
sys.path.append(mcp_dir)
@ -276,9 +292,8 @@ def finish_setup_fml(fml_dir, mcp_dir):
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):
def apply_patches(mcp_dir, patch_dir, target_dir, find=None, rep=None):
sys.path.append(mcp_dir)
from runtime.pylibs.normlines import normaliselines
from runtime.commands import cmdsplit
temp = os.path.abspath('temp.patch')
@ -293,14 +308,46 @@ def apply_patches(mcp_dir, patch_dir, target_dir):
for path, _, filelist in os.walk(patch_dir, followlinks=True):
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))
if display:
print 'patching file %s' % os.path.join(path[len(patch_dir)+1:], cur_file)
normaliselines(patch_file, temp)
process = subprocess.Popen(cmd, cwd=target_dir, bufsize=-1)
process.communicate()
target_file = os.path.join(target_dir, fix_patch(patch_file, temp, find, rep))
if os.path.isfile(target_file):
if display:
print 'patching file %s' % os.path.normpath(target_file)
process = subprocess.Popen(cmd, cwd=target_dir, bufsize=-1)
process.communicate()
if os.path.isfile(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
def _mkdir(newdir):

View File

@ -8,7 +8,7 @@ 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)
apply_fml_patches(fml_dir, mcp_sir, os.path.join(mcp_dir, 'src'))
finish_setup_fml(fml_dir, mcp_dir)
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-work/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
@@ -4,6 +4,6 @@
{
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-work/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
@@ -126,6 +126,10 @@
import org.lwjgl.opengl.PixelFormat;
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-work/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
@@ -3,6 +3,8 @@
import java.applet.Applet;
import java.awt.BorderLayout;
@ -9,18 +9,18 @@
import net.minecraft.src.CanvasMinecraftApplet;
import net.minecraft.src.MinecraftAppletImpl;
import net.minecraft.src.Session;
@@ -15,6 +17,11 @@
@@ -14,6 +16,11 @@
private Thread field_71482_c = null;
public void init()
{
+ {
+ FMLEmbeddingRelauncher.appletEntry(this);
+ }
+
+ public void fmlInitReentry()
+ {
{
this.field_71483_a = new CanvasMinecraftApplet(this);
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 @@
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-work/minecraft/net/minecraft/src/GuiMainMenu.java 0000-00-00 00:00:00.000000000 -0000
@@ -8,11 +8,18 @@
--- ../src-base/minecraft/net/minecraft/src/GuiMainMenu.java
+++ ../src-work/minecraft/net/minecraft/src/GuiMainMenu.java
@@ -8,10 +8,17 @@
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
@ -9,16 +9,15 @@
import net.minecraft.client.Minecraft;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+
+import cpw.mods.fml.client.GuiModList;
+import cpw.mods.fml.common.FMLCommonHandler;
+
public class GuiMainMenu extends GuiScreen
{
private static final Random field_73976_a = new Random();
@@ -118,7 +125,8 @@
this.func_73969_a(var4, 24, var2);
}
@ -29,18 +28,18 @@
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();
}
+ }
+
+ if (p_73875_1_.field_73741_f == 6)
+ {
+ this.field_73882_e.func_71373_a(new GuiModList(this));
+ }
+
}
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 @@
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-work/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
@@ -124,17 +124,17 @@
{
String var2 = "local";

View File

@ -5,6 +5,8 @@ import fnmatch
import re
import subprocess, shlex
import difflib, time
def cmdsplit(args):
if os.sep == '\\':
args = args.replace('\\', '\\\\')
@ -27,27 +29,25 @@ def cleanDirs(path):
def main():
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'))
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 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_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)
process = subprocess.Popen(cmdsplit(cmd), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=-1)
patch, _ = process.communicate()
patch_dir = os.path.join(sys.argv[2], path[len(work)+1:])
fromlines = open(file_base, 'U').readlines()
tolines = open(file_work, 'U').readlines()
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')
if len(patch) > 0:
print patch_file
patch = timestamp.sub("0000-00-00 00:00:00.000000000 -0000\n", patch)
patch = mcpath.sub('..',patch)
print patch_file[len(patchd)+1:]
patch = patch.replace('\r\n', '\n')
if not os.path.exists(patch_dir):
@ -60,7 +60,7 @@ def main():
os.remove(patch_file)
cleanDirs('patches')
cleanDirs(patchd)
if __name__ == '__main__':
main()