Skip to content
This repository was archived by the owner on Jan 17, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
35880cd
Use version manifest v2
mat-1 Jun 25, 2022
3c26e20
Update CFR
Tisawesomeness Oct 31, 2022
96e4abc
Merge branch 'Tisawesomeness/master'
queengooborg Oct 17, 2023
1a5597c
Have download_file throw an error instead of exit the program
queengooborg Oct 17, 2023
130ebf4
Ensure manifest.json stays downloaded for offline use
queengooborg Oct 17, 2023
633b2e5
Remove excessive use of sys.exit(-1); inverse if/else for simplicity
queengooborg Oct 17, 2023
33e0575
Update messages
queengooborg Oct 17, 2023
5174987
Handle exceptions better
queengooborg Oct 17, 2023
71288d4
Use relative path for get_latest_version()
queengooborg Oct 17, 2023
bfb443a
Merge remote-tracking branch 'upstream/master'
queengooborg Jul 13, 2024
dca9d55
Use pathlib paths for all file paths
queengooborg Jul 13, 2024
225516a
Ensure that parent directories exist when downloading files
queengooborg Jul 13, 2024
e77159a
Use str(var) instead of var.__str__()
queengooborg Jul 13, 2024
6e4b3d9
Fix path for manifest.json
queengooborg Jul 13, 2024
ec58c45
Update message
queengooborg Jul 13, 2024
e00058d
Use .get() to check if dictionary item exists
queengooborg Jul 15, 2024
90ee5d5
Consolidate code between interactive and non-interactive modes
queengooborg Jul 15, 2024
dc379ef
Introduce --interactive command line argument
queengooborg Jul 15, 2024
fc34a1c
Remove "delete dependencies" step
queengooborg Jul 15, 2024
e9af7d6
Remove "manual" mode altogether
queengooborg Jul 15, 2024
03c8193
Rename "removal_bool" to "clean" for consistency
queengooborg Jul 15, 2024
5c5239d
Cleanup variables and output
queengooborg Jul 15, 2024
e9585f3
Improve and simplify Java check function
queengooborg Jul 15, 2024
61d2504
Print full error traceback
queengooborg Jul 15, 2024
fd14830
Remove --forceno as an argument
queengooborg Jul 15, 2024
d7ea559
Update command line arguments
queengooborg Jul 15, 2024
290b4eb
Ensure all file paths are relative to main.py
queengooborg Jul 16, 2024
b3ee668
Don't wait for user action to finish program
queengooborg Jul 16, 2024
a6238f7
Quiet is not on by default
queengooborg Jul 16, 2024
2844581
Ensure SpecialSource and CFR output to relative paths
queengooborg Jul 16, 2024
0d42173
Make MC version a positional argument
queengooborg Jul 16, 2024
c4584a1
Simplify get_mappings()
queengooborg Jul 16, 2024
283efac
Don't reconvert mappings file if there is no need to
queengooborg Jul 16, 2024
3072f70
Re-download version_manifest.json if file is old
queengooborg Jul 7, 2025
7c298b5
Update readme
queengooborg Jul 7, 2025
779fd56
Merge remote-tracking branch 'upstream/master'
queengooborg Jul 7, 2025
eb4dce0
Update and simplify readme
queengooborg Jul 7, 2025
c1a933c
Add additional typedefs and fix formatting/typos
queengooborg Jul 7, 2025
6d94e41
Handle additional error types
queengooborg Jul 7, 2025
6f879bb
Fix a typo
queengooborg Jul 7, 2025
42794a0
Use built-in logger
queengooborg Jul 7, 2025
a674429
Remove user-input questions asked during execution
queengooborg Jul 7, 2025
a3af4cb
Remove now-redundant "quiet" variable across script
queengooborg Jul 7, 2025
b83040c
Merge branch 'hube12:master' into main
queengooborg Mar 26, 2026
3d6d9b1
Handle no obfuscation in Minecraft 26.1
queengooborg Mar 26, 2026
0c577e8
Update description
queengooborg Mar 26, 2026
0679031
Update SpecialSource
queengooborg Mar 26, 2026
4be8a9f
Fix a typo
queengooborg Jun 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 41 additions & 57 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,79 +1,63 @@
Archiving of the tool is in effect since Mojang released unobfuscated jar of both Minecraft client and server of Java edition.
Thanks for using this script, it still works for older version if you need it.
https://www.minecraft.net/en-us/article/removing-obfuscation-in-java-edition

> [!WARNING]
> [Since Minecraft 26.1](https://www.minecraft.net/en-us/article/removing-obfuscation-in-java-edition), this tool is no longer required and is not recommended for use in new modding projects.
>
> For convenience of developers still using this project in their workflow, this tool has been updated to skip the unneeded decompiling/deobfuscating steps and extract the contents of Minecraft 26.1+ .jar files directly.

# DecompilerMC

This tool automatically decompiles and remaps specific Minecraft versions. (Specifically, it converts Mojang's mappings from their proguard format to the tsrg format. SpecialSource then uses that and remaps the client jar, which is then decompiled either with CFR (code only) or Fernflower (assets and code).)

Your output will be readable/executable code similar to ModCoderPack or other decompilers.
This tool allows you to download and extract the source code for a specified Minecraft version for modding purposes. On applicable versions (1.14.4 to 1.21.11), it obtains the deobfuscation mappings provided by Mojang and applies them. It then decompiles the JAR and outputs the contents, providing readable/executable code similar to ModCoderPack or other decompilers.

## Prerequisites

You will need
- an Internet connection to download the mappings. You can obviously put them in the respective folder if you have them physically.
- Windows, MacOS, or Linux.
- A Java runtime inside your path (Java 8 should be good).
- An Internet connection (to download the mappings)
- Windows, macOS, or Linux
- Java 8 or higher
- Python 3.7 or higher

You can run this directly with Python 3.7+ with `python3 main.py`. CFR decompilation takes approximately 60s and fernflower takes roughly 200s. The code will then be inside the folder called `./src/<name_version(option_hash)>/<side>`; you can find the jar and the version manifest in the `./versions/` directory.
## Running

The `./tmp/` directory can be removed without impact.
Simply run `python3 main.py` in your terminal. You can also specify the following arguments and options:

There is a common release here: https://github.com/hube12/DecompilerMC/releases/latest for all versions.
```bash
usage: main.py [-h] [--interactive INTERACTIVE] [--side {client,server}] [--clean] [--force] [--decompiler {fernflower,cfr}] [--quiet]
[mcversion]

----
Decompile Minecraft source code

## Command-line Arguments (Optional)
You can use arguments instead of terminal-based choices. This is not required, but will automatically start if a mcversion is passed.
positional arguments:
mcversion The version you want to decompile (any version starting from 19w36a (snapshot) and 1.14.4 (releases)) Use 'snap' for
latest snapshot or 'latest' for latest version

```bash
usage: main.py [-h] [--mcversion MCVERSION] [--side SIDE] [--clean] [--force]
[--forceno] [--decompiler DECOMPILER] [--nauto]
[--download_mapping DOWNLOAD_MAPPING]
[--remap_mapping [REMAP_MAPPING]]
[--download_jar [DOWNLOAD_JAR]] [--remap_jar [REMAP_JAR]]
[--delete_dep [DELETE_DEP]] [--decompile [DECOMPILE]] [--quiet]

optional arguments:
options:
-h, --help show this help message and exit
--mcversion MCVERSION, -mcv MCVERSION
The version you want to decompile (all versions
starting from 19w36a (snapshot) and 1.14.4 (releases))
Use 'snap' for latest snapshot (20w48a for example, it will get it automatically) or 'latest'
for latest version (1.16.4 for example, it will get it automatically)
--side SIDE, -s SIDE The side you want to decompile (either client or
server)
--interactive, -i INTERACTIVE
Enable an interactive CLI to specify options (all other command line arguments, besides --quiet, will be ignored)
--side, -s {client,server}
Whether to decompile the client side or server side
--clean, -c Clean old runs
--force, -f Force resolve conflicts by replacing old files. (Use if a specific path is necessary)
--forceno, -fn Force resolve conflicts by creating new directories.
--decompiler DECOMPILER, -d DECOMPILER
Choose between fernflower and cfr.
--nauto, -na Choose between auto and manual mode.
--download_mapping DOWNLOAD_MAPPING, -dm DOWNLOAD_MAPPING
Download the mappings (only if auto off)
--remap_mapping [REMAP_MAPPING], -rmap [REMAP_MAPPING]
Remap the mappings to tsrg (only if auto off)
--download_jar [DOWNLOAD_JAR], -dj [DOWNLOAD_JAR]
Download the jar (only if auto off)
--remap_jar [REMAP_JAR], -rjar [REMAP_JAR]
Remap the jar (only if auto off)
--delete_dep [DELETE_DEP], -dd [DELETE_DEP]
Delete the dependencies (only if auto off)
--decompile [DECOMPILE], -dec [DECOMPILE]
Decompile (only if auto off)
--quiet, -q Doesn't display messages (recommended)
--force, -f Force resolving conflicts by replacing old files
--decompiler, -d {fernflower,cfr}
Select a copmiler to run
--quiet, -q Suppresses logging output
```

Examples:
- Decompile latest release without any output: `python3 main.py --mcv latest -q`
- Decompile latest snapshot server side with output: `python3 main.py --mcversion snap --side server`
- Decompile 1.14.4 client side with output and not automatic with forcing delete of old runs: `python3 main.py -mcv 1.14.4 -s client -na -f -rmap -rjar -dm -dj -dd -dec -q -c`
- Decompile latest snapshot server side with output: `python3 main.py snap --side server`
- Decompile 1.14.4 client side with output, cleaning up old runs: `python3 main.py 1.14.4 -s client -f -q -c`

----
CFR decompilation takes approximately 60s and fernflower takes roughly 200s. The code will then be inside the folder called `./src/<name_version(option_hash)>/<side>`; you can find the jar and the version manifest in the `./versions/` directory.

To build as an executable, the commands are
```python
pip install pyinstaller
The `./tmp/` directory can be removed without impact.

There is a common release here: https://github.com/hube12/DecompilerMC/releases/latest for all versions.

## Building Executable

To build DecompilerMC as an executable using `pyinstaller`, you can run the following:

```sh
pyinstaller main.py --distpath build --onefile
```

If you do not have `pyinstaller`, you can install it via `pip`: `pip install pyinstaller`
Binary file removed lib/SpecialSource-1.11.4.jar
Binary file not shown.
Binary file added lib/SpecialSource-1.11.6.jar
Binary file not shown.
Loading