ISource2ModNatives

Natives for SourcePawn plugins, from a native (C++) plugin.

What a SourceMod extension does for its scripts: register natives a .sp declares and calls, a library its scripts can test for, and handles of a type of its own. The natives are SourcePawn's -- SPVM_NATIVE_FUNC, called with the script's IPluginContext and its parameters -- so the SourcePawn headers come with this one (public/sourcepawn, the core's VM version).

SOURCE2MOD_SAVEVARS() fills g_pSource2ModNatives like every other global (null on a core without script support); including this header is only needed to call it.

g_pSource2ModNatives->AddNatives(g_PluginID, g_MyNatives);

Everything registered here goes when the plugin unloads: its natives become unbound (a script calling one gets an error), its libraries are removed (OnLibraryRemoved) and its handle types are destroyed together with every handle of them.

The other way round (002): a script's API, called from C++. A script exposes it the way it does for other scripts -- natives (Source2ModNatives.CreateNative), a library (RegisterLibrary) and global forwards (GlobalForward) -- and a C++ plugin reaches them by name:

ISource2ModScriptNative* give = g_pSource2ModNatives->FindScriptNative("Shop_GiveCredits");
int total = give->Call<int>(pController, 100, "kill bonus");   // 0 when no script serves it
if (!give->TryCall(&total, pController, 100, "kill bonus"))
    Msg("%s\n", give->GetLastError());

g_pSource2ModNatives->HookScriptForward("Shop_OnBuy", [](const char*, Source2ModScriptArg* args, int count) -> cell_t
{
    return args[1].AsInt() > 1000 ? 2 : 0;   // Action_Supersede : Action_Ignore
});
g_pSource2ModNatives->AddLibraryListener([](const char* name, bool added) { ... });

The objects Find* returns belong to the core and stay valid until it unloads: they name the native or forward, not the script, so one found before the script loads works once it does, and a call after the script unloaded is refused (false / a value-initialised result) instead of reaching freed code.

Interface id ISource2ModNatives002 (SOURCE2MOD_NATIVES_INTERFACE) · Global g_pSource2ModNatives · Header source2mod/ISource2ModNatives.h

Types

Source2ModHandleType

using Source2ModHandleType = uint32_t;

A handle type registered through CreateHandleType(); 0 is none.

Source2ModHandleDestructor

using Source2ModHandleDestructor = void (*)(void* object);

Takes a handle's object when its last handle is closed.

Source2ModScriptForwardHandler

using Source2ModScriptForwardHandler = Source2ModCallback<cell_t(const char* forward, Source2ModScriptArg* args, int count)>;

A C++ hook on a script global forward. @p args are the forward's parameters; a reference, an array or a string buffer is written back to the script that fired it. Returns what a script function of the forward would (an Action for most).

Source2ModLibraryHandler

using Source2ModLibraryHandler = Source2ModCallback<void(const char* name, bool added)>;

A library came (added) or went, as OnLibraryAdded / OnLibraryRemoved.

Methods

AddNatives

virtual bool AddNatives(PluginId owner, const sp_nativeinfo_t* natives) = 0;

Registers natives for scripts.

Scripts already loaded get the ones they were missing; a script that failed to load for want of one of them is loaded again. A name that a live plugin already registered is refused (and logged), the rest of the list still goes in.

ParameterTypeDescription
ownerPluginIdThe plugin's id (g_PluginID)
nativesconst sp_nativeinfo_t*Name and function pairs, ending in { nullptr, nullptr }; copied, the array need not outlive the call

Returns bool — false when any of them was refused

RegisterLibrary

virtual bool RegisterLibrary(PluginId owner, const char* name) = 0;

Registers a library, what LibraryExists() and OnLibraryAdded() in a script see. Scripts that are running get OnLibraryAdded now.

Several plugins may register the same library; it is removed (OnLibraryRemoved) when the last of them unloads.

ParameterType
ownerPluginId
nameconst char*

Returns bool — false on an empty name

LibraryExists

virtual bool LibraryExists(const char* name) = 0;

Whether a plugin (script or native) registered this library.

ParameterType
nameconst char*

GetScriptPlugin

virtual PluginId GetScriptPlugin(SourcePawn::IPluginContext* ctx) = 0;

The script plugin a native was called from.

ParameterType
ctxSourcePawn::IPluginContext*

Returns PluginId — Its plugin id, 0 when the context is no script's

FormatString

virtual bool FormatString(SourcePawn::IPluginContext* ctx, const cell_t* params, int fmtParam, char* buffer, size_t maxlen, size_t* written = nullptr) = 0;

SourceMod's format, as Format() and PrintToServer() do it: the format at params[fmtParam], its arguments after it.

ParameterTypeDefault
ctxSourcePawn::IPluginContext*
paramsconst cell_t*
fmtParamint
bufferchar*
maxlensize_t
writtensize_t*nullptr

Returns bool — false after reporting the error to the script

CreateHandleType

virtual Source2ModHandleType CreateHandleType(PluginId owner, const char* name, Source2ModHandleDestructor destroy) = 0;

Registers a handle type for the objects this plugin hands out.

ParameterTypeDescription
ownerPluginId
nameconst char*
destroySource2ModHandleDestructorCalled with the object when its last handle is closed (CloseHandle / delete, the owning script unloading); may be nullptr

CreateHandle

virtual cell_t CreateHandle(Source2ModHandleType type, void* object, SourcePawn::IPluginContext* ctx) = 0;

A new handle to object, owned by the script that ctx is -- closed when that script unloads.

ParameterType
typeSource2ModHandleType
objectvoid*
ctxSourcePawn::IPluginContext*

Returns cell_t — The handle, 0 on an unknown type or a full handle table

ReadHandle

virtual void* ReadHandle(SourcePawn::IPluginContext* ctx, cell_t handle, Source2ModHandleType type) = 0;

The object behind a handle of this type.

ParameterType
ctxSourcePawn::IPluginContext*
handlecell_t
typeSource2ModHandleType

Returns void* — The object, or nullptr after reporting SourceMod's "Invalid Handle" error to the script

CloseHandle

virtual bool CloseHandle(cell_t handle) = 0;

Closes a handle whoever owns it.

ParameterType
handlecell_t

FindScriptNative

virtual ISource2ModScriptNative* FindScriptNative(const char* name) = 0;

A native a script made (CreateNative), by name.

Never nullptr for a non-empty name: the object stands for the name, so it can be found before the script registers the native and keeps working across the script's reloads. IsAvailable() says whether a script serves it now; a native a C++ plugin registered is not available here (call that plugin's code directly).

ParameterType
nameconst char*

FindScriptForward

virtual ISource2ModScriptForward* FindScriptForward(const char* name) = 0;

A global forward by name (see ISource2ModScriptForward); never nullptr for a non-empty name.

ParameterType
nameconst char*

HookScriptForward

virtual Source2ModHookId HookScriptForward(const char* name, Source2ModScriptForwardHandler handler) = 0;

Hooks a script global forward: the handler runs whenever a script fires it (after the scripts' own functions), and when C++ calls it through FindScriptForward(). Goes when the plugin that made the handler unloads.

ParameterType
nameconst char*
handlerSource2ModScriptForwardHandler

Returns Source2ModHookId — The hook's id, 0 on an empty name or handler

UnhookScriptForward

virtual bool UnhookScriptForward(Source2ModHookId id) = 0;
ParameterType
idSource2ModHookId

AddLibraryListener

virtual Source2ModHookId AddLibraryListener(Source2ModLibraryHandler handler, bool replay = true) = 0;

Tells about libraries coming and going -- a script's RegisterLibrary or a C++ RegisterLibrary(), what scripts get as OnLibraryAdded / OnLibraryRemoved. A library goes when the last plugin that registered it unloads; by then that plugin's natives no longer answer (a call from the handler is refused).

ParameterTypeDefaultDescription
handlerSource2ModLibraryHandler
replaybooltrueCall the handler now for every library already there

Returns Source2ModHookId — The listener's id, 0 on an empty handler

RemoveLibraryListener

virtual bool RemoveLibraryListener(Source2ModHookId id) = 0;
ParameterType
idSource2ModHookId

EntityFromScriptCell

virtual CEntityInstance* EntityFromScriptCell(cell_t value) = 0;

The live entity a script's entity cell names (natives, forward arguments); nullptr for NULL_ENTITY or a removed one.

ParameterType
valuecell_t

ScriptCellFromEntity

virtual cell_t ScriptCellFromEntity(CEntityInstance* entity) = 0;

An entity as a script's entity methodmap value; -1 (NULL_ENTITY) for nullptr.

ParameterType
entityCEntityInstance*

Source2ModScriptBuffer

A string a script writes into: Call(..., Source2ModScriptBuffer{ buf, sizeof(buf) }).

Fields

FieldType
datachar*
sizesize_t

Source2ModScriptArray

A cell array: Call(..., Source2ModScriptArray{ values, 3 }); copyback takes the script's changes.

Fields

FieldType
datacell_t*
countsize_t
copybackbool

Source2ModScriptArg

One argument of a call into a script, or of a script forward a C++ hook receives. The pointers are the caller's: a script writing a reference, an array or a string buffer writes through them.

Fields

FieldTypeDescription
typeSource2ModScriptArgType
sizeuint32_tStringBuffer: bytes, Array: cells
copybackboolArray

Constructors

Source2ModScriptArg();

Int

static Source2ModScriptArg Int(cell_t value);
ParameterType
valuecell_t

Float

static Source2ModScriptArg Float(float value);
ParameterType
valuefloat

Bool

static Source2ModScriptArg Bool(bool value);
ParameterType
valuebool

Entity

static Source2ModScriptArg Entity(CEntityInstance* value);
ParameterType
valueCEntityInstance*

String

static Source2ModScriptArg String(const char* value);
ParameterType
valueconst char*

Buffer

static Source2ModScriptArg Buffer(char* data, size_t size);
ParameterType
datachar*
sizesize_t

Array

static Source2ModScriptArg Array(cell_t* data, size_t count, bool copyback = false);
ParameterTypeDefault
datacell_t*
countsize_t
copybackboolfalse

CellRef

static Source2ModScriptArg CellRef(cell_t* value);
ParameterType
valuecell_t*

FloatRef

static Source2ModScriptArg FloatRef(float* value);
ParameterType
valuefloat*

Null

static Source2ModScriptArg Null(Source2ModScriptArgType nullType);
ParameterType
nullTypeSource2ModScriptArgType

AsInt

cell_t AsInt() const;

The value as a cell: a Cell / Bool / Entity forward argument (an entity as the script's cell, see EntityFromScriptCell), a reference's value.

AsFloat

float AsFloat() const;

AsBool

bool AsBool() const;

AsString

const char* AsString() const;

A String or StringBuffer argument; "" for anything else.

ISource2ModScriptCallable

Something in a script C++ can call: a native a script made, a global forward. Owned by the core, valid until it unloads.

GetName

virtual const char* GetName() const = 0;

IsAvailable

virtual bool IsAvailable() const = 0;

Whether a call would reach a script right now.

Invoke

virtual bool Invoke(const Source2ModScriptArg* args, int count, cell_t* result) = 0;

Calls it with arguments as they are.

ParameterTypeDescription
argsconst Source2ModScriptArg*
countint
resultcell_t*The return value (a forward's, combined by its ExecType); may be nullptr

Returns bool — false when refused (not available, a bad argument) or the script raised an error; GetLastError() says which

GetLastError

virtual const char* GetLastError() const = 0;

Why the last Invoke() failed; "" after one that went through.

EntityFromCell

virtual CEntityInstance* EntityFromCell(cell_t value) const = 0;

The live entity a script's entity cell names, nullptr for NULL_ENTITY or a removed one.

ParameterType
valuecell_t

Call

template <typename R = void, typename... A> R Call(A&&... args);

A typed call. Arguments: integers / enums / a Handle (cell), bool, float / double, const char* / std::string / a string literal (const char[]), char buf[N] or Source2ModScriptBuffer (a string the script writes), Source2ModScriptArray, cell_t* / float* (int& / float&), an entity pointer (CEntityInstance or derived; nullptr is NULL_ENTITY), Source2ModScriptNullString / NullVector, or a ready Source2ModScriptArg. R: void, bool, an integer or enum, float, or an entity pointer.

ParameterType
argsA&&...

Returns R — The result, value-initialised when the call failed

TryCall

template <typename R, typename... A> bool TryCall(R* out, A&&... args);

Call() that says whether it went through; @p out may be nullptr.

ParameterType
outR*
argsA&&...

ISource2ModScriptNative

A native a script made with Source2ModNatives.CreateNative, by name. The script reads the arguments with Source2ModNatives.GetCell / GetString / GetCellRef / GetArray... as for a script caller; its plugin parameter is INVALID_HANDLE (a C++ caller has none). Source2ModNatives.FormatString and GetFunction have nothing to read from a C++ caller and fail.

Inherits ISource2ModScriptCallable

GetOwner

virtual PluginId GetOwner() const = 0;

The plugin that registered it now, 0 while none has.

ISource2ModScriptForward

A global forward by name: every running script's public function of that name (GlobalForward semantics) and every C++ HookScriptForward() on it, in that order. The result -- a Source2ModAction value, 0 Ignore, 1 Override, 2 Supersede -- is combined by the ExecType of the script's GlobalForward of that name, ET_Event (the highest) when no script made one.

Inherits ISource2ModScriptCallable

GetFunctionCount

virtual int GetFunctionCount() const = 0;

Script functions plus C++ hooks a call would reach.

Enums

Source2ModScriptArgType

enum class Source2ModScriptArgType : int32_t

What an argument of a call into a script is.

NameValueDescription
Cell0any, int, a Handle: cell
Floatfloat: flt
Boolbool: cell (0 / 1)
Entityan entity methodmap value: entity (nullptr is NULL_ENTITY)
Stringconst char[]: string
StringBufferchar[] the script may write (Source2ModNatives.SetString): buffer, size bytes
Arrayany[]: array, size cells; written back when copyback
CellRefint &: cellRef
FloatReffloat &: floatRef
NullStringNULL_STRING
NullVectorNULL_VECTOR

Functions

ToArg

template <typename T> Source2ModScriptArg ToArg(T&& value);
ParameterType
valueT&&

On this page