Chat about this codebase

AI-powered code exploration

Online

1. Project Overview

A lightweight, Java-based Minecraft launcher that simplifies account management and keeps your game up to date. OLauncher handles Microsoft authentication, bundled JVM selection, and patch-based updates—all under a CC0 public-domain dedication. Note: the project is currently on indefinite hiatus.

Purpose

Provide a drop-in replacement for the official Minecraft launcher that:

  • Authenticates via Microsoft OAuth-2.0
  • Manages bundled JVMs for cross-platform compatibility
  • Checks for and applies updates to game assets and patches

Main Features

  • Microsoft account login (Xbox Live, XSTS, Minecraft token exchanges)
  • Automatic JVM discovery and selection
  • Update checks against a custom server or GitHub Releases
  • Patch-based modding support via Git-driven workflows

Quick Start

  1. Download the latest JAR from Releases:
    wget https://github.com/olauncher/olauncher/releases/download/v1.2.3/olauncher-1.2.3.jar
    
  2. Launch the UI:
    java -jar olauncher-1.2.3.jar
    
  3. Click “Log In with Microsoft” and follow the browser-based flow.
  4. Select or install a bundled JVM when prompted.
  5. Choose your Minecraft version and click “Play.”

License

This repository dedicates all contents to the public domain under Creative Commons CC0 1.0 Universal. Include in your README or website:

## License
This project is dedicated to the public domain under CC0 1.0 Universal.  
See [COPYING.txt](https://github.com/olauncher/olauncher/blob/master/COPYING.txt) for full text.

Funding

Configure GitHub’s “Sponsor” button via .github/FUNDING.yml:

# .github/FUNDING.yml
github: bigfoot547

After pushing, visitors see a “Sponsor” button linking to GitHub Sponsors for bigfoot547.

Maintenance Status

The project is on indefinite hiatus.
• No new features planned
• Bug fixes only via community pull requests
• Use at your own risk and consider forking if you need active development

2. Quick Start (Binary Users)

This section shows how to download and launch the prebuilt OLauncher JAR and apply common runtime customizations using JVM system properties.

Prerequisites

  • Java Runtime Environment (JRE) 8 or higher installed
  • Internet access for Microsoft authentication and update checks

Download the Prebuilt Launcher

  1. Visit the latest release on GitHub:
    https://github.com/olauncher/olauncher/releases
  2. Download the redistributable JAR named:
    olauncher-<version>-redist.jar

Launching the Launcher

Run the launcher with your system’s default Java:

java -jar olauncher-<version>-redist.jar

The UI will prompt for Microsoft account login and display the News tab.

Customizing Runtime Options

Override defaults by passing -D system properties before -jar.

Custom Window Title

Replaces the default <LauncherName> <Version><Environment> title:

java \
  -Dnet.minecraft.launcher.WindowTitle="My Custom Launcher" \
  -jar olauncher-<version>-redist.jar

Custom News URL

Point the News tab to your own endpoint:

java \
  -Ddev.figboot.olauncher.URLNews="https://mycompany.com/minecraft-news" \
  -jar olauncher-<version>-redist.jar

Combining Multiple Flags

Apply several overrides in one command:

java \
  -Dnet.minecraft.launcher.WindowTitle="Team Build" \
  -Ddev.figboot.olauncher.URLNews="https://news.example.org" \
  -jar olauncher-<version>-redist.jar

Updating the Launcher

When a new release is available:

  1. Download the updated olauncher-<new-version>-redist.jar.
  2. Replace the old JAR with the new one.
    Your authentication tokens and settings persist across upgrades.

3. Building From Source

Reproduce the full OLauncher build from scratch: decompile the vanilla launcher, initialize a Git repo, apply patches, compile, and generate a redistributable JAR.

Prerequisites

• Git (with submodule support)
• Bash, curl, jar (from JDK)
• JDK 8+ (set JAVA_HOME)
• Maven 3+
• tools/fernflower.jar in tools/


3.1 Clean the Workspace

Remove all previous artifacts and temp files.

chmod +x clean.sh
./clean.sh
# Deletes work/, launcher/, olauncher/, genredist/, target/

3.2 Decompile the Vanilla Launcher

Download and decompile the official launcher JAR into work/decomp/.

chmod +x decompile.sh
./decompile.sh
# Outputs raw .java sources under work/decomp/
# Edit the URL constant in decompile.sh if the upstream JAR URL changes.

3.3 Initialize a Git Repository

Turn the decompiled sources into a clean Git history on branch original.

chmod +x init.sh
./init.sh
# Creates launcher/ as a new repo, commits all sources to branch "original"

3.4 Apply OLauncher Patches

Clone launcher/ into olauncher/, reset to upstream, and apply all .patch files.

chmod +x applyPatches.sh
./applyPatches.sh launcher olauncher
# launcher-patches/*.patch → olauncher/
# On success: “Patches applied cleanly to olauncher!”

If you omit args (defaults), the script clones launcherolauncher and picks patches from launcher-patches/.


3.5 Compile with Maven

Build the patched launcher; output lands in olauncher/target/.

cd olauncher
mvn clean package -DskipTests
# Produces olauncher-<version>.jar, shaded and resource-filtered via pom.xml

3.6 Generate the Redistributable JAR

Bundle native libs, assets and JVM-downloader into a single -redist artifact.

cd ..
chmod +x genredist.sh
./genredist.sh
# Outputs olauncher-<version>-redist.jar → genredist/
# Only this JAR may be redistributed.

3.7 (Optional) Update JRE Manifest

Fetch the latest JRE manifest URL used by upstream launcher.

chmod +x maintain.sh
./maintain.sh getJREManifest
# Prints the JSON manifest URL for use in custom launcher setups

Practical Tips

• Automate CI with:

./clean.sh \
 && ./decompile.sh \
 && ./init.sh \
 && ./applyPatches.sh \
 && cd olauncher && mvn clean package -DskipTests \
 && cd .. && ./genredist.sh

• To add new patches, drop numbered .patch files into launcher-patches/ and re-run applyPatches.sh.
• Adjust JVM bundles or download URLs in AutoOL/config.json before genredist.sh.
• If patches fail, re-decompile or sync your patch offsets.

4. Core Concepts & Features

This section covers the major functional areas introduced or enhanced by OLauncher. Each subsection explains key classes, configuration points, and actionable code examples.

4.1 Microsoft Authentication Support

OLauncher adds full Microsoft account integration, including both embedded-browser OAuth and the device-code flow for headless environments.

4.1.1 Embedded-Browser OAuth Flow

Key classes:

  • MicrosoftAuthenticationService – creates MicrosoftUserAuthentication instances.
  • MicrosoftUserAuthentication – handles standard OAuth: logIn(), refresh(), logOut().
  • UI components under com.mojang.launcher.ui.login.microsoft.

Usage:

Proxy proxy = Proxy.NO_PROXY;
MicrosoftAuthenticationService service = new MicrosoftAuthenticationService(proxy, clientToken);
MicrosoftUserAuthentication auth = (MicrosoftUserAuthentication)
    service.createUserAuthentication(Agent.MINECRAFT);
auth.logIn();  // opens browser, handles redirect
System.out.println("Token: " + auth.getAuthenticatedToken());

4.1.2 Device Code Authentication

Essential classes/methods:

  • MicrosoftUserAuthentication.startDeviceAuth()MSDeviceCodeResponse
  • MicrosoftUserAuthentication.checkDeviceAuth(deviceCode)MSDeviceCodeHeartbeatResponse
  • MicrosoftUserAuthentication.setDeviceLoginResponse(...)
  • DeviceCodeDialog – Swing dialog automating polling and prompting.

Console example:

var proxy = Proxy.NO_PROXY;
var service = new MicrosoftAuthenticationService(proxy, clientToken);
var auth = (MicrosoftUserAuthentication) service.createUserAuthentication(Agent.MINECRAFT);

// 1. Start device flow
MSDeviceCodeResponse resp = auth.startDeviceAuth();
System.out.println(resp.getMessage());  // "Go to ... and enter CODE"

// 2. Poll until authorized
MSDeviceCodeHeartbeatResponse hb;
while (true) {
  hb = auth.checkDeviceAuth(resp.getDeviceCode());
  if (hb.getAccesToken() != null) break;
  Thread.sleep(resp.getInterval() * 1000L);
}

// 3. Complete login
auth.setDeviceLoginResponse(hb);
auth.logIn();
System.out.println("Logged in: " + auth.getSelectedProfile().getName());

UI example:

new DeviceCodeDialog(auth, heartbeat -> {
  auth.setDeviceLoginResponse(heartbeat);
  try { auth.logIn(); }
  catch (AuthenticationException e) { /* handle */ }
});

Practical tips:

  • Run polling off the EDT (e.g. ScheduledExecutorService).
  • Respect getInterval() between polls.
  • On errors (authorization_pending, expired_token), inspect getError() and getErrorDescription().

4.2 Bundled Java Runtime Support

OLauncher can download and manage its own Java runtimes, removing the need for a local Java install.

Initialization

// OLauncherConstants.JRE_MANIFEST_URL → Mojang manifest endpoint
JavaRuntimeManager jreManager = new JavaRuntimeManager(
    OLauncherConstants.JRE_MANIFEST_URL,
    proxy, workDir);

Refresh available runtimes

launcher.getJreManager().getExecutorService().submit(() -> {
    try { launcher.getJreManager().reloadRuntimes(); }
    catch (Throwable t) { LOGGER.error("Failed fetching JRE list", t); }
});

Launching with bundled JRE

boolean bundledRuntime = profile.getJavaPath() == null;
gameRunner.playGame(versionInfo, bundledRuntime);

In AbstractGameRunner.playGame(...):

  1. ensureRuntime() downloads/verifies the JRE.
  2. Sets bundledRuntimeDir to <workDir>/olruntime/.../java[.exe].
  3. Uses that path when spawning the game process.

Practical guidance:

  • Leave profile’s Java path blank to enable bundled JRE.
  • Runtimes cache under <workDir>/olruntime/<platform>/<component>/.
  • Delete a component folder to force redownload.

4.3 Launcher Update Checker

Automatically queries GitHub for new releases, persists state, and prompts users.

Initialization

LauncherUpdateChecker checker = new LauncherUpdateChecker();
checker.loadInfo();      // reads or creates olauncher_update.json
checker.updateCheck();   // triggers immediate or scheduled check

Key methods

  • loadInfo() – loads JSON state: lastCheck, ignoreVersions, disabled, latestRelease.
  • updateCheck() – skips if disabled or recently checked; else spawns background query.
  • queryReleases() – GETs https://api.github.com/repos/olauncher/olauncher/releases/latest, parses into ReleaseInfo, persists and calls onReleaseResponse().
  • ignoreUpdate(long id) / setDisabled(boolean) – update state and call saveInfo().

State file (olauncher_update.json):

{
  "lastCheck": "2025-07-11T12:34:56Z",
  "ignoreVersions": [12345678],
  "disabled": false,
  "latestRelease": {
    "id": 12345678,
    "tag_name": "v1.2.3",
    "html_url": "https://github.com/olauncher/olauncher/releases/tag/v1.2.3",
    "assets": [ /* ... */ ]
  }
}

User prompt

UpdateAvailableDialog offers:

  • Download redist JAR
  • Open release page
  • Remind later
  • Ignore this version
  • Disable future checks

Testing:

java -Ddev.figboot.olauncher.LauncherUpdateChecker.updateTest=true -jar olauncher.jar

4.4 Custom Window Title

Patch 0020 adds net.minecraft.launcher.WindowTitle system property.

Usage:

java -Dnet.minecraft.launcher.WindowTitle="My Custom Launcher" -jar olauncher.jar

If unset, windows show default: version (environment). Developers can override programmatically:

System.setProperty("net.minecraft.launcher.WindowTitle", "Dev Build");
new Launcher(...).show();

4.5 Legacy Version & Asset Support

OLauncher can launch very old Minecraft versions (pre-1.6.2) that use a resources/ directory and handles updated native-library syntax for modern mods.

4.5.1 Map-to-resources flag

In AssetIndex JSON:

{ "map_to_resources": true, /* other fields */ }

In runner:

File targetDir = index.mapToResources()
    ? new File(profile.getGameDir(), "resources")
    : new File(profile.getGameDir(), "assets");
// Copy each asset if missing or SHA1-mismatch
if (needsCopy(out, expectedHash)) {
    FileUtils.copyFile(in, out, false);
}

needsCopy() checks existence and verifies SHA1.

4.5.2 Native classifier parsing

Library now splits coordinates on up to 4 segments:

String[] parts = name.split(":", 4);
String filename = parts.length < 4
    ? String.format("%s-%s%s.jar", parts[1], parts[2], suffix)
    : String.format("%s-%s%s-%s.jar",
        parts[1], parts[2], suffix, parts[3]);

Supports group:artifact:version:classifier (e.g. natives-windows).

4.5.3 Forge compatibility tweaks

  • Exposes ${library_directory} pointing to <workDir>/libraries:
    variables.put("library_directory",
        new File(launcher.getWorkingDirectory(), "libraries").getAbsolutePath());
    
  • Treats empty compatibilityRules array same as null (always allowed).

Practical tip:

  • Add "map_to_resources": true to legacy asset indexes to rebuild resources/ once and reuse.

5. Architecture & Patch Index

Provides a structured overview of the olauncher patch set, its layout, intent and inter-dependencies. Use this index to add, reorder or refactor patches safely.

5.1 Patch Directory Structure

All patches live in the olauncher-patches/ folder at the repo root.

  • Naming convention:
    <NNNN>-<short-description>.patch
    where NNNN is a zero-padded sequence number.
  • Application order: sorted by NNNN ascending.
  • Patch metadata: add an optional Depends-On: YYYY tag in the header to document cross-patch constraints.

Example:

olauncher-patches/
├── 0001-fix-window-resize.patch
├── 0002-add-custom-shortcuts.patch
└── 0003-swatch-theme-support.patch

5.2 Patch Index

Use this table as a quick reference. Update it whenever you add, remove or change patches.

Seq Filename Description Depends On
0001 0001-fix-window-resize.patch Corrects Wayland window‐resize logic
0002 0002-add-custom-shortcuts.patch Exposes user‐configurable key bindings 0001
0003 0003-swatch-theme-support.patch Enables dynamic theme swatches

5.3 applyPatches.sh

Automates cloning or refreshing olauncher, resetting to upstream master, and applying every patch in olauncher-patches/.

Usage

# Clone or update a working copy into 'olauncher-dev'
./applyPatches.sh path/to/olauncher olauncher-dev

Parameters:

  • $1 = path or URL of the upstream olauncher repo
  • $2 = target directory for the patched clone

What it does:

  1. If olauncher-dev exists, reuses it; otherwise, creates it.
  2. Adds upstream remote pointing at $1.
  3. Resets olauncher-dev to upstream/master.
  4. Runs git am --3way olauncher-patches/*.patch.

Exit codes:

  • 0 – all patches applied cleanly
  • 1 – aborts on first conflict (git am --abort)

5.4 rebuildPatches.sh

Regenerates olauncher-patches/ from commits in your working copy, pruning any empty diffs.

Usage

# After committing changes in olauncher-dev:
./rebuildPatches.sh path/to/olauncher olauncher-dev

Workflow:

  1. Ensures olauncher-patches/ exists.
  2. In olauncher-dev, runs:
    git format-patch --no-stat -N origin/HEAD \
      -o ../olauncher-patches
    
  3. Removes any .patch where diff vs. HEAD is empty.
  4. Leaves numbered, non-empty patches ready for review and commit.

5.5 Managing Patch Dependencies

  • Sequence numbers enforce primary order.

  • When a patch relies on another’s changes, tag its header:

    From: Jane Doe <jane@example.com>
    Subject: [PATCH 0004] Add swipe gesture support
    Depends-On: 0002
    
  • applyPatches.sh applies strictly by file name order; ensure Depends-On references a lower sequence.

--end of Section 5--

6. Contribution Guide

This section covers how to report issues, submit code or patch contributions, follow coding conventions, and release new builds for OLauncher.

6.1 Issue Reporting & Funding

Report bugs and request features on our GitHub issue tracker. Include:

  • A concise title.
  • Steps to reproduce.
  • Stack traces or logs (olauncher.log in %USER_HOME%/.olauncher/logs).

Issue URL
https://github.com/olauncher/olauncher/issues/new

Funding
We accept sponsorships via GitHub Sponsors. Visit:
https://github.com/sponsors/bigfoot547
Contributions help cover hosting and development costs.

6.2 Submitting Code & Patches

Working with launcher-patches/

We apply upstream fixes and customizations as Git-format patch files in launcher-patches/. Use rebuildPatches.sh to regenerate or clean patches.

  1. Clone side-by-side directories
    git clone https://github.com/Minecraft/launcher.git launcher
    git clone https://github.com/olauncher/olauncher.git olauncher
    
  2. Regenerate patches
    cd <repo-root>
    ./rebuildPatches.sh launcher olauncher
    git add launcher-patches/*.patch
    git commit -m "Refresh patches from olauncher"
    
  3. Apply patches before build
    Applied automatically on CI; locally run:
    cd olauncher
    bash applyPatches.sh
    
  4. Verify each patch contains only meaningful diffs. Empty patches are removed automatically.

Submitting a Pull Request

  1. Fork olauncher/olauncher and create a feature branch.
  2. Implement your changes in src/.
  3. Update or add a patch under launcher-patches/ if modifying decompiled sources.
  4. Run tests and build locally:
    mvn clean verify
    bash genredist.sh
    
  5. Push your branch and open a PR against master. Reference relevant issue numbers.

6.3 Coding Conventions

  • Java 11, Maven-based project.
  • Indent with 4 spaces; no tabs.
  • Follow Google Java Style:
    • Class names in PascalCase.
    • Method/variable names in camelCase.
    • Constants in UPPER_SNAKE_CASE.
  • Document public classes and methods with Javadoc.
  • Annotate overrides with @Override.
  • Keep lines ≤ 100 characters.
  • Write unit tests under src/test/java using JUnit 5.
  • Before committing, run:
    mvn fmt:format   # if using fmt plugin
    mvn clean verify
    

6.4 Release Process

We automate builds and draft releases via GitHub Actions defined in .github/workflows/build.yml.

Tagging a Release

  1. Bump version in pom.xml.
  2. Commit and tag:
    git commit -am "Release v1.2.3"
    git tag v1.2.3
    git push origin master --tags
    
  3. The CI pipeline will:
    • Build and test on JDK 11.
    • Generate olauncher-<version>-redist.jar.
    • Upload artifact and draft a GitHub release named v1.2.3.

Manual Release Verification

Download the draft release artifacts, then test locally:

gh release download v1.2.3 --dir test-reld
java -jar test-reld/olauncher-1.2.3-redist.jar

Confirm launcher starts, authentication works, and update checks complete without errors.

For publishing to Maven Central or other registries, extend the CI workflow with a new job after build that uses mvn deploy with proper credentials in secrets.