Handles to SourcePawn variables
The name says it all. This extension adds the ability to create handles to your variables and use them as pointers. It was designed to allow fast access to a buffer that is not known at compile time. Such as the one that is provided by the code of another authors. It's done on rather low level so if you create handle to a temporary variable and then try to mess with it after it was deallocated, you may crash the server.
Include file:
PHP Code:
#if defined _spvhandles_included
#endinput
#endif
#define _spvhandles_included
/**
* Returns handle to the cell.
*
* @param cell Source cell.
* @return Handle to the source cell.
*/
native Handle:CreateCellHandle(const &any:cell);
/**
* Returns handle to the array.
*
* @param array Source array.
* @param size Size of the source array.
* @return Handle to the source array.
* @error Invalid array size.
*/
native Handle:CreateArrayHandle(const any:array[], const size);
/**
* Returns handle to the string.
*
* @param string Source string.
* @param size Size of the source string.
* @return Handle to the source string.
* @error Invalid string size.
*/
native Handle:CreateStringHandle(const String:string[], const size);
/**
* Checks if provided handle is a valid cell handle.
*
* @param handle Source handle.
* @return True if it's a valid handle, false otherwise.
*/
native bool:IsValidCellHandle(const Handle:handle);
/**
* Returns the value of the cell associated with handle.
*
* @param handle Source handle.
* @return Value of the cell associated with handle.
* @error Invalid handle.
*/
native GetHandleCell(const Handle:handle);
/**
* Sets the value of the cell associated with handle.
*
* @param handle Source handle.
* @param value Value to set.
* @return True on success, false otherwise.
* @error Invalid handle.
*/
native bool:SetHandleCell(const Handle:handle, const any:value);
/**
* Checks if provided handle is a valid array handle.
*
* @param handle Source handle.
* @return True if it's a valid handle, false otherwise.
*/
native bool:IsValidArrayHandle(const Handle:handle);
/**
* Returns the size of the array associated with handle.
*
* @param handle Source handle.
* @return Size of the array associated with handle.
* @error Invalid handle.
*/
native GetHandleArraySize(const Handle:handle);
/**
* Returns the value of the array cell associated with handle.
*
* @param handle Source handle.
* @param index Index of the cell.
* @return Value of the array cell associated with handle.
* @error Invalid handle or array index is out of bounds.
*/
native GetHandleArrayCell(const Handle:handle, const index);
/**
* Sets the value of the array cell associated with handle.
*
* @param handle Source handle.
* @param index Index of the cell.
* @param value Value to set.
* @return True on success, false otherwise.
* @error Invalid handle or array index is out of bounds.
*/
native bool:SetHandleArrayCell(const Handle:handle, const index, const any:value);
/**
* Copies contents of the array associated with handle.
*
* @param handle Source handle.
* @param array Array to hold contents in.
* @param size Size of the provided array.
* @return Number of cells written.
* @error Invalid handle or array size.
*/
native GetHandleArray(const Handle:handle, any:array[], const size);
/**
* Copies contents of the provided array into the array associated with handle.
*
* @param handle Source handle.
* @param array Array to copy.
* @param size Size of the provided array.
* @return Number of cells written.
* @error Invalid handle or array size.
*/
native SetHandleArray(const Handle:handle, const any:array[], const size);
/**
* Checks if provided handle is a valid string handle.
*
* @param handle Source handle.
* @return True if it's a valid handle, false otherwise.
*/
native bool:IsValidStringHandle(const Handle:handle);
/**
* Returns the size of the string associated with handle.
*
* @param handle Source handle.
* @return Size of the string associated with handle.
* @error Invalid handle.
*/
native GetHandleStringSize(const Handle:handle);
/**
* Copies contents of the string associated with handle.
*
* @param handle Source handle.
* @param string String to hold contents in.
* @param size Size of the provided string.
* @return Number of characters written.
* @error Invalid handle or string size.
*/
native GetHandleString(const Handle:handle, String:string[], const size);
/**
* Copies contents of the provided string into the one associated with handle.
*
* @param handle Source handle.
* @param string String to copy.
* @param size Size of the provided string.
* @return Number of characters written.
* @error Invalid handle or string size.
*/
native SetHandleString(const Handle:handle, const String:string[], const size);
public Extension:__ext_spvhandles =
{
name = "Handles to SourcePawn variables",
file = "ftz_handles.ext",
#if defined AUTOLOAD_EXTENSIONS
autoload = 1,
#else
autoload = 0,
#endif
#if defined REQUIRE_EXTENSIONS
required = 1,
#else
required = 0,
#endif
};
This example plugin tests all natives:
PHP Code:
#include <sourcemod>
#include "ftz_public/spvhandles"
#define PLUGIN_VERSION "1.0.0.2"
public Plugin:myinfo =
{
name = "SPV handles test",
author = "FaTony",
description = "Test",
version = PLUGIN_VERSION,
url = "http://fatony.com/"
};
new globalcell = 1337;
new globalarray[3] = { 0, 1, 2 }
new String:globalstring[5] = "Hello";
public OnPluginStart()
{
RegServerCmd("ftz_spvhandles_test", Command_SPVHandlesTest);
}
public Action:Command_SPVHandlesTest(args)
{
new Handle:cellhandle = CreateCellHandle(globalcell);
if (!IsValidCellHandle(cellhandle))
{
PrintToServer("Invalid cell handle");
return Plugin_Handled;
}
PrintToServer("Value = %d (should be 1337)", GetHandleCell(cellhandle));
SetHandleCell(cellhandle, 69);
PrintToServer("Value = %d (should be 69)", globalcell);
CloseHandle(cellhandle);
cellhandle = INVALID_HANDLE;
new Handle:arrayhandle = CreateArrayHandle(globalarray, 3);
if (!IsValidArrayHandle(arrayhandle))
{
PrintToServer("Invalid array handle");
return Plugin_Handled;
}
PrintToServer("Size = %d (should be 3)", GetHandleArraySize(arrayhandle));
PrintToServer("Array cells = %d %d %d (should be 0 1 2)", GetHandleArrayCell(arrayhandle, 0), GetHandleArrayCell(arrayhandle, 1), GetHandleArrayCell(arrayhandle, 2));
SetHandleArrayCell(arrayhandle, 0, 3);
SetHandleArrayCell(arrayhandle, 1, 5);
SetHandleArrayCell(arrayhandle, 2, 7);
PrintToServer("New values = %d %d %d (should be 3 5 7)", globalarray[0], globalarray[1], globalarray[2]);
decl array[3];
GetHandleArray(arrayhandle, array, 3);
PrintToServer("Values = %d %d %d (should be 3 5 7)", array[0], array[1], array[2]);
array[0] = 2;
array[1] = 1;
array[2] = 0;
SetHandleArray(arrayhandle, array, 3);
PrintToServer("Yet another new values = %d %d %d (should be 2 1 0)", globalarray[0], globalarray[1], globalarray[2]);
CloseHandle(arrayhandle);
arrayhandle = INVALID_HANDLE;
new Handle:stringhandle = CreateStringHandle(globalstring, 5);
if (!IsValidStringHandle(stringhandle))
{
PrintToServer("Invalid string handle");
return Plugin_Handled;
}
PrintToServer("Size = %d (should be 5)", GetHandleStringSize(stringhandle));
decl String:string[5];
GetHandleString(stringhandle, string, 5);
PrintToServer("String = \"%s\" (should be \"Hello\")", string);
strcopy(string, 5, "Hi");
SetHandleString(stringhandle, string, 5);
PrintToServer("String = \"%s\" (should be \"Hi\")", globalstring);
CloseHandle(stringhandle);
stringhandle = INVALID_HANDLE;
return Plugin_Handled;
}
Thanks to [AAA] Thrawn for the linux build.
Projects using this extension:
[INC] Hard linking ConVars to variables