GolinksPRO Download Manager
  1. Startseite
  2. Hilfe
  3. Architektur

Architektur

How GolinksPRO Download Manager's pieces fit together.

Crates

Pfad Crate Rolle
crates/engine mdm-engine Lädt eine Datei über HTTP(S) oder FTP(S) herunter: Probe, Segmentplaner, Verbindungs-Worker, Wiederaufnahmezustand, Host-spezifische Limits, Geschwindigkeitsbegrenzer, Prüfsummen, Proxy-Skripte
crates/app mdm-app Die Desktop-App (misterdownloadmanager.exe, egui): Liste, Kategorien, Warteschlangen, Scheduler, Dialoge, Tray, Einstellungen
crates/cli mdm-cli Downloads ohne grafische Oberfläche mit Fortschritt (get, resume), Videos, Torrents und die Befehle der Automatisierungs-API: eine Bibliothek, die das Programm der App ausführt (misterdownloadmanager --cli …), und misterdownloadmanager-cli, ein kleiner Launcher, der sie mit denselben Argumenten, Terminal und Exit-Code startet
crates/mcp mdm-mcp Der MCP-Server (misterdownloadmanager-mcp): KI-Assistenten listen die Downloads der laufenden App auf, fügen sie hinzu und steuern sie über die Automatisierungs-API
crates/remote mdm-remote Fernzugriff (#141): der HTTPS-Server, den ein gekoppeltes Telefon oder ein Computer im lokalen Netzwerk verwendet (seine Seite, Kopplungscodes, Gerätetoken, das selbstsignierte Zertifikat); jede Anfrage wird zu einem Automatisierungs-API-Befehl, den die App beantwortet
crates/nmhost mdm-nmhost Der native Messaging-Host des Browsers: nimmt erfasste Downloads von der Erweiterung entgegen und übergibt sie an die App
crates/ipc mdm-ipc Der Single-Instance-Kanal (ein Token-geschützter lokaler Socket), der Datenordner und die Erfassungsregeln, die von der App und dem Host gemeinsam genutzt werden
crates/debrid mdm-debrid Debrid-Konten (#44): Die offiziellen APIs der Dienste (Real-Debrid, AllDebrid, Premiumize) wandeln einen Link eines Filehosters in einen direkten Link um, den die Engine herunterlädt.
crates/extract mdm-extract Archiv-Extraktion (#37): zip, tar, gz und xz im Prozess; 7z und RAR über ein installiertes 7-Zip, als eigenes Programm ausgeführt.
crates/geo mdm-geo Wo sich der Server eines Downloads befindet (#140): eine IP-zu-Land-Bereichstabelle, erstellt aus DB-IPs Lite-Daten (tools/geo/build.py), nur auf diesem Computer nachgeschlagen, und die Flaggen der Länder.
crates/tools mdm-tools Video pages through yt-dlp and ffmpeg, image galleries through gallery-dl (run as separate programs); while a network adapter is chosen, their connections go through a proxy of GDM's on 127.0.0.1 that binds them to it (relay.rs)
crates/crash mdm-crash Absturz- und Einfrierberichte: der Überwachungsprozess, Out-of-Process-Minidumps, symbolisierte Stacks, der Berichtstext und die Release-Logs (crash-reports.md)
crates/torrent mdm-torrent BitTorrent- und Magnet-Links über librqbit
crates/labserver mdm-labserver Ein HTTP-Range-Server mit einem Anforderungsprotokoll und Fehlerinjektion sowie ein FTP/FTPS-Server mit eigenen Fehlern für Tests und Benchmarks
extension/ — Die Chromium (MV3)- und Firefox-Erweiterung
docs/ — Die Bedienungsanleitung und Tutorials, diese Datei, die Benchmark-Daten; die Website macht die Anleitung zu ihren Hilfeseiten, die Hilfe öffnet
website/ — Die eigenen Seiten von misterdownloadmanager.com (Startseite, Download, Funktionen, Designs, FAQ); tools/website/build.py fügt die Hilfe von docs/ und die Neuigkeiten aus dem CHANGELOG in 22 Sprachen hinzu, und GitHub Pages veröffentlicht sie.

Abhängigkeiten zeigen nach innen: app, cli, mcp, nmhost und remote verwenden engine und ipc; die Engine weiß nichts von der UI. Die App sieht die Engine nur durch ihre Ereignisse (Fortschritt, Schnappschüsse der Segmenttabelle, abgeschlossen, fehlgeschlagen).

Engine

Download
 ├─ probe()              size, resumable?, validators (ETag / Last-Modified), file name
 ├─ Planner (pure)       segment table: when a connection is free, the largest remaining
 │                       part is split in half (planner.rs, tested by random simulation)
 ├─ Worker × N           one HTTP/1.1 connection each, reused across segments; slow ones
 │                       are dropped and their part re-split
 │    └─ writes at its offset into <name>.mdm.part (created sparse)
 ├─ HostLimits           learns how many connections each server accepts
 ├─ Limiter (shared)     per-download and global token buckets
 ├─ State                segment table saved atomically (craft-atomic) for crash-safe resume
 └─ events → channel     Progress, Done, Failed

Wenn alle Segmente abgeschlossen sind, wird die Part-Datei mit der erwarteten Größe abgeglichen und umbenannt; das Dateidatum kann dem des Servers folgen.

Die erste Anfrage eines Downloads (get) folgt Weiterleitungen und Seiten, die von selbst zu einer Datei führen (die Aktualisierung einer Warteseite). Websites, deren Links nicht die Adresse der Datei sind, haben ein Modul in sites/ (Google Drive: sites/gdrive.rs): Es wandelt den Link in die Adresse der Datei um, liest die eigenen Seiten der Website (ein Bestätigungsformular, eine Fehlerseite) und benennt deren Ablehnungen (Error::Refused), mit reinen Funktionen, die ohne Netzwerk getestet wurden. Der Laborserver spielt eine solche Website auf ihren echten Hostnamen für die End-to-End-Tests (labserver/src/drive.rs).

FTP und FTPS (ftp.rs) durchlaufen denselben Planer, dieselben Worker und denselben Zustand: Ein Segment ist REST + RETR auf einer Kontrollsitzung anstelle eines Bereichs- GET, SIZE und MDTM stehen für die Header, und Sitzungen werden pro Download gepoolt und zwischen Segmenten wiederverwendet.

App

Ein egui-Fenster, das auf feste Pixelkoordinaten gezeichnet wird, plus ein sofortiger Viewport pro Dialog. app.rs verwaltet den Zustand (Downloads, Warteschlangen, Einstellungen, die Auswahl der Liste) und wandelt Menü-, Symbolleisten-, Tastatur- und IPC-Befehle in Aktionen um. Jeder Dialog ist ein eigenes Modul und gibt ein Outcome zurück (offen, geschlossen, mit einem Wert abgeschlossen). Windows-spezifische Aufrufe sind auf win32.rs beschränkt und ihre Linux- und macOS-Pendants auf unix.rs (beginnend mit der Sitzung, dem Browser-Host, Sounds, im Ordner anzeigen, dem Absturz-Handler); jede andere Datei ist sicherer, portabler Rust-Code. Schriftarten stammen vom System: Windows-Schriftartenordner, macOS-Systemschriftarten, fontconfig unter Linux (theme.rs). Unter Windows wird lateinischer, griechischer und kyrillischer Text von DirectWrite im GDI-Classic-Modus gezeichnet (win32.rs, über egui's Glyph-Rasterizer-Hook), sodass die angedeutete Form und die Ganzpixelbreite jedes Buchstabens zusammenkommen; andere Schriften werden von egui geformt und gezeichnet.

Designs

Jede Farbe und Größe, mit der ein Steuerelement gezeichnet wird, stammt vom aktiven Design (#45). Ein Design ist eine helle und eine dunkle Palette, Metriken, Steuerelementstile und ein Icon-Stil (palette.rs):

  • Palettenrollen. palette.rs deklariert jede Rolle mit einem stabilen Schlüssel ("button.hot", "list.row", "caption"…), einer Beschreibung und den hellen und dunklen Werten des klassischen Aussehens, ausgeschrieben (das klassische Aussehen wird nicht abgeleitet). Die gemeinsamen Painter (winui.rs, chrome.rs, list.rs, scrollbar.rs) lesen sie über theme::colors() und theme::metrics() und entscheiden daraus die Zustände jedes Steuerelements; kein Zeichencode hält eine eigene Farbe.
  • Abgeleitete Paletten. derive.rs erstellt eine ganze Palette aus wenigen Ausgangsfarben (Hintergrund, Oberfläche, Text, Akzent…), mischt jede andere Rolle in OKLab und hält den WCAG-Kontrast (4,5:1 für Text, 3:1 für Kanten) ein; Hoher Kontrast verstärkt jede Kante zusätzlich. native.rs leitet das System-Design aus dem Akzent und Kontrast des Systems ab (Windows-Einstellungen, das freedesktop-Portal unter Linux, macOS-Akzent).
  • Control styles. palette::Controls names each control's shape (text boxes, check boxes, buttons, progress bars, scroll bars, the focus mark, the title bar); the style themes (Metro, Adwaita, Breeze, Luna, Aero, Aqua) pick theirs, and on Windows GDM then draws the title bar itself (the caption.* roles).
  • Design-Dateien. themefile.rs liest TOML oder JSON aus dem themes-Ordner (eine Datei oder <id>/theme.toml mit Icons daneben). Eine Datei benennt nur, was sie ändert; der Rest stammt vom Design, das sie inherits (die ID eines integrierten Designs oder eine andere Datei, standardmäßig das klassische Aussehen), entlang einer Kette, in der ein Zyklus abgelehnt wird. Unbekannte Schlüssel sind Warnungen, keine Fehler. Die integrierten Stil-Designs sind ebenfalls solche Dateien, die im Programm enthalten sind (crates/app/assets/themes).
  • Icon-Sets. themeicons.rs zeichnet die Icons eines Designs (benannt nach ihrem Zweck: tb-add-url, cat-music…, SVG oder PNG in 16, 24, 32 und 48 px, -symbolic-Icons in der Textfarbe eingefärbt), wo das klassische Aussehen seine eigenen zeichnet; ein Bedarf, den das Set nicht deckt, behält das klassische Icon bei.

Wo ein Fenster seine Steuerelemente platziert, bleibt sein Layout. Das gilt auch für die Icons vor Dateinamen (fileicons.rs): die System-Imagelisten der Windows-Shell, macOS Finders (NSWorkspace), das Icon-Design des Linux-Desktops (xdgicons.rs, shared-mime-info und die Icon Theme Specification). Jeder Typ wird einmal pro Pixelgröße in einem Hintergrund-Thread nachgeschlagen. Tangos Icons (gebündelt) dienen als Platzhalter, bis das System-Icon bereit ist, und überall dort, wo das System keines hat.

Zeichnen

The windows are drawn with OpenGL (eframe's glow) or with the system's own graphics API through eframe's wgpu, with that one backend only: Direct3D 12 on Windows (the default there), Vulkan on Linux, Metal on macOS (choices there; OpenGL stays their default until real graphics cards have tried them, #206). View → Draw with picks one, from the next start. One code path does it on every system (crates/app/src/renderer.rs): when the chosen one can't start, the other one is tried, so the windows always open. A watched start with the system's API leaves a marker until its first frame is drawn: a start that ends before it (a crash inside the driver), one whose first frame doesn't come within 10 seconds (GDM then starts again with OpenGL), or a graphics card lost twice in 10 minutes is remembered with its reason, which the menu shows.

Ansicht → Oberflächengröße (scale.rs, #262) ist der Zoomfaktor von egui über die eigene Skalierung des Displays: Jedes Fenster wird in Punkten angelegt, sodass es entsprechend größer geöffnet wird; ein Fenster, das größer als der Bildschirm ist, scrollt.

Daten

Die Download-Liste und die Einstellungen werden atomar im Datenordner gespeichert (downloads.json): %APPDATA%\misterdownloadmanager\ unter Windows, ~/.local/share/misterdownloadmanager unter Linux, ~/Library/Application Support/misterdownloadmanager unter macOS, ein data-Ordner neben einer portablen Kopie oder MDM_DATA_DIR (mdm_ipc::data_dir). Der Browser-Host liest dieselbe Datei für die Erfassungsregeln, sodass eine Änderung in den Optionen für den nächsten erfassten Download gilt.

Sign-in secrets (debrid accounts, Sites Logins' and the proxy's passwords) live in the system's keychain (secrets.rs, #44): Windows Credential Manager (win32.rs), the Secret Service on Linux or the macOS keychain (unix.rs). The settings keep a keychain:<service>/<scope>/<key> reference in their place, written only once the keychain has confirmed the secret; without a keychain (or with a locked one, never unlocked for GDM) the secret stays in the settings as before.

Der Serverstandort eines Downloads (#140) ist das Land der Adresse, mit der er verbunden war, nachgeschlagen in der Tabelle von mdm-geo auf diesem Computer (countries.rs benennt es in der Oberflächensprache); der Release-Job erstellt die Tabelle jeden Monat neu aus den Daten (tools/geo/build.py --release).

Browser-Integration

page ──► extension ──native messaging──► mdm-nmhost ──ipc──► app

Die Erweiterung fragt den Host, welche Dateitypen übernommen werden sollen, prüft jeden Download dagegen und bricht den Browser-Download erst ab, nachdem die App ihn akzeptiert hat; andernfalls behält der Browser ihn, und die Erweiterung erklärt, warum.

The host serves only GDM's own extension. Its IDs are in one place, mdm_ipc::extension (crates/ipc/src/extension.rs): the unpacked copy's (UNPACKED_ID, from the manifest's public key), the Chrome Web Store's (STORE_ID, signed with the store's own key: pack.ps1 leaves the manifest's key out of the store's copy), the Firefox add-on's (FIREFOX_ID) and its addons.mozilla.org page; the Edge and Opera stores' are placeholders, never served, until the extension is listed there. The host writes each browser's manifest with those IDs, and the app offers the store's copy (Add to Chrome, Add to Firefox) before the unpacked one.

Fernzugriff

phone ──HTTPS (paired token)──► mdm-remote ──ipc::Sink──► app (answer, remote_add)

--headless(headless.rs, #157) führt dasselbe App ohne eframe aus: Eine Schleife ruft dessen tick (was logic bei jedem Frame ausführt) auf einem nackten egui::Context auf, geweckt durch den Befehlskanal, und niemals dessen ui; Befehle werden hinzugefügt, wenn die Fernbedienung sie hinzufügt (kein Fenster). Die Dockerfile und docker/ (Compose, Unraid-Vorlage) führen es auf einem Server aus (server.md).

Der Server läuft auf der Tokio-Laufzeitumgebung der App, ein Listener pro lokaler Netzwerkadresse. Jede Anfrage wird geprüft (Host, Origin, Token), in ein mdm_ipc::Command umgewandelt, das als remote gekennzeichnet ist (ein Feld, das keine Anforderungszeile setzen kann), und über denselben Kanal wie die Befehlszeile an die App übergeben; die App beantwortet sie in ihrem nächsten Frame, so wie sie die Automatisierungs-API beantwortet. Ihre Seite ist eingebaut (crates/remote/web) und ihre Texte stammen aus den Katalogen der App (remote.rs).

Übersetzungen

Jeder Text, den die Benutzeroberfläche anzeigt, durchläuft crate::i18n (craft-i18n-Kataloge, i18n/<locale>.tsv). tools/i18n/extract.py erstellt i18n/en.tsv aus der Quelle neu, mit einem Hinweis für Übersetzer zu jedem Text (was er ist, wo er angezeigt wird, seine Platzhalter). tools/i18n/translate.py füllt, was den anderen Katalogen fehlt (Zeilen, die mit #, machine markiert sind), gemäß dem Stilhandbuch jeder Sprache (i18n/style/) und dem Glossar; eine von einer Person überprüfte Zeile wird niemals ersetzt, und CI (reviewed_guard.py) lässt eine Änderung fehlschlagen, die eine solche Zeile löscht. Die Website hat ihre eigenen Kataloge (i18n/site/, tools/website/translate_site.py).

Bilder

The help pages' pictures (docs/images/help/) come from one list, tools/shots/shots.toml: tools/shots/make.py opens each window through GDM's own /show <window> command line in a test instance off the screen, crops and annotates it from the window's accessibility tree, and writes lossless WebP; make.py check (CI) keeps the list, the pages and the files in step. The published ones are taken on GitHub's Windows runner (docs-shots.yml).

Mitwirkende

tools/contributors.pyliest von GitHubs öffentlicher API, wer Pull Requests und Issues geöffnet und wer kommentiert hat (der Maintainer, Claude und Bots ausgenommen), für jeden Ort, der ihnen dankt: die Startseite der Website, /contributors.html und jede Veröffentlichung auf der News-Seite (build.py, bei jedem Build), die Versionshinweise jeder Veröffentlichung (release.yml, die seit der vorherigen Veröffentlichung aktiven Personen) und die README (python tools/contributors.py readme bei der Vorbereitung jeder Veröffentlichung: ihre runden Fotos werden in art/contributors/ committet, da GitHub ein Bild in einer README nicht runden kann).

Tests und Benchmarks

cargo testführt Unit-Tests und End-to-End-Downloads gegen mdm-labserver mit injizierten Fehlern (langsame, abgebrochene und abgelehnte Verbindungen, Server ohne Bereiche, sich ändernde Dateien) aus. tools/bench führt den veröffentlichten Geschwindigkeitsvergleich aus; seine Rohdaten befinden sich in docs/bench/.

Kostenlos, Open Source, keine Werbung, keine Testversion.

Download GolinksPRO Download Manager