This looks amazing. Great way to take a look inside some mods and figure out how they work. (There's only so much you can learn from tutorials.)
In theory, anyway. When I try to deobfuscate any mods, I end up with a bunch of files that contain nothing but this:
// INTERNAL ERROR //
No idea why. The jars and zip files I input are good. Output is straightforward enough. I'm using the correct version of Minecraft. Unless I have to manually download the mappings somewhere?
How about a deobfuscator that automatically generates deobfuscated names, and therefore eliminates the need to download a separate mapping file. Each time it runs into a collision between a class name and a package name or function name or field name, or any combination of these that can cause a collision, it resolves the issues by generating a unique name such as class_1234 or something like that. It then scans all the other files for references to that class, package, function, or field, and fixes the references as required. It then increments the number portion of the name, each time it discovers a new class, package, function or field that needs renaming. The output of this deobfuscator is a jar file containing all of the renamed code, and also a separate mapping file that can be used to re-obfuscate later.
To make a mod, simply decompile the deobfuscated jar with whatever decompiler you prefer (such as JD GUI). Then after editing the source code, use whatever Java IDE you prefer (such as Netbeans) to recompile (or if you only need to recompile a few class files to make your mod, you can use javac.exe directly from the command line). The last step is to use the deobfuscator with the command line switch -reobfuscate, in conjunction with the map file auto-generated in the first step, to reobfuscate the class files in the output jar. This jar file would contain the modified and reobfuscated class files, which could then be directly copied into the original game jar file to replace the corresponding class files to install the mod.
Because no original mapping file would be needed, this would work on very old versions, for which the makers of MCP have not created mapping files, such as Classic and Indev versions of Minecraft. While such deobfuscated class names, method names, package names, and field names would not convey their purpose like level.class or something, any names involved in a collision would be changed to be absolutely unique with classes that got renamed so they would always start with "class_" and methods (functions) that got renamed would always start with "method_" etc. This GUARANTIES that they could be recompiled, as there would be no collisions between the names. And this means that simple edits to the source code could be performed, by simply looking at the source code and guessing the functionality of a given variable or function, based on the context in which it was being used (such as a String variable getting set to the name of a level file, indicates that the variable in question is being used in the level saving or loading process).
Because the deobfuscation process generates a mapping file, if that mapping file were in plain text (such as CSV), then when one did find the functionality of a class or function, they could manually rename it in the mapping file, and then use the edited mapping file to again deobfuscate the game's jar file but this time including the filename of the mapping file (instead of no file name). Now instead of generating a mapping file, it would load the existing (and edited) mapping file, and generate class file names, method names, field names, and package names, which much more accurately describe their functionality.
No. You don't need more then actually two files ever. One is for mdk the other is for obfsucated. It tells forge wheat to turn the stuff into srg for obfsucated and readable names for deobfuscated.
d
For this you only ever need one file it deobfuscates them depending upon the code will determine the file you use.
Well, I decided to update this. Hopefully, this fixes any issues anyone was having with it. Feel pretty good that I made it with C# instead of java. I also completed it way faster than I thought I would. Took me around than 12 hours in total, I think. Feels good man.
This slightly worries me. It can take ANY mod and turn it into source code, allowing for the less-honest community to steal source code.
Talk about stealing code written for an originally illegally disassembled game. Especially when mod authors abandon their development, but still "protect their code rights." ROFL. It is not ethical to hide the source code of mods. Especially for unsupported versions.
Talk about stealing code written for an originally illegally disassembled game. Especially when mod authors abandon their development, but still "protect their code rights." ROFL. It is not ethical to hide the source code of mods. Especially for unsupported versions.
Even without a deobfuscator it is easy enough to decompile a mod; I've decompiled Optifine (closed source) by simply decompiling a modded jar so I could modify it for my own use, as well as know what code to avoid replacing in my own mods to maintain compatibility and/or add in fields and empty methods to avoid NoSuchField/Method errors (there might still be issues if certain settings are used, such as antialiasing/anisotropic filtering, which I make note of in a Readme; only its most basic functionality is guaranteed) or access them for my own reimplementations of lost functionality; for example, I overrode the cloud rendering code in RenderGlobal so I could optimize it (over 15x faster for Fancy clouds!) and check for Optifine's own fields in GameSettings so its cloud settings still work (this is not the same as stealing its code since I wrote my own code that just uses its settings; likewise, vanilla has since added its own setting for switching clouds from Fast/Fancy independent of the global Fast/Fancy setting):
// Included for Optifine compatibility (used by antialiasing/anisotropic filtering options, but otherwise
// not needed for proper operation. Not tested to see what happens if they are enabled)
public static boolean renderingWorldRenderer = false;
public boolean defaultTexture = true;
public int textureID = 0;
private boolean renderingChunk;
public boolean isRenderingChunk()
{
return this.renderingChunk;
}
public void setRenderingChunk(boolean renderingChunk)
{
this.renderingChunk = renderingChunk;
}
// Checks for presence of Optifine-added fields in GameSettings
try
{
Field[] fields = this.minecraft.gameSettings.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; ++i)
{
Field f = fields[i];
if (f.getName().equals("ofClouds") && Integer.TYPE.equals(f.getType()))
{
this.gameSettingsClouds = f;
}
if (f.getName().equals("ofCloudsHeight") && Float.TYPE.equals(f.getType()))
{
this.gameSettingsCloudsHeight = f;
}
if (f.getName().equals("ofRenderDistanceFine") && Integer.TYPE.equals(f.getType()))
{
this.gameSettingsRenderDistance = f;
}
}
if (this.gameSettingsClouds == null) System.out.println("Field GameSettings.ofClouds not found");
if (this.gameSettingsCloudsHeight == null) System.out.println("Field GameSettings.ofCloudsHeight not found");
if (this.gameSettingsRenderDistance == null) System.out.println("Field GameSettings.ofRenderDistanceFine not found");
}
catch (Throwable t)
{
t.printStackTrace();
}
// Returns 0 for Fast, 1 for Fancy, 2 for Off
private int getCloudType()
{
if (this.gameSettingsClouds != null)
{
try
{
int clouds = this.gameSettingsClouds.getInt(this.minecraft.gameSettings);
return (clouds <= 0 ? (this.minecraft.gameSettings.fancyGraphics ? 1 : 0) : clouds - 1);
}
catch (Throwable t)
{
this.gameSettingsClouds = null;
t.printStackTrace();
}
}
return (this.minecraft.gameSettings.fancyGraphics ? 1 : 0);
}
// Returns world cloud height + 0.33, plus 0-128 if Optifine is installed
private float getCloudHeight()
{
if (this.gameSettingsCloudsHeight != null)
{
try
{
return this.worldObj.provider.getCloudHeight() + 0.33F + this.gameSettingsCloudsHeight.getFloat(this.minecraft.gameSettings) * 128.0F;
}
catch (Throwable t)
{
this.gameSettingsCloudsHeight = null;
t.printStackTrace();
}
}
return this.worldObj.provider.getCloudHeight() + 0.33F;
}
// Returns render distance in blocks; Tiny = 32, Short = 64, Normal = 128, Far = 256;
// Optifine varies it in intervals of 16
private int getRenderDistance()
{
if (this.gameSettingsRenderDistance != null)
{
try
{
return this.gameSettingsRenderDistance.getInt(this.minecraft.gameSettings);
}
catch (Throwable t)
{
this.gameSettingsRenderDistance = null;
t.printStackTrace();
}
}
return 32 << (3 - this.minecraft.gameSettings.renderDistance);
}
Also, I doubt that most modders will go through the trouble to obfuscate their own code; for example, you can easily see my own modifications to the lightmap code which makes a light level of 0 in the Overworld totally black no matter what, with lower light levels on higher gamma settings also reduced:
For comparison, this is the original source (most of the variables are "var#" since I didn't bother renaming them from the vanilla source I copied and modified); as with Optifine you can also use MCP to decompile a modded jar with one of my mods to fully deobfuscate it, minus comments (this is probably more difficult with Forge mods but I presume MCP will still deobfuscate it as much as it can, just not produce working code without Forge itself being installed, and even then older versions of Forge used MCP for its development environment; back when I used Forge for some other mods in 1.6.2 I directly modified the Forge-patched MCP source to guarantee compatibility with my own non-Forge mods):
public EntityRendererTMCW(Minecraft par1Minecraft)
{
super(par1Minecraft);
this.minecraft = par1Minecraft;
// Prevents user from editing options.txt to set gamma outside its valid range of 0-1
if (this.minecraft.gameSettings.gammaSetting > 1.0F) this.minecraft.gameSettings.gammaSetting = 1.0F;
if (this.minecraft.gameSettings.gammaSetting < 0.0F) this.minecraft.gameSettings.gammaSetting = 0.0F;
private void refreshLightmap(float par1)
{
WorldClient worldObj = this.minecraft.theWorld;
if (worldObj == null || this.minecraft.thePlayer == null) return;
float[] brightnessTable = worldObj.provider.lightBrightnessTable;
boolean nightVision = this.minecraft.thePlayer.isPotionActive(Potion.nightVision);
float nvBrightness = (nightVision ? this.getNightVisionBrightness(this.minecraft.thePlayer, par1) : 0.0F);
boolean lightning = worldObj.lastLightningBolt > 0;
float torchFlicker = this.torchFlickerX * 0.1F + 1.5F;
float sunBrightness1 = worldObj.getSunBrightness(1.0F);
float sunBrightness2 = sunBrightness1 * 0.65F + 0.35F;
sunBrightness1 = sunBrightness1 * 0.95F + 0.05F;
boolean isEnd = (worldObj.provider.dimensionId == 1);
// With Night Vision active nvBrightness varies from 0.4 to 1.0; forces gamma higher to prevent
// discoloration near light sources, especially on lower gamma settings.
float gamma = (nightVision ? 0.968F + nvBrightness * nvBrightness * 0.2F : this.minecraft.gameSettings.gammaSetting);
// Scales light levels so that levels 1-15 cover a wider range with lower levels being darker
// than vanilla (level 15 is the same).
// Scales with gamma setting; equivalent to (0.96 + 0.03) * scale - offset.
float offset = gamma * 0.1F;
float scale = (offset + 1.0F) * 0.96F;
offset = (offset + 1.0F) * 0.03F - offset;
// When true sets a light level of (0,0) to total darkness
boolean setBlackLevel = (worldObj.provider.dimensionId == 0 && !nightVision);
for (int var3 = (setBlackLevel ? 1 : 0); var3 < 256; ++var3)
{
float var5 = (lightning ? brightnessTable[var3 >> 4] : brightnessTable[var3 >> 4] * sunBrightness1);
float var6 = brightnessTable[var3 & 15] * torchFlicker;
float var7 = var5 * sunBrightness2;
float var11 = var6 * (var6 * 0.36F + 0.64F);
float var12 = var6 * (var6 * var6 * 0.6F + 0.4F);
float var13 = var7 + var6;
float var14 = var7 + var11;
float var15 = var5 + var12;
var13 = var13 * 0.96F + 0.03F;
var14 = var14 * 0.96F + 0.03F;
var15 = var15 * 0.96F + 0.03F;
if (isEnd)
{
var13 = 0.22F + var6 * 0.75F;
var14 = 0.28F + var11 * 0.75F;
var15 = 0.25F + var12 * 0.75F;
}
else if (this.bossStatus1 > 0.0F)
{
float var16 = this.bossStatus2 + (this.bossStatus1 - this.bossStatus2) * par1;
float inv = 1.0F - var16;
var13 = var13 * inv + var13 * 0.7F * var16;
var14 = var14 * inv + var14 * 0.6F * var16;
var15 = var15 * inv + var15 * 0.6F * var16;
}
if (var13 > 1.0F) var13 = 1.0F;
if (var14 > 1.0F) var14 = 1.0F;
if (var15 > 1.0F) var15 = 1.0F;
if (nightVision)
{
float var17 = 1.0F / var13;
if (var17 > 1.0F / var14) var17 = 1.0F / var14;
if (var17 > 1.0F / var15) var17 = 1.0F / var15;
float inv = 1.0F - nvBrightness;
var17 *= nvBrightness;
var13 = var13 * inv + var13 * var17;
var14 = var14 * inv + var14 * var17;
var15 = var15 * inv + var15 * var17;
}
float var17 = 1.0F - var13;
float var18 = 1.0F - var14;
float var19 = 1.0F - var15;
float inv = 1.0F - gamma;
var13 = var13 * inv + (1.0F - var17 * var17 * var17 * var17) * gamma;
var14 = var14 * inv + (1.0F - var18 * var18 * var18 * var18) * gamma;
var15 = var15 * inv + (1.0F - var19 * var19 * var19 * var19) * gamma;
// Multiplies values by scale and adds offset so range is expanded downwards (1 remains the same
// while lower values progressively decrease)
var13 = var13 * scale + offset;
var14 = var14 * scale + offset;
var15 = var15 * scale + offset;
if (var13 > 1.0F) var13 = 1.0F;
if (var14 > 1.0F) var14 = 1.0F;
if (var15 > 1.0F) var15 = 1.0F;
if (var13 < 0.0F) var13 = 0.0F;
if (var14 < 0.0F) var14 = 0.0F;
if (var15 < 0.0F) var15 = 0.0F;
this.lightmapData[var3] = -16777216 | (int)(var13 * 255.0F) << 16 | (int)(var14 * 255.0F) << 8 | (int)(var15 * 255.0F);
}
// Sets a light level of (0,0) to total darkness, not applied when Night Vision is in effect
// or in the Nether/End
if (setBlackLevel) this.lightmapData[0] = -16777216;
this.lightmapTex.updateDynamicTexture();
this.updateLightmap = false;
// Debug; saves lightmap to disk
if (this.printTable)
{
this.printTable = false;
BufferedImage image = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
for (int i = 0; i < 256; ++i)
{
image.setRGB(i & 15, i >> 4, this.lightmapData[i]);
}
try
{
File outputfile = new File(Minecraft.getMinecraft().mcDataDir, "lightmap.png");
ImageIO.write(image, "png", outputfile);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
Also, Mojang allows you to mod the game in the EULA, so it isn't illegal to decompile it, as long as you don't distribute the original unmodified code (which many people do anyway; I've found code for versions as recent as 1.12 on GitHub, as in the entire decompiled source, including for mods or hacked clients which only modify a few classes, which are the only ones that should be there, hence why the EULA says that your mods should not contain a "substantial" amount of their code or assets (whatever that means; I've had people tell me that my own jar mods are illegal, but then so is this trivial Forge mod which copied a method from a vanilla class, with far fewer changes than the code I show above, or the base classes I've edited).
Has it been 4 months since I last updated this? Man feels like it's been way longer. Pretty happy with the fact that new versions of minecraft don't break this either. Are people interested in the source code?
Rollback Post to RevisionRollBack
My Mods:
Working on updating Little Maid Mod to 1.12 with my own twist. I am a Japanese anime fan :3 Teasers here
Blood Baubles - An addon for BloodMagic that adds related Baubles to the game. (Currently on hold)
Blood Magic Wiki - A Blood Mages Choice Encylopedia (Currently on hold)
LazyModder- A libary that makes modding easier. Currently being developed for 1.12)
Deobfuscator - A program used to deobfuscate obfuscated mods.
Has it been 4 months since I last updated this? Man feels like it's been way longer. Pretty happy with the fact that new versions of minecraft don't break this either. Are people interested in the source code?
Okay, maybe I spoke to soon about my code not breaking. I was working on an update for this tool from Windows Forms to using WPF and I ran into a few bugs, one that just made it stop working o.O Anyways, about done with a beta version that will offer some more features and improvements. One such feature is a search box that lets you search for obfuscated and deobfuscated names, something I tried and failed at last time along with an improvement on how mappings are selected.
Will be posting a download link in the next day or so to finish, fix and improve some things. Feedback is encouraged and some testers would be nice. Perhaps some suggestions on other tools. Do people want source?!
The Meaning of Life, the Universe, and Everything.
Join Date:
2/1/2017
Posts:
56
Member Details
Would this be useful in deobfuscating net.minecraft.server itself? I've always been interested in playing around in NMS without using something like Spigot etc.
Rollback Post to RevisionRollBack
Wondering where my posts are? Lost during migration.
Would this be useful in deobfuscating net.minecraft.server itself? I've always been interested in playing around in NMS without using something like Spigot etc.
The server is more or less the same as the client since singleplayer runs on an integrated server which is the same as a dedicated server except with certain settings predefined (a major reason for the client-server merge in 1.3.1 was to simplify official updates, which also benefited mods); I've installed many of my own mods, all designed on the client, in the server jar without any issues when using it with Minecraft Land Generator to pregenerate a world (due to how I coded some things in they won't work in multiplayer; I use a static class to pass data from the server to the client, such as my "inventory stats", server-sided debug information like mob counts and server performance, or fixing client-side brightness during thunderstorms, but it would otherwise run since I don't directly access client-side code from the server-side; if you properly use networking this won't be an issue (e.g. the thunderstorm issue can easily be fixed by modifying the weather packet handler but I didn't want to modify another class just for that and I technically don't support multiplayer anyway).
Glad to see that it still works (at least for me). No idea what happened to the lite version, it's not in my dropbox anymore, so I removed the link. Did it work for you @Pangamma?
Rollback Post to RevisionRollBack
My Mods:
Working on updating Little Maid Mod to 1.12 with my own twist. I am a Japanese anime fan :3 Teasers here
Blood Baubles - An addon for BloodMagic that adds related Baubles to the game. (Currently on hold)
Blood Magic Wiki - A Blood Mages Choice Encylopedia (Currently on hold)
LazyModder- A libary that makes modding easier. Currently being developed for 1.12)
Deobfuscator - A program used to deobfuscate obfuscated mods.
Another update? Only took me a little over a year to get to.
My Mods:
- Happy Coding -
Interesting. Too often old src from 1.6.4 is obf'd.
Thanks.
This looks amazing. Great way to take a look inside some mods and figure out how they work. (There's only so much you can learn from tutorials.)
In theory, anyway. When I try to deobfuscate any mods, I end up with a bunch of files that contain nothing but this:
No idea why. The jars and zip files I input are good. Output is straightforward enough. I'm using the correct version of Minecraft. Unless I have to manually download the mappings somewhere?
Very nice deobfucator! But! He sometimes loses decompiled classes. Also, it would not hurt to add the ability to use obfuscator via the command line.
No. You don't need more then actually two files ever. One is for mdk the other is for obfsucated. It tells forge wheat to turn the stuff into srg for obfsucated and readable names for deobfuscated.
d
For this you only ever need one file it deobfuscates them depending upon the code will determine the file you use.
Well, I decided to update this. Hopefully, this fixes any issues anyone was having with it. Feel pretty good that I made it with C# instead of java. I also completed it way faster than I thought I would. Took me around than 12 hours in total, I think. Feels good man.
My Mods:
- Happy Coding -
Hi! Thank you for the work done, but why not open source?
Talk about stealing code written for an originally illegally disassembled game. Especially when mod authors abandon their development, but still "protect their code rights." ROFL. It is not ethical to hide the source code of mods. Especially for unsupported versions.
Even without a deobfuscator it is easy enough to decompile a mod; I've decompiled Optifine (closed source) by simply decompiling a modded jar so I could modify it for my own use, as well as know what code to avoid replacing in my own mods to maintain compatibility and/or add in fields and empty methods to avoid NoSuchField/Method errors (there might still be issues if certain settings are used, such as antialiasing/anisotropic filtering, which I make note of in a Readme; only its most basic functionality is guaranteed) or access them for my own reimplementations of lost functionality; for example, I overrode the cloud rendering code in RenderGlobal so I could optimize it (over 15x faster for Fancy clouds!) and check for Optifine's own fields in GameSettings so its cloud settings still work (this is not the same as stealing its code since I wrote my own code that just uses its settings; likewise, vanilla has since added its own setting for switching clouds from Fast/Fancy independent of the global Fast/Fancy setting):
Also, I doubt that most modders will go through the trouble to obfuscate their own code; for example, you can easily see my own modifications to the lightmap code which makes a light level of 0 in the Overworld totally black no matter what, with lower light levels on higher gamma settings also reduced:
For comparison, this is the original source (most of the variables are "var#" since I didn't bother renaming them from the vanilla source I copied and modified); as with Optifine you can also use MCP to decompile a modded jar with one of my mods to fully deobfuscate it, minus comments (this is probably more difficult with Forge mods but I presume MCP will still deobfuscate it as much as it can, just not produce working code without Forge itself being installed, and even then older versions of Forge used MCP for its development environment; back when I used Forge for some other mods in 1.6.2 I directly modified the Forge-patched MCP source to guarantee compatibility with my own non-Forge mods):
Also, Mojang allows you to mod the game in the EULA, so it isn't illegal to decompile it, as long as you don't distribute the original unmodified code (which many people do anyway; I've found code for versions as recent as 1.12 on GitHub, as in the entire decompiled source, including for mods or hacked clients which only modify a few classes, which are the only ones that should be there, hence why the EULA says that your mods should not contain a "substantial" amount of their code or assets (whatever that means; I've had people tell me that my own jar mods are illegal, but then so is this trivial Forge mod which copied a method from a vanilla class, with far fewer changes than the code I show above, or the base classes I've edited).
TheMasterCaver's First World - possibly the most caved-out world in Minecraft history - includes world download.
TheMasterCaver's World - my own version of Minecraft largely based on my views of how the game should have evolved since 1.6.4.
Why do I still play in 1.6.4?
Has it been 4 months since I last updated this? Man feels like it's been way longer. Pretty happy with the fact that new versions of minecraft don't break this either. Are people interested in the source code?
My Mods:
- Happy Coding -
Okay, maybe I spoke to soon about my code not breaking. I was working on an update for this tool from Windows Forms to using WPF and I ran into a few bugs, one that just made it stop working o.O Anyways, about done with a beta version that will offer some more features and improvements. One such feature is a search box that lets you search for obfuscated and deobfuscated names, something I tried and failed at last time along with an improvement on how mappings are selected.
Will be posting a download link in the next day or so to finish, fix and improve some things. Feedback is encouraged and some testers would be nice. Perhaps some suggestions on other tools. Do people want source?!
My Mods:
- Happy Coding -
And updated. The update is live. Find the link in the main post.
My Mods:
- Happy Coding -
The lite version gives me error 404
If I helped, or you just like my post, please press the button.
My mods...
Lite version - gives me corrupted archive (end of file).
Please fix the lite version download link
Would this be useful in deobfuscating net.minecraft.server itself? I've always been interested in playing around in NMS without using something like Spigot etc.
The server is more or less the same as the client since singleplayer runs on an integrated server which is the same as a dedicated server except with certain settings predefined (a major reason for the client-server merge in 1.3.1 was to simplify official updates, which also benefited mods); I've installed many of my own mods, all designed on the client, in the server jar without any issues when using it with Minecraft Land Generator to pregenerate a world (due to how I coded some things in they won't work in multiplayer; I use a static class to pass data from the server to the client, such as my "inventory stats", server-sided debug information like mob counts and server performance, or fixing client-side brightness during thunderstorms, but it would otherwise run since I don't directly access client-side code from the server-side; if you properly use networking this won't be an issue (e.g. the thunderstorm issue can easily be fixed by modifying the weather packet handler but I didn't want to modify another class just for that and I technically don't support multiplayer anyway).
TheMasterCaver's First World - possibly the most caved-out world in Minecraft history - includes world download.
TheMasterCaver's World - my own version of Minecraft largely based on my views of how the game should have evolved since 1.6.4.
Why do I still play in 1.6.4?
Man I sure hope this works.
This site's rules are too strict.
Glad to see that it still works (at least for me). No idea what happened to the lite version, it's not in my dropbox anymore, so I removed the link. Did it work for you @Pangamma?
My Mods:
- Happy Coding -