Expand description
IComponent interface from the Open Multiplayer SDK in pure Rust.
The memory layout and vtable indices were derived from the public specification of the Open Multiplayer SDK (https://github.com/openmultiplayer/open.mp-sdk). No SDK code was copied — only signatures and vtable layouts were used as reference for this pure Rust reimplementation.
§Platform support
| Target | SA-MP | native Open Multiplayer |
|---|---|---|
i686-unknown-linux-gnu | yes | yes (Itanium ABI) |
i686-pc-windows-msvc | yes | yes (MSVC ABI) |
i686-pc-windows-gnu | yes | no (incompatible ABI) |
§Multiple inheritance and vtables
IComponent : public IExtensible, public IUIDProvider results in two
vtable pointers in the object. The offsets differ between Itanium (Linux GCC)
and MSVC because the FlatHashMap (robin_hood::unordered_flat_map) has a
different size on the two platforms — confirmed via disasm of omp-server.exe.
Offset Field (Linux / GCC i686)
------ -----
0 vtable* (primary: IExtensible + IComponent)
4..39 _misc_ext (robin_hood::unordered_flat_map, 36 bytes)
40 uid_vtable* (secondary: IUIDProvider)
44 uid (u64 — plugin's own field)
52 plugin_ptr (*mut () — plugin's own field)
Offset Field (Windows / MSVC i686)
------ -----
0 vtable* (primary: IExtensible + IComponent)
4..55 _misc_ext (52 bytes: padding + robin_hood + trailing padding)
56 uid_vtable* (secondary: IUIDProvider) — offset hardcoded by the server
60 _uid_pad (4 bytes to align uid (u64) to 8 bytes)
64 uid (u64 — plugin's own field)
72 plugin_ptr (*mut () — plugin's own field)§Primary vtable
Itanium ABI — two destructor slots (D1 complete + D0 deleting):
[0] getExtension
[1] addExtension
[2] removeExtension(ext*)
[3] removeExtension(uid)
[4] ~destructor D1 (complete object)
[5] ~destructor D0 (deleting)
[6] supportedVersion
[7] componentName
[8] componentType
[9] componentVersion
[10] onLoad
[11] onInit
[12] onReady
[13] onFree
[14] provideConfiguration
[15] free
[16] resetMSVC ABI — single destructor (scalar deleting) between IExtensible and IComponent:
[0] getExtension
[1] addExtension
[2] removeExtension(ext*)
[3] removeExtension(uid)
[4] ~destructor (single scalar deleting — MSVC does not emit D0)
[5] supportedVersion
[6] componentName
[7] componentType
[8] componentVersion
[9] onLoad
[10] onInit
[11] onReady
[12] onFree
[13] provideConfiguration
[14] free
[15] resetThe slots were confirmed by runtime + disasm of omp-server.exe
(componentVersion calls at [edx+0x20] = slot 8; componentName at
[eax+0x18] = slot 6).
§Secondary vtable — IUIDProvider
Itanium ABI — two destructor slots before getUID:
[0] destructor D1 thunk
[1] destructor D0 thunk
[2] getUIDMSVC ABI — only getUID (IUIDProvider does not declare a virtual destructor):
[0] getUIDStructs§
- IComponent
List IComponentList*— list of loaded components. Received inon_init; use to query other components.- IComponentV
Table - Primary
IComponentvtable for the MSVC ABI (Windows). - ICore
ICore*— opaque pointer to the Open Multiplayer server core. Received inon_load; use only for caching or future queries.- IEarly
Config IEarlyConfig*— configuration during initialization.- ILogger
ILogger*— server logging interface.- IUID
ProviderV Table - Secondary
IUIDProvidervtable for the MSVC ABI (Windows). - OmpComponent
Functions§
- comp_
component_ ⚠type - Safety
- comp_
on_ ⚠free - Safety
- comp_
on_ ⚠init - Safety
- comp_
on_ ⚠ready - Safety
- comp_
provide_ ⚠configuration - Safety
- comp_
supported_ ⚠version - Safety
- ext_
add_ ⚠extension - Safety
- ext_
destructor ⚠ - Scalar deleting destructor — no-op: cleanup is done via
free(). No explicit parameter: this in ECX, no args on the stack (avoidsret 4). - ext_
get_ ⚠extension - Safety
- ext_
remove_ ⚠extension_ ptr - Safety
- ext_
remove_ ⚠extension_ uid - Safety
- uid_
get_ ⚠uid getUID()via the secondary IUIDProvider vtable (MSVC ABI).