github amule-project/amule 3.0.0
aMule 3.0.0

6 hours ago

3.0.0 — The "alive again" version

Hi! We are back.

This is the first major release in 5+ years (since 2.3.3, 2021-02-07). Headline changes are dramatic throughput improvements, full build-system overhaul, modernized dependency stack, native binaries for Linux / macOS / Windows, and a broad legacy-API cleanup.

We went through hard times, we missed programmers and maintainers. There were doubts whether aMule could reemerge. People called aMule a dead project. But eD2k still has users, and those users need working software. So here we are — back to bring you the best eD2k client.

One unfortunate thing happened: Gonosztopi, one of aMule's most prolific devs, who has been the maintainer for many years, is missing. We have no news from him (we hope you are well, man!). And he was the only owner of the original GitHub repo. The other members left in amule-project do not have enough rights on the organization to properly manage the project. So we were forced to create a new one. New org, new repos, but the same folks.

You can find the new aMule site here.

You will find everything there: the home page, complete documentation, download links, news and links to the source code.

Highlights

  • Throughput rewrite. Disk I/O moved off the main thread, ASIO/EPOLLET races fixed, throttlers replaced with proper token-bucket limiters. Peer-to-peer download on the same hardware sees ~100–380× speedups across macOS / Linux / Windows over 2.3.3, plus aMule 3.0.0 sustains ~4.8× the upload throughput of eMule 0.70b on Windows. See Performance for the full matrix and per-PR breakdown.
  • Both throttlers (MaxUpload, MaxDownload) were also broken pre-fix — MaxUpload=0 capped at "current rate + 5 KB/s", MaxDownload was a ratio controller rather than a literal cap. Both rewritten (#461, #491). Important user-facing bug fixes, but secondary to the headline numbers.
  • Big-library / big-shareset scaling. Follow-up wave targeting nodes with 100 k+ shared files: per-file EC payload caches (#725, #736), skip-unchanged EC updates (#727), local-peer ZLIB bypass (#728), and a string of O(N²) → O(N log N) / O(1) algorithmic fixes across SharedFileList, SharedFilesCtrl, KnownFileList, wxListCtrl, ExternalConn, and amuleweb — the WebUI / amulegui stay responsive even on libraries where the previous GUI took minutes to redraw.
  • CMake replaces autotools. Single build system, modern toolchain — minimum CMake 3.10, minimum wxWidgets 3.2.0.
  • Native binaries for every major desktop. AppImage (x86_64 + aarch64), Flatpak (x86_64 + aarch64), macOS Universal2 .dmg (now bundling aMuleGUI.app alongside aMule.app, #529), Windows portable .zip and NSIS installer (x64 + ARM64, #740). First-run desktop integration prompt for AppImage; cross-platform autostart-on-login toggle (#744).
  • Auto-rescan of shared folders. wxFileSystemWatcher-driven (#591), with recursive vs explicit-share intent split (#606) and coverage of Incoming + per-category Incoming dirs (#743).
  • HTTPS works again. CHTTPDownloadThread rewritten on top of wxWebRequest; the hand-rolled stack had silently stopped working against modern TLS.
  • Kad parallel searches with alpha-frontier widening.
  • MaxMindDB replaces deprecated GeoIP for IP→country.

Performance

Throughput work landed across April 2026. The bottom-line cross-platform
numbers first, then the per-PR contributions that produced them.

Cross-platform end-to-end (2.3.3 vs 3.0.0)

Leecher platform 2.3.3 (sustained) 3.0.0 (sustained) Speedup
macOS (Apple Silicon, Mac Studio) 0.35 MB/s 135 MB/s 381×
Linux ARM (UTM VM, Ubuntu 25.10) 0.34 MB/s 117 MB/s 345×
Windows ARM (UTM VM, Windows 11) 0.36 MB/s 39 MB/s 107×

Sustained over a 90 s window, single LAN peer downloading a 30 GB file
from an x86_64 Linux seeder running the same aMule version under test.

Per-platform breakdown of the seeder-side vs leecher-side contributions:

Platform 2.3.3 + seeder fix + leecher fix (3.0.0)
macOS 0.35 MB/s 30 MB/s 135 MB/s
Linux 0.34 MB/s 20 MB/s 117 MB/s
Windows 0.36 MB/s 6.8 MB/s 39 MB/s

The seeder-side contribution (PR #451 CUploadDiskIOThread + ASIO fixes)
dominates everywhere; the leecher-side contribution (#454 partfile-write
offload + #484 throttler-wake fix + #491 token-bucket cap) stacks another
~4–6× on top.

vs eMule 0.70b (Windows · same UTM hardware)

Direction eMule 0.70b aMule 3.0.0 Speedup
Upload (Windows seeds → Mac leecher) 22 MB/s 106 MB/s ~4.8×
Download (Linux seeds → Windows leeches) 20 MB/s 39 MB/s ~1.9×

Upload

  • #451 — eMule CUploadDiskIOThread port. Disk reads + ed2k packet construction off the main thread, RC4 stream-desync race fixed in the ASIO layer, EPOLLET spurious-wakeup fix in HandleRead, adaptive per-slot packet sizing (10 KiB → EMBLOCKSIZE). Dominant contributor to the upload gain.
  • #461MaxUpload=0 is now literal unlimited. The legacy code set allowedDataRate = current_rate + 5 KB/s per iteration — a tracking cap that pinned the uplink at a fraction of capacity on any link above a few hundred KB/s.
  • #436 — Speed-limit fields widened from uint16 to uint32. Legacy 65,534 KB/s (~524 Mbps) configuration ceiling gone; gigabit-class links can now be configured.
  • #463 — Bandwidth-cap UI. Spin button ceiling 19,375 → 1,000,000 KB/s; field width 100 → 140 px so the + button no longer clips off on modern themes. Slot Allocation cap 100 → 100,000 KB/s.
  • #898 — Default SlotAllocation raised from 2 kB/s to 10 kB/s. The previous default (set in 2005) fragmented uploads into so many sub-slot slices that fast peers were rate-shaped down to a trickle.

Download

  • #454CPartFileWriteThread. Disk writes for downloads moved off the main thread.
  • #484 — Throttler-wake fix. UploadBandwidthThrottler::Entry() adaptive backoff dozed for 5–25 ms between control-queue pumps, stalling the request→response loop. Empty→non-empty wake gate added on the control-queue path, plus IOCP-native async_read_some on Windows, wxMutexstd::mutex, and decoupling m_MaxBlockRequests from per-packet block count. The biggest win on Windows specifically.
  • #491MaxDownload is now a literal byte/sec cap. The legacy code was a closed-loop ratio controller that nudged each peer's rate ±5%/tick relative to its own current speed, so MaxDownload=20000 (20 MB/s) shaped traffic toward whatever the aggregate converged on — generally well below configured. Replaced with a global token bucket (CDownloadBandwidthThrottler) enforcing the cap to within 2.5% across platforms.
  • #498 — Per-part hash verification deferred to a dedicated worker thread (only runs when the file isn't actively transferring). Follow-ups #499, #500.

Other

  • #467 — ASIO handler binding modernised. boost::bind → C++11 lambda, strand.wrap()bind_executor(), deadline_timersteady_timer, null_buffersasync_wait(wait_read). Fixes the long-standing boost::bind placeholder warning. Minimum Boost bumped 1.47 → 1.70.
  • #504 — Fast-path bare-filename comparison skips wxGetCwd().

Big-library / big-shareset scaling

A follow-up wave targeting nodes with 100 k+ shared files, where the daemon ↔ GUI / WebUI / amuleweb traffic and several internal data structures were quadratic in the shareset size:

  • EC payload caches. Per-file ed2k:// link and partmet basename cached on CKnownFile / CPartFile so EC enumeration stops rebuilding them on every tick (#725). Per-file byte cache covers the FULL GET_SHARED_FILES / GET_DLOAD_QUEUE paths so wire-marshalling cost drops by orders of magnitude on huge sharesets (#736).
  • EC skip-unchanged. Per-file change tracking infrastructure threaded through every field-change site so INC_UPDATE only re-sends what actually moved, with a backward-compatible partial-update protocol opt-in for amuleweb (#727 — landed as a 6-commit series). MarkECChanged gaps closed for paused / user-action setters.
  • Local-peer EC bypass. ZLIB compression skipped on local peers (#728), receiver limit raised to 256 MB, and the locality decision later moved to the client side with a user override checkbox / --force-zlib flag (#840 — handles the WireGuard-as-LAN case).
  • O(N²) → O(N log N) / O(1) algorithmic fixes.
    • SharedFilesCtrl bulk-update API skips per-row repaints during ClearED2KPublishInfo (#561, #2bf9b8f34).
    • SharedFileList keyword indexing in Reload (#566).
    • known2.met AICH SaveHashSet dedup made O(1) (#581).
    • known.met hash-collision dedup on Init dropped to O(N log N) (#584).
    • wxListCtrl::FindItem(data) O(N) → O(1) via user-data hash map (#614).
    • ExternalConn file-list enumeration snapshotted to avoid O(N²) GetFileByIndex loops (#687).
    • amuleweb array_push_back made O(N) via cached scan hint (#689).
    • KnownFileList indexes its size-map by (size, mtime) instead of size alone to cut false-positive collision-dedup walks (#593).
  • Disk I/O. CFile gains a 64 KB userspace write buffer to coalesce metadata-save syscalls (#573); the buffer was subsequently moved off the stack onto the heap so it survives musl's 128 KiB pthread stack, and an internal recursive_mutex was added to serialise buffer + fd access against the concurrent-corruption race surfaced on Alpine (#576). SavePartFile switched to atomic-rename (#670) and gated on an in-memory dirty flag so periodic ticks only touch disk when something actually changed (#671). Upload-stats persistence on 10-min heartbeat when only stats moved (#e8363bf42).
  • Memory bounds. amuleIPV4Address::operator= no longer leaks the endpoint copy on every assign (#716) — was 7 MB / 514 k objects per ~10 h of runtime on a busy node. CKeyEntry::m_filenames capped so the list can't grow unbounded (#652). known.met growth bounded by per-hash cap + 30-day TTL (#598, #f33c56b44). KnownFileList::Append only stamps lastSeen=now on actual sightings (#fafbb8a66). Wake-from-sleep SIGSEGV in asio socket impls fixed via shared_from_this (#596).
  • Backpressure & yielding. ECSocket::OnOutput yields when asio backpressures Write to zero bytes (#672). CECServerSocket notification-dispatch recursion capped so EC bursts no longer stall the event loop (#667). HTTPDownload bounds libcurl connect-phase via GetNativeHandle() (#565). Startup HTTP downloads deferred until after partfile + shared-file scan (#719) so cold-start UI is responsive while ipfilter.dat and friends are fetched.
  • Recursive share walks deferred + cancellable, with confirmation prompts for sensitive home-parent paths (#594, #599).
  • macOS daemon shutdown driven from OnCoreTimer to fix the long-standing hang (#563).

Networking & Discovery

  • Kad parallel searches with alpha-frontier widening; new "More" button to ask additional peers for results (#505).
  • MaxMindDB replaces deprecated GeoIP for IP→country (.dat → .mmdb; free MaxMind account required for the database) (#502, #507, #509).
  • HTTPS downloads work again — CHTTPDownloadThread rewritten on top of wxWebRequest (#462), with a hard-fail when wxUSE_WEBREQUEST is off (#481).
  • Wire-parser hardening: OP_SERVERMESSAGE size validation (#447), buffer overflow fix in ECSocket (#421), uninitialized memory fix in UInt128 (#424). EC tags whose declared length underflows the children size now rejected (#879). Proxy::SendTo SOCKS5 UDP relay bounded against oversized payloads (#882). Webserver/PHP IDENT strcpy into YYSTYPE.str_val bounded (#890). Memory leaks on malformed-packet exception paths plugged (#886, fixes #884 / #885).
  • ed2k-link float tags endian-swapped correctly on big-endian hosts (#368).
  • Friend's shared list and search-result rating exposed via EC (#430, #452).
  • Shared-folder watcher. wxFileSystemWatcher-driven auto-rescan (#591), with recursive vs explicit-share intent split + cold-discover of subdirs created while offline (#606). Watcher also covers the Incoming dir + per-category Incoming dirs so completed downloads register without a manual reload (#743). Incremental rescan replaces full Reload per filesystem event (#751); SharedFileList AICH-hash scan dropped from O(N·M) to O(N+M) (#746); optional "Follow symbolic links in shared folders" preference (#809). macOS amuled now pumps CFRunLoop so FSEvents deliver (#975f60fb0). File rename / move-out / delete during in-flight hash handled cleanly (#858).
  • Kad index hygiene. CEntry::SetFileName rejects empty filenames in the merge path (#675); CKeyEntry::m_filenames bounded (#652); known2_64.met orphan-pruned at sync startup (#605). m_filenames rotation now uses O(N) compare-and-skip insertion instead of sort+resize (#795); a popularity-decay experiment (#799) was introduced and then reverted (#805), keeping the GetCommonFileName all-zero robustness fix. Kad late UDP firewall responses dropped; Recheck assert downgraded (#afb9da010). SearchID collisions between Kad and ed2k searches no longer mix tab results (#530, #3008ada0f).
  • Server protocol. Future ping timestamps discarded from server.met (#3f70856a0); several server-ping fixes (#715). Control-traffic bypasses the download throttler (#615); inbound server probes also bypass it (#787). Server-name updates parsed as Unicode without the obsolete SRV_TCPFLG_UNICODE gate (#835); explicit disconnect when the server assigns no client ID (#788). OP_IDCHANGE sanity checks demoted to debug log (#613). ServerUDPSocket "additional packet" notice demoted to non-critical debug (#548). HTTP/HTTPS auto-update for addresses.dat accepts https URLs (#721); default eMule-security + shortypower URLs upgraded to HTTPS (#718).
  • EC / WebUI / amuleweb. 65535-children-per-tag wire-format ceiling lifted (#570). FRIEND_REMOVE made idempotent (#632); friend-slot flag persisted on CFriend so it survives disconnects (#633). amuleweb honours amule_set_options() nickname (#634); fixes POST body parsing when URL has a query string (#729); fixes split() byte/wide-char confusion on UTF-8 input (#619); fixes SIGSEGV rendering y-axis labels above 9999 (#618); fixes crash with >65535 shared files (#700). WebUI adds Kad + ed2k connect/disconnect controls (#660), Kad nodes-URL control, "Disconnect from current ed2k server" (#a82cd2e1a, #b5d83829a), and persistent ED2K / Kad enable checkboxes (#661, #8ce30f910); sends max upload/download rate as uint32 (#645). amulegui surfaces EC_OP_FAILED from ADD_LINK (#557), implements category-tab Stop/Pause/Resume/Cancel + Prio (#701), renders statistics graphs via EC_OP_GET_STATSGRAPHS (#639), and overrides OnFatalException with libbfd backtrace (#695). Aggregated single-popup AddLink error reporting (#577).
  • amuleweb security hardening (ngosang triage, all in #875). XSS-safe whitelist on the sort query param + htmlspecialchars defence-in-depth (#869); rand()-derived session IDs replaced with a 64-bit CSPRNG token from CryptoPP::AutoSeededRandomPool (#870); HttpOnly; SameSite=Strict on the session cookie (#871); login handler refuses to consume pass when reachable via the pre-POST-body-merge URL (#872); read-buffer NUL-terminator allocation fix (#873); dead SESSION_TIMEOUT_SECS macro wired up (#874).
  • UPnP. Filter non-WAN device announcements before fetching description (#623). Cache failed XML fetches + demote routine discovery logs from critical to debug (#653, #627).
  • ClientTCPSocket strict "no trailing bytes" asserts demoted to debug log (#710).
  • SharedFileList emits the honest file count in OP_OFFERFILES (#556) and skips empty OP_OFFERFILES when nothing made the LF cut (#169910998).

Build System & Dependencies

aMule 3.0 requires CMake ≥ 3.10 and wxWidgets ≥ 3.2.0. Autotools is removed entirely.

  • Full CMake build replaces autotools (#449).
  • Autotools, debian/ packaging dir, and dead platform/subtool trees retired (#466).
  • wxWidgets 3.x build fixes (#438, #443, #453); macOS framework / app-bundle compat (#453).
  • Boost 1.87 / 1.89 build fixes (#387, #429) — modern Boost ASIO no longer breaks the build.
  • CMake hard-fails when ENABLE_X=YES cannot be honored: UPnP (#511), NLS (#512), Boost (#513), IP2Country (#509). No more silent disable.
  • CMake mins / detection: minimum 3.10 and version.rc path fix (#490), MIN_WX_VERSION 3.2 with legacy wx.cmake retired (#459), default build type Release (#469), broken UPNP.cmake workaround (#439), BFD link fixes for modern binutils (#487, #489), find_package(Intl) outside YYENABLE_NLS gate (#495).
  • SVNDATE banner: stops freezing at first configure (#483); refreshes on git reset / commit (#493). SVN macros / files renamed to GIT throughout the source tree (#726)SVNDATEGITDATE, __SVN____GIT__, config.h.cm and Windows version.rc.in follow suit. No user-facing impact; reflects 5+ years of Git as the canonical SCM.
  • compile_commands.json generated (#441); compile.sh and find_uncompiled.py build/analysis scripts (#494, #501).
  • Loongarch64 architecture support (#286).
  • OpenSUSE platform fixes (#440); libupnp 1.18 compatibility (#448).
  • boost::asio mandatory. wxWidgets-sockets fallback path removed; ENABLE_BOOST and DOWNLOAD_AND_BUILD_DEPS escape hatches retired (#603).
  • CMake polish (post-#518). wx_NEED_NET kept on for BUILD_WEBSERVER-only (#620) and BUILD_AMULECMD-only (#630) configurations. libatomic linked directly on 32-bit targets where std::atomic<int64_t> needs it (#648, #662) — the heuristic atomic-probe is gone. glib-2.0 hard-fail when missing for amule / amuled / amulegui (#571), but the dependency itself is dropped on macOS even under wxGTK (#647). PACKAGE / PACKAGE_VERSION pre-defined for the bfd.h probe (#545).
  • license.txt moved to project root (#730).
  • CodeQL alerts cleared (#732, #733); CI runs CodeQL on push to master only, not on PRs (#c02d5ec04). actions/checkout bumped (#446 in initial pass).
  • README + docs polish. Distro version and GitHub activity badges (#7a1b310b5); markdown / ortography sweep (#6e9a9fe5a); INSTALL.md MD012/MD060 markup warnings fixed (#31aff1499).

Packaging

aMule 3.0 ships native binaries covering most modern desktops:

  • Linux AppImage (x86_64, aarch64) — works across all major distros.
  • Linux Flatpak (x86_64, aarch64) — runs in the GNOME Platform sandbox.
  • macOS Universal2 .dmg — single installer containing Apple Silicon and Intel binaries (the per-arch .app trees are CI intermediates for the lipo merge job and are not published as separate downloads).
  • Windows portable .zip (x64, ARM64).
  • Windows NSIS installer .exe (x64, ARM64) — guided installation, alternative to the portable zip.

Recipes, manifests, and the GitHub Actions packaging matrix landed in #510. AppImage's first-run prompt installs a desktop launcher to the user's application menu (reversible, opt-in).

Other platform integration work:

  • Wayland-friendly desktop integration: matching app_id, SNI tray icon (replaces deprecated GtkStatusIcon), macOS dock-restore on quit, tray opt-in (#508; fallback workaround in #474).
  • macOS Carbon FSRef API retired in favor of $HOME-based paths (#468).
  • macOS Dock right-click Quit triggers proper shutdown cleanup (#456).
  • Windows / MinGW build support: cmake fixes, LLP64 pointer safety, ASIO on Windows (#457).
  • Icons across all platforms: Linux hicolor PNG, Windows .rc icon, macOS amulegui.app (#464).
  • Initial AppStream metainfo (#367).
  • Localization on macOS and Windows fixed — wxLocale lookup paths repaired (#492).
  • macOS spurious wxGetCwd() errors silenced (#480).
  • Flatpak libupnp install-libdir pinned for pkg-config (#515).
  • macOS .dmg now bundles aMuleGUI.app alongside aMule.app so installing the .dmg gives both the daemon-style and GUI binaries in /Applications (#529). Locale catalogs are bundled inside the aMuleGUI.app Contents/Resources tree so translated strings render correctly when run from the .dmg (#543).
  • Windows NSIS installer shipped alongside the existing portable .zip (#740), with un.SecRemoveUserData no longer appearing on the install Components page (#65178406a). Installer UI now driven from po/<lang>.po via a po-to-nsh.py bridge so every supported NSIS language gets translated strings with English fallback (#899).
  • Cross-platform autostart-on-login toggle in Preferences (#744): Linux .desktop, macOS LaunchAgent, Windows registry under one checkbox.
  • All platforms ship alc / alcc / cas / wxcas; Windows additionally ships amuleweb (#785); macOS .dmg now contains amuleweb after build-path correction (#794).
  • Release-asset filenames standardised on <OS>-<arch> so every package is reachable by predictable URL (#789).
  • Windows non-DPI executables (alc, wxcas) get a comctl32 v6 + PerMonitorV2 manifest so they aren't bitmap-scaled on hi-DPI displays (#796); the main GUI got the same PerMonitorV2 declaration in #780.
  • Windows resource lookup paths corrected so skins and webserver templates resolve to share/amule (#784).

Internals & Refactoring

  • Legacy wx 2.x-era deprecated APIs removed (#470).
  • 2.x-compat globals and event-table macros retired (#475).
  • Dialog code migrated to wxSizerFlags; wxDesigner-generated code retired; GCC 15 enum-enum conversion warnings eliminated (#473).
  • macOS 10.10-era deprecation cleanup (#470).
  • OnAssertFailure ternary fixed for strict GCC / Alpine builds (#476).
  • Documentation transitioned to Markdown; staleness audit; broken README icon URL fixed (#514).
  • Late-cycle docs polish. Petar Maymounkov's email + paper URL refreshed to current (#851); IRC channel pointed to irc.libera.chat (#855); leftover references to the removed XAS module dropped (#862); README project-migration notice (#888); English man-page masters resynced to source (#900); --enable-webserver build hint refreshed in amuleweb-launch failure (#866, fixes #864); copyright headers refreshed across the source tree (#867); EC host default corrected in i18n docs (#895).
  • Code-quality follow-ups. FileLock platform #ifdef moved out of class body (#909); redundant null guard after early return removed from SharedFileList (#910); unused UPnP symbols dropped from WebSocket and SafeFile.h typo fixed (#912).
  • po4a config restored + optional CMake po4a-update target (#485).
  • Wiki content migrated into the repository (#496).
  • Crash diagnostics. MuleDebug PIE-translates runtime PCs back to link-time addresses for bfd (#677, #678), uses popen() instead of wxExecute() for the addr2line fallback (#682), and the Do_not_auto_remove marker is replaced with the modern IWYU pragma: keep (#679). amulegui's OnFatalException overridden with libbfd backtrace (#695). wxcas / alc disable wxSizerFlags consistency checks at startup (#694) — eliminates spurious assertion noise that broke the apps under wx 3.3.
  • Tray-icon overhaul. Unified Linux/macOS/Windows tray path (#574); dock icon dropped while hidden via tray on macOS (#a5a9a5866); HideOnClose decoupled from confirm-exit (#f1d0e85f0); iconize-aware menu + single-left toggle + robust ShowGUI (#0640373c8); ServerWnd sash anchored to top, persist-on-drag only (#47c811191); 'Enable Tray Icon' master placed before its dependents (#64b83e48e). Linux-specific tray-icon limitations gated separately (#2a0b874d7). 'Hide on close' exposed cross-platform behind the tray-icon gate (#e82b4bac5).
  • Wayland. amule-remote-gui binds wl_app_id via g_set_prgname() (#572).
  • GUI dispatch polish. MuleNotebook dispatches the right-click forward synchronously so PopupMenu's grab is fresh (#683). ClientDetailDialog binds Escape to Close (#681). Destructive YES_NO prompts no longer treat ESC as confirm (#612).
  • amulecmd. Search filters (type/extension/availability/size) now exposed via flags (#542) and documented (#544, #547). amulecmd.1 stops translating command names in section headers (#4296bbccf).
  • amule --disable-fatal also skips the assertion dialog (#549).
  • First-run prompt for nodes.dat alongside server.met (#558), with translations regenerated (#71542203f).
  • Logger. Sticky stdio EOF cleared on CLoggerAccess so EC log polls see new lines (#567). Control characters escaped in 'Invalid Kad tag type' log lines (#550). ExternalConnector console binaries respect VerboseDebug from amule.conf (#654) and setlocale at init so non-interactive output keeps accented chars (#629).
  • Y2038. Internal time-handling unified on uint64 GetTickCount64() to properly manage milliseconds past 2038 (#702). CLOCK_REALTIMECLOCK_MONOTONIC for steady-state intervals (#56a369e95).
  • EC ADD_LINK aggregates per-link result into a single response (#551).
  • Misc. asio sets FD_CLOEXEC on listen + UDP sockets (#552). FileFunctions bails out when wxZipInputStream stalls on a bad entry (#553). GuiEvents NULL-guards ECNotifier before dereferencing on download notifies (#554). StatTree stops double-counting session bytes (#555) and guards total ratio div-by-zero on fresh installs (#585). KnownFileList takes list_mut before opening known.met.new (#546) and closes a TOCTOU UAF window in Save() / PruneDuplicates (#690). SharedFileList takes list_mut around m_keywords ops in Reload and Publish so concurrent Kad publishes don't iterate a mid-mutation map (#686). PrefsUnifiedDlg flags user-home parents as sensitive (#599). amuleweb URL migration to amule-org and dead amule.org refs removed (#526).
  • Tooling / type cleanup. fileview CLogger stub extended with IsEnabled() for Debug builds (#657). muleunit adds missing override keywords (#664). Sockets override keyword sweep on CEMSocket-derived classes (#625). WebServer uses vector::data() in CProgressImage::CreateSpan (#684). Constant rename: PR_VERYLOWPR_VERY_LOW (#97fcd3ae8); PS_WAITINGFORHASHPS_WAITING_FOR_HASH (#2ae100b56). Webserver internal renames: gaptag / parttag / reqtaggap_tag / part_tag / req_tag (#412f5aa27); autoprioauto_priority (#f0bca611b). Backtrace internal rename: s_abfds_a_bfd (#5a576c3c1). Webserver enum typo fixes (#5a0d13718). Spelling sweeps across webserver (#fd823eff8, #0cda3b03c) and backtrace (#bb76d0ad8).
  • PartFile. m_lastDateChanged stamped on data arrival, not flush (#638). FlushBuffer size-correction guarded against closed fd (#609). m_hpartfile locked in ReadData + AICHRecoveryDataAvailable (#709). HashSinglePart bound-checked against partfile length (#130b0f495). Async hash enqueue gated on IsComplete (#c660e1281). Per-part hashing hardened against gap/disk-state drift (#560).
  • Preferences. No longer drops inaccessible shared dirs on load (#707); preserves unknown WebServer Template across GUI Save (#621); prefs/directories surfaces that the Incoming folder is shared (#631). ExternalConnector deletes m_ECClient in dtor to stop one-shot leak (#706).
  • Listctrl polish. RefreshLines skipped when range is outside visible (#624). Unfocused selection visible on themes where BTNSHADOW == LISTBOX (#646). LTR cell paint forced to fix RTL-locale glyph mirroring (#540).
  • Search dialog. Clipped Min/Max Size + Availability spin controls on Linux (#607, #82626f2f3). 10px-tall extension input field (#569 / #971310402).
  • Misc UI. amuleDlg re-Realizes toolbar after Show() to fix wxMSW long-locale clipping (#532). Hardcoded 20px height on the FastEd2kLinks bar dropped (#534, #c710c08fe). Icons migrated from XPM #include to wxArtProvider + embedded PNG (#537, #59d718818). Gtk-CRITICAL warnings on Preferences + Networks tabs silenced (#739).
  • PartFileConvertDlg collects ids before removing rows so GetNextItem stays valid (#649).
  • SafeFile oversized-string assertion demoted to debug log (#617).
  • KnownFile. Skip notify when SetPublishedED2K value didn't change (#dde5294fc). m_duplicateFileList growth bounded with a per-hash cap (#f33c56b44).
  • Code-quality baseline. Baseline .clang-tidy configuration introduced (#770); first sweeps produced 6 safety fixes (#773) and 4 cosmetic fixes (#774); wxASSERTwxCHECK_MSG on array-access guards in Logger / UserEvents (#772).
  • Dead-code removal. 2011-era /Statistics legacy config migration dropped (#825); long-broken "Automatic server connect without proxy" checkbox removed from preferences (#806).

Translations

  • Italian: AppImage integration prompt translated (#518).
  • Spanish updated and completed (#497).
  • Dutch updated (#343).
  • Catalan updated (#425).
  • Simplified Chinese updated (#348).
  • Translation pipeline: scripts/update-po.sh introduced.
  • AI-assisted gap-fill for it / fr / de / es app strings (#582) and man pages (#580).
  • Spanish further updates (cpp + docs, manpages rebuilt) (#655).
  • French + Turkish updated (#691) and added to the AppStream info file (#698, #86a08ffc7).
  • Brazilian Portuguese (pt-BR) added to metainfo (#86bafee35); metainfo screenshot URLs fixed (amule/amuleamule-org/amule, #cf84ec2c6); TODO comment syntax fix (shellXML, #fc205619f).
  • po regeneration from updated sources + msgmerge across all locales (#c2bbea0ed).
  • Late-cycle wave: French + Turkish manual pages (#753, #754, #776); Galician update (#763); Slovenian recovered from forum.amule.org (#771); Brazilian Portuguese man page added (#768) and the .po completed (#775); pt-BR translations on 4 .desktop files (#812); French manual-page update (#811).
  • Man-page tooling: .TH headers templatized for date + version so they no longer drift per release (#802).
  • Pre-release final wave (3.0.0 cut): French + Turkish updates (#847, #856, #891, #908); Brazilian Portuguese (#860, #904); Spanish app + man pages (#859, #863); Italian completed (it / it_CH fuzzy + untranslated) (#861); German (#880, #911); Vietnamese README added (#901); regenerated po/pot for app + man pages with Italian translations applied (#902); obsolete (#~) entries swept from app + man po (#889); stale Copyright year bumped + obsolete entries pruned (#868); Petar Maymounkov's email + paper URL updated in all catalogs (#853).

Bug Fixes & Stability

  • CFile::doSeek no longer asserts when IsOpened() is false (#294).
  • RLE_Data memory delete issue fixed (Valgrind report) (#379).
  • Selected lines in Download/Shared lists no longer become illegible when losing focus (#385).
  • amulegui: clean startup on Cancel + watchdog on wrong connection data (#465).
  • amuleweb: missing prefs apply options restored (#419).
  • PartFileWriteThread catches CIOFailureException so disk-full doesn't kill the process (#499).
  • StatTree fix (#319); totalizers added to download/upload stats (#338, #339).
  • Doc / source-comment typos cleanup (#297); missing include (#360).
  • amuleweb crash with >65535 shared files fixed (#700) with regression test (#61276d70d).
  • CFile musl SIGSEGV + concurrent corruption caught and fixed (#576) — musl's 128 KiB pthread stack interacted badly with the 64 KB userspace write buffer added in #573; a separate concurrent-corruption race on a shared write buffer was also fixed in the same PR.
  • macOS link error caused by implicit AppKit framework dependency now resolved by naming it explicitly (#578).
  • Wake-from-sleep SIGSEGV in asio socket impls — root cause shared_from_this lifetime gap (#596). NULL m_socket also guarded in UDP DispatchClose (#82b5400dc).
  • WebUI rate-limit fields no longer truncate at 16 bits (#645).
  • PartFileConvertDlg iteration invalidation crash (#649).
  • amulegui EC connect-timeout shutdown crash (#717).
  • ExternalConnector one-shot m_ECClient leak on dtor (#706).
  • EC notification path raw-pointer CECPacket leak plugged (#797).
  • Detect dead amuled cleanly across all clients (#758); EC --upnp-port fixed from switch to numeric option in amuleweb (#820); amuleweb remote.conf round-trip + Windows webserver template path fixed (#822).
  • amulegui improvements and fixes: ghost-entry sources — stale EC alive-marker for unknown ID no longer creates phantom rows (#810), INC_UPDATE tag for unknown file ID with suppressed identifying metadata now skipped cleanly (#819); connection dialog reappears on failure instead of quitting (#841); ED2K Info pane readability + clipboard copy fixed (#824); DirectoryTreeCtrl wxNullFont crash on the Windows revert-recursive-share path (#830); modal popups deferred out of OnPacketReceived call stack (#760). ECIDs the client hasn't received yet now sent with full detail instead of an empty alive marker (#857).
  • PartFile: first-share early hash so a downloading file appears in "Shared files" before it completes (#762); drop LowID-0 sources in CanAddSource (#790).
  • Crypto stream: don't UB if EncryptedStreamSocket::Negotiate() is entered with no expected bytes (#779).
  • UAF prevention: Notify_KnownFileBeingDestroyed broadcast on every CKnownFile destruction (#756).
  • GUI / GTK warnings: silenced on the Advanced Preferences tab via sizer simplification (#833); slider min-height pin attempted (#826) then reverted (#836) after wxGTK 3.2.9 surfaced an invisibility regression.
  • SearchListCtrl dropped bogus "File" title from right-click popup (#769).
  • Three GUI fixes from #800: toolbar races and web-template placeholder loop closed (#803).
  • amuled constructs CPartFileWriteThread + hash worker AFTER the InitGui fork so the daemon no longer crashes on first flush (#850, fixes #849).
  • Locale. LC_CTYPE=C scoped around wxFileConfig ops and the country-flag lookup so non-C locales no longer break preference number parsing or flag matching (#854, fixes #852).
  • ServerUDPSocket Delete() leaked the detached CAsyncDNS on thread Create/Run failure (#878).
  • eD2k socket CLibSocket::OnLost(int) now forwards to CEMSocket::OnClose so server/peer disconnects actually fire (#906).

CI

  • macOS and Windows MinGW64 build jobs added (#458); ccpp.yml adjustments (#460).
  • Ubuntu CI installs binutils-dev so the BFD path is exercised (#488).
  • Assert tests gated on wxDEBUG_LEVEL; ctest runs in Release in CI (#506).
  • CodeQL adjustments and code-scanning fixes (#477, #478, #482).
  • actions/checkout bumped from v4 to v6 (#446).
  • ccache wired across all compile jobs in both ccpp.yml (#892) and the packaging matrix (#903) — actions/cache-backed, gated off for tag builds. CodeQL workflow also gets binutils-dev so its BFD detection mirrors the main Ubuntu job (#907).

Known Limitations

Known caveats users should be aware of for this release:

  • macOS .dmg is not yet code-signed or notarized — users will see Gatekeeper warnings on first launch.
  • Flathub submission pending — for now, install the .flatpak directly with flatpak install <file>.
  • AppImage doesn't yet ship through AppImageLauncher's catalogue.
  • Tray-icon library (libayatana-appindicator) is deprecated upstream; migration to libayatana-appindicator-glib deferred until LTS distros pick it up.

Contributors

This release reflects 5+ years of work across 234 merged PRs (98 initial + 136 follow-ups through to the tag). Particular thanks to:

  • got3nks — 182 PRs.
  • Marcelo Jimenez (mrjimenez) — 17 PRs.
  • Werner Mahr (Vollstrecker) — 38 commits.
  • Pablo Barciela (sc0w) — 3 PRs, 17 commits.
  • Dévai Tamás (GonoszTopi) — 16 commits.
  • danim7 — 5 PRs across the follow-up cycle (translations, server pings, y2038, cmake polish).
  • cardpuncher — French + Turkish translations and AppStream entries (#691, #698).
  • ngosang — UX feedback driving the late-3.0 cycle (issues #817, #818, #821, #828, #844) and ongoing work on the user-facing manual at https://amule-org.github.io.

Plus contributions from RealGreenDragon, frnjjq, Sergi Amoros, Stefano Picerno, Alexander Tsoy, sergiomb2, puleglot, mercu01, lggcs, comio, MPolleke, mike2718, joebonrichie, matoro, dependabot, tbo47, SevC10, topotech, minterior, luzpaz, loongson-zn, mifritscher, nguyenhoangminhhieu2004-gif.

Merged PRs in this release

Complete list of PRs that landed for 3.0.0, in numerical order. The narrative sections above call out the most impactful changes; this index gives the full traceback.

#286, #294, #297, #319, #338, #339, #343, #348, #360, #367, #368, #379, #385, #387, #419, #421, #424, #425, #429, #430, #436, #438, #439, #440, #441, #443, #446, #447, #448, #449, #451, #452, #453, #454, #456, #457, #458, #459, #460, #461, #462, #463, #464, #465, #466, #467, #468, #469, #470, #473, #474, #475, #476, #477, #478, #480, #481, #482, #483, #484, #485, #487, #488, #489, #490, #491, #492, #493, #494, #495, #496, #497, #498, #499, #500, #501, #502, #504, #505, #506, #507, #508, #509, #510, #511, #512, #513, #514, #515, #518, #526, #529, #530, #532, #534, #537, #540, #542, #543, #544, #545, #546, #547, #548, #549, #550, #551, #552, #553, #554, #555, #556, #557, #558, #560, #561, #563, #565, #566, #567, #569, #570, #571, #572, #573, #574, #576, #577, #578, #580, #581, #582, #584, #585, #591, #593, #594, #596, #598, #599, #603, #605, #606, #607, #609, #612, #613, #614, #615, #617, #618, #619, #620, #621, #623, #624, #625, #627, #629, #630, #631, #632, #633, #634, #638, #639, #645, #646, #647, #648, #649, #652, #653, #654, #655, #657, #660, #661, #662, #664, #667, #670, #671, #672, #675, #677, #678, #679, #681, #682, #683, #684, #686, #687, #689, #690, #691, #694, #695, #698, #700, #701, #702, #706, #707, #709, #710, #715, #716, #717, #718, #719, #721, #725, #726, #727, #728, #729, #730, #732, #733, #736, #739, #740, #743, #744, #746, #747, #750, #751, #753, #754, #756, #758, #760, #762, #763, #768, #769, #770, #771, #772, #773, #774, #775, #776, #779, #780, #784, #785, #787, #788, #789, #790, #794, #795, #796, #797, #799, #801, #802, #803, #805, #806, #809, #810, #811, #812, #819, #820, #822, #824, #825, #826, #830, #833, #834, #835, #836, #839, #840, #841, #845, #847, #850, #851, #853, #854, #855, #856, #857, #858, #859, #860, #861, #862, #863, #866, #867, #868, #875, #878, #879, #880, #882, #886, #888, #889, #890, #891, #892, #895, #898, #899, #900, #901, #902, #903, #904, #906, #907, #908, #909, #910, #911, #912.

Don't miss a new amule release

NewReleases is sending notifications on new releases.