jit refactoring branch
--HG-- branch : refac-jit extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/refac-jit%402369
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Admin File Reader Plugin
|
||||
* Manages the standard flat files for admins. This is the file to compile.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
/* We like semicolons */
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "Admin File Reader",
|
||||
author = "AlliedModders LLC",
|
||||
description = "Reads admin files",
|
||||
version = SOURCEMOD_VERSION,
|
||||
url = "http://www.sourcemod.net/"
|
||||
};
|
||||
|
||||
/** Various parsing globals */
|
||||
new bool:g_LoggedFileName = false; /* Whether or not the file name has been logged */
|
||||
new g_ErrorCount = 0; /* Current error count */
|
||||
new g_IgnoreLevel = 0; /* Nested ignored section count, so users can screw up files safely */
|
||||
new g_CurrentLine = 0; /* Current line we're on */
|
||||
new String:g_Filename[PLATFORM_MAX_PATH]; /* Used for error messages */
|
||||
|
||||
#include "admin-overrides.sp"
|
||||
#include "admin-groups.sp"
|
||||
#include "admin-users.sp"
|
||||
#include "admin-simple.sp"
|
||||
|
||||
public OnRebuildAdminCache(AdminCachePart:part)
|
||||
{
|
||||
if (part == AdminCache_Overrides)
|
||||
{
|
||||
ReadOverrides();
|
||||
} else if (part == AdminCache_Groups) {
|
||||
ReadGroups();
|
||||
} else if (part == AdminCache_Admins) {
|
||||
ReadUsers();
|
||||
ReadSimpleUsers();
|
||||
}
|
||||
}
|
||||
|
||||
ParseError(const String:format[], {Handle,String,Float,_}:...)
|
||||
{
|
||||
decl String:buffer[512];
|
||||
|
||||
if (!g_LoggedFileName)
|
||||
{
|
||||
LogError("Error(s) detected parsing %s", g_Filename);
|
||||
g_LoggedFileName = true;
|
||||
}
|
||||
|
||||
VFormat(buffer, sizeof(buffer), format, 2);
|
||||
|
||||
LogError(" (line %d) %s", g_CurrentLine, buffer);
|
||||
|
||||
g_ErrorCount++;
|
||||
}
|
||||
|
||||
InitGlobalStates()
|
||||
{
|
||||
g_ErrorCount = 0;
|
||||
g_IgnoreLevel = 0;
|
||||
g_CurrentLine = 0;
|
||||
g_LoggedFileName = false;
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Admin File Reader Plugin
|
||||
* Reads the admin_groups.cfg file. Do not compile this directly.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#define GROUP_STATE_NONE 0
|
||||
#define GROUP_STATE_GROUPS 1
|
||||
#define GROUP_STATE_INGROUP 2
|
||||
#define GROUP_STATE_OVERRIDES 3
|
||||
#define GROUP_PASS_FIRST 1
|
||||
#define GROUP_PASS_SECOND 2
|
||||
|
||||
static Handle:g_hGroupParser = INVALID_HANDLE;
|
||||
static GroupId:g_CurGrp = INVALID_GROUP_ID;
|
||||
static g_GroupState = GROUP_STATE_NONE;
|
||||
static g_GroupPass = 0;
|
||||
static bool:g_NeedReparse = false;
|
||||
|
||||
public SMCResult:ReadGroups_NewSection(Handle:smc, const String:name[], bool:opt_quotes)
|
||||
{
|
||||
if (g_IgnoreLevel)
|
||||
{
|
||||
g_IgnoreLevel++;
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
if (g_GroupState == GROUP_STATE_NONE)
|
||||
{
|
||||
if (StrEqual(name, "Groups"))
|
||||
{
|
||||
g_GroupState = GROUP_STATE_GROUPS;
|
||||
} else {
|
||||
g_IgnoreLevel++;
|
||||
}
|
||||
} else if (g_GroupState == GROUP_STATE_GROUPS) {
|
||||
if ((g_CurGrp = CreateAdmGroup(name)) == INVALID_GROUP_ID)
|
||||
{
|
||||
g_CurGrp = FindAdmGroup(name);
|
||||
}
|
||||
g_GroupState = GROUP_STATE_INGROUP;
|
||||
} else if (g_GroupState == GROUP_STATE_INGROUP) {
|
||||
if (StrEqual(name, "Overrides"))
|
||||
{
|
||||
g_GroupState = GROUP_STATE_OVERRIDES;
|
||||
} else {
|
||||
g_IgnoreLevel++;
|
||||
}
|
||||
} else {
|
||||
g_IgnoreLevel++;
|
||||
}
|
||||
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
public SMCResult:ReadGroups_KeyValue(Handle:smc,
|
||||
const String:key[],
|
||||
const String:value[],
|
||||
bool:key_quotes,
|
||||
bool:value_quotes)
|
||||
{
|
||||
if (g_CurGrp == INVALID_GROUP_ID
|
||||
|| g_IgnoreLevel)
|
||||
{
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
new AdminFlag:flag;
|
||||
|
||||
if (g_GroupPass == GROUP_PASS_FIRST)
|
||||
{
|
||||
if (g_GroupState == GROUP_STATE_INGROUP)
|
||||
{
|
||||
if (StrEqual(key, "flags"))
|
||||
{
|
||||
new len = strlen(value);
|
||||
for (new i=0; i<len; i++)
|
||||
{
|
||||
if (!FindFlagByChar(value[i], flag))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
SetAdmGroupAddFlag(g_CurGrp, flag, true);
|
||||
}
|
||||
} else if (StrEqual(key, "immunity")) {
|
||||
g_NeedReparse = true;
|
||||
}
|
||||
} else if (g_GroupState == GROUP_STATE_OVERRIDES) {
|
||||
new OverrideRule:rule = Command_Deny;
|
||||
|
||||
if (StrEqual(value, "allow", false))
|
||||
{
|
||||
rule = Command_Allow;
|
||||
}
|
||||
|
||||
if (key[0] == '@')
|
||||
{
|
||||
AddAdmGroupCmdOverride(g_CurGrp, key[1], Override_CommandGroup, rule);
|
||||
} else {
|
||||
AddAdmGroupCmdOverride(g_CurGrp, key, Override_Command, rule);
|
||||
}
|
||||
}
|
||||
} else if (g_GroupPass == GROUP_PASS_SECOND
|
||||
&& g_GroupState == GROUP_STATE_INGROUP) {
|
||||
/* Check for immunity again, core should handle double inserts */
|
||||
if (StrEqual(key, "immunity"))
|
||||
{
|
||||
/* If it's a value we know about, use it */
|
||||
if (StrEqual(value, "*"))
|
||||
{
|
||||
SetAdmGroupImmunityLevel(g_CurGrp, 2);
|
||||
} else if (StrEqual(value, "$")) {
|
||||
SetAdmGroupImmunityLevel(g_CurGrp, 1);
|
||||
} else {
|
||||
new level;
|
||||
if (StringToIntEx(value, level))
|
||||
{
|
||||
SetAdmGroupImmunityLevel(g_CurGrp, level);
|
||||
} else {
|
||||
new GroupId:id;
|
||||
if (value[0] == '@')
|
||||
{
|
||||
id = FindAdmGroup(value[1]);
|
||||
} else {
|
||||
id = FindAdmGroup(value);
|
||||
}
|
||||
if (id != INVALID_GROUP_ID)
|
||||
{
|
||||
SetAdmGroupImmuneFrom(g_CurGrp, id);
|
||||
} else {
|
||||
ParseError("Unable to find group: \"%s\"", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
public SMCResult:ReadGroups_EndSection(Handle:smc)
|
||||
{
|
||||
/* If we're ignoring, skip out */
|
||||
if (g_IgnoreLevel)
|
||||
{
|
||||
g_IgnoreLevel--;
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
if (g_GroupState == GROUP_STATE_OVERRIDES)
|
||||
{
|
||||
g_GroupState = GROUP_STATE_INGROUP;
|
||||
} else if (g_GroupState == GROUP_STATE_INGROUP) {
|
||||
g_GroupState = GROUP_STATE_GROUPS;
|
||||
g_CurGrp = INVALID_GROUP_ID;
|
||||
} else if (g_GroupState == GROUP_STATE_GROUPS) {
|
||||
g_GroupState = GROUP_STATE_NONE;
|
||||
}
|
||||
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
public SMCResult:ReadGroups_CurrentLine(Handle:smc, const String:line[], lineno)
|
||||
{
|
||||
g_CurrentLine = lineno;
|
||||
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
static InitializeGroupParser()
|
||||
{
|
||||
if (g_hGroupParser == INVALID_HANDLE)
|
||||
{
|
||||
g_hGroupParser = SMC_CreateParser();
|
||||
SMC_SetReaders(g_hGroupParser,
|
||||
ReadGroups_NewSection,
|
||||
ReadGroups_KeyValue,
|
||||
ReadGroups_EndSection);
|
||||
SMC_SetRawLine(g_hGroupParser, ReadGroups_CurrentLine);
|
||||
}
|
||||
}
|
||||
|
||||
static InternalReadGroups(const String:path[], pass)
|
||||
{
|
||||
/* Set states */
|
||||
InitGlobalStates();
|
||||
g_GroupState = GROUP_STATE_NONE;
|
||||
g_CurGrp = INVALID_GROUP_ID;
|
||||
g_GroupPass = pass;
|
||||
g_NeedReparse = false;
|
||||
|
||||
new SMCError:err = SMC_ParseFile(g_hGroupParser, path);
|
||||
if (err != SMCError_Okay)
|
||||
{
|
||||
decl String:buffer[64];
|
||||
if (SMC_GetErrorString(err, buffer, sizeof(buffer)))
|
||||
{
|
||||
ParseError("%s", buffer);
|
||||
} else {
|
||||
ParseError("Fatal parse error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReadGroups()
|
||||
{
|
||||
InitializeGroupParser();
|
||||
|
||||
BuildPath(Path_SM, g_Filename, sizeof(g_Filename), "configs/admin_groups.cfg");
|
||||
|
||||
InternalReadGroups(g_Filename, GROUP_PASS_FIRST);
|
||||
if (g_NeedReparse)
|
||||
{
|
||||
InternalReadGroups(g_Filename, GROUP_PASS_SECOND);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Admin File Reader Plugin
|
||||
* Reads overrides from the admin_levels.cfg file. Do not compile
|
||||
* this directly.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#define OVERRIDE_STATE_NONE 0
|
||||
#define OVERRIDE_STATE_LEVELS 1
|
||||
#define OVERRIDE_STATE_OVERRIDES 2
|
||||
|
||||
static Handle:g_hOldOverrideParser = INVALID_HANDLE;
|
||||
static Handle:g_hNewOverrideParser = INVALID_HANDLE;
|
||||
static g_OverrideState = OVERRIDE_STATE_NONE;
|
||||
|
||||
public SMCResult:ReadOldOverrides_NewSection(Handle:smc, const String:name[], bool:opt_quotes)
|
||||
{
|
||||
if (g_IgnoreLevel)
|
||||
{
|
||||
g_IgnoreLevel++;
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
if (g_OverrideState == OVERRIDE_STATE_NONE)
|
||||
{
|
||||
if (StrEqual(name, "Levels"))
|
||||
{
|
||||
g_OverrideState = OVERRIDE_STATE_LEVELS;
|
||||
} else {
|
||||
g_IgnoreLevel++;
|
||||
}
|
||||
} else if (g_OverrideState == OVERRIDE_STATE_LEVELS) {
|
||||
if (StrEqual(name, "Overrides"))
|
||||
{
|
||||
g_OverrideState = OVERRIDE_STATE_OVERRIDES;
|
||||
} else {
|
||||
g_IgnoreLevel++;
|
||||
}
|
||||
} else {
|
||||
g_IgnoreLevel++;
|
||||
}
|
||||
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
public SMCResult:ReadNewOverrides_NewSection(Handle:smc, const String:name[], bool:opt_quotes)
|
||||
{
|
||||
if (g_IgnoreLevel)
|
||||
{
|
||||
g_IgnoreLevel++;
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
if (g_OverrideState == OVERRIDE_STATE_NONE)
|
||||
{
|
||||
if (StrEqual(name, "Overrides"))
|
||||
{
|
||||
g_OverrideState = OVERRIDE_STATE_OVERRIDES;
|
||||
} else {
|
||||
g_IgnoreLevel++;
|
||||
}
|
||||
} else {
|
||||
g_IgnoreLevel++;
|
||||
}
|
||||
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
public SMCResult:ReadOverrides_KeyValue(Handle:smc,
|
||||
const String:key[],
|
||||
const String:value[],
|
||||
bool:key_quotes,
|
||||
bool:value_quotes)
|
||||
{
|
||||
if (g_OverrideState != OVERRIDE_STATE_OVERRIDES
|
||||
|| g_IgnoreLevel)
|
||||
{
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
new flags = ReadFlagString(value);
|
||||
|
||||
if (key[0] == '@')
|
||||
{
|
||||
AddCommandOverride(key[1], Override_CommandGroup, flags);
|
||||
} else {
|
||||
AddCommandOverride(key, Override_Command, flags);
|
||||
}
|
||||
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
public SMCResult:ReadOldOverrides_EndSection(Handle:smc)
|
||||
{
|
||||
/* If we're ignoring, skip out */
|
||||
if (g_IgnoreLevel)
|
||||
{
|
||||
g_IgnoreLevel--;
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
if (g_OverrideState == OVERRIDE_STATE_LEVELS)
|
||||
{
|
||||
g_OverrideState = OVERRIDE_STATE_NONE;
|
||||
} else if (g_OverrideState == OVERRIDE_STATE_OVERRIDES) {
|
||||
/* We're totally done parsing */
|
||||
g_OverrideState = OVERRIDE_STATE_LEVELS;
|
||||
return SMCParse_Halt;
|
||||
}
|
||||
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
public SMCResult:ReadNewOverrides_EndSection(Handle:smc)
|
||||
{
|
||||
/* If we're ignoring, skip out */
|
||||
if (g_IgnoreLevel)
|
||||
{
|
||||
g_IgnoreLevel--;
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
if (g_OverrideState == OVERRIDE_STATE_OVERRIDES)
|
||||
{
|
||||
g_OverrideState = OVERRIDE_STATE_NONE;
|
||||
}
|
||||
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
public SMCResult:ReadOverrides_CurrentLine(Handle:smc, const String:line[], lineno)
|
||||
{
|
||||
g_CurrentLine = lineno;
|
||||
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
static InitializeOverrideParsers()
|
||||
{
|
||||
if (g_hOldOverrideParser == INVALID_HANDLE)
|
||||
{
|
||||
g_hOldOverrideParser = SMC_CreateParser();
|
||||
SMC_SetReaders(g_hOldOverrideParser,
|
||||
ReadOldOverrides_NewSection,
|
||||
ReadOverrides_KeyValue,
|
||||
ReadOldOverrides_EndSection);
|
||||
SMC_SetRawLine(g_hOldOverrideParser, ReadOverrides_CurrentLine);
|
||||
}
|
||||
if (g_hNewOverrideParser == INVALID_HANDLE)
|
||||
{
|
||||
g_hNewOverrideParser = SMC_CreateParser();
|
||||
SMC_SetReaders(g_hNewOverrideParser,
|
||||
ReadNewOverrides_NewSection,
|
||||
ReadOverrides_KeyValue,
|
||||
ReadNewOverrides_EndSection);
|
||||
SMC_SetRawLine(g_hNewOverrideParser, ReadOverrides_CurrentLine);
|
||||
}
|
||||
}
|
||||
|
||||
InternalReadOverrides(Handle:parser, const String:file[])
|
||||
{
|
||||
BuildPath(Path_SM, g_Filename, sizeof(g_Filename), file);
|
||||
|
||||
/* Set states */
|
||||
InitGlobalStates();
|
||||
g_OverrideState = OVERRIDE_STATE_NONE;
|
||||
|
||||
new SMCError:err = SMC_ParseFile(parser, g_Filename);
|
||||
if (err != SMCError_Okay)
|
||||
{
|
||||
decl String:buffer[64];
|
||||
if (SMC_GetErrorString(err, buffer, sizeof(buffer)))
|
||||
{
|
||||
ParseError("%s", buffer);
|
||||
} else {
|
||||
ParseError("Fatal parse error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReadOverrides()
|
||||
{
|
||||
InitializeOverrideParsers();
|
||||
InternalReadOverrides(g_hOldOverrideParser, "configs/admin_levels.cfg");
|
||||
InternalReadOverrides(g_hNewOverrideParser, "configs/admin_overrides.cfg");
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Admin File Reader Plugin
|
||||
* Reads the admins.cfg file. Do not compile this directly.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
public ReadSimpleUsers()
|
||||
{
|
||||
BuildPath(Path_SM, g_Filename, sizeof(g_Filename), "configs/admins_simple.ini");
|
||||
|
||||
new Handle:file = OpenFile(g_Filename, "rt");
|
||||
if (file == INVALID_HANDLE)
|
||||
{
|
||||
ParseError("Could not open file!");
|
||||
return;
|
||||
}
|
||||
|
||||
while (!IsEndOfFile(file))
|
||||
{
|
||||
decl String:line[255];
|
||||
if (!ReadFileLine(file, line, sizeof(line)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* Trim comments */
|
||||
new len = strlen(line);
|
||||
new bool:ignoring = false;
|
||||
for (new i=0; i<len; i++)
|
||||
{
|
||||
if (ignoring)
|
||||
{
|
||||
if (line[i] == '"')
|
||||
{
|
||||
ignoring = false;
|
||||
}
|
||||
} else {
|
||||
if (line[i] == '"')
|
||||
{
|
||||
ignoring = true;
|
||||
} else if (line[i] == ';') {
|
||||
line[i] = '\0';
|
||||
break;
|
||||
} else if (line[i] == '/'
|
||||
&& i != len - 1
|
||||
&& line[i+1] == '/')
|
||||
{
|
||||
line[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TrimString(line);
|
||||
|
||||
if ((line[0] == '/' && line[1] == '/')
|
||||
|| (line[0] == ';' || line[0] == '\0'))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ReadAdminLine(line);
|
||||
}
|
||||
|
||||
CloseHandle(file);
|
||||
}
|
||||
|
||||
|
||||
|
||||
DecodeAuthMethod(const String:auth[], String:method[32], &offset)
|
||||
{
|
||||
if (StrContains(auth, "STEAM_") == 0)
|
||||
{
|
||||
strcopy(method, sizeof(method), AUTHMETHOD_STEAM);
|
||||
offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auth[0] == '!')
|
||||
{
|
||||
strcopy(method, sizeof(method), AUTHMETHOD_IP);
|
||||
offset = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcopy(method, sizeof(method), AUTHMETHOD_NAME);
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReadAdminLine(const String:line[])
|
||||
{
|
||||
new bool:is_bound;
|
||||
new AdminId:admin;
|
||||
new String:auth[64];
|
||||
decl String:auth_method[32];
|
||||
new idx, cur_idx, auth_offset;
|
||||
|
||||
if ((cur_idx = BreakString(line, auth, sizeof(auth))) == -1)
|
||||
{
|
||||
/* This line is bad... we need at least two parameters */
|
||||
return;
|
||||
}
|
||||
|
||||
idx = cur_idx;
|
||||
|
||||
/* Check if we can bind beforehand */
|
||||
DecodeAuthMethod(auth, auth_method, auth_offset);
|
||||
if ((admin = FindAdminByIdentity(auth_method, auth[auth_offset])) == INVALID_ADMIN_ID)
|
||||
{
|
||||
/* There is no binding, create the admin */
|
||||
admin = CreateAdmin();
|
||||
}
|
||||
else
|
||||
{
|
||||
is_bound = true;
|
||||
}
|
||||
|
||||
/* Read flags */
|
||||
new String:flags[64];
|
||||
cur_idx = BreakString(line[idx], flags, sizeof(flags));
|
||||
idx += cur_idx;
|
||||
|
||||
/* Read immunity level, if any */
|
||||
new level, flag_idx;
|
||||
|
||||
if ((flag_idx = StringToIntEx(flags, level)) > 0)
|
||||
{
|
||||
SetAdminImmunityLevel(admin, level);
|
||||
if (flags[flag_idx] == ':')
|
||||
{
|
||||
flag_idx++;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags[flag_idx] == '@')
|
||||
{
|
||||
new GroupId:gid = FindAdmGroup(flags[flag_idx + 1]);
|
||||
if (gid == INVALID_GROUP_ID)
|
||||
{
|
||||
ParseError("Invalid group detected: %s", flags[flag_idx + 1]);
|
||||
return;
|
||||
}
|
||||
AdminInheritGroup(admin, gid);
|
||||
}
|
||||
else
|
||||
{
|
||||
new len = strlen(flags[flag_idx]);
|
||||
new bool:is_default = false;
|
||||
for (new i=0; i<len; i++)
|
||||
{
|
||||
if (!level && flags[flag_idx + i] == '$')
|
||||
{
|
||||
SetAdminImmunityLevel(admin, 1);
|
||||
} else {
|
||||
new AdminFlag:flag;
|
||||
|
||||
if (!FindFlagByChar(flags[flag_idx + i], flag))
|
||||
{
|
||||
ParseError("Invalid flag detected: %c", flags[flag_idx + i]);
|
||||
continue;
|
||||
}
|
||||
SetAdminFlag(admin, flag, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_default)
|
||||
{
|
||||
new GroupId:gid = FindAdmGroup("Default");
|
||||
if (gid != INVALID_GROUP_ID)
|
||||
{
|
||||
AdminInheritGroup(admin, gid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Lastly, is there a password? */
|
||||
if (cur_idx != -1)
|
||||
{
|
||||
decl String:password[64];
|
||||
BreakString(line[idx], password, sizeof(password));
|
||||
SetAdminPassword(admin, password);
|
||||
}
|
||||
|
||||
/* Now, bind the identity to something */
|
||||
if (!is_bound)
|
||||
{
|
||||
if (!BindAdminIdentity(admin, auth_method, auth[auth_offset]))
|
||||
{
|
||||
/* We should never reach here */
|
||||
ParseError("Failed to bind identity %s (method %s)", auth[auth_offset], auth_method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Admin File Reader Plugin
|
||||
* Reads the admins.cfg file. Do not compile this directly.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#define USER_STATE_NONE 0
|
||||
#define USER_STATE_ADMINS 1
|
||||
#define USER_STATE_INADMIN 2
|
||||
|
||||
static Handle:g_hUserParser = INVALID_HANDLE;
|
||||
static g_UserState = USER_STATE_NONE;
|
||||
static String:g_CurAuth[64];
|
||||
static String:g_CurIdent[64];
|
||||
static String:g_CurName[64];
|
||||
static String:g_CurPass[64];
|
||||
static Handle:g_GroupArray;
|
||||
static g_CurFlags;
|
||||
static g_CurImmunity;
|
||||
|
||||
public SMCResult:ReadUsers_NewSection(Handle:smc, const String:name[], bool:opt_quotes)
|
||||
{
|
||||
if (g_IgnoreLevel)
|
||||
{
|
||||
g_IgnoreLevel++;
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
if (g_UserState == USER_STATE_NONE)
|
||||
{
|
||||
if (StrEqual(name, "Admins"))
|
||||
{
|
||||
g_UserState = USER_STATE_ADMINS;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_IgnoreLevel++;
|
||||
}
|
||||
}
|
||||
else if (g_UserState == USER_STATE_ADMINS)
|
||||
{
|
||||
g_UserState = USER_STATE_INADMIN;
|
||||
strcopy(g_CurName, sizeof(g_CurName), name);
|
||||
g_CurAuth[0] = '\0';
|
||||
g_CurIdent[0] = '\0';
|
||||
g_CurPass[0] = '\0';
|
||||
ClearArray(g_GroupArray);
|
||||
g_CurFlags = 0;
|
||||
g_CurImmunity = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_IgnoreLevel++;
|
||||
}
|
||||
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
public SMCResult:ReadUsers_KeyValue(Handle:smc,
|
||||
const String:key[],
|
||||
const String:value[],
|
||||
bool:key_quotes,
|
||||
bool:value_quotes)
|
||||
{
|
||||
if (g_UserState != USER_STATE_INADMIN || g_IgnoreLevel)
|
||||
{
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
if (StrEqual(key, "auth"))
|
||||
{
|
||||
strcopy(g_CurAuth, sizeof(g_CurAuth), value);
|
||||
}
|
||||
else if (StrEqual(key, "identity"))
|
||||
{
|
||||
strcopy(g_CurIdent, sizeof(g_CurIdent), value);
|
||||
}
|
||||
else if (StrEqual(key, "password"))
|
||||
{
|
||||
strcopy(g_CurPass, sizeof(g_CurPass), value);
|
||||
}
|
||||
else if (StrEqual(key, "group"))
|
||||
{
|
||||
new GroupId:id = FindAdmGroup(value);
|
||||
if (id == INVALID_GROUP_ID)
|
||||
{
|
||||
ParseError("Unknown group \"%s\"", value);
|
||||
}
|
||||
|
||||
PushArrayCell(g_GroupArray, id);
|
||||
}
|
||||
else if (StrEqual(key, "flags"))
|
||||
{
|
||||
new len = strlen(value);
|
||||
new AdminFlag:flag;
|
||||
|
||||
for (new i = 0; i < len; i++)
|
||||
{
|
||||
if (!FindFlagByChar(value[i], flag))
|
||||
{
|
||||
ParseError("Invalid flag detected: %c", value[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_CurFlags |= FlagToBit(flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (StrEqual(key, "immunity"))
|
||||
{
|
||||
g_CurImmunity = StringToInt(value);
|
||||
}
|
||||
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
public SMCResult:ReadUsers_EndSection(Handle:smc)
|
||||
{
|
||||
if (g_IgnoreLevel)
|
||||
{
|
||||
g_IgnoreLevel--;
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
if (g_UserState == USER_STATE_INADMIN)
|
||||
{
|
||||
/* Dump this user to memory */
|
||||
if (g_CurIdent[0] != '\0' && g_CurAuth[0] != '\0')
|
||||
{
|
||||
decl AdminFlag:flags[26];
|
||||
new AdminId:id, i, num_groups, num_flags;
|
||||
|
||||
if ((id = FindAdminByIdentity(g_CurAuth, g_CurIdent)) == INVALID_ADMIN_ID)
|
||||
{
|
||||
id = CreateAdmin(g_CurName);
|
||||
if (!BindAdminIdentity(id, g_CurAuth, g_CurIdent))
|
||||
{
|
||||
ParseError("Failed to bind auth \"%s\" to identity \"%s\"", g_CurAuth, g_CurIdent);
|
||||
}
|
||||
}
|
||||
|
||||
num_groups = GetArraySize(g_GroupArray);
|
||||
for (i = 0; i < num_groups; i++)
|
||||
{
|
||||
AdminInheritGroup(id, GetArrayCell(g_GroupArray, i));
|
||||
}
|
||||
|
||||
SetAdminPassword(id, g_CurPass);
|
||||
if (GetAdminImmunityLevel(id) < g_CurImmunity)
|
||||
{
|
||||
SetAdminImmunityLevel(id, g_CurImmunity);
|
||||
}
|
||||
|
||||
num_flags = FlagBitsToArray(g_CurFlags, flags, sizeof(flags));
|
||||
for (i = 0; i < num_flags; i++)
|
||||
{
|
||||
SetAdminFlag(id, flags[i], true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ParseError("Failed to create admin: did you forget either the auth or identity properties?");
|
||||
}
|
||||
|
||||
g_UserState = USER_STATE_ADMINS;
|
||||
}
|
||||
else if (g_UserState == USER_STATE_ADMINS)
|
||||
{
|
||||
g_UserState = USER_STATE_NONE;
|
||||
}
|
||||
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
public SMCResult:ReadUsers_CurrentLine(Handle:smc, const String:line[], lineno)
|
||||
{
|
||||
g_CurrentLine = lineno;
|
||||
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
static InitializeUserParser()
|
||||
{
|
||||
if (g_hUserParser == INVALID_HANDLE)
|
||||
{
|
||||
g_hUserParser = SMC_CreateParser();
|
||||
SMC_SetReaders(g_hUserParser,
|
||||
ReadUsers_NewSection,
|
||||
ReadUsers_KeyValue,
|
||||
ReadUsers_EndSection);
|
||||
SMC_SetRawLine(g_hUserParser, ReadUsers_CurrentLine);
|
||||
|
||||
g_GroupArray = CreateArray();
|
||||
}
|
||||
}
|
||||
|
||||
ReadUsers()
|
||||
{
|
||||
InitializeUserParser();
|
||||
|
||||
BuildPath(Path_SM, g_Filename, sizeof(g_Filename), "configs/admins.cfg");
|
||||
|
||||
/* Set states */
|
||||
InitGlobalStates();
|
||||
g_UserState = USER_STATE_NONE;
|
||||
|
||||
new SMCError:err = SMC_ParseFile(g_hUserParser, g_Filename);
|
||||
if (err != SMCError_Okay)
|
||||
{
|
||||
decl String:buffer[64];
|
||||
if (SMC_GetErrorString(err, buffer, sizeof(buffer)))
|
||||
{
|
||||
ParseError("%s", buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
ParseError("Fatal parse error");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,386 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod SQL Admins Plugin (Prefetch)
|
||||
* Prefetches admins from an SQL database without threading.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
/* We like semicolons */
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "SQL Admins (Prefetch)",
|
||||
author = "AlliedModders LLC",
|
||||
description = "Reads all admins from SQL",
|
||||
version = SOURCEMOD_VERSION,
|
||||
url = "http://www.sourcemod.net/"
|
||||
};
|
||||
|
||||
public OnRebuildAdminCache(AdminCachePart:part)
|
||||
{
|
||||
/* First try to get a database connection */
|
||||
decl String:error[255];
|
||||
new Handle:db;
|
||||
|
||||
if (SQL_CheckConfig("admins"))
|
||||
{
|
||||
db = SQL_Connect("admins", true, error, sizeof(error));
|
||||
} else {
|
||||
db = SQL_Connect("default", true, error, sizeof(error));
|
||||
}
|
||||
|
||||
if (db == INVALID_HANDLE)
|
||||
{
|
||||
LogError("Could not connect to database \"default\": %s", error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (part == AdminCache_Overrides)
|
||||
{
|
||||
FetchOverrides(db);
|
||||
} else if (part == AdminCache_Groups) {
|
||||
FetchGroups(db);
|
||||
} else if (part == AdminCache_Admins) {
|
||||
FetchUsers(db);
|
||||
}
|
||||
|
||||
CloseHandle(db);
|
||||
}
|
||||
|
||||
FetchUserGroups(Handle:hQuery, AdminId:adm, id)
|
||||
{
|
||||
SQL_BindParamInt(hQuery, 0, id);
|
||||
if (!SQL_Execute(hQuery))
|
||||
{
|
||||
decl String:error[255];
|
||||
SQL_GetError(hQuery, error, sizeof(error));
|
||||
LogError("FetchUserGroups() statement execute failed: %s", error);
|
||||
return;
|
||||
}
|
||||
|
||||
decl String:name[80];
|
||||
new GroupId:gid;
|
||||
while (SQL_FetchRow(hQuery))
|
||||
{
|
||||
SQL_FetchString(hQuery, 0, name, sizeof(name));
|
||||
|
||||
if ((gid = FindAdmGroup(name)) == INVALID_GROUP_ID)
|
||||
{
|
||||
/* Group wasn't found, don't bother with it. */
|
||||
continue;
|
||||
}
|
||||
|
||||
#if defined _DEBUG
|
||||
PrintToServer("Found admin group (%d, %d, %d)", id, gid, adm);
|
||||
#endif
|
||||
|
||||
AdminInheritGroup(adm, gid);
|
||||
}
|
||||
}
|
||||
|
||||
FetchUsers(Handle:db)
|
||||
{
|
||||
decl String:query[255], String:error[255];
|
||||
new Handle:hQuery, Handle:hGroupQuery;
|
||||
|
||||
Format(query, sizeof(query), "SELECT id, authtype, identity, password, flags, name, immunity FROM sm_admins");
|
||||
if ((hQuery = SQL_Query(db, query)) == INVALID_HANDLE)
|
||||
{
|
||||
SQL_GetError(db, error, sizeof(error));
|
||||
LogError("FetchUsers() query failed: %s", query);
|
||||
LogError("Query error: %s", error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If this fails it's non-fatal */
|
||||
Format(query,
|
||||
sizeof(query),
|
||||
"SELECT g.name FROM sm_admins_groups ag JOIN sm_groups g ON ag.group_id = g.id WHERE ag.admin_id = ? ORDER BY inherit_order ASC");
|
||||
if ((hGroupQuery = SQL_PrepareQuery(db, query, error, sizeof(error))) == INVALID_HANDLE)
|
||||
{
|
||||
LogError("FetchUsers() group query preparation failed: %s", query);
|
||||
LogError("Query error: %s", error);
|
||||
}
|
||||
|
||||
decl String:authtype[16];
|
||||
decl String:identity[80];
|
||||
decl String:password[80];
|
||||
decl String:flags[32];
|
||||
decl String:name[80];
|
||||
new immunity;
|
||||
new AdminId:adm, id;
|
||||
|
||||
while (SQL_FetchRow(hQuery))
|
||||
{
|
||||
id = SQL_FetchInt(hQuery, 0);
|
||||
SQL_FetchString(hQuery, 1, authtype, sizeof(authtype));
|
||||
SQL_FetchString(hQuery, 2, identity, sizeof(identity));
|
||||
SQL_FetchString(hQuery, 3, password, sizeof(password));
|
||||
SQL_FetchString(hQuery, 4, flags, sizeof(flags));
|
||||
SQL_FetchString(hQuery, 5, name, sizeof(name));
|
||||
immunity = SQL_FetchInt(hQuery, 6);
|
||||
|
||||
/* Use a pre-existing admin if we can */
|
||||
if ((adm = FindAdminByIdentity(authtype, identity)) == INVALID_ADMIN_ID)
|
||||
{
|
||||
adm = CreateAdmin(name);
|
||||
if (!BindAdminIdentity(adm, authtype, identity))
|
||||
{
|
||||
LogError("Could not bind prefetched SQL admin (authtype \"%s\") (identity \"%s\")", authtype, identity);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined _DEBUG
|
||||
PrintToServer("Found SQL admin (%d,%s,%s,%s,%s,%s,%d):%d", id, authtype, identity, password, flags, name, immunity, adm);
|
||||
#endif
|
||||
|
||||
/* See if this admin wants a password */
|
||||
if (password[0] != '\0')
|
||||
{
|
||||
SetAdminPassword(adm, password);
|
||||
}
|
||||
|
||||
/* Apply each flag */
|
||||
new len = strlen(flags);
|
||||
new AdminFlag:flag;
|
||||
for (new i=0; i<len; i++)
|
||||
{
|
||||
if (!FindFlagByChar(flags[i], flag))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
SetAdminFlag(adm, flag, true);
|
||||
}
|
||||
|
||||
SetAdminImmunityLevel(adm, immunity);
|
||||
|
||||
/* Look up groups */
|
||||
if (hGroupQuery != INVALID_HANDLE)
|
||||
{
|
||||
FetchUserGroups(hGroupQuery, adm, id);
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(hGroupQuery);
|
||||
CloseHandle(hQuery);
|
||||
}
|
||||
|
||||
FetchGroups(Handle:db)
|
||||
{
|
||||
decl String:query[255];
|
||||
new Handle:hQuery;
|
||||
|
||||
Format(query, sizeof(query), "SELECT flags, name, immunity_level FROM sm_groups");
|
||||
|
||||
if ((hQuery = SQL_Query(db, query)) == INVALID_HANDLE)
|
||||
{
|
||||
decl String:error[255];
|
||||
SQL_GetError(db, error, sizeof(error));
|
||||
LogError("FetchGroups() query failed: %s", query);
|
||||
LogError("Query error: %s", error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now start fetching groups */
|
||||
decl String:flags[32];
|
||||
decl String:name[128];
|
||||
new immunity;
|
||||
while (SQL_FetchRow(hQuery))
|
||||
{
|
||||
SQL_FetchString(hQuery, 0, flags, sizeof(flags));
|
||||
SQL_FetchString(hQuery, 1, name, sizeof(name));
|
||||
immunity = SQL_FetchInt(hQuery, 2);
|
||||
|
||||
#if defined _DEBUG
|
||||
PrintToServer("Adding group (%d, %s, %s)", immunity, flags, name);
|
||||
#endif
|
||||
|
||||
/* Find or create the group */
|
||||
new GroupId:gid;
|
||||
if ((gid = FindAdmGroup(name)) == INVALID_GROUP_ID)
|
||||
{
|
||||
gid = CreateAdmGroup(name);
|
||||
}
|
||||
|
||||
/* Add flags from the database to the group */
|
||||
new num_flag_chars = strlen(flags);
|
||||
for (new i=0; i<num_flag_chars; i++)
|
||||
{
|
||||
decl AdminFlag:flag;
|
||||
if (!FindFlagByChar(flags[i], flag))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
SetAdmGroupAddFlag(gid, flag, true);
|
||||
}
|
||||
|
||||
/* Set the immunity level this group has */
|
||||
SetAdmGroupImmunityLevel(gid, immunity);
|
||||
}
|
||||
|
||||
CloseHandle(hQuery);
|
||||
|
||||
/**
|
||||
* Get immunity in a big lump. This is a nasty query but it gets the job done.
|
||||
*/
|
||||
new len = 0;
|
||||
len += Format(query[len], sizeof(query)-len, "SELECT g1.name, g2.name FROM sm_group_immunity gi");
|
||||
len += Format(query[len], sizeof(query)-len, " LEFT JOIN sm_groups g1 ON g1.id = gi.group_id ");
|
||||
len += Format(query[len], sizeof(query)-len, " LEFT JOIN sm_groups g2 ON g2.id = gi.other_id");
|
||||
|
||||
if ((hQuery = SQL_Query(db, query)) == INVALID_HANDLE)
|
||||
{
|
||||
decl String:error[255];
|
||||
SQL_GetError(db, error, sizeof(error));
|
||||
LogError("FetchGroups() query failed: %s", query);
|
||||
LogError("Query error: %s", error);
|
||||
return;
|
||||
}
|
||||
|
||||
while (SQL_FetchRow(hQuery))
|
||||
{
|
||||
decl String:group1[80];
|
||||
decl String:group2[80];
|
||||
new GroupId:gid1, GroupId:gid2;
|
||||
|
||||
SQL_FetchString(hQuery, 0, group1, sizeof(group1));
|
||||
SQL_FetchString(hQuery, 1, group2, sizeof(group2));
|
||||
|
||||
if (((gid1 = FindAdmGroup(group1)) == INVALID_GROUP_ID)
|
||||
|| (gid2 = FindAdmGroup(group2)) == INVALID_GROUP_ID)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
SetAdmGroupImmuneFrom(gid1, gid2);
|
||||
#if defined _DEBUG
|
||||
PrintToServer("SetAdmGroupImmuneFrom(%d, %d)", gid1, gid2);
|
||||
#endif
|
||||
}
|
||||
|
||||
CloseHandle(hQuery);
|
||||
|
||||
/**
|
||||
* Fetch overrides in a lump query.
|
||||
*/
|
||||
Format(query, sizeof(query), "SELECT g.name, go.type, go.name, go.access FROM sm_group_overrides go LEFT JOIN sm_groups g ON go.group_id = g.id");
|
||||
|
||||
if ((hQuery = SQL_Query(db, query)) == INVALID_HANDLE)
|
||||
{
|
||||
decl String:error[255];
|
||||
SQL_GetError(db, error, sizeof(error));
|
||||
LogError("FetchGroups() query failed: %s", query);
|
||||
LogError("Query error: %s", error);
|
||||
return;
|
||||
}
|
||||
|
||||
decl String:type[16];
|
||||
decl String:cmd[64];
|
||||
decl String:access[16];
|
||||
while (SQL_FetchRow(hQuery))
|
||||
{
|
||||
SQL_FetchString(hQuery, 0, name, sizeof(name));
|
||||
SQL_FetchString(hQuery, 1, type, sizeof(type));
|
||||
SQL_FetchString(hQuery, 2, cmd, sizeof(cmd));
|
||||
SQL_FetchString(hQuery, 3, access, sizeof(access));
|
||||
|
||||
new GroupId:gid;
|
||||
if ((gid = FindAdmGroup(name)) == INVALID_GROUP_ID)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
new OverrideType:o_type = Override_Command;
|
||||
if (StrEqual(type, "group"))
|
||||
{
|
||||
o_type = Override_CommandGroup;
|
||||
}
|
||||
|
||||
new OverrideRule:o_rule = Command_Deny;
|
||||
if (StrEqual(access, "allow"))
|
||||
{
|
||||
o_rule = Command_Allow;
|
||||
}
|
||||
|
||||
#if defined _DEBUG
|
||||
PrintToServer("AddAdmGroupCmdOverride(%d, %s, %d, %d)", gid, cmd, o_type, o_rule);
|
||||
#endif
|
||||
|
||||
AddAdmGroupCmdOverride(gid, cmd, o_type, o_rule);
|
||||
}
|
||||
|
||||
CloseHandle(hQuery);
|
||||
}
|
||||
|
||||
FetchOverrides(Handle:db)
|
||||
{
|
||||
decl String:query[255];
|
||||
new Handle:hQuery;
|
||||
|
||||
Format(query, sizeof(query), "SELECT type, name, flags FROM sm_overrides");
|
||||
|
||||
if ((hQuery = SQL_Query(db, query)) == INVALID_HANDLE)
|
||||
{
|
||||
decl String:error[255];
|
||||
SQL_GetError(db, error, sizeof(error));
|
||||
LogError("FetchOverrides() query failed: %s", query);
|
||||
LogError("Query error: %s", error);
|
||||
return;
|
||||
}
|
||||
|
||||
decl String:type[64];
|
||||
decl String:name[64];
|
||||
decl String:flags[32];
|
||||
new flag_bits;
|
||||
while (SQL_FetchRow(hQuery))
|
||||
{
|
||||
SQL_FetchString(hQuery, 0, type, sizeof(type));
|
||||
SQL_FetchString(hQuery, 1, name, sizeof(name));
|
||||
SQL_FetchString(hQuery, 2, flags, sizeof(flags));
|
||||
|
||||
#if defined _DEBUG
|
||||
PrintToServer("Adding override (%s, %s, %s)", type, name, flags);
|
||||
#endif
|
||||
|
||||
flag_bits = ReadFlagString(flags);
|
||||
if (StrEqual(type, "command"))
|
||||
{
|
||||
AddCommandOverride(name, Override_Command, flag_bits);
|
||||
} else if (StrEqual(type, "group")) {
|
||||
AddCommandOverride(name, Override_CommandGroup, flag_bits);
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(hQuery);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,855 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod SQL Admins Plugin (Threaded)
|
||||
* Fetches admins from an SQL database dynamically.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
/* We like semicolons */
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "SQL Admins (Threaded)",
|
||||
author = "AlliedModders LLC",
|
||||
description = "Reads admins from SQL dynamically",
|
||||
version = SOURCEMOD_VERSION,
|
||||
url = "http://www.sourcemod.net/"
|
||||
};
|
||||
|
||||
/**
|
||||
* Notes:
|
||||
*
|
||||
* 1) All queries in here are high priority. This is because the admin stuff
|
||||
* is very important. Do not take this to mean that in your script,
|
||||
* everything should be high priority.
|
||||
*
|
||||
* 2) All callbacks are locked with "sequence numbers." This is to make sure
|
||||
* that multiple calls to sm_reloadadmins and the like do not make us
|
||||
* store the results from two or more callbacks accidentally. Instead, we
|
||||
* check the sequence number in each callback with the current "allowed"
|
||||
* sequence number, and if it doesn't match, the callback is cancelled.
|
||||
*
|
||||
* 3) Sequence numbers for groups and overrides are not cleared unless there
|
||||
* was a 100% success in the fetch. This is so we can potentially implement
|
||||
* connection retries in the future.
|
||||
*
|
||||
* 4) Sequence numbers for the user cache are ignored except for being
|
||||
* non-zero, which means players in-game should be re-checked for admin
|
||||
* powers.
|
||||
*/
|
||||
|
||||
new Handle:hDatabase = INVALID_HANDLE; /** Database connection */
|
||||
new g_sequence = 0; /** Global unique sequence number */
|
||||
new ConnectLock = 0; /** Connect sequence number */
|
||||
new RebuildCachePart[3] = {0}; /** Cache part sequence numbers */
|
||||
new PlayerSeq[MAXPLAYERS+1]; /** Player-specific sequence numbers */
|
||||
new bool:PlayerAuth[MAXPLAYERS+1]; /** Whether a player has been "pre-authed" */
|
||||
|
||||
//#define _DEBUG
|
||||
|
||||
public OnMapEnd()
|
||||
{
|
||||
/**
|
||||
* Clean up on map end just so we can start a fresh connection when we need it later.
|
||||
*/
|
||||
if (hDatabase != INVALID_HANDLE)
|
||||
{
|
||||
CloseHandle(hDatabase);
|
||||
hDatabase = INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
public bool:OnClientConnect(client, String:rejectmsg[], maxlen)
|
||||
{
|
||||
PlayerSeq[client] = 0;
|
||||
PlayerAuth[client] = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public OnClientDisconnect(client)
|
||||
{
|
||||
PlayerSeq[client] = 0;
|
||||
PlayerAuth[client] = false;
|
||||
}
|
||||
|
||||
public OnDatabaseConnect(Handle:owner, Handle:hndl, const String:error[], any:data)
|
||||
{
|
||||
#if defined _DEBUG
|
||||
PrintToServer("OnDatabaseConnect(%x,%x,%d) ConnectLock=%d", owner, hndl, data, ConnectLock);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* If this happens to be an old connection request, ignore it.
|
||||
*/
|
||||
if (data != ConnectLock || hDatabase != INVALID_HANDLE)
|
||||
{
|
||||
if (hndl != INVALID_HANDLE)
|
||||
{
|
||||
CloseHandle(hndl);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ConnectLock = 0;
|
||||
hDatabase = hndl;
|
||||
|
||||
/**
|
||||
* See if the connection is valid. If not, don't un-mark the caches
|
||||
* as needing rebuilding, in case the next connection request works.
|
||||
*/
|
||||
if (hDatabase == INVALID_HANDLE)
|
||||
{
|
||||
LogError("Failed to connect to database: %s", error);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* See if we need to get any of the cache stuff now.
|
||||
*/
|
||||
new sequence;
|
||||
if ((sequence = RebuildCachePart[_:AdminCache_Overrides]) != 0)
|
||||
{
|
||||
FetchOverrides(hDatabase, sequence);
|
||||
}
|
||||
if ((sequence = RebuildCachePart[_:AdminCache_Groups]) != 0)
|
||||
{
|
||||
FetchGroups(hDatabase, sequence);
|
||||
}
|
||||
if ((sequence = RebuildCachePart[_:AdminCache_Admins]) != 0)
|
||||
{
|
||||
FetchUsersWeCan(hDatabase);
|
||||
}
|
||||
}
|
||||
|
||||
RequestDatabaseConnection()
|
||||
{
|
||||
ConnectLock = ++g_sequence;
|
||||
if (SQL_CheckConfig("admins"))
|
||||
{
|
||||
SQL_TConnect(OnDatabaseConnect, "admins", ConnectLock);
|
||||
} else {
|
||||
SQL_TConnect(OnDatabaseConnect, "default", ConnectLock);
|
||||
}
|
||||
}
|
||||
|
||||
public OnRebuildAdminCache(AdminCachePart:part)
|
||||
{
|
||||
/**
|
||||
* Mark this part of the cache as being rebuilt. This is used by the
|
||||
* callback system to determine whether the results should still be
|
||||
* used.
|
||||
*/
|
||||
new sequence = ++g_sequence;
|
||||
RebuildCachePart[_:part] = sequence;
|
||||
|
||||
/**
|
||||
* If we don't have a database connection, we can't do any lookups just yet.
|
||||
*/
|
||||
if (!hDatabase)
|
||||
{
|
||||
/**
|
||||
* Ask for a new connection if we need it.
|
||||
*/
|
||||
if (!ConnectLock)
|
||||
{
|
||||
RequestDatabaseConnection();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (part == AdminCache_Overrides)
|
||||
{
|
||||
FetchOverrides(hDatabase, sequence);
|
||||
} else if (part == AdminCache_Groups) {
|
||||
FetchGroups(hDatabase, sequence);
|
||||
} else if (part == AdminCache_Admins) {
|
||||
FetchUsersWeCan(hDatabase);
|
||||
}
|
||||
}
|
||||
|
||||
public Action:OnClientPreAdminCheck(client)
|
||||
{
|
||||
PlayerAuth[client] = true;
|
||||
|
||||
/**
|
||||
* Play nice with other plugins. If there's no database, don't delay the
|
||||
* connection process. Unfortunately, we can't attempt anything else and
|
||||
* we just have to hope either the database is waiting or someone will type
|
||||
* sm_reloadadmins.
|
||||
*/
|
||||
if (hDatabase == INVALID_HANDLE)
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Similarly, if the cache is in the process of being rebuilt, don't delay
|
||||
* the user's normal connection flow. The database will soon auth the user
|
||||
* normally.
|
||||
*/
|
||||
if (RebuildCachePart[_:AdminCache_Admins] != 0)
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* If someone has already assigned an admin ID (bad bad bad), don't
|
||||
* bother waiting.
|
||||
*/
|
||||
if (GetUserAdmin(client) != INVALID_ADMIN_ID)
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
FetchUser(hDatabase, client);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public OnReceiveUserGroups(Handle:owner, Handle:hndl, const String:error[], any:data)
|
||||
{
|
||||
new Handle:pk = Handle:data;
|
||||
ResetPack(pk);
|
||||
|
||||
new client = ReadPackCell(pk);
|
||||
new sequence = ReadPackCell(pk);
|
||||
|
||||
/**
|
||||
* Make sure it's the same client.
|
||||
*/
|
||||
if (PlayerSeq[client] != sequence)
|
||||
{
|
||||
CloseHandle(pk);
|
||||
return;
|
||||
}
|
||||
|
||||
new AdminId:adm = AdminId:ReadPackCell(pk);
|
||||
|
||||
/**
|
||||
* Someone could have sneakily changed the admin id while we waited.
|
||||
*/
|
||||
if (GetUserAdmin(client) != adm)
|
||||
{
|
||||
NotifyPostAdminCheck(client);
|
||||
CloseHandle(pk);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* See if we got results.
|
||||
*/
|
||||
if (hndl == INVALID_HANDLE)
|
||||
{
|
||||
decl String:query[255];
|
||||
ReadPackString(pk, query, sizeof(query));
|
||||
LogError("SQL error receiving user: %s", error);
|
||||
LogError("Query dump: %s", query);
|
||||
NotifyPostAdminCheck(client);
|
||||
CloseHandle(pk);
|
||||
return;
|
||||
}
|
||||
|
||||
decl String:name[80];
|
||||
new GroupId:gid;
|
||||
|
||||
while (SQL_FetchRow(hndl))
|
||||
{
|
||||
SQL_FetchString(hndl, 0, name, sizeof(name));
|
||||
|
||||
if ((gid = FindAdmGroup(name)) == INVALID_GROUP_ID)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
#if defined _DEBUG
|
||||
PrintToServer("Binding user group (%d, %d, %d, %s, %d)", client, sequence, adm, name, gid);
|
||||
#endif
|
||||
|
||||
AdminInheritGroup(adm, gid);
|
||||
}
|
||||
|
||||
/**
|
||||
* We're DONE! Omg.
|
||||
*/
|
||||
NotifyPostAdminCheck(client);
|
||||
CloseHandle(pk);
|
||||
}
|
||||
|
||||
public OnReceiveUser(Handle:owner, Handle:hndl, const String:error[], any:data)
|
||||
{
|
||||
new Handle:pk = Handle:data;
|
||||
ResetPack(pk);
|
||||
|
||||
new client = ReadPackCell(pk);
|
||||
|
||||
/**
|
||||
* Check if this is the latest result request.
|
||||
*/
|
||||
new sequence = ReadPackCell(pk);
|
||||
if (PlayerSeq[client] != sequence)
|
||||
{
|
||||
/* Discard everything, since we're out of sequence. */
|
||||
CloseHandle(pk);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* If we need to use the results, make sure they succeeded.
|
||||
*/
|
||||
if (hndl == INVALID_HANDLE)
|
||||
{
|
||||
decl String:query[255];
|
||||
ReadPackString(pk, query, sizeof(query));
|
||||
LogError("SQL error receiving user: %s", error);
|
||||
LogError("Query dump: %s", query);
|
||||
RunAdminCacheChecks(client);
|
||||
NotifyPostAdminCheck(client);
|
||||
CloseHandle(pk);
|
||||
return;
|
||||
}
|
||||
|
||||
new num_accounts = SQL_GetRowCount(hndl);
|
||||
if (num_accounts == 0)
|
||||
{
|
||||
RunAdminCacheChecks(client);
|
||||
NotifyPostAdminCheck(client);
|
||||
CloseHandle(pk);
|
||||
return;
|
||||
}
|
||||
|
||||
decl String:authtype[16];
|
||||
decl String:identity[80];
|
||||
decl String:password[80];
|
||||
decl String:flags[32];
|
||||
decl String:name[80];
|
||||
new AdminId:adm, id;
|
||||
new immunity;
|
||||
|
||||
/**
|
||||
* Cache user info -- [0] = db id, [1] = cache id, [2] = groups
|
||||
*/
|
||||
decl user_lookup[num_accounts][3];
|
||||
new total_users = 0;
|
||||
|
||||
while (SQL_FetchRow(hndl))
|
||||
{
|
||||
id = SQL_FetchInt(hndl, 0);
|
||||
SQL_FetchString(hndl, 1, authtype, sizeof(authtype));
|
||||
SQL_FetchString(hndl, 2, identity, sizeof(identity));
|
||||
SQL_FetchString(hndl, 3, password, sizeof(password));
|
||||
SQL_FetchString(hndl, 4, flags, sizeof(flags));
|
||||
SQL_FetchString(hndl, 5, name, sizeof(name));
|
||||
immunity = SQL_FetchInt(hndl, 7);
|
||||
|
||||
/* For dynamic admins we clear anything already in the cache. */
|
||||
if ((adm = FindAdminByIdentity(authtype, identity)) != INVALID_ADMIN_ID)
|
||||
{
|
||||
RemoveAdmin(adm);
|
||||
}
|
||||
|
||||
adm = CreateAdmin(name);
|
||||
if (!BindAdminIdentity(adm, authtype, identity))
|
||||
{
|
||||
LogError("Could not bind prefetched SQL admin (authtype \"%s\") (identity \"%s\")", authtype, identity);
|
||||
continue;
|
||||
}
|
||||
|
||||
user_lookup[total_users][0] = id;
|
||||
user_lookup[total_users][1] = _:adm;
|
||||
user_lookup[total_users][2] = SQL_FetchInt(hndl, 6);
|
||||
total_users++;
|
||||
|
||||
#if defined _DEBUG
|
||||
PrintToServer("Found SQL admin (%d,%s,%s,%s,%s,%s,%d):%d:%d", id, authtype, identity, password, flags, name, immunity, adm, user_lookup[total_users-1][2]);
|
||||
#endif
|
||||
|
||||
/* See if this admin wants a password */
|
||||
if (password[0] != '\0')
|
||||
{
|
||||
SetAdminPassword(adm, password);
|
||||
}
|
||||
|
||||
SetAdminImmunityLevel(adm, immunity);
|
||||
|
||||
/* Apply each flag */
|
||||
new len = strlen(flags);
|
||||
new AdminFlag:flag;
|
||||
for (new i=0; i<len; i++)
|
||||
{
|
||||
if (!FindFlagByChar(flags[i], flag))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
SetAdminFlag(adm, flag, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try binding the user.
|
||||
*/
|
||||
new group_count = 0;
|
||||
RunAdminCacheChecks(client);
|
||||
adm = GetUserAdmin(client);
|
||||
id = 0;
|
||||
|
||||
|
||||
for (new i=0; i<total_users; i++)
|
||||
{
|
||||
if (user_lookup[i][1] == _:adm)
|
||||
{
|
||||
id = user_lookup[i][0];
|
||||
group_count = user_lookup[i][2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined _DEBUG
|
||||
PrintToServer("Binding client (%d, %d) resulted in: (%d, %d, %d)", client, sequence, id, adm, group_count);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* If we can't verify that we assigned a database admin, or the user has no
|
||||
* groups, don't bother doing anything.
|
||||
*/
|
||||
if (!id || !group_count)
|
||||
{
|
||||
NotifyPostAdminCheck(client);
|
||||
CloseHandle(pk);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* The user has groups -- we need to fetch them!
|
||||
*/
|
||||
decl String:query[255];
|
||||
Format(query, sizeof(query), "SELECT g.name FROM sm_admins_groups ag JOIN sm_groups g ON ag.group_id = g.id WHERE ag.admin_id = %d", id);
|
||||
|
||||
ResetPack(pk);
|
||||
WritePackCell(pk, client);
|
||||
WritePackCell(pk, sequence);
|
||||
WritePackCell(pk, _:adm);
|
||||
WritePackString(pk, query);
|
||||
|
||||
SQL_TQuery(owner, OnReceiveUserGroups, query, pk, DBPrio_High);
|
||||
}
|
||||
|
||||
FetchUser(Handle:db, client)
|
||||
{
|
||||
decl String:name[65];
|
||||
decl String:safe_name[140];
|
||||
decl String:steamid[32];
|
||||
decl String:ipaddr[24];
|
||||
|
||||
/**
|
||||
* Get authentication information from the client.
|
||||
*/
|
||||
GetClientName(client, name, sizeof(name));
|
||||
GetClientIP(client, ipaddr, sizeof(ipaddr));
|
||||
|
||||
steamid[0] = '\0';
|
||||
if (GetClientAuthString(client, steamid, sizeof(steamid)))
|
||||
{
|
||||
if (StrEqual(steamid, "STEAM_ID_LAN"))
|
||||
{
|
||||
steamid[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
SQL_EscapeString(db, name, safe_name, sizeof(safe_name));
|
||||
|
||||
/**
|
||||
* Construct the query using the information the user gave us.
|
||||
*/
|
||||
decl String:query[512];
|
||||
new len = 0;
|
||||
|
||||
len += Format(query[len], sizeof(query)-len, "SELECT a.id, a.authtype, a.identity, a.password, a.flags, a.name, COUNT(ag.group_id), immunity");
|
||||
len += Format(query[len], sizeof(query)-len, " FROM sm_admins a LEFT JOIN sm_admins_groups ag ON a.id = ag.admin_id WHERE ");
|
||||
len += Format(query[len], sizeof(query)-len, " (a.authtype = 'ip' AND a.identity = '%s')", ipaddr);
|
||||
len += Format(query[len], sizeof(query)-len, " OR (a.authtype = 'name' AND a.identity = '%s')", safe_name);
|
||||
if (steamid[0] != '\0')
|
||||
{
|
||||
len += Format(query[len], sizeof(query)-len, " OR (a.authtype = 'steam' AND a.identity = '%s')", steamid);
|
||||
}
|
||||
len += Format(query[len], sizeof(query)-len, " GROUP BY a.id");
|
||||
|
||||
/**
|
||||
* Send the actual query.
|
||||
*/
|
||||
PlayerSeq[client] = ++g_sequence;
|
||||
|
||||
new Handle:pk;
|
||||
pk = CreateDataPack();
|
||||
WritePackCell(pk, client);
|
||||
WritePackCell(pk, PlayerSeq[client]);
|
||||
WritePackString(pk, query);
|
||||
|
||||
#if defined _DEBUG
|
||||
PrintToServer("Sending user query: %s", query);
|
||||
#endif
|
||||
|
||||
SQL_TQuery(db, OnReceiveUser, query, pk, DBPrio_High);
|
||||
}
|
||||
|
||||
FetchUsersWeCan(Handle:db)
|
||||
{
|
||||
new max_clients = GetMaxClients();
|
||||
|
||||
for (new i=1; i<=max_clients; i++)
|
||||
{
|
||||
if (PlayerAuth[i] && GetUserAdmin(i) == INVALID_ADMIN_ID)
|
||||
{
|
||||
FetchUser(db, i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This round of updates is done. Go in peace.
|
||||
*/
|
||||
RebuildCachePart[_:AdminCache_Admins] = 0;
|
||||
}
|
||||
|
||||
|
||||
public OnReceiveGroupImmunity(Handle:owner, Handle:hndl, const String:error[], any:data)
|
||||
{
|
||||
new Handle:pk = Handle:data;
|
||||
ResetPack(pk);
|
||||
|
||||
/**
|
||||
* Check if this is the latest result request.
|
||||
*/
|
||||
new sequence = ReadPackCell(pk);
|
||||
if (RebuildCachePart[_:AdminCache_Groups] != sequence)
|
||||
{
|
||||
/* Discard everything, since we're out of sequence. */
|
||||
CloseHandle(pk);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* If we need to use the results, make sure they succeeded.
|
||||
*/
|
||||
if (hndl == INVALID_HANDLE)
|
||||
{
|
||||
decl String:query[255];
|
||||
ReadPackString(pk, query, sizeof(query));
|
||||
LogError("SQL error receiving group immunity: %s", error);
|
||||
LogError("Query dump: %s", query);
|
||||
CloseHandle(pk);
|
||||
return;
|
||||
}
|
||||
|
||||
/* We're done with the pack forever. */
|
||||
CloseHandle(pk);
|
||||
|
||||
while (SQL_FetchRow(hndl))
|
||||
{
|
||||
decl String:group1[80];
|
||||
decl String:group2[80];
|
||||
new GroupId:gid1, GroupId:gid2;
|
||||
|
||||
SQL_FetchString(hndl, 0, group1, sizeof(group1));
|
||||
SQL_FetchString(hndl, 1, group2, sizeof(group2));
|
||||
|
||||
if (((gid1 = FindAdmGroup(group1)) == INVALID_GROUP_ID)
|
||||
|| (gid2 = FindAdmGroup(group2)) == INVALID_GROUP_ID)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
SetAdmGroupImmuneFrom(gid1, gid2);
|
||||
#if defined _DEBUG
|
||||
PrintToServer("SetAdmGroupImmuneFrom(%d, %d)", gid1, gid2);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Clear the sequence so another connect doesn't refetch */
|
||||
RebuildCachePart[_:AdminCache_Groups] = 0;
|
||||
}
|
||||
|
||||
public OnReceiveGroupOverrides(Handle:owner, Handle:hndl, const String:error[], any:data)
|
||||
{
|
||||
new Handle:pk = Handle:data;
|
||||
ResetPack(pk);
|
||||
|
||||
/**
|
||||
* Check if this is the latest result request.
|
||||
*/
|
||||
new sequence = ReadPackCell(pk);
|
||||
if (RebuildCachePart[_:AdminCache_Groups] != sequence)
|
||||
{
|
||||
/* Discard everything, since we're out of sequence. */
|
||||
CloseHandle(pk);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* If we need to use the results, make sure they succeeded.
|
||||
*/
|
||||
if (hndl == INVALID_HANDLE)
|
||||
{
|
||||
decl String:query[255];
|
||||
ReadPackString(pk, query, sizeof(query));
|
||||
LogError("SQL error receiving group overrides: %s", error);
|
||||
LogError("Query dump: %s", query);
|
||||
CloseHandle(pk);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the overrides.
|
||||
*/
|
||||
decl String:name[80];
|
||||
decl String:type[16];
|
||||
decl String:command[64];
|
||||
decl String:access[16];
|
||||
new GroupId:gid;
|
||||
while (SQL_FetchRow(hndl))
|
||||
{
|
||||
SQL_FetchString(hndl, 0, name, sizeof(name));
|
||||
SQL_FetchString(hndl, 1, type, sizeof(type));
|
||||
SQL_FetchString(hndl, 2, command, sizeof(command));
|
||||
SQL_FetchString(hndl, 3, access, sizeof(access));
|
||||
|
||||
/* Find the group. This is actually faster than doing the ID lookup. */
|
||||
if ((gid = FindAdmGroup(name)) == INVALID_GROUP_ID)
|
||||
{
|
||||
/* Oh well, just ignore it. */
|
||||
continue;
|
||||
}
|
||||
|
||||
new OverrideType:o_type = Override_Command;
|
||||
if (StrEqual(type, "group"))
|
||||
{
|
||||
o_type = Override_CommandGroup;
|
||||
}
|
||||
|
||||
new OverrideRule:o_rule = Command_Deny;
|
||||
if (StrEqual(access, "allow"))
|
||||
{
|
||||
o_rule = Command_Allow;
|
||||
}
|
||||
|
||||
#if defined _DEBUG
|
||||
PrintToServer("AddAdmGroupCmdOverride(%d, %s, %d, %d)", gid, command, o_type, o_rule);
|
||||
#endif
|
||||
|
||||
AddAdmGroupCmdOverride(gid, command, o_type, o_rule);
|
||||
}
|
||||
|
||||
/**
|
||||
* It's time to get the group immunity list.
|
||||
*/
|
||||
new len = 0;
|
||||
decl String:query[256];
|
||||
len += Format(query[len], sizeof(query)-len, "SELECT g1.name, g2.name FROM sm_group_immunity gi");
|
||||
len += Format(query[len], sizeof(query)-len, " LEFT JOIN sm_groups g1 ON g1.id = gi.group_id ");
|
||||
len += Format(query[len], sizeof(query)-len, " LEFT JOIN sm_groups g2 ON g2.id = gi.other_id");
|
||||
|
||||
ResetPack(pk);
|
||||
WritePackCell(pk, sequence);
|
||||
WritePackString(pk, query);
|
||||
|
||||
SQL_TQuery(owner, OnReceiveGroupImmunity, query, pk, DBPrio_High);
|
||||
}
|
||||
|
||||
public OnReceiveGroups(Handle:owner, Handle:hndl, const String:error[], any:data)
|
||||
{
|
||||
new Handle:pk = Handle:data;
|
||||
ResetPack(pk);
|
||||
|
||||
/**
|
||||
* Check if this is the latest result request.
|
||||
*/
|
||||
new sequence = ReadPackCell(pk);
|
||||
if (RebuildCachePart[_:AdminCache_Groups] != sequence)
|
||||
{
|
||||
/* Discard everything, since we're out of sequence. */
|
||||
CloseHandle(pk);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* If we need to use the results, make sure they succeeded.
|
||||
*/
|
||||
if (hndl == INVALID_HANDLE)
|
||||
{
|
||||
decl String:query[255];
|
||||
ReadPackString(pk, query, sizeof(query));
|
||||
LogError("SQL error receiving groups: %s", error);
|
||||
LogError("Query dump: %s", query);
|
||||
CloseHandle(pk);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Now start fetching groups.
|
||||
*/
|
||||
decl String:flags[32];
|
||||
decl String:name[128];
|
||||
new immunity;
|
||||
while (SQL_FetchRow(hndl))
|
||||
{
|
||||
SQL_FetchString(hndl, 0, flags, sizeof(flags));
|
||||
SQL_FetchString(hndl, 1, name, sizeof(name));
|
||||
immunity = SQL_FetchInt(hndl, 2);
|
||||
|
||||
#if defined _DEBUG
|
||||
PrintToServer("Adding group (%d, %s, %s)", immunity, flags, name);
|
||||
#endif
|
||||
|
||||
/* Find or create the group */
|
||||
new GroupId:gid;
|
||||
if ((gid = FindAdmGroup(name)) == INVALID_GROUP_ID)
|
||||
{
|
||||
gid = CreateAdmGroup(name);
|
||||
}
|
||||
|
||||
/* Add flags from the database to the group */
|
||||
new num_flag_chars = strlen(flags);
|
||||
for (new i=0; i<num_flag_chars; i++)
|
||||
{
|
||||
decl AdminFlag:flag;
|
||||
if (!FindFlagByChar(flags[i], flag))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
SetAdmGroupAddFlag(gid, flag, true);
|
||||
}
|
||||
|
||||
SetAdmGroupImmunityLevel(gid, immunity);
|
||||
}
|
||||
|
||||
/**
|
||||
* It's time to get the group override list.
|
||||
*/
|
||||
decl String:query[255];
|
||||
Format(query,
|
||||
sizeof(query),
|
||||
"SELECT g.name, og.type, og.name, og.access FROM sm_group_overrides og JOIN sm_groups g ON og.group_id = g.id ORDER BY g.id DESC");
|
||||
|
||||
ResetPack(pk);
|
||||
WritePackCell(pk, sequence);
|
||||
WritePackString(pk, query);
|
||||
|
||||
SQL_TQuery(owner, OnReceiveGroupOverrides, query, pk, DBPrio_High);
|
||||
}
|
||||
|
||||
FetchGroups(Handle:db, sequence)
|
||||
{
|
||||
decl String:query[255];
|
||||
new Handle:pk;
|
||||
|
||||
Format(query, sizeof(query), "SELECT flags, name, immunity_level FROM sm_groups");
|
||||
|
||||
pk = CreateDataPack();
|
||||
WritePackCell(pk, sequence);
|
||||
WritePackString(pk, query);
|
||||
|
||||
SQL_TQuery(db, OnReceiveGroups, query, pk, DBPrio_High);
|
||||
}
|
||||
|
||||
public OnReceiveOverrides(Handle:owner, Handle:hndl, const String:error[], any:data)
|
||||
{
|
||||
new Handle:pk = Handle:data;
|
||||
ResetPack(pk);
|
||||
|
||||
/**
|
||||
* Check if this is the latest result request.
|
||||
*/
|
||||
new sequence = ReadPackCell(pk);
|
||||
if (RebuildCachePart[_:AdminCache_Overrides] != sequence)
|
||||
{
|
||||
/* Discard everything, since we're out of sequence. */
|
||||
CloseHandle(pk);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* If we need to use the results, make sure they succeeded.
|
||||
*/
|
||||
if (hndl == INVALID_HANDLE)
|
||||
{
|
||||
decl String:query[255];
|
||||
ReadPackString(pk, query, sizeof(query));
|
||||
LogError("SQL error receiving overrides: %s", error);
|
||||
LogError("Query dump: %s", query);
|
||||
CloseHandle(pk);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* We're done with you, now.
|
||||
*/
|
||||
CloseHandle(pk);
|
||||
|
||||
decl String:type[64];
|
||||
decl String:name[64];
|
||||
decl String:flags[32];
|
||||
new flag_bits;
|
||||
while (SQL_FetchRow(hndl))
|
||||
{
|
||||
SQL_FetchString(hndl, 0, type, sizeof(type));
|
||||
SQL_FetchString(hndl, 1, name, sizeof(name));
|
||||
SQL_FetchString(hndl, 2, flags, sizeof(flags));
|
||||
|
||||
#if defined _DEBUG
|
||||
PrintToServer("Adding override (%s, %s, %s)", type, name, flags);
|
||||
#endif
|
||||
|
||||
flag_bits = ReadFlagString(flags);
|
||||
if (StrEqual(type, "command"))
|
||||
{
|
||||
AddCommandOverride(name, Override_Command, flag_bits);
|
||||
} else if (StrEqual(type, "group")) {
|
||||
AddCommandOverride(name, Override_CommandGroup, flag_bits);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear the sequence so another connect doesn't refetch */
|
||||
RebuildCachePart[_:AdminCache_Overrides] = 0;
|
||||
}
|
||||
|
||||
FetchOverrides(Handle:db, sequence)
|
||||
{
|
||||
decl String:query[255];
|
||||
new Handle:pk;
|
||||
|
||||
Format(query, sizeof(query), "SELECT type, name, flags FROM sm_overrides");
|
||||
|
||||
pk = CreateDataPack();
|
||||
WritePackCell(pk, sequence);
|
||||
WritePackString(pk, query);
|
||||
|
||||
SQL_TQuery(db, OnReceiveOverrides, query, pk, DBPrio_High);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Admin Help Plugin
|
||||
* Displays and searches SourceMod commands and descriptions.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
|
||||
#define COMMANDS_PER_PAGE 10
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "Admin Help",
|
||||
author = "AlliedModders LLC",
|
||||
description = "Display command information",
|
||||
version = SOURCEMOD_VERSION,
|
||||
url = "http://www.sourcemod.net/"
|
||||
};
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
LoadTranslations("common.phrases");
|
||||
LoadTranslations("adminhelp.phrases");
|
||||
RegConsoleCmd("sm_help", HelpCmd, "Displays SourceMod commands and descriptions");
|
||||
RegConsoleCmd("sm_searchcmd", HelpCmd, "Searches SourceMod commands");
|
||||
}
|
||||
|
||||
public Action:HelpCmd(client, args)
|
||||
{
|
||||
decl String:arg[64], String:CmdName[20];
|
||||
new PageNum = 1;
|
||||
new bool:DoSearch;
|
||||
|
||||
GetCmdArg(0, CmdName, sizeof(CmdName));
|
||||
|
||||
if (GetCmdArgs() >= 1)
|
||||
{
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
StringToIntEx(arg, PageNum);
|
||||
PageNum = (PageNum <= 0) ? 1 : PageNum;
|
||||
}
|
||||
|
||||
DoSearch = (strcmp("sm_help", CmdName) == 0) ? false : true;
|
||||
|
||||
if (GetCmdReplySource() == SM_REPLY_TO_CHAT)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "See console for output");
|
||||
}
|
||||
|
||||
decl String:Name[64];
|
||||
decl String:Desc[255];
|
||||
decl String:NoDesc[128];
|
||||
new Flags;
|
||||
new Handle:CmdIter = GetCommandIterator();
|
||||
|
||||
FormatEx(NoDesc, sizeof(NoDesc), "%t", "No description available");
|
||||
|
||||
if (DoSearch)
|
||||
{
|
||||
new i = 1;
|
||||
while (ReadCommandIterator(CmdIter, Name, sizeof(Name), Flags, Desc, sizeof(Desc)))
|
||||
{
|
||||
if ((StrContains(Name, arg, false) != -1) && CheckCommandAccess(client, Name, Flags))
|
||||
{
|
||||
PrintToConsole(client, "[%03d] %s - %s", i++, Name, (Desc[0] == '\0') ? NoDesc : Desc);
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 1)
|
||||
{
|
||||
PrintToConsole(client, "%t", "No matching results found");
|
||||
}
|
||||
} else {
|
||||
PrintToConsole(client, "%t", "SM help commands");
|
||||
|
||||
/* Skip the first N commands if we need to */
|
||||
if (PageNum > 1)
|
||||
{
|
||||
new i;
|
||||
new EndCmd = (PageNum-1) * COMMANDS_PER_PAGE - 1;
|
||||
for (i=0; ReadCommandIterator(CmdIter, Name, sizeof(Name), Flags, Desc, sizeof(Desc)) && i<EndCmd; )
|
||||
{
|
||||
if (CheckCommandAccess(client, Name, Flags))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
PrintToConsole(client, "%t", "No commands available");
|
||||
CloseHandle(CmdIter);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
}
|
||||
|
||||
/* Start printing the commands to the client */
|
||||
new i;
|
||||
new StartCmd = (PageNum-1) * COMMANDS_PER_PAGE;
|
||||
for (i=0; ReadCommandIterator(CmdIter, Name, sizeof(Name), Flags, Desc, sizeof(Desc)) && i<COMMANDS_PER_PAGE; )
|
||||
{
|
||||
if (CheckCommandAccess(client, Name, Flags))
|
||||
{
|
||||
i++;
|
||||
PrintToConsole(client, "[%03d] %s - %s", i+StartCmd, Name, (Desc[0] == '\0') ? NoDesc : Desc);
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
PrintToConsole(client, "%t", "No commands available");
|
||||
} else {
|
||||
PrintToConsole(client, "%t", "Entries n - m in page k", StartCmd+1, i+StartCmd, PageNum);
|
||||
}
|
||||
|
||||
/* Test if there are more commands available */
|
||||
if (ReadCommandIterator(CmdIter, Name, sizeof(Name), Flags, Desc, sizeof(Desc)) && CheckCommandAccess(client, Name, Flags))
|
||||
{
|
||||
PrintToConsole(client, "%t", "Type sm_help to see more", PageNum+1);
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(CmdIter);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Admin Menu Plugin
|
||||
* Creates the base admin menu, for plugins to add items to.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#include <topmenus>
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "Admin Menu",
|
||||
author = "AlliedModders LLC",
|
||||
description = "Administration Menu",
|
||||
version = SOURCEMOD_VERSION,
|
||||
url = "http://www.sourcemod.net/"
|
||||
};
|
||||
|
||||
new g_maxPlayers;
|
||||
|
||||
/* Forwards */
|
||||
new Handle:hOnAdminMenuReady = INVALID_HANDLE;
|
||||
new Handle:hOnAdminMenuCreated = INVALID_HANDLE;
|
||||
|
||||
/* Menus */
|
||||
new Handle:hAdminMenu = INVALID_HANDLE;
|
||||
|
||||
/* Top menu objects */
|
||||
new TopMenuObject:obj_playercmds = INVALID_TOPMENUOBJECT;
|
||||
new TopMenuObject:obj_servercmds = INVALID_TOPMENUOBJECT;
|
||||
new TopMenuObject:obj_votingcmds = INVALID_TOPMENUOBJECT;
|
||||
|
||||
#include "adminmenu/dynamicmenu.sp"
|
||||
|
||||
public bool:AskPluginLoad(Handle:myself, bool:late, String:error[], err_max)
|
||||
{
|
||||
CreateNative("GetAdminTopMenu", __GetAdminTopMenu);
|
||||
CreateNative("AddTargetsToMenu", __AddTargetsToMenu);
|
||||
CreateNative("AddTargetsToMenu2", __AddTargetsToMenu2);
|
||||
RegPluginLibrary("adminmenu");
|
||||
return true;
|
||||
}
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
LoadTranslations("common.phrases");
|
||||
LoadTranslations("adminmenu.phrases");
|
||||
|
||||
hOnAdminMenuCreated = CreateGlobalForward("OnAdminMenuCreated", ET_Ignore, Param_Cell);
|
||||
hOnAdminMenuReady = CreateGlobalForward("OnAdminMenuReady", ET_Ignore, Param_Cell);
|
||||
|
||||
RegAdminCmd("sm_admin", Command_DisplayMenu, ADMFLAG_GENERIC, "Displays the admin menu");
|
||||
}
|
||||
|
||||
public OnConfigsExecuted()
|
||||
{
|
||||
decl String:path[PLATFORM_MAX_PATH];
|
||||
decl String:error[256];
|
||||
|
||||
BuildPath(Path_SM, path, sizeof(path), "configs/adminmenu_sorting.txt");
|
||||
|
||||
if (!LoadTopMenuConfig(hAdminMenu, path, error, sizeof(error)))
|
||||
{
|
||||
LogError("Could not load admin menu config (file \"%s\": %s)", path, error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public OnMapStart()
|
||||
{
|
||||
g_maxPlayers = GetMaxClients();
|
||||
|
||||
ParseConfigs();
|
||||
}
|
||||
|
||||
public OnAllPluginsLoaded()
|
||||
{
|
||||
hAdminMenu = CreateTopMenu(DefaultCategoryHandler);
|
||||
|
||||
obj_playercmds = AddToTopMenu(hAdminMenu,
|
||||
"PlayerCommands",
|
||||
TopMenuObject_Category,
|
||||
DefaultCategoryHandler,
|
||||
INVALID_TOPMENUOBJECT);
|
||||
|
||||
obj_servercmds = AddToTopMenu(hAdminMenu,
|
||||
"ServerCommands",
|
||||
TopMenuObject_Category,
|
||||
DefaultCategoryHandler,
|
||||
INVALID_TOPMENUOBJECT);
|
||||
|
||||
obj_votingcmds = AddToTopMenu(hAdminMenu,
|
||||
"VotingCommands",
|
||||
TopMenuObject_Category,
|
||||
DefaultCategoryHandler,
|
||||
INVALID_TOPMENUOBJECT);
|
||||
|
||||
BuildDynamicMenu();
|
||||
|
||||
Call_StartForward(hOnAdminMenuCreated);
|
||||
Call_PushCell(hAdminMenu);
|
||||
Call_Finish();
|
||||
|
||||
Call_StartForward(hOnAdminMenuReady);
|
||||
Call_PushCell(hAdminMenu);
|
||||
Call_Finish();
|
||||
}
|
||||
|
||||
public DefaultCategoryHandler(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayTitle)
|
||||
{
|
||||
if (object_id == INVALID_TOPMENUOBJECT)
|
||||
{
|
||||
Format(buffer, maxlength, "%T:", "Admin Menu", param);
|
||||
}
|
||||
else if (object_id == obj_playercmds)
|
||||
{
|
||||
Format(buffer, maxlength, "%T:", "Player Commands", param);
|
||||
}
|
||||
else if (object_id == obj_servercmds)
|
||||
{
|
||||
Format(buffer, maxlength, "%T:", "Server Commands", param);
|
||||
}
|
||||
else if (object_id == obj_votingcmds)
|
||||
{
|
||||
Format(buffer, maxlength, "%T:", "Voting Commands", param);
|
||||
}
|
||||
}
|
||||
else if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
if (object_id == obj_playercmds)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Player Commands", param);
|
||||
}
|
||||
else if (object_id == obj_servercmds)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Server Commands", param);
|
||||
}
|
||||
else if (object_id == obj_votingcmds)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Voting Commands", param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public __GetAdminTopMenu(Handle:plugin, numParams)
|
||||
{
|
||||
return _:hAdminMenu;
|
||||
}
|
||||
|
||||
public __AddTargetsToMenu(Handle:plugin, numParams)
|
||||
{
|
||||
new bool:alive_only = false;
|
||||
|
||||
if (numParams >= 4)
|
||||
{
|
||||
alive_only = GetNativeCell(4);
|
||||
}
|
||||
|
||||
return UTIL_AddTargetsToMenu(GetNativeCell(1), GetNativeCell(2), GetNativeCell(3), alive_only);
|
||||
}
|
||||
|
||||
public __AddTargetsToMenu2(Handle:plugin, numParams)
|
||||
{
|
||||
return UTIL_AddTargetsToMenu2(GetNativeCell(1), GetNativeCell(2), GetNativeCell(3));
|
||||
}
|
||||
|
||||
public Action:Command_DisplayMenu(client, args)
|
||||
{
|
||||
if (client == 0)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Command is in-game only");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
DisplayTopMenu(hAdminMenu, client, TopMenuPosition_Start);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
stock UTIL_AddTargetsToMenu2(Handle:menu, source_client, flags)
|
||||
{
|
||||
new max_clients = GetMaxClients();
|
||||
decl String:user_id[12];
|
||||
decl String:name[MAX_NAME_LENGTH];
|
||||
decl String:display[MAX_NAME_LENGTH+12];
|
||||
|
||||
new num_clients;
|
||||
|
||||
for (new i = 1; i <= max_clients; i++)
|
||||
{
|
||||
if (!IsClientConnected(i) || IsClientInKickQueue(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
PrintToServer("%d, %d, %d", i, flags, IsFakeClient(i));
|
||||
|
||||
if (((flags & COMMAND_FILTER_NO_BOTS) == COMMAND_FILTER_NO_BOTS)
|
||||
&& IsFakeClient(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((flags & COMMAND_FILTER_CONNECTED) != COMMAND_FILTER_CONNECTED)
|
||||
&& !IsClientInGame(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((flags & COMMAND_FILTER_ALIVE) == COMMAND_FILTER_ALIVE)
|
||||
&& !IsPlayerAlive(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((flags & COMMAND_FILTER_DEAD) == COMMAND_FILTER_DEAD)
|
||||
&& IsPlayerAlive(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((source_client && ((flags & COMMAND_FILTER_NO_IMMUNITY) != COMMAND_FILTER_NO_IMMUNITY))
|
||||
&& !CanUserTarget(source_client, i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IntToString(GetClientUserId(i), user_id, sizeof(user_id));
|
||||
GetClientName(i, name, sizeof(name));
|
||||
Format(display, sizeof(display), "%s (%s)", name, user_id);
|
||||
AddMenuItem(menu, user_id, display);
|
||||
num_clients++;
|
||||
}
|
||||
|
||||
return num_clients;
|
||||
}
|
||||
|
||||
stock UTIL_AddTargetsToMenu(Handle:menu, source_client, bool:in_game_only, bool:alive_only)
|
||||
{
|
||||
new flags = 0;
|
||||
|
||||
if (!in_game_only)
|
||||
{
|
||||
flags |= COMMAND_FILTER_CONNECTED;
|
||||
}
|
||||
|
||||
if (alive_only)
|
||||
{
|
||||
flags |= COMMAND_FILTER_ALIVE;
|
||||
}
|
||||
|
||||
return UTIL_AddTargetsToMenu2(menu, source_client, flags);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,646 @@
|
||||
|
||||
#define NAME_LENGTH 32
|
||||
#define CMD_LENGTH 255
|
||||
|
||||
#define ARRAY_STRING_LENGTH 32
|
||||
|
||||
enum GroupCommands
|
||||
{
|
||||
Handle:groupListName,
|
||||
Handle:groupListCommand
|
||||
};
|
||||
|
||||
new g_groupList[GroupCommands];
|
||||
new g_groupCount;
|
||||
|
||||
new Handle:g_configParser = INVALID_HANDLE;
|
||||
|
||||
enum Places
|
||||
{
|
||||
Place_Category,
|
||||
Place_Item,
|
||||
Place_ReplaceNum
|
||||
};
|
||||
|
||||
new String:g_command[MAXPLAYERS+1][CMD_LENGTH];
|
||||
new g_currentPlace[MAXPLAYERS+1][Places];
|
||||
|
||||
/**
|
||||
* What to put in the 'info' menu field (for PlayerList and Player_Team menus only)
|
||||
*/
|
||||
enum PlayerMethod
|
||||
{
|
||||
ClientId, /** Client id number ( 1 - Maxplayers) */
|
||||
UserId, /** Client userid */
|
||||
Name, /** Client Name */
|
||||
SteamId, /** Client Steamid */
|
||||
IpAddress, /** Client's Ip Address */
|
||||
UserId2 /** Userid (not prefixed with #) */
|
||||
};
|
||||
|
||||
enum ExecuteType
|
||||
{
|
||||
Execute_Player,
|
||||
Execute_Server
|
||||
}
|
||||
|
||||
enum SubMenu_Type
|
||||
{
|
||||
SubMenu_Group,
|
||||
SubMenu_GroupPlayer,
|
||||
SubMenu_Player,
|
||||
SubMenu_MapCycle,
|
||||
SubMenu_List,
|
||||
SubMenu_OnOff
|
||||
}
|
||||
|
||||
enum Item
|
||||
{
|
||||
String:Item_cmd[256],
|
||||
ExecuteType:Item_execute,
|
||||
Handle:Item_submenus
|
||||
}
|
||||
|
||||
enum Submenu
|
||||
{
|
||||
SubMenu_Type:Submenu_type,
|
||||
String:Submenu_title[32],
|
||||
PlayerMethod:Submenu_method,
|
||||
Submenu_listcount,
|
||||
Handle:Submenu_listdata
|
||||
}
|
||||
|
||||
new Handle:g_DataArray;
|
||||
|
||||
BuildDynamicMenu()
|
||||
{
|
||||
new itemInput[Item];
|
||||
g_DataArray = CreateArray(sizeof(itemInput));
|
||||
|
||||
new String:executeBuffer[32];
|
||||
|
||||
new Handle:kvMenu;
|
||||
kvMenu = CreateKeyValues("Commands");
|
||||
KvSetEscapeSequences(kvMenu, true);
|
||||
|
||||
new String:file[256];
|
||||
|
||||
/* As a compatibility shim, we use the old file if it exists. */
|
||||
BuildPath(Path_SM, file, 255, "configs/dynamicmenu/menu.ini");
|
||||
if (FileExists(file))
|
||||
{
|
||||
LogError("Warning! configs/dynamicmenu/menu.ini is now configs/adminmenu_custom.txt.");
|
||||
LogError("Read the 1.0.2 release notes, as the dynamicmenu folder has been removed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
BuildPath(Path_SM, file, 255, "configs/adminmenu_custom.txt");
|
||||
}
|
||||
|
||||
FileToKeyValues(kvMenu, file);
|
||||
|
||||
new String:name[NAME_LENGTH];
|
||||
new String:buffer[NAME_LENGTH];
|
||||
|
||||
if (!KvGotoFirstSubKey(kvMenu))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
decl String:admin[30];
|
||||
|
||||
new TopMenuObject:categoryId;
|
||||
|
||||
do
|
||||
{
|
||||
KvGetSectionName(kvMenu, buffer, sizeof(buffer));
|
||||
|
||||
KvGetString(kvMenu, "admin", admin, sizeof(admin),"sm_admin");
|
||||
|
||||
if ((categoryId =FindTopMenuCategory(hAdminMenu, buffer)) == INVALID_TOPMENUOBJECT)
|
||||
{
|
||||
categoryId = AddToTopMenu(hAdminMenu,
|
||||
buffer,
|
||||
TopMenuObject_Category,
|
||||
DynamicMenuCategoryHandler,
|
||||
INVALID_TOPMENUOBJECT,
|
||||
admin,
|
||||
ADMFLAG_GENERIC,
|
||||
name);
|
||||
|
||||
}
|
||||
|
||||
if (!KvGotoFirstSubKey(kvMenu))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
KvGetSectionName(kvMenu, buffer, sizeof(buffer));
|
||||
|
||||
KvGetString(kvMenu, "admin", admin, sizeof(admin),"");
|
||||
|
||||
if (admin[0] == '\0')
|
||||
{
|
||||
//No 'admin' keyvalue was found
|
||||
//Use the first argument of the 'cmd' string instead
|
||||
|
||||
decl String:temp[64];
|
||||
KvGetString(kvMenu, "cmd", temp, sizeof(temp),"");
|
||||
|
||||
BreakString(temp, admin, sizeof(admin));
|
||||
}
|
||||
|
||||
|
||||
KvGetString(kvMenu, "cmd", itemInput[Item_cmd], sizeof(itemInput[Item_cmd]));
|
||||
KvGetString(kvMenu, "execute", executeBuffer, sizeof(executeBuffer));
|
||||
|
||||
if (StrEqual(executeBuffer, "server"))
|
||||
{
|
||||
itemInput[Item_execute] = Execute_Server;
|
||||
}
|
||||
else //assume player type execute
|
||||
{
|
||||
itemInput[Item_execute] = Execute_Player;
|
||||
}
|
||||
|
||||
/* iterate all submenus and load data into itemInput[Item_submenus] (adt array handle) */
|
||||
|
||||
new count = 1;
|
||||
decl String:countBuffer[10] = "1";
|
||||
|
||||
decl String:inputBuffer[32];
|
||||
|
||||
while (KvJumpToKey(kvMenu, countBuffer))
|
||||
{
|
||||
new submenuInput[Submenu];
|
||||
|
||||
if (count == 1)
|
||||
{
|
||||
itemInput[Item_submenus] = CreateArray(sizeof(submenuInput));
|
||||
}
|
||||
|
||||
KvGetString(kvMenu, "type", inputBuffer, sizeof(inputBuffer));
|
||||
|
||||
if (strncmp(inputBuffer,"group",5)==0)
|
||||
{
|
||||
if (StrContains(inputBuffer, "player") != -1)
|
||||
{
|
||||
submenuInput[Submenu_type] = SubMenu_GroupPlayer;
|
||||
}
|
||||
else
|
||||
{
|
||||
submenuInput[Submenu_type] = SubMenu_Group;
|
||||
}
|
||||
}
|
||||
else if (StrEqual(inputBuffer,"mapcycle"))
|
||||
{
|
||||
submenuInput[Submenu_type] = SubMenu_MapCycle;
|
||||
|
||||
KvGetString(kvMenu, "path", inputBuffer, sizeof(inputBuffer),"mapcycle.txt");
|
||||
|
||||
submenuInput[Submenu_listdata] = CreateDataPack();
|
||||
WritePackString(submenuInput[Submenu_listdata], inputBuffer);
|
||||
ResetPack(submenuInput[Submenu_listdata]);
|
||||
}
|
||||
else if (StrContains(inputBuffer, "player") != -1)
|
||||
{
|
||||
submenuInput[Submenu_type] = SubMenu_Player;
|
||||
}
|
||||
else if (StrEqual(inputBuffer,"onoff"))
|
||||
{
|
||||
submenuInput[Submenu_type] = SubMenu_OnOff;
|
||||
}
|
||||
else //assume 'list' type
|
||||
{
|
||||
submenuInput[Submenu_type] = SubMenu_List;
|
||||
|
||||
submenuInput[Submenu_listdata] = CreateDataPack();
|
||||
|
||||
new String:temp[6];
|
||||
new String:value[64];
|
||||
new String:text[64];
|
||||
new i=1;
|
||||
new bool:more = true;
|
||||
|
||||
new listcount = 0;
|
||||
|
||||
do
|
||||
{
|
||||
Format(temp,3,"%i",i);
|
||||
KvGetString(kvMenu, temp, value, sizeof(value), "");
|
||||
|
||||
Format(temp,5,"%i.",i);
|
||||
KvGetString(kvMenu, temp, text, sizeof(text), value);
|
||||
|
||||
Format(temp,5,"%i*",i);
|
||||
KvGetString(kvMenu, temp, admin, sizeof(admin),"");
|
||||
|
||||
if (value[0]=='\0')
|
||||
{
|
||||
more = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
listcount++;
|
||||
WritePackString(submenuInput[Submenu_listdata], value);
|
||||
WritePackString(submenuInput[Submenu_listdata], text);
|
||||
WritePackString(submenuInput[Submenu_listdata], admin);
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
} while (more);
|
||||
|
||||
ResetPack(submenuInput[Submenu_listdata]);
|
||||
submenuInput[Submenu_listcount] = listcount;
|
||||
}
|
||||
|
||||
if ((submenuInput[Submenu_type] == SubMenu_Player) || (submenuInput[Submenu_type] == SubMenu_GroupPlayer))
|
||||
{
|
||||
KvGetString(kvMenu, "method", inputBuffer, sizeof(inputBuffer));
|
||||
|
||||
if (StrEqual(inputBuffer, "clientid"))
|
||||
{
|
||||
submenuInput[Submenu_method] = ClientId;
|
||||
}
|
||||
else if (StrEqual(inputBuffer, "steamid"))
|
||||
{
|
||||
submenuInput[Submenu_method] = SteamId;
|
||||
}
|
||||
else if (StrEqual(inputBuffer, "userid2"))
|
||||
{
|
||||
submenuInput[Submenu_method] = UserId2;
|
||||
}
|
||||
else if (StrEqual(inputBuffer, "userid"))
|
||||
{
|
||||
submenuInput[Submenu_method] = UserId;
|
||||
}
|
||||
else if (StrEqual(inputBuffer, "ip"))
|
||||
{
|
||||
submenuInput[Submenu_method] = IpAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
submenuInput[Submenu_method] = Name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
KvGetString(kvMenu, "title", inputBuffer, sizeof(inputBuffer));
|
||||
strcopy(submenuInput[Submenu_title], sizeof(submenuInput[Submenu_title]), inputBuffer);
|
||||
|
||||
count++;
|
||||
Format(countBuffer, sizeof(countBuffer), "%i", count);
|
||||
|
||||
PushArrayArray(itemInput[Item_submenus], submenuInput[0]);
|
||||
|
||||
KvGoBack(kvMenu);
|
||||
}
|
||||
|
||||
/* Save this entire item into the global items array and add it to the menu */
|
||||
|
||||
new location = PushArrayArray(g_DataArray, itemInput[0]);
|
||||
|
||||
decl String:locString[10];
|
||||
IntToString(location, locString, sizeof(locString));
|
||||
|
||||
AddToTopMenu(hAdminMenu,
|
||||
buffer,
|
||||
TopMenuObject_Item,
|
||||
DynamicMenuItemHandler,
|
||||
categoryId,
|
||||
admin,
|
||||
ADMFLAG_GENERIC,
|
||||
locString);
|
||||
|
||||
} while (KvGotoNextKey(kvMenu));
|
||||
|
||||
KvGoBack(kvMenu);
|
||||
|
||||
} while (KvGotoNextKey(kvMenu));
|
||||
|
||||
CloseHandle(kvMenu);
|
||||
}
|
||||
|
||||
ParseConfigs()
|
||||
{
|
||||
if (g_configParser == INVALID_HANDLE)
|
||||
{
|
||||
g_configParser = SMC_CreateParser();
|
||||
}
|
||||
|
||||
SMC_SetReaders(g_configParser, NewSection, KeyValue, EndSection);
|
||||
|
||||
if (g_groupList[groupListName] != INVALID_HANDLE)
|
||||
{
|
||||
CloseHandle(g_groupList[groupListName]);
|
||||
}
|
||||
|
||||
if (g_groupList[groupListCommand] != INVALID_HANDLE)
|
||||
{
|
||||
CloseHandle(g_groupList[groupListCommand]);
|
||||
}
|
||||
|
||||
g_groupList[groupListName] = CreateArray(ARRAY_STRING_LENGTH);
|
||||
g_groupList[groupListCommand] = CreateArray(ARRAY_STRING_LENGTH);
|
||||
|
||||
decl String:configPath[256];
|
||||
BuildPath(Path_SM, configPath, sizeof(configPath), "configs/dynamicmenu/adminmenu_grouping.txt");
|
||||
if (FileExists(configPath))
|
||||
{
|
||||
LogError("Warning! configs/dynamicmenu/adminmenu_grouping.txt is now configs/adminmenu_grouping.txt.");
|
||||
LogError("Read the 1.0.2 release notes, as the dynamicmenu folder has been removed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
BuildPath(Path_SM, configPath, sizeof(configPath), "configs/adminmenu_grouping.txt");
|
||||
}
|
||||
|
||||
if (!FileExists(configPath))
|
||||
{
|
||||
LogError("Unable to locate admin menu groups file: %s", configPath);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
new line;
|
||||
new SMCError:err = SMC_ParseFile(g_configParser, configPath, line);
|
||||
if (err != SMCError_Okay)
|
||||
{
|
||||
decl String:error[256];
|
||||
SMC_GetErrorString(err, error, sizeof(error));
|
||||
LogError("Could not parse file (line %d, file \"%s\"):", line, configPath);
|
||||
LogError("Parser encountered error: %s", error);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public SMCResult:NewSection(Handle:smc, const String:name[], bool:opt_quotes)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public SMCResult:KeyValue(Handle:smc, const String:key[], const String:value[], bool:key_quotes, bool:value_quotes)
|
||||
{
|
||||
PushArrayString(g_groupList[groupListName], key);
|
||||
PushArrayString(g_groupList[groupListCommand], value);
|
||||
}
|
||||
|
||||
public SMCResult:EndSection(Handle:smc)
|
||||
{
|
||||
g_groupCount = GetArraySize(g_groupList[groupListName]);
|
||||
}
|
||||
|
||||
public DynamicMenuCategoryHandler(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if ((action == TopMenuAction_DisplayTitle) || (action == TopMenuAction_DisplayOption))
|
||||
{
|
||||
GetTopMenuObjName(topmenu, object_id, buffer, maxlength);
|
||||
}
|
||||
}
|
||||
|
||||
public DynamicMenuItemHandler(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
GetTopMenuObjName(topmenu, object_id, buffer, maxlength);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
new String:locString[10];
|
||||
GetTopMenuInfoString(topmenu, object_id, locString, sizeof(locString));
|
||||
|
||||
new location = StringToInt(locString);
|
||||
|
||||
new output[Item];
|
||||
GetArrayArray(g_DataArray, location, output[0]);
|
||||
|
||||
strcopy(g_command[param], sizeof(g_command[]), output[Item_cmd]);
|
||||
|
||||
g_currentPlace[param][Place_Item] = location;
|
||||
g_currentPlace[param][Place_ReplaceNum] = 1;
|
||||
|
||||
ParamCheck(param);
|
||||
}
|
||||
}
|
||||
|
||||
public ParamCheck(client)
|
||||
{
|
||||
new String:buffer[6];
|
||||
new String:buffer2[6];
|
||||
|
||||
new outputItem[Item];
|
||||
new outputSubmenu[Submenu];
|
||||
|
||||
GetArrayArray(g_DataArray, g_currentPlace[client][Place_Item], outputItem[0]);
|
||||
|
||||
if (g_currentPlace[client][Place_ReplaceNum] < 1)
|
||||
{
|
||||
g_currentPlace[client][Place_ReplaceNum] = 1;
|
||||
}
|
||||
|
||||
Format(buffer, 5, "#%i", g_currentPlace[client][Place_ReplaceNum]);
|
||||
Format(buffer2, 5, "@%i", g_currentPlace[client][Place_ReplaceNum]);
|
||||
|
||||
if (StrContains(g_command[client], buffer) != -1 || StrContains(g_command[client], buffer2) != -1)
|
||||
{
|
||||
GetArrayArray(outputItem[Item_submenus], g_currentPlace[client][Place_ReplaceNum] - 1, outputSubmenu[0]);
|
||||
|
||||
new Handle:itemMenu = CreateMenu(Menu_Selection);
|
||||
SetMenuExitBackButton(itemMenu, true);
|
||||
|
||||
if ((outputSubmenu[Submenu_type] == SubMenu_Group) || (outputSubmenu[Submenu_type] == SubMenu_GroupPlayer))
|
||||
{
|
||||
decl String:nameBuffer[ARRAY_STRING_LENGTH];
|
||||
decl String:commandBuffer[ARRAY_STRING_LENGTH];
|
||||
|
||||
for (new i = 0; i<g_groupCount; i++)
|
||||
{
|
||||
GetArrayString(g_groupList[groupListName], i, nameBuffer, sizeof(nameBuffer));
|
||||
GetArrayString(g_groupList[groupListCommand], i, commandBuffer, sizeof(commandBuffer));
|
||||
AddMenuItem(itemMenu, commandBuffer, nameBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (outputSubmenu[Submenu_type] == SubMenu_MapCycle)
|
||||
{
|
||||
decl String:path[200];
|
||||
ReadPackString(outputSubmenu[Submenu_listdata], path, sizeof(path));
|
||||
ResetPack(outputSubmenu[Submenu_listdata]);
|
||||
|
||||
new Handle:file = OpenFile(path, "rt");
|
||||
new String:readData[128];
|
||||
|
||||
if(file != INVALID_HANDLE)
|
||||
{
|
||||
while(!IsEndOfFile(file) && ReadFileLine(file, readData, sizeof(readData)))
|
||||
{
|
||||
TrimString(readData);
|
||||
|
||||
if (IsMapValid(readData))
|
||||
{
|
||||
AddMenuItem(itemMenu, readData, readData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((outputSubmenu[Submenu_type] == SubMenu_Player) || (outputSubmenu[Submenu_type] == SubMenu_GroupPlayer))
|
||||
{
|
||||
new PlayerMethod:playermethod = outputSubmenu[Submenu_method];
|
||||
|
||||
new String:nameBuffer[32];
|
||||
new String:infoBuffer[32];
|
||||
new String:temp[4];
|
||||
|
||||
//loop through players. Add name as text and name/userid/steamid as info
|
||||
for (new i=1; i<=g_maxPlayers; i++)
|
||||
{
|
||||
if (IsClientInGame(i))
|
||||
{
|
||||
GetClientName(i, nameBuffer, 31);
|
||||
|
||||
switch (playermethod)
|
||||
{
|
||||
case UserId:
|
||||
{
|
||||
new userid = GetClientUserId(i);
|
||||
Format(infoBuffer, sizeof(infoBuffer), "#%i", userid);
|
||||
AddMenuItem(itemMenu, infoBuffer, nameBuffer);
|
||||
}
|
||||
case UserId2:
|
||||
{
|
||||
new userid = GetClientUserId(i);
|
||||
Format(infoBuffer, sizeof(infoBuffer), "%i", userid);
|
||||
AddMenuItem(itemMenu, infoBuffer, nameBuffer);
|
||||
}
|
||||
case SteamId:
|
||||
{
|
||||
GetClientAuthString(i, infoBuffer, sizeof(infoBuffer));
|
||||
AddMenuItem(itemMenu, infoBuffer, nameBuffer);
|
||||
}
|
||||
case IpAddress:
|
||||
{
|
||||
GetClientIP(i, infoBuffer, sizeof(infoBuffer));
|
||||
AddMenuItem(itemMenu, infoBuffer, nameBuffer);
|
||||
}
|
||||
case Name:
|
||||
{
|
||||
AddMenuItem(itemMenu, nameBuffer, nameBuffer);
|
||||
}
|
||||
default: //assume client id
|
||||
{
|
||||
Format(temp,3,"%i",i);
|
||||
AddMenuItem(itemMenu, temp, nameBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (outputSubmenu[Submenu_type] == SubMenu_OnOff)
|
||||
{
|
||||
AddMenuItem(itemMenu, "1", "On");
|
||||
AddMenuItem(itemMenu, "0", "Off");
|
||||
}
|
||||
else
|
||||
{
|
||||
new String:value[64];
|
||||
new String:text[64];
|
||||
|
||||
new String:admin[NAME_LENGTH];
|
||||
|
||||
for (new i=0; i<outputSubmenu[Submenu_listcount]; i++)
|
||||
{
|
||||
ReadPackString(outputSubmenu[Submenu_listdata], value, sizeof(value));
|
||||
ReadPackString(outputSubmenu[Submenu_listdata], text, sizeof(text));
|
||||
ReadPackString(outputSubmenu[Submenu_listdata], admin, sizeof(admin));
|
||||
|
||||
if (CheckCommandAccess(client, admin, 0))
|
||||
{
|
||||
AddMenuItem(itemMenu, value, text);
|
||||
}
|
||||
}
|
||||
|
||||
ResetPack(outputSubmenu[Submenu_listdata]);
|
||||
}
|
||||
|
||||
SetMenuTitle(itemMenu, outputSubmenu[Submenu_title]);
|
||||
|
||||
DisplayMenu(itemMenu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
else
|
||||
{
|
||||
//nothing else need to be done. Run teh command.
|
||||
|
||||
DisplayTopMenu(hAdminMenu, client, TopMenuPosition_LastCategory);
|
||||
|
||||
if (outputItem[Item_execute] == Execute_Player) // assume 'player' type execute option
|
||||
{
|
||||
FakeClientCommand(client, g_command[client]);
|
||||
}
|
||||
else // assume 'server' type execute option
|
||||
{
|
||||
InsertServerCommand(g_command[client]);
|
||||
ServerExecute();
|
||||
}
|
||||
|
||||
g_command[client][0] = '\0';
|
||||
g_currentPlace[client][Place_ReplaceNum] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
public Menu_Selection(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
|
||||
if (action == MenuAction_Select)
|
||||
{
|
||||
new String:info[NAME_LENGTH];
|
||||
|
||||
/* Get item info */
|
||||
new bool:found = GetMenuItem(menu, param2, info, sizeof(info));
|
||||
|
||||
if (!found)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
new String:buffer[6];
|
||||
new String:infobuffer[NAME_LENGTH+2];
|
||||
Format(infobuffer, sizeof(infobuffer), "\"%s\"", info);
|
||||
|
||||
Format(buffer, 5, "#%i", g_currentPlace[param1][Place_ReplaceNum]);
|
||||
ReplaceString(g_command[param1], sizeof(g_command[]), buffer, infobuffer);
|
||||
//replace #num with the selected option (quoted)
|
||||
|
||||
Format(buffer, 5, "@%i", g_currentPlace[param1][Place_ReplaceNum]);
|
||||
ReplaceString(g_command[param1], sizeof(g_command[]), buffer, info);
|
||||
//replace @num with the selected option (unquoted)
|
||||
|
||||
// Increment the parameter counter.
|
||||
g_currentPlace[param1][Place_ReplaceNum]++;
|
||||
|
||||
ParamCheck(param1);
|
||||
}
|
||||
|
||||
if (action == MenuAction_Cancel && param2 == MenuCancel_ExitBack)
|
||||
{
|
||||
//client exited we should go back to submenu i think
|
||||
DisplayTopMenu(hAdminMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Anti-Flood Plugin
|
||||
* Protects against chat flooding.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "Anti-Flood",
|
||||
author = "AlliedModders LLC",
|
||||
description = "Protects against chat flooding",
|
||||
version = SOURCEMOD_VERSION,
|
||||
url = "http://www.sourcemod.net/"
|
||||
};
|
||||
|
||||
new Float:g_LastTime[MAXPLAYERS + 1] = {0.0, ...}; /* Last time player used say or say_team */
|
||||
new g_FloodTokens[MAXPLAYERS + 1] = {0, ...}; /* Number of flood tokens player has */
|
||||
|
||||
new Handle:sm_flood_time; /* Handle to sm_flood_time convar */
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
sm_flood_time = CreateConVar("sm_flood_time", "0.75", "Amount of time allowed between chat messages");
|
||||
}
|
||||
|
||||
public OnClientPutInServer(client)
|
||||
{
|
||||
g_LastTime[client] = 0.0;
|
||||
g_FloodTokens[client] = 0;
|
||||
}
|
||||
|
||||
new Float:max_chat;
|
||||
|
||||
public bool:OnClientFloodCheck(client)
|
||||
{
|
||||
max_chat = GetConVarFloat(sm_flood_time);
|
||||
|
||||
if (max_chat <= 0.0
|
||||
|| (GetUserFlagBits(client) & ADMFLAG_ROOT) == ADMFLAG_ROOT)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (g_LastTime[client] > GetGameTime())
|
||||
{
|
||||
/* If player has 3 or more flood tokens, block their message */
|
||||
if (g_FloodTokens[client] >= 3)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public OnClientFloodResult(client, bool:blocked)
|
||||
{
|
||||
if (max_chat <= 0.0
|
||||
|| (GetUserFlagBits(client) & ADMFLAG_ROOT) == ADMFLAG_ROOT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
new Float:curTime = GetGameTime();
|
||||
new Float:newTime = curTime + max_chat;
|
||||
|
||||
if (g_LastTime[client] > curTime)
|
||||
{
|
||||
/* If the last message was blocked, update their time limit */
|
||||
if (blocked)
|
||||
{
|
||||
newTime += 3.0;
|
||||
}
|
||||
/* Add one flood token when player goes over chat time limit */
|
||||
else if (g_FloodTokens[client] < 3)
|
||||
{
|
||||
g_FloodTokens[client]++;
|
||||
}
|
||||
}
|
||||
else if (g_FloodTokens[client] > 0)
|
||||
{
|
||||
/* Remove one flood token when player chats within time limit (slow decay) */
|
||||
g_FloodTokens[client]--;
|
||||
}
|
||||
|
||||
g_LastTime[client] = newTime;
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basic Commands Plugin
|
||||
* Implements basic admin commands.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#undef REQUIRE_PLUGIN
|
||||
#include <adminmenu>
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "Basic Ban Commands",
|
||||
author = "AlliedModders LLC",
|
||||
description = "Basic Banning Commands",
|
||||
version = SOURCEMOD_VERSION,
|
||||
url = "http://www.sourcemod.net/"
|
||||
};
|
||||
|
||||
new Handle:hTopMenu = INVALID_HANDLE;
|
||||
|
||||
new g_BanTarget[MAXPLAYERS+1];
|
||||
new g_BanTime[MAXPLAYERS+1];
|
||||
|
||||
#include "basebans/ban.sp"
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
LoadTranslations("common.phrases");
|
||||
LoadTranslations("basebans.phrases");
|
||||
|
||||
RegAdminCmd("sm_ban", Command_Ban, ADMFLAG_BAN, "sm_ban <#userid|name> <minutes|0> [reason]");
|
||||
RegAdminCmd("sm_unban", Command_Unban, ADMFLAG_UNBAN, "sm_unban <steamid>");
|
||||
RegAdminCmd("sm_addban", Command_AddBan, ADMFLAG_RCON, "sm_addban <time> <steamid> [reason]");
|
||||
RegAdminCmd("sm_banip", Command_BanIp, ADMFLAG_BAN, "sm_banip <ip|#userid|name> <time> [reason]");
|
||||
|
||||
/* Account for late loading */
|
||||
new Handle:topmenu;
|
||||
if (LibraryExists("adminmenu") && ((topmenu = GetAdminTopMenu()) != INVALID_HANDLE))
|
||||
{
|
||||
OnAdminMenuReady(topmenu);
|
||||
}
|
||||
}
|
||||
|
||||
public OnAdminMenuReady(Handle:topmenu)
|
||||
{
|
||||
/* Block us from being called twice */
|
||||
if (topmenu == hTopMenu)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save the Handle */
|
||||
hTopMenu = topmenu;
|
||||
|
||||
/* Find the "Player Commands" category */
|
||||
new TopMenuObject:player_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_PLAYERCOMMANDS);
|
||||
|
||||
if (player_commands != INVALID_TOPMENUOBJECT)
|
||||
{
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_ban",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_Ban,
|
||||
player_commands,
|
||||
"sm_ban",
|
||||
ADMFLAG_BAN);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_BanIp(client, args)
|
||||
{
|
||||
if (args < 2)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_banip <ip|#userid|name> <time> [reason]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl len, next_len;
|
||||
decl String:Arguments[256];
|
||||
decl String:arg[50], String:time[20];
|
||||
|
||||
GetCmdArgString(Arguments, sizeof(Arguments));
|
||||
len = BreakString(Arguments, arg, sizeof(arg));
|
||||
|
||||
if ((next_len = BreakString(Arguments[len], time, sizeof(time))) != -1)
|
||||
{
|
||||
len += next_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0;
|
||||
Arguments[0] = '\0';
|
||||
}
|
||||
|
||||
if (StrEqual(arg, "0"))
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Cannot ban that IP");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[1], bool:tn_is_ml;
|
||||
new found_client = -1;
|
||||
|
||||
if (ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
1,
|
||||
COMMAND_FILTER_CONNECTED|COMMAND_FILTER_NO_MULTI,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml) > 0)
|
||||
{
|
||||
found_client = target_list[0];
|
||||
}
|
||||
|
||||
new bool:has_rcon;
|
||||
|
||||
if (client == 0 || (client == 1 && !IsDedicatedServer()))
|
||||
{
|
||||
has_rcon = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
new AdminId:id = GetUserAdmin(client);
|
||||
has_rcon = (id == INVALID_ADMIN_ID) ? false : GetAdminFlag(id, Admin_RCON);
|
||||
}
|
||||
|
||||
new hit_client = -1;
|
||||
if (found_client != -1
|
||||
&& !IsFakeClient(found_client)
|
||||
&& (has_rcon || CanUserTarget(client, found_client)))
|
||||
{
|
||||
GetClientIP(found_client, arg, sizeof(arg));
|
||||
hit_client = found_client;
|
||||
}
|
||||
|
||||
if (hit_client == -1 && !has_rcon)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "No Access");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new minutes = StringToInt(time);
|
||||
|
||||
LogAction(client,
|
||||
hit_client,
|
||||
"\"%L\" added ban (minutes \"%d\") (ip \"%s\") (reason \"%s\")",
|
||||
client,
|
||||
minutes,
|
||||
arg,
|
||||
Arguments[len]);
|
||||
|
||||
ReplyToCommand(client, "[SM] %t", "Ban added");
|
||||
|
||||
BanIdentity(arg,
|
||||
minutes,
|
||||
BANFLAG_IP,
|
||||
Arguments[len],
|
||||
"sm_banip",
|
||||
client);
|
||||
|
||||
if (hit_client != -1)
|
||||
{
|
||||
KickClient(hit_client, "Banned: %s", Arguments[len]);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_AddBan(client, args)
|
||||
{
|
||||
if (args < 2)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_addban <time> <steamid> [reason]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg_string[256];
|
||||
new String:time[50];
|
||||
new String:authid[50];
|
||||
|
||||
GetCmdArgString(arg_string, sizeof(arg_string));
|
||||
|
||||
new len, total_len;
|
||||
|
||||
/* Get time */
|
||||
if ((len = BreakString(arg_string, time, sizeof(time))) == -1)
|
||||
{
|
||||
ReplyToCommand(client, "t[SM] Usage: sm_addban <time> <steamid> [reason]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
total_len += len;
|
||||
|
||||
/* Get steamid */
|
||||
if ((len = BreakString(arg_string[total_len], authid, sizeof(authid))) != -1)
|
||||
{
|
||||
total_len += len;
|
||||
}
|
||||
else
|
||||
{
|
||||
total_len = 0;
|
||||
arg_string[0] = '\0';
|
||||
}
|
||||
|
||||
/* Verify steamid */
|
||||
if (strncmp(authid, "STEAM_0:", 8) != 0)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Invalid SteamID specified");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new minutes = StringToInt(time);
|
||||
|
||||
LogAction(client,
|
||||
-1,
|
||||
"\"%L\" added ban (minutes \"%d\") (id \"%s\") (reason \"%s\")",
|
||||
client,
|
||||
minutes,
|
||||
authid,
|
||||
arg_string[total_len]);
|
||||
BanIdentity(authid,
|
||||
minutes,
|
||||
BANFLAG_AUTHID,
|
||||
arg_string[total_len],
|
||||
"sm_addban",
|
||||
client);
|
||||
|
||||
ReplyToCommand(client, "[SM] %t", "Ban added");
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Unban(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_unban <steamid|ip>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[50];
|
||||
GetCmdArgString(arg, sizeof(arg));
|
||||
|
||||
ReplaceString(arg, sizeof(arg), "\"", "");
|
||||
|
||||
new ban_flags;
|
||||
if (strncmp(arg, "STEAM_0:", 8) == 0)
|
||||
{
|
||||
ban_flags |= BANFLAG_AUTHID;
|
||||
}
|
||||
else
|
||||
{
|
||||
ban_flags |= BANFLAG_IP;
|
||||
}
|
||||
|
||||
LogAction(client, -1, "\"%L\" removed ban (filter \"%s\")", client, arg);
|
||||
RemoveBan(arg, ban_flags, "sm_unban", client);
|
||||
|
||||
ReplyToCommand(client, "[SM] %t", "Removed bans matching", arg);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,270 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basecommands
|
||||
* Functionality related to banning.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
PrepareBan(client, target, time, const String:reason[])
|
||||
{
|
||||
decl String:authid[64], String:name[32];
|
||||
GetClientAuthString(target, authid, sizeof(authid));
|
||||
GetClientName(target, name, sizeof(name));
|
||||
|
||||
if (!time)
|
||||
{
|
||||
if (reason[0] == '\0')
|
||||
{
|
||||
ShowActivity(client, "%t", "Permabanned player", name);
|
||||
} else {
|
||||
ShowActivity(client, "%t", "Permabanned player reason", name, reason);
|
||||
}
|
||||
} else {
|
||||
if (reason[0] == '\0')
|
||||
{
|
||||
ShowActivity(client, "%t", "Banned player", name, time);
|
||||
} else {
|
||||
ShowActivity(client, "%t", "Banned player reason", name, time, reason);
|
||||
}
|
||||
}
|
||||
|
||||
LogAction(client, target, "\"%L\" banned \"%L\" (minutes \"%d\") (reason \"%s\")", client, target, time, reason);
|
||||
|
||||
if (reason[0] == '\0')
|
||||
{
|
||||
BanClient(target, time, BANFLAG_AUTO, "Banned", "Banned", "sm_ban", client);
|
||||
}
|
||||
else
|
||||
{
|
||||
BanClient(target, time, BANFLAG_AUTO, reason, reason, "sm_ban", client);
|
||||
}
|
||||
}
|
||||
|
||||
DisplayBanTargetMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_BanPlayerList);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Ban player", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddTargetsToMenu2(menu, client, COMMAND_FILTER_NO_BOTS|COMMAND_FILTER_CONNECTED);
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
DisplayBanTimeMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_BanTimeList);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Ban player", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddMenuItem(menu, "0", "Permanent");
|
||||
AddMenuItem(menu, "10", "10 Minutes");
|
||||
AddMenuItem(menu, "30", "30 Minutes");
|
||||
AddMenuItem(menu, "60", "1 Hour");
|
||||
AddMenuItem(menu, "240", "4 Hours");
|
||||
AddMenuItem(menu, "1440", "1 Day");
|
||||
AddMenuItem(menu, "10080", "1 Week");
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
DisplayBanReasonMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_BanReasonList);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Ban reason", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
/* :TODO: we should either remove this or make it configurable */
|
||||
|
||||
AddMenuItem(menu, "Abusive", "Abusive");
|
||||
AddMenuItem(menu, "Racism", "Racism");
|
||||
AddMenuItem(menu, "General cheating/exploits", "General cheating/exploits");
|
||||
AddMenuItem(menu, "Wallhack", "Wallhack");
|
||||
AddMenuItem(menu, "Aimbot", "Aimbot");
|
||||
AddMenuItem(menu, "Speedhacking", "Speedhacking");
|
||||
AddMenuItem(menu, "Mic spamming", "Mic spamming");
|
||||
AddMenuItem(menu, "Admin disrepect", "Admin disrepect");
|
||||
AddMenuItem(menu, "Camping", "Camping");
|
||||
AddMenuItem(menu, "Team killing", "Team killing");
|
||||
AddMenuItem(menu, "Unacceptable Spray", "Unacceptable Spray");
|
||||
AddMenuItem(menu, "Breaking Server Rules", "Breaking Server Rules");
|
||||
AddMenuItem(menu, "Other", "Other");
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
public AdminMenu_Ban(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Ban player", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayBanTargetMenu(param);
|
||||
}
|
||||
}
|
||||
|
||||
public MenuHandler_BanReasonList(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[64];
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info));
|
||||
|
||||
PrepareBan(param1, g_BanTarget[param1], g_BanTime[param1], info);
|
||||
}
|
||||
}
|
||||
|
||||
public MenuHandler_BanPlayerList(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32], String:name[32];
|
||||
new userid, target;
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info), _, name, sizeof(name));
|
||||
userid = StringToInt(info);
|
||||
|
||||
if ((target = GetClientOfUserId(userid)) == 0)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player no longer available");
|
||||
}
|
||||
else if (!CanUserTarget(param1, target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Unable to target");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_BanTarget[param1] = target;
|
||||
DisplayBanTimeMenu(param1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MenuHandler_BanTimeList(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32];
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info));
|
||||
g_BanTime[param1] = StringToInt(info);
|
||||
|
||||
DisplayBanReasonMenu(param1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Action:Command_Ban(client, args)
|
||||
{
|
||||
if (args < 2)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_ban <#userid|name> <minutes|0> [reason]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl len, next_len;
|
||||
decl String:Arguments[256];
|
||||
GetCmdArgString(Arguments, sizeof(Arguments));
|
||||
|
||||
decl String:arg[65];
|
||||
len = BreakString(Arguments, arg, sizeof(arg));
|
||||
|
||||
new target = FindTarget(client, arg, true);
|
||||
if (target == -1)
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:s_time[12];
|
||||
if ((next_len = BreakString(Arguments[len], s_time, sizeof(s_time))) != -1)
|
||||
{
|
||||
len += next_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0;
|
||||
Arguments[0] = '\0';
|
||||
}
|
||||
|
||||
new time = StringToInt(s_time);
|
||||
|
||||
PrepareBan(client, target, time, Arguments[len]);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,479 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basic Chat Plugin
|
||||
* Implements basic communication commands.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "Basic Chat",
|
||||
author = "AlliedModders LLC",
|
||||
description = "Basic Communication Commands",
|
||||
version = SOURCEMOD_VERSION,
|
||||
url = "http://www.sourcemod.net/"
|
||||
};
|
||||
|
||||
#define CHAT_SYMBOL '@'
|
||||
|
||||
new String:g_ColorNames[13][10] = {"White", "Red", "Green", "Blue", "Yellow", "Purple", "Cyan", "Orange", "Pink", "Olive", "Lime", "Violet", "Lightblue"};
|
||||
new g_Colors[13][3] = {{255,255,255},{255,0,0},{0,255,0},{0,0,255},{255,255,0},{255,0,255},{0,255,255},{255,128,0},{255,0,128},{128,255,0},{0,255,128},{128,0,255},{0,128,255}};
|
||||
|
||||
new Handle:g_Cvar_Chatmode = INVALID_HANDLE;
|
||||
|
||||
new bool:g_DoColor = true;
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
LoadTranslations("common.phrases");
|
||||
|
||||
g_Cvar_Chatmode = CreateConVar("sm_chat_mode", "1", "Allows player's to send messages to admin chat.", 0, true, 0.0, true, 1.0);
|
||||
|
||||
RegConsoleCmd("say", Command_SayChat);
|
||||
RegConsoleCmd("say_team", Command_SayAdmin);
|
||||
RegAdminCmd("sm_say", Command_SmSay, ADMFLAG_CHAT, "sm_say <message> - sends message to all players");
|
||||
RegAdminCmd("sm_csay", Command_SmCsay, ADMFLAG_CHAT, "sm_csay <message> - sends centered message to all players");
|
||||
RegAdminCmd("sm_hsay", Command_SmHsay, ADMFLAG_CHAT, "sm_hsay <message> - sends hint message to all players");
|
||||
RegAdminCmd("sm_tsay", Command_SmTsay, ADMFLAG_CHAT, "sm_tsay [color] <message> - sends top-left message to all players");
|
||||
RegAdminCmd("sm_chat", Command_SmChat, ADMFLAG_CHAT, "sm_chat <message> - sends message to admins");
|
||||
RegAdminCmd("sm_psay", Command_SmPsay, ADMFLAG_CHAT, "sm_psay <name or #userid> <message> - sends private message");
|
||||
RegAdminCmd("sm_msay", Command_SmMsay, ADMFLAG_CHAT, "sm_msay <message> - sends message as a menu panel");
|
||||
|
||||
decl String:modname[64];
|
||||
GetGameFolderName(modname, sizeof(modname));
|
||||
|
||||
if (strcmp(modname, "hl2mp") == 0)
|
||||
{
|
||||
g_DoColor = false;
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_SayChat(client, args)
|
||||
{
|
||||
decl String:text[192];
|
||||
if (IsChatTrigger() || GetCmdArgString(text, sizeof(text)) < 1)
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
new startidx;
|
||||
if (text[strlen(text)-1] == '"')
|
||||
{
|
||||
text[strlen(text)-1] = '\0';
|
||||
startidx = 1;
|
||||
}
|
||||
|
||||
if (text[startidx] != CHAT_SYMBOL)
|
||||
return Plugin_Continue;
|
||||
|
||||
new msgStart = 1;
|
||||
|
||||
if (text[startidx+1] == CHAT_SYMBOL)
|
||||
{
|
||||
msgStart = 2;
|
||||
|
||||
if (text[startidx+2] == CHAT_SYMBOL)
|
||||
msgStart = 3;
|
||||
}
|
||||
|
||||
decl String:message[192];
|
||||
strcopy(message, 192, text[startidx+msgStart]);
|
||||
|
||||
decl String:name[64];
|
||||
GetClientName(client, name, sizeof(name));
|
||||
|
||||
if (msgStart == 1 && CheckCommandAccess(client, "sm_say", ADMFLAG_CHAT)) // sm_say alias
|
||||
{
|
||||
SendChatToAll(name, message);
|
||||
LogAction(client, -1, "%L triggered sm_say (text %s)", client, message);
|
||||
}
|
||||
else if (msgStart == 3 && CheckCommandAccess(client, "sm_csay", ADMFLAG_CHAT)) // sm_csay alias
|
||||
{
|
||||
PrintCenterTextAll("%s: %s", name, message);
|
||||
LogAction(client, -1, "%L triggered sm_csay (text %s)", client, text);
|
||||
}
|
||||
else if (msgStart == 2 && CheckCommandAccess(client, "sm_psay", ADMFLAG_CHAT)) // sm_psay alias
|
||||
{
|
||||
decl String:arg[64];
|
||||
|
||||
new len = BreakString(message, arg, sizeof(arg));
|
||||
new target = FindTarget(client, arg, true, false);
|
||||
|
||||
if (target == -1)
|
||||
return Plugin_Handled;
|
||||
|
||||
decl String:name2[64];
|
||||
GetClientName(target, name2, sizeof(name2));
|
||||
|
||||
if (g_DoColor)
|
||||
{
|
||||
PrintToChat(client, "\x04(Private to %s) %s: \x01%s", name2, name, message[len]);
|
||||
PrintToChat(target, "\x04(Private to %s) %s: \x01%s", name2, name, message[len]);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintToChat(client, "(Private to %s) %s: %s", name2, name, message[len]);
|
||||
PrintToChat(target, "(Private to %s) %s: %s", name2, name, message[len]);
|
||||
}
|
||||
|
||||
LogAction(client, -1, "%L triggered sm_psay to %L (text %s)", client, target, message);
|
||||
}
|
||||
else
|
||||
return Plugin_Continue;
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_SayAdmin(client, args)
|
||||
{
|
||||
if (!CheckCommandAccess(client, "sm_chat", ADMFLAG_CHAT) && !GetConVarBool(g_Cvar_Chatmode))
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
decl String:text[192];
|
||||
if (IsChatTrigger() || GetCmdArgString(text, sizeof(text)) < 1)
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
new startidx;
|
||||
if (text[strlen(text)-1] == '"')
|
||||
{
|
||||
text[strlen(text)-1] = '\0';
|
||||
startidx = 1;
|
||||
}
|
||||
|
||||
if (text[startidx] != CHAT_SYMBOL)
|
||||
return Plugin_Continue;
|
||||
|
||||
decl String:message[192];
|
||||
strcopy(message, 192, text[startidx+1]);
|
||||
|
||||
decl String:name[64];
|
||||
GetClientName(client, name, sizeof(name));
|
||||
|
||||
SendChatToAdmins(name, message);
|
||||
LogAction(client, -1, "%L triggered sm_chat (text %s)", client, message);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_SmSay(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_say <message>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:text[192];
|
||||
GetCmdArgString(text, sizeof(text));
|
||||
|
||||
decl String:name[64];
|
||||
GetClientName(client, name, sizeof(name));
|
||||
|
||||
SendChatToAll(name, text);
|
||||
LogAction(client, -1, "%L triggered sm_say (text %s)", client, text);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_SmCsay(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_csay <message>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:text[192];
|
||||
GetCmdArgString(text, sizeof(text));
|
||||
|
||||
new String:name[64];
|
||||
GetClientName(client, name, sizeof(name));
|
||||
|
||||
PrintCenterTextAll("%s: %s", name, text);
|
||||
LogAction(client, -1, "%L triggered sm_csay (text %s)", client, text);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_SmHsay(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_hsay <message>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:text[192];
|
||||
GetCmdArgString(text, sizeof(text));
|
||||
|
||||
decl String:name[64];
|
||||
GetClientName(client, name, sizeof(name));
|
||||
|
||||
PrintHintTextToAll("%s: %s", name, text);
|
||||
LogAction(client, -1, "%L triggered sm_hsay (text %s)", client, text);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_SmTsay(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_tsay <message>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:text[192], String:colorStr[16];
|
||||
GetCmdArgString(text, sizeof(text));
|
||||
|
||||
new len = BreakString(text, colorStr, 16);
|
||||
|
||||
decl String:name[64];
|
||||
GetClientName(client, name, sizeof(name));
|
||||
|
||||
new color = FindColor(colorStr);
|
||||
|
||||
if (color == -1)
|
||||
SendDialogToAll(_, "%s: %s", name, text);
|
||||
else
|
||||
SendDialogToAll(color, "%s: %s", name, text[len]);
|
||||
|
||||
LogAction(client, -1, "%L triggered sm_tsay (text %s)", client, text);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_SmChat(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_chat <message>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:text[192];
|
||||
GetCmdArgString(text, sizeof(text));
|
||||
|
||||
decl String:name[64];
|
||||
GetClientName(client, name, sizeof(name));
|
||||
|
||||
SendChatToAdmins(name, text);
|
||||
LogAction(client, -1, "%L triggered sm_chat (text %s)", client, text);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_SmPsay(client, args)
|
||||
{
|
||||
if (args < 2)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_psay <name or #userid> <message>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:text[192], String:arg[64], String:message[192];
|
||||
GetCmdArgString(text, sizeof(text));
|
||||
|
||||
new len = BreakString(text, arg, sizeof(arg));
|
||||
BreakString(text[len], message, sizeof(message));
|
||||
|
||||
new target = FindTarget(client, arg, true, false);
|
||||
|
||||
if (target == -1)
|
||||
return Plugin_Handled;
|
||||
|
||||
decl String:name[64], String:name2[64];
|
||||
|
||||
if (client == 0)
|
||||
{
|
||||
name = "Console";
|
||||
}
|
||||
else
|
||||
{
|
||||
GetClientName(client, name, sizeof(name));
|
||||
}
|
||||
|
||||
GetClientName(target, name2, sizeof(name2));
|
||||
|
||||
if (client == 0)
|
||||
{
|
||||
PrintToServer("(Private: %s) %s: %s", name2, name, message);
|
||||
}
|
||||
else if (g_DoColor)
|
||||
{
|
||||
PrintToChat(client, "\x04(Private: %s) %s: \x01%s", name2, name, message);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintToChat(client, "(Private: %s) %s: %s", name2, name, message);
|
||||
}
|
||||
|
||||
if (g_DoColor)
|
||||
{
|
||||
PrintToChat(target, "\x04(Private: %s) %s: \x01%s", name2, name, message);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintToChat(target, "(Private: %s) %s: %s", name2, name, message);
|
||||
}
|
||||
|
||||
LogAction(client, -1, "%L triggered sm_psay to %L (text %s)", client, target, message);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_SmMsay(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_msay <message>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:text[192];
|
||||
GetCmdArgString(text, sizeof(text));
|
||||
|
||||
decl String:name[64];
|
||||
GetClientName(client, name, sizeof(name));
|
||||
|
||||
SendPanelToAll(name, text);
|
||||
|
||||
LogAction(client, -1, "%L triggered sm_msay (text %s)", client, text);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
FindColor(String:color[])
|
||||
{
|
||||
for (new i = 0; i < 13; i++)
|
||||
{
|
||||
if (strcmp(color, g_ColorNames[i], false) == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
SendChatToAll(String:name[], String:message[])
|
||||
{
|
||||
if (g_DoColor)
|
||||
{
|
||||
PrintToChatAll("\x04(ALL) %s: \x01%s", name, message);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintToChatAll("(ALL) %s: %s", name, message);
|
||||
}
|
||||
}
|
||||
|
||||
SendChatToAdmins(String:name[], String:message[])
|
||||
{
|
||||
new iMaxClients = GetMaxClients();
|
||||
|
||||
for (new i = 1; i <= iMaxClients; i++)
|
||||
{
|
||||
if (IsClientInGame(i))
|
||||
{
|
||||
if (CheckCommandAccess(i, "sm_chat", ADMFLAG_CHAT))
|
||||
{
|
||||
if (g_DoColor)
|
||||
{
|
||||
PrintToChat(i, "\x04(ADMINS) %s: \x01%s", name, message);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintToChat(i, "(ADMINS) %s: %s", name, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SendDialogToAll(color = 0, String:text[], any:...)
|
||||
{
|
||||
new String:message[100];
|
||||
VFormat(message, sizeof(message), text, 3);
|
||||
|
||||
new MaxClients = GetMaxClients();
|
||||
for(new i = 1; i < MaxClients; i++)
|
||||
{
|
||||
if(IsClientInGame(i))
|
||||
{
|
||||
new Handle:kv = CreateKeyValues("Stuff", "title", message);
|
||||
KvSetColor(kv, "color", g_Colors[color][0], g_Colors[color][1], g_Colors[color][2], 255);
|
||||
KvSetNum(kv, "level", 1);
|
||||
KvSetNum(kv, "time", 10);
|
||||
|
||||
CreateDialog(i, kv, DialogType_Msg);
|
||||
|
||||
CloseHandle(kv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SendPanelToAll(String:name[], String:message[])
|
||||
{
|
||||
decl String:title[100];
|
||||
Format(title, 64, "%s:", name);
|
||||
|
||||
ReplaceString(message, 192, "\\n", "\n");
|
||||
|
||||
new Handle:mSayPanel = CreatePanel();
|
||||
SetPanelTitle(mSayPanel, title);
|
||||
DrawPanelItem(mSayPanel, "", ITEMDRAW_SPACER);
|
||||
DrawPanelText(mSayPanel, message);
|
||||
DrawPanelItem(mSayPanel, "", ITEMDRAW_SPACER);
|
||||
|
||||
SetPanelCurrentKey(mSayPanel, 10);
|
||||
DrawPanelItem(mSayPanel, "Exit", ITEMDRAW_CONTROL);
|
||||
|
||||
new MaxClients = GetMaxClients();
|
||||
for(new i = 1; i < MaxClients; i++)
|
||||
{
|
||||
if(IsClientInGame(i) && !IsFakeClient(i))
|
||||
{
|
||||
SendPanelToClient(mSayPanel, i, Handler_DoNothing, 10);
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(mSayPanel);
|
||||
}
|
||||
|
||||
public Handler_DoNothing(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Communication Plugin
|
||||
* Provides fucntionality for controlling communication on the server
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
* 1
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
#undef REQUIRE_PLUGIN
|
||||
#include <adminmenu>
|
||||
|
||||
#pragma semicolon 1
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "Basic Comm Control",
|
||||
author = "AlliedModders LLC",
|
||||
description = "Provides methods of controllingg communication.",
|
||||
version = SOURCEMOD_VERSION,
|
||||
url = "http://www.sourcemod.net/"
|
||||
};
|
||||
|
||||
new bool:g_Muted[MAXPLAYERS+1]; // Is the player muted?
|
||||
new bool:g_Gagged[MAXPLAYERS+1]; // Is the player gagged?
|
||||
|
||||
new Handle:g_Cvar_Deadtalk = INVALID_HANDLE; // Holds the handle for sm_deadtalk
|
||||
new Handle:g_Cvar_Alltalk = INVALID_HANDLE; // Holds the handle for sv_alltalk
|
||||
new bool:g_Hooked = false; // Tracks if we've hooked events for deadtalk
|
||||
|
||||
new Handle:hTopMenu = INVALID_HANDLE;
|
||||
|
||||
new g_GagTarget[MAXPLAYERS+1];
|
||||
|
||||
#include "basecomm/gag.sp"
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
LoadTranslations("common.phrases");
|
||||
LoadTranslations("basecomm.phrases");
|
||||
|
||||
g_Cvar_Deadtalk = CreateConVar("sm_deadtalk", "0", "Controls how dead communicate. 0 - Off. 1 - Dead players ignore teams. 2 - Dead players talk to living teammates.", 0, true, 0.0, true, 2.0);
|
||||
g_Cvar_Alltalk = FindConVar("sv_alltalk");
|
||||
|
||||
RegConsoleCmd("say", Command_Say);
|
||||
RegConsoleCmd("say_team", Command_Say);
|
||||
|
||||
RegAdminCmd("sm_mute", Command_Mute, ADMFLAG_CHAT, "sm_mute <player> - Removes a player's ability to use voice.");
|
||||
RegAdminCmd("sm_gag", Command_Gag, ADMFLAG_CHAT, "sm_gag <player> - Removes a player's ability to use chat.");
|
||||
RegAdminCmd("sm_silence", Command_Silence, ADMFLAG_CHAT, "sm_silence <player> - Removes a player's ability to use voice or chat.");
|
||||
|
||||
RegAdminCmd("sm_unmute", Command_Unmute, ADMFLAG_CHAT, "sm_unmute <player> - Restores a player's ability to use voice.");
|
||||
RegAdminCmd("sm_ungag", Command_Ungag, ADMFLAG_CHAT, "sm_ungag <player> - Restores a player's ability to use chat.");
|
||||
RegAdminCmd("sm_unsilence", Command_Unsilence, ADMFLAG_CHAT, "sm_unsilence <player> - Restores a player's ability to use voice and chat.");
|
||||
|
||||
HookConVarChange(g_Cvar_Deadtalk, ConVarChange_Deadtalk);
|
||||
HookConVarChange(g_Cvar_Alltalk, ConVarChange_Alltalk);
|
||||
|
||||
/* Account for late loading */
|
||||
new Handle:topmenu;
|
||||
if (LibraryExists("adminmenu") && ((topmenu = GetAdminTopMenu()) != INVALID_HANDLE))
|
||||
{
|
||||
OnAdminMenuReady(topmenu);
|
||||
}
|
||||
}
|
||||
|
||||
public OnAdminMenuReady(Handle:topmenu)
|
||||
{
|
||||
/* Block us from being called twice */
|
||||
if (topmenu == hTopMenu)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save the Handle */
|
||||
hTopMenu = topmenu;
|
||||
|
||||
/* Build the "Player Commands" category */
|
||||
new TopMenuObject:player_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_PLAYERCOMMANDS);
|
||||
|
||||
if (player_commands != INVALID_TOPMENUOBJECT)
|
||||
{
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_gag",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_Gag,
|
||||
player_commands,
|
||||
"sm_gag",
|
||||
ADMFLAG_CHAT);
|
||||
}
|
||||
}
|
||||
|
||||
public ConVarChange_Deadtalk(Handle:convar, const String:oldValue[], const String:newValue[])
|
||||
{
|
||||
if (GetConVarInt(g_Cvar_Deadtalk))
|
||||
{
|
||||
HookEvent("player_spawn", Event_PlayerSpawn, EventHookMode_Post);
|
||||
HookEvent("player_death", Event_PlayerDeath, EventHookMode_Post);
|
||||
g_Hooked = true;
|
||||
}
|
||||
else if (g_Hooked)
|
||||
{
|
||||
UnhookEvent("player_spawn", Event_PlayerSpawn);
|
||||
UnhookEvent("player_death", Event_PlayerDeath);
|
||||
g_Hooked = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool:OnClientConnect(client, String:rejectmsg[], maxlen)
|
||||
{
|
||||
g_Gagged[client] = false;
|
||||
g_Muted[client] = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Action:Command_Say(client, args)
|
||||
{
|
||||
if (client)
|
||||
{
|
||||
if (g_Gagged[client])
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
}
|
||||
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public ConVarChange_Alltalk(Handle:convar, const String:oldValue[], const String:newValue[])
|
||||
{
|
||||
new mode = GetConVarInt(g_Cvar_Deadtalk);
|
||||
new maxClients = GetMaxClients();
|
||||
|
||||
for (new i = 1; i <= maxClients; i++)
|
||||
{
|
||||
if (!IsClientInGame(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_Muted[i])
|
||||
{
|
||||
SetClientListeningFlags(i, VOICE_MUTED);
|
||||
}
|
||||
else if (GetConVarBool(g_Cvar_Alltalk))
|
||||
{
|
||||
SetClientListeningFlags(i, VOICE_NORMAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mode == 1)
|
||||
{
|
||||
SetClientListeningFlags(i, VOICE_LISTENALL);
|
||||
}
|
||||
else if (mode == 2)
|
||||
{
|
||||
SetClientListeningFlags(i, VOICE_TEAM);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Event_PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
|
||||
{
|
||||
new client = GetClientOfUserId(GetEventInt(event, "userid"));
|
||||
|
||||
if (g_Muted[client])
|
||||
{
|
||||
SetClientListeningFlags(client, VOICE_MUTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetClientListeningFlags(client, VOICE_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
|
||||
{
|
||||
new client = GetClientOfUserId(GetEventInt(event, "userid"));
|
||||
|
||||
if (g_Muted[client])
|
||||
{
|
||||
SetClientListeningFlags(client, VOICE_MUTED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetConVarBool(g_Cvar_Alltalk))
|
||||
{
|
||||
SetClientListeningFlags(client, VOICE_NORMAL);
|
||||
return;
|
||||
}
|
||||
|
||||
new mode = GetConVarInt(g_Cvar_Deadtalk);
|
||||
if (mode == 1)
|
||||
{
|
||||
SetClientListeningFlags(client, VOICE_LISTENALL);
|
||||
}
|
||||
else if (mode == 2)
|
||||
{
|
||||
SetClientListeningFlags(client, VOICE_TEAM);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,580 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basecomm
|
||||
* Part of Basecomm plugin, menu and other functionality.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
enum CommType
|
||||
{
|
||||
CommType_Mute,
|
||||
CommType_UnMute,
|
||||
CommType_Gag,
|
||||
CommType_UnGag,
|
||||
CommType_Silence,
|
||||
CommType_UnSilence
|
||||
};
|
||||
|
||||
DisplayGagTypesMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_GagTypes);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Choose Type", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
new target = g_GagTarget[client];
|
||||
|
||||
if (!g_Muted[target])
|
||||
{
|
||||
AddMenuItem(menu, "0", "Mute Player");
|
||||
}
|
||||
else
|
||||
{
|
||||
AddMenuItem(menu, "1", "UnMute Player");
|
||||
}
|
||||
|
||||
if (!g_Gagged[target])
|
||||
{
|
||||
AddMenuItem(menu, "2", "Gag Player");
|
||||
}
|
||||
else
|
||||
{
|
||||
AddMenuItem(menu, "3", "UnGag Player");
|
||||
}
|
||||
|
||||
if (!g_Muted[target] || !g_Gagged[target])
|
||||
{
|
||||
AddMenuItem(menu, "4", "Silence Player");
|
||||
}
|
||||
else
|
||||
{
|
||||
AddMenuItem(menu, "5", "UnSilence Player");
|
||||
}
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
DisplayGagPlayerMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_GagPlayer);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Gag/Mute player", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddTargetsToMenu(menu, client, true, false);
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
public AdminMenu_Gag(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Gag/Mute player", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayGagPlayerMenu(param);
|
||||
}
|
||||
}
|
||||
|
||||
public MenuHandler_GagPlayer(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32];
|
||||
new userid, target;
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info));
|
||||
userid = StringToInt(info);
|
||||
|
||||
if ((target = GetClientOfUserId(userid)) == 0)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player no longer available");
|
||||
}
|
||||
else if (!CanUserTarget(param1, target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Unable to target");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_GagTarget[param1] = GetClientOfUserId(userid);
|
||||
DisplayGagTypesMenu(param1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MenuHandler_GagTypes(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32];
|
||||
new CommType:type;
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info));
|
||||
type = CommType:StringToInt(info);
|
||||
|
||||
decl String:name[MAX_NAME_LENGTH];
|
||||
GetClientName(g_GagTarget[param1], name, sizeof(name));
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case CommType_Mute:
|
||||
{
|
||||
PerformMute(param1, g_GagTarget[param1]);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Muted target", "_s", name);
|
||||
}
|
||||
case CommType_UnMute:
|
||||
{
|
||||
PerformUnMute(param1, g_GagTarget[param1]);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Unmuted target", "_s", name);
|
||||
}
|
||||
case CommType_Gag:
|
||||
{
|
||||
PerformGag(param1, g_GagTarget[param1]);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Gagged target", "_s", name);
|
||||
}
|
||||
case CommType_UnGag:
|
||||
{
|
||||
PerformUnGag(param1, g_GagTarget[param1]);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Ungagged target", "_s", name);
|
||||
}
|
||||
case CommType_Silence:
|
||||
{
|
||||
PerformSilence(param1, g_GagTarget[param1]);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Silenced target", "_s", name);
|
||||
}
|
||||
case CommType_UnSilence:
|
||||
{
|
||||
PerformUnSilence(param1, g_GagTarget[param1]);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Unsilenced target", "_s", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PerformMute(client, target)
|
||||
{
|
||||
g_Muted[target] = true;
|
||||
SetClientListeningFlags(target, VOICE_MUTED);
|
||||
LogAction(client, target, "\"%L\" muted \"%L\"", client, target);
|
||||
}
|
||||
|
||||
PerformUnMute(client, target)
|
||||
{
|
||||
g_Muted[target] = false;
|
||||
if (GetConVarInt(g_Cvar_Deadtalk) == 1 && !IsPlayerAlive(target))
|
||||
{
|
||||
SetClientListeningFlags(target, VOICE_LISTENALL);
|
||||
}
|
||||
else if (GetConVarInt(g_Cvar_Deadtalk) == 2 && !IsPlayerAlive(target))
|
||||
{
|
||||
SetClientListeningFlags(target, VOICE_TEAM);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetClientListeningFlags(target, VOICE_NORMAL);
|
||||
}
|
||||
|
||||
LogAction(client, target, "\"%L\" unmuted \"%L\"", client, target);
|
||||
}
|
||||
|
||||
PerformGag(client, target)
|
||||
{
|
||||
g_Gagged[target] = true;
|
||||
LogAction(client, target, "\"%L\" gagged \"%L\"", client, target);
|
||||
}
|
||||
|
||||
PerformUnGag(client, target)
|
||||
{
|
||||
g_Gagged[target] = false;
|
||||
LogAction(client, target, "\"%L\" ungagged \"%L\"", client, target);
|
||||
}
|
||||
|
||||
PerformSilence(client, target)
|
||||
{
|
||||
if (!g_Gagged[target])
|
||||
{
|
||||
g_Gagged[target] = true;
|
||||
}
|
||||
|
||||
if (!g_Muted[target])
|
||||
{
|
||||
g_Muted[target] = true;
|
||||
SetClientListeningFlags(target, VOICE_MUTED);
|
||||
}
|
||||
|
||||
LogAction(client, target, "\"%L\" silenced \"%L\"", client, target);
|
||||
}
|
||||
|
||||
PerformUnSilence(client, target)
|
||||
{
|
||||
if (g_Gagged[target])
|
||||
{
|
||||
g_Gagged[target] = false;
|
||||
}
|
||||
|
||||
if (g_Muted[target])
|
||||
{
|
||||
g_Muted[target] = false;
|
||||
|
||||
if (GetConVarInt(g_Cvar_Deadtalk) == 1 && !IsPlayerAlive(target))
|
||||
{
|
||||
SetClientListeningFlags(target, VOICE_LISTENALL);
|
||||
}
|
||||
else if (GetConVarInt(g_Cvar_Deadtalk) == 2 && !IsPlayerAlive(target))
|
||||
{
|
||||
SetClientListeningFlags(target, VOICE_TEAM);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetClientListeningFlags(target, VOICE_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
LogAction(client, target, "\"%L\" unsilenced \"%L\"", client, target);
|
||||
}
|
||||
|
||||
public Action:Command_Mute(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_mute <player>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[64];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
0,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for (new i = 0; i < target_count; i++)
|
||||
{
|
||||
new target = target_list[i];
|
||||
|
||||
PerformMute(client, target);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Muted target", target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Muted target", "_s", target_name);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Gag(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_gag <player>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[64];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
0,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for (new i = 0; i < target_count; i++)
|
||||
{
|
||||
new target = target_list[i];
|
||||
|
||||
PerformGag(client, target);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Gagged target", target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Gagged target", "_s", target_name);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Silence(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_silence <player>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[64];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
0,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for (new i = 0; i < target_count; i++)
|
||||
{
|
||||
new target = target_list[i];
|
||||
|
||||
PerformSilence(client, target);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Silenced target", target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Silenced target", "_s", target_name);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Unmute(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_unmute <player>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[64];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
0,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for (new i = 0; i < target_count; i++)
|
||||
{
|
||||
new target = target_list[i];
|
||||
|
||||
if (!g_Muted[target])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
PerformUnMute(client, target);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Unmuted target", target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Unmuted target", "_s", target_name);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Ungag(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_ungag <player>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[64];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
0,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for (new i = 0; i < target_count; i++)
|
||||
{
|
||||
new target = target_list[i];
|
||||
|
||||
PerformUnGag(client, target);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Ungagged target", target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Ungagged target", "_s", target_name);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Unsilence(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_unsilence <player>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[64];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
0,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for (new i = 0; i < target_count; i++)
|
||||
{
|
||||
new target = target_list[i];
|
||||
|
||||
PerformUnSilence(client, target);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Unsilenced target", target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Unsilenced target", "_s", target_name);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,399 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basic Commands Plugin
|
||||
* Implements basic admin commands.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative 1works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#undef REQUIRE_PLUGIN
|
||||
#include <adminmenu>
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "Basic Commands",
|
||||
author = "AlliedModders LLC",
|
||||
description = "Basic Admin Commands",
|
||||
version = SOURCEMOD_VERSION,
|
||||
url = "http://www.sourcemod.net/"
|
||||
};
|
||||
|
||||
new Handle:hTopMenu = INVALID_HANDLE;
|
||||
|
||||
new Handle:g_MapList;
|
||||
new Handle:g_ProtectedVars;
|
||||
|
||||
#include "basecommands/kick.sp"
|
||||
#include "basecommands/reloadadmins.sp"
|
||||
#include "basecommands/cancelvote.sp"
|
||||
#include "basecommands/who.sp"
|
||||
#include "basecommands/map.sp"
|
||||
#include "basecommands/execcfg.sp"
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
LoadTranslations("common.phrases");
|
||||
LoadTranslations("plugin.basecommands");
|
||||
|
||||
RegAdminCmd("sm_kick", Command_Kick, ADMFLAG_KICK, "sm_kick <#userid|name> [reason]");
|
||||
RegAdminCmd("sm_map", Command_Map, ADMFLAG_CHANGEMAP, "sm_map <map>");
|
||||
RegAdminCmd("sm_rcon", Command_Rcon, ADMFLAG_RCON, "sm_rcon <args>");
|
||||
RegAdminCmd("sm_cvar", Command_Cvar, ADMFLAG_CONVARS, "sm_cvar <cvar> [value]");
|
||||
RegAdminCmd("sm_execcfg", Command_ExecCfg, ADMFLAG_CONFIG, "sm_execcfg <filename>");
|
||||
RegAdminCmd("sm_who", Command_Who, ADMFLAG_GENERIC, "sm_who [#userid|name]");
|
||||
RegAdminCmd("sm_reloadadmins", Command_ReloadAdmins, ADMFLAG_BAN, "sm_reloadadmins");
|
||||
RegAdminCmd("sm_cancelvote", Command_CancelVote, ADMFLAG_VOTE, "sm_cancelvote");
|
||||
RegConsoleCmd("sm_revote", Command_ReVote);
|
||||
|
||||
/* Account for late loading */
|
||||
new Handle:topmenu;
|
||||
if (LibraryExists("adminmenu") && ((topmenu = GetAdminTopMenu()) != INVALID_HANDLE))
|
||||
{
|
||||
OnAdminMenuReady(topmenu);
|
||||
}
|
||||
|
||||
g_MapList = CreateMenu(MenuHandler_ChangeMap);
|
||||
SetMenuTitle(g_MapList, "Please select a map");
|
||||
SetMenuExitBackButton(g_MapList, true);
|
||||
|
||||
decl String:mapListPath[PLATFORM_MAX_PATH];
|
||||
BuildPath(Path_SM, mapListPath, sizeof(mapListPath), "configs/adminmenu_maplist.ini");
|
||||
SetMapListCompatBind("sm_map menu", mapListPath);
|
||||
|
||||
g_ProtectedVars = CreateTrie();
|
||||
ProtectVar("rcon_password");
|
||||
ProtectVar("sm_show_activity");
|
||||
ProtectVar("sm_immunity_mode");
|
||||
}
|
||||
|
||||
public OnMapStart()
|
||||
{
|
||||
ParseConfigs();
|
||||
}
|
||||
|
||||
public OnConfigsExecuted()
|
||||
{
|
||||
LoadMapList(g_MapList);
|
||||
}
|
||||
|
||||
ProtectVar(const String:cvar[])
|
||||
{
|
||||
SetTrieValue(g_ProtectedVars, cvar, 1);
|
||||
}
|
||||
|
||||
bool:IsVarProtected(const String:cvar[])
|
||||
{
|
||||
decl dummy_value;
|
||||
return GetTrieValue(g_ProtectedVars, cvar, dummy_value);
|
||||
}
|
||||
|
||||
public OnAdminMenuReady(Handle:topmenu)
|
||||
{
|
||||
/* Block us from being called twice */
|
||||
if (topmenu == hTopMenu)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save the Handle */
|
||||
hTopMenu = topmenu;
|
||||
|
||||
/* Build the "Player Commands" category */
|
||||
new TopMenuObject:player_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_PLAYERCOMMANDS);
|
||||
|
||||
if (player_commands != INVALID_TOPMENUOBJECT)
|
||||
{
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_kick",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_Kick,
|
||||
player_commands,
|
||||
"sm_kick",
|
||||
ADMFLAG_KICK);
|
||||
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_who",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_Who,
|
||||
player_commands,
|
||||
"sm_who",
|
||||
ADMFLAG_GENERIC);
|
||||
}
|
||||
|
||||
new TopMenuObject:server_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_SERVERCOMMANDS);
|
||||
|
||||
if (server_commands != INVALID_TOPMENUOBJECT)
|
||||
{
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_reloadadmins",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_ReloadAdmins,
|
||||
server_commands,
|
||||
"sm_reloadadmins",
|
||||
ADMFLAG_BAN);
|
||||
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_map",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_Map,
|
||||
server_commands,
|
||||
"sm_map",
|
||||
ADMFLAG_CHANGEMAP);
|
||||
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_execcfg",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_ExecCFG,
|
||||
server_commands,
|
||||
"sm_execcfg",
|
||||
ADMFLAG_CONFIG);
|
||||
}
|
||||
|
||||
new TopMenuObject:voting_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_VOTINGCOMMANDS);
|
||||
|
||||
if (voting_commands != INVALID_TOPMENUOBJECT)
|
||||
{
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_cancelvote",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_CancelVote,
|
||||
voting_commands,
|
||||
"sm_cancelvote",
|
||||
ADMFLAG_VOTE);
|
||||
}
|
||||
}
|
||||
|
||||
public OnLibraryRemoved(const String:name[])
|
||||
{
|
||||
if (strcmp(name, "adminmenu") == 0)
|
||||
{
|
||||
hTopMenu = INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
#define FLAG_STRINGS 14
|
||||
new String:g_FlagNames[FLAG_STRINGS][20] =
|
||||
{
|
||||
"res",
|
||||
"admin",
|
||||
"kick",
|
||||
"ban",
|
||||
"unban",
|
||||
"slay",
|
||||
"map",
|
||||
"cvars",
|
||||
"cfg",
|
||||
"chat",
|
||||
"vote",
|
||||
"pass",
|
||||
"rcon",
|
||||
"cheat"
|
||||
};
|
||||
|
||||
CustomFlagsToString(String:buffer[], maxlength, flags)
|
||||
{
|
||||
decl String:joins[6][6];
|
||||
new total;
|
||||
|
||||
for (new i=_:Admin_Custom1; i<=_:Admin_Custom6; i++)
|
||||
{
|
||||
if (flags & (1<<i))
|
||||
{
|
||||
IntToString(i - _:Admin_Custom1 + 1, joins[total++], 6);
|
||||
}
|
||||
}
|
||||
|
||||
ImplodeStrings(joins, total, ",", buffer, maxlength);
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
FlagsToString(String:buffer[], maxlength, flags)
|
||||
{
|
||||
decl String:joins[FLAG_STRINGS+1][32];
|
||||
new total;
|
||||
|
||||
for (new i=0; i<FLAG_STRINGS; i++)
|
||||
{
|
||||
if (flags & (1<<i))
|
||||
{
|
||||
strcopy(joins[total++], 32, g_FlagNames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
decl String:custom_flags[32];
|
||||
if (CustomFlagsToString(custom_flags, sizeof(custom_flags), flags))
|
||||
{
|
||||
Format(joins[total++], 32, "custom(%s)", custom_flags);
|
||||
}
|
||||
|
||||
ImplodeStrings(joins, total, ", ", buffer, maxlength);
|
||||
}
|
||||
|
||||
public Action:Command_Cvar(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
if (client == 0)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_cvar <cvar|protect> [value]");
|
||||
}
|
||||
else
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_cvar <cvar> [value]");
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:cvarname[64];
|
||||
GetCmdArg(1, cvarname, sizeof(cvarname));
|
||||
|
||||
if (client == 0 && StrEqual(cvarname, "protect"))
|
||||
{
|
||||
if (args < 2)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_cvar <protect> <cvar>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
GetCmdArg(2, cvarname, sizeof(cvarname));
|
||||
ProtectVar(cvarname);
|
||||
ReplyToCommand(client, "[SM] %t", "Cvar is now protected", cvarname);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new Handle:hndl = FindConVar(cvarname);
|
||||
if (hndl == INVALID_HANDLE)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Unable to find cvar", cvarname);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new bool:allowed = false;
|
||||
new client_flags = client == 0 ? ADMFLAG_ROOT : GetUserFlagBits(client);
|
||||
|
||||
if (client_flags & ADMFLAG_ROOT)
|
||||
{
|
||||
allowed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetConVarFlags(hndl) & FCVAR_PROTECTED)
|
||||
{
|
||||
allowed = ((client_flags & ADMFLAG_PASSWORD) == ADMFLAG_PASSWORD);
|
||||
}
|
||||
else if (StrEqual(cvarname, "sv_cheats"))
|
||||
{
|
||||
allowed = ((client_flags & ADMFLAG_CHEATS) == ADMFLAG_CHEATS);
|
||||
}
|
||||
else if (!IsVarProtected(cvarname))
|
||||
{
|
||||
allowed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!allowed)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "No access to cvar");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:value[255];
|
||||
if (args < 2)
|
||||
{
|
||||
GetConVarString(hndl, value, sizeof(value));
|
||||
|
||||
ReplyToCommand(client, "[SM] %t", "Value of cvar", cvarname, value);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
GetCmdArg(2, value, sizeof(value));
|
||||
|
||||
if ((GetConVarFlags(hndl) & FCVAR_PROTECTED) != FCVAR_PROTECTED)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Cvar changed", cvarname, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Cvar changed", cvarname, value);
|
||||
}
|
||||
|
||||
LogAction(client, -1, "\"%L\" changed cvar (cvar \"%s\") (value \"%s\")", client, cvarname, value);
|
||||
|
||||
SetConVarString(hndl, value, true);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Rcon(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_rcon <args>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:argstring[255];
|
||||
GetCmdArgString(argstring, sizeof(argstring));
|
||||
|
||||
LogAction(client, -1, "\"%L\" console command (cmdline \"%s\")", client, argstring);
|
||||
|
||||
ServerCommand("%s", argstring);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_ReVote(client, args)
|
||||
{
|
||||
if (client == 0)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Command is in-game only");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (!IsVoteInProgress())
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Vote Not In Progress");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (!IsClientInVotePool(client))
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Cannot participate in vote");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (!RedrawClientVoteMenu(client))
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Cannot change vote");
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basecommands Plugin
|
||||
* Provides cancelvote functionality.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
PerformCancelVote(client)
|
||||
{
|
||||
if (!IsVoteInProgress())
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Vote Not In Progress");
|
||||
return;
|
||||
}
|
||||
|
||||
ShowActivity2(client, "[SM] ", "%t", "Cancelled Vote");
|
||||
|
||||
CancelVote();
|
||||
}
|
||||
|
||||
public AdminMenu_CancelVote(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Cancel vote", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
PerformCancelVote(param);
|
||||
RedisplayAdminMenu(topmenu, param);
|
||||
}
|
||||
else if (action == TopMenuAction_DrawOption)
|
||||
{
|
||||
buffer[0] = IsVoteInProgress() ? ITEMDRAW_DEFAULT : ITEMDRAW_IGNORE;
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_CancelVote(client, args)
|
||||
{
|
||||
PerformCancelVote(client);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basecommands Plugin
|
||||
* Provides exec cfg functionality
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
new Handle:g_ConfigMenu = INVALID_HANDLE;
|
||||
|
||||
PerformExec(client, String:path[])
|
||||
{
|
||||
if (!FileExists(path))
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Config not found", path[4]);
|
||||
return;
|
||||
}
|
||||
|
||||
ShowActivity2(client, "[SM] ", "%t", "Executed config", path[4]);
|
||||
|
||||
LogAction(client, -1, "\"%L\" executed config (file \"%s\")", client, path[4]);
|
||||
|
||||
ServerCommand("exec \"%s\"", path[4]);
|
||||
}
|
||||
|
||||
public AdminMenu_ExecCFG(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Exec CFG", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayMenu(g_ConfigMenu, param, MENU_TIME_FOREVER);
|
||||
}
|
||||
}
|
||||
|
||||
public MenuHandler_ExecCFG(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:path[256];
|
||||
|
||||
GetMenuItem(menu, param2, path, sizeof(path));
|
||||
|
||||
PerformExec(param1, path);
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_ExecCfg(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_execcfg <filename>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new String:path[64] = "cfg/";
|
||||
GetCmdArg(1, path[4], sizeof(path)-4);
|
||||
|
||||
PerformExec(client, path);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new Handle:config_parser = INVALID_HANDLE;
|
||||
ParseConfigs()
|
||||
{
|
||||
if (config_parser == INVALID_HANDLE)
|
||||
{
|
||||
config_parser = SMC_CreateParser();
|
||||
}
|
||||
|
||||
SMC_SetReaders(config_parser, NewSection, KeyValue, EndSection);
|
||||
|
||||
if (g_ConfigMenu != INVALID_HANDLE)
|
||||
{
|
||||
CloseHandle(g_ConfigMenu);
|
||||
}
|
||||
|
||||
g_ConfigMenu = CreateMenu(MenuHandler_ExecCFG);
|
||||
SetMenuTitle(g_ConfigMenu, "Choose Config");
|
||||
SetMenuExitBackButton(g_ConfigMenu, true);
|
||||
|
||||
decl String:configPath[256];
|
||||
BuildPath(Path_SM, configPath, sizeof(configPath), "configs/adminmenu_cfgs.txt");
|
||||
|
||||
if (!FileExists(configPath))
|
||||
{
|
||||
LogError("Unable to locate exec config file, no maps loaded.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
new line;
|
||||
new SMCError:err = SMC_ParseFile(config_parser, configPath, line);
|
||||
if (err != SMCError_Okay)
|
||||
{
|
||||
decl String:error[256];
|
||||
SMC_GetErrorString(err, error, sizeof(error));
|
||||
LogError("Could not parse file (line %d, file \"%s\"):", line, configPath);
|
||||
LogError("Parser encountered error: %s", error);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public SMCResult:NewSection(Handle:smc, const String:name[], bool:opt_quotes)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public SMCResult:KeyValue(Handle:smc, const String:key[], const String:value[], bool:key_quotes, bool:value_quotes)
|
||||
{
|
||||
AddMenuItem(g_ConfigMenu, key, value);
|
||||
}
|
||||
|
||||
public SMCResult:EndSection(Handle:smc)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basecommands Plugin
|
||||
* Provides kick functionality
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
PerformKick(client, target, const String:reason[])
|
||||
{
|
||||
LogAction(client, target, "\"%L\" kicked \"%L\" (reason \"%s\")", client, target, reason);
|
||||
|
||||
if (reason[0] == '\0')
|
||||
{
|
||||
KickClient(target, "%t", "Kicked by admin");
|
||||
}
|
||||
else
|
||||
{
|
||||
KickClient(target, "%s", reason);
|
||||
}
|
||||
}
|
||||
|
||||
DisplayKickMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_Kick);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Kick player", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddTargetsToMenu(menu, client, false, false);
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
public AdminMenu_Kick(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Kick player", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayKickMenu(param);
|
||||
}
|
||||
}
|
||||
|
||||
public MenuHandler_Kick(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32];
|
||||
new userid, target;
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info));
|
||||
userid = StringToInt(info);
|
||||
|
||||
if ((target = GetClientOfUserId(userid)) == 0)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player no longer available");
|
||||
}
|
||||
else if (!CanUserTarget(param1, target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Unable to target");
|
||||
}
|
||||
else
|
||||
{
|
||||
decl String:name[MAX_NAME_LENGTH];
|
||||
GetClientName(target, name, sizeof(name));
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Kicked target", "_s", name);
|
||||
PerformKick(param1, target, "");
|
||||
}
|
||||
|
||||
/* Re-draw the menu if they're still valid */
|
||||
if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
|
||||
{
|
||||
DisplayKickMenu(param1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_Kick(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_kick <#userid|name> [reason]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:Arguments[256];
|
||||
GetCmdArgString(Arguments, sizeof(Arguments));
|
||||
|
||||
decl String:arg[65];
|
||||
new len = BreakString(Arguments, arg, sizeof(arg));
|
||||
|
||||
if (len == -1)
|
||||
{
|
||||
/* Safely null terminate */
|
||||
len = 0;
|
||||
Arguments[0] = '\0';
|
||||
}
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_CONNECTED,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) > 0)
|
||||
{
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Kicked target", target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Kicked target", "_s", target_name);
|
||||
}
|
||||
|
||||
new kick_self = 0;
|
||||
|
||||
for (new i = 0; i < target_count; i++)
|
||||
{
|
||||
/* Kick everyone else first */
|
||||
if (target_list[i] == client)
|
||||
{
|
||||
kick_self = client;
|
||||
}
|
||||
else
|
||||
{
|
||||
PerformKick(client, target_list[i], Arguments[len]);
|
||||
}
|
||||
}
|
||||
|
||||
if (kick_self)
|
||||
{
|
||||
PerformKick(client, client, Arguments[len]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basecommands Plugin
|
||||
* Provides map functionality
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
public MenuHandler_ChangeMap(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:map[64];
|
||||
|
||||
GetMenuItem(menu, param2, map, sizeof(map));
|
||||
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Changing map", map);
|
||||
|
||||
LogAction(param1, -1, "\"%L\" changed map to \"%s\"", param1, map);
|
||||
|
||||
new Handle:dp;
|
||||
CreateDataTimer(3.0, Timer_ChangeMap, dp);
|
||||
WritePackString(dp, map);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public AdminMenu_Map(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Choose Map", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayMenu(g_MapList, param, MENU_TIME_FOREVER);
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_Map(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_map <map>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:map[64];
|
||||
GetCmdArg(1, map, sizeof(map));
|
||||
|
||||
if (!IsMapValid(map))
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Map was not found", map);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
ShowActivity2(client, "[SM] ", "%t", "Changing map", map);
|
||||
|
||||
LogAction(client, -1, "\"%L\" changed map to \"%s\"", client, map);
|
||||
|
||||
new Handle:dp;
|
||||
CreateDataTimer(3.0, Timer_ChangeMap, dp);
|
||||
WritePackString(dp, map);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Timer_ChangeMap(Handle:timer, Handle:dp)
|
||||
{
|
||||
decl String:map[65];
|
||||
|
||||
ResetPack(dp);
|
||||
ReadPackString(dp, map, sizeof(map));
|
||||
|
||||
ServerCommand("changelevel \"%s\"", map);
|
||||
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
||||
new Handle:g_map_array = INVALID_HANDLE;
|
||||
new g_map_serial = -1;
|
||||
|
||||
LoadMapList(Handle:menu)
|
||||
{
|
||||
new Handle:map_array;
|
||||
|
||||
if ((map_array = ReadMapList(g_map_array,
|
||||
g_map_serial,
|
||||
"sm_map menu",
|
||||
MAPLIST_FLAG_CLEARARRAY|MAPLIST_FLAG_NO_DEFAULT|MAPLIST_FLAG_MAPSFOLDER))
|
||||
!= INVALID_HANDLE)
|
||||
{
|
||||
g_map_array = map_array;
|
||||
}
|
||||
|
||||
if (g_map_array == INVALID_HANDLE)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
RemoveAllMenuItems(menu);
|
||||
|
||||
decl String:map_name[64];
|
||||
new map_count = GetArraySize(g_map_array);
|
||||
|
||||
for (new i = 0; i < map_count; i++)
|
||||
{
|
||||
GetArrayString(g_map_array, i, map_name, sizeof(map_name));
|
||||
AddMenuItem(menu, map_name, map_name);
|
||||
}
|
||||
|
||||
return map_count;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basecommands Plugin
|
||||
* Provides reloadadmins functionality.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
PerformReloadAdmins(client)
|
||||
{
|
||||
/* Dump it all! */
|
||||
DumpAdminCache(AdminCache_Groups, true);
|
||||
DumpAdminCache(AdminCache_Overrides, true);
|
||||
|
||||
LogAction(client, -1, "\"%L\" refreshed the admin cache.", client);
|
||||
ReplyToCommand(client, "[SM] %t", "Admin cache refreshed");
|
||||
}
|
||||
|
||||
public AdminMenu_ReloadAdmins(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Reload admins", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
PerformReloadAdmins(param);
|
||||
RedisplayAdminMenu(topmenu, param);
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_ReloadAdmins(client, args)
|
||||
{
|
||||
PerformReloadAdmins(client);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basecommands Plugin
|
||||
* Provides sm_who functionality
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
PerformWho(client, target, ReplySource:reply, bool:is_admin)
|
||||
{
|
||||
decl String:name[MAX_NAME_LENGTH];
|
||||
GetClientName(target, name, sizeof(name));
|
||||
|
||||
new bool:show_name = false;
|
||||
new String:admin_name[MAX_NAME_LENGTH];
|
||||
new AdminId:id = GetUserAdmin(target);
|
||||
if (id != INVALID_ADMIN_ID && GetAdminUsername(id, admin_name, sizeof(admin_name)))
|
||||
{
|
||||
show_name = true;
|
||||
}
|
||||
|
||||
new ReplySource:old_reply = SetCmdReplySource(reply);
|
||||
|
||||
if (id == INVALID_ADMIN_ID)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Player is not an admin", name);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!is_admin)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Player is an admin", name);
|
||||
}
|
||||
else
|
||||
{
|
||||
new flags = GetUserFlagBits(target);
|
||||
decl String:flagstring[255];
|
||||
if (flags == 0)
|
||||
{
|
||||
strcopy(flagstring, sizeof(flagstring), "none");
|
||||
}
|
||||
else if (flags & ADMFLAG_ROOT)
|
||||
{
|
||||
strcopy(flagstring, sizeof(flagstring), "root");
|
||||
}
|
||||
else
|
||||
{
|
||||
FlagsToString(flagstring, sizeof(flagstring), flags);
|
||||
}
|
||||
|
||||
if (show_name)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Admin logged in as", name, admin_name, flagstring);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Admin logged in anon", name, flagstring);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetCmdReplySource(old_reply);
|
||||
}
|
||||
|
||||
DisplayWhoMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_Who);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Identify player", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddTargetsToMenu(menu, client, false, false);
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
public AdminMenu_Who(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Identify player", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayWhoMenu(param);
|
||||
}
|
||||
}
|
||||
|
||||
public MenuHandler_Who(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32];
|
||||
new userid, target;
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info));
|
||||
userid = StringToInt(info);
|
||||
|
||||
if ((target = GetClientOfUserId(userid)) == 0)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player no longer available");
|
||||
}
|
||||
else if (!CanUserTarget(param1, target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Unable to target");
|
||||
}
|
||||
else
|
||||
{
|
||||
PerformWho(param1, target, SM_REPLY_TO_CHAT, (GetUserFlagBits(param1) != 0 ? true : false));
|
||||
}
|
||||
|
||||
/* Re-draw the menu if they're still valid */
|
||||
|
||||
/* - Close the menu? redisplay? jump back up to the category?
|
||||
if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
|
||||
{
|
||||
DisplayWhoMenu(param1);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
public Action:Command_Who(client, args)
|
||||
{
|
||||
new bool:is_admin = false;
|
||||
|
||||
if (!client || (client && GetUserFlagBits(client) != 0))
|
||||
{
|
||||
is_admin = true;
|
||||
}
|
||||
|
||||
if (args < 1)
|
||||
{
|
||||
/* Display header */
|
||||
decl String:t_access[16], String:t_name[16], String:t_username[16];
|
||||
Format(t_access, sizeof(t_access), "%t", "Admin access", client);
|
||||
Format(t_name, sizeof(t_name), "%t", "Name", client);
|
||||
Format(t_username, sizeof(t_username), "%t", "Username", client);
|
||||
|
||||
if (is_admin)
|
||||
{
|
||||
PrintToConsole(client, " %-24.23s %-18.17s %s", t_name, t_username, t_access);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintToConsole(client, " %-24.23s %s", t_name, t_access);
|
||||
}
|
||||
|
||||
/* List all players */
|
||||
new maxClients = GetMaxClients();
|
||||
decl String:flagstring[255];
|
||||
|
||||
for (new i=1; i<=maxClients; i++)
|
||||
{
|
||||
if (!IsClientInGame(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
new flags = GetUserFlagBits(i);
|
||||
new AdminId:id = GetUserAdmin(i);
|
||||
if (flags == 0)
|
||||
{
|
||||
strcopy(flagstring, sizeof(flagstring), "none");
|
||||
}
|
||||
else if (flags & ADMFLAG_ROOT)
|
||||
{
|
||||
strcopy(flagstring, sizeof(flagstring), "root");
|
||||
}
|
||||
else
|
||||
{
|
||||
FlagsToString(flagstring, sizeof(flagstring), flags);
|
||||
}
|
||||
decl String:name[MAX_NAME_LENGTH];
|
||||
new String:username[MAX_NAME_LENGTH];
|
||||
|
||||
GetClientName(i, name, sizeof(name));
|
||||
|
||||
if (id != INVALID_ADMIN_ID)
|
||||
{
|
||||
GetAdminUsername(id, username, sizeof(username));
|
||||
}
|
||||
|
||||
if (is_admin)
|
||||
{
|
||||
PrintToConsole(client, "%2d. %-24.23s %-18.17s %s", i, name, username, flagstring);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flags == 0)
|
||||
{
|
||||
PrintToConsole(client, "%2d. %-24.23s %t", i, name, "No");
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintToConsole(client, "%2d. %-24.23s %t", i, name, "Yes");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GetCmdReplySource() == SM_REPLY_TO_CHAT)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "See console for output");
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[65];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
new target = FindTarget(client, arg, false, false);
|
||||
if (target == -1)
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
PerformWho(client, target, GetCmdReplySource(), is_admin);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,327 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basic Info Triggers Plugin
|
||||
* Implements basic information chat triggers like ff and timeleft.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "Basic Info Triggers",
|
||||
author = "AlliedModders LLC",
|
||||
description = "Adds ff, timeleft, thetime, and others.",
|
||||
version = SOURCEMOD_VERSION,
|
||||
url = "http://www.sourcemod.net/"
|
||||
};
|
||||
|
||||
new Handle:g_Cvar_TriggerShow = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_TimeleftInterval = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_FriendlyFire = INVALID_HANDLE;
|
||||
|
||||
new Handle:g_Timer_TimeShow = INVALID_HANDLE;
|
||||
|
||||
new Handle:g_Cvar_WinLimit = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_FragLimit = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_MaxRounds = INVALID_HANDLE;
|
||||
|
||||
#define TIMELEFT_ALL_ALWAYS 0
|
||||
#define TIMELEFT_ALL_MAYBE 1
|
||||
#define TIMELEFT_ONE 2
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
LoadTranslations("common.phrases");
|
||||
LoadTranslations("basetriggers.phrases");
|
||||
|
||||
g_Cvar_TriggerShow = CreateConVar("sm_trigger_show", "1", "Display triggers message to all players? (0 off, 1 on, def. 1)", 0, true, 0.0, true, 1.0);
|
||||
g_Cvar_TimeleftInterval = CreateConVar("sm_timeleft_interval", "0.0", "Display timeleft every x seconds. Default 0.", 0, true, 0.0, true, 1800.0);
|
||||
g_Cvar_FriendlyFire = FindConVar("mp_friendlyfire");
|
||||
|
||||
RegConsoleCmd("say", Command_Say);
|
||||
RegConsoleCmd("say_team", Command_Say);
|
||||
|
||||
RegConsoleCmd("timeleft", Command_Timeleft);
|
||||
|
||||
HookConVarChange(g_Cvar_TimeleftInterval, ConVarChange_TimeleftInterval);
|
||||
|
||||
|
||||
g_Cvar_WinLimit = FindConVar("mp_winlimit");
|
||||
g_Cvar_FragLimit = FindConVar("mp_fraglimit");
|
||||
g_Cvar_MaxRounds = FindConVar("mp_maxrounds");
|
||||
}
|
||||
|
||||
public ConVarChange_TimeleftInterval(Handle:convar, const String:oldValue[], const String:newValue[])
|
||||
{
|
||||
new Float:newval = StringToFloat(newValue);
|
||||
|
||||
if (newval < 1.0)
|
||||
{
|
||||
if (g_Timer_TimeShow != INVALID_HANDLE)
|
||||
{
|
||||
KillTimer(g_Timer_TimeShow);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_Timer_TimeShow != INVALID_HANDLE)
|
||||
{
|
||||
KillTimer(g_Timer_TimeShow);
|
||||
g_Timer_TimeShow = CreateTimer(newval, Timer_DisplayTimeleft, _, TIMER_REPEAT);
|
||||
}
|
||||
else
|
||||
g_Timer_TimeShow = CreateTimer(newval, Timer_DisplayTimeleft, _, TIMER_REPEAT);
|
||||
}
|
||||
|
||||
public Action:Timer_DisplayTimeleft(Handle:timer)
|
||||
{
|
||||
ShowTimeLeft(0, TIMELEFT_ALL_ALWAYS);
|
||||
}
|
||||
|
||||
public Action:Command_Timeleft(client, args)
|
||||
{
|
||||
ShowTimeLeft(client, TIMELEFT_ONE);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Say(client, args)
|
||||
{
|
||||
decl String:text[192], String:command[64];
|
||||
new startidx = 0;
|
||||
if (GetCmdArgString(text, sizeof(text)) < 1)
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
if (text[strlen(text)-1] == '"')
|
||||
{
|
||||
text[strlen(text)-1] = '\0';
|
||||
startidx = 1;
|
||||
}
|
||||
|
||||
if (strcmp(command, "say2", false) == 0)
|
||||
startidx += 4;
|
||||
|
||||
if (strcmp(text[startidx], "timeleft", false) == 0)
|
||||
{
|
||||
ShowTimeLeft(client, TIMELEFT_ALL_MAYBE);
|
||||
}
|
||||
else if (strcmp(text[startidx], "thetime", false) == 0)
|
||||
{
|
||||
decl String:ctime[64];
|
||||
FormatTime(ctime, 64, NULL_STRING);
|
||||
|
||||
if(GetConVarInt(g_Cvar_TriggerShow))
|
||||
{
|
||||
PrintToChatAll("[SM] %t", "Thetime", ctime);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintToChat(client,"[SM] %t", "Thetime", ctime);
|
||||
}
|
||||
}
|
||||
else if (strcmp(text[startidx], "ff", false) == 0 || strcmp(text[startidx], "/ff", false) == 0)
|
||||
{
|
||||
if (g_Cvar_FriendlyFire != INVALID_HANDLE)
|
||||
{
|
||||
decl String:message[64];
|
||||
if (GetConVarBool(g_Cvar_FriendlyFire))
|
||||
{
|
||||
Format(message, sizeof(message), "%T", "Friendly Fire On", client);
|
||||
}
|
||||
else
|
||||
{
|
||||
Format(message, sizeof(message), "%T", "Friendly Fire Off", client);
|
||||
}
|
||||
|
||||
if(GetConVarInt(g_Cvar_TriggerShow))
|
||||
{
|
||||
PrintToChatAll("[SM] %s", message);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintToChat(client,"[SM] %s", message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcmp(text[startidx], "currentmap", false) == 0)
|
||||
{
|
||||
decl String:map[64];
|
||||
GetCurrentMap(map, sizeof(map));
|
||||
|
||||
if(GetConVarInt(g_Cvar_TriggerShow))
|
||||
{
|
||||
PrintToChatAll("[SM] %t", "Current Map", map);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintToChat(client,"[SM] %t", "Current Map", map);
|
||||
}
|
||||
}
|
||||
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
ShowTimeLeft(client, who)
|
||||
{
|
||||
new bool:lastround = false;
|
||||
new bool:written = false;
|
||||
new bool:notimelimit = false;
|
||||
|
||||
decl String:finalOutput[1024];
|
||||
finalOutput[0] = 0;
|
||||
|
||||
if (who == TIMELEFT_ALL_ALWAYS
|
||||
|| (who == TIMELEFT_ALL_MAYBE && GetConVarInt(g_Cvar_TriggerShow)))
|
||||
{
|
||||
client = 0;
|
||||
}
|
||||
|
||||
new timeleft;
|
||||
if (GetMapTimeLeft(timeleft))
|
||||
{
|
||||
new mins, secs;
|
||||
new timelimit;
|
||||
|
||||
if (timeleft > 0)
|
||||
{
|
||||
mins = timeleft / 60;
|
||||
secs = timeleft % 60;
|
||||
written = true;
|
||||
FormatEx(finalOutput, sizeof(finalOutput), "%T %d:%02d", "Timeleft", client, mins, secs);
|
||||
}
|
||||
else if (GetMapTimeLimit(timelimit) && timelimit == 0)
|
||||
{
|
||||
notimelimit = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 0 timeleft so this must be the last round */
|
||||
lastround=true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!lastround)
|
||||
{
|
||||
if (g_Cvar_WinLimit != INVALID_HANDLE)
|
||||
{
|
||||
new winlimit = GetConVarInt(g_Cvar_WinLimit);
|
||||
|
||||
if (winlimit > 0)
|
||||
{
|
||||
if (written)
|
||||
{
|
||||
new len = strlen(finalOutput);
|
||||
if (len < sizeof(finalOutput))
|
||||
{
|
||||
FormatEx(finalOutput[len], sizeof(finalOutput)-len, "%T", "WinLimitAppend" ,client, winlimit, (winlimit == 1)? "":"s");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FormatEx(finalOutput, sizeof(finalOutput), "%T", "WinLimit", client, winlimit, (winlimit == 1)? "":"s");
|
||||
written = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Cvar_FragLimit != INVALID_HANDLE)
|
||||
{
|
||||
new fraglimit = GetConVarInt(g_Cvar_FragLimit);
|
||||
|
||||
if (fraglimit > 0)
|
||||
{
|
||||
if (written)
|
||||
{
|
||||
new len = strlen(finalOutput);
|
||||
if (len < sizeof(finalOutput))
|
||||
{
|
||||
FormatEx(finalOutput[len], sizeof(finalOutput)-len, "%T", "FragLimitAppend", client, fraglimit, (fraglimit == 1)? "":"s");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FormatEx(finalOutput, sizeof(finalOutput), "%T", "FragLimit", client, fraglimit, (fraglimit == 1)? "":"s");
|
||||
written = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Cvar_MaxRounds != INVALID_HANDLE)
|
||||
{
|
||||
new maxrounds = GetConVarInt(g_Cvar_MaxRounds);
|
||||
|
||||
if (maxrounds > 0)
|
||||
{
|
||||
if (written)
|
||||
{
|
||||
new len = strlen(finalOutput);
|
||||
if (len < sizeof(finalOutput))
|
||||
{
|
||||
FormatEx(finalOutput[len], sizeof(finalOutput)-len, "%T", "MaxRoundsAppend", client, maxrounds, (maxrounds == 1)? "":"s");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FormatEx(finalOutput, sizeof(finalOutput), "%T", "MaxRounds", client, maxrounds, (maxrounds == 1)? "":"s");
|
||||
written = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lastround)
|
||||
{
|
||||
FormatEx(finalOutput, sizeof(finalOutput), "%T", "LastRound", client);
|
||||
}
|
||||
else if (notimelimit && !written)
|
||||
{
|
||||
FormatEx(finalOutput, sizeof(finalOutput), "%T", "NoTimelimit", client);
|
||||
}
|
||||
|
||||
if (who == TIMELEFT_ALL_ALWAYS
|
||||
|| (who == TIMELEFT_ALL_MAYBE && GetConVarInt(g_Cvar_TriggerShow)))
|
||||
{
|
||||
PrintToChatAll("[SM] %s", finalOutput);
|
||||
}
|
||||
else if (client != 0)
|
||||
{
|
||||
PrintToChat(client, "[SM] %s", finalOutput);
|
||||
}
|
||||
|
||||
if (client == 0)
|
||||
{
|
||||
PrintToServer("[SM] %s", finalOutput);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,430 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basic Votes Plugin
|
||||
* Implements basic vote commands.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#undef REQUIRE_PLUGIN
|
||||
#include <adminmenu>
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "Basic Votes",
|
||||
author = "AlliedModders LLC",
|
||||
description = "Basic Vote Commands",
|
||||
version = SOURCEMOD_VERSION,
|
||||
url = "http://www.sourcemod.net/"
|
||||
};
|
||||
|
||||
#define VOTE_NO "###no###"
|
||||
#define VOTE_YES "###yes###"
|
||||
|
||||
new Handle:g_hVoteMenu = INVALID_HANDLE;
|
||||
|
||||
new Handle:g_Cvar_Limits[3] = {INVALID_HANDLE, ...};
|
||||
//new Handle:g_Cvar_VoteSay = INVALID_HANDLE;
|
||||
|
||||
enum voteType
|
||||
{
|
||||
map,
|
||||
kick,
|
||||
ban,
|
||||
question
|
||||
}
|
||||
|
||||
new voteType:g_voteType = voteType:question;
|
||||
|
||||
// Menu API does not provide us with a way to pass multiple peices of data with a single
|
||||
// choice, so some globals are used to hold stuff.
|
||||
//
|
||||
#define VOTE_CLIENTID 0
|
||||
#define VOTE_USERID 1
|
||||
new g_voteClient[2]; /* Holds the target's client id and user id */
|
||||
|
||||
#define VOTE_NAME 0
|
||||
#define VOTE_AUTHID 1
|
||||
#define VOTE_IP 2
|
||||
new String:g_voteInfo[3][65]; /* Holds the target's name, authid, and IP */
|
||||
|
||||
new String:g_voteArg[256]; /* Used to hold ban/kick reasons or vote questions */
|
||||
|
||||
|
||||
new Handle:hTopMenu = INVALID_HANDLE;
|
||||
|
||||
#include "basevotes/votekick.sp"
|
||||
#include "basevotes/voteban.sp"
|
||||
#include "basevotes/votemap.sp"
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
LoadTranslations("common.phrases");
|
||||
LoadTranslations("basevotes.phrases");
|
||||
LoadTranslations("plugin.basecommands");
|
||||
LoadTranslations("basebans.phrases");
|
||||
|
||||
RegAdminCmd("sm_votemap", Command_Votemap, ADMFLAG_VOTE|ADMFLAG_CHANGEMAP, "sm_votemap <mapname> [mapname2] ... [mapname5] ");
|
||||
RegAdminCmd("sm_votekick", Command_Votekick, ADMFLAG_VOTE|ADMFLAG_KICK, "sm_votekick <player> [reason]");
|
||||
RegAdminCmd("sm_voteban", Command_Voteban, ADMFLAG_VOTE|ADMFLAG_BAN, "sm_voteban <player> [reason]");
|
||||
RegAdminCmd("sm_vote", Command_Vote, ADMFLAG_VOTE, "sm_vote <question> [Answer1] [Answer2] ... [Answer5]");
|
||||
|
||||
/*
|
||||
g_Cvar_Show = FindConVar("sm_vote_show");
|
||||
if (g_Cvar_Show == INVALID_HANDLE)
|
||||
{
|
||||
g_Cvar_Show = CreateConVar("sm_vote_show", "1", "Show player's votes? Default on.", 0, true, 0.0, true, 1.0);
|
||||
}
|
||||
*/
|
||||
|
||||
g_Cvar_Limits[0] = CreateConVar("sm_vote_map", "0.60", "percent required for successful map vote.", 0, true, 0.05, true, 1.0);
|
||||
g_Cvar_Limits[1] = CreateConVar("sm_vote_kick", "0.60", "percent required for successful kick vote.", 0, true, 0.05, true, 1.0);
|
||||
g_Cvar_Limits[2] = CreateConVar("sm_vote_ban", "0.60", "percent required for successful ban vote.", 0, true, 0.05, true, 1.0);
|
||||
|
||||
/* Account for late loading */
|
||||
new Handle:topmenu;
|
||||
if (LibraryExists("adminmenu") && ((topmenu = GetAdminTopMenu()) != INVALID_HANDLE))
|
||||
{
|
||||
OnAdminMenuReady(topmenu);
|
||||
}
|
||||
|
||||
g_SelectedMaps = CreateArray(33);
|
||||
|
||||
g_MapList = CreateMenu(MenuHandler_Map, MenuAction_DrawItem);
|
||||
SetMenuTitle(g_MapList, "Please select a map");
|
||||
SetMenuExitBackButton(g_MapList, true);
|
||||
|
||||
decl String:mapListPath[PLATFORM_MAX_PATH];
|
||||
BuildPath(Path_SM, mapListPath, sizeof(mapListPath), "configs/adminmenu_maplist.ini");
|
||||
SetMapListCompatBind("sm_votemap menu", mapListPath);
|
||||
}
|
||||
|
||||
public OnConfigsExecuted()
|
||||
{
|
||||
g_mapCount = LoadMapList(g_MapList);
|
||||
}
|
||||
|
||||
public OnAdminMenuReady(Handle:topmenu)
|
||||
{
|
||||
/* Block us from being called twice */
|
||||
if (topmenu == hTopMenu)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save the Handle */
|
||||
hTopMenu = topmenu;
|
||||
|
||||
/* Build the "Voting Commands" category */
|
||||
new TopMenuObject:voting_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_VOTINGCOMMANDS);
|
||||
|
||||
if (voting_commands != INVALID_TOPMENUOBJECT)
|
||||
{
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_votekick",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_VoteKick,
|
||||
voting_commands,
|
||||
"sm_votekick",
|
||||
ADMFLAG_VOTE|ADMFLAG_KICK);
|
||||
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_voteban",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_VoteBan,
|
||||
voting_commands,
|
||||
"sm_voteban",
|
||||
ADMFLAG_VOTE|ADMFLAG_BAN);
|
||||
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_votemap",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_VoteMap,
|
||||
voting_commands,
|
||||
"sm_votemap",
|
||||
ADMFLAG_VOTE|ADMFLAG_CHANGEMAP);
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_Vote(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_vote <question> [Answer1] [Answer2] ... [Answer5]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (IsVoteInProgress())
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Vote in Progress");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (!TestVoteDelay(client))
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:text[256];
|
||||
GetCmdArgString(text, sizeof(text));
|
||||
|
||||
decl String:answers[5][64];
|
||||
new answerCount;
|
||||
new len = BreakString(text, g_voteArg, sizeof(g_voteArg));
|
||||
new pos = len;
|
||||
|
||||
while (args > 1 && pos != -1 && answerCount < 5)
|
||||
{
|
||||
pos = BreakString(text[len], answers[answerCount], sizeof(answers[]));
|
||||
answerCount++;
|
||||
|
||||
if (pos != -1)
|
||||
{
|
||||
len += pos;
|
||||
}
|
||||
}
|
||||
|
||||
LogAction(client, -1, "\"%L\" initiated a generic vote.", client);
|
||||
ShowActivity2(client, "[SM] ", "%t", "Initiate Vote", g_voteArg);
|
||||
|
||||
g_voteType = voteType:question;
|
||||
|
||||
g_hVoteMenu = CreateMenu(Handler_VoteCallback, MenuAction:MENU_ACTIONS_ALL);
|
||||
SetMenuTitle(g_hVoteMenu, "%s?", g_voteArg);
|
||||
|
||||
if (answerCount < 2)
|
||||
{
|
||||
AddMenuItem(g_hVoteMenu, VOTE_YES, "Yes");
|
||||
AddMenuItem(g_hVoteMenu, VOTE_NO, "No");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (new i = 0; i < answerCount; i++)
|
||||
{
|
||||
AddMenuItem(g_hVoteMenu, answers[i], answers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
SetMenuExitButton(g_hVoteMenu, false);
|
||||
VoteMenuToAll(g_hVoteMenu, 20);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Handler_VoteCallback(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
VoteMenuClose();
|
||||
}
|
||||
else if (action == MenuAction_Display)
|
||||
{
|
||||
if (g_voteType != voteType:question)
|
||||
{
|
||||
decl String:title[64];
|
||||
GetMenuTitle(menu, title, sizeof(title));
|
||||
|
||||
decl String:buffer[255];
|
||||
Format(buffer, sizeof(buffer), "%T", title, param1, g_voteInfo[VOTE_NAME]);
|
||||
|
||||
new Handle:panel = Handle:param2;
|
||||
SetPanelTitle(panel, buffer);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_DisplayItem)
|
||||
{
|
||||
decl String:display[64];
|
||||
GetMenuItem(menu, param2, "", 0, _, display, sizeof(display));
|
||||
|
||||
if (strcmp(display, "No") == 0 || strcmp(display, "Yes") == 0)
|
||||
{
|
||||
decl String:buffer[255];
|
||||
Format(buffer, sizeof(buffer), "%T", display, param1);
|
||||
|
||||
return RedrawMenuItem(buffer);
|
||||
}
|
||||
}
|
||||
/* else if (action == MenuAction_Select)
|
||||
{
|
||||
VoteSelect(menu, param1, param2);
|
||||
}*/
|
||||
else if (action == MenuAction_VoteCancel && param1 == VoteCancel_NoVotes)
|
||||
{
|
||||
PrintToChatAll("[SM] %t", "No Votes Cast");
|
||||
}
|
||||
else if (action == MenuAction_VoteEnd)
|
||||
{
|
||||
decl String:item[64], String:display[64];
|
||||
new Float:percent, Float:limit, votes, totalVotes;
|
||||
|
||||
GetMenuVoteInfo(param2, votes, totalVotes);
|
||||
GetMenuItem(menu, param1, item, sizeof(item), _, display, sizeof(display));
|
||||
|
||||
if (strcmp(item, VOTE_NO) == 0 && param1 == 1)
|
||||
{
|
||||
votes = totalVotes - votes; // Reverse the votes to be in relation to the Yes option.
|
||||
}
|
||||
|
||||
percent = GetVotePercent(votes, totalVotes);
|
||||
|
||||
if (g_voteType != voteType:question)
|
||||
{
|
||||
limit = GetConVarFloat(g_Cvar_Limits[g_voteType]);
|
||||
}
|
||||
|
||||
/* :TODO: g_voteClient[userid] needs to be checked */
|
||||
|
||||
// A multi-argument vote is "always successful", but have to check if its a Yes/No vote.
|
||||
if ((strcmp(item, VOTE_YES) == 0 && FloatCompare(percent,limit) < 0 && param1 == 0) || (strcmp(item, VOTE_NO) == 0 && param1 == 1))
|
||||
{
|
||||
/* :TODO: g_voteClient[userid] should be used here and set to -1 if not applicable.
|
||||
*/
|
||||
LogAction(-1, -1, "Vote failed.");
|
||||
PrintToChatAll("[SM] %t", "Vote Failed", RoundToNearest(100.0*limit), RoundToNearest(100.0*percent), totalVotes);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintToChatAll("[SM] %t", "Vote Successful", RoundToNearest(100.0*percent), totalVotes);
|
||||
|
||||
switch (g_voteType)
|
||||
{
|
||||
case (voteType:question):
|
||||
{
|
||||
if (strcmp(item, VOTE_NO) == 0 || strcmp(item, VOTE_YES) == 0)
|
||||
{
|
||||
strcopy(item, sizeof(item), display);
|
||||
}
|
||||
|
||||
PrintToChatAll("[SM] %t", "Vote End", g_voteArg, item);
|
||||
}
|
||||
|
||||
case (voteType:map):
|
||||
{
|
||||
LogAction(-1, -1, "Changing map to %s due to vote.", item);
|
||||
PrintToChatAll("[SM] %t", "Changing map", item);
|
||||
new Handle:dp;
|
||||
CreateDataTimer(5.0, Timer_ChangeMap, dp);
|
||||
WritePackString(dp, item);
|
||||
}
|
||||
|
||||
case (voteType:kick):
|
||||
{
|
||||
if (g_voteArg[0] == '\0')
|
||||
{
|
||||
strcopy(g_voteArg, sizeof(g_voteArg), "Votekicked");
|
||||
}
|
||||
|
||||
PrintToChatAll("[SM] %t", "Kicked target", "_s", g_voteInfo[VOTE_NAME]);
|
||||
LogAction(-1, g_voteClient[VOTE_CLIENTID], "Vote kick successful, kicked \"%L\" (reason \"%s\")", g_voteClient[VOTE_CLIENTID], g_voteArg);
|
||||
|
||||
ServerCommand("kickid %d \"%s\"", g_voteClient[VOTE_USERID], g_voteArg);
|
||||
}
|
||||
|
||||
case (voteType:ban):
|
||||
{
|
||||
if (g_voteArg[0] == '\0')
|
||||
{
|
||||
strcopy(g_voteArg, sizeof(g_voteArg), "Votebanned");
|
||||
}
|
||||
|
||||
PrintToChatAll("[SM] %t", "Banned player", g_voteInfo[VOTE_NAME], 30);
|
||||
LogAction(-1, g_voteClient[VOTE_CLIENTID], "Vote ban successful, banned \"%L\" (minutes \"30\") (reason \"%s\")", g_voteClient[VOTE_CLIENTID], g_voteArg);
|
||||
|
||||
BanClient(g_voteClient[VOTE_CLIENTID],
|
||||
30,
|
||||
BANFLAG_AUTO,
|
||||
g_voteArg,
|
||||
"Banned by vote",
|
||||
"sm_voteban");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
VoteSelect(Handle:menu, param1, param2 = 0)
|
||||
{
|
||||
if (GetConVarInt(g_Cvar_VoteShow) == 1)
|
||||
{
|
||||
decl String:voter[64], String:junk[64], String:choice[64];
|
||||
GetClientName(param1, voter, sizeof(voter));
|
||||
GetMenuItem(menu, param2, junk, sizeof(junk), _, choice, sizeof(choice));
|
||||
PrintToChatAll("[SM] %T", "Vote Select", LANG_SERVER, voter, choice);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
VoteMenuClose()
|
||||
{
|
||||
CloseHandle(g_hVoteMenu);
|
||||
g_hVoteMenu = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
Float:GetVotePercent(votes, totalVotes)
|
||||
{
|
||||
return FloatDiv(float(votes),float(totalVotes));
|
||||
}
|
||||
|
||||
bool:TestVoteDelay(client)
|
||||
{
|
||||
new delay = CheckVoteDelay();
|
||||
|
||||
if (delay > 0)
|
||||
{
|
||||
if (delay > 60)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Vote Delay Minutes", delay % 60);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Vote Delay Seconds", delay);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Action:Timer_ChangeMap(Handle:timer, Handle:dp)
|
||||
{
|
||||
decl String:mapname[65];
|
||||
|
||||
ResetPack(dp);
|
||||
ReadPackString(dp, mapname, sizeof(mapname));
|
||||
|
||||
ServerCommand("changelevel \"%s\"", mapname);
|
||||
|
||||
return Plugin_Stop;
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basevotes Plugin
|
||||
* Provides ban functionality
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
DisplayVoteBanMenu(client, target)
|
||||
{
|
||||
g_voteClient[VOTE_CLIENTID] = target;
|
||||
g_voteClient[VOTE_USERID] = GetClientUserId(target);
|
||||
|
||||
GetClientName(target, g_voteInfo[VOTE_NAME], sizeof(g_voteInfo[]));
|
||||
GetClientAuthString(target, g_voteInfo[VOTE_AUTHID], sizeof(g_voteInfo[]));
|
||||
GetClientIP(target, g_voteInfo[VOTE_IP], sizeof(g_voteInfo[]));
|
||||
|
||||
LogAction(client, target, "\"%L\" initiated a ban vote against \"%L\"", client, target);
|
||||
ShowActivity2(client, "[SM] ", "%t", "Initiated Vote Ban", g_voteInfo[VOTE_NAME]);
|
||||
|
||||
g_voteType = voteType:ban;
|
||||
|
||||
g_hVoteMenu = CreateMenu(Handler_VoteCallback, MenuAction:MENU_ACTIONS_ALL);
|
||||
SetMenuTitle(g_hVoteMenu, "Voteban Player");
|
||||
AddMenuItem(g_hVoteMenu, VOTE_YES, "Yes");
|
||||
AddMenuItem(g_hVoteMenu, VOTE_NO, "No");
|
||||
SetMenuExitButton(g_hVoteMenu, false);
|
||||
VoteMenuToAll(g_hVoteMenu, 20);
|
||||
}
|
||||
|
||||
DisplayBanTargetMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_Ban);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Ban vote", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddTargetsToMenu(menu, client, false, false);
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
public AdminMenu_VoteBan(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Ban vote", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayBanTargetMenu(param);
|
||||
}
|
||||
else if (action == TopMenuAction_DrawOption)
|
||||
{
|
||||
/* disable this option if a vote is already running */
|
||||
buffer[0] = !IsNewVoteAllowed() ? ITEMDRAW_IGNORE : ITEMDRAW_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
public MenuHandler_Ban(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32], String:name[32];
|
||||
new userid, target;
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info), _, name, sizeof(name));
|
||||
userid = StringToInt(info);
|
||||
|
||||
if ((target = GetClientOfUserId(userid)) == 0)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player no longer available");
|
||||
}
|
||||
else if (!CanUserTarget(param1, target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Unable to target");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_voteArg[0] = '\0';
|
||||
DisplayVoteBanMenu(param1, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_Voteban(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_voteban <player> [reason]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (IsVoteInProgress())
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Vote in Progress");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (!TestVoteDelay(client))
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:text[256], String:arg[64];
|
||||
GetCmdArgString(text, sizeof(text));
|
||||
|
||||
new len = BreakString(text, arg, sizeof(arg));
|
||||
|
||||
if (len != -1)
|
||||
{
|
||||
strcopy(g_voteArg, sizeof(g_voteArg), text[len]);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_voteArg[0] = '\0';
|
||||
}
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_NO_MULTI|COMMAND_FILTER_NO_BOTS,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
DisplayVoteBanMenu(client, target_list[0]);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basevotes Plugin
|
||||
* Provides kick functionality
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
|
||||
DisplayVoteKickMenu(client, target)
|
||||
{
|
||||
g_voteClient[VOTE_CLIENTID] = target;
|
||||
g_voteClient[VOTE_USERID] = GetClientUserId(target);
|
||||
|
||||
GetClientName(target, g_voteInfo[VOTE_NAME], sizeof(g_voteInfo[]));
|
||||
|
||||
LogAction(client, target, "\"%L\" initiated a kick vote against \"%L\"", client, target);
|
||||
ShowActivity(client, "%t", "Initiated Vote Kick", g_voteInfo[VOTE_NAME]);
|
||||
|
||||
g_voteType = voteType:kick;
|
||||
|
||||
g_hVoteMenu = CreateMenu(Handler_VoteCallback, MenuAction:MENU_ACTIONS_ALL);
|
||||
SetMenuTitle(g_hVoteMenu, "Votekick Player");
|
||||
AddMenuItem(g_hVoteMenu, VOTE_YES, "Yes");
|
||||
AddMenuItem(g_hVoteMenu, VOTE_NO, "No");
|
||||
SetMenuExitButton(g_hVoteMenu, false);
|
||||
VoteMenuToAll(g_hVoteMenu, 20);
|
||||
|
||||
}
|
||||
|
||||
DisplayKickTargetMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_Kick);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Kick vote", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddTargetsToMenu(menu, client, false, false);
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
public AdminMenu_VoteKick(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Kick vote", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayKickTargetMenu(param);
|
||||
}
|
||||
else if (action == TopMenuAction_DrawOption)
|
||||
{
|
||||
/* disable this option if a vote is already running */
|
||||
buffer[0] = !IsNewVoteAllowed() ? ITEMDRAW_IGNORE : ITEMDRAW_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
public MenuHandler_Kick(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32], String:name[32];
|
||||
new userid, target;
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info), _, name, sizeof(name));
|
||||
userid = StringToInt(info);
|
||||
|
||||
if ((target = GetClientOfUserId(userid)) == 0)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player no longer available");
|
||||
}
|
||||
else if (!CanUserTarget(param1, target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Unable to target");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_voteArg[0] = '\0';
|
||||
DisplayVoteKickMenu(param1, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_Votekick(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_votekick <player> [reason]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (IsVoteInProgress())
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Vote in Progress");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (!TestVoteDelay(client))
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:text[256], String:arg[64];
|
||||
GetCmdArgString(text, sizeof(text));
|
||||
|
||||
new len = BreakString(text, arg, sizeof(arg));
|
||||
|
||||
new target = FindTarget(client, arg);
|
||||
if (target == -1)
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (len != -1)
|
||||
{
|
||||
strcopy(g_voteArg, sizeof(g_voteArg), text[len]);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_voteArg[0] = '\0';
|
||||
}
|
||||
|
||||
DisplayVoteKickMenu(client, target);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basevotes Plugin
|
||||
* Provides map functionality
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
new Handle:g_MapList = INVALID_HANDLE;
|
||||
new g_mapCount;
|
||||
|
||||
new Handle:g_SelectedMaps;
|
||||
new bool:g_VoteMapInUse;
|
||||
|
||||
DisplayVoteMapMenu(client, mapCount, String:maps[5][])
|
||||
{
|
||||
LogAction(client, -1, "\"%L\" initiated a map vote.", client);
|
||||
ShowActivity2(client, "[SM] ", "%t", "Initiated Vote Map");
|
||||
|
||||
g_voteType = voteType:map;
|
||||
|
||||
g_hVoteMenu = CreateMenu(Handler_VoteCallback, MenuAction:MENU_ACTIONS_ALL);
|
||||
|
||||
if (mapCount == 1)
|
||||
{
|
||||
strcopy(g_voteInfo[VOTE_NAME], sizeof(g_voteInfo[]), maps[0]);
|
||||
|
||||
SetMenuTitle(g_hVoteMenu, "Change Map To");
|
||||
AddMenuItem(g_hVoteMenu, maps[0], "Yes");
|
||||
AddMenuItem(g_hVoteMenu, VOTE_NO, "No");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_voteInfo[VOTE_NAME][0] = '\0';
|
||||
|
||||
SetMenuTitle(g_hVoteMenu, "Map Vote");
|
||||
for (new i = 0; i < mapCount; i++)
|
||||
{
|
||||
AddMenuItem(g_hVoteMenu, maps[i], maps[i]);
|
||||
}
|
||||
}
|
||||
|
||||
SetMenuExitButton(g_hVoteMenu, false);
|
||||
VoteMenuToAll(g_hVoteMenu, 20);
|
||||
}
|
||||
|
||||
ResetMenu()
|
||||
{
|
||||
g_VoteMapInUse = false;
|
||||
ClearArray(g_SelectedMaps);
|
||||
}
|
||||
|
||||
ConfirmVote(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_Confirm);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Confirm Vote", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddMenuItem(menu, "Confirm", "Start the Vote");
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
public MenuHandler_Confirm(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
g_VoteMapInUse = false;
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
ResetMenu();
|
||||
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:maps[5][64];
|
||||
new selectedmaps = GetArraySize(g_SelectedMaps);
|
||||
|
||||
for (new i = 0; i < selectedmaps; i++)
|
||||
{
|
||||
GetArrayString(g_SelectedMaps, i, maps[i], sizeof(maps[]));
|
||||
}
|
||||
|
||||
DisplayVoteMapMenu(param1, selectedmaps, maps);
|
||||
|
||||
ResetMenu();
|
||||
}
|
||||
}
|
||||
|
||||
public MenuHandler_Map(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
ConfirmVote(param1);
|
||||
}
|
||||
else // no action was selected.
|
||||
{
|
||||
/* Re-enable the menu option */
|
||||
g_VoteMapInUse = false;
|
||||
|
||||
ResetMenu();
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_DrawItem)
|
||||
{
|
||||
decl String:info[32], String:name[32];
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info), _, name, sizeof(name));
|
||||
|
||||
if (FindStringInArray(g_SelectedMaps, info) != -1)
|
||||
{
|
||||
return ITEMDRAW_IGNORE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ITEMDRAW_DEFAULT;
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32], String:name[32];
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info), _, name, sizeof(name));
|
||||
|
||||
PushArrayString(g_SelectedMaps, info);
|
||||
|
||||
/* Redisplay the list */
|
||||
if (GetArraySize(g_SelectedMaps) < 5)
|
||||
{
|
||||
DisplayMenu(g_MapList, param1, MENU_TIME_FOREVER);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConfirmVote(param1);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public AdminMenu_VoteMap(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Map vote", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
g_VoteMapInUse = true;
|
||||
ResetMenu();
|
||||
DisplayMenu(g_MapList, param, MENU_TIME_FOREVER);
|
||||
}
|
||||
else if (action == TopMenuAction_DrawOption)
|
||||
{
|
||||
/* disable this option if a vote is already running, theres no maps listed or someone else has already acessed this menu */
|
||||
buffer[0] = (!IsNewVoteAllowed() || g_mapCount < 1 || g_VoteMapInUse) ? ITEMDRAW_IGNORE : ITEMDRAW_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_Votemap(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_votemap <mapname> [mapname2] ... [mapname5]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (IsVoteInProgress())
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Vote in Progress");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (!TestVoteDelay(client))
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:text[256];
|
||||
GetCmdArgString(text, sizeof(text));
|
||||
|
||||
decl String:maps[5][64];
|
||||
new mapCount;
|
||||
new len, pos;
|
||||
|
||||
while (pos != -1 && mapCount < 5)
|
||||
{
|
||||
pos = BreakString(text[len], maps[mapCount], sizeof(maps[]));
|
||||
|
||||
if (!IsMapValid(maps[mapCount]))
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Map was not found", maps[mapCount]);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
mapCount++;
|
||||
|
||||
if (pos != -1)
|
||||
{
|
||||
len += pos;
|
||||
}
|
||||
}
|
||||
|
||||
DisplayVoteMapMenu(client, mapCount, maps);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new Handle:g_map_array = INVALID_HANDLE;
|
||||
new g_map_serial = -1;
|
||||
|
||||
LoadMapList(Handle:menu)
|
||||
{
|
||||
new Handle:map_array;
|
||||
|
||||
if ((map_array = ReadMapList(g_map_array,
|
||||
g_map_serial,
|
||||
"sm_votemap menu",
|
||||
MAPLIST_FLAG_CLEARARRAY|MAPLIST_FLAG_NO_DEFAULT|MAPLIST_FLAG_MAPSFOLDER))
|
||||
!= INVALID_HANDLE)
|
||||
{
|
||||
g_map_array = map_array;
|
||||
}
|
||||
|
||||
if (g_map_array == INVALID_HANDLE)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
RemoveAllMenuItems(menu);
|
||||
|
||||
decl String:map_name[64];
|
||||
new map_count = GetArraySize(g_map_array);
|
||||
|
||||
for (new i = 0; i < map_count; i++)
|
||||
{
|
||||
GetArrayString(g_map_array, i, map_name, sizeof(map_name));
|
||||
AddMenuItem(menu, map_name, map_name);
|
||||
}
|
||||
|
||||
return map_count;
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Map Management Plugin
|
||||
* Provides all map related functionality, including map changing, map voting,
|
||||
* and nextmap.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
|
||||
#pragma semicolon 1
|
||||
#include <sourcemod>
|
||||
#include <clientprefs>
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "Client Preferences",
|
||||
author = "AlliedModders LLC",
|
||||
description = "Client peferences and settings menu",
|
||||
version = SOURCEMOD_VERSION,
|
||||
url = "http://www.sourcemod.net/"
|
||||
};
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
LoadTranslations("clientprefs.phrases");
|
||||
|
||||
RegConsoleCmd("sm_cookies", Command_Cookie, "sm_cookies <name> [value]");
|
||||
RegConsoleCmd("sm_settings", Command_Settings);
|
||||
}
|
||||
|
||||
public Action:Command_Cookie(client, args)
|
||||
{
|
||||
if (args == 0)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_cookie <name> [value]");
|
||||
ReplyToCommand(client, "[SM] %t", "Printing Cookie List");
|
||||
|
||||
/* Show list of cookies */
|
||||
new Handle:iter = GetCookieIterator();
|
||||
|
||||
decl String:name[30];
|
||||
name[0] = '\0';
|
||||
decl String:description[255];
|
||||
description[0] = '\0';
|
||||
|
||||
PrintToConsole(client, "%t:", "Cookie List");
|
||||
|
||||
new CookieAccess:access;
|
||||
|
||||
while (ReadCookieIterator(iter,
|
||||
name,
|
||||
sizeof(name),
|
||||
access,
|
||||
description,
|
||||
sizeof(description)) != false)
|
||||
{
|
||||
if (access < CookieAccess_Private)
|
||||
{
|
||||
PrintToConsole(client, "%s - %s", name, description);
|
||||
}
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (client == 0)
|
||||
{
|
||||
PrintToServer("%T", "No Console", LANG_SERVER);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:name[30];
|
||||
name[0] = '\0';
|
||||
GetCmdArg(1, name, sizeof(name));
|
||||
|
||||
new Handle:cookie = FindClientCookie(name);
|
||||
|
||||
if (cookie == INVALID_HANDLE)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Cookie not Found", name);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new CookieAccess:access = GetCookieAccess(cookie);
|
||||
|
||||
if (access == CookieAccess_Private)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Cookie not Found", name);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:value[100];
|
||||
value[0] = '\0';
|
||||
|
||||
if (args == 1)
|
||||
{
|
||||
GetClientCookie(client, cookie, value, sizeof(value));
|
||||
ReplyToCommand(client, "[SM] %t", "Cookie Value", name, value);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (access == CookieAccess_Protected)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Protected Cookie", name);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
/* Set the new value of the cookie */
|
||||
|
||||
GetCmdArg(2, value, sizeof(value));
|
||||
|
||||
SetClientCookie(client, cookie, value);
|
||||
ReplyToCommand(client, "[SM] %t", "Cookie Changed Value", name, value);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_Settings(client, args)
|
||||
{
|
||||
if (client == 0)
|
||||
{
|
||||
PrintToServer("%T", "No Console", LANG_SERVER);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
ShowCookieMenu(client);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
Executable
+11
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
test -e compiled || mkdir compiled
|
||||
|
||||
for sourcefile in *.sp
|
||||
do
|
||||
smxfile="`echo $sourcefile | sed -e 's/\.sp$/\.smx/'`"
|
||||
echo -n "Compiling $sourcefile ..."
|
||||
./spcomp $sourcefile -ocompiled/$smxfile
|
||||
done
|
||||
|
||||
@@ -0,0 +1,412 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basic Fun Commands Plugin
|
||||
* Implements basic punishment commands.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
#undef REQUIRE_PLUGIN
|
||||
#include <adminmenu>
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "Fun Commands",
|
||||
author = "AlliedModders LLC",
|
||||
description = "Fun Commands",
|
||||
version = SOURCEMOD_VERSION,
|
||||
url = "http://www.sourcemod.net/"
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
// Set any of these to 0 and recompile to completely disable those commands
|
||||
// -------------------------------------------------------------------------------
|
||||
#define BEACON 1
|
||||
#define TIMEBOMB 1
|
||||
#define FIRE 1
|
||||
#define ICE 1
|
||||
#define GRAVITY 1
|
||||
#define BLIND 1
|
||||
#define NOCLIP 1
|
||||
#define DRUG 1
|
||||
#define TELEPORT 1
|
||||
#define HEALTH 1
|
||||
#define COLORS 1
|
||||
#define CASH 1
|
||||
// -------------------------------------------------------------------------------
|
||||
|
||||
new Handle:hTopMenu = INVALID_HANDLE;
|
||||
|
||||
// Sounds
|
||||
#define SOUND_BLIP "buttons/blip1.wav"
|
||||
#define SOUND_BEEP "buttons/button17.wav"
|
||||
#define SOUND_FINAL "weapons/cguard/charging.wav"
|
||||
#define SOUND_BOOM "weapons/explode3.wav"
|
||||
#define SOUND_FREEZE "physics/glass/glass_impact_bullet4.wav"
|
||||
|
||||
// Following are model indexes for temp entities
|
||||
new g_BeamSprite;
|
||||
new g_BeamSprite2;
|
||||
new g_HaloSprite;
|
||||
new g_GlowSprite;
|
||||
new g_ExplosionSprite;
|
||||
|
||||
// Basic color arrays for temp entities
|
||||
new redColor[4] = {255, 75, 75, 255};
|
||||
new orangeColor[4] = {255, 128, 0, 255};
|
||||
new greenColor[4] = {75, 255, 75, 255};
|
||||
new blueColor[4] = {75, 75, 255, 255};
|
||||
new whiteColor[4] = {255, 255, 255, 255};
|
||||
new greyColor[4] = {128, 128, 128, 255};
|
||||
|
||||
// UserMessageId for Fade.
|
||||
new UserMsg:g_FadeUserMsgId;
|
||||
|
||||
// Include various commands and supporting functions
|
||||
#if BEACON
|
||||
#include "funcommands/beacon.sp"
|
||||
#endif
|
||||
#if TIMEBOMB
|
||||
#include "funcommands/timebomb.sp"
|
||||
#endif
|
||||
#if FIRE
|
||||
#include "funcommands/fire.sp"
|
||||
#endif
|
||||
#if ICE
|
||||
#include "funcommands/ice.sp"
|
||||
#endif
|
||||
#if GRAVITY
|
||||
#include "funcommands/gravity.sp"
|
||||
#endif
|
||||
#if BLIND
|
||||
#include "funcommands/blind.sp"
|
||||
#endif
|
||||
#if NOCLIP
|
||||
#include "funcommands/noclip.sp"
|
||||
#endif
|
||||
#if DRUG
|
||||
#include "funcommands/drug.sp"
|
||||
#endif
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
if (FindPluginByFile("basefuncommands.smx") != INVALID_HANDLE)
|
||||
{
|
||||
ThrowError("This plugin replaces basefuncommands. You cannot run both at once.");
|
||||
}
|
||||
|
||||
LoadTranslations("common.phrases");
|
||||
LoadTranslations("funcommands.phrases");
|
||||
|
||||
g_FadeUserMsgId = GetUserMessageId("Fade");
|
||||
|
||||
RegAdminCmd("sm_play", Command_Play, ADMFLAG_GENERIC, "sm_play <#userid|name> <filename>");
|
||||
|
||||
HookEvent("round_end", Event_RoundEnd, EventHookMode_PostNoCopy);
|
||||
|
||||
#if BEACON
|
||||
SetupBeacon(); // sm_beacon
|
||||
#endif
|
||||
|
||||
#if TIMEBOMB
|
||||
SetupTimeBomb(); // sm_timebomb
|
||||
#endif
|
||||
|
||||
#if FIRE
|
||||
SetupFire(); // sm_burn and sm_firebomb
|
||||
#endif
|
||||
|
||||
#if ICE
|
||||
SetupIce(); // sm_freeze and sm_freezebomb
|
||||
#endif
|
||||
|
||||
#if GRAVITY
|
||||
SetupGravity(); // sm_gravity
|
||||
#endif
|
||||
|
||||
#if BLIND
|
||||
SetupBlind(); // sm_blind
|
||||
#endif
|
||||
|
||||
#if NOCLIP
|
||||
SetupNoClip(); // sm_noclip
|
||||
#endif
|
||||
|
||||
#if DRUG
|
||||
SetupDrugs(); // sm_drug
|
||||
#endif
|
||||
|
||||
AutoExecConfig(true, "funcommands");
|
||||
|
||||
/* Account for late loading */
|
||||
new Handle:topmenu;
|
||||
if (LibraryExists("adminmenu") && ((topmenu = GetAdminTopMenu()) != INVALID_HANDLE))
|
||||
{
|
||||
OnAdminMenuReady(topmenu);
|
||||
}
|
||||
}
|
||||
|
||||
public OnMapStart()
|
||||
{
|
||||
PrecacheSound(SOUND_BLIP, true);
|
||||
PrecacheSound(SOUND_BEEP, true);
|
||||
PrecacheSound(SOUND_FINAL, true);
|
||||
PrecacheSound(SOUND_BOOM, true);
|
||||
PrecacheSound(SOUND_FREEZE, true);
|
||||
|
||||
g_BeamSprite = PrecacheModel("materials/sprites/laser.vmt");
|
||||
g_BeamSprite2 = PrecacheModel("sprites/bluelight1.vmt");
|
||||
g_HaloSprite = PrecacheModel("materials/sprites/halo01.vmt");
|
||||
g_GlowSprite = PrecacheModel("sprites/blueglow2.vmt");
|
||||
g_ExplosionSprite = PrecacheModel("sprites/sprite_fire01.vmt");
|
||||
}
|
||||
|
||||
public OnMapEnd()
|
||||
{
|
||||
#if BEACON
|
||||
KillAllBeacons();
|
||||
#endif
|
||||
#if TIMEBOMB
|
||||
KillAllTimeBombs();
|
||||
#endif
|
||||
#if FIRE
|
||||
KillAllFireBombs();
|
||||
#endif
|
||||
#if ICE
|
||||
KillAllFreezes();
|
||||
#endif
|
||||
#if DRUG
|
||||
KillAllDrugs();
|
||||
#endif
|
||||
}
|
||||
|
||||
public Action:Event_RoundEnd(Handle:event,const String:name[],bool:dontBroadcast)
|
||||
{
|
||||
#if BEACON
|
||||
KillAllBeacons();
|
||||
#endif
|
||||
#if TIMEBOMB
|
||||
KillAllTimeBombs();
|
||||
#endif
|
||||
#if FIRE
|
||||
KillAllFireBombs();
|
||||
#endif
|
||||
#if ICE
|
||||
KillAllFreezes();
|
||||
#endif
|
||||
#if DRUG
|
||||
KillAllDrugs();
|
||||
#endif
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public OnAdminMenuReady(Handle:topmenu)
|
||||
{
|
||||
/* Block us from being called twice */
|
||||
if (topmenu == hTopMenu)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save the Handle */
|
||||
hTopMenu = topmenu;
|
||||
|
||||
/* Find the "Player Commands" category */
|
||||
new TopMenuObject:player_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_PLAYERCOMMANDS);
|
||||
|
||||
if (player_commands != INVALID_TOPMENUOBJECT)
|
||||
{
|
||||
#if BEACON
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_beacon",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_Beacon,
|
||||
player_commands,
|
||||
"sm_beacon",
|
||||
ADMFLAG_SLAY);
|
||||
#endif
|
||||
|
||||
#if TIMEBOMB
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_timebomb",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_TimeBomb,
|
||||
player_commands,
|
||||
"sm_timebomb",
|
||||
ADMFLAG_SLAY);
|
||||
#endif
|
||||
|
||||
#if FIRE
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_burn",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_Burn,
|
||||
player_commands,
|
||||
"sm_burn",
|
||||
ADMFLAG_SLAY);
|
||||
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_firebomb",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_FireBomb,
|
||||
player_commands,
|
||||
"sm_firebomb",
|
||||
ADMFLAG_SLAY);
|
||||
#endif
|
||||
|
||||
#if ICE
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_freeze",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_Freeze,
|
||||
player_commands,
|
||||
"sm_freeze",
|
||||
ADMFLAG_SLAY);
|
||||
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_freezebomb",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_FreezeBomb,
|
||||
player_commands,
|
||||
"sm_freezebomb",
|
||||
ADMFLAG_SLAY);
|
||||
#endif
|
||||
|
||||
#if GRAVITY
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_gravity",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_Gravity,
|
||||
player_commands,
|
||||
"sm_gravity",
|
||||
ADMFLAG_SLAY);
|
||||
#endif
|
||||
|
||||
#if BLIND
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_blind",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_Blind,
|
||||
player_commands,
|
||||
"sm_blind",
|
||||
ADMFLAG_SLAY);
|
||||
#endif
|
||||
|
||||
#if NOCLIP
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_noclip",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_NoClip,
|
||||
player_commands,
|
||||
"sm_noclip",
|
||||
ADMFLAG_SLAY);
|
||||
#endif
|
||||
|
||||
#if DRUG
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_drug",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_Drug,
|
||||
player_commands,
|
||||
"sm_drug",
|
||||
ADMFLAG_SLAY);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_Play(client, args)
|
||||
{
|
||||
if (args < 2)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_play <#userid|name> <filename>");
|
||||
}
|
||||
|
||||
new String:Arguments[PLATFORM_MAX_PATH + 65];
|
||||
GetCmdArgString(Arguments, sizeof(Arguments));
|
||||
|
||||
decl String:Arg[65];
|
||||
new len = BreakString(Arguments, Arg, sizeof(Arg));
|
||||
|
||||
/* Make sure it does not go out of bound by doing "sm_play user "*/
|
||||
if (len == -1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_play <#userid|name> <filename>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
/* Incase they put quotes and white spaces after the quotes */
|
||||
if (Arguments[len] == '"')
|
||||
{
|
||||
len++;
|
||||
new FileLen = TrimString(Arguments[len]) + len;
|
||||
|
||||
if (Arguments[FileLen - 1] == '"')
|
||||
{
|
||||
Arguments[FileLen - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
Arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_NO_BOTS,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for (new i = 0; i < target_count; i++)
|
||||
{
|
||||
ClientCommand(target_list[i], "playgamesound \"%s\"", Arguments[len]);
|
||||
LogAction(client, target_list[i], "\"%L\" played sound on \"%L\" (file \"%s\")", client, target_list[i], Arguments[len]);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Played sound to target", target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Played sound to target", "_s", target_name);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basefuncommands Plugin
|
||||
* Provides beacon functionality
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
new Handle:g_BeaconTimers[MAXPLAYERS+1];
|
||||
|
||||
new Handle:g_BeaconRadius = INVALID_HANDLE;
|
||||
|
||||
SetupBeacon()
|
||||
{
|
||||
RegAdminCmd("sm_beacon", Command_Beacon, ADMFLAG_SLAY, "sm_beacon <#userid|name> [0/1]");
|
||||
|
||||
g_BeaconRadius = CreateConVar("sm_beacon_radius", "375", "Sets the radius for beacon's light rings.", 0, true, 50.0, true, 1500.0);
|
||||
}
|
||||
|
||||
CreateBeacon(client)
|
||||
{
|
||||
g_BeaconTimers[client] = CreateTimer(2.0, Timer_Beacon, client, TIMER_REPEAT);
|
||||
}
|
||||
|
||||
KillBeacon(client)
|
||||
{
|
||||
KillTimer(g_BeaconTimers[client]);
|
||||
g_BeaconTimers[client] = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
KillAllBeacons()
|
||||
{
|
||||
new maxclients = GetMaxClients();
|
||||
for (new i = 1; i <= maxclients; i++)
|
||||
{
|
||||
if (g_BeaconTimers[i] != INVALID_HANDLE)
|
||||
{
|
||||
KillBeacon(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PerformBeacon(client, target, toggle)
|
||||
{
|
||||
switch (toggle)
|
||||
{
|
||||
case (2):
|
||||
{
|
||||
if (g_BeaconTimers[target] == INVALID_HANDLE)
|
||||
{
|
||||
CreateBeacon(target);
|
||||
LogAction(client, target, "\"%L\" set a beacon on \"%L\"", client, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
KillBeacon(target);
|
||||
LogAction(client, target, "\"%L\" removed a beacon on \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
|
||||
case (1):
|
||||
{
|
||||
if (g_BeaconTimers[target] == INVALID_HANDLE)
|
||||
{
|
||||
CreateBeacon(target);
|
||||
LogAction(client, target, "\"%L\" set a beacon on \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
|
||||
case (0):
|
||||
{
|
||||
if (g_BeaconTimers[target] != INVALID_HANDLE)
|
||||
{
|
||||
KillBeacon(target);
|
||||
LogAction(client, target, "\"%L\" removed a beacon on \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Timer_Beacon(Handle:timer, any:client)
|
||||
{
|
||||
if (!IsClientInGame(client) || !IsPlayerAlive(client))
|
||||
{
|
||||
KillBeacon(client);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new team = GetClientTeam(client);
|
||||
|
||||
new Float:vec[3];
|
||||
GetClientAbsOrigin(client, vec);
|
||||
vec[2] += 10;
|
||||
|
||||
TE_SetupBeamRingPoint(vec, 10.0, GetConVarFloat(g_BeaconRadius), g_BeamSprite, g_HaloSprite, 0, 15, 0.5, 5.0, 0.0, greyColor, 10, 0);
|
||||
TE_SendToAll();
|
||||
|
||||
if (team == 2)
|
||||
{
|
||||
TE_SetupBeamRingPoint(vec, 10.0, GetConVarFloat(g_BeaconRadius), g_BeamSprite, g_HaloSprite, 0, 10, 0.6, 10.0, 0.5, redColor, 10, 0);
|
||||
}
|
||||
else if (team == 3)
|
||||
{
|
||||
TE_SetupBeamRingPoint(vec, 10.0, GetConVarFloat(g_BeaconRadius), g_BeamSprite, g_HaloSprite, 0, 10, 0.6, 10.0, 0.5, blueColor, 10, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
TE_SetupBeamRingPoint(vec, 10.0, GetConVarFloat(g_BeaconRadius), g_BeamSprite, g_HaloSprite, 0, 10, 0.6, 10.0, 0.5, greenColor, 10, 0);
|
||||
}
|
||||
|
||||
TE_SendToAll();
|
||||
|
||||
GetClientEyePosition(client, vec);
|
||||
EmitAmbientSound(SOUND_BLIP, vec, client, SNDLEVEL_RAIDSIREN);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public AdminMenu_Beacon(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Beacon player", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayBeaconMenu(param);
|
||||
}
|
||||
}
|
||||
|
||||
DisplayBeaconMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_Beacon);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Beacon player", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddTargetsToMenu(menu, client, true, true);
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
public MenuHandler_Beacon(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32];
|
||||
new userid, target;
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info));
|
||||
userid = StringToInt(info);
|
||||
|
||||
if ((target = GetClientOfUserId(userid)) == 0)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player no longer available");
|
||||
}
|
||||
else if (!CanUserTarget(param1, target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Unable to target");
|
||||
}
|
||||
else
|
||||
{
|
||||
new String:name[32];
|
||||
GetClientName(target, name, sizeof(name));
|
||||
|
||||
PerformBeacon(param1, target, 2);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Toggled beacon on target", "_s", name);
|
||||
}
|
||||
|
||||
/* Re-draw the menu if they're still valid */
|
||||
if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
|
||||
{
|
||||
DisplayBeaconMenu(param1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_Beacon(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_beacon <#userid|name> [0/1]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[65];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
new toggle = 2;
|
||||
if (args > 1)
|
||||
{
|
||||
decl String:arg2[2];
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
if (arg2[0])
|
||||
{
|
||||
toggle = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
toggle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for (new i = 0; i < target_count; i++)
|
||||
{
|
||||
PerformBeacon(client, target_list[i], toggle);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled beacon on target", target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled beacon on target", "_s", target_name);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basefuncommands Plugin
|
||||
* Provides blind functionality
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
new g_BlindTarget[MAXPLAYERS+1];
|
||||
|
||||
SetupBlind()
|
||||
{
|
||||
RegAdminCmd("sm_blind", Command_Blind, ADMFLAG_SLAY, "sm_blind <#userid|name> [amount] - Leave amount off to reset.");
|
||||
}
|
||||
|
||||
PerformBlind(client, target, amount)
|
||||
{
|
||||
new targets[2];
|
||||
targets[0] = target;
|
||||
|
||||
new Handle:message = StartMessageEx(g_FadeUserMsgId, targets, 1);
|
||||
BfWriteShort(message, 1536);
|
||||
BfWriteShort(message, 1536);
|
||||
|
||||
if (amount == 0)
|
||||
{
|
||||
BfWriteShort(message, (0x0001 | 0x0010));
|
||||
}
|
||||
else
|
||||
{
|
||||
BfWriteShort(message, (0x0002 | 0x0008));
|
||||
}
|
||||
|
||||
BfWriteByte(message, 0);
|
||||
BfWriteByte(message, 0);
|
||||
BfWriteByte(message, 0);
|
||||
BfWriteByte(message, amount);
|
||||
|
||||
EndMessage();
|
||||
|
||||
LogAction(client, target, "\"%L\" set blind on \"%L\", amount %d.", client, target, amount);
|
||||
}
|
||||
|
||||
public AdminMenu_Blind(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Blind player", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayBlindMenu(param);
|
||||
}
|
||||
else if (action == TopMenuAction_DrawOption)
|
||||
{
|
||||
// Disable if we could not find the user message id for Fade.
|
||||
buffer[0] = ((g_FadeUserMsgId == INVALID_MESSAGE_ID) ? ITEMDRAW_IGNORE : ITEMDRAW_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
DisplayBlindMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_Blind);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Blind player", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddTargetsToMenu(menu, client, true, true);
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
DisplayAmountMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_Amount);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Blind amount", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddMenuItem(menu, "255", "Fully blind");
|
||||
AddMenuItem(menu, "240", "Half blind");
|
||||
AddMenuItem(menu, "0", "No blind");
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
public MenuHandler_Blind(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32];
|
||||
new userid, target;
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info));
|
||||
userid = StringToInt(info);
|
||||
|
||||
if ((target = GetClientOfUserId(userid)) == 0)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player no longer available");
|
||||
}
|
||||
else if (!CanUserTarget(param1, target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Unable to target");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_BlindTarget[param1] = userid;
|
||||
DisplayAmountMenu(param1);
|
||||
return; // Return, because we went to a new menu and don't want the re-draw to occur.
|
||||
}
|
||||
|
||||
/* Re-draw the menu if they're still valid */
|
||||
if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
|
||||
{
|
||||
DisplayBlindMenu(param1);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public MenuHandler_Amount(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32];
|
||||
new amount, target;
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info));
|
||||
amount = StringToInt(info);
|
||||
|
||||
if ((target = GetClientOfUserId(g_BlindTarget[param1])) == 0)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player no longer available");
|
||||
}
|
||||
else if (!CanUserTarget(param1, target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Unable to target");
|
||||
}
|
||||
else
|
||||
{
|
||||
new String:name[32];
|
||||
GetClientName(target, name, sizeof(name));
|
||||
|
||||
PerformBlind(param1, target, amount);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Set blind on target", "_s", name, amount);
|
||||
}
|
||||
|
||||
/* Re-draw the menu if they're still valid */
|
||||
if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
|
||||
{
|
||||
DisplayBlindMenu(param1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Action:Command_Blind(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_blind <#userid|name> [amount]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[65];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
new amount = 0;
|
||||
if (args > 1)
|
||||
{
|
||||
decl String:arg2[20];
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
if (StringToIntEx(arg2, amount) == 0)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Invalid Amount");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (amount < 0)
|
||||
{
|
||||
amount = 0;
|
||||
}
|
||||
|
||||
if (amount > 255)
|
||||
{
|
||||
amount = 255;
|
||||
}
|
||||
}
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for (new i = 0; i < target_count; i++)
|
||||
{
|
||||
PerformBlind(client, target_list[i], amount);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Set blind on target", target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Set blind on target", "_s", target_name);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,315 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basefuncommands Plugin
|
||||
* Provides drug functionality
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
new Handle:g_DrugTimers[MAXPLAYERS+1];
|
||||
new Float:g_DrugAngles[20] = {0.0, 5.0, 10.0, 15.0, 20.0, 25.0, 20.0, 15.0, 10.0, 5.0, 0.0, -5.0, -10.0, -15.0, -20.0, -25.0, -20.0, -15.0, -10.0, -5.0};
|
||||
|
||||
SetupDrugs()
|
||||
{
|
||||
RegAdminCmd("sm_drug", Command_Drug, ADMFLAG_SLAY, "sm_drug <#userid|name> [0/1]");
|
||||
}
|
||||
|
||||
CreateDrug(client)
|
||||
{
|
||||
g_DrugTimers[client] = CreateTimer(1.0, Timer_Drug, client, TIMER_REPEAT);
|
||||
}
|
||||
|
||||
KillDrug(client)
|
||||
{
|
||||
KillDrugTimer(client);
|
||||
|
||||
new Float:pos[3];
|
||||
GetClientAbsOrigin(client, pos);
|
||||
new Float:angs[3];
|
||||
GetClientEyeAngles(client, angs);
|
||||
|
||||
angs[2] = 0.0;
|
||||
|
||||
TeleportEntity(client, pos, angs, NULL_VECTOR);
|
||||
|
||||
new clients[2];
|
||||
clients[0] = client;
|
||||
|
||||
new Handle:message = StartMessageEx(g_FadeUserMsgId, clients, 1);
|
||||
BfWriteShort(message, 1536);
|
||||
BfWriteShort(message, 1536);
|
||||
BfWriteShort(message, (0x0001 | 0x0010));
|
||||
BfWriteByte(message, 0);
|
||||
BfWriteByte(message, 0);
|
||||
BfWriteByte(message, 0);
|
||||
BfWriteByte(message, 0);
|
||||
EndMessage();
|
||||
}
|
||||
|
||||
KillDrugTimer(client)
|
||||
{
|
||||
KillTimer(g_DrugTimers[client]);
|
||||
g_DrugTimers[client] = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
KillAllDrugs()
|
||||
{
|
||||
new maxclients = GetMaxClients();
|
||||
for (new i = 1; i <= maxclients; i++)
|
||||
{
|
||||
if (g_DrugTimers[i] != INVALID_HANDLE)
|
||||
{
|
||||
if(IsClientInGame(i))
|
||||
{
|
||||
KillDrug(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
KillDrugTimer(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PerformDrug(client, target, toggle)
|
||||
{
|
||||
switch (toggle)
|
||||
{
|
||||
case (2):
|
||||
{
|
||||
if (g_DrugTimers[target] == INVALID_HANDLE)
|
||||
{
|
||||
CreateDrug(target);
|
||||
LogAction(client, target, "\"%L\" drugged \"%L\"", client, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
KillDrug(target);
|
||||
LogAction(client, target, "\"%L\" undrugged \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
|
||||
case (1):
|
||||
{
|
||||
if (g_DrugTimers[target] == INVALID_HANDLE)
|
||||
{
|
||||
CreateDrug(target);
|
||||
LogAction(client, target, "\"%L\" drugged \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
|
||||
case (0):
|
||||
{
|
||||
if (g_DrugTimers[target] != INVALID_HANDLE)
|
||||
{
|
||||
KillDrug(target);
|
||||
LogAction(client, target, "\"%L\" undrugged \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Timer_Drug(Handle:timer, any:client)
|
||||
{
|
||||
if (!IsClientInGame(client))
|
||||
{
|
||||
KillDrugTimer(client);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (!IsPlayerAlive(client))
|
||||
{
|
||||
KillDrug(client);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new Float:pos[3];
|
||||
GetClientAbsOrigin(client, pos);
|
||||
|
||||
new Float:angs[3];
|
||||
GetClientEyeAngles(client, angs);
|
||||
|
||||
angs[2] = g_DrugAngles[GetRandomInt(0,100) % 20];
|
||||
|
||||
TeleportEntity(client, pos, angs, NULL_VECTOR);
|
||||
|
||||
new clients[2];
|
||||
clients[0] = client;
|
||||
|
||||
new Handle:message = StartMessageEx(g_FadeUserMsgId, clients, 1);
|
||||
BfWriteShort(message, 255);
|
||||
BfWriteShort(message, 255);
|
||||
BfWriteShort(message, (0x0002));
|
||||
BfWriteByte(message, GetRandomInt(0,255));
|
||||
BfWriteByte(message, GetRandomInt(0,255));
|
||||
BfWriteByte(message, GetRandomInt(0,255));
|
||||
BfWriteByte(message, 128);
|
||||
|
||||
EndMessage();
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public AdminMenu_Drug(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Drug player", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayDrugMenu(param);
|
||||
}
|
||||
}
|
||||
|
||||
DisplayDrugMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_Drug);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Drug player", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddTargetsToMenu(menu, client, true, true);
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
public MenuHandler_Drug(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32];
|
||||
new userid, target;
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info));
|
||||
userid = StringToInt(info);
|
||||
|
||||
if ((target = GetClientOfUserId(userid)) == 0)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player no longer available");
|
||||
}
|
||||
else if (!CanUserTarget(param1, target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Unable to target");
|
||||
}
|
||||
else
|
||||
{
|
||||
new String:name[32];
|
||||
GetClientName(target, name, sizeof(name));
|
||||
|
||||
PerformDrug(param1, target, 2);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Toggled drug on target", "_s", name);
|
||||
}
|
||||
|
||||
/* Re-draw the menu if they're still valid */
|
||||
if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
|
||||
{
|
||||
DisplayDrugMenu(param1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_Drug(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_drug <#userid|name> [0/1]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[65];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
new toggle = 2;
|
||||
if (args > 1)
|
||||
{
|
||||
decl String:arg2[2];
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
if (arg2[0])
|
||||
{
|
||||
toggle = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
toggle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for (new i = 0; i < target_count; i++)
|
||||
{
|
||||
PerformDrug(client, target_list[i], toggle);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled drug on target", target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled drug on target", "_s", target_name);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,504 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basefuncommands Plugin
|
||||
* Provides FireBomb functionality
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
new Handle:g_FireBombTimers[MAXPLAYERS+1];
|
||||
new g_FireBombTracker[MAXPLAYERS+1];
|
||||
|
||||
new Handle:g_BurnDuration = INVALID_HANDLE;
|
||||
new Handle:g_FireBombTicks = INVALID_HANDLE;
|
||||
new Handle:g_FireBombRadius = INVALID_HANDLE;
|
||||
new Handle:g_FireBombMode = INVALID_HANDLE;
|
||||
|
||||
SetupFire()
|
||||
{
|
||||
RegAdminCmd("sm_burn", Command_Burn, ADMFLAG_SLAY, "sm_burn <#userid|name> [time]");
|
||||
RegAdminCmd("sm_firebomb", Command_FireBomb, ADMFLAG_SLAY, "sm_firebomb <#userid|name> [0/1]");
|
||||
|
||||
g_BurnDuration = CreateConVar("sm_burn_duration", "20", "Sets the default duration of sm_burn and firebomb victims.", 0, true, 0.5, true, 20.0);
|
||||
g_FireBombTicks = CreateConVar("sm_firebomb_ticks", "10", "Sets how long the FireBomb fuse is.", 0, true, 5.0, true, 120.0);
|
||||
g_FireBombRadius = CreateConVar("sm_firebomb_radius", "600", "Sets the bomb blast radius.", 0, true, 50.0, true, 3000.0);
|
||||
g_FireBombMode = CreateConVar("sm_firebomb_mode", "0", "Who is targetted by the FireBomb? 0 = Target only, 1 = Target's team, 2 = Everyone", 0, true, 0.0, true, 2.0);
|
||||
}
|
||||
|
||||
CreateFireBomb(client)
|
||||
{
|
||||
g_FireBombTimers[client] = CreateTimer(1.0, Timer_FireBomb, client, TIMER_REPEAT);
|
||||
g_FireBombTracker[client] = GetConVarInt(g_FireBombTicks);
|
||||
}
|
||||
|
||||
KillFireBomb(client)
|
||||
{
|
||||
KillTimer(g_FireBombTimers[client]);
|
||||
g_FireBombTimers[client] = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
KillAllFireBombs()
|
||||
{
|
||||
new maxclients = GetMaxClients();
|
||||
for (new i = 1; i <= maxclients; i++)
|
||||
{
|
||||
if (g_FireBombTimers[i] != INVALID_HANDLE)
|
||||
{
|
||||
KillFireBomb(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PerformBurn(client, target, Float:seconds)
|
||||
{
|
||||
LogAction(client, target, "\"%L\" ignited \"%L\" (seconds \"%f\")", client, target, seconds);
|
||||
IgniteEntity(target, seconds);
|
||||
}
|
||||
|
||||
PerformFireBomb(client, target, toggle)
|
||||
{
|
||||
switch (toggle)
|
||||
{
|
||||
case (2):
|
||||
{
|
||||
if (g_FireBombTimers[target] == INVALID_HANDLE)
|
||||
{
|
||||
CreateFireBomb(target);
|
||||
LogAction(client, target, "\"%L\" set a FireBomb on \"%L\"", client, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
KillFireBomb(target);
|
||||
SetEntityRenderColor(client, 255, 255, 255, 255);
|
||||
LogAction(client, target, "\"%L\" removed a FireBomb on \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
|
||||
case (1):
|
||||
{
|
||||
if (g_FireBombTimers[target] == INVALID_HANDLE)
|
||||
{
|
||||
CreateFireBomb(target);
|
||||
LogAction(client, target, "\"%L\" set a FireBomb on \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
|
||||
case (0):
|
||||
{
|
||||
if (g_FireBombTimers[target] != INVALID_HANDLE)
|
||||
{
|
||||
KillFireBomb(target);
|
||||
SetEntityRenderColor(client, 255, 255, 255, 255);
|
||||
LogAction(client, target, "\"%L\" removed a FireBomb on \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Timer_FireBomb(Handle:timer, any:client)
|
||||
{
|
||||
if (!IsClientInGame(client) || !IsPlayerAlive(client))
|
||||
{
|
||||
KillFireBomb(client);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
g_FireBombTracker[client]--;
|
||||
|
||||
new Float:vec[3];
|
||||
GetClientEyePosition(client, vec);
|
||||
|
||||
if (g_FireBombTracker[client] > 0)
|
||||
{
|
||||
new color;
|
||||
|
||||
if (g_FireBombTracker[client] > 1)
|
||||
{
|
||||
color = RoundToFloor(g_FireBombTracker[client] * (255.0 / GetConVarFloat(g_FireBombTicks)));
|
||||
EmitAmbientSound(SOUND_BEEP, vec, client, SNDLEVEL_RAIDSIREN);
|
||||
}
|
||||
else
|
||||
{
|
||||
color = 0;
|
||||
EmitAmbientSound(SOUND_FINAL, vec, client, SNDLEVEL_RAIDSIREN);
|
||||
}
|
||||
|
||||
SetEntityRenderColor(client, 255, color, color, 255);
|
||||
|
||||
decl String:name[64];
|
||||
GetClientName(client, name, sizeof(name));
|
||||
PrintCenterTextAll("%t", "Till Explodes", name, g_FireBombTracker[client]);
|
||||
|
||||
GetClientAbsOrigin(client, vec);
|
||||
vec[2] += 10;
|
||||
|
||||
TE_SetupBeamRingPoint(vec, 10.0, GetConVarFloat(g_FireBombRadius) / 3.0, g_BeamSprite, g_HaloSprite, 0, 15, 0.5, 5.0, 0.0, greyColor, 10, 0);
|
||||
TE_SendToAll();
|
||||
TE_SetupBeamRingPoint(vec, 10.0, GetConVarFloat(g_FireBombRadius) / 3.0, g_BeamSprite, g_HaloSprite, 0, 10, 0.6, 10.0, 0.5, whiteColor, 10, 0);
|
||||
TE_SendToAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
TE_SetupExplosion(vec, g_ExplosionSprite, 0.1, 1, 0, GetConVarInt(g_FireBombRadius), 5000);
|
||||
TE_SendToAll();
|
||||
|
||||
GetClientAbsOrigin(client, vec);
|
||||
vec[2] += 10;
|
||||
TE_SetupBeamRingPoint(vec, 50.0, GetConVarFloat(g_FireBombRadius), g_BeamSprite, g_HaloSprite, 0, 10, 0.5, 30.0, 1.5, orangeColor, 5, 0);
|
||||
TE_SendToAll();
|
||||
vec[2] += 15;
|
||||
TE_SetupBeamRingPoint(vec, 40.0, GetConVarFloat(g_FireBombRadius), g_BeamSprite, g_HaloSprite, 0, 10, 0.6, 30.0, 1.5, orangeColor, 5, 0);
|
||||
TE_SendToAll();
|
||||
vec[2] += 15;
|
||||
TE_SetupBeamRingPoint(vec, 30.0, GetConVarFloat(g_FireBombRadius), g_BeamSprite, g_HaloSprite, 0, 10, 0.7, 30.0, 1.5, orangeColor, 5, 0);
|
||||
TE_SendToAll();
|
||||
vec[2] += 15;
|
||||
TE_SetupBeamRingPoint(vec, 20.0, GetConVarFloat(g_FireBombRadius), g_BeamSprite, g_HaloSprite, 0, 10, 0.8, 30.0, 1.5, orangeColor, 5, 0);
|
||||
TE_SendToAll();
|
||||
|
||||
EmitAmbientSound(SOUND_BOOM, vec, client, SNDLEVEL_RAIDSIREN);
|
||||
|
||||
IgniteEntity(client, GetConVarFloat(g_BurnDuration));
|
||||
KillFireBomb(client);
|
||||
SetEntityRenderColor(client, 255, 255, 255, 255);
|
||||
|
||||
if (GetConVarInt(g_FireBombMode) > 0)
|
||||
{
|
||||
new teamOnly = ((GetConVarInt(g_FireBombMode) == 1) ? true : false);
|
||||
new maxClients = GetMaxClients();
|
||||
|
||||
for (new i = 1; i < maxClients; i++)
|
||||
{
|
||||
if (!IsClientInGame(i) || !IsPlayerAlive(i) || i == client)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (teamOnly && GetClientTeam(i) != GetClientTeam(client))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
new Float:pos[3];
|
||||
GetClientAbsOrigin(i, pos);
|
||||
|
||||
new Float:distance = GetVectorDistance(vec, pos);
|
||||
|
||||
if (distance > GetConVarFloat(g_FireBombRadius))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
new Float:duration = GetConVarFloat(g_BurnDuration);
|
||||
duration *= (GetConVarFloat(g_FireBombRadius) - distance) / GetConVarFloat(g_FireBombRadius);
|
||||
|
||||
IgniteEntity(i, duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public AdminMenu_Burn(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Burn player", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayBurnMenu(param);
|
||||
}
|
||||
}
|
||||
|
||||
public AdminMenu_FireBomb(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "FireBomb player", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayFireBombMenu(param);
|
||||
}
|
||||
}
|
||||
|
||||
DisplayBurnMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_Burn);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Burn player", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddTargetsToMenu(menu, client, true, true);
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
DisplayFireBombMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_FireBomb);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "FireBomb player", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddTargetsToMenu(menu, client, true, true);
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
public MenuHandler_Burn(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32];
|
||||
new userid, target;
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info));
|
||||
userid = StringToInt(info);
|
||||
|
||||
if ((target = GetClientOfUserId(userid)) == 0)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player no longer available");
|
||||
}
|
||||
else if (!CanUserTarget(param1, target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Unable to target");
|
||||
}
|
||||
else
|
||||
{
|
||||
new String:name[32];
|
||||
GetClientName(target, name, sizeof(name));
|
||||
PerformBurn(param1, target, 20.0);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Set target on fire", "_s", name);
|
||||
}
|
||||
|
||||
/* Re-draw the menu if they're still valid */
|
||||
if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
|
||||
{
|
||||
DisplayBurnMenu(param1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MenuHandler_FireBomb(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32];
|
||||
new userid, target;
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info));
|
||||
userid = StringToInt(info);
|
||||
|
||||
if ((target = GetClientOfUserId(userid)) == 0)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player no longer available");
|
||||
}
|
||||
else if (!CanUserTarget(param1, target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Unable to target");
|
||||
}
|
||||
else
|
||||
{
|
||||
new String:name[32];
|
||||
GetClientName(target, name, sizeof(name));
|
||||
|
||||
PerformFireBomb(param1, target, 2);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Toggled FireBomb on target", "_s", name);
|
||||
}
|
||||
|
||||
/* Re-draw the menu if they're still valid */
|
||||
if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
|
||||
{
|
||||
DisplayFireBombMenu(param1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_Burn(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_burn <#userid|name> [time]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[65];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
new Float:seconds = GetConVarFloat(g_BurnDuration);
|
||||
|
||||
if (args > 1)
|
||||
{
|
||||
decl String:time[20];
|
||||
GetCmdArg(2, time, sizeof(time));
|
||||
if (StringToFloatEx(time, seconds) == 0)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Invalid Amount");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
}
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for (new i = 0; i < target_count; i++)
|
||||
{
|
||||
PerformBurn(client, target_list[i], seconds);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Set target on fire", target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Set target on fire", "_s", target_name);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_FireBomb(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_firebomb <#userid|name> [0/1]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[65];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
new toggle = 2;
|
||||
if (args > 1)
|
||||
{
|
||||
decl String:arg2[2];
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
if (arg2[0])
|
||||
{
|
||||
toggle = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
toggle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for (new i = 0; i < target_count; i++)
|
||||
{
|
||||
PerformFireBomb(client, target_list[i], toggle);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled FireBomb on target", target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled FireBomb on target", "_s", target_name);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basefuncommands Plugin
|
||||
* Provides gravity functionality
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
new g_GravityTarget[MAXPLAYERS+1];
|
||||
|
||||
SetupGravity()
|
||||
{
|
||||
RegAdminCmd("sm_gravity", Command_Gravity, ADMFLAG_SLAY, "sm_gravity <#userid|name> [amount] - Leave amount off to reset. Amount is 0.0 through 5.0");
|
||||
}
|
||||
|
||||
PerformGravity(client, target, Float:amount)
|
||||
{
|
||||
new offset = FindDataMapOffs(client, "m_flGravity");
|
||||
new Float:temp = GetEntDataFloat(client, offset);
|
||||
PrintToChatAll("Gravity check %f", temp);
|
||||
|
||||
SetEntityGravity(target, amount);
|
||||
LogAction(client, target, "\"%L\" set gravity on \"%L\" to %d.", client, target, amount);
|
||||
}
|
||||
|
||||
public AdminMenu_Gravity(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Gravity player", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayGravityMenu(param);
|
||||
}
|
||||
}
|
||||
|
||||
DisplayGravityMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_Gravity);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Gravity player", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddTargetsToMenu(menu, client, true, true);
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
DisplayGravityAmountMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_GravityAmount);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Gravity amount", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddMenuItem(menu, "4.0", "Gravity Very High");
|
||||
AddMenuItem(menu, "2.0", "Gravity High");
|
||||
AddMenuItem(menu, "1.0", "Gravity Normal");
|
||||
AddMenuItem(menu, "0.5", "Gravity Low");
|
||||
AddMenuItem(menu, "0.1", "Gravity Very Low");
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
public MenuHandler_Gravity(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32];
|
||||
new userid, target;
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info));
|
||||
userid = StringToInt(info);
|
||||
|
||||
if ((target = GetClientOfUserId(userid)) == 0)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player no longer available");
|
||||
}
|
||||
else if (!CanUserTarget(param1, target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Unable to target");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_GravityTarget[param1] = userid;
|
||||
DisplayGravityAmountMenu(param1);
|
||||
return; // Return, because we went to a new menu and don't want the re-draw to occur.
|
||||
}
|
||||
|
||||
/* Re-draw the menu if they're still valid */
|
||||
if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
|
||||
{
|
||||
DisplayGravityMenu(param1);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public MenuHandler_GravityAmount(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32];
|
||||
new Float:amount, target;
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info));
|
||||
amount = StringToFloat(info);
|
||||
|
||||
if ((target = GetClientOfUserId(g_GravityTarget[param1])) == 0)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player no longer available");
|
||||
}
|
||||
else if (!CanUserTarget(param1, target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Unable to target");
|
||||
}
|
||||
else
|
||||
{
|
||||
new String:name[32];
|
||||
GetClientName(target, name, sizeof(name));
|
||||
|
||||
PerformGravity(param1, target, amount);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Set gravity on target", "_s", name, amount);
|
||||
}
|
||||
|
||||
/* Re-draw the menu if they're still valid */
|
||||
if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
|
||||
{
|
||||
DisplayGravityMenu(param1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_Gravity(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_gravity <#userid|name> [amount]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[65];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
new Float:amount = 1.0;
|
||||
if (args > 1)
|
||||
{
|
||||
decl String:arg2[20];
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
if (StringToFloatEx(arg2, amount) == 0)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Invalid Amount");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (amount < 0.0)
|
||||
{
|
||||
amount = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for (new i = 0; i < target_count; i++)
|
||||
{
|
||||
PerformGravity(client, target_list[i], amount);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Set gravity on target", target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Set gravity on target", "_s", target_name);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,573 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basefuncommands Plugin
|
||||
* Provides freeze and freezebomb functionality
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
new Handle:g_FreezeTimers[MAXPLAYERS+1];
|
||||
new Handle:g_FreezeBombTimers[MAXPLAYERS+1];
|
||||
new g_FreezeTracker[MAXPLAYERS+1];
|
||||
new g_FreezeBombTracker[MAXPLAYERS+1];
|
||||
|
||||
new Handle:g_FreezeDuration = INVALID_HANDLE;
|
||||
new Handle:g_FreezeBombTicks = INVALID_HANDLE;
|
||||
new Handle:g_FreezeBombRadius = INVALID_HANDLE;
|
||||
new Handle:g_FreezeBombMode = INVALID_HANDLE;
|
||||
|
||||
SetupIce()
|
||||
{
|
||||
RegAdminCmd("sm_freeze", Command_Freeze, ADMFLAG_SLAY, "sm_freeze <#userid|name> [time]");
|
||||
RegAdminCmd("sm_freezebomb", Command_FreezeBomb, ADMFLAG_SLAY, "sm_freezebomb <#userid|name> [0/1]");
|
||||
|
||||
g_FreezeDuration = CreateConVar("sm_freeze_duration", "10.0", "Sets the default duration for sm_freeze and freezebomb victims", 0, true, 1.0, true, 120.0);
|
||||
g_FreezeBombTicks = CreateConVar("sm_freezebomb_ticks", "10", "Sets how long the freezebomb fuse is.", 0, true, 5.0, true, 120.0);
|
||||
g_FreezeBombRadius = CreateConVar("sm_freezebomb_radius", "600", "Sets the freezebomb blast radius.", 0, true, 50.0, true, 3000.0);
|
||||
g_FreezeBombMode = CreateConVar("sm_freezebomb_mode", "0", "Who is targetted by the freezebomb? 0 = Target only, 1 = Target's team, 2 = Everyone", 0, true, 0.0, true, 2.0);
|
||||
}
|
||||
|
||||
FreezeClient(client, time)
|
||||
{
|
||||
if (g_FreezeTimers[client] != INVALID_HANDLE)
|
||||
{
|
||||
UnfreezeClient(client);
|
||||
}
|
||||
|
||||
SetEntityMoveType(client, MOVETYPE_NONE);
|
||||
SetEntityRenderColor(client, 0, 128, 255, 192);
|
||||
|
||||
new Float:vec[3];
|
||||
GetClientEyePosition(client, vec);
|
||||
EmitAmbientSound(SOUND_FREEZE, vec, client, SNDLEVEL_RAIDSIREN);
|
||||
|
||||
g_FreezeTimers[client] = CreateTimer(1.0, Timer_Freeze, client, TIMER_REPEAT);
|
||||
g_FreezeTracker[client] = time;
|
||||
}
|
||||
|
||||
UnfreezeClient(client)
|
||||
{
|
||||
KillFreezeTimer(client);
|
||||
|
||||
new Float:vec[3];
|
||||
GetClientAbsOrigin(client, vec);
|
||||
vec[2] += 10;
|
||||
|
||||
GetClientEyePosition(client, vec);
|
||||
EmitAmbientSound(SOUND_FREEZE, vec, client, SNDLEVEL_RAIDSIREN);
|
||||
|
||||
SetEntityMoveType(client, MOVETYPE_WALK);
|
||||
SetEntityRenderColor(client, 255, 255, 255, 255);
|
||||
}
|
||||
|
||||
KillFreezeTimer(client)
|
||||
{
|
||||
KillTimer(g_FreezeTimers[client]);
|
||||
g_FreezeTimers[client] = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
CreateFreezeBomb(client)
|
||||
{
|
||||
g_FreezeBombTimers[client] = CreateTimer(1.0, Timer_FreezeBomb, client, TIMER_REPEAT);
|
||||
g_FreezeBombTracker[client] = GetConVarInt(g_FreezeBombTicks);
|
||||
}
|
||||
|
||||
KillFreezeBomb(client)
|
||||
{
|
||||
KillTimer(g_FreezeBombTimers[client]);
|
||||
g_FreezeBombTimers[client] = INVALID_HANDLE;
|
||||
|
||||
SetEntityRenderColor(client, 255, 255, 255, 255);
|
||||
}
|
||||
|
||||
KillAllFreezes()
|
||||
{
|
||||
new maxclients = GetMaxClients();
|
||||
for (new i = 1; i <= maxclients; i++)
|
||||
{
|
||||
if (g_FreezeTimers[i] != INVALID_HANDLE)
|
||||
{
|
||||
if(IsClientInGame(i))
|
||||
{
|
||||
UnfreezeClient(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
KillFreezeTimer(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (g_FreezeBombTimers[i] != INVALID_HANDLE)
|
||||
{
|
||||
KillFreezeBomb(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PerformFreeze(client, target, time)
|
||||
{
|
||||
FreezeClient(target, time);
|
||||
LogAction(client, target, "\"%L\" froze \"%L\"", client, target);
|
||||
}
|
||||
|
||||
PerformFreezeBomb(client, target, toggle)
|
||||
{
|
||||
switch (toggle)
|
||||
{
|
||||
case (2):
|
||||
{
|
||||
if (g_FreezeBombTimers[target] == INVALID_HANDLE)
|
||||
{
|
||||
CreateFreezeBomb(target);
|
||||
LogAction(client, target, "\"%L\" set a FreezeBomb on \"%L\"", client, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
KillFreezeBomb(target);
|
||||
LogAction(client, target, "\"%L\" removed a FreezeBomb on \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
|
||||
case (1):
|
||||
{
|
||||
if (g_FreezeBombTimers[target] == INVALID_HANDLE)
|
||||
{
|
||||
CreateFreezeBomb(target);
|
||||
LogAction(client, target, "\"%L\" set a FreezeBomb on \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
|
||||
case (0):
|
||||
{
|
||||
if (g_FreezeBombTimers[target] != INVALID_HANDLE)
|
||||
{
|
||||
KillFreezeBomb(target);
|
||||
LogAction(client, target, "\"%L\" removed a FreezeBomb on \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Timer_Freeze(Handle:timer, any:client)
|
||||
{
|
||||
if (!IsClientInGame(client))
|
||||
{
|
||||
KillFreezeTimer(client);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (!IsPlayerAlive(client))
|
||||
{
|
||||
UnfreezeClient(client);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
g_FreezeTracker[client]--;
|
||||
|
||||
SetEntityMoveType(client, MOVETYPE_NONE);
|
||||
SetEntityRenderColor(client, 0, 128, 255, 135);
|
||||
|
||||
new Float:vec[3];
|
||||
GetClientAbsOrigin(client, vec);
|
||||
vec[2] += 10;
|
||||
|
||||
TE_SetupGlowSprite(vec, g_GlowSprite, 0.95, 1.5, 50);
|
||||
TE_SendToAll();
|
||||
|
||||
if (g_FreezeTracker[client] == 0)
|
||||
{
|
||||
UnfreezeClient(client);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Timer_FreezeBomb(Handle:timer, any:client)
|
||||
{
|
||||
if (!IsClientInGame(client) || !IsPlayerAlive(client))
|
||||
{
|
||||
KillFreezeBomb(client);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
g_FreezeBombTracker[client]--;
|
||||
|
||||
new Float:vec[3];
|
||||
GetClientEyePosition(client, vec);
|
||||
|
||||
if (g_FreezeBombTracker[client] > 0)
|
||||
{
|
||||
new color;
|
||||
|
||||
if (g_FreezeBombTracker[client] > 1)
|
||||
{
|
||||
color = RoundToFloor(g_FreezeBombTracker[client] * (255.0 / GetConVarFloat(g_FreezeBombTicks)));
|
||||
EmitAmbientSound(SOUND_BEEP, vec, client, SNDLEVEL_RAIDSIREN);
|
||||
}
|
||||
else
|
||||
{
|
||||
color = 0;
|
||||
EmitAmbientSound(SOUND_FINAL, vec, client, SNDLEVEL_RAIDSIREN);
|
||||
}
|
||||
|
||||
SetEntityRenderColor(client, color, color, 255, 255);
|
||||
|
||||
decl String:name[64];
|
||||
GetClientName(client, name, sizeof(name));
|
||||
PrintCenterTextAll("%t", "Till Explodes", name, g_FreezeBombTracker[client]);
|
||||
|
||||
GetClientAbsOrigin(client, vec);
|
||||
vec[2] += 10;
|
||||
|
||||
TE_SetupBeamRingPoint(vec, 10.0, GetConVarFloat(g_FreezeBombRadius) / 3.0, g_BeamSprite, g_HaloSprite, 0, 15, 0.5, 5.0, 0.0, greyColor, 10, 0);
|
||||
TE_SendToAll();
|
||||
TE_SetupBeamRingPoint(vec, 10.0, GetConVarFloat(g_FreezeBombRadius) / 3.0, g_BeamSprite, g_HaloSprite, 0, 10, 0.6, 10.0, 0.5, whiteColor, 10, 0);
|
||||
TE_SendToAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
TE_SetupExplosion(vec, g_ExplosionSprite, 5.0, 1, 0, GetConVarInt(g_FreezeBombRadius), 5000);
|
||||
TE_SendToAll();
|
||||
|
||||
EmitAmbientSound(SOUND_BOOM, vec, client, SNDLEVEL_RAIDSIREN);
|
||||
|
||||
KillFreezeBomb(client);
|
||||
FreezeClient(client, GetConVarInt(g_FreezeDuration));
|
||||
|
||||
if (GetConVarInt(g_FreezeBombMode) > 0)
|
||||
{
|
||||
new teamOnly = ((GetConVarInt(g_FreezeBombMode) == 1) ? true : false);
|
||||
new maxClients = GetMaxClients();
|
||||
|
||||
for (new i = 1; i < maxClients; i++)
|
||||
{
|
||||
if (!IsClientInGame(i) || !IsPlayerAlive(i) || i == client)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (teamOnly && GetClientTeam(i) != GetClientTeam(client))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
new Float:pos[3];
|
||||
GetClientEyePosition(i, pos);
|
||||
|
||||
new Float:distance = GetVectorDistance(vec, pos);
|
||||
|
||||
if (distance > GetConVarFloat(g_FreezeBombRadius))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
TE_SetupBeamPoints(vec, pos, g_BeamSprite2, g_HaloSprite, 0, 1, 0.7, 20.0, 50.0, 1, 1.5, blueColor, 10);
|
||||
TE_SendToAll();
|
||||
|
||||
FreezeClient(i, GetConVarInt(g_FreezeDuration));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public AdminMenu_Freeze(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Freeze player", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayFreezeMenu(param);
|
||||
}
|
||||
}
|
||||
|
||||
public AdminMenu_FreezeBomb(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "FreezeBomb player", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayFreezeBombMenu(param);
|
||||
}
|
||||
}
|
||||
|
||||
DisplayFreezeMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_Freeze);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Freeze player", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddTargetsToMenu(menu, client, true, true);
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
DisplayFreezeBombMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_FreezeBomb);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "FreezeBomb player", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddTargetsToMenu(menu, client, true, true);
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
public MenuHandler_Freeze(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32];
|
||||
new userid, target;
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info));
|
||||
userid = StringToInt(info);
|
||||
|
||||
if ((target = GetClientOfUserId(userid)) == 0)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player no longer available");
|
||||
}
|
||||
else if (!CanUserTarget(param1, target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Unable to target");
|
||||
}
|
||||
else
|
||||
{
|
||||
new String:name[32];
|
||||
GetClientName(target, name, sizeof(name));
|
||||
|
||||
PerformFreeze(param1, target, GetConVarInt(g_FreezeDuration));
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Froze target", "_s", name);
|
||||
}
|
||||
|
||||
/* Re-draw the menu if they're still valid */
|
||||
if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
|
||||
{
|
||||
DisplayFreezeMenu(param1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MenuHandler_FreezeBomb(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32];
|
||||
new userid, target;
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info));
|
||||
userid = StringToInt(info);
|
||||
|
||||
if ((target = GetClientOfUserId(userid)) == 0)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player no longer available");
|
||||
}
|
||||
else if (!CanUserTarget(param1, target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Unable to target");
|
||||
}
|
||||
else
|
||||
{
|
||||
new String:name[32];
|
||||
GetClientName(target, name, sizeof(name));
|
||||
|
||||
PerformFreezeBomb(param1, target, 2);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Toggled FreezeBomb on target", "_s", name);
|
||||
}
|
||||
|
||||
/* Re-draw the menu if they're still valid */
|
||||
if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
|
||||
{
|
||||
DisplayFreezeBombMenu(param1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_Freeze(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_freeze <#userid|name> [time]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[65];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
new seconds = GetConVarInt(g_FreezeDuration);
|
||||
|
||||
if (args > 1)
|
||||
{
|
||||
decl String:time[20];
|
||||
GetCmdArg(2, time, sizeof(time));
|
||||
if (StringToIntEx(time, seconds) == 0)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Invalid Amount");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
}
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for (new i = 0; i < target_count; i++)
|
||||
{
|
||||
PerformFreeze(client, target_list[i], seconds);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Froze target", target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Froze target", "_s", target_name);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:Command_FreezeBomb(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_freezebomb <#userid|name> [0/1]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[65];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
new toggle = 2;
|
||||
if (args > 1)
|
||||
{
|
||||
decl String:arg2[2];
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
if (arg2[0])
|
||||
{
|
||||
toggle = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
toggle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for (new i = 0; i < target_count; i++)
|
||||
{
|
||||
PerformFreezeBomb(client, target_list[i], toggle);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled FreezeBomb on target", target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled FreezeBomb on target", "_s", target_name);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basefuncommands Plugin
|
||||
* Provides noclip functionality
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
SetupNoClip()
|
||||
{
|
||||
RegAdminCmd("sm_noclip", Command_NoClip, ADMFLAG_SLAY|ADMFLAG_CHEATS, "sm_noclip <#userid|name>");
|
||||
}
|
||||
|
||||
PerformNoClip(client, target)
|
||||
{
|
||||
new MoveType:movetype = GetEntityMoveType(target);
|
||||
|
||||
if (movetype != MOVETYPE_NOCLIP)
|
||||
{
|
||||
SetEntityMoveType(target, MOVETYPE_NOCLIP);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetEntityMoveType(target, MOVETYPE_WALK);
|
||||
}
|
||||
|
||||
LogAction(client, target, "\"%L\" toggled noclip on \"%L\"", client, target);
|
||||
}
|
||||
|
||||
public AdminMenu_NoClip(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "NoClip player", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayNoClipMenu(param);
|
||||
}
|
||||
}
|
||||
|
||||
DisplayNoClipMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_NoClip);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "NoClip player", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddTargetsToMenu(menu, client, true, true);
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
public MenuHandler_NoClip(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32];
|
||||
new userid, target;
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info));
|
||||
userid = StringToInt(info);
|
||||
|
||||
if ((target = GetClientOfUserId(userid)) == 0)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player no longer available");
|
||||
}
|
||||
else if (!CanUserTarget(param1, target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Unable to target");
|
||||
}
|
||||
else
|
||||
{
|
||||
new String:name[32];
|
||||
GetClientName(target, name, sizeof(name));
|
||||
|
||||
PerformNoClip(param1, target);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Toggled noclip on target", "_s", name);
|
||||
}
|
||||
|
||||
/* Re-draw the menu if they're still valid */
|
||||
if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
|
||||
{
|
||||
DisplayNoClipMenu(param1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_NoClip(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_noclip <#userid|name>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[65];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for (new i = 0; i < target_count; i++)
|
||||
{
|
||||
PerformNoClip(client, target_list[i]);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled noclip on target", target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled noclip on target", "_s", target_name);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,365 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basefuncommands Plugin
|
||||
* Provides TimeBomb functionality
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
new Handle:g_TimeBombTimers[MAXPLAYERS+1];
|
||||
new g_TimeBombTracker[MAXPLAYERS+1];
|
||||
|
||||
new Handle:g_TimeBombTicks = INVALID_HANDLE;
|
||||
new Handle:g_TimeBombRadius = INVALID_HANDLE;
|
||||
new Handle:g_TimeBombMode = INVALID_HANDLE;
|
||||
|
||||
SetupTimeBomb()
|
||||
{
|
||||
RegAdminCmd("sm_timebomb", Command_TimeBomb, ADMFLAG_SLAY, "sm_timebomb <#userid|name> [0/1]");
|
||||
|
||||
g_TimeBombTicks = CreateConVar("sm_timebomb_ticks", "10", "Sets how long the timebomb fuse is.", 0, true, 5.0, true, 120.0);
|
||||
g_TimeBombRadius = CreateConVar("sm_timebomb_radius", "600", "Sets the bomb blast radius.", 0, true, 50.0, true, 3000.0);
|
||||
g_TimeBombMode = CreateConVar("sm_timebomb_mode", "0", "Who is killed by the timebomb? 0 = Target only, 1 = Target's team, 2 = Everyone", 0, true, 0.0, true, 2.0);
|
||||
}
|
||||
|
||||
CreateTimeBomb(client)
|
||||
{
|
||||
g_TimeBombTimers[client] = CreateTimer(1.0, Timer_TimeBomb, client, TIMER_REPEAT);
|
||||
g_TimeBombTracker[client] = GetConVarInt(g_TimeBombTicks);
|
||||
}
|
||||
|
||||
KillTimeBomb(client)
|
||||
{
|
||||
KillTimer(g_TimeBombTimers[client]);
|
||||
g_TimeBombTimers[client] = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
KillAllTimeBombs()
|
||||
{
|
||||
new maxclients = GetMaxClients();
|
||||
for (new i = 1; i <= maxclients; i++)
|
||||
{
|
||||
if (g_TimeBombTimers[i] != INVALID_HANDLE)
|
||||
{
|
||||
KillTimeBomb(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PerformTimeBomb(client, target, toggle)
|
||||
{
|
||||
switch (toggle)
|
||||
{
|
||||
case (2):
|
||||
{
|
||||
if (g_TimeBombTimers[target] == INVALID_HANDLE)
|
||||
{
|
||||
CreateTimeBomb(target);
|
||||
LogAction(client, target, "\"%L\" set a TimeBomb on \"%L\"", client, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
KillTimeBomb(target);
|
||||
SetEntityRenderColor(client, 255, 255, 255, 255);
|
||||
LogAction(client, target, "\"%L\" removed a TimeBomb on \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
|
||||
case (1):
|
||||
{
|
||||
if (g_TimeBombTimers[target] == INVALID_HANDLE)
|
||||
{
|
||||
CreateTimeBomb(target);
|
||||
LogAction(client, target, "\"%L\" set a TimeBomb on \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
|
||||
case (0):
|
||||
{
|
||||
if (g_TimeBombTimers[target] != INVALID_HANDLE)
|
||||
{
|
||||
KillTimeBomb(target);
|
||||
SetEntityRenderColor(client, 255, 255, 255, 255);
|
||||
LogAction(client, target, "\"%L\" removed a TimeBomb on \"%L\"", client, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Timer_TimeBomb(Handle:timer, any:client)
|
||||
{
|
||||
if (!IsClientInGame(client) || !IsPlayerAlive(client))
|
||||
{
|
||||
KillTimeBomb(client);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
g_TimeBombTracker[client]--;
|
||||
|
||||
new Float:vec[3];
|
||||
GetClientEyePosition(client, vec);
|
||||
|
||||
if (g_TimeBombTracker[client] > 0)
|
||||
{
|
||||
new color;
|
||||
|
||||
if (g_TimeBombTracker[client] > 1)
|
||||
{
|
||||
color = RoundToFloor(g_TimeBombTracker[client] * (128.0 / GetConVarFloat(g_TimeBombTicks)));
|
||||
EmitAmbientSound(SOUND_BEEP, vec, client, SNDLEVEL_RAIDSIREN);
|
||||
}
|
||||
else
|
||||
{
|
||||
color = 0;
|
||||
EmitAmbientSound(SOUND_FINAL, vec, client, SNDLEVEL_RAIDSIREN);
|
||||
}
|
||||
|
||||
SetEntityRenderColor(client, 255, 128, color, 255);
|
||||
|
||||
decl String:name[64];
|
||||
GetClientName(client, name, sizeof(name));
|
||||
PrintCenterTextAll("%t", "Till Explodes", name, g_TimeBombTracker[client]);
|
||||
|
||||
GetClientAbsOrigin(client, vec);
|
||||
vec[2] += 10;
|
||||
|
||||
TE_SetupBeamRingPoint(vec, 10.0, GetConVarFloat(g_TimeBombRadius) / 3.0, g_BeamSprite, g_HaloSprite, 0, 15, 0.5, 5.0, 0.0, greyColor, 10, 0);
|
||||
TE_SendToAll();
|
||||
TE_SetupBeamRingPoint(vec, 10.0, GetConVarFloat(g_TimeBombRadius) / 3.0, g_BeamSprite, g_HaloSprite, 0, 10, 0.6, 10.0, 0.5, whiteColor, 10, 0);
|
||||
TE_SendToAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
TE_SetupExplosion(vec, g_ExplosionSprite, 5.0, 1, 0, GetConVarInt(g_TimeBombRadius), 5000);
|
||||
TE_SendToAll();
|
||||
|
||||
EmitAmbientSound(SOUND_BOOM, vec, client, SNDLEVEL_RAIDSIREN);
|
||||
|
||||
ForcePlayerSuicide(client);
|
||||
KillTimeBomb(client);
|
||||
SetEntityRenderColor(client, 255, 255, 255, 255);
|
||||
|
||||
if (GetConVarInt(g_TimeBombMode) > 0)
|
||||
{
|
||||
new teamOnly = ((GetConVarInt(g_TimeBombMode) == 1) ? true : false);
|
||||
new maxClients = GetMaxClients();
|
||||
|
||||
//g_FilteredEntity = client;
|
||||
|
||||
for (new i = 1; i < maxClients; i++)
|
||||
{
|
||||
if (!IsClientInGame(i) || !IsPlayerAlive(i) || i == client)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (teamOnly && GetClientTeam(i) != GetClientTeam(client))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
new Float:pos[3];
|
||||
GetClientEyePosition(i, pos);
|
||||
|
||||
new Float:distance = GetVectorDistance(vec, pos);
|
||||
|
||||
if (distance > GetConVarFloat(g_TimeBombRadius))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
new damage = 220;
|
||||
damage = RoundToFloor(damage * ((GetConVarFloat(g_TimeBombRadius) - distance) / GetConVarFloat(g_TimeBombRadius)));
|
||||
|
||||
SlapPlayer(i, damage, false);
|
||||
TE_SetupExplosion(pos, g_ExplosionSprite, 0.05, 1, 0, 1, 1);
|
||||
TE_SendToAll();
|
||||
|
||||
/*
|
||||
new Float:dir[3];
|
||||
SubtractVectors(vec, pos, dir);
|
||||
TR_TraceRayFilter(vec, dir, MASK_SOLID, RayType_Infinite, TR_Filter_Client);
|
||||
|
||||
if (i == TR_GetEntityIndex())
|
||||
{
|
||||
new damage = 100;
|
||||
new radius = GetConVarInt(g_TimeBombRadius) / 2;
|
||||
|
||||
if (distance > radius)
|
||||
{
|
||||
distance -= radius;
|
||||
damage = RoundToFloor(damage * ((radius - distance) / radius));
|
||||
}
|
||||
|
||||
SlapPlayer(i, damage, false);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public AdminMenu_TimeBomb(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "TimeBomb player", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayTimeBombMenu(param);
|
||||
}
|
||||
}
|
||||
|
||||
DisplayTimeBombMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_TimeBomb);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "TimeBomb player", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddTargetsToMenu(menu, client, true, true);
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
public MenuHandler_TimeBomb(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32];
|
||||
new userid, target;
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info));
|
||||
userid = StringToInt(info);
|
||||
|
||||
if ((target = GetClientOfUserId(userid)) == 0)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player no longer available");
|
||||
}
|
||||
else if (!CanUserTarget(param1, target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Unable to target");
|
||||
}
|
||||
else
|
||||
{
|
||||
new String:name[32];
|
||||
GetClientName(target, name, sizeof(name));
|
||||
|
||||
PerformTimeBomb(param1, target, 2);
|
||||
ShowActivity2(param1, "[SM] ", "%t", "Toggled TimeBomb on target", "_s", name);
|
||||
}
|
||||
|
||||
/* Re-draw the menu if they're still valid */
|
||||
if (IsClientInGame(param1) && !IsClientInKickQueue(param1))
|
||||
{
|
||||
DisplayTimeBombMenu(param1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_TimeBomb(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_timebomb <#userid|name> [0/1]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:arg[65];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
|
||||
new toggle = 2;
|
||||
if (args > 1)
|
||||
{
|
||||
decl String:arg2[2];
|
||||
GetCmdArg(2, arg2, sizeof(arg2));
|
||||
if (arg2[0])
|
||||
{
|
||||
toggle = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
toggle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_ALIVE,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
for (new i = 0; i < target_count; i++)
|
||||
{
|
||||
PerformTimeBomb(client, target_list[i], toggle);
|
||||
}
|
||||
|
||||
if (tn_is_ml)
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled TimeBomb on target", target_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowActivity2(client, "[SM] ", "%t", "Toggled TimeBomb on target", "_s", target_name);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,355 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Fun Votes Plugin
|
||||
* Implements extra fun vote commands.
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
|
||||
#undef REQUIRE_PLUGIN
|
||||
#include <adminmenu>
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = "Fun Votes",
|
||||
author = "AlliedModders LLC",
|
||||
description = "Fun Vote Commands",
|
||||
version = SOURCEMOD_VERSION,
|
||||
url = "http://www.sourcemod.net/"
|
||||
};
|
||||
|
||||
#define VOTE_NO "###no###"
|
||||
#define VOTE_YES "###yes###"
|
||||
|
||||
new Handle:g_hVoteMenu = INVALID_HANDLE;
|
||||
|
||||
new Handle:g_Cvar_Limits[5] = {INVALID_HANDLE, ...};
|
||||
new Handle:g_Cvar_Gravity = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_Alltalk = INVALID_HANDLE;
|
||||
new Handle:g_Cvar_FF = INVALID_HANDLE;
|
||||
|
||||
// new Handle:g_Cvar_Show = INVALID_HANDLE;
|
||||
|
||||
enum voteType
|
||||
{
|
||||
gravity = 0,
|
||||
burn,
|
||||
slay,
|
||||
alltalk,
|
||||
ff
|
||||
};
|
||||
|
||||
new voteType:g_voteType = voteType:gravity;
|
||||
|
||||
// Menu API does not provide us with a way to pass multiple peices of data with a single
|
||||
// choice, so some globals are used to hold stuff.
|
||||
//
|
||||
#define VOTE_CLIENTID 0
|
||||
#define VOTE_USERID 1
|
||||
new g_voteClient[2]; /* Holds the target's client id and user id */
|
||||
|
||||
#define VOTE_NAME 0
|
||||
#define VOTE_AUTHID 1
|
||||
#define VOTE_IP 2
|
||||
new String:g_voteInfo[3][65]; /* Holds the target's name, authid, and IP */
|
||||
|
||||
new Handle:hTopMenu = INVALID_HANDLE;
|
||||
|
||||
#include "funvotes/votegravity.sp"
|
||||
#include "funvotes/voteburn.sp"
|
||||
#include "funvotes/voteslay.sp"
|
||||
#include "funvotes/votealltalk.sp"
|
||||
#include "funvotes/voteff.sp"
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
if (FindPluginByFile("basefunvotes.smx") != INVALID_HANDLE)
|
||||
{
|
||||
ThrowError("This plugin replaces basefuncommands. You cannot run both at once.");
|
||||
}
|
||||
|
||||
LoadTranslations("common.phrases");
|
||||
LoadTranslations("basevotes.phrases");
|
||||
LoadTranslations("funvotes.phrases");
|
||||
LoadTranslations("funcommands.phrases");
|
||||
|
||||
RegAdminCmd("sm_votegravity", Command_VoteGravity, ADMFLAG_VOTE, "sm_votegravity <amount> [amount2] ... [amount5]");
|
||||
RegAdminCmd("sm_voteburn", Command_VoteBurn, ADMFLAG_VOTE|ADMFLAG_SLAY, "sm_voteburn <player>");
|
||||
RegAdminCmd("sm_voteslay", Command_VoteSlay, ADMFLAG_VOTE|ADMFLAG_SLAY, "sm_voteslay <player>");
|
||||
RegAdminCmd("sm_votealltalk", Command_VoteAlltalk, ADMFLAG_VOTE, "sm_votealltalk");
|
||||
RegAdminCmd("sm_voteff", Command_VoteFF, ADMFLAG_VOTE, "sm_voteff");
|
||||
|
||||
g_Cvar_Limits[0] = CreateConVar("sm_vote_gravity", "0.60", "percent required for successful gravity vote.", 0, true, 0.05, true, 1.0);
|
||||
g_Cvar_Limits[1] = CreateConVar("sm_vote_burn", "0.60", "percent required for successful burn vote.", 0, true, 0.05, true, 1.0);
|
||||
g_Cvar_Limits[2] = CreateConVar("sm_vote_slay", "0.60", "percent required for successful slay vote.", 0, true, 0.05, true, 1.0);
|
||||
g_Cvar_Limits[3] = CreateConVar("sm_vote_alltalk", "0.60", "percent required for successful alltalk vote.", 0, true, 0.05, true, 1.0);
|
||||
g_Cvar_Limits[4] = CreateConVar("sm_vote_ff", "0.60", "percent required for successful friendly fire vote.", 0, true, 0.05, true, 1.0);
|
||||
|
||||
g_Cvar_Gravity = FindConVar("sv_gravity");
|
||||
g_Cvar_Alltalk = FindConVar("sv_alltalk");
|
||||
g_Cvar_FF = FindConVar("mp_friendlyfire");
|
||||
|
||||
/*
|
||||
g_Cvar_Show = FindConVar("sm_vote_show");
|
||||
if (g_Cvar_Show == INVALID_HANDLE)
|
||||
{
|
||||
g_Cvar_Show = CreateConVar("sm_vote_show", "1", "Show player's votes? Default on.", 0, true, 0.0, true, 1.0);
|
||||
}
|
||||
*/
|
||||
|
||||
/* Account for late loading */
|
||||
new Handle:topmenu;
|
||||
if (LibraryExists("adminmenu") && ((topmenu = GetAdminTopMenu()) != INVALID_HANDLE))
|
||||
{
|
||||
OnAdminMenuReady(topmenu);
|
||||
}
|
||||
}
|
||||
|
||||
public OnAdminMenuReady(Handle:topmenu)
|
||||
{
|
||||
/* Block us from being called twice */
|
||||
if (topmenu == hTopMenu)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save the Handle */
|
||||
hTopMenu = topmenu;
|
||||
|
||||
/* Build the "Voting Commands" category */
|
||||
new TopMenuObject:voting_commands = FindTopMenuCategory(hTopMenu, ADMINMENU_VOTINGCOMMANDS);
|
||||
|
||||
if (voting_commands != INVALID_TOPMENUOBJECT)
|
||||
{
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_votegravity",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_VoteGravity,
|
||||
voting_commands,
|
||||
"sm_votegravity",
|
||||
ADMFLAG_VOTE);
|
||||
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_voteburn",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_VoteBurn,
|
||||
voting_commands,
|
||||
"sm_voteburn",
|
||||
ADMFLAG_VOTE|ADMFLAG_SLAY);
|
||||
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_voteslay",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_VoteSlay,
|
||||
voting_commands,
|
||||
"sm_voteslay",
|
||||
ADMFLAG_VOTE|ADMFLAG_SLAY);
|
||||
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_votealltalk",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_VoteAllTalk,
|
||||
voting_commands,
|
||||
"sm_votealltalk",
|
||||
ADMFLAG_VOTE);
|
||||
|
||||
AddToTopMenu(hTopMenu,
|
||||
"sm_voteff",
|
||||
TopMenuObject_Item,
|
||||
AdminMenu_VoteFF,
|
||||
voting_commands,
|
||||
"sm_voteff",
|
||||
ADMFLAG_VOTE);
|
||||
}
|
||||
}
|
||||
|
||||
public Handler_VoteCallback(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
VoteMenuClose();
|
||||
}
|
||||
else if (action == MenuAction_Display)
|
||||
{
|
||||
decl String:title[64];
|
||||
GetMenuTitle(menu, title, sizeof(title));
|
||||
|
||||
decl String:buffer[255];
|
||||
Format(buffer, sizeof(buffer), "%T", title, param1, g_voteInfo[VOTE_NAME]);
|
||||
|
||||
new Handle:panel = Handle:param2;
|
||||
SetPanelTitle(panel, buffer);
|
||||
}
|
||||
else if (action == MenuAction_DisplayItem)
|
||||
{
|
||||
decl String:display[64];
|
||||
GetMenuItem(menu, param2, "", 0, _, display, sizeof(display));
|
||||
|
||||
if (strcmp(display, VOTE_NO) == 0 || strcmp(display, VOTE_YES) == 0)
|
||||
{
|
||||
decl String:buffer[255];
|
||||
Format(buffer, sizeof(buffer), "%T", display, param1);
|
||||
|
||||
return RedrawMenuItem(buffer);
|
||||
}
|
||||
}
|
||||
/* else if (action == MenuAction_Select)
|
||||
{
|
||||
VoteSelect(menu, param1, param2);
|
||||
}*/
|
||||
else if (action == MenuAction_VoteCancel && param1 == VoteCancel_NoVotes)
|
||||
{
|
||||
PrintToChatAll("[SM] %t", "No Votes Cast");
|
||||
}
|
||||
else if (action == MenuAction_VoteEnd)
|
||||
{
|
||||
decl String:item[64];
|
||||
new Float:percent, Float:limit, votes, totalVotes;
|
||||
|
||||
GetMenuVoteInfo(param2, votes, totalVotes);
|
||||
GetMenuItem(menu, param1, item, sizeof(item));
|
||||
|
||||
if (strcmp(item, VOTE_NO) == 0 && param1 == 1)
|
||||
{
|
||||
votes = totalVotes - votes; // Reverse the votes to be in relation to the Yes option.
|
||||
}
|
||||
|
||||
percent = GetVotePercent(votes, totalVotes);
|
||||
|
||||
limit = GetConVarFloat(g_Cvar_Limits[g_voteType]);
|
||||
|
||||
/* :TODO: g_voteClient[userid] needs to be checked.
|
||||
*/
|
||||
|
||||
// A multi-argument vote is "always successful", but have to check if its a Yes/No vote.
|
||||
if ((strcmp(item, VOTE_YES) == 0 && FloatCompare(percent,limit) < 0 && param1 == 0) || (strcmp(item, VOTE_NO) == 0 && param1 == 1))
|
||||
{
|
||||
/* :TODO: g_voteClient[userid] should be used here and set to -1 if not applicable.
|
||||
*/
|
||||
LogAction(-1, -1, "Vote failed.");
|
||||
PrintToChatAll("[SM] %t", "Vote Failed", RoundToNearest(100.0*limit), RoundToNearest(100.0*percent), totalVotes);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintToChatAll("[SM] %t", "Vote Successful", RoundToNearest(100.0*percent), totalVotes);
|
||||
|
||||
switch (g_voteType)
|
||||
{
|
||||
case (voteType:gravity):
|
||||
{
|
||||
PrintToChatAll("[SM] %t", "Cvar changed", "sv_gravity", item);
|
||||
LogAction(-1, -1, "Changing gravity to %s due to vote.", item);
|
||||
SetConVarInt(g_Cvar_Gravity, StringToInt(item));
|
||||
}
|
||||
|
||||
case (voteType:burn):
|
||||
{
|
||||
PrintToChatAll("[SM] %t", "Set target on fire", "_s", g_voteInfo[VOTE_NAME]);
|
||||
LogAction(-1, g_voteClient[VOTE_CLIENTID], "Vote burn successful, igniting \"%L\"", g_voteClient[VOTE_CLIENTID]);
|
||||
|
||||
IgniteEntity(g_voteClient[VOTE_CLIENTID], 19.8);
|
||||
}
|
||||
|
||||
case (voteType:slay):
|
||||
{
|
||||
PrintToChatAll("[SM] %t", "Slayed player", g_voteInfo[VOTE_NAME]);
|
||||
LogAction(-1, g_voteClient[VOTE_CLIENTID], "Vote slay successful, slaying \"%L\"", g_voteClient[VOTE_CLIENTID]);
|
||||
|
||||
ExtinguishEntity(g_voteClient[VOTE_CLIENTID]);
|
||||
ForcePlayerSuicide(g_voteClient[VOTE_CLIENTID]);
|
||||
}
|
||||
|
||||
case (voteType:alltalk):
|
||||
{
|
||||
PrintToChatAll("[SM] %t", "Cvar changed", "sv_alltalk", (GetConVarBool(g_Cvar_Alltalk) ? "0" : "1"));
|
||||
LogAction(-1, -1, "Changing alltalk to %s due to vote.", (GetConVarBool(g_Cvar_Alltalk) ? "0" : "1"));
|
||||
SetConVarBool(g_Cvar_Alltalk, !GetConVarBool(g_Cvar_Alltalk));
|
||||
}
|
||||
|
||||
case (voteType:ff):
|
||||
{
|
||||
PrintToChatAll("[SM] %t", "Cvar changed", "mp_friendlyfire", (GetConVarBool(g_Cvar_FF) ? "0" : "1"));
|
||||
LogAction(-1, -1, "Changing friendly fire to %s due to vote.", (GetConVarBool(g_Cvar_FF) ? "0" : "1"));
|
||||
SetConVarBool(g_Cvar_FF, !GetConVarBool(g_Cvar_FF));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
VoteSelect(Handle:menu, param1, param2 = 0)
|
||||
{
|
||||
if (GetConVarInt(g_Cvar_VoteShow) == 1)
|
||||
{
|
||||
decl String:voter[64], String:junk[64], String:choice[64];
|
||||
GetClientName(param1, voter, sizeof(voter));
|
||||
GetMenuItem(menu, param2, junk, sizeof(junk), _, choice, sizeof(choice));
|
||||
PrintToChatAll("[SM] %T", "Vote Select", LANG_SERVER, voter, choice);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
VoteMenuClose()
|
||||
{
|
||||
CloseHandle(g_hVoteMenu);
|
||||
g_hVoteMenu = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
Float:GetVotePercent(votes, totalVotes)
|
||||
{
|
||||
return FloatDiv(float(votes),float(totalVotes));
|
||||
}
|
||||
|
||||
bool:TestVoteDelay(client)
|
||||
{
|
||||
new delay = CheckVoteDelay();
|
||||
|
||||
if (delay > 0)
|
||||
{
|
||||
if (delay > 60)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Vote Delay Minutes", delay % 60);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Vote Delay Seconds", delay);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basefunvotes Plugin
|
||||
* Provides votealltalk functionality
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
DisplayVoteAllTalkMenu(client)
|
||||
{
|
||||
if (IsVoteInProgress())
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Vote in Progress");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TestVoteDelay(client))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LogAction(client, -1, "\"%L\" initiated an alltalk vote.", client);
|
||||
ShowActivity2(client, "[SM] ", "%t", "Initiated Vote Alltalk");
|
||||
|
||||
g_voteType = voteType:alltalk;
|
||||
g_voteInfo[VOTE_NAME][0] = '\0';
|
||||
|
||||
g_hVoteMenu = CreateMenu(Handler_VoteCallback, MenuAction:MENU_ACTIONS_ALL);
|
||||
|
||||
if (GetConVarBool(g_Cvar_Alltalk))
|
||||
{
|
||||
SetMenuTitle(g_hVoteMenu, "Votealltalk Off");
|
||||
}
|
||||
else
|
||||
{
|
||||
SetMenuTitle(g_hVoteMenu, "Votealltalk On");
|
||||
}
|
||||
|
||||
AddMenuItem(g_hVoteMenu, VOTE_YES, "Yes");
|
||||
AddMenuItem(g_hVoteMenu, VOTE_NO, "No");
|
||||
SetMenuExitButton(g_hVoteMenu, false);
|
||||
VoteMenuToAll(g_hVoteMenu, 20);
|
||||
}
|
||||
|
||||
|
||||
public AdminMenu_VoteAllTalk(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Alltalk vote", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayVoteAllTalkMenu(param);
|
||||
}
|
||||
else if (action == TopMenuAction_DrawOption)
|
||||
{
|
||||
/* disable this option if a vote is already running */
|
||||
buffer[0] = !IsNewVoteAllowed() ? ITEMDRAW_IGNORE : ITEMDRAW_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_VoteAlltalk(client, args)
|
||||
{
|
||||
if (args > 0)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_votealltalk");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
DisplayVoteAllTalkMenu(client);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basefunvotes Plugin
|
||||
* Provides voteburn functionality
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
DisplayVoteBurnMenu(client, target, String:name[])
|
||||
{
|
||||
if (!IsPlayerAlive(target))
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Cannot be performed on dead", name);
|
||||
return;
|
||||
}
|
||||
|
||||
g_voteClient[VOTE_CLIENTID] = target;
|
||||
GetClientName(target, g_voteInfo[VOTE_NAME], sizeof(g_voteInfo[]));
|
||||
|
||||
LogAction(client, target, "\"%L\" initiated a burn vote against \"%L\"", client, target);
|
||||
ShowActivity2(client, "[SM] ", "%t", "Initiated Vote Burn", g_voteInfo[VOTE_NAME]);
|
||||
|
||||
g_voteType = voteType:burn;
|
||||
|
||||
g_hVoteMenu = CreateMenu(Handler_VoteCallback, MenuAction:MENU_ACTIONS_ALL);
|
||||
SetMenuTitle(g_hVoteMenu, "Voteburn player");
|
||||
AddMenuItem(g_hVoteMenu, VOTE_YES, "Yes");
|
||||
AddMenuItem(g_hVoteMenu, VOTE_NO, "No");
|
||||
SetMenuExitButton(g_hVoteMenu, false);
|
||||
VoteMenuToAll(g_hVoteMenu, 20);
|
||||
}
|
||||
|
||||
DisplayBurnTargetMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_Burn);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Burn vote", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddTargetsToMenu(menu, client, true, true);
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
public AdminMenu_VoteBurn(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Burn vote", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayBurnTargetMenu(param);
|
||||
}
|
||||
else if (action == TopMenuAction_DrawOption)
|
||||
{
|
||||
/* disable this option if a vote is already running */
|
||||
buffer[0] = !IsNewVoteAllowed() ? ITEMDRAW_IGNORE : ITEMDRAW_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
public MenuHandler_Burn(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32], String:name[32];
|
||||
new userid, target;
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info), _, name, sizeof(name));
|
||||
userid = StringToInt(info);
|
||||
|
||||
if ((target = GetClientOfUserId(userid)) == 0)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player no longer available");
|
||||
}
|
||||
else if (!CanUserTarget(param1, target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Unable to target");
|
||||
}
|
||||
else if (!IsPlayerAlive(target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player has since died");
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayVoteBurnMenu(param1, target, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_VoteBurn(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_voteburn <player>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (IsVoteInProgress())
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Vote in Progress");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (!TestVoteDelay(client))
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:text[256], String:arg[64];
|
||||
GetCmdArgString(text, sizeof(text));
|
||||
|
||||
BreakString(text, arg, sizeof(arg));
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_NO_MULTI,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
DisplayVoteBurnMenu(client, target_list[0], arg);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basefunvotes Plugin
|
||||
* Provides vote ff functionality
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
DisplayVoteFFMenu(client)
|
||||
{
|
||||
if (IsVoteInProgress())
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Vote in Progress");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TestVoteDelay(client))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LogAction(client, -1, "\"%L\" initiated a friendly fire vote.", client);
|
||||
ShowActivity2(client, "[SM] ", "%t", "Initiated Vote FF");
|
||||
|
||||
g_voteType = voteType:ff;
|
||||
g_voteInfo[VOTE_NAME][0] = '\0';
|
||||
|
||||
g_hVoteMenu = CreateMenu(Handler_VoteCallback, MenuAction:MENU_ACTIONS_ALL);
|
||||
|
||||
if (GetConVarBool(g_Cvar_FF))
|
||||
{
|
||||
SetMenuTitle(g_hVoteMenu, "Voteff Off");
|
||||
}
|
||||
else
|
||||
{
|
||||
SetMenuTitle(g_hVoteMenu, "Voteff On");
|
||||
}
|
||||
|
||||
AddMenuItem(g_hVoteMenu, VOTE_YES, "Yes");
|
||||
AddMenuItem(g_hVoteMenu, VOTE_NO, "No");
|
||||
SetMenuExitButton(g_hVoteMenu, false);
|
||||
VoteMenuToAll(g_hVoteMenu, 20);
|
||||
}
|
||||
|
||||
public AdminMenu_VoteFF(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Vote FF", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplayVoteFFMenu(param);
|
||||
}
|
||||
else if (action == TopMenuAction_DrawOption)
|
||||
{
|
||||
/* disable this option if a vote is already running */
|
||||
buffer[0] = !IsNewVoteAllowed() ? ITEMDRAW_IGNORE : ITEMDRAW_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_VoteFF(client, args)
|
||||
{
|
||||
if (args > 0)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_voteff");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
DisplayVoteFFMenu(client);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basefunvotes Plugin
|
||||
* Provides votegravity functionality
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
|
||||
DisplayVoteGravityMenu(client,count,String:items[5][])
|
||||
{
|
||||
LogAction(client, -1, "\"%L\" initiated a gravity vote.", client);
|
||||
ShowActivity2(client, "[SM] ", "%t", "Initiated Vote Gravity");
|
||||
|
||||
g_voteType = voteType:gravity;
|
||||
|
||||
g_hVoteMenu = CreateMenu(Handler_VoteCallback, MenuAction:MENU_ACTIONS_ALL);
|
||||
|
||||
if (count == 1)
|
||||
{
|
||||
strcopy(g_voteInfo[VOTE_NAME], sizeof(g_voteInfo[]), items[0]);
|
||||
|
||||
SetMenuTitle(g_hVoteMenu, "Change Gravity To");
|
||||
AddMenuItem(g_hVoteMenu, items[0], "Yes");
|
||||
AddMenuItem(g_hVoteMenu, VOTE_NO, "No");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_voteInfo[VOTE_NAME][0] = '\0';
|
||||
|
||||
SetMenuTitle(g_hVoteMenu, "Gravity Vote");
|
||||
for (new i = 0; i < count; i++)
|
||||
{
|
||||
AddMenuItem(g_hVoteMenu, items[i], items[i]);
|
||||
}
|
||||
}
|
||||
|
||||
SetMenuExitButton(g_hVoteMenu, false);
|
||||
VoteMenuToAll(g_hVoteMenu, 20);
|
||||
}
|
||||
|
||||
public AdminMenu_VoteGravity(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Gravity vote", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
/* Might need a better way of selecting the list of pre-defined gravity choices */
|
||||
new String:items[5][5] ={"200","400","800","1600","3200"};
|
||||
DisplayVoteGravityMenu(param,5, items);
|
||||
}
|
||||
else if (action == TopMenuAction_DrawOption)
|
||||
{
|
||||
/* disable this option if a vote is already running */
|
||||
buffer[0] = !IsNewVoteAllowed() ? ITEMDRAW_IGNORE : ITEMDRAW_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_VoteGravity(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_votegravity <amount> [amount2] ... [amount5]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (IsVoteInProgress())
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Vote in Progress");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (!TestVoteDelay(client))
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:text[256];
|
||||
GetCmdArgString(text, sizeof(text));
|
||||
|
||||
decl String:items[5][64];
|
||||
new count;
|
||||
new len, pos;
|
||||
|
||||
while (pos != -1 && count < 5)
|
||||
{
|
||||
pos = BreakString(text[len], items[count], sizeof(items[]));
|
||||
|
||||
decl Float:temp;
|
||||
if (StringToFloatEx(items[count], temp) == 0)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Invalid Amount");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
count++;
|
||||
|
||||
if (pos != -1)
|
||||
{
|
||||
len += pos;
|
||||
}
|
||||
}
|
||||
|
||||
DisplayVoteGravityMenu(client, count, items);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Basefunvotes Plugin
|
||||
* Provides voteslay functionality
|
||||
*
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
|
||||
DisplayVoteSlayMenu(client, target, String:name[])
|
||||
{
|
||||
if (!IsPlayerAlive(target))
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Cannot be performed on dead", name);
|
||||
return;
|
||||
}
|
||||
|
||||
g_voteClient[VOTE_CLIENTID] = target;
|
||||
GetClientName(target, g_voteInfo[VOTE_NAME], sizeof(g_voteInfo[]));
|
||||
|
||||
LogAction(client, target, "\"%L\" initiated a slay vote against \"%L\"", client, target);
|
||||
ShowActivity2(client, "[SM] ", "%t", "Initiated Vote Slay", g_voteInfo[VOTE_NAME]);
|
||||
|
||||
g_voteType = voteType:slay;
|
||||
|
||||
g_hVoteMenu = CreateMenu(Handler_VoteCallback, MenuAction:MENU_ACTIONS_ALL);
|
||||
SetMenuTitle(g_hVoteMenu, "Voteslay Player");
|
||||
AddMenuItem(g_hVoteMenu, VOTE_YES, "Yes");
|
||||
AddMenuItem(g_hVoteMenu, VOTE_NO, "No");
|
||||
SetMenuExitButton(g_hVoteMenu, false);
|
||||
VoteMenuToAll(g_hVoteMenu, 20);
|
||||
}
|
||||
|
||||
DisplaySlayTargetMenu(client)
|
||||
{
|
||||
new Handle:menu = CreateMenu(MenuHandler_Slay);
|
||||
|
||||
decl String:title[100];
|
||||
Format(title, sizeof(title), "%T:", "Slay vote", client);
|
||||
SetMenuTitle(menu, title);
|
||||
SetMenuExitBackButton(menu, true);
|
||||
|
||||
AddTargetsToMenu(menu, client, true, true);
|
||||
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
public AdminMenu_VoteSlay(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength)
|
||||
{
|
||||
if (action == TopMenuAction_DisplayOption)
|
||||
{
|
||||
Format(buffer, maxlength, "%T", "Slay vote", param);
|
||||
}
|
||||
else if (action == TopMenuAction_SelectOption)
|
||||
{
|
||||
DisplaySlayTargetMenu(param);
|
||||
}
|
||||
else if (action == TopMenuAction_DrawOption)
|
||||
{
|
||||
/* disable this option if a vote is already running */
|
||||
buffer[0] = !IsNewVoteAllowed() ? ITEMDRAW_IGNORE : ITEMDRAW_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
public MenuHandler_Slay(Handle:menu, MenuAction:action, param1, param2)
|
||||
{
|
||||
if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu);
|
||||
}
|
||||
else if (action == MenuAction_Cancel)
|
||||
{
|
||||
if (param2 == MenuCancel_ExitBack && hTopMenu != INVALID_HANDLE)
|
||||
{
|
||||
DisplayTopMenu(hTopMenu, param1, TopMenuPosition_LastCategory);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:info[32], String:name[32];
|
||||
new userid, target;
|
||||
|
||||
GetMenuItem(menu, param2, info, sizeof(info), _, name, sizeof(name));
|
||||
userid = StringToInt(info);
|
||||
|
||||
if ((target = GetClientOfUserId(userid)) == 0)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player no longer available");
|
||||
}
|
||||
else if (!CanUserTarget(param1, target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Unable to target");
|
||||
}
|
||||
else if (!IsPlayerAlive(target))
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Player has since died");
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayVoteSlayMenu(param1, target, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action:Command_VoteSlay(client, args)
|
||||
{
|
||||
if (args < 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_voteslay <player>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (IsVoteInProgress())
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Vote in Progress");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (!TestVoteDelay(client))
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:text[256], String:arg[64];
|
||||
GetCmdArgString(text, sizeof(text));
|
||||
|
||||
BreakString(text, arg, sizeof(arg));
|
||||
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[MAXPLAYERS], target_count, bool:tn_is_ml;
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
arg,
|
||||
client,
|
||||
target_list,
|
||||
MAXPLAYERS,
|
||||
COMMAND_FILTER_NO_MULTI,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) <= 0)
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
DisplayVoteSlayMenu(client, target_list[0], arg);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@@ -0,0 +1,622 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _admin_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _admin_included
|
||||
|
||||
/**
|
||||
* Access levels (flags) for admins.
|
||||
*/
|
||||
enum AdminFlag
|
||||
{
|
||||
Admin_Reservation = 0, /**< Reserved slot */
|
||||
Admin_Generic, /**< Generic admin abilities */
|
||||
Admin_Kick, /**< Kick another user */
|
||||
Admin_Ban, /**< Ban another user */
|
||||
Admin_Unban, /**< Unban another user */
|
||||
Admin_Slay, /**< Slay/kill/damage another user */
|
||||
Admin_Changemap, /**< Change the map */
|
||||
Admin_Convars, /**< Change basic convars */
|
||||
Admin_Config, /**< Change configuration */
|
||||
Admin_Chat, /**< Special chat privileges */
|
||||
Admin_Vote, /**< Special vote privileges */
|
||||
Admin_Password, /**< Set a server password */
|
||||
Admin_RCON, /**< Use RCON */
|
||||
Admin_Cheats, /**< Change sv_cheats and use its commands */
|
||||
Admin_Root, /**< All access by default */
|
||||
Admin_Custom1, /**< First custom flag type */
|
||||
Admin_Custom2, /**< Second custom flag type */
|
||||
Admin_Custom3, /**< Third custom flag type */
|
||||
Admin_Custom4, /**< Fourth custom flag type */
|
||||
Admin_Custom5, /**< Fifth custom flag type */
|
||||
Admin_Custom6, /**< Sixth custom flag type */
|
||||
/* --- */
|
||||
};
|
||||
|
||||
#define AdminFlags_TOTAL 21 /**< Total number of admin flags */
|
||||
|
||||
/**
|
||||
* @section Bitwise values definitions for admin flags.
|
||||
*/
|
||||
#define ADMFLAG_RESERVATION (1<<0) /**< Convenience macro for Admin_Reservation as a FlagBit */
|
||||
#define ADMFLAG_GENERIC (1<<1) /**< Convenience macro for Admin_Generic as a FlagBit */
|
||||
#define ADMFLAG_KICK (1<<2) /**< Convenience macro for Admin_Kick as a FlagBit */
|
||||
#define ADMFLAG_BAN (1<<3) /**< Convenience macro for Admin_Ban as a FlagBit */
|
||||
#define ADMFLAG_UNBAN (1<<4) /**< Convenience macro for Admin_Unban as a FlagBit */
|
||||
#define ADMFLAG_SLAY (1<<5) /**< Convenience macro for Admin_Slay as a FlagBit */
|
||||
#define ADMFLAG_CHANGEMAP (1<<6) /**< Convenience macro for Admin_Changemap as a FlagBit */
|
||||
#define ADMFLAG_CONVARS (1<<7) /**< Convenience macro for Admin_Convars as a FlagBit */
|
||||
#define ADMFLAG_CONFIG (1<<8) /**< Convenience macro for Admin_Config as a FlagBit */
|
||||
#define ADMFLAG_CHAT (1<<9) /**< Convenience macro for Admin_Chat as a FlagBit */
|
||||
#define ADMFLAG_VOTE (1<<10) /**< Convenience macro for Admin_Vote as a FlagBit */
|
||||
#define ADMFLAG_PASSWORD (1<<11) /**< Convenience macro for Admin_Password as a FlagBit */
|
||||
#define ADMFLAG_RCON (1<<12) /**< Convenience macro for Admin_RCON as a FlagBit */
|
||||
#define ADMFLAG_CHEATS (1<<13) /**< Convenience macro for Admin_Cheats as a FlagBit */
|
||||
#define ADMFLAG_ROOT (1<<14) /**< Convenience macro for Admin_Root as a FlagBit */
|
||||
#define ADMFLAG_CUSTOM1 (1<<15) /**< Convenience macro for Admin_Custom1 as a FlagBit */
|
||||
#define ADMFLAG_CUSTOM2 (1<<16) /**< Convenience macro for Admin_Custom2 as a FlagBit */
|
||||
#define ADMFLAG_CUSTOM3 (1<<17) /**< Convenience macro for Admin_Custom3 as a FlagBit */
|
||||
#define ADMFLAG_CUSTOM4 (1<<18) /**< Convenience macro for Admin_Custom4 as a FlagBit */
|
||||
#define ADMFLAG_CUSTOM5 (1<<19) /**< Convenience macro for Admin_Custom5 as a FlagBit */
|
||||
#define ADMFLAG_CUSTOM6 (1<<20) /**< Convenience macro for Admin_Custom6 as a FlagBit */
|
||||
|
||||
/**
|
||||
* @endsection
|
||||
*/
|
||||
|
||||
/**
|
||||
* @section Hardcoded authentication methods
|
||||
*/
|
||||
#define AUTHMETHOD_STEAM "steam" /**< SteamID based authentication */
|
||||
#define AUTHMETHOD_IP "ip" /**< IP based authentication */
|
||||
#define AUTHMETHOD_NAME "name" /**< Name based authentication */
|
||||
|
||||
/**
|
||||
* @endsection
|
||||
*/
|
||||
|
||||
/**
|
||||
* Access override types.
|
||||
*/
|
||||
enum OverrideType
|
||||
{
|
||||
Override_Command = 1, /**< Command */
|
||||
Override_CommandGroup, /**< Command group */
|
||||
};
|
||||
|
||||
/**
|
||||
* Access override rules.
|
||||
*/
|
||||
enum OverrideRule
|
||||
{
|
||||
Command_Deny = 0,
|
||||
Command_Allow = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* DEPRECATED, do not use.
|
||||
*/
|
||||
enum ImmunityType
|
||||
{
|
||||
Immunity_Default = 1, /**< Deprecated. */
|
||||
Immunity_Global, /**< Deprecated. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Identifies a unique entry in the group permissions cache. These are not Handles.
|
||||
*/
|
||||
enum GroupId
|
||||
{
|
||||
INVALID_GROUP_ID = -1, /**< An invalid/nonexistant group */
|
||||
};
|
||||
|
||||
/**
|
||||
* Identifies a unique entry in the admin permissions cache. These are not Handles.
|
||||
*/
|
||||
enum AdminId
|
||||
{
|
||||
INVALID_ADMIN_ID = -1, /**< An invalid/nonexistant admin */
|
||||
};
|
||||
|
||||
/**
|
||||
* Methods of computing access permissions.
|
||||
*/
|
||||
enum AdmAccessMode
|
||||
{
|
||||
Access_Real, /**< Access the user has inherently */
|
||||
Access_Effective, /**< Access the user has from their groups */
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents the various cache regions.
|
||||
*/
|
||||
enum AdminCachePart
|
||||
{
|
||||
AdminCache_Overrides = 0, /**< Global overrides */
|
||||
AdminCache_Groups = 1, /**< All groups (automatically invalidates admins too) */
|
||||
AdminCache_Admins = 2, /**< All admins */
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when part of the cache which needs to be rebuilt.
|
||||
*
|
||||
* @param part Part of the admin cache to rebuild.
|
||||
*/
|
||||
forward OnRebuildAdminCache(AdminCachePart:part);
|
||||
|
||||
/**
|
||||
* Tells the admin system to dump a portion of the cache.
|
||||
*
|
||||
* @param part Part of the cache to dump. Specifying groups also dumps admins.
|
||||
* @param rebuild If true, the rebuild forwards will fire.
|
||||
* @noreturn
|
||||
*/
|
||||
native DumpAdminCache(AdminCachePart:part, bool:rebuild);
|
||||
|
||||
/**
|
||||
* Adds a global command flag override. Any command registered with this name
|
||||
* will assume the new flag. This is applied retroactively as well.
|
||||
*
|
||||
* @param cmd String containing command name (case sensitive).
|
||||
* @param type Override type (specific command or group).
|
||||
* @param flags New admin flag.
|
||||
* @noreturn
|
||||
*/
|
||||
native AddCommandOverride(const String:cmd[], OverrideType:type, flags);
|
||||
|
||||
/**
|
||||
* Returns a command override.
|
||||
*
|
||||
* @param cmd String containing command name (case sensitive).
|
||||
* @param type Override type (specific command or group).
|
||||
* @param flags By-reference cell to store the flag (undefined if not found).
|
||||
* @return True if there is an override, false otherwise.
|
||||
*/
|
||||
native bool:GetCommandOverride(const String:cmd[], OverrideType:type, &flags);
|
||||
|
||||
/**
|
||||
* Unsets a command override.
|
||||
*
|
||||
* @param cmd String containing command name (case sensitive).
|
||||
* @param type Override type (specific command or group).
|
||||
* @noreturn
|
||||
*/
|
||||
native UnsetCommandOverride(const String:cmd[], OverrideType:type);
|
||||
|
||||
/**
|
||||
* Adds a new group. Name must be unique.
|
||||
*
|
||||
* @param group_name String containing the group name.
|
||||
* @return A new group id, INVALID_GROUP_ID if it already exists.
|
||||
*/
|
||||
native GroupId:CreateAdmGroup(const String:group_name[]);
|
||||
|
||||
/**
|
||||
* Finds a group by name.
|
||||
*
|
||||
* @param group_name String containing the group name.
|
||||
* @return A group id, or INVALID_GROUP_ID if not found.
|
||||
*/
|
||||
native GroupId:FindAdmGroup(const String:group_name[]);
|
||||
|
||||
/**
|
||||
* Adds or removes a flag from a group's flag set.
|
||||
* @note These are called "add flags" because they add to a user's flags.
|
||||
*
|
||||
* @param id Group id.
|
||||
* @param flag Admin flag to toggle.
|
||||
* @param enabled True to set the flag, false to unset/disable.
|
||||
* @noreturn
|
||||
*/
|
||||
native SetAdmGroupAddFlag(GroupId:id, AdminFlag:flag, bool:enabled);
|
||||
|
||||
/**
|
||||
* Gets the set value of an add flag on a group's flag set.
|
||||
* @note These are called "add flags" because they add to a user's flags.
|
||||
*
|
||||
* @param id Group id.
|
||||
* @param flag Admin flag to retrieve.
|
||||
* @return True if enabled, false otherwise,
|
||||
*/
|
||||
native bool:GetAdmGroupAddFlag(GroupId:id, AdminFlag:flag);
|
||||
|
||||
/**
|
||||
* Returns the flag set that is added to a user from their group.
|
||||
* @note These are called "add flags" because they add to a user's flags.
|
||||
*
|
||||
* @param id GroupId of the group.
|
||||
* @return Bitstring containing the flags enabled.
|
||||
*/
|
||||
native GetAdmGroupAddFlags(GroupId:id);
|
||||
|
||||
/**
|
||||
* @deprecated Functionality removed.
|
||||
*/
|
||||
#pragma deprecated Use SetAdmGroupImmunityLevel() instead.
|
||||
native SetAdmGroupImmunity(GroupId:id, ImmunityType:type, bool:enabled);
|
||||
|
||||
/**
|
||||
* @deprecated Functionality removed.
|
||||
*/
|
||||
#pragma deprecated Use GetAdmGroupImmunityLevel() instead.
|
||||
native bool:GetAdmGroupImmunity(GroupId:id, ImmunityType:type);
|
||||
|
||||
/**
|
||||
* Adds immunity to a specific group.
|
||||
*
|
||||
* @param id Group id.
|
||||
* @param other_id Group id to receive immunity to.
|
||||
* @noreturn
|
||||
*/
|
||||
native SetAdmGroupImmuneFrom(GroupId:id, GroupId:other_id);
|
||||
|
||||
/**
|
||||
* Returns the number of specific group immunities.
|
||||
*
|
||||
* @param id Group id.
|
||||
* @return Number of group immunities.
|
||||
*/
|
||||
native GetAdmGroupImmuneCount(GroupId:id);
|
||||
|
||||
/**
|
||||
* Returns a group that this group is immune to given an index.
|
||||
*
|
||||
* @param id Group id.
|
||||
* @param number Index from 0 to N-1, from GetAdmGroupImmuneCount().
|
||||
* @return GroupId that this group is immune to, or INVALID_GROUP_ID on failure.
|
||||
*/
|
||||
native GroupId:GetAdmGroupImmuneFrom(GroupId:id, number);
|
||||
|
||||
/**
|
||||
* Adds a group-specific override type.
|
||||
*
|
||||
* @param id Group id.
|
||||
* @param name String containing command name (case sensitive).
|
||||
* @param type Override type (specific command or group).
|
||||
* @param rule Override allow/deny setting.
|
||||
* @noreturn
|
||||
*/
|
||||
native AddAdmGroupCmdOverride(GroupId:id, const String:name[], OverrideType:type, OverrideRule:rule);
|
||||
|
||||
/**
|
||||
* Retrieves a group-specific command override.
|
||||
*
|
||||
* @param id Group id.
|
||||
* @param name String containing command name (case sensitive).
|
||||
* @param type Override type (specific command or group).
|
||||
* @param rule Optional pointer to store allow/deny setting.
|
||||
* @return True if an override exists, false otherwise.
|
||||
*/
|
||||
native bool:GetAdmGroupCmdOverride(GroupId:id, const String:name[], OverrideType:type, &OverrideRule:rule);
|
||||
|
||||
/**
|
||||
* Registers an authentication identity type. You normally never need to call this except for
|
||||
* very specific systems.
|
||||
*
|
||||
* @param codename Codename to use for your authentication type.
|
||||
* @noreturn
|
||||
*/
|
||||
native RegisterAuthIdentType(const String:name[]);
|
||||
|
||||
/**
|
||||
* Creates a new admin entry in the permissions cache.
|
||||
*
|
||||
* @param name Name for this entry (does not have to be unique).
|
||||
* Specify an empty string for an anonymous admin.
|
||||
*/
|
||||
native AdminId:CreateAdmin(const String:name[]="");
|
||||
|
||||
/**
|
||||
* Retrieves an admin's user name as made with CreateAdmin().
|
||||
*
|
||||
* @note This function can return UTF-8 strings, and will safely chop UTF-8 strings.
|
||||
*
|
||||
* @param id AdminId of the admin.
|
||||
* @param name String buffer to store name.
|
||||
* @param maxlength Maximum size of string buffer.
|
||||
* @return Number of bytes written.
|
||||
*/
|
||||
native GetAdminUsername(AdminId:id, const String:name[], maxlength);
|
||||
|
||||
/**
|
||||
* Binds an admin to an identity for fast lookup later on. The bind must be unique.
|
||||
*
|
||||
* @param id AdminId of the admin.
|
||||
* @param auth Auth method to use, predefined or from RegisterAuthIdentType().
|
||||
* @param ident String containing the arbitrary, unique identity.
|
||||
* @return True on success, false if the auth method was not found,
|
||||
* or ident was already taken.
|
||||
*/
|
||||
native bool:BindAdminIdentity(AdminId:id, const String:auth[], const String:ident[]);
|
||||
|
||||
/**
|
||||
* Sets whether or not a flag is enabled on an admin.
|
||||
*
|
||||
* @param id AdminId index of the admin.
|
||||
* @param flag Admin flag to use.
|
||||
* @param enabled True to enable, false to disable.
|
||||
* @noreturn
|
||||
*/
|
||||
native SetAdminFlag(AdminId:id, AdminFlag:flag, bool:enabled);
|
||||
|
||||
/**
|
||||
* Returns whether or not a flag is enabled on an admin.
|
||||
*
|
||||
* @param id AdminId index of the admin.
|
||||
* @param flag Admin flag to use.
|
||||
* @param mode Access mode to check.
|
||||
* @return True if enabled, false otherwise.
|
||||
*/
|
||||
native bool:GetAdminFlag(AdminId:id, AdminFlag:flag, AdmAccessMode:mode=Access_Effective);
|
||||
|
||||
/**
|
||||
* Returns the bitstring of access flags on an admin.
|
||||
*
|
||||
* @param id AdminId index of the admin.
|
||||
* @param mode Access mode to use.
|
||||
* @return A bitstring containing which flags are enabled.
|
||||
*/
|
||||
native GetAdminFlags(AdminId:id, AdmAccessMode:mode);
|
||||
|
||||
/**
|
||||
* Adds a group to an admin's inherited group list. Any flags the group has
|
||||
* will be added to the admin's effective flags.
|
||||
*
|
||||
* @param id AdminId index of the admin.
|
||||
* @param gid GroupId index of the group.
|
||||
* @return True on success, false on invalid input or duplicate membership.
|
||||
*/
|
||||
native bool:AdminInheritGroup(AdminId:id, GroupId:gid);
|
||||
|
||||
/**
|
||||
* Returns the number of groups this admin is a member of.
|
||||
*
|
||||
* @param id AdminId index of the admin.
|
||||
* @return Number of groups this admin is a member of.
|
||||
*/
|
||||
native GetAdminGroupCount(AdminId:id);
|
||||
|
||||
/**
|
||||
* Returns group information from an admin.
|
||||
*
|
||||
* @param id AdminId index of the admin.
|
||||
* @param index Group number to retrieve, from 0 to N-1, where N
|
||||
* is the value of GetAdminGroupCount(id).
|
||||
* @param name Buffer to store the group's name.
|
||||
* Note: This will safely chop UTF-8 strings.
|
||||
* @param maxlength Maximum size of the output name buffer.
|
||||
* @return A GroupId index and a name pointer, or
|
||||
* INVALID_GROUP_ID and NULL if an error occurred.
|
||||
*/
|
||||
native GroupId:GetAdminGroup(AdminId:id, index, const String:name[], maxlength);
|
||||
|
||||
/**
|
||||
* Sets a password on an admin.
|
||||
*
|
||||
* @param id AdminId index of the admin.
|
||||
* @param passwd String containing the password.
|
||||
* @noreturn
|
||||
*/
|
||||
native SetAdminPassword(AdminId:id, const String:password[]);
|
||||
|
||||
/**
|
||||
* Gets an admin's password.
|
||||
*
|
||||
* @param id AdminId index of the admin.
|
||||
* @param name Optional buffer to store the admin's password.
|
||||
* @param maxlength Maximum size of the output name buffer.
|
||||
* Note: This will safely chop UTF-8 strings.
|
||||
* @return True if there was a password set, false otherwise.
|
||||
*/
|
||||
native bool:GetAdminPassword(AdminId:id, const String:buffer[]="", maxlength=0);
|
||||
|
||||
/**
|
||||
* Attempts to find an admin by an auth method and an identity.
|
||||
*
|
||||
* @param auth Auth method to try.
|
||||
* @param identity Identity string to look up.
|
||||
* @return An AdminId index if found, INVALID_ADMIN_ID otherwise.
|
||||
*/
|
||||
native AdminId:FindAdminByIdentity(const String:auth[], const String:identity[]);
|
||||
|
||||
/**
|
||||
* Removes an admin entry from the cache.
|
||||
*
|
||||
* @note This will remove any bindings to a specific user.
|
||||
*
|
||||
* @param id AdminId index to remove/invalidate.
|
||||
* @return True on success, false otherwise.
|
||||
*/
|
||||
native bool:RemoveAdmin(AdminId:id);
|
||||
|
||||
/**
|
||||
* Converts a flag bit string to a bit array.
|
||||
*
|
||||
* @param bits Bit string containing the flags.
|
||||
* @param array Array to write the flags to. Enabled flags will be 'true'.
|
||||
* @param maxSize Maximum number of flags the array can store.
|
||||
* @return Number of flags written.
|
||||
*/
|
||||
native FlagBitsToBitArray(bits, bool:array[], maxSize);
|
||||
|
||||
/**
|
||||
* Converts a flag array to a bit string.
|
||||
*
|
||||
* @param array Array containing true or false for each AdminFlag.
|
||||
* @param maxSize Maximum size of the flag array.
|
||||
* @return A bit string composed of the array bits.
|
||||
*/
|
||||
native FlagBitArrayToBits(const bool:array[], maxSize);
|
||||
|
||||
/**
|
||||
* Converts an array of flags to bits.
|
||||
*
|
||||
* @param array Array containing flags that are enabled.
|
||||
* @param numFlags Number of flags in the array.
|
||||
* @return A bit string composed of the array flags.
|
||||
*/
|
||||
native FlagArrayToBits(const AdminFlag:array[], numFlags);
|
||||
|
||||
/**
|
||||
* Converts a bit string to an array of flags.
|
||||
*
|
||||
* @param bits Bit string containing the flags.
|
||||
* @param array Output array to write flags.
|
||||
* @param maxSize Maximum size of the flag array.
|
||||
* @return Number of flags written.
|
||||
*/
|
||||
native FlagBitsToArray(bits, AdminFlag:array[], maxSize);
|
||||
|
||||
/**
|
||||
* Finds a flag by its string name.
|
||||
*
|
||||
* @param name Flag name (like "kick"), case sensitive.
|
||||
* @param flag Variable to store flag in.
|
||||
* @return True on success, false if not found.
|
||||
*/
|
||||
native bool:FindFlagByName(const String:name[], &AdminFlag:flag);
|
||||
|
||||
/**
|
||||
* Finds a flag by a given character.
|
||||
*
|
||||
* @param c Flag ASCII character/token.
|
||||
* @param flag Variable to store flag in.
|
||||
* @return True on success, false if not found.
|
||||
*/
|
||||
native bool:FindFlagByChar(c, &AdminFlag:flag);
|
||||
|
||||
/**
|
||||
* Converts a string of flag characters to a bit string.
|
||||
*
|
||||
* @param flags Flag ASCII string.
|
||||
* @param numchars Optional variable to store the number of bytes read.
|
||||
* @return Bit string of ADMFLAG values.
|
||||
*/
|
||||
native ReadFlagString(const String:flags[], &numchars=0);
|
||||
|
||||
/**
|
||||
* Tests whether one admin can target another.
|
||||
*
|
||||
* The hueristics for this check are as follows:
|
||||
* 0. If the targeting AdminId is INVALID_ADMIN_ID, targeting fails.
|
||||
* 1. If the targeted AdminId is INVALID_ADMIN_ID, targeting succeeds.
|
||||
* 2. If the targeted AdminId is the same as the targeting AdminId,
|
||||
* (self) targeting succeeds.
|
||||
* 3. If the targeting admin is root, targeting succeeds.
|
||||
* 4. If the targeted admin has access higher (as interpreted by
|
||||
* (sm_immunity_mode) than the targeting admin, then targeting fails.
|
||||
* 5. If the targeted admin has specific immunity from the
|
||||
* targeting admin via group immunities, targeting fails.
|
||||
* 6. Targeting succeeds.
|
||||
*
|
||||
* @param admin Admin doing the targetting (may be INVALID_ADMIN_ID).
|
||||
* @param target Target admin (may be INVALID_ADMIN_ID).
|
||||
* @return True if targetable, false if immune.
|
||||
*/
|
||||
native CanAdminTarget(AdminId:admin, AdminId:target);
|
||||
|
||||
/**
|
||||
* Creates an admin auth method. This does not need to be called more than once
|
||||
* per method, ever.
|
||||
*
|
||||
* @param method Name of the authentication method.
|
||||
* @return True on success, false on failure.
|
||||
*/
|
||||
native bool:CreateAuthMethod(const String:method[]);
|
||||
|
||||
/**
|
||||
* Sets a group's immunity level.
|
||||
*
|
||||
* @param gid Group Id.
|
||||
* @param level Immunity level value.
|
||||
* @return Old immunity level value.
|
||||
*/
|
||||
native SetAdmGroupImmunityLevel(GroupId:gid, level);
|
||||
|
||||
/**
|
||||
* Gets a group's immunity level (defaults to 0).
|
||||
*
|
||||
* @param gid Group Id.
|
||||
* @return Immunity level value.
|
||||
*/
|
||||
native GetAdmGroupImmunityLevel(GroupId:gid);
|
||||
|
||||
/**
|
||||
* Sets an admin's immunity level.
|
||||
*
|
||||
* @param id Admin Id.
|
||||
* @param level Immunity level value.
|
||||
* @return Old immunity level value.
|
||||
*/
|
||||
native SetAdminImmunityLevel(AdminId:id, level);
|
||||
|
||||
/**
|
||||
* Gets an admin's immunity level.
|
||||
*
|
||||
* @param id Admin Id.
|
||||
* @return Immunity level value.
|
||||
*/
|
||||
native GetAdminImmunityLevel(AdminId:id);
|
||||
|
||||
/**
|
||||
* Converts a flag to its single bit.
|
||||
*
|
||||
* @param flag Flag to convert.
|
||||
* @return Bit representation of the flag.
|
||||
*/
|
||||
stock FlagToBit(AdminFlag:flag)
|
||||
{
|
||||
return (1<<_:flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a bit to an AdminFlag.
|
||||
*
|
||||
* @param bit Bit to convert.
|
||||
* @param flag Stores the converted flag by reference.
|
||||
* @return True on success, false otherwise.
|
||||
*/
|
||||
stock bool:BitToFlag(bit, &AdminFlag:flag)
|
||||
{
|
||||
new AdminFlag:array[1];
|
||||
|
||||
if (FlagBitsToArray(bit, array, 1))
|
||||
{
|
||||
flag = array[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _adminmenu_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _adminmenu_included
|
||||
|
||||
/* Decide whether topmenus should be required */
|
||||
#if !defined REQUIRE_PLUGIN
|
||||
#if defined REQUIRE_EXTENSIONS
|
||||
#define TEMP_REQUIRE_EXTENSIONS
|
||||
#undef REQUIRE_EXTENSIONS
|
||||
#endif
|
||||
|
||||
#include <topmenus>
|
||||
|
||||
/* Restore old REQUIRE_EXTENSIONS value if necessary */
|
||||
#if defined TEMP_REQUIRE_EXTENSIONS
|
||||
#define REQUIRE_EXTENSIONS
|
||||
#undef TEMP_REQUIRE_EXTENSIONS
|
||||
#endif
|
||||
|
||||
/** Category for player commands. */
|
||||
#define ADMINMENU_PLAYERCOMMANDS "PlayerCommands"
|
||||
/** Category for server commands. */
|
||||
#define ADMINMENU_SERVERCOMMANDS "ServerCommands"
|
||||
/** Category for voting commands. */
|
||||
#define ADMINMENU_VOTINGCOMMANDS "VotingCommands"
|
||||
|
||||
/**
|
||||
* Called when the admin menu is created and 3rd party plugins can grab
|
||||
* the Handle or add categories.
|
||||
*
|
||||
* @param topmenu Handle to the admin menu's TopMenu.
|
||||
* @noreturn
|
||||
*/
|
||||
forward OnAdminMenuCreated(Handle:topmenu);
|
||||
|
||||
/**
|
||||
* Called when the admin menu is ready to have items added.
|
||||
*
|
||||
* @param topmenu Handle to the admin menu's TopMenu.
|
||||
* @noreturn
|
||||
*/
|
||||
forward OnAdminMenuReady(Handle:topmenu);
|
||||
|
||||
/**
|
||||
* Retrieves the Handle to the admin top menu.
|
||||
*
|
||||
* @return Handle to the admin menu's TopMenu,
|
||||
* or INVALID_HANDLE if not created yet.
|
||||
*/
|
||||
native Handle:GetAdminTopMenu();
|
||||
|
||||
/**
|
||||
* Adds targets to an admin menu.
|
||||
*
|
||||
* Each client is displayed as: name (userid)
|
||||
* Each item contains the userid as a string for its info.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @param source_client Source client, or 0 to ignore immunity.
|
||||
* @param in_game_only True to only select in-game players.
|
||||
* @param alive_only True to only select alive players.
|
||||
* @return Number of clients added.
|
||||
*/
|
||||
native AddTargetsToMenu(Handle:menu,
|
||||
source_client,
|
||||
bool:in_game_only=true,
|
||||
bool:alive_only=false);
|
||||
|
||||
/**
|
||||
* Adds targets to an admin menu.
|
||||
*
|
||||
* Each client is displayed as: name (userid)
|
||||
* Each item contains the userid as a string for its info.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @param source_client Source client, or 0 to ignore immunity.
|
||||
* @param flags COMMAND_FILTER flags from commandfilters.inc.
|
||||
* @return Number of clients added.
|
||||
*/
|
||||
native AddTargetsToMenu2(Handle:menu, source_client, flags);
|
||||
|
||||
/**
|
||||
* Re-displays the admin menu to a client after selecting an item.
|
||||
* Auto-aborts if the Handle is invalid.
|
||||
*
|
||||
* @param topmenu TopMenu Handle.
|
||||
* @param client Client index.
|
||||
* @return True on success, false on failure.
|
||||
*/
|
||||
stock bool:RedisplayAdminMenu(Handle:topmenu, client)
|
||||
{
|
||||
if (topmenu == INVALID_HANDLE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return DisplayTopMenu(topmenu, client, TopMenuPosition_LastCategory);
|
||||
}
|
||||
|
||||
/* DO NOT EDIT BELOW THIS LINE */
|
||||
|
||||
public SharedPlugin:__pl_adminmenu =
|
||||
{
|
||||
name = "adminmenu",
|
||||
file = "adminmenu.smx",
|
||||
#if defined REQUIRE_PLUGIN
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined REQUIRE_PLUGIN
|
||||
public __pl_adminmenu_SetNTVOptional()
|
||||
{
|
||||
MarkNativeAsOptional("GetAdminTopMenu");
|
||||
MarkNativeAsOptional("AddTargetsToMenu");
|
||||
MarkNativeAsOptional("AddTargetsToMenu2");
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _adt_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _adt_included
|
||||
|
||||
#include <adt_array>
|
||||
#include <adt_trie>
|
||||
#include <adt_stack>
|
||||
@@ -0,0 +1,283 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _adt_array_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _adt_array_included
|
||||
|
||||
/**
|
||||
* Given a maximum string size (including the null terminator),
|
||||
* returns the number of cells required to fit that string.
|
||||
*
|
||||
* @param size Number of bytes.
|
||||
* @return Minimum number of cells required to fit the byte count.
|
||||
*/
|
||||
stock ByteCountToCells(size)
|
||||
{
|
||||
if (!size)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return (size + 3) / 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a dynamic global cell array. While slower than a normal array,
|
||||
* it can be used globally AND dynamically, which is otherwise impossible.
|
||||
*
|
||||
* The contents of the array are uniform; i.e. storing a string at index X
|
||||
* and then retrieving it as an integer is NOT the same as StringToInt()!
|
||||
* The "blocksize" determines how many cells each array slot has; it cannot
|
||||
* be changed after creation.
|
||||
*
|
||||
* @param blocksize The number of cells each member of the array can
|
||||
* hold. For example, 32 cells is equivalent to:
|
||||
* new Array[X][32]
|
||||
* @param startsize Initial size of the array. Note that data will
|
||||
* NOT be auto-intialized.
|
||||
* @return New Handle to the array object.
|
||||
*/
|
||||
native Handle:CreateArray(blocksize=1, startsize=0);
|
||||
|
||||
/**
|
||||
* Clears an array of all entries. This is the same as ResizeArray(0).
|
||||
*
|
||||
* @param array Array Handle.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native ClearArray(Handle:array);
|
||||
|
||||
/**
|
||||
* Clones an array, returning a new handle with the same size and data. This should NOT
|
||||
* be confused with CloneHandle. This is a completely new handle with the same data but
|
||||
* no relation to the original. You MUST close it.
|
||||
*
|
||||
* @param array Array handle to be cloned
|
||||
* @return New handle to the cloned array object
|
||||
* @error Invalid Handle
|
||||
*/
|
||||
native Handle:CloneArray(Handle:array);
|
||||
|
||||
/**
|
||||
* Resizes an array. If the size is smaller than the current size,
|
||||
* the array is truncated.
|
||||
*
|
||||
* @param array Array Handle.
|
||||
* @param newsize New size.
|
||||
* @noreturn
|
||||
* @error Invalid Handle or out of memory.
|
||||
*/
|
||||
native bool:ResizeArray(Handle:array, newsize);
|
||||
|
||||
/**
|
||||
* Returns the array size.
|
||||
*
|
||||
* @param array Array Handle.
|
||||
* @return Number of elements in the array.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native GetArraySize(Handle:array);
|
||||
|
||||
/**
|
||||
* Pushes a value onto the end of an array, adding a new index.
|
||||
*
|
||||
* This may safely be used even if the array has a blocksize
|
||||
* greater than 1.
|
||||
*
|
||||
* @param array Array Handle.
|
||||
* @param value Value to push.
|
||||
* @return Index of the new entry.
|
||||
* @error Invalid Handle or out of memory.
|
||||
*/
|
||||
native PushArrayCell(Handle:array, any:value);
|
||||
|
||||
/**
|
||||
* Pushes a string onto the end of an array, truncating it
|
||||
* if it is too big.
|
||||
*
|
||||
* @param array Array Handle.
|
||||
* @param value String to push.
|
||||
* @return Index of the new entry.
|
||||
* @error Invalid Handle or out of memory.
|
||||
*/
|
||||
native PushArrayString(Handle:array, const String:value[]);
|
||||
|
||||
/**
|
||||
* Pushes an array of cells onto the end of an array. The cells
|
||||
* are pushed as a block (i.e. the entire array sits at the index),
|
||||
* rather than pushing each cell individually.
|
||||
*
|
||||
* @param array Array Handle.
|
||||
* @param values Block of values to copy.
|
||||
* @param size If not set, the number of elements copied from the array
|
||||
* will be equal to the blocksize. If set higher than the
|
||||
* blocksize, the operation will be truncated.
|
||||
* @return Index of the new entry.
|
||||
* @error Invalid Handle or out of memory.
|
||||
*/
|
||||
native PushArrayArray(Handle:array, const any:values[], size=-1);
|
||||
|
||||
/**
|
||||
* Retrieves a cell value from an array.
|
||||
*
|
||||
* @param array Array Handle.
|
||||
* @param index Index in the array.
|
||||
* @param block Optionally specify which block to read from
|
||||
* (useful if the blocksize > 0).
|
||||
* @param asChar Optionally read as a byte instead of a cell.
|
||||
* @return Value read.
|
||||
* @error Invalid Handle, invalid index, or invalid block.
|
||||
*/
|
||||
native any:GetArrayCell(Handle:array, index, block=0, bool:asChar=false);
|
||||
|
||||
/**
|
||||
* Retrieves a string value from an array.
|
||||
*
|
||||
* @param array Array Handle.
|
||||
* @param index Index in the array.
|
||||
* @param buffer Buffer to copy to.
|
||||
* @param maxlength Maximum size of the buffer.
|
||||
* @return Number of characters copied.
|
||||
* @error Invalid Handle or invalid index.
|
||||
*/
|
||||
native GetArrayString(Handle:array, index, String:buffer[], maxlength);
|
||||
|
||||
/**
|
||||
* Retrieves an array of cells from an array.
|
||||
*
|
||||
* @param array Array Handle.
|
||||
* @param index Index in the array.
|
||||
* @param buffer Buffer to store the array in.
|
||||
* @param size If not set, assumes the buffer size is equal to the
|
||||
* blocksize. Otherwise, the size passed is used.
|
||||
* @return Number of cells copied.
|
||||
* @error Invalid Handle or invalid index.
|
||||
*/
|
||||
native GetArrayArray(Handle:array, index, any:buffer[], size=-1);
|
||||
|
||||
/**
|
||||
* Sets a cell value in an array.
|
||||
*
|
||||
* @param array Array Handle.
|
||||
* @param index Index in the array.
|
||||
* @param value Cell value to set.
|
||||
* @param block Optionally specify which block to write to
|
||||
* (useful if the blocksize > 0).
|
||||
* @param asChar Optionally set as a byte instead of a cell.
|
||||
* @noreturn
|
||||
* @error Invalid Handle, invalid index, or invalid block.
|
||||
*/
|
||||
native any:SetArrayCell(Handle:array, index, any:value, block=0, bool:asChar=false);
|
||||
|
||||
/**
|
||||
* Sets a string value in an array.
|
||||
*
|
||||
* @param array Array Handle.
|
||||
* @param index Index in the array.
|
||||
* @param value String value to set.
|
||||
* @return Number of characters copied.
|
||||
* @error Invalid Handle or invalid index.
|
||||
*/
|
||||
native SetArrayString(Handle:array, index, const String:buffer[]);
|
||||
|
||||
/**
|
||||
* Sets an array of cells in an array.
|
||||
*
|
||||
* @param array Array Handle.
|
||||
* @param index Index in the array.
|
||||
* @param buffer Array to copy.
|
||||
* @param size If not set, assumes the buffer size is equal to the
|
||||
* blocksize. Otherwise, the size passed is used.
|
||||
* @return Number of cells copied.
|
||||
* @error Invalid Handle or invalid index.
|
||||
*/
|
||||
native SetArrayArray(Handle:array, index, const any:values[], size=-1);
|
||||
|
||||
/**
|
||||
* Shifts an array up. All array contents after and including the given
|
||||
* index are shifted up by one, and the given index is then "free."
|
||||
* After shifting, the contents of the given index is undefined.
|
||||
*
|
||||
* @param array Array Handle.
|
||||
* @param index Index in the array to shift up from.
|
||||
* @noreturn
|
||||
* @error Invalid Handle or invalid index.
|
||||
*/
|
||||
native ShiftArrayUp(Handle:array, index);
|
||||
|
||||
/**
|
||||
* Removes an array index, shifting the entire array down from that position
|
||||
* on. For example, if item 8 of 10 is removed, the last 3 items will then be
|
||||
* (6,7,8) instead of (7,8,9), and all indexes before 8 will remain unchanged.
|
||||
*
|
||||
* @param array Array Handle.
|
||||
* @param index Index in the array to remove at.
|
||||
* @noreturn
|
||||
* @error Invalid Handle or invalid index.
|
||||
*/
|
||||
native RemoveFromArray(Handle:array, index);
|
||||
|
||||
/**
|
||||
* Swaps two items in the array.
|
||||
*
|
||||
* @param array Array Handle.
|
||||
* @param index1 First index.
|
||||
* @param index2 Second index.
|
||||
* @noreturn
|
||||
* @error Invalid Handle or invalid index.
|
||||
*/
|
||||
native SwapArrayItems(Handle:array, index1, index2);
|
||||
|
||||
/**
|
||||
* Returns the index for the first occurance of the provided string. If the string
|
||||
* cannot be located, -1 will be returned.
|
||||
*
|
||||
* @param array Array Handle.
|
||||
* @param item String to search for
|
||||
* @return Array index, or -1 on failure
|
||||
* @error Invalid Handle
|
||||
*/
|
||||
native FindStringInArray(Handle:array, const String:item[]);
|
||||
|
||||
/**
|
||||
* Returns the index for the first occurance of the provided value. If the value
|
||||
* cannot be located, -1 will be returned.
|
||||
*
|
||||
* @param array Array Handle.
|
||||
* @param item Value to search for
|
||||
* @return Array index, or -1 on failure
|
||||
* @error Invalid Handle
|
||||
*/
|
||||
native FindValueInArray(Handle:array, any:item);
|
||||
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _adt_stack_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _adt_stack_included
|
||||
|
||||
/**
|
||||
* Creates a stack structure. A stack is a LIFO (last in, first out)
|
||||
* vector (array) of items. It has O(1) insertion and O(1) removal.
|
||||
*
|
||||
* Stacks have two operations: Push (adding an item) and Pop (removes
|
||||
* items in reverse-push order).
|
||||
*
|
||||
* The contents of the stack are uniform; i.e. storing a string and then
|
||||
* retrieving it as an integer is NOT the same as StringToInt()!
|
||||
*
|
||||
* The "blocksize" determines how many cells each slot has; it cannot
|
||||
* be changed after creation.
|
||||
*
|
||||
* @param blocksize The number of cells each entry in the stack can
|
||||
* hold. For example, 32 cells is equivalent to:
|
||||
* new Array[X][32]
|
||||
* @return New stack Handle.
|
||||
*/
|
||||
native Handle:CreateStack(blocksize=1);
|
||||
|
||||
/**
|
||||
* Pushes a value onto the end of the stack, adding a new index.
|
||||
*
|
||||
* This may safely be used even if the stack has a blocksize
|
||||
* greater than 1.
|
||||
*
|
||||
* @param stack Stack Handle.
|
||||
* @param value Value to push.
|
||||
* @noreturn
|
||||
* @error Invalid Handle or out of memory.
|
||||
*/
|
||||
native PushStackCell(Handle:stack, any:value);
|
||||
|
||||
/**
|
||||
* Pushes a string onto the end of a stack, truncating it if it is
|
||||
* too big.
|
||||
*
|
||||
* @param stack Stack Handle.
|
||||
* @param value String to push.
|
||||
* @noreturn
|
||||
* @error Invalid Handle or out of memory.
|
||||
*/
|
||||
native PushStackString(Handle:stack, const String:value[]);
|
||||
|
||||
/**
|
||||
* Pushes an array of cells onto the end of a stack. The cells
|
||||
* are pushed as a block (i.e. the entire array takes up one stack slot),
|
||||
* rather than pushing each cell individually.
|
||||
*
|
||||
* @param stack Stack Handle.
|
||||
* @param values Block of values to copy.
|
||||
* @param size If not set, the number of elements copied from the array
|
||||
* will be equal to the blocksize. If set higher than the
|
||||
* blocksize, the operation will be truncated.
|
||||
* @noreturn
|
||||
* @error Invalid Handle or out of memory.
|
||||
*/
|
||||
native PushStackArray(Handle:stack, const any:values[], size=-1);
|
||||
|
||||
/**
|
||||
* Pops a cell value from a stack.
|
||||
*
|
||||
* @param stack Stack Handle.
|
||||
* @param value Variable to store the value.
|
||||
* @param block Optionally specify which block to read from
|
||||
* (useful if the blocksize > 0).
|
||||
* @param asChar Optionally read as a byte instead of a cell.
|
||||
* @return True on success, false if the stack is empty.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:PopStackCell(Handle:stack, &any:value, block=0, bool:asChar=false);
|
||||
|
||||
/**
|
||||
* Pops a string value from a stack.
|
||||
*
|
||||
* @param stack Stack Handle.
|
||||
* @param buffer Buffer to store string.
|
||||
* @param maxlength Maximum size of the buffer.
|
||||
* @return True on success, false if the stack is empty.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:PopStackString(Handle:stack, String:buffer[], maxlength, &written=0);
|
||||
|
||||
/**
|
||||
* Pops an array of cells from a stack.
|
||||
*
|
||||
* @param stack Stack Handle.
|
||||
* @param buffer Buffer to store the array in.
|
||||
* @param size If not set, assumes the buffer size is equal to the
|
||||
* blocksize. Otherwise, the size passed is used.
|
||||
* @return True on success, false if the stack is empty.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:PopStackArray(Handle:stack, any:buffer[], size=-1);
|
||||
|
||||
/**
|
||||
* Checks if a stack is empty.
|
||||
*
|
||||
* @param stack Stack Handle.
|
||||
* @return True if empty, false if not empty.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:IsStackEmpty(Handle:stack);
|
||||
|
||||
/**
|
||||
* Pops a value off a stack, ignoring it completely.
|
||||
*
|
||||
* @param stack Stack Handle.
|
||||
* @return True if something was popped, false otherwise.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
stock PopStack(Handle:stack)
|
||||
{
|
||||
new value;
|
||||
|
||||
return PopStackCell(stack, value);
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _adt_trie_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _adt_trie_included
|
||||
|
||||
/**
|
||||
* Creates a Trie structure. A trie is a data storage object that maps any value to a
|
||||
* string of text. It features very fast lookup and deletion, but grows very slow for
|
||||
* insertion once tens of thousands of items are added.
|
||||
*
|
||||
* Keys in Tries are unique. That is, each key may only have one value. Unlike arrays,
|
||||
* Tries cannot be iterated right now. Since the contents are known to be unique, to
|
||||
* work around this, you can use ADT Arrays to store a list of keys known to be in a
|
||||
* Trie.
|
||||
*
|
||||
* @return New Trie Handle, which must be freed via CloseHandle().
|
||||
*/
|
||||
native Handle:CreateTrie();
|
||||
|
||||
/**
|
||||
* Sets a value in a Trie, either inserting a new entry or replacing an old one.
|
||||
*
|
||||
* @param trie Trie Handle.
|
||||
* @param key Key string.
|
||||
* @param value Value to store at this key.
|
||||
* @param replace If false, operation will fail if the key is already set.
|
||||
* @return True on success, false on failure.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:SetTrieValue(Handle:trie, const String:key[], any:value, bool:replace=true);
|
||||
|
||||
/**
|
||||
* Sets an array value in a Trie, either inserting a new entry or replacing an old one.
|
||||
*
|
||||
* @param trie Trie Handle.
|
||||
* @param key Key string.
|
||||
* @param array Array to store.
|
||||
* @param num_items Number of items in the array.
|
||||
* @param replace If false, operation will fail if the key is already set.
|
||||
* @return True on success, false on failure.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:SetTrieArray(Handle:trie, const String:key[], const any:array[], num_items, bool:replace=true);
|
||||
|
||||
/**
|
||||
* Sets a string value in a Trie, either inserting a new entry or replacing an old one.
|
||||
*
|
||||
* @param trie Trie Handle.
|
||||
* @param key Key string.
|
||||
* @param array Array to store.
|
||||
* @param num_items Number of items in the array.
|
||||
* @param replace If false, operation will fail if the key is already set.
|
||||
* @return True on success, false on failure.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:SetTrieString(Handle:trie, const String:key[], const String:value[], bool:replace=true);
|
||||
|
||||
/**
|
||||
* Retrieves a value in a Trie.
|
||||
*
|
||||
* @param trie Trie Handle.
|
||||
* @param key Key string.
|
||||
* @param val Variable to store value.
|
||||
* @return True on success. False if the key is not set, or the key is set
|
||||
* as an array or string (not a value).
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:GetTrieValue(Handle:trie, const String:key[], &any:value);
|
||||
|
||||
/**
|
||||
* Retrieves an array in a Trie.
|
||||
*
|
||||
* @param trie Trie Handle.
|
||||
* @param key Key string.
|
||||
* @param array Buffer to store array.
|
||||
* @param max_size Maximum size of array buffer.
|
||||
* @param size Optional parameter to store the number of elements written to the buffer.
|
||||
* @return True on success. False if the key is not set, or the key is set
|
||||
* as a value or string (not an array).
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:GetTrieArray(Handle:trie, const String:key[], any:array[], max_size, &size=0);
|
||||
|
||||
/**
|
||||
* Retrieves a string in a Trie.
|
||||
*
|
||||
* @param trie Trie Handle.
|
||||
* @param key Key string.
|
||||
* @param value Buffer to store value.
|
||||
* @param max_size Maximum size of string buffer.
|
||||
* @param size Optional parameter to store the number of bytes written to the buffer.
|
||||
* @return True on success. False if the key is not set, or the key is set
|
||||
* as a value or array (not a string).
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:GetTrieString(Handle:trie, const String:key[], String:value[], max_size, &size=0);
|
||||
|
||||
/**
|
||||
* Removes a key entry from a Trie.
|
||||
*
|
||||
* @param trie Trie Handle.
|
||||
* @param key Key string.
|
||||
* @return True on success, false if the value was never set.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native RemoveFromTrie(Handle:trie, const String:key[]);
|
||||
|
||||
/**
|
||||
* Clears all entries from a Trie.
|
||||
*
|
||||
* @param trie Trie Handle.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native ClearTrie(Handle:trie);
|
||||
|
||||
/**
|
||||
* Retrieves the number of elements in a trie.
|
||||
*
|
||||
* Note that trie items are not enumerable/iteratable. If you need to
|
||||
* retrieve the elements in a trie, store its keys in an ADT Array.
|
||||
*
|
||||
* @param trie Trie Handle.
|
||||
* @return Number of elements in the trie.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native GetTrieSize(Handle:trie);
|
||||
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _banning_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _banning_included
|
||||
|
||||
#define BANFLAG_AUTO (1<<0) /**< Auto-detects whether to ban by steamid or IP */
|
||||
#define BANFLAG_IP (1<<1) /**< Always ban by IP address */
|
||||
#define BANFLAG_AUTHID (1<<2) /**< Always ban by authstring (for BanIdentity) if possible */
|
||||
#define BANFLAG_NOKICK (1<<3) /**< Does not kick the client */
|
||||
|
||||
/**
|
||||
* Called for calls to BanClient() with a non-empty command.
|
||||
*
|
||||
* @param client Client being banned.
|
||||
* @param time Time the client is being banned for (0 = permanent).
|
||||
* @param flags One if AUTHID or IP will be enabled. If AUTO is also
|
||||
* enabled, it means Core autodetected which to use.
|
||||
* @param reason Reason passed via BanClient().
|
||||
* @param kick_message Kick message passed via BanClient().
|
||||
* @param command Command string to identify the ban source.
|
||||
* @param source Source value passed via BanClient().
|
||||
* @return Plugin_Handled to block the actual server banning.
|
||||
* Kicking will still occur.
|
||||
*/
|
||||
forward Action:OnBanClient(client,
|
||||
time,
|
||||
flags,
|
||||
const String:reason[],
|
||||
const String:kick_message[],
|
||||
const String:command[],
|
||||
any:source);
|
||||
|
||||
/**
|
||||
* Called for calls to BanIdentity() with a non-empty command.
|
||||
*
|
||||
* @param identity Identity string being banned (authstring or ip).
|
||||
* @param time Time the client is being banned for (0 = permanent).
|
||||
* @param flags Ban flags (only IP or AUTHID are valid here).
|
||||
* @param reason Reason passed via BanIdentity().
|
||||
* @param command Command string to identify the ban source.
|
||||
* @param source Source value passed via BanIdentity().
|
||||
* @return Plugin_Handled to block the actual server banning.
|
||||
*/
|
||||
forward Action:OnBanIdentity(const String:identity[],
|
||||
time,
|
||||
flags,
|
||||
const String:reason[],
|
||||
const String:command[],
|
||||
any:source);
|
||||
|
||||
/**
|
||||
* Called for calls to RemoveBan() with a non-empty command.
|
||||
*
|
||||
* @param identity Identity string being banned (authstring or ip).
|
||||
* @param flags Ban flags (only IP or AUTHID are valid here).
|
||||
* @param command Command string to identify the ban source.
|
||||
* @param source Source value passed via BanIdentity().
|
||||
* @return Plugin_Handled to block the actual server banning.
|
||||
*/
|
||||
forward Action:OnRemoveBan(const String:identity[],
|
||||
flags,
|
||||
const String:command[],
|
||||
any:source);
|
||||
|
||||
/**
|
||||
* Bans a client.
|
||||
*
|
||||
* @param client Client being banned.
|
||||
* @param time Time (in minutes) to ban (0 = permanent).
|
||||
* @param flags Flags for controlling the ban mechanism. If AUTHID
|
||||
* is set and no AUTHID is available, the ban will fail
|
||||
* unless AUTO is also flagged.
|
||||
* @param reason Reason to ban the client for.
|
||||
* @param kick_message Message to display to the user when kicking.
|
||||
* @param command Command string to identify the source. If this is left
|
||||
* empty, then the OnBanClient forward will not be called.
|
||||
* @param source A source value that could be interpreted as a player
|
||||
* index of any sort (not actually checked by Core).
|
||||
* @return True on success, false on failure.
|
||||
* @error Invalid client index or client not in game.
|
||||
*/
|
||||
native bool:BanClient(client,
|
||||
time,
|
||||
flags,
|
||||
const String:reason[],
|
||||
const String:kick_message[]="",
|
||||
const String:command[]="",
|
||||
any:source=0);
|
||||
|
||||
/**
|
||||
* Bans an identity (either an IP address or auth string).
|
||||
*
|
||||
* @param identity String to ban (ip or authstring).
|
||||
* @param time Time to ban for (0 = permanent).
|
||||
* @param flags Flags (only IP and AUTHID are valid flags here).
|
||||
* @param reason Ban reason string.
|
||||
* @param command Command string to identify the source. If this is left
|
||||
* empty, then the OnBanIdentity forward will not be called.
|
||||
* @param source A source value that could be interpreted as a player
|
||||
* index of any sort (not actually checked by Core).
|
||||
* @return True on success, false on failure.
|
||||
*/
|
||||
native bool:BanIdentity(const String:identity[],
|
||||
time,
|
||||
flags,
|
||||
const String:reason[],
|
||||
const String:command[]="",
|
||||
any:source=0);
|
||||
|
||||
/**
|
||||
* Removes a ban that was written to the server (either in memory or on disk).
|
||||
*
|
||||
* @param identity String to unban (ip or authstring).
|
||||
* @param flags Flags (only IP and AUTHID are valid flags here).
|
||||
* @param command Command string to identify the source. If this is left
|
||||
* empty, then OnRemoveBan will not be called.
|
||||
* @param source A source value that could be interpreted as a player
|
||||
* index of any sort (not actually checked by Core).
|
||||
* @return True on success, false on failure.
|
||||
*/
|
||||
native bool:RemoveBan(const String:identity[],
|
||||
flags,
|
||||
const String:command[]="",
|
||||
any:source=0);
|
||||
|
||||
@@ -0,0 +1,325 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _bitbuffer_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _bitbuffer_included
|
||||
|
||||
/**
|
||||
* Writes a single bit to a writable bitbuffer (bf_write).
|
||||
*
|
||||
* @param bf bf_write handle to write to.
|
||||
* @param bit Bit to write (true for 1, false for 0).
|
||||
* @noreturn
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfWriteBool(Handle:bf, bool:bit);
|
||||
|
||||
/**
|
||||
* Writes a byte to a writable bitbuffer (bf_write).
|
||||
*
|
||||
* @param bf bf_write handle to write to.
|
||||
* @param byte Byte to write (value will be written as 8bit).
|
||||
* @noreturn
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfWriteByte(Handle:bf, byte);
|
||||
|
||||
/**
|
||||
* Writes a byte to a writable bitbuffer (bf_write).
|
||||
*
|
||||
* @param bf bf_write handle to write to.
|
||||
* @param chr Character to write.
|
||||
* @noreturn
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfWriteChar(Handle:bf, chr);
|
||||
|
||||
/**
|
||||
* Writes a 16bit integer to a writable bitbuffer (bf_write).
|
||||
*
|
||||
* @param bf bf_write handle to write to.
|
||||
* @param num Integer to write (value will be written as 16bit).
|
||||
* @noreturn
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfWriteShort(Handle:bf, num);
|
||||
|
||||
/**
|
||||
* Writes a 16bit unsigned integer to a writable bitbuffer (bf_write).
|
||||
*
|
||||
* @param bf bf_write handle to write to.
|
||||
* @param num Integer to write (value will be written as 16bit).
|
||||
* @noreturn
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfWriteWord(Handle:bf, num);
|
||||
|
||||
/**
|
||||
* Writes a normal integer to a writable bitbuffer (bf_write).
|
||||
*
|
||||
* @param bf bf_write handle to write to.
|
||||
* @param num Integer to write (value will be written as 32bit).
|
||||
* @noreturn
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfWriteNum(Handle:bf, num);
|
||||
|
||||
/**
|
||||
* Writes a floating point number to a writable bitbuffer (bf_write).
|
||||
*
|
||||
* @param bf bf_write handle to write to.
|
||||
* @param num Number to write.
|
||||
* @noreturn
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfWriteFloat(Handle:bf, Float:num);
|
||||
|
||||
/**
|
||||
* Writes a string to a writable bitbuffer (bf_write).
|
||||
*
|
||||
* @param bf bf_write handle to write to.
|
||||
* @param string Text string to write.
|
||||
* @noreturn
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfWriteString(Handle:bf, const String:string[]);
|
||||
|
||||
/**
|
||||
* Writes an entity to a writable bitbuffer (bf_write).
|
||||
* @note This is a wrapper around BfWriteShort().
|
||||
*
|
||||
* @param bf bf_write handle to write to.
|
||||
* @param ent Entity index to write.
|
||||
* @noreturn
|
||||
* @error Invalid or incorrect Handle, or invalid entity.
|
||||
*/
|
||||
native BfWriteEntity(Handle:bf, ent);
|
||||
|
||||
/**
|
||||
* Writes a bit angle to a writable bitbuffer (bf_write).
|
||||
*
|
||||
* @param bf bf_write handle to write to.
|
||||
* @param angle Angle to write.
|
||||
* @param numBits Optional number of bits to use.
|
||||
* @noreturn
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfWriteAngle(Handle:bf, Float:angle, numBits=8);
|
||||
|
||||
/**
|
||||
* Writes a coordinate to a writable bitbuffer (bf_write).
|
||||
*
|
||||
* @param bf bf_write handle to write to.
|
||||
* @param coord Coordinate to write.
|
||||
* @noreturn
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfWriteCoord(Handle:bf, Float:coord);
|
||||
|
||||
/**
|
||||
* Writes a 3D vector of coordinates to a writable bitbuffer (bf_write).
|
||||
*
|
||||
* @param bf bf_write handle to write to.
|
||||
* @param coord Coordinate array to write.
|
||||
* @noreturn
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfWriteVecCoord(Handle:bf, Float:coord[3]);
|
||||
|
||||
/**
|
||||
* Writes a 3D normal vector to a writable bitbuffer (bf_write).
|
||||
*
|
||||
* @param bf bf_write handle to write to.
|
||||
* @param vec Vector to write.
|
||||
* @noreturn
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfWriteVecNormal(Handle:bf, Float:vec[3]);
|
||||
|
||||
/**
|
||||
* Writes a 3D angle vector to a writable bitbuffer (bf_write).
|
||||
*
|
||||
* @param bf bf_write handle to write to.
|
||||
* @param angles Angle vector to write.
|
||||
* @noreturn
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfWriteAngles(Handle:bf, Float:angles[3]);
|
||||
|
||||
/**
|
||||
* Reads a single bit from a readable bitbuffer (bf_read).
|
||||
*
|
||||
* @param bf bf_read handle to read from.
|
||||
* @return Bit value read.
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native bool:BfReadBool(Handle:bf);
|
||||
|
||||
/**
|
||||
* Reads a byte from a readable bitbuffer (bf_read).
|
||||
*
|
||||
* @param bf bf_read handle to read from.
|
||||
* @return Byte value read (read as 8bit).
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfReadByte(Handle:bf);
|
||||
|
||||
/**
|
||||
* Reads a character from a readable bitbuffer (bf_read).
|
||||
*
|
||||
* @param bf bf_read handle to read from.
|
||||
* @return Character value read.
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfReadChar(Handle:bf);
|
||||
|
||||
/**
|
||||
* Reads a 16bit integer from a readable bitbuffer (bf_read).
|
||||
*
|
||||
* @param bf bf_read handle to read from.
|
||||
* @return Integer value read (read as 16bit).
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfReadShort(Handle:bf);
|
||||
|
||||
/**
|
||||
* Reads a 16bit unsigned integer from a readable bitbuffer (bf_read).
|
||||
*
|
||||
* @param bf bf_read handle to read from.
|
||||
* @return Integer value read (read as 16bit).
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfReadWord(Handle:bf);
|
||||
|
||||
/**
|
||||
* Reads a normal integer to a readable bitbuffer (bf_read).
|
||||
*
|
||||
* @param bf bf_read handle to read from.
|
||||
* @return Integer value read (read as 32bit).
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfReadNum(Handle:bf);
|
||||
|
||||
/**
|
||||
* Reads a floating point number from a readable bitbuffer (bf_read).
|
||||
*
|
||||
* @param bf bf_read handle to read from.
|
||||
* @return Floating point value read.
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native Float:BfReadFloat(Handle:bf);
|
||||
|
||||
/**
|
||||
* Reads a string from a readable bitbuffer (bf_read).
|
||||
*
|
||||
* @param bf bf_read handle to read from.
|
||||
* @param buffer Destination string buffer.
|
||||
* @param maxlength Maximum length of output string buffer.
|
||||
* @param line If true the buffer will be copied until it reaches a '\n' or a null terminator.
|
||||
* @return Number of bytes written to the buffer. If the bitbuffer stream overflowed,
|
||||
* that is, had no terminator before the end of the stream, then a negative
|
||||
* number will be returned equal to the number of characters written to the
|
||||
* buffer minus 1. The buffer will be null terminated regardless of the
|
||||
* return value.
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfReadString(Handle:bf, String:buffer[], maxlength, bool:line=false);
|
||||
|
||||
/**
|
||||
* Reads an entity from a readable bitbuffer (bf_read).
|
||||
* @note This is a wrapper around BfReadShort().
|
||||
*
|
||||
* @param bf bf_read handle to read from.
|
||||
* @return Entity index read.
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfReadEntity(Handle:bf);
|
||||
|
||||
/**
|
||||
* Reads a bit angle from a readable bitbuffer (bf_read).
|
||||
*
|
||||
* @param bf bf_read handle to read from.
|
||||
* @param numBits Optional number of bits to use.
|
||||
* @return Angle read.
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native Float:BfReadAngle(Handle:bf, numBits=8);
|
||||
|
||||
/**
|
||||
* Reads a coordinate from a readable bitbuffer (bf_read).
|
||||
*
|
||||
* @param bf bf_read handle to read from.
|
||||
* @return Coordinate read.
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native Float:BfReadCoord(Handle:bf);
|
||||
|
||||
/**
|
||||
* Reads a 3D vector of coordinates from a readable bitbuffer (bf_read).
|
||||
*
|
||||
* @param bf bf_read handle to read from.
|
||||
* @param coord Destination coordinate array.
|
||||
* @noreturn
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfReadVecCoord(Handle:bf, Float:coord[3]);
|
||||
|
||||
/**
|
||||
* Reads a 3D normal vector from a readable bitbuffer (bf_read).
|
||||
*
|
||||
* @param bf bf_read handle to read from.
|
||||
* @param vec Destination vector array.
|
||||
* @noreturn
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfReadVecNormal(Handle:bf, Float:vec[3]);
|
||||
|
||||
/**
|
||||
* Reads a 3D angle vector from a readable bitbuffer (bf_read).
|
||||
*
|
||||
* @param bf bf_read handle to read from.
|
||||
* @param angles Destination angle vector.
|
||||
* @noreturn
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfReadAngles(Handle:bf, Float:angles[3]);
|
||||
|
||||
/**
|
||||
* Returns the number of bytes left in a readable bitbuffer (bf_read).
|
||||
*
|
||||
* @param bf bf_read handle to read from.
|
||||
* @return Number of bytes left unread.
|
||||
* @error Invalid or incorrect Handle.
|
||||
*/
|
||||
native BfGetNumBytesLeft(Handle:bf);
|
||||
@@ -0,0 +1,230 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _clientprefs_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _clientprefs_included
|
||||
|
||||
/**
|
||||
* Cookie access types for client viewing
|
||||
*/
|
||||
enum CookieAccess
|
||||
{
|
||||
CookieAccess_Public, /**< Visible and Changeable by users */
|
||||
CookieAccess_Protected, /**< Read only to users */
|
||||
CookieAccess_Private, /**< Completely hidden cookie */
|
||||
};
|
||||
|
||||
/**
|
||||
* Cookie Prefab menu types
|
||||
*/
|
||||
enum CookieMenu
|
||||
{
|
||||
CookieMenu_YesNo, /**< Yes/No menu with "yes"/"no" results saved into the cookie */
|
||||
CookieMenu_YesNo_Int, /**< Yes/No menu with 1/0 saved into the cookie */
|
||||
CookieMenu_OnOff, /**< On/Off menu with "on"/"off" results saved into the cookie */
|
||||
CookieMenu_OnOff_Int, /**< On/Off menu with 1/0 saved into the cookie */
|
||||
};
|
||||
|
||||
enum CookieMenuAction
|
||||
{
|
||||
/**
|
||||
* An option is being drawn for a menu.
|
||||
*
|
||||
* INPUT : Client index and data if available.
|
||||
* OUTPUT: Buffer for rendering, maxlength of buffer.
|
||||
*/
|
||||
CookieMenuAction_DisplayOption = 0,
|
||||
|
||||
/**
|
||||
* A menu option has been selected.
|
||||
*
|
||||
* INPUT : Client index and any data if available.
|
||||
*/
|
||||
CookieMenuAction_SelectOption = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new Client preference cookie.
|
||||
*
|
||||
* @param name Name of the new preference cookie.
|
||||
* @param description Optional description of the preference cookie.
|
||||
* @param access What CookieAccess level to assign to this cookie.
|
||||
* @return A handle to the newly created cookie. If the cookie already exists, a handle to it will still be returned.
|
||||
* @error Cookie name is blank.
|
||||
*/
|
||||
native Handle:RegClientCookie(const String:name[], const String:description[], CookieAccess:access);
|
||||
|
||||
/**
|
||||
* Searches for a Client preference cookie.
|
||||
*
|
||||
* @param name Name of cookie to find.
|
||||
* @return A handle to the cookie if it is found. INVALID_HANDLE otherwise.
|
||||
*/
|
||||
native Handle:FindClientCookie(const String:name[]);
|
||||
|
||||
/**
|
||||
* Set the value of a Client preference cookie.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param cookie Client preference cookie handle.
|
||||
* @param value String value to set.
|
||||
* @noreturn
|
||||
* @error Invalid cookie handle or invalid client index.
|
||||
*/
|
||||
native SetClientCookie(client, Handle:cookie, const String:value[]);
|
||||
|
||||
/**
|
||||
* Retrieve the value of a Client preference cookie.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param cookie Client preference cookie handle.
|
||||
* @param buffer Copyback buffer for value.
|
||||
* @param maxlen Maximum length of the buffer.
|
||||
* @noreturn
|
||||
* @error Invalid cookie handle or invalid client index.
|
||||
*/
|
||||
native GetClientCookie(client, Handle:cookie, String:buffer[], maxlen);
|
||||
|
||||
/**
|
||||
* Checks if a clients cookies have been loaded from the database.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @return True if loaded, false otherwise.
|
||||
* @error Invalid client index.
|
||||
*/
|
||||
native bool:AreClientCookiesCached(client);
|
||||
|
||||
/**
|
||||
* Called once a client's saved cookies have been loaded from the database.
|
||||
*
|
||||
* @param client Client index.
|
||||
*/
|
||||
forward OnClientCookiesCached(client);
|
||||
|
||||
/**
|
||||
* Cookie Menu Callback prototype
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param action CookeMenuAction being performed.
|
||||
* @param data Info data passed.
|
||||
* @param buffer Outbut buffer.
|
||||
* @param maxlen Max length of the output buffer.
|
||||
*/
|
||||
functag CookieMenuHandler public(client, CookieMenuAction:action, any:info, String:buffer[], maxlen);
|
||||
|
||||
/**
|
||||
* Add a new prefab item to the client cookie settings menu.
|
||||
*
|
||||
* Note: This handles everything automatically and does not require a callback
|
||||
*
|
||||
* @param cookie Client preference cookie handle.
|
||||
* @param type A CookieMenu prefab menu type.
|
||||
* @param display Text to show on the menu.
|
||||
* @param handler Optional handler callback for translations and output on selection
|
||||
* @param info Info data to pass to the callback.
|
||||
* @noreturn
|
||||
* @error Invalid cookie handle.
|
||||
*/
|
||||
native SetCookiePrefabMenu(Handle:cookie, CookieMenu:type, const String:display[], CookieMenuHandler:handler=CookieMenuHandler:-1, info=0);
|
||||
|
||||
/**
|
||||
* Adds a new item to the client cookie settings menu.
|
||||
*
|
||||
* Note: This only adds the top level menu item. You need to handle any submenus from the callback.
|
||||
*
|
||||
* @param handler A MenuHandler callback function.
|
||||
* @param info Data to pass to the callback.
|
||||
* @param display Text to show on the menu.
|
||||
* @noreturn
|
||||
* @error Invalid cookie handle.
|
||||
*/
|
||||
native SetCookieMenuItem(CookieMenuHandler:handler, any:info, const String:display[]);
|
||||
|
||||
/**
|
||||
* Displays the settings menu to a client.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @noreturn
|
||||
*/
|
||||
native ShowCookieMenu(client);
|
||||
|
||||
/**
|
||||
* Gets a cookie iterator. Must be freed with CloseHandle().
|
||||
*
|
||||
* @return A new cookie iterator.
|
||||
*/
|
||||
native Handle:GetCookieIterator();
|
||||
|
||||
/**
|
||||
* Reads a cookie iterator, then advances to the next cookie if any.
|
||||
*
|
||||
* @param iter Cookie iterator Handle.
|
||||
* @param name Name buffer.
|
||||
* @param nameLen Name buffer size.
|
||||
* @param access Access level of the cookie.
|
||||
* @param desc Cookie description buffer.
|
||||
* @param descLen Cookie description buffer size.
|
||||
* @param
|
||||
* @return True on success, false if there are no more commands.
|
||||
*/
|
||||
native bool:ReadCookieIterator(Handle:iter,
|
||||
String:name[],
|
||||
nameLen,
|
||||
&CookieAccess:access,
|
||||
String:desc[]="",
|
||||
descLen=0);
|
||||
|
||||
/**
|
||||
* Returns the access level of a cookie
|
||||
*
|
||||
* @param cookie Client preference cookie handle.
|
||||
* @return CookieAccess access level.
|
||||
* @error Invalid cookie handle.
|
||||
*/
|
||||
native CookieAccess:GetCookieAccess(Handle:cookie);
|
||||
|
||||
/**
|
||||
* Do not edit below this line!
|
||||
*/
|
||||
public Extension:__ext_clientprefs =
|
||||
{
|
||||
name = "Client Preferences",
|
||||
file = "clientprefs.ext",
|
||||
autoload = 1,
|
||||
#if defined REQUIRE_EXTENSIONS
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
@@ -0,0 +1,684 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _clients_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _clients_included
|
||||
|
||||
/**
|
||||
* Network flow directions.
|
||||
*/
|
||||
enum NetFlow
|
||||
{
|
||||
NetFlow_Outgoing = 0, /**< Outgoing traffic */
|
||||
NetFlow_Incoming, /**< Incoming traffic */
|
||||
NetFlow_Both, /**< Both values added together */
|
||||
};
|
||||
|
||||
#define MAXPLAYERS 64 /**< Maximum number of players that can be in server */
|
||||
#define MAX_NAME_LENGTH 32 /**< Maximum buffer required to store a client name */
|
||||
|
||||
/**
|
||||
* Called on client connection.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param rejectmsg Buffer to store the rejection message when the connection is refused.
|
||||
* @param maxlen Maximum number of characters for rejection buffer.
|
||||
* @return True to validate client's connection, false to refuse it.
|
||||
*/
|
||||
forward bool:OnClientConnect(client, String:rejectmsg[], maxlen);
|
||||
|
||||
/**
|
||||
* Called when a client is entering the game.
|
||||
*
|
||||
* Whether a client has a steamid is undefined until OnClientAuthorized
|
||||
* is called, which may occur either before or after OnClientPutInServer.
|
||||
* Similarly, use OnClientPostAdminCheck() if you need to verify whether
|
||||
* connecting players are admins.
|
||||
*
|
||||
* GetClientCount() will include clients as they are passed through this
|
||||
* function, as clients are already in game at this point.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @noreturn
|
||||
*/
|
||||
forward OnClientPutInServer(client);
|
||||
|
||||
/**
|
||||
* Called when a client is disconnecting from the server.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @noreturn
|
||||
*/
|
||||
forward OnClientDisconnect(client);
|
||||
|
||||
/**
|
||||
* Called when a client is disconnected from the server.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @noreturn
|
||||
*/
|
||||
forward OnClientDisconnect_Post(client);
|
||||
|
||||
/**
|
||||
* Called when a client is sending a command.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param args Number of arguments.
|
||||
* @noreturn
|
||||
*/
|
||||
forward Action:OnClientCommand(client, args);
|
||||
|
||||
/**
|
||||
* Called whenever the client's settings are changed.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @noreturn
|
||||
*/
|
||||
forward OnClientSettingsChanged(client);
|
||||
|
||||
/**
|
||||
* Called when a client receives a Steam ID. The state of a client's
|
||||
* authorization via Steam or as an admin is not guaranteed here.
|
||||
* Use OnClientAuthorized() or OnClientPostAdminCheck() for those,
|
||||
* respectively.
|
||||
*
|
||||
* This is called by bots, but the ID will be "BOT".
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param auth Client auth string.
|
||||
* @noreturn
|
||||
*/
|
||||
forward OnClientAuthorized(client, const String:auth[]);
|
||||
|
||||
/**
|
||||
* Called once a client is authorized and fully in-game, but
|
||||
* before admin checks are done. This can be used to override
|
||||
* the default admin checks for a client. You should only use
|
||||
* this for overriding; use OnClientPostAdminCheck() instead
|
||||
* if you want notification.
|
||||
*
|
||||
* Note: If handled/blocked, PostAdminCheck must be signalled
|
||||
* manually via NotifyPostAdminCheck().
|
||||
*
|
||||
* This callback is gauranteed to occur on all clients, and always
|
||||
* after each OnClientPutInServer() call.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @return Plugin_Handled to block admin checks.
|
||||
*/
|
||||
forward Action:OnClientPreAdminCheck(client);
|
||||
|
||||
/**
|
||||
* Called directly before OnClientPostAdminCheck() as a method to
|
||||
* alter administrative permissions before plugins perform final
|
||||
* post-connect operations.
|
||||
*
|
||||
* In general, do not use this function unless you are specifically
|
||||
* attempting to change access permissions. Use OnClientPostAdminCheck()
|
||||
* instead if you simply want to perform post-connect authorization
|
||||
* routines.
|
||||
*
|
||||
* See OnClientPostAdminCheck() for more information.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @noreturn
|
||||
*/
|
||||
forward OnClientPostAdminFilter(client);
|
||||
|
||||
/**
|
||||
* Called once a client is authorized and fully in-game, and
|
||||
* after all post-connection authorizations have been performed.
|
||||
*
|
||||
* This callback is gauranteed to occur on all clients, and always
|
||||
* after each OnClientPutInServer() call.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @noreturn
|
||||
*/
|
||||
forward OnClientPostAdminCheck(client);
|
||||
|
||||
/**
|
||||
* Returns the maximum number of clients allowed on the server. This may
|
||||
* return 0 if called before OnMapStart(), and thus should not be called
|
||||
* in OnPluginStart().
|
||||
*
|
||||
* @return Maximum number of clients allowed.
|
||||
*/
|
||||
native GetMaxClients();
|
||||
|
||||
/**
|
||||
* Returns the client count put in the server.
|
||||
*
|
||||
* @param inGameOnly If false connecting players are also counted.
|
||||
* @return Client count in the server.
|
||||
*/
|
||||
native GetClientCount(bool:inGameOnly=true);
|
||||
|
||||
/**
|
||||
* Returns the client's name.
|
||||
*
|
||||
* @param client Player index.
|
||||
* @param name Buffer to store the client's name.
|
||||
* @param maxlen Maximum length of string buffer (includes NULL terminator).
|
||||
* @return True on success, false otherwise.
|
||||
* @error If the client is not connected an error will be thrown.
|
||||
*/
|
||||
native bool:GetClientName(client, String:name[], maxlen);
|
||||
|
||||
/**
|
||||
* Retrieves a client's IP address.
|
||||
*
|
||||
* @param client Player index.
|
||||
* @param name Buffer to store the client's ip address.
|
||||
* @param maxlen Maximum length of string buffer (includes NULL terminator).
|
||||
* @param remport Remove client's port from the ip string (true by default).
|
||||
* @return True on success, false otherwise.
|
||||
* @error If the client is not connected or the index is invalid.
|
||||
*/
|
||||
native bool:GetClientIP(client, String:ip[], maxlen, bool:remport=true);
|
||||
|
||||
/**
|
||||
* Retrieves a client's authentication string (SteamID).
|
||||
*
|
||||
* @param client Player index.
|
||||
* @param auth Buffer to store the client's auth string.
|
||||
* @param maxlen Maximum length of string buffer (includes NULL terminator).
|
||||
* @return True on success, false otherwise.
|
||||
* @error If the client is not connected or the index is invalid.
|
||||
*/
|
||||
native bool:GetClientAuthString(client, String:auth[], maxlen);
|
||||
|
||||
/**
|
||||
* Retrieves a client's user id, which is an index incremented for every client
|
||||
* that joins the server.
|
||||
*
|
||||
* @param client Player index.
|
||||
* @return User id of the client.
|
||||
* @error If the client is not connected or the index is invalid.
|
||||
*/
|
||||
native GetClientUserId(client);
|
||||
|
||||
/**
|
||||
* Returns if a certain player is connected.
|
||||
*
|
||||
* @param client Player index.
|
||||
* @return True if player is connected to the server, false otherwise.
|
||||
*/
|
||||
native bool:IsClientConnected(client);
|
||||
|
||||
/**
|
||||
* Returns if a certain player has entered the game.
|
||||
*
|
||||
* @param client Player index (index does not have to be connected).
|
||||
* @return True if player has entered the game, false otherwise.
|
||||
* @error Invalid client index.
|
||||
*/
|
||||
native bool:IsClientInGame(client);
|
||||
|
||||
/**
|
||||
* Returns if a client is in the "kick queue" (i.e. the client will be kicked
|
||||
* shortly and thus they should not appear as valid).
|
||||
*
|
||||
* @param client Player index (must be connected).
|
||||
* @return True if in the kick queue, false otherwise.
|
||||
* @error Invalid client index.
|
||||
*/
|
||||
native bool:IsClientInKickQueue(client);
|
||||
|
||||
/**
|
||||
* Backwards compatibility stock - use IsClientInGame
|
||||
* @deprecated Renamed to IsClientInGame
|
||||
*/
|
||||
#pragma deprecated Use IsClientInGame() instead
|
||||
stock bool:IsPlayerInGame(client)
|
||||
{
|
||||
return IsClientInGame(client);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if a certain player has been authenticated.
|
||||
*
|
||||
* @param client Player index.
|
||||
* @return True if player has been authenticated, false otherwise.
|
||||
*/
|
||||
native bool:IsClientAuthorized(client);
|
||||
|
||||
/**
|
||||
* Returns if a certain player is a fake client.
|
||||
*
|
||||
* @param client Player index.
|
||||
* @return True if player is a fake client, false otherwise.
|
||||
*/
|
||||
native bool:IsFakeClient(client);
|
||||
|
||||
/**
|
||||
* Returns if a certain player is an observer/spectator.
|
||||
*
|
||||
* @param client Player index.
|
||||
* @return True if player is an obverser, false otherwise.
|
||||
*/
|
||||
native bool:IsClientObserver(client);
|
||||
|
||||
/**
|
||||
* Returns if the client is alive or dead.
|
||||
*
|
||||
* Note: This function was originally in SDKTools and was moved to core.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @return True if the client is alive, false otherwise.
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native bool:IsPlayerAlive(client);
|
||||
|
||||
/**
|
||||
* Retrieves values from client replicated keys.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param key Key string.
|
||||
* @param value Buffer to store value.
|
||||
* @param maxlen Maximum length of valve (UTF-8 safe).
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid client index, or client not connected.
|
||||
*/
|
||||
native bool:GetClientInfo(client, const String:key[], String:value[], maxlen);
|
||||
|
||||
/**
|
||||
* Retrieves a client's team index.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @return Team index the client is on (mod specific).
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native GetClientTeam(client);
|
||||
|
||||
/**
|
||||
* Sets a client's AdminId.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param id AdminId to set. INVALID_ADMIN_ID removes admin permissions.
|
||||
* @param temp True if the id should be freed on disconnect.
|
||||
* @noreturn
|
||||
* @error Invalid client index, client not connected, or bogus AdminId.
|
||||
*/
|
||||
native SetUserAdmin(client, AdminId:id, bool:temp=false);
|
||||
|
||||
/**
|
||||
* Retrieves a client's AdminId.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @return AdminId of the client, or INVALID_ADMIN_ID if none.
|
||||
* @error Invalid client index, or client not connected.
|
||||
*/
|
||||
native AdminId:GetUserAdmin(client);
|
||||
|
||||
/**
|
||||
* Sets access flags on a client. If the client is not an admin,
|
||||
* a temporary, anonymous AdminId is given.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param ... Flags to set on the client.
|
||||
* @noreturn
|
||||
* @error Invalid client index, or client not connected.
|
||||
*/
|
||||
native AddUserFlags(client, AdminFlag:...);
|
||||
|
||||
/**
|
||||
* Removes flags from a client. If the client is not an admin,
|
||||
* this has no effect.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param ... Flags to remove from the client.
|
||||
* @noreturn
|
||||
* @error Invalid client index, or client not connected.
|
||||
*/
|
||||
native RemoveUserFlags(client, AdminFlag:...);
|
||||
|
||||
/**
|
||||
* Sets access flags on a client using bits instead of flags. If the
|
||||
* client is not an admin, and flags not 0, a temporary, anonymous AdminId is given.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param flags Bitstring of flags to set on client.
|
||||
* @noreturn
|
||||
*/
|
||||
native SetUserFlagBits(client, flags);
|
||||
|
||||
/**
|
||||
* Returns client access flags. If the client is not an admin,
|
||||
* the result is always 0.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @return Flags
|
||||
* @error Invalid client index, or client not connected.
|
||||
*/
|
||||
native GetUserFlagBits(client);
|
||||
|
||||
/**
|
||||
* Returns whether a user can target another user.
|
||||
* This is a helper function for CanAdminTarget.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param target Target player's index.
|
||||
* @return True if target is targettable by the player, false otherwise.
|
||||
* @error Invalid or unconnected player indexers.
|
||||
*/
|
||||
native bool:CanUserTarget(client, target);
|
||||
|
||||
/**
|
||||
* Runs through the Core-defined admin authorization checks on a player.
|
||||
* Has no effect if the player is already an admin.
|
||||
*
|
||||
* Note: This function is based on the internal cache only.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @return True if access was changed, false if it did not.
|
||||
* @error Invalid client index or client not in-game AND authorized.
|
||||
*/
|
||||
native bool:RunAdminCacheChecks(client);
|
||||
|
||||
/**
|
||||
* Signals that a player has completed post-connection admin checks.
|
||||
* Has no effect if the player has already had this event signalled.
|
||||
*
|
||||
* Note: This must be sent even if no admin id was assigned.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @noreturn
|
||||
* @error Invalid client index or client not in-game AND authorized.
|
||||
*/
|
||||
native NotifyPostAdminCheck(client);
|
||||
|
||||
/**
|
||||
* Creates a fake client.
|
||||
*
|
||||
* @param name Name to use.
|
||||
* @return Client index on success, 0 otherwise.
|
||||
*/
|
||||
native CreateFakeClient(const String:name[]);
|
||||
|
||||
/**
|
||||
* Sets a convar value on a fake client.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param cvar ConVar name.
|
||||
* @param value ConVar value.
|
||||
* @noreturn
|
||||
* @error Invalid client index, client not connected,
|
||||
* or client not a fake client.
|
||||
*/
|
||||
native SetFakeClientConVar(client, const String:cvar[], const String:value[]);
|
||||
|
||||
/**
|
||||
* Returns the client's health.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @return Health value.
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native GetClientHealth(client);
|
||||
|
||||
/**
|
||||
* Returns the client's model name.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param model Buffer to store the client's model name.
|
||||
* @param maxlen Maximum length of string buffer (includes NULL terminator).
|
||||
* @noreturn
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native GetClientModel(client, String:model[], maxlen);
|
||||
|
||||
/**
|
||||
* Returns the client's weapon name.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param weapon Buffer to store the client's weapon name.
|
||||
* @param maxlen Maximum length of string buffer (includes NULL terminator).
|
||||
* @noreturn
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native GetClientWeapon(client, String:weapon[], maxlen);
|
||||
|
||||
/**
|
||||
* Returns the client's max size vector.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param vec Destination vector to store the client's max size.
|
||||
* @noreturn
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native GetClientMaxs(client, Float:vec[3]);
|
||||
|
||||
/**
|
||||
* Returns the client's min size vector.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param vec Destination vector to store the client's min size.
|
||||
* @noreturn
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native GetClientMins(client, Float:vec[3]);
|
||||
|
||||
/**
|
||||
* Returns the client's position angle.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param ang Destination vector to store the client's position angle.
|
||||
* @noreturn
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native GetClientAbsAngles(client, Float:ang[3]);
|
||||
|
||||
/**
|
||||
* Returns the client's origin vector.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param vec Destination vector to store the client's origin vector.
|
||||
* @noreturn
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native GetClientAbsOrigin(client, Float:vec[3]);
|
||||
|
||||
/**
|
||||
* Returns the client's armor.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @return Armor value.
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native GetClientArmor(client);
|
||||
|
||||
/**
|
||||
* Returns the client's death count.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @return Death count.
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native GetClientDeaths(client);
|
||||
|
||||
/**
|
||||
* Returns the client's frag count.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @return Frag count.
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native GetClientFrags(client);
|
||||
|
||||
/**
|
||||
* Returns the client's send data rate in bytes/sec.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @return Data rate.
|
||||
* @error Invalid client index, client not in game, or fake client.
|
||||
*/
|
||||
native GetClientDataRate(client);
|
||||
|
||||
/**
|
||||
* Returns if a client is timing out
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @return True if client is timing out, false otherwise.
|
||||
* @error Invalid client index, client not in game, or fake client.
|
||||
*/
|
||||
native bool:IsClientTimingOut(client);
|
||||
|
||||
/**
|
||||
* Returns the client's connection time in seconds.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @return Connection time.
|
||||
* @error Invalid client index, client not in game, or fake client.
|
||||
*/
|
||||
native Float:GetClientTime(client);
|
||||
|
||||
/**
|
||||
* Returns the client's current latency (RTT), more accurate than GetAvgLatency but jittering.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param flow Traffic flowing direction.
|
||||
* @return Latency.
|
||||
* @error Invalid client index, client not in game, or fake client.
|
||||
*/
|
||||
native Float:GetClientLatency(client, NetFlow:flow);
|
||||
|
||||
/**
|
||||
* Returns the client's average packet latency in seconds.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param flow Traffic flowing direction.
|
||||
* @return Average latency.
|
||||
* @error Invalid client index, client not in game, or fake client.
|
||||
*/
|
||||
native Float:GetClientAvgLatency(client, NetFlow:flow);
|
||||
|
||||
/**
|
||||
* Returns the client's average packet loss, values go from 0 to 1 (for percentages).
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param flow Traffic flowing direction.
|
||||
* @return Average packet loss.
|
||||
* @error Invalid client index, client not in game, or fake client.
|
||||
*/
|
||||
native Float:GetClientAvgLoss(client, NetFlow:flow);
|
||||
|
||||
/**
|
||||
* Returns the client's average packet choke, values go from 0 to 1 (for percentages).
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param flow Traffic flowing direction.
|
||||
* @return Average packet choke.
|
||||
* @error Invalid client index, client not in game, or fake client.
|
||||
*/
|
||||
native Float:GetClientAvgChoke(client, NetFlow:flow);
|
||||
|
||||
/**
|
||||
* Returns the client's data flow in bytes/sec.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param flow Traffic flowing direction.
|
||||
* @return Data flow.
|
||||
* @error Invalid client index, client not in game, or fake client.
|
||||
*/
|
||||
native Float:GetClientAvgData(client, NetFlow:flow);
|
||||
|
||||
/**
|
||||
* Returns the client's average packet frequency in packets/sec.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param flow Traffic flowing direction.
|
||||
* @return Packet frequency.
|
||||
* @error Invalid client index, client not in game, or fake client.
|
||||
*/
|
||||
native Float:GetClientAvgPackets(client, NetFlow:flow);
|
||||
|
||||
/**
|
||||
* Translates an userid index to the real player index.
|
||||
*
|
||||
* @param userid Userid value.
|
||||
* @return Client value.
|
||||
* @error Returns 0 if invalid userid.
|
||||
*/
|
||||
native GetClientOfUserId(userid);
|
||||
|
||||
/**
|
||||
* Disconnects a client from the server as soon as the next frame starts.
|
||||
*
|
||||
* Note: Originally, KickClient() was immediate. The delay was introduced
|
||||
* because despite warnings, plugins were using it in ways that would crash.
|
||||
* The new safe version can break cases that rely on immediate disconnects,
|
||||
* but ensures that plugins do not accidentally cause crashes.
|
||||
*
|
||||
* If you need immediate disconnects, use KickClientEx().
|
||||
*
|
||||
* Note: IsClientInKickQueue() will return true before the kick occurs.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param format Optional formatting rules for disconnect reason.
|
||||
* Note that a period is automatically appended to the string by the engine.
|
||||
* @param ... Variable number of format parameters.
|
||||
* @noreturn
|
||||
* @error Invalid client index, or client not connected.
|
||||
*/
|
||||
native KickClient(client, const String:format[]="", any:...);
|
||||
|
||||
/**
|
||||
* Immediately disconnects a client from the server.
|
||||
*
|
||||
* Kicking clients from certain events or callbacks may cause crashes. If in
|
||||
* doubt, create a short (0.1 second) timer to kick the client in the next
|
||||
* available frame.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param format Optional formatting rules for disconnect reason.
|
||||
* Note that a period is automatically appended to the string by the engine.
|
||||
* @param ... Variable number of format parameters.
|
||||
* @noreturn
|
||||
* @error Invalid client index, or client not connected.
|
||||
*/
|
||||
native KickClientEx(client, const String:format[]="", any:...);
|
||||
|
||||
/**
|
||||
* Changes a client's team through the mod's generic team changing function.
|
||||
* On CS:S, this will kill the player.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param team Mod-specific team index.
|
||||
* @noreturn
|
||||
* @error Invalid client index, client not connected, or lack of
|
||||
* mod support.
|
||||
*/
|
||||
native ChangeClientTeam(client, team);
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _commandfilters_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _commandfilters_included
|
||||
|
||||
#define MAX_TARGET_LENGTH 64
|
||||
|
||||
#define COMMAND_FILTER_ALIVE (1<<0) /**< Only allow alive players */
|
||||
#define COMMAND_FILTER_DEAD (1<<1) /**< Only filter dead players */
|
||||
#define COMMAND_FILTER_CONNECTED (1<<2) /**< Allow players not fully in-game */
|
||||
#define COMMAND_FILTER_NO_IMMUNITY (1<<3) /**< Ignore immunity rules */
|
||||
#define COMMAND_FILTER_NO_MULTI (1<<4) /**< Do not allow multiple target patterns */
|
||||
#define COMMAND_FILTER_NO_BOTS (1<<5) /**< Do not allow bots to be targetted */
|
||||
|
||||
#define COMMAND_TARGET_NONE 0 /**< No target was found */
|
||||
#define COMMAND_TARGET_NOT_ALIVE -1 /**< Single client is not alive */
|
||||
#define COMMAND_TARGET_NOT_DEAD -2 /**< Single client is not dead */
|
||||
#define COMMAND_TARGET_NOT_IN_GAME -3 /**< Single client is not in game */
|
||||
#define COMMAND_TARGET_IMMUNE -4 /**< Single client is immune */
|
||||
#define COMMAND_TARGET_EMPTY_FILTER -5 /**< A multi-filter (such as @all) had no targets */
|
||||
#define COMMAND_TARGET_NOT_HUMAN -6 /**< Target was not human */
|
||||
#define COMMAND_TARGET_AMBIGUOUS -7 /**< Partial name had too many targets */
|
||||
|
||||
/**
|
||||
* Processes a generic command target string, and resolves it to a list
|
||||
* of clients or one client, based on filtering rules and a pattern.
|
||||
*
|
||||
* Note that you should use LoadTranslations("common.phrases") in OnPluginStart(),
|
||||
* as that file is guaranteed to contain all of the translatable phrases that
|
||||
* ProcessTargetString() will return.
|
||||
*
|
||||
* @param pattern Pattern to find clients against.
|
||||
* @param admin Admin performing the action, or 0 if the server.
|
||||
* @param targets Array to hold targets.
|
||||
* @param max_targets Maximum size of the targets array.
|
||||
* @param filter_flags Filter flags.
|
||||
* @param target_name Buffer to store the target name.
|
||||
* @param tn_maxlength Maximum length of the target name buffer.
|
||||
* @param tn_is_ml OUTPUT: Will be true if the target name buffer is an ML phrase,
|
||||
* false if it is a normal string.
|
||||
* @return If a multi-target pattern was used, the number of clients found
|
||||
* is returned. If a single-target pattern was used, 1 is returned
|
||||
* if one valid client is found. Otherwise, a COMMAND_TARGET reason
|
||||
* for failure is returned.
|
||||
*/
|
||||
native ProcessTargetString(const String:pattern[],
|
||||
admin,
|
||||
targets[],
|
||||
max_targets,
|
||||
filter_flags,
|
||||
String:target_name[],
|
||||
tn_maxlength,
|
||||
&bool:tn_is_ml);
|
||||
|
||||
/**
|
||||
* Replies to a client with a given message describing a targetting
|
||||
* failure reason.
|
||||
*
|
||||
* Note: The translation phrases are found in common.phrases.txt.
|
||||
*
|
||||
* @param client Client index, or 0 for server.
|
||||
* @param reason COMMAND_TARGET reason.
|
||||
* @noreturn
|
||||
*/
|
||||
stock ReplyToTargetError(client, reason)
|
||||
{
|
||||
switch (reason)
|
||||
{
|
||||
case COMMAND_TARGET_NONE:
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "No matching client");
|
||||
}
|
||||
case COMMAND_TARGET_NOT_ALIVE:
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Target must be alive");
|
||||
}
|
||||
case COMMAND_TARGET_NOT_DEAD:
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Target must be dead");
|
||||
}
|
||||
case COMMAND_TARGET_NOT_IN_GAME:
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Target is not in game");
|
||||
}
|
||||
case COMMAND_TARGET_IMMUNE:
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Unable to target");
|
||||
}
|
||||
case COMMAND_TARGET_EMPTY_FILTER:
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "No matching clients");
|
||||
}
|
||||
case COMMAND_TARGET_NOT_HUMAN:
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "Cannot target bot");
|
||||
}
|
||||
case COMMAND_TARGET_AMBIGUOUS:
|
||||
{
|
||||
ReplyToCommand(client, "[SM] %t", "More than one client matched");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,771 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _console_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _console_included
|
||||
|
||||
#define INVALID_FCVAR_FLAGS (-1)
|
||||
|
||||
/**
|
||||
* Console variable bound values used with Get/SetConVarBounds()
|
||||
*/
|
||||
enum ConVarBounds
|
||||
{
|
||||
ConVarBound_Upper = 0,
|
||||
ConVarBound_Lower
|
||||
};
|
||||
|
||||
/**
|
||||
* Console variable query helper values.
|
||||
*/
|
||||
enum QueryCookie
|
||||
{
|
||||
QUERYCOOKIE_FAILED = 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* Reply sources for commands.
|
||||
*/
|
||||
enum ReplySource
|
||||
{
|
||||
SM_REPLY_TO_CONSOLE = 0,
|
||||
SM_REPLY_TO_CHAT = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* Console variable query result values.
|
||||
*/
|
||||
enum ConVarQueryResult
|
||||
{
|
||||
ConVarQuery_Okay = 0, /**< Retrieval of client convar value was successful. */
|
||||
ConVarQuery_NotFound, /**< Client convar was not found. */
|
||||
ConVarQuery_NotValid, /**< A console command with the same name was found, but there is no convar. */
|
||||
ConVarQuery_Protected /**< Client convar was found, but it is protected. The server cannot retrieve its value. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @section Flags for console commands and console variables. The descriptions
|
||||
* for each constant come directly from the Source SDK.
|
||||
*/
|
||||
#define FCVAR_NONE 0 /**< The default, no flags at all */
|
||||
#define FCVAR_UNREGISTERED (1<<0) /**< If this is set, don't add to linked list, etc. */
|
||||
#define FCVAR_LAUNCHER (1<<1) /**< Defined by launcher. */
|
||||
#define FCVAR_GAMEDLL (1<<2) /**< Defined by the game DLL. */
|
||||
#define FCVAR_CLIENTDLL (1<<3) /**< Defined by the client DLL. */
|
||||
#define FCVAR_MATERIAL_SYSTEM (1<<4) /**< Defined by the material system. */
|
||||
#define FCVAR_PROTECTED (1<<5) /**< It's a server cvar, but we don't send the data since it's a password, etc. Sends 1 if it's not bland/zero, 0 otherwise as value. */
|
||||
#define FCVAR_SPONLY (1<<6) /**< This cvar cannot be changed by clients connected to a multiplayer server. */
|
||||
#define FCVAR_ARCHIVE (1<<7) /**< Set to cause it to be saved to vars.rc */
|
||||
#define FCVAR_NOTIFY (1<<8) /**< Notifies players when changed. */
|
||||
#define FCVAR_USERINFO (1<<9) /**< Changes the client's info string. */
|
||||
#define FCVAR_PRINTABLEONLY (1<<10) /**< This cvar's string cannot contain unprintable characters (e.g., used for player name, etc.) */
|
||||
#define FCVAR_UNLOGGED (1<<11) /**< If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log */
|
||||
#define FCVAR_NEVER_AS_STRING (1<<12) /**< Never try to print that cvar. */
|
||||
#define FCVAR_REPLICATED (1<<13) /**< Server setting enforced on clients. */
|
||||
#define FCVAR_CHEAT (1<<14) /**< Only useable in singleplayer / debug / multiplayer & sv_cheats */
|
||||
#define FCVAR_STUDIORENDER (1<<15) /**< Defined by the studiorender system. */
|
||||
#define FCVAR_DEMO (1<<16) /**< Record this cvar when starting a demo file. */
|
||||
#define FCVAR_DONTRECORD (1<<17) /**< Don't record these command in demo files. */
|
||||
#define FCVAR_PLUGIN (1<<18) /**< Defined by a 3rd party plugin. */
|
||||
#define FCVAR_DATACACHE (1<<19) /**< Defined by the datacache system. */
|
||||
#define FCVAR_TOOLSYSTEM (1<<20) /**< Defined by an IToolSystem library */
|
||||
#define FCVAR_FILESYSTEM (1<<21) /**< Defined by the file system. */
|
||||
#define FCVAR_NOT_CONNECTED (1<<22) /**< Cvar cannot be changed by a client that is connected to a server. */
|
||||
#define FCVAR_SOUNDSYSTEM (1<<23) /**< Defined by the soundsystem library. */
|
||||
#define FCVAR_ARCHIVE_XBOX (1<<24) /**< Cvar written to config.cfg on the Xbox. */
|
||||
#define FCVAR_INPUTSYSTEM (1<<25) /**< Defined by the inputsystem DLL. */
|
||||
#define FCVAR_NETWORKSYSTEM (1<<26) /**< Defined by the network system. */
|
||||
#define FCVAR_VPHYSICS (1<<27) /**< Defined by vphysics. */
|
||||
|
||||
/**
|
||||
* @endsection
|
||||
*/
|
||||
|
||||
/**
|
||||
* Executes a server command as if it were on the server console (or RCON)
|
||||
*
|
||||
* @param format Formatting rules.
|
||||
* @param ... Variable number of format parameters.
|
||||
* @noreturn
|
||||
*/
|
||||
native ServerCommand(const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Inserts a server command at the beginning of the server command buffer.
|
||||
*
|
||||
* @param format Formatting rules.
|
||||
* @param ... Variable number of format parameters.
|
||||
* @noreturn
|
||||
*/
|
||||
native InsertServerCommand(const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Executes every command in the server's command buffer, rather than once per frame.
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
native ServerExecute();
|
||||
|
||||
/**
|
||||
* Executes a client command. Note that this will not work on clients unless
|
||||
* they have cl_restrict_server_commands set to 0.
|
||||
*
|
||||
* @param client Index of the client.
|
||||
* @param fmt Format of the client command.
|
||||
* @param ... Format parameters/
|
||||
* @noreturn
|
||||
* @error Invalid client index, or client not connected.
|
||||
*/
|
||||
native ClientCommand(client, const String:fmt[], any:...);
|
||||
|
||||
/**
|
||||
* Executes a client command on the server without being networked.
|
||||
*
|
||||
* FakeClientCommand() overwrites the command tokenization buffer. This can
|
||||
* cause undesired effects because future calls to GetCmdArg* will return
|
||||
* data from the FakeClientCommand(), not the parent command. If you are in
|
||||
* a hook where this matters (for example, a "say" hook), you should use
|
||||
* FakeClientCommandEx() instead.
|
||||
*
|
||||
* @param client Index of the client.
|
||||
* @param fmt Format of the client command.
|
||||
* @param ... Format parameters
|
||||
* @noreturn
|
||||
* @error Invalid client index, or client not connected.
|
||||
*/
|
||||
native FakeClientCommand(client, const String:fmt[], any:...);
|
||||
|
||||
/**
|
||||
* Executes a client command on the server without being networked. The
|
||||
* execution of the client command is delayed by one frame to prevent any
|
||||
* re-entrancy issues that might surface with FakeClientCommand().
|
||||
*
|
||||
* @param client Index of the client.
|
||||
* @param fmt Format of the client command.
|
||||
* @param ... Format parameters
|
||||
* @noreturn
|
||||
* @error Invalid client index, or client not connected.
|
||||
*/
|
||||
native FakeClientCommandEx(client, const String:fmt[], any:...);
|
||||
|
||||
/**
|
||||
* Sends a message to the server console.
|
||||
*
|
||||
* @param format Formatting rules.
|
||||
* @param ... Variable number of format parameters.
|
||||
* @noreturn
|
||||
*/
|
||||
native PrintToServer(const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Sends a message to a client's console.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param format Formatting rules.
|
||||
* @param ... Variable number of format parameters.
|
||||
* @noreturn
|
||||
* @error If the client is not connected an error will be thrown.
|
||||
*/
|
||||
native PrintToConsole(client, const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Reples to a message in a command.
|
||||
*
|
||||
* A client index of 0 will use PrintToServer().
|
||||
* If the command was from the console, PrintToConsole() is used.
|
||||
* If the command was from chat, PrintToChat() is used.
|
||||
*
|
||||
* @param client Client index, or 0 for server.
|
||||
* @param format Formatting rules.
|
||||
* @param ... Variable number of format parameters.
|
||||
* @noreturn
|
||||
* @error If the client is not connected or invalid.
|
||||
*/
|
||||
native ReplyToCommand(client, const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Returns the current reply source of a command.
|
||||
*
|
||||
* @return ReplySource value.
|
||||
*/
|
||||
native ReplySource:GetCmdReplySource();
|
||||
|
||||
/**
|
||||
* Sets the current reply source of a command.
|
||||
*
|
||||
* Only use this if you know what you are doing. You should save the old value
|
||||
* and restore it once you are done.
|
||||
*
|
||||
* @param source New ReplySource value.
|
||||
* @return Old ReplySource value.
|
||||
*/
|
||||
native ReplySource:SetCmdReplySource(ReplySource:source);
|
||||
|
||||
/**
|
||||
* Returns whether the current say hook is a chat trigger.
|
||||
*
|
||||
* This function is only meaningful inside say or say_team hooks.
|
||||
*
|
||||
* @return True if a chat trigger, false otherwise.
|
||||
*/
|
||||
native bool:IsChatTrigger();
|
||||
|
||||
/**
|
||||
* Displays usage of an admin command to users depending on the
|
||||
* setting of the sm_show_activity cvar. All users receive a message
|
||||
* in their chat text, except for the originating client, who receives
|
||||
* the message based on the current ReplySource.
|
||||
*
|
||||
* @param client Client index doing the action, or 0 for server.
|
||||
* @param tag Tag to prepend to the message.
|
||||
* @param format Formatting rules.
|
||||
* @param ... Variable number of format parameters.
|
||||
* @noreturn
|
||||
* @error
|
||||
*/
|
||||
native ShowActivity2(client, const String:tag[], const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Displays usage of an admin command to users depending on the
|
||||
* setting of the sm_show_activity cvar.
|
||||
*
|
||||
* This version does not display a message to the originating client
|
||||
* if used from chat triggers or menus. If manual replies are used
|
||||
* for these cases, then this function will suffice. Otherwise,
|
||||
* ShowActivity2() is slightly more useful.
|
||||
*
|
||||
* @param client Client index doing the action, or 0 for server.
|
||||
* @param format Formatting rules.
|
||||
* @param ... Variable number of format parameters.
|
||||
* @noreturn
|
||||
* @error
|
||||
*/
|
||||
native ShowActivity(client, const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Same as ShowActivity(), except the tag parameter is used instead of
|
||||
* "[SM] " (note that you must supply any spacing).
|
||||
*
|
||||
* @param client Client index doing the action, or 0 for server.
|
||||
* @param tag Tag to display with.
|
||||
* @param format Formatting rules.
|
||||
* @param ... Variable number of format parameters.
|
||||
* @noreturn
|
||||
* @error
|
||||
*/
|
||||
native ShowActivityEx(client, const String:tag[], const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Called when a server-only command is invoked.
|
||||
*
|
||||
* @params args Number of arguments that were in the argument string.
|
||||
* @return An Action value. Not handling the command
|
||||
* means that Source will report it as "not found."
|
||||
*/
|
||||
functag SrvCmd Action:public(args);
|
||||
|
||||
/**
|
||||
* Creates a server-only console command, or hooks an already existing one.
|
||||
*
|
||||
* @param cmd Name of the command to hook or create.
|
||||
* @param callback A function to use as a callback for when the command is invoked.
|
||||
* @param description Optional description to use for command creation.
|
||||
* @param flags Optional flags to use for command creation.
|
||||
* @noreturn
|
||||
* @error Command name is the same as an existing convar.
|
||||
*/
|
||||
native RegServerCmd(const String:cmd[], SrvCmd:callback, const String:description[]="", flags=0);
|
||||
|
||||
/**
|
||||
* Called when a generic console command is invoked.
|
||||
*
|
||||
* @param client Index of the client, or 0 from the server.
|
||||
* @param args Number of arguments that were in the argument string.
|
||||
* @return An Action value. Not handling the command
|
||||
* means that Source will report it as "not found."
|
||||
*/
|
||||
functag ConCmd Action:public(client, args);
|
||||
|
||||
/**
|
||||
* Creates a console command, or hooks an already existing one.
|
||||
*
|
||||
* @param cmd Name of the command to hook or create.
|
||||
* @param callback A function to use as a callback for when the command is invoked.
|
||||
* @param description Optional description to use for command creation.
|
||||
* @param flags Optional flags to use for command creation.
|
||||
* @noreturn
|
||||
* @error Command name is the same as an existing convar.
|
||||
*/
|
||||
native RegConsoleCmd(const String:cmd[], ConCmd:callback, const String:description[]="", flags=0);
|
||||
|
||||
/**
|
||||
* Creates a console command as an administrative command. If the command does not exist,
|
||||
* it is created. When this command is invoked, the access rights of the player are
|
||||
* automatically checked before allowing it to continue.
|
||||
*
|
||||
* @param cmd String containing command to register.
|
||||
* @param callback A function to use as a callback for when the command is invoked.
|
||||
* @param adminflags Administrative flags (bitstring) to use for permissions.
|
||||
* @param description Optional description to use for help.
|
||||
* @param group String containing the command group to use. If empty,
|
||||
* the plugin's filename will be used instead.
|
||||
* @param flags Optional console flags.
|
||||
* @noreturn
|
||||
* @error Command name is the same as an existing convar.
|
||||
*/
|
||||
native RegAdminCmd(const String:cmd[],
|
||||
ConCmd:callback,
|
||||
adminflags,
|
||||
const String:description[]="",
|
||||
const String:group[]="",
|
||||
flags=0);
|
||||
|
||||
/**
|
||||
* Returns the number of arguments from the current console or server command.
|
||||
* @note Unlike the HL2 engine call, this does not include the command itself.
|
||||
*
|
||||
* @return Number of arguments to the current command.
|
||||
*/
|
||||
native GetCmdArgs();
|
||||
|
||||
/**
|
||||
* Retrieves a command argument given its index, from the current console or
|
||||
* server command.
|
||||
* @note Argument indexes start at 1; 0 retrieves the command name.
|
||||
*
|
||||
* @param argnum Argument number to retrieve.
|
||||
* @param buffer Buffer to use for storing the string.
|
||||
* @param maxlength Maximum length of the buffer.
|
||||
* @return Length of string written to buffer.
|
||||
*/
|
||||
native GetCmdArg(argnum, String:buffer[], maxlength);
|
||||
|
||||
/**
|
||||
* Retrieves the entire command argument string in one lump from the current
|
||||
* console or server command.
|
||||
*
|
||||
* @param buffer Buffer to use for storing the string.
|
||||
* @param maxlength Maximum length of the buffer.
|
||||
* @return Length of string written to buffer.
|
||||
*/
|
||||
native GetCmdArgString(String:buffer[], maxlength);
|
||||
|
||||
/**
|
||||
* Creates a new console variable.
|
||||
*
|
||||
* @param name Name of new convar.
|
||||
* @param defaultValue String containing the default value of new convar.
|
||||
* @param description Optional description of the convar.
|
||||
* @param flags Optional bitstring of flags determining how the convar should be handled. See FCVAR_* constants for more details.
|
||||
* @param hasMin Optional boolean that determines if the convar has a minimum value.
|
||||
* @param min Minimum floating point value that the convar can have if hasMin is true.
|
||||
* @param hasMax Optional boolean that determines if the convar has a maximum value.
|
||||
* @param max Maximum floating point value that the convar can have if hasMax is true.
|
||||
* @return A handle to the newly created convar. If the convar already exists, a handle to it will still be returned.
|
||||
* @error Convar name is blank or is the same as an existing console command.
|
||||
*/
|
||||
native Handle:CreateConVar(const String:name[], const String:defaultValue[], const String:description[]="", flags=0, bool:hasMin=false, Float:min=0.0, bool:hasMax=false, Float:max=0.0);
|
||||
|
||||
/**
|
||||
* Searches for a console variable.
|
||||
*
|
||||
* @param name Name of convar to find.
|
||||
* @return A handle to the convar if it is found. INVALID_HANDLE otherwise.
|
||||
*/
|
||||
native Handle:FindConVar(const String:name[]);
|
||||
|
||||
/**
|
||||
* Called when a console variable's value is changed.
|
||||
*
|
||||
* @param convar Handle to the convar that was changed.
|
||||
* @param oldValue String containing the value of the convar before it was changed.
|
||||
* @param newValue String containing the new value of the convar.
|
||||
* @noreturn
|
||||
*/
|
||||
functag ConVarChanged public(Handle:convar, const String:oldValue[], const String:newValue[]);
|
||||
|
||||
/**
|
||||
* Creates a hook for when a console variable's value is changed.
|
||||
*
|
||||
* @param convar Handle to the convar.
|
||||
* @param callback An OnConVarChanged function pointer.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt Handle or invalid callback function.
|
||||
*/
|
||||
native HookConVarChange(Handle:convar, ConVarChanged:callback);
|
||||
|
||||
/**
|
||||
* Removes a hook for when a console variable's value is changed.
|
||||
*
|
||||
* @param convar Handle to the convar.
|
||||
* @param callback An OnConVarChanged function pointer.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt Handle, invalid callback function, or no active hook on convar.
|
||||
*/
|
||||
native UnhookConVarChange(Handle:convar, ConVarChanged:callback);
|
||||
|
||||
/**
|
||||
* Returns the boolean value of a console variable.
|
||||
*
|
||||
* @param convar Handle to the convar.
|
||||
* @return The boolean value of the convar.
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native bool:GetConVarBool(Handle:convar);
|
||||
|
||||
/**
|
||||
* Sets the boolean value of a console variable.
|
||||
*
|
||||
* @param convar Handle to the convar.
|
||||
* @param value New boolean value.
|
||||
* @param replicate If set to true, the new convar value will be set on all clients.
|
||||
* This will only work if the convar has the FCVAR_REPLICATED flag
|
||||
* and actually exists on clients.
|
||||
* @param notify If set to true, clients will be notified that the convar has changed.
|
||||
* This will only work if the convar has the FCVAR_NOTIFY flag.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native SetConVarBool(Handle:convar, bool:value, bool:replicate=false, bool:notify=false);
|
||||
|
||||
/**
|
||||
* Returns the integer value of a console variable.
|
||||
*
|
||||
* @param convar Handle to the convar.
|
||||
* @return The integer value of the convar.
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native GetConVarInt(Handle:convar);
|
||||
|
||||
/**
|
||||
* Sets the integer value of a console variable.
|
||||
*
|
||||
* @param convar Handle to the convar.
|
||||
* @param value New integer value.
|
||||
* @param replicate If set to true, the new convar value will be set on all clients.
|
||||
* This will only work if the convar has the FCVAR_REPLICATED flag
|
||||
* and actually exists on clients.
|
||||
* @param notify If set to true, clients will be notified that the convar has changed.
|
||||
* This will only work if the convar has the FCVAR_NOTIFY flag.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native SetConVarInt(Handle:convar, value, bool:replicate=false, bool:notify=false);
|
||||
|
||||
/**
|
||||
* Returns the floating point value of a console variable.
|
||||
*
|
||||
* @param convar Handle to the convar.
|
||||
* @return The floating point value of the convar.
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native Float:GetConVarFloat(Handle:convar);
|
||||
|
||||
/**
|
||||
* Sets the floating point value of a console variable.
|
||||
*
|
||||
* @param convar Handle to the convar.
|
||||
* @param value New floating point value.
|
||||
* @param replicate If set to true, the new convar value will be set on all clients.
|
||||
* This will only work if the convar has the FCVAR_REPLICATED flag
|
||||
* and actually exists on clients.
|
||||
* @param notify If set to true, clients will be notified that the convar has changed.
|
||||
* This will only work if the convar has the FCVAR_NOTIFY flag.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native SetConVarFloat(Handle:convar, Float:value, bool:replicate=false, bool:notify=false);
|
||||
|
||||
/**
|
||||
* Retrieves the string value of a console variable.
|
||||
*
|
||||
* @param convar Handle to the convar.
|
||||
* @param value Buffer to store the value of the convar.
|
||||
* @param maxlength Maximum length of string buffer.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native GetConVarString(Handle:convar, String:value[], maxlength);
|
||||
|
||||
/**
|
||||
* Sets the string value of a console variable.
|
||||
*
|
||||
* @param convar Handle to the convar.
|
||||
* @param value New string value.
|
||||
* @param replicate If set to true, the new convar value will be set on all clients.
|
||||
* This will only work if the convar has the FCVAR_REPLICATED flag
|
||||
* and actually exists on clients.
|
||||
* @param notify If set to true, clients will be notified that the convar has changed.
|
||||
* This will only work if the convar has the FCVAR_NOTIFY flag.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native SetConVarString(Handle:convar, const String:value[], bool:replicate=false, bool:notify=false);
|
||||
|
||||
/**
|
||||
* Resets the console variable to its default value.
|
||||
*
|
||||
* @param convar Handle to the convar.
|
||||
* @param replicate If set to true, the new convar value will be set on all clients.
|
||||
* This will only work if the convar has the FCVAR_REPLICATED flag
|
||||
* and actually exists on clients.
|
||||
* @param notify If set to true, clients will be notified that the convar has changed.
|
||||
* This will only work if the convar has the FCVAR_NOTIFY flag.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native ResetConVar(Handle:convar, bool:replicate=false, bool:notify=false);
|
||||
|
||||
/**
|
||||
* Returns the bitstring of flags on a console variable.
|
||||
*
|
||||
* @param convar Handle to the convar.
|
||||
* @return A bitstring containing the FCVAR_* flags that are enabled.
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native GetConVarFlags(Handle:convar);
|
||||
|
||||
/**
|
||||
* Sets the bitstring of flags on a console variable.
|
||||
*
|
||||
* @param convar Handle to the convar.
|
||||
* @param flags A bitstring containing the FCVAR_* flags to enable.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native SetConVarFlags(Handle:convar, flags);
|
||||
|
||||
/**
|
||||
* Retrieves the specified bound of a console variable.
|
||||
*
|
||||
* @param convar Handle to the convar.
|
||||
* @param type Type of bound to retrieve, ConVarBound_Lower or ConVarBound_Upper.
|
||||
* @param value By-reference cell to store the specified floating point bound value.
|
||||
* @return True if the convar has the specified bound set, false otherwise.
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native bool:GetConVarBounds(Handle:convar, ConVarBounds:type, &Float:value);
|
||||
|
||||
/**
|
||||
* Sets the specified bound of a console variable.
|
||||
*
|
||||
* @param convar Handle to the convar.
|
||||
* @param type Type of bound to set, ConVarBound_Lower or ConVarBound_Upper
|
||||
* @param set If set to true, convar will use specified bound. If false, bound will be removed.
|
||||
* @param value Floating point value to use as the specified bound.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native SetConVarBounds(Handle:convar, ConVarBounds:type, bool:set, Float:value=0.0);
|
||||
|
||||
/**
|
||||
* Retrieves the name of a console variable.
|
||||
*
|
||||
* @param convar Handle to the convar.
|
||||
* @param value Buffer to store the name of the convar.
|
||||
* @param maxlength Maximum length of string buffer.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native GetConVarName(Handle:convar, const String:name[], maxlength);
|
||||
|
||||
funcenum ConVarQueryFinished
|
||||
{
|
||||
/**
|
||||
* Called when a query to retrieve a client's console variable has finished.
|
||||
*
|
||||
* @param cookie Unique identifier of query.
|
||||
* @param client Player index.
|
||||
* @param result Result of query that tells one whether or not query was successful.
|
||||
* See ConVarQueryResult enum for more details.
|
||||
* @param convarName Name of client convar that was queried.
|
||||
* @param convarValue Value of client convar that was queried if successful. This will be "" if it was not.
|
||||
* @param value Value that was passed when query was started.
|
||||
* @noreturn
|
||||
*/
|
||||
public(QueryCookie:cookie, client, ConVarQueryResult:result, const String:cvarName[], const String:cvarValue[], any:value),
|
||||
|
||||
/**
|
||||
* Called when a query to retrieve a client's console variable has finished.
|
||||
*
|
||||
* @param cookie Unique identifier of query.
|
||||
* @param client Player index.
|
||||
* @param result Result of query that tells one whether or not query was successful.
|
||||
* See ConVarQueryResult enum for more details.
|
||||
* @param convarName Name of client convar that was queried.
|
||||
* @param convarValue Value of client convar that was queried if successful. This will be "" if it was not.
|
||||
* @noreturn
|
||||
*/
|
||||
public(QueryCookie:cookie, client, ConVarQueryResult:result, const String:cvarName[], const String:cvarValue[])
|
||||
};
|
||||
|
||||
/**
|
||||
* Starts a query to retrieve the value of a client's console variable.
|
||||
*
|
||||
* @param client Player index.
|
||||
* @param name Name of client convar to query.
|
||||
* @param callback A function to use as a callback when the query has finished.
|
||||
* @param value Optional value to pass to the callback function.
|
||||
* @return A cookie that uniquely identifies the query.
|
||||
* Returns QUERYCOOKIE_FAILED on failure, such as when used on a bot.
|
||||
*/
|
||||
native QueryCookie:QueryClientConVar(client, const String:cvarName[], ConVarQueryFinished:callback, any:value=0);
|
||||
|
||||
/**
|
||||
* Gets a command iterator. Must be freed with CloseHandle().
|
||||
*
|
||||
* @return A new command iterator.
|
||||
*/
|
||||
native Handle:GetCommandIterator();
|
||||
|
||||
/**
|
||||
* Reads a command iterator, then advances to the next command if any.
|
||||
* Only SourceMod specific commands are returned.
|
||||
*
|
||||
* @param iter Command iterator Handle.
|
||||
* @param name Name buffer.
|
||||
* @param nameLen Name buffer size.
|
||||
* @param eflags Effective default flags of a command.
|
||||
* @param desc Command description buffer.
|
||||
* @param descLen Command description buffer size.
|
||||
* @return True on success, false if there are no more commands.
|
||||
*/
|
||||
native bool:ReadCommandIterator(Handle:iter,
|
||||
String:name[],
|
||||
nameLen,
|
||||
&eflags=0,
|
||||
String:desc[]="",
|
||||
descLen=0);
|
||||
|
||||
/**
|
||||
* Returns whether a client has access to a given command string. The string
|
||||
* can also be any override string, as overrides can be independent of
|
||||
* commands. This important feature essentially allows you to create custom
|
||||
* flags using the override system.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param command Command name. If the command is not found, the default
|
||||
* flags are used.
|
||||
* @param flags Flag string to use as a default, if the command or override
|
||||
* is not found.
|
||||
* @param override_only If true, SourceMod will not attempt to find a matching
|
||||
* command, and it will only use the default flags specified.
|
||||
* Otherwise, SourceMod will ignore the default flags if
|
||||
* there is a matching admin command.
|
||||
* @return True if the client has access, false otherwise.
|
||||
*/
|
||||
native bool:CheckCommandAccess(client,
|
||||
const String:command[],
|
||||
flags,
|
||||
bool:override_only=false);
|
||||
|
||||
/**
|
||||
* Returns true if the supplied character is valid in a ConVar name.
|
||||
*
|
||||
* @param c Character to validate.
|
||||
* @return True is valid for ConVars, false otherwise
|
||||
*/
|
||||
stock bool:IsValidConVarChar(c)
|
||||
{
|
||||
return (c == '_' || IsCharAlpha(c) || IsCharNumeric(c));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bitstring of flags of a command.
|
||||
*
|
||||
* @param name Name of the command.
|
||||
* @return A bitstring containing the FCVAR_* flags that are enabled
|
||||
* or INVALID_FCVAR_FLAGS if command not found.
|
||||
*/
|
||||
native GetCommandFlags(const String:name[]);
|
||||
|
||||
/**
|
||||
* Sets the bitstring of flags of a command.
|
||||
*
|
||||
* @param name Name of the command.
|
||||
* @param flags A bitstring containing the FCVAR_* flags to enable.
|
||||
* @return True on success, otherwise false.
|
||||
*/
|
||||
native bool:SetCommandFlags(const String:name[], flags);
|
||||
|
||||
/**
|
||||
* Starts a ConCommandBase search, traversing the list of ConVars and
|
||||
* ConCommands. If a Handle is returned, the next entry must be read
|
||||
* via FindNextConCommand(). The order of the list is undefined.
|
||||
*
|
||||
* @param buffer Buffer to store entry name.
|
||||
* @param max_size Maximum size of the buffer.
|
||||
* @param isCommand Variable to store whether the entry is a command.
|
||||
* If it is not a command, it is a ConVar.
|
||||
* @param flags Variable to store entry flags.
|
||||
* @param description Buffer to store the description, empty if no description present.
|
||||
* @param descrmax_size Maximum size of the description buffer.
|
||||
* @return On success, a ConCmdIter Handle is returned, which
|
||||
* can be read via FindNextConCommand(), and must be
|
||||
* closed via CloseHandle(). Additionally, the output
|
||||
* parameters will be filled with information of the
|
||||
* first ConCommandBase entry.
|
||||
* On failure, INVALID_HANDLE is returned, and the
|
||||
* contents of outputs is undefined.
|
||||
*/
|
||||
native Handle:FindFirstConCommand(String:buffer[], max_size, &bool:isCommand, &flags=0, String:description[]="", descrmax_size=0);
|
||||
|
||||
/**
|
||||
* Reads the next entry in a ConCommandBase iterator.
|
||||
*
|
||||
* @param search ConCmdIter Handle to search.
|
||||
* @param buffer Buffer to store entry name.
|
||||
* @param max_size Maximum size of the buffer.
|
||||
* @param isCommand Variable to store whether the entry is a command.
|
||||
* If it is not a command, it is a ConVar.
|
||||
* @param flags Variable to store entry flags.
|
||||
* @param description Buffer to store the description, empty if no description present.
|
||||
* @param descrmax_size Maximum size of the description buffer.
|
||||
* @return On success, the outputs are filled, the iterator is
|
||||
* advanced to the next entry, and true is returned.
|
||||
* If no more entries exist, false is returned, and the
|
||||
* contents of outputs is undefined.
|
||||
*/
|
||||
native bool:FindNextConCommand(Handle:search, String:buffer[], max_size, &bool:isCommand, &flags=0, String:description[]="", descrmax_size=0);
|
||||
|
||||
/**
|
||||
* Replicates a convar value to a specific client. This does not change the actual convar value.
|
||||
*
|
||||
* @param client Client index
|
||||
* @param convar ConVar handle
|
||||
* @param value String value to send
|
||||
* @return True on success, false on failure
|
||||
* @error Invalid client index, client not in game, or client is fake
|
||||
*/
|
||||
native bool:SendConVarValue(client, Handle:convar, const String:value[]);
|
||||
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _core_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _core_included
|
||||
|
||||
#include <version>
|
||||
|
||||
#define SOURCEMOD_PLUGINAPI_VERSION 3
|
||||
struct PlVers
|
||||
{
|
||||
version,
|
||||
String:filevers[],
|
||||
String:date[],
|
||||
String:time[]
|
||||
};
|
||||
|
||||
/**
|
||||
* Function helper values.
|
||||
*/
|
||||
enum Function
|
||||
{
|
||||
INVALID_FUNCTION = -1,
|
||||
};
|
||||
|
||||
/**
|
||||
* Specifies what to do after a hook completes.
|
||||
*/
|
||||
enum Action
|
||||
{
|
||||
Plugin_Continue = 0, /**< Continue with the original action */
|
||||
Plugin_Changed = 1, /**< Inputs or outputs have been overridden with new values */
|
||||
Plugin_Handled = 3, /**< Handle the action at the end (don't call it) */
|
||||
Plugin_Stop = 4, /**< Immediately stop the hook chain and handle the original */
|
||||
};
|
||||
|
||||
/**
|
||||
* Specifies identity types.
|
||||
*/
|
||||
enum Identity
|
||||
{
|
||||
Identity_Core = 0,
|
||||
Identity_Extension = 1,
|
||||
Identity_Plugin = 2
|
||||
};
|
||||
|
||||
public PlVers:__version =
|
||||
{
|
||||
version = SOURCEMOD_PLUGINAPI_VERSION,
|
||||
filevers = SOURCEMOD_VERSION,
|
||||
date = __DATE__,
|
||||
time = __TIME__
|
||||
};
|
||||
|
||||
/**
|
||||
* Plugin status values.
|
||||
*/
|
||||
enum PluginStatus
|
||||
{
|
||||
Plugin_Running=0, /**< Plugin is running */
|
||||
/* All states below are "temporarily" unexecutable */
|
||||
Plugin_Paused, /**< Plugin is loaded but paused */
|
||||
Plugin_Error, /**< Plugin is loaded but errored/locked */
|
||||
/* All states below do not have all natives */
|
||||
Plugin_Loaded, /**< Plugin has passed loading and can be finalized */
|
||||
Plugin_Failed, /**< Plugin has a fatal failure */
|
||||
Plugin_Created, /**< Plugin is created but not initialized */
|
||||
Plugin_Uncompiled, /**< Plugin is not yet compiled by the JIT */
|
||||
Plugin_BadLoad, /**< Plugin failed to load */
|
||||
};
|
||||
|
||||
/**
|
||||
* Plugin information properties.
|
||||
*/
|
||||
enum PluginInfo
|
||||
{
|
||||
PlInfo_Name, /**< Plugin name */
|
||||
PlInfo_Author, /**< Plugin author */
|
||||
PlInfo_Description, /**< Plugin description */
|
||||
PlInfo_Version, /**< Plugin verison */
|
||||
PlInfo_URL, /**< Plugin URL */
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines how an extension must expose itself for autoloading.
|
||||
*/
|
||||
struct Extension
|
||||
{
|
||||
const String:name[], /**< Short name */
|
||||
const String:file[], /**< Default file name */
|
||||
bool:autoload, /**< Whether or not to auto-load */
|
||||
bool:required, /**< Whether or not to require */
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines how a plugin must expose itself for native requiring.
|
||||
*/
|
||||
struct SharedPlugin
|
||||
{
|
||||
const String:name[], /**< Short name */
|
||||
const String:file[], /**< File name */
|
||||
bool:required, /**< Whether or not to require */
|
||||
};
|
||||
|
||||
public Float:NULL_VECTOR[3]; /**< Pass this into certain functions to act as a C++ NULL */
|
||||
public const String:NULL_STRING[1]; /**< pass this into certain functions to act as a C++ NULL */
|
||||
|
||||
#define AUTOLOAD_EXTENSIONS
|
||||
#define REQUIRE_EXTENSIONS
|
||||
#define REQUIRE_PLUGIN
|
||||
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _cstrike_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _cstrike_included
|
||||
|
||||
#define CS_TEAM_NONE 0 /**< No team yet. */
|
||||
#define CS_TEAM_SPECTATOR 1 /**< Spectators. */
|
||||
#define CS_TEAM_T 2 /**< Terrorists. */
|
||||
#define CS_TEAM_CT 3 /**< Counter-Terrorists. */
|
||||
|
||||
#define CS_SLOT_PRIMARY 0 /**< Primary weapon slot. */
|
||||
#define CS_SLOT_SECONDARY 1 /**< Secondary weapon slot. */
|
||||
#define CS_SLOT_GRENADE 3 /**< Grenade slot (will only return one grenade). */
|
||||
#define CS_SLOT_C4 4 /**< C4 slot. */
|
||||
|
||||
/**
|
||||
* Respawns a player.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @noreturn
|
||||
* @error Invalid client index, client not in game.
|
||||
*/
|
||||
native CS_RespawnPlayer(client);
|
||||
|
||||
/**
|
||||
* Switches the player's team.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param team Team index.
|
||||
* @noreturn
|
||||
* @error Invalid client index, client not in game.
|
||||
*/
|
||||
native CS_SwitchTeam(client, team);
|
||||
|
||||
/**
|
||||
* Do not edit below this line!
|
||||
*/
|
||||
public Extension:__ext_cstrike =
|
||||
{
|
||||
name = "cstrike",
|
||||
file = "games/game.cstrike.ext",
|
||||
autoload = 0,
|
||||
#if defined REQUIRE_EXTENSIONS
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined REQUIRE_EXTENSIONS
|
||||
public __ext_cstrike_SetNTVOptional()
|
||||
{
|
||||
MarkNativeAsOptional("CS_RespawnPlayer");
|
||||
MarkNativeAsOptional("CS_SwitchTeam");
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,142 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _datapack_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _datapack_included
|
||||
|
||||
/**
|
||||
* Creates a new data pack.
|
||||
*
|
||||
* @return A Handle to the data pack. Must be closed with CloseHandle().
|
||||
*/
|
||||
native Handle:CreateDataPack();
|
||||
|
||||
/**
|
||||
* Packs a normal cell into a data pack.
|
||||
*
|
||||
* @param pack Handle to the data pack.
|
||||
* @param cell Cell to add.
|
||||
* @noreturn
|
||||
* @error Invalid handle.
|
||||
*/
|
||||
native WritePackCell(Handle:pack, cell);
|
||||
|
||||
/**
|
||||
* Packs a float into a data pack.
|
||||
*
|
||||
* @param pack Handle to the data pack.
|
||||
* @param val Float to add.
|
||||
* @noreturn
|
||||
* @error Invalid handle.
|
||||
*/
|
||||
native WritePackFloat(Handle:pack, Float:val);
|
||||
|
||||
/**
|
||||
* Packs a string into a data pack.
|
||||
*
|
||||
* @param pack Handle to the data pack.
|
||||
* @param str String to add.
|
||||
* @noreturn
|
||||
* @error Invalid handle.
|
||||
*/
|
||||
native WritePackString(Handle:pack, const String:str[]);
|
||||
|
||||
/**
|
||||
* Reads a cell from a data pack.
|
||||
*
|
||||
* @param pack Handle to the data pack.
|
||||
* @return Cell value.
|
||||
* @error Invalid handle, or bounds error.
|
||||
*/
|
||||
native ReadPackCell(Handle:pack);
|
||||
|
||||
/**
|
||||
* Reads a float from a data pack.
|
||||
*
|
||||
* @param pack Handle to the data pack.
|
||||
* @return Float value.
|
||||
* @error Invalid handle, or bounds error.
|
||||
*/
|
||||
native Float:ReadPackFloat(Handle:pack);
|
||||
|
||||
/**
|
||||
* Reads a string from a data pack.
|
||||
*
|
||||
* @param pack Handle to the data pack.
|
||||
* @param buffer Destination string buffer.
|
||||
* @param maxlen Maximum length of output string buffer.
|
||||
* @noreturn
|
||||
* @error Invalid handle, or bounds error.
|
||||
*/
|
||||
native ReadPackString(Handle:pack, String:buffer[], maxlen);
|
||||
|
||||
/**
|
||||
* Resets the position in a data pack.
|
||||
*
|
||||
* @param pack Handle to the data pack.
|
||||
* @param clear If true, clears the contained data.
|
||||
* @noreturn
|
||||
* @error Invalid handle.
|
||||
*/
|
||||
native ResetPack(Handle:pack, bool:clear=false);
|
||||
|
||||
/**
|
||||
* Returns the read or write position in a data pack.
|
||||
*
|
||||
* @param pack Handle to the data pack.
|
||||
* @return Numerical position in the data pack.
|
||||
* @error Invalid handle.
|
||||
*/
|
||||
native GetPackPosition(Handle:pack);
|
||||
|
||||
/**
|
||||
* Sets the read/write position in a data pack.
|
||||
*
|
||||
* @param pack Handle to the data pack.
|
||||
* @param position New position to set.
|
||||
* @noreturn
|
||||
* @error Invalid handle, or position is beyond the pack bounds.
|
||||
*/
|
||||
native SetPackPosition(Handle:pack, position);
|
||||
|
||||
/**
|
||||
* Returns whether or not a specified number of bytes from the data pack
|
||||
* position to the end can be read.
|
||||
*
|
||||
* @param pack Handle to the data pack.
|
||||
* @param bytes Number of bytes to simulate reading.
|
||||
* @return True if can be read, false otherwise.
|
||||
* @error Invalid handle.
|
||||
*/
|
||||
native bool:IsPackReadable(Handle:pack, bytes);
|
||||
@@ -0,0 +1,633 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _dbi_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _dbi_included
|
||||
|
||||
/**
|
||||
* @handle Driver
|
||||
*
|
||||
* Contains information about an SQL driver.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @handle Database
|
||||
*
|
||||
* Contains information about a database connection.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @handle Query
|
||||
*
|
||||
* Contains information about an active query and its
|
||||
* result sets.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @handle Statement : Query
|
||||
*
|
||||
* Extends a Query Handle and can be used as a Query Handle.
|
||||
* Statement Handles are for prepared queries and contain
|
||||
* their own function for binding parameters. Statement
|
||||
* Handles can be used instead of database Handles in a few
|
||||
* select functions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Describes a database field fetch status.
|
||||
*/
|
||||
enum DBResult
|
||||
{
|
||||
DBVal_Error = 0, /**< Column number/field is invalid. */
|
||||
DBVal_TypeMismatch = 1, /**< You cannot retrieve this data with this type. */
|
||||
DBVal_Null = 2, /**< Field has no data (NULL) */
|
||||
DBVal_Data = 3, /**< Field has data */
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes binding types.
|
||||
*/
|
||||
enum DBBindType
|
||||
{
|
||||
DBBind_Int = 0, /**< Bind an integer. */
|
||||
DBBind_Float = 1, /**< Bind a float. */
|
||||
DBBind_String = 2, /**< Bind a string. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Threading priority level.
|
||||
*/
|
||||
enum DBPriority
|
||||
{
|
||||
DBPrio_High = 0, /**< High priority. */
|
||||
DBPrio_Normal = 1, /**< Normal priority. */
|
||||
DBPrio_Low = 2, /**< Low priority. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an SQL connection from a named configuration.
|
||||
*
|
||||
* @param confname Named configuration.
|
||||
* @param persistent True to re-use a previous persistent connection if
|
||||
* possible, false otherwise.
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum length of the error buffer.
|
||||
* @return A database connection Handle, or INVALID_HANDLE on failure.
|
||||
*/
|
||||
native Handle:SQL_Connect(const String:confname[], bool:persistent, String:error[], maxlength);
|
||||
|
||||
/**
|
||||
* Creates a default SQL connection.
|
||||
*
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum length of the error buffer.
|
||||
* @param persistent True to re-use a previous persistent connection
|
||||
* if possible, false otherwise.
|
||||
* @return A database connection Handle, or INVALID_HANDLE on failure.
|
||||
*/
|
||||
stock Handle:SQL_DefConnect(String:error[], maxlength, bool:persistent=true)
|
||||
{
|
||||
return SQL_Connect("default", persistent, error, maxlength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an SQL connection from specific parameters.
|
||||
*
|
||||
* @param driver Driver Handle, or INVALID_HANDLE for default.
|
||||
* @param host Host name.
|
||||
* @param user User name.
|
||||
* @param pass User password.
|
||||
* @param database Database name.
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum length of the error buffer.
|
||||
* @param persistent True to re-use a previous persistent connection
|
||||
* if possible, false otherwise.
|
||||
* @param port Optional port to specify.
|
||||
* @param maxTimeout Maximum timeout in seconds if applicable.
|
||||
* @return A database connection Handle, or INVALID_HANDLE on failure.
|
||||
* @error Invalid driver Handle other than INVALID_HANDLE.
|
||||
*/
|
||||
native Handle:SQL_ConnectEx(Handle:driver,
|
||||
const String:host[],
|
||||
const String:user[],
|
||||
const String:pass[],
|
||||
const String:database[],
|
||||
String:error[],
|
||||
maxlength,
|
||||
bool:persistent=true,
|
||||
port=0,
|
||||
maxTimeout=0);
|
||||
|
||||
/**
|
||||
* Returns if a named configuration is present in databases.cfg.
|
||||
*
|
||||
* @param name Configuration name.
|
||||
* @return True if it exists, false otherwise.
|
||||
*/
|
||||
native bool:SQL_CheckConfig(const String:name[]);
|
||||
|
||||
/**
|
||||
* Returns a driver Handle from a name string.
|
||||
*
|
||||
* If the driver is not found, SourceMod will attempt
|
||||
* to load an extension named dbi.<name>.ext.[dll|so].
|
||||
*
|
||||
* @param name Driver identification string, or an empty
|
||||
* string to return the default driver.
|
||||
* @return Driver Handle, or INVALID_HANDLE on failure.
|
||||
*/
|
||||
native Handle:SQL_GetDriver(const String:name[]="");
|
||||
|
||||
/**
|
||||
* Reads the driver of an opened database.
|
||||
*
|
||||
* @param database Database Handle.
|
||||
* @param ident Option buffer to store the identification string.
|
||||
* @param ident_length Maximum length of the buffer.
|
||||
* @return Driver Handle.
|
||||
*/
|
||||
native Handle:SQL_ReadDriver(Handle:database, String:ident[]="", ident_length=0);
|
||||
|
||||
/**
|
||||
* Retrieves a driver's identification string.
|
||||
*
|
||||
* Example: "mysql", "sqlite"
|
||||
*
|
||||
* @param driver Driver Handle, or INVALID_HANDLE for the default driver.
|
||||
* @param ident Identification string buffer.
|
||||
* @param maxlength Maximum length of the buffer.
|
||||
* @noreturn
|
||||
* @error Invalid Handle other than INVALID_HANDLE.
|
||||
*/
|
||||
native SQL_GetDriverIdent(Handle:driver, String:ident[], maxlength);
|
||||
|
||||
/**
|
||||
* Retrieves a driver's product string.
|
||||
*
|
||||
* Example: "MySQL", "SQLite"
|
||||
*
|
||||
* @param driver Driver Handle, or INVALID_HANDLE for the default driver.
|
||||
* @param product Product string buffer.
|
||||
* @param maxlength Maximum length of the buffer.
|
||||
* @noreturn
|
||||
* @error Invalid Handle other than INVALID_HANDLE.
|
||||
*/
|
||||
native SQL_GetDriverProduct(Handle:driver, String:product[], maxlength);
|
||||
|
||||
/**
|
||||
* Returns the number of affected rows from the last query.
|
||||
*
|
||||
* @param hndl A database OR statement Handle.
|
||||
* @return Number of rows affected by the last query.
|
||||
* @error Invalid database or statement Handle.
|
||||
*/
|
||||
native SQL_GetAffectedRows(Handle:hndl);
|
||||
|
||||
/**
|
||||
* Returns the last query's insertion id.
|
||||
*
|
||||
* @param hndl A database OR statement Handle.
|
||||
* @return Last query's insertion id.
|
||||
* @error Invalid database or statement Handle.
|
||||
*/
|
||||
native SQL_GetInsertId(Handle:hndl);
|
||||
|
||||
/**
|
||||
* Returns the error reported by the last query.
|
||||
*
|
||||
* @param hndl A database OR statement Handle.
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum length of the buffer.
|
||||
* @return True if there was an error, false otherwise.
|
||||
* @error Invalid database or statement Handle.
|
||||
*/
|
||||
native bool:SQL_GetError(Handle:hndl, String:error[], maxlength);
|
||||
|
||||
/**
|
||||
* Escapes a database string for literal insertion. This is not needed
|
||||
* for binding strings in prepared statements.
|
||||
*
|
||||
* Generally, database strings are inserted into queries enclosed in
|
||||
* single quotes ('). If user input has a single quote in it, the
|
||||
* quote needs to be escaped. This function ensures that any unsafe
|
||||
* characters are safely escaped according to the database engine and
|
||||
* the database's character set.
|
||||
*
|
||||
* @param hndl A database Handle.
|
||||
* @param string String to quote.
|
||||
* @param buffer Buffer to store quoted string in.
|
||||
* @param maxlength Maximum length of the buffer.
|
||||
* @param written Optionally returns the number of bytes written.
|
||||
* @return True on success, false if buffer is not big enough.
|
||||
* The buffer must be at least 2*strlen(string)+1.
|
||||
* @error Invalid database or statement Handle.
|
||||
*/
|
||||
native bool:SQL_EscapeString(Handle:database,
|
||||
const String:string[],
|
||||
String:buffer[],
|
||||
maxlength,
|
||||
&written=0);
|
||||
|
||||
/**
|
||||
* This is a backwards compatibility stock. You should use SQL_EscapeString()
|
||||
* instead, as this function will probably be deprecated in SourceMod 1.1.
|
||||
*/
|
||||
stock bool:SQL_QuoteString(Handle:database,
|
||||
const String:string[],
|
||||
String:buffer[],
|
||||
maxlength,
|
||||
&written=0)
|
||||
{
|
||||
return SQL_EscapeString(database, string, buffer, maxlength, written);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a query and ignores the result set.
|
||||
*
|
||||
* @param database A database Handle.
|
||||
* @param query Query string.
|
||||
* @param len Optional parameter to specify the query length, in
|
||||
* bytes. This can be used to send binary queries that
|
||||
* have a premature terminator.
|
||||
* @return True if query succeeded, false otherwise. Use
|
||||
* SQL_GetError to find the last error.
|
||||
* @error Invalid database Handle.
|
||||
*/
|
||||
native bool:SQL_FastQuery(Handle:database, const String:query[], len=-1);
|
||||
|
||||
/**
|
||||
* Executes a simple query and returns a new query Handle for
|
||||
* receiving the results.
|
||||
*
|
||||
* @param database A database Handle.
|
||||
* @param query Query string.
|
||||
* @param len Optional parameter to specify the query length, in
|
||||
* bytes. This can be used to send binary queries that
|
||||
* have a premature terminator.
|
||||
* @return A new Query Handle on success, INVALID_HANDLE
|
||||
* otherwise. The Handle must be freed with CloseHandle().
|
||||
* @error Invalid database Handle.
|
||||
*/
|
||||
native Handle:SQL_Query(Handle:database, const String:query[], len=-1);
|
||||
|
||||
/**
|
||||
* Creates a new prepared statement query. Prepared statements can
|
||||
* be executed any number of times. They can also have placeholder
|
||||
* parameters, similar to variables, which can be bound safely and
|
||||
* securely (for example, you do not need to quote bound strings).
|
||||
*
|
||||
* Statement handles will work in any function that accepts a Query handle.
|
||||
*
|
||||
* @param database A database Handle.
|
||||
* @param query Query string.
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum size of the error buffer.
|
||||
* @return A new statement Handle on success, INVALID_HANDLE
|
||||
* otherwise. The Handle must be freed with CloseHandle().
|
||||
* @error Invalid database Handle.
|
||||
*/
|
||||
native Handle:SQL_PrepareQuery(Handle:database, const String:query[], String:error[], maxlength);
|
||||
|
||||
/**
|
||||
* Advances to the next set of results.
|
||||
*
|
||||
* In some SQL implementations, multiple result sets can exist on one query.
|
||||
* This is possible in MySQL with simple queries when executing a CALL
|
||||
* query. If this is the case, all result sets must be processed before
|
||||
* another query is made.
|
||||
*
|
||||
* @param query A query Handle.
|
||||
* @return True if there was another result set, false otherwise.
|
||||
* @error Invalid query Handle.
|
||||
*/
|
||||
native bool:SQL_FetchMoreResults(Handle:query);
|
||||
|
||||
/**
|
||||
* Returns whether or not a result set exists. This will
|
||||
* return true even if 0 results were returned, but false
|
||||
* on queries like UPDATE, INSERT, or DELETE.
|
||||
*
|
||||
* @param query A query (or statement) Handle.
|
||||
* @return True if there is a result set, false otherwise.
|
||||
* @error Invalid query Handle.
|
||||
*/
|
||||
native bool:SQL_HasResultSet(Handle:query);
|
||||
|
||||
/**
|
||||
* Retrieves the number of rows in the last result set.
|
||||
*
|
||||
* @param query A query (or statement) Handle.
|
||||
* @return Number of rows in the current result set.
|
||||
* @error Invalid query Handle.
|
||||
*/
|
||||
native SQL_GetRowCount(Handle:query);
|
||||
|
||||
/**
|
||||
* Retrieves the number of fields in the last result set.
|
||||
*
|
||||
* @param query A query (or statement) Handle.
|
||||
* @return Number of fields in the current result set.
|
||||
* @error Invalid query Handle.
|
||||
*/
|
||||
native SQL_GetFieldCount(Handle:query);
|
||||
|
||||
/**
|
||||
* Retrieves the name of a field by index.
|
||||
*
|
||||
* @param query A query (or statement) Handle.
|
||||
* @param field Field number (starting from 0).
|
||||
* @param name Name buffer.
|
||||
* @param maxlength Maximum length of the name buffer.
|
||||
* @noreturn
|
||||
* @error Invalid query Handle, invalid field index, or
|
||||
* no current result set.
|
||||
*/
|
||||
native SQL_FieldNumToName(Handle:query, field, String:name[], maxlength);
|
||||
|
||||
/**
|
||||
* Retrieves a field index by name.
|
||||
*
|
||||
* @param query A query (or statement) Handle.
|
||||
* @param name Name of the field (case sensitive).
|
||||
* @param field Variable to store field index in.
|
||||
* @return True if found, false if not found.
|
||||
* @error Invalid query Handle or no current result set.
|
||||
*/
|
||||
native bool:SQL_FieldNameToNum(Handle:query, const String:name[], &field);
|
||||
|
||||
/**
|
||||
* Fetches a row from the current result set. This must be
|
||||
* successfully called before any results are fetched.
|
||||
*
|
||||
* If this function fails, SQL_MoreResults() can be used to
|
||||
* tell if there was an error or the result set is finished.
|
||||
*
|
||||
* @param query A query (or statement) Handle.
|
||||
* @return True if a row was fetched, false otherwise.
|
||||
* @error Invalid query Handle.
|
||||
*/
|
||||
native bool:SQL_FetchRow(Handle:query);
|
||||
|
||||
/**
|
||||
* Returns if there are more rows.
|
||||
*
|
||||
* @param query A query (or statement) Handle.
|
||||
* @return True if there are more rows, false otherwise.
|
||||
* @error Invalid query Handle.
|
||||
*/
|
||||
native bool:SQL_MoreRows(Handle:query);
|
||||
|
||||
/**
|
||||
* Rewinds a result set back to the first result.
|
||||
*
|
||||
* @param query A query (or statement) Handle.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid query Handle or no current result set.
|
||||
*/
|
||||
native bool:SQL_Rewind(Handle:query);
|
||||
|
||||
/**
|
||||
* Fetches a string from a field in the current row of a result set.
|
||||
* If the result is NULL, an empty string will be returned. A NULL
|
||||
* check can be done with the result parameter, or SQL_IsFieldNull().
|
||||
*
|
||||
* @param query A query (or statement) Handle.
|
||||
* @param field The field index (starting from 0).
|
||||
* @param buffer String buffer.
|
||||
* @param maxlength Maximum size of the string buffer.
|
||||
* @param result Optional variable to store the status of the return value.
|
||||
* @return Number of bytes written.
|
||||
* @error Invalid query Handle or field index, invalid
|
||||
* type conversion requested from the database,
|
||||
* or no current result set.
|
||||
*/
|
||||
native SQL_FetchString(Handle:query, field, String:buffer[], maxlength, &DBResult:result=DBVal_Error);
|
||||
|
||||
/**
|
||||
* Fetches a float from a field in the current row of a result set.
|
||||
* If the result is NULL, a value of 0.0 will be returned. A NULL
|
||||
* check can be done with the result parameter, or SQL_IsFieldNull().
|
||||
*
|
||||
* @param query A query (or statement) Handle.
|
||||
* @param field The field index (starting from 0).
|
||||
* @param result Optional variable to store the status of the return value.
|
||||
* @return A float value.
|
||||
* @error Invalid query Handle or field index, invalid
|
||||
* type conversion requested from the database,
|
||||
* or no current result set.
|
||||
*/
|
||||
native Float:SQL_FetchFloat(Handle:query, field, &DBResult:result=DBVal_Error);
|
||||
|
||||
/**
|
||||
* Fetches an integer from a field in the current row of a result set.
|
||||
* If the result is NULL, a value of 0 will be returned. A NULL
|
||||
* check can be done with the result parameter, or SQL_IsFieldNull().
|
||||
*
|
||||
* @param query A query (or statement) Handle.
|
||||
* @param field The field index (starting from 0).
|
||||
* @param result Optional variable to store the status of the return value.
|
||||
* @return An integer value.
|
||||
* @error Invalid query Handle or field index, invalid
|
||||
* type conversion requested from the database,
|
||||
* or no current result set.
|
||||
*/
|
||||
native SQL_FetchInt(Handle:query, field, &DBResult:result=DBVal_Error);
|
||||
|
||||
/**
|
||||
* Returns whether a field's data in the current row of a result set is
|
||||
* NULL or not. NULL is an SQL type which means "no data."
|
||||
*
|
||||
* @param query A query (or statement) Handle.
|
||||
* @param field The field index (starting from 0).
|
||||
* @return True if data is NULL, false otherwise.
|
||||
* @error Invalid query Handle or field index, or no
|
||||
* current result set.
|
||||
*/
|
||||
native bool:SQL_IsFieldNull(Handle:query, field);
|
||||
|
||||
/**
|
||||
* Returns the length of a field's data in the current row of a result
|
||||
* set. This only needs to be called for strings to determine how many
|
||||
* bytes to use. Note that the return value does not include the null
|
||||
* terminator.
|
||||
*
|
||||
* @param query A query (or statement) Handle.
|
||||
* @param field The field index (starting from 0).
|
||||
* @return Number of bytes for the field's data size.
|
||||
* @error Invalid query Handle or field index or no
|
||||
* current result set.
|
||||
*/
|
||||
native SQL_FetchSize(Handle:query, field);
|
||||
|
||||
/**
|
||||
* Binds a parameter in a prepared statement to a given integer value.
|
||||
*
|
||||
* @param statement A statement (prepared query) Handle.
|
||||
* @param param The parameter index (starting from 0).
|
||||
* @param number The number to bind.
|
||||
* @param signed True to bind the number as signed, false to
|
||||
* bind it as unsigned.
|
||||
* @noreturn
|
||||
* @error Invalid statement Handle or parameter index, or
|
||||
* SQL error.
|
||||
*/
|
||||
native SQL_BindParamInt(Handle:statement, param, number, bool:signed=true);
|
||||
|
||||
/**
|
||||
* Binds a parameter in a prepared statement to a given float value.
|
||||
*
|
||||
* @param statement A statement (prepared query) Handle.
|
||||
* @param param The parameter index (starting from 0).
|
||||
* @param float The float number to bind.
|
||||
* @noreturn
|
||||
* @error Invalid statement Handle or parameter index, or
|
||||
* SQL error.
|
||||
*/
|
||||
native SQL_BindParamFloat(Handle:statement, param, Float:value);
|
||||
|
||||
/**
|
||||
* Binds a parameter in a prepared statement to a given string value.
|
||||
*
|
||||
* @param statement A statement (prepared query) Handle.
|
||||
* @param param The parameter index (starting from 0).
|
||||
* @param value The string to bind.
|
||||
* @param copy Whether or not SourceMod should copy the value
|
||||
* locally if necessary. If the string contents
|
||||
* won't change before calling SQL_Execute(), this
|
||||
* can be set to false for optimization.
|
||||
* @noreturn
|
||||
* @error Invalid statement Handle or parameter index, or
|
||||
* SQL error.
|
||||
*/
|
||||
native SQL_BindParamString(Handle:statement, param, const String:value[], bool:copy);
|
||||
|
||||
/**
|
||||
* Executes a prepared statement. All parameters must be bound beforehand.
|
||||
*
|
||||
* @param statement A statement (prepared query) Handle.
|
||||
* @return True on success, false on failure.
|
||||
* @error Invalid statement Handle.
|
||||
*/
|
||||
native bool:SQL_Execute(Handle:statement);
|
||||
|
||||
/**
|
||||
* Locks a database so threading operations will not interrupt.
|
||||
*
|
||||
* If you are using a database Handle for both threading and non-threading,
|
||||
* this MUST be called before doing any set of non-threading DB operations.
|
||||
* Otherwise you risk corrupting the database driver's memory or network
|
||||
* connection.
|
||||
*
|
||||
* Leaving a lock on a database and then executing a threaded query results
|
||||
* in a dead lock! Make sure to call SQL_UnlockDatabase()!
|
||||
*
|
||||
* If the lock cannot be acquired, the main thread will pause until the
|
||||
* threaded operation has concluded.
|
||||
*
|
||||
* @param database A database Handle.
|
||||
* @noreturn
|
||||
* @error Invalid database Handle.
|
||||
*/
|
||||
native SQL_LockDatabase(Handle:database);
|
||||
|
||||
/**
|
||||
* Unlocks a database so threading operations may continue.
|
||||
*
|
||||
* @param database A database Handle.
|
||||
* @noreturn
|
||||
* @error Invalid database Handle.
|
||||
*/
|
||||
native SQL_UnlockDatabase(Handle:database);
|
||||
|
||||
/**
|
||||
* General callback for threaded SQL stuff.
|
||||
*
|
||||
* @param db Parent object of the Handle (or INVALID_HANDLE if none).
|
||||
* @param hndl Handle to the child object (or INVALID_HANDLE if none).
|
||||
* @param error Error string if there was an error. The error could be
|
||||
* empty even if an error condition exists, so it is important
|
||||
* to check the actual Handle value instead.
|
||||
* @param data Data passed in via the original threaded invocation.
|
||||
* @param
|
||||
*/
|
||||
functag SQLTCallback public(Handle:owner, Handle:hndl, const String:error[], any:data);
|
||||
|
||||
/**
|
||||
* Tells whether two database handles both point to the same database
|
||||
* connection.
|
||||
*
|
||||
* @param hndl1 First database Handle.
|
||||
* @param hndl2 Second database Handle.
|
||||
* @return True if the Handles point to the same
|
||||
* connection, false otherwise.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:SQL_IsSameConnection(Handle:hndl1, Handle:hndl2);
|
||||
|
||||
/**
|
||||
* Connects to a database via a thread. This can be used instead of
|
||||
* SQL_Connect() if you wish for non-blocking functionality.
|
||||
*
|
||||
* It is not necessary to use this to use threaded queries. However, if you
|
||||
* don't (or you mix threaded/non-threaded queries), you should see
|
||||
* SQL_LockDatabase().
|
||||
*
|
||||
* @param callback Callback; new Handle will be in hndl, owner is the driver.
|
||||
* If no driver was found, the owner is INVALID_HANDLE.
|
||||
* @param name Database name.
|
||||
* @noreturn
|
||||
*/
|
||||
native SQL_TConnect(SQLTCallback:callback, const String:name[]="default", any:data=0);
|
||||
|
||||
/**
|
||||
* Executes a simple query via a thread. The query Handle is passed through
|
||||
* the callback.
|
||||
*
|
||||
* The database Handle returned through the callback is always a new Handle,
|
||||
* and if necessary, SQL_IsSameConnection() should be used to test against
|
||||
* other conenctions.
|
||||
*
|
||||
* The query Handle returned through the callback is temporary and destroyed
|
||||
* at the end of the callback. If you need to hold onto it, use CloneHandle().
|
||||
*
|
||||
* @param database A database Handle.
|
||||
* @param callback Callback; database is in "owner" and the query Handle
|
||||
* is passed in "hndl".
|
||||
* @param query Query string.
|
||||
* @param data Extra data value to pass to the callback.
|
||||
* @param prio Priority queue to use.
|
||||
* @noreturn
|
||||
* @error Invalid database Handle.
|
||||
*/
|
||||
native SQL_TQuery(Handle:database, SQLTCallback:callback, const String:query[], any:data=0, DBPriority:prio=DBPrio_Normal);
|
||||
@@ -0,0 +1,679 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _entity_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _entity_included
|
||||
|
||||
/**
|
||||
* Property types for entities.
|
||||
*/
|
||||
enum PropType
|
||||
{
|
||||
Prop_Send = 0, /**< This property is networked. */
|
||||
Prop_Data = 1, /**< This property is for save game data fields. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @section For more information on these, see the HL2SDK (public/edict.h)
|
||||
*/
|
||||
#define FL_EDICT_CHANGED (1<<0) /**< Game DLL sets this when the entity state changes
|
||||
Mutually exclusive with FL_EDICT_PARTIAL_CHANGE. */
|
||||
#define FL_EDICT_FREE (1<<1) /**< this edict if free for reuse */
|
||||
#define FL_EDICT_FULL (1<<2) /**< this is a full server entity */
|
||||
#define FL_EDICT_FULLCHECK (0<<0) /**< call ShouldTransmit() each time, this is a fake flag */
|
||||
#define FL_EDICT_ALWAYS (1<<3) /**< always transmit this entity */
|
||||
#define FL_EDICT_DONTSEND (1<<4) /**< don't transmit this entity */
|
||||
#define FL_EDICT_PVSCHECK (1<<5) /**< always transmit entity, but cull against PVS */
|
||||
#define FL_EDICT_PENDING_DORMANT_CHECK (1<<6)
|
||||
#define FL_EDICT_DIRTY_PVS_INFORMATION (1<<7)
|
||||
#define FL_FULL_EDICT_CHANGED (1<<8)
|
||||
|
||||
enum PropFieldType
|
||||
{
|
||||
PropField_Unsupported, /**< The type is unsupported. */
|
||||
PropField_Integer, /**< Valid for SendProp and Data fields */
|
||||
PropField_Float, /**< Valid for SendProp and Data fields */
|
||||
PropField_Entity, /**< Valid for Data fields only (SendProp shows as int) */
|
||||
PropField_Vector, /**< Valid for SendProp and Data fields */
|
||||
PropField_String, /**< Valid for SendProp and Data fields */
|
||||
PropField_String_T, /**< Valid for Data fields. Read only.
|
||||
Note that the size of a string_t is dynamic, and
|
||||
thus FindDataMapOffs() will return the constant size
|
||||
of the string_t container (which is 32 bits right now).
|
||||
*/
|
||||
};
|
||||
|
||||
/**
|
||||
* @endsection
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the maximum number of entities.
|
||||
*
|
||||
* @return Maximum number of entities.
|
||||
*/
|
||||
native GetMaxEntities();
|
||||
|
||||
/**
|
||||
* Returns the number of entities in the server.
|
||||
*
|
||||
* @return Number of entities in the server.
|
||||
*/
|
||||
native GetEntityCount();
|
||||
|
||||
/**
|
||||
* Returns whether or not an entity is valid. Returns false
|
||||
* if there is no matching CBaseEntity for this edict index.
|
||||
*
|
||||
* @param edict Index of the entity/edict.
|
||||
* @return True if valid, false otherwise.
|
||||
*/
|
||||
native bool:IsValidEntity(edict);
|
||||
|
||||
/**
|
||||
* Returns whether or not an edict index is valid.
|
||||
*
|
||||
* @param edict Index of the edict.
|
||||
* @return True if valid, false otherwise.
|
||||
*/
|
||||
native bool:IsValidEdict(edict);
|
||||
|
||||
/**
|
||||
* Returns whether or not an entity is a valid networkable edict.
|
||||
*
|
||||
* @param edict Index of the edict.
|
||||
* @return True if networkable, false if invalid or not networkable.
|
||||
*/
|
||||
native bool:IsEntNetworkable(edict);
|
||||
|
||||
/**
|
||||
* Creates a new edict (the basis of a networkable entity)
|
||||
*
|
||||
* @return Index of the edict, 0 on failure.
|
||||
*/
|
||||
native CreateEdict();
|
||||
|
||||
/**
|
||||
* Removes an edict from the world.
|
||||
*
|
||||
* @param edict Index of the edict.
|
||||
* @noreturn
|
||||
* @error Invalid edict index.
|
||||
*/
|
||||
native RemoveEdict(edict);
|
||||
|
||||
/**
|
||||
* Returns the flags on an edict. These are not the same as entity flags.
|
||||
*
|
||||
* @param edict Index of the entity.
|
||||
* @return Edict flags.
|
||||
* @error Invalid edict index.
|
||||
*/
|
||||
native GetEdictFlags(edict);
|
||||
|
||||
/**
|
||||
* Sets the flags on an edict. These are not the same as entity flags.
|
||||
*
|
||||
* @param edict Index of the entity.
|
||||
* @param flags Flags to set.
|
||||
* @noreturn
|
||||
* @error Invalid edict index.
|
||||
*/
|
||||
native SetEdictFlags(edict, flags);
|
||||
|
||||
/**
|
||||
* Retrieves an edict classname.
|
||||
*
|
||||
* @param edict Index of the entity.
|
||||
* @param clsname Buffer to store the classname.
|
||||
* @param maxlength Maximum length of the buffer.
|
||||
* @return True on success, false if there is no classname set.
|
||||
*/
|
||||
native bool:GetEdictClassname(edict, String:clsname[], maxlength);
|
||||
|
||||
/**
|
||||
* Retrieves an entity's networkable serverclass name.
|
||||
* This is not the same as the classname and is used for networkable state changes.
|
||||
*
|
||||
* @param edict Index of the entity.
|
||||
* @param clsname Buffer to store the serverclass name.
|
||||
* @param maxlength Maximum lnegth of the buffer.
|
||||
* @return True on success, false if the edict is not networkable.
|
||||
* @error Invalid edict index.
|
||||
*/
|
||||
native bool:GetEntityNetClass(edict, String:clsname[], maxlength);
|
||||
|
||||
/**
|
||||
* @section Entity offset functions
|
||||
*
|
||||
* Offsets should be specified in byte distance from the CBaseEntity
|
||||
* structure, not short (double byte) or integer (four byte) multiples.
|
||||
* It is somewhat common practice to use offsets aligned to their final
|
||||
* type, and thus make sure you are not falling to this error in SourceMod.
|
||||
* For example, if your "integer-aligned" offset was 119, your byte-aligned
|
||||
* offset is 119*4, or 476.
|
||||
|
||||
* Specifying incorrect offsets or the incorrect data type for an offset
|
||||
* can have fatal consequences. If you are hardcoding offsets, and the
|
||||
* layout of CBaseEntity does not match, you can easily crash the server.
|
||||
*
|
||||
* The reasonable bounds for offsets is greater than or equal to 0 and
|
||||
* below 32768. Offsets out of these bounds will throw an error. However,
|
||||
* this does not represent any real range, it is simply a sanity check for
|
||||
* illegal values. Any range outside of the CBaseEntity structure's private
|
||||
* size will cause undefined behaviour or even crash.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Marks an entity as state changed. This can be useful if you set an offset
|
||||
* and wish for it to be immediately changed over the network. By default this
|
||||
* is not done for offset setting functions.
|
||||
*
|
||||
* @param edict Index to the edict.
|
||||
* @param offset Offset to mark as changed. If 0,
|
||||
* the entire edict is marked as changed.
|
||||
* @noreturn
|
||||
* @error Invalid entity or offset out of bounds.
|
||||
*/
|
||||
native ChangeEdictState(edict, offset = 0);
|
||||
|
||||
/**
|
||||
* Peeks into an entity's object data and retrieves the integer value at
|
||||
* the given offset.
|
||||
*
|
||||
* @param entity Edict index.
|
||||
* @param offset Offset to use.
|
||||
* @param size Number of bytes to read (valid values are 1, 2, or 4).
|
||||
* @return Value at the given memory location.
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
*/
|
||||
native GetEntData(entity, offset, size=4);
|
||||
|
||||
/**
|
||||
* Peeks into an entity's object data and sets the integer value at
|
||||
* the given offset.
|
||||
*
|
||||
* @param entity Edict index.
|
||||
* @param offset Offset to use.
|
||||
* @param size Number of bytes to write (valid values are 1, 2, or 4).
|
||||
* @param changeState If true, change will be sent over the network.
|
||||
* @return Value at the given memory location.
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
* @noreturn
|
||||
*/
|
||||
native SetEntData(entity, offset, any:value, size=4, bool:changeState=false);
|
||||
|
||||
/**
|
||||
* Peeks into an entity's object data and retrieves the float value at
|
||||
* the given offset.
|
||||
*
|
||||
* @param entity Edict index.
|
||||
* @param offset Offset to use.
|
||||
* @return Value at the given memory location.
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
*/
|
||||
native Float:GetEntDataFloat(entity, offset);
|
||||
|
||||
/**
|
||||
* Peeks into an entity's object data and sets the integer value at
|
||||
* the given offset.
|
||||
*
|
||||
* @param entity Edict index.
|
||||
* @param offset Offset to use.
|
||||
* @param changeState If true, change will be sent over the network.
|
||||
* @return Value at the given memory location.
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
* @noreturn
|
||||
*/
|
||||
native SetEntDataFloat(entity, offset, Float:value, bool:changeState=false);
|
||||
|
||||
/**
|
||||
* This function is deprecated. Use GetEntDataEnt2 instead, for
|
||||
* reasons explained in the notes.
|
||||
*
|
||||
* Note: This function returns 0 on failure, which may be misleading,
|
||||
* as the number 0 is also used for the world entity index.
|
||||
*
|
||||
* Note: This function makes no attempt to validate the returned
|
||||
* entity, and in fact, it could be garbage or completely unexpected.
|
||||
*
|
||||
* @param entity Edict index.
|
||||
* @param offset Offset to use.
|
||||
* @return Entity index at the given location, or 0 if none.
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
*/
|
||||
#pragma deprecated Use GetEntDataEnt2() instead.
|
||||
native GetEntDataEnt(entity, offset);
|
||||
|
||||
/**
|
||||
* This function is deprecated. Use SetEntDataEnt2 instead, for
|
||||
* reasons explained in the notes.
|
||||
*
|
||||
* Note: This function uses 0 as an indicator to unset data, but
|
||||
* 0 is also the world entity index. Thus, the a property cannot
|
||||
* be set to the world entity using this native.
|
||||
*
|
||||
* @param entity Edict index.
|
||||
* @param offset Offset to use.
|
||||
* @param other Entity index to set, or 0 to clear.
|
||||
* @param changeState If true, change will be sent over the network.
|
||||
* @noreturn
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
*/
|
||||
#pragma deprecated Use SetEntDataEnt2() instead.
|
||||
native SetEntDataEnt(entity, offset, other, bool:changeState=false);
|
||||
|
||||
/**
|
||||
* Peeks into an entity's object data and retrieves the entity index
|
||||
* at the given offset.
|
||||
*
|
||||
* Note: This will only work on offsets that are stored as "entity
|
||||
* handles" (which usually looks like m_h* in properties). These
|
||||
* are not SourceMod Handles, but internal Source structures.
|
||||
*
|
||||
* @param entity Edict index.
|
||||
* @param offset Offset to use.
|
||||
* @return Entity index at the given location. If there is no entity,
|
||||
* or the stored entity is invalid, then -1 is returned.
|
||||
* @error Invalid input entity, or offset out of reasonable bounds.
|
||||
*/
|
||||
native GetEntDataEnt2(entity, offset);
|
||||
|
||||
/**
|
||||
* Peeks into an entity's object data and sets the entity index at the
|
||||
* given offset.
|
||||
*
|
||||
* Note: This will only work on offsets that are stored as "entity
|
||||
* handles" (which usually looks like m_h* in properties). These
|
||||
* are not SourceMod Handles, but internal Source structures.
|
||||
*
|
||||
* @param entity Edict index.
|
||||
* @param offset Offset to use.
|
||||
* @param other Entity index to set, or -1 to clear.
|
||||
* @param changeState If true, change will be sent over the network.
|
||||
* @noreturn
|
||||
* @error Invalid input entity, or offset out of reasonable bounds.
|
||||
*/
|
||||
native SetEntDataEnt2(entity, offset, other, bool:changeState=false);
|
||||
|
||||
/**
|
||||
* Peeks into an entity's object data and retrieves the vector at the
|
||||
* given offset.
|
||||
* @note Both a Vector and a QAngle are three floats. This is a
|
||||
* convenience function and will work with both types.
|
||||
*
|
||||
* @param entity Edict index.
|
||||
* @param offset Offset to use.
|
||||
* @param vec Vector buffer to store data in.
|
||||
* @noreturn
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
*/
|
||||
native GetEntDataVector(entity, offset, Float:vec[3]);
|
||||
|
||||
/**
|
||||
* Peeks into an entity's object data and sets the vector at the given
|
||||
* offset.
|
||||
* @note Both a Vector and a QAngle are three floats. This is a
|
||||
* convenience function and will work with both types.
|
||||
*
|
||||
* @param entity Edict index.
|
||||
* @param offset Offset to use.
|
||||
* @param vec Vector to set.
|
||||
* @param changeState If true, change will be sent over the network.
|
||||
* @noreturn
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
*/
|
||||
native SetEntDataVector(entity, offset, const Float:vec[3], bool:changeState=false);
|
||||
|
||||
/**
|
||||
* Peeks into an entity's object data and retrieves the string at
|
||||
* the given offset.
|
||||
*
|
||||
* @param entity Edict index.
|
||||
* @param offset Offset to use.
|
||||
* @param buffer Destination string buffer.
|
||||
* @param maxlen Maximum length of output string buffer.
|
||||
* @return Number of non-null bytes written.
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
*/
|
||||
native GetEntDataString(entity, offset, String:buffer[], maxlen);
|
||||
|
||||
/**
|
||||
* Peeks into an entity's object data and sets the string at
|
||||
* the given offset.
|
||||
*
|
||||
* @param entity Edict index.
|
||||
* @param offset Offset to use.
|
||||
* @param buffer String to set.
|
||||
* @param maxlen Maximum length of bytes to write.
|
||||
* @param changeState If true, change will be sent over the network.
|
||||
* @return Number of non-null bytes written.
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
*/
|
||||
native SetEntDataString(entity, offset, const String:buffer[], maxlen, bool:changeState=false);
|
||||
|
||||
/**
|
||||
* @endsection
|
||||
*/
|
||||
|
||||
/**
|
||||
* Given a ServerClass name, finds a networkable send property offset.
|
||||
* This information is cached for future calls.
|
||||
*
|
||||
* Note, this function may return offsets that do not work!
|
||||
* If a property is nested beneath a parent object, the resulting offset
|
||||
* will be invalid for direct use with data functions. Therefore, you
|
||||
* should use FindSendPropInfo() instead. An example of such a property is
|
||||
* CTFPlayer::DT_LocalPlayer.m_nDisguiseClass on Team Fortress.
|
||||
*
|
||||
* @param cls Classname.
|
||||
* @param prop Property name.
|
||||
* @return An offset, or -1 on failure.
|
||||
*/
|
||||
native FindSendPropOffs(const String:cls[], const String:prop[]);
|
||||
|
||||
/**
|
||||
* Given a ServerClass name, finds a networkable send property offset.
|
||||
* This information is cached for future calls.
|
||||
*
|
||||
* Note: This function will correctly compute nested offsets, unlike
|
||||
* FindSendPropOffs(). YOU SHOULD NOT use this function to self-compute
|
||||
* nested offsets. For example, it is okay to add indexes for arrays,
|
||||
* but not to add DT_LocalPlayer to m_nDisguiseClass.
|
||||
*
|
||||
* @param cls Classname.
|
||||
* @param prop Property name.
|
||||
* @param type Optional parameter to store the type.
|
||||
* @param num_bits Optional parameter to store the number of bits the field
|
||||
* uses, if applicable (otherwise 0 is stored). The number
|
||||
* of bits varies for integers and floats, and is always 0
|
||||
* for strings.
|
||||
* @param local_offset Optional parameter to store the local offset, as
|
||||
* FindSendPropOffs() would return.
|
||||
* @return On success, returns an absolutely computed offset.
|
||||
* If no offset is available, 0 is returned.
|
||||
* If the property is not found, -1 is returned.
|
||||
*/
|
||||
native FindSendPropInfo(const String:cls[],
|
||||
const String:prop[],
|
||||
&PropFieldType:type=PropFieldType:0,
|
||||
&num_bits=0,
|
||||
&local_offset=0);
|
||||
|
||||
/**
|
||||
* Given an entity, finds a datamap property offset.
|
||||
* This information is cached for future calls.
|
||||
*
|
||||
* @param entity Entity index.
|
||||
* @param prop Property name.
|
||||
* @param type Optional parameter to store the type.
|
||||
* @param num_bits Optional parameter to store the number of bits the field
|
||||
* uses. The bit count will either be 1 (for boolean) or
|
||||
* divisible by 8 (including 0 if unknown).
|
||||
* @return An offset, or -1 on failure.
|
||||
*/
|
||||
native FindDataMapOffs(entity,
|
||||
const String:prop[],
|
||||
&PropFieldType:type=PropFieldType:0,
|
||||
&num_bits=0);
|
||||
|
||||
/**
|
||||
* Wrapper function for finding a send property for a particular entity.
|
||||
*
|
||||
* @param ent Entity index.
|
||||
* @param prop Property name.
|
||||
* @param actual Defaults to false for backwards compatibility.
|
||||
* If true, the newer FindSendPropInfo() function
|
||||
* is used instead.
|
||||
* @return An offset, or -1 on failure.
|
||||
*/
|
||||
stock GetEntSendPropOffs(ent, const String:prop[], bool:actual=false)
|
||||
{
|
||||
decl String:cls[64];
|
||||
|
||||
if (!GetEntityNetClass(ent, cls, sizeof(cls)))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (actual)
|
||||
{
|
||||
return FindSendPropInfo(cls, prop);
|
||||
}
|
||||
else
|
||||
{
|
||||
return FindSendPropOffs(cls, prop);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an integer value from an entity's property.
|
||||
*
|
||||
* This function is considered safer and more robust over GetEntData,
|
||||
* because it performs strict offset checking and typing rules. There is a
|
||||
* very minor performance hit from this.
|
||||
*
|
||||
* @param entity Entity/edict index.
|
||||
* @param type Property type.
|
||||
* @param prop Property name.
|
||||
* @param size Number of bytes to write (valid values are 1, 2, or 4).
|
||||
* This value is auto-detected, and the size parameter is
|
||||
* only used as a fallback in case detection fails.
|
||||
* @return Value at the given property offset.
|
||||
* @error Invalid entity or property not found.
|
||||
*/
|
||||
native GetEntProp(entity, PropType:type, const String:prop[], size=4);
|
||||
|
||||
/**
|
||||
* Sets an integer value in an entity's property.
|
||||
*
|
||||
* This function is considered safer and more robust over SetEntData,
|
||||
* because it performs strict offset checking and typing rules. There is a
|
||||
* very minor performance hit from this.
|
||||
*
|
||||
* @param entity Entity/edict index.
|
||||
* @param type Property type.
|
||||
* @param prop Property name.
|
||||
* @param size Number of bytes to write (valid values are 1, 2, or 4).
|
||||
* This value is auto-detected, and the size parameter is
|
||||
* only used as a fallback in case detection fails.
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
* @noreturn
|
||||
*/
|
||||
native SetEntProp(entity, PropType:type, const String:prop[], any:value, size=4);
|
||||
|
||||
/**
|
||||
* Retrieves a float value from an entity's property.
|
||||
*
|
||||
* This function is considered safer and more robust over GetEntDataFloat,
|
||||
* because it performs strict offset checking and typing rules. There is a
|
||||
* very minor performance hit from this.
|
||||
*
|
||||
* @param entity Entity/edict index.
|
||||
* @param type Property type.
|
||||
* @param prop Property name.
|
||||
* @return Value at the given property offset.
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
*/
|
||||
native Float:GetEntPropFloat(entity, PropType:type, const String:prop[]);
|
||||
|
||||
/**
|
||||
* Sets a float value in an entity's property.
|
||||
*
|
||||
* This function is considered safer and more robust over SetEntDataFloat,
|
||||
* because it performs strict offset checking and typing rules. There is a
|
||||
* very minor performance hit from this.
|
||||
*
|
||||
* @param entity Entity/edict index.
|
||||
* @param type Property type.
|
||||
* @param prop Property name.
|
||||
* @param value Value to set.
|
||||
* @noreturn
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
*/
|
||||
native SetEntPropFloat(entity, PropType:type, const String:prop[], Float:value);
|
||||
|
||||
/**
|
||||
* Retrieves an entity index from an entity's property.
|
||||
*
|
||||
* This function is considered safer and more robust over GetEntDataEnt*,
|
||||
* because it performs strict offset checking and typing rules. There is a
|
||||
* very minor performance hit from this.
|
||||
*
|
||||
* @param entity Entity/edict index.
|
||||
* @param type Property type.
|
||||
* @param prop Property name.
|
||||
* @return Entity index at the given property.
|
||||
* If there is no entity, or the entity is not valid,
|
||||
* then -1 is returned.
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
*/
|
||||
native GetEntPropEnt(entity, PropType:type, const String:prop[]);
|
||||
|
||||
/**
|
||||
* Sets an entity index in an entity's property.
|
||||
*
|
||||
* This function is considered safer and more robust over SetEntDataEnt*,
|
||||
* because it performs strict offset checking and typing rules. There is a
|
||||
* very minor performance hit from this.
|
||||
*
|
||||
* @param entity Entity/edict index.
|
||||
* @param type Property type.
|
||||
* @param prop Property name.
|
||||
* @param other Entity index to set, or -1 to unset.
|
||||
* @noreturn
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
*/
|
||||
native SetEntPropEnt(entity, PropType:type, const String:prop[], other);
|
||||
|
||||
/**
|
||||
* Retrieves a vector of floats from an entity, given a named network property.
|
||||
*
|
||||
* This function is considered safer and more robust over GetEntDataVector,
|
||||
* because it performs strict offset checking and typing rules. There is a
|
||||
* very minor performance hit from this.
|
||||
*
|
||||
* @param entity Entity/edict index.
|
||||
* @param type Property type.
|
||||
* @param prop Property name.
|
||||
* @param vec Vector buffer to store data in.
|
||||
* @noreturn
|
||||
* @error Invalid entity, property not found, or property not
|
||||
* actually a vector data type.
|
||||
*/
|
||||
native GetEntPropVector(entity, PropType:type, const String:prop[], Float:vec[3]);
|
||||
|
||||
/**
|
||||
* Sets a vector of floats in an entity, given a named network property.
|
||||
*
|
||||
* This function is considered safer and more robust over SetEntDataVector,
|
||||
* because it performs strict offset checking and typing rules. There is a
|
||||
* very minor performance hit from this.
|
||||
*
|
||||
* @param entity Entity/edict index.
|
||||
* @param type Property type.
|
||||
* @param prop Property name.
|
||||
* @param vec Vector to set.
|
||||
* @noreturn
|
||||
* @error Invalid entity, property not found, or property not
|
||||
* actually a vector data type.
|
||||
*/
|
||||
native SetEntPropVector(entity, PropType:type, const String:prop[], const Float:vec[3]);
|
||||
|
||||
/**
|
||||
* Gets a network property as a string.
|
||||
*
|
||||
* @param entity Edict index.
|
||||
* @param type Property type.
|
||||
* @param prop Property to use.
|
||||
* @param buffer Destination string buffer.
|
||||
* @param maxlen Maximum length of output string buffer.
|
||||
* @return Number of non-null bytes written.
|
||||
* @error Invalid entity, offset out of reasonable bounds, or property is not a valid string.
|
||||
*/
|
||||
native GetEntPropString(entity, PropType:type, const String:prop[], String:buffer[], maxlen);
|
||||
|
||||
/**
|
||||
* Sets a network property as a string.
|
||||
*
|
||||
* This cannot set property fields of type PropField_String_T (such as "m_target").
|
||||
* To set such fields, you should use DispatchKeyValue() from SDKTools.
|
||||
*
|
||||
* @param entity Edict index.
|
||||
* @param type Property type.
|
||||
* @param prop Property to use.
|
||||
* @param buffer String to set.
|
||||
* @return Number of non-null bytes written.
|
||||
* @error Invalid entity, offset out of reasonable bounds, or property is not a valid string.
|
||||
*/
|
||||
native SetEntPropString(entity, PropType:type, const String:prop[], const String:buffer[]);
|
||||
|
||||
/**
|
||||
* Copies an array of cells from an entity at a given offset.
|
||||
*
|
||||
* @param entity Entity index.
|
||||
* @param offset Offset to use.
|
||||
* @param array Array to read into.
|
||||
* @param arraySize Number of values to read.
|
||||
* @param dataSize Size of each value in bytes (1, 2, or 4).
|
||||
* @noreturn
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
*/
|
||||
stock GetEntDataArray(entity, offset, array[], arraySize, dataSize=4)
|
||||
{
|
||||
for (new i=0; i<arraySize; i++)
|
||||
{
|
||||
array[i] = GetEntData(entity, offset + i*dataSize, dataSize)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies an array of cells to an entity at a given offset.
|
||||
*
|
||||
* @param entity Entity index.
|
||||
* @param offset Offset to use.
|
||||
* @param array Array of values to copy.
|
||||
* @param arraySize Number of values to copy.
|
||||
* @param dataSize Size of each value in bytes (1, 2, or 4).
|
||||
* @param changeState True to set the network state as changed; false otherwise.
|
||||
* @noreturn
|
||||
* @error Invalid entity or offset out of reasonable bounds.
|
||||
*/
|
||||
stock SetEntDataArray(entity, offset, const array[], arraySize, dataSize=4, bool:changeState=false)
|
||||
{
|
||||
for (new i=0; i<arraySize; i++)
|
||||
{
|
||||
SetEntData(entity, offset + i*dataSize, array[i], dataSize, changeState);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,324 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _entity_prop_stocks_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _entity_prop_stocks_included
|
||||
|
||||
enum MoveType
|
||||
{
|
||||
MOVETYPE_NONE = 0, /**< never moves */
|
||||
MOVETYPE_ISOMETRIC, /**< For players */
|
||||
MOVETYPE_WALK, /**< Player only - moving on the ground */
|
||||
MOVETYPE_STEP, /**< gravity, special edge handling -- monsters use this */
|
||||
MOVETYPE_FLY, /**< No gravity, but still collides with stuff */
|
||||
MOVETYPE_FLYGRAVITY, /**< flies through the air + is affected by gravity */
|
||||
MOVETYPE_VPHYSICS, /**< uses VPHYSICS for simulation */
|
||||
MOVETYPE_PUSH, /**< no clip to world, push and crush */
|
||||
MOVETYPE_NOCLIP, /**< No gravity, no collisions, still do velocity/avelocity */
|
||||
MOVETYPE_LADDER, /**< Used by players only when going onto a ladder */
|
||||
MOVETYPE_OBSERVER, /**< Observer movement, depends on player's observer mode */
|
||||
MOVETYPE_CUSTOM, /**< Allows the entity to describe its own physics */
|
||||
};
|
||||
|
||||
enum RenderMode
|
||||
{
|
||||
RENDER_NORMAL, /**< src */
|
||||
RENDER_TRANSCOLOR, /**< c*a+dest*(1-a) */
|
||||
RENDER_TRANSTEXTURE, /**< src*a+dest*(1-a) */
|
||||
RENDER_GLOW, /**< src*a+dest -- No Z buffer checks -- Fixed size in screen space */
|
||||
RENDER_TRANSALPHA, /**< src*srca+dest*(1-srca) */
|
||||
RENDER_TRANSADD, /**< src*a+dest */
|
||||
RENDER_ENVIRONMENTAL, /**< not drawn, used for environmental effects */
|
||||
RENDER_TRANSADDFRAMEBLEND, /**< use a fractional frame value to blend between animation frames */
|
||||
RENDER_TRANSALPHAADD, /**< src + dest*(1-a) */
|
||||
RENDER_WORLDGLOW, /**< Same as kRenderGlow but not fixed size in screen space */
|
||||
RENDER_NONE, /**< Don't render. */
|
||||
};
|
||||
|
||||
enum RenderFx
|
||||
{
|
||||
RENDERFX_NONE = 0,
|
||||
RENDERFX_PULSE_SLOW,
|
||||
RENDERFX_PULSE_FAST,
|
||||
RENDERFX_PULSE_SLOW_WIDE,
|
||||
RENDERFX_PULSE_FAST_WIDE,
|
||||
RENDERFX_FADE_SLOW,
|
||||
RENDERFX_FADE_FAST,
|
||||
RENDERFX_SOLID_SLOW,
|
||||
RENDERFX_SOLID_FAST,
|
||||
RENDERFX_STROBE_SLOW,
|
||||
RENDERFX_STROBE_FAST,
|
||||
RENDERFX_STROBE_FASTER,
|
||||
RENDERFX_FLICKER_SLOW,
|
||||
RENDERFX_FLICKER_FAST,
|
||||
RENDERFX_NO_DISSIPATION,
|
||||
RENDERFX_DISTORT, /**< Distort/scale/translate flicker */
|
||||
RENDERFX_HOLOGRAM, /**< kRenderFxDistort + distance fade */
|
||||
RENDERFX_EXPLODE, /**< Scale up really big! */
|
||||
RENDERFX_GLOWSHELL, /**< Glowing Shell */
|
||||
RENDERFX_CLAMP_MIN_SCALE, /**< Keep this sprite from getting very small (SPRITES only!) */
|
||||
RENDERFX_ENV_RAIN, /**< for environmental rendermode, make rain */
|
||||
RENDERFX_ENV_SNOW, /**< " " " , make snow */
|
||||
RENDERFX_SPOTLIGHT, /**< TEST CODE for experimental spotlight */
|
||||
RENDERFX_RAGDOLL, /**< HACKHACK: TEST CODE for signalling death of a ragdoll character */
|
||||
RENDERFX_PULSE_FAST_WIDER,
|
||||
RENDERFX_MAX
|
||||
};
|
||||
|
||||
// These defines are for client button presses.
|
||||
#define IN_ATTACK (1 << 0)
|
||||
#define IN_JUMP (1 << 1)
|
||||
#define IN_DUCK (1 << 2)
|
||||
#define IN_FORWARD (1 << 3)
|
||||
#define IN_BACK (1 << 4)
|
||||
#define IN_USE (1 << 5)
|
||||
#define IN_CANCEL (1 << 6)
|
||||
#define IN_LEFT (1 << 7)
|
||||
#define IN_RIGHT (1 << 8)
|
||||
#define IN_MOVELEFT (1 << 9)
|
||||
#define IN_MOVERIGHT (1 << 10)
|
||||
#define IN_ATTACK2 (1 << 11)
|
||||
#define IN_RUN (1 << 12)
|
||||
#define IN_RELOAD (1 << 13)
|
||||
#define IN_ALT1 (1 << 14)
|
||||
#define IN_ALT2 (1 << 15)
|
||||
#define IN_SCORE (1 << 16) // Used by client.dll for when scoreboard is held down
|
||||
#define IN_SPEED (1 << 17) // Player is holding the speed key
|
||||
#define IN_WALK (1 << 18) // Player holding walk key
|
||||
#define IN_ZOOM (1 << 19) // Zoom key for HUD zoom
|
||||
#define IN_WEAPON1 (1 << 20) // weapon defines these bits
|
||||
#define IN_WEAPON2 (1 << 21) // weapon defines these bits
|
||||
#define IN_BULLRUSH (1 << 22)
|
||||
#define IN_GRENADE1 (1 << 23) // grenade 1
|
||||
#define IN_GRENADE2 (1 << 24) // grenade 2
|
||||
|
||||
// CBaseEntity::m_fFlags
|
||||
// PLAYER SPECIFIC FLAGS FIRST BECAUSE WE USE ONLY A FEW BITS OF NETWORK PRECISION
|
||||
#define FL_ONGROUND (1 << 0) // At rest / on the ground
|
||||
#define FL_DUCKING (1 << 1) // Player flag -- Player is fully crouched
|
||||
#define FL_WATERJUMP (1 << 2) // player jumping out of water
|
||||
#define FL_ONTRAIN (1 << 3) // Player is _controlling_ a train, so movement commands should be ignored on client during prediction.
|
||||
#define FL_INRAIN (1 << 4) // Indicates the entity is standing in rain
|
||||
#define FL_FROZEN (1 << 5) // Player is frozen for 3rd person camera
|
||||
#define FL_ATCONTROLS (1 << 6) // Player can't move, but keeps key inputs for controlling another entity
|
||||
#define FL_CLIENT (1 << 7) // Is a player
|
||||
#define FL_FAKECLIENT (1 << 8) // Fake client, simulated server side; don't send network messages to them
|
||||
// NOTE if you move things up, make sure to change this value
|
||||
#define PLAYER_FLAG_BITS 9
|
||||
// NON-PLAYER SPECIFIC (i.e., not used by GameMovement or the client .dll ) -- Can still be applied to players, though
|
||||
#define FL_INWATER (1 << 9) // In water
|
||||
#define FL_FLY (1 << 10) // Changes the SV_Movestep() behavior to not need to be on ground
|
||||
#define FL_SWIM (1 << 11) // Changes the SV_Movestep() behavior to not need to be on ground (but stay in water)
|
||||
#define FL_CONVEYOR (1 << 12)
|
||||
#define FL_NPC (1 << 13)
|
||||
#define FL_GODMODE (1 << 14)
|
||||
#define FL_NOTARGET (1 << 15)
|
||||
#define FL_AIMTARGET (1 << 16) // set if the crosshair needs to aim onto the entity
|
||||
#define FL_PARTIALGROUND (1 << 17) // not all corners are valid
|
||||
#define FL_STATICPROP (1 << 18) // Eetsa static prop!
|
||||
#define FL_GRAPHED (1 << 19) // worldgraph has this ent listed as something that blocks a connection
|
||||
#define FL_GRENADE (1 << 20)
|
||||
#define FL_STEPMOVEMENT (1 << 21) // Changes the SV_Movestep() behavior to not do any processing
|
||||
#define FL_DONTTOUCH (1 << 22) // Doesn't generate touch functions, generates Untouch() for anything it was touching when this flag was set
|
||||
#define FL_BASEVELOCITY (1 << 23) // Base velocity has been applied this frame (used to convert base velocity into momentum)
|
||||
#define FL_WORLDBRUSH (1 << 24) // Not moveable/removeable brush entity (really part of the world, but represented as an entity for transparency or something)
|
||||
#define FL_OBJECT (1 << 25) // Terrible name. This is an object that NPCs should see. Missiles, for example.
|
||||
#define FL_KILLME (1 << 26) // This entity is marked for death -- will be freed by game DLL
|
||||
#define FL_ONFIRE (1 << 27) // You know...
|
||||
#define FL_DISSOLVING (1 << 28) // We're dissolving!
|
||||
#define FL_TRANSRAGDOLL (1 << 29) // In the process of turning into a client side ragdoll.
|
||||
#define FL_UNBLOCKABLE_BY_PLAYER (1 << 30) // pusher that can't be blocked by the player
|
||||
// END m_fFlags #defines
|
||||
|
||||
/**
|
||||
* Get an entity's flags.
|
||||
*
|
||||
* @param entity Entity index.
|
||||
* @return Entity's flags, see m_fFlag defines above
|
||||
* @error Invalid entity index, or lack of mod compliance.
|
||||
*/
|
||||
stock GetEntityFlags(entity)
|
||||
{
|
||||
return GetEntProp(entity, Prop_Data, "m_fFlags");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an entity's movetype.
|
||||
*
|
||||
* @param entity Entity index.
|
||||
* @return Movetype, see enum above.
|
||||
* @error Invalid entity index, or lack of mod compliance.
|
||||
*/
|
||||
stock MoveType:GetEntityMoveType(entity)
|
||||
{
|
||||
new offset = GetEntSendPropOffs(entity, "movetype");
|
||||
return MoveType:GetEntData(entity, offset, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an entity's movetype.
|
||||
*
|
||||
* @param entity Entity index.
|
||||
* @param mt Movetype, see enum above.
|
||||
* @noreturn
|
||||
* @error Invalid entity index, or lack of mod compliance.
|
||||
*/
|
||||
stock SetEntityMoveType(entity, MoveType:mt)
|
||||
{
|
||||
new offset = GetEntSendPropOffs(entity, "movetype");
|
||||
SetEntData(entity, offset, mt, 1, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an entity's render mode.
|
||||
*
|
||||
* @param entity Entity index.
|
||||
* @return RenderMode value.
|
||||
* @error Invalid entity index, or lack of mod compliance.
|
||||
*/
|
||||
stock RenderMode:GetEntityRenderMode(entity)
|
||||
{
|
||||
return RenderMode:GetEntProp(entity, Prop_Send, "m_nRenderMode", 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an entity's render mode.
|
||||
*
|
||||
* @param entity Entity index.
|
||||
* @param mode RenderMode value.
|
||||
* @noreturn
|
||||
* @error Invalid entity index, or lack of mod compliance.
|
||||
*/
|
||||
stock SetEntityRenderMode(entity, RenderMode:mode)
|
||||
{
|
||||
SetEntProp(entity, Prop_Send, "m_nRenderMode", mode, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an entity's render Fx.
|
||||
*
|
||||
* @param entity Entity index.
|
||||
* @return RenderFx value.
|
||||
* @error Invalid entity index, or lack of mod compliance.
|
||||
*/
|
||||
stock RenderFx:GetEntityRenderFx(entity)
|
||||
{
|
||||
return RenderFx:GetEntProp(entity, Prop_Send, "m_nRenderFX", 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an entity's render Fx.
|
||||
*
|
||||
* @param entity Entity index.
|
||||
* @param fx RenderFx value.
|
||||
* @noreturn
|
||||
* @error Invalid entity index, or lack of mod compliance.
|
||||
*/
|
||||
stock SetEntityRenderFx(entity, RenderFx:fx)
|
||||
{
|
||||
SetEntProp(entity, Prop_Send, "m_nRenderFX", fx, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an entity's color.
|
||||
*
|
||||
* @param entity Entity index
|
||||
* @param r Amount of red (0-255)
|
||||
* @param g Amount of green (0-255)
|
||||
* @param b Amount of blue (0-255)
|
||||
* @param a Amount of alpha (0-255)
|
||||
* @noreturn
|
||||
* @error Invalid entity index, or lack of mod compliance.
|
||||
*/
|
||||
stock SetEntityRenderColor(entity, r=255, g=255, b=255, a=255)
|
||||
{
|
||||
new offset = GetEntSendPropOffs(entity, "m_clrRender");
|
||||
SetEntData(entity, offset, r, 1, true);
|
||||
SetEntData(entity, offset + 1, g, 1, true);
|
||||
SetEntData(entity, offset + 2, b, 1, true);
|
||||
SetEntData(entity, offset + 3, a, 1, true);
|
||||
}
|
||||
|
||||
/* GuessSDKVersion */
|
||||
|
||||
/**
|
||||
* Gets an entity's gravity.
|
||||
*
|
||||
* @param entity Entity index.
|
||||
* @return Entity's m_flGravity value.
|
||||
* @error Invalid entity index, or lack of mod compliance.
|
||||
*/
|
||||
stock Float:GetEntityGravity(entity)
|
||||
{
|
||||
return GetEntPropFloat(entity, Prop_Data, "m_flGravity");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an entity's gravity.
|
||||
*
|
||||
* @param entity Entity index.
|
||||
* @param amount Gravity to set (default = 1.0, half = 0.5, double = 2.0).
|
||||
* @noreturn
|
||||
* @error Invalid entity index, or lack of mod compliance.
|
||||
*/
|
||||
stock SetEntityGravity(entity, Float:amount)
|
||||
{
|
||||
SetEntPropFloat(entity, Prop_Data, "m_flGravity", amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an entity's health
|
||||
*
|
||||
* @param entity Entity index.
|
||||
* @param amount Health amount.
|
||||
* @noreturn
|
||||
* @error Invalid entity index, or lack of mod compliance.
|
||||
*/
|
||||
stock SetEntityHealth(entity, amount)
|
||||
{
|
||||
SetEntProp(entity, Prop_Send, "m_iHealth", amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get's a users current pressed buttons
|
||||
*
|
||||
* @param client Client index
|
||||
* @return Bitsum of buttons
|
||||
* @error Invalid client index, client not in game,
|
||||
* or lack of mod compliance.
|
||||
*/
|
||||
stock GetClientButtons(client)
|
||||
{
|
||||
return GetEntProp(client, Prop_Data, "m_nButtons");
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _events_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _events_included
|
||||
|
||||
/**
|
||||
* Event hook modes determining how hooking should be handled
|
||||
*/
|
||||
enum EventHookMode
|
||||
{
|
||||
EventHookMode_Pre, /**< Hook callback fired before event is fired */
|
||||
EventHookMode_Post, /**< Hook callback fired after event is fired */
|
||||
EventHookMode_PostNoCopy /**< Hook callback fired after event is fired, but event data won't be copied */
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook function types for events.
|
||||
*/
|
||||
funcenum EventHook
|
||||
{
|
||||
/**
|
||||
* Called when a game event is fired.
|
||||
*
|
||||
* @param event Handle to event. This could be INVALID_HANDLE if every plugin hooking
|
||||
* this event has set the hook mode EventHookMode_PostNoCopy.
|
||||
* @param name String containing the name of the event.
|
||||
* @param dontBroadcast True if event was not broadcast to clients, false otherwise.
|
||||
* @return Ignored for post hooks. Plugin_Handled will block event if hooked as pre.
|
||||
*/
|
||||
Action:public(Handle:event, const String:name[], bool:dontBroadcast),
|
||||
/**
|
||||
* Called when a game event is fired.
|
||||
*
|
||||
* @param event Handle to event. This could be INVALID_HANDLE if every plugin hooking
|
||||
* this event has set the hook mode EventHookMode_PostNoCopy.
|
||||
* @param name String containing the name of the event.
|
||||
* @param dontBroadcast True if event was not broadcast to clients, false otherwise.
|
||||
* @noreturn
|
||||
*/
|
||||
public(Handle:event, const String:name[], bool:dontBroadcast),
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a hook for when a game event is fired.
|
||||
*
|
||||
* @param name Name of event.
|
||||
* @param callback An EventHook function pointer.
|
||||
* @param mode Optional EventHookMode determining the type of hook.
|
||||
* @noreturn
|
||||
* @error Invalid event name or invalid callback function.
|
||||
*/
|
||||
native HookEvent(const String:name[], EventHook:callback, EventHookMode:mode=EventHookMode_Post);
|
||||
|
||||
/**
|
||||
* Creates a hook for when a game event is fired.
|
||||
*
|
||||
* @param name Name of event.
|
||||
* @param callback An EventHook function pointer.
|
||||
* @param mode Optional EventHookMode determining the type of hook.
|
||||
* @return True if event exists and was hooked successfully, false otherwise.
|
||||
* @error Invalid callback function.
|
||||
*/
|
||||
native bool:HookEventEx(const String:name[], EventHook:callback, EventHookMode:mode=EventHookMode_Post);
|
||||
|
||||
/**
|
||||
* Removes a hook for when a game event is fired.
|
||||
*
|
||||
* @param name Name of event.
|
||||
* @param callback An EventHook function pointer.
|
||||
* @param mode Optional EventHookMode determining the type of hook.
|
||||
* @noreturn
|
||||
* @error Invalid callback function or no active hook for specified event.
|
||||
*/
|
||||
native UnhookEvent(const String:name[], EventHook:callback, EventHookMode:mode=EventHookMode_Post);
|
||||
|
||||
/**
|
||||
* Creates a game event to be fired later.
|
||||
*
|
||||
* The Handle should not be closed via CloseHandle(). It must be closed via
|
||||
* FireEvent() or CancelCreatedEvent().
|
||||
*
|
||||
* @param name Name of event.
|
||||
* @param force If set to true, this forces the event to be created even if it's not being hooked.
|
||||
* Note that this will not force it if the event doesn't exist at all.
|
||||
* @return Handle to event. INVALID_HANDLE is returned if the event doesn't exist or isn't
|
||||
being hooked (unless force is true).
|
||||
*/
|
||||
native Handle:CreateEvent(const String:name[], bool:force=false);
|
||||
|
||||
/**
|
||||
* Fires a game event.
|
||||
*
|
||||
* This function closes the event Handle after completing.
|
||||
*
|
||||
* @param event Handle to the event.
|
||||
* @param dontBroadcast Optional boolean that determines if event should be broadcast to clients.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native FireEvent(Handle:event, bool:dontBroadcast=false);
|
||||
|
||||
/**
|
||||
* Cancels a previously created game event that has not been fired.
|
||||
*
|
||||
* @param event Handled to the event.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native CancelCreatedEvent(Handle:event);
|
||||
|
||||
/**
|
||||
* Returns the boolean value of a game event's key.
|
||||
*
|
||||
* @param event Handle to the event.
|
||||
* @param key Name of event key.
|
||||
* @return The boolean value of the specfied event key.
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native bool:GetEventBool(Handle:event, const String:key[]);
|
||||
|
||||
/**
|
||||
* Sets the boolean value of a game event's key.
|
||||
*
|
||||
* @param event Handle to the event.
|
||||
* @param key Name of event key.
|
||||
* @param value New boolean value.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native SetEventBool(Handle:event, const String:key[], bool:value);
|
||||
|
||||
/**
|
||||
* Returns the integer value of a game event's key.
|
||||
*
|
||||
* @param event Handle to the event.
|
||||
* @param key Name of event key.
|
||||
* @return The integer value of the specfied event key.
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native GetEventInt(Handle:event, const String:key[]);
|
||||
|
||||
/**
|
||||
* Sets the integer value of a game event's key.
|
||||
*
|
||||
* Integer value refers to anything that can be reduced to an integer.
|
||||
* The various size specifiers, such as "byte" and "short" are still
|
||||
* integers, and only refer to how much data will actually be sent
|
||||
* over the network (if applicable).
|
||||
*
|
||||
* @param event Handle to the event.
|
||||
* @param key Name of event key.
|
||||
* @param value New integer value.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native SetEventInt(Handle:event, const String:key[], value);
|
||||
|
||||
/**
|
||||
* Returns the floating point value of a game event's key.
|
||||
*
|
||||
* @param event Handle to the event.
|
||||
* @param key Name of event key.
|
||||
* @return The floating point value of the specfied event key.
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native Float:GetEventFloat(Handle:event, const String:key[]);
|
||||
|
||||
/**
|
||||
* Sets the floating point value of a game event's key.
|
||||
*
|
||||
* @param event Handle to the event.
|
||||
* @param key Name of event key.
|
||||
* @param value New floating point value.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native SetEventFloat(Handle:event, const String:key[], Float:value);
|
||||
|
||||
/**
|
||||
* Retrieves the string value of a game event's key.
|
||||
*
|
||||
* @param event Handle to the event.
|
||||
* @param key Name of event key.
|
||||
* @param value Buffer to store the value of the specified event key.
|
||||
* @param maxlength Maximum length of string buffer.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native GetEventString(Handle:event, const String:key[], String:value[], maxlength);
|
||||
|
||||
/**
|
||||
* Sets the string value of a game event's key.
|
||||
*
|
||||
* @param event Handle to the event.
|
||||
* @param key Name of event key.
|
||||
* @param value New string value.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native SetEventString(Handle:event, const String:key[], const String:value[]);
|
||||
|
||||
/**
|
||||
* Retrieves the name of a game event.
|
||||
*
|
||||
* @param event Handle to the event.
|
||||
* @param value Buffer to store the name of the event.
|
||||
* @param maxlength Maximum length of string buffer.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native GetEventName(Handle:event, String:name[], maxlength);
|
||||
@@ -0,0 +1,388 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _files_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _files_included
|
||||
|
||||
/**
|
||||
* @global All paths in SourceMod natives are relative to the mod folder
|
||||
* unless otherwise noted.
|
||||
*
|
||||
* Most functions in SourceMod (at least, ones that deal with direct
|
||||
* file manipulation) will support an alternate path specification.
|
||||
*
|
||||
* If the path starts with the string "file://" and the PathType is
|
||||
* not relative, then the "file://" portion is stripped off, and the
|
||||
* rest of the path is used without any modification (except for
|
||||
* correcting slashes). This can be used to override the path
|
||||
* builder to supply alternate absolute paths. Examples:
|
||||
*
|
||||
* file://C:/Temp/file.txt
|
||||
* file:///tmp/file.txt
|
||||
*/
|
||||
|
||||
/**
|
||||
* File inode types.
|
||||
*/
|
||||
enum FileType
|
||||
{
|
||||
FileType_Unknown = 0, /* Unknown file type (device/socket) */
|
||||
FileType_Directory = 1, /* File is a directory */
|
||||
FileType_File = 2, /* File is a file */
|
||||
};
|
||||
|
||||
/**
|
||||
* File time modes.
|
||||
*/
|
||||
enum FileTimeMode
|
||||
{
|
||||
FileTime_LastAccess = 0, /* Last access (does not work on FAT) */
|
||||
FileTime_Created = 1, /* Creation (does not work on FAT) */
|
||||
FileTime_LastChange = 2, /* Last modification */
|
||||
};
|
||||
|
||||
#define PLATFORM_MAX_PATH 256 /**< Maximum path length. */
|
||||
|
||||
#define SEEK_SET 0 /**< Seek from start. */
|
||||
#define SEEK_CUR 1 /**< Seek from current position. */
|
||||
#define SEEK_END 2 /**< Seek from end position. */
|
||||
|
||||
/**
|
||||
* Path types.
|
||||
*/
|
||||
enum PathType
|
||||
{
|
||||
Path_SM, /**< SourceMod root folder */
|
||||
};
|
||||
|
||||
/**
|
||||
* Builds a path relative to the SourceMod folder. This should be used instead of
|
||||
* directly referencing addons/sourcemod, in case users change the name of their
|
||||
* folder layout.
|
||||
*
|
||||
* @param type Type of path to build as the base.
|
||||
* @param buffer Buffer to store the path.
|
||||
* @param maxlength Maximum length of buffer.
|
||||
* @param fmt Format string.
|
||||
* @param ... Format arguments.
|
||||
* @return Number of bytes written to buffer (not including null terminator).
|
||||
*/
|
||||
native BuildPath(PathType:type, String:buffer[], maxlength, const String:fmt[], any:...);
|
||||
|
||||
/**
|
||||
* Opens a directory/folder for contents enumeration.
|
||||
*
|
||||
* @note Directories are closed with CloseHandle().
|
||||
* @note Directories Handles can be cloned.
|
||||
* @note OpenDirectory() supports the "file://" notation.
|
||||
*
|
||||
* @param path Path to open.
|
||||
* @return A Handle to the directory, INVALID_HANDLE on open error.
|
||||
*/
|
||||
native Handle:OpenDirectory(const String:path[]);
|
||||
|
||||
/**
|
||||
* Reads the current directory entry as a local filename, then moves to the next file.
|
||||
*
|
||||
* @note Contents of buffers are undefined when returning false.
|
||||
* @note Both the '.' and '..' automatic directory entries will be retrieved for Windows and Linux.
|
||||
*
|
||||
* @param dir Handle to a directory.
|
||||
* @param buffer String buffer to hold directory name.
|
||||
* @param maxlength Maximum size of string buffer.
|
||||
* @param type Optional variable to store the file type.
|
||||
* @return True on success, false if there are no more files to read.
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native bool:ReadDirEntry(Handle:dir, String:buffer[], maxlength, &FileType:type=FileType_Unknown);
|
||||
|
||||
/**
|
||||
* Opens a file.
|
||||
*
|
||||
* @note Files are closed with CloseHandle().
|
||||
* @note File Handles can be cloned.
|
||||
* @note OpenFile() supports the "file://" notation.
|
||||
*
|
||||
* @param file File to open.
|
||||
* @param mode Open mode.
|
||||
* @return A Handle to the file, INVALID_HANDLE on open error.
|
||||
*/
|
||||
native Handle:OpenFile(const String:file[], const String:mode[]);
|
||||
|
||||
/**
|
||||
* Deletes a file.
|
||||
*
|
||||
* @param path Path of the file to delete.
|
||||
* @return True on success, false otherwise.
|
||||
*/
|
||||
native bool:DeleteFile(const String:path[]);
|
||||
|
||||
/**
|
||||
* Reads a line from a text file.
|
||||
*
|
||||
* @param hndl Handle to the file.
|
||||
* @param buffer String buffer to hold the line.
|
||||
* @param maxlength Maximum size of string buffer.
|
||||
* @return True on success, false otherwise.
|
||||
*/
|
||||
native bool:ReadFileLine(Handle:hndl, String:buffer[], maxlength);
|
||||
|
||||
/**
|
||||
* Reads binary data from a file.
|
||||
*
|
||||
* @param hndl Handle to the file.
|
||||
* @param items Array to store each item read.
|
||||
* @param num_items Number of items to read into the array.
|
||||
* @param size Size of each element, in bytes, to be read.
|
||||
* Valid sizes are 1, 2, or 4.
|
||||
* @return Number of elements read, or -1 on error.
|
||||
*/
|
||||
native ReadFile(Handle:hndl, items[], num_items, size);
|
||||
|
||||
/**
|
||||
* Reads a UTF8 or ANSI string from a file.
|
||||
*
|
||||
* @param hndl Handle to the file.
|
||||
* @param buffer Buffer to store the string.
|
||||
* @param max_size Maximum size of the string buffer.
|
||||
* @param stop If true, reading will stop once max_size-1 bytes have
|
||||
* been read. If false, reading will stop once a NUL
|
||||
* terminator is reached. The buffer will simply be
|
||||
* terminated in either case, the difference is in how
|
||||
* the far the file position is changed.
|
||||
* @return Number of characters written to the buffer, or -1
|
||||
* if an error was encountered.
|
||||
* @error Invalid Handle, or read_count > max_size.
|
||||
*/
|
||||
native ReadFileString(Handle:hndl, String:buffer[], max_size, read_count=-1);
|
||||
|
||||
/**
|
||||
* Writes binary data to a file.
|
||||
*
|
||||
* @param hndl Handle to the file.
|
||||
* @param items Array of items to write. The data is read directly.
|
||||
* That is, in 1 or 2-byte mode, the lower byte(s) in
|
||||
* each cell are used directly, rather than performing
|
||||
* any casts from a 4-byte number to a smaller number.
|
||||
* @param num_items Number of items in the array.
|
||||
* @param size Size of each item in the array in bytes.
|
||||
* Valid sizes are 1, 2, or 4.
|
||||
* @return True on success, false on error.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:WriteFile(Handle:hndl, const items[], num_items, size);
|
||||
|
||||
/**
|
||||
* Writes a binary string to a file.
|
||||
*
|
||||
* @param hndl Handle to th efile.
|
||||
* @param buffer String to write.
|
||||
* @param term True to append NUL terminator, false otherwise.
|
||||
* @return True on success, false on error.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:WriteFileString(Handle:hndl, const String:buffer[], bool:term);
|
||||
|
||||
/**
|
||||
* Writes a line of text to a text file. A newline is automatically appended.
|
||||
*
|
||||
* @param hndl Handle to the file.
|
||||
* @param format Formatting rules.
|
||||
* @param ... Variable number of format parameters.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:WriteFileLine(Handle:hndl, const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Reads a single binary cell from a file.
|
||||
*
|
||||
* @param hndl Handle to the file.
|
||||
* @param data Variable to store the data read.
|
||||
* @param size Size of the data to read in bytes. Valid
|
||||
* sizes are 1, 2, or 4 bytes.
|
||||
* @return Number of elements read (max 1), or -1 on error.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
stock ReadFileCell(Handle:hndl, &data, size)
|
||||
{
|
||||
new array[1], ret;
|
||||
|
||||
if ((ret = ReadFile(hndl, array, 1, size)) == 1)
|
||||
{
|
||||
data = array[0];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a single binary cell to a file.
|
||||
*
|
||||
* @param hndl Handle to the file.
|
||||
* @param data Cell to write to the file.
|
||||
* @param size Size of the data to read in bytes. Valid
|
||||
* sizes are 1, 2, or 4 bytes. If the size
|
||||
* is less than 4 bytes, the data is truncated
|
||||
* rather than casted. That is, only the lower
|
||||
* bits will be read.
|
||||
* @return True on success, false on error.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
stock bool:WriteFileCell(Handle:hndl, data, size)
|
||||
{
|
||||
new array[1];
|
||||
|
||||
array[0] = data;
|
||||
|
||||
return WriteFile(hndl, array, 1, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the end of file has been reached.
|
||||
*
|
||||
* @param file Handle to the file.
|
||||
* @return True if end of file has been reached, false otherwise.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:IsEndOfFile(Handle:file);
|
||||
|
||||
/**
|
||||
* Sets the file position indicator.
|
||||
*
|
||||
* @param file Handle to the file.
|
||||
* @param position Position relative to what is specified in whence.
|
||||
* @param where SEEK_ constant value of where to see from.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:FileSeek(Handle:file, position, where);
|
||||
|
||||
/**
|
||||
* Get current position in the file.
|
||||
*
|
||||
* @param file Handle to the file.
|
||||
* @return Value for the file position indicator.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native FilePosition(Handle:file);
|
||||
|
||||
/**
|
||||
* Checks if a file exists.
|
||||
*
|
||||
* @param path Path to the file.
|
||||
* @param use_valve_fs If true, the Valve file system will be used instead.
|
||||
* This can be used to check for the existance of files
|
||||
* inside GCFs or the game cache, rather than solely files
|
||||
* that are on disk.
|
||||
* @return True if the file exists, false otherwise.
|
||||
*/
|
||||
native bool:FileExists(const String:path[], bool:use_valve_fs=false);
|
||||
|
||||
/**
|
||||
* Renames a file.
|
||||
*
|
||||
* @param newpath New path to the file.
|
||||
* @param oldpath Path to the existing file.
|
||||
* @return True on success, false otherwise.
|
||||
*/
|
||||
native bool:RenameFile(const String:newpath[], const String:oldpath[]);
|
||||
|
||||
/**
|
||||
* Checks if a directory exists.
|
||||
*
|
||||
* @param path Path to the directory.
|
||||
* @return True if the directory exists, false otherwise.
|
||||
*/
|
||||
native bool:DirExists(const String:path[]);
|
||||
|
||||
/**
|
||||
* Get the file size in bytes.
|
||||
*
|
||||
* @param path Path to the file.
|
||||
* @return File size in bytes, -1 if file not found.
|
||||
*/
|
||||
native FileSize(const String:path[]);
|
||||
|
||||
/**
|
||||
* Flushes a file's buffered output; any buffered output
|
||||
* is immediately written to the file.
|
||||
*
|
||||
* @param file Handle to the file.
|
||||
* @return True on success, false on failure.
|
||||
*/
|
||||
native FlushFile(Handle:file);
|
||||
|
||||
/**
|
||||
* Removes a directory.
|
||||
* @note On most Operating Systems you cannot remove a directory which has files inside it.
|
||||
*
|
||||
* @param path Path to the directory.
|
||||
* @return True on success, false otherwise.
|
||||
*/
|
||||
native bool:RemoveDir(const String:path[]);
|
||||
|
||||
/**
|
||||
* Returns a file timestamp as a unix timestamp.
|
||||
*
|
||||
* @param file File name.
|
||||
* @param tmode Time mode.
|
||||
* @return Time value, or -1 on failure.
|
||||
*/
|
||||
native GetFileTime(const String:file[], FileTimeMode:tmode);
|
||||
|
||||
/**
|
||||
* Same as LogToFile(), except uses an open file Handle. The file must
|
||||
* be opened in text appending mode.
|
||||
*
|
||||
* @param hndl Handle to the file.
|
||||
* @param message Message format.
|
||||
* @param ... Message format parameters.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native LogToOpenFile(Handle:hndl, const String:message[], any:...);
|
||||
|
||||
/**
|
||||
* Same as LogToFileEx(), except uses an open file Handle. The file must
|
||||
* be opened in text appending mode.
|
||||
*
|
||||
* @param hndl Handle to the file.
|
||||
* @param message Message format.
|
||||
* @param ... Message format parameters.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native LogToOpenFileEx(Handle:hndl, const String:message[], any:...);
|
||||
|
||||
@@ -0,0 +1,415 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _float_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _float_included
|
||||
|
||||
/**
|
||||
* Converts an integer into a floating point value.
|
||||
*
|
||||
* @param value Integer to convert.
|
||||
* @return Floating point value.
|
||||
*/
|
||||
native Float:float(value);
|
||||
|
||||
/**
|
||||
* Multiplies two floats together.
|
||||
*
|
||||
* @param oper1 First value.
|
||||
* @param oper2 Second value.
|
||||
* @return oper1*oper2.
|
||||
*/
|
||||
native Float:FloatMul(Float:oper1, Float:oper2);
|
||||
|
||||
/**
|
||||
* Divides the dividend by the divisor.
|
||||
*
|
||||
* @param dividend First value.
|
||||
* @param divisor Second value.
|
||||
* @return dividend/divisor.
|
||||
*/
|
||||
native Float:FloatDiv(Float:dividend, Float:divisor);
|
||||
|
||||
/**
|
||||
* Adds two floats together.
|
||||
*
|
||||
* @param oper1 First value.
|
||||
* @param oper2 Second value.
|
||||
* @return oper1+oper2.
|
||||
*/
|
||||
native Float:FloatAdd(Float:oper1, Float:oper2);
|
||||
|
||||
/**
|
||||
* Subtracts oper2 from oper1.
|
||||
*
|
||||
* @param oper1 First value.
|
||||
* @param oper2 Second value.
|
||||
* @return oper1-oper2.
|
||||
*/
|
||||
native Float:FloatSub(Float:oper1, Float:oper2);
|
||||
|
||||
/**
|
||||
* Returns the decimal part of a float.
|
||||
*
|
||||
* @param value Input value.
|
||||
* @return Decimal part.
|
||||
*/
|
||||
native Float:FloatFraction(Float:value);
|
||||
|
||||
/**
|
||||
* Rounds a float to the closest integer to zero.
|
||||
*
|
||||
* @param value Input value to be rounded.
|
||||
* @return Rounded value.
|
||||
*/
|
||||
native RoundToZero(Float:value);
|
||||
|
||||
/**
|
||||
* Rounds a float to the next highest integer value.
|
||||
*
|
||||
* @param value Input value to be rounded.
|
||||
* @return Rounded value.
|
||||
*/
|
||||
native RoundToCeil(Float:value);
|
||||
|
||||
/**
|
||||
* Rounds a float to the next lowest integer value.
|
||||
*
|
||||
* @param value Input value to be rounded.
|
||||
* @return Rounded value.
|
||||
*/
|
||||
native RoundToFloor(Float:value);
|
||||
|
||||
/**
|
||||
* Standard IEEE rounding.
|
||||
*
|
||||
* @param value Input value to be rounded.
|
||||
* @return Rounded value.
|
||||
*/
|
||||
native RoundToNearest(Float:value);
|
||||
|
||||
/**
|
||||
* Compares two floats.
|
||||
*
|
||||
* @param fOne First value.
|
||||
* @param fTwo Second value.
|
||||
* @return Returns 1 if the first argument is greater than the second argument.
|
||||
* Returns -1 if the first argument is smaller than the second argument.
|
||||
* Returns 0 if both arguments are equal.
|
||||
*/
|
||||
native FloatCompare(Float:fOne, Float:fTwo);
|
||||
|
||||
/**
|
||||
* Returns the square root of the input value, equivalent to floatpower(value, 0.5).
|
||||
*
|
||||
* @param value Input value.
|
||||
* @return Square root of the value.
|
||||
*/
|
||||
native Float:SquareRoot(Float:value);
|
||||
|
||||
/**
|
||||
* Returns the value raised to the power of the exponent.
|
||||
*
|
||||
* @param value Value to be raised.
|
||||
* @param exponent Value to raise the base.
|
||||
* @return value^exponent.
|
||||
*/
|
||||
native Float:Pow(Float:value, Float:exponent);
|
||||
|
||||
/**
|
||||
* Returns the value of raising the input by e.
|
||||
*
|
||||
* @param value Input value.
|
||||
* @return exp(value).
|
||||
*/
|
||||
native Float:Exponential(Float:value);
|
||||
|
||||
/**
|
||||
* Returns the logarithm of any base specified.
|
||||
*
|
||||
* @param value Input value.
|
||||
* @param base Logarithm base to use, default is 10.
|
||||
* @return log(value)/log(base).
|
||||
*/
|
||||
native Float:Logarithm(Float:value, Float:base=10.0);
|
||||
|
||||
/**
|
||||
* Returns the sine of the argument.
|
||||
*
|
||||
* @param value Input value in radians.
|
||||
* @return sin(value).
|
||||
*/
|
||||
native Float:Sine(Float:value);
|
||||
|
||||
/**
|
||||
* Returns the cosine of the argument.
|
||||
*
|
||||
* @param value Input value in radians.
|
||||
* @return cos(value).
|
||||
*/
|
||||
native Float:Cosine(Float:value);
|
||||
|
||||
/**
|
||||
* Returns the tangent of the argument.
|
||||
*
|
||||
* @param value Input value in radians.
|
||||
* @return tan(value).
|
||||
*/
|
||||
native Float:Tangent(Float:value);
|
||||
|
||||
/**
|
||||
* Returns an absolute value.
|
||||
*
|
||||
* @param value Input value.
|
||||
* @return Absolute value of the input.
|
||||
*/
|
||||
native Float:FloatAbs(Float:value);
|
||||
|
||||
/**
|
||||
* Returns the arctangent of the input value.
|
||||
*
|
||||
* @param angle Input value.
|
||||
* @return atan(value) in radians.
|
||||
*/
|
||||
native Float:ArcTangent(Float:angle);
|
||||
|
||||
/**
|
||||
* Returns the arccosine of the input value.
|
||||
*
|
||||
* @param angle Input value.
|
||||
* @return acos(value) in radians.
|
||||
*/
|
||||
native Float:ArcCosine(Float:angle);
|
||||
|
||||
/**
|
||||
* Returns the arcsine of the input value.
|
||||
*
|
||||
* @param angle Input value.
|
||||
* @return asin(value) in radians.
|
||||
*/
|
||||
native Float:ArcSine(Float:angle);
|
||||
|
||||
/**
|
||||
* Returns the arctangent2 of the input values.
|
||||
*
|
||||
* @param x Horizontal value.
|
||||
* @param y Vertical value.
|
||||
* @return atan2(value) in radians.
|
||||
*/
|
||||
native Float:ArcTangent2(Float:x, Float:y);
|
||||
|
||||
/**
|
||||
* Rounds a floating point number using the "round to nearest" algorithm.
|
||||
*
|
||||
* @param value Floating point value to round.
|
||||
* @return The value rounded to the nearest integer.
|
||||
*/
|
||||
stock RoundFloat(Float:value)
|
||||
{
|
||||
return RoundToNearest(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* User defined operators.
|
||||
*
|
||||
*/
|
||||
#pragma rational Float
|
||||
|
||||
native Float:operator*(Float:oper1, Float:oper2) = FloatMul;
|
||||
native Float:operator/(Float:oper1, Float:oper2) = FloatDiv;
|
||||
native Float:operator+(Float:oper1, Float:oper2) = FloatAdd;
|
||||
native Float:operator-(Float:oper1, Float:oper2) = FloatSub;
|
||||
|
||||
stock Float:operator++(Float:oper)
|
||||
{
|
||||
return oper+1.0;
|
||||
}
|
||||
|
||||
stock Float:operator--(Float:oper)
|
||||
{
|
||||
return oper-1.0;
|
||||
}
|
||||
|
||||
stock Float:operator-(Float:oper)
|
||||
{
|
||||
return oper^Float:((-1)^((-1)/2)); /* IEEE values are sign/magnitude */
|
||||
}
|
||||
|
||||
stock Float:operator*(Float:oper1, oper2)
|
||||
{
|
||||
return FloatMul(oper1, float(oper2)); /* "*" is commutative */
|
||||
}
|
||||
|
||||
stock Float:operator/(Float:oper1, oper2)
|
||||
{
|
||||
return FloatDiv(oper1, float(oper2));
|
||||
}
|
||||
|
||||
stock Float:operator/(oper1, Float:oper2)
|
||||
{
|
||||
return FloatDiv(float(oper1), oper2);
|
||||
}
|
||||
|
||||
stock Float:operator+(Float:oper1, oper2)
|
||||
{
|
||||
return FloatAdd(oper1, float(oper2)); /* "+" is commutative */
|
||||
}
|
||||
|
||||
stock Float:operator-(Float:oper1, oper2)
|
||||
{
|
||||
return FloatSub(oper1, float(oper2));
|
||||
}
|
||||
|
||||
stock Float:operator-(oper1, Float:oper2)
|
||||
{
|
||||
return FloatSub(float(oper1), oper2);
|
||||
}
|
||||
|
||||
stock bool:operator==(Float:oper1, Float:oper2)
|
||||
{
|
||||
return FloatCompare(oper1, oper2) == 0;
|
||||
}
|
||||
|
||||
stock bool:operator==(Float:oper1, oper2)
|
||||
{
|
||||
return FloatCompare(oper1, float(oper2)) == 0; /* "==" is commutative */
|
||||
}
|
||||
|
||||
stock bool:operator!=(Float:oper1, Float:oper2)
|
||||
{
|
||||
return FloatCompare(oper1, oper2) != 0;
|
||||
}
|
||||
|
||||
stock bool:operator!=(Float:oper1, oper2)
|
||||
{
|
||||
return FloatCompare(oper1, float(oper2)) != 0; /* "==" is commutative */
|
||||
}
|
||||
|
||||
stock bool:operator>(Float:oper1, Float:oper2)
|
||||
{
|
||||
return FloatCompare(oper1, oper2) > 0;
|
||||
}
|
||||
|
||||
stock bool:operator>(Float:oper1, oper2)
|
||||
{
|
||||
return FloatCompare(oper1, float(oper2)) > 0;
|
||||
}
|
||||
|
||||
stock bool:operator>(oper1, Float:oper2)
|
||||
{
|
||||
return FloatCompare(float(oper1), oper2) > 0;
|
||||
}
|
||||
|
||||
stock bool:operator>=(Float:oper1, Float:oper2)
|
||||
{
|
||||
return FloatCompare(oper1, oper2) >= 0;
|
||||
}
|
||||
|
||||
stock bool:operator>=(Float:oper1, oper2)
|
||||
{
|
||||
return FloatCompare(oper1, float(oper2)) >= 0;
|
||||
}
|
||||
|
||||
stock bool:operator>=(oper1, Float:oper2)
|
||||
{
|
||||
return FloatCompare(float(oper1), oper2) >= 0;
|
||||
}
|
||||
|
||||
stock bool:operator<(Float:oper1, Float:oper2)
|
||||
{
|
||||
return FloatCompare(oper1, oper2) < 0;
|
||||
}
|
||||
|
||||
stock bool:operator<(Float:oper1, oper2)
|
||||
{
|
||||
return FloatCompare(oper1, float(oper2)) < 0;
|
||||
}
|
||||
|
||||
stock bool:operator<(oper1, Float:oper2)
|
||||
{
|
||||
return FloatCompare(float(oper1), oper2) < 0;
|
||||
}
|
||||
|
||||
stock bool:operator<=(Float:oper1, Float:oper2)
|
||||
{
|
||||
return FloatCompare(oper1, oper2) <= 0;
|
||||
}
|
||||
|
||||
stock bool:operator<=(Float:oper1, oper2)
|
||||
{
|
||||
return FloatCompare(oper1, float(oper2)) <= 0;
|
||||
}
|
||||
|
||||
stock bool:operator<=(oper1, Float:oper2)
|
||||
{
|
||||
return FloatCompare(float(oper1), oper2) <= 0;
|
||||
}
|
||||
|
||||
stock bool:operator!(Float:oper)
|
||||
{
|
||||
return (_:oper & ((-1)/2)) == 0; /* -1 = all bits to 1; /2 = remove most significant bit (sign)
|
||||
works on both 32bit and 64bit systems; no constant required */
|
||||
}
|
||||
|
||||
/**
|
||||
* Forbidden operators.
|
||||
*
|
||||
*/
|
||||
forward operator%(Float:oper1, Float:oper2);
|
||||
forward operator%(Float:oper1, oper2);
|
||||
forward operator%(oper1, Float:oper2);
|
||||
|
||||
#define FLOAT_PI 3.1415926535897932384626433832795
|
||||
|
||||
/**
|
||||
* Converts degrees to radians.
|
||||
*
|
||||
* @param angle Degrees.
|
||||
* @return Radians.
|
||||
*/
|
||||
stock Float:DegToRad(Float:angle)
|
||||
{
|
||||
return (angle*FLOAT_PI)/180;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts degrees to radians.
|
||||
*
|
||||
* @param angle Radians.
|
||||
* @return Degrees.
|
||||
*/
|
||||
stock Float:RadToDeg(Float:angle)
|
||||
{
|
||||
return (angle*180)/FLOAT_PI;
|
||||
}
|
||||
@@ -0,0 +1,489 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#define SP_PARAMFLAG_BYREF (1<<0) /**< Internal use only. */
|
||||
|
||||
/**
|
||||
* Describes the various ways to pass parameters to functions or forwards.
|
||||
*/
|
||||
enum ParamType
|
||||
{
|
||||
Param_Any = 0, /**< Any data type can be pushed */
|
||||
Param_Cell = (1<<1), /**< Only basic cells can be pushed */
|
||||
Param_Float = (2<<1), /**< Only floats can be pushed */
|
||||
Param_String = (3<<1)|SP_PARAMFLAG_BYREF, /**< Only strings can be pushed */
|
||||
Param_Array = (4<<1)|SP_PARAMFLAG_BYREF, /**< Only arrays can be pushed */
|
||||
Param_VarArgs = (5<<1), /**< Same as "..." in plugins, anything can be pushed, but it will always be byref */
|
||||
Param_CellByRef = (1<<1)|SP_PARAMFLAG_BYREF, /**< Only a cell by reference can be pushed */
|
||||
Param_FloatByRef = (2<<1)|SP_PARAMFLAG_BYREF /**< Only a float by reference can be pushed */
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines how a forward iterates through plugin functions.
|
||||
*/
|
||||
enum ExecType
|
||||
{
|
||||
ET_Ignore = 0, /**< Ignore all return values, return 0 */
|
||||
ET_Single = 1, /**< Only return the last exec, ignore all others */
|
||||
ET_Event = 2, /**< Acts as an event with the Actions defined in core.inc, no mid-Stops allowed, returns highest */
|
||||
ET_Hook = 3 /**< Acts as a hook with the Actions defined in core.inc, mid-Stops allowed, returns highest */
|
||||
};
|
||||
|
||||
/**
|
||||
* @section Flags that are used with Call_PushArrayEx() and Call_PushStringEx()
|
||||
*/
|
||||
|
||||
#define SM_PARAM_COPYBACK (1<<0) /**< Copy an array/reference back after call */
|
||||
|
||||
#define SM_PARAM_STRING_UTF8 (1<<0) /**< String should be UTF-8 handled */
|
||||
#define SM_PARAM_STRING_COPY (1<<1) /**< String should be copied into the plugin */
|
||||
#define SM_PARAM_STRING_BINARY (1<<2) /**< Treat the string as a binary string */
|
||||
|
||||
/**
|
||||
* @endsection
|
||||
*/
|
||||
|
||||
/**
|
||||
* @section Error codes
|
||||
*/
|
||||
#define SP_ERROR_NONE 0 /**< No error occurred */
|
||||
#define SP_ERROR_FILE_FORMAT 1 /**< File format unrecognized */
|
||||
#define SP_ERROR_DECOMPRESSOR 2 /**< A decompressor was not found */
|
||||
#define SP_ERROR_HEAPLOW 3 /**< Not enough space left on the heap */
|
||||
#define SP_ERROR_PARAM 4 /**< Invalid parameter or parameter type */
|
||||
#define SP_ERROR_INVALID_ADDRESS 5 /**< A memory address was not valid */
|
||||
#define SP_ERROR_NOT_FOUND 6 /**< The object in question was not found */
|
||||
#define SP_ERROR_INDEX 7 /**< Invalid index parameter */
|
||||
#define SP_ERROR_STACKLOW 8 /**< Nnot enough space left on the stack */
|
||||
#define SP_ERROR_NOTDEBUGGING 9 /**< Debug mode was not on or debug section not found */
|
||||
#define SP_ERROR_INVALID_INSTRUCTION 10 /**< Invalid instruction was encountered */
|
||||
#define SP_ERROR_MEMACCESS 11 /**< Invalid memory access */
|
||||
#define SP_ERROR_STACKMIN 12 /**< Stack went beyond its minimum value */
|
||||
#define SP_ERROR_HEAPMIN 13 /**< Heap went beyond its minimum value */
|
||||
#define SP_ERROR_DIVIDE_BY_ZERO 14 /**< Division by zero */
|
||||
#define SP_ERROR_ARRAY_BOUNDS 15 /**< Array index is out of bounds */
|
||||
#define SP_ERROR_INSTRUCTION_PARAM 16 /**< Instruction had an invalid parameter */
|
||||
#define SP_ERROR_STACKLEAK 17 /**< A native leaked an item on the stack */
|
||||
#define SP_ERROR_HEAPLEAK 18 /**< A native leaked an item on the heap */
|
||||
#define SP_ERROR_ARRAY_TOO_BIG 19 /**< A dynamic array is too big */
|
||||
#define SP_ERROR_TRACKER_BOUNDS 20 /**< Tracker stack is out of bounds */
|
||||
#define SP_ERROR_INVALID_NATIVE 21 /**< Native was pending or invalid */
|
||||
#define SP_ERROR_PARAMS_MAX 22 /**< Maximum number of parameters reached */
|
||||
#define SP_ERROR_NATIVE 23 /**< Error originates from a native */
|
||||
#define SP_ERROR_NOT_RUNNABLE 24 /**< Function or plugin is not runnable */
|
||||
#define SP_ERROR_ABORTED 25 /**< Function call was aborted */
|
||||
|
||||
/**
|
||||
* @endsection
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets a function id from a function name.
|
||||
*
|
||||
* @param plugin Handle of the plugin that contains the function.
|
||||
Pass INVALID_HANDLE to search in the calling plugin.
|
||||
* @param name Name of the function.
|
||||
* @return Function id or INVALID_FUNCTION if not found.
|
||||
* @error Invalid or corrupt plugin handle.
|
||||
*/
|
||||
native Function:GetFunctionByName(Handle:plugin, const String:name[]);
|
||||
|
||||
/**
|
||||
* Creates a global forward.
|
||||
*
|
||||
* @note The name used to create the forward is used as its public function in all target plugins.
|
||||
* @note This is ideal for global, static forwards that are never changed.
|
||||
* @note Global forwards cannot be cloned.
|
||||
* @note Use CloseHandle() to destroy these.
|
||||
*
|
||||
* @param name Name of public function to use in forward.
|
||||
* @param type Execution type to be used.
|
||||
* @param ... Variable number of parameter types (up to 32).
|
||||
* @return Handle to new global forward.
|
||||
* @error More than 32 paramater types passed.
|
||||
*/
|
||||
native Handle:CreateGlobalForward(const String:name[], ExecType:type, ParamType:...);
|
||||
|
||||
/**
|
||||
* Creates a private forward.
|
||||
*
|
||||
* @note No functions are automatically added. Use AddToForward() to do this.
|
||||
* @note Private forwards can be cloned.
|
||||
* @note Use CloseHandle() to destroy these.
|
||||
*
|
||||
* @param type Execution type to be used.
|
||||
* @param ... Variable number of parameter types (up to 32).
|
||||
* @return Handle to new private forward.
|
||||
* @error More than 32 paramater types passed.
|
||||
*/
|
||||
native Handle:CreateForward(ExecType:type, ParamType:...);
|
||||
|
||||
/**
|
||||
* Returns the number of functions in a global or private forward's call list.
|
||||
*
|
||||
* @param fwd Handle to global or private forward.
|
||||
* @return Number of functions in forward.
|
||||
* @error Invalid or corrupt forward handle.
|
||||
*/
|
||||
native GetForwardFunctionCount(Handle:fwd);
|
||||
|
||||
/**
|
||||
* Adds a function to a private forward's call list.
|
||||
*
|
||||
* @note Cannot be used during an incompleted call.
|
||||
*
|
||||
* @param fwd Handle to private forward.
|
||||
* @param plugin Handle of the plugin that contains the function.
|
||||
* Pass INVALID_HANDLE to specify the calling plugin.
|
||||
* @param func Function to add to forward.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid or corrupt private forward handle, invalid or corrupt plugin handle, or invalid function.
|
||||
*/
|
||||
native bool:AddToForward(Handle:fwd, Handle:plugin, Function:func);
|
||||
|
||||
/**
|
||||
* Removes a function from a private forward's call list.
|
||||
*
|
||||
* @note Only removes one instance.
|
||||
* @note Functions will be removed automatically if their parent plugin is unloaded.
|
||||
*
|
||||
* @param fwd Handle to private forward.
|
||||
* @param plugin Handle of the plugin that contains the function.
|
||||
* Pass INVALID_HANDLE to specify the calling plugin.
|
||||
* @param func Function to remove from forward.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid or corrupt private forward handle, invalid or corrupt plugin handle, or invalid function.
|
||||
*/
|
||||
native bool:RemoveFromForward(Handle:fwd, Handle:plugin, Function:func);
|
||||
|
||||
/**
|
||||
* Removes all instances of a plugin from a private forward's call list.
|
||||
*
|
||||
* @note Functions will be removed automatically if their parent plugin is unloaded.
|
||||
*
|
||||
* @param fwd Handle to private forward.
|
||||
* @param plugin Handle of the plugin to remove instances of.
|
||||
* Pass INVALID_HANDLE to specify the calling plugin.
|
||||
* @return Number of functions removed from forward.
|
||||
* @error Invalid or corrupt private forward handle or invalid or corrupt plugin handle.
|
||||
*/
|
||||
native RemoveAllFromForward(Handle:fwd, Handle:plugin);
|
||||
|
||||
/**
|
||||
* Starts a call to functions in a forward's call list.
|
||||
*
|
||||
* @note Cannot be used during an incompleted call.
|
||||
*
|
||||
* @param fwd Handle to global or private forward.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt forward handle or called before another call has completed.
|
||||
*/
|
||||
native Call_StartForward(Handle:fwd);
|
||||
|
||||
/**
|
||||
* Starts a call to a function.
|
||||
*
|
||||
* @note Cannot be used during an incompleted call.
|
||||
*
|
||||
* @param plugin Handle of the plugin that contains the function.
|
||||
* Pass INVALID_HANDLE to specify the calling plugin.
|
||||
* @param func Function to call.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt plugin handle, invalid function, or called before another call has completed.
|
||||
*/
|
||||
native Call_StartFunction(Handle:plugin, Function:func);
|
||||
|
||||
/**
|
||||
* Pushes a cell onto the current call.
|
||||
*
|
||||
* @note Cannot be used before a call has been started.
|
||||
*
|
||||
* @param value Cell value to push.
|
||||
* @noreturn
|
||||
* @error Called before a call has been started.
|
||||
*/
|
||||
native Call_PushCell(any:value);
|
||||
|
||||
/**
|
||||
* Pushes a cell by reference onto the current call.
|
||||
*
|
||||
* @note Cannot be used before a call has been started.
|
||||
*
|
||||
* @param value Cell reference to push.
|
||||
* @noreturn
|
||||
* @error Called before a call has been started.
|
||||
*/
|
||||
native Call_PushCellRef(&any:value);
|
||||
|
||||
/**
|
||||
* Pushes a float onto the current call.
|
||||
*
|
||||
* @note Cannot be used before a call has been started.
|
||||
*
|
||||
* @param value Floating point value to push.
|
||||
* @noreturn
|
||||
* @error Called before a call has been started.
|
||||
*/
|
||||
native Call_PushFloat(Float:value);
|
||||
|
||||
/**
|
||||
* Pushes a float by reference onto the current call.
|
||||
*
|
||||
* @note Cannot be used before a call has been started.
|
||||
*
|
||||
* @param value Floating point reference to push.
|
||||
* @noreturn
|
||||
* @error Called before a call has been started.
|
||||
*/
|
||||
native Call_PushFloatRef(&Float:value);
|
||||
|
||||
/**
|
||||
* Pushes an array onto the current call.
|
||||
*
|
||||
* @note Changes to array are not copied back to caller. Use PushArrayEx() to do this.
|
||||
* @note Cannot be used before a call has been started.
|
||||
*
|
||||
* @param value Array to push.
|
||||
* @param size Size of array.
|
||||
* @noreturn
|
||||
* @error Called before a call has been started.
|
||||
*/
|
||||
native Call_PushArray(const any:value[], size);
|
||||
|
||||
/**
|
||||
* Pushes an array onto the current call.
|
||||
*
|
||||
* @note Cannot be used before a call has been started.
|
||||
*
|
||||
* @param value Array to push.
|
||||
* @param size Size of array.
|
||||
* @param cpflags Whether or not changes should be copied back to the input array.
|
||||
* See SP_PARAM_* constants for details.
|
||||
* @noreturn
|
||||
* @error Called before a call has been started.
|
||||
*/
|
||||
native Call_PushArrayEx(any:value[], size, cpflags);
|
||||
|
||||
/**
|
||||
* Pushes a string onto the current call.
|
||||
*
|
||||
* @note Changes to string are not copied back to caller. Use PushStringEx() to do this.
|
||||
* @note Cannot be used before a call has been started.
|
||||
*
|
||||
* @param value String to push.
|
||||
* @noreturn
|
||||
* @error Called before a call has been started.
|
||||
*/
|
||||
native Call_PushString(const String:value[]);
|
||||
|
||||
/**
|
||||
* Pushes a string onto the current call.
|
||||
*
|
||||
* @note Cannot be used before a call has been started.
|
||||
*
|
||||
* @param value String to push.
|
||||
* @param length Length of string buffer.
|
||||
* @param szflags Flags determining how string should be handled.
|
||||
* See SP_PARAM_STRING_* constants for details.
|
||||
* The default (0) is to push ASCII.
|
||||
* @param cpflags Whether or not changes should be copied back to the input array.
|
||||
* See SP_PARAM_* constants for details.
|
||||
* @noreturn
|
||||
* @error Called before a call has been started.
|
||||
*/
|
||||
native Call_PushStringEx(String:value[], length, szflags, cpflags);
|
||||
|
||||
/**
|
||||
* Completes a call to a function or forward's call list.
|
||||
*
|
||||
* @note Cannot be used before a call has been started.
|
||||
*
|
||||
* @param result Return value of function or forward's call list.
|
||||
* @return SP_ERROR_NONE on success, any other integer on failure.
|
||||
* @error Called before a call has been started.
|
||||
*/
|
||||
native Call_Finish(&any:result=0);
|
||||
|
||||
/**
|
||||
* Cancels a call to a function or forward's call list.
|
||||
*
|
||||
* @note Cannot be used before a call has been started.
|
||||
*
|
||||
* @noreturn
|
||||
* @error Called before a call has been started.
|
||||
*/
|
||||
native Call_Cancel();
|
||||
|
||||
/**
|
||||
* Defines a native function.
|
||||
*
|
||||
* It is not necessary to validate the parameter count
|
||||
*
|
||||
* @param plugin Handle of the calling plugin.
|
||||
* @param numParams Number of parameters passed to the native.
|
||||
* @return Value for the native call to return.
|
||||
*/
|
||||
functag NativeCall public(Handle:plugin, numParams);
|
||||
|
||||
/**
|
||||
* Creates a dynamic native. This should only be called in AskPluginLoad(), or
|
||||
* else you risk not having your native shared with other plugins.
|
||||
*
|
||||
* @param name Name of the dynamic native; must be unique amongst
|
||||
* all other registered dynamic natives.
|
||||
* @param func Function to use as the dynamic native.
|
||||
* @noreturn
|
||||
*/
|
||||
native CreateNative(const String:name[], NativeCall:func);
|
||||
|
||||
/**
|
||||
* Throws an error in the calling plugin of a native, instead of your own plugin.
|
||||
*
|
||||
* @param error Error code to use.
|
||||
* @param fmt Error message format.
|
||||
* @param ... Format arguments.
|
||||
*/
|
||||
native ThrowNativeError(error, const String:fmt[], any:...);
|
||||
|
||||
/**
|
||||
* Retrieves the string length from a native parameter string. This is useful
|
||||
* fetching the entire string using dynamic arrays.
|
||||
* @note If this function succeeds, Get/SetNativeString will also succeed.
|
||||
*
|
||||
* @param param Parameter number, starting from 1.
|
||||
* @param length Stores the length of the string.
|
||||
* @return SP_ERROR_NONE on success, any other integer on failure.
|
||||
* @error Invalid parameter number or calling from a non-native function.
|
||||
*/
|
||||
native GetNativeStringLength(param, &length);
|
||||
|
||||
/**
|
||||
* Retrieves a string from a native parameter.
|
||||
* @note Output conditions are undefined on failure.
|
||||
*
|
||||
* @param param Parameter number, starting from 1.
|
||||
* @param buffer Buffer to store the string in.
|
||||
* @param maxlength Maximum length of the buffer.
|
||||
* @param bytes Optionally store the number of bytes written.
|
||||
* @return SP_ERROR_NONE on success, any other integer on failure.
|
||||
* @error Invalid parameter number or calling from a non-native function.
|
||||
*/
|
||||
native GetNativeString(param, String:buffer[], maxlength, &bytes=0);
|
||||
|
||||
/**
|
||||
* Sets a string in a native parameter.
|
||||
* @note Output conditions are undefined on failure.
|
||||
*
|
||||
* @param param Parameter number, starting from 1.
|
||||
* @param source Source string to use.
|
||||
* @param maxlength Maximum number of bytes to write.
|
||||
* @param utf8 If false, string will not be written
|
||||
* with UTF8 safety.
|
||||
* @param bytes Optionally store the number of bytes written.
|
||||
* @return SP_ERROR_NONE on success, any other integer on failure.
|
||||
* @error Invalid parameter number or calling from a non-native function.
|
||||
*/
|
||||
native SetNativeString(param, const String:source[], maxlength, bool:utf8=true, &bytes=0);
|
||||
|
||||
/**
|
||||
* Gets a cell from a native parameter.
|
||||
*
|
||||
* @param param Parameter number, starting from 1.
|
||||
* @return Cell value at the parameter number.
|
||||
* @error Invalid parameter number or calling from a non-native function.
|
||||
*/
|
||||
native any:GetNativeCell(param);
|
||||
|
||||
/**
|
||||
* Gets a cell from a native parameter, by reference.
|
||||
*
|
||||
* @param param Parameter number, starting from 1.
|
||||
* @return Cell value at the parameter number.
|
||||
* @error Invalid parameter number or calling from a non-native function.
|
||||
*/
|
||||
native any:GetNativeCellRef(param);
|
||||
|
||||
/**
|
||||
* Sets a cell from a native parameter, by reference.
|
||||
*
|
||||
* @param param Parameter number, starting from 1.
|
||||
* @param value Cell value at the parameter number to set by reference.
|
||||
* @noreturn
|
||||
* @error Invalid parameter number or calling from a non-native function.
|
||||
*/
|
||||
native SetNativeCellRef(param, any:value);
|
||||
|
||||
/**
|
||||
* Gets an array from a native parameter (always by reference).
|
||||
*
|
||||
* @param param Parameter number, starting from 1.
|
||||
* @param local Local array to copy into.
|
||||
* @param size Maximum size of local array.
|
||||
* @return SP_ERROR_NONE on success, anything else on failure.
|
||||
* @error Invalid parameter number or calling from a non-native function.
|
||||
*/
|
||||
native GetNativeArray(param, any:local[], size);
|
||||
|
||||
/**
|
||||
* Copies a local array into a native parameter array (always by reference).
|
||||
*
|
||||
* @param param Parameter number, starting from 1.
|
||||
* @param local Local array to copy from.
|
||||
* @param size Size of the local array to copy.
|
||||
* @return SP_ERROR_NONE on success, anything else on failure.
|
||||
* @error Invalid parameter number or calling from a non-native function.
|
||||
*/
|
||||
native SetNativeArray(param, const any:local[], size);
|
||||
|
||||
/**
|
||||
* Formats a string using parameters from a native.
|
||||
*
|
||||
* @note All parameter indexes start at 1.
|
||||
* @note If the input and output buffers overlap, the contents
|
||||
* of the output buffer at the end is undefined.
|
||||
*
|
||||
* @param out_param Output parameter number to write to. If 0, out_string is used.
|
||||
* @param fmt_param Format parameter number. If 0, fmt_string is used.
|
||||
* @param vararg_param First variable parameter number.
|
||||
* @param out_len Output string buffer maximum length (always required).
|
||||
* @param written Optionally stores the number of bytes written.
|
||||
* @param out_string Output string buffer to use if out_param is not used.
|
||||
* @param fmt_string Format string to use if fmt_param is not used.
|
||||
* @return SP_ERROR_NONE on success, anything else on failure.
|
||||
*/
|
||||
native FormatNativeString(out_param,
|
||||
fmt_param,
|
||||
vararg_param,
|
||||
out_len,
|
||||
&written=0,
|
||||
String:out_string[]="",
|
||||
const String:fmt_string[]="");
|
||||
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _geoip_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _geoip_included
|
||||
|
||||
#include <core>
|
||||
|
||||
/**
|
||||
* @section IP addresses can contain ports, the ports will be stripped out.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets the two character country code from an IP address. (US, CA, etc)
|
||||
*
|
||||
* @param ip Ip to determine the country code.
|
||||
* @param ccode Destination string buffer to store the code.
|
||||
* @return True on success, false if no country found.
|
||||
*/
|
||||
native bool:GeoipCode2(const String:ip[], String:ccode[3]);
|
||||
|
||||
/**
|
||||
* Gets the three character country code from an IP address. (USA, CAN, etc)
|
||||
*
|
||||
* @param ip Ip to determine the country code.
|
||||
* @param ccode Destination string buffer to store the code.
|
||||
* @return True on success, false if no country found.
|
||||
*/
|
||||
native bool:GeoipCode3(const String:ip[], String:ccode[4]);
|
||||
|
||||
/**
|
||||
* Gets the full country name. (max length of output string is 45)
|
||||
*
|
||||
* @param ip Ip to determine the country code.
|
||||
* @param ccode Destination string buffer to store the country name.
|
||||
* @param len Maximum length of output string buffer.
|
||||
* @return True on success, false if no country found.
|
||||
*/
|
||||
native bool:GeoipCountry(const String:ip[], String:name[], maxlength);
|
||||
|
||||
/**
|
||||
* @endsection
|
||||
*/
|
||||
|
||||
/**
|
||||
* Do not edit below this line!
|
||||
*/
|
||||
public Extension:__ext_geoip =
|
||||
{
|
||||
name = "GeoIP",
|
||||
file = "geoip.ext",
|
||||
#if defined AUTOLOAD_EXTENSIONS
|
||||
autoload = 1,
|
||||
#else
|
||||
autoload = 0,
|
||||
#endif
|
||||
#if defined REQUIRE_EXTENSIONS
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined REQUIRE_EXTENSIONS
|
||||
public __ext_geoip_SetNTVOptional()
|
||||
{
|
||||
MarkNativeAsOptional("GeoipCode2");
|
||||
MarkNativeAsOptional("GeoipCode3");
|
||||
MarkNativeAsOptional("GeoipCountry");
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,544 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _halflife_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _halflife_included
|
||||
|
||||
#define SOURCE_SDK_UNKNOWN 0 /**< Could not determine the engine version */
|
||||
#define SOURCE_SDK_ORIGINAL 10 /**< Original Source engine (still used by "The Ship") */
|
||||
#define SOURCE_SDK_EPISODE1 20 /**< SDK+Engine released after Episode 1 */
|
||||
#define SOURCE_SDK_EPISODE2 30 /**< Engine released after Episode 2 (no SDK yet) */
|
||||
|
||||
#define MOTDPANEL_TYPE_TEXT 0 /**< Treat msg as plain text */
|
||||
#define MOTDPANEL_TYPE_INDEX 1 /**< Msg is auto determined by the engine */
|
||||
#define MOTDPANEL_TYPE_URL 2 /**< Treat msg as an URL link */
|
||||
#define MOTDPANEL_TYPE_FILE 3 /**< Treat msg as a filename to be openned */
|
||||
|
||||
enum DialogType
|
||||
{
|
||||
DialogType_Msg = 0, /**< just an on screen message */
|
||||
DialogType_Menu, /**< an options menu */
|
||||
DialogType_Text, /**< a richtext dialog */
|
||||
DialogType_Entry, /**< an entry box */
|
||||
DialogType_AskConnect /**< ask the client to connect to a specified IP */
|
||||
};
|
||||
|
||||
/**
|
||||
* Logs a generic message to the HL2 logs.
|
||||
*
|
||||
* @param format String format.
|
||||
* @param ... Format arguments.
|
||||
* @noreturn
|
||||
*/
|
||||
native LogToGame(const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Sets the seed value for the global Half-Life 2 Random Stream.
|
||||
*
|
||||
* @param seed Seed value.
|
||||
* @noreturn
|
||||
*/
|
||||
native SetRandomSeed(seed);
|
||||
|
||||
/**
|
||||
* Returns a random floating point number from the Half-Life 2 Random Stream.
|
||||
*
|
||||
* @param fMin Minimum random bound.
|
||||
* @param fMax Maximum random bound.
|
||||
* @return A random number between (inclusive) fMin and fMax.
|
||||
*/
|
||||
native Float:GetRandomFloat(Float:fMin=0.0, Float:fMax=1.0);
|
||||
|
||||
/**
|
||||
* Returns a random number from the Half-Life 2 Random Stream.
|
||||
*
|
||||
* @param nmin Minimum random bound.
|
||||
* @param nmax Maximum random bound.
|
||||
* @return A random number between (inclusive) nmin and nmax.
|
||||
*/
|
||||
native GetRandomInt(nmin, nmax);
|
||||
|
||||
/**
|
||||
* Returns whether a map is valid or not.
|
||||
*
|
||||
* @param Map name, excluding .bsp extension.
|
||||
* @return True if valid, false otherwise.
|
||||
*/
|
||||
native bool:IsMapValid(const String:map[]);
|
||||
|
||||
/**
|
||||
* Returns whether the server is dedicated.
|
||||
*
|
||||
* @return True if dedicated, false otherwise.
|
||||
*/
|
||||
native bool:IsDedicatedServer();
|
||||
|
||||
/**
|
||||
* Returns a high-precision time value for profiling the engine.
|
||||
*
|
||||
* @return A floating point time value.
|
||||
*/
|
||||
native Float:GetEngineTime();
|
||||
|
||||
/**
|
||||
* Returns the game time based on the game tick.
|
||||
*
|
||||
* @return Game tick time.
|
||||
*/
|
||||
native Float:GetGameTime();
|
||||
|
||||
/**
|
||||
* Returns the game description from the mod.
|
||||
*
|
||||
* @param buffer Buffer to store the description.
|
||||
* @param maxlength Maximum size of the buffer.
|
||||
* @param original If true, retrieves the original game description,
|
||||
* ignoring any potential hooks from plugins.
|
||||
* @return Number of bytes written to the buffer (UTF-8 safe).
|
||||
*/
|
||||
native GetGameDescription(String:buffer[], maxlength, bool:original=false);
|
||||
|
||||
/**
|
||||
* Returns the name of the game's directory.
|
||||
*
|
||||
* @param buffer Buffer to store the directory name.
|
||||
* @param maxlength Maximum size of the buffer.
|
||||
*
|
||||
* return Number of bytes written to the buffer (UTF-8 safe).
|
||||
*/
|
||||
native GetGameFolderName(String:buffer[], maxlength);
|
||||
|
||||
/**
|
||||
* Returns the current map name.
|
||||
*
|
||||
* @param buffer Buffer to store map name.
|
||||
* @param maxlength Maximum length of buffer.
|
||||
* @return Number of bytes written (UTF-8 safe).
|
||||
*/
|
||||
native GetCurrentMap(String:buffer[], maxlength);
|
||||
|
||||
/**
|
||||
* Precaches a given model.
|
||||
*
|
||||
* @param model Name of the model to precache.
|
||||
* @param preload If preload is true the file will be precached before level startup.
|
||||
* @return Returns the model index, 0 for error.
|
||||
*/
|
||||
native PrecacheModel(const String:model[], bool:preload=false);
|
||||
|
||||
/**
|
||||
* Precaches a given sentence file.
|
||||
*
|
||||
* @param file Name of the sentence file to precache.
|
||||
* @param preload If preload is true the file will be precached before level startup.
|
||||
* @return Returns a sentence file index.
|
||||
*/
|
||||
native PrecacheSentenceFile(const String:file[], bool:preload=false);
|
||||
|
||||
/**
|
||||
* Precaches a given decal.
|
||||
*
|
||||
* @param decal Name of the decal to precache.
|
||||
* @param preload If preload is true the file will be precached before level startup.
|
||||
* @return Returns a decal index.
|
||||
*/
|
||||
native PrecacheDecal(const String:decal[], bool:preload=false);
|
||||
|
||||
/**
|
||||
* Precaches a given generic file.
|
||||
*
|
||||
* @param generic Name of the generic file to precache.
|
||||
* @param preload If preload is true the file will be precached before level startup.
|
||||
* @return Returns a generic file index.
|
||||
*/
|
||||
native PrecacheGeneric(const String:generic[], bool:preload=false);
|
||||
|
||||
/**
|
||||
* Returns if a given model is precached.
|
||||
*
|
||||
* @param model Name of the model to check.
|
||||
* @return True if precached, false otherwise.
|
||||
*/
|
||||
native bool:IsModelPrecached(const String:model[]);
|
||||
|
||||
/**
|
||||
* Returns if a given decal is precached.
|
||||
*
|
||||
* @param decal Name of the decal to check.
|
||||
* @return True if precached, false otherwise.
|
||||
*/
|
||||
native bool:IsDecalPrecached(const String:decal[]);
|
||||
|
||||
/**
|
||||
* Returns if a given generic file is precached.
|
||||
*
|
||||
* @param decal Name of the generic file to check.
|
||||
* @return True if precached, false otherwise.
|
||||
*/
|
||||
native bool:IsGenericPrecached(const String:generic[]);
|
||||
|
||||
/**
|
||||
* Precaches a given sound.
|
||||
*
|
||||
* @param sound Name of the sound to precache.
|
||||
* @param preload If preload is true the file will be precached before level startup.
|
||||
* @return True if successfully precached, false otherwise.
|
||||
*/
|
||||
native bool:PrecacheSound(const String:sound[], bool:preload=false);
|
||||
|
||||
/**
|
||||
* Returns if a given sound is precached.
|
||||
*
|
||||
* @param sound Name of the sound to check.
|
||||
* @return True if precached, false otherwise.
|
||||
*/
|
||||
native bool:IsSoundPrecached(const String:sound[]);
|
||||
|
||||
/**
|
||||
* Creates different types of ingame messages.
|
||||
*
|
||||
* @param client Index of the client.
|
||||
* @param kv KeyValues handle to set the menu keys and options. (Check iserverplugin.h for more information).
|
||||
* @param type Message type to display ingame.
|
||||
* @noreturn
|
||||
* @error Invalid client index, or client not connected.
|
||||
*/
|
||||
native CreateDialog(client, Handle:kv, DialogType:type);
|
||||
|
||||
/**
|
||||
* Guesses the SDK version a mod was compiled against. If nothing
|
||||
* specific is known about the game, the engine version is used instead.
|
||||
*
|
||||
* The return values are guaranteed to increase chronologically (that is,
|
||||
* a later release will have a higher value).
|
||||
*
|
||||
* @return SOURCE_SDK version code.
|
||||
*/
|
||||
native GuessSDKVersion();
|
||||
|
||||
/**
|
||||
* Prints a message to a specific client in the chat area.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param format Formatting rules.
|
||||
* @param ... Variable number of format parameters.
|
||||
* @noreturn
|
||||
* @error If the client is not connected an error will be thrown.
|
||||
*/
|
||||
native PrintToChat(client, const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Prints a message to all clients in the chat area.
|
||||
*
|
||||
* @param format Formatting rules.
|
||||
* @param ... Variable number of format parameters.
|
||||
* @noreturn
|
||||
*/
|
||||
stock PrintToChatAll(const String:format[], any:...)
|
||||
{
|
||||
new maxClients = GetMaxClients();
|
||||
decl String:buffer[192];
|
||||
|
||||
for (new i = 1; i <= maxClients; i++)
|
||||
{
|
||||
if (IsClientInGame(i))
|
||||
{
|
||||
SetGlobalTransTarget(i);
|
||||
VFormat(buffer, sizeof(buffer), format, 2);
|
||||
PrintToChat(i, "%s", buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a message to a specific client in the center of the screen.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param format Formatting rules.
|
||||
* @param ... Variable number of format parameters.
|
||||
* @noreturn
|
||||
* @error If the client is not connected an error will be thrown.
|
||||
*/
|
||||
native PrintCenterText(client, const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Prints a message to all clients in the center of the screen.
|
||||
*
|
||||
* @param format Formatting rules.
|
||||
* @param ... Variable number of format parameters.
|
||||
* @noreturn
|
||||
*/
|
||||
stock PrintCenterTextAll(const String:format[], any:...)
|
||||
{
|
||||
new maxClients = GetMaxClients();
|
||||
decl String:buffer[192];
|
||||
|
||||
for (new i = 1; i <= maxClients; i++)
|
||||
{
|
||||
if (IsClientInGame(i))
|
||||
{
|
||||
SetGlobalTransTarget(i);
|
||||
VFormat(buffer, sizeof(buffer), format, 2);
|
||||
PrintCenterText(i, "%s", buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a message to a specific client with a hint box.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param format Formatting rules.
|
||||
* @param ... Variable number of format parameters.
|
||||
* @noreturn
|
||||
* @error If the client is not connected an error will be thrown.
|
||||
*/
|
||||
native PrintHintText(client, const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Prints a message to all clients with a hint box.
|
||||
*
|
||||
* @param format Formatting rules.
|
||||
* @param ... Variable number of format parameters.
|
||||
* @noreturn
|
||||
*/
|
||||
stock PrintHintTextToAll(const String:format[], any:...)
|
||||
{
|
||||
new maxClients = GetMaxClients();
|
||||
decl String:buffer[192];
|
||||
|
||||
for (new i = 1; i <= maxClients; i++)
|
||||
{
|
||||
if (IsClientInGame(i))
|
||||
{
|
||||
SetGlobalTransTarget(i);
|
||||
VFormat(buffer, sizeof(buffer), format, 2);
|
||||
PrintHintText(i, "%s", buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a VGUI panel to a specific client.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param name Panel type name (Check viewport_panel_names.h to see a list of
|
||||
* some panel names).
|
||||
* @param Kv KeyValues handle with all the data for the panel setup (Depends
|
||||
* on the panel type and may be unused).
|
||||
* @param show True to show the panel, or false to remove it from the client screen.
|
||||
* @noreturn
|
||||
* @error If the client is not connected an error will be thrown.
|
||||
*/
|
||||
native ShowVGUIPanel(client, const String:name[], Handle:Kv=INVALID_HANDLE, bool:show=true);
|
||||
|
||||
/**
|
||||
* Creates a HUD synchronization object. This object is used to automatically assign and
|
||||
* re-use channels for a set of messages.
|
||||
*
|
||||
* The HUD has a hardcoded number of channels (usually 6) for displaying
|
||||
* text. You can use any channel for any area of the screen. Text on
|
||||
* different channels can overlap, but text on the same channel will
|
||||
* erase the old text first. This overlapping and overwriting gets problematic.
|
||||
*
|
||||
* A HUD synchronization object automatically selects channels for you based on
|
||||
* the following heuristics:
|
||||
* - If channel X was last used by the object, and hasn't been modified again,
|
||||
* channel X gets re-used.
|
||||
* - Otherwise, a new channel is chosen based on the least-recently-used channel.
|
||||
*
|
||||
* This ensures that if you display text on a sync object, that the previous text
|
||||
* displayed on it will always be cleared first. This is because your new text
|
||||
* will either overwrite the old text on the same channel, or because another
|
||||
* channel has already erased your text.
|
||||
*
|
||||
* Note that messages can still overlap if they are on different synchronization
|
||||
* objects, or they are displayed to manual channels.
|
||||
*
|
||||
* These are particularly useful for displaying repeating or refreshing HUD text, in
|
||||
* addition to displaying multiple message sets in one area of the screen (for example,
|
||||
* center-say messages that may pop up randomly that you don't want to overlap each
|
||||
* other).
|
||||
*
|
||||
* @return New HUD synchronization object.
|
||||
* The Handle can be closed with CloseHandle().
|
||||
* If HUD text is not supported on this mod, then
|
||||
* INVALID_HANDLE is returned.
|
||||
*/
|
||||
native Handle:CreateHudSynchronizer();
|
||||
|
||||
/**
|
||||
* Sets the HUD parameters for drawing text. These parameters are stored
|
||||
* globally, although nothing other than this function and SetHudTextParamsEx
|
||||
* modify them.
|
||||
*
|
||||
* You must call this function before drawing text. If you are drawing
|
||||
* text to multiple clients, you can set the parameters once, since
|
||||
* they won't be modified. However, as soon as you pass control back
|
||||
* to other plugins, you must reset the parameters next time you draw.
|
||||
*
|
||||
* @param x x coordinate, from 0 to 1. -1.0 is the center.
|
||||
* @param y y coordinate, from 0 to 1. -1.0 is the center.
|
||||
* @param holdTime Number of seconds to hold the text.
|
||||
* @param r Red color value.
|
||||
* @param g Green color value.
|
||||
* @param b Blue color value.
|
||||
* @param a Alpha transparency value.
|
||||
* @param effect 0/1 causes the text to fade in and fade out.
|
||||
* 2 causes the text to flash[?].
|
||||
* @param fxTime Duration of chosen effect (may not apply to all effects).
|
||||
* @param fadeIn Number of seconds to spend fading in.
|
||||
* @param fadeOut Number of seconds to spend fading out.
|
||||
* @noreturn
|
||||
*/
|
||||
native SetHudTextParams(Float:x, Float:y, Float:holdTime, r, g, b, a, effect = 0,
|
||||
Float:fxTime=6.0, Float:fadeIn=0.1, Float:fadeOut=0.2);
|
||||
|
||||
/**
|
||||
* Sets the HUD parameters for drawing text. These parameters are stored
|
||||
* globally, although nothing other than this function and SetHudTextParams
|
||||
* modify them.
|
||||
*
|
||||
* This is the same as SetHudTextParams(), except it lets you set the alternate
|
||||
* color for when effects require it.
|
||||
*
|
||||
* @param x x coordinate, from 0 to 1. -1.0 is the center.
|
||||
* @param y y coordinate, from 0 to 1. -1.0 is the center.
|
||||
* @param holdTime Number of seconds to hold the text.
|
||||
* @param color1 First color set, array values being [red, green, blue, alpha]
|
||||
* @param color2 Second color set, array values being [red, green, blue, alpha]
|
||||
* @param effect 0/1 causes the text to fade in and fade out.
|
||||
* 2 causes the text to flash[?].
|
||||
* @param fxTime Duration of chosen effect (may not apply to all effects).
|
||||
* @param fadeIn Number of seconds to spend fading in.
|
||||
* @param fadeOut Number of seconds to spend fading out.
|
||||
* @noreturn
|
||||
*/
|
||||
native SetHudTextParamsEx(Float:x, Float:y, Float:holdTime, color1[4],
|
||||
color2[4]={255,255,255,0}, effect = 0, Float:fxTime=6.0,
|
||||
Float:fadeIn=0.1, Float:fadeOut=0.2);
|
||||
|
||||
/**
|
||||
* Shows a synchronized HUD message to a client.
|
||||
*
|
||||
* As of this writing, only TF, HL2MP, and SourceForts support HUD Text.
|
||||
*
|
||||
* @param client Client index to send the message to.
|
||||
* @param sync Synchronization object.
|
||||
* @param message Message text or formatting rules.
|
||||
* @param ... Message formatting parameters.
|
||||
* @return -1 on failure, anything else on success.
|
||||
* This function fails if the mod does not support it.
|
||||
* @error Client not in-game, or sync object not valid.
|
||||
*/
|
||||
native ShowSyncHudText(client, Handle:sync, const String:message[], any:...);
|
||||
|
||||
/**
|
||||
* Clears the text on a synchronized HUD channel.
|
||||
*
|
||||
* This is not the same as sending "" because it guarantees that it won't
|
||||
* overwrite text on another channel. For example, consider the scenario:
|
||||
*
|
||||
* 1. Your synchronized message goes to channel 3.
|
||||
* 2. Someone else's non-synchronized message goes to channel 3.
|
||||
*
|
||||
* If you were to simply send "" on your synchronized message,
|
||||
* then someone else's text could be overwritten.
|
||||
*
|
||||
* @param client Client index to send the message to.
|
||||
* @param sync Synchronization object.
|
||||
* @noreturn
|
||||
* @error Client not in-game, or sync object not valid.
|
||||
*/
|
||||
native ClearSyncHud(client, Handle:sync);
|
||||
|
||||
/**
|
||||
* Shows a HUD message to a client on the given channel.
|
||||
*
|
||||
* As of this writing, only TF, HL2MP, and SourceForts support HUD Text.
|
||||
*
|
||||
* @param client Client index to send the message to.
|
||||
* @param channel A channel number.
|
||||
* If -1, then a channel will automatically be selected
|
||||
* based on the least-recently-used channel. If the
|
||||
* channel is any other number, it will be modulo'd with
|
||||
* the channel count to get a final channel number.
|
||||
* @param message Message text or formatting rules.
|
||||
* @param ... Message formatting parameters.
|
||||
* @return -1 on failure (lack of mod support).
|
||||
* Any other return value is the channel number that was
|
||||
* used to render the text.
|
||||
*/
|
||||
native ShowHudText(client, channel, const String:message[], any:...);
|
||||
|
||||
/**
|
||||
* Shows a MOTD panel to a specific client.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param title Title of the panel (printed on the top border of the window).
|
||||
* @param msg Contents of the panel, it can be treated as an url, filename or plain text
|
||||
* depending on the type parameter (WARNING: msg has to be 192 bytes maximum!)
|
||||
* @param type Determines the way to treat the message body of the panel.
|
||||
* @noreturn
|
||||
* @error If the client is not connected an error will be thrown.
|
||||
*/
|
||||
stock ShowMOTDPanel(client, const String:title[], const String:msg[], type=MOTDPANEL_TYPE_INDEX)
|
||||
{
|
||||
decl String:num[3];
|
||||
new Handle:Kv = CreateKeyValues("data");
|
||||
IntToString(type, num, sizeof(num));
|
||||
|
||||
KvSetString(Kv, "title", title);
|
||||
KvSetString(Kv, "type", num);
|
||||
KvSetString(Kv, "msg", msg);
|
||||
ShowVGUIPanel(client, "info", Kv);
|
||||
CloseHandle(Kv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a panel asking the client to connect to a specified IP.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param time Duration to hold the panel on the client's screen.
|
||||
* @param ip Destionation IP.
|
||||
* @noreturn
|
||||
*/
|
||||
stock DisplayAskConnectBox(client, Float:time, const String:ip[])
|
||||
{
|
||||
new Handle:Kv = CreateKeyValues("data");
|
||||
KvSetFloat(Kv, "time", time);
|
||||
KvSetString(Kv, "title", ip);
|
||||
CreateDialog(client, Kv, DialogType_AskConnect);
|
||||
CloseHandle(Kv);
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _handles_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _handles_included
|
||||
|
||||
/**
|
||||
* Handle helper macros.
|
||||
*/
|
||||
enum Handle
|
||||
{
|
||||
INVALID_HANDLE = 0,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Closes a Handle. If the handle has multiple copies open,
|
||||
* it is not destroyed unless all copies are closed.
|
||||
*
|
||||
* @note Closing a Handle has a different meaning for each Handle type. Make
|
||||
* sure you read the documentation on whatever provided the Handle.
|
||||
*
|
||||
* @param hndl Handle to close.
|
||||
* @return True if successful, false if not closeable.
|
||||
* @error Invalid handles will cause a run time error.
|
||||
*/
|
||||
native bool:CloseHandle(Handle:hndl);
|
||||
|
||||
/**
|
||||
* Clones a Handle. When passing handles in between plugins, caching handles
|
||||
* can result in accidental invalidation when one plugin releases the Handle, or is its owner
|
||||
* is unloaded from memory. To prevent this, the Handle may be "cloned" with a new owner.
|
||||
*
|
||||
* @note Usually, you will be cloning Handles for other plugins. This means that if you clone
|
||||
* the Handle without specifying the new owner, it will assume the identity of your original calling
|
||||
* plugin, which is not very useful. You should either specify that the receiving plugin should
|
||||
* clone the handle on its own, or you should explicitly clone the Handle using the receiving plugin's
|
||||
* identity Handle.
|
||||
*
|
||||
* @param hndl Handle to clone/duplicate.
|
||||
* @param plugin Optional Handle to another plugin to mark as the new owner.
|
||||
* If no owner is passed, the owner becomes the calling plugin.
|
||||
* @return Handle on success, INVALID_HANDLE if not cloneable.
|
||||
* @error Invalid handles will cause a run time error.
|
||||
*/
|
||||
native Handle:CloneHandle(Handle:hndl, Handle:plugin=INVALID_HANDLE);
|
||||
|
||||
/**
|
||||
* Do not use this function. Returns if a Handle and its contents
|
||||
* are readable, whereas INVALID_HANDLE only checks for the absence
|
||||
* of a Handle.
|
||||
*
|
||||
* This function is intended only for tests where the validity of a
|
||||
* Handle can absolutely not be known.
|
||||
*
|
||||
* Do not use this to check the return values of functions, or to
|
||||
* check if timers should be closed (except in very rare cases).
|
||||
* This function is for very specific usage and using it for general
|
||||
* purpose routines can and will hide very subtle bugs.
|
||||
*
|
||||
* @param hndl Handle to test for validity.
|
||||
* @return True if handle is valid, false otherwise.
|
||||
*/
|
||||
#pragma deprecated Do not use this function.
|
||||
native bool:IsValidHandle(Handle:hndl);
|
||||
@@ -0,0 +1,294 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _helpers_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _helpers_included
|
||||
|
||||
/**
|
||||
* Formats a user's info as log text. This is usually not needed because
|
||||
* %L can be used to auto-format client information into a string.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param buffer Buffer for text.
|
||||
* @param maxlength Maximum length of text.
|
||||
*/
|
||||
stock FormatUserLogText(client, String:buffer[], maxlength)
|
||||
{
|
||||
decl String:auth[32];
|
||||
decl String:name[40];
|
||||
|
||||
new userid = GetClientUserId(client);
|
||||
if (!GetClientAuthString(client, auth, sizeof(auth)))
|
||||
{
|
||||
strcopy(auth, sizeof(auth), "UNKNOWN");
|
||||
}
|
||||
if (!GetClientName(client, name, sizeof(name)))
|
||||
{
|
||||
strcopy(name, sizeof(name), "UNKNOWN");
|
||||
}
|
||||
|
||||
/** Currently, no team stuff ... */
|
||||
|
||||
Format(buffer, maxlength, "\"%s<%d><%s><>\"", name, userid, auth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns plugin handle from plugin filename.
|
||||
*
|
||||
* @param filename Filename of the plugin to search for.
|
||||
* @return Handle to plugin if found, INVALID_HANDLE otherwise.
|
||||
*/
|
||||
stock Handle:FindPluginByFile(const String:filename[])
|
||||
{
|
||||
decl String:buffer[256];
|
||||
|
||||
new Handle:iter = GetPluginIterator();
|
||||
new Handle:pl;
|
||||
|
||||
while (MorePlugins(iter))
|
||||
{
|
||||
pl = ReadPlugin(iter);
|
||||
|
||||
GetPluginFilename(pl, buffer, sizeof(buffer));
|
||||
if (strcmp(buffer, filename, false) == 0)
|
||||
{
|
||||
CloseHandle(iter);
|
||||
return pl;
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(iter);
|
||||
|
||||
return INVALID_HANDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use FindTarget() or ProcessTargetString().
|
||||
*/
|
||||
#pragma deprecated Use FindTarget() or ProcessTargetString()
|
||||
stock SearchForClients(const String:pattern[], clients[], maxClients)
|
||||
{
|
||||
new maxclients = GetMaxClients();
|
||||
new total = 0;
|
||||
|
||||
if (maxClients == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pattern[0] == '#')
|
||||
{
|
||||
new input = StringToInt(pattern[1]);
|
||||
if (!input)
|
||||
{
|
||||
decl String:name[65]
|
||||
for (new i=1; i<=maxclients; i++)
|
||||
{
|
||||
if (!IsClientInGame(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
GetClientName(i, name, sizeof(name));
|
||||
if (strcmp(name, pattern, false) == 0)
|
||||
{
|
||||
clients[0] = i;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
new client = GetClientOfUserId(input);
|
||||
if (client)
|
||||
{
|
||||
clients[0] = client;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decl String:name[65]
|
||||
for (new i=1; i<=maxclients; i++)
|
||||
{
|
||||
if (!IsClientInGame(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
GetClientName(i, name, sizeof(name));
|
||||
if (StrContains(name, pattern, false) != -1)
|
||||
{
|
||||
clients[total++] = i;
|
||||
if (total >= maxClients)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps ProcessTargetString() and handles producing error messages for
|
||||
* bad targets.
|
||||
*
|
||||
* @param client Client who issued command
|
||||
* @param target Client's target argument
|
||||
* @param nobots Optional. Set to true if bots should NOT be targetted
|
||||
* @param immunity Optional. Set to false to ignore target immunity.
|
||||
* @return Index of target client, or -1 on error.
|
||||
*/
|
||||
stock FindTarget(client, const String:target[], bool:nobots = false, bool:immunity = true)
|
||||
{
|
||||
decl String:target_name[MAX_TARGET_LENGTH];
|
||||
decl target_list[1], target_count, bool:tn_is_ml;
|
||||
|
||||
new flags = COMMAND_FILTER_NO_MULTI;
|
||||
if (nobots)
|
||||
{
|
||||
flags |= COMMAND_FILTER_NO_BOTS;
|
||||
}
|
||||
if (!immunity)
|
||||
{
|
||||
flags |= COMMAND_FILTER_NO_IMMUNITY;
|
||||
}
|
||||
|
||||
if ((target_count = ProcessTargetString(
|
||||
target,
|
||||
client,
|
||||
target_list,
|
||||
1,
|
||||
flags,
|
||||
target_name,
|
||||
sizeof(target_name),
|
||||
tn_is_ml)) > 0)
|
||||
{
|
||||
return target_list[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
ReplyToTargetError(client, target_count);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is no longer supported. It has been replaced with ReadMapList(),
|
||||
* which uses a more unified caching and configuration mechanism. This function also
|
||||
* has a bug where if the cvar contents changes, the fileTime change won't be recognized.
|
||||
*
|
||||
* Loads a specified array with maps. The maps will be either loaded from mapcyclefile, or if supplied
|
||||
* a cvar containing a file name. If the file in the cvar is bad, it will use mapcyclefile. The fileTime
|
||||
* parameter is used to store a timestamp of the file. If specified, the file will only be reloaded if it
|
||||
* has changed.
|
||||
*
|
||||
* @param array Valid array handle, should be created with CreateArray(33) or larger.
|
||||
* @param fileTime Variable containing the "last changed" time of the file. Used to avoid needless reloading.
|
||||
* @param fileCvar CVAR set to the file to be loaded. Optional.
|
||||
* @return Number of maps loaded or 0 if in error.
|
||||
*/
|
||||
#pragma deprecated Use ReadMapList() instead.
|
||||
stock LoadMaps(Handle:array, &fileTime = 0, Handle:fileCvar = INVALID_HANDLE)
|
||||
{
|
||||
decl String:mapPath[256], String:mapFile[64];
|
||||
new bool:fileFound = false;
|
||||
|
||||
if (fileCvar != INVALID_HANDLE)
|
||||
{
|
||||
GetConVarString(fileCvar, mapFile, 64);
|
||||
BuildPath(Path_SM, mapPath, sizeof(mapPath), mapFile);
|
||||
fileFound = FileExists(mapPath);
|
||||
}
|
||||
|
||||
if (!fileFound)
|
||||
{
|
||||
new Handle:mapCycleFile = FindConVar("mapcyclefile");
|
||||
GetConVarString(mapCycleFile, mapPath, sizeof(mapPath));
|
||||
fileFound = FileExists(mapPath);
|
||||
}
|
||||
|
||||
if (!fileFound)
|
||||
{
|
||||
LogError("Failed to find a file to load maps from. No maps loaded.");
|
||||
ClearArray(array);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If the file hasn't changed, there's no reason to reload
|
||||
// all of the maps.
|
||||
new newTime = GetFileTime(mapPath, FileTime_LastChange);
|
||||
if (fileTime == newTime)
|
||||
{
|
||||
return GetArraySize(array);
|
||||
}
|
||||
|
||||
fileTime = newTime;
|
||||
|
||||
ClearArray(array);
|
||||
|
||||
new Handle:file = OpenFile(mapPath, "rt");
|
||||
if (file == INVALID_HANDLE)
|
||||
{
|
||||
LogError("Could not open file: %s", mapPath);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LogMessage("Loading maps from file: %s", mapPath);
|
||||
|
||||
decl String:buffer[64], len;
|
||||
while (!IsEndOfFile(file) && ReadFileLine(file, buffer, sizeof(buffer)))
|
||||
{
|
||||
TrimString(buffer);
|
||||
|
||||
if ((len = StrContains(buffer, ".bsp", false)) != -1)
|
||||
{
|
||||
buffer[len] = '\0';
|
||||
}
|
||||
|
||||
if (buffer[0] == '\0' || !IsValidConVarChar(buffer[0]) || !IsMapValid(buffer))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FindStringInArray(array, buffer) != -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
PushArrayString(array, buffer);
|
||||
}
|
||||
|
||||
CloseHandle(file);
|
||||
return GetArraySize(array);
|
||||
}
|
||||
@@ -0,0 +1,429 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _keyvalues_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _keyvalues_included
|
||||
|
||||
/**
|
||||
* KeyValue data value types
|
||||
*/
|
||||
enum KvDataTypes
|
||||
{
|
||||
KvData_None = 0, /**< Type could not be identified, or no type */
|
||||
KvData_String, /**< String value */
|
||||
KvData_Int, /**< Integer value */
|
||||
KvData_Float, /**< Floating point value */
|
||||
KvData_Ptr, /**< Pointer value (sometimes called "long") */
|
||||
KvData_WString, /**< Wide string value */
|
||||
KvData_Color, /**< Color value */
|
||||
KvData_UInt64, /**< Large integer value */
|
||||
/* --- */
|
||||
KvData_NUMTYPES,
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new KeyValues structure. The Handle must always be closed.
|
||||
*
|
||||
* @param name Name of the root section.
|
||||
* @param firstKey If non-empty, specifies the first key value.
|
||||
* @param firstValue If firstKey is non-empty, specifies the first key's value.
|
||||
* @return A Handle to a new KeyValues structure.
|
||||
*/
|
||||
native Handle:CreateKeyValues(const String:name[], const String:firstkey[]="", const String:firstValue[]="");
|
||||
|
||||
/**
|
||||
* Sets a string value of a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key, or NULL_STRING.
|
||||
* @param value String value.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvSetString(Handle:kv, const String:key[], const String:value[]);
|
||||
|
||||
/**
|
||||
* Sets an integer value of a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key, or NULL_STRING.
|
||||
* @param value Value number.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvSetNum(Handle:kv, const String:key[], value);
|
||||
|
||||
/**
|
||||
* Sets a large integer value of a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key, or NULL_STRING.
|
||||
* @param value Large integer value (0=High bits, 1=Low bits)
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvSetUInt64(Handle:kv, const String:key[], const value[2]);
|
||||
|
||||
/**
|
||||
* Sets a floating point value of a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key, or NULL_STRING.
|
||||
* @param value Floating point value.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvSetFloat(Handle:kv, const String:key[], Float:value);
|
||||
|
||||
/**
|
||||
* Sets a set of color values of a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key, or NULL_STRING.
|
||||
* @param r Red value.
|
||||
* @param g Green value.
|
||||
* @param b Blue value.
|
||||
* @param a Alpha value.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvSetColor(Handle:kv, const String:key[], r, g, b, a=0);
|
||||
|
||||
/**
|
||||
* Sets a vector value of a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key, or NULL_STRING.
|
||||
* @param vec Vector value.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvSetVector(Handle:kv, const String:key[], const Float:vec[3]);
|
||||
|
||||
/**
|
||||
* Retrieves a string value from a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key, or NULL_STRING.
|
||||
* @param value Buffer to store key value in.
|
||||
* @param maxlength Maximum length of the value buffer.
|
||||
* @param defvalue Optional default value to use if the key is not found.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvGetString(Handle:kv, const String:key[], String:value[], maxlength, const String:defvalue[]="");
|
||||
|
||||
/**
|
||||
* Retrieves an integer value from a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key, or NULL_STRING.
|
||||
* @param defvalue Optional default value to use if the key is not found.
|
||||
* @return Integer value of the key.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvGetNum(Handle:kv, const String:key[], defvalue=0);
|
||||
|
||||
/**
|
||||
* Retrieves a floating point value from a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key, or NULL_STRING.
|
||||
* @param defvalue Optional default value to use if the key is not found.
|
||||
* @return Floating point value of the key.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native Float:KvGetFloat(Handle:kv, const String:key[], Float:defvalue=0.0);
|
||||
|
||||
/**
|
||||
* Retrieves a set of color values from a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key, or NULL_STRING.
|
||||
* @param r Red value, set by reference.
|
||||
* @param g Green value, set by reference.
|
||||
* @param b Blue value, set by reference.
|
||||
* @param a Alpha value, set by reference.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvGetColor(Handle:kv, const String:key[], &r, &g, &b, &a);
|
||||
|
||||
/**
|
||||
* Retrieves a large integer value from a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key, or NULL_STRING.
|
||||
* @param value Array to represent the large integer.
|
||||
* @param defvalue Optional default value to use if the key is not found.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvGetUInt64(Handle:kv, const String:key[], value[2], defvalue[2]={0,0});
|
||||
|
||||
/**
|
||||
* Retrieves a vector value from a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key, or NULL_STRING.
|
||||
* @param vec Destination vector to store the value in.
|
||||
* @param defvalue Optional default value to use if the key is not found.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvGetVector(Handle:kv, const String:key[], Float:vec[3], const Float:defvalue[3]={0.0, 0.0, 0.0});
|
||||
|
||||
/**
|
||||
* Sets the current position in the KeyValues tree to the given key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key.
|
||||
* @param create If true, and the key does not exist, it will be created.
|
||||
* @return True if the key exists, false if it does not and was not created.
|
||||
*/
|
||||
native bool:KvJumpToKey(Handle:kv, const String:key[], bool:create=false);
|
||||
|
||||
/**
|
||||
* Sets the current position in the KeyValues tree to the given key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param id KeyValues id.
|
||||
* @return True if the key exists, false if it does not.
|
||||
*/
|
||||
native bool:KvJumpToKeySymbol(Handle:kv, id);
|
||||
|
||||
/**
|
||||
* Sets the current position in the KeyValues tree to the first sub key.
|
||||
* This native adds to the internal traversal stack.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param keyOnly If false, non-keys will be traversed (values).
|
||||
* @return True on success, false if there was no first sub key.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:KvGotoFirstSubKey(Handle:kv, bool:keyOnly=true);
|
||||
|
||||
/**
|
||||
* Sets the current position in the KeyValues tree to the next sub key.
|
||||
* This native does NOT add to the internal traversal stack, and thus
|
||||
* KvGoBack() is not needed for each successive call to this function.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param keyOnly If false, non-keys will be traversed (values).
|
||||
* @return True on success, false if there was no next sub key.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:KvGotoNextKey(Handle:kv, bool:keyOnly=true);
|
||||
|
||||
/**
|
||||
* Saves the current position in the traversal stack onto the traversal
|
||||
* stack. This can be useful if you wish to use KvGotoNextKey() and
|
||||
* have the previous key saved for backwards traversal.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvSavePosition(Handle:kv);
|
||||
|
||||
/**
|
||||
* Removes the given key from the current position.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key.
|
||||
* @return True on success, false if key did not exist.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:KvDeleteKey(Handle:kv, const String:key[]);
|
||||
|
||||
/**
|
||||
* Removes the current sub-key and attempts to set the position
|
||||
* to the sub-key after the removed one. If no such sub-key exists,
|
||||
* the position will be the parent key in the traversal stack.
|
||||
* Given the sub-key having position "N" in the traversal stack, the
|
||||
* removal will always take place from position "N-1."
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @return 1 if removal succeeded and there was another key.
|
||||
* 0 if the current node was not contained in the
|
||||
* previous node, or no previous node exists.
|
||||
* -1 if removal succeeded and there were no more keys,
|
||||
* thus the state is as if KvGoBack() was called.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvDeleteThis(Handle:kv);
|
||||
|
||||
/**
|
||||
* Jumps back to the previous position. Returns false if there are no
|
||||
* previous positions (i.e., at the root node). This should be called
|
||||
* once for each successful Jump call, in order to return to the top node.
|
||||
* This function pops one node off the internal traversal stack.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @return True on success, false if there is no higher node.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:KvGoBack(Handle:kv);
|
||||
|
||||
/**
|
||||
* Sets the position back to the top node, emptying the entire node
|
||||
* traversal history. This can be used instead of looping KvGoBack()
|
||||
* if recursive iteration is not important.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvRewind(Handle:kv);
|
||||
|
||||
/**
|
||||
* Retrieves the current section name.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param section Buffer to store the section name.
|
||||
* @param maxlength Maximum length of the name buffer.
|
||||
* @return True on success, false on failure.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:KvGetSectionName(Handle:kv, String:section[], maxlength);
|
||||
|
||||
/**
|
||||
* Sets the current section name.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param section Section name.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvSetSectionName(Handle:kv, const String:section[]);
|
||||
|
||||
/**
|
||||
* Returns the data type at a key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Key name.
|
||||
* @return KvDataType value of the key.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvDataTypes:KvGetDataType(Handle:kv, const String:key[]);
|
||||
|
||||
/**
|
||||
* Converts a KeyValues tree to a file. The tree is dumped
|
||||
* from the current position.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param file File to dump write to.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:KeyValuesToFile(Handle:kv, const String:file[]);
|
||||
|
||||
/**
|
||||
* Converts a file to a KeyValues tree. The file is read into
|
||||
* the current position of the tree.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param file File to read from.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:FileToKeyValues(Handle:kv, const String:file[]);
|
||||
|
||||
/**
|
||||
* Sets whether or not the KeyValues parser will read escape sequences.
|
||||
* For example, \n would be read as a literal newline. This defaults
|
||||
* to false for new KeyValues structures.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param useEscapes Whether or not to read escape sequences.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvSetEscapeSequences(Handle:kv, bool:useEscapes);
|
||||
|
||||
/**
|
||||
* Returns the position in the jump stack; I.e. the number of calls
|
||||
* required for KvGoBack to return to the root node. If at the root node,
|
||||
* 0 is returned.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @return Number of non-root nodes in the jump stack.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvNodesInStack(Handle:kv);
|
||||
|
||||
/**
|
||||
* Makes a new copy of all subkeys in the origin KeyValues to
|
||||
* the destination KeyValues.
|
||||
* NOTE: All KeyValues are processed from the current location not the root one.
|
||||
*
|
||||
* @param origin Origin KeyValues Handle.
|
||||
* @param dest Destination KeyValues Handlee.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvCopySubkeys(Handle:origin, Handle:dest);
|
||||
|
||||
/**
|
||||
* Finds a KeyValues name by id.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param id KeyValues id.
|
||||
* @param name Buffer to store the name.
|
||||
* @param maxlength Maximum length of the value buffer.
|
||||
* @return True on success, false if id not found.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:KvFindKeyById(Handle:kv, id, String:name[], maxlength);
|
||||
|
||||
/**
|
||||
* Finds a KeyValues id inside a KeyValues tree.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Key name.
|
||||
* @param id Id of the found KeyValue.
|
||||
* @return True on success, false if key not found.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:KvGetNameSymbol(Handle:kv, const String:key[], &id);
|
||||
|
||||
/**
|
||||
* Retrieves the current section id.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param id Id of the current section.
|
||||
* @return True on success, false on failure.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:KvGetSectionSymbol(Handle:kv, &id);
|
||||
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _lang_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _lang_included
|
||||
|
||||
#define LANG_SERVER 0 /**< Translate using the server's language */
|
||||
|
||||
/**
|
||||
* Loads a translation file for the plugin calling this native.
|
||||
* If no extension is specified, .txt is assumed.
|
||||
*
|
||||
* @param path Translation file.
|
||||
* @noreturn
|
||||
*/
|
||||
native LoadTranslations(const String:file[]);
|
||||
|
||||
/**
|
||||
* Sets the global language target. This is useful for creating functions
|
||||
* that will be compatible with the %t format specifier. Note that invalid
|
||||
* indexes can be specified but the error will occur during translation,
|
||||
* not during this function call.
|
||||
*
|
||||
* @param client Client index or LANG_SERVER.
|
||||
* @noreturn
|
||||
*/
|
||||
native SetGlobalTransTarget(client);
|
||||
|
||||
/**
|
||||
* Retrieves the language number of a client.
|
||||
* Currently this simply returns the server language index.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @return Language number client is using.
|
||||
* @error Invalid client index or client not in game.
|
||||
*/
|
||||
native GetClientLanguage(client);
|
||||
|
||||
/**
|
||||
* Retrieves the server's language.
|
||||
*
|
||||
* @return Language number server is using.
|
||||
*/
|
||||
native GetServerLanguage();
|
||||
|
||||
/**
|
||||
* Returns the number of languages known in languages.cfg.
|
||||
*
|
||||
* @return Language count.
|
||||
*/
|
||||
native GetLanguageCount();
|
||||
|
||||
/**
|
||||
* Retrieves info about a given language number.
|
||||
*
|
||||
* @param language Language number.
|
||||
* @param code Language code buffer (2-3 characters usually).
|
||||
* @param codeLen Maximum length of the language code buffer.
|
||||
* @param name Language name buffer.
|
||||
* @param nameLen Maximum length of the language name buffer.
|
||||
* @noreturn
|
||||
* @error Invalid language number.
|
||||
*/
|
||||
native GetLanguageInfo(language, String:code[]="", codeLen=0, String:name[]="", nameLen=0);
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _sm_logging_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _sm_logging_included
|
||||
|
||||
/**
|
||||
* Logs a plugin message to the SourceMod logs. The log message will be
|
||||
* prefixed by the plugin's logtag (filename).
|
||||
*
|
||||
* @param format String format.
|
||||
* @param ... Format arguments.
|
||||
* @noreturn
|
||||
*/
|
||||
native LogMessage(const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Logs a message to the SourceMod logs without any plugin logtag. This is
|
||||
* useful for re-routing messages from other plugins, for example, messages
|
||||
* from LogAction().
|
||||
*
|
||||
* @param format String format.
|
||||
* @param ... Format arguments.
|
||||
* @noreturn
|
||||
*/
|
||||
native LogMessageEx(const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Logs a message to any file. The log message will be in the normal
|
||||
* SourceMod format, with the plugin logtag prepended.
|
||||
*
|
||||
* @param file File to write the log message in.
|
||||
* @param format String format.
|
||||
* @param ... Format arguments.
|
||||
* @noreturn
|
||||
* @error File could not be opened/written.
|
||||
*/
|
||||
native LogToFile(const String:file[], const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Same as LogToFile(), except no plugin logtag is prepended.
|
||||
*
|
||||
* @param file File to write the log message in.
|
||||
* @param format String format.
|
||||
* @param ... Format arguments.
|
||||
* @noreturn
|
||||
* @error File could not be opened/written.
|
||||
*/
|
||||
native LogToFileEx(const String:file[], const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Logs an action from a command or event whereby interception and routing may
|
||||
* be important. This is intended to be a logging version of ShowActivity().
|
||||
*
|
||||
* @param client Client performing the action, 0 for server, or -1 if not
|
||||
* applicable.
|
||||
* @param target Client being targetted, or -1 if not applicable.
|
||||
* @param message Message format.
|
||||
* @param ... Message formatting parameters.
|
||||
* @noreturn
|
||||
*/
|
||||
native LogAction(client, target, const String:message[], any:...);
|
||||
|
||||
/**
|
||||
* Logs a plugin error message to the SourceMod logs.
|
||||
*
|
||||
* @param format String format.
|
||||
* @param ... Format arguments.
|
||||
* @noreturn
|
||||
*/
|
||||
native LogError(const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Called when an action is going to be logged.
|
||||
*
|
||||
* @param source Handle to the object logging the action, or INVALID_HANDLE
|
||||
* if Core is logging the action.
|
||||
* @param ident Type of object logging the action (plugin, ext, or core).
|
||||
* @param client Client the action is from; 0 for server, -1 if not applicable.
|
||||
* @param target Client the action is targetting, or -1 if not applicable.
|
||||
* @param message Message that is being logged.
|
||||
* @return Plugin_Continue will cause Core to defaulty log the message.
|
||||
* Plugin_Handled will stop Core from logging the message.
|
||||
* Plugin_Stop is the same as Handled, but prevents any other
|
||||
* plugins from handling the message.
|
||||
*/
|
||||
forward Action:OnLogAction(Handle:source,
|
||||
Identity:ident,
|
||||
client,
|
||||
target,
|
||||
const String:message[]);
|
||||
|
||||
/**
|
||||
* Called when a game log message is received.
|
||||
*
|
||||
* Any Log*() functions called within this callback will not recursively
|
||||
* pass through. That is, they will log directly, bypassing this callback.
|
||||
*
|
||||
* Note that this does not capture log messages from the engine. It only
|
||||
* captures log messages being sent from the game/mod itself.
|
||||
*
|
||||
* @param message Message contents.
|
||||
* @return Plugin_Handled or Plugin_Stop will prevent the message
|
||||
* from being written to the log file.
|
||||
*/
|
||||
functag GameLogHook Action:public(const String:message[]);
|
||||
|
||||
/**
|
||||
* Adds a game log hook.
|
||||
*
|
||||
* @param hook Hook function.
|
||||
* @noreturn
|
||||
*/
|
||||
native AddGameLogHook(GameLogHook:hook);
|
||||
|
||||
/**
|
||||
* Removes a game log hook.
|
||||
*
|
||||
* @param hook Hook function.
|
||||
* @noreturn
|
||||
*/
|
||||
native RemoveGameLogHook(GameLogHook:hook);
|
||||
@@ -0,0 +1,80 @@
|
||||
#if defined _mapchooser_included_
|
||||
#endinput
|
||||
#endif
|
||||
#define _mapchooser_included_
|
||||
|
||||
enum NominateResult
|
||||
{
|
||||
Nominate_Added, /** The map was added to the nominate list */
|
||||
Nominate_Replaced, /** A clients existing nomination was replaced */
|
||||
Nominate_AlreadyInVote, /** Specified map was already in the vote */
|
||||
Nominate_InvalidMap, /** Mapname specifed wasn't a valid map */
|
||||
Nominate_VoteFull, /** This will only occur if force was set to false */
|
||||
};
|
||||
|
||||
enum MapChange
|
||||
{
|
||||
MapChange_Instant, /** Change map as soon as the voting results have come in */
|
||||
MapChange_RoundEnd, /** Change map at the end of the round */
|
||||
MapChange_MapEnd, /** Change the sm_nextmap cvar */
|
||||
};
|
||||
|
||||
/**
|
||||
* Attempt to add a map to the mapchooser map list.
|
||||
*
|
||||
* @param map Map to add.
|
||||
* @param force Should we force the map in even if it requires overwriting an existing nomination?
|
||||
* @param owner Client index of the nominater. If the client disconnects the nomination will be removed. Use 0 for constant nominations
|
||||
* @return Nominate Result of the outcome
|
||||
*/
|
||||
native NominateResult:NominateMap(const String:map[], bool:force, owner);
|
||||
|
||||
/**
|
||||
* Gets the current list of excluded maps.
|
||||
*
|
||||
* @param array An ADT array handle to add the map strings to. Needs to be
|
||||
* @noreturn
|
||||
*/
|
||||
native GetExcludeMapList(Handle:array);
|
||||
|
||||
/**
|
||||
* Checks if MapChooser will allow a vote
|
||||
*
|
||||
* @return True if a vote can be held, or false if mapchooser is already holding a vote.
|
||||
*/
|
||||
native bool:CanMapChooserStartVote();
|
||||
|
||||
/**
|
||||
* Initiates a MapChooser map vote
|
||||
*
|
||||
* Note: If no input array is specified mapchooser will use its internal list. This includes
|
||||
* any nominations and excluded maps (as per mapchoosers convars).
|
||||
*
|
||||
* @param when MapChange consant of when the resulting mapchange should occur.
|
||||
* @param inputarray ADT array list of maps to add to the vote.
|
||||
*/
|
||||
native InitiateMapChooserVote(MapChange:when, Handle:inputarray=INVALID_HANDLE);
|
||||
|
||||
|
||||
/**
|
||||
* A horribly named native that checks if MapChooser's end of map vote has completed.
|
||||
*/
|
||||
native bool:HasEndOfMapVoteFinished();
|
||||
|
||||
/**
|
||||
* Called when mapchooser removes a nomination from its list.
|
||||
* Nominations cleared on map start will not trigger this forward
|
||||
*/
|
||||
forward OnNominationRemoved(String:map[], owner);
|
||||
|
||||
|
||||
public SharedPlugin:__pl_mapchooser =
|
||||
{
|
||||
name = "mapchooser",
|
||||
file = "mapchooser.smx",
|
||||
#if defined REQUIRE_PLUGIN
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
@@ -0,0 +1,809 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _menus_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _menus_included
|
||||
|
||||
/**
|
||||
* Low-level drawing style of the menu.
|
||||
*/
|
||||
enum MenuStyle
|
||||
{
|
||||
MenuStyle_Default = 0, /**< The "default" menu style for the mod */
|
||||
MenuStyle_Valve = 1, /**< The Valve provided menu style (Used on HL2DM) */
|
||||
MenuStyle_Radio = 2, /**< The simpler menu style commonly used on CS:S */
|
||||
};
|
||||
|
||||
/**
|
||||
* Different actions for the menu "pump" callback
|
||||
*/
|
||||
enum MenuAction
|
||||
{
|
||||
MenuAction_Start = (1<<0), /**< A menu has been started (nothing passed) */
|
||||
MenuAction_Display = (1<<1), /**< A menu is about to be displayed (param1=client, param2=MenuPanel Handle) */
|
||||
MenuAction_Select = (1<<2), /**< An item was selected (param1=client, param2=item) */
|
||||
MenuAction_Cancel = (1<<3), /**< The menu was cancelled (param1=client, param2=reason) */
|
||||
MenuAction_End = (1<<4), /**< A menu display has fully ended.
|
||||
param1 is the MenuEnd reason, and if it's MenuEnd_Cancelled, then
|
||||
param2 is the MenuCancel reason from MenuAction_Cancel.
|
||||
*/
|
||||
MenuAction_VoteEnd = (1<<5), /**< (VOTE ONLY): A vote sequence has succeeded (param1=chosen item)
|
||||
This is not called if SetVoteResultCallback has been used on the menu. */
|
||||
MenuAction_VoteStart = (1<<6), /**< (VOTE ONLY): A vote sequence has started (nothing passed) */
|
||||
MenuAction_VoteCancel = (1<<7), /**< (VOTE ONLY): A vote sequence has been cancelled (param1=reason) */
|
||||
MenuAction_DrawItem = (1<<8), /**< An item is being drawn; return the new style (param1=client, param2=item) */
|
||||
MenuAction_DisplayItem = (1<<9),/**< Item text is being drawn to the display (param1=client, param2=item)
|
||||
To change the text, use RedrawMenuItem().
|
||||
If you do so, return its return value. Otherwise, return 0.
|
||||
*/
|
||||
};
|
||||
|
||||
/** Default menu actions */
|
||||
#define MENU_ACTIONS_DEFAULT MenuAction_Select|MenuAction_Cancel|MenuAction_End
|
||||
/** All menu actions */
|
||||
#define MENU_ACTIONS_ALL MenuAction:0xFFFFFFFF
|
||||
|
||||
#define MENU_NO_PAGINATION 0 /**< Menu should not be paginated (10 items max) */
|
||||
#define MENU_TIME_FOREVER 0 /**< Menu should be displayed as long as possible */
|
||||
|
||||
#define ITEMDRAW_DEFAULT (0) /**< Item should be drawn normally */
|
||||
#define ITEMDRAW_DISABLED (1<<0) /**< Item is drawn but not selectable */
|
||||
#define ITEMDRAW_RAWLINE (1<<1) /**< Item should be a raw line, without a slot */
|
||||
#define ITEMDRAW_NOTEXT (1<<2) /**< No text should be drawn */
|
||||
#define ITEMDRAW_SPACER (1<<3) /**< Item should be drawn as a spacer, if possible */
|
||||
#define ITEMDRAW_IGNORE ((1<<1)|(1<<2)) /**< Item should be completely ignored (rawline + notext) */
|
||||
#define ITEMDRAW_CONTROL (1<<4) /**< Item is control text (back/next/exit) */
|
||||
|
||||
#define MENUFLAG_BUTTON_EXIT (1<<0) /**< Menu has an "exit" button (default if paginated) */
|
||||
#define MENUFLAG_BUTTON_EXITBACK (1<<1) /**< Menu has an "exit back" button */
|
||||
#define MENUFLAG_NO_SOUND (1<<2) /**< Menu will not have any select sounds */
|
||||
|
||||
#define VOTEINFO_CLIENT_INDEX 0 /**< Client index */
|
||||
#define VOTEINFO_CLIENT_ITEM 1 /**< Item the client selected, or -1 for none */
|
||||
#define VOTEINFO_ITEM_INDEX 0 /**< Item index */
|
||||
#define VOTEINFO_ITEM_VOTES 1 /**< Number of votes for the item */
|
||||
|
||||
/**
|
||||
* Reasons a menu can be cancelled (MenuAction_Cancel).
|
||||
*/
|
||||
enum
|
||||
{
|
||||
MenuCancel_Disconnected = -1, /**< Client dropped from the server */
|
||||
MenuCancel_Interrupted = -2, /**< Client was interrupted with another menu */
|
||||
MenuCancel_Exit = -3, /**< Client exited via "exit" */
|
||||
MenuCancel_NoDisplay = -4, /**< Menu could not be displayed to the client */
|
||||
MenuCancel_Timeout = -5, /**< Menu timed out */
|
||||
MenuCancel_ExitBack = -6, /**< Client selected "exit back" on a paginated menu */
|
||||
};
|
||||
|
||||
/**
|
||||
* Reasons a vote can be cancelled (MenuAction_VoteCancel).
|
||||
*/
|
||||
enum
|
||||
{
|
||||
VoteCancel_Generic = -1, /**< Vote was generically cancelled. */
|
||||
VoteCancel_NoVotes = -2, /**< Vote did not receive any votes. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Reasons a menu ended (MenuAction_End).
|
||||
*/
|
||||
enum
|
||||
{
|
||||
MenuEnd_Selected = 0, /**< Menu item was selected */
|
||||
MenuEnd_VotingDone = -1, /**< Voting finished */
|
||||
MenuEnd_VotingCancelled = -2, /**< Voting was cancelled */
|
||||
MenuEnd_Cancelled = -3, /**< Menu was cancelled (reason in param2) */
|
||||
MenuEnd_Exit = -4, /**< Menu was cleanly exited via "exit" */
|
||||
MenuEnd_ExitBack = -5, /**< Menu was cleanly exited via "back" */
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes a menu's source
|
||||
*/
|
||||
enum MenuSource
|
||||
{
|
||||
MenuSource_None = 0, /**< No menu is being displayed */
|
||||
MenuSource_External = 1, /**< External menu */
|
||||
MenuSource_Normal = 2, /**< A basic menu is being displayed */
|
||||
MenuSource_RawPanel = 3, /**< A display is active, but it is not tied to a menu */
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when a menu action is completed.
|
||||
*
|
||||
* @param menu The menu being acted upon.
|
||||
* @param action The action of the menu.
|
||||
* @param param1 First action parameter (usually the client).
|
||||
* @param param2 Second action parameter (usually the item).
|
||||
* @noreturn
|
||||
*/
|
||||
functag MenuHandler public(Handle:menu, MenuAction:action, param1, param2);
|
||||
|
||||
/**
|
||||
* Creates a new, empty menu using the default style.
|
||||
*
|
||||
* @param handler Function which will receive menu actions.
|
||||
* @param actions Optionally set which actions to receive. Select,
|
||||
* Cancel, and End will always be received regardless
|
||||
* of whether they are set or not. They are also
|
||||
* the only default actions.
|
||||
* @return A new menu Handle.
|
||||
*/
|
||||
native Handle:CreateMenu(MenuHandler:handler, MenuAction:actions=MENU_ACTIONS_DEFAULT);
|
||||
|
||||
/**
|
||||
* Displays a menu to a client.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @param client Client index.
|
||||
* @param time Maximum time to leave menu on the screen.
|
||||
* @return True on success, false on failure.
|
||||
* @error Invalid Handle or client not in game.
|
||||
*/
|
||||
native bool:DisplayMenu(Handle:menu, client, time);
|
||||
|
||||
/**
|
||||
* Displays a menu to a client, starting from the given item.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @param client Client index.
|
||||
* @param first_item First item to begin drawing from.
|
||||
* @param time Maximum time to leave menu on the screen.
|
||||
* @return True on success, false on failure.
|
||||
* @error Invalid Handle or client not in game.
|
||||
*/
|
||||
native bool:DisplayMenuAtItem(Handle:menu, client, first_item, time);
|
||||
|
||||
/**
|
||||
* Appends a new item to the end of a menu.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @param info Item information string.
|
||||
* @param display Default item display string.
|
||||
* @param style Drawing style flags. Anything other than DEFAULT or
|
||||
* DISABLED will be completely ignored when paginating.
|
||||
* @return True on success, false on failure.
|
||||
* @error Invalid Handle or item limit reached.
|
||||
*/
|
||||
native AddMenuItem(Handle:menu,
|
||||
const String:info[],
|
||||
const String:display[],
|
||||
style=ITEMDRAW_DEFAULT);
|
||||
|
||||
/**
|
||||
* Inserts an item into the menu before a certain position; the new item will
|
||||
* be at the given position and all next items pushed forward.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @param position Position, starting from 0.
|
||||
* @param info Item information string.
|
||||
* @param display Default item display string.
|
||||
* @param style Drawing style flags. Anything other than DEFAULT or
|
||||
* DISABLED will be completely ignored when paginating.
|
||||
* @return True on success, false on failure.
|
||||
* @error Invalid Handle or menu position.
|
||||
*/
|
||||
native bool:InsertMenuItem(Handle:menu,
|
||||
position,
|
||||
const String:info[],
|
||||
const String:display[],
|
||||
style=ITEMDRAW_DEFAULT);
|
||||
|
||||
/**
|
||||
* Removes an item from the menu.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @param position Position, starting from 0.
|
||||
* @return True on success, false on failure.
|
||||
* @error Invalid Handle or menu position.
|
||||
*/
|
||||
native bool:RemoveMenuItem(Handle:menu, position);
|
||||
|
||||
/**
|
||||
* Removes all items from a menu.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @noreturn
|
||||
* @error Invalid Handle or menu position.
|
||||
*/
|
||||
native RemoveAllMenuItems(Handle:menu);
|
||||
|
||||
/**
|
||||
* Retrieves information about a menu item.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @param position Position, starting from 0.
|
||||
* @param infoBuf Info buffer.
|
||||
* @param infoBufLen Maximum length of the info buffer.
|
||||
* @param style By-reference variable to store drawing flags.
|
||||
* @param dispBuf Display buffer.
|
||||
* @param dispBufLen Maximum length of the display buffer.
|
||||
* @return True on success, false if position is invalid.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:GetMenuItem(Handle:menu,
|
||||
position,
|
||||
String:infoBuf[],
|
||||
infoBufLen,
|
||||
&style=0,
|
||||
String:dispBuf[]="",
|
||||
dispBufLen=0);
|
||||
|
||||
/**
|
||||
* Returns the first item on the page of a currently selected menu.
|
||||
*
|
||||
* This is only valid inside a MenuAction_Select callback.
|
||||
*
|
||||
* @return First item number on the page the client was viewing
|
||||
* before selecting the item in the callback. This can
|
||||
* be used to re-display the menu from the original
|
||||
* position.
|
||||
* @error Not called from inside a MenuAction_Select callback.
|
||||
*/
|
||||
native GetMenuSelectionPosition();
|
||||
|
||||
/**
|
||||
* Returns the number of items in a menu.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @return Number of items in the menu.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native GetMenuItemCount(Handle:menu);
|
||||
|
||||
/**
|
||||
* Sets whether the menu should be paginated or not.
|
||||
*
|
||||
* If itemsPerPage is MENU_NO_PAGINATION, and the exit button flag is set,
|
||||
* then the exit button flag is removed. It can be re-applied if desired.
|
||||
*
|
||||
* @param menu Handle to the menu.
|
||||
* @param itemsPerPage Number of items per page, or MENU_NO_PAGINATION.
|
||||
* @return True on success, false if pagination is too high or
|
||||
* low.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:SetMenuPagination(Handle:menu, itemsPerPage);
|
||||
|
||||
/**
|
||||
* Returns a menu's pagination setting.
|
||||
*
|
||||
* @param menu Handle to the menu.
|
||||
* @return Pagination setting.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native GetMenuPagination(Handle:menu);
|
||||
|
||||
/**
|
||||
* Returns a menu's MenuStyle Handle. The Handle
|
||||
* is global and cannot be freed.
|
||||
*
|
||||
* @param menu Handle to the menu.
|
||||
* @return Handle to the menu's draw style.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native Handle:GetMenuStyle(Handle:menu);
|
||||
|
||||
/**
|
||||
* Sets the menu's default title/instruction message.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @param fmt Message string format
|
||||
* @param ... Message string arguments.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native SetMenuTitle(Handle:menu, const String:fmt[], any:...);
|
||||
|
||||
/**
|
||||
* Returns the text of a menu's title.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @param buffer Buffer to store title.
|
||||
* @param maxlength Maximum length of the buffer.
|
||||
* @return Number of bytes written.
|
||||
* @error Invalid Handle/
|
||||
*/
|
||||
native GetMenuTitle(Handle:menu, String:buffer[], maxlength);
|
||||
|
||||
/**
|
||||
* Creates a raw MenuPanel based off the menu's style.
|
||||
* The Handle must be freed with CloseHandle().
|
||||
*
|
||||
* @return A new MenuPanel Handle.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native Handle:CreatePanelFromMenu(Handle:menu);
|
||||
|
||||
/**
|
||||
* Returns whether or not the menu has an exit button.
|
||||
* By default, menus have an exit button.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @return True if the menu has an exit button; false otherwise.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:GetMenuExitButton(Handle:menu);
|
||||
|
||||
/**
|
||||
* Sets whether or not the menu has an exit button. By default, paginated menus
|
||||
* have an exit button.
|
||||
*
|
||||
* If a menu's pagination is changed to MENU_NO_PAGINATION, and the pagination
|
||||
* was previously a different value, then the Exit button status is changed to
|
||||
* false. It must be explicitly re-enabled afterwards.
|
||||
*
|
||||
* If a non-paginated menu has an exit button, then at most 9 items will be
|
||||
* displayed.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @param button True to enable the button, false to remove it.
|
||||
* @return True if allowed; false on failure.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:SetMenuExitButton(Handle:menu, bool:button);
|
||||
|
||||
/**
|
||||
* Returns whether or not the menu has an "exit back" button. By default,
|
||||
* menus do not have an exit back button.
|
||||
*
|
||||
* Exit Back buttons appear as "Back" on page 1 of paginated menus and have
|
||||
* functionality defined by the user in MenuEnd_ExitBack.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @return True if the menu has an exit back button; false otherwise.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:GetMenuExitBackButton(Handle:menu);
|
||||
|
||||
/**
|
||||
* Sets whether or not the menu has an "exit back" button. By default, menus
|
||||
* do not have an exit back button.
|
||||
*
|
||||
* Exit Back buttons appear as "Back" on page 1 of paginated menus and have
|
||||
* functionality defined by the user in MenuEnd_ExitBack.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @param button True to enable the button, false to remove it.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native SetMenuExitBackButton(Handle:menu, bool:button);
|
||||
|
||||
|
||||
/**
|
||||
* Cancels a menu from displaying on all clients. While the
|
||||
* cancellation is in progress, this menu cannot be re-displayed
|
||||
* to any clients.
|
||||
*
|
||||
* The menu may still exist on the client's screen after this command.
|
||||
* This simply verifies that the menu is not being used anywhere.
|
||||
*
|
||||
* If any vote is in progress on a menu, it will be cancelled.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native CancelMenu(Handle:menu);
|
||||
|
||||
/**
|
||||
* Retrieves a menu's option flags.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @return A bitstring of MENUFLAG bits.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native GetMenuOptionFlags(Handle:menu);
|
||||
|
||||
/**
|
||||
* Sets a menu's option flags.
|
||||
*
|
||||
* If a certain bit is not supported, it will be stripped before being set.
|
||||
* See SetMenuExitButton() for information on Exit buttons.
|
||||
* See SetMenuExitBackButton() for information on Exit Back buttons.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @param flags A new bitstring of MENUFLAG bits.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native SetMenuOptionFlags(Handle:menu, flags);
|
||||
|
||||
/**
|
||||
* Returns whether a vote is in progress.
|
||||
*
|
||||
* @param menu Deprecated; no longer used.
|
||||
* @return True if a vote is in progress, false otherwise.
|
||||
*/
|
||||
native bool:IsVoteInProgress(Handle:menu=INVALID_HANDLE);
|
||||
|
||||
/**
|
||||
* Cancels the vote in progress.
|
||||
*
|
||||
* @noreturn
|
||||
* @error If no vote is in progress.
|
||||
*/
|
||||
native CancelVote();
|
||||
|
||||
/**
|
||||
* Broadcasts a menu to a list of clients. The most selected item will be
|
||||
* returned through MenuAction_End. On a tie, a random item will be returned
|
||||
* from a list of the tied items.
|
||||
*
|
||||
* Note that MenuAction_VoteEnd and MenuAction_VoteStart are both
|
||||
* default callbacks and do not need to be enabled.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @param clients Array of clients to broadcast to.
|
||||
* @param numClients Number of clients in the array.
|
||||
* @param time Maximum time to leave menu on the screen.
|
||||
* @return True on success, false if this menu already has a vote session
|
||||
* in progress.
|
||||
* @error Invalid Handle, or a vote is already in progress.
|
||||
*/
|
||||
native bool:VoteMenu(Handle:menu, clients[], numClients, time);
|
||||
|
||||
/**
|
||||
* Sends a vote menu to all clients. See VoteMenu() for more information.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @param time Maximum time to leave menu on the screen.
|
||||
* @return True on success, false if this menu already has a vote session
|
||||
* in progress.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
stock VoteMenuToAll(Handle:menu, time)
|
||||
{
|
||||
new num = GetMaxClients();
|
||||
new total;
|
||||
decl players[num];
|
||||
|
||||
for (new i=1; i<=num; i++)
|
||||
{
|
||||
if (!IsClientInGame(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
players[total++] = i;
|
||||
}
|
||||
|
||||
return VoteMenu(menu, players, total, time);
|
||||
}
|
||||
/**
|
||||
* Callback for when a vote has ended and results are available.
|
||||
*
|
||||
* @param menu The menu being voted on.
|
||||
* @param num_votes Number of votes tallied in total.
|
||||
* @param num_clients Number of clients who could vote.
|
||||
* @param client_info Array of clients. Use VOTEINFO_CLIENT_ defines.
|
||||
* @param num_items Number of unique items that were selected.
|
||||
* @param item_info Array of items, sorted by count. Use VOTEINFO_ITEM
|
||||
* defines.
|
||||
* @noreturn
|
||||
*/
|
||||
functag VoteHandler public(Handle:menu,
|
||||
num_votes,
|
||||
num_clients,
|
||||
const client_info[][2],
|
||||
num_items,
|
||||
const item_info[][2]);
|
||||
|
||||
/**
|
||||
* Sets an advanced vote handling callback. If this callback is set,
|
||||
* MenuAction_VoteEnd will not be called.
|
||||
*
|
||||
* @param menu Menu Handle.
|
||||
* @param callback Callback function.
|
||||
* @noreturn
|
||||
* @error Invalid Handle or callback.
|
||||
*/
|
||||
native SetVoteResultCallback(Handle:menu, VoteHandler:callback);
|
||||
|
||||
/**
|
||||
* Returns the number of seconds you should "wait" before displaying
|
||||
* a publicly invocable menu. This number is the time remaining until
|
||||
* (last_vote + sm_vote_delay).
|
||||
*
|
||||
* @return Number of seconds to wait, or 0 for none.
|
||||
*/
|
||||
native CheckVoteDelay();
|
||||
|
||||
/**
|
||||
* Returns whether a client is in the pool of clients allowed
|
||||
* to participate in the current vote. This is determined by
|
||||
* the client list passed to StartVote().
|
||||
*
|
||||
* @param client Client index.
|
||||
* @return True if client is allowed to vote, false otherwise.
|
||||
* @error If no vote is in progress or client index is invalid.
|
||||
*/
|
||||
native bool:IsClientInVotePool(client);
|
||||
|
||||
/**
|
||||
* Redraws the current vote menu to a client in the voting pool.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @return True on success, false if the client is in the vote pool
|
||||
* but cannot vote again.
|
||||
* @error No vote in progress, client is not in the voting pool,
|
||||
* or client index is invalid.
|
||||
*/
|
||||
native bool:RedrawClientVoteMenu(client);
|
||||
|
||||
/**
|
||||
* Returns a style's global Handle.
|
||||
*
|
||||
* @param style Menu Style.
|
||||
* @return A Handle, or INVALID_HANDLE if not found or unusable.
|
||||
*/
|
||||
native Handle:GetMenuStyleHandle(MenuStyle:style);
|
||||
|
||||
/**
|
||||
* Creates a MenuPanel from a MenuStyle. Panels are used for drawing raw
|
||||
* menus without any extra helper functions. The Handle must be closed
|
||||
* with CloseHandle().
|
||||
*
|
||||
* @param hStyle MenuStyle Handle, or INVALID_HANDLE to use the default style.
|
||||
* @return A new MenuPanel Handle.
|
||||
* @error Invalid Handle other than INVALID_HANDLE.
|
||||
*/
|
||||
native Handle:CreatePanel(Handle:hStyle=INVALID_HANDLE);
|
||||
|
||||
/**
|
||||
* Creates a Menu from a MenuStyle. The Handle must be closed with
|
||||
* CloseHandle().
|
||||
*
|
||||
* @parma hStyle MenuStyle Handle, or INVALID_HANDLE to use the default style.
|
||||
* @param handler Function which will receive menu actions.
|
||||
* @param actions Optionally set which actions to receive. Select,
|
||||
* Cancel, and End will always be received regardless
|
||||
* of whether they are set or not. They are also
|
||||
* the only default actions.
|
||||
* @return A new menu Handle.
|
||||
* @error Invalid Handle other than INVALID_HANDLE.
|
||||
*/
|
||||
native Handle:CreateMenuEx(Handle:hStyle=INVALID_HANDLE, MenuHandler:handler, MenuAction:actions=MENU_ACTIONS_DEFAULT);
|
||||
|
||||
/**
|
||||
* Returns whether a client is viewing a menu.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param hStyle MenuStyle Handle, or INVALID_HANDLE to use the default style.
|
||||
* @return A MenuSource value.
|
||||
* @error Invalid Handle other than INVALID_HANDLE.
|
||||
*/
|
||||
native MenuSource:GetClientMenu(client, Handle:hStyle=INVALID_HANDLE);
|
||||
|
||||
/**
|
||||
* Cancels a menu on a client. This will only affect non-external menus.
|
||||
*
|
||||
* @param hstyle MenuStyle Handle, or INVALID_HANDLE to use the default style.
|
||||
* @param client Client index.
|
||||
* @param autoIgnore If true, no menus can be re-drawn on the client during
|
||||
* the cancellation process.
|
||||
* @return True if a menu was cancelled, false otherwise.
|
||||
*/
|
||||
native bool:CancelClientMenu(client, bool:autoIgnore=false, Handle:hStyle=INVALID_HANDLE);
|
||||
|
||||
/**
|
||||
* Returns a style's maximum items per page.
|
||||
*
|
||||
* @param hStyle MenuStyle Handle, or INVALID_HANDLE to use the default style.
|
||||
* @return Maximum items per page.
|
||||
* @error Invalid Handle other than INVALID_HANDLE.
|
||||
*/
|
||||
native GetMaxPageItems(Handle:hStyle=INVALID_HANDLE);
|
||||
|
||||
/**
|
||||
* Returns a MenuPanel's parent style.
|
||||
*
|
||||
* @param panel A MenuPanel Handle.
|
||||
* @return The MenuStyle Handle that created the panel.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native Handle:GetPanelStyle(Handle:panel);
|
||||
|
||||
/**
|
||||
* Sets the panel's title.
|
||||
*
|
||||
* @param panel A MenuPanel Handle.
|
||||
* @param title Text to set as the title.
|
||||
* @param onlyIfEmpty If true, the title will only be set if no title is set.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native Handle:SetPanelTitle(Handle:panel, const String:text[], bool:onlyIfEmpty=false);
|
||||
|
||||
/**
|
||||
* Draws an item on a panel. If the item takes up a slot, the position
|
||||
* is returned.
|
||||
*
|
||||
* @param panel A MenuPanel Handle.
|
||||
* @param text Display text to use. If not a raw line,
|
||||
* the style may automatically add color markup.
|
||||
* No numbering or newlines are needed.
|
||||
* @param style ITEMDRAW style flags.
|
||||
* @return A slot position, or 0 if item was a rawline or could not be drawn.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native DrawPanelItem(Handle:panel, const String:text[], style=ITEMDRAW_DEFAULT);
|
||||
|
||||
/**
|
||||
* Draws a raw line of text on a panel, without any markup other than a newline.
|
||||
*
|
||||
* @param panel A MenuPanel Handle, or INVALID_HANDLE if inside a
|
||||
* MenuAction_DisplayItem callback.
|
||||
* @param text Display text to use.
|
||||
* @return True on success, false if raw lines are not supported.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native DrawPanelText(Handle:panel, const String:text[]);
|
||||
|
||||
/**
|
||||
* Returns whether or not the given drawing flags are supported by
|
||||
* the menu style.
|
||||
*
|
||||
* @param panel A MenuPanel Handle.
|
||||
* @param style ITEMDRAW style flags.
|
||||
* @return True if item is drawable, false otherwise.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native CanPanelDrawFlags(Handle:panel, style);
|
||||
|
||||
/**
|
||||
* Sets the selectable key map of a panel. This is not supported by
|
||||
* all styles (only by Radio, as of this writing).
|
||||
*
|
||||
* @param keys An integer where each bit N allows key
|
||||
* N+1 to be selected. If no keys are selectable,
|
||||
* then key 0 (bit 9) is automatically set.
|
||||
* @return True if supported, false otherwise.
|
||||
*/
|
||||
native bool:SetPanelKeys(Handle:panel, keys);
|
||||
|
||||
/**
|
||||
* Sends a panel to a client. Unlike full menus, the handler
|
||||
* function will only receive the following actions, both of
|
||||
* which will have INVALID_HANDLE for a menu, and the client
|
||||
* as param1.
|
||||
*
|
||||
* MenuAction_Select (param2 will be the key pressed)
|
||||
* MenuAction_Cancel (param2 will be the reason)
|
||||
*
|
||||
* Also, if the menu fails to display, no callbacks will be called.
|
||||
*
|
||||
* @param panel A MenuPanel Handle.
|
||||
* @param client A client to draw to.
|
||||
* @param handler The MenuHandler function to catch actions with.
|
||||
* @param time Time to hold the menu for.
|
||||
* @return True on success, false on failure.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:SendPanelToClient(Handle:panel, client, MenuHandler:handler, time);
|
||||
|
||||
/**
|
||||
* @brief Returns the amount of text the menu can still hold. If this is
|
||||
* limit is reached or overflowed, the text is silently truncated.
|
||||
*
|
||||
* Radio menus: Currently 511 characters (512 bytes).
|
||||
* Valve menus: Currently -1 (no meaning).
|
||||
*
|
||||
* @param panel A MenuPanel Handle.
|
||||
* @return Number of characters that the menu can still hold,
|
||||
* or -1 if there is no known limit.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native GetPanelTextRemaining(Handle:panel);
|
||||
|
||||
/**
|
||||
* @brief Returns the current key position.
|
||||
*
|
||||
* @param panel A MenuPanel Handle.
|
||||
* @return Current key position starting at 1.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native GetPanelCurrentKey(Handle:panel);
|
||||
|
||||
/**
|
||||
* @brief Sets the next key position. This cannot be used
|
||||
* to traverse backwards.
|
||||
*
|
||||
* @param panel A MenuPanel Handle.
|
||||
* @param key Key that is greater or equal to
|
||||
* GetPanelCurrentKey().
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:SetPanelCurrentKey(Handle:panel, key);
|
||||
|
||||
/**
|
||||
* @brief Redraws menu text from inside a MenuAction_DisplayItem callback.
|
||||
*
|
||||
* @param text Menu text to draw.
|
||||
* @return Item position; must be returned via the callback.
|
||||
*/
|
||||
native RedrawMenuItem(const String:text[]);
|
||||
|
||||
/**
|
||||
* This function is provided for legacy code only. Some older plugins may use
|
||||
* network messages instead of the panel API. This function wraps the panel
|
||||
* API for eased portability into the SourceMod menu system.
|
||||
*
|
||||
* This function is only usable with the Radio Menu style. You do not need to
|
||||
* split up your menu into multiple packets; SourceMod will break the string
|
||||
* up internally.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param str Full menu string as would be passed over the network.
|
||||
* @param time Time to hold the menu for.
|
||||
* @param keys Selectable key bitstring.
|
||||
* @param handler Optional handler function, with the same rules as
|
||||
* SendPanelToClient().
|
||||
* @return True on success, false on failure.
|
||||
* @error Invalid client index, or radio menus not supported.
|
||||
*/
|
||||
native bool:InternalShowMenu(client, const String:str[], time, keys=-1, MenuHandler:handler=MenuHandler:-1);
|
||||
|
||||
/**
|
||||
* Retrieves voting information from MenuAction_VoteEnd.
|
||||
*
|
||||
* @param param2 Second parameter of MenuAction_VoteEnd.
|
||||
* @param winningVotes Number of votes received by the winning option.
|
||||
* @param totalVotes Number of total votes received.
|
||||
* @noreturn
|
||||
*/
|
||||
stock GetMenuVoteInfo(param2, &winningVotes, &totalVotes)
|
||||
{
|
||||
winningVotes = param2 & 0xFFFF;
|
||||
totalVotes = param2 >> 16;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quick stock to determine whether voting is allowed. This doesn't let you
|
||||
* fine-tune a reason for not voting, so it's not recommended for lazily
|
||||
* telling clients that voting isn't allowed.
|
||||
*
|
||||
* @return True if voting is allowed, false if voting is in progress
|
||||
* or the cooldown is active.
|
||||
*/
|
||||
stock bool:IsNewVoteAllowed()
|
||||
{
|
||||
if (IsVoteInProgress() || CheckVoteDelay() != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _nextmap_included_
|
||||
#endinput
|
||||
#endif
|
||||
#define _nextmap_included_
|
||||
|
||||
/**
|
||||
* Sets SourceMod's internal nextmap.
|
||||
* Equivalent to changing sm_nextmap but with an added validity check.
|
||||
*
|
||||
* @param map Next map to set.
|
||||
* @return True if the nextmap was set, false if map was invalid.
|
||||
*/
|
||||
native bool:SetNextMap(const String:map[]);
|
||||
|
||||
/**
|
||||
* Returns SourceMod's internal nextmap.
|
||||
*
|
||||
* @param map Buffer to store the nextmap name.
|
||||
* @param maxlen Maximum length of the map buffer.
|
||||
* @return True if a Map was found and copied, false if no nextmap is set (map will be unchanged).
|
||||
*/
|
||||
native bool:GetNextMap(String:map[], maxlen);
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _profiler_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _profiler_included
|
||||
|
||||
/**
|
||||
* ONLY AVAILABLE ON WINDOWS RIGHT NOW K.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a new profile object. The Handle must be freed
|
||||
* using CloseHandle().
|
||||
*
|
||||
* @return Handle to the profiler object.
|
||||
*/
|
||||
native Handle:CreateProfiler();
|
||||
|
||||
/**
|
||||
* Starts profiling.
|
||||
*
|
||||
* @param prof Profiling object.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native StartProfiling(Handle:prof);
|
||||
|
||||
/**
|
||||
* Stops profiling.
|
||||
*
|
||||
* @param prof Profiling object.
|
||||
* @noreturn
|
||||
* @error Invalid Handle or profiling was never started.
|
||||
*/
|
||||
native StopProfiling(Handle:prof);
|
||||
|
||||
/**
|
||||
* Returns the amount of high-precision time in seconds
|
||||
* that passed during the profiler's last start/stop
|
||||
* cycle.
|
||||
*
|
||||
* @param prof Profiling object.
|
||||
* @return Time elapsed in seconds.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native Float:GetProfilerTime(Handle:prof);
|
||||
@@ -0,0 +1,173 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _regex_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _regex_included
|
||||
|
||||
/**
|
||||
* @section Flags for compiling regex expressions. These come directly from the
|
||||
* pcre library and can be used in MatchRegex and CompileRegex.
|
||||
*/
|
||||
#define PCRE_CASELESS 0x00000001 /* Ignore Case */
|
||||
#define PCRE_MULTILINE 0x00000002 /* Multilines (affects ^ and $ so that they match the start/end of a line rather than matching the start/end of the string). */
|
||||
#define PCRE_DOTALL 0x00000004 /* Single line (affects . so that it matches any character, even new line characters). */
|
||||
#define PCRE_EXTENDED 0x00000008 /* Pattern extension (ignore whitespace and # comments). */
|
||||
#define PCRE_UNGREEDY 0x00000200 /* Invert greediness of quantifiers */
|
||||
#define PCRE_UTF8 0x00000800 /* Use UTF-8 Chars */
|
||||
#define PCRE_NO_UTF8_CHECK 0x00002000 /* Do not check the pattern for UTF-8 validity (only relevant if PCRE_UTF8 is set) */
|
||||
|
||||
|
||||
/**
|
||||
* Regex expression error codes.
|
||||
*/
|
||||
enum RegexError
|
||||
{
|
||||
REGEX_ERROR_NONE = 0, /* No error */
|
||||
REGEX_ERROR_NOMATCH = -1, /* No match was found */
|
||||
REGEX_ERROR_NULL = -2,
|
||||
REGEX_ERROR_BADOPTION = -3,
|
||||
REGEX_ERROR_BADMAGIC = -4,
|
||||
REGEX_ERROR_UNKNOWN_OPCODE = -5,
|
||||
REGEX_ERROR_NOMEMORY = -6,
|
||||
REGEX_ERROR_NOSUBSTRING = -7,
|
||||
REGEX_ERROR_MATCHLIMIT = -8,
|
||||
REGEX_ERROR_CALLOUT = -9, /* Never used by PCRE itself */
|
||||
REGEX_ERROR_BADUTF8 = -10,
|
||||
REGEX_ERROR_BADUTF8_OFFSET = -11,
|
||||
REGEX_ERROR_PARTIAL = -12,
|
||||
REGEX_ERROR_BADPARTIAL = -13,
|
||||
REGEX_ERROR_INTERNAL = -14,
|
||||
REGEX_ERROR_BADCOUNT = -15,
|
||||
REGEX_ERROR_DFA_UITEM = -16,
|
||||
REGEX_ERROR_DFA_UCOND = -17,
|
||||
REGEX_ERROR_DFA_UMLIMIT = -18,
|
||||
REGEX_ERROR_DFA_WSSIZE = -19,
|
||||
REGEX_ERROR_DFA_RECURSE = -20,
|
||||
REGEX_ERROR_RECURSIONLIMIT = -21,
|
||||
REGEX_ERROR_NULLWSLIMIT = -22, /* No longer actually used */
|
||||
REGEX_ERROR_BADNEWLINE = -23
|
||||
};
|
||||
|
||||
/**
|
||||
* Precompile a regular expression. Use this if you intend on using the
|
||||
* same expression multiple times. Pass the regex handle returned here to
|
||||
* MatchRegex to check for matches.
|
||||
*
|
||||
* @param pattern The regular expression pattern.
|
||||
* @param flags General flags for the regular expression.
|
||||
* @param error Error message encountered, if applicable.
|
||||
* @param maxLen Maximum string length of the error buffer.
|
||||
* @param errcode Regex type error code encountered, if applicable.
|
||||
* @return Valid regex handle on success, INVALID_HANDLE on failure.
|
||||
*/
|
||||
native Handle:CompileRegex(const String:pattern[], flags = 0, String:error[]="", maxLen = 0, &RegexError:errcode = REGEX_ERROR_NONE);
|
||||
|
||||
/**
|
||||
* Matches a string against a pre-compiled regular expression pattern.
|
||||
*
|
||||
* @param str The string to check.
|
||||
* @param regex Regex Handle from CompileRegex()
|
||||
* @param ret Error code, if applicable.
|
||||
* @return Number of substrings found or -1 on failure.
|
||||
*
|
||||
* @note Use the regex handle passed to this function to extract
|
||||
* matches with GetRegexSubString().
|
||||
*/
|
||||
native MatchRegex(Handle:regex, const String:str[], &RegexError:ret = REGEX_ERROR_NONE);
|
||||
|
||||
/**
|
||||
* Returns a matched substring from a regex handle.
|
||||
* Substring ids start at 0 and end at substrings-1, where substrings is the number returned
|
||||
* by MatchRegex
|
||||
*
|
||||
* @param regex The regex handle to extract data from.
|
||||
* @param str_id The index of the expression to get - starts at 0, and ends at substrings - 1.
|
||||
* @param buffer The buffer to set to the matching substring.
|
||||
* @param maxLen The maximum string length of the buffer.
|
||||
* @return True if a substring was found, False on fail/error
|
||||
*/
|
||||
native bool:GetRegexSubString(Handle:regex, str_id, String:buffer[], maxlen);
|
||||
|
||||
/**
|
||||
* Matches a string against a regular expression pattern.
|
||||
*
|
||||
* @note If you intend on using the same regular expression pattern
|
||||
* multiple times, consider using CompileRegex and MatchRegex
|
||||
* instead of making this function reparse the expression each time.
|
||||
*
|
||||
* @param str The string to check.
|
||||
* @param pattern The regular expression pattern.
|
||||
* @param flags General flags for the regular expression.
|
||||
* @param error Error message, if applicable.
|
||||
* @param maxLen Maximum length of the error buffer.
|
||||
* @return Number of substrings found or -1 on failure.
|
||||
*/
|
||||
stock SimpleRegexMatch(const String:str[], const String:pattern[], flags = 0, String:error[]="", maxLen = 0)
|
||||
{
|
||||
new Handle:regex = CompileRegex(pattern, flags, error, maxLen);
|
||||
|
||||
if (regex == INVALID_HANDLE)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
new substrings = MatchRegex(regex, str);
|
||||
|
||||
CloseHandle(regex);
|
||||
|
||||
return substrings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @endsection
|
||||
*/
|
||||
|
||||
/**
|
||||
* Do not edit below this line!
|
||||
*/
|
||||
public Extension:__ext_regex =
|
||||
{
|
||||
name = "Regex Extension",
|
||||
file = "regex.ext",
|
||||
#if defined AUTOLOAD_EXTENSIONS
|
||||
autoload = 1,
|
||||
#else
|
||||
autoload = 0,
|
||||
#endif
|
||||
#if defined REQUIRE_EXTENSIONS
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
@@ -0,0 +1,212 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _sdktools_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _sdktools_included
|
||||
|
||||
#include <core>
|
||||
#include <sdktools_engine>
|
||||
#include <sdktools_functions>
|
||||
#if !defined SDKTOOLS_DISABLE_SOUNDAPI
|
||||
#include <sdktools_sound>
|
||||
#endif
|
||||
#include <sdktools_stringtables>
|
||||
#include <sdktools_trace>
|
||||
#include <sdktools_tempents>
|
||||
#include <sdktools_tempents_stocks>
|
||||
#include <sdktools_voice>
|
||||
#include <sdktools_entinput>
|
||||
#include <sdktools_entoutput>
|
||||
|
||||
enum SDKCallType
|
||||
{
|
||||
SDKCall_Static, /**< Static call */
|
||||
SDKCall_Entity, /**< CBaseEntity call */
|
||||
SDKCall_Player, /**< CBasePlayer call */
|
||||
SDKCall_GameRules, /**< CGameRules call */
|
||||
SDKCall_EntityList, /**< CGlobalEntityList call */
|
||||
};
|
||||
|
||||
enum SDKLibrary
|
||||
{
|
||||
SDKLibrary_Server, /**< server.dll/server_i486.so */
|
||||
SDKLibrary_Engine, /**< engine.dll/engine_*.so */
|
||||
};
|
||||
|
||||
enum SDKFuncConfSource
|
||||
{
|
||||
SDKConf_Virtual = 0, /**< Read a virtual index from the Offsets section */
|
||||
SDKConf_Signature = 1, /**< Read a signature from the Signatures section */
|
||||
};
|
||||
|
||||
enum SDKType
|
||||
{
|
||||
SDKType_CBaseEntity, /**< CBaseEntity (always as pointer) */
|
||||
SDKType_CBasePlayer, /**< CBasePlayer (always as pointer) */
|
||||
SDKType_Vector, /**< Vector (pointer, byval, or byref) */
|
||||
SDKType_QAngle, /**< QAngles (pointer, byval, or byref) */
|
||||
SDKType_PlainOldData, /**< Integer/generic data <=32bit (any) */
|
||||
SDKType_Float, /**< Float (any) */
|
||||
SDKType_Edict, /**< edict_t (always as pointer) */
|
||||
SDKType_String, /**< NULL-terminated string (always as pointer) */
|
||||
SDKType_Bool, /**< Boolean (any) */
|
||||
};
|
||||
|
||||
enum SDKPassMethod
|
||||
{
|
||||
SDKPass_Pointer, /**< Pass as a pointer */
|
||||
SDKPass_Plain, /**< Pass as plain data */
|
||||
SDKPass_ByValue, /**< Pass an object by value */
|
||||
SDKPass_ByRef, /**< Pass an object by reference */
|
||||
};
|
||||
|
||||
#define VDECODE_FLAG_ALLOWNULL (1<<0) /**< Allow NULL for pointers */
|
||||
#define VDECODE_FLAG_ALLOWNOTINGAME (1<<1) /**< Allow players not in game */
|
||||
#define VDECODE_FLAG_ALLOWWORLD (1<<2) /**< Allow World entity */
|
||||
#define VDECODE_FLAG_BYREF (1<<3) /**< Floats/ints by reference */
|
||||
|
||||
#define VENCODE_FLAG_COPYBACK (1<<0) /**< Copy back data once done */
|
||||
|
||||
/**
|
||||
* Starts the preparation of an SDK call.
|
||||
*
|
||||
* @param type Type of function call this will be.
|
||||
* @noreturn
|
||||
*/
|
||||
native StartPrepSDKCall(SDKCallType:type);
|
||||
|
||||
/**
|
||||
* Sets the virtual index of the SDK call if it is virtual.
|
||||
*
|
||||
* @param vtblidx Virtual table index.
|
||||
* @noreturn
|
||||
*/
|
||||
native PrepSDKCall_SetVirtual(vtblidx);
|
||||
|
||||
/**
|
||||
* Finds an address in a library and sets it as the address to use for the SDK call.
|
||||
*
|
||||
* @param lib Library to use.
|
||||
* @param signature Binary data to search for in the library. If it starts with '@',
|
||||
* the bytes parameter is ignored and the signature is interpreted
|
||||
* as a symbol lookup in the library.
|
||||
* @param bytes Number of bytes in the binary search string.
|
||||
* @return True on success, false if nothing was found.
|
||||
*/
|
||||
native bool:PrepSDKCall_SetSignature(SDKLibrary:lib, const String:signature[], bytes);
|
||||
|
||||
/**
|
||||
* Finds an address or virtual function index in a GameConfig file and sets it as
|
||||
* the calling information for the SDK call.
|
||||
*
|
||||
* @param gameconf GameConfig Handle, or INVALID_HANDLE to use sdktools.games.txt.
|
||||
* @param source Whether to look in Offsets or Signatures.
|
||||
* @param name Name of the property to find.
|
||||
* @return True on success, false if nothing was found.
|
||||
*/
|
||||
native bool:PrepSDKCall_SetFromConf(Handle:gameconf, SDKFuncConfSource:source, const String:name[]);
|
||||
|
||||
/**
|
||||
* Sets the return information of an SDK call. Do not call this if there is no return data.
|
||||
* This must be called if there is a return value (i.e. it is not necessarily safe to ignore
|
||||
* the data).
|
||||
*
|
||||
* @param type Data type to convert to/from.
|
||||
* @param pass How the data is passed in C++.
|
||||
* @param decflags Flags on decoding from the plugin to C++.
|
||||
* @param encflags Flags on encoding from C++ to the plugin.
|
||||
* @noreturn
|
||||
*/
|
||||
native PrepSDKCall_SetReturnInfo(SDKType:type, SDKPassMethod:pass, decflags=0, encflags=0);
|
||||
|
||||
/**
|
||||
* Adds a parameter to the calling convention. This should be called in normal ascending order.
|
||||
*
|
||||
* @param type Data type to convert to/from.
|
||||
* @param pass How the data is passed in C++.
|
||||
* @param decflags Flags on decoding from the plugin to C++.
|
||||
* @param encflags Flags on encoding from C++ to the plugin.
|
||||
* @noreturn
|
||||
*/
|
||||
native PrepSDKCall_AddParameter(SDKType:type, SDKPassMethod:pass, decflags=0, encflags=0);
|
||||
|
||||
/**
|
||||
* Finalizes an SDK call preparation and returns the resultant Handle.
|
||||
*
|
||||
* @return A new SDKCall Handle on success, or INVALID_HANDLE on failure.
|
||||
*/
|
||||
native Handle:EndPrepSDKCall();
|
||||
|
||||
/**
|
||||
* Calls an SDK function with the given parameters.
|
||||
*
|
||||
* If the call type is Entity or Player, the index MUST ALWAYS be the FIRST parameter passed.
|
||||
* If the call type is GameRules, then nothing special needs to be passed.
|
||||
* If the return value is a Vector or QAngles, the SECOND parameter must be a Float[3].
|
||||
* If the return value is a string, the THIRD parameter must be a String buffer, and the
|
||||
* FOURTH parameter must be the maximum length.
|
||||
* All parameters must be passed after the above is followed. Failure to follow these
|
||||
* rules will result in crashes or wildly unexpected behavior!
|
||||
*
|
||||
* If the return value is a float or integer, the return value will be this value.
|
||||
* If the return value is a CBaseEntity, CBasePlayer, or edict, the return value will
|
||||
* always be the entity index, or -1 for NULL.
|
||||
*
|
||||
* @param call SDKCall Handle.
|
||||
* @param ... Call Parameters.
|
||||
* @return Simple return value, if any.
|
||||
* @error Invalid Handle or internal decoding error.
|
||||
*/
|
||||
native any:SDKCall(Handle:call, any:...);
|
||||
|
||||
#include <sdktools_stocks>
|
||||
|
||||
/**
|
||||
* Do not edit below this line!
|
||||
*/
|
||||
public Extension:__ext_sdktools =
|
||||
{
|
||||
name = "SDKTools",
|
||||
file = "sdktools.ext",
|
||||
#if defined AUTOLOAD_EXTENSIONS
|
||||
autoload = 1,
|
||||
#else
|
||||
autoload = 0,
|
||||
#endif
|
||||
#if defined REQUIRE_EXTENSIONS
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _sdktools_engine_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _sdktools_engine_included
|
||||
|
||||
#define MAX_LIGHTSTYLES 64
|
||||
|
||||
/**
|
||||
* Sets a client's "viewing entity."
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param entity Entity index.
|
||||
* @noreturn
|
||||
* @error Invalid client or entity, lack of mod support, or client not in
|
||||
* game.
|
||||
*/
|
||||
native SetClientViewEntity(client, entity);
|
||||
|
||||
/**
|
||||
* Sets a light style.
|
||||
*
|
||||
* @param style Light style (from 0 to MAX_LIGHTSTYLES-1)
|
||||
* @param value Light value string (see world.cpp/light.cpp in dlls)
|
||||
* @noreturn
|
||||
* @error Light style index is out of range.
|
||||
*/
|
||||
native SetLightStyle(style, const String:value[]);
|
||||
|
||||
/**
|
||||
* Returns the client's eye position.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param pos Destination vector to store the client's eye position.
|
||||
* @noreturn
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native GetClientEyePosition(client, Float:pos[3]);
|
||||
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _sdktools_entinput_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _sdktools_entinput_included
|
||||
|
||||
/**
|
||||
* Invokes a named input method on an entity.
|
||||
*
|
||||
* After completion (successful or not), the current global variant is re-initalized.
|
||||
*
|
||||
* @param dest Destination entity index.
|
||||
* @param input Input action.
|
||||
* @param activator Entity index which initiated the sequence of actions (-1 for a NULL entity).
|
||||
* @param caller Entity index from which this event is sent (-1 for a NULL entity).
|
||||
* @param outputid Unknown.
|
||||
* @return True if successful otherwise false.
|
||||
* @error Invalid entity index or no mod support.
|
||||
*/
|
||||
native bool:AcceptEntityInput(dest, const String:input[], activator=-1, caller=-1, outputid=0);
|
||||
|
||||
/**
|
||||
* Sets a bool value in the global variant object.
|
||||
*
|
||||
* @param val Input value.
|
||||
* @noreturn
|
||||
*/
|
||||
native SetVariantBool(bool:val);
|
||||
|
||||
/**
|
||||
* Sets a string in the global variant object.
|
||||
*
|
||||
* @param str Input string.
|
||||
* @noreturn
|
||||
*/
|
||||
native SetVariantString(const String:str[]);
|
||||
|
||||
/**
|
||||
* Sets an integer value in the global variant object.
|
||||
*
|
||||
* @param val Input value.
|
||||
* @noreturn
|
||||
*/
|
||||
native SetVariantInt(val);
|
||||
|
||||
/**
|
||||
* Sets a floating point value in the global variant object.
|
||||
*
|
||||
* @param val Input value.
|
||||
* @noreturn
|
||||
*/
|
||||
native SetVariantFloat(Float:val);
|
||||
|
||||
/**
|
||||
* Sets a 3D vector in the global variant object.
|
||||
*
|
||||
* @param vec Input vector.
|
||||
* @noreturn
|
||||
*/
|
||||
native SetVariantVector3D(const Float:vec[3]);
|
||||
|
||||
/**
|
||||
* Sets a 3D position vector in the global variant object.
|
||||
*
|
||||
* @param vec Input position vector.
|
||||
* @noreturn
|
||||
*/
|
||||
native SetVariantPosVector3D(const Float:vec[3]);
|
||||
|
||||
/**
|
||||
* Sets a color in the global variant object.
|
||||
*
|
||||
* @param color Input color.
|
||||
* @noreturn
|
||||
*/
|
||||
native SetVariantColor(const color[4]);
|
||||
|
||||
/**
|
||||
* Sets an entity in the global variant object.
|
||||
*
|
||||
* @param Entity index.
|
||||
* @noreturn
|
||||
* @error Invalid entity index.
|
||||
*/
|
||||
native SetVariantEntity(entity);
|
||||
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _sdktools_entoutput_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _sdktools_entoutput_included
|
||||
|
||||
/**
|
||||
* Called when an entity output is fired.
|
||||
*
|
||||
* @param output Name of the output that fired.
|
||||
* @param caller Entity index of the caller.
|
||||
* @param activator Entity index of the activator.
|
||||
* @param delay Delay in seconds? before the event gets fired.
|
||||
*/
|
||||
functag EntityOutput public(const String:output[], caller, activator, Float:delay);
|
||||
|
||||
/**
|
||||
* Add an entity output hook on a entity classname
|
||||
*
|
||||
* @param classname The classname to hook.
|
||||
* @param output The output name to hook.
|
||||
* @param callback An EntityOutput function pointer.
|
||||
* @noreturn
|
||||
* @error Entity Outputs disabled.
|
||||
*/
|
||||
native HookEntityOutput(const String:classname[], const String:output[], EntityOutput:callback);
|
||||
|
||||
/**
|
||||
* Remove an entity output hook.
|
||||
* @param classname The classname to hook.
|
||||
* @param output The output name to hook.
|
||||
* @param callback An EntityOutput function pointer.
|
||||
* @return True on success, false if no valid hook was found.
|
||||
* @error Entity Outputs disabled.
|
||||
*/
|
||||
native bool:UnhookEntityOutput(const String:classname[], const String:output[], EntityOutput:callback);
|
||||
|
||||
/**
|
||||
* Add an entity output hook on a single entity instance
|
||||
*
|
||||
* @param entity The entity on which to add a hook.
|
||||
* @param output The output name to hook.
|
||||
* @param callback An EntityOutput function pointer.
|
||||
* @param once Only fire this hook once and then remove itself.
|
||||
* @noreturn
|
||||
* @error Entity Outputs disabled or Invalid Entity index.
|
||||
*/
|
||||
native HookSingleEntityOutput(entity, const String:output[], EntityOutput:callback , bool:once=false);
|
||||
|
||||
/**
|
||||
* Remove a single entity output hook.
|
||||
*
|
||||
* @param entity The entity on which to remove the hook.
|
||||
* @param output The output name to hook.
|
||||
* @param callback An EntityOutput function pointer.
|
||||
* @return True on success, false if no valid hook was found.
|
||||
* @error Entity Outputs disabled or Invalid Entity index.
|
||||
*/
|
||||
native bool:UnhookSingleEntityOutput(entity, const String:output[], EntityOutput:callback);
|
||||
|
||||
@@ -0,0 +1,322 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _sdktools_functions_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _sdktools_functions_included
|
||||
|
||||
/**
|
||||
* Removes a player's item.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param item CBaseCombatWeapon entity index.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid client or entity, lack of mod support, or client not in
|
||||
* game.
|
||||
*/
|
||||
native bool:RemovePlayerItem(client, item);
|
||||
|
||||
/**
|
||||
* Gives a named item to a player.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param item Item classname (such as weapon_ak47).
|
||||
* @param iSubType Unknown.
|
||||
* @return Entity index on success, or -1 on failure.
|
||||
* @error Invalid client or client not in game, or lack of mod support.
|
||||
*/
|
||||
native GivePlayerItem(client, const String:item[], iSubType=0);
|
||||
|
||||
/**
|
||||
* Returns the weapon in a player's slot.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param slot Slot index (mod specific).
|
||||
* @return Entity index on success, -1 if no weapon existed.
|
||||
* @error Invalid client or client not in game, or lack of mod support.
|
||||
*/
|
||||
native GetPlayerWeaponSlot(client, slot);
|
||||
|
||||
/**
|
||||
* Ignites an entity on fire.
|
||||
*
|
||||
* @param entity Entity index.
|
||||
* @param time Number of seconds to set on fire.
|
||||
* @param npc True to only affect NPCs.
|
||||
* @param size Unknown.
|
||||
* @param level Unknown.
|
||||
* @noreturn
|
||||
* @error Invalid entity or client not in game, or lack of mod support.
|
||||
*/
|
||||
native IgniteEntity(entity, Float:time, bool:npc=false, Float:size=0.0, bool:level=false);
|
||||
|
||||
/**
|
||||
* Extinguishes a player that is on fire.
|
||||
*
|
||||
* @param entity Entity index.
|
||||
* @noreturn
|
||||
* @error Invalid entity or client not in game, or lack of mod support.
|
||||
*/
|
||||
native ExtinguishEntity(client);
|
||||
|
||||
/**
|
||||
* Teleports an entity.
|
||||
*
|
||||
* @param entity Client index.
|
||||
* @param origin New origin, or NULL_VECTOR for no change.
|
||||
* @param angles New angles, or NULL_VECTOR for no change.
|
||||
* @param velocity New velocity, or NULL_VECTOR for no change.
|
||||
* @noreturn
|
||||
* @error Invalid entity or client not in game, or lack of mod support.
|
||||
*/
|
||||
native TeleportEntity(entity, const Float:origin[3], const Float:angles[3], const Float:velocity[3]);
|
||||
|
||||
/**
|
||||
* Forces a player to commit suicide.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @noreturn
|
||||
* @error Invalid client or client not in game, or lack of mod support.
|
||||
*/
|
||||
native ForcePlayerSuicide(client);
|
||||
|
||||
/**
|
||||
* Slaps a player in a random direction.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param health Health to subtract.
|
||||
* @param sound False to disable the sound effects.
|
||||
* @noreturn
|
||||
* @error Invalid client or client not in game, or lack of mod support.
|
||||
*/
|
||||
native SlapPlayer(client, health=5, bool:sound=true);
|
||||
|
||||
/**
|
||||
* Searches for an entity by classname.
|
||||
*
|
||||
* @param startEnt The entity index after which to begin searching from.
|
||||
* Use -1 to start from the first entity.
|
||||
* @param classname Classname of the entity to find.
|
||||
* @return Entity index >= 0 if found, -1 otherwise.
|
||||
* @error Lack of mod support.
|
||||
*/
|
||||
native FindEntityByClassname(startEnt, const String:classname[]);
|
||||
|
||||
/**
|
||||
* Returns the client's eye angles.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param ang Destination vector to store the client's eye angles.
|
||||
* @return True on success, false on failure.
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native bool:GetClientEyeAngles(client, Float:ang[3]);
|
||||
|
||||
/**
|
||||
* Creates an entity by string name, but does not spawn it (see DispatchSpawn).
|
||||
* If ForceEdictIndex is not -1, then it will use the edict by that index. If the index is
|
||||
* invalid or there is already an edict using that index, it will error out.
|
||||
*
|
||||
* @param classname Entity classname.
|
||||
* @param ForceEdictIndex Edict index used by the created entity.
|
||||
* @return Entity index on success, or -1 on failure.
|
||||
* @error Invalid edict index, or no mod support.
|
||||
*/
|
||||
native CreateEntityByName(const String:classname[], ForceEdictIndex=-1);
|
||||
|
||||
/**
|
||||
* Spawns an entity into the game.
|
||||
*
|
||||
* @param entity Entity index of the created entity.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid entity index, or no mod support.
|
||||
*/
|
||||
native bool:DispatchSpawn(entity);
|
||||
|
||||
/**
|
||||
* Dispatches a KeyValue into given entity using a string value.
|
||||
*
|
||||
* @param entity Destination entity index.
|
||||
* @param keyName Name of the key.
|
||||
* @param value String value.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid entity index, or no mod support.
|
||||
*/
|
||||
native bool:DispatchKeyValue(entity, const String:keyName[], const String:value[]);
|
||||
|
||||
/**
|
||||
* Dispatches a KeyValue into given entity using a floating point value.
|
||||
*
|
||||
* @param entity Destination entity index.
|
||||
* @param keyName Name of the key.
|
||||
* @param value Floating point value.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid entity index, or no mod support.
|
||||
*/
|
||||
native bool:DispatchKeyValueFloat(entity, const String:keyName[], Float:value);
|
||||
|
||||
/**
|
||||
* Dispatches a KeyValue into given entity using a vector value.
|
||||
*
|
||||
* @param entity Destination entity index.
|
||||
* @param keyName Name of the key.
|
||||
* @param vec Vector value.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid entity index, or no mod support.
|
||||
*/
|
||||
native bool:DispatchKeyValueVector(entity, const String:keyName[], const Float:vector[3]);
|
||||
|
||||
/**
|
||||
* Returns the entity a client is aiming at.
|
||||
*
|
||||
* @param client Client performing the aiming.
|
||||
* @param only_clients True to exclude all entities but clients.
|
||||
* @return Entity index being aimed at.
|
||||
* -1 if no entity is being aimed at.
|
||||
* -2 if the function is not supported.
|
||||
* @error Invalid client index or client not in game.
|
||||
*/
|
||||
native GetClientAimTarget(client, bool:only_clients=true);
|
||||
|
||||
/**
|
||||
* Returns the total number of teams in a game.
|
||||
* Note: This native should not be called before OnMapStart.
|
||||
*
|
||||
* @return Total number of teams.
|
||||
*/
|
||||
native GetTeamCount();
|
||||
|
||||
/**
|
||||
* Retrieves the team name based on a team index.
|
||||
* Note: This native should not be called before OnMapStart.
|
||||
*
|
||||
* @param index Team index.
|
||||
* @param name Buffer to store string in.
|
||||
* @param maxlength Maximum length of string buffer.
|
||||
* @noreturn
|
||||
* @error Invalid team index.
|
||||
*/
|
||||
native GetTeamName(index, String:name[], maxlength);
|
||||
|
||||
/**
|
||||
* Returns the score of a team based on a team index.
|
||||
* Note: This native should not be called before OnMapStart.
|
||||
*
|
||||
* @param index Team index.
|
||||
* @return Score.
|
||||
* @error Invalid team index.
|
||||
*/
|
||||
native GetTeamScore(index);
|
||||
|
||||
/**
|
||||
* Sets the score of a team based on a team index.
|
||||
* Note: This native should not be called before OnMapStart.
|
||||
*
|
||||
* @param index Team index.
|
||||
* @param value New score value.
|
||||
* @return Score.
|
||||
* @error Invalid team index.
|
||||
*/
|
||||
native SetTeamScore(index, value);
|
||||
|
||||
/**
|
||||
* Retrieves the number of players in a certain team.
|
||||
* Note: This native should not be called before OnMapStart.
|
||||
*
|
||||
* @param index Team index.
|
||||
* @return Number of players in the team.
|
||||
* @error Invalid team index.
|
||||
*/
|
||||
native GetTeamClientCount(index);
|
||||
|
||||
/**
|
||||
* Sets the model to a given entity.
|
||||
*
|
||||
* @param entity Entity index.
|
||||
* @param model Model name.
|
||||
* @noreturn
|
||||
* @error Invalid entity index, or no mod support.
|
||||
*/
|
||||
native SetEntityModel(entity, const String:model[]);
|
||||
|
||||
/**
|
||||
* Retrieves the decal file name associated to a given client.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param hex Buffer to store the logo filename.
|
||||
* @param maxlength Maximum length of string buffer.
|
||||
* @return True on success, otherwise false.
|
||||
* @error Invalid client or client not in game.
|
||||
*/
|
||||
native bool:GetPlayerDecalFile(client, String:hex[], maxlength);
|
||||
|
||||
/**
|
||||
* Returns the average server network traffic in bytes/sec.
|
||||
*
|
||||
* @param in Buffer to store the input traffic velocity.
|
||||
* @param out Buffer to store the output traffic velocity.
|
||||
* @noreturn
|
||||
*/
|
||||
native GetServerNetStats(&Float:in, &Float:out);
|
||||
|
||||
/**
|
||||
* Equip's a player's weapon.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param item CBaseCombatWeapon entity index.
|
||||
* @noreturn
|
||||
* @error Invalid client or entity, lack of mod support, or client not in
|
||||
* game.
|
||||
*/
|
||||
native EquipPlayerWeapon(client, weapon);
|
||||
|
||||
/**
|
||||
* Activates an entity (CBaseAnimating::Activate)
|
||||
*
|
||||
* @param entity Entity index.
|
||||
* @noreturn
|
||||
* @error Invalid entity or lack of mod support.
|
||||
*/
|
||||
native ActivateEntity(entity);
|
||||
|
||||
/**
|
||||
* Sets values to client info buffer keys and notifies the engine of the change.
|
||||
* The change does not get propogated to mods until the next frame.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param key Key string.
|
||||
* @param value Value string.
|
||||
* @noreturn
|
||||
* @error Invalid client index, or client not connected.
|
||||
*/
|
||||
native SetClientInfo(client, const String:key[], const String:value[]);
|
||||
@@ -0,0 +1,442 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _sdktools_sound_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _sdktools_sound_included
|
||||
|
||||
/**
|
||||
* Sound should be from the target client.
|
||||
*/
|
||||
#define SOUND_FROM_PLAYER -2
|
||||
|
||||
/**
|
||||
* Sound should be from the listen server player.
|
||||
*/
|
||||
#define SOUND_FROM_LOCAL_PLAYER -1
|
||||
|
||||
/**
|
||||
* Sound is from the world.
|
||||
*/
|
||||
#define SOUND_FROM_WORLD 0
|
||||
|
||||
/**
|
||||
* Sound channels.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
SNDCHAN_REPLACE = -1, /**< Unknown */
|
||||
SNDCHAN_AUTO = 0, /**< Auto */
|
||||
SNDCHAN_WEAPON = 1, /**< Weapons */
|
||||
SNDCHAN_VOICE = 2, /**< Voices */
|
||||
SNDCHAN_ITEM = 3, /**< Items */
|
||||
SNDCHAN_BODY = 4, /**< Player? */
|
||||
SNDCHAN_STREAM = 5, /**< "Stream channel from the static or dynamic area" */
|
||||
SNDCHAN_STATIC = 6, /**< "Stream channel from the static area" */
|
||||
SNDCHAN_VOICE_BASE = 7, /**< "Channel for network voice data" */
|
||||
SNDCHAN_USER_BASE = 135 /**< Anything >= this is allocated to game code */
|
||||
};
|
||||
|
||||
/**
|
||||
* Sound flags for the sound emitter system.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
SND_NOFLAGS= 0, /**< Nothing */
|
||||
SND_CHANGEVOL = 1, /**< Change sound volume */
|
||||
SND_CHANGEPITCH = 2, /**< Change sound pitch */
|
||||
SND_STOP = 3, /**< Stop the sound */
|
||||
SND_SPAWNING = 4, /**< Used in some cases for ambients */
|
||||
SND_DELAY = 5, /**< Sound has an initial delay */
|
||||
SND_STOPLOOPING = 6, /**< Stop looping all sounds on the entity */
|
||||
SND_SPEAKER = 7, /**< Being played by a mic through a speaker */
|
||||
SND_SHOULDPAUSE = 8, /**< Pause if game is paused */
|
||||
};
|
||||
|
||||
/**
|
||||
* Various predefined sound levels in dB.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
SNDLEVEL_NONE = 0, /**< None */
|
||||
SNDLEVEL_RUSTLE = 20, /**< Rustling leaves */
|
||||
SNDLEVEL_WHISPER = 25, /**< Whispering */
|
||||
SNDLEVEL_LIBRARY = 30, /**< In a library */
|
||||
SNDLEVEL_FRIDGE = 45, /**< Refridgerator */
|
||||
SNDLEVEL_HOME = 50, /**< Average home (3.9 attn) */
|
||||
SNDLEVEL_CONVO = 60, /**< Normal conversation (2.0 attn) */
|
||||
SNDLEVEL_DRYER = 60, /**< Clothes dryer */
|
||||
SNDLEVEL_DISHWASHER = 65, /**< Dishwasher/washing machine (1.5 attn) */
|
||||
SNDLEVEL_CAR = 70, /**< Car or vacuum cleaner (1.0 attn) */
|
||||
SNDLEVEL_NORMAL = 75, /**< Normal sound level */
|
||||
SNDLEVEL_TRAFFIC = 75, /**< Busy traffic (0.8 attn) */
|
||||
SNDLEVEL_MINIBIKE = 80, /**< Mini-bike, alarm clock (0.7 attn) */
|
||||
SNDLEVEL_SCREAMING = 90, /**< Screaming child (0.5 attn) */
|
||||
SNDLEVEL_TRAIN = 100, /**< Subway train, pneumatic drill (0.4 attn) */
|
||||
SNDLEVEL_HELICOPTER = 105, /**< Helicopter */
|
||||
SNDLEVEL_SNOWMOBILE = 110, /**< Snow mobile */
|
||||
SNDLEVEL_AIRCRAFT = 120, /**< Auto horn, aircraft */
|
||||
SNDLEVEL_RAIDSIREN = 130, /**< Air raid siren */
|
||||
SNDLEVEL_GUNFIRE = 140, /**< Gunshot, jet engine (0.27 attn) */
|
||||
SNDLEVEL_ROCKET = 180, /**< Rocket launching (0.2 attn) */
|
||||
};
|
||||
|
||||
#define SNDVOL_NORMAL 1.0 /**< Normal volume */
|
||||
#define SNDPITCH_NORMAL 100 /**< Normal pitch */
|
||||
#define SNDPITCH_LOW 95 /**< A low pitch */
|
||||
#define SNDPITCH_HIGH 120 /**< A high pitch */
|
||||
#define SNDATTN_NONE 0.0 /**< No attenuation */
|
||||
#define SNDATTN_NORMAL 0.8 /**< Normal attenuation */
|
||||
#define SNDATTN_STATIC 1.25 /**< Static attenuation? */
|
||||
#define SNDATTN_RICOCHET 1.5 /**< Ricochet effect */
|
||||
#define SNDATTN_IDLE 2.0 /**< Idle attenuation? */
|
||||
|
||||
/**
|
||||
* Prefetches a sound.
|
||||
*
|
||||
* @param name Sound file name relative to the "sounds" folder.
|
||||
* @noreturn
|
||||
*/
|
||||
native PrefetchSound(const String:nane[]);
|
||||
|
||||
/**
|
||||
* This function is not known to work, and may crash. You should
|
||||
* not use it. It is provided for backwards compatibility only.
|
||||
*
|
||||
* @param name Sound file name relative to the "sounds" folder.
|
||||
* @return Duration in seconds.
|
||||
*/
|
||||
#pragma deprecated Does not work, may crash.
|
||||
native Float:GetSoundDuration(const String:name[]);
|
||||
|
||||
/**
|
||||
* Emits an ambient sound.
|
||||
*
|
||||
* @param name Sound file name relative to the "sounds" folder.
|
||||
* @param pos Origin of sound.
|
||||
* @param entity Entity index to associate sound with.
|
||||
* @param level Sound level (from 0 to 255).
|
||||
* @param flags Sound flags.
|
||||
* @param vol Volume (from 0.0 to 1.0).
|
||||
* @param pitch Pitch (from 0 to 255).
|
||||
* @param delay Play delay.
|
||||
* @noreturn
|
||||
*/
|
||||
native EmitAmbientSound(const String:name[],
|
||||
const Float:pos[3],
|
||||
entity = SOUND_FROM_WORLD,
|
||||
level = SNDLEVEL_NORMAL,
|
||||
flags = SND_NOFLAGS,
|
||||
Float:vol = SNDVOL_NORMAL,
|
||||
pitch = SNDPITCH_NORMAL,
|
||||
Float:delay = 0.0);
|
||||
|
||||
/**
|
||||
* Fades a client's volume level toward silence or a given percentage.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param percent Fade percentage.
|
||||
* @param outtime Fade out time, in seconds.
|
||||
* @param holdtime Hold time, in seconds.
|
||||
* @param intime Fade in time, in seconds.
|
||||
* @noreturn
|
||||
* @error Invalid client index or client not in game.
|
||||
*/
|
||||
native FadeClientVolume(client, Float:percent, Float:outtime, Float:holdtime, Float:intime);
|
||||
|
||||
/**
|
||||
* Stops a sound.
|
||||
*
|
||||
* @param entity Entity index.
|
||||
* @param channel Channel number.
|
||||
* @param name Sound file name relative to the "sounds" folder.
|
||||
* @noreturn
|
||||
*/
|
||||
native StopSound(entity, channel, const String:name[]);
|
||||
|
||||
/**
|
||||
* Emits a sound to a list of clients.
|
||||
*
|
||||
* @param clients Array of client indexes.
|
||||
* @param numClients Number of clients in the array.
|
||||
* @param sample Sound file name relative to the "sounds" folder.
|
||||
* @param entity Entity to emit from.
|
||||
* @param channel Channel to emit with.
|
||||
* @param level Sound level.
|
||||
* @param flags Sound flags.
|
||||
* @param volume Sound volume.
|
||||
* @param pitch Sound pitch.
|
||||
* @param speakerentity Unknown.
|
||||
* @param origin Sound origin.
|
||||
* @param dir Sound direction.
|
||||
* @param updatePos Unknown (updates positions?)
|
||||
* @param soundtime Alternate time to play sound for.
|
||||
* @param ... Optional list of Float[3] arrays to specify additional origins.
|
||||
* @noreturn
|
||||
* @error Invalid client index.
|
||||
*/
|
||||
native EmitSound(const clients[],
|
||||
numClients,
|
||||
const String:sample[],
|
||||
entity = SOUND_FROM_PLAYER,
|
||||
channel = SNDCHAN_AUTO,
|
||||
level = SNDLEVEL_NORMAL,
|
||||
flags = SND_NOFLAGS,
|
||||
Float:volume = SNDVOL_NORMAL,
|
||||
pitch = SNDPITCH_NORMAL,
|
||||
speakerentity = -1,
|
||||
const Float:origin[3] = NULL_VECTOR,
|
||||
const Float:dir[3] = NULL_VECTOR,
|
||||
bool:updatePos = true,
|
||||
Float:soundtime = 0.0,
|
||||
any:...);
|
||||
|
||||
/**
|
||||
* Emits a sentence to a list of clients.
|
||||
*
|
||||
* @param clients Array of client indexes.
|
||||
* @param numClients Number of clients in the array.
|
||||
* @param sentence Sentence index (from PrecacheSenteFile).
|
||||
* @param entity Entity to emit from.
|
||||
* @param channel Channel to emit with.
|
||||
* @param level Sound level.
|
||||
* @param flags Sound flags.
|
||||
* @param volume Sound volume.
|
||||
* @param pitch Sound pitch.
|
||||
* @param speakerentity Unknown.
|
||||
* @param origin Sound origin.
|
||||
* @param dir Sound direction.
|
||||
* @param updatePos Unknown (updates positions?)
|
||||
* @param soundtime Alternate time to play sound for.
|
||||
* @param ... Optional list of Float[3] arrays to specify additional origins.
|
||||
* @noreturn
|
||||
* @error Invalid client index.
|
||||
*/
|
||||
native EmitSentence(const clients[],
|
||||
numClients,
|
||||
sentence,
|
||||
entity,
|
||||
channel = SNDCHAN_AUTO,
|
||||
level = SNDLEVEL_NORMAL,
|
||||
flags = SND_NOFLAGS,
|
||||
Float:volume = SNDVOL_NORMAL,
|
||||
pitch = SNDPITCH_NORMAL,
|
||||
speakerentity = -1,
|
||||
const Float:origin[3] = NULL_VECTOR,
|
||||
const Float:dir[3] = NULL_VECTOR,
|
||||
bool:updatePos = true,
|
||||
Float:soundtime = 0.0,
|
||||
any:...);
|
||||
|
||||
/**
|
||||
* Called when an ambient sound is about to be emitted to one or more clients.
|
||||
*
|
||||
* NOTICE: all parameters can be overwritten to modify the default behavior.
|
||||
*
|
||||
* @param sample Sound file name relative to the "sounds" folder.
|
||||
* @param entity Entity index associated to the sound.
|
||||
* @param volume Volume (from 0.0 to 1.0).
|
||||
* @param level Sound level (from 0 to 255).
|
||||
* @param pitch Pitch (from 0 to 255).
|
||||
* @param pos Origin of sound.
|
||||
* @param flags Sound flags.
|
||||
* @param delay Play delay.
|
||||
* @return Plugin_Continue to allow the sound to be played, Plugin_Stop to block it,
|
||||
* Plugin_Changed when any parameter has been modified.
|
||||
*/
|
||||
functag AmbientSHook Action:public(String:sample[PLATFORM_MAX_PATH], &entity, &Float:volume, &level, &pitch, Float:pos[3], &flags, &Float:delay);
|
||||
|
||||
/**
|
||||
* Called when a sound is going to be emitted to one or more clients.
|
||||
* NOTICE: all params can be overwritten to modify the default behaviour.
|
||||
*
|
||||
* @param clients Array of client indexes.
|
||||
* @param numClients Number of clients in the array (modify this value if you add/remove elements from the client array).
|
||||
* @param sample Sound file name relative to the "sounds" folder.
|
||||
* @param entity Entity emitting the sound.
|
||||
* @param channel Channel emitting the sound.
|
||||
* @param volume Sound volume.
|
||||
* @param level Sound level.
|
||||
* @param pitch Sound pitch.
|
||||
* @param flags Sound flags.
|
||||
* @return Plugin_Continue to allow the sound to be played, Plugin_Stop to block it,
|
||||
* Plugin_Changed when any parameter has been modified.
|
||||
*/
|
||||
functag NormalSHook Action:public(clients[64], &numClients, String:sample[PLATFORM_MAX_PATH], &entity, &channel, &Float:volume, &level, &pitch, &flags);
|
||||
|
||||
/**
|
||||
* Hooks all played ambient sounds.
|
||||
*
|
||||
* @param hook Function to use as a hook.
|
||||
* @noreturn
|
||||
* @error Invalid function hook.
|
||||
*/
|
||||
native AddAmbientSoundHook(AmbientSHook:hook);
|
||||
|
||||
/**
|
||||
* Hooks all played normal sounds.
|
||||
*
|
||||
* @param hook Function to use as a hook.
|
||||
* @noreturn
|
||||
* @error Invalid function hook.
|
||||
*/
|
||||
native AddNormalSoundHook(NormalSHook:hook);
|
||||
|
||||
/**
|
||||
* Unhooks all played ambient sounds.
|
||||
*
|
||||
* @param hook Function used for the hook.
|
||||
* @noreturn
|
||||
* @error Invalid function hook.
|
||||
*/
|
||||
native RemoveAmbientSoundHook(AmbientSHook:hook);
|
||||
|
||||
/**
|
||||
* Unhooks all played normal sounds.
|
||||
*
|
||||
* @param hook Function used for the hook.
|
||||
* @noreturn
|
||||
* @error Invalid function hook.
|
||||
*/
|
||||
native RemoveNormalSoundHook(NormalSHook:hook);
|
||||
|
||||
/**
|
||||
* Wrapper to emit sound to one client.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param sample Sound file name relative to the "sounds" folder.
|
||||
* @param entity Entity to emit from.
|
||||
* @param channel Channel to emit with.
|
||||
* @param level Sound level.
|
||||
* @param flags Sound flags.
|
||||
* @param volume Sound volume.
|
||||
* @param pitch Sound pitch.
|
||||
* @param speakerentity Unknown.
|
||||
* @param origin Sound origin.
|
||||
* @param dir Sound direction.
|
||||
* @param updatePos Unknown (updates positions?)
|
||||
* @param soundtime Alternate time to play sound for.
|
||||
* @noreturn
|
||||
* @error Invalid client index.
|
||||
*/
|
||||
stock EmitSoundToClient(client,
|
||||
const String:sample[],
|
||||
entity = SOUND_FROM_PLAYER,
|
||||
channel = SNDCHAN_AUTO,
|
||||
level = SNDLEVEL_NORMAL,
|
||||
flags = SND_NOFLAGS,
|
||||
Float:volume = SNDVOL_NORMAL,
|
||||
pitch = SNDPITCH_NORMAL,
|
||||
speakerentity = -1,
|
||||
const Float:origin[3] = NULL_VECTOR,
|
||||
const Float:dir[3] = NULL_VECTOR,
|
||||
bool:updatePos = true,
|
||||
Float:soundtime = 0.0)
|
||||
{
|
||||
new clients[1];
|
||||
clients[0] = client;
|
||||
/* Save some work for SDKTools and remove SOUND_FROM_PLAYER references */
|
||||
entity = (entity == SOUND_FROM_PLAYER) ? client : entity;
|
||||
EmitSound(clients, 1, sample, entity, channel,
|
||||
level, flags, volume, pitch, speakerentity,
|
||||
origin, dir, updatePos, soundtime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper to emit sound to all clients.
|
||||
*
|
||||
* @param sample Sound file name relative to the "sounds" folder.
|
||||
* @param entity Entity to emit from.
|
||||
* @param channel Channel to emit with.
|
||||
* @param level Sound level.
|
||||
* @param flags Sound flags.
|
||||
* @param volume Sound volume.
|
||||
* @param pitch Sound pitch.
|
||||
* @param speakerentity Unknown.
|
||||
* @param origin Sound origin.
|
||||
* @param dir Sound direction.
|
||||
* @param updatePos Unknown (updates positions?)
|
||||
* @param soundtime Alternate time to play sound for.
|
||||
* @noreturn
|
||||
* @error Invalid client index.
|
||||
*/
|
||||
stock EmitSoundToAll(const String:sample[],
|
||||
entity = SOUND_FROM_PLAYER,
|
||||
channel = SNDCHAN_AUTO,
|
||||
level = SNDLEVEL_NORMAL,
|
||||
flags = SND_NOFLAGS,
|
||||
Float:volume = SNDVOL_NORMAL,
|
||||
pitch = SNDPITCH_NORMAL,
|
||||
speakerentity = -1,
|
||||
const Float:origin[3] = NULL_VECTOR,
|
||||
const Float:dir[3] = NULL_VECTOR,
|
||||
bool:updatePos = true,
|
||||
Float:soundtime = 0.0)
|
||||
{
|
||||
new maxClients = GetMaxClients();
|
||||
new clients[maxClients];
|
||||
new total = 0;
|
||||
|
||||
for (new i=1; i<=maxClients; i++)
|
||||
{
|
||||
if (IsClientInGame(i))
|
||||
{
|
||||
clients[total++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (!total)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EmitSound(clients, total, sample, entity, channel,
|
||||
level, flags, volume, pitch, speakerentity,
|
||||
origin, dir, updatePos, soundtime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an attenuation value to a sound level.
|
||||
* This function is from the HL2SDK.
|
||||
*
|
||||
* @param attn Attenuation value.
|
||||
* @return Integer sound level.
|
||||
*/
|
||||
stock ATTN_TO_SNDLEVEL(Float:attn)
|
||||
{
|
||||
if (attn > 0.0)
|
||||
{
|
||||
return RoundFloat(50.0 + (20.0 / attn));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _sdktools_stocks_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _sdktools_stocks_included
|
||||
|
||||
/**
|
||||
* Given a partial team name, attempts to find a matching team.
|
||||
*
|
||||
* The search is performed case insensitively and only against the
|
||||
* first N characters of the team names, where N is the number of
|
||||
* characters in the search pattern.
|
||||
*
|
||||
* @param name Partial or full team name.
|
||||
* @return A valid team index on success.
|
||||
* -1 if no team matched.
|
||||
* -2 if more than one team matched.
|
||||
*/
|
||||
stock FindTeamByName(const String:name[])
|
||||
{
|
||||
new name_len = strlen(name);
|
||||
new num_teams = GetTeamCount();
|
||||
decl String:team_name[32];
|
||||
new found_team = -1
|
||||
|
||||
for (new i = 0; i < num_teams; i++)
|
||||
{
|
||||
GetTeamName(i, team_name, sizeof(team_name));
|
||||
|
||||
if (strncmp(team_name, name, name_len) == 0)
|
||||
{
|
||||
if (found_team >= 0)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
else
|
||||
{
|
||||
found_team = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found_team;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _sdktools_stringtables_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _sdktools_stringtables_included
|
||||
|
||||
#define INVALID_STRING_TABLE -1 /**< An invalid string table index */
|
||||
#define INVALID_STRING_INDEX -1 /**< An invalid string index in a table */
|
||||
|
||||
/**
|
||||
* Searches for a string table.
|
||||
*
|
||||
* @param name Name of string table to find.
|
||||
* @return A string table index number if found, INVALID_STRING_TABLE otherwise.
|
||||
*/
|
||||
native FindStringTable(const String:name[]);
|
||||
|
||||
/**
|
||||
* Returns the number of string tables that currently exist.
|
||||
*
|
||||
* @return Number of string tables that currently exist.
|
||||
*/
|
||||
native GetNumStringTables();
|
||||
|
||||
/**
|
||||
* Returns the number of strings that currently exist in a given string table.
|
||||
*
|
||||
* @param tableidx A string table index.
|
||||
* @return Number of strings that currently exist.
|
||||
* @error Invalid string table index.
|
||||
*/
|
||||
native GetStringTableNumStrings(tableidx);
|
||||
|
||||
/**
|
||||
* Returns the maximum number of strings that are allowed in a given string table.
|
||||
*
|
||||
* @param tableidx A string table index.
|
||||
* @return Maximum number of strings allowed.
|
||||
* @error Invalid string table index.
|
||||
*/
|
||||
native GetStringTableMaxStrings(tableidx);
|
||||
|
||||
/**
|
||||
* Retrieves the name of a string table.
|
||||
*
|
||||
* @param tableidx A string table index.
|
||||
* @param name Buffer to store the name of the string table.
|
||||
* @param maxlength Maximum length of string buffer.
|
||||
* @return Number of bytes written to the buffer (UTF-8 safe).
|
||||
* @error Invalid string table index.
|
||||
*/
|
||||
native GetStringTableName(tableidx, String:name[], maxlength);
|
||||
|
||||
/**
|
||||
* Searches for the index of a given string in a string table.
|
||||
*
|
||||
* @param tableidx A string table index.
|
||||
* @param string String to find.
|
||||
* @return String index if found, INVALID_STRING_INDEX otherwise.
|
||||
* @error Invalid string table index.
|
||||
*/
|
||||
native FindStringIndex(tableidx, const String:str[]);
|
||||
|
||||
/**
|
||||
* Retrieves the string at a given index of a string table.
|
||||
*
|
||||
* @param tableidx A string table index.
|
||||
* @param stringidx A string index.
|
||||
* @param name Buffer to store the string value.
|
||||
* @param maxlength Maximum length of string buffer.
|
||||
* @return Number of bytes written to the buffer (UTF-8 safe).
|
||||
* @error Invalid string table index or string index.
|
||||
*/
|
||||
native ReadStringTable(tableidx, stringIdx, String:str[], maxlength);
|
||||
|
||||
/**
|
||||
* Returns the length of the user data associated with a given string index.
|
||||
*
|
||||
* @param tableidx A string table index.
|
||||
* @param stringidx A string index.
|
||||
* @return Length of user data. This will be 0 if there is no user data.
|
||||
* @error Invalid string table index or string index.
|
||||
*/
|
||||
native GetStringTableDataLength(tableidx, stringidx);
|
||||
|
||||
/**
|
||||
* Retrieves the user data associated with a given string index.
|
||||
*
|
||||
* @param tableidx A string table index.
|
||||
* @param stringidx A string index.
|
||||
* @param userdata Buffer to store the user data. This will be set to "" if there is no user data.
|
||||
* @param maxlength Maximum length of string buffer.
|
||||
* @return Number of bytes written to the buffer (UTF-8 safe).
|
||||
* @error Invalid string table index or string index.
|
||||
*/
|
||||
native GetStringTableData(tableidx, stringIdx, String:userdata[], maxlength);
|
||||
|
||||
/**
|
||||
* Sets the user data associated with a given string index.
|
||||
*
|
||||
* @param tableidx A string table index.
|
||||
* @param stringidx A string index.
|
||||
* @param userdata User data string that will be set.
|
||||
* @param length Length of user data string. This should include the null terminator.
|
||||
* @return Number of bytes written to the buffer (UTF-8 safe).
|
||||
* @error Invalid string table index or string index.
|
||||
*/
|
||||
native SetStringTableData(tableidx, stringIdx, const String:userdata[], length);
|
||||
|
||||
/**
|
||||
* Adds a string to a given string table.
|
||||
*
|
||||
* @param tableidx A string table index.
|
||||
* @param string String to add.
|
||||
* @param userdata An optional user data string.
|
||||
* @param length Length of user data string. This should include the null terminator.
|
||||
* If set to -1, then user data will be not be altered if the specified string
|
||||
* already exists in the string table.
|
||||
*/
|
||||
native AddToStringTable(tableidx, const String:str[], const String:userdata[]="", length=-1);
|
||||
|
||||
/**
|
||||
* Locks or unlocks the network string tables.
|
||||
*
|
||||
* @param lock Determines whether network string tables should be locked.
|
||||
* True means the tables should be locked for writing; false means unlocked.
|
||||
* @return Previous lock state.
|
||||
*/
|
||||
native bool:LockStringTables(bool:lock);
|
||||
|
||||
/**
|
||||
* Adds a file to the downloadables network string table.
|
||||
* This forces a client to download the file if they do not already have it.
|
||||
*
|
||||
* @param filename File that will be added to downloadables table.
|
||||
*/
|
||||
stock AddFileToDownloadsTable(const String:filename[])
|
||||
{
|
||||
static table = INVALID_STRING_TABLE;
|
||||
|
||||
if (table == INVALID_STRING_TABLE)
|
||||
{
|
||||
table = FindStringTable("downloadables");
|
||||
}
|
||||
|
||||
new bool:save = LockStringTables(false);
|
||||
AddToStringTable(table, filename);
|
||||
LockStringTables(save);
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _sdktools_tempents_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _sdktools_tempents_included
|
||||
|
||||
/**
|
||||
* Called when a temp entity is going to be sent.
|
||||
*
|
||||
* @param te_name TE name.
|
||||
* @param Players Array containing target player indexes.
|
||||
* @param numClients Number of players in the array.
|
||||
* @param delay Delay in seconds to send the TE.
|
||||
* @return Plugin_Continue to allow the transmission of the TE, Plugin_Stop to block it.
|
||||
*/
|
||||
functag TEHook Action:public(const String:te_name[], const Players[], numClients, Float:delay);
|
||||
|
||||
/**
|
||||
* Hooks a temp entity.
|
||||
*
|
||||
* @param te_name TE name to hook.
|
||||
* @param hook Function to use as a hook.
|
||||
* @noreturn
|
||||
* @error Temp Entity name not available or invalid function hook.
|
||||
*/
|
||||
native AddTempEntHook(const String:te_name[], TEHook:hook);
|
||||
|
||||
/**
|
||||
* Removes a temp entity hook.
|
||||
*
|
||||
* @param te_name TE name to unhook.
|
||||
* @param hook Function used for the hook.
|
||||
* @noreturn
|
||||
* @error Temp Entity name not available or invalid function hook.
|
||||
*/
|
||||
native RemoveTempEntHook(const String:te_name[], TEHook:hook);
|
||||
|
||||
/**
|
||||
* Starts a temp entity transmission.
|
||||
*
|
||||
* @param te_name TE name.
|
||||
* @noreturn
|
||||
* @error Temp Entity name not available.
|
||||
*/
|
||||
native TE_Start(const String:te_name[]);
|
||||
|
||||
/**
|
||||
* Checks if a certain TE property exists.
|
||||
*
|
||||
* @param prop Property to use.
|
||||
* @return True if the property exists, otherwise false.
|
||||
*/
|
||||
native bool:TE_IsValidProp(const String:prop[]);
|
||||
|
||||
/**
|
||||
* Sets an integer value in the current temp entity.
|
||||
*
|
||||
* @param prop Property to use.
|
||||
* @param value Integer value to set.
|
||||
* @noreturn
|
||||
* @error Property not found.
|
||||
*/
|
||||
native TE_WriteNum(const String:prop[], value);
|
||||
|
||||
/**
|
||||
* Reads an integer value in the current temp entity.
|
||||
*
|
||||
* @param prop Property to use.
|
||||
* @return Property value.
|
||||
* @error Property not found.
|
||||
*/
|
||||
native TE_ReadNum(const String:prop[]);
|
||||
|
||||
/**
|
||||
* Sets a floating point number in the current temp entity.
|
||||
*
|
||||
* @param prop Property to use.
|
||||
* @param value Floating point number to set.
|
||||
* @noreturn
|
||||
* @error Property not found.
|
||||
*/
|
||||
native TE_WriteFloat(const String:prop[], Float:value);
|
||||
|
||||
/**
|
||||
* Reads a floating point number in the current temp entity.
|
||||
*
|
||||
* @param prop Property to use.
|
||||
* @noreturn Property value.
|
||||
* @error Property not found.
|
||||
*/
|
||||
native Float:TE_ReadFloat(const String:prop[]);
|
||||
|
||||
/**
|
||||
* Sets a vector in the current temp entity.
|
||||
*
|
||||
* @param prop Property to use.
|
||||
* @param vector Vector to set.
|
||||
* @noreturn
|
||||
* @error Property not found.
|
||||
*/
|
||||
native TE_WriteVector(const String:prop[], const Float:vector[3]);
|
||||
|
||||
/**
|
||||
* Reads a vector in the current temp entity.
|
||||
*
|
||||
* @param prop Property to use.
|
||||
* @param vector Vector to read.
|
||||
* @noreturn
|
||||
* @error Property not found.
|
||||
*/
|
||||
native TE_ReadVector(const String:prop[], Float:vector[3]);
|
||||
|
||||
/**
|
||||
* Sets a QAngle in the current temp entity.
|
||||
*
|
||||
* @param prop Property to use.
|
||||
* @param angles Angles to set.
|
||||
* @return True on success, otherwise false.
|
||||
* @error Property not found.
|
||||
*/
|
||||
native TE_WriteAngles(const String:prop[], const Float:angles[3]);
|
||||
|
||||
/**
|
||||
* Sets an array of floats in the current temp entity.
|
||||
*
|
||||
* @param prop Property to use.
|
||||
* @param array Array of values to copy.
|
||||
* @param arraySize Number of values to copy.
|
||||
* @return True on success, otherwise false.
|
||||
* @error Property not found.
|
||||
*/
|
||||
native TE_WriteFloatArray(const String:prop[], const Float:array[], arraySize);
|
||||
|
||||
/**
|
||||
* Sends the current temp entity to one or more clients.
|
||||
*
|
||||
* @param clients Array containing player indexes to broadcast to.
|
||||
* @param numClients Number of players in the array.
|
||||
* @param delay Delay in seconds to send the TE.
|
||||
* @noreturn
|
||||
* @error Invalid client index or client not in game.
|
||||
*/
|
||||
native TE_Send(clients[], numClients, Float:delay=0.0);
|
||||
|
||||
/**
|
||||
* Sets an encoded entity index in the current temp entity.
|
||||
* (This is usually used for m_nStartEntity and m_nEndEntity).
|
||||
*
|
||||
* @param prop Property to use.
|
||||
* @param value Value to set.
|
||||
* @noreturn
|
||||
* @error Property not found.
|
||||
*/
|
||||
stock TE_WriteEncodedEnt(const String:prop[], value)
|
||||
{
|
||||
new encvalue = (value & 0x0FFF) | ((1 & 0xF)<<12);
|
||||
return TE_WriteNum(prop, encvalue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts the current temp entity to all clients.
|
||||
* @note See TE_Start().
|
||||
*
|
||||
* @param delay Delay in seconds to send the TE.
|
||||
* @noreturn
|
||||
*/
|
||||
stock TE_SendToAll(Float:delay=0.0)
|
||||
{
|
||||
new maxClients = GetMaxClients();
|
||||
new total = 0;
|
||||
new clients[maxClients];
|
||||
for (new i=1; i<=maxClients; i++)
|
||||
{
|
||||
if (IsClientInGame(i))
|
||||
{
|
||||
clients[total++] = i;
|
||||
}
|
||||
}
|
||||
return TE_Send(clients, total, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the current TE to only a client.
|
||||
* @note See TE_Start().
|
||||
*
|
||||
* @param client Client to send to.
|
||||
* @param delay Delay in seconds to send the TE.
|
||||
* @noreturn
|
||||
* @error Invalid client index or client not in game.
|
||||
*/
|
||||
stock TE_SendToClient(client, Float:delay=0.0)
|
||||
{
|
||||
new players[1];
|
||||
|
||||
players[0] = client;
|
||||
|
||||
return TE_Send(players, 1, delay);
|
||||
}
|
||||
@@ -0,0 +1,458 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _te_stocks_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _te_stocks_included
|
||||
|
||||
/**
|
||||
* @section TE Explosion flags.
|
||||
*/
|
||||
#define TE_EXPLFLAG_NONE 0x0 /**< all flags clear makes default Half-Life explosion */
|
||||
#define TE_EXPLFLAG_NOADDITIVE 0x1 /**< sprite will be drawn opaque (ensure that the sprite you send is a non-additive sprite) */
|
||||
#define TE_EXPLFLAG_NODLIGHTS 0x2 /**< do not render dynamic lights */
|
||||
#define TE_EXPLFLAG_NOSOUND 0x4 /**< do not play client explosion sound */
|
||||
#define TE_EXPLFLAG_NOPARTICLES 0x8 /**< do not draw particles */
|
||||
#define TE_EXPLFLAG_DRAWALPHA 0x10 /**< sprite will be drawn alpha */
|
||||
#define TE_EXPLFLAG_ROTATE 0x20 /**< rotate the sprite randomly */
|
||||
#define TE_EXPLFLAG_NOFIREBALL 0x40 /**< do not draw a fireball */
|
||||
#define TE_EXPLFLAG_NOFIREBALLSMOKE 0x80 /**< do not draw smoke with the fireball */
|
||||
|
||||
/**
|
||||
* @endsection
|
||||
*/
|
||||
|
||||
/**
|
||||
* @section TE Beam flags.
|
||||
*/
|
||||
#define FBEAM_STARTENTITY 0x00000001
|
||||
#define FBEAM_ENDENTITY 0x00000002
|
||||
#define FBEAM_FADEIN 0x00000004
|
||||
#define FBEAM_FADEOUT 0x00000008
|
||||
#define FBEAM_SINENOISE 0x00000010
|
||||
#define FBEAM_SOLID 0x00000020
|
||||
#define FBEAM_SHADEIN 0x00000040
|
||||
#define FBEAM_SHADEOUT 0x00000080
|
||||
#define FBEAM_ONLYNOISEONCE 0x00000100 /**< Only calculate our noise once */
|
||||
#define FBEAM_NOTILE 0x00000200
|
||||
#define FBEAM_USE_HITBOXES 0x00000400 /**< Attachment indices represent hitbox indices instead when this is set. */
|
||||
#define FBEAM_STARTVISIBLE 0x00000800 /**< Has this client actually seen this beam's start entity yet? */
|
||||
#define FBEAM_ENDVISIBLE 0x00001000 /**< Has this client actually seen this beam's end entity yet? */
|
||||
#define FBEAM_ISACTIVE 0x00002000
|
||||
#define FBEAM_FOREVER 0x00004000
|
||||
#define FBEAM_HALOBEAM 0x00008000 /**< When drawing a beam with a halo, don't ignore the segments and endwidth */
|
||||
|
||||
/**
|
||||
* @endsection
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets up a sparks effect.
|
||||
*
|
||||
* @param pos Position of the sparks.
|
||||
* @param dir Direction of the sparks.
|
||||
* @param Magnitude Sparks size.
|
||||
* @param TrailLength Trail lenght of the sparks.
|
||||
* @noreturn
|
||||
*/
|
||||
stock TE_SetupSparks(const Float:pos[3], const Float:dir[3], Magnitude, TrailLength)
|
||||
{
|
||||
TE_Start("Sparks");
|
||||
TE_WriteVector("m_vecOrigin[0]", pos);
|
||||
TE_WriteVector("m_vecDir", dir);
|
||||
TE_WriteNum("m_nMagnitude", Magnitude);
|
||||
TE_WriteNum("m_nTrailLength", TrailLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a smoke effect.
|
||||
*
|
||||
* @param pos Position of the smoke.
|
||||
* @param Model Precached model index.
|
||||
* @param Scale Scale of the smoke.
|
||||
* @param Framerate Frame rate of the smoke.
|
||||
* @noreturn
|
||||
*/
|
||||
stock TE_SetupSmoke(const Float:pos[3], Model, Float:Scale, FrameRate)
|
||||
{
|
||||
TE_Start("Smoke");
|
||||
TE_WriteVector("m_vecOrigin", pos);
|
||||
TE_WriteNum("m_nModelIndex", Model);
|
||||
TE_WriteFloat("m_fScale", Scale);
|
||||
TE_WriteNum("m_nFrameRate", FrameRate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a dust cloud effect.
|
||||
*
|
||||
* @param pos Position of the dust.
|
||||
* @param dir Direction of the dust.
|
||||
* @param Size Dust cloud size.
|
||||
* @param Speed Dust cloud speed.
|
||||
* @noreturn
|
||||
*/
|
||||
stock TE_SetupDust(const Float:pos[3], const Float:dir[3], Float:Size, Float:Speed)
|
||||
{
|
||||
TE_Start("Dust");
|
||||
TE_WriteVector("m_vecOrigin[0]", pos);
|
||||
TE_WriteVector("m_vecDirection", dir);
|
||||
TE_WriteFloat("m_flSize", Size);
|
||||
TE_WriteFloat("m_flSpeed", Speed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a muzzle flash effect.
|
||||
*
|
||||
* @param pos Position of the muzzle flash.
|
||||
* @param angles Rotation angles of the muzzle flash.
|
||||
* @param Scale Scale of the muzzle flash.
|
||||
* @param Type Muzzle flash type to render (Mod specific).
|
||||
* @noreturn
|
||||
*/
|
||||
stock TE_SetupMuzzleFlash(const Float:pos[3], const Float:angles[3], Float:Scale, Type)
|
||||
{
|
||||
TE_Start("MuzzleFlash");
|
||||
TE_WriteVector("m_vecOrigin", pos);
|
||||
TE_WriteVector("m_vecAngles", angles);
|
||||
TE_WriteFloat("m_flScale", Scale);
|
||||
TE_WriteNum("m_nType", Type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a metal sparks effect.
|
||||
*
|
||||
* @param pos Position of the metal sparks.
|
||||
* @param dir Direction of the metal sparks.
|
||||
* @noreturn
|
||||
*/
|
||||
stock TE_SetupMetalSparks(const Float:pos[3], const Float:dir[3])
|
||||
{
|
||||
TE_Start("Metal Sparks");
|
||||
TE_WriteVector("m_vecPos", pos);
|
||||
TE_WriteVector("m_vecDir", dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up an energy splash effect.
|
||||
*
|
||||
* @param pos Position of the energy splash.
|
||||
* @param dir Direction of the energy splash.
|
||||
* @param Explosive Makes the effect explosive.
|
||||
* @noreturn
|
||||
*/
|
||||
stock TE_SetupEnergySplash(const Float:pos[3], const Float:dir[3], bool:Explosive)
|
||||
{
|
||||
TE_Start("Energy Splash");
|
||||
TE_WriteVector("m_vecPos", pos);
|
||||
TE_WriteVector("m_vecDir", dir);
|
||||
TE_WriteNum("m_bExplosive", Explosive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up an armor ricochet effect.
|
||||
*
|
||||
* @param pos Position of the armor ricochet.
|
||||
* @param dir Directon of the armor ricochet.
|
||||
* @noreturn
|
||||
*/
|
||||
stock TE_SetupArmorRicochet(const Float:pos[3], const Float:dir[3])
|
||||
{
|
||||
TE_Start("Armor Ricochet");
|
||||
TE_WriteVector("m_vecPos", pos);
|
||||
TE_WriteVector("m_vecDir", dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a glowing sprite effect.
|
||||
*
|
||||
* @param pos Position of the sprite.
|
||||
* @param Model Precached model index.
|
||||
* @param Life Time duration of the sprite.
|
||||
* @param Size Sprite size.
|
||||
* @param Brightness Sprite brightness.
|
||||
* @noreturn
|
||||
*/
|
||||
stock TE_SetupGlowSprite(const Float:pos[3], Model, Float:Life, Float:Size, Brightness)
|
||||
{
|
||||
TE_Start("GlowSprite");
|
||||
TE_WriteVector("m_vecOrigin", pos);
|
||||
TE_WriteNum("m_nModelIndex", Model);
|
||||
TE_WriteFloat("m_fScale", Size);
|
||||
TE_WriteFloat("m_fLife", Life);
|
||||
TE_WriteNum("m_nBrightness", Brightness);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a explosion effect.
|
||||
*
|
||||
* @param pos Explosion position.
|
||||
* @param Model Precached model index.
|
||||
* @param Scale Explosion scale.
|
||||
* @param Framerate Explosion frame rate.
|
||||
* @param Flags Explosion flags.
|
||||
* @param Radius Explosion radius.
|
||||
* @param Magnitude Explosion size.
|
||||
* @param normal Normal vector to the explosion.
|
||||
* @param MaterialType Exploded material type.
|
||||
* @noreturn
|
||||
*/
|
||||
stock TE_SetupExplosion(const Float:pos[3], Model, Float:Scale, Framerate, Flags, Radius, Magnitude, const Float:normal[3]={0.0, 0.0, 1.0}, MaterialType='C')
|
||||
{
|
||||
TE_Start("Explosion");
|
||||
TE_WriteVector("m_vecOrigin[0]", pos);
|
||||
TE_WriteVector("m_vecNormal", normal);
|
||||
TE_WriteNum("m_nModelIndex", Model);
|
||||
TE_WriteFloat("m_fScale", Scale);
|
||||
TE_WriteNum("m_nFrameRate", Framerate);
|
||||
TE_WriteNum("m_nFlags", Flags);
|
||||
TE_WriteNum("m_nRadius", Radius);
|
||||
TE_WriteNum("m_nMagnitude", Magnitude);
|
||||
TE_WriteNum("m_chMaterialType", MaterialType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a blood sprite effect.
|
||||
*
|
||||
* @param pos Position of the sprite.
|
||||
* @param dir Sprite direction.
|
||||
* @param color Color array (r, g, b, a).
|
||||
* @param Size Sprite size.
|
||||
* @param SprayModel Precached model index.
|
||||
* @param BloodDropModel Precached model index.
|
||||
* @noreturn
|
||||
*/
|
||||
stock TE_SetupBloodSprite(const Float:pos[3], const Float:dir[3], const color[4], Size, SprayModel, BloodDropModel)
|
||||
{
|
||||
TE_Start("Blood Sprite");
|
||||
TE_WriteVector("m_vecOrigin", pos);
|
||||
TE_WriteVector("m_vecDirection", dir);
|
||||
TE_WriteNum("r", color[0]);
|
||||
TE_WriteNum("g", color[1]);
|
||||
TE_WriteNum("b", color[2]);
|
||||
TE_WriteNum("a", color[3]);
|
||||
TE_WriteNum("m_nSize", Size);
|
||||
TE_WriteNum("m_nSprayModel", SprayModel);
|
||||
TE_WriteNum("m_nDropModel", BloodDropModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a beam ring point effect.
|
||||
*
|
||||
* @param center Center position of the ring.
|
||||
* @param Start_Radius Initial ring radius.
|
||||
* @param End_Radius Final ring radius.
|
||||
* @param ModelIndex Precached model index.
|
||||
* @param HaloIndex Precached model index.
|
||||
* @param StartFrame Initital frame to render.
|
||||
* @param FrameRate Ring frame rate.
|
||||
* @param Life Time duration of the ring.
|
||||
* @param Width Beam width.
|
||||
* @param Amplitude Beam amplitude.
|
||||
* @param color Color array (r, g, b, a).
|
||||
* @param Speed Speed of the beam.
|
||||
* @param Flags Beam flags.
|
||||
* @noreturn
|
||||
*/
|
||||
stock TE_SetupBeamRingPoint(const Float:center[3], Float:Start_Radius, Float:End_Radius, ModelIndex, HaloIndex, StartFrame,
|
||||
FrameRate, Float:Life, Float:Width, Float:Amplitude, const Color[4], Speed, Flags)
|
||||
{
|
||||
TE_Start("BeamRingPoint");
|
||||
TE_WriteVector("m_vecCenter", center);
|
||||
TE_WriteFloat("m_flStartRadius", Start_Radius);
|
||||
TE_WriteFloat("m_flEndRadius", End_Radius);
|
||||
TE_WriteNum("m_nModelIndex", ModelIndex);
|
||||
TE_WriteNum("m_nHaloIndex", HaloIndex);
|
||||
TE_WriteNum("m_nStartFrame", StartFrame);
|
||||
TE_WriteNum("m_nFrameRate", FrameRate);
|
||||
TE_WriteFloat("m_fLife", Life);
|
||||
TE_WriteFloat("m_fWidth", Width);
|
||||
TE_WriteFloat("m_fEndWidth", Width);
|
||||
TE_WriteFloat("m_fAmplitude", Amplitude);
|
||||
TE_WriteNum("r", Color[0]);
|
||||
TE_WriteNum("g", Color[1]);
|
||||
TE_WriteNum("b", Color[2]);
|
||||
TE_WriteNum("a", Color[3]);
|
||||
TE_WriteNum("m_nSpeed", Speed);
|
||||
TE_WriteNum("m_nFlags", Flags);
|
||||
TE_WriteNum("m_nFadeLength", 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a point to point beam effect.
|
||||
*
|
||||
* @param start Start position of the beam.
|
||||
* @param end End position of the beam.
|
||||
* @param ModelIndex Precached model index.
|
||||
* @param HaloIndex Precached model index.
|
||||
* @param StartFrame Initital frame to render.
|
||||
* @param FrameRate Beam frame rate.
|
||||
* @param Life Time duration of the beam.
|
||||
* @param Width Initial beam width.
|
||||
* @param EndWidth Final beam width.
|
||||
* @param FadeLength Beam fade time duration.
|
||||
* @param Amplitude Beam amplitude.
|
||||
* @param color Color array (r, g, b, a).
|
||||
* @param Speed Speed of the beam.
|
||||
* @noreturn
|
||||
*/
|
||||
stock TE_SetupBeamPoints(const Float:start[3], const Float:end[3], ModelIndex, HaloIndex, StartFrame, FrameRate, Float:Life,
|
||||
Float:Width, Float:EndWidth, FadeLength, Float:Amplitude, const Color[4], Speed)
|
||||
{
|
||||
TE_Start("BeamPoints");
|
||||
TE_WriteVector("m_vecStartPoint", start);
|
||||
TE_WriteVector("m_vecEndPoint", end);
|
||||
TE_WriteNum("m_nModelIndex", ModelIndex);
|
||||
TE_WriteNum("m_nHaloIndex", HaloIndex);
|
||||
TE_WriteNum("m_nStartFrame", StartFrame);
|
||||
TE_WriteNum("m_nFrameRate", FrameRate);
|
||||
TE_WriteFloat("m_fLife", Life);
|
||||
TE_WriteFloat("m_fWidth", Width);
|
||||
TE_WriteFloat("m_fEndWidth", EndWidth);
|
||||
TE_WriteFloat("m_fAmplitude", Amplitude);
|
||||
TE_WriteNum("r", Color[0]);
|
||||
TE_WriteNum("g", Color[1]);
|
||||
TE_WriteNum("b", Color[2]);
|
||||
TE_WriteNum("a", Color[3]);
|
||||
TE_WriteNum("m_nSpeed", Speed);
|
||||
TE_WriteNum("m_nFadeLength", FadeLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up an entity to entity laser effect.
|
||||
*
|
||||
* @param StartEntity Entity index from where the beam starts.
|
||||
* @param EndEntity Entity index from where the beam ends.
|
||||
* @param ModelIndex Precached model index.
|
||||
* @param HaloIndex Precached model index.
|
||||
* @param StartFrame Initital frame to render.
|
||||
* @param FrameRate Beam frame rate.
|
||||
* @param Life Time duration of the beam.
|
||||
* @param Width Initial beam width.
|
||||
* @param EndWidth Final beam width.
|
||||
* @param FadeLength Beam fade time duration.
|
||||
* @param Amplitude Beam amplitude.
|
||||
* @param color Color array (r, g, b, a).
|
||||
* @param Speed Speed of the beam.
|
||||
* @noreturn
|
||||
*/
|
||||
stock TE_SetupBeamLaser(StartEntity, EndEntity, ModelIndex, HaloIndex, StartFrame, FrameRate, Float:Life,
|
||||
Float:Width, Float:EndWidth, FadeLength, Float:Amplitude, const Color[4], Speed)
|
||||
{
|
||||
TE_Start("BeamLaser");
|
||||
TE_WriteEncodedEnt("m_nStartEntity", StartEntity);
|
||||
TE_WriteEncodedEnt("m_nEndEntity", EndEntity);
|
||||
TE_WriteNum("m_nModelIndex", ModelIndex);
|
||||
TE_WriteNum("m_nHaloIndex", HaloIndex);
|
||||
TE_WriteNum("m_nStartFrame", StartFrame);
|
||||
TE_WriteNum("m_nFrameRate", FrameRate);
|
||||
TE_WriteFloat("m_fLife", Life);
|
||||
TE_WriteFloat("m_fWidth", Width);
|
||||
TE_WriteFloat("m_fEndWidth", EndWidth);
|
||||
TE_WriteFloat("m_fAmplitude", Amplitude);
|
||||
TE_WriteNum("r", Color[0]);
|
||||
TE_WriteNum("g", Color[1]);
|
||||
TE_WriteNum("b", Color[2]);
|
||||
TE_WriteNum("a", Color[3]);
|
||||
TE_WriteNum("m_nSpeed", Speed);
|
||||
TE_WriteNum("m_nFadeLength", FadeLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a beam ring effect.
|
||||
*
|
||||
* @param StartEntity Entity index from where the ring starts.
|
||||
* @param EndEntity Entity index from where the ring ends.
|
||||
* @param ModelIndex Precached model index.
|
||||
* @param HaloIndex Precached model index.
|
||||
* @param StartFrame Initital frame to render.
|
||||
* @param FrameRate Ring frame rate.
|
||||
* @param Life Time duration of the ring.
|
||||
* @param Width Beam width.
|
||||
* @param Amplitude Beam amplitude.
|
||||
* @param color Color array (r, g, b, a).
|
||||
* @param Speed Speed of the beam.
|
||||
* @param Flags Beam flags.
|
||||
* @noreturn
|
||||
*/
|
||||
stock TE_SetupBeamRing(StartEntity, EndEntity, ModelIndex, HaloIndex, StartFrame, FrameRate, Float:Life, Float:Width, Float:Amplitude, const Color[4], Speed, Flags)
|
||||
{
|
||||
TE_Start("BeamRing");
|
||||
TE_WriteEncodedEnt("m_nStartEntity", StartEntity);
|
||||
TE_WriteEncodedEnt("m_nEndEntity", EndEntity);
|
||||
TE_WriteNum("m_nModelIndex", ModelIndex);
|
||||
TE_WriteNum("m_nHaloIndex", HaloIndex);
|
||||
TE_WriteNum("m_nStartFrame", StartFrame);
|
||||
TE_WriteNum("m_nFrameRate", FrameRate);
|
||||
TE_WriteFloat("m_fLife", Life);
|
||||
TE_WriteFloat("m_fWidth", Width);
|
||||
TE_WriteFloat("m_fEndWidth", Width);
|
||||
TE_WriteFloat("m_fAmplitude", Amplitude);
|
||||
TE_WriteNum("r", Color[0]);
|
||||
TE_WriteNum("g", Color[1]);
|
||||
TE_WriteNum("b", Color[2]);
|
||||
TE_WriteNum("a", Color[3]);
|
||||
TE_WriteNum("m_nSpeed", Speed);
|
||||
TE_WriteNum("m_nFadeLength", 0);
|
||||
TE_WriteNum("m_nFlags", Flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a follow beam effect.
|
||||
*
|
||||
* @param EntIndex Entity index from where the beam starts.
|
||||
* @param ModelIndex Precached model index.
|
||||
* @param HaloIndex Precached model index.
|
||||
* @param Life Time duration of the beam.
|
||||
* @param Width Initial beam width.
|
||||
* @param EndWidth Final beam width.
|
||||
* @param FadeLength Beam fade time duration.
|
||||
* @param color Color array (r, g, b, a).
|
||||
* @noreturn
|
||||
*/
|
||||
stock TE_SetupBeamFollow(EntIndex, ModelIndex, HaloIndex, Float:Life, Float:Width, Float:EndWidth, FadeLength, const Color[4])
|
||||
{
|
||||
TE_Start("BeamFollow");
|
||||
TE_WriteEncodedEnt("m_iEntIndex", EntIndex);
|
||||
TE_WriteNum("m_nModelIndex", ModelIndex);
|
||||
TE_WriteNum("m_nHaloIndex", HaloIndex);
|
||||
TE_WriteNum("m_nStartFrame", 0);
|
||||
TE_WriteNum("m_nFrameRate", 0);
|
||||
TE_WriteFloat("m_fLife", Life);
|
||||
TE_WriteFloat("m_fWidth", Width);
|
||||
TE_WriteFloat("m_fEndWidth", EndWidth);
|
||||
TE_WriteNum("m_nFadeLength", FadeLength);
|
||||
TE_WriteNum("r", Color[0]);
|
||||
TE_WriteNum("g", Color[1]);
|
||||
TE_WriteNum("b", Color[2]);
|
||||
TE_WriteNum("a", Color[3]);
|
||||
}
|
||||
@@ -0,0 +1,367 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _sdktools_trace_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _sdktools_trace_included
|
||||
|
||||
#define CONTENTS_EMPTY 0 /**< No contents. */
|
||||
#define CONTENTS_SOLID 0x1 /**< an eye is never valid in a solid . */
|
||||
#define CONTENTS_WINDOW 0x2 /**< translucent, but not watery (glass). */
|
||||
#define CONTENTS_AUX 0x4
|
||||
#define CONTENTS_GRATE 0x8 /**< alpha-tested "grate" textures. Bullets/sight pass through, but solids don't. */
|
||||
#define CONTENTS_SLIME 0x10
|
||||
#define CONTENTS_WATER 0x20
|
||||
#define CONTENTS_MIST 0x40
|
||||
#define CONTENTS_OPAQUE 0x80 /**< things that cannot be seen through (may be non-solid though). */
|
||||
#define LAST_VISIBLE_CONTENTS 0x80
|
||||
#define ALL_VISIBLE_CONTENTS (LAST_VISIBLE_CONTENTS | (LAST_VISIBLE_CONTENTS-1))
|
||||
#define CONTENTS_TESTFOGVOLUME 0x100
|
||||
#define CONTENTS_UNUSED5 0x200
|
||||
#define CONTENTS_UNUSED6 0x4000
|
||||
#define CONTENTS_TEAM1 0x800 /**< per team contents used to differentiate collisions. */
|
||||
#define CONTENTS_TEAM2 0x1000 /**< between players and objects on different teams. */
|
||||
#define CONTENTS_IGNORE_NODRAW_OPAQUE 0x2000 /**< ignore CONTENTS_OPAQUE on surfaces that have SURF_NODRAW. */
|
||||
#define CONTENTS_MOVEABLE 0x4000 /**< hits entities which are MOVETYPE_PUSH (doors, plats, etc) */
|
||||
#define CONTENTS_AREAPORTAL 0x8000 /**< remaining contents are non-visible, and don't eat brushes. */
|
||||
#define CONTENTS_PLAYERCLIP 0x10000
|
||||
#define CONTENTS_MONSTERCLIP 0x20000
|
||||
|
||||
/**
|
||||
* @section currents can be added to any other contents, and may be mixed
|
||||
*/
|
||||
#define CONTENTS_CURRENT_0 0x40000
|
||||
#define CONTENTS_CURRENT_90 0x80000
|
||||
#define CONTENTS_CURRENT_180 0x100000
|
||||
#define CONTENTS_CURRENT_270 0x200000
|
||||
#define CONTENTS_CURRENT_UP 0x400000
|
||||
#define CONTENTS_CURRENT_DOWN 0x800000
|
||||
|
||||
/**
|
||||
* @endsection
|
||||
*/
|
||||
|
||||
#define CONTENTS_ORIGIN 0x1000000 /**< removed before bsping an entity. */
|
||||
#define CONTENTS_MONSTER 0x2000000 /**< should never be on a brush, only in game. */
|
||||
#define CONTENTS_DEBRIS 0x4000000
|
||||
#define CONTENTS_DETAIL 0x8000000 /**< brushes to be added after vis leafs. */
|
||||
#define CONTENTS_TRANSLUCENT 0x10000000 /**< auto set if any surface has trans. */
|
||||
#define CONTENTS_LADDER 0x20000000
|
||||
#define CONTENTS_HITBOX 0x40000000 /**< use accurate hitboxes on trace. */
|
||||
|
||||
/**
|
||||
* @section Trace masks.
|
||||
*/
|
||||
#define MASK_ALL (0xFFFFFFFF)
|
||||
#define MASK_SOLID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE) /**< everything that is normally solid */
|
||||
#define MASK_PLAYERSOLID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE) /**< everything that blocks player movement */
|
||||
#define MASK_NPCSOLID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE) /**< blocks npc movement */
|
||||
#define MASK_WATER (CONTENTS_WATER|CONTENTS_MOVEABLE|CONTENTS_SLIME) /**< water physics in these contents */
|
||||
#define MASK_OPAQUE (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_OPAQUE) /**< everything that blocks line of sight for AI, lighting, etc */
|
||||
#define MASK_OPAQUE_AND_NPCS (MASK_OPAQUE|CONTENTS_MONSTER) /**< everything that blocks line of sight for AI, lighting, etc, but with monsters added. */
|
||||
#define MASK_VISIBLE (MASK_OPAQUE|CONTENTS_IGNORE_NODRAW_OPAQUE) /**< everything that blocks line of sight for players */
|
||||
#define MASK_VISIBLE_AND_NPCS (MASK_OPAQUE_AND_NPCS|CONTENTS_IGNORE_NODRAW_OPAQUE) /**< everything that blocks line of sight for players, but with monsters added. */
|
||||
#define MASK_SHOT (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_HITBOX) /**< bullets see these as solid */
|
||||
#define MASK_SHOT_HULL (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_GRATE) /**< non-raycasted weapons see this as solid (includes grates) */
|
||||
#define MASK_SHOT_PORTAL (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW) /**< hits solids (not grates) and passes through everything else */
|
||||
#define MASK_SOLID_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_GRATE) /**< everything normally solid, except monsters (world+brush only) */
|
||||
#define MASK_PLAYERSOLID_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_PLAYERCLIP|CONTENTS_GRATE) /**< everything normally solid for player movement, except monsters (world+brush only) */
|
||||
#define MASK_NPCSOLID_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE) /**< everything normally solid for npc movement, except monsters (world+brush only) */
|
||||
#define MASK_NPCWORLDSTATIC (CONTENTS_SOLID|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE) /**< just the world, used for route rebuilding */
|
||||
#define MASK_SPLITAREAPORTAL (CONTENTS_WATER|CONTENTS_SLIME) /**< These are things that can split areaportals */
|
||||
|
||||
/**
|
||||
* @endsection
|
||||
*/
|
||||
|
||||
enum RayType
|
||||
{
|
||||
RayType_EndPoint, /**< The trace ray will go from the start position to the end position. */
|
||||
RayType_Infinite /**< The trace ray will go from the start position to infinity using a direction vector. */
|
||||
};
|
||||
|
||||
funcenum TraceEntityFilter
|
||||
{
|
||||
/**
|
||||
* Called on entity filtering.
|
||||
*
|
||||
* @param entity Entity index.
|
||||
* @param contentsMask Contents Mask.
|
||||
* @return True to allow the current entity to be hit, otherwise false.
|
||||
*/
|
||||
bool:public(entity, contentsMask),
|
||||
|
||||
/**
|
||||
* Called on entity filtering.
|
||||
*
|
||||
* @param entity Entity index.
|
||||
* @param contentsMask Contents Mask.
|
||||
* @param data Data value, if used.
|
||||
* @return True to allow the current entity to be hit, otherwise false.
|
||||
*/
|
||||
bool:public(entity, contentsMask, any:data),
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the contents mask and the entity index at the given position.
|
||||
*
|
||||
* @param pos World position to test.
|
||||
* @param entindex Entity index found at the given position (by reference).
|
||||
* @return Contents mask.
|
||||
*/
|
||||
native TR_GetPointContents(const Float:pos[3], &entindex=-1);
|
||||
|
||||
/**
|
||||
* Get the point contents testing only the given entity index.
|
||||
*
|
||||
* @param entindex Entity index to test.
|
||||
* @param pos World position.
|
||||
* @return Contents mask.
|
||||
*/
|
||||
native TR_GetPointContentsEnt(entindex, const Float:pos[3]);
|
||||
|
||||
/**
|
||||
* Starts up a new trace ray using a global trace result.
|
||||
*
|
||||
* @param pos Starting position of the ray.
|
||||
* @param vec Depending on RayType, it will be used as the
|
||||
* ending point, or the direction angle.
|
||||
* @param flags Trace flags.
|
||||
* @param rtype Method to calculate the ray direction.
|
||||
* @noreturn
|
||||
*/
|
||||
native TR_TraceRay(const Float:pos[3],
|
||||
const Float:vec[3],
|
||||
flags,
|
||||
RayType:rtype);
|
||||
|
||||
/**
|
||||
* Starts up a new trace hull using a global trace result.
|
||||
*
|
||||
* @param pos Starting position of the ray.
|
||||
* @param vec Ending position of the ray.
|
||||
* @param mins Hull minimum size.
|
||||
* @param maxs Hull maximum size.
|
||||
* @param flags Trace flags.
|
||||
* @noreturn
|
||||
*/
|
||||
native TR_TraceHull(const Float:pos[3],
|
||||
const Float:vec[3],
|
||||
const Float:mins[3],
|
||||
const Float:maxs[3],
|
||||
flags);
|
||||
|
||||
/**
|
||||
* Starts up a new trace ray using a global trace result and a customized
|
||||
* trace ray filter.
|
||||
*
|
||||
* Calling TR_Trace*Filter or TR_Trace*FilterEx from inside a filter
|
||||
* function is currently not allowed and may not work.
|
||||
*
|
||||
* @param pos Starting position of the ray.
|
||||
* @param vec Depending on RayType, it will be used as the ending
|
||||
* point, or the direction angle.
|
||||
* @param flags Trace flags.
|
||||
* @param rtype Method to calculate the ray direction.
|
||||
* @param filter Function to use as a filter.
|
||||
* @param data Arbitrary data value to pass through to the filter
|
||||
* function.
|
||||
* @noreturn
|
||||
*/
|
||||
native TR_TraceRayFilter(const Float:pos[3],
|
||||
const Float:vec[3],
|
||||
flags,
|
||||
RayType:rtype,
|
||||
TraceEntityFilter:filter,
|
||||
any:data=0);
|
||||
|
||||
/**
|
||||
* Starts up a new trace hull using a global trace result and a customized
|
||||
* trace ray filter.
|
||||
*
|
||||
* Calling TR_Trace*Filter or TR_Trace*FilterEx from inside a filter
|
||||
* function is currently not allowed and may not work.
|
||||
*
|
||||
* @param pos Starting position of the ray.
|
||||
* @param vec Depending on RayType, it will be used as the ending
|
||||
* point, or the direction angle.
|
||||
* @param mins Hull minimum size.
|
||||
* @param maxs Hull maximum size.
|
||||
* @param flags Trace flags.
|
||||
* @param filter Function to use as a filter.
|
||||
* @param data Arbitrary data value to pass through to the filter
|
||||
* function.
|
||||
* @noreturn
|
||||
*/
|
||||
native TR_TraceHullFilter(const Float:pos[3],
|
||||
const Float:vec[3],
|
||||
const Float:mins[3],
|
||||
const Float:maxs[3],
|
||||
flags,
|
||||
TraceEntityFilter:filter,
|
||||
any:data=0);
|
||||
|
||||
/**
|
||||
* Starts up a new trace ray using a new trace result.
|
||||
*
|
||||
* @param pos Starting position of the ray.
|
||||
* @param vec Depending on RayType, it will be used as the ending
|
||||
* point, or the direction angle.
|
||||
* @param flags Trace flags.
|
||||
* @param rtype Method to calculate the ray direction.
|
||||
* @return Ray trace handle, which must be closed via CloseHandle().
|
||||
*/
|
||||
native Handle:TR_TraceRayEx(const Float:pos[3],
|
||||
const Float:vec[3],
|
||||
flags,
|
||||
RayType:rtype);
|
||||
|
||||
/**
|
||||
* Starts up a new trace hull using a new trace result.
|
||||
*
|
||||
* @param pos Starting position of the ray.
|
||||
* @param vec Ending position of the ray.
|
||||
* @param mins Hull minimum size.
|
||||
* @param maxs Hull maximum size.
|
||||
* @param flags Trace flags.
|
||||
* @return Ray trace handle, which must be closed via CloseHandle().
|
||||
*/
|
||||
native Handle:TR_TraceHullEx(const Float:pos[3],
|
||||
const Float:vec[3],
|
||||
const Float:mins[3],
|
||||
const Float:maxs[3],
|
||||
flags);
|
||||
|
||||
/**
|
||||
* Starts up a new trace ray using a new trace result and a customized
|
||||
* trace ray filter.
|
||||
*
|
||||
* Calling TR_Trace*Filter or TR_TraceRay*Ex from inside a filter
|
||||
* function is currently not allowed and may not work.
|
||||
*
|
||||
* @param pos Starting position of the ray.
|
||||
* @param vec Depending on RayType, it will be used as the ending
|
||||
* point, or the direction angle.
|
||||
* @param flags Trace flags.
|
||||
* @param rtype Method to calculate the ray direction.
|
||||
* @param filter Function to use as a filter.
|
||||
* @param data Arbitrary data value to pass through to the filter function.
|
||||
* @return Ray trace handle, which must be closed via CloseHandle().
|
||||
*/
|
||||
native Handle:TR_TraceRayFilterEx(const Float:pos[3],
|
||||
const Float:vec[3],
|
||||
flags,
|
||||
RayType:rtype,
|
||||
TraceEntityFilter:filter,
|
||||
any:data=0);
|
||||
|
||||
/**
|
||||
* Starts up a new trace hull using a new trace result and a customized
|
||||
* trace ray filter.
|
||||
*
|
||||
* Calling TR_Trace*Filter or TR_Trace*FilterEx from inside a filter
|
||||
* function is currently not allowed and may not work.
|
||||
*
|
||||
* @param pos Starting position of the ray.
|
||||
* @param vec Ending position of the ray.
|
||||
* @param mins Hull minimum size.
|
||||
* @param maxs Hull maximum size.
|
||||
* @param flags Trace flags.
|
||||
* @param filter Function to use as a filter.
|
||||
* @param data Arbitrary data value to pass through to the filter function.
|
||||
* @return Ray trace handle, which must be closed via CloseHandle().
|
||||
*/
|
||||
native Handle:TR_TraceHullFilterEx(const Float:pos[3],
|
||||
const Float:vec[3],
|
||||
const Float:mins[3],
|
||||
const Float:maxs[3],
|
||||
flags,
|
||||
TraceEntityFilter:filter,
|
||||
any:data=0);
|
||||
|
||||
/**
|
||||
* Returns the time fraction from a trace result (1.0 means no collision).
|
||||
*
|
||||
* @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result.
|
||||
* @return Time fraction value of the trace.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native Float:TR_GetFraction(Handle:hndl=INVALID_HANDLE);
|
||||
|
||||
/**
|
||||
* Returns the collision position of a trace result.
|
||||
*
|
||||
* @param pos Vector buffer to store data in.
|
||||
* @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native TR_GetEndPosition(Float:pos[3], Handle:hndl=INVALID_HANDLE);
|
||||
|
||||
/**
|
||||
* Returns the entity index that collided with the trace.
|
||||
*
|
||||
* @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result.
|
||||
* @return Entity index or -1 for no collision.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native TR_GetEntityIndex(Handle:hndl=INVALID_HANDLE);
|
||||
|
||||
/**
|
||||
* Returns if there was any kind of collision along the trace ray.
|
||||
*
|
||||
* @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result.
|
||||
* @return True if any collision found, otherwise false.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:TR_DidHit(Handle:hndl=INVALID_HANDLE);
|
||||
|
||||
/**
|
||||
* Returns in which body hit group the trace collided if any.
|
||||
*
|
||||
* @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result.
|
||||
* @return Body hit group.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native TR_GetHitGroup(Handle:hndl=INVALID_HANDLE);
|
||||
|
||||
/**
|
||||
* Find the normal vector to the collison plane of a trace.
|
||||
*
|
||||
* @param hndl A trace Handle, or INVALID_HANDLE to use a global trace result.
|
||||
* @param normal Vector buffer to store the vector normal to the collision plane
|
||||
* @noreturn
|
||||
* @error Invalid Handle
|
||||
*/
|
||||
native TR_GetPlaneNormal(Handle:hndl, Float:normal[3]);
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _sdktools_voice_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _sdktools_voice_included
|
||||
|
||||
/**
|
||||
* @section voice flags.
|
||||
*/
|
||||
#define VOICE_NORMAL 0 /**< Allow the client to listen and speak normally. */
|
||||
#define VOICE_MUTED 1 /**< Mutes the client from speaking to everyone. */
|
||||
#define VOICE_SPEAKALL 2 /**< Allow the client to speak to everyone. */
|
||||
#define VOICE_LISTENALL 4 /**< Allow the client to listen to everyone. */
|
||||
#define VOICE_TEAM 8 /**< Allow the client to always speak to team, even when dead. */
|
||||
#define VOICE_LISTENTEAM 16 /**< Allow the client to always hear teammates, including dead ones. */
|
||||
|
||||
/**
|
||||
* @endsection
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set the client listening flags.
|
||||
*
|
||||
* @param client The client index
|
||||
* @param flags The voice flags
|
||||
* @noreturn
|
||||
*/
|
||||
native SetClientListeningFlags(client, flags);
|
||||
|
||||
/**
|
||||
* Retrieve the client current listening flags.
|
||||
*
|
||||
* @param client The client index
|
||||
* @return The current voice flags
|
||||
*/
|
||||
native GetClientListeningFlags(client);
|
||||
|
||||
/**
|
||||
* Set the receiver ability to listen to the sender.
|
||||
*
|
||||
* @param iReceiver The listener index.
|
||||
* @param iSender The sender index.
|
||||
* @return True if successful otherwise false.
|
||||
*/
|
||||
native bool:SetClientListening(iReceiver, iSender, bool:bListen);
|
||||
|
||||
/**
|
||||
* Retrieves if the receiver can listen to the sender.
|
||||
*
|
||||
* @param iReceiver The listener index.
|
||||
* @param iSender The sender index.
|
||||
* @return True if successful otherwise false.
|
||||
*/
|
||||
native bool:GetClientListening(iReceiver, iSender);
|
||||
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
|
||||
#if defined _sorting_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _sorting_included
|
||||
|
||||
/**
|
||||
* Contains sorting orders.
|
||||
*/
|
||||
enum SortOrder
|
||||
{
|
||||
Sort_Ascending = 0, /**< Ascending order */
|
||||
Sort_Descending = 1, /**< Descending order */
|
||||
Sort_Random = 2 /**< Random order */
|
||||
};
|
||||
|
||||
/**
|
||||
* Data types for ADT Array Sorts
|
||||
*/
|
||||
enum SortType
|
||||
{
|
||||
Sort_Integer = 0,
|
||||
Sort_Float,
|
||||
Sort_String,
|
||||
};
|
||||
|
||||
/**
|
||||
* Sorts an array of integers.
|
||||
*
|
||||
* @param array Array of integers to sort in-place.
|
||||
* @param array_size Size of the array.
|
||||
* @param order Sorting order to use.
|
||||
* @noreturn
|
||||
*/
|
||||
native SortIntegers(array[], array_size, SortOrder:order = Sort_Ascending);
|
||||
|
||||
/**
|
||||
* Sorts an array of float point numbers.
|
||||
*
|
||||
* @param array Array of floating point numbers to sort in-place.
|
||||
* @param array_size Size of the array.
|
||||
* @param order Sorting order to use.
|
||||
* @noreturn
|
||||
*/
|
||||
native SortFloats(Float:array[], array_size, SortOrder:order = Sort_Ascending);
|
||||
|
||||
/**
|
||||
* Sorts an array of strings.
|
||||
*
|
||||
* @param array Array of strings to sort in-place.
|
||||
* @param array_size Size of the array.
|
||||
* @param order Sorting order to use.
|
||||
* @noreturn
|
||||
*/
|
||||
native SortStrings(String:array[][], num_strings, SortOrder:order = Sort_Ascending);
|
||||
|
||||
/**
|
||||
* Sort comparison function for 1D array elements.
|
||||
* @note You may need to use explicit tags in order to use data properly.
|
||||
*
|
||||
* @param elem1 First element to compare.
|
||||
* @param elem2 Second element to compare.
|
||||
* @param array Array that is being sorted (order is undefined).
|
||||
* @param hndl Handle optionally passed in while sorting.
|
||||
* @return -1 if first should go before second
|
||||
* 0 if first is equal to second
|
||||
* 1 if first should go after second
|
||||
*/
|
||||
functag SortFunc1D public(elem1, elem2, const array[], Handle:hndl);
|
||||
|
||||
/**
|
||||
* Sorts a custom 1D array. You must pass in a comparison function.
|
||||
*
|
||||
* @param array Array to sort.
|
||||
* @param array_size Size of the array to sort.
|
||||
* @param sortfunc Sort function.
|
||||
* @param hndl Optional Handle to pass through the comparison calls.
|
||||
* @noreturn
|
||||
*/
|
||||
native SortCustom1D(array[], array_size, SortFunc1D:sortfunc, Handle:hndl=INVALID_HANDLE);
|
||||
|
||||
/**
|
||||
* Sort comparison function for 2D array elements (sub-arrays).
|
||||
* @note You may need to use explicit tags in order to use data properly.
|
||||
*
|
||||
* @param elem1 First array to compare.
|
||||
* @param elem2 Second array to compare.
|
||||
* @param array Array that is being sorted (order is undefined).
|
||||
* @param hndl Handle optionally passed in while sorting.
|
||||
* @return -1 if first should go before second
|
||||
* 0 if first is equal to second
|
||||
* 1 if first should go after second
|
||||
*/
|
||||
funcenum SortFunc2D
|
||||
{
|
||||
public(array[], array[], const array[][], Handle:hndl),
|
||||
public(String:array[], String:array[], const String:array[][], Handle:hndl),
|
||||
};
|
||||
|
||||
/**
|
||||
* Sorts a custom 2D array. You must pass in a comparison function.
|
||||
*
|
||||
* @param array Array to sort.
|
||||
* @param array_size Size of the major array to sort (first index, outermost).
|
||||
* @param sortfunc Sort comparison function to use.
|
||||
* @param hndl Optional Handle to pass through the comparison calls.
|
||||
* @noreturn
|
||||
*/
|
||||
native SortCustom2D(array[][], array_size, SortFunc2D:sortfunc, Handle:hndl=INVALID_HANDLE);
|
||||
|
||||
/**
|
||||
* Sort an ADT Array. Specify the type as Integer, Float, or String.
|
||||
*
|
||||
* @param array Array Handle to sort
|
||||
* @param order Sort order to use, same as other sorts.
|
||||
* @param type Data type stored in the ADT Array
|
||||
* @noreturn
|
||||
*/
|
||||
native SortADTArray(Handle:array, SortOrder:order, SortType:type);
|
||||
|
||||
/**
|
||||
* Sort comparison function for ADT Array elements. Function provides you with
|
||||
* indexes currently being sorted, use ADT Array functions to retrieve the
|
||||
* index values and compare.
|
||||
*
|
||||
* @param index1 First index to compare.
|
||||
* @param index2 Second index to compare.
|
||||
* @param array Array that is being sorted (order is undefined).
|
||||
* @param hndl Handle optionally passed in while sorting.
|
||||
* @return -1 if first should go before second
|
||||
* 0 if first is equal to second
|
||||
* 1 if first should go after second
|
||||
*/
|
||||
functag SortFuncADTArray public(index1, index2, Handle:array, Handle:hndl);
|
||||
|
||||
/**
|
||||
* Custom sorts an ADT Array. You must pass in a comparison function.
|
||||
*
|
||||
* @param array Array Handle to sort
|
||||
* @param sortfunc Sort comparision function to use
|
||||
* @param hndl Optional Handle to pass through the comparison calls.
|
||||
* @noreturn
|
||||
*/
|
||||
native SortADTArrayCustom(Handle:array, SortFuncADTArray:sortfunc, Handle:hndl=INVALID_HANDLE);
|
||||
@@ -0,0 +1,555 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _sourcemod_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _sourcemod_included
|
||||
|
||||
/**
|
||||
* Plugin public information.
|
||||
*/
|
||||
struct Plugin
|
||||
{
|
||||
const String:name[], /**< Plugin Name */
|
||||
const String:description[], /**< Plugin Description */
|
||||
const String:author[], /**< Plugin Author */
|
||||
const String:version[], /**< Plugin Version */
|
||||
const String:url[], /**< Plugin URL */
|
||||
};
|
||||
|
||||
#include <core>
|
||||
#include <float>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <handles>
|
||||
#include <functions>
|
||||
#include <files>
|
||||
#include <logging>
|
||||
#include <timers>
|
||||
#include <admin>
|
||||
#include <dbi>
|
||||
#include <lang>
|
||||
#include <sorting>
|
||||
#include <textparse>
|
||||
#include <clients>
|
||||
#include <console>
|
||||
#include <events>
|
||||
#include <bitbuffer>
|
||||
#include <usermessages>
|
||||
#include <keyvalues>
|
||||
#include <menus>
|
||||
#include <halflife>
|
||||
#include <adt>
|
||||
#include <banning>
|
||||
#include <commandfilters>
|
||||
#include <nextmap>
|
||||
|
||||
/**
|
||||
* Declare this as a struct in your plugin to expose its information.
|
||||
* Example:
|
||||
*
|
||||
* public Plugin:myinfo =
|
||||
* {
|
||||
* name = "My Plugin",
|
||||
* //etc
|
||||
* };
|
||||
*/
|
||||
public Plugin:myinfo;
|
||||
|
||||
/**
|
||||
* Called when the plugin is fully initialized and all known external references
|
||||
* are resolved. This is only called once in the lifetime of the plugin, and is
|
||||
* paired with OnPluginEnd().
|
||||
*
|
||||
* If any run-time error is thrown during this callback, the plugin will be marked
|
||||
* as failed.
|
||||
*
|
||||
* It is not necessary to close any handles or remove hooks in this function.
|
||||
* SourceMod guarantees that plugin shutdown automatically and correctly releases
|
||||
* all resources.
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward OnPluginStart();
|
||||
|
||||
/**
|
||||
* Called before OnPluginStart, in case the plugin wants to check for load failure.
|
||||
* This is called even if the plugin type is "private." Any natives from modules are
|
||||
* not available at this point. Thus, this forward should only be used for explicit
|
||||
* pre-emptive things, such as adding dynamic natives, or setting certain types of load filters.
|
||||
*
|
||||
* @note It is not safe to call externally resolved natives until OnPluginStart().
|
||||
* @note Any sort of RTE in this function will cause the plugin to fail loading.
|
||||
* @note You MUST remember to return SOMETHING here. The act of not returning is
|
||||
* equivalent to returning 0 (false). If you forgot to return, it will
|
||||
* cause your plugin to not load with a very strange error message.
|
||||
*
|
||||
* @param myself Handle to the plugin.
|
||||
* @param late Whether or not the plugin was loaded "late" (after map load).
|
||||
* @param error Error message buffer in case load failed.
|
||||
* @param err_max Maximum number of characters for error message buffer.
|
||||
* @return True if load success, false otherwise.
|
||||
*/
|
||||
forward bool:AskPluginLoad(Handle:myself, bool:late, String:error[], err_max);
|
||||
|
||||
/**
|
||||
* Called when the plugin is about to be unloaded.
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward OnPluginEnd();
|
||||
|
||||
/**
|
||||
* Called when the plugin's pause status is changing.
|
||||
*
|
||||
* @param pause True if the plugin is being paused, false otherwise.
|
||||
* @noreturn
|
||||
*/
|
||||
forward OnPluginPauseChange(bool:pause);
|
||||
|
||||
/**
|
||||
* Called before every server frame. Note that you should avoid
|
||||
* doing expensive computations here, and you should declare large
|
||||
* local arrays using 'decl' instead of 'new'.
|
||||
*/
|
||||
forward OnGameFrame();
|
||||
|
||||
/**
|
||||
* Called when the map is loaded.
|
||||
*
|
||||
* @note This used to be OnServerLoad(), which is now deprecated.
|
||||
* Plugins still using the old forward will work.
|
||||
*/
|
||||
forward OnMapStart();
|
||||
|
||||
/**
|
||||
* Called right before a map ends.
|
||||
*/
|
||||
forward OnMapEnd();
|
||||
|
||||
/**
|
||||
* Called when the map has loaded, servercfgfile (server.cfg) has been
|
||||
* executed, and all plugin configs are done executing. This is the best
|
||||
* place to initialize plugin functions which are based on cvar data.
|
||||
*
|
||||
* @note This will always be called once and only once per map. It will be
|
||||
* called after OnMapStart().
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward OnConfigsExecuted();
|
||||
|
||||
/**
|
||||
* This is called once, right after OnMapStart() but any time before
|
||||
* OnConfigsExecuted(). It is called after the "exec sourcemod.cfg"
|
||||
* command and all AutoExecConfig() exec commands have been added to
|
||||
* the ServerCommand() buffer.
|
||||
*
|
||||
* If you need to load per-map settings that override default values,
|
||||
* adding commands to the ServerCommand() buffer here will guarantee
|
||||
* that they're set before OnConfigsExecuted().
|
||||
*
|
||||
* Unlike OnMapStart() and OnConfigsExecuted(), this is not called on
|
||||
* late loads that occur after OnMapStart().
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
forward OnAutoConfigsBuffered();
|
||||
|
||||
/**
|
||||
* @deprecated Use OnConfigsExecuted() instead.
|
||||
*/
|
||||
#pragma deprecated Use OnConfigsExecuted() instead
|
||||
forward OnServerCfg();
|
||||
|
||||
/**
|
||||
* Called after all plugins have been loaded. This is called once for
|
||||
* every plugin. If a plugin late loads, it will be called immediately
|
||||
* after OnPluginStart().
|
||||
*/
|
||||
forward OnAllPluginsLoaded();
|
||||
|
||||
/**
|
||||
* Returns the calling plugin's Handle.
|
||||
*
|
||||
* @return Handle of the calling plugin.
|
||||
*/
|
||||
native Handle:GetMyHandle();
|
||||
|
||||
/**
|
||||
* Returns an iterator that can be used to search through plugins.
|
||||
*
|
||||
* @return Handle to iterate with. Must be closed via
|
||||
* CloseHandle().
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native Handle:GetPluginIterator();
|
||||
|
||||
/**
|
||||
* Returns whether there are more plugins available in the iterator.
|
||||
*
|
||||
* @param iter Handle to the plugin iterator.
|
||||
* @return True on more plugins, false otherwise.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:MorePlugins(Handle:iter);
|
||||
|
||||
/**
|
||||
* Returns the current plugin in the iterator and advances the iterator.
|
||||
*
|
||||
* @param iter Handle to the plugin iterator.
|
||||
* @return Current plugin the iterator is at, before
|
||||
* the iterator is advanced.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native Handle:ReadPlugin(Handle:iter);
|
||||
|
||||
/**
|
||||
* Returns a plugin's status.
|
||||
*
|
||||
* @param plugin Plugin Handle (INVALID_HANDLE uses the calling plugin).
|
||||
* @return Status code for the plugin.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native PluginStatus:GetPluginStatus(Handle:plugin);
|
||||
|
||||
/**
|
||||
* Retrieves a plugin's file name relative to the plugins folder.
|
||||
*
|
||||
* @param plugin Plugin Handle (INVALID_HANDLE uses the calling plugin).
|
||||
* @param buffer Buffer to the store the file name.
|
||||
* @param maxlength Maximum length of the name buffer.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native GetPluginFilename(Handle:plugin, String:buffer[], maxlength);
|
||||
|
||||
/**
|
||||
* Retrieves whether or not a plugin is being debugged.
|
||||
*
|
||||
* @param plugin Plugin Handle (INVALID_HANDLE uses the calling plugin).
|
||||
* @return True if being debugged, false otherwise.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:IsPluginDebugging(Handle:hndl);
|
||||
|
||||
/**
|
||||
* Retrieves a plugin's public info.
|
||||
*
|
||||
* @param plugin Plugin Handle (INVALID_HANDLE uses the calling plugin).
|
||||
* @param info Plugin info property to retrieve.
|
||||
* @param buffer Buffer to store info in.
|
||||
* @param maxlength Maximum length of buffer.
|
||||
* @return True on success, false if property is not available.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:GetPluginInfo(Handle:plugin, PluginInfo:info, String:buffer[], maxlength);
|
||||
|
||||
/**
|
||||
* Finds a plugin by its order in the list from the "plugins list" server
|
||||
* "sm" command. You should not use this function to loop through all plugins,
|
||||
* use the iterator instead. Looping through all plugins using this native
|
||||
* is O(n^2), whereas using the iterator is O(n).
|
||||
*
|
||||
* @param order_num Number of the plugin as it appears in "sm plugins list".
|
||||
* @return Plugin Handle on success, INVALID_HANDLE if no plugin
|
||||
* matches the given number.
|
||||
*/
|
||||
native Handle:FindPluginByNumber(order_num);
|
||||
|
||||
/**
|
||||
* Causes the plugin to enter a failed state. An error will be thrown and
|
||||
* the plugin will be paused until it is unloaded or reloaded.
|
||||
*
|
||||
* For backwards compatibility, if no extra arguments are passed, no
|
||||
* formatting is applied. If one or more additional arguments is passed,
|
||||
* the string is formatted using Format(). If any errors are encountered
|
||||
* during formatting, both the format specifier string and an additional
|
||||
* error message are written.
|
||||
*
|
||||
* This function does not return, and no further code in the plugin is
|
||||
* executed.
|
||||
*
|
||||
* @param string Format specifier string.
|
||||
* @param ... Formatting arguments.
|
||||
* @noreturn
|
||||
* @error Always throws SP_ERROR_ABORT.
|
||||
*/
|
||||
native SetFailState(const String:string[], any:...);
|
||||
|
||||
/**
|
||||
* Aborts the current callback and throws an error. This function
|
||||
* does not return in that no code is executed following it.
|
||||
*
|
||||
* @param format String format.
|
||||
* @param ... Format arguments.
|
||||
* @noreturn
|
||||
* @error Always!
|
||||
*/
|
||||
native ThrowError(const String:fmt[], any:...);
|
||||
|
||||
/**
|
||||
* Gets the system time as a unix timestamp.
|
||||
*
|
||||
* @param bigStamp Optional array to store the 64bit timestamp in.
|
||||
* @return 32bit timestamp (number of seconds since unix epoch).
|
||||
*/
|
||||
native GetTime(bigStamp[2]={0,0});
|
||||
|
||||
/**
|
||||
* Produces a date and/or time string value for a timestamp.
|
||||
*
|
||||
* See this URL for valid parameters:
|
||||
* http://cplusplus.com/reference/clibrary/ctime/strftime.html
|
||||
*
|
||||
* @param buffer Destination string buffer.
|
||||
* @param maxlength Maximum length of output string buffer.
|
||||
* @param format Formatting rules (passing NULL_STRING will use the rules defined in sm_datetime_format).
|
||||
* @param stamp Optional time stamp.
|
||||
* @noreturn
|
||||
* @error Buffer too small or invalid time format.
|
||||
*/
|
||||
native FormatTime(String:buffer[], maxlength, const String:format[], stamp=-1);
|
||||
|
||||
/**
|
||||
* Loads a game config file.
|
||||
*
|
||||
* @param file File to load. The path must be relative to the 'gamedata' folder under the config folder
|
||||
* and the extension should be omitted.
|
||||
* @return A handle to the game config file or INVALID_HANDLE in failure.
|
||||
*/
|
||||
native Handle:LoadGameConfigFile(const String:file[]);
|
||||
|
||||
/**
|
||||
* Returns an offset value.
|
||||
*
|
||||
* @param gc Game config handle.
|
||||
* @param key Key to retrieve from the offset section.
|
||||
* @return An offset, or -1 on failure.
|
||||
*/
|
||||
native GameConfGetOffset(Handle:gc, const String:key[]);
|
||||
|
||||
/**
|
||||
* Gets the value of a key from the "Keys" section.
|
||||
*
|
||||
* @param gc Game config handle.
|
||||
* @param key Key to retrieve from the Keys section.
|
||||
* @param buffer Destination string buffer.
|
||||
* @param maxlen Maximum length of output string buffer.
|
||||
* @return True if key existed, false otherwise.
|
||||
*/
|
||||
native bool:GameConfGetKeyValue(Handle:gc, const String:key[], String:buffer[], maxlen);
|
||||
|
||||
/**
|
||||
* Returns the operating system's "tick count," which is a number of
|
||||
* milliseconds since the operating system loaded. This can be used
|
||||
* for basic benchmarks.
|
||||
*
|
||||
* @return Tick count in milliseconds.
|
||||
*/
|
||||
native GetSysTickCount();
|
||||
|
||||
/**
|
||||
* Specifies that the given config file should be executed after plugin load.
|
||||
* OnConfigsExecuted() will not be called until the config file has executed,
|
||||
* but it will be called if the execution fails.
|
||||
*
|
||||
* @param autoCreate If true, and the config file does not exist, such a config
|
||||
* file will be automatically created and populated with
|
||||
* information from the plugin's registered cvars.
|
||||
* @param name Name of the config file, excluding the .cfg extension.
|
||||
* If empty, <plugin.filename.cfg> is assumed.
|
||||
* @param folder Folder under cfg/ to use. By default this is "sourcemod."
|
||||
* @noreturn
|
||||
*/
|
||||
native AutoExecConfig(bool:autoCreate=true, const String:name[]="", const String:folder[]="sourcemod");
|
||||
|
||||
/**
|
||||
* Sets a native as optional, such that if it is unloaded, removed,
|
||||
* or otherwise non-existent, the plugin will still work. Calling
|
||||
* removed natives results in a run-time error.
|
||||
*
|
||||
* @param name Native name.
|
||||
* @noreturn
|
||||
*/
|
||||
native MarkNativeAsOptional(const String:name[]);
|
||||
|
||||
/**
|
||||
* Registers a library name for identifying as a dependency to
|
||||
* other plugins.
|
||||
*
|
||||
* @param name Library name.
|
||||
* @noreturn
|
||||
*/
|
||||
native RegPluginLibrary(const String:name[]);
|
||||
|
||||
/**
|
||||
* Returns whether a library exists. This function should be considered
|
||||
* expensive; it should only be called on plugin to determine availability
|
||||
* of resources. Use OnLibraryAdded()/OnLibraryRemoved() to detect changes
|
||||
* in optional resources.
|
||||
*
|
||||
* @param name Library name of a plugin or extension.
|
||||
* @return True if exists, false otherwise.
|
||||
*/
|
||||
native bool:LibraryExists(const String:name[]);
|
||||
|
||||
/**
|
||||
* Returns the status of an extension, by filename.
|
||||
*
|
||||
* @param name Extension name (like "sdktools.ext").
|
||||
* @param error Optional error message buffer.
|
||||
* @param maxlength Length of optional error message buffer.
|
||||
* @return -2 if the extension was not found.
|
||||
* -1 if the extension was found but failed to load.
|
||||
* 0 if the extension loaded but reported an error.
|
||||
* 1 if the extension is running without error.
|
||||
*/
|
||||
native GetExtensionFileStatus(const String:name[], String:error[]="", maxlength=0);
|
||||
|
||||
/**
|
||||
* Called after a library is added that the current plugin references
|
||||
* optionally. A library is either a plugin name or extension name, as
|
||||
* exposed via its include file.
|
||||
*
|
||||
* @param name Library name.
|
||||
*/
|
||||
forward OnLibraryAdded(const String:name[]);
|
||||
|
||||
/**
|
||||
* Called right before a library is removed that the current plugin references
|
||||
* optionally. A library is either a plugin name or extension name, as
|
||||
* exposed via its include file.
|
||||
*
|
||||
* @param name Library name.
|
||||
*/
|
||||
forward OnLibraryRemoved(const String:name[]);
|
||||
|
||||
#define MAPLIST_FLAG_MAPSFOLDER (1<<0) /**< On failure, use all maps in the maps folder. */
|
||||
#define MAPLIST_FLAG_CLEARARRAY (1<<1) /**< If an input array is specified, clear it before adding. */
|
||||
#define MAPLIST_FLAG_NO_DEFAULT (1<<2) /**< Do not read "default" or "mapcyclefile" on failure. */
|
||||
|
||||
/**
|
||||
* Loads a map list to an ADT Array.
|
||||
*
|
||||
* A map list is a list of maps from a file. SourceMod allows easy configuration of
|
||||
* maplists through addons/sourcemod/configs/maplists.cfg. Each entry is given a
|
||||
* name and a file (for example, "rtv" => "rtv.cfg"), or a name and a redirection
|
||||
* (for example, "rtv" => "default"). This native will read a map list entry,
|
||||
* cache the file, and return the list of maps it holds.
|
||||
*
|
||||
* Serial change numbers are used to identify if a map list has changed. Thus, if
|
||||
* you pass a serial change number and it's equal to what SourceMod currently knows
|
||||
* about the map list, then SourceMod won't reparse the file.
|
||||
*
|
||||
* If the maps end up being read from the maps folder (MAPLIST_FLAG_MAPSFOLDER), they
|
||||
* are automatically sorted in alphabetical, ascending order.
|
||||
*
|
||||
* Arrays created by this function are temporary and must be freed via CloseHandle().
|
||||
* Modifying arrays created by this function will not affect future return values or
|
||||
* or the contents of arrays returned to other plugins.
|
||||
*
|
||||
* @param array Array to store the map list. If INVALID_HANDLE, a new blank
|
||||
* array will be created. The blocksize should be at least 16;
|
||||
* otherwise results may be truncated. Items are added to the array
|
||||
* as strings. The array is never checked for duplicates, and it is
|
||||
* not read beforehand. Only the serial number is used to detect
|
||||
* changes.
|
||||
* @param serial Serial number to identify last known map list change. If -1, the
|
||||
* the value will not be checked. If the map list has since changed,
|
||||
* the serial is updated (even if -1 was passed). If there is an error
|
||||
* finding a valid maplist, then the serial is set to -1.
|
||||
* @param str Config name, or "default" for the default map list. Config names
|
||||
* should be somewhat descriptive. For example, the admin menu uses
|
||||
* a config name of "admin menu". The list names can be configured
|
||||
* by users in addons/sourcemod/configs/maplists.cfg.
|
||||
* @param flags MAPLIST_FLAG flags.
|
||||
* @return On failure:
|
||||
* INVALID_HANDLE is returned, the serial is set to -1, and the input
|
||||
* array (if any) is left unchanged.
|
||||
* On no change:
|
||||
INVALID_HANDLE is returned, the serial is unchanged, and the input
|
||||
array (if any) is left unchanged.
|
||||
* On success:
|
||||
* A valid array Handle is returned, containing at least one map string.
|
||||
* If an array was passed, the return value is equal to the passed Array
|
||||
* Handle. If the passed array was not cleared, it will have grown by at
|
||||
* least one item. The serial number is updated to a positive number.
|
||||
* @error Invalid array Handle that is not INVALID_HANDLE.
|
||||
*/
|
||||
native Handle:ReadMapList(Handle:array=INVALID_HANDLE,
|
||||
&serial=-1,
|
||||
const String:str[]="default",
|
||||
flags=MAPLIST_FLAG_CLEARARRAY);
|
||||
|
||||
/**
|
||||
* Makes a compatibility binding for map lists. For example, if a function previously used
|
||||
* "clam.cfg" for map lists, this function will insert a "fake" binding to "clam.cfg" that
|
||||
* will be overridden if it's in the maplists.cfg file.
|
||||
*
|
||||
* @param name Configuration name that would be used with ReadMapList().
|
||||
* @param file Default file to use.
|
||||
* @noreturn
|
||||
*/
|
||||
native SetMapListCompatBind(const String:name[], const String:file[]);
|
||||
|
||||
/**
|
||||
* Called when a client has sent chat text. This must return either true or
|
||||
* false to indicate that a client is or is not spamming the server.
|
||||
*
|
||||
* The return value is a hint only. Core or another plugin may decide
|
||||
* otherwise.
|
||||
*
|
||||
* @param client Client index. The server (0) will never be passed.
|
||||
* @return True if client is spamming the server, false otherwise.
|
||||
*/
|
||||
forward bool:OnClientFloodCheck(client);
|
||||
|
||||
/**
|
||||
* Called after a client's flood check has been computed. This can be used
|
||||
* by antiflood algorithms to decay/increase flooding weights.
|
||||
*
|
||||
* Since the result from "OnClientFloodCheck" isn't guaranteed to be the
|
||||
* final result, it is generally a good idea to use this to play with other
|
||||
* algorithms nicely.
|
||||
*
|
||||
* @param client Client index. The server (0) will never be passed.
|
||||
* @param blocked True if client flooded last "say", false otherwise.
|
||||
* @noreturn
|
||||
*/
|
||||
forward OnClientFloodResult(client, bool:blocked);
|
||||
|
||||
#include <helpers>
|
||||
#include <entity>
|
||||
#include <entity_prop_stocks>
|
||||
|
||||
@@ -0,0 +1,557 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _string_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _string_included
|
||||
|
||||
/**
|
||||
* @global Unless otherwise noted, all string functions which take in a
|
||||
* writable buffer and maximum length should have the null terminator INCLUDED
|
||||
* in the length. This means that this is valid:
|
||||
* strcopy(string, sizeof(string), ...)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Calculates the length of a string.
|
||||
*
|
||||
* @param str String to check.
|
||||
* @return Number of valid character bytes in the string.
|
||||
*/
|
||||
native strlen(const String:str[]);
|
||||
|
||||
/**
|
||||
* Tests whether a string is found inside another string.
|
||||
*
|
||||
* @param str String to search in.
|
||||
* @param substr Substring to find inside the original string.
|
||||
* @param caseSensitive If true (default), search is case sensitive.
|
||||
* If false, search is case insensitive.
|
||||
* @return -1 on failure (no match found). Any other value
|
||||
* indicates a position in the string where the match starts.
|
||||
*/
|
||||
native StrContains(const String:str[], const String:substr[], bool:caseSensitive=true);
|
||||
|
||||
/**
|
||||
* Compares two strings lexographically.
|
||||
*
|
||||
* @param str1 First string (left).
|
||||
* @param str2 Second string (right).
|
||||
* @param caseSensitive If true (default), comparison is case sensitive.
|
||||
* If false, comparison is case insensitive.
|
||||
* @return -1 if str1 < str2
|
||||
* 0 if str1 == str2
|
||||
* 1 if str1 > str2
|
||||
*/
|
||||
native strcmp(const String:str1[], const String:str2[], bool:caseSensitive=true);
|
||||
|
||||
/**
|
||||
* Compares two strings parts lexographically.
|
||||
*
|
||||
* @param str1 First string (left).
|
||||
* @param str2 Second string (right).
|
||||
* @param num Number of characters to compare.
|
||||
* @param caseSensitive If true (default), comparison is case sensitive.
|
||||
* If false, comparison is case insensitive.
|
||||
* @return -1 if str1 < str2
|
||||
* 0 if str1 == str2
|
||||
* 1 if str1 > str2
|
||||
*/
|
||||
native strncmp(const String:str1[], const String:str2[], num, bool:caseSensitive=true);
|
||||
|
||||
/**
|
||||
* Backwards compatible stock - StrCompare is now strcmp
|
||||
* @deprecated Renamed to strcmp
|
||||
*/
|
||||
#pragma deprecated Use strcmp() instead
|
||||
stock StrCompare(const String:str1[], const String:str2[], bool:caseSensitive=true)
|
||||
{
|
||||
return strcmp(str1, str2, caseSensitive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether two strings are equal.
|
||||
*
|
||||
* @param str1 First string (left).
|
||||
* @param str2 Second string (right).
|
||||
* @param caseSensitive If true (default), comparison is case sensitive.
|
||||
* If false, comparison is case insensitive.
|
||||
* @return True if equal, false otherwise.
|
||||
*/
|
||||
stock bool:StrEqual(const String:str1[], const String:str2[], bool:caseSensitive=true)
|
||||
{
|
||||
return (strcmp(str1, str2, caseSensitive) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies one string to another string.
|
||||
* @note If the destination buffer is too small to hold the source string, the
|
||||
* destination will be truncated.
|
||||
*
|
||||
* @param dest Destination string buffer to copy to.
|
||||
* @param destlen Destination buffer length (includes null terminator).
|
||||
* @param source Source string buffer to copy from.
|
||||
* @return Number of cells written.
|
||||
*/
|
||||
native strcopy(String:dest[], destLen, const String:source[]);
|
||||
|
||||
/**
|
||||
* Backwards compatibility stock - use strcopy
|
||||
* @deprecated Renamed to strcopy
|
||||
*/
|
||||
#pragma deprecated Use strcopy() instead
|
||||
stock StrCopy(String:dest[], destLen, const String:source[])
|
||||
{
|
||||
return strcopy(dest, destLen, source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a string according to the SourceMod format rules (see documentation).
|
||||
*
|
||||
* @param buffer Destination string buffer.
|
||||
* @param maxlength Maximum length of output string buffer.
|
||||
* @param format Formatting rules.
|
||||
* @param ... Variable number of format parameters.
|
||||
* @return Number of cells written.
|
||||
*/
|
||||
native Format(String:buffer[], maxlength, const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Formats a string according to the SourceMod format rules (see documentation).
|
||||
* @note This is the same as Format(), except none of the input buffers can
|
||||
* overlap the same memory as the output buffer. Since this security
|
||||
* check is removed, it is slightly faster.
|
||||
*
|
||||
* @param buffer Destination string buffer.
|
||||
* @param maxlength Maximum length of output string buffer.
|
||||
* @param format Formatting rules.
|
||||
* @param ... Variable number of format parameters.
|
||||
* @return Number of cells written.
|
||||
*/
|
||||
native FormatEx(String:buffer[], maxlength, const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Formats a string according to the SourceMod format rules (see documentation).
|
||||
* @note This is the same as Format(), except it grabs parameters from a
|
||||
* parent parameter stack, rather than a local. This is useful for
|
||||
* implementing your own variable argument functions.
|
||||
*
|
||||
* @param buffer Destination string buffer.
|
||||
* @param maxlength Maximum length of output string buffer.
|
||||
* @param format Formatting rules.
|
||||
* @param varpos Argument number which contains the '...' symbol.
|
||||
* Note: Arguments start at 1.
|
||||
* @return Number of bytes written.
|
||||
*/
|
||||
native VFormat(String:buffer[], maxlength, const String:format[], varpos);
|
||||
|
||||
/**
|
||||
* Converts a string to an integer.
|
||||
*
|
||||
* @param str String to convert.
|
||||
* @param nBase Numerical base to use. 10 is default.
|
||||
* @return Integer conversion of string, or 0 on failure.
|
||||
*/
|
||||
native StringToInt(const String:str[], nBase=10);
|
||||
|
||||
/**
|
||||
* Converts a string to an integer with some more options.
|
||||
*
|
||||
* @param str String to convert.
|
||||
* @param result Variable to store the result in.
|
||||
* @param nBase Numerical base to use. 10 is default.
|
||||
* @return Number of characters consumed.
|
||||
*/
|
||||
native StringToIntEx(const String:str[], &result, nBase=10);
|
||||
|
||||
/**
|
||||
* Converts an integer to a string.
|
||||
*
|
||||
* @param num Integer to convert.
|
||||
* @param str Buffer to store string in.
|
||||
* @param maxlength Maximum length of string buffer.
|
||||
* @return Number of cells written to buffer.
|
||||
*/
|
||||
native IntToString(num, String:str[], maxlength);
|
||||
|
||||
/**
|
||||
* Converts a string to a floating point number.
|
||||
*
|
||||
* @param str String to convert to a foat.
|
||||
* @return Floating point result, or 0.0 on error.
|
||||
*/
|
||||
native Float:StringToFloat(const String:str[]);
|
||||
|
||||
/**
|
||||
* Converts a string to a floating point number with some more options.
|
||||
*
|
||||
* @param str String to convert to a foat.
|
||||
* @param result Variable to store result in.
|
||||
* @return Number of characters consumed.
|
||||
*/
|
||||
native StringToFloatEx(const String:str[], &Float:result);
|
||||
|
||||
/**
|
||||
* Converts a floating point number to a string.
|
||||
*
|
||||
* @param num Floating point number to convert.
|
||||
* @param str Buffer to store string in.
|
||||
* @param maxlength Maximum length of string buffer.
|
||||
* @return Number of cells written to buffer.
|
||||
*/
|
||||
native FloatToString(Float:num, String:str[], maxlength);
|
||||
|
||||
/**
|
||||
* Finds the first "argument" in a string; either a set of space
|
||||
* terminated characters, or a fully quoted string. After the
|
||||
* argument is found, whitespace is read until the next portion
|
||||
* of the string is reached. If nothing remains, -1 is returned.
|
||||
* Otherwise, the index to the first character is returned.
|
||||
*
|
||||
* @param source Source input string.
|
||||
* @param arg Stores argument read from string.
|
||||
* @param argLen Maximum length of argument buffer.
|
||||
* @return Index to next piece of string, or -1 if none.
|
||||
*/
|
||||
native BreakString(const String:source[], String:arg[], argLen);
|
||||
|
||||
/**
|
||||
* Backwards compatibility stock - use BreakString
|
||||
* @deprecated Renamed to BreakString.
|
||||
*/
|
||||
#pragma deprecated Use BreakString() instead
|
||||
stock StrBreak(const String:source[], String:arg[], argLen)
|
||||
{
|
||||
return BreakString(source, arg, argLen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes whitespace characters from the beginning and end of a string.
|
||||
*
|
||||
* @param str The string to trim.
|
||||
* @return Number of bytes written (UTF-8 safe).
|
||||
*/
|
||||
native TrimString(String:str[]);
|
||||
|
||||
/**
|
||||
* Returns text in a string up until a certain character sequence is reached.
|
||||
*
|
||||
* @param source Source input string.
|
||||
* @param split A string which specifies a search point to break at.
|
||||
* @param part Buffer to store string part.
|
||||
* @param partLen Maximum length of the string part buffer.
|
||||
* @return -1 if no match was found; otherwise, an index into source
|
||||
* marking the first index after the searched text. The
|
||||
* index is always relative to the start of the input string.
|
||||
*/
|
||||
native SplitString(const String:source[], const String:split[], String:part[], partLen);
|
||||
|
||||
/**
|
||||
* Given a string, replaces all occurrences of a search string with a
|
||||
* replacement string.
|
||||
*
|
||||
* @param text String to perform search and replacements on.
|
||||
* @param maxlength Maximum length of the string buffer.
|
||||
* @param search String to search for.
|
||||
* @param replace String to replace the search string with.
|
||||
* @return Number of replacements that were performed.
|
||||
*/
|
||||
native ReplaceString(String:text[], maxlength, const String:search[], const String:replace[]);
|
||||
|
||||
/**
|
||||
* Given a string, replaces the first occurrence of a search string with a
|
||||
* replacement string.
|
||||
*
|
||||
* @param text String to perform search and replacements on.
|
||||
* @param maxlength Maximum length of the string buffer.
|
||||
* @param search String to search for.
|
||||
* @param replace String to replace the search string with.
|
||||
* @param searchLen If higher than -1, its value will be used instead of
|
||||
* a strlen() call on the search parameter.
|
||||
* @param replaceLen If higher than -1, its value will be used instead of
|
||||
* a strlen() call on the replace parameter.
|
||||
* @return Index into the buffer (relative to the start) from where
|
||||
* the last replacement ended, or -1 if no replacements were
|
||||
* made.
|
||||
*/
|
||||
native ReplaceStringEx(String:text[], maxlength, const String:search[], const String:replace[], searchLen=-1, replaceLen=-1);
|
||||
|
||||
/**
|
||||
* Returns the number of bytes a character is using. This is
|
||||
* for multi-byte characters (UTF-8). For normal ASCII characters,
|
||||
* this will return 1.
|
||||
*
|
||||
* @param source Source input string.
|
||||
* @return Number of bytes the current character uses.
|
||||
*/
|
||||
native GetCharBytes(const String:source[]);
|
||||
|
||||
/**
|
||||
* Returns whether a character is an ASCII alphabet character.
|
||||
*
|
||||
* @note Multi-byte characters will always return false.
|
||||
*
|
||||
* @param char Character to test.
|
||||
* @return True if character is alphabetical, otherwise false.
|
||||
*/
|
||||
native bool:IsCharAlpha(chr);
|
||||
|
||||
/**
|
||||
* Returns whether a character is numeric.
|
||||
*
|
||||
* @note Multi-byte characters will always return false.
|
||||
*
|
||||
* @param char Character to test.
|
||||
* @return True if character is numeric, otherwise false.
|
||||
*/
|
||||
native bool:IsCharNumeric(chr);
|
||||
|
||||
/**
|
||||
* Returns whether a character is whitespace.
|
||||
*
|
||||
* @note Multi-byte characters will always return false.
|
||||
*
|
||||
* @param char Character to test.
|
||||
* @return True if character is whitespace, otherwise false.
|
||||
*/
|
||||
native bool:IsCharSpace(chr);
|
||||
|
||||
/**
|
||||
* Returns if a character is multi-byte or not.
|
||||
*
|
||||
* @param char Character to test.
|
||||
* @return 0 for a normal 7-bit ASCII character,
|
||||
* otherwise number of bytes in multi-byte character.
|
||||
*/
|
||||
native IsCharMB(chr);
|
||||
|
||||
/**
|
||||
* Returns whether an alphabetic character is uppercase.
|
||||
*
|
||||
* @note Multi-byte characters will always return false.
|
||||
*
|
||||
* @param char Character to test.
|
||||
* @return True if character is uppercase, otherwise false.
|
||||
*/
|
||||
native bool:IsCharUpper(chr);
|
||||
|
||||
/**
|
||||
* Returns whether an alphabetic character is lowercase.
|
||||
*
|
||||
* @note Multi-byte characters will always return false.
|
||||
*
|
||||
* @param char Character to test.
|
||||
* @return True if character is lowercase, otherwise false.
|
||||
*/
|
||||
native bool:IsCharLower(chr);
|
||||
|
||||
/**
|
||||
* Strips a quote pair off a string if it exists. That is, the following
|
||||
* replace rule is applied once: $"(.*)"^ -> $\1^
|
||||
*
|
||||
* Note that the leading and trailing quotes will only be removed if both
|
||||
* exist. Otherwise, the string is left unmodified. This function should
|
||||
* be considered O(k) (all characters get shifted down).
|
||||
*
|
||||
* @param text String to modify (in place).
|
||||
* @return True if string was modified, false if there was no
|
||||
* set of quotes.
|
||||
*/
|
||||
native bool:StripQuotes(String:text[]);
|
||||
|
||||
/**
|
||||
* Returns an uppercase character to a lowercase character.
|
||||
*
|
||||
* @param chr Characer to convert.
|
||||
* @return Lowercase character on success,
|
||||
* no change on failure.
|
||||
*/
|
||||
stock CharToUpper(chr)
|
||||
{
|
||||
if (IsCharLower(chr))
|
||||
{
|
||||
return (chr & ~(1<<5));
|
||||
}
|
||||
return chr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a lowercase character to an uppercase character.
|
||||
*
|
||||
* @param chr Characer to convert.
|
||||
* @return Uppercase character on success,
|
||||
* no change on failure.
|
||||
*/
|
||||
stock CharToLower(chr)
|
||||
{
|
||||
if (IsCharUpper(chr))
|
||||
{
|
||||
return (chr | (1<<5));
|
||||
}
|
||||
return chr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the first occurrence of a character in a string.
|
||||
*
|
||||
* @param str String.
|
||||
* @param c Character to search for.
|
||||
* @param reverse False (default) to search forward, true to search
|
||||
* backward.
|
||||
* @return The index of the first occurrence of the character
|
||||
* in the string, or -1 if the character was not found.
|
||||
*/
|
||||
stock FindCharInString(const String:str[], c, bool:reverse = false)
|
||||
{
|
||||
new i, len
|
||||
|
||||
len = strlen(str);
|
||||
|
||||
if (!reverse)
|
||||
{
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (str[i] == c)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = len - 1; i >= 0; i--)
|
||||
{
|
||||
if (str[i] == c)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenates one string onto another.
|
||||
*
|
||||
* @param buffer String to append to.
|
||||
* @param maxlength Maximum length of entire buffer.
|
||||
* @param source Source string to concatenate.
|
||||
* @return Number of bytes written.
|
||||
*/
|
||||
stock StrCat(String:buffer[], maxlength, const String:source[])
|
||||
{
|
||||
new len = strlen(buffer);
|
||||
if (len >= maxlength)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Format(buffer[len], maxlength-len, "%s", source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Breaks a string into pieces and stores each piece into an array of buffers.
|
||||
*
|
||||
* @param text The string to split.
|
||||
* @param split The string to use as a split delimiter.
|
||||
* @param buffers An array of string buffers (2D array).
|
||||
* @param maxStrings Number of string buffers (first dimension size).
|
||||
* @param maxStringLength Maximum length of each string buffer.
|
||||
* @return Number of strings retrieved.
|
||||
*/
|
||||
stock ExplodeString(const String:text[], const String:split[], String:buffers[][], maxStrings, maxStringLength)
|
||||
{
|
||||
new reloc_idx, idx, total;
|
||||
|
||||
if (maxStrings < 1 || split[0] == '\0')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
while ((idx = SplitString(text[reloc_idx], split, buffers[total], maxStringLength)) != -1)
|
||||
{
|
||||
reloc_idx += idx;
|
||||
if (text[reloc_idx] == '\0')
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (++total >= maxStrings)
|
||||
{
|
||||
return total;
|
||||
}
|
||||
}
|
||||
|
||||
if (text[reloc_idx] != '\0' && total <= maxStrings - 1)
|
||||
{
|
||||
strcopy(buffers[total++], maxStringLength, text[reloc_idx]);
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins an array of strings into one string, with a "join" string inserted in
|
||||
* between each given string. This function complements ExplodeString.
|
||||
*
|
||||
* @param strings An array of strings.
|
||||
* @param numStrings Number of strings in the array.
|
||||
* @param join The join string to insert between each string.
|
||||
* @param buffer Output buffer to write the joined string to.
|
||||
* @param maxLength Maximum length of the output buffer.
|
||||
* @return Number of bytes written to the output buffer.
|
||||
*/
|
||||
stock ImplodeStrings(const String:strings[][], numStrings, const String:join[], String:buffer[], maxLength)
|
||||
{
|
||||
new total, length, part_length;
|
||||
new join_length = strlen(join);
|
||||
for (new i=0; i<numStrings; i++)
|
||||
{
|
||||
length = strcopy(buffer[total], maxLength-total, strings[i]);
|
||||
total += length;
|
||||
if (length < part_length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (i != numStrings - 1)
|
||||
{
|
||||
length = strcopy(buffer[total], maxLength-total, join);
|
||||
total += length;
|
||||
if (length < join_length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _textparse_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _textparse_included
|
||||
|
||||
|
||||
/********************************
|
||||
* Everything below describes the SMC Parse, or "SourceMod Configuration" format.
|
||||
* This parser is entirely event based. You must hook events to receive data.
|
||||
* The file format itself is nearly identical to Valve's KeyValues format.
|
||||
********************************/
|
||||
|
||||
/**
|
||||
* Parse result directive.
|
||||
*/
|
||||
enum SMCResult
|
||||
{
|
||||
SMCParse_Continue, /**< Continue parsing */
|
||||
SMCParse_Halt, /**< Stop parsing here */
|
||||
SMCParse_HaltFail /**< Stop parsing and return failure */
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse error codes.
|
||||
*/
|
||||
enum SMCError
|
||||
{
|
||||
SMCError_Okay = 0, /**< No error */
|
||||
SMCError_StreamOpen, /**< Stream failed to open */
|
||||
SMCError_StreamError, /**< The stream died... somehow */
|
||||
SMCError_Custom, /**< A custom handler threw an error */
|
||||
SMCError_InvalidSection1, /**< A section was declared without quotes, and had extra tokens */
|
||||
SMCError_InvalidSection2, /**< A section was declared without any header */
|
||||
SMCError_InvalidSection3, /**< A section ending was declared with too many unknown tokens */
|
||||
SMCError_InvalidSection4, /**< A section ending has no matching beginning */
|
||||
SMCError_InvalidSection5, /**< A section beginning has no matching ending */
|
||||
SMCError_InvalidTokens, /**< There were too many unidentifiable strings on one line */
|
||||
SMCError_TokenOverflow, /**< The token buffer overflowed */
|
||||
SMCError_InvalidProperty1, /**< A property was declared outside of any section */
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new SMC file format parser. This is used to set parse hooks.
|
||||
*
|
||||
* @return A new Handle to an SMC Parse structure.
|
||||
*/
|
||||
native Handle:SMC_CreateParser();
|
||||
|
||||
/**
|
||||
* Parses an SMC file.
|
||||
*
|
||||
* @param smc A Handle to an SMC Parse structure.
|
||||
* @param file A string containing the file path.
|
||||
* @param line An optional by reference cell to store the last line number read.
|
||||
* @param col An optional by reference cell to store the last column number read.
|
||||
* @return An SMCParseError result.
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native SMCError:SMC_ParseFile(Handle:smc, const String:file[], &line=0, &col=0);
|
||||
|
||||
/**
|
||||
* Gets an error string for an SMCError code.
|
||||
* @note SMCError_Okay returns false.
|
||||
* @note SMCError_Custom (which is thrown on SMCParse_HaltFail) returns false.
|
||||
*
|
||||
* @param error The SMCParseError code.
|
||||
* @param buffer A string buffer for the error (contents undefined on failure).
|
||||
* @param buf_max The maximum size of the buffer.
|
||||
* @return True on success, false otherwise.
|
||||
*/
|
||||
native bool:SMC_GetErrorString(SMCError:error, String:buffer[], buf_max);
|
||||
|
||||
/**
|
||||
* Called when parsing is started.
|
||||
*
|
||||
* @param smc The SMC Parse Handle.
|
||||
* @noreturn
|
||||
*/
|
||||
functag SMC_ParseStart public(Handle:smc);
|
||||
|
||||
/**
|
||||
* Sets the SMC_ParseStart function of a parse Handle.
|
||||
*
|
||||
* @param smc Handle to an SMC Parse.
|
||||
* @param func SMC_ParseStart function.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native SMC_SetParseStart(Handle:smc, SMC_ParseStart:func);
|
||||
|
||||
/**
|
||||
* Called when parsing is halted.
|
||||
*
|
||||
* @param smc The SMC Parse Handle.
|
||||
* @param halted True if abnormally halted, false otherwise.
|
||||
* @param failed True if parsing failed, false otherwise.
|
||||
* @noreturn
|
||||
*/
|
||||
functag SMC_ParseEnd public(Handle:smc, bool:halted, bool:failed);
|
||||
|
||||
/**
|
||||
* Sets the SMC_ParseEnd of a parse handle.
|
||||
*
|
||||
* @param smc Handle to an SMC Parse.
|
||||
* @param func SMC_ParseEnd function.
|
||||
* @noreturn
|
||||
* @error Invalid or corrupt Handle.
|
||||
*/
|
||||
native SMC_SetParseEnd(Handle:smc, SMC_ParseEnd:func);
|
||||
|
||||
/**
|
||||
* Called when the parser is entering a new section or sub-section.
|
||||
* @note Enclosing quotes are always stripped.
|
||||
*
|
||||
* @param smc The SMC Parse Handle.
|
||||
* @param name String containing section name.
|
||||
* @param opt_quotes True if the section name was quote-enclosed in the file.
|
||||
* @return An SMCResult action to take.
|
||||
*/
|
||||
functag SMC_NewSection SMCResult:public(Handle:smc, const String:name[], bool:opt_quotes);
|
||||
|
||||
/**
|
||||
* Called when the parser finds a new key/value pair.
|
||||
* @note Enclosing quotes are always stripped.
|
||||
*
|
||||
* @param smc The SMC Parse Handle.
|
||||
* @param key String containing key name.
|
||||
* @param value String containing value name.
|
||||
* @param key_quotes Whether or not the key was enclosed in quotes.
|
||||
* @param value_quotes Whether or not the value was enclosed in quotes.
|
||||
* @return An SMCResult action to take.
|
||||
*/
|
||||
functag SMC_KeyValue SMCResult:public(Handle:smc, const String:key[], const String:value[], bool:key_quotes, bool:value_quotes);
|
||||
|
||||
/**
|
||||
* Called when the parser finds the end of the current section.
|
||||
*
|
||||
* @param smc The SMC Parse Handle.
|
||||
* @return An SMCResult action to take.
|
||||
*/
|
||||
functag SMC_EndSection SMCResult:public(Handle:smc);
|
||||
|
||||
/**
|
||||
* Sets the three main reader functions.
|
||||
*
|
||||
* @param smc An SMC parse Handle.
|
||||
* @param ns An SMC_NewSection function pointer.
|
||||
* @param kv An SMC_KeyValue function pointer.
|
||||
* @param es An SMC_EndSection function pointer.
|
||||
* @noreturn
|
||||
*/
|
||||
native SMC_SetReaders(Handle:smc, SMC_NewSection:ns, SMC_KeyValue:kv, SMC_EndSection:es);
|
||||
|
||||
/**
|
||||
* Called whenever a raw line is read.
|
||||
*
|
||||
* @param smc The SMC Parse Handle.
|
||||
* @param line A string containing the raw line from the file.
|
||||
* @param lineno The line number it occurs on.
|
||||
* @return An SMCResult action to take.
|
||||
*/
|
||||
functag SMC_RawLine SMCResult:public(Handle:smc, const String:line[], lineno);
|
||||
|
||||
/**
|
||||
* Sets a raw line reader on an SMC parser Handle.
|
||||
*
|
||||
* @param smc Handle to an SMC Parse.
|
||||
* @param func SMC_RawLine function.
|
||||
* @noreturn
|
||||
*/
|
||||
native SMC_SetRawLine(Handle:smc, SMC_RawLine:func);
|
||||
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _tf2_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _tf2_included
|
||||
|
||||
enum TFClassType
|
||||
{
|
||||
TFClass_Unknown = 0,
|
||||
TFClass_Scout,
|
||||
TFClass_Sniper,
|
||||
TFClass_Soldier,
|
||||
TFClass_DemoMan,
|
||||
TFClass_Medic,
|
||||
TFClass_Heavy,
|
||||
TFClass_Pyro,
|
||||
TFClass_Spy,
|
||||
TFClass_Engineer
|
||||
};
|
||||
|
||||
enum TFTeam
|
||||
{
|
||||
TFTeam_Unassigned = 0,
|
||||
TFTeam_Spectator = 1,
|
||||
TFTeam_Red = 2,
|
||||
TFTeam_Blue = 3
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Respawns a client
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @noreturn
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native TF2_RespawnPlayer(client);
|
||||
|
||||
/**
|
||||
* Disguises a client to the given model and team. Only has an effect on spies.
|
||||
*
|
||||
* Note: This only starts the disguise process and a delay occurs before the spy is fully disguised
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param team Team to disguise the player as (only TFTeam_Red and TFTeam_Blue have an effect)
|
||||
* @param class TFClassType class to disguise the player as
|
||||
* @noreturn
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native TF2_DisguisePlayer(client, TFTeam:team, TFClassType:class);
|
||||
|
||||
/**
|
||||
* Removes the current disguise from a client. Only has an effect on spies.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @noreturn
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native TF2_RemovePlayerDisguise(client);
|
||||
|
||||
/**
|
||||
* Retrieves the entity index of the CPlayerResource entity
|
||||
*
|
||||
* @return The current resource entity index.
|
||||
*/
|
||||
native TF2_GetResourceEntity();
|
||||
|
||||
/**
|
||||
* Finds the TFClassType for a given class name.
|
||||
*
|
||||
* @param classname A classname string such as "sniper" or "demoman"
|
||||
* @return A TFClassType constant.
|
||||
*/
|
||||
native TFClassType:TF2_GetClass(const String:classname[]);
|
||||
|
||||
/**
|
||||
* Called on weapon fire to decide if the current shot should be critical.
|
||||
* Return Plugin_Continue to let the original calculation or return a higher
|
||||
* action to override the decision with the value of 'result'
|
||||
*
|
||||
* @note Since critical shots are also calculated client side any changes made with
|
||||
* this will not show for the shooter. Projectile weapons such as the rocketlauncher
|
||||
* and demoman weapons will show a critical bullet but no critical sound effect.
|
||||
* Bullet hits should appear as expected.
|
||||
*
|
||||
* @param client Client Index.
|
||||
* @param weapon Weapon entity Index.
|
||||
* @param weaponname Classname of the weapon.
|
||||
* @param result Buffer param for the result of the decision.
|
||||
*/
|
||||
forward Action:TF2_CalcIsAttackCritical(client, weapon, String:weaponname[], &bool:result);
|
||||
|
||||
/**
|
||||
* Do not edit below this line!
|
||||
*/
|
||||
public Extension:__ext_tf2 =
|
||||
{
|
||||
name = "TF2 Tools",
|
||||
file = "game.tf2.ext",
|
||||
autoload = 1,
|
||||
#if defined REQUIRE_EXTENSIONS
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
@@ -0,0 +1,219 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _tf2_stocks_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _tf2_stocks_included
|
||||
|
||||
#include <tf2>
|
||||
#include <sdktools>
|
||||
|
||||
enum TFResourceType
|
||||
{
|
||||
TFResource_Ping,
|
||||
TFResource_Score,
|
||||
TFResource_Deaths,
|
||||
TFResource_TotalScore,
|
||||
TFResource_Captures,
|
||||
TFResource_Defenses,
|
||||
TFResource_Dominations,
|
||||
TFResource_Revenge,
|
||||
TFResource_BuildingsDestroyed,
|
||||
TFResource_Headshots,
|
||||
TFResource_Backstabs,
|
||||
TFResource_HealPoints,
|
||||
TFResource_Invulns,
|
||||
TFResource_Teleports,
|
||||
TFResource_ResupplyPoints,
|
||||
TFResource_KillAssists,
|
||||
TFResource_MaxHealth,
|
||||
TFResource_PlayerClass
|
||||
};
|
||||
|
||||
static const String:TFResourceNames[TFResourceType][] =
|
||||
{
|
||||
"m_iPing",
|
||||
"m_iScore",
|
||||
"m_iDeaths",
|
||||
"m_iTotalScore",
|
||||
"m_iCaptures",
|
||||
"m_iDefenses",
|
||||
"m_iDominations",
|
||||
"m_iRevenge",
|
||||
"m_iBuildingsDestroyed",
|
||||
"m_iHeadshots",
|
||||
"m_iBackstabs",
|
||||
"m_iHealPoints",
|
||||
"m_iInvulns",
|
||||
"m_iTeleports",
|
||||
"m_iResupplyPoints",
|
||||
"m_iKillAssists",
|
||||
"m_iMaxHealth",
|
||||
"m_iPlayerClass"
|
||||
};
|
||||
|
||||
/**
|
||||
* Get's a Clients current class.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param class TFClassType to change to.
|
||||
* @noreturn
|
||||
* @error Invalid client index.
|
||||
*/
|
||||
stock TFClassType:TF2_GetPlayerClass(client)
|
||||
{
|
||||
return TFClassType:GetEntProp(client, Prop_Send, "m_iClass");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set's a Clients class.
|
||||
*
|
||||
* Note: If setting player class in a player spawn hook weapons should be set to false.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param class TFClassType class symbol.
|
||||
* @param weapons This paramater is ignored.
|
||||
* @param persistant If true changes the players desired class so the change stays after death.
|
||||
* @noreturn
|
||||
* @error Invalid client index.
|
||||
*/
|
||||
stock TF2_SetPlayerClass(client, TFClassType:class, bool:weapons=true, bool:persistant=true)
|
||||
{
|
||||
SetEntProp(client, Prop_Send, "m_iClass", _:class);
|
||||
|
||||
if (persistant)
|
||||
{
|
||||
SetEntProp(client, Prop_Send, "m_iDesiredPlayerClass", _:class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves client data from the resource entity
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param type ResourceType constant
|
||||
* @return Value or -1 on failure.
|
||||
* @error Invalid client index, client not in game or failed to find resource entity.
|
||||
*/
|
||||
stock TF2_GetPlayerResourceData(client, TFResourceType:type)
|
||||
{
|
||||
if (!IsClientConnected(client))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
new offset = FindSendPropInfo("CTFPlayerResource", TFResourceNames[type]);
|
||||
|
||||
if (offset < 1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
new entity = TF2_GetResourceEntity();
|
||||
|
||||
if (entity == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return GetEntData(entity, offset + (client*4));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets client data in the resource entity
|
||||
*
|
||||
* Note: The game overwrites these values every frame, so changing them will have very little effect.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param type ResourceType constant
|
||||
* @param value Value to set.
|
||||
* @return Value or -1 on failure.
|
||||
* @error Invalid client index, client not in game or failed to find resource entity.
|
||||
*/
|
||||
stock bool:TF2_SetPlayerResourceData(client, TFResourceType:type, any:value)
|
||||
{
|
||||
if (!IsClientConnected(client))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
new offset = FindSendPropInfo("CTFPlayerResource", TFResourceNames[type]);
|
||||
|
||||
if (offset < 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
new entity = TF2_GetResourceEntity();
|
||||
|
||||
if (entity == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SetEntData(entity, offset + (client*4), value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all weapons from a client's weapon slot
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @param slot Slot index (0-5)
|
||||
* @noreturn
|
||||
* @error Invalid client, invalid slot or lack of mod support
|
||||
*/
|
||||
stock TF2_RemoveWeaponSlot(client, slot)
|
||||
{
|
||||
new weaponIndex;
|
||||
while ((weaponIndex = GetPlayerWeaponSlot(client, slot)) != -1)
|
||||
{
|
||||
RemovePlayerItem(client, weaponIndex);
|
||||
RemoveEdict(weaponIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all weapons from a client
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @noreturn
|
||||
*/
|
||||
stock TF2_RemoveAllWeapons(client)
|
||||
{
|
||||
for (new i = 0; i <= 5; i++)
|
||||
{
|
||||
TF2_RemoveWeaponSlot(client, i);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _timers_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _timers_included
|
||||
|
||||
#include <datapack>
|
||||
|
||||
#define TIMER_REPEAT (1<<0) /**< Timer will repeat until it returns Plugin_Stop */
|
||||
#define TIMER_FLAG_NO_MAPCHANGE (1<<1) /**< Timer will not carry over mapchanges */
|
||||
#define TIMER_HNDL_CLOSE (1<<9) /**< Timer will automatically call CloseHandle() on its value when finished */
|
||||
|
||||
/**
|
||||
* Any of the following prototypes will work for a timed function.
|
||||
*/
|
||||
funcenum Timer
|
||||
{
|
||||
/**
|
||||
* Called when the timer interval has elapsed.
|
||||
*
|
||||
* @param timer Handle to the timer object.
|
||||
* @param hndl Handle passed when the timer was created.
|
||||
* @return Plugin_Stop to stop a repeating timer, any other value for
|
||||
* default behavior.
|
||||
*/
|
||||
Action:public(Handle:timer, Handle:hndl),
|
||||
|
||||
/**
|
||||
* Called when the timer interval has elapsed.
|
||||
*
|
||||
* @param timer Handle to the timer object.
|
||||
* @param value Value passed when the timer was created.
|
||||
* @return Plugin_Stop to stop a repeating timer, any other value for
|
||||
* default behavior.
|
||||
*/
|
||||
Action:public(Handle:timer, any:value),
|
||||
|
||||
/**
|
||||
* Called when the timer interval has elapsed.
|
||||
*
|
||||
* @param timer Handle to the timer object.
|
||||
* @return Plugin_Stop to stop a repeating timer, any other value for
|
||||
* default behavior.
|
||||
*/
|
||||
Action:public(Handle:timer),
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a basic timer. Calling CloseHandle() on a timer will end the timer.
|
||||
*
|
||||
* @param interval Interval from the current game time to execute the given function.
|
||||
* @param func Function to execute once the given interval has elapsed.
|
||||
* @param value Handle or value to give to the timer function.
|
||||
* @param flags Flags to set (such as repeatability or auto-Handle closing).
|
||||
* @return Handle to the timer object. You do not need to call CloseHandle().
|
||||
* If the timer could not be created, INVALID_HANDLE will be returned.
|
||||
*/
|
||||
native Handle:CreateTimer(Float:interval, Timer:func, any:value=INVALID_HANDLE, flags=0);
|
||||
|
||||
/**
|
||||
* Kills a timer. Use this instead of CloseHandle() if you need more options.
|
||||
*
|
||||
* @param autoClose If autoClose is true, the timer's value will be
|
||||
* closed as a handle if TIMER_HNDL_CLOSE was not specified.
|
||||
* @noreturn
|
||||
*/
|
||||
native KillTimer(Handle:timer, bool:autoClose=false);
|
||||
|
||||
/**
|
||||
* Manually triggers a timer so its function will be called.
|
||||
*
|
||||
* @param timer Timer Handle to trigger.
|
||||
* @param reset If reset is true, the elapsed time counter is reset
|
||||
* so the full interval must pass again.
|
||||
* @noreturn
|
||||
*/
|
||||
native TriggerTimer(Handle:timer, bool:reset=false);
|
||||
|
||||
/**
|
||||
* Returns the simulated game time.
|
||||
*
|
||||
* This time is internally maintained by SourceMod and is based on the game
|
||||
* tick count and tick rate. Unlike GetGameTime(), it will increment past
|
||||
* map changes and while no players are connected. Unlike GetEngineTime(),
|
||||
* it will not increment based on the system clock (i.e. it is still bound
|
||||
* to the ticking process).
|
||||
*
|
||||
* @return Time based on the game tick count.
|
||||
*/
|
||||
native Float:GetTickedTime();
|
||||
|
||||
/**
|
||||
* Returns an estimate of the time left before the map ends. If the server
|
||||
* has not processed any frames yet (i.e. no players have joined the map yet),
|
||||
* then the time left returned will always be infinite.
|
||||
*
|
||||
* @param timeleft Variable to store the time, in seconds. If the
|
||||
* value is less than 0, the time limit is infinite.
|
||||
* @return True if the operation is supported, false otherwise.
|
||||
*/
|
||||
native bool:GetMapTimeLeft(&timeleft);
|
||||
|
||||
/**
|
||||
* Retrieves the current map time limit. If the server has not processed any
|
||||
* frames yet (i.e. no players have joined the map yet), then the time limit
|
||||
* returned will always be 0.
|
||||
*
|
||||
* @param time Set to the number of total seconds in the map time
|
||||
* limit, or 0 if there is no time limit set.
|
||||
* @return True on success, false if operation is not supported.
|
||||
*/
|
||||
native bool:GetMapTimeLimit(&time);
|
||||
|
||||
/**
|
||||
* Extends the map time limit in a way that will notify all plugins.
|
||||
*
|
||||
* @param time Number of seconds to extend map time limit by.
|
||||
* The number can be negative to decrease the time limit.
|
||||
* If 0, the map will be set to have no time limit.
|
||||
* @return True on success, false if operation is not supported.
|
||||
*/
|
||||
native bool:ExtendMapTimeLimit(time);
|
||||
|
||||
/**
|
||||
* Returns the number of seconds in between game server ticks.
|
||||
*
|
||||
* Note: A tick, in this context, is a frame.
|
||||
*
|
||||
* @return Number of seconds in between ticks.
|
||||
*/
|
||||
native Float:GetTickInterval();
|
||||
|
||||
/**
|
||||
* Notification that the map's time left has changed via a change in the time
|
||||
* limit or a change in the game rules (such as mp_restartgame). This is useful
|
||||
* for plugins trying to create timers based on the time left in the map.
|
||||
*
|
||||
* Calling ExtendMapTimeLimit() from here, without proper precaution, will
|
||||
* cause infinite recursion.
|
||||
*
|
||||
* If the operation is not supported, this will never be called.
|
||||
|
||||
* If the server has not yet processed any frames (i.e. no players have joined
|
||||
* the map yet), then this will be called once the server begins ticking, even
|
||||
* if there is no time limit set.
|
||||
*/
|
||||
forward OnMapTimeLeftChanged();
|
||||
|
||||
/**
|
||||
* Returns whether or not the server is processing frames or not.
|
||||
*
|
||||
* The server does not process frames until at least one client joins the game.
|
||||
* Once the first player has in, even if that player, leaves, the server's
|
||||
* timers and entities will work.
|
||||
*
|
||||
* @return True if the server is ticking, false otherwise.
|
||||
*/
|
||||
native bool:IsServerProcessing();
|
||||
|
||||
/**
|
||||
* Creates a timer associated with a new data pack, and returns the datapack.
|
||||
* @note The datapack is automatically freed when the timer ends.
|
||||
* @note The position of the datapack is not reset or changed for the timer function.
|
||||
*
|
||||
* @param interval Interval from the current game time to execute the given function.
|
||||
* @param func Function to execute once the given interval has elapsed.
|
||||
* @param data The newly created datapack is passed though this by-reference parameter.
|
||||
* @param flags Timer flags.
|
||||
* @return Handle to the timer object. You do not need to call CloseHandle().
|
||||
*/
|
||||
stock Handle:CreateDataTimer(Float:interval, Timer:func, &Handle:data, flags=0)
|
||||
{
|
||||
data = CreateDataPack();
|
||||
flags |= TIMER_HNDL_CLOSE;
|
||||
return CreateTimer(interval, func, data, flags);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,290 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _topmenus_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _topmenus_included
|
||||
|
||||
#include <menus>
|
||||
|
||||
/**
|
||||
* Actions a top menu will take on an object.
|
||||
*/
|
||||
enum TopMenuAction
|
||||
{
|
||||
/**
|
||||
* An option is being drawn for a menu (or for sorting purposes).
|
||||
*
|
||||
* INPUT : TopMenu Handle, object ID, client index.
|
||||
* OUTPUT: Buffer for rendering, maxlength of buffer.
|
||||
*/
|
||||
TopMenuAction_DisplayOption = 0,
|
||||
|
||||
/**
|
||||
* The title of a menu is being drawn for a given object.
|
||||
*
|
||||
* Note: The Object ID will be INVALID_TOPMENUOBJECT if drawing the
|
||||
* root title. Otherwise, the Object ID is a category.
|
||||
*
|
||||
* INPUT : TopMenu Handle, object ID, client index.
|
||||
* OUTPUT: Buffer for rendering, maxlength of buffer.
|
||||
*/
|
||||
TopMenuAction_DisplayTitle = 1,
|
||||
|
||||
/**
|
||||
* A menu option has been selected.
|
||||
*
|
||||
* The Object ID will always be an item (not a category).
|
||||
*
|
||||
* INPUT : TopMenu Handle, object ID, client index.
|
||||
*/
|
||||
TopMenuAction_SelectOption = 2,
|
||||
|
||||
/**
|
||||
* A menu option is being drawn and its flags can be overridden.
|
||||
*
|
||||
* INPUT : TopMenu Handle, object ID, client index.
|
||||
* OUTPUT: The first byte of the 'buffer' string should be set
|
||||
* to the desired flags. By default, it will contain
|
||||
* ITEMDRAW_DEFAULT.
|
||||
*/
|
||||
TopMenuAction_DrawOption = 3,
|
||||
|
||||
/**
|
||||
* Called when an object is being removed from the menu.
|
||||
* This can be used to clean up data stored in the info string.
|
||||
*
|
||||
* INPUT : TopMenu Handle, object ID.
|
||||
*/
|
||||
TopMenuAction_RemoveObject = 4,
|
||||
};
|
||||
|
||||
/**
|
||||
* Top menu object types.
|
||||
*/
|
||||
enum TopMenuObjectType
|
||||
{
|
||||
TopMenuObject_Category = 0, /**< Category (sub-menu branching from root) */
|
||||
TopMenuObject_Item = 1 /**< Item on a sub-menu */
|
||||
};
|
||||
|
||||
/**
|
||||
* Top menu starting positions for display.
|
||||
*/
|
||||
enum TopMenuPosition
|
||||
{
|
||||
TopMenuPosition_Start = 0, /**< Start/root of the menu */
|
||||
TopMenuPosition_LastRoot = 1, /**< Last position in the root menu */
|
||||
TopMenuPosition_LastCategory = 3, /**< Last position in their last category */
|
||||
};
|
||||
|
||||
/**
|
||||
* Top menu object tag for type checking.
|
||||
*/
|
||||
enum TopMenuObject
|
||||
{
|
||||
INVALID_TOPMENUOBJECT = 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* TopMenu callback prototype.
|
||||
*
|
||||
* @param topmenu Handle to the TopMenu.
|
||||
* @param action TopMenuAction being performed.
|
||||
* @param object_id The object ID (if used).
|
||||
* @param param Extra parameter (if used).
|
||||
* @param buffer Output buffer (if used).
|
||||
* @param maxlength Output buffer (if used).
|
||||
* @noreturn
|
||||
*/
|
||||
functag TopMenuHandler public(Handle:topmenu,
|
||||
TopMenuAction:action,
|
||||
TopMenuObject:object_id,
|
||||
param,
|
||||
String:buffer[],
|
||||
maxlength);
|
||||
|
||||
/**
|
||||
* Creates a TopMenu.
|
||||
*
|
||||
* @param handler Handler to use for drawing the root title.
|
||||
* @return A new TopMenu Handle, or INVALID_HANDLE on failure.
|
||||
*/
|
||||
native Handle:CreateTopMenu(TopMenuHandler:handler);
|
||||
|
||||
/**
|
||||
* Re-sorts the items in a TopMenu via a configuration file.
|
||||
*
|
||||
* The format of the configuration file should be a Valve Key-Values
|
||||
* formatted file that SourceMod can parse. There should be one root
|
||||
* section, and one sub-section for each category. Each sub-section's
|
||||
* name should match the category name.
|
||||
*
|
||||
* Each sub-section may only contain key/value pairs in the form of:
|
||||
* key: "item"
|
||||
* value: Name of the item as passed to AddToTopMenu().
|
||||
*
|
||||
* The TopMenu will draw items in the order declared in the configuration
|
||||
* file. If items do not appear in the configuration file, they are sorted
|
||||
* per-player based on how the handler function renders for that player.
|
||||
* These items appear after the configuration sorted items.
|
||||
*
|
||||
* @param topmenu TopMenu Handle.
|
||||
* @param file File path.
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum size of the error buffer.
|
||||
* Error buffer will be filled with a
|
||||
* zero-terminated string if false is
|
||||
* returned.
|
||||
* @return True on success, false on failure.
|
||||
* @error Invalid TopMenu Handle.
|
||||
*/
|
||||
native bool:LoadTopMenuConfig(Handle:topmenu, const String:file[], String:error[], maxlength);
|
||||
|
||||
/**
|
||||
* Adds an object to a TopMenu.
|
||||
*
|
||||
* @param topmenu TopMenu Handle.
|
||||
* @param name Object name (MUST be unique).
|
||||
* @param type Object type.
|
||||
* @param handler Handler for object.
|
||||
* @param cmdname Command name (for access overrides).
|
||||
* @param flags Default access flags.
|
||||
* @param parent Parent object ID, or INVALID_TOPMENUOBJECT for none.
|
||||
* Items must have a category parent.
|
||||
* Categories must not have a parent.
|
||||
* @param info_string Arbitrary storage (max 255 bytes).
|
||||
* @return A new TopMenuObject ID, or INVALID_TOPMENUOBJECT on
|
||||
* failure.
|
||||
* @error Invalid TopMenu Handle.
|
||||
*/
|
||||
native TopMenuObject:AddToTopMenu(Handle:topmenu,
|
||||
const String:name[],
|
||||
TopMenuObjectType:type,
|
||||
TopMenuHandler:handler,
|
||||
TopMenuObject:parent,
|
||||
const String:cmdname[]="",
|
||||
flags=0,
|
||||
const String:info_string[]="");
|
||||
|
||||
/**
|
||||
* Retrieves the info string of a top menu item.
|
||||
*
|
||||
* @param topmenu TopMenu Handle.
|
||||
* @param object TopMenuObject ID.
|
||||
* @param buffer Buffer to store info string.
|
||||
* @param maxlength Maximum size of info string.
|
||||
* @return Number of bytes written, not including the
|
||||
* null terminator.
|
||||
* @error Invalid TopMenu Handle or TopMenuObject ID.
|
||||
*/
|
||||
native GetTopMenuInfoString(Handle:topmenu, TopMenuObject:parent, String:buffer[], maxlength);
|
||||
|
||||
/**
|
||||
* Retrieves the name string of a top menu item.
|
||||
*
|
||||
* @param topmenu TopMenu Handle.
|
||||
* @param object TopMenuObject ID.
|
||||
* @param buffer Buffer to store info string.
|
||||
* @param maxlength Maximum size of info string.
|
||||
* @return Number of bytes written, not including the
|
||||
* null terminator.
|
||||
* @error Invalid TopMenu Handle or TopMenuObject ID.
|
||||
*/
|
||||
native GetTopMenuObjName(Handle:topmenu, TopMenuObject:object, String:buffer[], maxlength);
|
||||
|
||||
/**
|
||||
* Removes an object from a TopMenu.
|
||||
*
|
||||
* Plugins' objects are automatically removed all TopMenus when the given
|
||||
* plugin unloads or pauses. In the case of unpausing, all items are restored.
|
||||
*
|
||||
* @param topmenu TopMenu Handle.
|
||||
* @param object TopMenuObject ID.
|
||||
* @noreturn
|
||||
* @error Invalid TopMenu Handle.
|
||||
*/
|
||||
native RemoveFromTopMenu(Handle:topmenu, TopMenuObject:object);
|
||||
|
||||
/**
|
||||
* Displays a TopMenu to a client.
|
||||
*
|
||||
* @param topmenu TopMenu Handle.
|
||||
* @param client Client index.
|
||||
* @param position Position to display from.
|
||||
* @return True on success, false on failure.
|
||||
* @error Invalid TopMenu Handle or client not in game.
|
||||
*/
|
||||
native bool:DisplayTopMenu(Handle:topmenu, client, TopMenuPosition:position);
|
||||
|
||||
/**
|
||||
* Finds a category's object ID in a TopMenu.
|
||||
*
|
||||
* @param topmenu TopMenu Handle.
|
||||
* @param name Object's unique name.
|
||||
* @return TopMenuObject ID on success, or
|
||||
* INVALID_TOPMENUOBJECT on failure.
|
||||
* @error Invalid TopMenu Handle.
|
||||
*/
|
||||
native TopMenuObject:FindTopMenuCategory(Handle:topmenu, const String:name[]);
|
||||
|
||||
/**
|
||||
* Do not edit below this line!
|
||||
*/
|
||||
public Extension:__ext_topmenus =
|
||||
{
|
||||
name = "TopMenus",
|
||||
file = "topmenus.ext",
|
||||
#if defined AUTOLOAD_EXTENSIONS
|
||||
autoload = 1,
|
||||
#else
|
||||
autoload = 0,
|
||||
#endif
|
||||
#if defined REQUIRE_EXTENSIONS
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined REQUIRE_EXTENSIONS
|
||||
public __ext_topmenus_SetNTVOptional()
|
||||
{
|
||||
MarkNativeAsOptional("CreateTopMenu");
|
||||
MarkNativeAsOptional("LoadTopMenuConfig");
|
||||
MarkNativeAsOptional("AddToTopMenu");
|
||||
MarkNativeAsOptional("RemoveFromTopMenu");
|
||||
MarkNativeAsOptional("DisplayTopMenu");
|
||||
MarkNativeAsOptional("FindTopMenuCategory");
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,202 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This file is part of the SourceMod/SourcePawn SDK.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined _eventsmsgs_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _eventsmsgs_included
|
||||
|
||||
/**
|
||||
* UserMsg helper values.
|
||||
*/
|
||||
enum UserMsg
|
||||
{
|
||||
INVALID_MESSAGE_ID = -1,
|
||||
};
|
||||
|
||||
/**
|
||||
* @section Message Flags.
|
||||
*/
|
||||
#define USERMSG_RELIABLE (1<<2) /**< Message will be set on the reliable stream */
|
||||
#define USERMSG_INITMSG (1<<3) /**< Message will be considered to be an initmsg */
|
||||
#define USERMSG_BLOCKHOOKS (1<<7) /**< Prevents the message from triggering SourceMod and Metamod hooks */
|
||||
|
||||
/**
|
||||
* @endsection
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the ID of a given message, or -1 on failure.
|
||||
*
|
||||
* @param msg String containing message name (case sensitive).
|
||||
* @return A message index, or INVALID_MESSAGE_ID on failure.
|
||||
*/
|
||||
native UserMsg:GetUserMessageId(const String:msg[]);
|
||||
|
||||
/**
|
||||
* Retrieves the name of a message by ID.
|
||||
*
|
||||
* @param msg_id Message index.
|
||||
* @param msg Buffer to store the name of the message.
|
||||
* @param maxlength Maximum length of string buffer.
|
||||
* @return True if message index is valid, false otherwise.
|
||||
*/
|
||||
native bool:GetUserMessageName(UserMsg:msg_id, String:msg[], maxlength);
|
||||
|
||||
/**
|
||||
* Starts a usermessage (network message).
|
||||
* @note Only one message can be active at a time.
|
||||
* @note It is illegal to send any message while a non-intercept hook is in progress.
|
||||
*
|
||||
* @param msgname Message name to start.
|
||||
* @param clients Array containing player indexes to broadcast to.
|
||||
* @param numClients Number of players in the array.
|
||||
* @param flags Optional flags to set.
|
||||
* @return A handle to a bf_write bit packing structure, or
|
||||
* INVALID_HANDLE on failure.
|
||||
* @error Invalid message name, unable to start a message, invalid client,
|
||||
* or client not connected.
|
||||
*/
|
||||
native Handle:StartMessage(String:msgname[], clients[], numClients, flags=0);
|
||||
|
||||
/**
|
||||
* Starts a usermessage (network message).
|
||||
* @note Only one message can be active at a time.
|
||||
* @note It is illegal to send any message while a non-intercept hook is in progress.
|
||||
*
|
||||
* @param msg Message index to start.
|
||||
* @param clients Array containing player indexes to broadcast to.
|
||||
* @param numClients Number of players in the array.
|
||||
* @param flags Optional flags to set.
|
||||
* @return A handle to a bf_write bit packing structure, or
|
||||
* INVALID_HANDLE on failure.
|
||||
* @error Invalid message name, unable to start a message, invalid client,
|
||||
* or client not connected.
|
||||
*/
|
||||
native Handle:StartMessageEx(UserMsg:msg, clients[], numClients, flags=0);
|
||||
|
||||
/**
|
||||
* Ends a previously started user message (network message).
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
native EndMessage();
|
||||
|
||||
/**
|
||||
* Called when a message is hooked
|
||||
*
|
||||
* @param msg_id Message index.
|
||||
* @param bf Handle to the input bit buffer of the message.
|
||||
* @param players Array containing player indexes.
|
||||
* @param playersNum Number of players in the array.
|
||||
* @param reliable True if message is reliable, false otherwise.
|
||||
* @param init True if message is an initmsg, false otherwise.
|
||||
* @return Ignored for normal hooks. For intercept hooks, Plugin_Handled
|
||||
* blocks the message from being sent, and Plugin_Continue
|
||||
* resumes normal functionality.
|
||||
*/
|
||||
functag MsgHook Action:public(UserMsg:msg_id, Handle:bf, const players[], playersNum, bool:reliable, bool:init);
|
||||
|
||||
/**
|
||||
* Called when a message is finished sending.
|
||||
*
|
||||
* @param msg_id Message index.
|
||||
*/
|
||||
functag MsgSentNotify public(UserMsg:msg_id);
|
||||
|
||||
/**
|
||||
* Hooks a user message.
|
||||
*
|
||||
* @param msg_id Message index.
|
||||
* @param hook Function to use as a hook.
|
||||
* @param intercept If intercept is true, message will be fully intercepted,
|
||||
* allowing the user to block the message. Otherwise,
|
||||
* the hook is normal and ignores the return value.
|
||||
* @param notify Notification function.
|
||||
* @noreturn
|
||||
* @error Invalid message index.
|
||||
*/
|
||||
native HookUserMessage(UserMsg:msg_id, MsgHook:hook, bool:intercept=false, MsgSentNotify:notify=MsgSentNotify:-1);
|
||||
|
||||
/**
|
||||
* Removes one usermessage hook.
|
||||
*
|
||||
* @param msg_id Message index.
|
||||
* @param hook Function used for the hook.
|
||||
* @param intercept Specifies whether the hook was an intercept hook or not.
|
||||
* @noreturn
|
||||
* @error Invalid message index.
|
||||
*/
|
||||
native UnhookUserMessage(UserMsg:msg_id, MsgHook:hook, bool:intercept=false);
|
||||
|
||||
/**
|
||||
* Starts a usermessage (network message) that broadcasts to all clients.
|
||||
* @note See StartMessage or StartMessageEx().
|
||||
*
|
||||
* @param msgname Message name to start.
|
||||
* @param flags Optional flags to set.
|
||||
* @return A handle to a bf_write bit packing structure, or
|
||||
* INVALID_HANDLE on failure.
|
||||
*/
|
||||
stock Handle:StartMessageAll(String:msgname[], flags=0)
|
||||
{
|
||||
new maxClients = GetMaxClients();
|
||||
new total = 0;
|
||||
new clients[maxClients];
|
||||
for (new i=1; i<=maxClients; i++)
|
||||
{
|
||||
if (IsClientConnected(i))
|
||||
{
|
||||
clients[total++] = i;
|
||||
}
|
||||
}
|
||||
return StartMessage(msgname, clients, total, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a simpler usermessage (network message) for one client.
|
||||
* @note See StartMessage or StartMessageEx().
|
||||
*
|
||||
* @param msgname Message name to start.
|
||||
* @param client Client to send to.
|
||||
* @param flags Optional flags to set.
|
||||
* @return A handle to a bf_write bit packing structure, or
|
||||
* INVALID_HANDLE on failure.
|
||||
*/
|
||||
stock Handle:StartMessageOne(String:msgname[], client, flags=0)
|
||||
{
|
||||
new players[1];
|
||||
|
||||
players[0] = client;
|
||||
|
||||
return StartMessage(msgname, players, 1, flags);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user