<?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=Berni</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=Berni"/>
	<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/Special:Contributions/Berni"/>
	<updated>2026-05-25T20:45:53Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.6</generator>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Virtual_Offsets_(Source_Mods)&amp;diff=8707</id>
		<title>Virtual Offsets (Source Mods)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Virtual_Offsets_(Source_Mods)&amp;diff=8707"/>
		<updated>2012-09-30T21:41:01Z</updated>

		<summary type="html">&lt;p&gt;Berni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Metamod:Source Development]]&lt;br /&gt;
== Calling virtual functions ==&lt;br /&gt;
I got this method from [[User:Mani|Mani]], who I believe got it from [[User:PM|Pavol Marko]]. Thank you!&lt;br /&gt;
&lt;br /&gt;
I hope to expand on an actual explanation when I have the time (and understand it better). Hopefully, someone can expand on this, but for now I'll just post the examples and a list of the CCSPlayer virtual function table offsets.&lt;br /&gt;
&lt;br /&gt;
== Offset Lists ==&lt;br /&gt;
==== Automated Offsets ====&lt;br /&gt;
You can get automatically updated offsets from Berni's VTable Offset list. It automatically updates the offsets when an update is pushed by valve, making it a very resourceful tool. &lt;br /&gt;
* [http://www.sourcemodplugins.org/vtableoffsets Automated Offsets - Thanks to Berni] &lt;br /&gt;
==== Counter-Strike: Source ====&lt;br /&gt;
* [[CCSPlayer Offset List (Counter-Strike: Source)|CCSPlayer]]&lt;br /&gt;
* [[CBaseCombatWeapon Offset List (Counter-Strike: Source)|CBaseCombatWeapon]]&lt;br /&gt;
* [[CCSGameRules Offset List (Counter-Strike: Source) | CCSGameRules]]&lt;br /&gt;
* [[CBaseGrenade Offset List (Counter-Strike: Source) | CBaseGrenade]]&lt;br /&gt;
* [[CDEagle Offset List (Counter-Strike: Source) | CDEagle]]&lt;br /&gt;
&lt;br /&gt;
==== Day of Defeat: Source ====&lt;br /&gt;
* [[CDODPlayer Offset List (Day of Defeat: Source)|CDODPlayer]]&lt;br /&gt;
&lt;br /&gt;
==== Dystopia ====&lt;br /&gt;
* [[CDYSPlayer Offset List (Dystopia)|CDYSPlayer]]&lt;br /&gt;
&lt;br /&gt;
==== Empires v2.12 ====&lt;br /&gt;
* [[CSDKPlayer Offset List (Empires)|CSDKPlayer]]&lt;br /&gt;
&lt;br /&gt;
==== Fortress Forever ====&lt;br /&gt;
* [[CFFPlayer Offset List (Fortress Forever)|CFFPlayer]]&lt;br /&gt;
&lt;br /&gt;
==== Half-Life 2: Capture the Flag ====&lt;br /&gt;
* [[CHL2_Player Offset List (Half-Life 2: Capture the Flag)|CHL2_Player]]&lt;br /&gt;
&lt;br /&gt;
==== Half-Life 2: Deathmatch ====&lt;br /&gt;
* [[CHL2MP_Player Offset List (Half-Life 2: Deathmatch)|CHL2MP_Player]]&lt;br /&gt;
&lt;br /&gt;
==== Hidden: Source ====&lt;br /&gt;
* [[CSDKPlayer Offset List (Hidden: Source)|CSDKPlayer]]&lt;br /&gt;
&lt;br /&gt;
==== Insurgency ====&lt;br /&gt;
* [[CINSPlayer Offset List (Insurgency)|CINSPlayer]]&lt;br /&gt;
&lt;br /&gt;
==== Left 4 Dead ====&lt;br /&gt;
* [[CTerrorPlayer Offset List (Left 4 Dead)|CTerrorPlayer]]&lt;br /&gt;
&lt;br /&gt;
==== Left 4 Dead 2 ====&lt;br /&gt;
* [[CTerrorPlayer Offset List (Left 4 Dead 2)|CTerrorPlayer]]&lt;br /&gt;
&lt;br /&gt;
==== Obsidian Conflict ====&lt;br /&gt;
* [[CHL2MP_Player Offset List (Obsidian Conflict)|CHL2MP_Player]]&lt;br /&gt;
&lt;br /&gt;
==== Pirates, Vikings, and Knights II ====&lt;br /&gt;
* [[CPVK2Player Offset List (Pirates, Vikings, and Knights II)|CPVK2Player]]&lt;br /&gt;
&lt;br /&gt;
==== The Ship ====&lt;br /&gt;
* [[CShipPlayer Offset List (The Ship)|CShipPlayer]]&lt;br /&gt;
&lt;br /&gt;
==== SourceForts ====&lt;br /&gt;
* [[CHL2MP_Player Offset List (SourceForts)|CHL2MP_Player]]&lt;br /&gt;
&lt;br /&gt;
==== Synergy ====&lt;br /&gt;
* [[CHL2MP_Player Offset List (Synergy)|CHL2MP_Player]]&lt;br /&gt;
&lt;br /&gt;
==== Synergy SteamWorks (Synergy Orange Box Edition)====&lt;br /&gt;
* [[CHL2MP_Player Offset List (SynergyOB)|CHL2MP_Player]]&lt;br /&gt;
&lt;br /&gt;
==== Team Fortress 2 ====&lt;br /&gt;
* [[CTFPlayer Offset List (Team Fortress 2)|CTFPlayer]]&lt;br /&gt;
&lt;br /&gt;
==== Zombie Master ====&lt;br /&gt;
* [[CHL2MP_Player Offset List (Zombie Master)|CHL2MP_Player]]&lt;br /&gt;
&lt;br /&gt;
==== Zombie Panic: Source ====&lt;br /&gt;
* [[CHL2MP_Player Offset List (Zombie Panic: Source)|CHL2MP_Player]]&lt;br /&gt;
&lt;br /&gt;
==== GoldenEye: Source ====&lt;br /&gt;
* [[CGEPlayer Offset List (GoldenEye: Source)|CGEPlayer]]&lt;br /&gt;
&lt;br /&gt;
== How to use the examples ==&lt;br /&gt;
&lt;br /&gt;
Basically, this lets you call any [[virtual function]] by knowing it's offset. A table is created for each class that lists the address of the function for each virtual function. This method takes advantage of that to call those addresses.&lt;br /&gt;
&lt;br /&gt;
Look at the examples below and edit to match the function you want to call:&lt;br /&gt;
Use the offset for the function you want to call in this line. ([[CCSPlayer_offset_list_(SourceMM)]])&lt;br /&gt;
&amp;lt;cpp&amp;gt;void *func = vtable[m_Off_GiveNamedItem];&amp;lt;/cpp&amp;gt;&lt;br /&gt;
Change this line to match your return type and parameters:&lt;br /&gt;
&amp;lt;cpp&amp;gt;union {CBaseEntity *(VfuncEmptyClass::*mfpnew)(const char *, int );&amp;lt;/cpp&amp;gt;&lt;br /&gt;
Call the original function with your parameters (change the return type to match the function you're calling):&lt;br /&gt;
&amp;lt;cpp&amp;gt;return (CBaseEntity *) (reinterpret_cast&amp;lt;VfuncEmptyClass*&amp;gt;(this_ptr)-&amp;gt;*u.mfpnew)(ItemName, iSubType);&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You'll need to add an empty class for the union. Something like this:&lt;br /&gt;
&amp;lt;cpp&amp;gt;class VfuncEmptyClass {};&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
These examples are for CSS. Mani has created a set of macros to make this easier. If you ask nicely, maybe he'll give them to you or let you post them here.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;cpp&amp;gt;datamap_t *VFuncs::GetDataDescMap(CBaseEntity *pThisPtr)&lt;br /&gt;
{&lt;br /&gt;
	void **this_ptr = *(void ***)&amp;amp;pThisPtr;&lt;br /&gt;
	void **vtable = *(void ***)pThisPtr;&lt;br /&gt;
	void *func = vtable[m_Off_GetDataDescMap]; &lt;br /&gt;
&lt;br /&gt;
	union {datamap_t *(VfuncEmptyClass::*mfpnew)();&lt;br /&gt;
#ifndef __linux__&lt;br /&gt;
        void *addr;	} u; 	u.addr = func;&lt;br /&gt;
#else /* GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 */&lt;br /&gt;
			struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
	return (datamap_t *) (reinterpret_cast&amp;lt;VfuncEmptyClass*&amp;gt;(this_ptr)-&amp;gt;*u.mfpnew)();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void VFuncs::SetModel(CBaseEntity *pThisPtr, const char *ModelName)&lt;br /&gt;
{&lt;br /&gt;
	void **this_ptr = *(void ***)&amp;amp;pThisPtr;&lt;br /&gt;
	void **vtable = *(void ***)pThisPtr;&lt;br /&gt;
	void *func = vtable[m_Off_SetModel]; &lt;br /&gt;
&lt;br /&gt;
	union {void (VfuncEmptyClass::*mfpnew)(const char *);&lt;br /&gt;
	#ifndef __linux__&lt;br /&gt;
			void *addr;	} u; 	u.addr = func;&lt;br /&gt;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 &lt;br /&gt;
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;&lt;br /&gt;
	#endif&lt;br /&gt;
&lt;br /&gt;
	(void) (reinterpret_cast&amp;lt;VfuncEmptyClass*&amp;gt;(this_ptr)-&amp;gt;*u.mfpnew)(ModelName);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void VFuncs::Teleport(CBaseEntity *pThisPtr, const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity)&lt;br /&gt;
{&lt;br /&gt;
	void **this_ptr = *(void ***)&amp;amp;pThisPtr;&lt;br /&gt;
	void **vtable = *(void ***)pThisPtr;&lt;br /&gt;
	void *func = vtable[m_Off_Teleport]; &lt;br /&gt;
&lt;br /&gt;
	union {void (VfuncEmptyClass::*mfpnew)(const Vector *, const QAngle *, const Vector *);&lt;br /&gt;
	#ifndef __linux__&lt;br /&gt;
			void *addr;	} u; 	u.addr = func;&lt;br /&gt;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 &lt;br /&gt;
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;&lt;br /&gt;
	#endif&lt;br /&gt;
&lt;br /&gt;
	(void) (reinterpret_cast&amp;lt;VfuncEmptyClass*&amp;gt;(this_ptr)-&amp;gt;*u.mfpnew)(newPosition, newAngles, newVelocity);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Vector VFuncs::EyePosition( CBaseEntity *pThisPtr )&lt;br /&gt;
{&lt;br /&gt;
	void **this_ptr = *(void ***)&amp;amp;pThisPtr;&lt;br /&gt;
	void **vtable = *(void ***)pThisPtr;&lt;br /&gt;
	void *func = vtable[m_Off_EyePosition]; &lt;br /&gt;
&lt;br /&gt;
	union {Vector (VfuncEmptyClass::*mfpnew)( void );&lt;br /&gt;
	#ifndef __linux__&lt;br /&gt;
			void *addr;	} u; 	u.addr = func;&lt;br /&gt;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 &lt;br /&gt;
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;&lt;br /&gt;
	#endif&lt;br /&gt;
&lt;br /&gt;
	return (Vector) (reinterpret_cast&amp;lt;VfuncEmptyClass*&amp;gt;(this_ptr)-&amp;gt;*u.mfpnew)( );&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
QAngle &amp;amp;VFuncs::EyeAngles( CBaseEntity *pThisPtr )&lt;br /&gt;
{&lt;br /&gt;
	void **this_ptr = *(void ***)&amp;amp;pThisPtr;&lt;br /&gt;
	void **vtable = *(void ***)pThisPtr;&lt;br /&gt;
	void *func = vtable[m_Off_EyeAngles]; &lt;br /&gt;
&lt;br /&gt;
	union {QAngle&amp;amp; (VfuncEmptyClass::*mfpnew)( void );&lt;br /&gt;
	#ifndef __linux__&lt;br /&gt;
			void *addr;	} u; 	u.addr = func;&lt;br /&gt;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 &lt;br /&gt;
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;&lt;br /&gt;
	#endif&lt;br /&gt;
&lt;br /&gt;
	return (QAngle&amp;amp;) (reinterpret_cast&amp;lt;VfuncEmptyClass*&amp;gt;(this_ptr)-&amp;gt;*u.mfpnew)( );&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void VFuncs::Ignite(CBaseEntity *pThisPtr, float flFlameLifetime, bool bNPCOnly, float flSize, bool bCalledByLevelDesigner)&lt;br /&gt;
{&lt;br /&gt;
	void **this_ptr = *(void ***)&amp;amp;pThisPtr;&lt;br /&gt;
	void **vtable = *(void ***)pThisPtr;&lt;br /&gt;
	void *func = vtable[m_Off_Ignite]; &lt;br /&gt;
&lt;br /&gt;
	union {void (VfuncEmptyClass::*mfpnew)(float , bool , float , bool );&lt;br /&gt;
	#ifndef __linux__&lt;br /&gt;
			void *addr;	} u; 	u.addr = func;&lt;br /&gt;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 &lt;br /&gt;
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;&lt;br /&gt;
	#endif&lt;br /&gt;
&lt;br /&gt;
	(void) (reinterpret_cast&amp;lt;VfuncEmptyClass*&amp;gt;(this_ptr)-&amp;gt;*u.mfpnew)(flFlameLifetime, bNPCOnly, flSize, bCalledByLevelDesigner);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
CBaseEntity *VFuncs::GiveNamedItem(CBaseEntity *pThisPtr, const char *ItemName, int iSubType)&lt;br /&gt;
{&lt;br /&gt;
	void **this_ptr = *(void ***)&amp;amp;pThisPtr;&lt;br /&gt;
	void **vtable = *(void ***)pThisPtr;&lt;br /&gt;
	void *func = vtable[m_Off_GiveNamedItem]; &lt;br /&gt;
&lt;br /&gt;
	union {CBaseEntity *(VfuncEmptyClass::*mfpnew)(const char *, int );&lt;br /&gt;
	#ifndef __linux__&lt;br /&gt;
			void *addr;	} u; 	u.addr = func;&lt;br /&gt;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 &lt;br /&gt;
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;&lt;br /&gt;
	#endif&lt;br /&gt;
&lt;br /&gt;
	return (CBaseEntity *) (reinterpret_cast&amp;lt;VfuncEmptyClass*&amp;gt;(this_ptr)-&amp;gt;*u.mfpnew)(ItemName, iSubType);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void VFuncs::CommitSuicide(CBaseEntity *pThisPtr)&lt;br /&gt;
{&lt;br /&gt;
	void **this_ptr = *(void ***)&amp;amp;pThisPtr;&lt;br /&gt;
	void **vtable = *(void ***)pThisPtr;&lt;br /&gt;
	void *func = vtable[m_Off_CommitSuicide]; &lt;br /&gt;
&lt;br /&gt;
	union {CBaseEntity *(VfuncEmptyClass::*mfpnew)( void );&lt;br /&gt;
	#ifndef __linux__&lt;br /&gt;
			void *addr;	} u; 	u.addr = func;&lt;br /&gt;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 &lt;br /&gt;
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;&lt;br /&gt;
	#endif&lt;br /&gt;
&lt;br /&gt;
	(reinterpret_cast&amp;lt;VfuncEmptyClass*&amp;gt;(this_ptr)-&amp;gt;*u.mfpnew)();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/cpp&amp;gt;&lt;/div&gt;</summary>
		<author><name>Berni</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Timers_(SourceMod_Scripting)&amp;diff=8606</id>
		<title>Timers (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Timers_(SourceMod_Scripting)&amp;diff=8606"/>
		<updated>2012-07-17T20:15:39Z</updated>

		<summary type="html">&lt;p&gt;Berni: /* Data Packs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Timers in [[SourceMod]] are timed events that occur once or repeatedly at a given interval.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Timers allow you to set an interval, a function to use as the event callback, and an optional Handle to pass through the callback.  This is useful for saving data asynchronously.&lt;br /&gt;
&lt;br /&gt;
All timer functions are in &amp;lt;tt&amp;gt;plugins/include/timers.inc&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
=Basic Usage=&lt;br /&gt;
==One-Time Timers==&lt;br /&gt;
One-time timers are timers that only execute once.  An example of a one-time timer might look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	CreateTimer(5.0, LoadStuff)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:LoadStuff(Handle:timer)&lt;br /&gt;
{&lt;br /&gt;
	PrintToServer(&amp;quot;Loading stuff!&amp;quot;)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code will print &amp;quot;Loading stuff!&amp;quot; to the server console five seconds after the map loads.  The return value has no meaning for one-time timers.&lt;br /&gt;
&lt;br /&gt;
==Repeatable Timers==&lt;br /&gt;
Repeatable timers execute infinitely many times, once every interval.  Based on the return value, they either continue or cancel.&lt;br /&gt;
&lt;br /&gt;
For example, say you want to display a message five times, once every three seconds:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
someFunction()&lt;br /&gt;
{&lt;br /&gt;
	CreateTimer(3.0, Timer_PrintMessageFiveTimes, _, TIMER_REPEAT);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Timer_PrintMessageFiveTimes(Handle:timer)&lt;br /&gt;
{&lt;br /&gt;
	// Create a global variable visible only in the local scope (this function).&lt;br /&gt;
	static numPrinted = 0;&lt;br /&gt;
&lt;br /&gt;
	if (numPrinted &amp;gt;= 5) {&lt;br /&gt;
		return Plugin_Stop;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	PrintToServer(&amp;quot;Warning! This is a message.&amp;quot;);&lt;br /&gt;
	numPrinted++;&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Continue;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; stops the timer, and &amp;lt;tt&amp;gt;Plugin_Continue&amp;lt;/tt&amp;gt; allows it to continue repeating.&lt;br /&gt;
&lt;br /&gt;
=Passing Data=&lt;br /&gt;
==Simple Values==&lt;br /&gt;
As mentioned earlier, timers let you pass values on to the callback function.  This value can be any type.  For example, let's say we want to print a message to a player fifteen seconds after they connect.  However, we want to cancel the timer if the player disconnects.  Implementing this is very easy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new Handle:WelcomeTimers[MAXPLAYERS+1]&lt;br /&gt;
&lt;br /&gt;
public OnClientPutInServer(client)&lt;br /&gt;
{&lt;br /&gt;
	WelcomeTimers[client] = CreateTimer(15.0, WelcomePlayer, client)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnect(client)&lt;br /&gt;
{&lt;br /&gt;
	if (WelcomeTimers[client] != INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		KillTimer(WelcomeTimers[client])&lt;br /&gt;
		WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:WelcomePlayer(Handle:timer, any:client)&lt;br /&gt;
{&lt;br /&gt;
	PrintToConsole(client, &amp;quot;Welcome to the server!&amp;quot;)&lt;br /&gt;
	WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Handles==&lt;br /&gt;
If you want to pass a Handle as a value, you have the option of using &amp;lt;tt&amp;gt;TIMER_HNDL_CLOSE&amp;lt;/tt&amp;gt;, which will automatically call &amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt; for you once the timer dies.  &lt;br /&gt;
&lt;br /&gt;
==Data Packs==&lt;br /&gt;
Data packs are packable structures that can be used to hold asynchronous data (data that must be saved and unpacked for later).  They are especially useful for timers, and thus there exists a helper function, called &amp;lt;tt&amp;gt;CreateDataTimer()&amp;lt;/tt&amp;gt;, which creates a timer using a data pack handle.  The handle is created and closed automatically for you.&lt;br /&gt;
&lt;br /&gt;
The above example could be rewritten as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new Handle:WelcomeTimers[MAXPLAYERS+1]&lt;br /&gt;
&lt;br /&gt;
public OnClientPutInServer(client)&lt;br /&gt;
{&lt;br /&gt;
	new Handle:pack&lt;br /&gt;
	WelcomeTimers[client] = CreateDataTimer(15.0, WelcomePlayer, pack)&lt;br /&gt;
	WritePackCell(pack, client)&lt;br /&gt;
	WritePackString(pack, &amp;quot;Welcome to the server!&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnect(client)&lt;br /&gt;
{&lt;br /&gt;
	if (WelcomeTimers[client] != INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		KillTimer(WelcomeTimers[client])&lt;br /&gt;
		WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:WelcomePlayer(Handle:timer, Handle:pack)&lt;br /&gt;
{&lt;br /&gt;
	decl String:str[128]&lt;br /&gt;
	new client&lt;br /&gt;
&lt;br /&gt;
	/* Set to the beginning and unpack it */&lt;br /&gt;
	ResetPack(pack)&lt;br /&gt;
	client = ReadPackCell(pack)&lt;br /&gt;
	ReadPackString(pack, str, sizeof(str))&lt;br /&gt;
&lt;br /&gt;
	PrintToConsole(client, &amp;quot;%s&amp;quot;, str)&lt;br /&gt;
	WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Notes=&lt;br /&gt;
==Accuracy==&lt;br /&gt;
The smallest possible interval is 0.1 seconds.  Timers have high precision (floating point) but low accuracy, as the current time is based on the in-game tick count, not the system clock.  This has two implications:&lt;br /&gt;
*If the server is paused (not ticking), timers will not run.&lt;br /&gt;
*The server will not always tick at an exact interval.  &lt;br /&gt;
&lt;br /&gt;
For example, a 1.234 second interval timer starting from time &amp;lt;tt&amp;gt;t&amp;lt;/tt&amp;gt; might not tick until &amp;lt;tt&amp;gt;t+1.242&amp;lt;/tt&amp;gt; at a tickrate of 66 ticks per second.&lt;br /&gt;
&lt;br /&gt;
==Timer Death==&lt;br /&gt;
All timers are guaranteed to die either by:&lt;br /&gt;
*&amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt; being called (or on plugin unload);&lt;br /&gt;
*&amp;lt;tt&amp;gt;KillTimer()&amp;lt;/tt&amp;gt; being called;&lt;br /&gt;
*&amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; being returned from a repeatable timer;&lt;br /&gt;
*&amp;lt;tt&amp;gt;TriggerTimer()&amp;lt;/tt&amp;gt; being called on a one-time timer;&lt;br /&gt;
*Execution of a one-time timer finishes.&lt;br /&gt;
&lt;br /&gt;
When a timer dies, if &amp;lt;tt&amp;gt;TIMER_HNDL_CLOSE&amp;lt;/tt&amp;gt; is set, the Handle will always be closed with the permissions that &amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt; uses by default.  Since timers cannot be cloned, there should be no ownership issues.&lt;br /&gt;
&lt;br /&gt;
==Changing Intervals==&lt;br /&gt;
The interval of a timer cannot be changed as of this writing.  The timer must be killed and a new one created.&lt;br /&gt;
&lt;br /&gt;
==AMX Mod X==&lt;br /&gt;
Unlike [[AMX Mod X]]'s &amp;lt;tt&amp;gt;set_task&amp;lt;/tt&amp;gt; function, you cannot pass arrays using &amp;lt;tt&amp;gt;CreateTimer&amp;lt;/tt&amp;gt;.  To accomplish this, you should use the data pack functionality explained above.&lt;br /&gt;
&lt;br /&gt;
Similarly, there are no flags for counted repeats (non-infinite loops) or timers based on the map start or end.  These must be done manually.&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
*[http://www.sourcemod.net/devlog/?p=130 On Timer Design, Part 3] (SourceMod DevLog)&lt;br /&gt;
*[http://www.sourcemod.net/devlog/?p=119 On Timer Design, Part 2] (SourceMod DevLog)&lt;br /&gt;
*[http://www.sourcemod.net/devlog/?p=118 On Timer Design, Part 1] (SourceMod DevLog)&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Berni</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Timers_(SourceMod_Scripting)&amp;diff=8605</id>
		<title>Timers (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Timers_(SourceMod_Scripting)&amp;diff=8605"/>
		<updated>2012-07-17T20:15:24Z</updated>

		<summary type="html">&lt;p&gt;Berni: /* Simple Values */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Timers in [[SourceMod]] are timed events that occur once or repeatedly at a given interval.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Timers allow you to set an interval, a function to use as the event callback, and an optional Handle to pass through the callback.  This is useful for saving data asynchronously.&lt;br /&gt;
&lt;br /&gt;
All timer functions are in &amp;lt;tt&amp;gt;plugins/include/timers.inc&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
=Basic Usage=&lt;br /&gt;
==One-Time Timers==&lt;br /&gt;
One-time timers are timers that only execute once.  An example of a one-time timer might look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	CreateTimer(5.0, LoadStuff)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:LoadStuff(Handle:timer)&lt;br /&gt;
{&lt;br /&gt;
	PrintToServer(&amp;quot;Loading stuff!&amp;quot;)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code will print &amp;quot;Loading stuff!&amp;quot; to the server console five seconds after the map loads.  The return value has no meaning for one-time timers.&lt;br /&gt;
&lt;br /&gt;
==Repeatable Timers==&lt;br /&gt;
Repeatable timers execute infinitely many times, once every interval.  Based on the return value, they either continue or cancel.&lt;br /&gt;
&lt;br /&gt;
For example, say you want to display a message five times, once every three seconds:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
someFunction()&lt;br /&gt;
{&lt;br /&gt;
	CreateTimer(3.0, Timer_PrintMessageFiveTimes, _, TIMER_REPEAT);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Timer_PrintMessageFiveTimes(Handle:timer)&lt;br /&gt;
{&lt;br /&gt;
	// Create a global variable visible only in the local scope (this function).&lt;br /&gt;
	static numPrinted = 0;&lt;br /&gt;
&lt;br /&gt;
	if (numPrinted &amp;gt;= 5) {&lt;br /&gt;
		return Plugin_Stop;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	PrintToServer(&amp;quot;Warning! This is a message.&amp;quot;);&lt;br /&gt;
	numPrinted++;&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Continue;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; stops the timer, and &amp;lt;tt&amp;gt;Plugin_Continue&amp;lt;/tt&amp;gt; allows it to continue repeating.&lt;br /&gt;
&lt;br /&gt;
=Passing Data=&lt;br /&gt;
==Simple Values==&lt;br /&gt;
As mentioned earlier, timers let you pass values on to the callback function.  This value can be any type.  For example, let's say we want to print a message to a player fifteen seconds after they connect.  However, we want to cancel the timer if the player disconnects.  Implementing this is very easy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new Handle:WelcomeTimers[MAXPLAYERS+1]&lt;br /&gt;
&lt;br /&gt;
public OnClientPutInServer(client)&lt;br /&gt;
{&lt;br /&gt;
	WelcomeTimers[client] = CreateTimer(15.0, WelcomePlayer, client)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnect(client)&lt;br /&gt;
{&lt;br /&gt;
	if (WelcomeTimers[client] != INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		KillTimer(WelcomeTimers[client])&lt;br /&gt;
		WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:WelcomePlayer(Handle:timer, any:client)&lt;br /&gt;
{&lt;br /&gt;
	PrintToConsole(client, &amp;quot;Welcome to the server!&amp;quot;)&lt;br /&gt;
	WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Handles==&lt;br /&gt;
If you want to pass a Handle as a value, you have the option of using &amp;lt;tt&amp;gt;TIMER_HNDL_CLOSE&amp;lt;/tt&amp;gt;, which will automatically call &amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt; for you once the timer dies.  &lt;br /&gt;
&lt;br /&gt;
==Data Packs==&lt;br /&gt;
Data packs are packable structures that can be used to hold asynchronous data (data that must be saved and unpacked for later).  They are especially useful for timers, and thus there exists a helper function, called &amp;lt;tt&amp;gt;CreateDataTimer()&amp;lt;/tt&amp;gt;, which creates a timer using a data pack handle.  The handle is created and closed automatically for you.&lt;br /&gt;
&lt;br /&gt;
The above example could be rewritten as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;#define MAX_PLAYERS 256&lt;br /&gt;
&lt;br /&gt;
new Handle:WelcomeTimers[MAX_PLAYERS+1]&lt;br /&gt;
&lt;br /&gt;
public OnClientPutInServer(client)&lt;br /&gt;
{&lt;br /&gt;
	new Handle:pack&lt;br /&gt;
	WelcomeTimers[client] = CreateDataTimer(15.0, WelcomePlayer, pack)&lt;br /&gt;
	WritePackCell(pack, client)&lt;br /&gt;
	WritePackString(pack, &amp;quot;Welcome to the server!&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnect(client)&lt;br /&gt;
{&lt;br /&gt;
	if (WelcomeTimers[client] != INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		KillTimer(WelcomeTimers[client])&lt;br /&gt;
		WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:WelcomePlayer(Handle:timer, Handle:pack)&lt;br /&gt;
{&lt;br /&gt;
	decl String:str[128]&lt;br /&gt;
	new client&lt;br /&gt;
&lt;br /&gt;
	/* Set to the beginning and unpack it */&lt;br /&gt;
	ResetPack(pack)&lt;br /&gt;
	client = ReadPackCell(pack)&lt;br /&gt;
	ReadPackString(pack, str, sizeof(str))&lt;br /&gt;
&lt;br /&gt;
	PrintToConsole(client, &amp;quot;%s&amp;quot;, str)&lt;br /&gt;
	WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Notes=&lt;br /&gt;
==Accuracy==&lt;br /&gt;
The smallest possible interval is 0.1 seconds.  Timers have high precision (floating point) but low accuracy, as the current time is based on the in-game tick count, not the system clock.  This has two implications:&lt;br /&gt;
*If the server is paused (not ticking), timers will not run.&lt;br /&gt;
*The server will not always tick at an exact interval.  &lt;br /&gt;
&lt;br /&gt;
For example, a 1.234 second interval timer starting from time &amp;lt;tt&amp;gt;t&amp;lt;/tt&amp;gt; might not tick until &amp;lt;tt&amp;gt;t+1.242&amp;lt;/tt&amp;gt; at a tickrate of 66 ticks per second.&lt;br /&gt;
&lt;br /&gt;
==Timer Death==&lt;br /&gt;
All timers are guaranteed to die either by:&lt;br /&gt;
*&amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt; being called (or on plugin unload);&lt;br /&gt;
*&amp;lt;tt&amp;gt;KillTimer()&amp;lt;/tt&amp;gt; being called;&lt;br /&gt;
*&amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; being returned from a repeatable timer;&lt;br /&gt;
*&amp;lt;tt&amp;gt;TriggerTimer()&amp;lt;/tt&amp;gt; being called on a one-time timer;&lt;br /&gt;
*Execution of a one-time timer finishes.&lt;br /&gt;
&lt;br /&gt;
When a timer dies, if &amp;lt;tt&amp;gt;TIMER_HNDL_CLOSE&amp;lt;/tt&amp;gt; is set, the Handle will always be closed with the permissions that &amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt; uses by default.  Since timers cannot be cloned, there should be no ownership issues.&lt;br /&gt;
&lt;br /&gt;
==Changing Intervals==&lt;br /&gt;
The interval of a timer cannot be changed as of this writing.  The timer must be killed and a new one created.&lt;br /&gt;
&lt;br /&gt;
==AMX Mod X==&lt;br /&gt;
Unlike [[AMX Mod X]]'s &amp;lt;tt&amp;gt;set_task&amp;lt;/tt&amp;gt; function, you cannot pass arrays using &amp;lt;tt&amp;gt;CreateTimer&amp;lt;/tt&amp;gt;.  To accomplish this, you should use the data pack functionality explained above.&lt;br /&gt;
&lt;br /&gt;
Similarly, there are no flags for counted repeats (non-infinite loops) or timers based on the map start or end.  These must be done manually.&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
*[http://www.sourcemod.net/devlog/?p=130 On Timer Design, Part 3] (SourceMod DevLog)&lt;br /&gt;
*[http://www.sourcemod.net/devlog/?p=119 On Timer Design, Part 2] (SourceMod DevLog)&lt;br /&gt;
*[http://www.sourcemod.net/devlog/?p=118 On Timer Design, Part 1] (SourceMod DevLog)&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Berni</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Timers_(SourceMod_Scripting)&amp;diff=8604</id>
		<title>Timers (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Timers_(SourceMod_Scripting)&amp;diff=8604"/>
		<updated>2012-07-17T13:34:26Z</updated>

		<summary type="html">&lt;p&gt;Berni: /* Repeatable Timers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Timers in [[SourceMod]] are timed events that occur once or repeatedly at a given interval.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Timers allow you to set an interval, a function to use as the event callback, and an optional Handle to pass through the callback.  This is useful for saving data asynchronously.&lt;br /&gt;
&lt;br /&gt;
All timer functions are in &amp;lt;tt&amp;gt;plugins/include/timers.inc&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
=Basic Usage=&lt;br /&gt;
==One-Time Timers==&lt;br /&gt;
One-time timers are timers that only execute once.  An example of a one-time timer might look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	CreateTimer(5.0, LoadStuff)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:LoadStuff(Handle:timer)&lt;br /&gt;
{&lt;br /&gt;
	PrintToServer(&amp;quot;Loading stuff!&amp;quot;)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code will print &amp;quot;Loading stuff!&amp;quot; to the server console five seconds after the map loads.  The return value has no meaning for one-time timers.&lt;br /&gt;
&lt;br /&gt;
==Repeatable Timers==&lt;br /&gt;
Repeatable timers execute infinitely many times, once every interval.  Based on the return value, they either continue or cancel.&lt;br /&gt;
&lt;br /&gt;
For example, say you want to display a message five times, once every three seconds:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
someFunction()&lt;br /&gt;
{&lt;br /&gt;
	CreateTimer(3.0, Timer_PrintMessageFiveTimes, _, TIMER_REPEAT);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Timer_PrintMessageFiveTimes(Handle:timer)&lt;br /&gt;
{&lt;br /&gt;
	// Create a global variable visible only in the local scope (this function).&lt;br /&gt;
	static numPrinted = 0;&lt;br /&gt;
&lt;br /&gt;
	if (numPrinted &amp;gt;= 5) {&lt;br /&gt;
		return Plugin_Stop;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	PrintToServer(&amp;quot;Warning! This is a message.&amp;quot;);&lt;br /&gt;
	numPrinted++;&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Continue;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; stops the timer, and &amp;lt;tt&amp;gt;Plugin_Continue&amp;lt;/tt&amp;gt; allows it to continue repeating.&lt;br /&gt;
&lt;br /&gt;
=Passing Data=&lt;br /&gt;
==Simple Values==&lt;br /&gt;
As mentioned earlier, timers let you pass values on to the callback function.  This value can be any type.  For example, let's say we want to print a message to a player fifteen seconds after they connect.  However, we want to cancel the timer if the player disconnects.  Implementing this is very easy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#define MAX_PLAYERS 256&lt;br /&gt;
&lt;br /&gt;
new Handle:WelcomeTimers[MAX_PLAYERS+1]&lt;br /&gt;
&lt;br /&gt;
public OnClientPutInServer(client)&lt;br /&gt;
{&lt;br /&gt;
	WelcomeTimers[client] = CreateTimer(15.0, WelcomePlayer, client)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnect(client)&lt;br /&gt;
{&lt;br /&gt;
	if (WelcomeTimers[client] != INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		KillTimer(WelcomeTimers[client])&lt;br /&gt;
		WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:WelcomePlayer(Handle:timer, any:client)&lt;br /&gt;
{&lt;br /&gt;
	PrintToConsole(client, &amp;quot;Welcome to the server!&amp;quot;)&lt;br /&gt;
	WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Handles==&lt;br /&gt;
If you want to pass a Handle as a value, you have the option of using &amp;lt;tt&amp;gt;TIMER_HNDL_CLOSE&amp;lt;/tt&amp;gt;, which will automatically call &amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt; for you once the timer dies.  &lt;br /&gt;
&lt;br /&gt;
==Data Packs==&lt;br /&gt;
Data packs are packable structures that can be used to hold asynchronous data (data that must be saved and unpacked for later).  They are especially useful for timers, and thus there exists a helper function, called &amp;lt;tt&amp;gt;CreateDataTimer()&amp;lt;/tt&amp;gt;, which creates a timer using a data pack handle.  The handle is created and closed automatically for you.&lt;br /&gt;
&lt;br /&gt;
The above example could be rewritten as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;#define MAX_PLAYERS 256&lt;br /&gt;
&lt;br /&gt;
new Handle:WelcomeTimers[MAX_PLAYERS+1]&lt;br /&gt;
&lt;br /&gt;
public OnClientPutInServer(client)&lt;br /&gt;
{&lt;br /&gt;
	new Handle:pack&lt;br /&gt;
	WelcomeTimers[client] = CreateDataTimer(15.0, WelcomePlayer, pack)&lt;br /&gt;
	WritePackCell(pack, client)&lt;br /&gt;
	WritePackString(pack, &amp;quot;Welcome to the server!&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnect(client)&lt;br /&gt;
{&lt;br /&gt;
	if (WelcomeTimers[client] != INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		KillTimer(WelcomeTimers[client])&lt;br /&gt;
		WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:WelcomePlayer(Handle:timer, Handle:pack)&lt;br /&gt;
{&lt;br /&gt;
	decl String:str[128]&lt;br /&gt;
	new client&lt;br /&gt;
&lt;br /&gt;
	/* Set to the beginning and unpack it */&lt;br /&gt;
	ResetPack(pack)&lt;br /&gt;
	client = ReadPackCell(pack)&lt;br /&gt;
	ReadPackString(pack, str, sizeof(str))&lt;br /&gt;
&lt;br /&gt;
	PrintToConsole(client, &amp;quot;%s&amp;quot;, str)&lt;br /&gt;
	WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Notes=&lt;br /&gt;
==Accuracy==&lt;br /&gt;
The smallest possible interval is 0.1 seconds.  Timers have high precision (floating point) but low accuracy, as the current time is based on the in-game tick count, not the system clock.  This has two implications:&lt;br /&gt;
*If the server is paused (not ticking), timers will not run.&lt;br /&gt;
*The server will not always tick at an exact interval.  &lt;br /&gt;
&lt;br /&gt;
For example, a 1.234 second interval timer starting from time &amp;lt;tt&amp;gt;t&amp;lt;/tt&amp;gt; might not tick until &amp;lt;tt&amp;gt;t+1.242&amp;lt;/tt&amp;gt; at a tickrate of 66 ticks per second.&lt;br /&gt;
&lt;br /&gt;
==Timer Death==&lt;br /&gt;
All timers are guaranteed to die either by:&lt;br /&gt;
*&amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt; being called (or on plugin unload);&lt;br /&gt;
*&amp;lt;tt&amp;gt;KillTimer()&amp;lt;/tt&amp;gt; being called;&lt;br /&gt;
*&amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; being returned from a repeatable timer;&lt;br /&gt;
*&amp;lt;tt&amp;gt;TriggerTimer()&amp;lt;/tt&amp;gt; being called on a one-time timer;&lt;br /&gt;
*Execution of a one-time timer finishes.&lt;br /&gt;
&lt;br /&gt;
When a timer dies, if &amp;lt;tt&amp;gt;TIMER_HNDL_CLOSE&amp;lt;/tt&amp;gt; is set, the Handle will always be closed with the permissions that &amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt; uses by default.  Since timers cannot be cloned, there should be no ownership issues.&lt;br /&gt;
&lt;br /&gt;
==Changing Intervals==&lt;br /&gt;
The interval of a timer cannot be changed as of this writing.  The timer must be killed and a new one created.&lt;br /&gt;
&lt;br /&gt;
==AMX Mod X==&lt;br /&gt;
Unlike [[AMX Mod X]]'s &amp;lt;tt&amp;gt;set_task&amp;lt;/tt&amp;gt; function, you cannot pass arrays using &amp;lt;tt&amp;gt;CreateTimer&amp;lt;/tt&amp;gt;.  To accomplish this, you should use the data pack functionality explained above.&lt;br /&gt;
&lt;br /&gt;
Similarly, there are no flags for counted repeats (non-infinite loops) or timers based on the map start or end.  These must be done manually.&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
*[http://www.sourcemod.net/devlog/?p=130 On Timer Design, Part 3] (SourceMod DevLog)&lt;br /&gt;
*[http://www.sourcemod.net/devlog/?p=119 On Timer Design, Part 2] (SourceMod DevLog)&lt;br /&gt;
*[http://www.sourcemod.net/devlog/?p=118 On Timer Design, Part 1] (SourceMod DevLog)&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Berni</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Timers_(SourceMod_Scripting)&amp;diff=8603</id>
		<title>Timers (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Timers_(SourceMod_Scripting)&amp;diff=8603"/>
		<updated>2012-07-17T13:33:52Z</updated>

		<summary type="html">&lt;p&gt;Berni: /* Repeatable Timers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Timers in [[SourceMod]] are timed events that occur once or repeatedly at a given interval.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
Timers allow you to set an interval, a function to use as the event callback, and an optional Handle to pass through the callback.  This is useful for saving data asynchronously.&lt;br /&gt;
&lt;br /&gt;
All timer functions are in &amp;lt;tt&amp;gt;plugins/include/timers.inc&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
=Basic Usage=&lt;br /&gt;
==One-Time Timers==&lt;br /&gt;
One-time timers are timers that only execute once.  An example of a one-time timer might look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	CreateTimer(5.0, LoadStuff)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:LoadStuff(Handle:timer)&lt;br /&gt;
{&lt;br /&gt;
	PrintToServer(&amp;quot;Loading stuff!&amp;quot;)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code will print &amp;quot;Loading stuff!&amp;quot; to the server console five seconds after the map loads.  The return value has no meaning for one-time timers.&lt;br /&gt;
&lt;br /&gt;
==Repeatable Timers==&lt;br /&gt;
Repeatable timers execute infinitely many times, once every interval.  Based on the return value, they either continue or cancel.&lt;br /&gt;
&lt;br /&gt;
For example, say you want to display a message five times, once every three seconds:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
DoMessage()&lt;br /&gt;
{&lt;br /&gt;
	CreateTimer(3.0, Timer_PrintMessageFiveTimes, _, TIMER_REPEAT);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Timer_PrintMessageFiveTimes(Handle:timer)&lt;br /&gt;
{&lt;br /&gt;
	// Create a global variable visible only in the local scope (this function).&lt;br /&gt;
	static numPrinted = 0;&lt;br /&gt;
&lt;br /&gt;
	if (numPrinted &amp;gt;= 5) {&lt;br /&gt;
		return Plugin_Stop;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	PrintToServer(&amp;quot;Warning! This is a message.&amp;quot;);&lt;br /&gt;
	numPrinted++;&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Continue;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; stops the timer, and &amp;lt;tt&amp;gt;Plugin_Continue&amp;lt;/tt&amp;gt; allows it to continue repeating.&lt;br /&gt;
&lt;br /&gt;
=Passing Data=&lt;br /&gt;
==Simple Values==&lt;br /&gt;
As mentioned earlier, timers let you pass values on to the callback function.  This value can be any type.  For example, let's say we want to print a message to a player fifteen seconds after they connect.  However, we want to cancel the timer if the player disconnects.  Implementing this is very easy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#define MAX_PLAYERS 256&lt;br /&gt;
&lt;br /&gt;
new Handle:WelcomeTimers[MAX_PLAYERS+1]&lt;br /&gt;
&lt;br /&gt;
public OnClientPutInServer(client)&lt;br /&gt;
{&lt;br /&gt;
	WelcomeTimers[client] = CreateTimer(15.0, WelcomePlayer, client)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnect(client)&lt;br /&gt;
{&lt;br /&gt;
	if (WelcomeTimers[client] != INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		KillTimer(WelcomeTimers[client])&lt;br /&gt;
		WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:WelcomePlayer(Handle:timer, any:client)&lt;br /&gt;
{&lt;br /&gt;
	PrintToConsole(client, &amp;quot;Welcome to the server!&amp;quot;)&lt;br /&gt;
	WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Handles==&lt;br /&gt;
If you want to pass a Handle as a value, you have the option of using &amp;lt;tt&amp;gt;TIMER_HNDL_CLOSE&amp;lt;/tt&amp;gt;, which will automatically call &amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt; for you once the timer dies.  &lt;br /&gt;
&lt;br /&gt;
==Data Packs==&lt;br /&gt;
Data packs are packable structures that can be used to hold asynchronous data (data that must be saved and unpacked for later).  They are especially useful for timers, and thus there exists a helper function, called &amp;lt;tt&amp;gt;CreateDataTimer()&amp;lt;/tt&amp;gt;, which creates a timer using a data pack handle.  The handle is created and closed automatically for you.&lt;br /&gt;
&lt;br /&gt;
The above example could be rewritten as:&lt;br /&gt;
&amp;lt;pawn&amp;gt;#define MAX_PLAYERS 256&lt;br /&gt;
&lt;br /&gt;
new Handle:WelcomeTimers[MAX_PLAYERS+1]&lt;br /&gt;
&lt;br /&gt;
public OnClientPutInServer(client)&lt;br /&gt;
{&lt;br /&gt;
	new Handle:pack&lt;br /&gt;
	WelcomeTimers[client] = CreateDataTimer(15.0, WelcomePlayer, pack)&lt;br /&gt;
	WritePackCell(pack, client)&lt;br /&gt;
	WritePackString(pack, &amp;quot;Welcome to the server!&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnect(client)&lt;br /&gt;
{&lt;br /&gt;
	if (WelcomeTimers[client] != INVALID_HANDLE)&lt;br /&gt;
	{&lt;br /&gt;
		KillTimer(WelcomeTimers[client])&lt;br /&gt;
		WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:WelcomePlayer(Handle:timer, Handle:pack)&lt;br /&gt;
{&lt;br /&gt;
	decl String:str[128]&lt;br /&gt;
	new client&lt;br /&gt;
&lt;br /&gt;
	/* Set to the beginning and unpack it */&lt;br /&gt;
	ResetPack(pack)&lt;br /&gt;
	client = ReadPackCell(pack)&lt;br /&gt;
	ReadPackString(pack, str, sizeof(str))&lt;br /&gt;
&lt;br /&gt;
	PrintToConsole(client, &amp;quot;%s&amp;quot;, str)&lt;br /&gt;
	WelcomeTimers[client] = INVALID_HANDLE&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Notes=&lt;br /&gt;
==Accuracy==&lt;br /&gt;
The smallest possible interval is 0.1 seconds.  Timers have high precision (floating point) but low accuracy, as the current time is based on the in-game tick count, not the system clock.  This has two implications:&lt;br /&gt;
*If the server is paused (not ticking), timers will not run.&lt;br /&gt;
*The server will not always tick at an exact interval.  &lt;br /&gt;
&lt;br /&gt;
For example, a 1.234 second interval timer starting from time &amp;lt;tt&amp;gt;t&amp;lt;/tt&amp;gt; might not tick until &amp;lt;tt&amp;gt;t+1.242&amp;lt;/tt&amp;gt; at a tickrate of 66 ticks per second.&lt;br /&gt;
&lt;br /&gt;
==Timer Death==&lt;br /&gt;
All timers are guaranteed to die either by:&lt;br /&gt;
*&amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt; being called (or on plugin unload);&lt;br /&gt;
*&amp;lt;tt&amp;gt;KillTimer()&amp;lt;/tt&amp;gt; being called;&lt;br /&gt;
*&amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; being returned from a repeatable timer;&lt;br /&gt;
*&amp;lt;tt&amp;gt;TriggerTimer()&amp;lt;/tt&amp;gt; being called on a one-time timer;&lt;br /&gt;
*Execution of a one-time timer finishes.&lt;br /&gt;
&lt;br /&gt;
When a timer dies, if &amp;lt;tt&amp;gt;TIMER_HNDL_CLOSE&amp;lt;/tt&amp;gt; is set, the Handle will always be closed with the permissions that &amp;lt;tt&amp;gt;CloseHandle()&amp;lt;/tt&amp;gt; uses by default.  Since timers cannot be cloned, there should be no ownership issues.&lt;br /&gt;
&lt;br /&gt;
==Changing Intervals==&lt;br /&gt;
The interval of a timer cannot be changed as of this writing.  The timer must be killed and a new one created.&lt;br /&gt;
&lt;br /&gt;
==AMX Mod X==&lt;br /&gt;
Unlike [[AMX Mod X]]'s &amp;lt;tt&amp;gt;set_task&amp;lt;/tt&amp;gt; function, you cannot pass arrays using &amp;lt;tt&amp;gt;CreateTimer&amp;lt;/tt&amp;gt;.  To accomplish this, you should use the data pack functionality explained above.&lt;br /&gt;
&lt;br /&gt;
Similarly, there are no flags for counted repeats (non-infinite loops) or timers based on the map start or end.  These must be done manually.&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
*[http://www.sourcemod.net/devlog/?p=130 On Timer Design, Part 3] (SourceMod DevLog)&lt;br /&gt;
*[http://www.sourcemod.net/devlog/?p=119 On Timer Design, Part 2] (SourceMod DevLog)&lt;br /&gt;
*[http://www.sourcemod.net/devlog/?p=118 On Timer Design, Part 1] (SourceMod DevLog)&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Berni</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=SRCDS_Hardening&amp;diff=8188</id>
		<title>SRCDS Hardening</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=SRCDS_Hardening&amp;diff=8188"/>
		<updated>2011-07-31T10:48:39Z</updated>

		<summary type="html">&lt;p&gt;Berni: /* Linux File Premission Setup */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Securing your server = &lt;br /&gt;
== General Tips == &lt;br /&gt;
* Do not enable sv_cheats, do not run any plugins that do so.&lt;br /&gt;
* [http://www.goodpassword.com/ Use secure passwords.]  This should be obvious, but your clan name is not a good rcon password, nor is &amp;quot;password&amp;quot;.&lt;br /&gt;
* Don't blindly give admin out.  Depending on what flags you give people, you could allow them to take over the server.&lt;br /&gt;
* Don't piss people off.  Many servers get attacked because players get pissed off that admins are abusing them.&lt;br /&gt;
&lt;br /&gt;
== File Permissions ==&lt;br /&gt;
If you are running your own server (not renting one from a GSP), there are some things you can do to prevent many of the more malicious exploits.  The basic theory here is to give srcds as little access to the machine as possible.  It only needs write access to the following directories:&lt;br /&gt;
* downloads/&lt;br /&gt;
* cache/&lt;br /&gt;
* addons/sourcemod/gamedata/&lt;br /&gt;
* addons/sourcemod/data/&lt;br /&gt;
* addons/sourcemod/logs/&lt;br /&gt;
* logs/&lt;br /&gt;
Note that some plugins rely on being able to write to directories other then these, and permissions may break them.  At the very least, it's a good idea to make sure srcds is running as a user that does not have permission to change anything outside of it's own directory.  That will prevent your machine from being comprised and made into a botnet client.&lt;br /&gt;
&lt;br /&gt;
== Linux File Permission Setup ==&lt;br /&gt;
&lt;br /&gt;
Create a unprivileged users to run the server.&lt;br /&gt;
&lt;br /&gt;
'''useradd -m -s /bin/bash -d /home/srcds srcds'''&lt;br /&gt;
&lt;br /&gt;
* useradd = Linux command to add users&lt;br /&gt;
* -m = Creates the user's home directory if it does not exist.&lt;br /&gt;
* -s /bin/bash = Users login shell ( if you are not sure what this should be leave it blank)&lt;br /&gt;
* -d /home/srcds = Location of users home directory.&lt;br /&gt;
&lt;br /&gt;
Set a password for the account make sure it is secure.&lt;br /&gt;
&lt;br /&gt;
'''passwd srcds'''&lt;br /&gt;
&lt;br /&gt;
* passwd srcds = Linux change password command&lt;br /&gt;
&lt;br /&gt;
Now move your existing srcds install to the new home dir or do a fresh install.&lt;br /&gt;
&lt;br /&gt;
'''cp -r /path/to/old/install /path/to/new/users/home''' &lt;br /&gt;
&lt;br /&gt;
*cp = Linux copy command&lt;br /&gt;
&lt;br /&gt;
'''chown -R srcds:scrds'''&lt;br /&gt;
&lt;br /&gt;
* chown = Linux command to change owner of files&lt;br /&gt;
* -R = Changes all the directory you are in and all subdirectories&lt;br /&gt;
&lt;br /&gt;
The last things you want to do is make the files read only and run the srcds as the new user.&lt;br /&gt;
&lt;br /&gt;
'''chmod -R 444 * /path/to/srcds/'''&lt;br /&gt;
&lt;br /&gt;
*chmod = Linux change permission command&lt;br /&gt;
* -R = Change files and directories recursively&lt;br /&gt;
* 444 = Read only&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt; = wild card[http://www.tuxfiles.org/linuxhelp/wildcards.html]&lt;br /&gt;
&lt;br /&gt;
Now you need to make the files mentioned above to read and write and a few exec.&lt;br /&gt;
&lt;br /&gt;
Read Write (chmod 644):&lt;br /&gt;
* downloads/&lt;br /&gt;
* cache/&lt;br /&gt;
* addons/sourcemod/gamedata/&lt;br /&gt;
* addons/sourcemod/data/&lt;br /&gt;
* addons/sourcemod/logs/&lt;br /&gt;
* logs/&lt;br /&gt;
&lt;br /&gt;
Read and exec (cmond 744):&lt;br /&gt;
* /orangebox/srcds_linux&lt;br /&gt;
* /orangebox/srcds_run&lt;br /&gt;
&lt;br /&gt;
== Plugins ==&lt;br /&gt;
There are a few plugins that can be installed to prevent exploits.  Some of the recommended ones include [https://forums.alliedmods.net/showthread.php?p=841590 Rcon locker / exploit fix], [https://forums.alliedmods.net/showthread.php?p=779851 Forlix FloodCheck], [https://forums.alliedmods.net/showthread.php?t=109453 D-FENS], and [http://www.sourceop.com/modules.php?name=Downloads&amp;amp;d_op=viewdownload&amp;amp;cid=9 DAF].&lt;br /&gt;
&lt;br /&gt;
Many of the Eventscripts plugins that claim to fix exploits are mostly useless at best, or actively harmful to your server at worst.  If you are running the plugins listed in the previous paragraph, you do not need anything else to protect your server.  Installing extra plugins other then those will likely cause issues with your server, and is not recommended.&lt;br /&gt;
&lt;br /&gt;
= Current Exploits =&lt;br /&gt;
&lt;br /&gt;
== Crashes ==&lt;br /&gt;
&lt;br /&gt;
=== Invalid RCON Crash ===&lt;br /&gt;
SRCDS will crash on some machines if you attempt to use an incorrect rcon password too many times.  It seems that some machines are affected by this, while others are not.  Valve has been notified a few times, and has been unwilling/unable to fix this.&lt;br /&gt;
&lt;br /&gt;
*Fix: Firewall off rcon (TCP port 27015) from everyone except for certain whitelisted IP's.&lt;br /&gt;
&lt;br /&gt;
=== HalfConnected Crash ===&lt;br /&gt;
If a command is received as the client is connecting, the server will crash or enter a state where it does not accept new connections, but has not crashed.  This exploit can also happen if you remove the players entity, which shouldn't happen under normal circumstances.  Valve has been notified, and is unwilling to fix this.&lt;br /&gt;
&lt;br /&gt;
*Fix: [https://forums.alliedmods.net/showthread.php?p=841590 Rcon locker / exploit fix]&lt;br /&gt;
&lt;br /&gt;
=== Disconnect Crash ===&lt;br /&gt;
Using modified clients, it is possible to send disconnect messages with large numbers of special characters.  These have a variety of effects, including crashing the server or crashing all connected clients.&lt;br /&gt;
&lt;br /&gt;
*Fix: [https://forums.alliedmods.net/showthread.php?p=841590 Rcon locker / exploit fix]&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;K&amp;quot; packet Crash ===&lt;br /&gt;
Using modified clients, it is possible to send a Steam auth packet that contains an invalid header length.  Upon receiving this packet, the server will crash.&lt;br /&gt;
&lt;br /&gt;
*Fix: 4/19/10: Apply the latest steam beta patch.  Run hldsupdatetool with &amp;quot;-beta cs0419&amp;quot; to get this.&lt;br /&gt;
&lt;br /&gt;
== Takeover == &lt;br /&gt;
=== ent_fire server takeover ===&lt;br /&gt;
If cheats are enabled on a server, the point_servercommand entity can be created, which can be used by clients to execute rcon commands on the server.  Premade scripts exist for this that will change the rcon password, and add the client as an admin.  Valve has been notified, and is unwilling to fix this.&lt;br /&gt;
&lt;br /&gt;
*Fix: [https://forums.alliedmods.net/showthread.php?p=841590 Rcon locker / exploit fix] will prevent the rcon password from being changed, as well as disallowing the point_servercommand entity.  The alternative is to not run with sv_cheats 1, and take other measures to ensure it is never enabled.&lt;br /&gt;
=== ES_Tools changelevel exploit ===&lt;br /&gt;
The &amp;quot;changelevel&amp;quot; command can be abused when ES_tools is running to execute commands on the server&lt;br /&gt;
&lt;br /&gt;
*Fix: [https://forums.alliedmods.net/showthread.php?p=841590 Rcon locker / exploit fix] will prevent this.  Alternatively, remove es_tools if at all possible.&lt;br /&gt;
=== File upload/download ===&lt;br /&gt;
It's possible to convince the server to let you upload or download random files from it.  Valve has been attempting to fix this, but there still seem to be some workarounds to their fixes.&lt;br /&gt;
&lt;br /&gt;
If you are running your own servers (not rented from a GSP), you can set file permissions on them to fix the upload issue.&lt;br /&gt;
&lt;br /&gt;
*Fix: [https://forums.alliedmods.net/showthread.php?t=109453 dfens] will prevent this.&lt;br /&gt;
&lt;br /&gt;
== Lag/DOS ==&lt;br /&gt;
=== A2C_PRINT Spam ===&lt;br /&gt;
SRCDS does not do any sort of authentication on A2C_PRINT messages.  This means that anyone can print messages to the servers console, simply by sending UDP packets.  It seems this is a legacy feature, and is not actually used by anything. Valve has been notified, and doesn't see this as a problem.&lt;br /&gt;
&lt;br /&gt;
*Fix: Block any packets beginning with \xFF\xFF\xFF\xFF\x6C or run [http://www.sourceop.com/modules.php?name=Downloads&amp;amp;d_op=viewdownload&amp;amp;cid=9 DAF]&lt;br /&gt;
=== A2S_INFO Spam ===&lt;br /&gt;
If large numbers of A2S_INFO packets are sent at the server, the FPS will severely drop, making the server essentially unplayable.  Since these packets can be spoofed, rate limiting one IP is fairly useless&lt;br /&gt;
&lt;br /&gt;
*Fix: You can use sv_max_queries_sec_global to limit this, though that would mean your server would be invisible on the master server list while the attacks are in progress.  [https://forums.alliedmods.net/showthread.php?t=114787 Query Cache] (a SM extension) will also work.&lt;br /&gt;
*'''Fixed in:''' TF2 (partial fix) (August 13, 2009)&lt;br /&gt;
&lt;br /&gt;
=== Command spam ===&lt;br /&gt;
Various commands built into the game can be spammed to lag or crash the server.  Some of these commands can cause the ingame physiscs to freeze up.  The fix for most of these is quite simple, just disable them by adding the cheats flag. Valve has been notified, and fixes commands in the occasional patch.&lt;br /&gt;
&lt;br /&gt;
*Fix: [https://forums.alliedmods.net/showthread.php?p=779851 Forlix FloodCheck] can be used to kick players who have been caught spamming, [https://forums.alliedmods.net/showthread.php?p=841590 Rcon locker / exploit fix] adds the cheats flag to most of the known commands.  [https://forums.alliedmods.net/showthread.php?p=880328 Scortched Earth] will disable all commands except for those on a whitelist, which is the &amp;quot;better&amp;quot; way to fix this, but can break other addons.&lt;br /&gt;
&lt;br /&gt;
=== Bell characters in name ===&lt;br /&gt;
If your name contains bell characters, this can be used to lag the server on windows.&lt;br /&gt;
&lt;br /&gt;
Fix: [https://forums.alliedmods.net/showthread.php?p=841590 Rcon locker / exploit fix] will kick players with these characters in their name.&lt;br /&gt;
=== Force fullupdate ===&lt;br /&gt;
If you send an empty packet to the server, you can force it to send you the full state of the game, which will lag the server if done enough.  Valve has been notified, and is unwilling to fix this.&lt;br /&gt;
&lt;br /&gt;
*Fix: [http://www.sourceop.com/modules.php?name=Downloads&amp;amp;d_op=viewdownload&amp;amp;cid=9 DAF] has a partial workaround&lt;br /&gt;
&lt;br /&gt;
== Annoyances ==&lt;br /&gt;
=== Teleport exploit ===&lt;br /&gt;
If you use very large values for your mouse sensitivity, you can overwrite your X and Y coordinates, letting you teleport around.  This has the potential to crash the server as well.  Valve has been notified, and is unwilling to fix this.&lt;br /&gt;
&lt;br /&gt;
*Fix: [https://forums.alliedmods.net/showthread.php?p=841590 Rcon locker / exploit fix] has a partial fix for this.&lt;br /&gt;
*'''Fixed in:''' TF2 (July 14 2009)&lt;br /&gt;
=== Clientside plugins ===&lt;br /&gt;
The VSP interface built into the game can be used to load plugins on the game client, allowing them to change cheat-flagged cvars.  This can allow them to have wallhacks, or alter weapon recharge rates.  Valve has been notified, and is unwilling to fix this.&lt;br /&gt;
&lt;br /&gt;
*Fix: [https://forums.alliedmods.net/showthread.php?p=841590 Rcon locker / exploit fix] has a partial fix for this.&lt;br /&gt;
=== Empty name / unconnected ===&lt;br /&gt;
Players can set their name to an empty string using the setinfo console command.  Some admin plugins will be unable to kick or perform other actions on them.  Valve has been notified, and is unwilling to fix this.&lt;br /&gt;
&lt;br /&gt;
*Fix: [https://forums.alliedmods.net/showthread.php?p=841590 Rcon locker / exploit fix] will automatically kick anyone found to have an empty name&lt;br /&gt;
=== Special name characters ===&lt;br /&gt;
If certain special characters are added to your name, you can create messages that appear to be sent by the server administrator.&lt;br /&gt;
&lt;br /&gt;
*Fix: [https://forums.alliedmods.net/showthread.php?p=841590 Rcon locker / exploit fix]&lt;br /&gt;
&lt;br /&gt;
= Fixed Exploits = &lt;br /&gt;
== Memory corruption crash ==&lt;br /&gt;
See [http://aluigi.altervista.org/adv/sourcefraghof-adv.txt this link]&lt;br /&gt;
&lt;br /&gt;
Fix: none&lt;br /&gt;
*'''Fixed in:''' Orangebox, L4D (August 21 2009) CSS (August 25 2009)&lt;br /&gt;
&lt;br /&gt;
== Arbitrary file upload ==&lt;br /&gt;
See [http://aluigi.altervista.org/adv/sourceupfile-adv.txt this link]&lt;br /&gt;
&lt;br /&gt;
Fix: [https://forums.alliedmods.net/showthread.php?p=905647 File upload exploit fix]&lt;br /&gt;
*'''Fixed in:''' Orangebox, L4D (August 21 2009) CSS (August 25 2009)&lt;br /&gt;
&lt;br /&gt;
== &amp;quot;ProcessClientInfo: SourceTV can not connect to game directly&amp;quot; crash ==&lt;br /&gt;
See [http://aluigi.altervista.org/adv/sourcenotvnull-adv.txt this link]&lt;br /&gt;
&lt;br /&gt;
Fix: Add &amp;quot;tv_enable 1&amp;quot; to cfg/autoexec.cfg, and (optionally) &amp;quot;tv_enable 0&amp;quot; to server.cfg (You only need tv_enable 0 if you don't want sourcetv)&lt;br /&gt;
*'''Fixed in:''' Orangebox, L4D (August 21 2009) CSS (August 25 2009)&lt;br /&gt;
&lt;br /&gt;
== Player disconnect crash ==&lt;br /&gt;
See [http://aluigi.altervista.org/adv/sourcefs-adv.txt this link]&lt;br /&gt;
&lt;br /&gt;
Fix: [https://forums.alliedmods.net/showthread.php?p=841590 Rcon locker / exploit fix] has what may be a partial fix. &lt;br /&gt;
*'''Fixed in:''' Orangebox, L4D (August 21 2009) CSS (August 25 2009)&lt;/div&gt;</summary>
		<author><name>Berni</name></author>
		
	</entry>
</feed>