aMule 3.0.0
Release name: The 'alive again' version
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.
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=0capped at "current rate + 5 KB/s",MaxDownloadwas 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.appalongsideaMule.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.
CHTTPDownloadThreadrewritten on top ofwxWebRequest; 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
CUploadDiskIOThreadport. Disk reads + ed2k packet construction off the main thread, RC4 stream-desync race fixed in the ASIO layer, EPOLLET spurious-wakeup fix inHandleRead, adaptive per-slot packet sizing (10 KiB → EMBLOCKSIZE). Dominant contributor to the upload gain. - #461 —
MaxUpload=0is now literal unlimited. The legacy code setallowedDataRate = current_rate + 5 KB/sper 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
uint16touint32. 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.
Download
- #454 —
CPartFileWriteThread. 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-nativeasync_read_someon Windows,wxMutex→std::mutex, and decouplingm_MaxBlockRequestsfrom per-packet block count. The biggest win on Windows specifically. - #491 —
MaxDownloadis 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, soMaxDownload=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_timer→steady_timer,null_buffers→async_wait(wait_read). Fixes the long-standingboost::bindplaceholder 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 onCKnownFile/CPartFileso EC enumeration stops rebuilding them on every tick (#725). Per-file byte cache covers the FULLGET_SHARED_FILES/GET_DLOAD_QUEUEpaths 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_UPDATEonly re-sends what actually moved, with a backward-compatible partial-update protocol opt-in for amuleweb (#727 — landed as a 6-commit series).MarkECChangedgaps 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-zlibflag (#840 — handles the WireGuard-as-LAN case). - O(N²) → O(N log N) / O(1) algorithmic fixes.
SharedFilesCtrlbulk-update API skips per-row repaints duringClearED2KPublishInfo(#561, #2bf9b8f34).SharedFileListkeyword indexing inReload(#566).known2.metAICHSaveHashSetdedup made O(1) (#581).known.methash-collision dedup on Init dropped to O(N log N) (#584).wxListCtrl::FindItem(data)O(N) → O(1) via user-data hash map (#614).ExternalConnfile-list enumeration snapshotted to avoid O(N²)GetFileByIndexloops (#687).- amuleweb
array_push_backmade O(N) via cached scan hint (#689). KnownFileListindexes its size-map by(size, mtime)instead of size alone to cut false-positive collision-dedup walks (#593).
- Disk I/O.
CFilegains 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).SavePartFileswitched 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_filenamescapped so the list can't grow unbounded (#652).known.metgrowth bounded by per-hash cap + 30-day TTL (#598, #f33c56b44).KnownFileList::Appendonly stampslastSeen=nowon actual sightings (#fafbb8a66). Wake-from-sleep SIGSEGV in asio socket impls fixed viashared_from_this(#596). - Backpressure & yielding.
ECSocket::OnOutputyields when asio backpressuresWriteto zero bytes (#672).CECServerSocketnotification-dispatch recursion capped so EC bursts no longer stall the event loop (#667).HTTPDownloadbounds libcurl connect-phase viaGetNativeHandle()(#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
OnCoreTimerto 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 —
CHTTPDownloadThreadrewritten on top ofwxWebRequest(#462), with a hard-fail whenwxUSE_WEBREQUESTis off (#481). - Wire-parser hardening:
OP_SERVERMESSAGEsize validation (#447), buffer overflow fix inECSocket(#421), uninitialized memory fix inUInt128(#424). - 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 fullReloadper filesystem event (#751);SharedFileListAICH-hash scan dropped from O(N·M) to O(N+M) (#746); optional "Follow symbolic links in shared folders" preference (#809). macOS amuled now pumpsCFRunLoopso FSEvents deliver (#975f60fb0). - Kad index hygiene.
CEntry::SetFileNamerejects empty filenames in the merge path (#675);CKeyEntry::m_filenamesbounded (#652);known2_64.metorphan-pruned at sync startup (#605).m_filenamesrotation 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 theGetCommonFileNameall-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_UNICODEgate (#835); explicit disconnect when the server assigns no client ID (#788).OP_IDCHANGEsanity checks demoted to debug log (#613).ServerUDPSocket"additional packet" notice demoted to non-critical debug (#548). HTTP/HTTPS auto-update foraddresses.dataccepts 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_REMOVEmade idempotent (#632); friend-slot flag persisted onCFriendso it survives disconnects (#633). amuleweb honoursamule_set_options()nickname (#634); fixes POST body parsing when URL has a query string (#729); fixessplit()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 surfacesEC_OP_FAILEDfromADD_LINK(#557), implements category-tab Stop/Pause/Resume/Cancel + Prio (#701), renders statistics graphs viaEC_OP_GET_STATSGRAPHS(#639), and overridesOnFatalExceptionwith libbfd backtrace (#695). Aggregated single-popup AddLink error reporting (#577). - 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 emptyOP_OFFERFILESwhen 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=YEScannot be honored: UPnP (#511), NLS (#512), Boost (#513), IP2Country (#509). No more silent disable. - CMake mins / detection: minimum 3.10 and
version.rcpath fix (#490),MIN_WX_VERSION3.2 with legacywx.cmakeretired (#459), default build type Release (#469), brokenUPNP.cmakeworkaround (#439), BFD link fixes for modern binutils (#487, #489),find_package(Intl)outsideYYENABLE_NLSgate (#495). - SVNDATE banner: stops freezing at first configure (#483); refreshes on
git reset/ commit (#493).SVNmacros / files renamed toGITthroughout the source tree (#726) —SVNDATE→GITDATE,__SVN__→__GIT__,config.h.cmand Windowsversion.rc.infollow suit. No user-facing impact; reflects 5+ years of Git as the canonical SCM. compile_commands.jsongenerated (#441);compile.shandfind_uncompiled.pybuild/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_BOOSTandDOWNLOAD_AND_BUILD_DEPSescape hatches retired (#603). - CMake polish (post-#518).
wx_NEED_NETkept on for BUILD_WEBSERVER-only (#620) and BUILD_AMULECMD-only (#630) configurations.libatomiclinked directly on 32-bit targets wherestd::atomic<int64_t>needs it (#648, #662) — the heuristic atomic-probe is gone.glib-2.0hard-fail when missing foramule/amuled/amulegui(#571), but the dependency itself is dropped on macOS even under wxGTK (#647).PACKAGE/PACKAGE_VERSIONpre-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/checkoutbumped (#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.apptrees are CI intermediates for thelipomerge 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 deprecatedGtkStatusIcon), macOS dock-restore on quit, tray opt-in (#508; fallback workaround in #474). - macOS Carbon
FSRefAPI 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
.rcicon, macOSamulegui.app(#464). - Initial AppStream metainfo (#367).
- Localization on macOS and Windows fixed — wxLocale lookup paths repaired (#492).
- macOS spurious
wxGetCwd()errors silenced (#480). - Flatpak
libupnpinstall-libdir pinned for pkg-config (#515). - macOS .dmg now bundles
aMuleGUI.appalongsideaMule.appso installing the .dmg gives both the daemon-style and GUI binaries in/Applications(#529). Locale catalogs are bundled inside theaMuleGUI.appContents/Resourcestree 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).
- 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 shipsamuleweb(#785); macOS.dmgnow containsamulewebafter 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 samePerMonitorV2declaration 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).
OnAssertFailureternary fixed for strict GCC / Alpine builds (#476).- Documentation transitioned to Markdown; staleness audit; broken README icon URL fixed (#514).
- po4a config restored + optional CMake
po4a-updatetarget (#485). - Wiki content migrated into the repository (#496).
- Crash diagnostics.
MuleDebugPIE-translates runtime PCs back to link-time addresses for bfd (#677, #678), usespopen()instead ofwxExecute()for the addr2line fallback (#682), and theDo_not_auto_removemarker is replaced with the modernIWYU pragma: keep(#679). amulegui'sOnFatalExceptionoverridden with libbfd backtrace (#695).wxcas/alcdisable 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);
HideOnClosedecoupled from confirm-exit (#f1d0e85f0); iconize-aware menu + single-left toggle + robust ShowGUI (#0640373c8);ServerWndsash 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_idviag_set_prgname()(#572). - GUI dispatch polish.
MuleNotebookdispatches the right-click forward synchronously so PopupMenu's grab is fresh (#683).ClientDetailDialogbinds 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-fatalalso 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
CLoggerAccessso EC log polls see new lines (#567). Control characters escaped in 'Invalid Kad tag type' log lines (#550).ExternalConnectorconsole binaries respectVerboseDebugfrom amule.conf (#654) andsetlocaleat 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_REALTIME→CLOCK_MONOTONICfor steady-state intervals (#56a369e95). - EC ADD_LINK aggregates per-link result into a single response (#551).
- Misc.
asiosetsFD_CLOEXECon listen + UDP sockets (#552).FileFunctionsbails out whenwxZipInputStreamstalls on a bad entry (#553).GuiEventsNULL-guardsECNotifierbefore dereferencing on download notifies (#554).StatTreestops double-counting session bytes (#555) and guards total ratio div-by-zero on fresh installs (#585).KnownFileListtakes list_mut before openingknown.met.new(#546) and closes a TOCTOU UAF window inSave()/PruneDuplicates(#690).SharedFileListtakeslist_mutaroundm_keywordsops inReloadandPublishso concurrent Kad publishes don't iterate a mid-mutation map (#686).PrefsUnifiedDlgflags user-home parents as sensitive (#599). amuleweb URL migration toamule-organd deadamule.orgrefs removed (#526). - Tooling / type cleanup.
fileviewCLogger stub extended withIsEnabled()for Debug builds (#657).muleunitadds missing override keywords (#664). Socketsoverridekeyword sweep onCEMSocket-derived classes (#625).WebServerusesvector::data()inCProgressImage::CreateSpan(#684). Constant rename:PR_VERYLOW→PR_VERY_LOW(#97fcd3ae8);PS_WAITINGFORHASH→PS_WAITING_FOR_HASH(#2ae100b56). Webserver internal renames:gaptag/parttag/reqtag→gap_tag/part_tag/req_tag(#412f5aa27);autoprio→auto_priority(#f0bca611b). Backtrace internal rename:s_abfd→s_a_bfd(#5a576c3c1). Webserver enum typo fixes (#5a0d13718). Spelling sweeps across webserver (#fd823eff8, #0cda3b03c) and backtrace (#bb76d0ad8). - PartFile.
m_lastDateChangedstamped on data arrival, not flush (#638).FlushBuffersize-correction guarded against closed fd (#609).m_hpartfilelocked inReadData+AICHRecoveryDataAvailable(#709).HashSinglePartbound-checked against partfile length (#130b0f495). Async hash enqueue gated onIsComplete(#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).
ExternalConnectordeletesm_ECClientin dtor to stop one-shot leak (#706). - Listctrl polish.
RefreshLinesskipped when range is outside visible (#624). Unfocused selection visible on themes whereBTNSHADOW == 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.
amuleDlgre-Realizes toolbar after Show() to fix wxMSW long-locale clipping (#532). Hardcoded 20px height on the FastEd2kLinks bar dropped (#534, #c710c08fe). Icons migrated fromXPM #includetowxArtProvider+ embedded PNG (#537, #59d718818). Gtk-CRITICAL warnings on Preferences + Networks tabs silenced (#739). - PartFileConvertDlg collects ids before removing rows so
GetNextItemstays valid (#649). - SafeFile oversized-string assertion demoted to debug log (#617).
- KnownFile. Skip notify when
SetPublishedED2Kvalue didn't change (#dde5294fc).m_duplicateFileListgrowth bounded with a per-hash cap (#f33c56b44). - Code-quality baseline. Baseline
.clang-tidyconfiguration introduced (#770); first sweeps produced 6 safety fixes (#773) and 4 cosmetic fixes (#774);wxASSERT→wxCHECK_MSGon array-access guards inLogger/UserEvents(#772). - Dead-code removal. 2011-era
/Statisticslegacy 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.shintroduced. - 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/amule→amule-org/amule, #cf84ec2c6); TODO comment syntax fix (shell→XML, #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
.pocompleted (#775); pt-BR translations on 4.desktopfiles (#812); French manual-page update (#811). - Man-page tooling:
.THheaders templatized for date + version so they no longer drift per release (#802).
Bug Fixes & Stability
CFile::doSeekno longer asserts whenIsOpened()is false (#294).RLE_Datamemory 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 applyoptions restored (#419). PartFileWriteThreadcatchesCIOFailureExceptionso 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_thislifetime gap (#596). NULLm_socketalso 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_ECClientleak on dtor (#706). - EC notification path raw-pointer
CECPacketleak plugged (#797). - Detect dead amuled cleanly across all clients (#758); EC
--upnp-portfixed from switch to numeric option inamuleweb(#820);amulewebremote.confround-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_UPDATEtag 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);DirectoryTreeCtrlwxNullFontcrash on the Windows revert-recursive-share path (#830); modal popups deferred out ofOnPacketReceivedcall stack (#760). - 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_KnownFileBeingDestroyedbroadcast on everyCKnownFiledestruction (#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).
CI
- macOS and Windows MinGW64 build jobs added (#458); ccpp.yml adjustments (#460).
- Ubuntu CI installs
binutils-devso the BFD path is exercised (#488). - Assert tests gated on
wxDEBUG_LEVEL;ctestruns in Release in CI (#506). - CodeQL adjustments and code-scanning fixes (#477, #478, #482).
actions/checkoutbumped from v4 to v6 (#446).
Known Limitations
Known caveats users should be aware of for this release:
- macOS
.dmgis not yet code-signed or notarized — users will see Gatekeeper warnings on first launch. - Flathub submission pending — for now, install the
.flatpakdirectly withflatpak install <file>. - AppImage doesn't yet ship through AppImageLauncher's catalogue.
- Tray-icon library (
libayatana-appindicator) is deprecated upstream; migration tolibayatana-appindicator-glibdeferred 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 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.
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.