Downloadbypass

A lightweight client-side helper that prompts players to download missing, external mod dependencies on first launch and installs them into the mods/ folder. It is designed for modpacks and servers that want a smoother onboarding experience without bundling third-party jars directly.

This page explains what the mod does, how the download flow works, and how to configure it using config/external-mods.json.


What it does

  • Prompts the player in-game when required mods are missing.
  • Downloads missing mods from multiple trusted sources:
    • CurseForge REST API (preferred if an API key is present) or Curse Maven fallback
    • GitHub Releases (public or private with token)
    • GitLab Releases (GitLab.com or self-hosted instances)
    • Modrinth (modern mod hosting platform)
    • Maven Repositories (Maven Central, Forge Maven, Fabric Maven, JitPack, custom repos)
    • Direct URLs (any HTTP/HTTPS download link with redirect support)
  • Verifies downloaded files by size and/or checksum before installing.
  • Installs the verified jars into the standard mods/ folder.
  • Remembers what it installed and offers a one-click cleanup button to remove auto-installed mods.
  • Skip tracking: If you decline an optional mod, it won't prompt again for 7 days.

Note: This mod is client-only. Mods are only loaded on the next game start after install.


How it works (high level)

  • On client setup, Downloadbypass checks config/external-mods.json for a list of external dependencies.
  • For each dependency that is not already installed, the player sees a confirmation prompt that shows the mod name and reason.
  • On approval, the mod resolves a download URL from the configured source (CurseForge, GitHub, GitLab, Modrinth, Maven, or direct URL) and downloads to a temporary *.part file.
  • Downloads support HTTP Range requests for automatic resume if interrupted.
  • After the download finishes and verification succeeds, the file is atomically moved to mods/<filename>.jar.
  • If any required dependency fails or is declined, the game exits with a helpful message.
  • Optional mods that are declined are tracked and won't prompt again for 7 days.

Why a mod like this?

  • Avoid shipping third-party jars in your distribution, while still guiding players to the correct files.
  • Ensure the exact intended artifact (file) is installed, matching the loader and game version you target.

Configuration file: config/external-mods.json

  • Location: config/external-mods.json (relative to the game directory).
  • Format: JSON with a schema version and a mods array.
  • Schema version currently supported: "1.0".

Minimal example

{
  "schema_version": "1.0",
  "mods": [
    {
      "name": "Example Mod",
      "slug": "example-mod",
      "curseforge_id": 123456,
      "file_id": 5678901,
      "version": "mc1.20.1",
      "required": true,
      "reason": "Required core library for the pack"
    }
  ]
}

Examples for all download sources

{
  "schema_version": "1.0",
  "mods": [
    {
      "name": "CurseForge Mod",
      "slug": "fancy-structures",
      "curseforge_id": 412345,
      "file_id": 4876543,
      "version": "1.20.1-forge",
      "required": true,
      "reason": "Provides worldgen used by the pack",
      "size_bytes": 3827465,
      "sha256_hash": "9b7f03da9c935e6e...<trimmed>...a3f2"
    },
    {
      "name": "GitHub Release Mod",
      "source": "github",
      "github_owner": "username",
      "github_repo": "my-mod",
      "github_tag": "v1.0.0",
      "github_asset_pattern": ".*-forge\\.jar$",
      "version": "1.20.1",
      "required": false,
      "sha256_hash": "abc123..."
    },
    {
      "name": "GitLab Mod",
      "source": "gitlab",
      "gitlab_host": "gitlab.com",
      "gitlab_project": "team/awesome-mod",
      "gitlab_tag": "v2.0.0",
      "version": "1.20.1",
      "required": false
    },
    {
      "name": "Modrinth Mod",
      "source": "modrinth",
      "modrinth_project_id": "AANobbMI",
      "modrinth_loader": "forge",
      "version": "1.20.1",
      "required": false,
      "reason": "Performance enhancement"
    },
    {
      "name": "Maven Artifact",
      "source": "maven",
      "maven_repository": "https://maven.minecraftforge.net/",
      "maven_group_id": "net.minecraftforge",
      "maven_artifact_id": "forge",
      "maven_version": "1.20.1-47.2.0",
      "maven_classifier": "universal",
      "required": true
    },
    {
      "name": "Direct Download",
      "source": "direct_url",
      "download_url": "https://example.com/mods/custom-mod.jar",
      "version": "1.20.1",
      "sha256_hash": "def456...",
      "required": false
    }
  ]
}

Fields (per mod entry)

  • name (string)
    • Human-readable mod name. Displayed in the in-game prompt.
  • slug (string)
    • CurseForge project slug. Also used to build the Curse Maven artifact path.
  • curseforge_id (integer)
    • CurseForge project ID (numeric). Required for resolution.
  • file_id (integer)
    • CurseForge file ID (numeric) that exactly identifies the intended artifact build.
    • Critical to select the correct loader (Forge) and game version (e.g., 1.20.1).
  • version (string)
    • Free-form informational string shown in logs. Commonly includes the Minecraft version.
    • The mod logs a warning if it doesn’t appear to match the current game version, but does not block installation.
  • required (boolean)
    • If true, the game will exit if the player declines install or if installation fails.
  • reason (string)
    • Short explanation shown to the player describing why the mod is needed.
  • size_bytes (integer, optional)
    • Expected file size used for a quick verification pass.
  • sha256_hash (string, optional)
    • Preferred cryptographic checksum verification. Use lowercase hex without delimiters.
  • md5_hash (string, optional)
    • Fallback checksum verification if SHA-256 is not provided.

Choosing the correct file_id

  • On the CurseForge project page, each file has:
    • A specific loader (Forge/Fabric/Quilt) and a game version tag (e.g., 1.20.1).
  • Always pick the Forge file for the exact game version you target.
  • Copy the numeric File ID from that file’s page and paste it as file_id.

If you accidentally point to a Fabric/Quilt file or a different Minecraft version, a startup crash is likely. Typical stack traces contain NoSuchFieldError or failed mixin injections involving vanilla classes.


Download sources and selection

  • If the environment variable CURSEFORGE_API_KEY is present, the mod prefers the CurseForge REST API to resolve the file’s metadata and download URL.
  • Without an API key, it tries known Curse Maven bases using the canonical path format:
    • https://www.cursemaven.com/curse/maven/<slug>-<projectId>/<fileId>/<slug>-<projectId>-<fileId>.jar
  • If Maven lookup fails or the project disallows third-party distribution, the mod falls back to the CurseForge API (some information may still be available without a key).

Respect project distribution policies and API rate limits. If a project prohibits third‑party hosting, Curse Maven will not serve the file.


Verification and safety

  • The download is written to a temporary *.part file.
  • Resume support: If download is interrupted, it will automatically resume from where it left off using HTTP Range requests (server support required).
  • After the transfer completes, the file is moved atomically to mods/<final>.jar (same volume), minimizing the chance of partial installs.
  • Verification stages:
    • Optional size check if size_bytes is provided.
    • Checksum verification (SHA‑256 preferred, MD5 as fallback) if provided.
  • If verification fails, the temporary file is removed, and the install is aborted.
  • Download caching: API responses are cached for 5 minutes to reduce repeated API calls.
  • Skip tracking: Declined optional mods are tracked for 7 days to avoid repeated prompts.

Mods are only picked up on the next game start. Installing during runtime does not affect the current session.

Security proxy and VirusTotal scanning

Downloadbypass now uses a mandatory secure proxy to gate all external downloads through a Supabase Edge Function with VirusTotal scanning.

  • Architecture
    • Client requests a signed URL via Supabase Edge Function request-download using a hardcoded project endpoint.
    • The function fetches the file server-side, computes sha256, checks a server blocklist, uploads to Supabase Storage, and records metadata.
    • VirusTotal flow:
      • First tries a VT hash lookup by sha256.
      • If found: evaluates against tolerance and returns a decision.
      • If not found: uploads the file to VT for analysis, inserts a scans row, and returns pending. The client then polls download-status until a final decision.
  • Tolerance rules
    • Sources from CurseForge/Modrinth domains allow up to 1 positive on VirusTotal.
    • All other sources require 0 positives.
  • Decisions and fields
    • Server responses include: status (ready/blocked/pending), decision, message, vt_positives, vt_total, vt_tolerance, and vt_report_url.
    • When approved, the response also includes a short-lived download_url (signed URL) and size.
  • Mandatory proxy
    • There is no direct-download fallback. If the proxy blocks or times out:
      • Required mods stop the game with a clear message.
      • Optional mods are skipped for this session.
  • UI improvements
    • The in-game prompt shows VirusTotal status, e.g. Security passed: VirusTotal 0/70 (tol 1).
    • When blocked, the prompt shows a descriptive reason including VT counts and offers a button to open the VirusTotal report.
  • Configuration
    • Client side does not need any environment variables for the proxy; the Supabase project endpoint is hardcoded and the proxy is always on.
    • Server side requires standard Supabase keys and a VIRUSTOTAL_API_KEY to enable scanning.

Player experience

  • On first launch, if dependencies are missing:
    • A prompt appears per mod with its name and reason.
    • A progress indicator shows download progress.
    • On success, the player is reminded to restart to load the new mods.
    • A secondary action allows removing all auto-installed jars if the player changes their mind.

Compatibility notes

  • Loader: Forge (client). The files you reference must be Forge builds.
  • Game version: Use file IDs that match the exact Minecraft version you support (e.g., 1.20.1).
  • If you see boot errors like NoSuchFieldError on vanilla classes, you likely selected the wrong loader or game version file ID.

Troubleshooting

The prompt never appears

  • Ensure config/external-mods.json exists and has schema_version set to "1.0".
  • Confirm there are entries in mods[].
  • Check if mod was previously declined (skip tracking). Delete config/downloadbypass/skipped-mods.json to reset.

Download fails immediately

  • Network connectivity: Check internet connection
  • Rate limiting: Set appropriate environment variables (GITHUB_TOKEN, GITLAB_TOKEN, CURSEFORGE_API_KEY)
  • Private repos: Ensure tokens have correct permissions
  • Third-party distribution: Some CurseForge projects disallow third-party hosting
  • Check logs for [EXTERNAL-MODS] messages with HTTP status codes

GitHub/GitLab specific issues

  • 404 Not Found: Verify repository path, release tag, or asset name pattern
  • 401/403 Unauthorized: Set GITHUB_TOKEN or GITLAB_TOKEN environment variable
  • No matching asset: Check github_asset_pattern or gitlab_asset_pattern regex

Modrinth issues

  • No versions found: Check if mod supports your Minecraft version and loader
  • Verify modrinth_loader matches your modpack (forge/fabric/neoforge)

Maven issues

  • Artifact not found: Verify Maven coordinates (group, artifact, version)
  • Check repository URL is correct and accessible
  • Try accessing the artifact URL directly in a browser

Startup crash after installing

  • Verify the installed jar is a Forge mod for the correct game version.
  • Open the jar as a zip. Forge mods typically contain META-INF/mods.toml. Fabric/Quilt mods contain fabric.mod.json or quilt.mod.json.
  • Check github_asset_pattern, modrinth_loader, or maven_classifier to ensure you're getting the Forge version

Verification fails

  • Ensure size_bytes or hashes match the actual file
  • For GitHub/GitLab, asset may have changed - verify hash with actual download
  • Remove the incorrect jar and restart to retry

Resume not working

  • Server must support HTTP Range requests (most do)
  • Check logs for "Resuming download from X bytes"
  • If server doesn't support resume, download will restart automatically

Best practices for pack authors

  • Always pin exact versions:
    • CurseForge: Use file_id for exact Forge+MC version
    • GitHub/GitLab: Use github_tag/gitlab_tag instead of latest
    • Modrinth: Use modrinth_version_id for specific versions
    • Maven: Use exact maven_version strings
  • Always provide sha256_hash for integrity verification.
  • Keep required to true only for hard requirements.
  • Write clear reason messages so players understand why each dependency is needed.
  • Use source field explicitly to avoid auto-detection ambiguity.
  • Test with all sources in a clean instance before release.
  • For private mods, provide documentation on setting environment variables (GITHUB_TOKEN, GITLAB_TOKEN).
  • Consider using Maven repositories for internal/company mods for better reliability.
  • Use Modrinth when possible for modern mods (better API, no rate limiting).

Environment variables

All environment variables are optional but recommended for better rate limits and reliability:

  • CURSEFORGE_API_KEY

    • Enables CurseForge API-first resolution
    • Improves reliability and speed for CurseForge downloads
  • GITHUB_TOKEN

    • GitHub personal access token
    • Increases rate limit from 60 to 5000 requests/hour
    • Required for private repositories
  • GITLAB_TOKEN

    • GitLab private access token
    • Enables access to private projects
    • Increases rate limits on self-hosted instances

Do not hardcode keys into public packs. Use documentation to instruct players/launchers to supply keys if needed.


Project members

Bobcat

Member

Details

Licensed MIT
Published 16 days ago
Updated 15 days ago