Step 1: The Purge

This commit is contained in:
AbrarSyed 2013-11-09 15:44:50 -06:00
parent 84fd2a147e
commit f9563e5a34
11 changed files with 0 additions and 1128 deletions

View file

@ -1,95 +0,0 @@
import os
import sys
import fnmatch
import shlex
import difflib
import time, subprocess
from optparse import OptionParser
def cmdsplit(args):
if os.sep == '\\':
args = args.replace('\\', '\\\\')
return shlex.split(args)
def main():
print("Applying patches")
parser = OptionParser()
parser.add_option('-m', '--mcp-dir', action='store', dest='mcp_dir', help='Path to MCP', default=None)
parser.add_option('-p', '--patch-dir', action='store', dest='patch_dir', help='Patches Directory', default=None)
parser.add_option('-t', '--target-dir', action='store', dest='target_dir', help='Target Directory', default=None)
options, _ = parser.parse_args()
if options.mcp_dir is None:
print 'Must supply MCP directory with --mcp-dir'
return
elif options.patch_dir is None:
print 'Must supply patches directory with --patch-dir'
return
elif options.target_dir is None:
print 'Must supplt target directory with --target-dir'
return
print "Applying patches from '%s' to '%s'" % (options.patch_dir, options.target_dir)
apply_patches(options.mcp_dir, options.patch_dir, options.target_dir)
def apply_patches(mcp_dir, patch_dir, target_dir, find=None, rep=None):
# Attempts to apply a directory full of patch files onto a target directory.
sys.path.append(mcp_dir)
temp = os.path.abspath('temp.patch')
cmd = cmdsplit('patch -p2 -i "%s" ' % temp)
if os.name == 'nt':
applydiff = os.path.abspath(os.path.join(mcp_dir, 'runtime', 'bin', 'applydiff.exe'))
cmd = cmdsplit('"%s" -uf -p2 -i "%s"' % (applydiff, temp))
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))
target_file = os.path.join(target_dir, fix_patch(patch_file, temp, find, rep))
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):
#Fixes the following issues in the patch file if they exist:
# Normalizes the path seperators for the current OS
# Normalizes the line endings
# Returns the path that the file wants to apply to
in_file = os.path.normpath(in_file)
if out_file is None:
tmp_file = 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 rep == 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
if __name__ == '__main__':
main()

View file

@ -1,34 +0,0 @@
import os, os.path, sys
from optparse import OptionParser
forge_dir = os.path.dirname(os.path.abspath(__file__))
mcp_dir = os.path.abspath('..')
from forge import build_forge_dev
def main():
parser = OptionParser()
parser.add_option('-m', '--mcp-dir', action='store', dest='mcp_dir', help='MCP Path', default=None)
parser.add_option('-b', '--build', action='store', dest='build', help='Build number', default=None)
options, _ = parser.parse_args()
build_num = 0
if not options.build is None:
try:
build_num = int(options.build)
except:
pass
fml_dir = os.path.join(forge_dir, 'fml')
mcp_dir = os.path.join(forge_dir, 'mcp')
if not options.mcp_dir is None:
mcp_dir = os.path.abspath(options.mcp_dir)
elif os.path.isfile(os.path.join('..', 'runtime', 'commands.py')):
mcp_dir = os.path.abspath('..')
sys.exit(build_forge_dev(mcp_dir, forge_dir, fml_dir, build_num))
if __name__ == '__main__':
main()

View file

@ -1,113 +0,0 @@
import os, os.path, sys, re
import json, urllib2
from pprint import pprint
from urlparse import urlparse
import base64
import optparse, ast
class PreemptiveBasicAuthHandler(urllib2.BaseHandler):
def __init__(self, password_mgr=None):
if password_mgr is None:
password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
self.passwd = password_mgr
self.add_password = self.passwd.add_password
def http_request(self,req):
uri = req.get_full_url()
user, pw = self.passwd.find_user_password(None,uri)
if pw is None: return req
raw = "%s:%s" % (user, pw)
auth = 'Basic %s' % base64.b64encode(raw).strip()
req.add_unredirected_header('Authorization', auth)
return req
def https_request(self,req):
return self.http_request(req)
def read_url(url):
handler = PreemptiveBasicAuthHandler()
handler.add_password(None, 'ci.jenkins.minecraftforge.net', 'console_script', 'dc6d48ca20a474beeac280a9a16a926e')
file = urllib2.build_opener(handler).open(url)
data = file.read()
file.close()
return data
def getBuildInfo(url, current_version=None):
data = read_url(url)
data = ast.literal_eval(data)['allBuilds']
data = sorted(data, key=lambda key: key['number'], reverse=False)
items = []
output = []
for build in data:
build['actions'] = filter(lambda act: act is not None, build['actions'])
build['actions'] = filter(lambda act: 'text' in act, build['actions'])
build['actions'] = filter(lambda act: not ' ' in act['text'], build['actions'])
if len(build['actions']) == 0:
build['version'] = current_version
current_version = None
else:
build['version'] = build['actions'][0]['text']
build['items'] = build['changeSet']['items']
for item in build['items']:
item['author'] = item['author']['fullName']
if build['result'] != 'SUCCESS':
items += build['items']
else:
build['items'] = items + build['items']
items = []
output += [build]
build.pop('changeSet')
build.pop('actions')
return sorted(output, key=lambda key: key['number'], reverse=True)
def add_latest_build(url, builds, current_version=None):
data = read_url(url)
data = ast.literal_eval(data)
number = data['number']
if builds[0]['number'] == data['number']:
return builds
for item in data['changeSet']['items']:
item['author'] = item['author']['fullName']
build = {
'number' : data['number'],
'result' : 'SUCCESS', #Currently build should always be success... Else things derp after words
'version' : current_version,
'items' : data['changeSet']['items']
}
return [build] + builds
def make_changelog(job_path, target_build, change_file, current_version=None):
builds = getBuildInfo('%s/api/python?tree=allBuilds[result,number,actions[text],changeSet[items[author[fullName],comment]]]&pretty=true' % job_path, current_version)
builds = add_latest_build('%s/lastBuild/api/python?pretty=true&tree=number,changeSet[items[author[fullName],comment]]' % job_path, builds, current_version)
log = [ "Changelog:" ]
for build in builds:
if int(build['number']) > target_build: continue
if len(build['items']) == 0: continue
log.append('')
if build['version'] is None:
log.append('Build %s' % build['number'])
else:
log.append('Build %s' % build['version'])
for change in build['items']:
comments = filter(lambda cmt: len(cmt) > 0, change['comment'].split('\n'))
if len(comments) > 1:
log.append('\t' + change['author'])
for comment in comments:
log.append('\t\t' + comment)
elif len(comments) == 1:
log.append('\t%s: %s' % (change['author'], comments[0]))
file = open(change_file, 'wb')
for line in log:
file.write('%s\n' % line)
file.close()
if __name__ == '__main__':
make_changelog("http://ci.jenkins.minecraftforge.net/job/minecraftforge/", 70000, 'changelog.txt', 'pinecone')

139
forge.py
View file

@ -1,139 +0,0 @@
import os, os.path, sys
import urllib, zipfile
import shutil, glob, fnmatch
import subprocess, logging, re
import csv, shutil
import pprint
forge_dir = os.path.dirname(os.path.abspath(__file__))
def reset_logger():
log = logging.getLogger()
while len(log.handlers) > 0:
log.removeHandler(log.handlers[0])
version_reg = re.compile(r'(([a-z]+)Version[\s]+=[\s]+)(\d+);')
def load_version(build=0):
info = {'major' : -1,
'minor' : -1,
'revision' : -1,
'build' : -1
}
hook_file = os.path.join(forge_dir, 'common/net/minecraftforge/common/ForgeVersion.java'.replace('/', os.sep))
with open(hook_file, 'r') as fh:
buf = fh.read()
def proc(match):
try:
info[match.group(2)] = int(match.group(3))
except:
pass
return match.group(0)
buf = version_reg.sub(proc, buf)
info['build'] = build
return info
def inject_version(src_file, build=0):
version = load_version(build)
tmp_file = src_file + '.tmp'
with open(src_file, 'r') as fh:
buf = fh.read()
def mapname(match):
try:
return '%s%s;' % (match.group(1), version[match.group(2)])
except KeyError:
pass
return match.group(0)
buf = version_reg.sub(mapname, buf).replace('\r\n', '\n')
with open(tmp_file, 'wb') as fh:
fh.write(buf)
shutil.move(tmp_file, src_file)
def zip_folder(path, key, zip):
import pprint
files = os.listdir(path)
for file in files:
file_path = os.path.join(path, file)
file_key = os.path.join(key, file)
if os.path.isdir(file_path):
zip_folder(file_path, file_key, zip)
else:
if not file_key.replace(os.sep, '/') in zip.NameToInfo:
print ' ' + file_key
zip.write(file_path, file_key)
def zip_create(path, key, zip_name):
zip = zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED)
if os.path.isdir(path):
zip_folder(path, key, zip)
else:
zip.write(path, key)
zip.close()
def apply_forge_patches(fml_dir, mcp_dir, forge_dir, src_dir, copy_files=True):
sys.path.append(fml_dir)
sys.path.append(os.path.join(fml_dir, 'install'))
from fml import copytree, apply_patches
#patch files
print 'Applying Minecraft Forge patches'
sys.stdout.flush()
if os.path.isdir(os.path.join(forge_dir, 'patches', 'minecraft')):
apply_patches(mcp_dir, os.path.join(forge_dir, 'patches', 'minecraft'), src_dir)
if copy_files and os.path.isdir(os.path.join(forge_dir, 'client')):
copytree(os.path.join(forge_dir, 'client'), os.path.join(src_dir, 'minecraft'))
if copy_files and os.path.isdir(os.path.join(forge_dir, 'common')):
copytree(os.path.join(forge_dir, 'common'), os.path.join(src_dir, 'minecraft'))
def build_forge_dev(mcp_dir, forge_dir, fml_dir, build_num=0):
version = load_version(build_num)
print '=================================== Build %d.%d.%d.%d Start =================================' % (version['major'], version['minor'], version['revision'], version['build'])
src_dir = os.path.join(mcp_dir, 'src')
if os.path.isdir(src_dir):
shutil.rmtree(src_dir)
sys.path.append(fml_dir)
sys.path.append(os.path.join(fml_dir, 'install'))
from fml import copytree
print 'src_work -> src'
copytree(os.path.join(mcp_dir, 'src_work'), src_dir)
print '\nCopying Client Code'
copytree(os.path.join(forge_dir, 'client'), os.path.join(src_dir, 'minecraft'), -1)
print '\nCopying Common Code'
copytree(os.path.join(forge_dir, 'common'), os.path.join(src_dir, 'minecraft'), -1)
print
inject_version(os.path.join(src_dir, 'minecraft/net/minecraftforge/common/ForgeVersion.java'.replace('/', os.sep)), build_num)
error_level = 0
try:
sys.path.append(mcp_dir)
from runtime.commands import Commands, CLIENT, SERVER, CalledProcessError
from runtime.mcp import recompile_side
os.chdir(mcp_dir)
reset_logger()
commands = Commands(None, verify=True)
try:
recompile_side(commands, CLIENT)
except CalledProcessError as e:
error_level = 1
pass
reset_logger()
os.chdir(forge_dir)
except SystemExit, e:
if not e.code == 0:
print 'Recompile Exception: %d ' % e.code
error_level = e.code
print '=================================== Build Finished %d =================================' % error_level
return error_level

View file

@ -1,3 +0,0 @@
@echo off
.\fml\python\python_fml install.py %*
pause

View file

@ -1,78 +0,0 @@
import os, os.path, sys
import urllib, zipfile
import shutil, glob, fnmatch
import subprocess, logging
from optparse import OptionParser
def fml_main(fml_dir, mcp_dir, gen_conf=True, disable_patches=False, disable_at=False, disable_merge=False, enable_server=False,
disable_client=False, disable_rename=False, disable_assets=False, decompile=False):
sys.path.append(fml_dir)
from fml import download_mcp, setup_mcp, decompile_minecraft, apply_fml_patches, finish_setup_fml
print '================ Forge ModLoader Setup Start ==================='
download_mcp(fml_dir, mcp_dir)
setup_mcp(fml_dir, mcp_dir, gen_conf)
if decompile:
decompile_minecraft(fml_dir, mcp_dir, disable_at=disable_at, disable_merge=disable_merge,
enable_server=enable_server, disable_client=disable_client,
disable_assets=disable_assets)
if disable_patches:
print 'Patching disabled'
else:
apply_fml_patches(fml_dir, mcp_dir, os.path.join(mcp_dir, 'src'))
finish_setup_fml(fml_dir, mcp_dir, enable_server=enable_server, disable_client=disable_client, disable_rename=disable_rename)
else:
print 'Decompile free install is on the to-do!'
print '================ Forge ModLoader Setup End ==================='
def forge_main(forge_dir, fml_dir, mcp_dir):
sys.path.append(mcp_dir)
sys.path.append(fml_dir)
from runtime.updatenames import updatenames
from runtime.updatemd5 import updatemd5
from forge import apply_forge_patches
from fml import reset_logger
print '=============================== Minecraft Forge Setup Start ====================================='
print 'Applying forge patches'
apply_forge_patches(fml_dir, mcp_dir, forge_dir, os.path.join(mcp_dir, 'src'), True)
os.chdir(mcp_dir)
updatenames(None, True, True, False)
reset_logger()
updatemd5(None, True, True, False)
reset_logger()
os.chdir(forge_dir)
print '=============================== Minecraft Forge Setup Finished ================================='
if __name__ == '__main__':
parser = OptionParser()
parser.add_option('-m', '--mcp-dir', action='store', dest='mcp_dir', help='Path to download/extract MCP to', default=None )
parser.add_option('-p', '--no-patch', action="store_true", dest='no_patch', help='Disable application of FML patches', default=False)
parser.add_option('-a', '--no-access', action="store_true", dest='no_access', help='Disable access transformers', default=False)
parser.add_option('-s', '--server', action="store_true", dest='enable_server', help='Enable decompilation of server', default=False)
parser.add_option('-c', '--no-client', action="store_true", dest='no_client', help='Disable decompilation of server', default=False)
parser.add_option('-e', '--no-merge', action="store_true", dest='no_merge', help='Disable merging server code into client', default=False)
parser.add_option('-n', '--no-rename', action="store_true", dest='no_rename', help='Disable running updatenames', default=False)
parser.add_option( '--no-assets', action="store_true", dest='no_assets', help='Disable downloading of assets folder', default=False)
parser.add_option('-d', '--decompile', action="store_true", dest='decompile', help='Decompile minecraft and apply patches', default=True)
options, _ = parser.parse_args()
forge_dir = os.path.dirname(os.path.abspath(__file__))
fml_dir = os.path.abspath('fml')
mcp_dir = os.path.abspath('mcp')
if not options.mcp_dir is None:
mcp_dir = os.path.abspath(options.mcp_dir)
if options.no_client:
options.no_patch = True
if options.no_merge:
options.no_patch = True
fml_main(fml_dir, mcp_dir, disable_patches=options.no_patch,
disable_at=options.no_access, disable_merge=options.no_merge,
enable_server=options.enable_server, disable_client=options.no_client,
disable_rename=options.no_rename, disable_assets=options.no_assets,
decompile=options.decompile, gen_conf=False)
forge_main(forge_dir, fml_dir, mcp_dir)

View file

@ -1,2 +0,0 @@
#!/bin/bash
python install.py "$@"

View file

@ -1,417 +0,0 @@
import os, os.path, sys, glob
import shutil, fnmatch, time, json
import logging, zipfile, re, subprocess
from pprint import pformat, pprint
from optparse import OptionParser
from urllib2 import HTTPError
from contextlib import closing
from datetime import datetime
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
forge_dir = os.path.dirname(os.path.abspath(__file__))
from forge import reset_logger, load_version, zip_folder, zip_create, inject_version, build_forge_dev
from changelog import make_changelog
zip = None
zip_name = None
zip_base = None
version_str = None
version_mc = None
def main():
global version_str
global version_mc
parser = OptionParser()
parser.add_option('-m', '--mcp-dir', action='store', dest='mcp_dir', help='MCP Path', default=None)
parser.add_option('-b', '--build', action='store', dest='build', help='Build number', default=None)
parser.add_option('-s', '--skipchangelog', action='store_true', dest='skip_changelog', help='Skip Changelog', default=False)
parser.add_option('-j', '--sign-jar', action='store', dest='sign_jar', help='Path to jar signer command', default=None)
options, _ = parser.parse_args()
build_num = 0
if not options.build is None:
try:
build_num = int(options.build)
except:
pass
mcp_dir = os.path.join(forge_dir, 'mcp')
if not options.mcp_dir is None:
mcp_dir = os.path.abspath(options.mcp_dir)
ret = 0
fml_dir = os.path.join(forge_dir, 'fml')
ret = build_forge_dev(mcp_dir, forge_dir, fml_dir, build_num)
if ret != 0:
sys.exit(ret)
temp_dir = os.path.join(forge_dir, 'temp')
src_dir = os.path.join(mcp_dir, 'src')
reobf_dir = os.path.join(mcp_dir, 'reobf')
client_dir = os.path.join(reobf_dir, 'minecraft')
fml_dir = os.path.join(temp_dir, 'fml')
print '=================================== Release Start ================================='
fml = glob.glob(os.path.join(forge_dir, 'fml', 'target', 'fml-src-*.%d-*.zip' % build_num))
if not len(fml) == 1:
if len(fml) == 0:
print 'Missing FML source zip, should be named fml-src-*.zip inside ./fml/target/ created when running setup'
else:
print 'To many FML source zips found, we should only have one. Check the Forge Git for the latest FML version supported'
sys.exit(1)
if os.path.isdir(fml_dir):
shutil.rmtree(fml_dir)
print 'Extracting: %s' % os.path.basename(fml[0])
zf = zipfile.ZipFile(fml[0])
zf.extractall(temp_dir)
zf.close()
if os.path.isfile('MANIFEST.MF'):
os.remove('MANIFEST.MF')
fml_name = os.path.basename(fml[0]).replace('src', 'universal').replace('.zip', '.jar').replace('-master.', '.')
print('Extracting %s MANIFEST.MF' % fml_name)
with closing(zipfile.ZipFile(os.path.join(forge_dir, 'fml', 'target', fml_name), mode='r')) as zip_in:
with closing(open('MANIFEST.MF', 'wb')) as out:
out.write(zip_in.read('META-INF/MANIFEST.MF'))
error_level = 0
try:
sys.path.append(mcp_dir)
from runtime.reobfuscate import reobfuscate
os.chdir(mcp_dir)
reset_logger()
reobfuscate(None, False, True, True, True, False, False)
reset_logger()
os.chdir(forge_dir)
except SystemExit, e:
print 'Reobfusicate Exception: %d ' % e.code
error_level = e.code
extract_fml_obfed(fml_dir, mcp_dir, reobf_dir, client_dir)
gen_bin_patches(mcp_dir, os.path.join(forge_dir, 'fml'), build_num, client_dir)
version = load_version(build_num)
version_forge = '%d.%d.%d.%d' % (version['major'], version['minor'], version['revision'], version['build'])
version_mc = load_mc_version(fml_dir)
branch = get_branch_name()
version_str = '%s-%s' % (version_mc, version_forge)
if not branch == "":
version_str = '%s-%s' % (version_str, branch)
out_folder = os.path.join(forge_dir, 'target')
if not os.path.isdir(out_folder):
os.makedirs(out_folder)
for f in ['minecraftforge-changelog-%s.txt', 'minecraftforge-universal-%s.jar', 'minecraftforge-installer-%s.jar']:
fn = os.path.join(out_folder, f % version_str)
if os.path.isfile(fn):
os.remove(fn)
if not options.skip_changelog:
changelog_file = 'target/minecraftforge-changelog-%s.txt' % (version_str)
try:
make_changelog("http://ci.jenkins.minecraftforge.net/job/minecraftforge/", build_num, changelog_file, version_str)
except HTTPError, e:
print 'Changelog failed to generate: %s' % e
options.skip_changelog = True
version_file = 'forgeversion.properties'
if os.path.exists(version_file):
os.remove(version_file)
with open(version_file, 'wb') as fh:
fh.write('forge.major.number=%d\n' % version['major'])
fh.write('forge.minor.number=%d\n' % version['minor'])
fh.write('forge.revision.number=%d\n' % version['revision'])
fh.write('forge.build.number=%d\n' % version['build'])
json_data = gather_json(forge_dir, version_mc, version_forge, version_str)
if not options.sign_jar is None:
sign_jar(forge_dir, options.sign_jar, client_dir, 'minecraftforge-universal-%s.jar' % version_str)
else:
zip_start('minecraftforge-universal-%s.jar' % version_str)
zip_folder(client_dir, '', zip)
zip_add('MANIFEST.MF','META-INF/MANIFEST.MF')
zip_add('client/forge_logo.png')
zip_add('install/MinecraftForge-Credits.txt')
zip_add('install/MinecraftForge-License.txt')
zip_add('install/Paulscode IBXM Library License.txt')
zip_add('install/Paulscode SoundSystem CodecIBXM License.txt')
zip_add('common/forge_at.cfg')
zip_add('common/assets','assets')
zip_add(version_file)
if not options.skip_changelog:
zip_add(changelog_file, 'MinecraftForge-Changelog.txt')
print(' version.json')
zip.writestr('version.json', json.dumps(json_data['versionInfo'], indent=4, separators=(',', ': ')))
#Add dependancy and licenses from FML
FML_FILES = [
'CREDITS-fml.txt',
'LICENSE-fml.txt',
'README-fml.txt',
'common/fml_at.cfg',
'common/fml_marker.cfg',
'common/fmlversion.properties',
'common/mcpmod.info',
'client/mcplogo.png',
'common/deobfuscation_data-%s.lzma' % version_mc
]
for file in FML_FILES:
zip_add(os.path.join(fml_dir, file))
zip_end()
build_installer(forge_dir, version_str, version_forge, version_mc, out_folder, json.dumps(json_data, indent=4, separators=(',', ': ')))
inject_version(os.path.join(forge_dir, 'common/net/minecraftforge/common/ForgeVersion.java'.replace('/', os.sep)), build_num)
zip_start('minecraftforge-src-%s.zip' % version_str, 'forge')
zip_add('client', 'client')
zip_add('common', 'common')
zip_add('patches', 'patches')
zip_add(fml_dir, 'fml')
zip_add('install', '')
zip_add('forge.py')
zip_add(version_file)
if not options.skip_changelog:
zip_add(changelog_file, 'MinecraftForge-Changelog.txt')
zip_end()
inject_version(os.path.join(forge_dir, 'common/net/minecraftforge/common/ForgeVersion.java'.replace('/', os.sep)), 0)
if os.path.exists(version_file):
os.remove(version_file)
shutil.rmtree(temp_dir)
if os.path.isfile('MANIFEST.MF'):
os.remove('MANIFEST.MF')
print '=================================== Release Finished %d =================================' % error_level
sys.exit(error_level)
def gather_json(forge_dir, version_mc, version_forge, version_str):
def getTZ():
ret = '-'
t = time.timezone
if (t < 0):
ret = '+'
t *= -1
h = int(t/60/60)
t -= (h*60*60)
m = int(t/60)
return '%s%02d%02d' % (ret, h, m)
timestamp = datetime.now().replace(microsecond=0).isoformat() + getTZ()
json_data = {}
with closing(open(os.path.join(forge_dir, 'fml', 'jsons', '%s-rel.json' % version_mc), 'r')) as fh:
data = fh.read()
data = data.replace('@version@', version_forge)
data = data.replace('@timestamp@', timestamp)
data = data.replace('@minecraft_version@', version_mc)
data = data.replace('@universal_jar@', 'minecraftforge-universal-%s.jar' % version_str)
data = data.replace('FMLTweaker', 'F_M_L_Tweaker')
data = data.replace('FML', 'Forge')
data = data.replace('F_M_L_Tweaker', 'FMLTweaker')
data = data.replace('cpw.mods:fml:', 'net.minecraftforge:minecraftforge:')
json_data = json.loads(data)
pprint(json_data)
return json_data
def build_installer(forge_dir, version_str, version_forge, version_minecraft, out_folder, json_data):
file_name = 'minecraftforge-installer-%s.jar' % version_str
universal_name = 'minecraftforge-universal-%s.jar' % version_str
print '================== %s Start ==================' % file_name
with closing(zipfile.ZipFile(os.path.join(forge_dir, 'fml', 'installer_base.jar'), mode='a')) as zip_in:
with closing(zipfile.ZipFile(os.path.join(out_folder, file_name), 'w', zipfile.ZIP_DEFLATED)) as zip_out:
# Copy everything over
for i in zip_in.filelist:
if not i.filename in ['install_profile.json', 'big_logo.png']:
#print(' %s' % i.filename)
zip_out.writestr(i.filename, zip_in.read(i.filename))
print(' %s' % universal_name)
zip_out.write(os.path.join(out_folder, universal_name), universal_name)
print(' big_logo.png')
zip_out.write(os.path.join(forge_dir, 'client', 'forge_logo.png'), 'big_logo.png')
print(' install_profile.json')
zip_out.writestr('install_profile.json', json_data)
print '================== %s Finished ==================' % file_name
def zip_add(file, key=None):
if key == None:
key = os.path.basename(file)
else:
key = key.replace('/', os.sep)
if not zip_base is None:
key = os.path.join(zip_base, key)
file = os.path.join(forge_dir, file.replace('/', os.sep))
if os.path.isdir(file):
zip_folder(file, key, zip)
else:
if os.path.isfile(file):
print ' ' + key
zip.write(file, key)
def zip_start(name, base=None):
global zip, zip_name, zip_base
zip_name = name
print '================== %s Start ==================' % zip_name
zip_file = os.path.join(forge_dir, 'target', name)
zip = zipfile.ZipFile(zip_file, 'w', zipfile.ZIP_DEFLATED)
zip_base = base
def zip_end():
global zip, zip_name, zip_base
zip.close()
print '================== %s Finished ==================' % zip_name
zip_name = None
zip_base = None
def load_mc_version(fml_dir):
props = os.path.join(fml_dir, 'common', 'fmlversion.properties')
if not os.path.isfile(props):
print 'Could not load fmlversion.properties, build failed'
sys.exit(1)
with open(props, 'r') as fh:
for line in fh:
line = line.strip()
if line.startswith('fmlbuild.mcversion'):
return line.split('=')[1].strip()
print 'Could not load fmlversion.properties, build failed'
sys.exit(1)
def extract_fml_obfed(fml_dir, mcp_dir, reobf_dir, client_dir):
fml_file = os.path.join(fml_dir, 'difflist.txt')
if not os.path.isfile(fml_file):
print 'Could not find Forge ModLoader\'s DiffList, looking for it at: %s' % fml_file
sys.exit(1)
with open(fml_file, 'r') as fh:
lines = fh.readlines()
client = zipfile.ZipFile(os.path.join(mcp_dir, 'temp', 'client_reobf.jar'))
print 'Extracting Reobfed Forge ModLoader classes'
for line in lines:
line = line.replace('\n', '').replace('\r', '').replace('/', os.sep)
if not os.path.isfile(os.path.join(reobf_dir, line)):
print ' %s' % line
side = line.split(os.sep)[0]
if side == 'minecraft':
client.extract(line[10:].replace(os.sep, '/'), client_dir)
client.close()
def get_branch_name():
from subprocess import Popen, PIPE, STDOUT
branch = ''
if os.getenv("GIT_BRANCH") is None:
try:
process = Popen(["git", "rev-parse", "--abbrev-ref", "HEAD"], stdout=PIPE, stderr=STDOUT, bufsize=-1)
branch, _ = process.communicate()
branch = branch.rstrip('\r\n')
except OSError:
print "Git not found"
else:
branch = os.getenv("GIT_BRANCH").rpartition('/')[2]
branch = branch.replace('master', '')
branch = branch.replace('HEAD', '')
print 'Detected Branch as \'%s\'' % branch
return branch
def sign_jar(forge_dir, command, files, dest_zip):
from subprocess import Popen, PIPE, STDOUT
global zip
zip_file = os.path.join(forge_dir, 'tmp.jar')
if os.path.isfile(zip_file):
os.remove(zip_file)
print '============== Creating tmp zip to sign ====================='
zf = zipfile.ZipFile(zip_file, 'w', zipfile.ZIP_DEFLATED)
zf.write(os.path.join(forge_dir, 'MANIFEST.MF'), 'META-INF/MANIFEST.MF')
zip_folder_filter(files, '', zf, 'cpw/mods/'.replace('/', os.sep))
zip_folder_filter(files, '', zf, 'net/minecraftforge/'.replace('/', os.sep))
zf.close()
print '================ End tmp zip to sign ========================'
try:
process = Popen([command, zip_file, "forge"], stdout=PIPE, stderr=STDOUT, bufsize=-1)
out, _ = process.communicate()
print out
except OSError as e:
print "Error creating signed tmp jar: %s" % e.strerror
sys.exit(1)
tmp_dir = os.path.join(forge_dir, 'tmp')
if os.path.isdir(tmp_dir):
shutil.rmtree(tmp_dir)
zf = zipfile.ZipFile(zip_file)
zf.extractall(tmp_dir)
zf.close()
os.remove(zip_file)
zip_start(dest_zip)
zip_folder(tmp_dir, '', zip)
zip_folder(files, '', zip)
if os.path.isdir(tmp_dir):
shutil.rmtree(tmp_dir)
def zip_folder_filter(path, key, zip, filter):
files = os.listdir(path)
for file in files:
file_path = os.path.join(path, file)
file_key = os.path.join(key, file)
if os.path.isdir(file_path):
zip_folder_filter(file_path, file_key, zip, filter)
else:
if file_key.startswith(filter):
print file_key
zip.write(file_path, file_key)
def gen_bin_patches(mcp_dir, fml_dir, build_num, client_dir):
print('Creating Binary patches')
os.environ['WORKSPACE'] = os.path.join(mcp_dir, '..')
os.environ['BUILD_NUMBER'] = str(build_num)
BUILD = ['ant', 'makebinpatches']
if sys.platform.startswith('win'):
BUILD = ['cmd', '/C'] + BUILD
if not run_command(BUILD, cwd=fml_dir):
print('Could not crate binary patches')
sys.exit(1)
fml_lzma = os.path.join(fml_dir, 'binpatches.pack.lzma')
obf_lzma = os.path.join(client_dir, 'binpatches.pack.lzma')
shutil.move(fml_lzma, obf_lzma)
def run_command(command, cwd='.', verbose=True):
print('Running command: ')
print(pformat(command))
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, cwd=cwd)
while process.poll() is None:
line = process.stdout.readline()
if line:
line = line.rstrip()
print(line)
if process.returncode:
print "failed: {0}".format(process.returncode)
return False
return True
if __name__ == '__main__':
main()

113
setup.py
View file

@ -1,113 +0,0 @@
import os, os.path, sys, zipfile
import shutil, glob, fnmatch, subprocess
from pprint import pformat
from optparse import OptionParser
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
forge_dir = os.path.dirname(os.path.abspath(__file__))
from forge import apply_forge_patches
def main():
print '=================================== Setup Start ================================='
parser = OptionParser()
parser.add_option('-m', '--mcp-dir', action='store', dest='mcp_dir', help='Path to download/extract MCP to', default=None)
parser.add_option('-b', '--build', action='store', dest='build', help='Build number', default=None)
options, _ = parser.parse_args()
build_num = 0
if not options.build is None:
try:
build_num = int(options.build)
except:
pass
fml_dir = os.path.join(forge_dir, 'fml')
mcp_dir = os.path.join(forge_dir, 'mcp')
if not options.mcp_dir is None:
mcp_dir = os.path.abspath(options.mcp_dir)
src_dir = os.path.join(mcp_dir, 'src')
setup_fml(mcp_dir, fml_dir, build_num)
base_dir = os.path.join(mcp_dir, 'src_base')
work_dir = os.path.join(mcp_dir, 'src_work')
if os.path.isdir(base_dir):
shutil.rmtree(base_dir)
if os.path.isdir(work_dir):
shutil.rmtree(work_dir)
print 'Setting up source directories'
shutil.copytree(src_dir, base_dir)
shutil.copytree(src_dir, work_dir)
print 'Applying forge patches'
apply_forge_patches(fml_dir, mcp_dir, forge_dir, work_dir, False)
setup_eclipse(forge_dir)
print '=================================== Setup Finished ================================='
def setup_fml(mcp_dir, fml_dir, build_num=0):
print 'Setting up Forge ModLoader'
os.environ['WORKSPACE'] = os.path.abspath(os.path.join(mcp_dir, '..'))
os.environ['BUILD_NUMBER'] = str(build_num)
BUILD = ['ant', 'jenkinsbuild']
if sys.platform.startswith('win'):
BUILD = ['cmd', '/C'] + BUILD
if not run_command(BUILD, cwd=fml_dir):
print('Could not setup FML')
sys.exit(1)
sys.path.append(fml_dir)
sys.path.append(os.path.join(fml_dir, 'install'))
from fml import finish_setup_fml
finish_setup_fml(fml_dir, mcp_dir)
print('Copy resources:')
copy_files(os.path.join(fml_dir, 'client'), os.path.join(mcp_dir, 'src', 'minecraft'))
copy_files(os.path.join(fml_dir, 'common'), os.path.join(mcp_dir, 'src', 'minecraft'))
name = 'fmlversion.properties'
print(' ' + name)
shutil.copy(os.path.join(fml_dir, name), os.path.join(mcp_dir, 'src', 'minecraft', name))
def copy_files(src_dir, dest_dir):
for file in glob.glob(os.path.join(src_dir, '*')):
if not os.path.isfile(file) or file.lower().endswith('.java'):
continue
print(' ' + file)
shutil.copy(file, os.path.join(dest_dir, os.path.basename(file)))
def run_command(command, cwd='.', verbose=True):
print('Running command: ')
print(pformat(command))
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, cwd=cwd)
while process.poll() is None:
line = process.stdout.readline()
if line:
line = line.rstrip()
print(line)
if process.returncode:
print "failed: {0}".format(process.returncode)
return False
return True
def setup_eclipse(forge_dir):
eclipse_dir = os.path.join(forge_dir, 'eclipse')
eclipse_zip = os.path.join(forge_dir, 'eclipse-workspace-dev.zip')
if not os.path.isdir(eclipse_dir) and os.path.isfile(eclipse_zip):
print 'Extracting Dev Workspace'
zf = zipfile.ZipFile(eclipse_zip)
zf.extractall(forge_dir)
zf.close()
if __name__ == '__main__':
main()

View file

@ -1,51 +0,0 @@
import subprocess, sys, os
from pprint import pformat
from optparse import OptionParser
def run_command(command, cwd='.'):
#print('Running command: ')
process = subprocess.Popen(command, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, cwd=cwd)
out, err = process.communicate()
out = out.strip('\n')
#print(pformat(out.split('\n')))
if process.returncode:
print('failed: %d' % process.returncode)
return None
return out.split('\n')
def main(options, args):
output = run_command(['git', 'diff', '--no-color', '--', 'fml'])
if output is None:
print('Failed to grab submodule commits')
sys.exit(1)
start = None
end = None
for line in output:
if not 'Subproject commit' in line:
continue
if line[0:18] == '-Subproject commit':
start = line[19:]
elif line[0:18] == '+Subproject commit':
end = line[19:]
if end.endswith('-dirty'):
end = end[0:len(end)-6]
if start == None or end == None:
print('Could not extract start and end range')
sys.exit(1)
#print('Start: %s' % start)
#print('End: %s' % end)
output = run_command(['git', 'log', '--reverse', '--pretty=oneline', '%s...%s' % (start, end)], './fml')
print('Updated FML:')
for line in output:
print('MinecraftForge/FML@%s' % line)
if __name__ == '__main__':
parser = OptionParser()
options, args = parser.parse_args()
main(options, args)

View file

@ -1,83 +0,0 @@
import os
import sys
import fnmatch
import shlex
import difflib
import time
from optparse import OptionParser
def cmdsplit(args):
if os.sep == '\\':
args = args.replace('\\', '\\\\')
return shlex.split(args)
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 main():
print("Creating patches")
parser = OptionParser()
parser.add_option('-m', '--mcp-dir', action='store', dest='mcp_dir', help='Path to MCP', default=None)
parser.add_option('-p', '--patch-dir', action='store', dest='patch_dir', help='Folder to place patches in', default=None)
options, _ = parser.parse_args()
forge_dir = os.path.dirname(os.path.abspath(__file__))
mcp = os.path.join(forge_dir, 'mcp')
if not options.mcp_dir is None:
mcp = os.path.abspath(options.mcp_dir)
elif os.path.isfile(os.path.join('..', 'runtime', 'commands.py')):
mcp = os.path.abspath('..')
patchd = os.path.normpath(os.path.join(forge_dir, 'patches'))
if not options.patch_dir is None:
patchd = os.path.normpath(options.patch_dir)
print "Patch folder set to '%s'" % patchd
base = os.path.normpath(os.path.join(mcp, 'src_base'))
work = os.path.normpath(os.path.join(mcp, 'src_work'))
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, '/')
if not os.path.isfile(file_base):
print("Missing base file %s"%(file_base))
continue
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[len(patchd)+1:]
patch = patch.replace('\r\n', '\n')
if not os.path.exists(patch_dir):
os.makedirs(patch_dir)
with open(patch_file, 'wb') as fh:
fh.write(patch)
else:
if os.path.isfile(patch_file):
print("Deleting empty patch: %s"%(patch_file))
os.remove(patch_file)
cleanDirs(patchd)
if __name__ == '__main__':
main()