How GolinksPRO Download Manager's pieces fit together.
Crates
| เส้นทาง | Crate | บทบาท |
|---|---|---|
crates/engine |
mdm-engine |
ดาวน์โหลดไฟล์เดียวผ่าน HTTP(S) หรือ FTP(S): ตรวจสอบไฟล์ วางแผนแบ่งส่วน ทำงานเชื่อมต่อ จัดเก็บสถานะการดาวน์โหลดเพื่อดำเนินการต่อ จำกัดการเชื่อมต่อต่อโฮสต์ จำกัดความเร็ว ตรวจสอบ checksum และใช้สคริปต์พร็อกซี |
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): ตารางช่วง IP ถึงประเทศ สร้างจากข้อมูล Lite ของ DB-IP (tools/geo/build.py) ค้นหาบนคอมพิวเตอร์เครื่องนี้เท่านั้น และแสดงธงชาติของประเทศ |
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 |
รายงานการขัดข้องและการค้าง: กระบวนการตรวจสอบ, minidump ที่สร้างนอกกระบวนการ, สแต็กที่ระบุสัญลักษณ์แล้ว, ข้อความในรายงาน และบันทึกการเผยแพร่ (crash-reports.md) |
crates/torrent |
mdm-torrent |
BitTorrent และลิงก์แม่เหล็กผ่าน librqbit |
crates/labserver |
mdm-labserver |
เซิร์ฟเวอร์ HTTP Range ที่มีบันทึกคำขอและการจำลองข้อผิดพลาด พร้อมเซิร์ฟเวอร์ FTP/FTPS ที่มีข้อผิดพลาดจำลองของตัวเอง สำหรับการทดสอบและการวัดประสิทธิภาพ |
extension/ |
— | ส่วนขยาย Chromium (MV3) และ Firefox |
docs/ |
— | คู่มือผู้ใช้และบทแนะนำ ไฟล์นี้ และข้อมูลการวัดประสิทธิภาพ; เว็บไซต์ใช้คู่มือนี้เป็นหน้าวิธีใช้ ซึ่งเปิดได้จาก วิธีใช้ |
website/ |
— | หน้าเว็บของ misterdownloadmanager.com เอง (หน้าแรก, ดาวน์โหลด, คุณสมบัติ, ชุดรูปแบบ, คำถามที่พบบ่อย); 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) ใช้ตัววางแผน ตัวทำงาน และสถานะเดียวกัน: แต่ละส่วนประกอบด้วย REST + RETR ในเซสชันควบคุม แทนคำขอ GET แบบระบุช่วง ส่วน SIZE และ MDTM ใช้แทนส่วนหัว และระบบจะรวมเซสชันไว้ต่อการดาวน์โหลดหนึ่งรายการ แล้วนำกลับมาใช้ระหว่างดาวน์โหลดแต่ละส่วน
แอป
หน้าต่าง egui หนึ่งบานจะถูกวาดไปยังพิกเซลพิกัดคงที่ และมีวิวพอร์ตแบบทันทีหนึ่งวิวพอร์ตต่อหนึ่งกล่องโต้ตอบ app.rs เก็บสถานะ (การดาวน์โหลด, คิว, การตั้งค่า, การเลือกรายการ) และเปลี่ยนคำสั่งเมนู, แถบเครื่องมือ, คีย์ และ IPC ให้เป็นการดำเนินการ กล่องโต้ตอบแต่ละกล่องเป็นโมดูลของตัวเองและส่งคืน Outcome (เปิด, ปิด, เสร็จสิ้นพร้อมค่า) การเรียกใช้เฉพาะ Windows จะถูกจำกัดอยู่ใน win32.rs และคู่ของ Linux และ macOS จะอยู่ใน unix.rs (เริ่มต้นด้วยเซสชัน, โฮสต์ของเบราว์เซอร์, เสียง, แสดงในโฟลเดอร์, ตัวจัดการข้อผิดพลาด); ไฟล์อื่น ๆ ทั้งหมดปลอดภัยและเป็น Rust แบบพกพา ฟอนต์มาจากระบบ: โฟลเดอร์ Fonts ของ Windows, ฟอนต์ระบบของ macOS, fontconfig บน Linux (theme.rs) บน Windows ข้อความภาษาละติน, กรีก และซีริลลิกจะถูกวาดโดย DirectWrite ในโหมด GDI-classic (win32.rs ผ่าน egui's glyph rasterizer hook) เพื่อให้รูปร่างที่บอกใบ้ของแต่ละตัวอักษรและความกว้างเต็มพิกเซลมารวมกัน; สคริปต์อื่น ๆ จะถูกจัดรูปและวาดโดย 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ใช้ค่าเริ่มต้นของชุดรูปแบบ Native จากสีเน้นและคอนทราสต์ของระบบ (การตั้งค่าของ Windows, พอร์ทัล freedesktop บน Linux, สีเน้นของ macOS) - Control styles.
palette::Controlsnames 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 (thecaption.*roles). - ไฟล์ชุดรูปแบบ
themefile.rsอ่านไฟล์ TOML หรือ JSON จากโฟลเดอร์ข้อมูลthemes(ไฟล์เดียว หรือ<id>/theme.tomlพร้อมไอคอนข้าง ๆ) ไฟล์จะระบุเฉพาะสิ่งที่เปลี่ยนแปลง ส่วนที่เหลือมาจากชุดรูปแบบที่inherits(ID ของชุดรูปแบบในตัว หรือไฟล์อื่น ๆ โดยค่าเริ่มต้นคือรูปลักษณ์คลาสสิก) ตามลำดับที่ไม่มีการวนซ้ำ คีย์ที่ไม่รู้จักจะถือเป็นคำเตือน ไม่ใช่ข้อผิดพลาด ชุดรูปแบบสไตล์ในตัวก็เป็นไฟล์ประเภทนี้เช่นกัน ซึ่งอยู่ในโปรแกรม (crates/app/assets/themes) - ชุดไอคอน
themeicons.rsวาดไอคอนของชุดรูปแบบ (ตั้งชื่อตามวัตถุประสงค์:tb-add-url,cat-music…, SVG หรือ PNG ที่ขนาด 16, 24, 32 และ 48 px, ไอคอน-symbolicที่ใช้สีเดียวกับข้อความ) ในตำแหน่งที่รูปลักษณ์คลาสสิกวาดไอคอนของตัวเอง หากชุดไอคอนไม่มีไอคอนที่ต้องการ จะใช้ไอคอนคลาสสิกแทน
ตำแหน่งที่หน้าต่างวางส่วนควบคุมยังคงเป็นเค้าโครงเดิม เช่นเดียวกับไอคอนที่อยู่หน้าชื่อไฟล์ (fileicons.rs): รายการรูปภาพระบบของ Windows shell, macOS Finder (NSWorkspace), ชุดรูปแบบไอคอนของเดสก์ท็อป Linux (xdgicons.rs, shared-mime-info และ Icon Theme Specification) แต่ละประเภทจะถูกค้นหาหนึ่งครั้งต่อขนาดพิกเซล ในเธรดพื้นหลัง ไอคอนของ 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): %APPDATA%\misterdownloadmanager\ บน Windows, ~/.local/share/misterdownloadmanager บน Linux, ~/Library/Application Support/misterdownloadmanager บน macOS, โฟลเดอร์ 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) รัน App เดียวกันโดยไม่มี eframe: ลูปเรียกใช้ tick (สิ่งที่ logic รันในทุกเฟรม) บน egui::Context เปล่า ซึ่งถูกปลุกด้วยช่องคำสั่ง และไม่เคยเรียกใช้ ui; คำสั่งจะถูกเพิ่มเมื่อรีโมทคอนโทรลเพิ่ม (ไม่มีหน้าต่าง) Dockerfile และ docker/ (Compose, เทมเพลตของ Unraid) รันบนเซิร์ฟเวอร์ (server.md)
เซิร์ฟเวอร์ทำงานบนรันไทม์ Tokio ของแอป, มีตัวฟังหนึ่งตัวต่อที่อยู่เครือข่ายท้องถิ่นหนึ่งที่อยู่ แต่ละคำขอจะถูกตรวจสอบ (Host, Origin, โทเค็น), เปลี่ยนเป็น mdm_ipc::Command ที่ทำเครื่องหมาย remote (ฟิลด์ที่ไม่มีบรรทัดคำขอใดสามารถตั้งค่าได้) และส่งไปยังแอปผ่านช่องทางเดียวกับบรรทัดคำสั่ง; แอปจะตอบกลับในเฟรมถัดไป, เช่นเดียวกับการตอบกลับ Automation 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 เติมเต็มสิ่งที่แค็ตตาล็อกอื่นขาด (แถวที่ทำเครื่องหมาย #, machine) ตามคู่มือสไตล์ของแต่ละภาษา (i18n/style/) และอภิธานศัพท์; แถวที่บุคคลตรวจสอบแล้วจะไม่ถูกแทนที่ และ 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อ่านข้อมูลผู้ที่เปิดคำขอพูลและปัญหา รวมถึงผู้ที่แสดงความคิดเห็น จาก API สาธารณะของ GitHub (ไม่รวมผู้ดูแล, Claude และบอท) สำหรับทุกที่ที่กล่าวขอบคุณพวกเขา: หน้าแรกของเว็บไซต์, /contributors.html และแต่ละรุ่นบนหน้าข่าว (build.py, ในทุกบิลด์), บันทึกประจำรุ่นแต่ละรุ่น (release.yml, ผู้ที่ใช้งานตั้งแต่รุ่นก่อนหน้า) และ README (python tools/contributors.py readme ในการเตรียมแต่ละรุ่น: รูปภาพวงกลมจะถูกคอมมิตใน art/contributors/ เนื่องจาก GitHub ไม่สามารถทำรูปภาพให้เป็นวงกลมใน README ได้)
การทดสอบและเกณฑ์มาตรฐาน
cargo testรันการทดสอบหน่วยและการดาวน์โหลดแบบ end-to-end กับ mdm-labserver ด้วยข้อผิดพลาดที่ถูกแทรก (การเชื่อมต่อช้า, หลุดและถูกปฏิเสธ, เซิร์ฟเวอร์ที่ไม่มีช่วง, ไฟล์ที่เปลี่ยนแปลง) tools/bench รันการเปรียบเทียบความเร็วที่เผยแพร่; ข้อมูลดิบอยู่ใน docs/bench/
ฟรี, โอเพนซอร์ส, ไม่มีโฆษณา, ไม่มีช่วงทดลองใช้
Download GolinksPRO Download Manager