Updated repo scripts to python, allowing more flexability and less code duplication.

This commit is contained in:
LexManos 2012-04-06 06:10:11 -07:00
parent cf0ce3b086
commit 9f327fd392
15 changed files with 1083 additions and 779 deletions

2
forge/.gitignore vendored
View file

@ -1,4 +1,4 @@
/*.zip
/fml/
/logs/
/*.pyc
/forge-*/

57
forge/build.py Normal file
View file

@ -0,0 +1,57 @@
import os, os.path, sys
import shutil, fnmatch
import logging
forge_dir = os.path.dirname(os.path.abspath(__file__))
mcp_dir = os.path.abspath('..')
src_dir = os.path.join(mcp_dir, 'src')
sys.path.append(mcp_dir)
from runtime.recompile import recompile
from forge import copytree, reset_logger, load_version, inject_version
def main():
build_num = 0
if len(sys.argv) > 1:
try:
build_num = int(sys.argv[1])
except:
pass
sys.exit(build(build_num))
def build(build_num=0):
version = load_version(build_num)
print '=================================== Build %d.%d.%d.%d Start =================================' % (version['major'], version['minor'], version['revision'], version['build'])
if os.path.isdir(src_dir):
shutil.rmtree(src_dir)
inject_version(os.path.join(forge_dir, 'forge_common', 'net', 'minecraft', 'src', 'forge', 'ForgeHooks.java'), build_num)
print 'src_work -> src'
copytree(os.path.join(mcp_dir, 'src_work'), src_dir)
print '\nforge_client -> minecraft'
copytree(os.path.join(forge_dir, 'forge_client', 'src'), os.path.join(src_dir, 'minecraft'), -1)
print '\nforge_server -> minecraft_server'
copytree(os.path.join(forge_dir, 'forge_server', 'src'), os.path.join(src_dir, 'minecraft_server'), -1)
print '\nforge_common -> minecraft'
copytree(os.path.join(forge_dir, 'forge_common'), os.path.join(src_dir, 'minecraft'), -1)
print '\nforge_common -> minecraft_server'
copytree(os.path.join(forge_dir, 'forge_common'), os.path.join(src_dir, 'minecraft_server'), -1)
print
error_level = 0
try:
os.chdir(mcp_dir)
recompile(None)
reset_logger()
os.chdir(forge_dir)
except SystemExit, e:
print 'Decompile Exception: %d ' % e.code
error_level = e.code
print '=================================== Build Finished %d =================================' % error_level
return error_level
if __name__ == '__main__':
main()

View file

@ -1,10 +0,0 @@
import urllib
import zipfile
if __name__ == '__main__':
try:
urllib.urlretrieve("http://goo.gl/PnJHp", './fernflower.zip')
zf = zipfile.ZipFile('fernflower.zip')
zf.extract('fernflower.jar', '../runtime/bin')
except:
print "Downloading Fernflower failed download manually from http://goo.gl/PnJHp"

BIN
forge/fml-src-1.0.0.45.zip Normal file

Binary file not shown.

187
forge/forge.py Normal file
View file

@ -0,0 +1,187 @@
import os, os.path, sys
import urllib, zipfile
import shutil, glob, fnmatch
import subprocess, logging, re
forge_dir = os.path.dirname(os.path.abspath(__file__))
mcp_dir = os.path.abspath('..')
src_dir = os.path.join(mcp_dir, 'src')
sys.path.append(mcp_dir)
from runtime.pylibs.normlines import normaliselines
from runtime.commands import cmdsplit
def apply_patches(patch_dir, target_dir):
temp = os.path.abspath('temp.patch')
cmd = cmdsplit('patch -p2 -i "%s" ' % temp)
display = True
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))
display = False
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()
if os.path.isfile(temp):
os.remove(temp)
#Taken from: http://stackoverflow.com/questions/7545299/distutil-shutil-copytree
def _mkdir(newdir):
"""works the way a good mkdir should :)
- already exists, silently complete
- regular file in the way, raise an exception
- parent directory(ies) does not exist, make them as well
"""
if os.path.isdir(newdir):
pass
elif os.path.isfile(newdir):
raise OSError("a file with the same name as the desired " \
"dir, '%s', already exists." % newdir)
else:
head, tail = os.path.split(newdir)
if head and not os.path.isdir(head):
_mkdir(head)
#print "_mkdir %s" % repr(newdir)
if tail:
os.mkdir(newdir)
#Taken from: http://stackoverflow.com/questions/7545299/distutil-shutil-copytree
def copytree(src, dst, verbose=0, symlinks=False):
"""Recursively copy a directory tree using copy2().
The destination directory must not already exist.
If exception(s) occur, an Error is raised with a list of reasons.
If the optional symlinks flag is true, symbolic links in the
source tree result in symbolic links in the destination tree; if
it is false, the contents of the files pointed to by symbolic
links are copied.
XXX Consider this example code rather than the ultimate tool.
"""
if verbose == -1:
verbose = len(os.path.abspath(dst)) - 1
names = os.listdir(src)
# os.makedirs(dst)
_mkdir(dst) # XXX
errors = []
for name in names:
srcname = os.path.join(src, name)
dstname = os.path.join(dst, name)
try:
if symlinks and os.path.islink(srcname):
linkto = os.readlink(srcname)
os.symlink(linkto, dstname)
elif os.path.isdir(srcname):
copytree(srcname, dstname, verbose, symlinks)
else:
shutil.copy2(srcname, dstname)
if verbose > 0:
print os.path.abspath(srcname)[verbose:]
# XXX What about devices, sockets etc.?
except (IOError, os.error), why:
errors.append((srcname, dstname, str(why)))
# catch the Error from the recursive copytree so that we can
# continue with other files
except Exception, err:
errors.extend(err.args[0])
try:
shutil.copystat(src, dst)
except WindowsError:
# can't copy file access times on Windows
pass
def reset_logger():
log = logging.getLogger()
while len(log.handlers) > 0:
log.removeHandler(log.handlers[0])
def download_ff(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'))
if os.path.isfile(ff_path):
return True
try:
urllib.urlretrieve("http://goo.gl/PnJHp", 'fernflower.zip')
zf = zipfile.ZipFile('fernflower.zip')
zf.extract('fernflower.jar', bin_path)
zf.close()
os.remove('fernflower.zip')
print "Downloaded Fernflower successfully"
return True
except:
print "Downloading Fernflower failed download manually from http://goo.gl/PnJHp"
return False
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, 'forge_common/net/minecraft/src/forge/ForgeHooks.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)
with open(tmp_file, 'w') as fh:
fh.write(buf)
shutil.move(tmp_file, src_file)
def zip_folder(path, key, zip):
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:
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()

View file

@ -553,10 +553,10 @@ public class ForgeHooks
}
public static ArrayList<IArrowNockHandler> arrowNockHandlers = new ArrayList<IArrowNockHandler>();
public static final int majorVersion=0;
public static final int minorVersion=0;
public static final int revisionVersion=0;
public static final int buildVersion=0;
public static final int majorVersion = 3;
public static final int minorVersion = 0;
public static final int revisionVersion = 0;
public static final int buildVersion = 0;
static
{
plantGrassList = new ArrayList<ProbableItem>();

View file

@ -1,20 +0,0 @@
@echo off
setlocal enableextensions enabledelayedexpansion
FOR /F "tokens=1-4" %%A IN (version.txt) DO (
set major=%%A
set minor=%%B
set revision=%%C
set build=%%D
)
set file=%*
echo Injecting Revision !major!.!minor!.!revision!.!build! %file%
set PATH=.\bin;%PATH%
sed s/majorVersion=0/majorVersion=!major!/ <!file! | ^
sed s/minorVersion=0/minorVersion=!minor!/ | ^
sed s/revisionVersion=0/revisionVersion=!revision!/ | ^
sed s/buildVersion=0/buildVersion=!build!/ | ^
tr -d '\r' >!file!.tmp
move /Y !file:/=\!.tmp !file:/=\! >nul

View file

@ -1,14 +0,0 @@
#!/bin/bash
target=$1
read major minor rev build <version.txt
echo Injecting Revision $major.$minor.$rev.$build $target
sed s/majorVersion=0/majorVersion=$major/ <$target | \
sed s/minorVersion=0/minorVersion=$minor/ | \
sed s/revisionVersion=0/revisionVersion=$rev/ | \
sed s/buildVersion=0/buildVersion=$build/ | \
tr -d '\r' > $target.tmp
mv $target.tmp $target

View file

@ -1,8 +0,0 @@
#! /usr/bin/env python
import sys, re, os
data = open(sys.argv[1], "rb").read()
newdata = re.sub("\r?\n", "\r\n", data)
f = open(sys.argv[2], "wb")
f.write(newdata)
f.close()

View file

@ -1,69 +0,0 @@
read major minor revision build <version.txt
version=$major.$minor.$revision.$build
build_dir=`pwd`
dir=`pwd`/../forge-$version
function package_all () {
qual=$1
echo "=================================== MinecraftForge$qual-$version.zip Start ================================="
cp "$build_dir/minecraftforge_credits.txt" .
zip -r "$dir/minecraftforge$qual-$version.zip" .
echo "=================================== MinecraftForge$qual-$version.zip Finished ================================="
}
cd ../reobf
if [ ! -d "minecraft" -o ! -d "minecraft_server" ]; then
echo "Reobfusication failed, output directories do no exist."
exit 1
fi
rm -rf "$dir"
mkdir "$dir"
cd minecraft
package_all "-client"
cd ../minecraft_server
package_all "-server"
cd ../..
rm -rf reobf
cd "$build_dir"
echo "=================================== MinecraftForge-src-$version.zip Start ================================="
mkdir forge
cd forge
mkdir src
mkdir src/minecraft
mkdir src/minecraft_server
mkdir patches
mkdir conf
cp -r ../forge_client/src/* src/minecraft
cp -r ../forge_server/src/* src/minecraft_server
cp -r ../forge_common/* src/minecraft
cp -r ../forge_common/* src/minecraft_server
cp -r ../patches/* patches
cp -r ../conf/* conf
cp ../lfcr.py .
cp ../clean_src.py .
cp ../install/install.cmd .
cp ../install/install.sh .
cp ../download_fernflower.py .
cp ../install/README.txt .
cp ../minecraftforge_credits.txt .
cd ..
sh inject_version.sh forge/src/minecraft/net/minecraft/src/forge/ForgeHooks.java
sh inject_version.sh forge/src/minecraft_server/net/minecraft/src/forge/ForgeHooks.java
zip -r "$dir/minecraftforge-src-$version.zip" forge
rm -rf forge
echo "=================================== MinecraftForge-src-$version.zip Finished ================================="

View file

@ -1,16 +1,2 @@
@echo off
call build.bat
if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL%
echo =================================== Release Start =================================
cd ..
runtime\bin\python\python_mcp runtime\reobfuscate.py
cd forge
set PATH=E:\cygwin\bin;%PATH%
sh package.sh
echo =================================== Release Finished %ERRORLEVEL% =================================
if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL%
..\runtime\bin\python\python_mcp release.py %*

149
forge/release.py Normal file
View file

@ -0,0 +1,149 @@
import os, os.path, sys
import shutil, fnmatch
import logging, zipfile
forge_dir = os.path.dirname(os.path.abspath(__file__))
mcp_dir = os.path.abspath('..')
src_dir = os.path.join(mcp_dir, 'src')
sys.path.append(mcp_dir)
from runtime.reobfuscate import reobfuscate
from forge import reset_logger, load_version, zip_folder, zip_create
from build import build
reobf_dir = os.path.join(mcp_dir, 'reobf')
client_dir = os.path.join(reobf_dir, 'minecraft')
server_dir = os.path.join(reobf_dir, 'minecraft_server')
zip = None
zip_name = None
zip_base = None
version_str = None
def main():
global version_str
build_num = 0
if len(sys.argv) > 1:
try:
build_num = int(sys.argv[1])
except:
pass
ret = 0
ret = build(build_num)
if ret != 0:
sys.exit(ret)
print '=================================== Release Start ================================='
error_level = 0
try:
os.chdir(mcp_dir)
reobfuscate(None, False, True, True)
reset_logger()
os.chdir(forge_dir)
except SystemExit, e:
print 'Reobfusicate Exception: %d ' % e.code
error_level = e.code
out_folder = os.path.join(forge_dir, 'forge-%s' % version_str)
if os.path.isdir(out_folder):
shutil.rmtree(out_folder)
os.makedirs(out_folder)
extract_fml_obfed()
version = load_version(build_num)
version_str = '%d.%d.%d.%d' % (version['major'], version['minor'], version['revision'], version['build'])
zip_start('minecraftforge-client-%s.zip' % version_str)
zip_folder(client_dir, '', zip)
zip_add('minecraftforge_credits.txt')
zip_add('license.txt')
zip_end()
zip_start('minecraftforge-server-%s.zip' % version_str)
zip_folder(server_dir, '', zip)
zip_add('minecraftforge_credits.txt')
zip_add('license.txt')
zip_end()
zip_start('minecraftforge-src-%s.zip' % version_str, 'forge')
zip_add('forge_client/src', 'src/minecraft')
zip_add('forge_server/src', 'src/minecraft_server')
zip_add('forge_common', 'src/minecraft')
zip_add('forge_common', 'src/minecraft_server')
zip_add('patches', 'patches')
zip_add('fml', 'fml')
zip_add('conf', 'conf')
zip_add('minecraftforge_credits.txt')
zip_add('install/install.cmd')
zip_add('install/install.sh')
zip_add('install/README.txt')
zip_add('install/install.py')
zip_add('forge.py')
zip_add('minecraftforge_credits.txt')
zip_add('license.txt')
zip_end()
print '=================================== Release Finished %d =================================' % error_level
sys.exit(error_level)
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, 'forge-%s' % version_str, 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 extract_fml_obfed():
fml_file = os.path.join(forge_dir, 'fml', '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'))
server = zipfile.ZipFile(os.path.join(mcp_dir, 'temp', 'server_reobf.jar'))
print 'Extracting Reobfed Forge ModLoader classes'
for line in lines:
line = line.replace('\n', '').replace('\r', '').replace('/', os.sep)
print line
if not os.path.isfile(os.path.join(reobf_dir, line)):
side = line.split(os.sep)[0]
if side == 'minecraft':
client.extract(line[10:].replace(os.sep, '/'), client_dir)
else:
server.extract(line[17:].replace(os.sep, '/'), server_dir)
client.close()
server.close()
if __name__ == '__main__':
main()

View file

@ -1,51 +1,5 @@
@echo off
echo =================================== Setup Start =================================
pushd .. >nul
if "%1"=="-skipdecompile" (
@echo | cmd /C updatenames.bat -f
) ELSE (
if not exist "runtime\bin\fernflower.jar" (
pushd forge
..\runtime\bin\python\python_mcp download_fernflower.py
popd
)
if not exist "runtime\bin\fernflower.jar" (
echo Failed to download fernflower, install it manually and re-run setup.
exit 1
)
rmdir /S /Q src
echo | cmd /C decompile.bat -r
)
echo | cmd /C updatemd5.bat -f
rmdir /S /Q src_base
rmdir /S /Q src_work
mkdir src_base
mkdir src_work
xcopy /Y /E /Q src\* src_base
xcopy /Y /E /Q src\* src_work
pushd src_work >nul
@setlocal enabledelayedexpansion
@echo off
set PATH=..\forge\bin;%PATH%
echo Applying patches
for /f %%i in ('find ../forge/patches -type f') do (
set file=%%i
if /I "!file:~-6!" EQU ".patch" (
..\runtime\bin\python\python_mcp ..\forge\lfcr.py %%i ..\forge\temp.patch
..\runtime\bin\applydiff.exe -uf -p2 -i ..\forge\temp.patch
del ..\forge\temp.patch >nul 1>nul
)
)
popd >nul
popd >nul
echo =================================== Setup Finished =================================
..\runtime\bin\python\python_mcp setup.py %*
if NOT "%1"=="-skipdecompile" (
pause
)

93
forge/setup.py Normal file
View file

@ -0,0 +1,93 @@
import os, os.path, sys
import urllib, zipfile
import shutil, glob, fnmatch
import subprocess, logging
forge_dir = os.path.dirname(os.path.abspath(__file__))
mcp_dir = os.path.abspath('..')
src_dir = os.path.join(mcp_dir, 'src')
sys.path.append(mcp_dir)
from runtime.decompile import decompile
from runtime.updatenames import updatenames
from runtime.updatemd5 import updatemd5
from forge import apply_patches, copytree, reset_logger, download_ff
def main():
print '=================================== Setup Start ================================='
skipDecompile = len(sys.argv) > 1 and sys.argv[1] == '-skipdecompile'
if not skipDecompile:
if not download_ff(mcp_dir):
sys.exit(1)
if os.path.isdir(src_dir):
shutil.rmtree(src_dir)
try:
os.chdir(mcp_dir)
# Conf JAD CSV -r -d -a -n -p -o -l -g
decompile(None, False, False, True, True, False, True, False, False, False, False)
reset_logger()
os.chdir(forge_dir)
except SystemExit, e:
print 'Decompile Exception: %d ' % e.code
raise e
if not os.path.isdir(src_dir):
print 'Something went wrong, src folder not found at: %s' % src_dir
sys.exit(1)
setup_fml()
os.chdir(mcp_dir)
updatenames(None, True)
reset_logger()
updatemd5(None, True)
reset_logger()
os.chdir(forge_dir)
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_patches(os.path.join(forge_dir, 'patches'), work_dir)
print '=================================== Setup Finished ================================='
def setup_fml():
print 'Setting up Forge ModLoader'
fml = glob.glob(os.path.join(forge_dir, 'fml-src-*.zip'))
if not len(fml) == 1:
if len(fml) == 0:
print 'Missing FML source zip, should be named fml-src-*.zip inside your forge folder, obtain it from the repo'
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)
fml_dir = os.path.join(forge_dir, 'fml')
if os.path.isdir(fml_dir):
shutil.rmtree(fml_dir)
print 'Extracting Forge ModLoader: %s' % os.path.basename(fml[0])
zf = zipfile.ZipFile(fml[0])
zf.extractall(forge_dir)
zf.close()
print 'Applying Forge ModLoader patches'
apply_patches(os.path.join(fml_dir, 'patches'), src_dir)
copytree(os.path.join(fml_dir, 'src'), src_dir)
if __name__ == '__main__':
main()

View file

@ -1 +0,0 @@
2 0 0 0