Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/FarlandsModdingTeam/TerbinProyect/llms.txt

Use this file to discover all available pages before exploring further.

When a payload exceeds TerbinProtocol.MAX_PLD (65,520 bytes), Terbin splits it into fragments and sends them as separate packets. The receiver side uses TerbinMemory slots — managed by TerbinMemoryManager — to accumulate those fragments before reassembling the complete payload. Application code does not need to interact with these classes directly; TerbinCommunicator handles the entire lifecycle automatically.
Slots with IDs ≤ TerbinProtocol.RESERVE_MEMORY (9) are reserved for internal protocol operations. TerbinMemoryHelper.TryReleaseMemory refuses to release reserved slots.

TerbinMemory

A single fragment accumulation slot.

Properties

Id
byte
The slot’s identifier, assigned when the slot is created in the pool.
IdRequest
ushort
The request ID currently using this slot. A value of CodeTerbinMemory.NotAsign (1) means the slot is free.
IsOcupated
bool
Computed: true when IdRequest != (ushort)CodeTerbinMemory.NotAsign.

Events

OnAdd
event Action?
Fires after each AddFragment() call. Useful for monitoring assembly progress.
OnRelease
event Action?
Fires when Release() is called. Clears OnAdd first, then invokes OnRelease, then calls Clear().

Methods

AddFragment(ushort pOrder, byte[] pData)
void
Adds a fragment at the given order index in a thread-safe manner (locks _fragments). Duplicate order keys are silently ignored. Fires OnAdd.
TryGetFullData(out byte[] pData)
(bool succes, TerbinErrorCode typeError)
Sorts all stored fragments by order key, validates there are no gaps in the sequence, then concatenates them into a single byte[]. Returns (true, None) on success or (false, OrderMismatch) if a fragment is missing.
Release()
void
Resets IdRequest to NotAsign, clears OnAdd, fires OnRelease, and calls Clear().
Clear()
void
Discards all stored fragments and resets _totalSize to 0. Thread-safe via lock.

TerbinMemoryManager (Static)

The global pool of TerbinMemory slots backed by a ConcurrentDictionary<byte, TerbinMemory>.
public static ConcurrentDictionary<byte, TerbinMemory> Containers { get; }

Methods

GetFreeStore()
byte
Scans Containers for any slot where IsOcupated == false. If none is found, creates a new slot with a random byte ID via MiniID.NewB. Returns the slot’s byte ID.
Store(byte pIdMemory, ushort pOrder, byte[] pData)
void
Stores a fragment in the slot identified by pIdMemory, creating the slot if it does not exist yet.
ReStore(byte pIdMemory, ushort pOrder, byte[] pData)
void
Creates a fresh slot and forcibly replaces any existing entry at pIdMemory via AddOrUpdate.
OverwriteStore(byte pIdMemory, ushort pOrder, byte[] pData)
void
If a slot exists, calls Clear() on it and adds the fragment. Otherwise delegates to Store.
TryGetResult(byte pIdMemory, out byte[] pData)
(bool succes, TerbinErrorCode typeError)
Retrieves the complete reassembled byte array from the slot by calling TryGetFullData. Returns (false, ValueOutOfRange) if the slot does not exist.
TryGetMemory(byte pIdMemory, out TerbinMemory? pMemory)
bool
Returns the raw TerbinMemory instance for a slot without reassembling it.
Release(byte pIdMemory)
bool
Calls TerbinMemory.Release() on the slot, marking it free. Returns true if the slot existed.
Remove(byte pIdMemory)
bool
Permanently removes the slot from Containers. Returns true if it was present.

TerbinMemoryHelper (Static)

High-level helpers used internally by TerbinCommunicator.handleReceive.

Methods

TryGetMemoryStream(PacketRequest pCapsule, out byte[] pMemory)
TerbinErrorCode
The main entry point for the receive loop.
  • If pCapsule.Head.OrderRequest != FINAL_PACKET: returns the packet’s own Payload directly (single packet, no memory slot involved).
  • If pCapsule.Head.OrderRequest == FINAL_PACKET: calls TryAssembleStream, then TryReleaseMemory. Returns None on success, the TerbinErrorCode from TryAssembleStream on assembly failure, or MemoryReleaseFailed if the slot could not be freed.
TryAssembleStream(PacketRequest pCapsule, out byte[] pMemory)
TerbinErrorCode
Calls TerbinMemoryManager.TryGetResult to get the fragments, then concatenates them with pCapsule.Payload via CombinePayload. Returns the TerbinErrorCode from the manager.
CombinePayload(PacketRequest pCapsule, byte[] pBytes)
byte[]
Concatenates pBytes (previously stored fragments) and pCapsule.Payload (the final packet’s payload) into a single byte[].
TryReleaseMemory(byte pIdMemory)
bool
Refuses to release slots with IDs ≤ TerbinProtocol.RESERVE_MEMORY (9). For valid IDs, delegates to TerbinMemoryManager.Release.

Fragment Lifecycle

Client                                  Server
------                                  ------
SoliciteRequestMemory() ─────────────► Solicit handler assigns slot ID
◄── idMemory (byte) ──────────────────
Load(1, idMemory, fragment1) ────────► TerbinMemoryManager.Store(idMemory, 1, fragment1)
Load(2, idMemory, fragment2) ────────► TerbinMemoryManager.Store(idMemory, 2, fragment2)
...
HandleSendSigle(FINAL, pld) ─────────► handleReceive fires
                                        TryGetMemoryStream assembles all fragments
                                        OnRecive fires with full payload
                                        TryReleaseMemory(idMemory)
If TryGetFullData returns TerbinErrorCode.OrderMismatch, one or more fragments arrived out of order or are missing. The communicator reports CodeStatus.ErrorGetPaylaodMemory back to the sender.

Build docs developers (and LLMs) love