Cached at:
06/09/26, 10:42 AM
# aMule 3.0.0
Source: [https://amule-org.github.io/changelog/3.0.0](https://amule-org.github.io/changelog/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[](https://amule-org.github.io/changelog/3.0.0#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](https://amule-org.github.io/changelog/3.0.0#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[](https://amule-org.github.io/changelog/3.0.0#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\)[](https://amule-org.github.io/changelog/3.0.0#cross-platform-end-to-end-233-vs-300)
Leecher platform2\.3\.3 \(sustained\)3\.0\.0 \(sustained\)SpeedupmacOS \(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:
Platform2\.3\.3\+ seeder fix\+ leecher fix \(3\.0\.0\)macOS0\.35 MB/s30 MB/s**135 MB/s**Linux0\.34 MB/s20 MB/s**117 MB/s**Windows0\.36 MB/s6\.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\)[](https://amule-org.github.io/changelog/3.0.0#vs-emule-070b-windows--same-utm-hardware)
DirectioneMule 0\.70baMule 3\.0\.0Speedup**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[](https://amule-org.github.io/changelog/3.0.0#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\.
- **\#461 —`MaxUpload=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[](https://amule-org.github.io/changelog/3.0.0#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\-native`async\_read\_some`on Windows,`wxMutex`→`std::mutex`, and decoupling`m\_MaxBlockRequests`from per\-packet block count\. The biggest win on Windows specifically\.
- **\#491 —`MaxDownload`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[](https://amule-org.github.io/changelog/3.0.0#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\-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[](https://amule-org.github.io/changelog/3.0.0#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[](https://amule-org.github.io/changelog/3.0.0#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[](https://amule-org.github.io/changelog/3.0.0#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\)**—`SVNDATE`→`GITDATE`,`\_\_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[](https://amule-org.github.io/changelog/3.0.0#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[](https://amule-org.github.io/changelog/3.0.0#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\_REALTIME`→`CLOCK\_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\_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\_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\);`wxASSERT`→`wxCHECK\_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[](https://amule-org.github.io/changelog/3.0.0#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/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`\.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[](https://amule-org.github.io/changelog/3.0.0#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[](https://amule-org.github.io/changelog/3.0.0#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[](https://amule-org.github.io/changelog/3.0.0#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[](https://amule-org.github.io/changelog/3.0.0#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](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[](https://amule-org.github.io/changelog/3.0.0#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\.