Changelog¶
All notable changes to MafiaNet are documented here.
Version 0.10.0¶
Core / API
Real umbrella header
mafianet/mafianet.h. Aggregates the core public headers (RakPeerInterface, types, message IDs,PacketPriority,BitStream,GetTime,Statistics) behind a single include, so the common client/server path only needs#include "mafianet/mafianet.h". Purely additive — the granular headers remain for advanced users. Encryption headers are intentionally omitted; connection security stays opt-in viaRakPeerInterface::InitializeSecurity().Canonical type aliases in
mafianet/aliases.hover the legacy RakNet-named public types:PeerInterface(RakPeerInterface),Guid(RakNetGUID),Statistics(RakNetStatistics) andUnassignedGuid(UNASSIGNED_RAKNET_GUID). These areusingaliases denoting the exact same types/objects, so old and new names interoperate freely. The legacy declarations are left untouched and un-deprecated. Pulled into the umbrella header.RAII handles
PeerandPacketPtrinmafianet/PeerHandle.h(exported from the umbrella header).Peerowns aRakPeerInterfaceinstance and destroys it on scope exit;PacketPtrowns a receivedPacketand deallocates it automatically — removing manualDestroyInstance/DeallocatePacketbookkeeping. The ChatExample client is rewritten to demonstrate them.Thread-safe value-type GUID accessors in
mafianet/guid_util.h:std::string MafiaNet::to_string(const RakNetGUID&)owns its buffer and is thread-safe, andstd::optional<SystemAddress> connected_address(...)maps theUNASSIGNED_SYSTEM_ADDRESSsentinel tostd::nullopt.
Spatial
PointGridSectorizer — a uniform grid over point entries that keeps a per-entry record (cell + slot) in a pointer-keyed hash, giving O(1)
RemoveEntryandMoveEntry(swap-remove within a cell, with a cheap early-out when a move stays in its current cell).AddEntry/MoveEntryshare upsert semantics (one entry per pointer), andGetEntriesnever returns duplicates. Out-of-bounds positions and query rectangles clamp to the edge cells.GridSectorizeris left untouched.
Breaking changes
Scoped enum classes for priority and reliability. The unscoped global C enums
PacketPriority/PacketReliability(which leaked their enumerators into the global namespace) are removed and replaced with scopedMafiaNet::Priority/MafiaNet::Reliabilityenum classes. Enumerator order is preserved, so underlying integer values — and the 3-bit reliability wire field — are unchanged and remain wire-compatible. PublicSend()/CloseConnection()/ etc. now take the new types; update call sites (e.g.HIGH_PRIORITY→MafiaNet::Priority::High,RELIABLE_ORDERED→MafiaNet::Reliability::ReliableOrdered). TheNUMBER_OF_PRIORITIES/NUMBER_OF_RELIABILITIESsentinels are nowconstexpr unsigned intcounts (4 and 8) in namespaceMafiaNet.Removed the non-thread-safe
RakNetGUID::ToString(void)member (which returned a shared static buffer). UseMafiaNet::to_string(g).c_str()instead.AddressOrGUID::ToString(bool)now self-contains its rotating buffer;SystemAddress/AddressOrGUIDToStringcalls are otherwise unchanged.
Bug fix
PeerHandleno longer dereferences a moved-fromPeerinreceive(); corrected the header copyright.
Testing
Added
PointGridSectorizerTest,PeerHandleTestandGuidUtilTest; hardenedDisconnectReasonTestagainst CI scheduler starvation with a bounded retry.
Version 0.9.0¶
Core
Strong-typed
PeerGuid. A newenum class PeerGuid : uint64_tnames a peer’sRakNetGUIDvalue distinctly fromNetworkID(an object id), so the two can no longer be passed interchangeably in auint64_t-typed signature — removing a class of silent “passed the wrong id” bugs in ReplicaManager3 glue andvoid(uint64_t)callbacks. Convert withToPeerGuid()/ToGuid(), and compare against theUNASSIGNED_PEER_GUIDsentinel. Being a trivially-copyable 8-byte scoped enum, it serializes byte-identically throughBitStream(and thereforeVariableDeltaSerializer) to the rawuint64_tit replaces, so it is fully wire-compatible and requires no netcode/protocol bump. Purely additive — no behavioural change.
Version 0.8.0¶
Core
Optional disconnect reason on graceful disconnects.
CloseConnectiongains a final optionalconst BitStream *reasonDataargument whose bytes are appended right after theID_DISCONNECTION_NOTIFICATIONmessage ID, so the remote peer can learn why it was dropped (e.g. a kick/ban enum plus a custom string). The receiver reads it exactly like any other message body —packet->data + 1forpacket->length - 1bytes. Only graceful disconnects carry a reason; locally-synthesized notifications (ID_CONNECTION_LOSTand the timeout/dead-connection path) stay payload-less, so consumers must tolerate a zero-length body. Appending bytes after the 1-byte ID is wire-backward-compatible: peers that only inspectdata[0]are unaffected.
Bug fix
RakPeer::CloseConnectionno longer coerces an unresolved target index (-1fromGetIndexFromSystemAddress) to0and then readsremoteSystemList[0]— which targeted an unrelated peer’s slot or crashed when the list was unallocated. The close socket is now resolved without assuming a valid slot index.
Documentation
Added a “Disconnect with a reason” section to the connecting guide and a cross-reference from the disconnect-debugging guide.
Testing
Added
DisconnectReasonTestcovering reason round-trip, thenullptrdefault, and the empty-but-non-nullBitStreamguard.
Version 0.7.0¶
Plugins
Virtual worlds (dimensions) for ReplicaManager3. A new lightweight per-entity / per-observer
VirtualWorldIdtag scopes visibility at runtime — the SA-MPSetPlayerVirtualWorld/ routing-bucket model for instanced interiors such as apartments. Players only see entities sharing their virtual world (or theVIRTUAL_WORLD_GLOBALsentinel), switchable on the fly with no reconnect, while staying on the same connection and the same RM3WorldId. Derive entities from the newVirtualWorldReplica3base (mafianet/VirtualWorldReplica3.h);Connection_RM3gainsGet/SetVirtualWorld;ReplicaManager3gainsGetConnectionsInVirtualWorld/GetGuidsInVirtualWorld(recipient-filter helpers for scoping non-replica traffic like chat and RPC) andSetPlayerVirtualWorld. The filter is applied only by the authority for an (entity, connection) pair, so a downloaded copy never despawns the entity at its owner. Seemafianet/VirtualWorld.hand theSamples/VirtualWorlddemo.
Documentation
Added a “Virtual Worlds (Dimensions)” plugin guide and expanded the contributing guide with how to test networked features (unit + end-to-end), the ReplicaManager3 authority model, and multi-peer-in-one-process gotchas.
Testing
Added
VirtualWorldTest(deterministic unit coverage, including the non-authority case) and a self-containedSamples/VirtualWorldsmoke test.Fixed the test harness so a subset run (
Tests <name>) callsDestroyPeers()on the test that actually ran.
Version 0.6.1¶
Plugins
ReplicaManager3::GetReplicaAtIndex is now const. It was the only one of the four read accessors (
GetReplicaCount,GetReplicaAtIndex,GetConnectionCount,GetConnectionAtIndex) that was non-const, which forcedconstmethods on derived managers toconst_castaway constness just to iterate replicas. The accessor only reads the world’s replica list and returns an existing pointer, so the qualifier is accurate; the returnedReplica3*stays non-const, matchingGetConnectionAtIndex. Source-compatible — addingconstto a read accessor doesn’t break existing non-const call sites.
Version 0.6.0¶
Plugins
RPC4 handlers now carry user context.
RegisterFunction,RegisterSlot,RegisterBlockingFunctionand theRPC4GlobalRegistrationhandler constructors take an opaquevoid *contextthat is passed back to the handler on every invocation. This removes the need for file-static global pointers to route an RPC back to an object instance; each registration carries its own context, so the same handler may serve multiple object instances under one identifier. Thevoid*approach preserves RPC4’s zero-external-dependency design.
Bug Fixes
RakPeer::CloseConnectionno longer dereferences a nullrakNetSocketduring connection teardown (a pre-existing crash in release builds, where the assertion is compiled out); it now falls back to the primary socket, matching the existing buffered-close path.
Testing
Added
RPC4ContextTestcovering slot, nonblocking, and blocking handler context.Quarantined the flaky
ManyClientsOneServerDeallocateBlockingTestunder CI while a pre-existing multithreaded teardown race is investigated.
Breaking Changes
RPC4 handler signatures gained a trailing
void *contextparameter, and the registration / global-registration functions take a context argument. There are no compatibility overloads — update handlers and registration calls (passnullptrwhen no context is needed).
Version 0.5.1¶
Plugins
Added
DirectoryDeltaTransfer::AddFile(const char *filePath, const char *fileName)to queue a single file for upload, complementing the recursiveAddUploadsFromSubdirectory. It forwards to the existingFileList::AddFileoverload, making the fork self-sufficient for downstream consumers (MafiaHub Framework) that depend on this helper.
Version 0.5.0¶
API & Namespace Cleanup
Standardized on the
MafiaNetnamespace throughout the libraryRemoved the legacy
SLNetcompatibility macro and replaced it with anMNetshort-hand alias that expands toMafiaNetDropped stale
RakNetnamespace-alias references (the alias no longer existed in code) and migrated the remaining sample code toMafiaNet::Collapsed the three header layers inherited from the RakNet/SLikeNet lineage down to the single canonical
Source/include/mafianet/set; the redirect-onlySource/*.handSource/mafianet/*.hstubs were removed and all includes now use themafianet/...form
Bug Fixes
Guarded
BitStream’s catch-allWrite/Readtemplates with astd::is_trivially_copyablestatic_assert, preventing silent pointer-aliasing and double-frees when serializing types that own heap memory (e.g.std::string)Added binary-safe, length-prefixed
std::stringBitStreamspecializations (wire-compatible withRakString)Fixed
Ranking_GetMatchesserializingSubmittedMatchthrough the unsafe catch-all instead of its ownSerialize()
Testing
Added the
BitStreamStringTestregression test
Breaking Changes
Legacy include spellings are gone — include public headers via the
mafianet/...path (e.g.mafianet/string.hinstead ofRakString.h)The
SLNetnamespace macro has been removed — useMafiaNet(or the newMNetshorthand)Serializing a non-trivially-copyable type through the generic
BitStream::Write/Readnow fails to compile by design; provide an explicitSerialize()or a type specialization
Version 0.4.0¶
Cross-Platform Support
Full macOS and Linux compatibility, including merged
Socket2definitionsRemoved deprecated platform back-ends to simplify the socket layer
Fixed IPv6 connectivity and initialization issues
Guarded the
<sys/io.h>include to x86/x86_64 only (fixes ARM builds)
Dependencies
Build pipeline upgraded to OpenSSL 3.6.0 (3.0+ still required)
Updated miniupnpc 2.2.8 → 2.3.3
Updated Opus 1.5.2 → 1.6.1
Dependencies are now fetched on demand via CMake
FetchContentinstead of being bundled in-tree
Bug Fixes
Fixed undefined behaviour from a negative
double→unsignedcast in congestion controlGuard against a null socket in
BCS_CLOSE_CONNECTIONhandlingFixed DLL exports on Windows
Fixed sample compilation across all platforms
Testing & CI
CI now builds and runs the full test suite on Linux, macOS and Windows (stress tests included)
Added a Dockerfile for running the test suite in a container
Numerous test-stability improvements: mesh-convergence waits, race-condition fixes, and a thread-safe plugin lifecycle for
PacketChangerPlugin
Version 0.3.0¶
RakVoice: Speex to Opus Migration
Replaced deprecated Speex codec with Opus 1.5.2
Added RNNoise for neural network-based noise suppression
Supported sample rates changed to native Opus rates: 8000, 16000, 24000, 48000 Hz
VAD now uses Opus DTX (Discontinuous Transmission)
Added
SetSignalType()for voice/music optimization hintsRemoved
SetEncoderComplexity()/GetEncoderComplexity()(Opus handles internally)Bundled Opus and RNNoise sources (no external dependencies)
Removed Speex and SpeexDSP from DependentExtensions
Breaking Changes:
Sample rate 32000 Hz is no longer supported (use 24000 or 48000)
SendFrame()andRequestVoiceChannel()now useRakNetGUIDinstead ofSystemAddress
Version 0.2.0¶
Rebranded from SLikeNet to MafiaNet
Updated to C++17 standard
Modernized CMake build system
Added Sphinx documentation with Breathe integration
Removed pre-generated Visual Studio solution files
Updated dependencies (miniupnpc, OpenSSL)
Version 0.1.0¶
Initial fork from SLikeNet
Basic project structure established