<?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=AlicanC</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=AlicanC"/>
	<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/Special:Contributions/AlicanC"/>
	<updated>2026-06-05T22:14:25Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.6</generator>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Generic_Source_Events&amp;diff=5032</id>
		<title>Generic Source Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Generic_Source_Events&amp;diff=5032"/>
		<updated>2007-08-14T16:22:26Z</updated>

		<summary type="html">&lt;p&gt;AlicanC: /* round_start */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:''Refer back to [[Game Events (Source)]] for more events.''&lt;br /&gt;
&lt;br /&gt;
These '''should''' apply to all Source engine games&lt;br /&gt;
=== team_info ===&lt;br /&gt;
{{qnotice|Info about team}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|team_info|string}}&lt;br /&gt;
{{hl2msg|byte|teamid}}&lt;br /&gt;
{{hl2msg|string|teamname}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== team_score ===&lt;br /&gt;
{{qnotice|Team score changed}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|team_info|string}}&lt;br /&gt;
{{hl2msg|byte|teamid}}&lt;br /&gt;
{{hl2msg|short|score}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_team ===&lt;br /&gt;
{{qnotice|Player change his team}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_team|string}}&lt;br /&gt;
{{hl2msg|short|userid}}&lt;br /&gt;
{{hl2msg|byte|team}}&lt;br /&gt;
{{hl2msg|byte|oldteam}}&lt;br /&gt;
{{hl2msg|bool|disconnect}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_class ===&lt;br /&gt;
{{qnotice|A player changed his class}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_class|string}}&lt;br /&gt;
{{hl2msg|short|userid}}&lt;br /&gt;
{{hl2msg|string|class}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_death ===&lt;br /&gt;
{{qnotice|A game event, name may be 32 charaters long}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_death|string}}&lt;br /&gt;
{{hl2msg|short|userid}}&lt;br /&gt;
{{hl2msg|short|attacker}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_hurt ===&lt;br /&gt;
{{qnotice|A player was hurt}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_hurt|string}}&lt;br /&gt;
{{hl2msg|short|userid}}&lt;br /&gt;
{{hl2msg|short|attacker}}&lt;br /&gt;
{{hl2msg|byte|health}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_chat ===&lt;br /&gt;
{{qnotice|A public player chat}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_chat|string}}&lt;br /&gt;
{{hl2msg|bool|teamonly}}&lt;br /&gt;
{{hl2msg|short|userid}}&lt;br /&gt;
{{hl2msg|string|text}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_score ===&lt;br /&gt;
{{qnotice|Players scores changed}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_score|string}}&lt;br /&gt;
{{hl2msg|short|userid}}&lt;br /&gt;
{{hl2msg|short|kills}}&lt;br /&gt;
{{hl2msg|short|deaths}}&lt;br /&gt;
{{hl2msg|short|score}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_spawn ===&lt;br /&gt;
{{qnotice|player spawned in game}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_spawn|string}}&lt;br /&gt;
{{hl2msg|short|userid}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_shoot ===&lt;br /&gt;
{{qnotice|Player shoot his weapon}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_shoot|string}}&lt;br /&gt;
{{hl2msg|short|userid}}&lt;br /&gt;
{{hl2msg|byte|weapon}}&lt;br /&gt;
{{hl2msg|byte|mode}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_use ===&lt;br /&gt;
{{qnotice|When a player uses an option}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_use|string}}&lt;br /&gt;
{{hl2msg|short|userid}}&lt;br /&gt;
{{hl2msg|short|entity}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== player_changename ===&lt;br /&gt;
{{qnotice|Player changed name}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|player_changename|string}}&lt;br /&gt;
{{hl2msg|string|userid}}&lt;br /&gt;
{{hl2msg|string|oldname}}&lt;br /&gt;
{{hl2msg|string|newname}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== game_newmap ===&lt;br /&gt;
{{qnotice|Send when new map is completely loaded}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|game_newmap|string}}&lt;br /&gt;
{{hl2msg|string|mapname}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== game_start ===&lt;br /&gt;
{{qnotice|A new game starts}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|game_start|string}}&lt;br /&gt;
{{hl2msg|long|roundslimit}}&lt;br /&gt;
{{hl2msg|long|timelimit}}&lt;br /&gt;
{{hl2msg|long|fraglimit}}&lt;br /&gt;
{{hl2msg|string|objective}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== game_end ===&lt;br /&gt;
{{qnotice|A game ended}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|game_end|string}}&lt;br /&gt;
{{hl2msg|byte|winner}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== round_start ===&lt;br /&gt;
{{qnotice|The round started}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|round_start|string}}&lt;br /&gt;
{{hl2msg|long|timelimit}}&lt;br /&gt;
{{hl2msg|long|fraglimit}}&lt;br /&gt;
{{hl2msg|string|objective}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== round_end ===&lt;br /&gt;
{{qnotice|The round ended}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|round_end|string}}&lt;br /&gt;
{{hl2msg|byte|winner}}&lt;br /&gt;
{{hl2msg|byte|reason}}&lt;br /&gt;
{{hl2msg|string|message}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== game_message ===&lt;br /&gt;
{{qnotice|A game message}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|game_message|string}}&lt;br /&gt;
{{hl2msg|byte|target}}&lt;br /&gt;
{{hl2msg|string|text}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== break_breakable ===&lt;br /&gt;
{{qnotice|A breakable (func_break) is broken.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|break_breakable|string}}&lt;br /&gt;
{{hl2msg|long|entindex}}&lt;br /&gt;
{{hl2msg|short|userid}}&lt;br /&gt;
{{hl2msg|byte|material}}&lt;br /&gt;
{{end-hl2msg}}&lt;br /&gt;
&lt;br /&gt;
=== break_prop ===&lt;br /&gt;
{{qnotice|A breakable prop is broken.}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{begin-hl2msg|break_prop|string}}&lt;br /&gt;
{{hl2msg|long|entindex}}&lt;br /&gt;
{{hl2msg|short|userid}}&lt;br /&gt;
{{end-hl2msg}}&lt;/div&gt;</summary>
		<author><name>AlicanC</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=SQL_Admins_(SourceMod)&amp;diff=5030</id>
		<title>SQL Admins (SourceMod)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=SQL_Admins_(SourceMod)&amp;diff=5030"/>
		<updated>2007-08-14T11:46:45Z</updated>

		<summary type="html">&lt;p&gt;AlicanC: /* Frequently Asked Questions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SourceMod has support for loading and managing admins via SQL, using any of the supported SQL drivers provided (currently, MySQL and SQLite).  This can be very advantageous if you have a large number of admins, you wish to manage your admins via external tools, or you wish to share admins across servers.  &lt;br /&gt;
&lt;br /&gt;
This article will explain how to set up your server to use admins through SQL.  No knowledge of SQL is required for basic administration; however, by using this feature you should realize that SourceMod does not provide easy functionality for full SQL control.  You will need to use a third party tool or learn SQL yourself if you need greater functionality.&lt;br /&gt;
&lt;br /&gt;
However, it is assumed that you:&lt;br /&gt;
*Have access to an SQL database;&lt;br /&gt;
*Know how to access the SQL database;&lt;br /&gt;
*Know how to execute commands or scripts on the SQL database.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Database Setup=&lt;br /&gt;
==MySQL==&lt;br /&gt;
If you have not already created a database on your MySQL server, do so.  &lt;br /&gt;
&lt;br /&gt;
Find the script &amp;lt;tt&amp;gt;configs/sql-init-scripts/admins-mysql.sql&amp;lt;/tt&amp;gt; in the SourceMod distribution.  Then, using either the command line or a tool such as [http://www.phpmyadmin.net/ phpMyAdmin], run its contents.  This will create the necessary tables.&lt;br /&gt;
&lt;br /&gt;
Next, open &amp;lt;tt&amp;gt;configs/databases.cfg&amp;lt;/tt&amp;gt; on your server.  You should see a section called &amp;lt;tt&amp;gt;&amp;quot;default&amp;quot;&amp;lt;/tt&amp;gt;.  You can either use this section, or create a new one called &amp;lt;tt&amp;gt;&amp;quot;admins&amp;quot;&amp;lt;/tt&amp;gt; if you wish to separate your connections.  You must fill out the &amp;lt;tt&amp;gt;driver&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;host&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;database&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;user&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;pass&amp;lt;/tt&amp;gt; fields.  If you do not need a field, use empty quotation marks as the value (&amp;lt;tt&amp;gt;&amp;quot;&amp;quot;&amp;lt;/tt&amp;gt;).  &lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	&amp;quot;default&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;driver&amp;quot;			&amp;quot;mysql&amp;quot;&lt;br /&gt;
		&amp;quot;host&amp;quot;				&amp;quot;localhost&amp;quot;&lt;br /&gt;
		&amp;quot;database&amp;quot;			&amp;quot;sourcemod&amp;quot;&lt;br /&gt;
		&amp;quot;user&amp;quot;				&amp;quot;myaccount&amp;quot;&lt;br /&gt;
		&amp;quot;pass&amp;quot;				&amp;quot;mypassword&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==SQLite==&lt;br /&gt;
SourceMod distributes a pre-made SQLite database file with all of the admin tables created.  If you with to manually create a database or add tables to a pre-existing database, use the contents of the &amp;lt;tt&amp;gt;configs/sql-init-scripts/admins-sqlite.sql&amp;lt;/tt&amp;gt; script.&lt;br /&gt;
&lt;br /&gt;
Copy the &amp;lt;tt&amp;gt;configs/sql-init-scripts/admins-sqlite.sq3&amp;lt;/tt&amp;gt; binary from the SourceMod distribution into your server's &amp;lt;tt&amp;gt;data/sqlite&amp;lt;/tt&amp;gt; folder.  Then, add a section to your server's &amp;lt;tt&amp;gt;configs/databases.cfg&amp;lt;/tt&amp;gt; file as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	&amp;quot;admins&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;driver&amp;quot;			&amp;quot;sqlite&amp;quot;&lt;br /&gt;
		&amp;quot;database&amp;quot;			&amp;quot;admins-sqlite&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may choose to rename the database file, or to use the file as your default database instead.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Enabling Plugins=&lt;br /&gt;
By default, all of the SQL plugins are located in the &amp;lt;tt&amp;gt;plugins/disabled&amp;lt;/tt&amp;gt; folder on your server -- they are not loaded by default.  To enable plugins, move them from the &amp;lt;tt&amp;gt;plugins/disabled&amp;lt;/tt&amp;gt; folder and into &amp;lt;tt&amp;gt;plugins&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
You will usually want to enable &amp;lt;tt&amp;gt;sql-admin-manager.smx&amp;lt;/tt&amp;gt;.  This plugin adds some helpful console commands for very basic admin management.  However, you should only enable '''ONE''' of the other two SQL plugins:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;admin-sql-prefetch.smx&amp;lt;/tt&amp;gt;: This plugin is ideal for small to medium sized databases without much connection lag.  It loads the entire database admin contents at map load (or whenever a refresh is requested).  If you have serious database delay or want to be able to add/delete/edit admins without refreshing the per-map cache on each server,  this isn't the plugin for you.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;PROS:&amp;lt;/b&amp;gt; Very simple plugin with no extra complexity.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;*&amp;lt;b&amp;gt;CONS:&amp;lt;/b&amp;gt; Gameserver will stall whenever the cache is refreshed (mapload or when using &amp;lt;tt&amp;gt;sm_reloadadmins&amp;lt;/tt&amp;gt;).  If you add, remove, or edit admins, the changes are not reflected until the cache is refreshed.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;tt&amp;gt;admin-sql-threaded.smx&amp;lt;/tt&amp;gt;: This plugin is completely threaded.  This makes it much more complex, and thus it is currently &amp;quot;experimental&amp;quot; (although it has been tested to work fine).  It pre-caches all group and override information.  Admin-lookup is done completely dynamically.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;PROS:&amp;lt;/b&amp;gt; A faulty/slow database connection will never halt the server.  If you add/remove/edit admins, the changes will be reflected as soon as the player connects to the server.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;CONS:&amp;lt;/b&amp;gt; It is very complex and thus not trivial to edit for custom changes.  It also may have unexpected functionality (for example, &amp;lt;tt&amp;gt;sm_reloadadmins&amp;lt;/tt&amp;gt; will have a slight delayed reaction because the plugin is multi-threaded).&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once you have enabled the manager, and enabled &amp;lt;b&amp;gt;ONE&amp;lt;/b&amp;gt; of the &amp;lt;tt&amp;gt;admin-sql&amp;lt;/tt&amp;gt; plugins, you are ready to go!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Management Commands=&lt;br /&gt;
As a convenience, SourceMod provides a few basic SQL admin management commands via the &amp;lt;tt&amp;gt;sql-admin-manager.smx&amp;lt;/tt&amp;gt; plugin.  All of the commands require the &amp;lt;tt&amp;gt;root&amp;lt;/tt&amp;gt; admin flag.&lt;br /&gt;
&lt;br /&gt;
The following conventions are used:&lt;br /&gt;
*When &amp;amp;lt;authtype&amp;amp;gt; is requested, it means one of the following three values: &amp;lt;tt&amp;gt;steam&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;ip&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*When &amp;amp;lt;identity&amp;amp;gt; is requested, it should be the unique string to be paired with the &amp;lt;tt&amp;gt;authtype&amp;lt;/tt&amp;gt;.  For example, a &amp;lt;tt&amp;gt;steam&amp;lt;/tt&amp;gt; identity would be a Steam ID.  An &amp;lt;tt&amp;gt;ip&amp;lt;/tt&amp;gt; identity would be an IP address, and a &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt; identity would be a Half-Life 2 player name.&lt;br /&gt;
*When [immunity] is requested, it means one of the following three values: &amp;lt;tt&amp;gt;none&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;default&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;global&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note: if a string has spaces, it must be in quotes!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note: A colon is a break character and Steam IDs must be in quotes!&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:{|&lt;br /&gt;
|- class=&amp;quot;t2th&amp;quot;&lt;br /&gt;
| Command&lt;br /&gt;
| Format&lt;br /&gt;
| Description&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| sm_sql_addadmin&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;&amp;lt;alias&amp;gt; &amp;lt;authtype&amp;gt; &amp;lt;identity&amp;gt; &amp;lt;flags&amp;gt; [password]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| Adds a new entry to the &amp;lt;tt&amp;gt;sm_admins&amp;lt;/tt&amp;gt; table.  The &amp;lt;tt&amp;gt;alias&amp;lt;/tt&amp;gt; can be any value and is usually used to assign a readable name to an IP/SteamID.&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| sm_sql_deladmin&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;&amp;lt;authtype&amp;gt; &amp;lt;identity&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| Removes an admin.&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| sm_sql_addgroup&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;&amp;lt;name&amp;gt; &amp;lt;flags&amp;gt; [immunity]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| Adds a new group with the specified flags and immunity/&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| sm_sql_delgroup&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;&amp;lt;name&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| Removes the specified group.  Quotation marks are optional if the name has odd characters.&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot; &lt;br /&gt;
| sm_sql_setadmingroups&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;&amp;lt;authtype&amp;gt; &amp;lt;identity&amp;gt; [group1] ... [group N]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| Sets an admin's group list.  The inheritance order is the order the groups are specified in.  This sets, and does not add; thus specifying no groups removes the user from all groups.  Example:&lt;br /&gt;
&amp;lt;tt&amp;gt;sm_sql_setadmingroups steam &amp;quot;STEAM_0:1:16&amp;quot; &amp;quot;Full Admins&amp;quot;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
&amp;lt;b&amp;gt;Q:&amp;lt;/b&amp;gt; Can I use &amp;lt;tt&amp;gt;admin-sql&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;admin-flatfile&amp;lt;/tt&amp;gt; at the same time?&lt;br /&gt;
&amp;lt;b&amp;gt;A:&amp;lt;/b&amp;gt; Yes.  The data will be merged together in SourceMod's cache.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Q:&amp;lt;/b&amp;gt; Can I use both the &amp;lt;tt&amp;gt;threaded&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;prefetch&amp;lt;/tt&amp;gt; SQL plugins at the same time?&lt;br /&gt;
&amp;lt;b&amp;gt;A:&amp;lt;/b&amp;gt; No.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Q:&amp;lt;/b&amp;gt; Can duplicate groups/admins be in the flat files and the SQL database?&lt;br /&gt;
&amp;lt;b&amp;gt;A:&amp;lt;/b&amp;gt; Yup.  They will be merged safely.&lt;br /&gt;
&lt;br /&gt;
=Schemas=&lt;br /&gt;
This section documents the required portions of the admin table schema.  You do not need to read or learn this unless you plan to use SQL directly.&lt;br /&gt;
&lt;br /&gt;
The exact schemas for each driver are located in &amp;lt;tt&amp;gt;configs/sql-init-scripts&amp;lt;/tt&amp;gt;.  The purpose of this document is to explain the fields rather than list the exact structures.&lt;br /&gt;
&lt;br /&gt;
==sm_admins==&lt;br /&gt;
This table is used to store administrators.  Although the primary key is &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, applications should enforce that &amp;lt;tt&amp;gt;authtype&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;identity&amp;lt;/tt&amp;gt; have no combined duplicates.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Primary key:&amp;lt;/b&amp;gt; &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; (auto increments).&lt;br /&gt;
&lt;br /&gt;
:{|&lt;br /&gt;
|- class=&amp;quot;t2th&amp;quot;&lt;br /&gt;
| Field&lt;br /&gt;
| Type&lt;br /&gt;
| Purpose&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| id&lt;br /&gt;
| integer&lt;br /&gt;
| Unique integer identifying the row.&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| authtype&lt;br /&gt;
| string NOT NULL&lt;br /&gt;
Constrained to 'steam', 'name', or 'ip'&lt;br /&gt;
| Authentication type the identity is against.&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| identity&lt;br /&gt;
| string NOT NULL&lt;br /&gt;
| Steam ID, name, or IP address.&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| password&lt;br /&gt;
| string&lt;br /&gt;
| Password, if any, the admin must use.&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| flags&lt;br /&gt;
| string NOT NULL&lt;br /&gt;
| Permission flag string.&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| name&lt;br /&gt;
| string NOT NULL&lt;br /&gt;
| Alias used for external tools (all but ignored in SourceMod).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==sm_groups==&lt;br /&gt;
This table is used to store all groups entries.  Although the primary key is &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, applications should enforce that the &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt; field stays unique.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Primary key:&amp;lt;/b&amp;gt; &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; (auto increments).&lt;br /&gt;
&lt;br /&gt;
:{|&lt;br /&gt;
|- class=&amp;quot;t2th&amp;quot;&lt;br /&gt;
| Field&lt;br /&gt;
| Type&lt;br /&gt;
| Purpose&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| id&lt;br /&gt;
| integer&lt;br /&gt;
| Unique integer identifying the row.&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| immunity&lt;br /&gt;
| string NOT NULL&lt;br /&gt;
Constrained to 'none', 'global', or 'default'&lt;br /&gt;
| Immunity level the group gets.&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| flags&lt;br /&gt;
| string NOT NULL&lt;br /&gt;
| Permissions flag string.&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| name&lt;br /&gt;
| string NOT NULL&lt;br /&gt;
| Unique name of the group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==sm_admins_groups==&lt;br /&gt;
This table is used to map admins to the groups they will inherit.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Primary key:&amp;lt;/b&amp;gt; &amp;lt;tt&amp;gt;admin_id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;group_id&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:{|&lt;br /&gt;
|- class=&amp;quot;t2th&amp;quot;&lt;br /&gt;
| Field&lt;br /&gt;
| Type&lt;br /&gt;
| Purpose&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| admin_id &lt;br /&gt;
| integer&lt;br /&gt;
| Reference to the &amp;lt;tt&amp;gt;sm_admins.id&amp;lt;/tt&amp;gt; field.  Specifies the admin inheriting the group.&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| group_id&lt;br /&gt;
| integer&lt;br /&gt;
| Reference to the &amp;lt;tt&amp;gt;sm_groups.id&amp;lt;/tt&amp;gt; field.  Specifies the group the admin is inheriting.&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| inherit_order&lt;br /&gt;
| integer NOT NULL&lt;br /&gt;
| Order of inheritance for the given admin.  Lower means earlier inheritance.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==sm_group_immunity==&lt;br /&gt;
This table is used to map which groups are immune from other groups.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Primary key:&amp;lt;/b&amp;gt; &amp;lt;tt&amp;gt;group_id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;other_id&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:{|&lt;br /&gt;
|- class=&amp;quot;t2th&amp;quot;&lt;br /&gt;
| Field&lt;br /&gt;
| Type&lt;br /&gt;
| Purpose&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| group_id&lt;br /&gt;
| integer&lt;br /&gt;
| Reference to the &amp;lt;tt&amp;gt;sm_groups.id&amp;lt;/tt&amp;gt; field.  Specifies the group gaining immunity.&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| other_id&lt;br /&gt;
| integer&lt;br /&gt;
| Reference to the &amp;lt;tt&amp;gt;sm_groups.id&amp;lt;/tt&amp;gt; field.  Specifies who &amp;lt;tt&amp;gt;group_id&amp;lt;/tt&amp;gt; is becoming immune from.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==sm_group_overrides==&lt;br /&gt;
This table is used to specify group-based command overrides.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Primary key:&amp;lt;/b&amp;gt; &amp;lt;tt&amp;gt;group_id&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:{|&lt;br /&gt;
|- class=&amp;quot;t2th&amp;quot;&lt;br /&gt;
| Field&lt;br /&gt;
| Type&lt;br /&gt;
| Purpose&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| group_id&lt;br /&gt;
| integer&lt;br /&gt;
| Reference to the &amp;lt;tt&amp;gt;sm_groups.id&amp;lt;/tt&amp;gt; field.  Specifies the group the override is for.&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| type&lt;br /&gt;
| string NOT NULL&lt;br /&gt;
Constrained to 'command' or 'group'.&lt;br /&gt;
| Specifies whether the override is a command or a command group.&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| name&lt;br /&gt;
| string NOT NULL&lt;br /&gt;
| Command name.&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| access&lt;br /&gt;
| string NOT NULL&lt;br /&gt;
Constrained to 'allow' or 'deny'.&lt;br /&gt;
| Whether the command is allowed or denied to this group.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==sm_overrides==&lt;br /&gt;
This table is used to specify global command overrides.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Primary key:&amp;lt;/b&amp;gt; &amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:{|&lt;br /&gt;
|- class=&amp;quot;t2th&amp;quot;&lt;br /&gt;
| Field&lt;br /&gt;
| Type&lt;br /&gt;
| Purpose&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| type&lt;br /&gt;
| string NOT NULL&lt;br /&gt;
Constrained to 'command' or 'group'.&lt;br /&gt;
| Specifies whether the override is a command or a command group.&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| name&lt;br /&gt;
| string NOT NULL&lt;br /&gt;
| Command name.&lt;br /&gt;
|- class=&amp;quot;t2td&amp;quot;&lt;br /&gt;
| flags&lt;br /&gt;
| string NOT NULL&lt;br /&gt;
| Permissions flag string.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Documentation]]&lt;/div&gt;</summary>
		<author><name>AlicanC</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Commands_(SourceMod_Scripting)&amp;diff=4741</id>
		<title>Commands (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Commands_(SourceMod_Scripting)&amp;diff=4741"/>
		<updated>2007-06-10T16:23:44Z</updated>

		<summary type="html">&lt;p&gt;AlicanC: &amp;quot;remove console&amp;quot; -&amp;gt; &amp;quot;remote console&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[SourceMod]] allows you to create console commands similar to [[AMX Mod X]].  There are two main types of console commands:&lt;br /&gt;
*'''Server Commands''', which are fired from one of the following input methods:&lt;br /&gt;
**the server console itself;&lt;br /&gt;
**the remote console (RCON);&lt;br /&gt;
**the ServerCommand() function, either from SourceMod or the [[Half-Life 2]] engine.&lt;br /&gt;
*'''Console Commands''', which are fired from one of the following input methods:&lt;br /&gt;
**a client's console&lt;br /&gt;
**any of the server command input methods &lt;br /&gt;
&lt;br /&gt;
For server commands, there is no client index.  For console/client commands, there is a client index, but it may be 0 to indicate that the command is from the server.&lt;br /&gt;
&lt;br /&gt;
Note that button &amp;quot;commands,&amp;quot; such as +attach and +duck, are not actually console commands.  They are a separate command stream sent over the network, as they need to be tied to a specific frame.  &lt;br /&gt;
&lt;br /&gt;
=Server Commands=&lt;br /&gt;
As noted above, server commands are fired through the server console, whether remote, local, or through the Source engine.  There is no client index associated with a server command.  &lt;br /&gt;
&lt;br /&gt;
Server commands are registered through the &amp;lt;tt&amp;gt;RegServerCmd()&amp;lt;/tt&amp;gt; function, listed in &amp;lt;tt&amp;gt;console.inc&amp;lt;/tt&amp;gt;.  When registering a server command, you may be hooking an already existing command, and thus whether you return &amp;lt;tt&amp;gt;Plugin_Handled&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;Plugin_Continue&amp;lt;/tt&amp;gt; is important.  &lt;br /&gt;
*&amp;lt;tt&amp;gt;Plugin_Continue&amp;lt;/tt&amp;gt;: The original server command will be processed, if there was one.  If the server command was created by a plugin, this has no effect.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Plugin_Handled&amp;lt;/tt&amp;gt;: The original server command will not be processed, if there was one.  If the server command was created by a plugin, this has no effect.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt;: This original server command will not be processed, if there was one.  Additionally, no further hooks will be called for this command until it is fired again.&lt;br /&gt;
&lt;br /&gt;
==Adding Server Commands==&lt;br /&gt;
Let's say we want to add a test command to show how Half-Life 2 breaks down command arguments.  A possible implementation might be:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegServerCmd(&amp;quot;test_command&amp;quot;, Command_Test)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_Test(args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg[128]&lt;br /&gt;
	new String:full[256]&lt;br /&gt;
&lt;br /&gt;
	GetCmdArgString(full, sizeof(full))&lt;br /&gt;
&lt;br /&gt;
	PrintToServer(&amp;quot;Argument string: %s&amp;quot;, full)&lt;br /&gt;
	PrintToServer(&amp;quot;Argument count: %d&amp;quot;, args)&lt;br /&gt;
	for (new i=1; i&amp;lt;=args; i++)&lt;br /&gt;
	{&lt;br /&gt;
		GetCmdArg(i, arg, sizeof(arg))&lt;br /&gt;
		PrintToServer(&amp;quot;Argument %d: %s&amp;quot;, i, arg)&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Blocking Server Commands==&lt;br /&gt;
Let's say we wanted to disable the &amp;quot;kickid&amp;quot; command on the server.  There's no real good reason to do this, but for example's sake:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegServerCmd(&amp;quot;kickid&amp;quot;, Command_KickId)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_Kickid(args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Console Commands=&lt;br /&gt;
Unlike server commands, console commands can be triggered by either the server or the client, so the callback function receives a client index as well as the argument count.  If the server fired the command, the client index will be 0.  &lt;br /&gt;
&lt;br /&gt;
When returning the &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; from the callback, the following effects will happen:&lt;br /&gt;
*&amp;lt;tt&amp;gt;Plugin_Continue&amp;lt;/tt&amp;gt;: The original functionality of the command (if any) will still be processed.  If there was no original functionality, the client will receive &amp;quot;Unknown command&amp;quot; in their console.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Plugin_Handled&amp;lt;/tt&amp;gt;: The original functionality of the command (if any) will be blocked.  If there was no functionality originally, this prevents clients from seeing &amp;quot;Unknown command&amp;quot; in their console.&lt;br /&gt;
*&amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt;: Same as &amp;lt;tt&amp;gt;Plugin_Handled&amp;lt;/tt&amp;gt;, except that this will be the last hook called.&lt;br /&gt;
&lt;br /&gt;
Note that, unlike AMX Mod X, SourceMod does not allow you to register command filters.  I.e., there is no equivalent to this notation:&lt;br /&gt;
&amp;lt;pawn&amp;gt;register_clcmd(&amp;quot;say /ff&amp;quot;, &amp;quot;Command_SayFF&amp;quot;);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This notation was removed to make our internal code simpler and faster.  Writing the same functionality is easy, and demonstrated below.&lt;br /&gt;
&lt;br /&gt;
==Adding Commands==&lt;br /&gt;
Adding client commands is very simple.  Let's port our earlier testing command to display information about the client as well.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegConsoleCmd(&amp;quot;test_command&amp;quot;, Command_Test)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_Test(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg[128]&lt;br /&gt;
	new String:full[256]&lt;br /&gt;
&lt;br /&gt;
	GetCmdArgString(full, sizeof(full))&lt;br /&gt;
&lt;br /&gt;
	if (client)&lt;br /&gt;
	{&lt;br /&gt;
		new String:name[32]&lt;br /&gt;
		GetClientName(client, name, sizeof(name))&lt;br /&gt;
		PrintToServer(&amp;quot;Command from client: %s&amp;quot;, name);&lt;br /&gt;
	} else {&lt;br /&gt;
		PrintToServer(&amp;quot;Command from server.&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	PrintToServer(&amp;quot;Argument string: %s&amp;quot;, full)&lt;br /&gt;
	PrintToServer(&amp;quot;Argument count: %d&amp;quot;, args)&lt;br /&gt;
	for (new i=1; i&amp;lt;=args; i++)&lt;br /&gt;
	{&lt;br /&gt;
		GetCmdArg(i, arg, sizeof(arg))&lt;br /&gt;
		PrintToServer(&amp;quot;Argument %d: %s&amp;quot;, i, arg)&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Hooking Commands==&lt;br /&gt;
A common example is hooking the say command.  Let's say we want to tell players whether FF is enabled when they say '/ff' in game.  &lt;br /&gt;
&lt;br /&gt;
Before we implement this, a common point of confusion with the 'say' command is that Half-Life 2 (and Half-Life 1), by default, send it with the text in one big quoted string.  This means if you say &amp;quot;I like hot dogs,&amp;quot; your command will be broken down as such:&lt;br /&gt;
*Argument string: &amp;quot;I like hot dogs&amp;quot;&lt;br /&gt;
*Argument count: 1&lt;br /&gt;
*Argument #1: I like hot dogs&lt;br /&gt;
&lt;br /&gt;
However, if a player types this in their console: &amp;lt;tt&amp;gt;say I like yams&amp;lt;/tt&amp;gt;, it will be broken up as:&lt;br /&gt;
*Argument string: I like yams&lt;br /&gt;
*Argument count: 3&lt;br /&gt;
*Argument #1: I&lt;br /&gt;
*Argument #2: like&lt;br /&gt;
*Argument #3: yams&lt;br /&gt;
&lt;br /&gt;
Thus, to take into account both of these situations, we are going to use &amp;lt;tt&amp;gt;GetCmdArgString&amp;lt;/tt&amp;gt; and manually parse the input.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegConsoleCmd(&amp;quot;say&amp;quot;, Command_Say)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_Say(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:text[192]&lt;br /&gt;
	GetCmdArgString(text, sizeof(text))&lt;br /&gt;
&lt;br /&gt;
	new startidx = 0&lt;br /&gt;
	if (text[0] == '&amp;quot;')&lt;br /&gt;
	{&lt;br /&gt;
		startidx = 1&lt;br /&gt;
		/* Strip the ending quote, if there is one */&lt;br /&gt;
		new len = strlen(text);&lt;br /&gt;
		if (text[len-1] == '&amp;quot;')&lt;br /&gt;
		{&lt;br /&gt;
			text[len-1] = '\0'&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (StrEqual(text[startidx], &amp;quot;/ff&amp;quot;))&lt;br /&gt;
	{&lt;br /&gt;
		new Handle:ff = FindConVar(&amp;quot;mp_friendlyfire&amp;quot;)&lt;br /&gt;
		if (GetConVarInt(ff))&lt;br /&gt;
		{&lt;br /&gt;
			PrintToConsole(client, &amp;quot;Friendly fire is enabled.&amp;quot;)&lt;br /&gt;
		} else {&lt;br /&gt;
			PrintToConsole(client, &amp;quot;Friendly fire is disabled.&amp;quot;)&lt;br /&gt;
		}&lt;br /&gt;
		/* Block the client's messsage from broadcasting */&lt;br /&gt;
		return Plugin_Handled&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Let say continue normally */&lt;br /&gt;
	return Plugin_Continue&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Creating Admin Commands==&lt;br /&gt;
Let's create a simple admin command which kicks another player by their full name.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;admin_kick&amp;quot;,&lt;br /&gt;
		Command_Kick,&lt;br /&gt;
		ADMFLAG_KICK,&lt;br /&gt;
		&amp;quot;Kicks a player by name&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_Kick(client, args)&lt;br /&gt;
{&lt;br /&gt;
	if (args &amp;lt; 1)&lt;br /&gt;
	{&lt;br /&gt;
		PrintToConsole(client, &amp;quot;Usage: admin_kick &amp;lt;name&amp;gt;&amp;quot;)&lt;br /&gt;
		return Plugin_Handled&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	new String:name[32], maxplayers, target = -1&lt;br /&gt;
	GetCmdArg(1, name, sizeof(name))&lt;br /&gt;
&lt;br /&gt;
	maxplayers = GetMaxClients()&lt;br /&gt;
	for (new i=1; i&amp;lt;=maxplayers; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if (!IsClientConnected(i))&lt;br /&gt;
		{&lt;br /&gt;
			continue&lt;br /&gt;
		}&lt;br /&gt;
		decl String:other[32]&lt;br /&gt;
		GetClientName(i, other, sizeof(other))&lt;br /&gt;
		if (StrEqual(name, other))&lt;br /&gt;
		{&lt;br /&gt;
			target = i&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		PrintToConsole(client, &amp;quot;Could not find any player with the name: \&amp;quot;%s\&amp;quot;&amp;quot;, name)&lt;br /&gt;
		return Plugin_Handled&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	ServerCommand(&amp;quot;kickid %d&amp;quot;, GetClientUserId(target));&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Immunity==&lt;br /&gt;
In our previous example, we did not take immunity into account.  Immunity is a much more complex system in SourceMod than it was in AMX Mod X, and there is no simple flag to denote its permissions.  Instead, two functions are provided:&lt;br /&gt;
*&amp;lt;tt&amp;gt;CanAdminTarget&amp;lt;/tt&amp;gt;: Tests raw AdminId values for immunity.&lt;br /&gt;
*&amp;lt;tt&amp;gt;CanUserTarget&amp;lt;/tt&amp;gt;: Tests in-game clients for immunity.&lt;br /&gt;
&lt;br /&gt;
While immunity is generally tested ''player versus player'', it is possible you might want to check for immunity and not have a targetting client.  While there is no convenience function for this yet, a good idea might be to check for either ''default'' or ''global'' immunity on the player's groups (these can be user-defined for non-player targeted scenarios).&lt;br /&gt;
&lt;br /&gt;
When checking for immunity, the following heuristics are performed in this exact order:&lt;br /&gt;
&amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;If the targeting AdminId is &amp;lt;tt&amp;gt;INVALID_ADMIN_ID&amp;lt;/tt&amp;gt;, targeting fails.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If the targetted AdminId is &amp;lt;tt&amp;gt;INVALID_ADMIN_ID&amp;lt;/tt&amp;gt;, targeting succeeds.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If the targeting admin has &amp;lt;tt&amp;gt;Admin_Root&amp;lt;/tt&amp;gt; (&amp;lt;tt&amp;gt;ADMFLAG_ROOT&amp;lt;/tt&amp;gt;), targeting succeeds.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If the targetted admin has global immunity, targeting fails.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If the targetted admin has default immunity, and the targeting admin belongs to no groups, targeting fails.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If the targetted admin has specific immunity from the targeting admin via group immunities, targeting fails.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If no conclusion is reached via the previous steps, targeting succeeds.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, how can we adapt our function about to use immunity?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_Kick(client, args)&lt;br /&gt;
{&lt;br /&gt;
	if (args &amp;lt; 1)&lt;br /&gt;
	{&lt;br /&gt;
		PrintToConsole(client, &amp;quot;Usage: admin_kick &amp;lt;name&amp;gt;&amp;quot;)&lt;br /&gt;
		return Plugin_Handled&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	new String:name[32], maxplayers, target = -1&lt;br /&gt;
	GetCmdArg(1, name, sizeof(name))&lt;br /&gt;
&lt;br /&gt;
	maxplayers = GetMaxClients()&lt;br /&gt;
	for (new i=1; i&amp;lt;=maxplayers; i++)&lt;br /&gt;
	{&lt;br /&gt;
		if (!IsClientConnected(i))&lt;br /&gt;
		{&lt;br /&gt;
			continue&lt;br /&gt;
		}&lt;br /&gt;
		decl String:other[32]&lt;br /&gt;
		GetClientName(i, other, sizeof(other))&lt;br /&gt;
		if (StrEqual(name, other))&lt;br /&gt;
		{&lt;br /&gt;
			target = i&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		PrintToConsole(client, &amp;quot;Could not find any player with the name: \&amp;quot;%s\&amp;quot;&amp;quot;, name)&lt;br /&gt;
		return Plugin_Handled&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (!CanUserTarget(client, target))&lt;br /&gt;
	{&lt;br /&gt;
		PrintToConsole(client, &amp;quot;You cannot target this client.&amp;quot;)&lt;br /&gt;
		return Plugin_Handled&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	ServerCommand(&amp;quot;kickid %d&amp;quot;, GetClientUserId(target))&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Client-Only Commands=&lt;br /&gt;
SourceMod exposes a forward that is called whenever a client executes any command string in their console, called &amp;lt;tt&amp;gt;OnClientCommand&amp;lt;/tt&amp;gt;.  An example of this looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:OnClientCommand(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:cmd[16]&lt;br /&gt;
	GetCmdArg(0, cmd, sizeof(cmd));	/* Get command name */&lt;br /&gt;
&lt;br /&gt;
	if (StrEqual(cmd, &amp;quot;test_command&amp;quot;))&lt;br /&gt;
	{&lt;br /&gt;
		/* Got the client command! Block it... */&lt;br /&gt;
		return Plugin_Handled&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Continue&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is worth noting that not everything a client sends will be available through this command.  Command registered via external sources in C++ may not be available, especially if they are created via &amp;lt;tt&amp;gt;CON_COMMAND&amp;lt;/tt&amp;gt; in the game mod itself.  For example, &amp;quot;say&amp;quot; is usually implemented this way, because it can be used by both clients and the server, and thus it does not channel through this forward.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Chat Triggers=&lt;br /&gt;
SourceMod will automatically create chat triggers for every command you make (as of revision 900).  For example, if you create a console command called &amp;quot;sm_megaslap,&amp;quot; administrators will be able to type any of the following commands in &amp;lt;tt&amp;gt;say&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;say_team&amp;lt;/tt&amp;gt; message modes:&lt;br /&gt;
&amp;lt;pre&amp;gt;!sm_megaslap&lt;br /&gt;
!megaslap&lt;br /&gt;
/sm_megaslap&lt;br /&gt;
/megaslap&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SourceMod then executes this command and its arguments as if it came from the client console.&lt;br /&gt;
*&amp;quot;&amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt;&amp;quot; is the default ''public'' trigger (&amp;lt;tt&amp;gt;PublicChatTrigger&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;configs/core.cfg&amp;lt;/tt&amp;gt;) and your entry will be displayed to all clients as normal.&lt;br /&gt;
*&amp;quot;&amp;lt;tt&amp;gt;/&amp;lt;/tt&amp;gt;&amp;quot; is the default ''silent'' trigger (&amp;lt;tt&amp;gt;SilentChatTrigger&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;configs/core.cfg&amp;lt;/tt&amp;gt;) and your entry will be blocked from being displayed.&lt;br /&gt;
&lt;br /&gt;
SourceMod will only execute commands registered with &amp;lt;tt&amp;gt;RegConsoleCmd&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;RegAdminCmd&amp;lt;/tt&amp;gt;, and only if those commands are not already provided by Half-Life 2 or the game mod.  If the command is prefixed with &amp;quot;sm_&amp;quot; then the &amp;quot;sm_&amp;quot; can be omitted from the chat trigger.&lt;br /&gt;
&lt;br /&gt;
Console commands which wish to support usage as a chat trigger should not use &amp;lt;tt&amp;gt;PrintTo*&amp;lt;/tt&amp;gt; natives.  Instead, they should use &amp;lt;tt&amp;gt;ReplyToCommand()&amp;lt;/tt&amp;gt;, which will automatically print your message either as a chat message or to the client's console, depending on the source of the command.&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Development]][[Category:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>AlicanC</name></author>
		
	</entry>
</feed>