Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not mix up legacy client JSON formatting with modern one #12

Open
brawaru opened this issue Feb 28, 2021 · 0 comments
Open

Do not mix up legacy client JSON formatting with modern one #12

brawaru opened this issue Feb 28, 2021 · 0 comments

Comments

@brawaru
Copy link

brawaru commented Feb 28, 2021

Hello! I'm not sure whether this issue is related to the Fabric Meta project, but I think you'll be able to figure out where to redirect this.

Currently, Fabric uses a mix of old and modern formatting of the version JSON file.

GET https://meta.fabricmc.net/v2/versions/loader/1.16.5/0.11.2/profile/json:

{
  "id": "fabric-loader-0.11.2-1.16.5",
  "inheritsFrom": "1.16.5",
  "releaseTime": "2021-02-28T13:24:03+0000",
  "time": "2021-02-28T13:24:03+0000",
  "type": "release",
  "mainClass": "net.fabricmc.loader.launch.knot.KnotClient",
  "arguments": {
    "game": [
      
    ]
  },
  "libraries": [
    {
      "name": "net.fabricmc:tiny-mappings-parser:0.2.2.14",
      "url": "https://maven.fabricmc.net/"
    },
    ...
  ]
  ...
}

Here, it uses the arguments property, which is a modern formatting property, it is split for both game and jvm, legacy formatting only used minecraftArguments. But then, in libraries, it uses a simple combination from old formatting — name (library coordinates) + url (Maven repository URL).

The correct way to list libraries in modern formatting is by providing name (library coordinates) and:

  • downloads property, which is a map of downloads where the key is a classifier of the download. It supposed to be "artifact" for libraries downloads.

    Each ‘download’ has to contain:

    • path where the library is installed, relative to libraries folder;
    • sha1 — checksum of the library file, preferably created during the build process;
    • size — the size of the library file in bytes;
    • and url — full download URL of the library file.

Here's the example from the official Mojang launcher meta:

{
  "downloads": {
    "artifact": {
      "path": "oshi-project/oshi-core/1.1/oshi-core-1.1.jar",
      "sha1": "9ddf7b048a8d701be231c0f4f95fd986198fd2d8",
      "size": 30973,
      "url": "https://libraries.minecraft.net/oshi-project/oshi-core/1.1/oshi-core-1.1.jar"
    }
  },
  "name": "oshi-project:oshi-core:1.1"
}

The modern formatting is clearly superior as it is lacking this element of unpredictability — you're giving Minecraft launcher clear instructions on where to search for the library, where to download it, and what file to expect in return. It also gives Minecraft launcher the ability to check integrity of the library files before firing up the game.

Current legacy formatting allows for the following things to happen:

  • If Fabric sites get hijacked, attackers can put a fake library file that will be loaded and launched by the launcher, it then gets to do whatever JVM can do when run in the context of the user.

    Of course, with Fabric this can happen even with modern formatting because the client JSON is still downloaded from the remote resource during installation. Projects like Forge try to mitigate this issue by creating separate installers for each version, hosting client JSON within the installer itself.

  • In a case when the player has an unreliable internet connection, due to random disconnect or hiccup, a library file might be incorrectly downloaded. The launcher then has no way of checking its integrity besides checking whether it exists or not, and if it does, it will attempt to launch Minecraft with a broken set of libraries, causing the crash with a generic unhelpful message:

    Screenshot of Minecraft launcher error message: ‘Error! Game crashed. An unexpected issue occurred and the game has crashed. We're sorry for the inconvenience.’

    Even if the player will be able to access the launcher log, the only thing they'll see is:

    [Info: 2021-02-28 14:42:01.783255619: GameCallbacks.cpp(162)] Game/game () Info Error: Could not find or load main class
    

    This is a standard Java message, googling it provides close to zero helpful results to an unadvanced user.

  • [Added (might be recent change)] It seems that using mixed formatting also causes launcher to actually send additional requests every time game launches to retrieve .sha1 files for libraries (e.g. for net.fabricmc:tiny-mappings-parser:0.2.2.14 library it will retrieve tiny-mappings-parser-0.2.2.14.jar.sha1) to check their integrity. It might be a new feature, or there might be something to do with the launcher ignoring library with incorrect SHA-1 — previous point describes a real case, although it should be prevented by this point (weird!).

I hope this little bit of research brings some awareness to the consequences of using mixed legacy formatting in modern versions of the launcher. I hope Fabric will be able to follow the steps to resolve this issue by generating a modern client JSON during the build of the next Fabric versions, ensuring safety and a nice experience for the players.

@modmuss50 modmuss50 mentioned this issue Dec 15, 2023
16 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant