GolinksPRO Download Manager
  1. 홈
  2. 도움말
  3. 아키텍처

아키텍처

How GolinksPRO Download Manager's pieces fit together.

크레이트

경로 크레이트 역할
crates/engine mdm-engine HTTP(S) 또는 FTP(S)로 파일 하나를 다운로드합니다. 연결 확인, 세그먼트 계획, 연결 작업자, 재개 상태, 호스트별 제한, 속도 제한, 체크섬, 프록시 스크립트를 처리합니다.
crates/app mdm-app 데스크톱 앱(misterdownloadmanager.exe, egui): 목록, 카테고리, 대기열, 스케줄러, 대화 상자, 시스템 트레이, 설정
crates/cli mdm-cli 진행 상황을 표시하는 헤드리스 다운로드(get, resume), 비디오, 토렌트 및 자동화 API 명령을 처리합니다. 앱 프로그램이 실행하는 라이브러리(misterdownloadmanager --cli …)와 동일한 인수로 실행되어 터미널과 종료 코드를 공유하는 작은 실행 프로그램인 misterdownloadmanager-cli로 구성됩니다.
crates/mcp mdm-mcp MCP 서버(misterdownloadmanager-mcp): AI 비서가 자동화 API를 통해 앱에서 실행 중인 다운로드를 조회하고, 추가하고, 제어합니다.
crates/remote mdm-remote 원격 제어(#141): 로컬 네트워크에서 페어링된 휴대폰이나 컴퓨터가 사용하는 HTTPS 서버(해당 페이지, 페어링 코드, 장치 토큰, 자체 서명된 인증서); 모든 요청은 앱이 응답하는 자동화 API 명령이 됩니다.
crates/nmhost mdm-nmhost 브라우저의 네이티브 메시징 호스트: 확장 프로그램에서 가로챈 다운로드를 받아 앱으로 전달합니다.
crates/ipc mdm-ipc 단일 인스턴스 채널(토큰으로 보호되는 로컬 소켓), 데이터 폴더, 앱과 호스트가 공유하는 다운로드 가로채기 규칙
crates/debrid mdm-debrid Debrid 계정(#44): 서비스의 공식 API(Real-Debrid, AllDebrid, Premiumize)가 파일 호스트 링크를 엔진이 다운로드하는 직접 링크로 변환합니다.
crates/extract mdm-extract 압축 파일 추출(#37): zip, tar, gz, xz는 처리 중이며, 7z 및 RAR은 설치된 7-Zip을 자체 프로그램으로 실행하여 처리합니다.
crates/geo mdm-geo 다운로드 서버 위치(#140): DB-IP Lite 데이터(tools/geo/build.py)로 구축된 IP-국가 범위 테이블을 이 컴퓨터에서만 조회하며, 해당 국가의 국기를 표시합니다.
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 충돌 및 멈춤 보고서: 모니터 프로세스, 별도 프로세스에서 생성하는 미니덤프, 심볼을 표시한 스택, 보고서 텍스트 및 릴리스 로그(crash-reports.md)
crates/torrent mdm-torrent librqbit을 통한 BitTorrent 및 마그넷 링크 처리
crates/labserver mdm-labserver 요청 로그와 오류 주입 기능이 있는 HTTP Range 서버, 자체 오류 주입 기능이 있는 FTP/FTPS 서버. 테스트 및 벤치마크용입니다.
extension/ — Chromium (MV3) 및 Firefox 확장 프로그램
docs/ — 사용자 가이드와 튜토리얼, 이 파일, 벤치마크 데이터. 웹사이트는 가이드를 도움말 페이지로 제공하며, 도움말에서 열 수 있습니다.
website/ — misterdownloadmanager.com의 자체 페이지(홈, 다운로드, 기능, 테마, FAQ); tools/website/build.py은 docs/의 도움말과 CHANGELOG의 소식을 22개 언어로 추가하며, GitHub Pages에서 게시합니다.

종속성은 내부를 향합니다: app, cli, mcp, nmhost 및 remote는 engine 및 ipc을 사용합니다. 엔진은 UI에 대해 아무것도 모릅니다. 앱은 엔진의 이벤트(진행 상황, 세그먼트 테이블 스냅샷, 완료됨, 실패함)를 통해서만 엔진을 봅니다.

엔진

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

모든 세그먼트가 완료되면 부분 파일의 크기가 예상 크기와 일치하는지 확인한 뒤, 파일 이름을 바꿔 최종 위치에 저장합니다. 파일 날짜는 서버의 날짜를 따를 수 있습니다.

다운로드의 첫 요청(get)은 리디렉션과 파일로 이어지는 페이지(대기 페이지의 새로 고침 등)를 자동으로 따라갑니다. 링크가 파일 주소가 아닌 사이트는 sites/에 전용 모듈이 있습니다(Google Drive: sites/gdrive.rs). 이 모듈은 링크를 파일 주소로 바꾸고, 확인 양식이나 오류 페이지 같은 사이트 자체 페이지를 읽으며, 다운로드 거부 사유(Error::Refused)를 분류합니다. 순수 함수는 네트워크 없이 테스트합니다. 테스트용 랩 서버는 실제 호스트 이름을 사용해 해당 사이트처럼 동작합니다(labserver/src/drive.rs).

FTP 및 FTPS(ftp.rs)도 같은 계획 수립, 작업자 및 상태를 사용합니다. 세그먼트는 범위 요청 GET 대신 제어 세션에서 REST + RETR로 처리합니다. 헤더 대신 SIZE 및 MDTM을 사용하고, 세션은 다운로드별로 풀링해 세그먼트 간에 재사용합니다.

앱

고정된 픽셀 좌표에 그려지는 하나의 egui 창과 대화 상자당 하나의 즉시 뷰포트가 있습니다. app.rs는 상태(다운로드, 대기열, 설정, 목록 선택)를 유지하고 메뉴, 도구 모음, 키 및 IPC 명령을 작업으로 전환합니다. 각 대화 상자는 자체 모듈이며 Outcome(열림, 닫힘, 값으로 완료됨)를 반환합니다. Windows 전용 호출은 win32.rs에, Linux 및 macOS 호출은 unix.rs에 제한됩니다(세션 시작, 브라우저 호스트, 소리, 폴더에 표시, 충돌 처리기). 다른 모든 파일은 안전하고 이식 가능한 Rust입니다. 글꼴은 시스템에서 가져옵니다. Windows의 글꼴 폴더, macOS의 시스템 글꼴, Linux의 fontconfig(theme.rs). Windows에서는 라틴어, 그리스어, 키릴어 텍스트가 GDI-클래식 모드의 DirectWrite(win32.rs, egui의 글리프 래스터라이저 후크를 통해)로 그려지므로 각 문자의 힌트 모양과 전체 픽셀 너비가 함께 나타납니다. 다른 스크립트는 egui로 모양이 지정되고 그려집니다.

테마

컨트롤이 그려지는 모든 색상과 크기는 활성 테마(#45)에서 가져옵니다. 테마는 밝고 어두운 팔레트, 측정 기준, 컨트롤 스타일 및 아이콘 스타일(palette.rs)로 구성됩니다.

  • 팔레트 역할. palette.rs은 안정적인 키("button.hot", "list.row", "caption"…), 설명, 그리고 클래식 모양의 밝고 어두운 값을 명시적으로 선언합니다(클래식 모양은 파생되지 않음). 공유 페인터(winui.rs, chrome.rs, list.rs, scrollbar.rs)는 theme::colors()과 theme::metrics()을 통해 이들을 읽고 각 컨트롤의 상태를 결정합니다. 페인팅 코드 자체는 색상을 보유하지 않습니다.
  • 파생 팔레트. derive.rs은 몇 가지 시드(배경, 표면, 텍스트, 강조색 등)에서 전체 팔레트를 생성하며, OKLab에서 다른 모든 역할을 혼합하고 WCAG 대비(텍스트 4.5:1, 가장자리 3:1)를 유지합니다. 고대비는 모든 가장자리를 더욱 강조합니다. native.rs은 시스템의 강조색과 대비(Windows 설정, Linux의 freedesktop 포털, macOS의 강조색)를 사용하여 기본 테마를 시드합니다.
  • 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).
  • 테마 파일. themefile.rs은 데이터 폴더의 themes에서 TOML 또는 JSON을 읽습니다(단일 파일 또는 아이콘이 함께 있는 <id>/theme.toml). 파일은 변경하는 내용만 지정하며, 나머지는 inherits하는 테마(내장 테마 ID 또는 다른 파일, 기본적으로 클래식 모양)에서 가져옵니다. 순환 참조는 허용되지 않습니다. 알 수 없는 키는 오류가 아닌 경고로 처리됩니다. 내장 스타일 테마도 프로그램에 포함된 이러한 파일입니다(crates/app/assets/themes).
  • 아이콘 세트. themeicons.rs은 테마의 아이콘(용도별로 이름 지정: tb-add-url, cat-music…, 16, 24, 32, 48px의 SVG 또는 PNG, 텍스트 색상으로 채색된 -symbolic 아이콘)을 클래식 모양이 자체 아이콘을 그리는 위치에 그립니다. 세트에 없는 아이콘은 클래식 아이콘을 유지합니다.

창이 컨트롤을 배치하는 방식은 레이아웃으로 유지됩니다. 파일 이름 앞의 아이콘(fileicons.rs)도 마찬가지입니다. Windows 셸의 시스템 이미지 목록, macOS Finder(NSWorkspace), Linux 데스크톱의 아이콘 테마(xdgicons.rs, shared-mime-info 및 아이콘 테마 사양)를 사용합니다. 각 유형은 픽셀 크기별로 한 번씩 백그라운드 스레드에서 조회됩니다. 시스템 아이콘이 준비될 때까지, 그리고 시스템에 아이콘이 없는 모든 곳에서는 Tango 아이콘(번들)이 대신 사용됩니다.

그리기

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.

보기 → 인터페이스 크기(scale.rs, #262)는 디스플레이 자체 배율에 대한 egui의 확대/축소 비율입니다. 모든 창은 포인트 단위로 배치되므로 그만큼 더 크게 열립니다. 화면보다 큰 창은 스크롤됩니다.

데이터

다운로드 목록과 설정은 데이터 폴더(downloads.json)에 원자적으로 저장됩니다. Windows에서는 %APPDATA%\misterdownloadmanager\, Linux에서는 ~/.local/share/misterdownloadmanager, macOS에서는 ~/Library/Application Support/misterdownloadmanager, 휴대용 복사본 옆에는 data 폴더, 또는 MDM_DATA_DIR(mdm_ipc::data_dir)에 저장됩니다. 브라우저 호스트는 캡처 규칙에 대해 동일한 파일을 읽으므로, 옵션에서 변경된 내용은 다음 캡처된 다운로드에 적용됩니다.

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.

다운로드 서버 위치(#140)는 연결된 주소의 국가이며, 이 컴퓨터의 mdm-geo 테이블에서 조회됩니다(countries.rs는 인터페이스 언어로 이름을 지정합니다). 릴리스 작업은 해당 월의 데이터(tools/geo/build.py --release)로 테이블을 다시 구축합니다.

브라우저 통합

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

확장 프로그램은 호스트에게 어떤 파일 형식을 가져올지 묻고, 각 다운로드를 해당 형식과 비교하여 확인하며, 앱이 다운로드를 수락한 후에만 브라우저의 다운로드를 취소합니다. 그렇지 않으면 브라우저가 다운로드를 유지하고 확장 프로그램이 그 이유를 알려줍니다.

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.

원격 제어

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

--headless(headless.rs, #157)은 eframe 없이 동일한 App을 실행합니다. 루프는 명령 채널에 의해 깨어난 일반 egui::Context에서 tick(모든 프레임에서 logic가 실행하는 것)를 호출하며, ui은 호출하지 않습니다. 명령은 원격 제어가 추가하는 대로 추가됩니다(창 없음). Dockerfile 및 docker/(Compose, Unraid 템플릿)은 서버에서 이를 실행합니다(server.md).

서버는 앱의 Tokio 런타임에서 로컬 네트워크 주소당 하나의 리스너로 실행됩니다. 각 요청은 Host, Origin, 토큰을 확인하고, mdm_ipc::Command으로 표시된 remote(요청 라인에서 설정할 수 없는 필드)로 전환되어 명령줄과 동일한 채널을 통해 앱으로 전달됩니다. 앱은 자동화 API에 응답하는 것처럼 다음 프레임에서 응답합니다. 해당 페이지는 crates/remote/web에 내장되어 있으며 텍스트는 앱의 카탈로그(remote.rs)에서 가져옵니다.

번역

UI에 표시되는 모든 텍스트는 crate::i18n(craft-i18n 카탈로그, i18n/<locale>.tsv)를 거칩니다. tools/i18n/extract.py은 원본에서 i18n/en.tsv를 다시 빌드하며, 각 텍스트에 대해 번역가를 위한 메모(내용, 표시 위치, 자리 표시자)를 포함합니다. tools/i18n/translate.py은 각 언어의 스타일 가이드(i18n/style/)와 용어집에 따라 다른 카탈로그에 없는 내용( #, machine으로 표시된 행)을 채웁니다. 사람이 검토한 행은 절대 교체되지 않으며, CI(reviewed_guard.py)는 해당 행을 삭제하는 변경 사항에 대해 실패합니다. 웹사이트에는 자체 카탈로그(i18n/site/, tools/website/translate_site.py)가 있습니다.

그림

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).

기여자

tools/contributors.py감사 인사를 전하는 모든 곳(웹사이트 홈페이지, /contributors.html, 뉴스 페이지의 각 릴리스(build.py, 모든 빌드), 각 릴리스 노트(release.yml, 이전 릴리스 이후 활동한 사람), README(python tools/contributors.py readme, 각 릴리스 준비 시: GitHub에서는 README에서 사진을 둥글게 처리할 수 없으므로 둥근 사진은 art/contributors/에 커밋됨))에 대해 GitHub의 공개 API에서 풀 리퀘스트와 이슈를 열고 댓글을 단 사람을 읽어옵니다(유지 관리자, Claude 및 봇은 제외).

테스트 및 벤치마크

cargo test주입된 오류(느린 연결, 끊긴 연결, 거부된 연결, 범위가 없는 서버, 변경되는 파일)가 있는 mdm-labserver에 대해 단위 테스트 및 엔드투엔드 다운로드를 실행합니다. tools/bench는 게시된 속도 비교를 실행합니다. 원시 데이터는 docs/bench/에 있습니다.

무료, 오픈 소스, 광고 없음, 평가판 없음.

Download GolinksPRO Download Manager