Init
commit
77e5f11979
@ -0,0 +1,6 @@
|
||||
/bin/
|
||||
/eclipse/
|
||||
/jars/
|
||||
/reobf/
|
||||
/temp/
|
||||
/logs/
|
@ -0,0 +1,89 @@
|
||||
== v7.0a ==
|
||||
+ Still for client 1.3.1 & server 1.3.1
|
||||
+ Added fernflower decompiler
|
||||
|
||||
== v7.0 ==
|
||||
+ Updated to client 1.3.1 & server 1.3.1
|
||||
+ Extended patches to remove herobrine code from decompiled classes
|
||||
|
||||
== v6.2 ==
|
||||
+ Updated to client 1.2.5 & server 1.2.5
|
||||
|
||||
Update patches to work around worldgen crash in vanilla minecraft client and server,
|
||||
and a client crash when clicking on chat history
|
||||
|
||||
== v6.1 ==
|
||||
+ Updated to client 1.2.4 & server 1.2.4
|
||||
|
||||
Disabled rounding of float and double constants due to issues with getting stuck on respawn.
|
||||
Updated client patches to work around OpenGL issues with main window on OSX and Linux.
|
||||
You will need to cleanup and decompile again for these changes to take effect.
|
||||
|
||||
== v6.0 ==
|
||||
+ Updated to client 1.2.3 & server 1.2.3
|
||||
+ Added javadoc comments to the decompiled sourcecode
|
||||
|
||||
== v5.6 ==
|
||||
+ Updated to client 1.1 & server 1.1
|
||||
+ Run Artistic Style source beautifier on decompiled source code
|
||||
|
||||
== v5.0 ==
|
||||
+ Updated to client 1.0.0 & server 1.0.1
|
||||
|
||||
== v4.5 ==
|
||||
+ Updated to client & server v1.9 pre 5
|
||||
+ Improved Retroguard and Exceptor tools
|
||||
|
||||
YOU NEED TO DOWNLOAD MCP FROM THE WIKI IF YOU ARE UPDATING FROM MCP 4.3, UPDATEMCP.BAT WILL NOT WORK FOR 4.3 TO 4.4 UPDATES!
|
||||
+ Fixes to mapping of methods in EntityLiving
|
||||
+ Bugfix for crashes when playing sounds due to issue in Block.java
|
||||
|
||||
== v4.4 ==
|
||||
+ Updated to client & server v1.8.1
|
||||
+ Improved Retroguard and Exceptor tools
|
||||
|
||||
== v4.3 ==
|
||||
+ Updated to client & server v1.7.3
|
||||
|
||||
== v4.2 ==
|
||||
+ Updated to client & server v1.7.2
|
||||
* If you get compile errors for ik.java or ik.class, just delete conf/patches/ik.java
|
||||
|
||||
== v4.1 ==
|
||||
+ Added an Eclipse workspace
|
||||
+ Included a reobfuscation bugfix
|
||||
|
||||
== v4.0 ==
|
||||
+ Added new tool Exceptor
|
||||
+ Added alternative support for fernflower decompiler
|
||||
|
||||
== v3.4 ==
|
||||
+ Updated to client & server v1.6.6
|
||||
|
||||
== v3.3 ==
|
||||
+ Updated to client & server v1.6.5
|
||||
|
||||
== v3.2 ==
|
||||
+ Updated to client & server v1.6.4
|
||||
+ Added support for external jar files in recompile and reobfuscation
|
||||
+ Finally updated the readme files
|
||||
|
||||
== v3.1.1 ==
|
||||
+ Small bugfix for using mcp offline
|
||||
|
||||
== v3.1 ==
|
||||
+ Updated to client v1.5_01 / server v1.5_02
|
||||
+ some more bugfixes in the python scripts
|
||||
|
||||
== v3.0 ==
|
||||
+ Complete rewrite of the scripts in python
|
||||
+ RetroGuard used both for deof and reobf
|
||||
+ Automatic detection of modified classes during reobfuscation
|
||||
+ Protection on cleanup.bat/sh
|
||||
+ Advanced logging system (logs/mcp.log, logs/mcperr.log)
|
||||
+ Removed repackager.exe and mono dependancy on Linux
|
||||
+ Cleaner directory structure
|
||||
+ Out of the box decompilation compatibility with modded jars
|
||||
+ Rolling update model on top of the usual full package distrib
|
||||
+ Custom files in bin directory are preserved during recompilation
|
||||
+ Custom files are automaticly copied to reobf directory during reobf
|
@ -0,0 +1,21 @@
|
||||
MCP - Minecraft Coder Pack
|
||||
MCP is (c) Copyright by the MCP Team
|
||||
|
||||
License and terms of use.
|
||||
|
||||
No warranties. If MCP does not work for you, or causes any damage, it's your problem. Use it at own risk.
|
||||
|
||||
You are allowed to:
|
||||
- Use MCP to decompile the Minecraft client and server jar files.
|
||||
- Use the decompiled source code to create mods for Minecraft.
|
||||
- Recompile modified versions of Minecraft.
|
||||
- Reobfuscate the classes of your mod for Minecraft.
|
||||
|
||||
You are NOT allowed to:
|
||||
- Use MCP to do anything that violated Mojangs terms of use for Minecraft.
|
||||
- Release Minecraft versions or modifications that allow you to play without having bought Minecraft from Mojang.
|
||||
- Release modified or unmodified versions of MCP anywhere.
|
||||
- Use any of MCPs scripts, tools or data files without explicit written permission.
|
||||
- Make money with anything based on MCP (excluding Minecraft mods created by using MCP).
|
||||
- Use MCP to create clients that are used for griefing or exploiting server bugs.
|
||||
- Release the decompiled source code of Minecraft in any way.
|
@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
runtime\bin\python\python_mcp runtime\cleanup.py %*
|
||||
pause
|
@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
python runtime/cleanup.py "$@"
|
@ -0,0 +1,19 @@
|
||||
# Artistic Style format configuration
|
||||
# see http://astyle.sourceforge.net/astyle.html
|
||||
|
||||
style=allman
|
||||
|
||||
add-brackets
|
||||
break-closing-brackets
|
||||
|
||||
indent-switches
|
||||
|
||||
max-instatement-indent=2
|
||||
|
||||
pad-oper
|
||||
pad-header
|
||||
unpad-paren
|
||||
|
||||
break-blocks
|
||||
|
||||
delete-empty-lines
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,155 @@
|
||||
[DEFAULT]
|
||||
DirTemp = temp
|
||||
DirSrc = src
|
||||
DirLogs = logs
|
||||
DirBin = bin
|
||||
DirJars = jars
|
||||
DirReobf = reobf
|
||||
DirConf = conf
|
||||
DirRuntime = runtime
|
||||
DirLib = lib
|
||||
DirTempSrc = temp/src
|
||||
DirTempCls = temp/cls
|
||||
DirTempBin = temp/bin
|
||||
DirModSrc = modsrc
|
||||
DirEclipse = eclipse
|
||||
|
||||
[CSV]
|
||||
Classes = %(DirConf)s/classes.csv
|
||||
Methods = %(DirConf)s/methods.csv
|
||||
Fields = %(DirConf)s/fields.csv
|
||||
Params = %(DirConf)s/params.csv
|
||||
NewIds = %(DirConf)s/newids.csv
|
||||
|
||||
[SRGS]
|
||||
ConfClient = %(DirConf)s/client.srg
|
||||
ConfServer = %(DirConf)s/server.srg
|
||||
Client = %(DirTemp)s/client_rg.srg
|
||||
Server = %(DirTemp)s/server_rg.srg
|
||||
DeobfClient = %(DirTemp)s/client_deobf.srg
|
||||
DeobfServer = %(DirTemp)s/server_deobf.srg
|
||||
ReobfClient = %(DirTemp)s/client_ro.srg
|
||||
ReobfServer = %(DirTemp)s/server_ro.srg
|
||||
|
||||
[JAR]
|
||||
DirNatives = %(DirJars)s/bin/natives
|
||||
Client = %(DirJars)s/bin/minecraft.jar
|
||||
Server = %(DirJars)s/minecraft_server.jar
|
||||
LWJGL = %(DirJars)s/bin/jinput.jar,%(DirJars)s/bin/lwjgl.jar,%(DirJars)s/bin/lwjgl_util.jar
|
||||
MD5Client = 969699f13e5bbe7f12e40ac4f32b7d9a
|
||||
MD5Server = c047f82522e53f2ec3c6b64304dfad0f
|
||||
|
||||
[RETROGUARD]
|
||||
Location = %(DirRuntime)s/bin/retroguard.jar
|
||||
RetroConf = %(DirTemp)s/retroguard.cfg
|
||||
RetroReobConf = %(DirTemp)s/retroguard_ro.cfg
|
||||
ClientConf = %(DirTemp)s/client_rg.cfg
|
||||
ServerConf = %(DirTemp)s/server_rg.cfg
|
||||
ClientReobConf = %(DirTemp)s/client_ro.cfg
|
||||
ServerReobConf = %(DirTemp)s/server_ro.cfg
|
||||
ClientOut = %(DirTemp)s/minecraft_rg.jar
|
||||
ServerOut = %(DirTemp)s/minecraft_server_rg.jar
|
||||
ClientLog = %(DirLogs)s/client_rg.log
|
||||
ServerLog = %(DirLogs)s/server_rg.log
|
||||
ClientDeobLog = %(DirLogs)s/client_deob.log
|
||||
ServerDeobLog = %(DirLogs)s/server_deob.log
|
||||
NullPkg = net/minecraft/src
|
||||
|
||||
[EXCEPTOR]
|
||||
XClientCfg = %(DirConf)s/client.exc
|
||||
XServerCfg = %(DirConf)s/server.exc
|
||||
XClientOut = %(DirTemp)s/minecraft_exc.jar
|
||||
XServerOut = %(DirTemp)s/minecraft_server_exc.jar
|
||||
XClientLog = %(DirLogs)s/client_exc.log
|
||||
XServerLog = %(DirLogs)s/server_exc.log
|
||||
|
||||
[DECOMPILE]
|
||||
ClsClientTemp = %(DirTempCls)s/minecraft
|
||||
ClsServerTemp = %(DirTempCls)s/minecraft_server
|
||||
SrcClientTemp = %(DirTempSrc)s/minecraft
|
||||
SrcServerTemp = %(DirTempSrc)s/minecraft_server
|
||||
FFSource = net
|
||||
|
||||
[OUTPUT]
|
||||
BinClientTemp = %(DirTempBin)s/minecraft
|
||||
BinServerTemp = %(DirTempBin)s/minecraft_server
|
||||
SrcClient = %(DirSrc)s/minecraft
|
||||
SrcServer = %(DirSrc)s/minecraft_server
|
||||
TestClient = net/minecraft/client/Minecraft
|
||||
TestServer = net/minecraft/server/MinecraftServer
|
||||
|
||||
[PATCHES]
|
||||
PatchClient = %(DirConf)s/patches/minecraft.patch
|
||||
PatchServer = %(DirConf)s/patches/minecraft_server.patch
|
||||
PatchTemp = %(DirTemp)s/temp.patch
|
||||
FFPatchClient = %(DirConf)s/patches/minecraft_ff.patch
|
||||
FFPatchServer = %(DirConf)s/patches/minecraft_server_ff.patch
|
||||
PatchClient_osx = %(DirConf)s/patches/minecraft_osx.patch
|
||||
PatchServer_osx = %(DirConf)s/patches/minecraft_server_osx.patch
|
||||
|
||||
[RECOMPILE]
|
||||
BinClient = %(DirBin)s/minecraft
|
||||
BinServer = %(DirBin)s/minecraft_server
|
||||
LogClient = %(DirLogs)s/client_compile.log
|
||||
LogServer = %(DirLogs)s/server_compile.log
|
||||
ClassPathClient = %(DirLib)s/,%(DirLib)s/*,%(DirJars)s/bin/minecraft.jar,%(DirJars)s/bin/jinput.jar,%(DirJars)s/bin/lwjgl.jar,%(DirJars)s/bin/lwjgl_util.jar
|
||||
ClassPathServer = %(DirLib)s/,%(DirLib)s/*,%(DirJars)s/minecraft_server.jar
|
||||
ClientFixes = %(DirConf)s/patches
|
||||
FixStart = Start
|
||||
IgnorePkg = paulscode,com/jcraft,isom,ibxm,de/matthiasmann/twl,org/xmlpull,javax/xml
|
||||
|
||||
[REOBF]
|
||||
MD5Client = %(DirTemp)s/client.md5
|
||||
MD5Server = %(DirTemp)s/server.md5
|
||||
MD5PreReobfClient = %(DirTemp)s/client_reobf.md5
|
||||
MD5PreReobfServer = %(DirTemp)s/server_reobf.md5
|
||||
RecompJarClient = %(DirTemp)s/client_recomp.jar
|
||||
RecompJarServer = %(DirTemp)s/server_recomp.jar
|
||||
ObfJarClient = %(DirTemp)s/client_reobf.jar
|
||||
ObfJarServer = %(DirTemp)s/server_reobf.jar
|
||||
ReobfDirClient = %(DirReobf)s/minecraft
|
||||
ReobfDirServer = %(DirReobf)s/minecraft_server
|
||||
ClientRoLog = %(DirLogs)s/client_ro.log
|
||||
ServerRoLog = %(DirLogs)s/server_ro.log
|
||||
ReobfClientLog = %(DirLogs)s/client_reob.log
|
||||
ReobfServerLog = %(DirLogs)s/server_reob.log
|
||||
|
||||
[GETMODSOURCE]
|
||||
OutSRCClient = %(DirModSrc)s/minecraft
|
||||
OutSRCServer = %(DirModSrc)s/minecraft_server
|
||||
|
||||
[MCP]
|
||||
LogFile = %(DirLogs)s/mcp.log
|
||||
LogFileErr = %(DirLogs)s/mcperr.log
|
||||
UpdateUrl = http://mcp.ocean-labs.de/files/mcprolling_{version}/
|
||||
IgnoreUpdate = %(DirBin)s,%(DirLib)s,%(DirLogs)s,%(DirModSrc)s,%(DirReobf)s,%(DirSrc)s,%(DirTemp)s,%(DirEclipse)s/Client/bin,%(DirEclipse)s/Server/bin,%(DirJars)s/world,%(DirJars)s/saves,%(DirJars)s/resources
|
||||
RGIndex = 80000
|
||||
ParamIndex = 4000
|
||||
|
||||
[ASTYLE]
|
||||
AstyleConfig = %(DirConf)s/astyle.cfg
|
||||
|
||||
[COMMANDS]
|
||||
Wine = wine
|
||||
Patcher_win = %(DirRuntime)s/bin/applydiff.exe
|
||||
Patcher_linux = patch
|
||||
Patcher_osx = patch
|
||||
Jad_win = %(DirRuntime)s/bin/jad.exe
|
||||
Jad_osx = %(DirRuntime)s/bin/jad-osx
|
||||
AStyle_win = %(DirRuntime)s/bin/astyle.exe
|
||||
AStyle_linux = astyle
|
||||
AStyle_osx = %(DirRuntime)s/bin/astyle-osx
|
||||
JadRetro = %(DirRuntime)s/bin/jadretro.jar
|
||||
Fernflower = %(DirRuntime)s/bin/fernflower.jar
|
||||
Exceptor = %(DirRuntime)s/bin/mcinjector.jar
|
||||
CmdPatch = %s -p1 -u -i {patchfile} -d {srcdir}
|
||||
CmdJad = %s -b -d {outdir} -dead -o -r -s .java -stat -ff {classes}
|
||||
CmdAStyle = %s --suffix=none --quiet --options={conffile} {classes}
|
||||
CmdRG = %s -cp "{classpath}" RetroGuard -searge {conffile}
|
||||
CmdRGReobf = %s -cp "{classpath}" RetroGuard -notch {conffile}
|
||||
CmdJadretro = %s -jar %s {targetdir}
|
||||
CmdFernflower = %s -jar %s -din=0 -rbr=0 -dgs=1 -asc=1 -log=WARN {indir} {outdir}
|
||||
CmdExceptor = %s -jar %s {input} {output} {conf} {log}
|
||||
CmdRecomp = %s -Xlint:-options -deprecation -g -source 1.6 -target 1.6 -classpath "{classpath}" -sourcepath {sourcepath} -d {outpath} {pkgs}
|
||||
CmdStartSrv = %s -Xincgc -Xms1024M -Xmx1024M -cp "{classpath}" net.minecraft.server.MinecraftServer
|
||||
CmdStartClt = %s -Xincgc -Xms1024M -Xmx1024M -cp "{classpath}" -Djava.library.path={natives} Start
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,27 @@
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
public class Start
|
||||
{
|
||||
public static void main(String[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
// set new minecraft data folder to prevent it from using the .minecraft folder
|
||||
// this makes it a portable version
|
||||
Field f = Minecraft.class.getDeclaredField("field_71463_am");
|
||||
Field.setAccessible(new Field[] { f }, true);
|
||||
f.set(null, new File("."));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
// start minecraft game application
|
||||
Minecraft.main(args);
|
||||
}
|
||||
}
|
@ -0,0 +1,184 @@
|
||||
diff -r -U 3 minecraft\net\minecraft\client\Minecraft.java minecraft_patched\net\minecraft\client\Minecraft.java
|
||||
--- minecraft\net\minecraft\client\Minecraft.java Tue Aug 14 20:15:26 2012
|
||||
+++ minecraft_patched\net\minecraft\client\Minecraft.java Tue Aug 14 20:18:48 2012
|
||||
@@ -539,9 +539,8 @@
|
||||
return;
|
||||
}
|
||||
|
||||
- while(true) {
|
||||
try {
|
||||
- if(this.field_71425_J) {
|
||||
+ while(this.field_71425_J) {
|
||||
if(this.field_71434_R && this.field_71433_S != null) {
|
||||
this.func_71377_b(this.field_71433_S);
|
||||
return;
|
||||
@@ -559,7 +558,6 @@
|
||||
this.func_71373_a(new GuiMemoryErrorScreen());
|
||||
System.gc();
|
||||
}
|
||||
- continue;
|
||||
}
|
||||
} catch (MinecraftError var12) {
|
||||
;
|
||||
@@ -577,8 +575,6 @@
|
||||
this.func_71405_e();
|
||||
}
|
||||
|
||||
- return;
|
||||
- }
|
||||
}
|
||||
|
||||
private void func_71411_J() {
|
||||
diff -r -U 3 minecraft\net\minecraft\src\CodecMus.java minecraft_patched\net\minecraft\src\CodecMus.java
|
||||
--- minecraft\net\minecraft\src\CodecMus.java Tue Aug 14 20:15:26 2012
|
||||
+++ minecraft_patched\net\minecraft\src\CodecMus.java Tue Aug 14 20:18:48 2012
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
+import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import net.minecraft.src.MusInputStream;
|
||||
import paulscode.sound.codecs.CodecJOrbis;
|
||||
@@ -7,6 +8,10 @@
|
||||
public class CodecMus extends CodecJOrbis {
|
||||
|
||||
protected InputStream openInputStream() {
|
||||
+ try {
|
||||
return new MusInputStream(this, this.url, this.urlConnection.getInputStream());
|
||||
+ } catch(IOException ex) {
|
||||
+ return null;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
diff -r -U 3 minecraft\net\minecraft\src\ComponentStrongholdRightTurn.java minecraft_patched\net\minecraft\src\ComponentStrongholdRightTurn.java
|
||||
--- minecraft\net\minecraft\src\ComponentStrongholdRightTurn.java Tue Aug 14 20:15:26 2012
|
||||
+++ minecraft_patched\net\minecraft\src\ComponentStrongholdRightTurn.java Tue Aug 14 20:18:48 2012
|
||||
@@ -11,6 +11,10 @@
|
||||
|
||||
public class ComponentStrongholdRightTurn extends ComponentStrongholdLeftTurn {
|
||||
|
||||
+ public ComponentStrongholdRightTurn(int p_i3843_1_, Random p_i3843_2_, StructureBoundingBox p_i3843_3_, int p_i3843_4_) {
|
||||
+ super(p_i3843_1_, p_i3843_2_, p_i3843_3_, p_i3843_4_);
|
||||
+ }
|
||||
+
|
||||
public void func_74861_a(StructureComponent p_74861_1_, List p_74861_2_, Random p_74861_3_) {
|
||||
if(this.field_74885_f != 2 && this.field_74885_f != 3) {
|
||||
this.func_74989_b((ComponentStrongholdStairs2)p_74861_1_, p_74861_2_, p_74861_3_, 1, 1);
|
||||
diff -r -U 3 minecraft\net\minecraft\src\DedicatedServer.java minecraft_patched\net\minecraft\src\DedicatedServer.java
|
||||
--- minecraft\net\minecraft\src\DedicatedServer.java Tue Aug 14 20:15:26 2012
|
||||
+++ minecraft_patched\net\minecraft\src\DedicatedServer.java Tue Aug 14 20:25:02 2012
|
||||
@@ -183,7 +183,7 @@
|
||||
|
||||
}
|
||||
|
||||
- protected CrashReport func_71230_b(CrashReport p_71230_1_) {
|
||||
+ public CrashReport func_71230_b(CrashReport p_71230_1_) {
|
||||
p_71230_1_ = super.func_71230_b(p_71230_1_);
|
||||
p_71230_1_.func_71500_a("Type", new CallableType(this));
|
||||
return p_71230_1_;
|
||||
@@ -193,7 +193,7 @@
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
- protected void func_71190_q() {
|
||||
+ public void func_71190_q() {
|
||||
super.func_71190_q();
|
||||
this.func_71333_ah();
|
||||
}
|
||||
diff -r -U 3 minecraft\net\minecraft\src\FontRenderer.java minecraft_patched\net\minecraft\src\FontRenderer.java
|
||||
--- minecraft\net\minecraft\src\FontRenderer.java Tue Aug 14 20:15:26 2012
|
||||
+++ minecraft_patched\net\minecraft\src\FontRenderer.java Tue Aug 14 20:18:48 2012
|
||||
@@ -711,8 +711,6 @@
|
||||
for(boolean var7 = false; var5 < var3; ++var5) {
|
||||
char var8 = p_78259_1_.charAt(var5);
|
||||
switch(var8) {
|
||||
- case 32:
|
||||
- var6 = var5;
|
||||
case 167:
|
||||
if(var5 < var3 - 1) {
|
||||
++var5;
|
||||
@@ -726,6 +724,8 @@
|
||||
}
|
||||
}
|
||||
break;
|
||||
+ case 32:
|
||||
+ var6 = var5;
|
||||
default:
|
||||
var4 += this.func_78263_a(var8);
|
||||
if(var7) {
|
||||
diff -r -U 3 minecraft\net\minecraft\src\IntegratedServer.java minecraft_patched\net\minecraft\src\IntegratedServer.java
|
||||
--- minecraft\net\minecraft\src\IntegratedServer.java Tue Aug 14 20:15:26 2012
|
||||
+++ minecraft_patched\net\minecraft\src\IntegratedServer.java Tue Aug 14 20:24:49 2012
|
||||
@@ -98,7 +98,7 @@
|
||||
return true;
|
||||
}
|
||||
|
||||
- protected void func_71217_p() {
|
||||
+ public void func_71217_p() {
|
||||
boolean var1 = this.field_71348_o;
|
||||
this.field_71348_o = this.field_71347_n.func_71752_f();
|
||||
if(!var1 && this.field_71348_o) {
|
||||
@@ -145,7 +145,7 @@
|
||||
this.field_71349_l.func_71404_a(p_71228_1_);
|
||||
}
|
||||
|
||||
- protected CrashReport func_71230_b(CrashReport p_71230_1_) {
|
||||
+ public CrashReport func_71230_b(CrashReport p_71230_1_) {
|
||||
p_71230_1_ = super.func_71230_b(p_71230_1_);
|
||||
p_71230_1_.func_71500_a("Type", new CallableType3(this));
|
||||
p_71230_1_.func_71500_a("Is Modded", new CallableIsModded(this));
|
||||
diff -r -U 3 minecraft\net\minecraft\src\ItemMap.java minecraft_patched\net\minecraft\src\ItemMap.java
|
||||
--- minecraft\net\minecraft\src\ItemMap.java Tue Aug 14 20:15:26 2012
|
||||
+++ minecraft_patched\net\minecraft\src\ItemMap.java Tue Aug 14 20:18:48 2012
|
||||
@@ -24,7 +24,6 @@
|
||||
}
|
||||
|
||||
public static MapData func_77874_a(short p_77874_0_, World p_77874_1_) {
|
||||
- "map_" + p_77874_0_;
|
||||
MapData var3 = (MapData)p_77874_1_.func_72943_a(MapData.class, "map_" + p_77874_0_);
|
||||
if(var3 == null) {
|
||||
int var4 = p_77874_1_.func_72841_b("map");
|
||||
@@ -37,7 +36,6 @@
|
||||
}
|
||||
|
||||
public MapData func_77873_a(ItemStack p_77873_1_, World p_77873_2_) {
|
||||
- "map_" + p_77873_1_.func_77960_j();
|
||||
MapData var4 = (MapData)p_77873_2_.func_72943_a(MapData.class, "map_" + p_77873_1_.func_77960_j());
|
||||
if(var4 == null) {
|
||||
p_77873_1_.func_77964_b(p_77873_2_.func_72841_b("map"));
|
||||
diff -r -U 3 minecraft\net\minecraft\src\RenderGlobal.java minecraft_patched\net\minecraft\src\RenderGlobal.java
|
||||
--- minecraft\net\minecraft\src\RenderGlobal.java Tue Aug 14 20:15:27 2012
|
||||
+++ minecraft_patched\net\minecraft\src\RenderGlobal.java Tue Aug 14 20:18:48 2012
|
||||
@@ -1431,7 +1431,7 @@
|
||||
double var15 = this.field_72777_q.field_71451_h.field_70165_t - p_72726_2_;
|
||||
double var17 = this.field_72777_q.field_71451_h.field_70163_u - p_72726_4_;
|
||||
double var19 = this.field_72777_q.field_71451_h.field_70161_v - p_72726_6_;
|
||||
- Object var21 = null;
|
||||
+ EntityFX var21 = null;
|
||||
if(p_72726_1_.equals("hugeexplosion")) {
|
||||
this.field_72777_q.field_71452_i.func_78873_a(var21 = new EntityHugeExplodeFX(this.field_72769_h, p_72726_2_, p_72726_4_, p_72726_6_, p_72726_8_, p_72726_10_, p_72726_12_));
|
||||
} else if(p_72726_1_.equals("largeexplode")) {
|
||||
diff -r -U 3 minecraft\net\minecraft\src\TcpMasterThread.java minecraft_patched\net\minecraft\src\TcpMasterThread.java
|
||||
--- minecraft\net\minecraft\src\TcpMasterThread.java Tue Aug 14 20:15:27 2012
|
||||
+++ minecraft_patched\net\minecraft\src\TcpMasterThread.java Tue Aug 14 20:18:48 2012
|
||||
@@ -11,6 +11,7 @@
|
||||
this.field_74504_a = p_i3285_1_;
|
||||
}
|
||||
|
||||
+ @SuppressWarnings("deprecation")
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(5000L);
|
||||
diff -r -U 3 minecraft\net\minecraft\src\ThreadedFileIOBase.java minecraft_patched\net\minecraft\src\ThreadedFileIOBase.java
|
||||
--- minecraft\net\minecraft\src\ThreadedFileIOBase.java Tue Aug 14 20:15:27 2012
|
||||
+++ minecraft_patched\net\minecraft\src\ThreadedFileIOBase.java Tue Aug 14 20:18:48 2012
|
||||
@@ -20,7 +20,9 @@
|
||||
}
|
||||
|
||||
public void run() {
|
||||
+ while(true) {
|
||||
this.func_75736_b();
|
||||
+ }
|
||||
}
|
||||
|
||||
private void func_75736_b() {
|
@ -0,0 +1,70 @@
|
||||
diff -r -U 3 minecraft_server\net\minecraft\src\ComponentStrongholdRightTurn.java minecraft_server_patched\net\minecraft\src\ComponentStrongholdRightTurn.java
|
||||
--- minecraft_server\net\minecraft\src\ComponentStrongholdRightTurn.java Tue Aug 14 20:16:02 2012
|
||||
+++ minecraft_server_patched\net\minecraft\src\ComponentStrongholdRightTurn.java Tue Aug 14 20:19:30 2012
|
||||
@@ -11,6 +11,10 @@
|
||||
|
||||
public class ComponentStrongholdRightTurn extends ComponentStrongholdLeftTurn {
|
||||
|
||||
+ public ComponentStrongholdRightTurn(int p_i3843_1_, Random p_i3843_2_, StructureBoundingBox p_i3843_3_, int p_i3843_4_) {
|
||||
+ super(p_i3843_1_, p_i3843_2_, p_i3843_3_, p_i3843_4_);
|
||||
+ }
|
||||
+
|
||||
public void func_74861_a(StructureComponent p_74861_1_, List p_74861_2_, Random p_74861_3_) {
|
||||
if(this.field_74885_f != 2 && this.field_74885_f != 3) {
|
||||
this.func_74989_b((ComponentStrongholdStairs2)p_74861_1_, p_74861_2_, p_74861_3_, 1, 1);
|
||||
diff -r -U 3 minecraft_server\net\minecraft\src\DedicatedServer.java minecraft_server_patched\net\minecraft\src\DedicatedServer.java
|
||||
--- minecraft_server\net\minecraft\src\DedicatedServer.java Tue Aug 14 20:16:03 2012
|
||||
+++ minecraft_server_patched\net\minecraft\src\DedicatedServer.java Tue Aug 14 20:24:26 2012
|
||||
@@ -184,7 +184,7 @@
|
||||
|
||||
}
|
||||
|
||||
- protected CrashReport func_71230_b(CrashReport p_71230_1_) {
|
||||
+ public CrashReport func_71230_b(CrashReport p_71230_1_) {
|
||||
p_71230_1_ = super.func_71230_b(p_71230_1_);
|
||||
p_71230_1_.func_71500_a("Type", new CallableType(this));
|
||||
return p_71230_1_;
|
||||
@@ -194,7 +194,7 @@
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
- protected void func_71190_q() {
|
||||
+ public void func_71190_q() {
|
||||
super.func_71190_q();
|
||||
this.func_71333_ah();
|
||||
}
|
||||
diff -r -U 3 minecraft_server\net\minecraft\src\ItemMap.java minecraft_server_patched\net\minecraft\src\ItemMap.java
|
||||
--- minecraft_server\net\minecraft\src\ItemMap.java Tue Aug 14 20:16:03 2012
|
||||
+++ minecraft_server_patched\net\minecraft\src\ItemMap.java Tue Aug 14 20:19:30 2012
|
||||
@@ -24,7 +24,6 @@
|
||||
}
|
||||
|
||||
public MapData func_77873_a(ItemStack p_77873_1_, World p_77873_2_) {
|
||||
- "map_" + p_77873_1_.func_77960_j();
|
||||
MapData var4 = (MapData)p_77873_2_.func_72943_a(MapData.class, "map_" + p_77873_1_.func_77960_j());
|
||||
if(var4 == null) {
|
||||
p_77873_1_.func_77964_b(p_77873_2_.func_72841_b("map"));
|
||||
diff -r -U 3 minecraft_server\net\minecraft\src\TcpMasterThread.java minecraft_server_patched\net\minecraft\src\TcpMasterThread.java
|
||||
--- minecraft_server\net\minecraft\src\TcpMasterThread.java Tue Aug 14 20:16:03 2012
|
||||
+++ minecraft_server_patched\net\minecraft\src\TcpMasterThread.java Tue Aug 14 20:19:30 2012
|
||||
@@ -11,6 +11,7 @@
|
||||
this.field_74504_a = p_i3285_1_;
|
||||
}
|
||||
|
||||
+ @SuppressWarnings("deprecation")
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(5000L);
|
||||
diff -r -U 3 minecraft_server\net\minecraft\src\ThreadedFileIOBase.java minecraft_server_patched\net\minecraft\src\ThreadedFileIOBase.java
|
||||
--- minecraft_server\net\minecraft\src\ThreadedFileIOBase.java Tue Aug 14 20:16:03 2012
|
||||
+++ minecraft_server_patched\net\minecraft\src\ThreadedFileIOBase.java Tue Aug 14 20:19:30 2012
|
||||
@@ -20,7 +20,9 @@
|
||||
}
|
||||
|
||||
public void run() {
|
||||
+ while(true) {
|
||||
this.func_75736_b();
|
||||
+ }
|
||||
}
|
||||
|
||||
private void func_75736_b() {
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,4 @@
|
||||
[VERSION]
|
||||
MCPVersion = 7.2
|
||||
ClientVersion = 1.3.2
|
||||
ServerVersion = 1.3.2
|
@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
runtime\bin\python\python_mcp runtime\decompile.py %*
|
||||
pause
|
@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
python runtime/decompile.py "$@"
|
@ -0,0 +1,8 @@
|
||||
To use eclipse with MCP, just do the following steps:
|
||||
- Decompile the Minecraft sources
|
||||
- Open Eclipse
|
||||
- Select the "eclipse" folder in MCP as workspace
|
||||
- Create a mod
|
||||
- You can test the modified client and server in Eclipse, debug
|
||||
settings are already prepared to start the game in the IDE
|
||||
- Recompile and reobfuscate as usual
|
@ -0,0 +1,73 @@
|
||||
To use the fernflower decompiler, just put the fernflower.jar file into the runtime/bin folder.
|
||||
Only tested with fernflower 0.8.6, other versions may fail.
|
||||
|
||||
|
||||
Hi Searge,
|
||||
|
||||
I was told you might be planning to distribute Fernflower as a part of
|
||||
MCP. It looks like a very nice project to me (excellent work btw :))
|
||||
so I'm happy to allow the integration. Below you'll find the necessary
|
||||
supplement to the general license.
|
||||
|
||||
Based on the general Fernflower license the following additional
|
||||
permissions are granted to the project Minecraft Coder Pack (MCP). As
|
||||
long as the project remains non-commercial it may use, integrate and
|
||||
distribute every binary version of the decompiler Fernflower in any
|
||||
desired way as part of MCP tools. Custom patches to Fernflower are
|
||||
generally possible after a brief consultation with me.
|
||||
|
||||
Cheers,
|
||||
Stiver
|
||||
|
||||
|
||||
Fernflower Freeware License 1.0
|
||||
|
||||
This license applies to the Fernflower decompiler (hereafter “Software")
|
||||
including any associated files, information and examples.
|
||||
|
||||
You are hereby granted a non-exclusive and non-transferable license to
|
||||
use and distribute the Software in binary form according to the following
|
||||
terms and conditions.
|
||||
|
||||
|
||||
1) Copies and Redistribution
|
||||
|
||||
You may copy and distribute unmodified binary copies of the Software
|
||||
provided that you keep this license intact. You must NOT charge money
|
||||
or fees for the Software except to cover the absolutely necessary
|
||||
distribution costs.
|
||||
|
||||
Any other form of redistribution is prohibited. Especially you are not
|
||||
allowed to redistribute the Software as part of any other software
|
||||
collection or other product.
|
||||
|
||||
|
||||
2) Use
|
||||
|
||||
You may use the Software "as is" in any commercial or non-commercial environment
|
||||
for any purpose.
|
||||
|
||||
|
||||
3) Contact Information
|
||||
|
||||
The sole author and owner of Fernflower is Stiver. Address all correspondence regarding
|
||||
this license to:
|
||||
|
||||
fernflower.decompiler@gmail.com
|
||||
|
||||
http://www.reversed-java.com
|
||||
|
||||
|
||||
4) Disclaimer of Warranty
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
@ -0,0 +1,9 @@
|
||||
Things required to run:
|
||||
|
||||
- wine to run jad. We know, there are linux binaries of jad BUT those are
|
||||
v1.5.8e, we need 1.5.8g
|
||||
- python to run most of the tools
|
||||
- patch to fix the decompiled sources
|
||||
- minecraft.jar, lwjgl jars, and the linux version of the natives, these can
|
||||
be found in your home dir under ".minecraft/bin", the entire bin folder
|
||||
itself should be copied into the jars folder
|
@ -0,0 +1,310 @@
|
||||
Minecraft Coder Pack 7.2 for Minecraft 1.3.2
|
||||
============================================
|
||||
MCP is (c) Copyright by the MCP Team
|
||||
|
||||
License and terms of use.
|
||||
=========================
|
||||
|
||||
No warranties. If MCP does not work for you, or causes any damage, it's your problem. Use it at own risk.
|
||||
|
||||
You are allowed to:
|
||||
- Use MCP to decompile the Minecraft client and server jar files.
|
||||
- Use the decompiled source code to create mods for Minecraft.
|
||||
- Recompile modified versions of Minecraft.
|
||||
- Reobfuscate the classes of your mod for Minecraft.
|
||||
|
||||
You are NOT allowed to:
|
||||
- Use MCP to do anything that violated Mojangs terms of use for Minecraft.
|
||||
- Release Minecraft versions or modifications that allow you to play without having bought Minecraft from Mojang.
|
||||
- Release modified or unmodified versions of MCP anywhere.
|
||||
- Use any of MCPs scripts, tools or data files without explicit written permission.
|
||||
- Make money with anything based on MCP (excluding Minecraft mods created by using MCP).
|
||||
- Use MCP to create clients that are used for griefing or exploiting server bugs.
|
||||
- Release the decompiled source code of Minecraft in any way.
|
||||
|
||||
Prerequisites:
|
||||
==============
|
||||
1.) Install Java SDK Standard Edition (short JDK).
|
||||
Link: http://www.oracle.com/technetwork/java/javase/downloads/
|
||||
|
||||
2.) Add the paths to your JDK and JRE bin folders to the Environment Variable PATH.
|
||||
|
||||
Description where to find the variable:
|
||||
http://www.java.com/en/download/help/path.xml
|
||||
|
||||
Example for Windows users of what you have to add to the variable (entries are seperated by ";" )
|
||||
C:\Program Files\Java\jdk1.6.0_24\bin;C:\Program Files\Java\jre6\bin
|
||||
|
||||
We wont provide any help setting it up - this _is_ a prerequesite.
|
||||
|
||||
Note: MCP versions 4.4 and higher should also work properly with JDK 1.7
|
||||
|
||||
How to use:
|
||||
===========
|
||||
1) Prepare the files:
|
||||
- Copy the "minecraft_server.jar" file into the "jars" folder.
|
||||
- Copy the folders "bin" and "resources" from your "%APPDATA$\.minecraft" folder into the "jars" folder.
|
||||
|
||||
2) Decompilation and patching
|
||||
- Start the "decompile.bat" script in this folder.
|
||||
|
||||
3) Modding
|
||||
- Modify the sourcecode in the "src\minecraft" folder or in the "src\minecraft_server" folder.
|
||||
|
||||
4) Compile
|
||||
- Start the "recompile.bat" script in this folder.
|
||||
|
||||
5) Testing
|
||||
- To test the modified game, start the "startclient.bat" script
|
||||
- To test the modified server, start the "startserver.bat" script
|
||||
|
||||
6) Obfuscation
|
||||
- Decompile the code, modify and recompile.
|
||||
- Start "reobfuscate.bat" to start the reobfuscation step, it will automatically detect changed classes and reobfuscate them.
|
||||
- Your obfuscated classes are now available in "reobf\minecraft" and "reobf\minecraft_server", ready to be injected in MC.
|
||||
- Make sure to delete the META-INF folder in minecraft.jar, otherwise the game will just black-screen when you start it.
|
||||
|
||||
WARNINGS:
|
||||
=========
|
||||
- Make sure that you backup the modified sources before you run "decompile.bat" again or all changes will be lost!
|
||||
- The "cleanup.bat" file will delete most of the generated files and sources. Be careful with this one :)
|
||||
|
||||
Notes:
|
||||
======
|
||||
* If you want to include external libraries (either as .jar or .class) to the classpath during recompilation add them
|
||||
to a folder called "lib" creating it first if required.
|
||||
|
||||
* Should mcp complain about "java.lang.NoClassDefFoundError: Start" when trying to run startclient.bat or startserver.bat
|
||||
try cleanup.bat (make backups of you sources!), decompile again and recompile as the final step.
|
||||
|
||||
* Do not use this to release complete packages of minecraft jar, class or java files. They are copyrighted
|
||||
material by Notch and mods should only contain small changes to some classes, never complete sets that
|
||||
can be used by people who did not buy the game to play it.
|
||||
|
||||
* Make sure you use the original minecraft.jar and minecraft_server.jar files. If you have already modded them
|
||||
they will NOT work with the patches in these scripts.
|
||||
|
||||
* The "startclient.bat" file uses the "Start.class" file to start the game. This will make sure the game will not
|
||||
use your "%APPDATA%\.minecraft" folder, but instead use the "jars" folder for all saves. So any bugs in the modified
|
||||
game will not corrupt your normal worlds.
|
||||
|
||||
* If you have any problems using this toolpack, put the "logs\*.log" files that the scripts generated into a
|
||||
zip-file and send it to us (post it in the minecraft forum):
|
||||
http://www.minecraftforum.net/viewtopic.php?f=25&t=58464
|
||||
|
||||
* This version of the MCP uses a deobfuscator to change all field and method names in the sources.
|
||||
Look in the csv files in "conf", namely "conf\classes.csv", "conf\fields.csv" and "conf\methods.csv" files for a complete mapping of the names.
|
||||
|
||||
* There are currently no known bugs in the recompiled game or server, except those that were already in the original
|
||||
game :)
|
||||
|
||||
* If your reobfuscated classes cause a black screen in Minecraft, make sure that you've deleted the META-INF folder
|
||||
in the minecraft.jar file.
|
||||
|
||||
* To add new resources to the game, for example png files, put them in the bin folder tree, they will also get copied to the reob folder
|
||||
automatically when you reobfuscate your changes.
|
||||
|
||||
Credits:
|
||||
========
|
||||
== Currently Active ==
|
||||
Searge
|
||||
* Creator of MCP
|
||||
* Fixes all compile errors in the decompiled sourcecode
|
||||
* Created the MCP mod system and API
|
||||
* Created the Eclipse workspace for MCP 4.x
|
||||
* Created the new RetroGuard deobfuscation module for MCP 3.0
|
||||
* Created the new mod system
|
||||
ProfMobius
|
||||
* Creator of the renaming codes and re-obfuscation procedures
|
||||
* Helped to port scripts to Linux
|
||||
* Developer and maintainer of the MCP chan bot
|
||||
* Is now bald after working too much with java constant pool and re-obfuscation
|
||||
* Created the new workflow scripts and renamer for MCP 3.0
|
||||
IngisKahn
|
||||
* Creator of the bytecode compare tool that helps us to update the name mappings quickly for new minecraft versions
|
||||
* Contributed to the de-obfuscation spreadsheet
|
||||
* Working hard on creating better internal tools for mapping updates and decompiling
|
||||
Fesh0r
|
||||
* php/sql code monkey
|
||||
* Uses his magic to create mappings, patches, and general release work
|
||||
* Has Searge's approval to make official MCP releases ;)
|
||||
* Makes sure we get proper patches for the sourcecode that JAD generates
|
||||
* Maintains our scripts and toolkits
|
||||
* Optimized the Retroguard and Exceptor tools
|
||||
R4WK
|
||||
* Works on MCP updates and contributes to the new mod system
|
||||
* Helps ZeuX with Techne improvements
|
||||
ZeuX
|
||||
* Helps out in the IRC channels - Head of HR
|
||||
* Did server patches for the most recent versions - if you run into any (patch-related) problems, it's his fault :P
|
||||
* Created the famous Techne model editor for Minecraft
|
||||
* Contributes features to the new mod system
|
||||
303
|
||||
* Wiki contributor
|
||||
* Tries to help out newbies in the IRC channels
|
||||
* Makes sure modloader mods can be created with MCP
|
||||
Mr_okushama
|
||||
* Wiki contributor
|
||||
* Public Support Manager
|
||||
* IRC Operator
|
||||
* Savior of the 2011 April fools prank
|
||||
Cryect
|
||||
* Contributed a lot of deobfuscation mappings
|
||||
* Created the awesome AdventureCraft mod
|
||||
LexManos
|
||||
* Helped Fesh0r to update MCP for Minecraft 1.0.0/1.0.1
|
||||
Mysterio N
|
||||
* Created the getmodsource scripts
|
||||
|
||||
== Former Contributors ==
|
||||
Generic
|
||||
* Works on improving IngisKahn's bytecode compare tool
|
||||
* Added some important features to retroguard
|
||||
Risugami
|
||||
* The guy who created the first mods I (Searge) ever used in Minecraft
|
||||
* The creator of modloader who gave us permission to include files from his system in MCP
|
||||
fotoply
|
||||
* Helped to improve the batch files
|
||||
Cadde
|
||||
* Community manager and Wiki manager
|
||||
* Works on the de-obfuscation spreadsheet
|
||||
* Mod support (making old mods work with MCP)
|
||||
* All round handyman
|
||||
Vaprtek
|
||||
* Works on the de-obfuscation spreadsheet
|
||||
* Knows how to make pet creepers
|
||||
gronk
|
||||
* Script support
|
||||
n00bish
|
||||
* Linux script maintenance
|
||||
Sage Pourpre
|
||||
* His thread in the forums inspired me (Searge) to create this toolpack in the first place
|
||||
Tei
|
||||
* Supported the MCP project since the first version was released
|
||||
spec10
|
||||
* The new linux scripts guy
|
||||
Head
|
||||
* Wiki contributor / Administrator
|
||||
* Explains classes and their members on the Wiki
|
||||
MissLil
|
||||
* Various scripting stuff
|
||||
* Lots of reverse engineering
|
||||
* OpenGL constants annoting
|
||||
ScottyDoesKnow
|
||||
* obfuscathonCharmer, the obfuscathon GUI
|
||||
Chase
|
||||
* MCP Launcher Work
|
||||
* External jar loading
|
||||
* Scrollable mod list.
|
||||
titegtnodI
|
||||
* Wiki contributor
|
||||
* IRC Operator
|
||||
|
||||
== Superspecial thanks to ==
|
||||
Stiver - for allowing us to include the fernflower decompiler in MCP releases
|
||||
|
||||
== Special thanks to ==
|
||||
UltraMoogleMan
|
||||
Yamachi
|
||||
|
||||
and of course:
|
||||
- Everybody who contributed to the google spreadsheet and MCPBot or who created some mods with MCP.
|
||||
- NOTCH and JEB for creating a game that is just awesome, I hope they do not feel offended by our decompiling efforts.
|
||||
Please, Notch, support our ambitions to mod your game. I know people who bought it just because of
|
||||
some great mods.
|
||||
|
||||
History:
|
||||
========
|
||||
7.2 - Updated to support Minecraft 1.3.2 and MinecraftServer 1.3.2
|
||||
7.0a - Added fernflower decompiler
|
||||
7.0 - Updated to support Minecraft 1.3.1 and MinecraftServer 1.3.1
|
||||
6.2 - Updated to support Minecraft 1.2.5 and MinecraftServer 1.2.5
|
||||
6.1 - Updated to support Minecraft 1.2.4 and MinecraftServer 1.2.4
|
||||
6.0 - Updated to support Minecraft 1.2.3 and MinecraftServer 1.2.3
|
||||
5.6 - Updated to support Minecraft 1.1 and MinecraftServer 1.1
|
||||
5.0 - Updated to support Minecraft 1.0.0 and MinecraftServer 1.0.1
|
||||
4.5 - Updated to support Minecraft 1.9 pre 5 and MinecraftServer 1.9 pre 5
|
||||
4.4 - Updated to support Minecraft 1.8.1 and MinecraftServer 1.8.1
|
||||
4.3 - Updated to support Minecraft 1.7.3 and MinecraftServer 1.7.3
|
||||
4.2 - Updated to support Minecraft 1.7.2 and MinecraftServer 1.7.2
|
||||
4.1 - Added an Eclipse workspace and included a reobfuscation bugfix
|
||||
4.0 - Added improved decompile scripts with new Exceptor tool
|
||||
3.4 - Updated to support Minecraft 1.6.6 and MinecraftServer 1.6.6
|
||||
3.3 - Updated to support Minecraft 1.6.5 and MinecraftServer 1.6.5
|
||||
3.2 - Updated to support Minecraft 1.6.4 and MinecraftServer 1.6.4
|
||||
3.1 - Complete rewrite of the framework, works with Minecraft 1.5_01 and MinecraftServer 1.5_02
|
||||
2.12 - Updated to support Minecraft 1.5_01 and MinecraftServer 1.5_02
|
||||
2.11 - Updated to support Minecraft 1.4_01 and MinecraftServer 1.4_01
|
||||
2.10 - Updated to support Minecraft 1.4 and MinecraftServer 1.4
|
||||
2.9a - Added MCP Mod System for 1.3_01, added mod loader support, updated mappings
|
||||
2.9 - Updated to support Minecraft 1.3_01 and MinecraftServer 1.3
|
||||
2.8 - Added the MCP mod system SDK and support for OSX
|
||||
2.7 - Updated to support Minecraft 1.2_02 and MinecraftServer 1.2_01
|
||||
2.6 - Updated to support Minecraft 1.1_02 and MinecraftServer 1.1_02
|
||||
2.5 - Updated to support Minecraft 1.2.6 and MinecraftServer 0.2.8
|
||||
2.4 - Updated to support Minecraft 1.2.5 and MinecraftServer 0.2.7
|
||||
2.3 - Updated to support Minecraft 1.2.3_04 and MinecraftServer 0.2.5_02. Linux support beta.
|
||||
2.2a - Bugfix release to improve the re-obfuscation tools
|
||||
2.2 - The reobfuscation beta test release. Still for Minecraft 1.2.2
|
||||
2.1 - Updated to support Minecraft 1.2.2
|
||||
2.0a - Bugfix release
|
||||
2.0 - Major updates to MCP and support for post-Halloween versions of Minecraft
|
||||
1.6 - All classes have meaningful names now, the class name mappings and the field name mappings are applied
|
||||
1.5 - Extend the scripts to also support decompiling, recompiling and testing the minecraft_server.jar file
|
||||
1.4 - Using a deobfuscator to rename all fields and methods and jadretro to fix some decompile bugs
|
||||
1.3 - Added upgrade scripts to decompile and recompile Minecraft.class, MinecraftApplet.class and MinecraftServer.class
|
||||
1.2 - Redirect output of all tools to a logfile
|
||||
1.1 - Fixed TNT bug
|
||||
1.0 - First release
|
||||
|
||||
Roadmap:
|
||||
========
|
||||
7.3+ - New awesome features, improvements and updates :)
|
||||
|
||||
_________________________________________________________________________________________________________________
|
||||
_________________________________________________________________________________________________________________
|
||||
________,.--:=r=.._______________________________________________________________________________,,...___________
|
||||
_ -:'` :^)-.!..[``P: ___________________________________________________________ ,.=~r?`[:_i=. `'~-._ _
|
||||
_ . :=)~.|:.| [j ___________________________________________________________ l| [3 .:,[:. ! _
|
||||
_ : :.[ .|:.( [| ______________________________________________________________[|=^): [_ | . ! _
|
||||
__ :~)=.i..j [] ___________________________________________________________ )|:') [ _|;. ! _
|
||||
_ . :.)..i._|;.)| ___________________________________________________________ [!:=[` |: | . ! _
|
||||
_ ) _ :.[ .! | .[| ___________________________________________________________ )j:^[` (: | . ! _
|
||||
_ :_ <=l:.____ . | ___________________________________________________________ [!:`` :.|:. . ! _
|
||||
_ ._ _ __ __:..;.|,.) .[j ___________________________________________________________ [!3`T``l:. . ` ! _
|
||||
____ [,...-+=c=f7l`!-( _____.~~~~~~~~._____=~~~~~~~/_____,>====~<.y=.__y~~~~~~~~~~=~.._ ```[j)=[=[.;,,_ _|'`` _
|
||||
____ [ -~= ( '=r::::~( _____!<. L____F .=._ ,c ;>~~<. [_ F<. .>~~<. ".__ (.......!.( .. | ____
|
||||
____ [`) [ ! !^) !') ______ [ JL (___F Z. ( ___/ ./ ____ ". J___ L ? ___J. J _ |-l ,.( !-| )-| ____
|
||||
____ ) !` ( ```[ ( _____ :. [[ J__F /] .L___F .F _______"L L__J [____/ / _ | )~~~~ r- !~! | ____
|
||||
____ [ . . [_) (___|_( _____ | :L! J.F / L J __[ | _________ _ [ =+~~=l ;/ __ |'[^^^( [ :'. ::( ____
|
||||
____ [.. (.;.i.) ( ______L ? :. * / J. [__ L L______________:L ;...=+=^` ____ (`["[ l [`` ! ! | ____
|
||||
____ ).. .... !.. ( _____J. L_ L / _[ :L__ [ [_________,.__ | .L_____________ ( . ! | ____
|
||||
____ ).. --. --..!-( _____[ :.__| / _.L J ___"c ?.______,/.;F _L J._____________ [_[___ __ _| ____
|
||||
____ )~)~r -)~r - ( ( __:tT ":LJ / r^` ")___ \. 7*==^`.;* r^` "tL___________ ! ( ,,[ ._].|_____
|
||||
___ _z;! : = ( ( : !=( __'^^^^^^" ^^ *^^^^^^^^`____ "*~~~~^` __"^^^^^^^^" ___________ ;.) ( ( ..!.!.| ____
|
||||
____F"*:P*si_(^^======.____________________________________________________________________j.....[.( !,.ztSP\ ___
|
||||
_ _! 7*.) L L___________________________________________________________________: J :?x>'` l___
|
||||
__[ ;~.! ; :=l .-<--~~[___________________________________________________________________|,J .__ !. :. _,_ . _
|
||||
I :`~. `\[ (.J-= [___________________________________________________________________| ._L_)~\./ ..==`.
|
||||
-.;`'=._ .L!;)-+--=-=-l___________________________________________________________________|___;__[_;=[\ ,>=`
|
||||
_ =-: `` _ --:...-...___________________________________________________________________ :_: ._[ \=^ .-!
|
||||
_ ` - L______-.- ..-___________________________________________________________________: ! ._____ -' _ -' _
|
||||
_____ _________________________________________________________________________________ ______ ' _____
|
||||
|
||||
|
||||
d8b db .d88b. db d8b db d888888b d888888b d888888b .d8888.
|
||||
888o 88 .8P Y8. 88 I8I 88 `88' `~~88~~' `88' 88' YP
|
||||
88V8o 88 88 88 88 I8I 88 88 88 88 `8bo.
|
||||
88 V8o88 88 88 Y8 I8I 88 88 88 88 `Y8b.
|
||||
88 V888 `8b d8' `8b d8'8b d8' .88. 88 .88. db 8D
|
||||
VP V8P `Y88P' `8b8' `8d8' Y888888P YP Y888888P `8888Y'
|
||||
|
||||
|
||||
db db .d88b. db db d8888b. .o88b. d8888b. .d8b. d88888b d888888b
|
||||
`8b d8' .8P Y8. 88 88 88 `8D d8P Y8 88 `8D d8' `8b 88' `~~88~~'
|
||||
`8bd8' 88 88 88 88 88oobY' 8P 88oobY' 88ooo88 88ooo 88
|
||||
88 88 88 88 88 88`8b 8b 88`8b 88~~~88 88~~~ 88
|
||||
88 `8b d8' 88b d88 88 `88. Y8b d8 88 `88. 88 88 88 88
|
||||
YP `Y88P' ~Y8888P' 88 YD `Y88P' 88 YD YP YP YP YP
|
||||
|
||||
======================================================================================================================
|
@ -0,0 +1,7 @@
|
||||
Things required to run:
|
||||
|
||||
- python to run most of the tools
|
||||
- patch to fix the decompiled sources
|
||||
- minecraft.jar, lwjgl jars, and the OSX version of the natives, these can be
|
||||
found in your home folder under "Library/Application Support/minecraft/bin",
|
||||
the entire bin folder itself should be copied into the jars folder
|
@ -0,0 +1,51 @@
|
||||
Fernflower Freeware License 1.0
|
||||
|
||||
This license applies to the Fernflower decompiler (hereafter “Software")
|
||||
including any associated files, information and examples.
|
||||
|
||||
You are hereby granted a non-exclusive and non-transferable license to
|
||||
use and distribute the Software in binary form according to the following
|
||||
terms and conditions.
|
||||
|
||||
|
||||
1) Copies and Redistribution
|
||||
|
||||
You may copy and distribute unmodified binary copies of the Software
|
||||
provided that you keep this license intact. You must NOT charge money
|
||||
or fees for the Software except to cover the absolutely necessary
|
||||
distribution costs.
|
||||
|
||||
Any other form of redistribution is prohibited. Especially you are not
|
||||
allowed to redistribute the Software as part of any other software
|
||||
collection or other product.
|
||||
|
||||
|
||||
2) Use
|
||||
|
||||
You may use the Software "as is" in any commercial or non-commercial environment
|
||||
for any purpose.
|
||||
|
||||
|
||||
3) Contact Information
|
||||
|
||||
The sole author and owner of Fernflower is Stiver. Address all correspondence regarding
|
||||
this license to:
|
||||
|
||||
fernflower.decompiler@gmail.com
|
||||
|
||||
http://www.reversed-java.com
|
||||
|
||||
|
||||
4) Disclaimer of Warranty
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
@ -0,0 +1,86 @@
|
||||
1. About the decompiler
|
||||
|
||||
Fernflower is the first actually working analytical decompiler for Java and
|
||||
probably for a high-level programming language in general. Naturally it is still
|
||||
under development, please send your bug reports and improvement suggestions at
|
||||
fernflower.decompiler@gmail.com
|
||||
|
||||
|
||||
2. License
|
||||
|
||||
See license_en.txt
|
||||
|
||||
|
||||
3. Running from the command line
|
||||
|
||||
java -jar fernflower.jar [-<option>=<value>]* [<source>]+ <destination>
|
||||
|
||||
* means 0 or more times
|
||||
+ means 1 or more times
|
||||
|
||||
<source>: file or directory with files to be decompiled. Directories are recursively scanned. Allowed file extensions are class, zip and jar.
|
||||
Sources prefixed with -e= mean "library" files that won't be decompiled, but taken into account when analysing relationships between
|
||||
classes or methods. Especially renaming of identifiers (s. option 'ren') can benefit from information about external classes.
|
||||
<destination>: destination directory
|
||||
<option>,<value>: command line option with the corresponding value, see 4.
|
||||
|
||||
Examples:
|
||||
|
||||
java -jar fernflower.jar -hes=0 -hdc=0 c:\Temp\binary\ -e=c:\Java\rt.jar c:\Temp\source\
|
||||
|
||||
java -jar fernflower.jar -dgs=1 c:\Temp\binary\library.jar c:\Temp\binary\Boot.class c:\Temp\source\
|
||||
|
||||
|
||||
4. Command line options
|
||||
|
||||
With the exception of mpm and urc the value of 1 means the option is activated, 0 - deactivated. Default
|
||||
value, if any, is given between parentheses.
|
||||
|
||||
Typically, the following options will be changed by user, if any: hes, hdc, dgs, mpm, ren, urc
|
||||
The rest of options can be left as they are: they are aimed at professional reverse engineers.
|
||||
|
||||
rbr (1): hide bridge methods
|
||||
rsy (0): hide synthetic class members
|
||||
din (1): decompile inner classes
|
||||
dc4 (1): collapse 1.4 class references
|
||||
das (1): decompile assertions
|
||||
hes (1): hide empty super invocation
|
||||
hdc (1): hide empty default constructor
|
||||
dgs (0): decompile generic signatures
|
||||
occ (0): ouput copyright comment
|
||||
ner (1): assume return not throwing exceptions
|
||||
den (1): decompile enumerations
|
||||
rgn (1): remove getClass() invocation, when it is part of a qualified new statement
|
||||
bto (1): interpret int 1 as boolean true (workaround to a compiler bug)
|
||||
nns (1): allow for not set synthetic attribute (workaround to a compiler bug)
|
||||
uto (1): consider nameless types as java.lang.Object (workaround to a compiler architecture flaw)
|
||||
udv (1): reconstruct variable names from debug information, if present
|
||||
rer (1): remove empty exception ranges
|
||||
fdi (1): deinline finally structures
|
||||
asc (0): allow only ASCII characters in string literals. All other characters will be encoded using Unicode escapes (JLS 3.3). Default encoding is UTF8.
|
||||
mpm (0): maximum allowed processing time per decompiled method, in seconds. 0 means no upper limit.
|
||||
ren (0): rename ambiguous (resp. obfuscated) classes and class elements
|
||||
urc : full name of user-supplied class implementing IIdentifierRenamer. It is used to determine which
|
||||
class identifiers should be renamed and provides new identifier names. For more information
|
||||
s. section 5
|
||||
|
||||
The default logging level is INFO. This value can be overwritten by setting the option 'log' as follows:
|
||||
|
||||
log (INFO): possible values TRACE, INFO, WARN, ERROR
|
||||
|
||||
|
||||
5. Renaming identifiers
|
||||
|
||||
Some obfuscators give classes and their member elements short, meaningless and above all ambiguous names. Recompiling of such
|
||||
code leads to a great number of conflicts. Therefore it is advisable to let the decompiler rename elements in its turn,
|
||||
ensuring uniqueness of each identifier.
|
||||
|
||||
Option 'ren' (i.e. -ren=1) activates renaming functionality. Default renaming strategy goes as follows:
|
||||
- rename an element if its name is a reserved word or is shorter than 3 characters
|
||||
- new names are built according to a simple pattern: (class|method|field)_<consecutive unique number>
|
||||
You can overwrite this rules by providing your own implementation of the 4 key methods invoked by the decompiler while renaming. Simply
|
||||
pass a class that implements de.fernflower.main.extern.IIdentifierRenamer in the option 'urc' (e.g. -urc=com.mypackage.MyRenamer) to
|
||||
Fernflower. The class must be available on the application classpath.
|
||||
|
||||
The meaning of each method should be clear from naming: toBeRenamed determine whether the element will be renamed, while the other three
|
||||
provide new names for classes, methods and fields respectively.
|
Binary file not shown.
@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
runtime\bin\python\python_mcp runtime\getchangedsrc.py %*
|
||||
pause
|
@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
python runtime/getchangedsrc.py "$@"
|
@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
runtime\bin\python\python_mcp runtime\recompile.py %*
|
||||
pause
|
@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
python runtime/recompile.py "$@"
|
@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
runtime\bin\python\python_mcp runtime\reformat.py %*
|
||||
pause
|
@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
python runtime/reformat.py "$@"
|
@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
runtime\bin\python\python_mcp runtime\reobfuscate.py %*
|
||||
pause
|
@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
python runtime/reobfuscate.py "$@"
|
@ -0,0 +1 @@
|
||||
#
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,83 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Sat Apr 9 13:51:48 2011
|
||||
|
||||
@author: ProfMobius & Searge
|
||||
@version: v1.0
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import glob
|
||||
import logging
|
||||
from optparse import OptionParser
|
||||
|
||||
from commands import Commands, reallyrmtree
|
||||
|
||||
|
||||
def main():
|
||||
parser = OptionParser(version='MCP %s' % Commands.fullversion())
|
||||
parser.add_option('-f', '--force', action='store_true', dest='force', help='force cleanup', default=False)
|
||||
parser.add_option('-c', '--config', dest='config', help='additional configuration file')
|
||||
options, _ = parser.parse_args()
|
||||
cleanup(options.config, options.force)
|
||||
|
||||
|
||||
def cleanup(conffile, force):
|
||||
try:
|
||||
commands = Commands(conffile)
|
||||
|
||||
if not force:
|
||||
print 'WARNING:'
|
||||
print 'The cleanup script will delete all folders created by MCP, including the'
|
||||
print 'src folder which may contain changes you made to the code, along with any'
|
||||
print 'saved worlds from the client or server.'
|
||||
answer = raw_input('If you really want to clean up, enter "Yes" ')
|
||||
if answer.lower() not in ['yes']:
|
||||
print 'You have not entered "Yes", aborting the clean up process'
|
||||
sys.exit(1)
|
||||
|
||||
commands.checkupdates()
|
||||
|
||||
try:
|
||||
commands.logger.info('> Cleaning temp')
|
||||
reallyrmtree(commands.dirtemp)
|
||||
|
||||
commands.logger.info('> Cleaning src')
|
||||
reallyrmtree(commands.dirsrc)
|
||||
|
||||
commands.logger.info('> Cleaning bin')
|
||||
reallyrmtree(commands.dirbin)
|
||||
|
||||
commands.logger.info('> Cleaning reobf')
|
||||
reallyrmtree(commands.dirreobf)
|
||||
|
||||
commands.logger.info('> Cleaning lib')
|
||||
reallyrmtree(commands.dirlib)
|
||||
|
||||
commands.logger.info('> Cleaning jars')
|
||||
reallyrmtree(os.path.join(commands.dirjars, 'saves'))
|
||||
reallyrmtree(os.path.join(commands.dirjars, 'stats'))
|
||||
reallyrmtree(os.path.join(commands.dirjars, 'texturepacks'))
|
||||
reallyrmtree(os.path.join(commands.dirjars, 'texturepacks-mp-cache'))
|
||||
reallyrmtree(os.path.join(commands.dirjars, 'mcpworld'))
|
||||
if os.path.exists(os.path.join(commands.dirjars, 'server.log')):
|
||||
os.remove(os.path.join(commands.dirjars, 'server.log'))
|
||||
for txt_file in glob.glob(os.path.join(commands.dirjars, '*.txt')):
|
||||
os.remove(txt_file)
|
||||
|
||||
commands.logger.info('> Cleaning logs')
|
||||
logging.shutdown()
|
||||
reallyrmtree(commands.dirlogs)
|
||||
except OSError as ex:
|
||||
print >> sys.stderr, 'Cleanup FAILED'
|
||||
if hasattr(ex, 'filename'):
|
||||
print >> sys.stderr, 'Failed to remove ' + ex.filename
|
||||
sys.exit(1)
|
||||
except Exception: # pylint: disable-msg=W0703
|
||||
logging.exception('FATAL ERROR')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -0,0 +1,132 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Fri Apr 8 16:54:36 2011
|
||||
|
||||
@author: ProfMobius
|
||||
@version: v1.2
|
||||
"""
|
||||
|
||||
import sys
|
||||
import logging
|
||||
from optparse import OptionParser
|
||||
|
||||
from commands import Commands, CLIENT, SERVER, CalledProcessError
|
||||
from mcp import decompile_side, updatemd5_side
|
||||
|
||||
|
||||
def main():
|
||||
parser = OptionParser(version='MCP %s' % Commands.fullversion())
|
||||
parser.add_option('-j', '--jad', dest='force_jad', action='store_true',
|
||||
help='force use of JAD even if Fernflower available', default=False)
|
||||
parser.add_option('-s', '--csv', dest='force_csv', action='store_true',
|
||||
help='force use of CSVs even if SRGs available', default=False)
|
||||
parser.add_option('-r', '--norecompile', dest='no_recompile', action='store_true',
|
||||
help='disable recompile after decompile', default=False)
|
||||
parser.add_option('-d', '--nocomments', dest='no_comments', action='store_true', help='disable javadoc',
|
||||
default=False)
|
||||
parser.add_option('-a', '--noreformat', dest='no_reformat', action='store_true',
|
||||
help='disable source reformatting', default=False)
|
||||
parser.add_option('-n', '--norenamer', dest='no_renamer', action='store_true',
|
||||
help='disable field and method renaming', default=False)
|
||||
parser.add_option('-l', '--lvt', dest='keep_lvt', action='store_true', help='preserve local variable table',
|
||||
default=False)
|
||||
parser.add_option('-g', '--generics', dest='keep_generics', action='store_true',
|
||||
help='preserve generics as well as local variables', default=False)
|
||||
parser.add_option('-o', '--onlypatch', dest='only_patch', action='store_true', help='only patch source',
|
||||
default=False)
|
||||
parser.add_option('-p', dest='no_patch', action='store_true', help='Undocumented magic', default=False)
|
||||
parser.add_option('-c', '--config', dest='config', help='additional configuration file')
|
||||
options, _ = parser.parse_args()
|
||||
decompile(options.config, options.force_jad, options.force_csv, options.no_recompile, options.no_comments,
|
||||
options.no_reformat, options.no_renamer, options.no_patch, options.only_patch, options.keep_lvt,
|
||||
options.keep_generics)
|
||||
|
||||
|
||||
def decompile(conffile, force_jad, force_csv, no_recompile, no_comments, no_reformat, no_renamer, no_patch, only_patch,
|
||||
keep_lvt, keep_generics):
|
||||
try:
|
||||
commands = Commands(conffile, verify=True, no_patch=no_patch)
|
||||
|
||||
commands.checkupdates()
|
||||
|
||||
use_ff = commands.has_ff and not force_jad
|
||||
use_srg = commands.has_srg and not force_csv
|
||||
|
||||
if force_jad and not commands.has_jad:
|
||||
commands.logger.error('!! forcing jad when not available !!')
|
||||
sys.exit(1)
|
||||
|
||||
if force_csv and not commands.has_map_csv:
|
||||
commands.logger.error('!! forcing csvs when not available !!')
|
||||
sys.exit(1)
|
||||
|
||||
# always strip comments by default, turn off in update mode if required
|
||||
strip_comments = True
|
||||
|
||||
# update only options
|
||||
rg_update = False
|
||||
exc_update = False
|
||||
|
||||
if no_patch:
|
||||
# no_patch is basically update mode, disables everything
|
||||
# and reuses a few different options to do update stuff
|
||||
if only_patch:
|
||||
# with only_patch then we actually do the patches, but not the comment stripping, for use when updating
|
||||
# the fernflower patches
|
||||
no_patch = False
|
||||
strip_comments = False
|
||||
if no_reformat:
|
||||
# reuse -a no_reformat to switch rg to fullmap=1 startindex=RGIndex
|
||||
rg_update = True
|
||||
if no_renamer:
|
||||
# reuse -n to switch mcinjector to outputing exc file, and adding new parameters
|
||||
exc_update = True
|
||||
no_comments = True
|
||||
no_reformat = True
|
||||
no_renamer = True
|
||||
no_recompile = True
|
||||
elif only_patch:
|
||||
# if only_patch then disable everything but patching and comment stripping
|
||||
no_comments = True
|
||||
no_reformat = True
|
||||
no_renamer = True
|
||||
no_recompile = True
|
||||
|
||||
# if we have generics enabled we need the lvt as well
|
||||
if keep_generics:
|
||||
keep_lvt = True
|
||||
|
||||
commands.logger.info('> Creating Retroguard config files')
|
||||
commands.creatergcfg(reobf=False, keep_lvt=keep_lvt, keep_generics=keep_generics, rg_update=rg_update)
|
||||
|
||||
try:
|
||||
cltdecomp = decompile_side(commands, CLIENT, use_ff=use_ff, use_srg=use_srg, no_comments=no_comments,
|
||||
no_reformat=no_reformat, no_renamer=no_renamer, no_patch=no_patch,
|
||||
strip_comments=strip_comments, exc_update=exc_update)
|
||||
srvdecomp = decompile_side(commands, SERVER, use_ff=use_ff, use_srg=use_srg, no_comments=no_comments,
|
||||
no_reformat=no_reformat, no_renamer=no_renamer, no_patch=no_patch,
|
||||
strip_comments=strip_comments, exc_update=exc_update)
|
||||
except CalledProcessError:
|
||||
# retroguard or other called process error so bail
|
||||
commands.logger.error('Decompile failed')
|
||||
sys.exit(1)
|
||||
if not no_recompile:
|
||||
if cltdecomp:
|
||||
try:
|
||||
updatemd5_side(commands, CLIENT)
|
||||
except CalledProcessError:
|
||||
commands.logger.error('Initial client recompile failed, correct source then run updatemd5')
|
||||
if srvdecomp:
|
||||
try:
|
||||
updatemd5_side(commands, SERVER)
|
||||
except CalledProcessError:
|
||||
commands.logger.error('Initial server recompile failed, correct source then run updatemd5')
|
||||
else:
|
||||
commands.logger.info('!! recompile disabled !!')
|
||||
except Exception: # pylint: disable-msg=W0703
|
||||
logging.exception('FATAL ERROR')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1 @@
|
||||
#
|
Binary file not shown.
@ -0,0 +1,92 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Fri Apr 8 13:44:42 2011
|
||||
|
||||
@author: ProfMobius
|
||||
@version: 0.1
|
||||
"""
|
||||
|
||||
import csv
|
||||
|
||||
import srgshandler
|
||||
|
||||
|
||||
CLIENT = 0
|
||||
SERVER = 1
|
||||
|
||||
|
||||
def writesrgsfromcsvs(csvclass, csvmethods, csvfields, outsrgs, side, ignore_classes=None):
|
||||
"""Reads 3 CSVs and output a srgs"""
|
||||
|
||||
if ignore_classes is None:
|
||||
ignore_classes = []
|
||||
|
||||
packages = []
|
||||
classes = []
|
||||
methods = []
|
||||
fields = []
|
||||
|
||||
# HINT: We are adding the package conversions
|
||||
packages.append(['.', 'net/minecraft/src'])
|
||||
packages.append(['net', 'net'])
|
||||
packages.append(['net/minecraft', 'net/minecraft'])
|
||||
if side == CLIENT:
|
||||
packages.append(['net/minecraft/client', 'net/minecraft/client'])
|
||||
packages.append(['net/minecraft/isom', 'net/minecraft/isom'])
|
||||
elif side == SERVER:
|
||||
packages.append(['net/minecraft/server', 'net/minecraft/server'])
|
||||
else:
|
||||
raise Exception("Side not recognized : %d" % side)
|
||||
|
||||
# HINT: We append the class elements. We also handle the special case of Minecraft, MinecraftApplet, MinecraftServer
|
||||
with open(csvclass, 'rb') as fh:
|
||||
csvreader = csv.DictReader(fh)
|
||||
for row in csvreader:
|
||||
if int(row['side']) == side:
|
||||
# HINT : Those checks are here to append the proper packages to notch version of the Minecraft, etc.
|
||||
# They are needed since we don't have notch package information (lost during recompilation)
|
||||
# The skip on start is there because of a quirk of the bot updating process
|
||||
# We use recompiled sources, so the bot catches the Start.class which have been added by Searge.
|
||||
if row['notch'] in ['Minecraft', 'MinecraftApplet']:
|
||||
row['notch'] = 'net/minecraft/client/%s' % row['notch']
|
||||
if row['notch'] in ['IsomPreviewApplet']:
|
||||
row['notch'] = 'net/minecraft/isom/%s' % row['notch']
|
||||
if row['notch'] in ['MinecraftServer']:
|
||||
row['notch'] = 'net/minecraft/server/%s' % row['notch']
|
||||
if row['name'] in ignore_classes:
|
||||
continue
|
||||
classes.append([row['notch'], '%s/%s' % (row['package'], row['name'])])
|
||||
|
||||
# HINT: We append the method elements
|
||||
with open(csvmethods, 'rb') as fh:
|
||||
csvreader = csv.DictReader(fh)
|
||||
for row in csvreader:
|
||||
if int(row['side']) == side:
|
||||
if row['classnotch'] in ['Minecraft', 'MinecraftApplet']:
|
||||
row['classnotch'] = 'net/minecraft/client/%s' % row['classnotch']
|
||||
if row['classnotch'] in ['IsomPreviewApplet']:
|
||||
row['classnotch'] = 'net/minecraft/isom/%s' % row['classnotch']
|
||||
if row['classnotch'] in ['MinecraftServer']:
|
||||
row['classnotch'] = 'net/minecraft/server/%s' % row['classnotch']
|
||||
if row['classname'] in ignore_classes:
|
||||
continue
|
||||
methods.append(['%s/%s %s' % (row['classnotch'], row['notch'], row['notchsig']),
|
||||
'%s/%s/%s %s' % (row['package'], row['classname'], row['searge'], row['sig'])])
|
||||
|
||||
# HINT: We append the field elements
|
||||
with open(csvfields, 'rb') as fh:
|
||||
csvreader = csv.DictReader(fh)
|
||||
for row in csvreader:
|
||||
if int(row['side']) == side:
|
||||
if row['classnotch'] in ['Minecraft', 'MinecraftApplet']:
|
||||
row['classnotch'] = 'net/minecraft/client/%s' % row['classnotch']
|
||||
if row['classnotch'] in ['IsomPreviewApplet']:
|
||||
row['classnotch'] = 'net/minecraft/isom/%s' % row['classnotch']
|
||||
if row['classnotch'] in ['MinecraftServer']:
|
||||
row['classnotch'] = 'net/minecraft/server/%s' % row['classnotch']
|
||||
if row['classname'] in ignore_classes:
|
||||
continue
|
||||
fields.append(['%s/%s' % (row['classnotch'], row['notch']),
|
||||
'%s/%s/%s' % (row['package'], row['classname'], row['searge'])])
|
||||
|
||||
srgshandler.writesrgs(outsrgs, {'PK': packages, 'CL': classes, 'FD': fields, 'MD': methods})
|
Binary file not shown.
@ -0,0 +1,43 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Fri Apr 8 12:50:02 2011
|
||||
|
||||
@author: ProfMobius
|
||||
@version : v0.1
|
||||
"""
|
||||
|
||||
|
||||
def parse_srg(srg_filename):
|
||||
"""Reads a SeargeRG file and returns a dictionary of lists for packages, classes, methods and fields"""
|
||||
srg_types = {'PK:': ['obf_name', 'deobf_name'],
|
||||
'CL:': ['obf_name', 'deobf_name'],
|
||||
'FD:': ['obf_name', 'deobf_name'],
|
||||
'MD:': ['obf_name', 'obf_desc', 'deobf_name', 'deobf_desc']}
|
||||
parsed_dict = {'PK': [],
|
||||
'CL': [],
|
||||
'FD': [],
|
||||
'MD': []}
|
||||
|
||||
def get_parsed_line(keyword, buf):
|
||||
return dict(zip(srg_types[keyword], [i.strip() for i in buf]))
|
||||
|
||||
with open(srg_filename, 'r') as srg_file:
|
||||
for buf in srg_file:
|
||||
buf = buf.strip()
|
||||
if buf == '' or buf[0] == '#':
|
||||
continue
|
||||
buf = buf.split()
|
||||
parsed_dict[buf[0][:2]].append(get_parsed_line(buf[0], buf[1:]))
|
||||
return parsed_dict
|
||||
|
||||
|
||||
def writesrgs(filename, data):
|
||||
"""Writes a srgs file based on data. Data is formatted similar to the output of readsrgs (dict of lists)"""
|
||||
if not 'PK' in data or not 'CL' in data or not 'FD' in data or not 'MD' in data:
|
||||
raise Exception("Malformed data for writesrgs. Keys should be in ['PK', 'CL', 'FD', 'MD']")
|
||||
|
||||
with open(filename, 'w') as srgsout:
|
||||
# HINT: We write all the entries for a given key in order
|
||||
for key in ['PK', 'CL', 'FD', 'MD']:
|
||||
for entry in data[key]:
|
||||
srgsout.write('%s: %s %s\n' % (key, entry[0], entry[1]))
|
Binary file not shown.
@ -0,0 +1,35 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Mon Oct 3 02:10:23 2011
|
||||
|
||||
@author: IxxI
|
||||
@version: v1.0
|
||||
"""
|
||||
|
||||
import sys
|
||||
import logging
|
||||
from optparse import OptionParser
|
||||
|
||||
from commands import Commands, CLIENT, SERVER
|
||||
from mcp import getchangedsrc_side
|
||||
|
||||
|
||||
def main():
|
||||
parser = OptionParser(version='MCP %s' % Commands.fullversion())
|
||||
parser.add_option('-c', '--config', dest='config', help='additional configuration file')
|
||||
options, _ = parser.parse_args()
|
||||
getchangedsrc(options.config)
|
||||
|
||||
|
||||
def getchangedsrc(conffile):
|
||||
try:
|
||||
commands = Commands(conffile)
|
||||
|
||||
getchangedsrc_side(commands, CLIENT)
|
||||
getchangedsrc_side(commands, SERVER)
|
||||
except Exception: # pylint: disable-msg=W0703
|
||||
logging.exception('FATAL ERROR')
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,189 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Thu Jan 19 15:04:52 2012
|
||||
|
||||
@author: Fesh0r
|
||||
@version: v1.0
|
||||
"""
|
||||
|
||||
import time
|
||||
|
||||
from commands import CLIENT, SIDE_NAME
|
||||
|
||||
|
||||
def decompile_side(commands, side, use_ff=False, use_srg=False, no_comments=False, no_reformat=False, no_renamer=False,
|
||||
no_patch=False, strip_comments=True, exc_update=False):
|
||||
if not commands.checkjars(side):
|
||||
commands.logger.warning('!! Missing %s jar file. Aborting !!', SIDE_NAME[side])
|
||||
return False
|
||||
if commands.checksourcedir(side):
|
||||
commands.logger.warning('!! %s already decompiled. Run cleanup before decompiling again !!', SIDE_NAME[side])
|
||||
return False
|
||||
starttime = time.time()
|
||||
decompiler = 'JAD'
|
||||
if use_ff:
|
||||
decompiler = 'fernflower'
|
||||
commands.logger.info('== Decompiling %s using %s ==', SIDE_NAME[side], decompiler)
|
||||
commands.logger.info('> Creating SRGs')
|
||||
commands.createsrgs(side, use_srg=use_srg)
|
||||
commands.logger.info('> Applying Retroguard')
|
||||
commands.applyrg(side)
|
||||
commands.logger.info('> Applying MCInjector')
|
||||
commands.applyexceptor(side, exc_update=exc_update)
|
||||
commands.logger.info('> Unpacking jar')
|
||||
commands.extractjar(side)
|
||||
commands.logger.info('> Copying classes')
|
||||
commands.copycls(side)
|
||||
if use_ff:
|
||||
commands.logger.info('> Decompiling')
|
||||
commands.applyff(side)
|
||||
else:
|
||||
commands.logger.info('> Applying jadretro')
|
||||
commands.applyjadretro(side)
|
||||
commands.logger.info('> Decompiling')
|
||||
commands.applyjad(side)
|
||||
commands.logger.info('> Copying sources')
|
||||
commands.copysrc(side)
|
||||
if use_ff:
|
||||
commands.logger.info('> Applying fernflower fixes')
|
||||
commands.process_fffixes(side)
|
||||
else:
|
||||
commands.logger.info('> Applying JAD fixes')
|
||||
commands.process_jadfixes(side)
|
||||
if commands.osname == 'osx' and not no_patch:
|
||||
commands.logger.info('> Applying OSX JAD fixes')
|
||||
commands.applypatches(side, use_ff=False, use_osx=True)
|
||||
if not no_patch:
|
||||
commands.logger.info('> Applying patches')
|
||||
commands.applypatches(side, use_ff=use_ff)
|
||||
if strip_comments:
|
||||
commands.logger.info('> Cleaning comments')
|
||||
commands.process_comments(side)
|
||||
else:
|
||||
commands.logger.warning('!! comment cleaning disabled !!')
|
||||
else:
|
||||
commands.logger.warning('!! patches disabled !!')
|
||||
commands.logger.info('- Done in %.2f seconds', time.time() - starttime)
|
||||
if not no_reformat:
|
||||
reformat_side(commands, side)
|
||||
else:
|
||||
commands.logger.warning('!! reformating disabled !!')
|
||||
if not no_renamer:
|
||||
updatenames_side(commands, side, no_comments=no_comments)
|
||||
else:
|
||||
commands.logger.warning('!! renaming disabled !!')
|
||||
return True
|
||||
|
||||
|
||||
def reformat_side(commands, side):
|
||||
if not commands.checksourcedir(side):
|
||||
return False
|
||||
starttime = time.time()
|
||||
commands.logger.info('== Reformating %s ==', SIDE_NAME[side])
|
||||
commands.logger.info('> Cleaning sources')
|
||||
commands.process_cleanup(side)
|
||||
if side == CLIENT:
|
||||
commands.logger.info('> Replacing OpenGL constants')
|
||||
commands.process_annotate(side)
|
||||
if commands.has_astyle:
|
||||
commands.logger.info('> Reformating sources')
|
||||
commands.applyastyle(side)
|
||||
else:
|
||||
commands.logger.warning('!! reformating disabled due to no astyle or config !!')
|
||||
commands.logger.info('- Done in %.2f seconds', time.time() - starttime)
|
||||
return True
|
||||
|
||||
|
||||
def updatenames_side(commands, side, no_comments=False):
|
||||
if not commands.checksourcedir(side):
|
||||
return False
|
||||
starttime = time.time()
|
||||
commands.logger.info('== Updating %s ==', SIDE_NAME[side])
|
||||
if not no_comments:
|
||||
if commands.has_doc_csv:
|
||||
commands.logger.info('> Adding javadoc')
|
||||
commands.process_javadoc(side)
|
||||
else:
|
||||
commands.logger.warning('!! javadoc disabled due to no csvs !!')
|
||||
else:
|
||||
commands.logger.warning('!! javadoc disabled !!')
|
||||
if commands.has_name_csv:
|
||||
commands.logger.info('> Renaming sources')
|
||||
commands.process_rename(side)
|
||||
else:
|
||||
commands.logger.warning('!! renaming disabled due to no csvs !!')
|
||||
commands.logger.info('- Done in %.2f seconds', time.time() - starttime)
|
||||
return True
|
||||
|
||||
|
||||
def recompile_side(commands, side):
|
||||
if not commands.checksources(side):
|
||||
commands.logger.warning('!! Can not find %s sources, try decompiling !!', SIDE_NAME[side])
|
||||
return False
|
||||
starttime = time.time()
|
||||
commands.logger.info('== Recompiling %s ==', SIDE_NAME[side])
|
||||
commands.logger.info('> Cleaning bin')
|
||||
commands.cleanbindirs(side)
|
||||
commands.logger.info('> Recompiling')
|
||||
commands.recompile(side)
|
||||
commands.logger.info('- Done in %.2f seconds', time.time() - starttime)
|
||||
return True
|
||||
|
||||
|
||||
def updatemd5_side(commands, side):
|
||||
recomp = recompile_side(commands, side)
|
||||
if recomp:
|
||||
commands.logger.info('> Generating %s md5s', SIDE_NAME[side])
|
||||
commands.gathermd5s(side)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def reobfuscate_side(commands, side, reobf_all=False):
|
||||
if not commands.checkmd5s(side):
|
||||
commands.logger.warning('!! Can not find %s md5s !!', SIDE_NAME[side])
|
||||
return False
|
||||
if not commands.checkbins(side):
|
||||
commands.logger.warning('!! Can not find %s bins, try recompiling !!', SIDE_NAME[side])
|
||||
return False
|
||||
starttime = time.time()
|
||||
commands.logger.info('== Reobfuscating %s ==', SIDE_NAME[side])
|
||||
commands.logger.info('> Cleaning reobf')
|
||||
commands.cleanreobfdir(side)
|
||||
commands.logger.info('> Generating md5s')
|
||||
commands.gathermd5s(side, True)
|
||||
commands.logger.info('> Packing jar')
|
||||
commands.packbin(side)
|
||||
commands.logger.info('> Reobfuscating jar')
|
||||
commands.applyrg(side, True)
|
||||
commands.logger.info('> Extracting modified classes')
|
||||
commands.unpackreobfclasses(side, reobf_all)
|
||||
commands.logger.info('- Done in %.2f seconds', time.time() - starttime)
|
||||
return True
|
||||
|
||||
|
||||
def getchangedsrc_side(commands, side):
|
||||
if not commands.checkmd5s(side):
|
||||
commands.logger.warning('!! Can not find %s md5s !!', SIDE_NAME[side])
|
||||
return False
|
||||
if not commands.checksources(side):
|
||||
commands.logger.warning('!! Can not find %s sources !!', SIDE_NAME[side])
|
||||
return False
|
||||
commands.logger.info('> Getting changed %s source', SIDE_NAME[side])
|
||||
commands.gathermd5s(side, True)
|
||||
commands.unpackmodifiedclasses(side)
|
||||
return True
|
||||
|
||||
|
||||
def updateids_side(commands, side, no_comments=False):
|
||||
if not commands.checksourcedir(side):
|
||||
return False
|
||||
starttime = time.time()
|
||||
commands.logger.info('== Updating %s ==', SIDE_NAME[side])
|
||||
if commands.has_renumber_csv:
|
||||
commands.logger.info('> Renumbering sources')
|
||||
commands.process_renumber(side)
|
||||
else:
|
||||
commands.logger.warning('!! renumbering disabled due to no csvs !!')
|
||||
commands.logger.info('- Done in %.2f seconds', time.time() - starttime)
|
||||
return True
|
Binary file not shown.
@ -0,0 +1 @@
|
||||
#
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -0,0 +1,296 @@
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import fnmatch
|
||||
import shutil
|
||||
from optparse import OptionParser
|
||||
|
||||
|
||||
def strip_comments(src_dir):
|
||||
"""Removes all C/C++/Java-style comments from files"""
|
||||
|
||||
regexps = {
|
||||
# Remove C and C++ style comments
|
||||
'comments': re.compile(r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
|
||||
re.MULTILINE | re.DOTALL),
|
||||
|
||||
# Remove trailing whitespace
|
||||
'trailing': re.compile(r'[ \t]+$', re.MULTILINE),
|
||||
|
||||
# Remove repeated blank lines
|
||||
'newlines': re.compile(r'^\n{2,}', re.MULTILINE),
|
||||
}
|
||||
|
||||
def comment_replacer(match):
|
||||
part = match.group(0)
|
||||
if part.startswith('/'):
|
||||
return ''
|
||||
else:
|
||||
return part
|
||||
|
||||
for path, _, filelist in os.walk(src_dir, followlinks=True):
|
||||
for cur_file in fnmatch.filter(filelist, '*.java'):
|
||||
src_file = os.path.normpath(os.path.join(path, cur_file))
|
||||
tmp_file = src_file + '.tmp'
|
||||
with open(src_file, 'r') as fh:
|
||||
buf = fh.read()
|
||||
|
||||
buf = regexps['comments'].sub(comment_replacer, buf)
|
||||
buf = regexps['trailing'].sub(r'', buf)
|
||||
buf = regexps['newlines'].sub(r'\n', buf)
|
||||
|
||||
with open(tmp_file, 'w') as fh:
|
||||
fh.write(buf)
|
||||
shutil.move(tmp_file, src_file)
|
||||
|
||||
|
||||
def src_cleanup(src_dir, fix_imports=True, fix_unicode=False, fix_charval=False, fix_pi=False, fix_round=False):
|
||||
"""Do lots of random cleanups including stripping comments, trailing whitespace and extra blank lines"""
|
||||
|
||||
regexps = {
|
||||
# Remove extra whitespace at start of file
|
||||
'header': re.compile(r'^\s+'),
|
||||
|
||||
# Remove extra whitespace at end of file
|
||||
'footer': re.compile(r'\s+$'),
|
||||
|
||||
# Remove trailing whitespace
|
||||
'trailing': re.compile(r'[ \t]+$', re.MULTILINE),
|
||||
|
||||
# find package
|
||||
'package': re.compile(r'^package (?P<package>[\w.]+);$', re.MULTILINE),
|
||||
|
||||
# find imports
|
||||
'import': re.compile(r'^import (?:(?P<package>[\w.]*?)\.)?(?P<class>[\w]+);\n', re.MULTILINE),
|
||||
|
||||
# Remove repeated blank lines
|
||||
'newlines': re.compile(r'^\n{2,}', re.MULTILINE),
|
||||
|
||||
# close up blanks in code like:
|
||||
# {
|
||||
#
|
||||
# private
|
||||
'blockstarts': re.compile(r'(?<={)\s+(?=\n[ \t]*\S)', re.MULTILINE),
|
||||
|
||||
# close up blanks in code like:
|
||||
# }
|
||||
#
|
||||
# }
|
||||
'blockends': re.compile(r'(?<=[;}])\s+(?=\n\s*})', re.MULTILINE),
|
||||
|
||||
# Remove GL comments and surrounding whitespace
|
||||
'gl': re.compile(r'\s*/\*\s*GL_[^*]+\*/\s*'),
|
||||
|
||||
# convert unicode character constants back to integers
|
||||
'unicode': re.compile(r"'\\u([0-9a-fA-F]{4})'"),
|
||||
|
||||
# strip out Character.valueof
|
||||
'charval': re.compile(r"Character\.valueOf\(('.')\)"),
|
||||
|
||||
# 1.7976...E+308D to Double.MAX_VALUE
|
||||
'maxD': re.compile(r'1\.7976[0-9]*[Ee]\+308[Dd]'),
|
||||
|
||||
# 3.1415...D to Math.PI
|
||||
'piD': re.compile(r'3\.1415[0-9]*[Dd]'),
|
||||
|
||||
# 3.1415...F to (float)Math.PI
|
||||
'piF': re.compile(r'3\.1415[0-9]*[Ff]'),
|
||||
|
||||
# 6.2831...D to (Math.PI * 2D)
|
||||
'2piD': re.compile(r'6\.2831[0-9]*[Dd]'),
|
||||
|
||||
# 6.2831...F to ((float)Math.PI * 2F)
|
||||
'2piF': re.compile(r'6\.2831[0-9]*[Ff]'),
|
||||
|
||||
# 1.5707...D to (Math.PI / 2D)
|
||||
'pi2D': re.compile(r'1\.5707[0-9]*[Dd]'),
|
||||
|
||||
# 1.5707...F to ((float)Math.PI / 2F)
|
||||
'pi2F': re.compile(r'1\.5707[0-9]*[Ff]'),
|
||||
|
||||
# 4.7123...D to (Math.PI * 3D / 2D)
|
||||
'3pi2D': re.compile(r'4\.7123[0-9]*[Dd]'),
|
||||
|
||||
# 4.7123...F to ((float)Math.PI * 3F / 2F)
|
||||
'3pi2F': re.compile(r'4\.7123[0-9]*[Ff]'),
|
||||
|
||||
# 0.7853...D to (Math.PI / 4D)
|
||||
'pi4D': re.compile(r'0\.7853[0-9]*[Dd]'),
|
||||
|
||||
# 0.7853...F to ((float)Math.PI / 4F)
|
||||
'pi4F': re.compile(r'0\.7853[0-9]*[Ff]'),
|
||||
|
||||
# 0.6283...D to (Math.PI / 5D)
|
||||
'pi5D': re.compile(r'0\.6283[0-9]*[Dd]'),
|
||||
|
||||
# 0.6283...F to ((float)Math.PI / 5F)
|
||||
'pi5F': re.compile(r'0\.6283[0-9]*[Ff]'),
|
||||
|
||||
# 57.295...D to (180D / Math.PI)
|
||||
'180piD': re.compile(r'57\.295[0-9]*[Dd]'),
|
||||
|
||||
# 57.295...F to (180F / (float)Math.PI)
|
||||
'180piF': re.compile(r'57\.295[0-9]*[Ff]'),
|
||||
|
||||
# 0.6981...D to (Math.PI * 2D / 9D)
|
||||
'2pi9D': re.compile(r'0\.6981[0-9]*[Dd]'),
|
||||
|
||||
# 0.6981...F to ((float)Math.PI * 2F / 9F)
|
||||
'2pi9F': re.compile(r'0\.6981[0-9]*[Ff]'),
|
||||
|
||||
# 0.3141...D to (Math.PI / 10D)
|
||||
'pi10D': re.compile(r'0\.3141[0-9]*[Dd]'),
|
||||
|
||||
# 0.3141...F to ((float)Math.PI / 10F)
|
||||
'pi10F': re.compile(r'0\.3141[0-9]*[Ff]'),
|
||||
|
||||
# 1.2566...D to (Math.PI * 2D / 5D)
|
||||
'2pi5D': re.compile(r'1\.2566[0-9]*[Dd]'),
|
||||
|
||||
# 1.2566...F to ((float)Math.PI 2F / 5F)
|
||||
'2pi5F': re.compile(r'1\.2566[0-9]*[Ff]'),
|
||||
|
||||
# 0.21991...D to (Math.PI * 7D / 100D)
|
||||
'7pi100D': re.compile(r'0\.21991[0-9]*[Dd]'),
|
||||
|
||||
# 0.21991...F to ((float)Math.PI * 7F / 100F)
|
||||
'7pi100F': re.compile(r'0\.21991[0-9]*[Ff]'),
|
||||
|
||||
# 5.8119...D to (Math.PI * 185D / 100D)
|
||||
'185pi100D': re.compile(r'5\.8119[0-9]*[Dd]'),
|
||||
|
||||
# 5.8119...F to ((float)Math.PI * 185F / 100F)
|
||||
'185pi100F': re.compile(r'0\.8119[0-9]*[Ff]'),
|
||||
|
||||
# 1.230000... to 1.23
|
||||
'rounddown': re.compile(r'(?P<full>[0-9]+\.(?P<decimal>[0-9]+?)00000000[0-9]*)(?P<type>[Dd])'),
|
||||
|
||||
# 1.239999... to 1.24
|
||||
'roundup': re.compile(r'(?P<full>[0-9]+\.(?P<decimal>[0-9]+?9)9999999[0-9]*)(?P<type>[Dd])'),
|
||||
}
|
||||
|
||||
def unicode_replacer(match):
|
||||
value = int(match.group(1), 16)
|
||||
# work around the replace('\u00a7', '$') call in MinecraftServer and a couple of '\u0000'
|
||||
if value > 255:
|
||||
return str(value)
|
||||
return match.group(0)
|
||||
|
||||
def rounddown_match(match):
|
||||
# hackaround for GL11.glScalef(1.000001F, 1.000001F, 1.000001F) in WorldRenderer
|
||||
if match.group(0) == '1.000001F':
|
||||
return match.group(0)
|
||||
val = float(match.group('full'))
|
||||
return '%.*f%s' % (len(match.group('decimal')), val, match.group('type'))
|
||||
|
||||
def roundup_match(match):
|
||||
val = float(match.group('full'))
|
||||
return '%.*f%s' % (len(match.group('decimal')) - 1, val, match.group('type'))
|
||||
|
||||
# HINT: We pathwalk the sources
|
||||
for path, _, filelist in os.walk(src_dir, followlinks=True):
|
||||
for cur_file in fnmatch.filter(filelist, '*.java'):
|
||||
src_file = os.path.normpath(os.path.join(path, cur_file))
|
||||
tmp_file = src_file + '.tmp'
|
||||
with open(src_file, 'r') as fh:
|
||||
buf = fh.read()
|
||||
|
||||
if fix_imports:
|
||||
# find the package for the current class
|
||||
match = regexps['package'].search(buf)
|
||||
if match:
|
||||
package = match.group('package')
|
||||
|
||||
# if the import is for the same package as current class then delete it
|
||||
def import_match(match):
|
||||
if match.group('package') != package:
|
||||
return match.group(0)
|
||||
return ''
|
||||
buf = regexps['import'].sub(import_match, buf)
|
||||
|
||||
buf = regexps['header'].sub(r'', buf)
|
||||
buf = regexps['footer'].sub(r'\n', buf)
|
||||
buf = regexps['trailing'].sub(r'', buf)
|
||||
buf = regexps['newlines'].sub(r'\n', buf)
|
||||
buf = regexps['blockstarts'].sub(r'', buf)
|
||||
buf = regexps['blockends'].sub(r'', buf)
|
||||
buf = regexps['gl'].sub(r'', buf)
|
||||
buf = regexps['maxD'].sub(r'Double.MAX_VALUE', buf)
|
||||
if fix_unicode:
|
||||
buf = regexps['unicode'].sub(unicode_replacer, buf)
|
||||
if fix_charval:
|
||||
buf = regexps['charval'].sub(r'\1', buf)
|
||||
|
||||
if fix_pi:
|
||||
buf = regexps['piD'].sub(r'Math.PI', buf)
|
||||
buf = regexps['piF'].sub(r'(float)Math.PI', buf)
|
||||
buf = regexps['2piD'].sub(r'(Math.PI * 2D)', buf)
|
||||
buf = regexps['2piF'].sub(r'((float)Math.PI * 2F)', buf)
|
||||
buf = regexps['pi2D'].sub(r'(Math.PI / 2D)', buf)
|
||||
buf = regexps['pi2F'].sub(r'((float)Math.PI / 2F)', buf)
|
||||
buf = regexps['3pi2D'].sub(r'(Math.PI * 3D / 2D)', buf)
|
||||
buf = regexps['3pi2F'].sub(r'((float)Math.PI * 3F / 2F)', buf)
|
||||
buf = regexps['pi4D'].sub(r'(Math.PI / 4D)', buf)
|
||||
buf = regexps['pi4F'].sub(r'((float)Math.PI / 4F)', buf)
|
||||
buf = regexps['pi5D'].sub(r'(Math.PI / 5D)', buf)
|
||||
buf = regexps['pi5F'].sub(r'((float)Math.PI / 5F)', buf)
|
||||
buf = regexps['180piD'].sub(r'(180D / Math.PI)', buf)
|
||||
buf = regexps['180piF'].sub(r'(180F / (float)Math.PI)', buf)
|
||||
buf = regexps['2pi9D'].sub(r'(Math.PI * 2D / 9D)', buf)
|
||||
buf = regexps['2pi9F'].sub(r'((float)Math.PI * 2F / 9F)', buf)
|
||||
buf = regexps['pi10D'].sub(r'(Math.PI / 10D)', buf)
|
||||
buf = regexps['pi10F'].sub(r'((float)Math.PI / 10F)', buf)
|
||||
buf = regexps['2pi5D'].sub(r'(Math.PI * 2D / 5D)', buf)
|
||||
buf = regexps['2pi5F'].sub(r'((float)Math.PI * 2F / 5F)', buf)
|
||||
buf = regexps['7pi100D'].sub(r'(Math.PI * 7D / 100D)', buf)
|
||||
buf = regexps['7pi100F'].sub(r'((float)Math.PI * 7F / 100F)', buf)
|
||||
buf = regexps['185pi100D'].sub(r'(Math.PI * 185D / 100D)', buf)
|
||||
buf = regexps['185pi100F'].sub(r'((float)Math.PI * 185F / 100F)', buf)
|
||||
|
||||
if fix_round:
|
||||
buf = regexps['rounddown'].sub(rounddown_match, buf)
|
||||
buf = regexps['roundup'].sub(roundup_match, buf)
|
||||
|
||||
with open(tmp_file, 'w') as fh:
|
||||
fh.write(buf)
|
||||
shutil.move(tmp_file, src_file)
|
||||
|
||||
|
||||
def cleanup_src(src_dir, clean_comments=True, clean_src=True, fix_imports=True, fix_unicode=False, fix_charval=False,
|
||||
fix_pi=False, fix_round=False):
|
||||
if clean_comments:
|
||||
strip_comments(src_dir)
|
||||
if clean_src:
|
||||
src_cleanup(src_dir, fix_imports=fix_imports, fix_unicode=fix_unicode, fix_charval=fix_charval, fix_pi=fix_pi,
|
||||
fix_round=fix_round)
|
||||
|
||||
|
||||
def main():
|
||||
usage = 'usage: %prog [options] src_dir'
|
||||
version = '%prog 6.0'
|
||||
parser = OptionParser(version=version, usage=usage)
|
||||
parser.add_option('-c', '--nocomment', action='store_false', dest='clean_comments', help="don't strip comments",
|
||||
default=True)
|
||||
parser.add_option('-s', '--nocleanup', action='store_false', dest='clean_src', help="don't cleanup source",
|
||||
default=True)
|
||||
parser.add_option('-i', '--imports', action='store_true', dest='fix_imports', help='cleanup unneeded imports',
|
||||
default=False)
|
||||
parser.add_option('-u', '--unicode', action='store_true', dest='fix_unicode',
|
||||
help='convert unicode character constant to integer', default=False)
|
||||
parser.add_option('-v', '--charval', action='store_true', dest='fix_charval',
|
||||
help='convert Character.valueof to constant', default=False)
|
||||
parser.add_option('-p', '--pi', action='store_true', dest='fix_pi',
|
||||
help='convert pi constants', default=False)
|
||||
parser.add_option('-r', '--round', action='store_true', dest='fix_round',
|
||||
help='round long float and double constants', default=False)
|
||||
options, args = parser.parse_args()
|
||||
if len(args) != 1:
|
||||
print >> sys.stderr, 'src_dir required'
|
||||
sys.exit(1)
|
||||
cleanup_src(args[0], clean_comments=options.clean_comments, clean_src=options.clean_src,
|
||||
fix_imports=options.fix_imports, fix_unicode=options.fix_unicode, fix_charval=options.fix_charval,
|
||||
fix_pi=options.fix_pi, fix_round=options.fix_round)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Binary file not shown.
@ -0,0 +1,173 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Thu Jan 19 16:29:03 2012
|
||||
|
||||
@author: Fesh0r
|
||||
@version: v0.1
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import fnmatch
|
||||
import shutil
|
||||
import re
|
||||
from optparse import OptionParser
|
||||
|
||||
|
||||
_MODIFIERS = r'public|protected|private|static|abstract|final|native|synchronized|transient|volatile|strictfp'
|
||||
|
||||
_REGEXP = {
|
||||
# Remove trailing whitespace
|
||||
'trailing': re.compile(r'[ \t]+$', re.MULTILINE),
|
||||
|
||||
# Remove repeated blank lines
|
||||
'newlines': re.compile(r'^\n{2,}', re.MULTILINE),
|
||||
|
||||
'modifiers': re.compile(r'(' + _MODIFIERS + ') '),
|
||||
'list': re.compile(r', '),
|
||||
|
||||
'enum_class': re.compile(r'^(?P<modifiers>(?:(?:' + _MODIFIERS + r') )*)(?P<type>enum) (?P<name>[\w$]+)(?: implements (?P<implements>[\w$.]+(?:, [\w$.]+)*))? \{\n(?P<body>(?:.*?\n)*?)(?P<end>\}\n+)', re.MULTILINE),
|
||||
|
||||
'enum_entries': re.compile(r'^ {3}(?P<name>[\w$]+)\("(?P=name)", [0-9]+(?:, (?P<body>.*?))?\)(?P<end>(?:;|,)\n+)', re.MULTILINE),
|
||||
|
||||
'empty_super': re.compile(r'^ +super\(\);\n', re.MULTILINE),
|
||||
|
||||
# strip trailing 0 from doubles and floats to fix decompile differences on OSX
|
||||
# 0.0010D => 0.001D
|
||||
'trailingzero': re.compile(r'(?P<value>[0-9]+\.[0-9]*[1-9])0+(?P<type>[DdFfEe])'),
|
||||
}
|
||||
|
||||
_REGEXP_STR = {
|
||||
'constructor': r'^ {3}(?P<modifiers>(?:(?:' + _MODIFIERS + r') )*)%s\((?P<parameters>.*?)\)(?: throws (?P<throws>[\w$.]+(?:, [\w$.]+)*))? \{(?:(?P<empty>\}\n+)|(?:(?P<body>\n(?:.*?\n)*?)(?P<end> {3}\}\n+)))',
|
||||
|
||||
'enum_values': r'^ {3}// \$FF: synthetic field\n {3}private static final %s\[\] [\w$]+ = new %s\[\]\{.*?\};\n',
|
||||
}
|
||||
|
||||
|
||||
class Error(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class ParseError(Error):
|
||||
pass
|
||||
|
||||
|
||||
def fffix(srcdir):
|
||||
for path, _, filelist in os.walk(srcdir, followlinks=True):
|
||||
for cur_file in fnmatch.filter(filelist, '*.java'):
|
||||
src_file = os.path.normpath(os.path.join(path, cur_file))
|
||||
_process_file(src_file)
|
||||
|
||||
|
||||
def _process_enum(class_name, class_type, modifiers, implements, body, end):
|
||||
def _enum_entries_match(match):
|
||||
entry_body = ''
|
||||
if match.group('body'):
|
||||
entry_body = '(' + match.group('body') + ')'
|
||||
new_entry = ' ' + match.group('name') + entry_body + match.group('end')
|
||||
return new_entry
|
||||
body = _REGEXP['enum_entries'].sub(_enum_entries_match, body)
|
||||
|
||||
values_regex = re.compile(_REGEXP_STR['enum_values'] % (re.escape(class_name), re.escape(class_name)), re.MULTILINE)
|
||||
body = values_regex.sub(r'', body)
|
||||
|
||||
# process constructors
|
||||
def constructor_match(match):
|
||||
modifiers = _REGEXP['modifiers'].findall(match.group('modifiers'))
|
||||
if match.group('modifiers') and not modifiers:
|
||||
raise ParseError('no modifiers match in %s \'%s\'' % (match.group('name'), match.group('modifiers')))
|
||||
parameters = []
|
||||
if match.group('parameters'):
|
||||
parameters = _REGEXP['list'].split(match.group('parameters'))
|
||||
throws = []
|
||||
if match.group('throws'):
|
||||
throws = _REGEXP['list'].split(match.group('throws'))
|
||||
if match.group('empty') is not None:
|
||||
method_body = ''
|
||||
method_end = match.group('empty')
|
||||
else:
|
||||
method_body = match.group('body')
|
||||
method_end = match.group('end')
|
||||
return _process_constructor(class_name, modifiers, parameters, throws, method_body, method_end)
|
||||
constructor_regex = re.compile(_REGEXP_STR['constructor'] % re.escape(class_name), re.MULTILINE)
|
||||
body = constructor_regex.sub(constructor_match, body)
|
||||
|
||||
# rebuild enum
|
||||
out = ''
|
||||
if modifiers:
|
||||
out += ' '.join(modifiers) + ' '
|
||||
out += class_type + ' ' + class_name
|
||||
if implements:
|
||||
out += ' implements ' + ', '.join(implements)
|
||||
out += ' {\n' + body + end
|
||||
return out
|
||||
|
||||
|
||||
def _process_constructor(class_name, modifiers, parameters, throws, body, end):
|
||||
if len(parameters) >= 2:
|
||||
if parameters[0].startswith('String ') and parameters[1].startswith('int '):
|
||||
parameters = parameters[2:]
|
||||
# empty constructor
|
||||
if body == '' and len(parameters) == 0:
|
||||
return ''
|
||||
else:
|
||||
raise ParseError('invalid initial parameters in enum %s: %s' % (class_name, str(parameters)))
|
||||
else:
|
||||
raise ParseError('not enough parameters in enum %s: %s' % (class_name, str(parameters)))
|
||||
|
||||
# rebuild constructor
|
||||
out = ' '
|
||||
if modifiers:
|
||||
out += ' '.join(modifiers) + ' '
|
||||
out += class_name + '(' + ', '.join(parameters) + ')'
|
||||
if throws:
|
||||
out += ' throws ' + ', '.join(throws)
|
||||
out += ' {' + body + end
|
||||
return out
|
||||
|
||||
|
||||
def _process_file(src_file):
|
||||
class_name = os.path.splitext(os.path.basename(src_file))[0]
|
||||
tmp_file = src_file + '.tmp'
|
||||
with open(src_file, 'r') as fh:
|
||||
buf = fh.read()
|
||||
|
||||
buf = _REGEXP['trailing'].sub(r'', buf)
|
||||
|
||||
def enum_match(match):
|
||||
if class_name != match.group('name'):
|
||||
raise ParseError("file name and class name differ: '%s' '%s" % (class_name, match.group('name')))
|
||||
modifiers = _REGEXP['modifiers'].findall(match.group('modifiers'))
|
||||
if match.group('modifiers') and not modifiers:
|
||||
raise ParseError("no modifiers match in %s '%s'" % (match.group('name'), match.group('modifiers')))
|
||||
implements = []
|
||||
if match.group('implements'):
|
||||
implements = _REGEXP['list'].split(match.group('implements'))
|
||||
return _process_enum(match.group('name'), match.group('type'), modifiers, implements, match.group('body'),
|
||||
match.group('end'))
|
||||
buf = _REGEXP['enum_class'].sub(enum_match, buf)
|
||||
|
||||
buf = _REGEXP['empty_super'].sub(r'', buf)
|
||||
|
||||
buf = _REGEXP['trailingzero'].sub(r'\g<value>\g<type>', buf)
|
||||
|
||||
buf = _REGEXP['newlines'].sub(r'\n', buf)
|
||||
|
||||
with open(tmp_file, 'w') as fh:
|
||||
fh.write(buf)
|
||||
shutil.move(tmp_file, src_file)
|
||||
|
||||
|
||||
def main():
|
||||
usage = 'usage: %prog [options] src_dir'
|
||||
version = '%prog 6.0'
|
||||
parser = OptionParser(version=version, usage=usage)
|
||||
options, args = parser.parse_args()
|
||||
if len(args) != 1:
|
||||
print >> sys.stderr, 'src_dir required'
|
||||
sys.exit(1)
|
||||
fffix(args[0])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Binary file not shown.
@ -0,0 +1,399 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Thu Jan 19 16:29:03 2012
|
||||
|
||||
@author: Fesh0r
|
||||
@version: v0.1
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import fnmatch
|
||||
import shutil
|
||||
import re
|
||||
from optparse import OptionParser
|
||||
|
||||
|
||||
_MODIFIERS = r'public|protected|private|static|abstract|final|native|synchronized|transient|volatile|strictfp'
|
||||
|
||||
_REGEXP = {
|
||||
# convert OSX double 1.23456789E-12D to Windows double 1.23456789E-012D
|
||||
'fltexp': re.compile(r'(?<=[Ee][+-])([0-9]{2})(?=[DdFf])'),
|
||||
|
||||
# Remove trailing whitespace
|
||||
'trailing': re.compile(r'[ \t]+$', re.MULTILINE),
|
||||
|
||||
# close up extends, and implements that JAD puts on a seperate line
|
||||
'extends': re.compile(r'$\n {4}(?=extends|implements)', re.MULTILINE),
|
||||
|
||||
# close up throws that JAD puts on a seperate line
|
||||
'throws': re.compile(r'$\n {8}(?=throws)', re.MULTILINE),
|
||||
|
||||
# close up method parameters that have wrapped
|
||||
'params': re.compile(r'^ {4}(?P<main>\S.*?)(?P<wrapped>(?:\n {12}\S.*?)+)(?P<suffix>(?:\n {4}\{$)|;)', re.MULTILINE),
|
||||
'params_sub': re.compile(r'\n {12}', re.MULTILINE),
|
||||
|
||||
# Remove repeated blank lines
|
||||
'newlines': re.compile(r'^\n{2,}', re.MULTILINE),
|
||||
|
||||
# Rename variables called enum
|
||||
'rename_enum': re.compile(r'(?<=\W)(enum)(?=\W)'),
|
||||
|
||||
'modifiers': re.compile(r'(' + _MODIFIERS + ') '),
|
||||
'list': re.compile(r', '),
|
||||
'deindent': re.compile(r'^ {4}(.*$)', re.MULTILINE),
|
||||
|
||||
# Class
|
||||
'class': re.compile(r'^(?P<modifiers>(?:(?:' + _MODIFIERS + r') )*)(?P<type>class|interface|enum) (?P<name>[\w$]+)(?: extends (?P<extends>[\w$.]+(?:, [\w$.]+)*))?(?: implements (?P<implements>[\w$.]+(?:, [\w$.]+)*))?\n\{\n(?P<body>(?:.*?\n)*?)(?P<end>\}\n+)', re.MULTILINE),
|
||||
|
||||
# method regex
|
||||
'method': re.compile(r'^ {4}(?P<modifiers>(?:(?:' + _MODIFIERS + r') )*)(?P<type>(?!' + _MODIFIERS + r')[\w$.[\]]+) (?P<name>[\w$]+)\((?P<parameters>.*?)\)(?: throws (?P<throws>[\w$.]+(?:, [\w$.]+)*))?\n {4}\{\n(?P<body>(?:.*?\n)*?)(?P<end> {4}\}\n+)', re.MULTILINE),
|
||||
|
||||
# abstract method regex
|
||||
'method_abstract': re.compile(r'^ {4}(?P<modifiers>(?:(?:' + _MODIFIERS + r') )*)(?P<type>(?!' + _MODIFIERS + r')[\w$.[\]]+) (?P<name>[\w$]+)\((?P<parameters>.*?)\)(?: throws (?P<throws>[\w$.]+(?:, [\w$.]+)*))?(?P<end>;\n+)', re.MULTILINE),
|
||||
|
||||
# move super call to start of method
|
||||
'fix_super': re.compile(r'(?P<before>(?:.*\n)*)(?P<super> {8}super\((?P<parameters>.*?)\);\n)(?P<after>(?:.*\n)*)', re.MULTILINE),
|
||||
|
||||
# remove super call in enum
|
||||
'enum_super': re.compile(r' {8}super\(\w+, \w+\);\n', re.MULTILINE),
|
||||
|
||||
# static block
|
||||
'static': re.compile(r'^ {4}static\n {4}\{\n(?P<body>(?:.*?\n)*?)(?P<end> {4}\}\n+)', re.MULTILINE),
|
||||
|
||||
# field_1234.field_5678 += abc + def;
|
||||
'str1': re.compile(r'(?P<indent>^ +)new StringBuilder\(\);\n +(?P<dest1>.*?);\n +JVM INSTR dup_x1 ;\n +(?P<dest2>.*?);\n +append\(\);\n +(?P<src1>.*?);\n(:? +append\(\);\n +(?P<src2>.*?);\n)? +append\(\);\n +toString\(\);\n +(?P=dest2);$', re.MULTILINE),
|
||||
|
||||
# field_1234[field_5678] += abc + def;
|
||||
'str2': re.compile(r'(?P<indent>^ +)new StringBuilder\(\);\n +(?P<dest1>.*?);\n +(?P<dest2>.*?);\n +JVM INSTR dup2_x1 ;\n +JVM INSTR aaload ;\n +append\(\);\n +(?P<src1>.*?);\n +append\(\);\n(:? +(?P<src2>.*?);\n +append\(\);\n)? +toString\(\);\n +JVM INSTR aastore ;$', re.MULTILINE),
|
||||
|
||||
# if(test) goto _L1; else goto _L2
|
||||
'if_goto': re.compile(r'(?P<indent>^ +)if(?P<test>\(.*\)) goto (?P<label1>_L[0-9]+); else goto (?P<label2>_L[0-9]+)\n(?P<label3>_L[0-9]+):$', re.MULTILINE),
|
||||
}
|
||||
|
||||
_REGEXP_STR = {
|
||||
'constructor': r'^ {4}(?P<modifiers>(?:(?:' + _MODIFIERS + r') )*)%s\((?P<parameters>.*?)\)(?: throws (?P<throws>[\w$.]+(?:, [\w$.]+)*))?\n {4}\{\n(?P<body>(?:.*?\n)*?)(?P<end> {4}\}\n+)',
|
||||
|
||||
'enum_methods': r'^ {4}public static %s(?:\[\])? value(?:s|Of)\(.*?\)\n {4}\{\n(?:.*?\n)*? {4}\}\n+',
|
||||
|
||||
'enum_fields': r'^ {4}(?:public|private) static final %s [\w$.[\]]+;.*\n',
|
||||
|
||||
'enum_entries': r'^ {8}(?P<name>[\w$]+) = new %s\("(?P=name)", [0-9]+(?:, (?P<body>.*?))?\);\n+',
|
||||
|
||||
'enum_values': r'^ {8}(?P<name>[\w$]+)(?P<body> = \(new %s\[\] \{\n(?:.*\n)*? {8}\}\));\n+',
|
||||
}
|
||||
|
||||
|
||||
class Error(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class ParseError(Error):
|
||||
pass
|
||||
|
||||
|
||||
def jadfix(srcdir):
|
||||
for path, _, filelist in os.walk(srcdir, followlinks=True):
|
||||
for cur_file in fnmatch.filter(filelist, '*.java'):
|
||||
src_file = os.path.normpath(os.path.join(path, cur_file))
|
||||
_process_file(src_file)
|
||||
|
||||
|
||||
def _process_class(class_name, class_type, modifiers, extends, implements, body, end):
|
||||
if class_type == 'class':
|
||||
# if we have an enum class then fix the class declaration
|
||||
if 'final' in modifiers and 'Enum' in extends:
|
||||
modifiers.remove('final')
|
||||
extends.remove('Enum')
|
||||
class_type = 'enum'
|
||||
if class_type == 'interface':
|
||||
# is this an annotation type? still missing too much info for it to actually work
|
||||
if 'Annotation' in extends:
|
||||
extends.remove('Annotation')
|
||||
class_type = '@interface'
|
||||
if class_type == 'enum':
|
||||
body = _process_enum(class_name, body)
|
||||
|
||||
# process normal methods
|
||||
def method_match(match):
|
||||
modifiers = _REGEXP['modifiers'].findall(match.group('modifiers'))
|
||||
if match.group('modifiers') and not modifiers:
|
||||
raise ParseError('no modifiers match in %s \'%s\'' % (match.group('name'), match.group('modifiers')))
|
||||
parameters = []
|
||||
if match.group('parameters'):
|
||||
parameters = _REGEXP['list'].split(match.group('parameters'))
|
||||
throws = []
|
||||
if match.group('throws'):
|
||||
throws = _REGEXP['list'].split(match.group('throws'))
|
||||
return _process_method(class_name, match.group('name'), modifiers, match.group('type'), parameters, throws,
|
||||
match.group('body'), match.group('end'))
|
||||
body = _REGEXP['method'].sub(method_match, body)
|
||||
|
||||
# process abstract methods
|
||||
def method_abstract_match(match):
|
||||
modifiers = _REGEXP['modifiers'].findall(match.group('modifiers'))
|
||||
if match.group('modifiers') and not modifiers:
|
||||
raise ParseError('no modifiers match in %s \'%s\'' % (match.group('name'), match.group('modifiers')))
|
||||
parameters = []
|
||||
if match.group('parameters'):
|
||||
parameters = _REGEXP['list'].split(match.group('parameters'))
|
||||
throws = []
|
||||
if match.group('throws'):
|
||||
throws = _REGEXP['list'].split(match.group('throws'))
|
||||
return _process_method_abstract(class_name, match.group('name'), modifiers, match.group('type'), parameters,
|
||||
throws, match.group('end'))
|
||||
body = _REGEXP['method_abstract'].sub(method_abstract_match, body)
|
||||
|
||||
# process constructors
|
||||
def constructor_match(match):
|
||||
modifiers = _REGEXP['modifiers'].findall(match.group('modifiers'))
|
||||
if match.group('modifiers') and not modifiers:
|
||||
raise ParseError('no modifiers match in %s \'%s\'' % (match.group('name'), match.group('modifiers')))
|
||||
parameters = []
|
||||
if match.group('parameters'):
|
||||
parameters = _REGEXP['list'].split(match.group('parameters'))
|
||||
throws = []
|
||||
if match.group('throws'):
|
||||
throws = _REGEXP['list'].split(match.group('throws'))
|
||||
return _process_constructor(class_type, class_name, modifiers, parameters, throws, match.group('body'),
|
||||
match.group('end'))
|
||||
constructor_regex = re.compile(_REGEXP_STR['constructor'] % re.escape(class_name), re.MULTILINE)
|
||||
body = constructor_regex.sub(constructor_match, body)
|
||||
|
||||
# rebuild class
|
||||
out = ''
|
||||
if modifiers:
|
||||
out += ' '.join(modifiers) + ' '
|
||||
out += class_type + ' ' + class_name
|
||||
if extends:
|
||||
out += ' extends ' + ', '.join(extends)
|
||||
if implements:
|
||||
out += ' implements ' + ', '.join(implements)
|
||||
out += '\n{\n' + body + end
|
||||
return out
|
||||
|
||||
|
||||
def _process_enum(class_name, body):
|
||||
# remove super call in constructor
|
||||
body = _REGEXP['enum_super'].sub(r'', body)
|
||||
|
||||
# remove values and valueOf methods
|
||||
methods_regex = re.compile(_REGEXP_STR['enum_methods'] % re.escape(class_name), re.MULTILINE)
|
||||
body = methods_regex.sub(r'', body)
|
||||
|
||||
# remove enum fields and $VALUES
|
||||
fields_regex = re.compile(_REGEXP_STR['enum_fields'] % re.escape(class_name), re.MULTILINE)
|
||||
body = fields_regex.sub(r'', body)
|
||||
|
||||
# rebuild enum entries from static block
|
||||
body = _process_enum_static(class_name, body)
|
||||
|
||||
return body
|
||||
|
||||
|
||||
def _process_enum_static(class_name, enum_body):
|
||||
# do we have a static block?
|
||||
static_match = _REGEXP['static'].search(enum_body)
|
||||
if not static_match:
|
||||
return enum_body
|
||||
|
||||
body = static_match.group('body')
|
||||
|
||||
# for each enum field in the static build up a enum entry
|
||||
enum_entries = ''
|
||||
entries = []
|
||||
|
||||
def _enum_entries_match(match):
|
||||
entry_body = ''
|
||||
if match.group('body'):
|
||||
entry_body = '(' + match.group('body') + ')'
|
||||
new_entry = ' ' + match.group('name') + entry_body
|
||||
new_entry = _REGEXP['deindent'].sub(r'\1', new_entry)
|
||||
entries.append(new_entry)
|
||||
return ''
|
||||
entries_regex = re.compile(_REGEXP_STR['enum_entries'] % re.escape(class_name), re.MULTILINE | re.DOTALL)
|
||||
body = entries_regex.sub(_enum_entries_match, body)
|
||||
if entries:
|
||||
enum_entries = '\n' + ',\n'.join(entries) + ';\n\n'
|
||||
|
||||
# remove the $VALUES array from the static block
|
||||
values_regex = re.compile(_REGEXP_STR['enum_values'] % re.escape(class_name), re.MULTILINE)
|
||||
body = values_regex.sub('', body)
|
||||
|
||||
# add the entries and $VALUES to start of body
|
||||
enum_body = enum_entries + enum_body
|
||||
|
||||
# remove the entries and values from the static block
|
||||
# and remove the block entirely if now empty
|
||||
full_static = ''
|
||||
if body:
|
||||
full_static = ' static\n {\n' + body + static_match.group('end')
|
||||
enum_body = _REGEXP['static'].sub(full_static, enum_body)
|
||||
return enum_body
|
||||
|
||||
|
||||
def _process_method(_class_name, method_name, modifiers, method_type, parameters, throws, body, end):
|
||||
# kill off the wierd _mthclass$ methods that JAD sticks in for some reason
|
||||
if method_name == '_mthclass$' and 'static' in modifiers:
|
||||
return ''
|
||||
|
||||
body = _process_string(body)
|
||||
body = _process_if_goto(body)
|
||||
|
||||
# rebuild method
|
||||
out = ' '
|
||||
if modifiers:
|
||||
out += ' '.join(modifiers) + ' '
|
||||
out += method_type + ' ' + method_name + '(' + ', '.join(parameters) + ')'
|
||||
if throws:
|
||||
out += ' throws ' + ', '.join(throws)
|
||||
out += '\n {\n' + body + end
|
||||
return out
|
||||
|
||||
|
||||
def _process_method_abstract(_class_name, method_name, modifiers, method_type, parameters, throws, end):
|
||||
# rebuild method
|
||||
out = ' '
|
||||
if modifiers:
|
||||
out += ' '.join(modifiers) + ' '
|
||||
out += method_type + ' ' + method_name + '(' + ', '.join(parameters) + ')'
|
||||
if throws:
|
||||
out += ' throws ' + ', '.join(throws)
|
||||
out += end
|
||||
return out
|
||||
|
||||
|
||||
def _process_constructor(class_type, class_name, modifiers, parameters, throws, body, end):
|
||||
if class_type == 'enum':
|
||||
if len(parameters) >= 2:
|
||||
if parameters[0].startswith('String ') and parameters[1].startswith('int '):
|
||||
parameters = parameters[2:]
|
||||
# empty constructor
|
||||
if body == '' and len(parameters) == 0:
|
||||
return ''
|
||||
else:
|
||||
raise ParseError('invalid initial parameters in enum %s: %s' % (class_name, str(parameters)))
|
||||
else:
|
||||
raise ParseError('not enough parameters in enum %s: %s' % (class_name, str(parameters)))
|
||||
|
||||
body = _process_string(body)
|
||||
body = _process_if_goto(body)
|
||||
|
||||
# move super calls to start of constructor and remove empty super calls
|
||||
def super_match(match):
|
||||
if match.group('parameters'):
|
||||
return match.group('super') + match.group('before') + match.group('after')
|
||||
else:
|
||||
return match.group('before') + match.group('after')
|
||||
body = _REGEXP['fix_super'].sub(super_match, body)
|
||||
|
||||
# rebuild constructor
|
||||
out = ' '
|
||||
if modifiers:
|
||||
out += ' '.join(modifiers) + ' '
|
||||
out += class_name + '(' + ', '.join(parameters) + ')'
|
||||
if throws:
|
||||
out += ' throws ' + ', '.join(throws)
|
||||
out += '\n {\n' + body + end
|
||||
return out
|
||||
|
||||
|
||||
def _process_string(body):
|
||||
# fix up plain string appends
|
||||
def string1_match(match):
|
||||
indent = match.group('indent')
|
||||
src = match.group('src1')
|
||||
if match.group('src2'):
|
||||
src = '%s + %s' % (src, match.group('src2'))
|
||||
dest = match.group('dest2')
|
||||
if match.group('dest1') != 'this':
|
||||
dest = '%s.%s' % (match.group('dest1'), dest)
|
||||
return '%s%s += %s;' % (indent, dest, src)
|
||||
body = _REGEXP['str1'].sub(string1_match, body)
|
||||
|
||||
# fix up string appends to an array
|
||||
def string2_match(match):
|
||||
indent = match.group('indent')
|
||||
src = match.group('src1')
|
||||
if match.group('src2'):
|
||||
src = '%s + %s' % (src, match.group('src2'))
|
||||
dest = '%s[%s]' % (match.group('dest1'), match.group('dest2'))
|
||||
return '%s%s += %s;' % (indent, dest, src)
|
||||
body = _REGEXP['str2'].sub(string2_match, body)
|
||||
|
||||
return body
|
||||
|
||||
|
||||
def _process_if_goto(body):
|
||||
def if_goto_match(match):
|
||||
indent = match.group('indent')
|
||||
# depending on the following label negate the if test
|
||||
if match.group('label3') == match.group('label2'):
|
||||
test = 'if(!%s)' % match.group('test')
|
||||
comment = '## JADFIX %s %s' % (match.group('label2'), match.group('label1'))
|
||||
else:
|
||||
test = 'if%s' % match.group('test')
|
||||
comment = '## JADFIX %s %s' % (match.group('label1'), match.group('label2'))
|
||||
label = '%s:' % match.group('label3')
|
||||
return '%s%s\n%s\n%s' % (indent, test, comment, label)
|
||||
body = _REGEXP['if_goto'].sub(if_goto_match, body)
|
||||
return body
|
||||
|
||||
|
||||
def _process_file(src_file):
|
||||
class_name = os.path.splitext(os.path.basename(src_file))[0]
|
||||
tmp_file = src_file + '.tmp'
|
||||
with open(src_file, 'r') as fh:
|
||||
buf = fh.read()
|
||||
|
||||
buf = _REGEXP['fltexp'].sub(r'0\1', buf)
|
||||
buf = _REGEXP['trailing'].sub(r'', buf)
|
||||
|
||||
buf = _REGEXP['extends'].sub(r' ', buf)
|
||||
buf = _REGEXP['throws'].sub(r' ', buf)
|
||||
|
||||
def params_match(match):
|
||||
body = re.sub(_REGEXP['params_sub'], r' ', match.group('wrapped'))
|
||||
return ' %s%s%s' % (match.group('main'), body, match.group('suffix'))
|
||||
buf = _REGEXP['params'].sub(params_match, buf)
|
||||
|
||||
buf = _REGEXP['rename_enum'].sub(r'\1_', buf)
|
||||
|
||||
def class_match(match):
|
||||
if class_name != match.group('name'):
|
||||
raise ParseError("file name and class name differ: '%s' '%s" % (class_name, match.group('name')))
|
||||
modifiers = _REGEXP['modifiers'].findall(match.group('modifiers'))
|
||||
if match.group('modifiers') and not modifiers:
|
||||
raise ParseError("no modifiers match in %s '%s'" % (match.group('name'), match.group('modifiers')))
|
||||
extends = []
|
||||
if match.group('extends'):
|
||||
extends = _REGEXP['list'].split(match.group('extends'))
|
||||
implements = []
|
||||
if match.group('implements'):
|
||||
implements = _REGEXP['list'].split(match.group('implements'))
|
||||
return _process_class(match.group('name'), match.group('type'), modifiers, extends, implements,
|
||||
match.group('body'), match.group('end'))
|
||||
(buf, match_count) = _REGEXP['class'].subn(class_match, buf)
|
||||
if not match_count:
|
||||
raise ParseError('no class in %s' % class_name)
|
||||
|
||||
buf = _REGEXP['newlines'].sub(r'\n', buf)
|
||||
|
||||
with open(tmp_file, 'w') as fh:
|
||||
fh.write(buf)
|
||||
shutil.move(tmp_file, src_file)
|
||||
|
||||
|
||||
def main():
|
||||
usage = 'usage: %prog [options] src_dir'
|
||||
version = '%prog 6.0'
|
||||
parser = OptionParser(version=version, usage=usage)
|
||||
options, args = parser.parse_args()
|
||||
if len(args) != 1:
|
||||
print >> sys.stderr, 'src_dir required'
|
||||
sys.exit(1)
|
||||
jadfix(args[0])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Binary file not shown.
@ -0,0 +1,69 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Wed Apr 18 11:19:07 2012
|
||||
|
||||
@author: Fesh0r
|
||||
@version: v0.1
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import fnmatch
|
||||
import shutil
|
||||
import re
|
||||
from optparse import OptionParser
|
||||
|
||||
|
||||
_REGEXP = {
|
||||
# Remove trailing whitespace
|
||||
'trailing': re.compile(r'[ \t]+$', re.MULTILINE),
|
||||
|
||||
# close up extends, and implements that JD-GUI puts on a seperate line
|
||||
'extends': re.compile(r'$\n {2}(?=extends|implements)', re.MULTILINE),
|
||||
|
||||
# close up throws that JD-GUI puts on a seperate line
|
||||
'throws': re.compile(r'$\n {4}(?=throws)', re.MULTILINE),
|
||||
|
||||
# Remove repeated blank lines
|
||||
'newlines': re.compile(r'^\n{2,}', re.MULTILINE),
|
||||
}
|
||||
|
||||
|
||||
def jdfix(srcdir):
|
||||
for path, _, filelist in os.walk(srcdir, followlinks=True):
|
||||
for cur_file in fnmatch.filter(filelist, '*.java'):
|
||||
src_file = os.path.normpath(os.path.join(path, cur_file))
|
||||
_process_file(src_file)
|
||||
|
||||
|
||||
def _process_file(src_file):
|
||||
class_name = os.path.splitext(os.path.basename(src_file))[0]
|
||||
tmp_file = src_file + '.tmp'
|
||||
with open(src_file, 'r') as fh:
|
||||
buf = fh.read()
|
||||
|
||||
buf = _REGEXP['trailing'].sub(r'', buf)
|
||||
|
||||
buf = _REGEXP['extends'].sub(r' ', buf)
|
||||
buf = _REGEXP['throws'].sub(r' ', buf)
|
||||
|
||||
buf = _REGEXP['newlines'].sub(r'\n', buf)
|
||||
|
||||
with open(tmp_file, 'w') as fh:
|
||||
fh.write(buf)
|
||||
shutil.move(tmp_file, src_file)
|
||||
|
||||
|
||||
def main():
|
||||
usage = 'usage: %prog [options] src_dir'
|
||||
version = '%prog 6.0'
|
||||
parser = OptionParser(version=version, usage=usage)
|
||||
options, args = parser.parse_args()
|
||||
if len(args) != 1:
|
||||
print >> sys.stderr, 'src_dir required'
|
||||
sys.exit(1)
|
||||
jdfix(args[0])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,72 @@
|
||||
import sys
|
||||
import os
|
||||
import shutil
|
||||
import fnmatch
|
||||
import re
|
||||
from optparse import OptionParser
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
||||
def normaliselines_dir(in_dirname, out_dirname=None):
|
||||
in_dirname = os.path.normpath(in_dirname)
|
||||
if out_dirname is not None:
|
||||
out_dirname = os.path.normpath(out_dirname)
|
||||
for path, _, filelist in os.walk(in_dirname, followlinks=True):
|
||||
sub_dir = os.path.relpath(path, in_dirname)
|
||||
for cur_file in fnmatch.filter(filelist, '*.java'):
|
||||
src_file = os.path.normpath(os.path.join(path, cur_file))
|
||||
if out_dirname is not None:
|
||||
dest_file = os.path.join(out_dirname, sub_dir, cur_file)
|
||||
else:
|
||||
dest_file = None
|
||||
normaliselines(src_file, dest_file)
|
||||
|
||||
|
||||
def main():
|
||||
usage = 'usage: %prog [options] src_file|src_dir [dest_file|dest_dir]'
|
||||
version = '%prog 6.0'
|
||||
parser = OptionParser(version=version, usage=usage)
|
||||
options, args = parser.parse_args()
|
||||
if len(args) == 1:
|
||||
in_name = args[0]
|
||||
out_name = None
|
||||
elif len(args) == 2:
|
||||
in_name = args[0]
|
||||
out_name = args[1]
|
||||
else:
|
||||
print >> sys.stderr, 'src_file or src_dir required'
|
||||
sys.exit(1)
|
||||
if not os.path.exists(in_name):
|
||||
print >> sys.stderr, 'src_file or src_dir not found'
|
||||
sys.exit(1)
|
||||
if os.path.isfile(in_name):
|
||||
normaliselines(in_name, out_name)
|
||||
elif os.path.isdir(in_name):
|
||||
normaliselines_dir(in_name, out_name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Binary file not shown.
@ -0,0 +1,48 @@
|
||||
import sys
|
||||
import os
|
||||
import shutil
|
||||
from optparse import OptionParser
|
||||
|
||||
|
||||
def normalisepatch(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)
|
||||
with open(in_filename, 'rb') as inpatch:
|
||||
with open(tmp_filename, 'wb') as outpatch:
|
||||
for line in inpatch:
|
||||
line = line.rstrip('\r\n')
|
||||
if line[:3] in ['+++', '---', 'Onl', 'dif']:
|
||||
outpatch.write(line.replace('\\', os.sep).replace('/', os.sep) + os.linesep)
|
||||
else:
|
||||
outpatch.write(line + os.linesep)
|
||||
if out_filename is None:
|
||||
shutil.move(tmp_filename, in_filename)
|
||||
|
||||
|
||||
def main():
|
||||
usage = 'usage: %prog [options] src_file [dest_file]'
|
||||
version = '%prog 6.0'
|
||||
parser = OptionParser(version=version, usage=usage)
|
||||
options, args = parser.parse_args()
|
||||
if len(args) == 1:
|
||||
in_file = args[0]
|
||||
out_file = None
|
||||
elif len(args) == 2:
|
||||
in_file = args[0]
|
||||
out_file = args[1]
|
||||
else:
|
||||
print >> sys.stderr, 'src_file required'
|
||||
sys.exit(1)
|
||||
normalisepatch(in_file, out_file)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Binary file not shown.
@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Fri Apr 8 16:36:26 2011
|
||||
|
||||
@author: ProfMobius
|
||||
@version: v0.1
|
||||
"""
|
||||
|
||||
import os
|
||||
import logging
|
||||
|
||||
|
||||
def whereis(filename, rootdir):
|
||||
if not os.path.exists(rootdir):
|
||||
return []
|
||||
logging.info('> Searching for %s in %s', filename, rootdir)
|
||||
results = []
|
||||
for path, _, filelist in os.walk(rootdir):
|
||||
if filename in filelist:
|
||||
results.append(path)
|
||||
return results
|
Binary file not shown.
@ -0,0 +1,42 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Fri Apr 8 16:54:36 2011
|
||||
|
||||
@author: ProfMobius
|
||||
@version: v1.0
|
||||
"""
|
||||
|
||||
import sys
|
||||
import logging
|
||||
from optparse import OptionParser
|
||||
|
||||
from commands import Commands, CLIENT, SERVER, CalledProcessError
|
||||
from mcp import recompile_side
|
||||
|
||||
|
||||
def main():
|
||||
parser = OptionParser(version='MCP %s' % Commands.fullversion())
|
||||
parser.add_option('-c', '--config', dest='config', help='additional configuration file')
|
||||
options, _ = parser.parse_args()
|
||||
recompile(options.config)
|
||||
|
||||
|
||||
def recompile(conffile):
|
||||
try:
|
||||
commands = Commands(conffile, verify=True)
|
||||
|
||||
try:
|
||||
recompile_side(commands, CLIENT)
|
||||
except CalledProcessError:
|
||||
pass
|
||||
try:
|
||||
recompile_side(commands, SERVER)
|
||||
except CalledProcessError:
|
||||
pass
|
||||
except Exception: # pylint: disable-msg=W0703
|
||||
logging.exception('FATAL ERROR')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,41 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Thu Jan 19 12:34:12 2012
|
||||
|
||||
@author: Fesh0r
|
||||
@version: v1.0
|
||||
"""
|
||||
|
||||
import sys
|
||||
import logging
|
||||
from optparse import OptionParser
|
||||
|
||||
from commands import Commands, CLIENT, SERVER, CalledProcessError
|
||||
from mcp import reformat_side
|
||||
|
||||
|
||||
def main():
|
||||
parser = OptionParser(version='MCP %s' % Commands.fullversion())
|
||||
parser.add_option('-c', '--config', dest='config', help='additional configuration file')
|
||||
options, _ = parser.parse_args()
|
||||
reformat(options.config)
|
||||
|
||||
|
||||
def reformat(conffile):
|
||||
try:
|
||||
commands = Commands(conffile, verify=True)
|
||||
|
||||
try:
|
||||
reformat_side(commands, CLIENT)
|
||||
reformat_side(commands, SERVER)
|
||||
except CalledProcessError:
|
||||
# astyle failed
|
||||
commands.logger.error('Reformat failed')
|
||||
sys.exit(1)
|
||||
except Exception: # pylint: disable-msg=W0703
|
||||
logging.exception('FATAL ERROR')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,47 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Fri Apr 8 16:54:36 2011
|
||||
|
||||
@author: ProfMobius
|
||||
@version: v1.1
|
||||
"""
|
||||
|
||||
import sys
|
||||
import logging
|
||||
from optparse import OptionParser
|
||||
|
||||
from commands import Commands, CLIENT, SERVER
|
||||
from mcp import reobfuscate_side
|
||||
|
||||
|
||||
def main():
|
||||
parser = OptionParser(version='MCP %s' % Commands.fullversion())
|
||||
parser.add_option('-a', '--all', action='store_true', dest='reobf_all', help='output all classes', default=False)
|
||||
parser.add_option('-n', '--nolvt', dest='keep_lvt', action='store_false', help='strip local variable table',
|
||||
default=True)
|
||||
parser.add_option('-g', '--generics', dest='keep_generics', action='store_true',
|
||||
help='preserve generics as well as local variables', default=False)
|
||||
parser.add_option('-c', '--config', dest='config', help='additional configuration file')
|
||||
options, _ = parser.parse_args()
|
||||
reobfuscate(options.config, options.reobf_all, options.keep_lvt, options.keep_generics)
|
||||
|
||||
|
||||
def reobfuscate(conffile, reobf_all, keep_lvt, keep_generics):
|
||||
try:
|
||||
commands = Commands(conffile, verify=True)
|
||||
|
||||
if keep_generics:
|
||||
keep_lvt = True
|
||||
|
||||
commands.logger.info('> Creating Retroguard config files')
|
||||
commands.creatergcfg(reobf=True, keep_lvt=keep_lvt, keep_generics=keep_generics)
|
||||
|
||||
reobfuscate_side(commands, CLIENT, reobf_all=reobf_all)
|
||||
reobfuscate_side(commands, SERVER, reobf_all=reobf_all)
|
||||
except Exception: # pylint: disable-msg=W0703
|
||||
logging.exception('FATAL ERROR')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,37 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Fri Apr 8 16:54:36 2011
|
||||
|
||||
@author: ProfMobius
|
||||
@version: v1.0
|
||||
"""
|
||||
|
||||
import sys
|
||||
import logging
|
||||
from optparse import OptionParser
|
||||
|
||||
from commands import Commands, CLIENT
|
||||
|
||||
|
||||
def main():
|
||||
parser = OptionParser(version='MCP %s' % Commands.fullversion())
|
||||
parser.add_option('-c', '--config', dest='config', help='additional configuration file')
|
||||
options, _ = parser.parse_args()
|
||||
startclient(options.config)
|
||||
|
||||
|
||||
def startclient(conffile):
|
||||
try:
|
||||
commands = Commands(conffile)
|
||||
|
||||
if not commands.checkbins(CLIENT):
|
||||
commands.logger.warning('!! Can not find client bins !!')
|
||||
sys.exit(1)
|
||||
commands.startclient()
|
||||
except Exception: # pylint: disable-msg=W0703
|
||||
logging.exception('FATAL ERROR')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,37 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Fri Apr 8 16:54:36 2011
|
||||
|
||||
@author: ProfMobius
|
||||
@version: v1.0
|
||||
"""
|
||||
|
||||
import sys
|
||||
import logging
|
||||
from optparse import OptionParser
|
||||
|
||||
from commands import Commands, SERVER
|
||||
|
||||
|
||||
def main():
|
||||
parser = OptionParser(version='MCP %s' % Commands.fullversion())
|
||||
parser.add_option('-c', '--config', dest='config', help='additional configuration file')
|
||||
options, _ = parser.parse_args()
|
||||
startserver(options.config)
|
||||
|
||||
|
||||
def startserver(conffile):
|
||||
try:
|
||||
commands = Commands(conffile)
|
||||
|
||||
if not commands.checkbins(SERVER):
|
||||
commands.logger.warning('!! Can not find server bins !!')
|
||||
sys.exit(1)
|
||||
commands.startserver()
|
||||
except Exception: # pylint: disable-msg=W0703
|
||||
logging.exception('FATAL ERROR')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,48 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Tue Jul 31 12:16:43 2012
|
||||
|
||||
@author: Fesh0r
|
||||
@version: v1.0
|
||||
"""
|
||||
|
||||
import sys
|
||||
import logging
|
||||
from optparse import OptionParser
|
||||
|
||||
from commands import Commands, CLIENT, SERVER
|
||||
from mcp import updateids_side
|
||||
|
||||
|
||||
def main():
|
||||
parser = OptionParser(version='MCP %s' % Commands.fullversion())
|
||||
parser.add_option('-f', '--force', action='store_true', dest='force', help='force update', default=False)
|
||||
parser.add_option('-c', '--config', dest='config', help='additional configuration file')
|
||||
options, _ = parser.parse_args()
|
||||
updateids(options.config, options.force)
|
||||
|
||||
|
||||
def updateids(conffile, force):
|
||||
try:
|
||||
commands = Commands(conffile)
|
||||
|
||||
if not force:
|
||||
print 'WARNING:'
|
||||
print 'The updateids script is unsupported, not recommended, and can break your'
|
||||
print 'code in hard to detect ways.'
|
||||
print 'Only use this script if you absolutely know what you are doing, or when a'
|
||||
print 'MCP team member asks you to do so.'
|
||||
answer = raw_input('If you really want to update all classes, enter "Yes" ')
|
||||
if answer.lower() not in ['yes']:
|
||||
print 'You have not entered "Yes", aborting the update process'
|
||||
sys.exit(1)
|
||||
|
||||
updateids_side(commands, CLIENT)
|
||||
updateids_side(commands, SERVER)
|
||||
except Exception: # pylint: disable-msg=W0703
|
||||
logging.exception('FATAL ERROR')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,36 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Fri Apr 8 16:54:36 2011
|
||||
|
||||
@author: ProfMobius
|
||||
@version: v1.0
|
||||
"""
|
||||
|
||||
import sys
|
||||
import logging
|
||||
from optparse import OptionParser
|
||||
|
||||
from commands import Commands
|
||||
|
||||
|
||||
def main():
|
||||
parser = OptionParser(version='MCP %s' % Commands.fullversion())
|
||||
parser.add_option('-f', '--force', action='store_true', dest='force', help='force update', default=False)
|
||||
parser.add_option('-c', '--config', dest='config', help='additional configuration file')
|
||||
options, _ = parser.parse_args()
|
||||
updatemcp(options.config, options.force)
|
||||
|
||||
|
||||
def updatemcp(conffile, force):
|
||||
try:
|
||||
commands = Commands(conffile)
|
||||
|
||||
commands.logger.info('== Updating MCP ==')
|
||||
commands.downloadupdates(force)
|
||||
except Exception: # pylint: disable-msg=W0703
|
||||
logging.exception('FATAL ERROR')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,57 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Fri May 22 23:32:36 2011
|
||||
|
||||
@author: Searge
|
||||
@version: v1.0
|
||||
"""
|
||||
|
||||
import sys
|
||||
import logging
|
||||
from optparse import OptionParser
|
||||
|
||||
from commands import Commands, CLIENT, SERVER, CalledProcessError
|
||||
from mcp import updatemd5_side
|
||||
|
||||
|
||||
def main():
|
||||
parser = OptionParser(version='MCP %s' % Commands.fullversion())
|
||||
parser.add_option('-f', '--force', action='store_true', dest='force', help='force update', default=False)
|
||||
parser.add_option('-c', '--config', dest='config', help='additional configuration file')
|
||||
options, _ = parser.parse_args()
|
||||
updatemd5(options.config, options.force)
|
||||
|
||||
|
||||
def updatemd5(conffile, force):
|
||||
try:
|
||||
commands = Commands(conffile)
|
||||
|
||||
if (commands.checkmd5s(CLIENT) or commands.checkmd5s(SERVER)) and not force:
|
||||
print 'WARNING:'
|
||||
print 'The updatemd5 script is unsupported and should only be run in special'
|
||||
print 'cases, such as if there were compile errors in the last decompile which'
|
||||
print 'have now been corrected. It will reset the changed status of all classes'
|
||||
print 'for reobfuscation, and only classes modified afterwards will end up in'
|
||||
print 'the reobf directory.'
|
||||
print 'Only use this script if you absolutely know what you are doing, or when a'
|
||||
print 'MCP team member asks you to do so.'
|
||||
answer = raw_input('If you really want to update all classes, enter "Yes" ')
|
||||
if answer.lower() not in ['yes']:
|
||||
print 'You have not entered "Yes", aborting the update process'
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
updatemd5_side(commands, CLIENT)
|
||||
except CalledProcessError:
|
||||
commands.logger.error('Client recompile failed, correct source then rerun updatemd5')
|
||||
try:
|
||||
updatemd5_side(commands, SERVER)
|
||||
except CalledProcessError:
|
||||
commands.logger.error('Server recompile failed, correct source then rerun updatemd5')
|
||||
except Exception: # pylint: disable-msg=W0703
|
||||
logging.exception('FATAL ERROR')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,48 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Fri Apr 8 16:54:36 2011
|
||||
|
||||
@author: Searge
|
||||
@version: v1.0
|
||||
"""
|
||||
|
||||
import sys
|
||||
import logging
|
||||
from optparse import OptionParser
|
||||
|
||||
from commands import Commands, CLIENT, SERVER
|
||||
from mcp import updatenames_side
|
||||
|
||||
|
||||
def main():
|
||||
parser = OptionParser(version='MCP %s' % Commands.fullversion())
|
||||
parser.add_option('-f', '--force', action='store_true', dest='force', help='force update', default=False)
|
||||
parser.add_option('-c', '--config', dest='config', help='additional configuration file')
|
||||
options, _ = parser.parse_args()
|
||||
updatenames(options.config, options.force)
|
||||
|
||||
|
||||
def updatenames(conffile, force):
|
||||
try:
|
||||
commands = Commands(conffile)
|
||||
|
||||
if not force:
|
||||
print 'WARNING:'
|
||||
print 'The updatenames script is unsupported, not recommended, and can break your'
|
||||
print 'code in hard to detect ways.'
|
||||
print 'Only use this script if you absolutely know what you are doing, or when a'
|
||||
print 'MCP team member asks you to do so.'
|
||||
answer = raw_input('If you really want to update all classes, enter "Yes" ')
|
||||
if answer.lower() not in ['yes']:
|
||||
print 'You have not entered "Yes", aborting the update process'
|
||||
sys.exit(1)
|
||||
|
||||
updatenames_side(commands, CLIENT)
|
||||
updatenames_side(commands, SERVER)
|
||||
except Exception: # pylint: disable-msg=W0703
|
||||
logging.exception('FATAL ERROR')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,24 @@
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
public class Start
|
||||
{
|
||||
public static void main(String[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
Field f = Minecraft.class.getDeclaredField("minecraftDir");
|
||||
Field.setAccessible(new Field[] { f }, true);
|
||||
f.set(null, new File("."));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
Minecraft.main(args);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue