<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.alliedmods.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Zerak</id>
	<title>AlliedModders Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.alliedmods.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Zerak"/>
	<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/Special:Contributions/Zerak"/>
	<updated>2026-05-09T11:38:46Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.6</generator>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Optional_Requirements_(SourceMod_Scripting)&amp;diff=6065</id>
		<title>Optional Requirements (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Optional_Requirements_(SourceMod_Scripting)&amp;diff=6065"/>
		<updated>2008-07-20T15:51:19Z</updated>

		<summary type="html">&lt;p&gt;Zerak: /* Optional Natives */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Normally, if you use natives from an extension or another plugin, your plugin will not load unless those natives exist.  However, it is possible to make your dependencies &amp;quot;optional.&amp;quot;  This article details how.&lt;br /&gt;
&lt;br /&gt;
=Disabling Requirements=&lt;br /&gt;
==Extensions==&lt;br /&gt;
To disable an extension being marked as &amp;quot;required,&amp;quot; remove the &amp;lt;tt&amp;gt;REQUIRE_EXTENSIONS&amp;lt;/tt&amp;gt; define.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#undef REQUIRE_EXTENSIONS&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that any extensions included after the &amp;lt;tt&amp;gt;#undef&amp;lt;/tt&amp;gt; will also be marked as not required.  Thus, you may need to move the include down, or do something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#undef REQUIRE_EXTENSIONS&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
#define REQUIRE_EXTENSIONS&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Plugins==&lt;br /&gt;
To disable an plugin being marked as &amp;quot;required,&amp;quot; remove the &amp;lt;tt&amp;gt;REQUIRE_PLUGIN&amp;lt;/tt&amp;gt; define.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#undef REQUIRE_PLUGIN&lt;br /&gt;
#include &amp;lt;ircrelay&amp;gt;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that any plugins included after the &amp;lt;tt&amp;gt;#undef&amp;lt;/tt&amp;gt; will also be marked as not required.  Thus, you may need to move the include down, or do something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#undef REQUIRE_PLUGIN&lt;br /&gt;
#include &amp;lt;ircrelay&amp;gt;&lt;br /&gt;
#define REQUIRE_PLUGIN&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Optional Natives==&lt;br /&gt;
To mark a native as optional, use &amp;lt;tt&amp;gt;MarkNativeAsOptional&amp;lt;/tt&amp;gt;.  It should be called in &amp;lt;tt&amp;gt;AskPluginLoad&amp;lt;/tt&amp;gt;.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public bool:AskPluginLoad(Handle:myself, bool:late, String:error[], err_max)&lt;br /&gt;
{&lt;br /&gt;
	MarkNativeAsOptional(&amp;quot;SDKCall&amp;quot;);&lt;br /&gt;
	return true;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Checking Optional Dependencies=&lt;br /&gt;
If you use a plugin or extension as an optional dependency, you may need to check whether it exists.  For example, let's say we're relying on a plugin with the library name of &amp;quot;ircrelay.&amp;quot;  The way to always know whether ircrelay is loaded (and working) is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new bool:ircrelay = false;&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	ircrelay = LibraryExists(&amp;quot;ircrelay&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnLibraryRemoved(const String:name[])&lt;br /&gt;
{&lt;br /&gt;
	if (StrEqual(name, &amp;quot;ircrelay&amp;quot;))&lt;br /&gt;
	{&lt;br /&gt;
		ircrelay = false;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnLibraryAdded(const String:name[])&lt;br /&gt;
{&lt;br /&gt;
	if (StrEqual(name, &amp;quot;ircrelay&amp;quot;))&lt;br /&gt;
	{&lt;br /&gt;
		ircrelay = true;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Creating a Dependency=&lt;br /&gt;
Allowing other plugins to use your plugin as a library requires making an include file with two structures (the second of which is optional).  The first structure must look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public SharedPlugin:__pl_myfile = &lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;myfile&amp;quot;,&lt;br /&gt;
	file = &amp;quot;myfile.smx&amp;quot;,&lt;br /&gt;
#if defined REQUIRE_PLUGIN&lt;br /&gt;
	required = 1,&lt;br /&gt;
#else&lt;br /&gt;
	required = 0,&lt;br /&gt;
#endif&lt;br /&gt;
};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The basic format is:&lt;br /&gt;
*The variable name MUST start with &amp;lt;tt&amp;gt;__pl_&amp;lt;/tt&amp;gt; and must end with a unique string.&lt;br /&gt;
*The &amp;quot;name&amp;quot; portion is treated as the library name and must be unique.&lt;br /&gt;
*The filename must match the filename of the plugin implementing the library.&lt;br /&gt;
*The requirement portion should remain unchanged in order to maintain standards.&lt;br /&gt;
&lt;br /&gt;
Additionally, you should expose a function which marks all of your natives as optional.  You can do this by:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public __pl_myfile_SetNTVOptional()&lt;br /&gt;
{&lt;br /&gt;
	MarkNativeAsOptional(&amp;quot;native1&amp;quot;);&lt;br /&gt;
	MarkNativeAsOptional(&amp;quot;native2&amp;quot;);&lt;br /&gt;
	MarkNativeAsOptional(&amp;quot;native3&amp;quot;);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This function will be secretly called before the plugin loads (if and only if the requirement is optional), thus allowing seamless optional usage by third party developers.  Note that the &amp;lt;tt&amp;gt;__pl_&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;_SetNTVOptional&amp;lt;/tt&amp;gt; portions &amp;lt;b&amp;gt;must&amp;lt;/b&amp;gt; be present, and that everything in between must match the ending of &amp;lt;tt&amp;gt;__pl_&amp;lt;/tt&amp;gt; for the &amp;lt;tt&amp;gt;SharedPlugin&amp;lt;/tt&amp;gt; structure.&lt;br /&gt;
&lt;br /&gt;
You also must register the library name with SourceMod -- again this should be the unique string. This is should be done inside the &amp;lt;code&amp;gt;OnPluginStart&amp;lt;/code&amp;gt; function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart() &lt;br /&gt;
{&lt;br /&gt;
	//... code here ...&lt;br /&gt;
	RegPluginLibrary(&amp;quot;myfile&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Full Example =&lt;br /&gt;
;''Bounty: bounty.sp''&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#undef REQUIRE_PLUGIN&lt;br /&gt;
#include &amp;lt;ircrelay&amp;gt;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
;''Bounty: bounty.config.sp''&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new bool:plugin_IrcRelay = LibraryExists(&amp;quot;ircrelay&amp;quot;);&lt;br /&gt;
if ((BountyIRC) &amp;amp;&amp;amp; (plugin_IrcRelay))&lt;br /&gt;
{&lt;br /&gt;
	RegisterIrcCommand(&amp;quot;!bounty&amp;quot;, &amp;quot;x&amp;quot;, Irc_ViewBounty);&lt;br /&gt;
	IrcMessage(CHAN_MASTER, &amp;quot;IRC Bounty Running!&amp;quot;);&lt;br /&gt;
} else {&lt;br /&gt;
	if ((BountyIRC) &amp;amp;&amp;amp; (!plugin_IrcRelay))&lt;br /&gt;
	{&lt;br /&gt;
		BountyConsole_Debug(&amp;quot;%t&amp;quot;, &amp;quot;Bounty IRC Relay failed&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
;''IRC Relay: ircrelay.sp''&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart() &lt;br /&gt;
{&lt;br /&gt;
	//... code here ...&lt;br /&gt;
	RegPluginLibrary(&amp;quot;ircrelay&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
;''IRC Relay: ircrelay.inc''&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public SharedPlugin:__pl_ircrelay = &lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;ircrelay&amp;quot;,&lt;br /&gt;
	file = &amp;quot;ircrelay.smx&amp;quot;,&lt;br /&gt;
#if defined REQUIRE_PLUGIN&lt;br /&gt;
	required = 1,&lt;br /&gt;
#else&lt;br /&gt;
	required = 0,&lt;br /&gt;
#endif&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public __pl_ircrelay_SetNTVOptional()&lt;br /&gt;
{&lt;br /&gt;
	MarkNativeAsOptional(&amp;quot;IrcMessage&amp;quot;);&lt;br /&gt;
	MarkNativeAsOptional(&amp;quot;RegisterIrcCommand&amp;quot;);&lt;br /&gt;
	MarkNativeAsOptional(&amp;quot;IrcGetCmdArgc&amp;quot;);&lt;br /&gt;
	MarkNativeAsOptional(&amp;quot;IrcGetCmdArgv&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; value is what will be checked when you run &amp;lt;code&amp;gt;LibraryExists&amp;lt;/code&amp;gt;. This allows the bounty script to fully work, even if the IRC relay plugin is not installed and/or running correctly on your server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Zerak</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Handle_API_(SourceMod)&amp;diff=5690</id>
		<title>Handle API (SourceMod)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Handle_API_(SourceMod)&amp;diff=5690"/>
		<updated>2008-03-29T12:38:39Z</updated>

		<summary type="html">&lt;p&gt;Zerak: &amp;quot;cannot&amp;quot; changed to &amp;quot;can also&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The SourceMod [[Handles (SourceMod Scripting)|Handle System]] marshals pointers into typed, unique, 32-bit integers.  This makes coding in SourceMod more cross-platform compatible, type safe, and mistake safe than its predecessor, [[AMX Mod X]].  It also allows for safe object sharing and reference count based object destruction.&lt;br /&gt;
&lt;br /&gt;
The fundamental aspect of Handles is that they encapsulate a single pointer.  This pointer is private data, and can only be read by the Handle's creator.  When the Handle is freed, the pointer is automatically freed (via a special interface), thus ensuring that memory is not leaked.&lt;br /&gt;
&lt;br /&gt;
Handles also provide a simple &amp;quot;security&amp;quot; system for restricting which areas of SourceMod are allowed to directly call certain functions on Handles under a given type.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Basic Types=&lt;br /&gt;
==Handle_t==&lt;br /&gt;
The &amp;lt;tt&amp;gt;Handle_t&amp;lt;/tt&amp;gt; type is a 32bit integer.  Currently, it is composed of two 16-bit integers, a serial number and a handle index.  The serial number is private and used for integrity checking.  The index is the internal ID of the Handle, which is tied to the encapsulated pointer and security information.&lt;br /&gt;
&lt;br /&gt;
Each &amp;lt;tt&amp;gt;Handle_t&amp;lt;/tt&amp;gt; is a unique Handle, however, there are ''cloned'' Handles which are copies of another Handle.  They have their own unique signatures, but they refer to another Handle internally.  Each Handle is also associated with a ''type'', explained below.&lt;br /&gt;
&lt;br /&gt;
==HandleType_t==&lt;br /&gt;
The &amp;lt;tt&amp;gt;HandleType_t&amp;lt;/tt&amp;gt; describes a type under which Handles can be created.  Types can have up to 15 sub-types; sub-types can also have their own sub-types, called child types.  When Handles are being read, they are &amp;quot;type checked,&amp;quot; to make sure they are being read under a given type.  When a type is destroyed, all Handles under the type are destroyed.  If the type has child types, each child type is also destroyed. &lt;br /&gt;
&lt;br /&gt;
Handle types also allow overloading of various Handle operations.  Currently, the only overloaded action is for overloading when a Handle is destroyed.  This allows the encapsulated pointer to be safely destroyed by the type interface.  The interface which overloads type operations is called &amp;lt;tt&amp;gt;IHandleTypeDispatch&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Lastly, types provide a &amp;quot;default security&amp;quot; system which lets programmers restrict which functions can be accessed by other areas in SourceMod.  This is explained later.&lt;br /&gt;
&lt;br /&gt;
=Security=&lt;br /&gt;
'''Note:''' Type defaults can be set via &amp;lt;tt&amp;gt;IHandleSys::InitAccessDefaults()&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Type Security==&lt;br /&gt;
Often, extensions may want to share HandleType_t values with each other, so they can create Handles of external types.  However, the owner of the handle type may not want other extensions to perform certain actions.  Thus, types can be ''secured'' by an &amp;lt;tt&amp;gt;IdentityToken_t&amp;lt;/tt&amp;gt; when created.  Unless the same &amp;lt;tt&amp;gt;IdentityToken&amp;lt;/tt&amp;gt; is provided, a function may fail if restricted.&lt;br /&gt;
&lt;br /&gt;
Type permissions are declared in a &amp;lt;tt&amp;gt;TypeAccess&amp;lt;/tt&amp;gt; struct, which has the following user-set members:&lt;br /&gt;
*&amp;lt;tt&amp;gt;ident&amp;lt;/tt&amp;gt;: The &amp;lt;tt&amp;gt;IdentityToken_t&amp;lt;/tt&amp;gt; owner of this type.&lt;br /&gt;
*&amp;lt;tt&amp;gt;access&amp;lt;/tt&amp;gt;: An array where each index is a &amp;lt;tt&amp;gt;HTypeAccessRight&amp;lt;/tt&amp;gt; enumeration member.  If an index is set to false, functions requiring that right will fail unless the correct &amp;lt;tt&amp;gt;IdentityToken_t&amp;lt;/tt&amp;gt; is passed in.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;HTypeAccessRight&amp;lt;/tt&amp;gt; enumeration has the following values:&lt;br /&gt;
*&amp;lt;tt&amp;gt;HTypeAccess_Create&amp;lt;/tt&amp;gt;: Handle creation using this type; default is false.&lt;br /&gt;
*&amp;lt;tt&amp;gt;HTypeAccess_Inherit&amp;lt;/tt&amp;gt;: Inheriting this type for child types; default is false.&lt;br /&gt;
&lt;br /&gt;
Below is a list of each Handle System function that requires type permissions, and which permissions may be required:&lt;br /&gt;
*&amp;lt;tt&amp;gt;CreateType&amp;lt;/tt&amp;gt;: &amp;lt;i&amp;gt;&amp;lt;tt&amp;gt;HTypeAccess_Inherit&amp;lt;/tt&amp;gt; if a parent is specified&amp;lt;/i&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;RemoveType&amp;lt;/tt&amp;gt;: &amp;lt;i&amp;gt;(none, always secured)&amp;lt;/i&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;CreateHandle&amp;lt;/tt&amp;gt;: &amp;lt;i&amp;gt;&amp;lt;tt&amp;gt;HTypeAccess_Create&amp;lt;/tt&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Handle Security==&lt;br /&gt;
Handle security permissions inherit from their parent type unless given an alternate set of permissions.  Handles are &amp;quot;secured&amp;quot; by two properties, unlike Handles, which just have one.  When verifying your identity with a secured Handle function, you must use the &amp;lt;tt&amp;gt;HandleSecurity&amp;lt;/tt&amp;gt; struct, which has two properties:&lt;br /&gt;
*&amp;lt;tt&amp;gt;pOwner&amp;lt;/tt&amp;gt;: The owner of the Handle, which is usually a plugin &amp;lt;tt&amp;gt;IdentityToken_t&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*&amp;lt;tt&amp;gt;pIdentity&amp;lt;/tt&amp;gt;: The owner of the Handle's type, or the &amp;lt;tt&amp;gt;IdentityToken_t&amp;lt;/tt&amp;gt; securing its type.&lt;br /&gt;
&lt;br /&gt;
Handle permissions are specified via the &amp;lt;tt&amp;gt;HandleAccess&amp;lt;/tt&amp;gt; struct.  It is passed either through &amp;lt;tt&amp;gt;CreateType&amp;lt;/tt&amp;gt; for default settings in a given type, or through &amp;lt;tt&amp;gt;CreateHandleEx&amp;lt;/tt&amp;gt; for explicit per-Handle permissions.  This struct has the following members:&lt;br /&gt;
*&amp;lt;tt&amp;gt;access&amp;lt;/tt&amp;gt;: An array where each index is a &amp;lt;tt&amp;gt;HandleAccessRight&amp;lt;/tt&amp;gt; enumeration member.  If set to 0, an access right is allowed without a &amp;lt;tt&amp;gt;HandleSecurity&amp;lt;/tt&amp;gt; instance.  Otherwise, the following bitwise flags are checked:&lt;br /&gt;
**&amp;lt;tt&amp;gt;HANDLE_RESTRICT_IDENTITY&amp;lt;/tt&amp;gt;: If flagged, this access right is only granted if the &amp;lt;tt&amp;gt;pIdentity&amp;lt;/tt&amp;gt; member of the &amp;lt;tt&amp;gt;HandleSecurity&amp;lt;/tt&amp;gt; struct matches the Handle's '''type's''' owner.&lt;br /&gt;
**&amp;lt;tt&amp;gt;HANDLE_RESTRICT_OWNER&amp;lt;/tt&amp;gt;: If flagged, this access right is onyl granted if the &amp;lt;tt&amp;gt;pOwner&amp;lt;/tt&amp;gt; member of the &amp;lt;tt&amp;gt;Handlesecurity&amp;lt;/tt&amp;gt; struct matches the Handle's owner.&lt;br /&gt;
&lt;br /&gt;
The following access rights exist for Handles:&lt;br /&gt;
*&amp;lt;tt&amp;gt;HandleAccess_Read&amp;lt;/tt&amp;gt;: This Handle's encapsulated pointer can be retrieved.  Defaults to &amp;lt;tt&amp;gt;HANDLE_RESTRICT_IDENTITY&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*&amp;lt;tt&amp;gt;HandleAccess_Delete&amp;lt;/tt&amp;gt;: This Handle can be removed or freed.  Defaults to &amp;lt;tt&amp;gt;HANDLE_RESTRICT_OWNER&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*&amp;lt;tt&amp;gt;HandleAccess_Clone&amp;lt;/tt&amp;gt;: This Handle can be cloned.  Defaults to 0.&lt;br /&gt;
&lt;br /&gt;
Below is a list of each Handle system function that requires permissions, and which permissions may be required:&lt;br /&gt;
*&amp;lt;tt&amp;gt;FreeHandle&amp;lt;/tt&amp;gt;: &amp;lt;i&amp;gt;&amp;lt;tt&amp;gt;HandleAccess_Delete&amp;lt;/tt&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;CloneHandle/CloneHandleEx&amp;lt;/tt&amp;gt;: &amp;lt;i&amp;gt;&amp;lt;tt&amp;gt;HandleAccess_Clone&amp;lt;/tt&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
*&amp;lt;tt&amp;gt;ReadHandle&amp;lt;/tt&amp;gt;: &amp;lt;i&amp;gt;&amp;lt;tt&amp;gt;HandleAccess_Read&amp;lt;/tt&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SourceMod's generic native wrappers assume follow these rules, however, they assume certain access rights, and will return &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; or 0 if these rights are denied.  Thus, you should make sure your permissions are compatible, unless you explicitly want to deny usage of these functions.&lt;br /&gt;
*&amp;lt;tt&amp;gt;CloneHandle()&amp;lt;/tt&amp;gt;: Passes &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; for &amp;lt;tt&amp;gt;HandleSecurity&amp;lt;/tt&amp;gt;, meaning &amp;lt;tt&amp;gt;HandleAccess_Clone&amp;lt;/tt&amp;gt; must be 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt;: Passes &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; for &amp;lt;tt&amp;gt;HandleSecurity::pIdentity&amp;lt;/tt&amp;gt;, and the plugin's &amp;lt;tt&amp;gt;IdentityToken_t&amp;lt;/tt&amp;gt; for &amp;lt;tt&amp;gt;HandleSecurity::pOwner&amp;lt;/tt/&amp;gt;.  This means that at most, the only restriction can be &amp;lt;tt&amp;gt;HANDLE_RESTRICT_OWNER&amp;lt;/tt&amp;gt; for &amp;lt;tt&amp;gt;HandleAccess_Delete&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Usage Examples=&lt;br /&gt;
Here are some examples of Handle usages.&lt;br /&gt;
&lt;br /&gt;
==Basic Handles==&lt;br /&gt;
The most basic use of Handles is to encapsulate a data structure and allow &amp;lt;tt&amp;gt;CloseHandle&amp;lt;/tt&amp;gt; to universally destroy it.  Let's say we want to implement two natives - &amp;lt;tt&amp;gt;CreateFile&amp;lt;/tt&amp;gt; for creating an empty file, and &amp;lt;tt&amp;gt;WriteLine&amp;lt;/tt&amp;gt; for writing a line to this file.  How could we implement this using the Handle system?&lt;br /&gt;
&lt;br /&gt;
After reading this, it is tempting to think, &amp;quot;Why can't we just return the &amp;lt;tt&amp;gt;FILE&amp;lt;/tt&amp;gt; pointer as a &amp;lt;tt&amp;gt;cell_t&amp;lt;/tt&amp;gt;?&amp;quot;  The reason is that a &amp;lt;tt&amp;gt;cell_t&amp;lt;/tt&amp;gt; is guaranteed to be a 32bit integer.  There is no guarantee that a pointer will always be this size, however, and thus casting on future platforms could break.  This problem happened in [[AMX Mod X]] and greatly restricted flexibility.  &lt;br /&gt;
&lt;br /&gt;
===Creating the type===&lt;br /&gt;
First, we have to create the type and its Dispatch interface.&lt;br /&gt;
&amp;lt;cpp&amp;gt;HandleType_t g_FileType = 0;	/* Holds the HandleType ID */&lt;br /&gt;
&lt;br /&gt;
class FileTypeHandler : public IHandleTypeDispatch&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
	void OnHandleDestroy(HandleType_t type, void *object)&lt;br /&gt;
	{&lt;br /&gt;
		/* :TODO: implement this */&lt;br /&gt;
	}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/* Create an instance of the handler */&lt;br /&gt;
FileTypeHandler g_FileTypeHandler;&lt;br /&gt;
&lt;br /&gt;
Initialize()&lt;br /&gt;
{&lt;br /&gt;
	/* Register the type with default security permissions */&lt;br /&gt;
	g_FileType = g_pHandleSys-&amp;gt;CreateType(&amp;quot;File&amp;quot;, &lt;br /&gt;
		&amp;amp;g_FileTypeHandler, &lt;br /&gt;
		0, &lt;br /&gt;
		NULL, &lt;br /&gt;
		NULL, &lt;br /&gt;
		myself-&amp;gt;GetIdentity(), &lt;br /&gt;
		NULL);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Shutdown()&lt;br /&gt;
{&lt;br /&gt;
	/* Remove the type on shutdown */&lt;br /&gt;
	g_pHandleSys-&amp;gt;RemoveType(g_FileType, myself-&amp;gt;GetIdentity());&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Creating Handles===&lt;br /&gt;
Creating the Handles is fairly easy once we have a valid pointer to stuff in it.&lt;br /&gt;
&amp;lt;cpp&amp;gt;/* native CreateFile(const String:file[]) */&lt;br /&gt;
static cell_t sm_CreateFile(IPluginContext *pContext, const cell_t *params)&lt;br /&gt;
{&lt;br /&gt;
	char path[PLATFORM_MAX_PATH];&lt;br /&gt;
	char *filename;&lt;br /&gt;
&lt;br /&gt;
	/* Get the filename */&lt;br /&gt;
	pContext-&amp;gt;LocalToString(params[1], &amp;amp;filename);&lt;br /&gt;
	/* Build a full path */&lt;br /&gt;
	g_pSM-&amp;gt;BuildPath(Path_SM, path, sizeof(path), &amp;quot;%s&amp;quot;, filename);&lt;br /&gt;
	&lt;br /&gt;
	/* Open for writing */&lt;br /&gt;
	FILE *fp = fopen(path, &amp;quot;wt&amp;quot;);&lt;br /&gt;
	if (!fp)&lt;br /&gt;
	{&lt;br /&gt;
		return BAD_HANDLE;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Create the Handle with our type, the FILE pointer, the plugin's identity, and our identity */&lt;br /&gt;
	return g_pHandleSys-&amp;gt;CreateHandle(g_FileType, &lt;br /&gt;
		fp, &lt;br /&gt;
		pContext-&amp;gt;GetIdentity(), &lt;br /&gt;
		myself-&amp;gt;GetIdentity(), &lt;br /&gt;
		NULL);&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Reading/Checking Handles===&lt;br /&gt;
Handles aren't very useful unless you have natives to use them.  Let's say we want to write lines of text to our File type.&lt;br /&gt;
&amp;lt;cpp&amp;gt;/* native WriteLine(Handle:hndl, const String:line[]); */&lt;br /&gt;
static cell_t sm_WriteLine(IPluginContext *pContext, const cell_t *params)&lt;br /&gt;
{&lt;br /&gt;
	Handle_t hndl = static_cast&amp;lt;Handle_t&amp;gt;(params[1]);&lt;br /&gt;
	HandleError err;&lt;br /&gt;
	HandleSecurity sec;&lt;br /&gt;
&lt;br /&gt;
	/* Build our security descriptor */&lt;br /&gt;
	sec.pOwner = NULL;	/* Not needed, owner access is not checked */&lt;br /&gt;
	sec.pIdentity = myself-&amp;gt;GetIdentity();	/* But only this extension can read */&lt;br /&gt;
&lt;br /&gt;
	/* Attempt to read the given handle as our type, using our security info.&lt;br /&gt;
	 * Note that we read the pointer directly in with a little cast.&lt;br /&gt;
	 * This type of cast is safe since sizeof(void **) == sizeof(void *) == sizeof(T *) in almost all cases.&lt;br /&gt;
	 */&lt;br /&gt;
	FILE *fp;&lt;br /&gt;
	if ((err = g_pHandleSys-&amp;gt;ReadHandle(hndl, g_FileType, &amp;amp;sec, (void **)&amp;amp;fp))&lt;br /&gt;
	     != HandleError_None)&lt;br /&gt;
	{&lt;br /&gt;
		return pContext-&amp;gt;ThrowNativeError(&amp;quot;Invalid file handle %x (error %d)&amp;quot;, hndl, err);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Get the text */&lt;br /&gt;
	char *text;&lt;br /&gt;
	pContext-&amp;gt;LocalToString(params[2], &amp;amp;text);&lt;br /&gt;
&lt;br /&gt;
	/* Write it */&lt;br /&gt;
	fputs(text, fp);&lt;br /&gt;
&lt;br /&gt;
	return 1;&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CloseHandle Support===&lt;br /&gt;
Lastly, we need to make it so &amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;FreeHandle()&amp;lt;/tt&amp;gt; will close our file pointer when removing the Handle, which we skipped before.&lt;br /&gt;
&amp;lt;cpp&amp;gt;class FileTypeHandler : public IHandleTypeDispatch&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
	void OnHandleDestroy(HandleType_t type, void *object)&lt;br /&gt;
	{&lt;br /&gt;
		fclose( (FILE *)object );&lt;br /&gt;
	}&lt;br /&gt;
};&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Restricting CloseHandle==&lt;br /&gt;
Let's say that, for various reasons, you don't want users to be able to call CloseHandle().  An example of this might be a data type that is non-temporary, or is being called from a forward, and thus should not be touched.  Or, you might have a special deconstructor that takes extra parameters, and thus you need a separate destroy function.&lt;br /&gt;
&lt;br /&gt;
For example, let's create a separate function called &amp;lt;tt&amp;gt;CloseFile&amp;lt;/tt&amp;gt;.  It doesn't do anything particularly special, but we are going to force its usage over CloseHandle().&lt;br /&gt;
&lt;br /&gt;
===New Security Rules===&lt;br /&gt;
&amp;lt;cpp&amp;gt;Initialize()&lt;br /&gt;
{&lt;br /&gt;
	/* Create default access rights */&lt;br /&gt;
	HandleAccess rules;&lt;br /&gt;
	g_pHandleSys-&amp;gt;InitAccessDefaults(NULL, &amp;amp;rules);&lt;br /&gt;
&lt;br /&gt;
	/* Restrict delete to only our identity */&lt;br /&gt;
	rules.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY;&lt;br /&gt;
&lt;br /&gt;
	/* Register the type with our security permissions */&lt;br /&gt;
	g_FileType = g_pHandleSys-&amp;gt;CreateType(&amp;quot;File&amp;quot;, &lt;br /&gt;
			&amp;amp;g_FileTypeHandler, &lt;br /&gt;
			0, &lt;br /&gt;
			NULL, &lt;br /&gt;
			&amp;amp;rules, &lt;br /&gt;
			myself-&amp;gt;GetIdentity(), &lt;br /&gt;
			NULL);&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Implementing the Native===&lt;br /&gt;
&amp;lt;cpp&amp;gt;/* native Closefile(Handle:hndl); */&lt;br /&gt;
static cell_t sm_CloseFile(IPluginContext *pContext, const cell_t *params)&lt;br /&gt;
{&lt;br /&gt;
	Handle_t hndl = static_cast&amp;lt;Handle_t&amp;gt;(params[1]);&lt;br /&gt;
	HandleError err;&lt;br /&gt;
	HandleSecurity sec;&lt;br /&gt;
&lt;br /&gt;
	/* Build our security descriptor */&lt;br /&gt;
	sec.pOwner = pContext-&amp;gt;GetIdentity();	/* Needed, HANDLE_RESTRICT_OWNER is default */&lt;br /&gt;
	sec.pIdentity = myself-&amp;gt;GetIdentity();	/* But only this extension can read */&lt;br /&gt;
&lt;br /&gt;
	/* Attempt to read the given handle as our type, using our security info.&lt;br /&gt;
	 * Note that we read the pointer directly in with a little cast.&lt;br /&gt;
	 * This type of cast is safe since sizeof(void **) == sizeof(void *) == sizeof(T *) in almost all cases.&lt;br /&gt;
	 */&lt;br /&gt;
	FILE *fp;&lt;br /&gt;
	if ((herr = g_pHandleSys-&amp;gt;FreeHandle(hndl, &amp;amp;src))&lt;br /&gt;
	     != HandleError_None)&lt;br /&gt;
	{&lt;br /&gt;
		return pContext-&amp;gt;ThrowNativeError(&amp;quot;Invalid file handle %x (error %d)&amp;quot;, hndl, err);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return 1;&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Restricting CloseHandle Per-Handle==&lt;br /&gt;
Taking our above example, it is possible that we might want some Handles to be closed via CloseHandle(), but others not.  Again, this is useful if you wish to pass a Handle as read-only to a plugin, commonly done when using non-temporary structures or Handles used in Forwards.&lt;br /&gt;
&lt;br /&gt;
In this example, we'll create a global instance of our file type, and this instance will be denied access to CloseHandle(), whereas files returned by OpenFile() will not.&lt;br /&gt;
&lt;br /&gt;
===Implementation===&lt;br /&gt;
&amp;lt;cpp&amp;gt;Handle_t g_GlobalFile;&lt;br /&gt;
&lt;br /&gt;
Initialize()&lt;br /&gt;
{&lt;br /&gt;
	/* Register the type with default security permissions */&lt;br /&gt;
	g_FileType = g_pHandleSys-&amp;gt;CreateType(&amp;quot;File&amp;quot;, &lt;br /&gt;
			&amp;amp;g_FileTypeHandler, &lt;br /&gt;
			0, &lt;br /&gt;
			NULL, &lt;br /&gt;
			NULL, &lt;br /&gt;
			myself-&amp;gt;GetIdentity(), &lt;br /&gt;
			NULL);&lt;br /&gt;
&lt;br /&gt;
	/* Create our 'global' file */&lt;br /&gt;
	FILE *fp = tmpfile();&lt;br /&gt;
&lt;br /&gt;
	/* Set up the security descriptor */&lt;br /&gt;
	HandleSecurity sec;&lt;br /&gt;
	sec.pOwner = NULL;		/* No owner for this Handle */&lt;br /&gt;
	sec.pIdentity = myself-&amp;gt;GetIdentity();	/* Only this identity will be allowed */&lt;br /&gt;
&lt;br /&gt;
	/* Set up the access permissions */&lt;br /&gt;
	HandleAccess rules;&lt;br /&gt;
	g_pHandleSys-&amp;gt;InitAccessDefaults(NULL, &amp;amp;rules);&lt;br /&gt;
	rules.access[HandleAccess_Delete] |= HANDLE_RESTRICT_IDENTITY;&lt;br /&gt;
&lt;br /&gt;
	/* Finally, create the Handle with our rules */&lt;br /&gt;
	g_GlobalFile = g_pHandleSys-&amp;gt;CreateHandleEx(g_FileType, fp, &amp;amp;sec, &amp;amp;rules, NULL);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Shutdown()&lt;br /&gt;
{&lt;br /&gt;
	/* Remove our global Handle (not needed, but we do it for clarity */&lt;br /&gt;
	HandleSecurity sec;&lt;br /&gt;
	sec.pOwner = NULL;&lt;br /&gt;
	sec.pIdentity = myself-&amp;gt;GetIdentity();&lt;br /&gt;
&lt;br /&gt;
	g_pHandleSys-&amp;gt;FreeHandle(g_GlobalFile, &amp;amp;sec);&lt;br /&gt;
&lt;br /&gt;
	/* Remove the type on shutdown */&lt;br /&gt;
	g_pHandleSys-&amp;gt;RemoveType(g_FileType, myself-&amp;gt;GetIdentity());&lt;br /&gt;
}&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Development]]&lt;/div&gt;</summary>
		<author><name>Zerak</name></author>
		
	</entry>
</feed>