diff --git a/fml/build.xml b/fml/build.xml
index 2bd8d87a0..e1aef8712 100644
--- a/fml/build.xml
+++ b/fml/build.xml
@@ -240,6 +240,10 @@
+
+
+
+
diff --git a/fml/eclipse/Clean-Client/.classpath b/fml/eclipse/Clean-Client/.classpath
index 2660e24ec..136f1484d 100644
--- a/fml/eclipse/Clean-Client/.classpath
+++ b/fml/eclipse/Clean-Client/.classpath
@@ -18,6 +18,6 @@
-
+
diff --git a/fml/eclipse/Clean-Client/.project b/fml/eclipse/Clean-Client/.project
index 7de653c48..49ce1e885 100644
--- a/fml/eclipse/Clean-Client/.project
+++ b/fml/eclipse/Clean-Client/.project
@@ -20,6 +20,11 @@
2
MCP_LOC/jars
+
+ lib
+ 2
+ MCP_LOC/lib
+
src
2
diff --git a/fml/install/download_fernflower.py b/fml/install/download_fernflower.py
deleted file mode 100755
index 8731bedd0..000000000
--- a/fml/install/download_fernflower.py
+++ /dev/null
@@ -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"
\ No newline at end of file
diff --git a/fml/install/eclipse/Client/.classpath b/fml/install/eclipse/Client/.classpath
new file mode 100644
index 000000000..c65206bff
--- /dev/null
+++ b/fml/install/eclipse/Client/.classpath
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fml/install/eclipse/Client/.project b/fml/install/eclipse/Client/.project
new file mode 100644
index 000000000..04e240e15
--- /dev/null
+++ b/fml/install/eclipse/Client/.project
@@ -0,0 +1,69 @@
+
+
+ Client
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
+
+ jars
+ 2
+ MCP_LOC/jars
+
+
+ src
+ 2
+ MCP_LOC/src/minecraft
+
+
+ lib
+ 2
+ MCP_LOC/lib
+
+
+
+
+ 1307293455427
+ jars
+ 13
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-bin
+
+
+
+ 1307293504507
+ jars/bin
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-*.jar
+
+
+
+ 1307293480435
+ jars/bin/natives
+ 6
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-*
+
+
+
+
+
+ MCP_LOC
+ $%7BPARENT-1-WORKSPACE_LOC%7D
+
+
+
diff --git a/fml/install/eclipse/Server/.classpath b/fml/install/eclipse/Server/.classpath
new file mode 100644
index 000000000..547b2f1f3
--- /dev/null
+++ b/fml/install/eclipse/Server/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/fml/install/eclipse/Server/.project b/fml/install/eclipse/Server/.project
new file mode 100644
index 000000000..eed2b1959
--- /dev/null
+++ b/fml/install/eclipse/Server/.project
@@ -0,0 +1,46 @@
+
+
+ Server
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
+
+ jars
+ 2
+ MCP_LOC/jars
+
+
+ src
+ 2
+ MCP_LOC/src/minecraft_server
+
+
+
+
+ 1307293529292
+ jars
+ 13
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-*.jar
+
+
+
+
+
+ MCP_LOC
+ $%7BPARENT-1-WORKSPACE_LOC%7D
+
+
+
diff --git a/fml/install/fml.py b/fml/install/fml.py
new file mode 100644
index 000000000..839ae95a5
--- /dev/null
+++ b/fml/install/fml.py
@@ -0,0 +1,296 @@
+import os, os.path, sys
+import urllib, zipfile
+import shutil, glob, fnmatch
+import subprocess, logging, re
+
+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'))
+ ret = True
+
+ if not os.path.isfile(ff_path):
+ 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"
+ except:
+ 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))
+ 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)
+ 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')
+
+ if os.path.isfile(back_jar):
+ if os.path.isfile(src_jar):
+ os.remove(src_jar)
+ shutil.move(back_jar, src_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)
+
+ zip_in = zipfile.ZipFile(back_jar, mode='a')
+ zip_out = zipfile.ZipFile(src_jar, 'w', zipfile.ZIP_DEFLATED)
+ for i in zip_in.filelist:
+ if not i.filename.startswith('META-INF'):
+ c = zip_in.read(i.filename)
+ zip_out.writestr(i.filename, c)
+ else:
+ print 'Skipping: %s' % i.filename
+ zip_out.close()
+
+def reset_logger():
+ log = logging.getLogger()
+ while len(log.handlers) > 0:
+ log.removeHandler(log.handlers[0])
+
+count = 0
+def cleanup_source(path):
+ path = os.path.normpath(path)
+ regex_cases_before = re.compile(r'((case|default).+\r?\n)\r?\n', re.MULTILINE) #Fixes newline after case before case body
+ regex_cases_after = re.compile(r'\r?\n(\r?\n[ \t]+(case|default))', re.MULTILINE) #Fixes newline after case body before new case
+
+ def updatefile(src_file):
+ global count
+ tmp_file = src_file + '.tmp'
+ count = 0
+ with open(src_file, 'r') as fh:
+ buf = fh.read()
+
+ def fix_cases(match):
+ global count
+ count += 1
+ return match.group(1)
+
+ buf = regex_cases_before.sub(fix_cases, buf)
+ buf = regex_cases_after.sub(fix_cases, buf)
+ if count > 0:
+ with open(tmp_file, 'w') as fh:
+ fh.write(buf)
+ shutil.move(tmp_file, src_file)
+
+ for path, _, filelist in os.walk(path, followlinks=True):
+ sub_dir = os.path.relpath(path, path)
+ for cur_file in fnmatch.filter(filelist, '*.java'):
+ src_file = os.path.normpath(os.path.join(path, cur_file))
+ updatefile(src_file)
+
+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
+
+ src_dir = os.path.join(mcp_dir, 'src')
+
+ if os.path.isdir(src_dir):
+ os.chdir(mcp_dir)
+ #cleanup -f
+ cleanup(None, False)
+ reset_logger()
+ os.chdir(fml_dir)
+
+ if os.path.isdir(src_dir):
+ print 'Please make sure to backup your modified files, and say yes when it asks you to do cleanup.'
+ sys.exit(1)
+
+ #download fernflower/argo/asm/guava
+ if not download_deps(mcp_dir):
+ sys.exit(1)
+
+ try:
+ pre_decompile(mcp_dir, fml_dir)
+
+ os.chdir(mcp_dir)
+ #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)
+ reset_logger()
+ os.chdir(fml_dir)
+
+ post_decompile(mcp_dir, fml_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)
+
+ #cleanup_source
+ cleanup_source(src_dir)
+
+ 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'))
+
+ #patch files
+ print 'Applying Forge ModLoader patches'
+ 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')):
+ 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 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')):
+ 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)
+
+ #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)
+ from runtime.updatenames import updatenames
+ from runtime.updatemd5 import updatemd5
+ from runtime.updatemcp import updatemcp
+
+ os.chdir(mcp_dir)
+ updatemcp(None, True)
+ reset_logger()
+ updatenames(None, True)
+ reset_logger()
+ updatemd5(None, True)
+ reset_logger()
+ os.chdir(fml_dir)
+
+def apply_patches(mcp_dir, patch_dir, target_dir):
+ sys.path.append(mcp_dir)
+ from runtime.pylibs.normlines import normaliselines
+ from runtime.commands import cmdsplit
+
+ 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 merge_tree(root_src_dir, root_dst_dir):
+ for src_dir, dirs, files in os.walk(root_src_dir):
+ dst_dir = src_dir.replace(root_src_dir, root_dst_dir)
+ if not os.path.exists(dst_dir):
+ os.mkdir(dst_dir)
+ for file_ in files:
+ src_file = os.path.join(src_dir, file_)
+ dst_file = os.path.join(dst_dir, file_)
+ if os.path.exists(dst_file):
+ os.remove(dst_file)
+ shutil.copy(src_file, dst_dir)
\ No newline at end of file
diff --git a/fml/install/install.cmd b/fml/install/install.cmd
index ff91c6f5d..44f664643 100755
--- a/fml/install/install.cmd
+++ b/fml/install/install.cmd
@@ -1,44 +1,4 @@
echo off
-
-echo Forge Mod Loader Windows Setup Program
-echo:
-
-@set PATH=%PATH%;%SystemDir%\system32;%SystemRoot%\System32
-
-if not exist "..\runtime\bin\fernflower.jar" (
- ..\runtime\bin\python\python_mcp download_fernflower.py
-)
-if not exist "..\runtime\bin\fernflower.jar" (
- echo Failed to download fernflower, install it manually and re-run setup.
- exit 1
-)
-
-pushd .. >nul
-
-if exist ".\src" (
- runtime\bin\python\python_mcp runtime\cleanup.py
-)
-if exist ".\src" (
- echo Please make sure to backup your modified files, and say yes when it asks you to do cleanup.
- exit 1
-)
-runtime\bin\python\python_mcp runtime\decompile.py -d -n -r
-
-pushd src >nul
-
- if exist ..\jars\minecraft_server.jar (
- for /f "delims=" %%a in ('dir /a -d /b /S ..\fml\patches\minecraft_server') do (
- pushd "%%a" 2>nul
- if errorlevel 1 (
- ..\runtime\bin\python\python_mcp ..\fml\lfcr.py "%%a" "%%a"
- ..\runtime\bin\applydiff.exe -uf -p1 -i "%%a"
- ) else popd
- )
- xcopy /Y /E ..\fml\src\* minecraft_server
- )
-popd >nul
-
-runtime\bin\python\python_mcp runtime\updatemcp.py -f
-runtime\bin\python\python_mcp runtime\updatenames.py -f
-runtime\bin\python\python_mcp runtime\updatemd5.py -f
+@set PATH=%PATH%;%SystemDir%\system32;%SystemRoot%\System32;..\runtime\bin\python
+python_mcp install.py
pause
diff --git a/fml/install/install.py b/fml/install/install.py
new file mode 100644
index 000000000..323e47036
--- /dev/null
+++ b/fml/install/install.py
@@ -0,0 +1,15 @@
+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
+
+def main():
+ print '================ Forge ModLoader Setup Start ==================='
+ setup_fml(fml_dir, mcp_dir)
+ finish_setup_fml(fml_dir, mcp_dir)
+ print '================ Forge ModLoader Setup End ==================='
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/fml/install/install.sh b/fml/install/install.sh
index 1c4bd3d24..fe9f86743 100644
--- a/fml/install/install.sh
+++ b/fml/install/install.sh
@@ -1,42 +1,2 @@
#!/bin/bash
-
-echo "Forge Mod Loader Linux Setup Program"
-echo
-
-if [ ! -f ../runtime/bin/fernflower.jar ]
-then
- python download_fernflower.py
-fi
-
-if [ ! -f ../runtime/bin/fernflower.jar ]
-then
- echo "Failed to download fernflower, install it manually and re-run setup."
- exit 1
-fi
-
-pushd .. > /dev/null
-
-./cleanup.sh
-
-if [ -d "src" ]
-then
- echo "Failed to cleanup the MCP folder, please backup your modified files and run this script again and say yes when prompted."
- exit 1
-fi
-
-./decompile.sh -d -n -r
-
-pushd src > /dev/null
- if [ -f ../jars/minecraft_server.jar ];
- then
- for i in `find ../fml/patches/minecraft_server/ -type f`
- do
- patch -p1 -i $i
- done
- cp -r ../fml/src/minecraft_server/* minecraft_server
- fi
-popd > /dev/null
-
-./updatemcp.sh -f
-./updatenames.sh -f
-./updatemd5.sh -f
+python install.py
diff --git a/fml/install/lfcr.py b/fml/install/lfcr.py
deleted file mode 100755
index d48f17c7b..000000000
--- a/fml/install/lfcr.py
+++ /dev/null
@@ -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()
\ No newline at end of file