Skip to main content

Module component

Module component 

Source
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

TargetSA-MPnative Open Multiplayer
i686-unknown-linux-gnuyesyes (Itanium ABI)
i686-pc-windows-msvcyesyes (MSVC ABI)
i686-pc-windows-gnuyesno (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] reset

MSVC 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] reset

The 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]  getUID

MSVC ABI — only getUID (IUIDProvider does not declare a virtual destructor):

[0]  getUID

Structs§

IComponentList
IComponentList* — list of loaded components. Received in on_init; use to query other components.
IComponentVTable
Primary IComponent vtable for the MSVC ABI (Windows).
ICore
ICore* — opaque pointer to the Open Multiplayer server core. Received in on_load; use only for caching or future queries.
IEarlyConfig
IEarlyConfig* — configuration during initialization.
ILogger
ILogger* — server logging interface.
IUIDProviderVTable
Secondary IUIDProvider vtable 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 (avoids ret 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).