Fix includes

This commit is contained in:
BotoX 2017-02-26 00:16:12 +01:00
parent 106e04ae7e
commit a68896fc18
27 changed files with 5545 additions and 1761 deletions

View File

@ -1,3 +1,6 @@
#pragma semicolon 1
#pragma newdecls required
#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
@ -7,9 +10,6 @@
#include <zombiereloaded>
#define REQUIRE_PLUGIN
#pragma semicolon 1
#pragma newdecls required
public Plugin myinfo =
{
name = "GlowColors",
@ -334,12 +334,12 @@ public Action Timer_ApplyGlowColor(Handle timer, int serial)
ApplyGlowColor(client);
}
public int ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn)
public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn)
{
ApplyGlowColor(client);
}
public int ZR_OnClientHumanPost(int client, bool respawn, bool protect)
public void ZR_OnClientHumanPost(int client, bool respawn, bool protect)
{
ApplyGlowColor(client);
}

View File

@ -1,9 +1,8 @@
#pragma semicolon 1
#pragma newdecls required
#include <sourcemod>
#include "morecolors.inc"
#pragma newdecls required
#include <multicolors>
Handle g_hCVar_NotificationTime = INVALID_HANDLE;
char g_sAttackerSID[MAXPLAYERS + 1][32];

View File

@ -144,12 +144,12 @@ public void Event_TeamChange(Handle event, const char[] name, bool dontBroadcast
UpdateSpecialMutesOtherClients(client);
}
public int ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn)
public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn)
{
UpdateSpecialMutesOtherClients(client);
}
public int ZR_OnClientHumanPost(int client, bool respawn, bool protect)
public void ZR_OnClientHumanPost(int client, bool respawn, bool protect)
{
UpdateSpecialMutesOtherClients(client);
}

View File

@ -1,11 +1,10 @@
#pragma semicolon 1
#pragma newdecls required
#include <sourcemod>
#include <sdktools>
#include "morecolors.inc"
#undef REQUIRE_PLUGIN
#include <multicolors>
#pragma newdecls required
#define PLUGIN_VERSION "1.3.0"
bool g_bStopSound[MAXPLAYERS+1];

View File

@ -10,7 +10,7 @@ if __name__ == "__main__":
Plugins = []
Path, Directories, Files = next(os.walk("."))
for Directory in Directories:
if Directory != ".git" and Directory != "include" and Directory != "includes" and Directory != "plugins":
if not Directory.startswith(".") and Directory != "include" and Directory != "includes" and Directory != "plugins":
Plugins.append(Directory)
for Plugin in Plugins:

View File

@ -1,13 +1,11 @@
#pragma semicolon 1
#pragma newdecls required
#include <sourcemod>
#include <regex>
#include <morecolors>
#include <multicolors>
//#undef REQUIRE_PLUGIN
#include <adminmenu>
#pragma newdecls required
#include <ccc>
#define PLUGIN_VERSION "6.1.4"
@ -2589,7 +2587,7 @@ public Action Hook_UserMessage(UserMsg msg_id, Handle bf, const players[], int p
if (!g_msgAuthor || HasFlag(g_msgAuthor, Admin_Generic))
{
CReplaceColorCodes(g_msgText, g_msgAuthor, false, sizeof(g_msgText));
CFormatColor(g_msgText, sizeof(g_msgText), g_msgAuthor);
}
if (!bIsAction)

63
includes/AsyncSocket.inc Normal file
View File

@ -0,0 +1,63 @@
#if defined _AsyncSocket_included
#endinput
#endif
#define _AsyncSocket_included
typedef AsyncSocketConnectCallback = function void(AsyncSocket socket);
typedef AsyncSocketErrorCallback = function void(AsyncSocket socket, int error, const char[] errorName);
typedef AsyncSocketDataCallback = function void(AsyncSocket socket, const char[] data, const int size);
methodmap AsyncSocket < Handle {
public native AsyncSocket();
public native bool Connect(const char[] host, const int port);
public native bool Listen(const char[] host, const int port);
public native bool Write(const char[] data, int length = -1);
public bool WriteNull(const char[] data)
{
this.Write(data, strlen(data) + 1);
}
public native bool SetConnectCallback(AsyncSocketConnectCallback callback);
public native bool SetErrorCallback(AsyncSocketErrorCallback callback);
public native bool SetDataCallback(AsyncSocketDataCallback callback);
}
/**
* Do not edit below this line!
*/
public Extension __ext_AsyncSocket =
{
name = "AsyncSocket",
file = "AsyncSocket.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_AsyncSocket_SetNTVOptional()
{
MarkNativeAsOptional("AsyncSocket.AsyncSocket");
MarkNativeAsOptional("AsyncSocket.Connect");
MarkNativeAsOptional("AsyncSocket.Listen");
MarkNativeAsOptional("AsyncSocket.Write");
MarkNativeAsOptional("AsyncSocket.SetConnectCallback");
MarkNativeAsOptional("AsyncSocket.SetErrorCallback");
MarkNativeAsOptional("AsyncSocket.SetDataCallback");
}
#endif

116
includes/basic.inc Normal file
View File

@ -0,0 +1,116 @@
/**
* =============================================================================
* Dynamic for SourceMod (C)2016 Matthew J Dunn. 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/>.
*
*/
#if defined _dynamic_basic_included
#endinput
#endif
#define _dynamic_basic_included
/*
This methodmap is based on the Dynamic methodmap while using a StringMap methodmap
for implementation. This methodmap doesn't implement the full features of the Dynamic
methodmap (type conversion, object naming, plugin sharing, ect). This methodmap can
be used for basic storage using the standard Dynamic methodmap Methods.
Please see '\scripting\dynamic\examples\basic\' for an example usage of this methodmap
*/
methodmap Basic < StringMap
{
public Basic()
{
return view_as<Basic>(new StringMap());
}
public int GetInt(const char[] membername, int defaultvalue=-1)
{
int value;
if (this.GetValue(membername, value))
return value;
return defaultvalue;
}
public void SetInt(const char[] membername, int value)
{
this.SetValue(membername, value);
}
public bool GetBool(const char[] membername, bool defaultvalue=false)
{
bool value;
if (this.GetValue(membername, value))
return value;
return defaultvalue;
}
public void SetBool(const char[] membername, bool value)
{
this.SetValue(membername, value);
}
public float GetFloat(const char[] membername, float defaultvalue=-1.0)
{
float value;
if (this.GetValue(membername, value))
return value;
return defaultvalue;
}
public void SetFloat(const char[] membername, float value)
{
this.SetValue(membername, value);
}
public bool GetString(const char[] membername, char[] buffer, int length)
{
return this.GetString(membername, buffer, length);
}
public void SetString(const char[] membername, const char[] value)
{
this.SetString(membername, value);
}
public Handle GetHandle(const char[] membername)
{
Handle value;
if (this.GetValue(membername, value))
return value;
return null;
}
public void SetHandle(const char[] membername, Handle value)
{
this.SetValue(membername, value);
}
public bool GetVector(const char[] membername, float[3] vector)
{
return this.GetArray(membername, vector, sizeof(vector));
}
public void SetVector(const char[] membername, const float[3] value)
{
this.SetArray(membername, value, sizeof(value));
}
}

View File

@ -1,539 +0,0 @@
/**************************************************************************
* *
* Colored Chat Functions *
* Author: exvel, Editor: Popoklopsi, Powerlord, Bara *
* Version: 1.1.3 *
* *
**************************************************************************/
#if defined _colors_included
#endinput
#endif
#define _colors_included
#define MAX_MESSAGE_LENGTH 250
#define MAX_COLORS 12
#define SERVER_INDEX 0
#define NO_INDEX -1
#define NO_PLAYER -2
enum Colors
{
Color_Default = 0,
Color_Darkred,
Color_Green,
Color_Lightgreen,
Color_Red,
Color_Blue,
Color_Olive,
Color_Lime,
Color_Lightred,
Color_Purple,
Color_Grey,
Color_Orange
}
/* Colors' properties */
new String:CTag[][] = {"{default}", "{darkred}", "{green}", "{lightgreen}", "{red}", "{blue}", "{olive}", "{lime}", "{lightred}", "{purple}", "{grey}", "{orange}"};
new String:CTagCode[][] = {"\x01", "\x02", "\x04", "\x03", "\x03", "\x03", "\x05", "\x06", "\x07", "\x03", "\x08", "\x09"};
new bool:CTagReqSayText2[] = {false, false, false, true, true, true, false, false, false, false, false, false};
new bool:CEventIsHooked = false;
new bool:CSkipList[MAXPLAYERS+1] = {false,...};
/* Game default profile */
new bool:CProfile_Colors[] = {true, false, true, false, false, false, false, false, false, false, false, false};
new CProfile_TeamIndex[] = {NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX};
new bool:CProfile_SayText2 = false;
/**
* Prints a message to a specific client in the chat area.
* Supports color tags.
*
* @param client Client index.
* @param szMessage Message (formatting rules).
* @return No return
*
* On error/Errors: If the client is not connected an error will be thrown.
*/
stock CPrintToChat(client, const String:szMessage[], any:...)
{
if (client <= 0 || client > MaxClients)
ThrowError("Invalid client index %d", client);
if (!IsClientInGame(client))
ThrowError("Client %d is not in game", client);
decl String:szBuffer[MAX_MESSAGE_LENGTH];
decl String:szCMessage[MAX_MESSAGE_LENGTH];
SetGlobalTransTarget(client);
Format(szBuffer, sizeof(szBuffer), "\x01%s", szMessage);
VFormat(szCMessage, sizeof(szCMessage), szBuffer, 3);
new index = CFormat(szCMessage, sizeof(szCMessage));
if (index == NO_INDEX)
PrintToChat(client, "%s", szCMessage);
else
CSayText2(client, index, szCMessage);
}
stock CReplyToCommand(client, const String:szMessage[], any:...)
{
decl String:szCMessage[MAX_MESSAGE_LENGTH];
VFormat(szCMessage, sizeof(szCMessage), szMessage, 3);
if (client == 0)
{
CRemoveTags(szCMessage, sizeof(szCMessage));
PrintToServer("%s", szCMessage);
}
else if (GetCmdReplySource() == SM_REPLY_TO_CONSOLE)
{
CRemoveTags(szCMessage, sizeof(szCMessage));
PrintToConsole(client, "%s", szCMessage);
}
else
{
CPrintToChat(client, "%s", szCMessage);
}
}
/**
* Prints a message to all clients in the chat area.
* Supports color tags.
*
* @param client Client index.
* @param szMessage Message (formatting rules)
* @return No return
*/
stock CPrintToChatAll(const String:szMessage[], any:...)
{
decl String:szBuffer[MAX_MESSAGE_LENGTH];
for (new i = 1; i <= MaxClients; i++)
{
if (IsClientInGame(i) && !IsFakeClient(i) && !CSkipList[i])
{
SetGlobalTransTarget(i);
VFormat(szBuffer, sizeof(szBuffer), szMessage, 2);
CPrintToChat(i, "%s", szBuffer);
}
CSkipList[i] = false;
}
}
/**
* Prints a message to a specific client in the chat area.
* Supports color tags and teamcolor tag.
*
* @param client Client index.
* @param author Author index whose color will be used for teamcolor tag.
* @param szMessage Message (formatting rules).
* @return No return
*
* On error/Errors: If the client or author are not connected an error will be thrown.
*/
stock CPrintToChatEx(client, author, const String:szMessage[], any:...)
{
if (client <= 0 || client > MaxClients)
ThrowError("Invalid client index %d", client);
if (!IsClientInGame(client))
ThrowError("Client %d is not in game", client);
if (author < 0 || author > MaxClients)
ThrowError("Invalid client index %d", author);
decl String:szBuffer[MAX_MESSAGE_LENGTH];
decl String:szCMessage[MAX_MESSAGE_LENGTH];
SetGlobalTransTarget(client);
Format(szBuffer, sizeof(szBuffer), "\x01%s", szMessage);
VFormat(szCMessage, sizeof(szCMessage), szBuffer, 4);
new index = CFormat(szCMessage, sizeof(szCMessage), author);
if (index == NO_INDEX)
PrintToChat(client, "%s", szCMessage);
else
CSayText2(client, author, szCMessage);
}
/**
* Prints a message to all clients in the chat area.
* Supports color tags and teamcolor tag.
*
* @param author Author index whos color will be used for teamcolor tag.
* @param szMessage Message (formatting rules).
* @return No return
*
* On error/Errors: If the author is not connected an error will be thrown.
*/
stock CPrintToChatAllEx(author, const String:szMessage[], any:...)
{
if (author < 0 || author > MaxClients)
ThrowError("Invalid client index %d", author);
if (!IsClientInGame(author))
ThrowError("Client %d is not in game", author);
decl String:szBuffer[MAX_MESSAGE_LENGTH];
for (new i = 1; i <= MaxClients; i++)
{
if (IsClientInGame(i) && !IsFakeClient(i) && !CSkipList[i])
{
SetGlobalTransTarget(i);
VFormat(szBuffer, sizeof(szBuffer), szMessage, 3);
CPrintToChatEx(i, author, "%s", szBuffer);
}
CSkipList[i] = false;
}
}
/**
* Removes color tags from the string.
*
* @param szMessage String.
* @return No return
*/
stock CRemoveTags(String:szMessage[], maxlength)
{
for (new i = 0; i < MAX_COLORS; i++)
ReplaceString(szMessage, maxlength, CTag[i], "", false);
ReplaceString(szMessage, maxlength, "{teamcolor}", "", false);
}
/**
* Checks whether a color is allowed or not
*
* @param tag Color Tag.
* @return True when color is supported, otherwise false
*/
stock CColorAllowed(Colors:color)
{
if (!CEventIsHooked)
{
CSetupProfile();
CEventIsHooked = true;
}
return CProfile_Colors[color];
}
/**
* Replace the color with another color
* Handle with care!
*
* @param color color to replace.
* @param newColor color to replace with.
* @noreturn
*/
stock CReplaceColor(Colors:color, Colors:newColor)
{
if (!CEventIsHooked)
{
CSetupProfile();
CEventIsHooked = true;
}
CProfile_Colors[color] = CProfile_Colors[newColor];
CProfile_TeamIndex[color] = CProfile_TeamIndex[newColor];
CTagReqSayText2[color] = CTagReqSayText2[newColor];
Format(CTagCode[color], sizeof(CTagCode[]), CTagCode[newColor])
}
/**
* This function should only be used right in front of
* CPrintToChatAll or CPrintToChatAllEx and it tells
* to those funcions to skip specified client when printing
* message to all clients. After message is printed client will
* no more be skipped.
*
* @param client Client index
* @return No return
*/
stock CSkipNextClient(client)
{
if (client <= 0 || client > MaxClients)
ThrowError("Invalid client index %d", client);
CSkipList[client] = true;
}
/**
* Replaces color tags in a string with color codes
*
* @param szMessage String.
* @param maxlength Maximum length of the string buffer.
* @return Client index that can be used for SayText2 author index
*
* On error/Errors: If there is more then one team color is used an error will be thrown.
*/
stock CFormat(String:szMessage[], maxlength, author=NO_INDEX)
{
decl String:szGameName[30];
GetGameFolderName(szGameName, sizeof(szGameName));
/* Hook event for auto profile setup on map start */
if (!CEventIsHooked)
{
CSetupProfile();
HookEvent("server_spawn", CEvent_MapStart, EventHookMode_PostNoCopy);
CEventIsHooked = true;
}
new iRandomPlayer = NO_INDEX;
// On CS:GO set invisible precolor
if (StrEqual(szGameName, "csgo", false))
Format(szMessage, maxlength, " \x01\x0B\x01%s", szMessage);
/* If author was specified replace {teamcolor} tag */
if (author != NO_INDEX)
{
if (CProfile_SayText2)
{
ReplaceString(szMessage, maxlength, "{teamcolor}", "\x03", false);
iRandomPlayer = author;
}
/* If saytext2 is not supported by game replace {teamcolor} with green tag */
else
ReplaceString(szMessage, maxlength, "{teamcolor}", CTagCode[Color_Green], false);
}
else
ReplaceString(szMessage, maxlength, "{teamcolor}", "", false);
/* For other color tags we need a loop */
for (new i = 0; i < MAX_COLORS; i++)
{
/* If tag not found - skip */
if (StrContains(szMessage, CTag[i], false) == -1)
continue;
/* If tag is not supported by game replace it with green tag */
else if (!CProfile_Colors[i])
ReplaceString(szMessage, maxlength, CTag[i], CTagCode[Color_Green], false);
/* If tag doesn't need saytext2 simply replace */
else if (!CTagReqSayText2[i])
ReplaceString(szMessage, maxlength, CTag[i], CTagCode[i], false);
/* Tag needs saytext2 */
else
{
/* If saytext2 is not supported by game replace tag with green tag */
if (!CProfile_SayText2)
ReplaceString(szMessage, maxlength, CTag[i], CTagCode[Color_Green], false);
/* Game supports saytext2 */
else
{
/* If random player for tag wasn't specified replace tag and find player */
if (iRandomPlayer == NO_INDEX)
{
/* Searching for valid client for tag */
iRandomPlayer = CFindRandomPlayerByTeam(CProfile_TeamIndex[i]);
/* If player not found replace tag with green color tag */
if (iRandomPlayer == NO_PLAYER)
ReplaceString(szMessage, maxlength, CTag[i], CTagCode[Color_Green], false);
/* If player was found simply replace */
else
ReplaceString(szMessage, maxlength, CTag[i], CTagCode[i], false);
}
/* If found another team color tag throw error */
else
{
//ReplaceString(szMessage, maxlength, CTag[i], "");
ThrowError("Using two team colors in one message is not allowed");
}
}
}
}
return iRandomPlayer;
}
/**
* Founds a random player with specified team
*
* @param color_team Client team.
* @return Client index or NO_PLAYER if no player found
*/
stock CFindRandomPlayerByTeam(color_team)
{
if (color_team == SERVER_INDEX)
return 0;
else
{
for (new i = 1; i <= MaxClients; i++)
{
if (IsClientInGame(i) && GetClientTeam(i) == color_team)
return i;
}
}
return NO_PLAYER;
}
/**
* Sends a SayText2 usermessage to a client
*
* @param szMessage Client index
* @param maxlength Author index
* @param szMessage Message
* @return No return.
*/
stock CSayText2(client, author, const String:szMessage[])
{
new Handle:hBuffer = StartMessageOne("SayText2", client, USERMSG_RELIABLE|USERMSG_BLOCKHOOKS);
if(GetFeatureStatus(FeatureType_Native, "GetUserMessageType") == FeatureStatus_Available && GetUserMessageType() == UM_Protobuf)
{
PbSetInt(hBuffer, "ent_idx", author);
PbSetBool(hBuffer, "chat", true);
PbSetString(hBuffer, "msg_name", szMessage);
PbAddString(hBuffer, "params", "");
PbAddString(hBuffer, "params", "");
PbAddString(hBuffer, "params", "");
PbAddString(hBuffer, "params", "");
}
else
{
BfWriteByte(hBuffer, author);
BfWriteByte(hBuffer, true);
BfWriteString(hBuffer, szMessage);
}
EndMessage();
}
/**
* Creates game color profile
* This function must be edited if you want to add more games support
*
* @return No return.
*/
stock CSetupProfile()
{
decl String:szGameName[30];
GetGameFolderName(szGameName, sizeof(szGameName));
if (StrEqual(szGameName, "cstrike", false))
{
CProfile_Colors[Color_Lightgreen] = true;
CProfile_Colors[Color_Red] = true;
CProfile_Colors[Color_Blue] = true;
CProfile_Colors[Color_Olive] = true;
CProfile_TeamIndex[Color_Lightgreen] = SERVER_INDEX;
CProfile_TeamIndex[Color_Red] = 2;
CProfile_TeamIndex[Color_Blue] = 3;
CProfile_SayText2 = true;
}
else if (StrEqual(szGameName, "csgo", false))
{
CProfile_Colors[Color_Red] = true;
CProfile_Colors[Color_Blue] = true;
CProfile_Colors[Color_Olive] = true;
CProfile_Colors[Color_Darkred] = true;
CProfile_Colors[Color_Lime] = true;
CProfile_Colors[Color_Lightred] = true;
CProfile_Colors[Color_Purple] = true;
CProfile_Colors[Color_Grey] = true;
CProfile_Colors[Color_Orange] = true;
CProfile_TeamIndex[Color_Red] = 2;
CProfile_TeamIndex[Color_Blue] = 3;
CProfile_SayText2 = true;
}
else if (StrEqual(szGameName, "tf", false))
{
CProfile_Colors[Color_Lightgreen] = true;
CProfile_Colors[Color_Red] = true;
CProfile_Colors[Color_Blue] = true;
CProfile_Colors[Color_Olive] = true;
CProfile_TeamIndex[Color_Lightgreen] = SERVER_INDEX;
CProfile_TeamIndex[Color_Red] = 2;
CProfile_TeamIndex[Color_Blue] = 3;
CProfile_SayText2 = true;
}
else if (StrEqual(szGameName, "left4dead", false) || StrEqual(szGameName, "left4dead2", false))
{
CProfile_Colors[Color_Lightgreen] = true;
CProfile_Colors[Color_Red] = true;
CProfile_Colors[Color_Blue] = true;
CProfile_Colors[Color_Olive] = true;
CProfile_TeamIndex[Color_Lightgreen] = SERVER_INDEX;
CProfile_TeamIndex[Color_Red] = 3;
CProfile_TeamIndex[Color_Blue] = 2;
CProfile_SayText2 = true;
}
else if (StrEqual(szGameName, "hl2mp", false))
{
/* hl2mp profile is based on mp_teamplay convar */
if (GetConVarBool(FindConVar("mp_teamplay")))
{
CProfile_Colors[Color_Red] = true;
CProfile_Colors[Color_Blue] = true;
CProfile_Colors[Color_Olive] = true;
CProfile_TeamIndex[Color_Red] = 3;
CProfile_TeamIndex[Color_Blue] = 2;
CProfile_SayText2 = true;
}
else
{
CProfile_SayText2 = false;
CProfile_Colors[Color_Olive] = true;
}
}
else if (StrEqual(szGameName, "dod", false))
{
CProfile_Colors[Color_Olive] = true;
CProfile_SayText2 = false;
}
/* Profile for other games */
else
{
if (GetUserMessageId("SayText2") == INVALID_MESSAGE_ID)
{
CProfile_SayText2 = false;
}
else
{
CProfile_Colors[Color_Red] = true;
CProfile_Colors[Color_Blue] = true;
CProfile_TeamIndex[Color_Red] = 2;
CProfile_TeamIndex[Color_Blue] = 3;
CProfile_SayText2 = true;
}
}
}
public Action:CEvent_MapStart(Handle:event, const String:name[], bool:dontBroadcast)
{
CSetupProfile();
for (new i = 1; i <= MaxClients; i++)
CSkipList[i] = false;
}

403
includes/multicolors.inc Normal file
View File

@ -0,0 +1,403 @@
#if defined _mutlicolors_included
#endinput
#endif
#define _mutlicolors_included
#define MuCo_VERSION "2.0.1"
#define MuCo_LoopClients(%1) for(int %1 = 1; %1 <= MaxClients; %1++)
#include <multicolors/morecolors>
#include <multicolors/colors>
/*
*
* Credits:
* - Popoklopsi
* - Powerlord
* - exvel
* - Dr. McKay
*
* Based on stamm-colors
* - https://github.com/popoklopsi/Stamm/blob/master/include/stamm/stamm-colors.inc
*
*/
/* Global var to check whether colors are fixed or not */
bool g_bCFixColors = false;
/**
* Writes a message to a client with the correct stock for the game.
*
* @param client Client index.
* @param message Message (formatting rules).
*
* @noreturn
* @error If the client is not connected an error will be thrown.
*/
stock void CPrintToChat(int client, const char[] message, any ...)
{
char buffer[MAX_MESSAGE_LENGTH];
VFormat(buffer, sizeof(buffer), message, 3);
if (!g_bCFixColors)
CFixColors();
if (!IsSource2009())
C_PrintToChat(client, "%s", buffer);
else
MC_PrintToChat(client, "%s", buffer);
}
/**
* Prints a message to all clients in the chat area.
* Supports color tags.
*
* @param client Client index.
* @param message Message (formatting rules)
* @return No return
*/
stock void CPrintToChatAll(const char[] message, any ...)
{
char buffer[MAX_MESSAGE_LENGTH];
VFormat(buffer, sizeof(buffer), message, 2);
if (!g_bCFixColors)
CFixColors();
if (!IsSource2009())
C_PrintToChatAll("%s", buffer);
else
MC_PrintToChatAll("%s", buffer);
}
/**
* Writes a message to all of a client's observers.
*
* @param target Client index.
* @param message Message (formatting rules).
*
* @noreturn
*/
stock void CPrintToChatObservers(int target, const char[] message, any ...)
{
char buffer[MAX_MESSAGE_LENGTH];
VFormat(buffer, sizeof(buffer), message, 3);
if (!g_bCFixColors)
CFixColors();
for(int client = 1; client <= MaxClients; client++)
{
if(IsClientInGame(client) && !IsPlayerAlive(client) && !IsFakeClient(client))
{
int observee = GetEntPropEnt(client, Prop_Send, "m_hObserverTarget");
int ObserverMode = GetEntProp(client, Prop_Send, "m_iObserverMode");
if(observee == target && (ObserverMode == 4 || ObserverMode == 5))
{
CPrintToChat(client, buffer);
}
}
}
}
/**
* Writes a message to a client with the correct stock for the game.
*
* @param client Client index.
* @param author Author index.
* @param message Message (formatting rules).
*
* @noreturn
* @error If the client is not connected an error will be thrown.
*/
stock void CPrintToChatEx(int client, int author, const char[] message, any ...)
{
char buffer[MAX_MESSAGE_LENGTH];
VFormat(buffer, sizeof(buffer), message, 4);
if (!g_bCFixColors)
CFixColors();
if (!IsSource2009())
C_PrintToChatEx(client, author, "%s", buffer);
else
MC_PrintToChatEx(client, author, "%s", buffer);
}
/**
* Writes a message to all clients with the correct stock for the game.
*
* @param author Author index.
* @param message Message (formatting rules).
*
* @noreturn
*/
stock void CPrintToChatAllEx(int author, const char[] message, any ...)
{
char buffer[MAX_MESSAGE_LENGTH];
VFormat(buffer, sizeof(buffer), message, 3);
if (!g_bCFixColors)
CFixColors();
if (!IsSource2009())
C_PrintToChatAllEx(author, "%s", buffer);
else
MC_PrintToChatAllEx(author, "%s", buffer);
}
/**
* Writes a message to all of a client's observers with the correct
* game stock.
*
* @param target Client index.
* @param message Message (formatting rules).
*
* @noreturn
*/
stock void CPrintToChatObserversEx(int target, const char[] message, any ...)
{
char buffer[MAX_MESSAGE_LENGTH];
VFormat(buffer, sizeof(buffer), message, 3);
if (!g_bCFixColors)
CFixColors();
for(int client = 1; client <= MaxClients; client++)
{
if(IsClientInGame(client) && !IsPlayerAlive(client) && !IsFakeClient(client))
{
int observee = GetEntPropEnt(client, Prop_Send, "m_hObserverTarget");
int ObserverMode = GetEntProp(client, Prop_Send, "m_iObserverMode");
if(observee == target && (ObserverMode == 4 || ObserverMode == 5))
{
CPrintToChatEx(client, target, buffer);
}
}
}
}
/**
* Replies to a command with colors
*
* @param client Client to reply to
* @param message Message (formatting rules)
* @noreturn
*/
stock void CReplyToCommand(int author, const char[] message, any ...)
{
char buffer[MAX_MESSAGE_LENGTH];
VFormat(buffer, sizeof(buffer), message, 3);
if (!g_bCFixColors)
CFixColors();
if (!IsSource2009())
C_ReplyToCommand(author, "%s", buffer);
else
MC_ReplyToCommand(author, "%s", buffer);
}
/**
* Replies to a command with colors
*
* @param client Client to reply to
* @param author Client to use for {teamcolor}
* @param message Message (formatting rules)
* @noreturn
*/
stock void CReplyToCommandEx(int client, int author, const char[] message, any ...)
{
char buffer[MAX_MESSAGE_LENGTH];
VFormat(buffer, sizeof(buffer), message, 4);
if (!g_bCFixColors)
CFixColors();
if (!IsSource2009())
C_ReplyToCommandEx(client, author, "%s", buffer);
else
MC_ReplyToCommandEx(client, author, "%s", buffer);
}
/**
* 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,
* CShowActivity2() is slightly more useful.
* Supports color tags.
*
* @param client Client index doing the action, or 0 for server.
* @param format Formatting rules.
* @param ... Variable number of format parameters.
* @noreturn
* @error
*/
stock void CShowActivity(int author, const char[] message, any ...)
{
char buffer[MAX_MESSAGE_LENGTH];
VFormat(buffer, sizeof(buffer), message, 3);
if (!g_bCFixColors)
CFixColors();
if (!IsSource2009())
C_ShowActivity(author, "%s", buffer);
else
MC_ShowActivity(author, "%s", buffer);
}
/**
* Same as C_ShowActivity(), except the tag parameter is used instead of "[SM] " (note that you must supply any spacing).
* Supports color tags.
*
* @param client Client index doing the action, or 0 for server.
* @param tags Tag to display with.
* @param format Formatting rules.
* @param ... Variable number of format parameters.
* @noreturn
* @error
*/
stock void CShowActivityEx(int author, const char[] tag, const char[] message, any ...)
{
char buffer[MAX_MESSAGE_LENGTH];
VFormat(buffer, sizeof(buffer), message, 4);
if (!g_bCFixColors)
CFixColors();
if (!IsSource2009())
C_ShowActivityEx(author, tag, "%s", buffer);
else
MC_ShowActivityEx(author, tag, "%s", buffer);
}
/**
* 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.
* Supports color tags.
*
* @param client Client index doing the action, or 0 for server.
* @param tags Tag to prepend to the message.
* @param format Formatting rules.
* @param ... Variable number of format parameters.
* @noreturn
* @error
*/
stock void CShowActivity2(int author, const char[] tag, const char[] message, any ...)
{
char buffer[MAX_MESSAGE_LENGTH];
VFormat(buffer, sizeof(buffer), message, 4);
if (!g_bCFixColors)
CFixColors();
if (!IsSource2009())
C_ShowActivity2(author, tag, "%s", buffer);
else
MC_ShowActivity2(author, tag, "%s", buffer);
}
/**
* Replaces color tags in a string with color codes
*
* @param message String.
* @param maxlength Maximum length of the string buffer.
*
* @noreturn
*/
stock void CFormatColor(char[] message, int maxlength, int author = -1)
{
if (!g_bCFixColors)
CFixColors();
if (!IsSource2009())
{
if (author == 0)
author = -1;
C_Format(message, maxlength, author);
}
else
{
if (author == -1)
author = 0;
MC_ReplaceColorCodes(message, author, false, maxlength);
}
}
/**
* Removes color tags from a message
*
* @param message Message to remove tags from
* @param maxlen Maximum buffer length
* @noreturn
*/
stock void CRemoveTags(char[] message, int maxlen)
{
if (!IsSource2009())
{
C_RemoveTags(message, maxlen);
}
else
{
MC_RemoveTags(message, maxlen);
}
}
/**
* Fixes missing Lightgreen color.
*
* @noreturn
*/
stock void CFixColors()
{
g_bCFixColors = true;
// Replace lightgreen if not exists
if (!C_ColorAllowed(Color_Lightgreen))
{
if (C_ColorAllowed(Color_Lime))
C_ReplaceColor(Color_Lightgreen, Color_Lime);
else if (C_ColorAllowed(Color_Olive))
C_ReplaceColor(Color_Lightgreen, Color_Olive);
}
}
stock bool IsSource2009()
{
if(GetEngineVersion() == Engine_CSS || GetEngineVersion() == Engine_HL2DM || GetEngineVersion() == Engine_DODS || GetEngineVersion() == Engine_TF2)
{
return true;
}
return false;
}

View File

@ -0,0 +1,944 @@
/**************************************************************************
* *
* Colored Chat Functions *
* Author: exvel, Editor: Popoklopsi, Powerlord, Bara *
* Version: 2.0.0-MC *
* *
**************************************************************************/
#if defined _colors_included
#endinput
#endif
#define _colors_included
#define MAX_MESSAGE_LENGTH 250
#define MAX_COLORS 18
#define SERVER_INDEX 0
#define NO_INDEX -1
#define NO_PLAYER -2
enum C_Colors
{
Color_Default = 0,
Color_Darkred,
Color_Green,
Color_Lightgreen,
Color_Red,
Color_Blue,
Color_Olive,
Color_Lime,
Color_Lightred,
Color_Purple,
Color_Grey,
Color_Orange,
Color_Bluegrey,
Color_Lightblue,
Color_Darkblue,
Color_Grey2,
Color_Orchid,
Color_Lightred2
}
/* C_Colors' properties */
char C_Tag[][] = {"{default}", "{darkred}", "{green}", "{lightgreen}", "{red}", "{blue}", "{olive}", "{lime}", "{lightred}", "{purple}", "{grey}", "{orange}", "{bluegrey}", "{lightblue}", "{darkblue}", "{grey2}", "{orchid}", "{lightred2}"};
char C_TagCode[][] = {"\x01", "\x02", "\x04", "\x03", "\x03", "\x03", "\x05", "\x06", "\x07", "\x03", "\x08", "\x09", "\x0A", "\x0B", "\x0C", "\x0D", "\x0E", "\x0F"};
bool C_TagReqSayText2[] = {false, false, false, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false};
bool C_EventIsHooked = false;
bool C_SkipList[MAXPLAYERS+1] = {false,...};
/* Game default profile */
bool C_Profile_Colors[] = {true, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false};
int C_Profile_TeamIndex[] = {NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX};
bool C_Profile_SayText2 = false;
static Handle sm_show_activity = null;
/**
* Prints a message to a specific client in the chat area.
* Supports color tags.
*
* @param client Client index.
* @param szMessage Message (formatting rules).
* @return No return
*
* On error/Errors: If the client is not connected an error will be thrown.
*/
stock void C_PrintToChat(int client, const char[] szMessage, any ...)
{
if (client <= 0 || client > MaxClients)
ThrowError("Invalid client index %d", client);
if (!IsClientInGame(client))
ThrowError("Client %d is not in game", client);
char szBuffer[MAX_MESSAGE_LENGTH];
char szCMessage[MAX_MESSAGE_LENGTH];
SetGlobalTransTarget(client);
Format(szBuffer, sizeof(szBuffer), "\x01%s", szMessage);
VFormat(szCMessage, sizeof(szCMessage), szBuffer, 3);
int index = C_Format(szCMessage, sizeof(szCMessage));
if (index == NO_INDEX)
PrintToChat(client, "%s", szCMessage);
else
C_SayText2(client, index, szCMessage);
}
/**
* 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, C_PrintToChat() is used.
* Supports color tags.
*
* @param client Client index, or 0 for server.
* @param szMessage Formatting rules.
* @param ... Variable number of format parameters.
* @return No return
*
* On error/Errors: If the client is not connected or invalid.
*/
stock void C_ReplyToCommand(int client, const char[] szMessage, any ...)
{
char szCMessage[MAX_MESSAGE_LENGTH];
SetGlobalTransTarget(client);
VFormat(szCMessage, sizeof(szCMessage), szMessage, 3);
if (client == 0)
{
C_RemoveTags(szCMessage, sizeof(szCMessage));
PrintToServer("%s", szCMessage);
}
else if (GetCmdReplySource() == SM_REPLY_TO_CONSOLE)
{
C_RemoveTags(szCMessage, sizeof(szCMessage));
PrintToConsole(client, "%s", szCMessage);
}
else
{
C_PrintToChat(client, "%s", szCMessage);
}
}
/**
* 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, C_PrintToChat() is used.
* Supports color tags.
*
* @param client Client index, or 0 for server.
* @param author Author index whose color will be used for teamcolor tag.
* @param szMessage Formatting rules.
* @param ... Variable number of format parameters.
* @return No return
*
* On error/Errors: If the client is not connected or invalid.
*/
stock void C_ReplyToCommandEx(int client, int author, const char[] szMessage, any ...)
{
char szCMessage[MAX_MESSAGE_LENGTH];
SetGlobalTransTarget(client);
VFormat(szCMessage, sizeof(szCMessage), szMessage, 4);
if (client == 0)
{
C_RemoveTags(szCMessage, sizeof(szCMessage));
PrintToServer("%s", szCMessage);
}
else if (GetCmdReplySource() == SM_REPLY_TO_CONSOLE)
{
C_RemoveTags(szCMessage, sizeof(szCMessage));
PrintToConsole(client, "%s", szCMessage);
}
else
{
C_PrintToChatEx(client, author, "%s", szCMessage);
}
}
/**
* Prints a message to all clients in the chat area.
* Supports color tags.
*
* @param client Client index.
* @param szMessage Message (formatting rules)
* @return No return
*/
stock void C_PrintToChatAll(const char[] szMessage, any ...)
{
char szBuffer[MAX_MESSAGE_LENGTH];
MuCo_LoopClients(i)
{
if (i > 0 && IsClientInGame(i) && !IsFakeClient(i) && !C_SkipList[i])
{
SetGlobalTransTarget(i);
VFormat(szBuffer, sizeof(szBuffer), szMessage, 2);
C_PrintToChat(i, "%s", szBuffer);
}
C_SkipList[i] = false;
}
}
/**
* Prints a message to a specific client in the chat area.
* Supports color tags and teamcolor tag.
*
* @param client Client index.
* @param author Author index whose color will be used for teamcolor tag.
* @param szMessage Message (formatting rules).
* @return No return
*
* On error/Errors: If the client or author are not connected an error will be thrown.
*/
stock void C_PrintToChatEx(int client, int author, const char[] szMessage, any ...)
{
if (client <= 0 || client > MaxClients)
ThrowError("Invalid client index %d", client);
if (!IsClientInGame(client))
ThrowError("Client %d is not in game", client);
if (author < 0 || author > MaxClients)
ThrowError("Invalid client index %d", author);
char szBuffer[MAX_MESSAGE_LENGTH];
char szCMessage[MAX_MESSAGE_LENGTH];
SetGlobalTransTarget(client);
Format(szBuffer, sizeof(szBuffer), "\x01%s", szMessage);
VFormat(szCMessage, sizeof(szCMessage), szBuffer, 4);
int index = C_Format(szCMessage, sizeof(szCMessage), author);
if (index == NO_INDEX)
PrintToChat(client, "%s", szCMessage);
else
C_SayText2(client, author, szCMessage);
}
/**
* Prints a message to all clients in the chat area.
* Supports color tags and teamcolor tag.
*
* @param author Author index whos color will be used for teamcolor tag.
* @param szMessage Message (formatting rules).
* @return No return
*
* On error/Errors: If the author is not connected an error will be thrown.
*/
stock void C_PrintToChatAllEx(int author, const char[] szMessage, any ...)
{
if (author < 0 || author > MaxClients)
ThrowError("Invalid client index %d", author);
if (!IsClientInGame(author))
ThrowError("Client %d is not in game", author);
char szBuffer[MAX_MESSAGE_LENGTH];
MuCo_LoopClients(i)
{
if (i > 0 && IsClientInGame(i) && !IsFakeClient(i) && !C_SkipList[i])
{
SetGlobalTransTarget(i);
VFormat(szBuffer, sizeof(szBuffer), szMessage, 3);
C_PrintToChatEx(i, author, "%s", szBuffer);
}
C_SkipList[i] = false;
}
}
/**
* Removes color tags from the string.
*
* @param szMessage String.
* @return No return
*/
stock void C_RemoveTags(char[] szMessage, int maxlength)
{
for (int i = 0; i < MAX_COLORS; i++)
ReplaceString(szMessage, maxlength, C_Tag[i], "", false);
ReplaceString(szMessage, maxlength, "{teamcolor}", "", false);
}
/**
* Checks whether a color is allowed or not
*
* @param tag Color Tag.
* @return True when color is supported, otherwise false
*/
stock bool C_ColorAllowed(C_Colors color)
{
if (!C_EventIsHooked)
{
C_SetupProfile();
C_EventIsHooked = true;
}
return C_Profile_Colors[color];
}
/**
* Replace the color with another color
* Handle with care!
*
* @param color color to replace.
* @param newColor color to replace with.
* @noreturn
*/
stock void C_ReplaceColor(C_Colors color, C_Colors newColor)
{
if (!C_EventIsHooked)
{
C_SetupProfile();
C_EventIsHooked = true;
}
C_Profile_Colors[color] = C_Profile_Colors[newColor];
C_Profile_TeamIndex[color] = C_Profile_TeamIndex[newColor];
C_TagReqSayText2[color] = C_TagReqSayText2[newColor];
Format(C_TagCode[color], sizeof(C_TagCode[]), C_TagCode[newColor]);
}
/**
* This function should only be used right in front of
* C_PrintToChatAll or C_PrintToChatAllEx and it tells
* to those funcions to skip specified client when printing
* message to all clients. After message is printed client will
* no more be skipped.
*
* @param client Client index
* @return No return
*/
stock void C_SkipNextClient(int client)
{
if (client <= 0 || client > MaxClients)
ThrowError("Invalid client index %d", client);
C_SkipList[client] = true;
}
/**
* Replaces color tags in a string with color codes
*
* @param szMessage String.
* @param maxlength Maximum length of the string buffer.
* @return Client index that can be used for SayText2 author index
*
* On error/Errors: If there is more then one team color is used an error will be thrown.
*/
stock int C_Format(char[] szMessage, int maxlength, int author = NO_INDEX)
{
/* Hook event for auto profile setup on map start */
if (!C_EventIsHooked)
{
C_SetupProfile();
HookEvent("server_spawn", C_Event_MapStart, EventHookMode_PostNoCopy);
C_EventIsHooked = true;
}
int iRandomPlayer = NO_INDEX;
// On CS:GO set invisible precolor
if (GetEngineVersion() == Engine_CSGO)
{
Format(szMessage, maxlength, " %s", szMessage);
}
/* If author was specified replace {teamcolor} tag */
if (author != NO_INDEX)
{
if (C_Profile_SayText2)
{
ReplaceString(szMessage, maxlength, "{teamcolor}", "\x03", false);
iRandomPlayer = author;
}
/* If saytext2 is not supported by game replace {teamcolor} with green tag */
else
ReplaceString(szMessage, maxlength, "{teamcolor}", C_TagCode[Color_Green], false);
}
else
ReplaceString(szMessage, maxlength, "{teamcolor}", "", false);
/* For other color tags we need a loop */
for (int i = 0; i < MAX_COLORS; i++)
{
/* If tag not found - skip */
if (StrContains(szMessage, C_Tag[i], false) == -1)
continue;
/* If tag is not supported by game replace it with green tag */
else if (!C_Profile_Colors[i])
ReplaceString(szMessage, maxlength, C_Tag[i], C_TagCode[Color_Green], false);
/* If tag doesn't need saytext2 simply replace */
else if (!C_TagReqSayText2[i])
ReplaceString(szMessage, maxlength, C_Tag[i], C_TagCode[i], false);
/* Tag needs saytext2 */
else
{
/* If saytext2 is not supported by game replace tag with green tag */
if (!C_Profile_SayText2)
ReplaceString(szMessage, maxlength, C_Tag[i], C_TagCode[Color_Green], false);
/* Game supports saytext2 */
else
{
/* If random player for tag wasn't specified replace tag and find player */
if (iRandomPlayer == NO_INDEX)
{
/* Searching for valid client for tag */
iRandomPlayer = C_FindRandomPlayerByTeam(C_Profile_TeamIndex[i]);
/* If player not found replace tag with green color tag */
if (iRandomPlayer == NO_PLAYER)
ReplaceString(szMessage, maxlength, C_Tag[i], C_TagCode[Color_Green], false);
/* If player was found simply replace */
else
ReplaceString(szMessage, maxlength, C_Tag[i], C_TagCode[i], false);
}
/* If found another team color tag throw error */
else
{
//ReplaceString(szMessage, maxlength, C_Tag[i], "");
ThrowError("Using two team colors in one message is not allowed");
}
}
}
}
return iRandomPlayer;
}
/**
* Founds a random player with specified team
*
* @param color_team Client team.
* @return Client index or NO_PLAYER if no player found
*/
stock int C_FindRandomPlayerByTeam(int color_team)
{
if (color_team == SERVER_INDEX)
return 0;
else
{
MuCo_LoopClients(i)
{
if (i > 0 && IsClientInGame(i) && GetClientTeam(i) == color_team)
return i;
}
}
return NO_PLAYER;
}
/**
* Sends a SayText2 usermessage to a client
*
* @param szMessage Client index
* @param maxlength Author index
* @param szMessage Message
* @return No return.
*/
stock void C_SayText2(int client, int author, const char[] szMessage)
{
Handle hBuffer = StartMessageOne("SayText2", client, USERMSG_RELIABLE|USERMSG_BLOCKHOOKS);
if(GetFeatureStatus(FeatureType_Native, "GetUserMessageType") == FeatureStatus_Available && GetUserMessageType() == UM_Protobuf)
{
PbSetInt(hBuffer, "ent_idx", author);
PbSetBool(hBuffer, "chat", true);
PbSetString(hBuffer, "msg_name", szMessage);
PbAddString(hBuffer, "params", "");
PbAddString(hBuffer, "params", "");
PbAddString(hBuffer, "params", "");
PbAddString(hBuffer, "params", "");
}
else
{
BfWriteByte(hBuffer, author);
BfWriteByte(hBuffer, true);
BfWriteString(hBuffer, szMessage);
}
EndMessage();
}
/**
* Creates game color profile
* This function must be edited if you want to add more games support
*
* @return No return.
*/
stock void C_SetupProfile()
{
EngineVersion engine = GetEngineVersion();
if (engine == Engine_CSS)
{
C_Profile_Colors[Color_Lightgreen] = true;
C_Profile_Colors[Color_Red] = true;
C_Profile_Colors[Color_Blue] = true;
C_Profile_Colors[Color_Olive] = true;
C_Profile_TeamIndex[Color_Lightgreen] = SERVER_INDEX;
C_Profile_TeamIndex[Color_Red] = 2;
C_Profile_TeamIndex[Color_Blue] = 3;
C_Profile_SayText2 = true;
}
else if (engine == Engine_CSGO)
{
C_Profile_Colors[Color_Red] = true;
C_Profile_Colors[Color_Blue] = true;
C_Profile_Colors[Color_Olive] = true;
C_Profile_Colors[Color_Darkred] = true;
C_Profile_Colors[Color_Lime] = true;
C_Profile_Colors[Color_Lightred] = true;
C_Profile_Colors[Color_Purple] = true;
C_Profile_Colors[Color_Grey] = true;
C_Profile_Colors[Color_Orange] = true;
C_Profile_Colors[Color_Bluegrey] = true;
C_Profile_Colors[Color_Lightblue] = true;
C_Profile_Colors[Color_Darkblue] = true;
C_Profile_Colors[Color_Grey2] = true;
C_Profile_Colors[Color_Orchid] = true;
C_Profile_Colors[Color_Lightred2] = true;
C_Profile_TeamIndex[Color_Red] = 2;
C_Profile_TeamIndex[Color_Blue] = 3;
C_Profile_SayText2 = true;
}
else if (engine == Engine_TF2)
{
C_Profile_Colors[Color_Lightgreen] = true;
C_Profile_Colors[Color_Red] = true;
C_Profile_Colors[Color_Blue] = true;
C_Profile_Colors[Color_Olive] = true;
C_Profile_TeamIndex[Color_Lightgreen] = SERVER_INDEX;
C_Profile_TeamIndex[Color_Red] = 2;
C_Profile_TeamIndex[Color_Blue] = 3;
C_Profile_SayText2 = true;
}
else if (engine == Engine_Left4Dead || engine == Engine_Left4Dead2)
{
C_Profile_Colors[Color_Lightgreen] = true;
C_Profile_Colors[Color_Red] = true;
C_Profile_Colors[Color_Blue] = true;
C_Profile_Colors[Color_Olive] = true;
C_Profile_TeamIndex[Color_Lightgreen] = SERVER_INDEX;
C_Profile_TeamIndex[Color_Red] = 3;
C_Profile_TeamIndex[Color_Blue] = 2;
C_Profile_SayText2 = true;
}
else if (engine == Engine_HL2DM)
{
/* hl2mp profile is based on mp_teamplay convar */
if (GetConVarBool(FindConVar("mp_teamplay")))
{
C_Profile_Colors[Color_Red] = true;
C_Profile_Colors[Color_Blue] = true;
C_Profile_Colors[Color_Olive] = true;
C_Profile_TeamIndex[Color_Red] = 3;
C_Profile_TeamIndex[Color_Blue] = 2;
C_Profile_SayText2 = true;
}
else
{
C_Profile_SayText2 = false;
C_Profile_Colors[Color_Olive] = true;
}
}
else if (engine == Engine_DODS)
{
C_Profile_Colors[Color_Olive] = true;
C_Profile_SayText2 = false;
}
/* Profile for other games */
else
{
if (GetUserMessageId("SayText2") == INVALID_MESSAGE_ID)
{
C_Profile_SayText2 = false;
}
else
{
C_Profile_Colors[Color_Red] = true;
C_Profile_Colors[Color_Blue] = true;
C_Profile_TeamIndex[Color_Red] = 2;
C_Profile_TeamIndex[Color_Blue] = 3;
C_Profile_SayText2 = true;
}
}
}
public Action C_Event_MapStart(Event event, const char[] name, bool dontBroadcast)
{
C_SetupProfile();
MuCo_LoopClients(i)
C_SkipList[i] = false;
}
/**
* 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,
* C_ShowActivity2() is slightly more useful.
* Supports color tags.
*
* @param client Client index doing the action, or 0 for server.
* @param format Formatting rules.
* @param ... Variable number of format parameters.
* @noreturn
* @error
*/
stock int C_ShowActivity(int client, const char[] format, any ...)
{
if (sm_show_activity == null)
sm_show_activity = FindConVar("sm_show_activity");
char tag[] = "[SM] ";
char szBuffer[MAX_MESSAGE_LENGTH];
//char szCMessage[MAX_MESSAGE_LENGTH];
int value = GetConVarInt(sm_show_activity);
ReplySource replyto = GetCmdReplySource();
char name[MAX_NAME_LENGTH] = "Console";
char sign[MAX_NAME_LENGTH] = "ADMIN";
bool display_in_chat = false;
if (client != 0)
{
if (client < 0 || client > MaxClients || !IsClientConnected(client))
ThrowError("Client index %d is invalid", client);
GetClientName(client, name, sizeof(name));
AdminId id = GetUserAdmin(client);
if (id == INVALID_ADMIN_ID
|| !GetAdminFlag(id, Admin_Generic, Access_Effective))
{
sign = "PLAYER";
}
/* Display the message to the client? */
if (replyto == SM_REPLY_TO_CONSOLE)
{
SetGlobalTransTarget(client);
VFormat(szBuffer, sizeof(szBuffer), format, 3);
C_RemoveTags(szBuffer, sizeof(szBuffer));
PrintToConsole(client, "%s%s\n", tag, szBuffer);
display_in_chat = true;
}
}
else
{
SetGlobalTransTarget(LANG_SERVER);
VFormat(szBuffer, sizeof(szBuffer), format, 3);
C_RemoveTags(szBuffer, sizeof(szBuffer));
PrintToServer("%s%s\n", tag, szBuffer);
}
if (!value)
{
return 1;
}
MuCo_LoopClients(i)
{
if (i == 0
|| !IsClientInGame(i)
|| IsFakeClient(i)
|| (display_in_chat && i == client))
{
continue;
}
AdminId id = GetUserAdmin(i);
SetGlobalTransTarget(i);
if (id == INVALID_ADMIN_ID
|| !GetAdminFlag(id, Admin_Generic, Access_Effective))
{
/* Treat this as a normal user. */
if ((value & 1) | (value & 2))
{
char newsign[MAX_NAME_LENGTH];
newsign = sign;
if ((value & 2) || (i == client))
{
newsign = name;
}
VFormat(szBuffer, sizeof(szBuffer), format, 3);
C_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
else
{
/* Treat this as an admin user */
bool is_root = GetAdminFlag(id, Admin_Root, Access_Effective);
if ((value & 4)
|| (value & 8)
|| ((value & 16) && is_root))
{
char newsign[MAX_NAME_LENGTH];
newsign = sign;
if ((value & 8) || ((value & 16) && is_root) || (i == client))
{
newsign = name;
}
VFormat(szBuffer, sizeof(szBuffer), format, 3);
C_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
}
return 1;
}
/**
* Same as C_ShowActivity(), except the tag parameter is used instead of "[SM] " (note that you must supply any spacing).
* Supports color tags.
*
* @param client Client index doing the action, or 0 for server.
* @param tags Tag to display with.
* @param format Formatting rules.
* @param ... Variable number of format parameters.
* @noreturn
* @error
*/
stock int C_ShowActivityEx(int client, const char[] tag, const char[] format, any ...)
{
if (sm_show_activity == null)
sm_show_activity = FindConVar("sm_show_activity");
char szBuffer[MAX_MESSAGE_LENGTH];
//char szCMessage[MAX_MESSAGE_LENGTH];
int value = GetConVarInt(sm_show_activity);
ReplySource replyto = GetCmdReplySource();
char name[MAX_NAME_LENGTH] = "Console";
char sign[MAX_NAME_LENGTH] = "ADMIN";
bool display_in_chat = false;
if (client != 0)
{
if (client < 0 || client > MaxClients || !IsClientConnected(client))
ThrowError("Client index %d is invalid", client);
GetClientName(client, name, sizeof(name));
AdminId id = GetUserAdmin(client);
if (id == INVALID_ADMIN_ID
|| !GetAdminFlag(id, Admin_Generic, Access_Effective))
{
sign = "PLAYER";
}
/* Display the message to the client? */
if (replyto == SM_REPLY_TO_CONSOLE)
{
SetGlobalTransTarget(client);
VFormat(szBuffer, sizeof(szBuffer), format, 4);
C_RemoveTags(szBuffer, sizeof(szBuffer));
PrintToConsole(client, "%s%s\n", tag, szBuffer);
display_in_chat = true;
}
}
else
{
SetGlobalTransTarget(LANG_SERVER);
VFormat(szBuffer, sizeof(szBuffer), format, 4);
C_RemoveTags(szBuffer, sizeof(szBuffer));
PrintToServer("%s%s\n", tag, szBuffer);
}
if (!value)
{
return 1;
}
MuCo_LoopClients(i)
{
if (i == 0
|| !IsClientInGame(i)
|| IsFakeClient(i)
|| (display_in_chat && i == client))
{
continue;
}
AdminId id = GetUserAdmin(i);
SetGlobalTransTarget(i);
if (id == INVALID_ADMIN_ID
|| !GetAdminFlag(id, Admin_Generic, Access_Effective))
{
/* Treat this as a normal user. */
if ((value & 1) | (value & 2))
{
char newsign[MAX_NAME_LENGTH];
newsign = sign;
if ((value & 2) || (i == client))
{
newsign = name;
}
VFormat(szBuffer, sizeof(szBuffer), format, 4);
C_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
else
{
/* Treat this as an admin user */
bool is_root = GetAdminFlag(id, Admin_Root, Access_Effective);
if ((value & 4)
|| (value & 8)
|| ((value & 16) && is_root))
{
char newsign[MAX_NAME_LENGTH];
newsign = sign;
if ((value & 8) || ((value & 16) && is_root) || (i == client))
{
newsign = name;
}
VFormat(szBuffer, sizeof(szBuffer), format, 4);
C_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
}
return 1;
}
/**
* 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.
* Supports color tags.
*
* @param client Client index doing the action, or 0 for server.
* @param tags Tag to prepend to the message.
* @param format Formatting rules.
* @param ... Variable number of format parameters.
* @noreturn
* @error
*/
stock int C_ShowActivity2(int client, const char[] tag, const char[] format, any ...)
{
if (sm_show_activity == null)
sm_show_activity = FindConVar("sm_show_activity");
char szBuffer[MAX_MESSAGE_LENGTH];
//char szCMessage[MAX_MESSAGE_LENGTH];
int value = GetConVarInt(sm_show_activity);
// ReplySource replyto = GetCmdReplySource();
char name[MAX_NAME_LENGTH] = "Console";
char sign[MAX_NAME_LENGTH] = "ADMIN";
if (client != 0)
{
if (client < 0 || client > MaxClients || !IsClientConnected(client))
ThrowError("Client index %d is invalid", client);
GetClientName(client, name, sizeof(name));
AdminId id = GetUserAdmin(client);
if (id == INVALID_ADMIN_ID
|| !GetAdminFlag(id, Admin_Generic, Access_Effective))
{
sign = "PLAYER";
}
SetGlobalTransTarget(client);
VFormat(szBuffer, sizeof(szBuffer), format, 4);
/* We don't display directly to the console because the chat text
* simply gets added to the console, so we don't want it to print
* twice.
*/
C_PrintToChatEx(client, client, "%s%s", tag, szBuffer);
}
else
{
SetGlobalTransTarget(LANG_SERVER);
VFormat(szBuffer, sizeof(szBuffer), format, 4);
C_RemoveTags(szBuffer, sizeof(szBuffer));
PrintToServer("%s%s\n", tag, szBuffer);
}
if (!value)
{
return 1;
}
MuCo_LoopClients(i)
{
if (i == 0
|| !IsClientInGame(i)
|| IsFakeClient(i)
|| i == client)
{
continue;
}
AdminId id = GetUserAdmin(i);
SetGlobalTransTarget(i);
if (id == INVALID_ADMIN_ID
|| !GetAdminFlag(id, Admin_Generic, Access_Effective))
{
/* Treat this as a normal user. */
if ((value & 1) | (value & 2))
{
char newsign[MAX_NAME_LENGTH];
newsign = sign;
if ((value & 2))
{
newsign = name;
}
VFormat(szBuffer, sizeof(szBuffer), format, 4);
C_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
else
{
/* Treat this as an admin user */
bool is_root = GetAdminFlag(id, Admin_Root, Access_Effective);
if ((value & 4)
|| (value & 8)
|| ((value & 16) && is_root))
{
char newsign[MAX_NAME_LENGTH];
newsign = sign;
if ((value & 8) || ((value & 16) && is_root))
{
newsign = name;
}
VFormat(szBuffer, sizeof(szBuffer), format, 4);
C_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
}
return 1;
}

View File

@ -2,27 +2,29 @@
// By Dr. McKay
// Inspired by: https://forums.alliedmods.net/showthread.php?t=96831
#if defined _colors_included
#if defined _more_colors_included
#endinput
#endif
#define _colors_included
#define _more_colors_included
#include <regex>
#define MORE_COLORS_VERSION "1.9.1"
#define MAX_MESSAGE_LENGTH 256
#define MAX_BUFFER_LENGTH (MAX_MESSAGE_LENGTH * 4)
#define MORE_COLORS_VERSION "2.0.0-MC"
#define MC_MAX_MESSAGE_LENGTH 256
#define MAX_BUFFER_LENGTH (MC_MAX_MESSAGE_LENGTH * 4)
#define COLOR_RED 0xFF4040
#define COLOR_BLUE 0x99CCFF
#define COLOR_GRAY 0xCCCCCC
#define COLOR_GREEN 0x3EFF3E
#define MCOLOR_RED 0xFF4040
#define MCOLOR_BLUE 0x99CCFF
#define MCOLOR_GRAY 0xCCCCCC
#define MCOLOR_GREEN 0x3EFF3E
#define GAME_DODS 0
#define MC_GAME_DODS 0
new bool:CSkipList[MAXPLAYERS + 1];
new Handle:CTrie;
new CTeamColors[][] = {{0xCCCCCC, 0x4D7942, 0xFF4040}}; // Multi-dimensional array for games that don't support SayText2. First index is the game index (as defined by the GAME_ defines), second index is team. 0 = spectator, 1 = team1, 2 = team2
bool MC_SkipList[MAXPLAYERS + 1];
Handle MC_Trie;
int MC_TeamColors[][] = {{0xCCCCCC, 0x4D7942, 0xFF4040}}; // Multi-dimensional array for games that don't support SayText2. First index is the game index (as defined by the GAME_ defines), second index is team. 0 = spectator, 1 = team1, 2 = team2
static Handle sm_show_activity = INVALID_HANDLE;
/**
* Prints a message to a specific client in the chat area.
@ -34,20 +36,20 @@ new CTeamColors[][] = {{0xCCCCCC, 0x4D7942, 0xFF4040}}; // Multi-dimensional arr
*
* On error/Errors: If the client is not connected an error will be thrown.
*/
stock CPrintToChat(client, const String:message[], any:...) {
CCheckTrie();
stock void MC_PrintToChat(int client, const char[] message, any ...) {
MC_CheckTrie();
if(client <= 0 || client > MaxClients) {
ThrowError("Invalid client index %i", client);
}
if(!IsClientInGame(client)) {
ThrowError("Client %i is not in game", client);
}
decl String:buffer[MAX_BUFFER_LENGTH], String:buffer2[MAX_BUFFER_LENGTH];
char buffer[MAX_BUFFER_LENGTH], buffer2[MAX_BUFFER_LENGTH];
SetGlobalTransTarget(client);
Format(buffer, sizeof(buffer), "\x01%s", message);
VFormat(buffer2, sizeof(buffer2), buffer, 3);
CReplaceColorCodes(buffer2);
CSendMessage(client, buffer2);
MC_ReplaceColorCodes(buffer2);
MC_SendMessage(client, buffer2);
}
/**
@ -58,19 +60,19 @@ stock CPrintToChat(client, const String:message[], any:...) {
* @param message Message (formatting rules).
* @noreturn
*/
stock CPrintToChatAll(const String:message[], any:...) {
CCheckTrie();
decl String:buffer[MAX_BUFFER_LENGTH], String:buffer2[MAX_BUFFER_LENGTH];
for(new i = 1; i <= MaxClients; i++) {
if(!IsClientInGame(i) || CSkipList[i]) {
CSkipList[i] = false;
stock void MC_PrintToChatAll(const char[] message, any ...) {
MC_CheckTrie();
char buffer[MAX_BUFFER_LENGTH], buffer2[MAX_BUFFER_LENGTH];
MuCo_LoopClients(i) {
if(i == 0 || !IsClientInGame(i) || MC_SkipList[i]) {
MC_SkipList[i] = false;
continue;
}
SetGlobalTransTarget(i);
Format(buffer, sizeof(buffer), "\x01%s", message);
VFormat(buffer2, sizeof(buffer2), buffer, 2);
CReplaceColorCodes(buffer2);
CSendMessage(i, buffer2);
MC_ReplaceColorCodes(buffer2);
MC_SendMessage(i, buffer2);
}
}
@ -85,8 +87,8 @@ stock CPrintToChatAll(const String:message[], any:...) {
*
* On error/Errors: If the client or author are not connected an error will be thrown
*/
stock CPrintToChatEx(client, author, const String:message[], any:...) {
CCheckTrie();
stock void MC_PrintToChatEx(int client, int author, const char[] message, any ...) {
MC_CheckTrie();
if(client <= 0 || client > MaxClients) {
ThrowError("Invalid client index %i", client);
}
@ -99,12 +101,12 @@ stock CPrintToChatEx(client, author, const String:message[], any:...) {
if(!IsClientInGame(author)) {
ThrowError("Client %i is not in game", author);
}
decl String:buffer[MAX_BUFFER_LENGTH], String:buffer2[MAX_BUFFER_LENGTH];
char buffer[MAX_BUFFER_LENGTH], buffer2[MAX_BUFFER_LENGTH];
SetGlobalTransTarget(client);
Format(buffer, sizeof(buffer), "\x01%s", message);
VFormat(buffer2, sizeof(buffer2), buffer, 4);
CReplaceColorCodes(buffer2, author);
CSendMessage(client, buffer2, author);
MC_ReplaceColorCodes(buffer2, author);
MC_SendMessage(client, buffer2, author);
}
/**
@ -117,25 +119,25 @@ stock CPrintToChatEx(client, author, const String:message[], any:...) {
*
* On error/Errors: If the author is not connected an error will be thrown.
*/
stock CPrintToChatAllEx(author, const String:message[], any:...) {
CCheckTrie();
stock void MC_PrintToChatAllEx(int author, const char[] message, any ...) {
MC_CheckTrie();
if(author <= 0 || author > MaxClients) {
ThrowError("Invalid client index %i", author);
}
if(!IsClientInGame(author)) {
ThrowError("Client %i is not in game", author);
}
decl String:buffer[MAX_BUFFER_LENGTH], String:buffer2[MAX_BUFFER_LENGTH];
for(new i = 1; i <= MaxClients; i++) {
if(!IsClientInGame(i) || CSkipList[i]) {
CSkipList[i] = false;
char buffer[MAX_BUFFER_LENGTH], buffer2[MAX_BUFFER_LENGTH];
MuCo_LoopClients(i) {
if(i == 0 || !IsClientInGame(i) || MC_SkipList[i]) {
MC_SkipList[i] = false;
continue;
}
SetGlobalTransTarget(i);
Format(buffer, sizeof(buffer), "\x01%s", message);
VFormat(buffer2, sizeof(buffer2), buffer, 3);
CReplaceColorCodes(buffer2, author);
CSendMessage(i, buffer2, author);
MC_ReplaceColorCodes(buffer2, author);
MC_SendMessage(i, buffer2, author);
}
}
@ -146,29 +148,28 @@ stock CPrintToChatAllEx(author, const String:message[], any:...) {
* @param message Message to send
* @noreturn
*/
stock CSendMessage(client, const String:message[], author=0) {
stock void MC_SendMessage(int client, const char[] message, int author = 0) {
if(author == 0) {
author = client;
}
decl String:buffer[MAX_MESSAGE_LENGTH], String:game[16];
GetGameFolderName(game, sizeof(game));
char buffer[MC_MAX_MESSAGE_LENGTH];
strcopy(buffer, sizeof(buffer), message);
new UserMsg:index = GetUserMessageId("SayText2");
UserMsg index = GetUserMessageId("SayText2");
if(index == INVALID_MESSAGE_ID) {
if(StrEqual(game, "dod")) {
new team = GetClientTeam(author);
if(GetEngineVersion() == Engine_DODS) {
int team = GetClientTeam(author);
if(team == 0) {
ReplaceString(buffer, sizeof(buffer), "\x03", "\x04", false); // Unassigned gets green
} else {
decl String:temp[16];
Format(temp, sizeof(temp), "\x07%06X", CTeamColors[GAME_DODS][team - 1]);
char temp[16];
Format(temp, sizeof(temp), "\x07%06X", MC_TeamColors[MC_GAME_DODS][team - 1]);
ReplaceString(buffer, sizeof(buffer), "\x03", temp, false);
}
}
PrintToChat(client, "%s", buffer);
return;
}
new Handle:buf = StartMessageOne("SayText2", client, USERMSG_RELIABLE|USERMSG_BLOCKHOOKS);
Handle buf = StartMessageOne("SayText2", client, USERMSG_RELIABLE|USERMSG_BLOCKHOOKS);
if(GetFeatureStatus(FeatureType_Native, "GetUserMessageType") == FeatureStatus_Available && GetUserMessageType() == UM_Protobuf) {
PbSetInt(buf, "ent_idx", author);
PbSetBool(buf, "chat", true);
@ -187,18 +188,18 @@ stock CSendMessage(client, const String:message[], author=0) {
/**
* This function should only be used right in front of
* CPrintToChatAll or CPrintToChatAllEx. It causes those functions
* MC_PrintToChatAll or MC_PrintToChatAllEx. It causes those functions
* to skip the specified client when printing the message.
* After printing the message, the client will no longer be skipped.
*
* @param client Client index
* @noreturn
*/
stock CSkipNextClient(client) {
stock void MC_SkipNextClient(int client) {
if(client <= 0 || client > MaxClients) {
ThrowError("Invalid client index %i", client);
}
CSkipList[client] = true;
MC_SkipList[client] = true;
}
/**
@ -206,25 +207,25 @@ stock CSkipNextClient(client) {
*
* @return No return
*/
stock CCheckTrie() {
if(CTrie == INVALID_HANDLE) {
CTrie = InitColorTrie();
stock void MC_CheckTrie() {
if(MC_Trie == INVALID_HANDLE) {
MC_Trie = MC_InitColorTrie();
}
}
/**
* Replaces color tags in a string with color codes (used internally by CPrintToChat, CPrintToChatAll, CPrintToChatEx, and CPrintToChatAllEx
* Replaces color tags in a string with color codes (used internally by MC_PrintToChat, MC_PrintToChatAll, MC_PrintToChatEx, and MC_PrintToChatAllEx
*
* @param buffer String.
* @param author Optional client index to use for {teamcolor} tags, or 0 for none
* @param removeTags Optional boolean value to determine whether we're replacing tags with colors, or just removing tags, used by CRemoveTags
* @param maxlen Optional value for max buffer length, used by CRemoveTags
* @param removeTags Optional boolean value to determine whether we're replacing tags with colors, or just removing tags, used by MC_RemoveTags
* @param maxlen Optional value for max buffer length, used by MC_RemoveTags
* @noreturn
*
* On error/Errors: If the client index passed for author is invalid or not in game.
*/
stock CReplaceColorCodes(String:buffer[], author=0, bool:removeTags=false, maxlen=MAX_BUFFER_LENGTH) {
CCheckTrie();
stock void MC_ReplaceColorCodes(char[] buffer, int author = 0, bool removeTags = false, int maxlen = MAX_BUFFER_LENGTH) {
MC_CheckTrie();
if(!removeTags) {
ReplaceString(buffer, maxlen, "{default}", "\x01", false);
} else {
@ -240,27 +241,29 @@ stock CReplaceColorCodes(String:buffer[], author=0, bool:removeTags=false, maxle
}
ReplaceString(buffer, maxlen, "{teamcolor}", "\x03", false);
}
new cursor = 0;
new value;
decl String:tag[32], String:buff[32], String:output[maxlen];
int cursor = 0;
int value;
char tag[32], buff[32];
char[] output = new char[maxlen];
strcopy(output, maxlen, buffer);
// Since the string's size is going to be changing, output will hold the replaced string and we'll search buffer
new Handle:regex = CompileRegex("{[a-zA-Z0-9]+}");
for(new i = 0; i < 1000; i++) { // The RegEx extension is quite flaky, so we have to loop here :/. This loop is supposed to be infinite and broken by return, but conditions have been added to be safe.
Handle regex = CompileRegex("{[a-zA-Z0-9]+}");
for(int i = 0; i < 1000; i++) { // The RegEx extension is quite flaky, so we have to loop here :/. This loop is supposed to be infinite and broken by return, but conditions have been added to be safe.
if(MatchRegex(regex, buffer[cursor]) < 1) {
CloseHandle(regex);
strcopy(buffer, maxlen, output);
return;
}
GetRegexSubString(regex, 0, tag, sizeof(tag));
CStrToLower(tag);
MC_StrToLower(tag);
cursor = StrContains(buffer[cursor], tag, false) + cursor + 1;
strcopy(buff, sizeof(buff), tag);
ReplaceString(buff, sizeof(buff), "{", "");
ReplaceString(buff, sizeof(buff), "}", "");
if(!GetTrieValue(CTrie, buff, value)) {
if(!GetTrieValue(MC_Trie, buff, value)) {
continue;
}
@ -284,8 +287,8 @@ stock CReplaceColorCodes(String:buffer[], author=0, bool:removeTags=false, maxle
* @param numChars Number of characters to return, or 0 for the end of the string
* @noreturn
*/
stock CSubString(const String:input[], String:output[], maxlen, start, numChars=0) {
new i = 0;
stock void CSubString(const char[] input, char[] output, int maxlen, int start, int numChars = 0) {
int i = 0;
for(;;) {
if(i == maxlen - 1 || i >= numChars || input[start + i] == '\0') {
output[i] = '\0';
@ -302,9 +305,9 @@ stock CSubString(const String:input[], String:output[], maxlen, start, numChars=
* @param buffer String to convert
* @noreturn
*/
stock CStrToLower(String:buffer[]) {
new len = strlen(buffer);
for(new i = 0; i < len; i++) {
stock void MC_StrToLower(char[] buffer) {
int len = strlen(buffer);
for(int i = 0; i < len; i++) {
buffer[i] = CharToLower(buffer[i]);
}
}
@ -316,16 +319,16 @@ stock CStrToLower(String:buffer[]) {
* @param color Hexadecimal representation of the color (0xRRGGBB)
* @return True if color was added successfully, false if a color already exists with that name
*/
stock bool:CAddColor(const String:name[], color) {
CCheckTrie();
new value;
if(GetTrieValue(CTrie, name, value)) {
stock bool MC_AddColor(const char[] name, int color) {
MC_CheckTrie();
int value;
if(GetTrieValue(MC_Trie, name, value)) {
return false;
}
decl String:newName[64];
char newName[64];
strcopy(newName, sizeof(newName), name);
CStrToLower(newName);
SetTrieValue(CTrie, newName, color);
MC_StrToLower(newName);
SetTrieValue(MC_Trie, newName, color);
return true;
}
@ -336,8 +339,8 @@ stock bool:CAddColor(const String:name[], color) {
* @param maxlen Maximum buffer length
* @noreturn
*/
stock CRemoveTags(String:message[], maxlen) {
CReplaceColorCodes(message, 0, true, maxlen);
stock void MC_RemoveTags(char[] message, int maxlen) {
MC_ReplaceColorCodes(message, 0, true, maxlen);
}
/**
@ -347,15 +350,15 @@ stock CRemoveTags(String:message[], maxlen) {
* @param message Message (formatting rules)
* @noreturn
*/
stock CReplyToCommand(client, const String:message[], any:...) {
decl String:buffer[MAX_BUFFER_LENGTH];
stock void MC_ReplyToCommand(int client, const char[] message, any ...) {
char buffer[MAX_BUFFER_LENGTH];
SetGlobalTransTarget(client);
VFormat(buffer, sizeof(buffer), message, 3);
if(!client || GetCmdReplySource() == SM_REPLY_TO_CONSOLE) {
CRemoveTags(buffer, sizeof(buffer));
if(GetCmdReplySource() == SM_REPLY_TO_CONSOLE) {
MC_RemoveTags(buffer, sizeof(buffer));
PrintToConsole(client, "%s", buffer);
} else {
CPrintToChat(client, "%s", buffer);
MC_PrintToChat(client, "%s", buffer);
}
}
@ -367,88 +370,364 @@ stock CReplyToCommand(client, const String:message[], any:...) {
* @param message Message (formatting rules)
* @noreturn
*/
stock CReplyToCommandEx(client, author, const String:message[], any:...) {
decl String:buffer[MAX_BUFFER_LENGTH];
stock void MC_ReplyToCommandEx(int client, int author, const char[] message, any ...) {
char buffer[MAX_BUFFER_LENGTH];
SetGlobalTransTarget(client);
VFormat(buffer, sizeof(buffer), message, 4);
if(GetCmdReplySource() == SM_REPLY_TO_CONSOLE) {
CRemoveTags(buffer, sizeof(buffer));
MC_RemoveTags(buffer, sizeof(buffer));
PrintToConsole(client, "%s", buffer);
} else {
CPrintToChatEx(client, author, "%s", buffer);
MC_PrintToChatEx(client, author, "%s", buffer);
}
}
/**
* Shows admin activity with colors
*
* @param client Client performing an action
* @param message Message (formatting rules)
* 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,
* MC_ShowActivity2() is slightly more useful.
* Supports color tags.
*
* @param client Client index doing the action, or 0 for server.
* @param format Formatting rules.
* @param ... Variable number of format parameters.
* @noreturn
* @error
*/
stock CShowActivity(client, const String:message[], any:...) {
CCheckTrie();
if(client < 0 || client > MaxClients) {
ThrowError("Invalid client index %d", client);
stock int MC_ShowActivity(int client, const char[] format, any ...)
{
if (sm_show_activity == INVALID_HANDLE)
sm_show_activity = FindConVar("sm_show_activity");
char tag[] = "[SM] ";
char szBuffer[MC_MAX_MESSAGE_LENGTH];
//char szCMessage[MC_MAX_MESSAGE_LENGTH];
int value = GetConVarInt(sm_show_activity);
ReplySource replyto = GetCmdReplySource();
char name[MAX_NAME_LENGTH] = "Console";
char sign[MAX_NAME_LENGTH] = "ADMIN";
bool display_in_chat = false;
if (client != 0)
{
if (client < 0 || client > MaxClients || !IsClientConnected(client))
ThrowError("Client index %d is invalid", client);
GetClientName(client, name, sizeof(name));
AdminId id = GetUserAdmin(client);
if (id == INVALID_ADMIN_ID
|| !GetAdminFlag(id, Admin_Generic, Access_Effective))
{
sign = "PLAYER";
}
/* Display the message to the client? */
if (replyto == SM_REPLY_TO_CONSOLE)
{
SetGlobalTransTarget(client);
VFormat(szBuffer, sizeof(szBuffer), format, 3);
MC_RemoveTags(szBuffer, sizeof(szBuffer));
PrintToConsole(client, "%s%s\n", tag, szBuffer);
display_in_chat = true;
}
}
if(client != 0 && !IsClientInGame(client)) {
ThrowError("Client %d is not in game", client);
else
{
SetGlobalTransTarget(LANG_SERVER);
VFormat(szBuffer, sizeof(szBuffer), format, 3);
MC_RemoveTags(szBuffer, sizeof(szBuffer));
PrintToServer("%s%s\n", tag, szBuffer);
}
decl String:buffer[MAX_BUFFER_LENGTH], String:buffer2[MAX_BUFFER_LENGTH];
Format(buffer, sizeof(buffer), "\x01%s", message);
VFormat(buffer2, sizeof(buffer2), buffer, 3);
CReplaceColorCodes(buffer2);
ShowActivity(client, "%s", buffer2);
if (!value)
{
return 1;
}
MuCo_LoopClients(i)
{
if (i == 0
|| !IsClientInGame(i)
|| IsFakeClient(i)
|| (display_in_chat && i == client))
{
continue;
}
AdminId id = GetUserAdmin(i);
SetGlobalTransTarget(i);
if (id == INVALID_ADMIN_ID
|| !GetAdminFlag(id, Admin_Generic, Access_Effective))
{
/* Treat this as a normal user. */
if ((value & 1) | (value & 2))
{
char newsign[MAX_NAME_LENGTH];
newsign = sign;
if ((value & 2) || (i == client))
{
newsign = name;
}
VFormat(szBuffer, sizeof(szBuffer), format, 3);
MC_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
else
{
/* Treat this as an admin user */
bool is_root = GetAdminFlag(id, Admin_Root, Access_Effective);
if ((value & 4)
|| (value & 8)
|| ((value & 16) && is_root))
{
char newsign[MAX_NAME_LENGTH];
newsign = sign;
if ((value & 8) || ((value & 16) && is_root) || (i == client))
{
newsign = name;
}
VFormat(szBuffer, sizeof(szBuffer), format, 3);
MC_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
}
return 1;
}
/**
* Shows admin activity with colors
*
* @param client Client performing an action
* @param tag Tag to prepend to the message (color tags supported)
* @param message Message (formatting rules)
* Same as MC_ShowActivity(), except the tag parameter is used instead of "[SM] " (note that you must supply any spacing).
* Supports color tags.
*
* @param client Client index doing the action, or 0 for server.
* @param tags Tag to display with.
* @param format Formatting rules.
* @param ... Variable number of format parameters.
* @noreturn
* @error
*/
stock CShowActivityEx(client, const String:tag[], const String:message[], any:...) {
CCheckTrie();
if(client < 0 || client > MaxClients) {
ThrowError("Invalid client index %d", client);
stock int MC_ShowActivityEx(int client, const char[] tag, const char[] format, any ...)
{
if (sm_show_activity == INVALID_HANDLE)
sm_show_activity = FindConVar("sm_show_activity");
char szBuffer[MC_MAX_MESSAGE_LENGTH];
//char szCMessage[MC_MAX_MESSAGE_LENGTH];
int value = GetConVarInt(sm_show_activity);
ReplySource replyto = GetCmdReplySource();
char name[MAX_NAME_LENGTH] = "Console";
char sign[MAX_NAME_LENGTH] = "ADMIN";
bool display_in_chat = false;
if (client != 0)
{
if (client < 0 || client > MaxClients || !IsClientConnected(client))
ThrowError("Client index %d is invalid", client);
GetClientName(client, name, sizeof(name));
AdminId id = GetUserAdmin(client);
if (id == INVALID_ADMIN_ID
|| !GetAdminFlag(id, Admin_Generic, Access_Effective))
{
sign = "PLAYER";
}
/* Display the message to the client? */
if (replyto == SM_REPLY_TO_CONSOLE)
{
SetGlobalTransTarget(client);
VFormat(szBuffer, sizeof(szBuffer), format, 4);
MC_RemoveTags(szBuffer, sizeof(szBuffer));
PrintToConsole(client, "%s%s\n", tag, szBuffer);
display_in_chat = true;
}
}
if(client != 0 && !IsClientInGame(client)) {
ThrowError("Client %d is not in game", client);
else
{
SetGlobalTransTarget(LANG_SERVER);
VFormat(szBuffer, sizeof(szBuffer), format, 4);
MC_RemoveTags(szBuffer, sizeof(szBuffer));
PrintToServer("%s%s\n", tag, szBuffer);
}
decl String:buffer[MAX_BUFFER_LENGTH], String:buffer2[MAX_BUFFER_LENGTH];
Format(buffer, sizeof(buffer), "\x01%s", message);
VFormat(buffer2, sizeof(buffer2), buffer, 4);
CReplaceColorCodes(buffer2);
strcopy(buffer, sizeof(buffer), tag);
CReplaceColorCodes(buffer);
ShowActivityEx(client, tag, "%s", buffer2);
if (!value)
{
return 1;
}
MuCo_LoopClients(i)
{
if (i == 0
|| !IsClientInGame(i)
|| IsFakeClient(i)
|| (display_in_chat && i == client))
{
continue;
}
AdminId id = GetUserAdmin(i);
SetGlobalTransTarget(i);
if (id == INVALID_ADMIN_ID
|| !GetAdminFlag(id, Admin_Generic, Access_Effective))
{
/* Treat this as a normal user. */
if ((value & 1) | (value & 2))
{
char newsign[MAX_NAME_LENGTH];
newsign = sign;
if ((value & 2) || (i == client))
{
newsign = name;
}
VFormat(szBuffer, sizeof(szBuffer), format, 4);
MC_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
else
{
/* Treat this as an admin user */
bool is_root = GetAdminFlag(id, Admin_Root, Access_Effective);
if ((value & 4)
|| (value & 8)
|| ((value & 16) && is_root))
{
char newsign[MAX_NAME_LENGTH];
newsign = sign;
if ((value & 8) || ((value & 16) && is_root) || (i == client))
{
newsign = name;
}
VFormat(szBuffer, sizeof(szBuffer), format, 4);
MC_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
}
return 1;
}
/**
* Shows admin activity with colors
*
* @param client Client performing an action
* @param tag Tag to prepend to the message (color tags supported)
* @param message Message (formatting rules)
* 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.
* Supports color tags.
*
* @param client Client index doing the action, or 0 for server.
* @param tags Tag to prepend to the message.
* @param format Formatting rules.
* @param ... Variable number of format parameters.
* @noreturn
* @error
*/
stock CShowActivity2(client, const String:tag[], const String:message[], any:...) {
CCheckTrie();
if(client < 0 || client > MaxClients) {
ThrowError("Invalid client index %d", client);
stock int MC_ShowActivity2(int client, const char[] tag, const char[] format, any ...)
{
if (sm_show_activity == INVALID_HANDLE)
sm_show_activity = FindConVar("sm_show_activity");
char szBuffer[MC_MAX_MESSAGE_LENGTH];
//char szCMessage[MC_MAX_MESSAGE_LENGTH];
int value = GetConVarInt(sm_show_activity);
// ReplySource replyto = GetCmdReplySource();
char name[MAX_NAME_LENGTH] = "Console";
char sign[MAX_NAME_LENGTH] = "ADMIN";
if (client != 0)
{
if (client < 0 || client > MaxClients || !IsClientConnected(client))
ThrowError("Client index %d is invalid", client);
GetClientName(client, name, sizeof(name));
AdminId id = GetUserAdmin(client);
if (id == INVALID_ADMIN_ID
|| !GetAdminFlag(id, Admin_Generic, Access_Effective))
{
sign = "PLAYER";
}
SetGlobalTransTarget(client);
VFormat(szBuffer, sizeof(szBuffer), format, 4);
/* We don't display directly to the console because the chat text
* simply gets added to the console, so we don't want it to print
* twice.
*/
MC_PrintToChatEx(client, client, "%s%s", tag, szBuffer);
}
if(client != 0 && !IsClientInGame(client)) {
ThrowError("Client %d is not in game", client);
else
{
SetGlobalTransTarget(LANG_SERVER);
VFormat(szBuffer, sizeof(szBuffer), format, 4);
MC_RemoveTags(szBuffer, sizeof(szBuffer));
PrintToServer("%s%s\n", tag, szBuffer);
}
decl String:buffer[MAX_BUFFER_LENGTH], String:buffer2[MAX_BUFFER_LENGTH];
Format(buffer, sizeof(buffer), "\x01%s", message);
VFormat(buffer2, sizeof(buffer2), buffer, 4);
CReplaceColorCodes(buffer2);
strcopy(buffer, sizeof(buffer), tag);
CReplaceColorCodes(buffer);
ShowActivity2(client, buffer, "%s", buffer2);
if (!value)
{
return 1;
}
MuCo_LoopClients(i)
{
if (i == 0
|| !IsClientInGame(i)
|| IsFakeClient(i)
|| i == client)
{
continue;
}
AdminId id = GetUserAdmin(i);
SetGlobalTransTarget(i);
if (id == INVALID_ADMIN_ID
|| !GetAdminFlag(id, Admin_Generic, Access_Effective))
{
/* Treat this as a normal user. */
if ((value & 1) | (value & 2))
{
char newsign[MAX_NAME_LENGTH];
newsign = sign;
if ((value & 2))
{
newsign = name;
}
VFormat(szBuffer, sizeof(szBuffer), format, 4);
MC_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
else
{
/* Treat this as an admin user */
bool is_root = GetAdminFlag(id, Admin_Root, Access_Effective);
if ((value & 4)
|| (value & 8)
|| ((value & 16) && is_root))
{
char newsign[MAX_NAME_LENGTH];
newsign = sign;
if ((value & 8) || ((value & 16) && is_root))
{
newsign = name;
}
VFormat(szBuffer, sizeof(szBuffer), format, 4);
MC_PrintToChatEx(i, client, "%s%s: %s", tag, newsign, szBuffer);
}
}
}
return 1;
}
/**
@ -457,10 +736,10 @@ stock CShowActivity2(client, const String:tag[], const String:message[], any:...
* @param color The color name to check
* @return True if the color exists, false otherwise
*/
stock bool:CColorExists(const String:color[]) {
CCheckTrie();
new temp;
return GetTrieValue(CTrie, color, temp);
stock bool CColorExists(const char[] color) {
MC_CheckTrie();
int temp;
return GetTrieValue(MC_Trie, color, temp);
}
/**
@ -470,33 +749,33 @@ stock bool:CColorExists(const String:color[]) {
* @return Client's team color in hexadecimal, or green if unknown
* On error/Errors: If the client index passed is invalid or not in game.
*/
stock CGetTeamColor(client) {
stock int CGetTeamColor(int client) {
if(client <= 0 || client > MaxClients) {
ThrowError("Invalid client index %i", client);
}
if(!IsClientInGame(client)) {
ThrowError("Client %i is not in game", client);
}
new value;
int value;
switch(GetClientTeam(client)) {
case 1: {
value = COLOR_GRAY;
value = MCOLOR_GRAY;
}
case 2: {
value = COLOR_RED;
value = MCOLOR_RED;
}
case 3: {
value = COLOR_BLUE;
value = MCOLOR_BLUE;
}
default: {
value = COLOR_GREEN;
value = MCOLOR_GREEN;
}
}
return value;
}
stock Handle:InitColorTrie() {
new Handle:hTrie = CreateTrie();
stock Handle MC_InitColorTrie() {
Handle hTrie = CreateTrie();
SetTrieValue(hTrie, "aliceblue", 0xF0F8FF);
SetTrieValue(hTrie, "allies", 0x4D7942); // same as Allies team in DoD:S
SetTrieValue(hTrie, "ancient", 0xEB4B4B); // same as Ancient item rarity in Dota 2

View File

@ -1,915 +0,0 @@
/**
* vim: set ts=4 :
* =============================================================================
* NativeVotes
* Copyright (C) 2011-2013 Ross Bemrose (Powerlord). 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$
*/
#include <menus>
#include <sourcemod>
// NativeVotes 0.8 series
#if defined _nativevotes_included
#endinput
#endif
#define _nativevotes_included
#define CLIENT_DISCONNECTED -1
#define NATIVEVOTES_EXTEND "Extend current Map" /** Defined in TF2, but doesn't appear to be localized */
#define NATIVEVOTES_ALL_TEAMS -1 // Defined by TF2, may be the same in L4D/L4D2
#define NATIVEVOTES_TF2_ALL_TEAMS 0 // Defined by TF2, may be the same in L4D/L4D2
#define NATIVEVOTES_TEAM_UNASSIGNED 0 // For completeness, do not otherwise use
#define NATIVEVOTES_TEAM_SPECTATOR 1 // Spectators
#define NATIVEVOTES_TEAM_1 2 // RED/Survivors/Terrorists
#define NATIVEVOTES_TEAM_2 3 // BLU/Infected/Counter-Terrorists
#define NATIVEVOTES_SERVER_INDEX 99 // Defined by TF2, may be the same in L4D/L4D2
// These may seem backwards, but this is the order that the votes appear in the vote screen
#define NATIVEVOTES_VOTE_INVALID -1 /**< Vote was invalid, currently only valid internally */
#define NATIVEVOTES_VOTE_YES 0 /**< Vote was yes */
#define NATIVEVOTES_VOTE_NO 1 /**< Vote was no */
/*
The following MenuActions are supported. Arguments are also listed, as they differ slightly from the default
MenuAction_Start A menu has been started (nothing passed). Only exists for compat reasons.
MenuAction_Display A menu is about to be displayed (param1=client). If you choose to change the vote text,
To change the text, use RedrawVoteTitle()
If you do so, return 1 or _:Plugin_Changed Otherwise, return _:Plugin_Continue or 0.
MenuAction_Select An item was selected (param1=client, param2=item). For subplugin support.
MenuAction_End A vote has fully ended and the vote object is ready to be cleaned up
param1 is MenuEnd reason, either MenuEnd_VotingCancelled or MenuEnd_VotingDone
MenuAction_VoteEnd A vote sequence has succeeded (param1=chosen item)
This is not called if NativeVotes_SetResultCallback has been used on the vote.
You should call NativeVotes_DisplayPass or NativeVotes_DisplayPassEx after this
MenuAction_VoteStart A vote sequence has started (nothing passed). Use this instead of MenuAction_Start
MenuAction_VoteCancel A vote sequence has been cancelled (param1=reason)
MenuAction_DisplayItem Item text is being drawn to the display (param1=client, param2=item)
To change the text, use RedrawVoteItem().
If you do so, return 1 or _:Plugin_Changed. Otherwise, return _:Plugin_Continue or 0.
*/
#define NATIVEVOTES_ACTIONS_DEFAULT MenuAction_VoteStart|MenuAction_VoteCancel|MenuAction_VoteEnd|MenuAction_End
/**
* Vote types. These are mapped to translation strings and pass strings by VoteStart and VotePass handlers
*/
enum NativeVotesType
{
NativeVotesType_None = 0, /** Special placeholder for callvote with no arguments for NativeVotes_OnCallVote */
NativeVotesType_Custom_YesNo, /**< Yes/No, details are vote text. */
NativeVotesType_Custom_Mult, /**< TF2/CS:GO: Multiple-choice, details are vote text. */
NativeVotesType_ChgCampaign, /**< L4D/L4D2: Yes/No, details are campaign name */
NativeVotesType_ChgDifficulty, /**< L4D/L4D2: Yes/No, details are difficulty number in L4D/L4D2 */
NativeVotesType_ReturnToLobby, /**< L4D/L4D2: Yes/No, details are ignored */
NativeVotesType_AlltalkOn, /**< L4D2: Yes/No, details are ignored (handled internally by extension) */
NativeVotesType_AlltalkOff, /**< L4D2: Yes/No, details are ignored (handled internally by extension) */
NativeVotesType_Restart, /**< Yes/No, details are ignored */
NativeVotesType_Kick, /**< Yes/No, target is player userid, details are auto-set by target */
NativeVotesType_KickIdle, /**< TF2/CS:GO: Yes/No, target is player userid, details are auto-set by target */
NativeVotesType_KickScamming, /**< TF2/CS:GO: Yes/No, target is player userid, details are auto-set by target */
NativeVotesType_KickCheating, /**< TF2/CS:GO: Yes/No, target is player userid, details are auto-set by target */
NativeVotesType_ChgLevel, /**< Yes/No, details are level number in L4D/L4D2 or map name in TF2 */
NativeVotesType_NextLevel, /**< TF2/CS:GO: Yes/No, details are map name */
NativeVotesType_NextLevelMult, /**< TF2/CS:GO: Multiple-choice, details are ignored */
NativeVotesType_ScrambleNow, /**< TF2/CS:GO: Yes/No, details are ignored */
NativeVotesType_ScrambleEnd, /**< TF2: Yes/No, details are ignored */
NativeVotesType_ChgMission, /**< TF2: Yes/No, details are popfile */
NativeVotesType_SwapTeams, /**< CS:GO: Yes/No, details are ignored */
NativeVotesType_Surrender, /**< CS:GO: Yes/No, details are ignored */
NativeVotesType_Rematch, /**< CS:GO: Yes/No, details are ignored */
NativeVotesType_Continue, /**< CS:GO: Yes/No, details are ignored */
NativeVotesType_StartRound, /**< TF2: Yes/No, details are ignored */
NativeVotesType_Eternaween, /**< TF2: Yes/No, details are ignored */
NativeVotesType_AutoBalanceOn, /**< TF2: Yes/No, details are ignored */
NativeVotesType_AutoBalanceOff, /**< TF2: Yes/No, details are ignored */
NativeVotesType_ClassLimitsOn, /**< TF2: Yes/No, details are ignored */
NativeVotesType_ClassLimitsOff, /**< TF2: Yes/No, details are ignored */
};
enum NativeVotesPassType
{
NativeVotesPass_None = 0, /**< Special placeholder for error value */
NativeVotesPass_Custom, /**< Details are custom pass message */
NativeVotesPass_ChgCampaign, /**< L4D/L4D2: Details are campaign name */
NativeVotesPass_ChgDifficulty, /**< L4D/L4D2/TF2: Details are difficulty number in L4D/L4D2 and mission name in TF2 */
NativeVotesPass_ReturnToLobby, /**< L4D/L4D2: Details are ignored */
NativeVotesPass_AlltalkOn, /**< L4D2: Details are ignored */
NativeVotesPass_AlltalkOff, /**< L4D2: Details are ignored */
NativeVotesPass_Restart, /**< Details are ignored */
NativeVotesPass_Kick, /**< Details are player name */
NativeVotesPass_ChgLevel, /**< Details are level number in L4D/L4D2 or map name in TF2/CS:GO */
NativeVotesPass_NextLevel, /**< TF2/CS:GO: Details are map name */
NativeVotesPass_Extend, /**< TF2/CS:GO: Details are ignored */
NativeVotesPass_Scramble, /**< TF2/CS:GO: Details are ignored */
NativeVotesPass_ChgMission, /**< TF2: Details are popfile */
NativeVotesPass_SwapTeams, /**< CS:GO: Details are ignored */
NativeVotesPass_Surrender, /**< CS:GO: Details are ignored */
NativeVotesPass_Rematch, /**< CS:GO: Details are ignored */
NativeVotesPass_Continue, /**< CS:GO: Details are ignored */
NativeVotesPass_StartRound, /**< TF2: Details are ignored */
NativeVotesPass_Eternaween, /**< TF2: Details are ignored */
NativeVotesPass_AutoBalanceOn, /**< TF2: Yes/No, details are ignored */
NativeVotesPass_AutoBalanceOff, /**< TF2: Yes/No, details are ignored */
NativeVotesPass_ClassLimitsOn, /**< TF2: Yes/No, details are ignored */
NativeVotesPass_ClassLimitsOff, /**< TF2: Yes/No, details are ignored */
};
/**
* Reasons a vote was canceled. Not used for L4D/L4D2, as they don't care
*/
enum NativeVotesFailType
{
NativeVotesFail_Generic = 0, /**< Vote was generically cancelled. */
NativeVotesFail_Loses = 3, /**< No votes outnumbered Yes votes */
NativeVotesFail_NotEnoughVotes = 4, /**< Vote did not receive enough votes. */
};
/**
* Reasons a callvote command failed.
* This is provided as a convenience to plugin authors as it's not strictly part of the vote system
*/
enum NativeVotesCallFailType
{
NativeVotesCallFail_Generic = 0, /**< Generic fail. */
NativeVotesCallFail_Loading = 1, /**< L4D/L4D2: Players are still loading. */
NativeVotesCallFail_Recent = 2, /**< TF2/CS:GO: You can't call another vote yet: Argument is seconds until you can call another vote. */
NativeVotesCallFail_Disabled = 5, /**< TF2/CS:GO: Server has disabled that issue. */
NativeVotesCallFail_MapNotFound = 6, /**< TF2/CS:GO: Server does not have that map. */
NativeVotesCallFail_SpecifyMap = 7, /**< TF2/CS:GO: You must specify a map. */
NativeVotesCallFail_Failed = 8, /**< TF2/CS:GO: This vote failed recently. */
NativeVotesCallFail_WrongTeam = 9, /**< TF2/CS:GO: Team can't call this vote. */
NativeVotesCallFail_Waiting = 10, /**< TF2/CS:GO: Vote can't be called during Waiting For Players. */
NativeVotesCallFail_PlayerNotFound = 11, /**< TF2/CS:GO: Player to kick can't be found. Buggy in TF2. */
NativeVotesCallFail_Unknown = 11,
NativeVotesCallFail_CantKickAdmin = 12, /**< TF2/CS:GO: Can't kick server admin. */
NativeVotesCallFail_ScramblePending = 13, /**< TF2/CS:GO: Team Scramble is pending.. */
NativeVotesCallFail_Spectators = 14, /**< TF2/CS:GO: Spectators aren't allowed to call votes. */
NativeVotesCallFail_LevelSet = 15, /**< TF2/CS:GO: Next level already set. */
NativeVotesCallFail_MapNotValid = 16, /**< ???: Map is invalid. */
NativeVotesCallFail_KickTime = 17, /**< ???: Cannot kick for time. */
NativeVotesCallFail_KickDuringRound = 18, /**< ???: Cannot kick during a round. */
NativeVotesCallFail_AlreadyActive = 19 /**< TF2: Cannot call vote because modification (Eternaween) is already active (may not work) */
};
/*
* Is a specific vote type supported by this game?
*
* @param voteType Vote type
*/
native bool:NativeVotes_IsVoteTypeSupported(NativeVotesType:voteType);
/**
* Creates a new, empty vote.
*
* @param handler Function which will receive vote actions.
* @param voteType Vote type, cannot be changed after set
* @param actions Optionally set which actions to receive. Start,
* 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 vote Handle on INVALID_HANDLE if a vote type is unsupported by this game.
*/
native Handle:NativeVotes_Create(MenuHandler:handler, NativeVotesType:voteType,
MenuAction:actions=NATIVEVOTES_ACTIONS_DEFAULT);
/**
* Frees all handles related to a vote.
*
* THIS MUST BE CALLED TO AVOID HANDLE LEAKS
*
* @param vote Vote handle
* @noreturn
*/
native Handle:NativeVotes_Close(Handle:vote);
/**
* Appends a new item to the end of a vote. Only valid for Multiple Choice votes
*
* @param vote NativeVotes Handle.
* @param info Item information string.
* @return True on success, false on failure.
* @error Invalid Handle, item limit reached, or if the vote is not multiple choice.
*/
native bool:NativeVotes_AddItem(Handle:vote, const String:info[], const String:display[]);
/**
* 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 vote Vote Handle.
* @param position Position, starting from 0.
* @param info Item information string.
* @return True on success, false on failure.
* @error Invalid Handle or vote position, or if the vote is not multiple choice.
*/
native bool:NativeVotes_InsertItem(Handle:vote, position, const String:info[], const String:display[]);
/**
* Removes an item from the menu.
*
* @param vote Vote Handle.
* @param position Position, starting from 0.
* @return True on success, false on failure.
* @error Invalid Handle or vote position, or if the vote is not multiple choice.
*/
native bool:NativeVotes_RemoveItem(Handle:vote, position);
/**
* Removes all items from a vote.
*
* @param vote Vote Handle.
* @noreturn
* @error Invalid Handle or vote position, or if the vote is not multiple choice.
*/
native NativeVotes_RemoveAllItems(Handle:vote);
/**
* Retrieves information about a vote item.
*
* @param vote Vote Handle.
* @param position Position, starting from 0.
* @param infoBuf Info buffer.
* @param infoBufLen Maximum length of the info buffer.
* @return True on success, false if position is invalid.
* @error Invalid Handlem
*/
native bool:NativeVotes_GetItem(Handle:vote,
position,
String:infoBuf[],
infoBufLen,
String:dispBuf[]="",
dispBufLen=0);
/**
* Returns the number of items in a vote.
*
* @param vote Vote Handle.
* @return Number of items in the vote.
* @error Invalid Handle.
*/
native NativeVotes_GetItemCount(Handle:vote);
/**
* Sets the vote's details for votes that support details
* If this is a custom vote, use NativeVotes_SetTitle to set the vote's title.
*
* @param vote Vote Handle.
* @param argument Details string. See vote types for what details stands for.
* @noreturn
* @error Invalid Handle.
*/
native NativeVotes_SetDetails(Handle:vote, const String:argument[]);
/**
* Returns the text of a vote's details if set.
*
* @param vote Vote Handle.
* @param buffer Buffer to store details.
* @param maxlength Maximum length of the buffer.
* @noreturn
* @error Invalid Handle.
*/
native NativeVotes_GetDetails(Handle:vote, String:buffer[], maxlength);
/**
* Sets a custom vote's title
*
* @param vote Vote Handle.
* @param title Vote title string.
* @noreturn
* @error Invalid Handle.
*/
native NativeVotes_SetTitle(Handle:vote, const String:argument[]);
/**
* Return the vote's Title.
* If not set, returns Details instead.
* This behavior is for compatibility with NativeVotes 0.8.0 and below.
*
* @param vote Vote Handle.
* @param buffer Buffer to store title.
* @param maxlength Maximum length of the buffer.
* @noreturn
* @error Invalid Handle.
*/
native NativeVotes_GetTitle(Handle:vote, String:buffer[], maxlength);
/**
* Sets the target userid for vote
* This should be used instead of SetArgument for votes that target players
*
* Also sets target SteamID
*
* @param vote Vote Handle.
* @param userid Client index of target player
* @param setDetails If true, also sets vote details to client's name
* @noreturn
* @error Invalid Handle.
*/
native NativeVotes_SetTarget(Handle:vote, client, bool:setDetails=true);
/**
* Returns the userid of a vote's target
*
* @param vote Vote Handle.
* @return Client index of target player or 0 for no target or target disconnected since vote started
* @error Invalid Handle.
*/
native NativeVotes_GetTarget(Handle:vote);
/**
* Get the Steam ID of a vote's target
* Useful if the target has disconnect from the server during a vote.
* This was added in specifically for Kick/Ban votes
*
* @param vote Vote Handle.
* @param buffer Buffer to store steamId. Should be 19 characters or more..
* @param maxlength Maximum length of the buffer.
* @noreturn
* @error Invalid Handle.
*/
native NativeVotes_GetTargetSteam(Handle:vote, String:buffer[], maxlength);
/**
* Returns whether a vote is in progress.
*
* @return True if a NativeVotes vote is in progress, false otherwise.
*/
native bool:NativeVotes_IsVoteInProgress();
/**
* Returns a style's maximum items
*
* @return Maximum items
*/
native NativeVotes_GetMaxItems();
/**
* Sets a vote's option flags.
*
* If a certain bit is not supported, it will be stripped before being set.
*
* NOTE: This is currently unused, but reserved for future use.
*
* @param menu Builtin Vote Handle.
* @param flags A new bitstring of VOTEFLAG bits.
* @noreturn
* @error Invalid Handle.
*/
native NativeVotes_SetOptionFlags(Handle:vote, flags);
/**
* Retrieves a menu's option flags.
*
* NOTE: This is currently unused, but reserved for future use.
*
* @param vote Builtin Vote Handle.
* @return A bitstring of VOTEFLAG bits.
* @error Invalid Handle.
*/
native NativeVotes_GetOptionFlags(Handle:vote);
/**
* Cancels the vote in progress.
*
* @noreturn
* @error If no vote is in progress.
*/
native NativeVotes_Cancel();
/**
* Callback for when a vote has ended and results are available.
*
* Due to SourceMod Forward limitations in plugins, multi-dimension arrays can't be passed
* to forwards. This means we have to split the client_info and item_info arrays into
* their components.
*
* @param vote The vote being voted on.
* @param num_votes Number of votes tallied in total.
* @param num_clients Number of clients who could vote.
* @param client_indexes Array of client indexes. Parallel with client_votes.
* @param client_votes Array of client votes. Parallel with client_indexes.
* @param num_items Number of unique items that were selected.
* @param item_indexes Array of vote item indexes. Parallel with item_votes..
* @param item_votes Array of vote vote counts. Parallel with item_indexes.
* @noreturn
*/
functag public NativeVotes_VoteHandler(Handle:vote,
num_votes,
num_clients,
const client_indexes[],
const client_votes[],
num_items,
const item_indexes[],
const item_votes[]);
/**
* Function to convert client/vote arrays into their two-dimensional versions,
* which can then be passed to a standard vote handler.
*
* client_info and item_info are the resulting arrays.
*
* Note: When declaring client_info and item_info, you'll probably want to declare them like this:
* new client_info[num_clients][2];
* new item_info[num_items][2];
*
* @param num_clients Number of clients who could vote.
* @param client_indexes Array of client indexes. Parallel with client_votes.
* @param client_votes Array of client votes. Parallel with client_indexes.
* @param num_items Number of unique items that were selected.
* @param item_indexes Array of vote item indexes. Parallel with item_votes..
* @param item_votes Array of vote vote counts. Parallel with item_indexes.
* @param client_info Array of clients. Use VOTEINFO_CLIENT_ defines.
* @param item_info Array of items, sorted by count. Use VOTEINFO_ITEM
* defines.
* @noreturn
*/
stock NativeVotes_FixResults(num_clients,
const client_indexes[],
const client_votes[],
num_items,
const item_indexes[],
const item_votes[],
client_info[][],
item_info[][])
{
for (new i = 0; i < num_clients; ++i)
{
client_info[i][VOTEINFO_CLIENT_INDEX] = client_indexes[i];
client_info[i][VOTEINFO_CLIENT_ITEM] = client_votes[i];
}
for (new i = 0; i < num_items; ++i)
{
item_info[i][VOTEINFO_ITEM_INDEX] = item_indexes[i];
item_info[i][VOTEINFO_ITEM_VOTES] = item_votes[i];
}
}
/**
* Sets an advanced vote handling callback. If this callback is set,
* MenuAction_VoteEnd will not be called.
*
* @param vote NativeVotes Handle.
* @param callback Callback function.
* @noreturn
* @error Invalid Handle or callback.
*/
native NativeVotes_SetResultCallback(Handle:vote, NativeVotes_VoteHandler:callback);
/**
* Returns the number of seconds you should "wait" before displaying
* a public vote. This number is the time remaining until
* (last_vote + sm_vote_delay).
*
* @return Number of seconds to wait, or 0 for none.
*/
native NativeVotes_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 NativeVotes_Display().
*
* @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:NativeVotes_IsClientInVotePool(client);
/**
* Redraws the current vote to a client in the voting pool.
*
* @param client Client index.
* @param revotes True to allow revotes, false otherwise.
* @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:NativeVotes_RedrawClientVote(client, bool:revotes=true);
/**
* Retrieve the vote type
*
* @param vote NativeVotes Handle.
* @return The built in vote type
* @error Invalid Handle
*/
native NativeVotesType:NativeVotes_GetType(Handle:vote);
/**
* Set the team this vote is for, or NATIVEVOTES_ALL_TEAMS for all teams.
*
* Defaults to NATIVEVOTES_ALL_TEAMS if not explicitly set.
*
* @param vote NativeVotes Handle.
* @param team Team number this vote is for
* @noreturn
* @error Invalid Handle
*/
native NativeVotes_SetTeam(Handle:vote, team);
/**
* Retrieve the team this vote is for
*
* @param vote NativeVotes Handle.
* @return Team index or NATIVEVOTES_ALL_TEAMS for all teams.
* @error Invalid Handle
*/
native NativeVotes_GetTeam(Handle:vote);
/**
* Set the client index of the player who initiated the vote.
* Use NATIVEVOTES_SERVER_INDEX if initiated by the server itself.
*
* Defaults to NATIVEVOTES_SERVER_INDEX if not explicitly set.
*
* @param vote NativeVotes Handle.
* @param client Client who initiated the vote or NATIVEVOTES_SERVER_INDEX
* @noreturn
* @error Invalid Handle
*/
native NativeVotes_SetInitiator(Handle:vote, client);
/**
* Retrieve the client index of the player who initiated the vote or NATIVEVOTES_SERVER_INDEX if
* initiated by the server itself.
*
* @param Vote handle
* @return Client index or NATIVEVOTES_SERVER_INDEX
* @error Invalid Handle
*/
native NativeVotes_GetInitiator(Handle:vote);
/**
* Broadcasts a vote to a list of clients. The most selected item will be
* returned through MenuAction_VoteEnd. On a tie, a random item will be returned
* from a list of the tied items.
*
* Note that MenuAction_VoteStart, MenuAction_VoteCancel, MenuAction_VoteEnd, and MenuAction_End are all
* default callbacks and do not need to be enabled.
*
* @param vote Vote 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 a vote is already in progress.
* @error Invalid Handle, or a vote is already in progress.
*/
native bool:NativeVotes_Display(Handle:vote, clients[], numClients, time);
/**
* Sends a vote menu to all clients. See NativeVotes_Display() for more information.
*
* @param vote Vote 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, or a vote is already in progress.
*/
stock bool:NativeVotes_DisplayToAll(Handle:vote, time)
{
new total = 0;
decl players[MaxClients];
for (new i=1; i<=MaxClients; i++)
{
if (!IsClientInGame(i) || IsFakeClient(i))
{
continue;
}
players[total++] = i;
}
return NativeVotes_Display(vote, players, total, time);
}
/**
* Sends a vote menu to a single team. See NativeVotes_Display() for more information.
*
* @param vote Vote Handle.
* @param team Team to send vote to. 1 = spectators, 2 = RED/Survivors/Terrorists, 3 = BLU/Infected/Counter-Terrorists
* @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.
*/
stock bool:NativeVotes_DisplayToTeam(Handle:vote, team, time)
{
NativeVotes_SetTeam(vote, team);
new total;
decl players[MaxClients];
for (new i=1; i<=MaxClients; i++)
{
if (!IsClientInGame(i) || IsFakeClient(i) || (GetClientTeam(i) != team))
{
continue;
}
players[total++] = i;
}
return NativeVotes_Display(vote, players, total, time);
}
/**
* Sends a vote menu to all clients who are not spectators or waiting to choose a team. See NativeVotes_Display() for more information.
*
* @param vote Vote 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, or a vote is already in progress.
*/
stock bool:NativeVotes_DisplayToAllNonSpectators(Handle:vote, time)
{
new total;
decl players[MaxClients];
for (new i=1; i<=MaxClients; i++)
{
if (!IsClientInGame(i) || IsFakeClient(i) || (GetClientTeam(i) < 2))
{
continue;
}
players[total++] = i;
}
return NativeVotes_Display(vote, players, total, time);
}
/**
* Display vote passed screen
*
* You MUST call one of the NativeVotesDisplayPass* or NativeVotes_DisplayFail functions
* to hide the vote screen for users who didn't vote, and to clear out their selection
* for the next vote.
*
* @param vote Vote handle
* @param details Normally the item that won the vote or format string. Also used for custom vote winners
* @param ... Variable number of format parameters.
* @noreturn
*/
native NativeVotes_DisplayPass(Handle:vote, const String:details[]="");
/**
* Display vote passed screen with custom text to a single user
*
* You MUST call one of the NativeVotesDisplayPass* or NativeVotes_DisplayFail functions
* to hide the vote screen for users who didn't vote, and to clear out their selection
* for the next vote.
*
* @param vote Vote handle
* @param client client to display to
* @param format A format string.
* @param any Variable number of format parameters
* @noreturn
*/
native NativeVotes_DisplayPassCustomToOne(Handle:vote, client, const String:format[], any:...);
/**
* Display vote passed screen with custom text
*
* You MUST call one of the NativeVotesDisplayPass* or NativeVotes_DisplayFail functions
* to hide the vote screen for users who didn't vote, and to clear out their selection
* for the next vote.
*
* @param vote Vote handle
* @param format A format string.
* @param any Variable number of format parameters
* @noreturn
*/
stock NativeVotes_DisplayPassCustom(Handle:vote, const String:format[], any:...)
{
decl String:buffer[192];
for (new i = 1; i <= MaxClients; ++i)
{
if (IsClientInGame(i))
{
SetGlobalTransTarget(i);
VFormat(buffer, sizeof(buffer), format, 3);
NativeVotes_DisplayPassCustomToOne(vote, i, "%s", buffer);
}
}
}
/**
* Display vote passed screen with a custom type.
*
* A sample usage of this would be if Extend won an RTV vote: NativeVotes_DisplayPassEx(vote, NativeVotesPass_Extend, map);
*
* You MUST call one of NativeVotes_DisplayPass, NativeVotes_DisplayPassEx,
* or NativeVotes_DisplayFail to hide the vote screen for users who didn't vote
* and to clear out their selection for the next vote.
*
* #param vote Vote handle
* @param passType The pass screen to display
* @param details Normally the item that won the vote. Also used for custom vote winners
* @noreturn
*/
native NativeVotes_DisplayPassEx(Handle:vote, NativeVotesPassType:passType, const String:details[]="");
/**
* Display failure screen.
*
* You MUST call one of NativeVotes_DisplayPass, NativeVotes_DisplayPassEx,
* or NativeVotes_DisplayFail to hide the vote screen for users who didn't vote,
* and to clear out their selection for the next vote.
*
* @param reason Vote failure reason from NativeVotesFailType enum
* @noreturn
*/
native NativeVotes_DisplayFail(Handle:vote, NativeVotesFailType:reason=NativeVotesFail_Generic);
/**
* 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:NativeVotes_IsNewVoteAllowed()
{
if (NativeVotes_IsVoteInProgress() || NativeVotes_CheckVoteDelay() != 0)
{
return false;
}
return true;
}
/**
* Used when callvote is called with no arguments.
*
* This is used to configure the VoteSetup usermessage on TF2 and CS:GO
*
* @param client Client, in case the votes are restricted by client
* @param voteTypes Populate this array with the vote types this server supports
* Custom and multiple choice votes are not supported from
* the GUI and are thus ignored.
* @return Plugin_Continue to allow the server itself (or another plugin) to process the callvote
* Plugin_Changed if you're changing the voteTypes,
* Plugin_Handled to return a blank VoteSetup usermessage
* Plugin_Stop to prevent VoteSetup usermessage (not recommended)
*/
//functag public Action:NativeVotes_CallVoteSetupHandler(client, NativeVotesType:voteTypes[]);
/**
* Forward for "callvote" handling
*
* You should respond to this by starting a vote or by calling NativeVotes_DisplayCallVoteFail
*
* @param client Client
* @param voteType Type of vote being called. This will NEVER be a multiple-choice or custom vote.
* @param voteArgument Vote argument or blank if the vote type has no argument.
* @param target target userid for kick votes or 0 for all other votes
* @return Plugin_Continue to allow the server itself (or another plugin) to process the callvote
* Plugin_Handled if you processed this vote type
* Plugin_Stop to block the vote type (not recommended)
*/
//functag public Action:NativeVotes_CallVoteHandler(client, NativeVotesType:voteType, const String:voteArgument[], target);
/**
* Register a plugin as a vote manager.
* This is used to abstract away the details of the callvote command.
*
* @param callHandler Handler for callvote commands.
* @param setupHandler Handler to override the which vote types your server supports. Only useful on TF2 and CS:GO.
* @noreturn
*/
//native NativeVotes_RegisterVoteManager(NativeVotes_CallVoteHandler:callHandler, NativeVotes_CallVoteSetupHandler:setupHandler=INVALID_FUNCTION);
/**
* Send a call vote fail screen to a user
* Used to respond to a callvote with invalid arguments or for other reasons
* (such as trying to target an admin for a kick/ban vote)
*
* @param client The client to display the fail screen to
* @param reason A vote call fail reason
* @param time For NativeVotesCallFail_Recent, the number of seconds until the vote
* can be called again
*/
native NativeVotes_DisplayCallVoteFail(client, NativeVotesCallFailType:reason, time);
/**
* Redraws the vote title from inside a MenuAction_Display callback
* Not supported on L4D
*
* @param text Vote title to draw
* @error If called from outside MenuAction_Display
* @return Plugin_Changed if the change is allowed, Plugin_Continue if it isn't.
*/
native Action:NativeVotes_RedrawVoteTitle(const String:text[]);
/**
* Redraws the vote text from inside a MenuAction_DisplayItem callback.
* Only supported on multiple-choice votes
*
* @param text Vote text to draw.
* @error If called from outside MenuAction_DisplayItem
* @return Plugin_Changed if the change is allowed, Plugin_Continue if it isn't.
*/
native Action:NativeVotes_RedrawVoteItem(const String:text[]);
/**
* 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 NativeVotes_GetInfo(param2, &winningVotes, &totalVotes)
{
winningVotes = param2 & 0xFFFF;
totalVotes = param2 >> 16;
}
/**
* Do not edit below this line!
*/
public SharedPlugin:__pl_nativevotes =
{
name = "nativevotes",
file = "nativevotes.smx",
#if defined REQUIRE_PLUGINS
required = 1,
#else
required = 0,
#endif
};
public __pl_nativevotes_SetNTVOptional()
{
MarkNativeAsOptional("NativeVotes_IsVoteTypeSupported");
MarkNativeAsOptional("NativeVotes_Create");
MarkNativeAsOptional("NativeVotes_Close");
MarkNativeAsOptional("NativeVotes_AddItem");
MarkNativeAsOptional("NativeVotes_InsertItem");
MarkNativeAsOptional("NativeVotes_RemoveItem");
MarkNativeAsOptional("NativeVotes_RemoveAllItems");
MarkNativeAsOptional("NativeVotes_GetItem");
MarkNativeAsOptional("NativeVotes_GetItemCount");
MarkNativeAsOptional("NativeVotes_SetDetails");
MarkNativeAsOptional("NativeVotes_GetDetails");
MarkNativeAsOptional("NativeVotes_SetTitle");
MarkNativeAsOptional("NativeVotes_GetTitle");
MarkNativeAsOptional("NativeVotes_SetTarget");
MarkNativeAsOptional("NativeVotes_GetTarget");
MarkNativeAsOptional("NativeVotes_GetTargetSteam");
MarkNativeAsOptional("NativeVotes_IsVoteInProgress");
MarkNativeAsOptional("NativeVotes_GetMaxItems");
MarkNativeAsOptional("NativeVotes_SetOptionFlags");
MarkNativeAsOptional("NativeVotes_GetOptionFlags");
MarkNativeAsOptional("NativeVotes_Cancel");
MarkNativeAsOptional("NativeVotes_SetResultCallback");
MarkNativeAsOptional("NativeVotes_CheckVoteDelay");
MarkNativeAsOptional("NativeVotes_IsClientInVotePool");
MarkNativeAsOptional("NativeVotes_RedrawClientVote");
MarkNativeAsOptional("NativeVotes_RedrawClientVote");
MarkNativeAsOptional("NativeVotes_GetType");
MarkNativeAsOptional("NativeVotes_SetTeam");
MarkNativeAsOptional("NativeVotes_GetTeam");
MarkNativeAsOptional("NativeVotes_SetInitiator");
MarkNativeAsOptional("NativeVotes_GetInitiator");
MarkNativeAsOptional("NativeVotes_Display");
MarkNativeAsOptional("NativeVotes_DisplayPass");
MarkNativeAsOptional("NativeVotes_DisplayPassCustomToOne");
MarkNativeAsOptional("NativeVotes_DisplayPassEx");
MarkNativeAsOptional("NativeVotes_DisplayFail");
MarkNativeAsOptional("NativeVotes_RegisterVoteManager");
MarkNativeAsOptional("NativeVotes_DisplayCallVoteFail");
MarkNativeAsOptional("NativeVotes_RedrawVoteTitle");
MarkNativeAsOptional("NativeVotes_RedrawVoteItem");
}

1763
includes/smjansson.inc Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,543 @@
#if defined _stvmngr_included
#endinput
#endif
#define _stvmngr_included
// Some guidelines from the SDK about director camera shot durations
#define MIN_SHOT_LENGTH 4.0 // minimum time of a cut (seconds)
#define MAX_SHOT_LENGTH 8.0 // maximum time of a cut (seconds)
#define DEF_SHOT_LENGTH 6.0 // average time of a cut (seconds)
enum SourceTVBroadcastTarget {
// Send message to all spectators including proxies.
BTarget_Everyone = 0,
// Send message only to locally connected spectators.
BTarget_OnlyLocal
};
/**
* Get the current amount of running SourceTV instances.
* Can usually only be 1 at max except for CSGO, which can have 2.
*
* @return SourceTV instance number count.
*/
native int SourceTV_GetServerInstanceCount();
/**
* Select a SourceTV instance to operate the rest of the natives on.
* The first SourceTV to connect will always be selected by default.
* Most games only have 1 instance, so this might only be useful in CS:GO,
* which can have 2 instances running.
*
* @param instance The SourceTV instance number.
* @error Invalid SourceTV instance number.
*/
native void SourceTV_SelectServerInstance(int instance);
/**
* Get the index of the currently selected SourceTV server instance.
*
* @return Index of the selected SourceTV instance number or -1 if no SourceTV enabled.
*/
native int SourceTV_GetSelectedServerInstance();
/**
* Called when a SourceTV is initialized.
*
* @param instance The SourceTV instance number.
*/
forward void SourceTV_OnServerStart(int instance);
/**
* Called when a SourceTV server instance is shutdown.
*
* @param instance The SourceTV instance number.
*/
forward void SourceTV_OnServerShutdown(int instance);
/**
* Returns whether this SourceTV instance is currently broadcasting.
*
* @return True if SourceTV instance is broadcasting, false otherwise.
*/
native bool SourceTV_IsActive();
/**
* Returns whether this SourceTV instance is a master proxy or relay.
*
* @return True if SourceTV instance is master proxy, false otherwise.
*/
native bool SourceTV_IsMasterProxy();
/**
* Get the local ip of the SourceTV server.
*
* @param ip Buffer to save IP in.
* @param maxlen Maximum length of the buffer.
* @return True if IP written, false otherwise.
*/
native bool SourceTV_GetServerIP(char[] ip, int maxlen);
/**
* Get the UDP port of the SourceTV server.
* This is the port clients use to connect.
*
* @return SourceTV server UDP port.
*/
native int SourceTV_GetServerPort();
/**
* Get the client index of the SourceTV bot.
*
* @return Client index of SourceTV bot.
*/
native int SourceTV_GetBotIndex();
/**
* Get stats of the local SourceTV instance.
* Returns only the stats of this server, don't include relays.
*
* You have to subtract the proxy count from the spectator count to
* get the real spectator count, because the proxies take one spectator slot
* on the SourceTV server.
*
* @param proxies Number of SourceTV proxies connected to this server.
* @param slots Number of maximal available SourceTV spectator slots.
* @param specs Number of currently connected SourceTV spectators.
* @return True if stats were retrieved, false otherwise.
*/
native bool SourceTV_GetLocalStats(int &proxies, int &slots, int &specs);
/**
* Get stats of this SourceTV network.
* Only the current Master Proxy can give accurate numbers.
* Relay proxies only get updates from the master from time to time.
*
* You have to subtract the proxy count from the spectator count to
* get the real spectator count, because the proxies take one spectator slot
* on the SourceTV server.
*
* @param proxies Number of SourceTV proxies connected to all servers.
* @param slots Number of maximal available SourceTV spectator slots on all servers.
* @param specs Number of currently connected SourceTV spectators on all servers.
* @return True if stats were retrieved, false otherwise.
*/
native bool SourceTV_GetGlobalStats(int &proxies, int &slots, int &specs);
/**
* Current broadcasted tick. Can be lower than the actual server tick,
* due to delay.
*
* @return Current broadcast tick from director.
*/
native int SourceTV_GetBroadcastTick();
/**
* Returns current delay in seconds. (tv_delay)
*
* @return Current delay in seconds.
*/
native float SourceTV_GetDelay();
/**
* Print a center message to all SourceTV spectators for ~2 seconds.
* Like the tv_msg command.
*
* @param target Send only to directly connected spectators or proxies as well?
* @param format The format string.
* @param ... Variable number of format string arguments.
* @return True if message was sent, false otherwise.
*/
native bool SourceTV_BroadcastScreenMessage(SourceTVBroadcastTarget target, const char[] format, any ...);
/**
* Prints text to the console of all connected SourceTV spectators.
*
* @param format The format string.
* @param ... Variable number of format string arguments.
* @return True if message was sent, false otherwise.
*/
native bool SourceTV_BroadcastConsoleMessage(const char[] format, any ...);
/**
* Print a chat message to all SourceTV spectators.
*
* @param target Send only to directly connected spectators or proxies as well?
* @param format The format string.
* @param ... Variable number of format string arguments.
* @return True if message was sent, false otherwise.
*/
native bool SourceTV_BroadcastChatMessage(SourceTVBroadcastTarget target, const char[] format, any ...);
/********************************************************************************
* SourceTV Director control
********************************************************************************/
/**
* Get entity index of current view entity (PVS) of the
* auto director. Check the view origin, if this returns 0.
* @see SourceTV_GetViewOrigin
*
* @return Current view entity index, 0 if coords are used.
*/
native int SourceTV_GetViewEntity();
/**
* Get origin of current view point if view entity is 0.
*
* @param view Vector to store view position in.
*/
native void SourceTV_GetViewOrigin(float view[3]);
/**
* Force the auto director to show a certain camera angle.
*
* @param pos The camera position.
* @param angle The camera angles (roll is unused).
* @param iTarget Target entity to keep the camera pointed towards or 0 to use the angle.
* @param fow Field of view of the camera.
* @param fDuration Length of the shot in seconds.
* @return True if shot was created, false otherwise.
* @error Invalid target entity.
*/
native bool SourceTV_ForceFixedCameraShot(float[] pos, float[] angle, int iTarget, float fov, float fDuration = DEF_SHOT_LENGTH);
/**
* Force the auto director to show a player.
*
* @param iTarget1 The target player to follow.
* @param iTarget2 The other player to keep the camera centered on or 0 to follow target1's view.
* @param distance Distance of camera behind the player.
* @param phi Up/down offset of view point.
* @param theta Left/right offset of view point.
* @param bInEye Show as in-eye camera of the target. Ignores all the other third-person settings.
* @param fDuration Length of the shot in seconds.
* @return True if shot was created, false otherwise.
* @error Invalid target1 or target2 entity
*/
native bool SourceTV_ForceChaseCameraShot(int iTarget1, int iTarget2, int distance, int phi, int theta, bool bInEye, float fDuration = DEF_SHOT_LENGTH);
/********************************************************************************
* SourceTV demo recording
********************************************************************************/
/**
* Starts recording a SourceTV demo into the specified file.
* Only the master proxy can record demos.
*
* @param sFilename Filename of the demo file.
* @return True if recording started, false otherwise.
*/
native bool SourceTV_StartRecording(const char[] sFilename);
/**
* Stops recording a SourceTV demo.
*
* @return True if recording stopped, false otherwise.
*/
native bool SourceTV_StopRecording();
/**
* Returns whether the SourceTV server is currently recording a demo.
*
* @return True if currently recording a SourceTV demo, false otherwise.
*/
native bool SourceTV_IsRecording();
/**
* Get the filename of the currently recorded demo.
*
* @param sFilename Buffer to store the filename in.
* @param maxlen Maximal length of the buffer.
* @return True if filename was written, false otherwise.
*/
native bool SourceTV_GetDemoFileName(char[] sFilename, int maxlen);
/**
* Get current tick in the demofile.
*
* @return Current recording tick in the demofle.
*/
native int SourceTV_GetRecordingTick();
/**
* Print text to the demo console.
* This will show up when playing the demo back in the client console later.
*
* @param format The format string.
* @param ... Variable number of format string arguments.
*
* @return True if message was printed, false otherwise.
*/
native bool SourceTV_PrintToDemoConsole(const char[] format, any ...);
/**
* Called when a SourceTV demo starts being recorded.
* @see SourceTV_SelectServerInstance
*
* @param instance The SourceTV instance of server recording.
* @param filename The filename of the demo.
*/
forward void SourceTV_OnStartRecording(int instance, const char[] filename);
/**
* Called when a SourceTV demo stops being recorded.
* @see SourceTV_SelectServerInstance
*
* @param instance The SourceTV instance of server recording.
* @param filename The filename of the demo.
* @param recordingtick The tick length of the demo.
*/
forward void SourceTV_OnStopRecording(int instance, const char[] filename, int recordingtick);
/********************************************************************************
* SourceTV spectator client handling
********************************************************************************/
/**
* Get currently connected SourcetV spectator count.
*
* @return SourceTV spectator count.
*/
native int SourceTV_GetSpectatorCount();
/**
* Get the current client limit.
*
* @return Maximal possible spectator count.
*/
native int SourceTV_GetMaxClients();
/**
* Get number of client slots (used & unused)
* Client slots are only allocated when they're needed.
* Use this when iterating spectators.
*
* @return Number of client slots (used & unused)
*/
native int SourceTV_GetClientCount();
/**
* Returns if the spectator is connected.
*
* @param client The spectator client index.
* @return True if client is connected, false otherwise.
* @error Invalid client index.
*/
native bool SourceTV_IsClientConnected(int client);
/**
* Returns if the spectator is a relay proxy.
*
* @param client The spectator client index.
* @return True if client is a proxy, false otherwise.
* @error Invalid client index.
*/
native bool SourceTV_IsClientProxy(int client);
/**
* Get the name of a SourceTV spectator client.
*
* @param client The spectator client index.
* @param name Buffer for the client name.
* @param maxlen Maximal length of the buffer.
* @error Invalid client index or not connected.
*/
native void SourceTV_GetClientName(int client, char[] name, int maxlen);
/**
* Get the IP of a SourceTV spectator client.
*
* @param client The spectator client index.
* @param name Buffer for the client ip.
* @param maxlen Maximal length of the buffer.
* @error Invalid client index or not connected.
*/
native void SourceTV_GetClientIP(int client, char[] ip, int maxlen);
/**
* Get the password of a SourceTV spectator client.
* The password the client tried to connect with.
* Ignores changes from the SourceTV_OnSpectatorPreConnect forward.
*
* @param client The spectator client index.
* @param name Buffer for the client ip.
* @param maxlen Maximal length of the buffer.
* @error Invalid client index or not connected.
*/
native void SourceTV_GetClientPassword(int client, char[] password, int maxlen);
/**
* Kick a SourceTV spectator client.
*
* @param client The spectator client index.
* @param sReason The kick reason.
* @error Invalid client index or not connected.
*/
native void SourceTV_KickClient(int client, const char[] sReason);
/**
* Print a message to a single client's chat.
*
* @param client The spectator client index.
* @param format The format string.
* @param ... Variable number of format string arguments.
* @error Invalid client index or not connected.
*/
native void SourceTV_PrintToChat(int client, const char[] format, any ...);
/**
* Print a message to a single client's console.
*
* @param client The spectator client index.
* @param format The format string.
* @param ... Variable number of format string arguments.
* @error Invalid client index or not connected.
*/
native void SourceTV_PrintToConsole(int client, const char[] format, any ...);
/**
* Change the stream title only for one spectator.
* This is like tv_title but for a single client.
* Gets overwritten when tv_title gets changed.
*
* @param client The spectator client index.
* @param format The format string.
* @param ... Variable number of format string arguments.
* @error Invalid client index or not connected.
*/
native void SourceTV_SetClientTVTitle(int client, const char[] format, any ...);
/**
* Called when a spectator wants to connect to the SourceTV server.
* This is called before any other validation has happened.
* Similar to the OnClientPreConnectEx forward in the Connect extension by asherkin.
*
* @param name The player name.
* @param password The password the client used to connect. Can be overwritten.
* @param ip The ip address of the client.
* @param rejectReason Buffer to write the reject reason to, if you want to reject the client from connecting.
* @return True to allow the client to connect, false to reject him with the given reason.
*/
forward bool SourceTV_OnSpectatorPreConnect(const char[] name, char password[255], const char[] ip, char rejectReason[255]);
/**
* Called when a spectator client connected to the SourceTV server.
*
* @param client The spectator client index.
*/
forward void SourceTV_OnSpectatorConnected(int client);
/**
* Called when a spectator client is about to disconnect.
*
* @param client The spectator client index.
* @param reason The reason for the disconnect. Can be overwritten.
*/
forward void SourceTV_OnSpectatorDisconnect(int client, char reason[255]);
/**
* Called after a spectator client disconnected.
*
* @param client The spectator client index.
* @param reason The reason for the disconnect.
*/
forward void SourceTV_OnSpectatorDisconnected(int client, const char reason[255]);
/**
* Called when a spectator client is entering the game.
*
* @param client The spectator client index.
*/
forward void SourceTV_OnSpectatorPutInServer(int client);
/**
* Called before a spectator's chat message is sent.
* The message and chat group can be changed.
* Only called for directly connected clients - no proxies.
*
* @param client The spectator client index.
* @param message The message the client typed.
* @param chatgroup The chatgroup this message is sent to (tv_chatgroup).
* @return >= Plugin_Handled to block the message, Plugin_Continue to let it through.
*/
forward Action SourceTV_OnSpectatorChatMessage(int client, char message[255], char chatgroup[255]);
/**
* Called after a spectator wrote a chat message.
* Only called for directly connected clients - no proxies.
*
* @param client The spectator client index.
* @param message The message the client typed.
* @param chatgroup The chatgroup this message is sent to (tv_chatgroup).
*/
forward void SourceTV_OnSpectatorChatMessage_Post(int client, const char[] message, const char[] chatgroup);
/**
* Do not edit below this line!
*/
public Extension __ext_stvmngr =
{
name = "SourceTV Manager",
file = "sourcetvmanager.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 void __ext_stvmngr_SetNTVOptional()
{
MarkNativeAsOptional("SourceTV_GetServerInstanceCount");
MarkNativeAsOptional("SourceTV_SelectServerInstance");
MarkNativeAsOptional("SourceTV_GetSelectedServerInstance");
MarkNativeAsOptional("SourceTV_IsActive");
MarkNativeAsOptional("SourceTV_IsMasterProxy");
MarkNativeAsOptional("SourceTV_GetServerIP");
MarkNativeAsOptional("SourceTV_GetServerPort");
MarkNativeAsOptional("SourceTV_GetBotIndex");
MarkNativeAsOptional("SourceTV_GetLocalStats");
MarkNativeAsOptional("SourceTV_GetGlobalStats");
MarkNativeAsOptional("SourceTV_GetBroadcastTick");
MarkNativeAsOptional("SourceTV_GetDelay");
MarkNativeAsOptional("SourceTV_BroadcastScreenMessage");
MarkNativeAsOptional("SourceTV_BroadcastConsoleMessage");
MarkNativeAsOptional("SourceTV_BroadcastChatMessage");
MarkNativeAsOptional("SourceTV_GetViewEntity");
MarkNativeAsOptional("SourceTV_GetViewOrigin");
MarkNativeAsOptional("SourceTV_ForceFixedCameraShot");
MarkNativeAsOptional("SourceTV_ForceChaseCameraShot");
MarkNativeAsOptional("SourceTV_StartRecording");
MarkNativeAsOptional("SourceTV_StopRecording");
MarkNativeAsOptional("SourceTV_IsRecording");
MarkNativeAsOptional("SourceTV_GetDemoFileName");
MarkNativeAsOptional("SourceTV_GetRecordingTick");
MarkNativeAsOptional("SourceTV_PrintToDemoConsole");
MarkNativeAsOptional("SourceTV_GetSpectatorCount");
MarkNativeAsOptional("SourceTV_GetMaxClients");
MarkNativeAsOptional("SourceTV_GetClientCount");
MarkNativeAsOptional("SourceTV_IsClientConnected");
MarkNativeAsOptional("SourceTV_IsClientProxy");
MarkNativeAsOptional("SourceTV_GetClientName");
MarkNativeAsOptional("SourceTV_GetClientIP");
MarkNativeAsOptional("SourceTV_GetClientPassword");
MarkNativeAsOptional("SourceTV_KickClient");
MarkNativeAsOptional("SourceTV_PrintToChat");
MarkNativeAsOptional("SourceTV_PrintToConsole");
MarkNativeAsOptional("SourceTV_SetClientTVTitle");
}
#endif

View File

@ -1,97 +0,0 @@
#if defined _updater_included
#endinput
#endif
#define _updater_included
/**
* Adds your plugin to the updater. The URL will be updated if
* your plugin was previously added.
*
* @param url URL to your plugin's update file.
* @noreturn
*/
native Updater_AddPlugin(const String:url[]);
/**
* Removes your plugin from the updater. This does not need to
* be called during OnPluginEnd.
*
* @noreturn
*/
native Updater_RemovePlugin();
/**
* Forces your plugin to be checked for updates. The behaviour
* of the update is dependant on the server's configuration.
*
* @return True if an update was triggered. False otherwise.
* @error Plugin not found in updater.
*/
native bool:Updater_ForceUpdate();
/**
* Called when your plugin is about to be checked for updates.
*
* @return Plugin_Handled to prevent checking, Plugin_Continue to allow it.
*/
forward Action:Updater_OnPluginChecking();
/**
* Called when your plugin is about to begin downloading an available update.
*
* @return Plugin_Handled to prevent downloading, Plugin_Continue to allow it.
*/
forward Action:Updater_OnPluginDownloading();
/**
* Called when your plugin's update files have been fully downloaded
* and are about to write to their proper location. This should be used
* to free read-only resources that require write access for your update.
*
* @note OnPluginUpdated will be called later during the same frame.
*
* @noreturn
*/
forward Updater_OnPluginUpdating();
/**
* Called when your plugin's update has been completed. It is safe
* to reload your plugin at this time.
*
* @noreturn
*/
forward Updater_OnPluginUpdated();
/**
* @brief Reloads a plugin.
*
* @param plugin Plugin Handle (INVALID_HANDLE uses the calling plugin).
* @noreturn
*/
stock ReloadPlugin(Handle:plugin=INVALID_HANDLE)
{
decl String:filename[64];
GetPluginFilename(plugin, filename, sizeof(filename));
ServerCommand("sm plugins reload %s", filename);
}
public SharedPlugin:__pl_updater =
{
name = "updater",
file = "updater.smx",
#if defined REQUIRE_PLUGIN
required = 1,
#else
required = 0,
#endif
};
#if !defined REQUIRE_PLUGIN
public __pl_updater_SetNTVOptional()
{
MarkNativeAsOptional("Updater_AddPlugin");
MarkNativeAsOptional("Updater_RemovePlugin");
MarkNativeAsOptional("Updater_ForceUpdate");
}
#endif

315
includes/webcon.inc Normal file
View File

@ -0,0 +1,315 @@
#if defined _webcon_included
#endinput
#endif
#define _webcon_included
#define WEB_CLIENT_ADDRESS_LENGTH 46
//const char WebMethod_Connect[] = "CONNECT";
//const char WebMethod_Delete[] = "DELETE";
//const char WebMethod_Get[] = "GET";
//const char WebMethod_Head[] = "HEAD";
//const char WebMethod_Options[] = "OPTIONS";
//const char WebMethod_Post[] = "POST";
//const char WebMethod_Put[] = "PUT";
//const char WebMethod_Patch[] = "PATCH";
//const char WebMethod_Trace[] = "TRACE";
#define WebMethod_Connect "CONNECT"
#define WebMethod_Delete "DELETE"
#define WebMethod_Get "GET"
#define WebMethod_Head "HEAD"
#define WebMethod_Options "OPTIONS"
#define WebMethod_Post "POST"
#define WebMethod_Put "PUT"
#define WebMethod_Patch "PATCH"
#define WebMethod_Trace "TRACE"
enum WebStatus
{
WebStatus_Continue = 100,
WebStatus_SwitchingProtocols = 101,
WebStatus_Processing = 102,
WebStatus_OK = 200,
WebStatus_Created = 201,
WebStatus_Accepted = 202,
WebStatus_NonAuthoritativeInformation = 203,
WebStatus_NoContent = 204,
WebStatus_ResetContent = 205,
WebStatus_PartialContent = 206,
WebStatus_MultiStatus = 207,
WebStatus_MultipleChoices = 300,
WebStatus_MovedPermanently = 301,
WebStatus_Found = 302,
WebStatus_SeeOther = 303,
WebStatus_NotModified = 304,
WebStatus_UseProxy = 305,
WebStatus_SwitchProxy = 306,
WebStatus_TemporaryRedirect = 307,
WebStatus_BadRequest = 400,
WebStatus_Unauthorized = 401,
WebStatus_PaymentRequired = 402,
WebStatus_Forbidden = 403,
WebStatus_NotFound = 404,
WebStatus_MethodNotAllowed = 405,
WebStatus_NotAcceptable = 406,
WebStatus_ProxyAuthenticationRequired = 407,
WebStatus_RequestTimeout = 408,
WebStatus_Conflict = 409,
WebStatus_Gone = 410,
WebStatus_LengthRequired = 411,
WebStatus_PreconditionFailed = 412,
WebStatus_RequestEntityTooLarge = 413,
WebStatus_RequestUriTooLong = 414,
WebStatus_UnsupportedMediaType = 415,
WebStatus_RequestedRangeNotSatisfiable = 416,
WebStatus_ExpectationFailed = 417,
WebStatus_UnprocessableEntity = 422,
WebStatus_Locked = 423,
WebStatus_FailedDependency = 424,
WebStatus_UnorderedCollection = 425,
WebStatus_UpgradeRequired = 426,
WebStatus_NoResponse = 444,
WebStatus_RetryWith = 449,
WebStatus_BlockedByWindowsParentalControls = 450,
WebStatus_UnavailableForLegalReasons = 451,
WebStatus_InternalServerError = 500,
WebStatus_NotImplemented = 501,
WebStatus_BadGateway = 502,
WebStatus_ServiceUnavailable = 503,
WebStatus_GatewayTimeout = 504,
WebStatus_HttpVersionNotSupported = 505,
WebStatus_VariantAlsoNegotiates = 506,
WebStatus_InsufficientStorage = 507,
WebStatus_BandwidthLimitExceeded = 509,
WebStatus_NotExtended = 510,
}
#define WebHeader_Accept "Accept"
#define WebHeader_AcceptCharset "Accept-Charset"
#define WebHeader_AcceptEncoding "Accept-Encoding"
#define WebHeader_AcceptLanguage "Accept-Language"
#define WebHeader_AcceptRanges "Accept-Ranges"
#define WebHeader_Age "Age"
#define WebHeader_Allow "Allow"
#define WebHeader_Authorization "Authorization"
#define WebHeader_CacheControl "Cache-Control"
#define WebHeader_Connection "Connection"
#define WebHeader_ContentEncoding "Content-Encoding"
#define WebHeader_ContentLanguage "Content-Language"
#define WebHeader_ContentLength "Content-Length"
#define WebHeader_ContentLocation "Content-Location"
#define WebHeader_ContentMD5 "Content-MD5"
#define WebHeader_ContentRange "Content-Range"
#define WebHeader_ContentType "Content-Type"
#define WebHeader_Cookie "Cookie"
#define WebHeader_Date "Date"
#define WebHeader_ETag "ETag"
#define WebHeader_Expect "Expect"
#define WebHeader_Expires "Expires"
#define WebHeader_From "From"
#define WebHeader_Host "Host"
#define WebHeader_IfMatch "If-Match"
#define WebHeader_IfModifiedSince "If-Modified-Since"
#define WebHeader_IfNoneMatch "If-None-Match"
#define WebHeader_IfRange "If-Range"
#define WebHeader_IfUnmodifiedSince "If-Unmodified-Since"
#define WebHeader_LastModified "Last-Modified"
#define WebHeader_Location "Location"
#define WebHeader_MaxForwards "Max-Forwards"
#define WebHeader_Pragma "Pragma"
#define WebHeader_ProxyAuthenticate "Proxy-Authenticate"
#define WebHeader_ProxyAuthorization "Proxy-Authorization"
#define WebHeader_Range "Range"
#define WebHeader_Referer "Referer"
#define WebHeader_RetryAfter "Retry-After"
#define WebHeader_Server "Server"
#define WebHeader_SetCookie "Set-Cookie"
#define WebHeader_SetCookie2 "Set-Cookie2"
#define WebHeader_TE "TE"
#define WebHeader_Trailer "Trailer"
#define WebHeader_TransferEncoding "Transfer-Encoding"
#define WebHeader_Upgrade "Upgrade"
#define WebHeader_UserAgent "User-Agent"
#define WebHeader_Vary "Vary"
#define WebHeader_Via "Via"
#define WebHeader_Warning "Warning"
#define WebHeader_WWWAuthenticate "WWW-Authenticate"
#define WebHeader_AccessControlAllowOrigin "Access-Control-Allow-Origin"
enum WebRequestDataType
{
WebRequestDataType_Get,
WebRequestDataType_Post,
WebRequestDataType_Cookie,
WebRequestDataType_Header,
}
methodmap WebResponse < Handle
{
/// Add a HTTP header to a response.
///
/// Multiple instances of the same header can be added to a response with different values.
/// This is only valid if the header is specified as a list, but the restriction is not enforced.
///
/// @param header Name of HTTP header to add. `WebHeader_*` constants exist for standard headers.
/// @param content Value to send in response for this header.
/// @return `true` if the header was sucessfully added, `false` otherwise.
public native bool AddHeader(const char[] header, const char[] content);
/// Remove an added HTTP header from a response.
///
/// @param header Name of HTTP header to remove. `WebHeader_*` constants exist for standard headers.
/// @param content If specified, only remove a header matching this value.
/// @return `true` if any headers were removed, `false` otherwise.
public native bool RemoveHeader(const char[] header, const char[] content = NULL_STRING);
};
methodmap WebStringResponse < WebResponse
{
/// Create a WebResponse from a character string.
///
/// The response length is determined automatically and thus is not binary-safe.
/// Use `WebBinaryResponse` for binary data.
///
/// @param content Content to use for response.
/// @return A new WebResponse instance with the specified content as the body.
public native WebStringResponse(const char[] content);
};
methodmap WebBinaryResponse < WebResponse
{
/// Create a WebResponse from binary data.
///
/// @param content Content to use for response.
/// @param length Length of content.
/// @return A new WebResponse instance with the specified content as the body.
public native WebBinaryResponse(const char[] content, int length);
};
methodmap WebFileResponse < WebResponse
{
/// Create a WebResponse from a file path.
///
/// This uses efficient kernel data transfer mechanisms where available, and avoids
/// reading the entire file into memory at once (or when not being sent to a client).
///
/// @param path Path to response file. Should be constructed using `BuildPath`.
/// @return A new WebResponse instance with the specified file content as the body.
/// @error Unable to open file path for reading.
public native WebFileResponse(const char[] path);
};
typeset WebBodyDataReceived
{
/// Callback for request body.
///
/// @param connection WebConnection handle for the request. Must not be deleted.
/// @param data Raw request body data OR "" if `data_in_cb` = false.
/// @param length Size of `data`.
/// @param data1 Optional user data 1.
/// @param data2 Optional user data 2.
/// @return `true` if the request was handled, `false` will terminate the connection.
function bool(WebConnection connection, char[] data, int length);
function bool(WebConnection connection, char[] data, int length, any data1);
function bool(WebConnection connection, char[] data, int length, any data1, any data2);
};
methodmap WebConnection < Handle
{
/// Get the remote client IP address.
///
/// @param buffer Buffer to store the address in. Should be `WEB_CLIENT_ADDRESS_LENGTH` bytes in size.
/// @param length Size of `buffer`.
/// @return `true` if the client address was stored in `buffer`, `false` otherwise.
public native bool GetClientAddress(char[] buffer, int length);
/// Get the length of the string that would be returned by GetRequestData().
///
/// @param key Paramater (GET or POST), Cookie, or Header to get data from.
/// @return int the size in bytes.
/// @error ParseRequestBody was not called for POST data.
public native int GetRequestDataLength(WebRequestDataType type, const char[] key);
/// Get data sent by the client in the request.
/// Retrieving data from the body (aka. POST) will only work after ParseRequestBody() has been run.
///
/// @param type Source of data. See `WebRequestDataType` for details.
/// @param key Paramater (GET or POST), Cookie, or Header to get data from.
/// @param buffer Buffer to store the data value in.
/// @param length Size of `buffer`.
/// @return `true` if the data exists in the request and was stored in `buffer`, `false` otherwise.
/// @error ParseRequestBody was not called for POST data.
public native bool GetRequestData(WebRequestDataType type, const char[] key, char[] buffer, int length);
/// Load full request body into memory and call `callback` when done.
///
/// @param callback WebBodyDataReceived callback that will be called when request body has been loaded.
/// @param data1 Optional user data 1.
/// @param data2 Optional user data 2.
/// @param data_in_cb Pass body through callback if true.
/// @return `true` on success
/// @error Function called more than once.
public native bool ReadRequestBody(WebBodyDataReceived callback, any data1 = 0, any data2 = 0, bool data_in_cb = true);
/// Get request body, or part of, into buffer.
///
/// @param start Start index in request body.
/// @param buffer Target buffer.
/// @param length Target buffer size.
/// @return `true` on success
/// @error Start exceeds data size.
public native bool GetRequestBody(int start, char[] buffer, int length);
/// Detect endcoding of request body and parse into hashtable for use with GetRequestData.
/// Supports: "application/x-www-form-urlencoded", "multipart/form-data"
///
/// @return `true` on success
/// @error ReadRequestBody() not called first. Function called twice.
public native bool ParseRequestBody();
/// Queue a response to send to the client.
///
/// @param status HTTP status code to use for response. See `WebStatus`.
/// @param response WebResonse to queue. You are responsible for deleting the response.
/// @return `true` if the response was successfully queued, `false` otherwise.
/// @error Invalid response handle.
public native bool QueueResponse(WebStatus status, WebResponse response);
};
/// Callback for incoming requests.
///
/// @param connection WebConnection handle for the request. Must not be deleted.
/// @param method HTTP method used for request. `WebMethod_*` constants exist for standard methods.
/// @param url URL requested by client.
/// @return `true` if the request was handled, `false` will terminate the connection.
typedef WebRequestHandler = function bool (WebConnection connection, const char[] method, const char[] url);
/// Register a request handler.
///
/// @param id Unique identifier for request handler. Used for virtual hosting.
/// @param handler WebRequestHandler callback for incoming requests.
/// @param name Optional name for handler on index page.
/// @param description Optional description for handler on index page.
/// @return `true` if the handler was sucessfully registered, `false` otherwise.
native bool Web_RegisterRequestHandler(const char[] id, WebRequestHandler handler, const char[] name = "", const char[] description = "");
public Extension __ext_Webcon =
{
name = "Webcon",
file = "webcon.ext",
#if defined AUTOLOAD_EXTENSIONS
autoload = 1,
#else
autoload = 0,
#endif
#if defined REQUIRE_EXTENSIONS
required = 1,
#else
required = 0,
#endif
}

View File

@ -35,7 +35,7 @@
#include <zr/respawn.zr>
#include <zr/class.zr>
public SharedPlugin:__pl_zombiereloaded =
public SharedPlugin __pl_zombiereloaded =
{
name = "zombiereloaded",
file = "zombiereloaded.smx",
@ -47,7 +47,7 @@ public SharedPlugin:__pl_zombiereloaded =
};
#if !defined REQUIRE_PLUGIN
public __pl_zombiereloaded_SetNTVOptional()
public void __pl_zombiereloaded_SetNTVOptional()
{
MarkNativeAsOptional("ZR_IsValidClassIndex");
MarkNativeAsOptional("ZR_GetActiveClass");

View File

@ -52,7 +52,7 @@ enum ClassSelectResult
*
* @return True if valid, false otherwise.
*/
native bool:ZR_IsValidClassIndex(classIndex);
native bool ZR_IsValidClassIndex(int classIndex);
/**
* Gets the currently active class index that the player is using.
@ -61,7 +61,7 @@ native bool:ZR_IsValidClassIndex(classIndex);
*
* @return The active class index.
*/
native bool:ZR_GetActiveClass(client);
native bool ZR_GetActiveClass(int client);
/**
* Gets the current human class index that the player is using.
@ -70,7 +70,7 @@ native bool:ZR_GetActiveClass(client);
*
* @return The human class index.
*/
native bool:ZR_GetHumanClass(client);
native bool ZR_GetHumanClass(int client);
/**
* Gets the current zombie class index that the player is using.
@ -79,7 +79,7 @@ native bool:ZR_GetHumanClass(client);
*
* @return The zombie class index.
*/
native bool:ZR_GetZombieClass(client);
native bool ZR_GetZombieClass(int client);
/**
* Selects a class for a player.
@ -99,7 +99,7 @@ native bool:ZR_GetZombieClass(client);
*
* @return Class selection result. See enum ClassSelectResult.
*/
native ClassSelectResult:ZR_SelectClientClass(client, classIndex, bool:applyIfPossible = true, bool:saveIfEnabled = true);
native ClassSelectResult ZR_SelectClientClass(int client, int classIndex, bool applyIfPossible = true, bool saveIfEnabled = true);
/**
* Gets the class index of the class with the specified name.
@ -112,7 +112,7 @@ native ClassSelectResult:ZR_SelectClientClass(client, classIndex, bool:applyIfPo
*
* @return Class index, or -1 if none found.
*/
native ZR_GetClassByName(const String:className[], cacheType = ZR_CLASS_CACHE_MODIFIED);
native int ZR_GetClassByName(const char[] className, int cacheType = ZR_CLASS_CACHE_MODIFIED);
/**
* Gets the class name displayed in the class menu.
@ -124,4 +124,4 @@ native ZR_GetClassByName(const String:className[], cacheType = ZR_CLASS_CACHE_MO
* @param cacheType Optional. Specifies which class cache to read from.
* @return Number of cells written. -1 on error.
*/
native ZR_GetClassDisplayName(index, String:buffer[], maxlen, cacheType = ZR_CLASS_CACHE_MODIFIED);
native int ZR_GetClassDisplayName(int index, char[] buffer, int maxlen, int cacheType = ZR_CLASS_CACHE_MODIFIED);

View File

@ -33,7 +33,7 @@
* @return True if zombie, false if not.
* @error Invalid client index, not connected or not alive.
*/
native bool:ZR_IsClientZombie(client);
native bool ZR_IsClientZombie(int client);
/**
* Returns true if the player is a human, false if not.
@ -43,7 +43,7 @@ native bool:ZR_IsClientZombie(client);
* @return True if human, false if not.
* @error Invalid client index, not connected or not alive.
*/
native bool:ZR_IsClientHuman(client);
native bool ZR_IsClientHuman(int client);
/**
* Infects a player.
@ -58,7 +58,7 @@ native bool:ZR_IsClientHuman(client);
*
* @error Invalid client index, not connected or not alive.
*/
native ZR_InfectClient(client, attacker = -1, bool:motherInfect = false, bool:respawnOverride = false, bool:respawn = false);
native int ZR_InfectClient(int client, int attacker = -1, bool motherInfect = false, bool respawnOverride = false, bool respawn = false);
/**
* Turns a zombie back into a human.
@ -72,7 +72,7 @@ native ZR_InfectClient(client, attacker = -1, bool:motherInfect = false, bool:re
*
* @error Invalid client index, not connected or not alive.
*/
native ZR_HumanClient(client, bool:respawn = false, bool:protect = false);
native int ZR_HumanClient(int client, bool respawn = false, bool protect = false);
/**
* Called when a player is about to become a zombie.
@ -87,7 +87,7 @@ native ZR_HumanClient(client, bool:respawn = false, bool:protect = false);
* @return Plugin_Handled to block infection. Anything else
* (like Plugin_Continue) to allow infection.
*/
forward Action:ZR_OnClientInfect(&client, &attacker, &bool:motherInfect, &bool:respawnOverride, &bool:respawn);
forward Action ZR_OnClientInfect(int &client, int &attacker, bool &motherInfect, bool &respawnOverride, bool &respawn);
/**
* Called after a player has become a zombie.
@ -98,7 +98,7 @@ forward Action:ZR_OnClientInfect(&client, &attacker, &bool:motherInfect, &bool:r
* @param respawnOverride True if the respawn cvar was overridden.
* @param respawn The value that respawn was overridden with.
*/
forward ZR_OnClientInfected(client, attacker, bool:motherInfect, bool:respawnOverride, bool:respawn);
forward void ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn);
/**
* Called when a player is about to become a human. (Through an admin command).
@ -111,7 +111,7 @@ forward ZR_OnClientInfected(client, attacker, bool:motherInfect, bool:respawnOve
* @return Plugin_Handled to block infection. Anything else
* (like Plugin_Continue) to allow acion.
*/
forward Action:ZR_OnClientHuman(&client, &bool:respawn, &bool:protect);
forward Action ZR_OnClientHuman(int &client, bool &respawn, bool &protect);
/**
* Called after a player has become a human. (Through an admin command.)
@ -120,4 +120,4 @@ forward Action:ZR_OnClientHuman(&client, &bool:respawn, &bool:protect);
* @param respawn Whether the client was respawned.
* @param protect Whether the client has spawn protection.
*/
forward ZR_OnClientHumanPost(client, bool:respawn, bool:protect);
forward void ZR_OnClientHumanPost(int client, bool respawn, bool protect);

View File

@ -44,7 +44,7 @@ enum ZR_RespawnCondition
* ZR settings. See ZR_RespawnCondition for details.
* @error Invalid client index, not connected or already alive.
*/
native ZR_RespawnClient(client, ZR_RespawnCondition:condition = ZR_Repsawn_Default);
native void ZR_RespawnClient(int client, ZR_RespawnCondition condition = ZR_Repsawn_Default);
/**
* Called right before ZR is about to respawn a player.
@ -56,7 +56,7 @@ native ZR_RespawnClient(client, ZR_RespawnCondition:condition = ZR_Repsawn_Defau
*
* @return Plugin_Handled to block respawn.
*/
forward Action:ZR_OnClientRespawn(&client, &ZR_RespawnCondition:condition);
forward Action ZR_OnClientRespawn(int &client, ZR_RespawnCondition &condition);
/**
* Called after ZR respawned a player.
@ -65,7 +65,7 @@ forward Action:ZR_OnClientRespawn(&client, &ZR_RespawnCondition:condition);
* @param condition Current condition of the respawned player. See
* ZR_RespawnCondition for details.
*/
forward ZR_OnClientRespawned(client, ZR_RespawnCondition:condition);
forward void ZR_OnClientRespawned(int client, ZR_RespawnCondition condition);
/**
* Set if a player died by a suicide or world damage.
@ -79,7 +79,7 @@ forward ZR_OnClientRespawned(client, ZR_RespawnCondition:condition);
*
* @error Invalid client index or not connected.
*/
native ZR_SetKilledByWorld(client, bool:suicide);
native void ZR_SetKilledByWorld(int client, bool suicide);
/**
* Get whether the player died by a suicide or world damage.
@ -92,4 +92,4 @@ native ZR_SetKilledByWorld(client, bool:suicide);
* another player.
* @error Invalid client index or not connected.
*/
native bool:ZR_GetKilledByWorld(client);
native bool ZR_GetKilledByWorld(int client);

View File

@ -1 +0,0 @@
../../../includes/colors.inc

View File

@ -54,29 +54,29 @@ enum CanNominateResult
* Called whenever warning timer starts
*
*/
forward OnMapVoteWarningStart();
forward void OnMapVoteWarningStart();
/**
* Called whenever runoff warning timer starts
*/
forward OnMapVoteRunnoffWarningStart();
forward void OnMapVoteRunnoffWarningStart();
/**
* Called whenever the timer ticks
*/
forward OnMapVoteWarningTick(time);
forward void OnMapVoteWarningTick(int time);
/**
* Called whenever vote starts
*
* @deprecated Will be removed in MapChooser 1.8. Use OnMapVoteStarted instead.
*/
forward OnMapVoteStart();
forward void OnMapVoteStart();
/**
* Called whenever vote ends
*/
forward OnMapVoteEnd(const char[] map);
forward void OnMapVoteEnd(const char[] map);
/**
* Is a map on the current game's official list?

View File

@ -1 +0,0 @@
../../../includes/nativevotes.inc

View File

@ -0,0 +1,915 @@
/**
* vim: set ts=4 :
* =============================================================================
* NativeVotes
* Copyright (C) 2011-2013 Ross Bemrose (Powerlord). 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$
*/
#include <menus>
#include <sourcemod>
// NativeVotes 0.8 series
#if defined _nativevotes_included
#endinput
#endif
#define _nativevotes_included
#define CLIENT_DISCONNECTED -1
#define NATIVEVOTES_EXTEND "Extend current Map" /** Defined in TF2, but doesn't appear to be localized */
#define NATIVEVOTES_ALL_TEAMS -1 // Defined by TF2, may be the same in L4D/L4D2
#define NATIVEVOTES_TF2_ALL_TEAMS 0 // Defined by TF2, may be the same in L4D/L4D2
#define NATIVEVOTES_TEAM_UNASSIGNED 0 // For completeness, do not otherwise use
#define NATIVEVOTES_TEAM_SPECTATOR 1 // Spectators
#define NATIVEVOTES_TEAM_1 2 // RED/Survivors/Terrorists
#define NATIVEVOTES_TEAM_2 3 // BLU/Infected/Counter-Terrorists
#define NATIVEVOTES_SERVER_INDEX 99 // Defined by TF2, may be the same in L4D/L4D2
// These may seem backwards, but this is the order that the votes appear in the vote screen
#define NATIVEVOTES_VOTE_INVALID -1 /**< Vote was invalid, currently only valid internally */
#define NATIVEVOTES_VOTE_YES 0 /**< Vote was yes */
#define NATIVEVOTES_VOTE_NO 1 /**< Vote was no */
/*
The following MenuActions are supported. Arguments are also listed, as they differ slightly from the default
MenuAction_Start A menu has been started (nothing passed). Only exists for compat reasons.
MenuAction_Display A menu is about to be displayed (param1=client). If you choose to change the vote text,
To change the text, use RedrawVoteTitle()
If you do so, return 1 or _:Plugin_Changed Otherwise, return _:Plugin_Continue or 0.
MenuAction_Select An item was selected (param1=client, param2=item). For subplugin support.
MenuAction_End A vote has fully ended and the vote object is ready to be cleaned up
param1 is MenuEnd reason, either MenuEnd_VotingCancelled or MenuEnd_VotingDone
MenuAction_VoteEnd A vote sequence has succeeded (param1=chosen item)
This is not called if NativeVotes_SetResultCallback has been used on the vote.
You should call NativeVotes_DisplayPass or NativeVotes_DisplayPassEx after this
MenuAction_VoteStart A vote sequence has started (nothing passed). Use this instead of MenuAction_Start
MenuAction_VoteCancel A vote sequence has been cancelled (param1=reason)
MenuAction_DisplayItem Item text is being drawn to the display (param1=client, param2=item)
To change the text, use RedrawVoteItem().
If you do so, return 1 or _:Plugin_Changed. Otherwise, return _:Plugin_Continue or 0.
*/
#define NATIVEVOTES_ACTIONS_DEFAULT MenuAction_VoteStart|MenuAction_VoteCancel|MenuAction_VoteEnd|MenuAction_End
/**
* Vote types. These are mapped to translation strings and pass strings by VoteStart and VotePass handlers
*/
enum NativeVotesType
{
NativeVotesType_None = 0, /** Special placeholder for callvote with no arguments for NativeVotes_OnCallVote */
NativeVotesType_Custom_YesNo, /**< Yes/No, details are vote text. */
NativeVotesType_Custom_Mult, /**< TF2/CS:GO: Multiple-choice, details are vote text. */
NativeVotesType_ChgCampaign, /**< L4D/L4D2: Yes/No, details are campaign name */
NativeVotesType_ChgDifficulty, /**< L4D/L4D2: Yes/No, details are difficulty number in L4D/L4D2 */
NativeVotesType_ReturnToLobby, /**< L4D/L4D2: Yes/No, details are ignored */
NativeVotesType_AlltalkOn, /**< L4D2: Yes/No, details are ignored (handled internally by extension) */
NativeVotesType_AlltalkOff, /**< L4D2: Yes/No, details are ignored (handled internally by extension) */
NativeVotesType_Restart, /**< Yes/No, details are ignored */
NativeVotesType_Kick, /**< Yes/No, target is player userid, details are auto-set by target */
NativeVotesType_KickIdle, /**< TF2/CS:GO: Yes/No, target is player userid, details are auto-set by target */
NativeVotesType_KickScamming, /**< TF2/CS:GO: Yes/No, target is player userid, details are auto-set by target */
NativeVotesType_KickCheating, /**< TF2/CS:GO: Yes/No, target is player userid, details are auto-set by target */
NativeVotesType_ChgLevel, /**< Yes/No, details are level number in L4D/L4D2 or map name in TF2 */
NativeVotesType_NextLevel, /**< TF2/CS:GO: Yes/No, details are map name */
NativeVotesType_NextLevelMult, /**< TF2/CS:GO: Multiple-choice, details are ignored */
NativeVotesType_ScrambleNow, /**< TF2/CS:GO: Yes/No, details are ignored */
NativeVotesType_ScrambleEnd, /**< TF2: Yes/No, details are ignored */
NativeVotesType_ChgMission, /**< TF2: Yes/No, details are popfile */
NativeVotesType_SwapTeams, /**< CS:GO: Yes/No, details are ignored */
NativeVotesType_Surrender, /**< CS:GO: Yes/No, details are ignored */
NativeVotesType_Rematch, /**< CS:GO: Yes/No, details are ignored */
NativeVotesType_Continue, /**< CS:GO: Yes/No, details are ignored */
NativeVotesType_StartRound, /**< TF2: Yes/No, details are ignored */
NativeVotesType_Eternaween, /**< TF2: Yes/No, details are ignored */
NativeVotesType_AutoBalanceOn, /**< TF2: Yes/No, details are ignored */
NativeVotesType_AutoBalanceOff, /**< TF2: Yes/No, details are ignored */
NativeVotesType_ClassLimitsOn, /**< TF2: Yes/No, details are ignored */
NativeVotesType_ClassLimitsOff, /**< TF2: Yes/No, details are ignored */
};
enum NativeVotesPassType
{
NativeVotesPass_None = 0, /**< Special placeholder for error value */
NativeVotesPass_Custom, /**< Details are custom pass message */
NativeVotesPass_ChgCampaign, /**< L4D/L4D2: Details are campaign name */
NativeVotesPass_ChgDifficulty, /**< L4D/L4D2/TF2: Details are difficulty number in L4D/L4D2 and mission name in TF2 */
NativeVotesPass_ReturnToLobby, /**< L4D/L4D2: Details are ignored */
NativeVotesPass_AlltalkOn, /**< L4D2: Details are ignored */
NativeVotesPass_AlltalkOff, /**< L4D2: Details are ignored */
NativeVotesPass_Restart, /**< Details are ignored */
NativeVotesPass_Kick, /**< Details are player name */
NativeVotesPass_ChgLevel, /**< Details are level number in L4D/L4D2 or map name in TF2/CS:GO */
NativeVotesPass_NextLevel, /**< TF2/CS:GO: Details are map name */
NativeVotesPass_Extend, /**< TF2/CS:GO: Details are ignored */
NativeVotesPass_Scramble, /**< TF2/CS:GO: Details are ignored */
NativeVotesPass_ChgMission, /**< TF2: Details are popfile */
NativeVotesPass_SwapTeams, /**< CS:GO: Details are ignored */
NativeVotesPass_Surrender, /**< CS:GO: Details are ignored */
NativeVotesPass_Rematch, /**< CS:GO: Details are ignored */
NativeVotesPass_Continue, /**< CS:GO: Details are ignored */
NativeVotesPass_StartRound, /**< TF2: Details are ignored */
NativeVotesPass_Eternaween, /**< TF2: Details are ignored */
NativeVotesPass_AutoBalanceOn, /**< TF2: Yes/No, details are ignored */
NativeVotesPass_AutoBalanceOff, /**< TF2: Yes/No, details are ignored */
NativeVotesPass_ClassLimitsOn, /**< TF2: Yes/No, details are ignored */
NativeVotesPass_ClassLimitsOff, /**< TF2: Yes/No, details are ignored */
};
/**
* Reasons a vote was canceled. Not used for L4D/L4D2, as they don't care
*/
enum NativeVotesFailType
{
NativeVotesFail_Generic = 0, /**< Vote was generically cancelled. */
NativeVotesFail_Loses = 3, /**< No votes outnumbered Yes votes */
NativeVotesFail_NotEnoughVotes = 4, /**< Vote did not receive enough votes. */
};
/**
* Reasons a callvote command failed.
* This is provided as a convenience to plugin authors as it's not strictly part of the vote system
*/
enum NativeVotesCallFailType
{
NativeVotesCallFail_Generic = 0, /**< Generic fail. */
NativeVotesCallFail_Loading = 1, /**< L4D/L4D2: Players are still loading. */
NativeVotesCallFail_Recent = 2, /**< TF2/CS:GO: You can't call another vote yet: Argument is seconds until you can call another vote. */
NativeVotesCallFail_Disabled = 5, /**< TF2/CS:GO: Server has disabled that issue. */
NativeVotesCallFail_MapNotFound = 6, /**< TF2/CS:GO: Server does not have that map. */
NativeVotesCallFail_SpecifyMap = 7, /**< TF2/CS:GO: You must specify a map. */
NativeVotesCallFail_Failed = 8, /**< TF2/CS:GO: This vote failed recently. */
NativeVotesCallFail_WrongTeam = 9, /**< TF2/CS:GO: Team can't call this vote. */
NativeVotesCallFail_Waiting = 10, /**< TF2/CS:GO: Vote can't be called during Waiting For Players. */
NativeVotesCallFail_PlayerNotFound = 11, /**< TF2/CS:GO: Player to kick can't be found. Buggy in TF2. */
NativeVotesCallFail_Unknown = 11,
NativeVotesCallFail_CantKickAdmin = 12, /**< TF2/CS:GO: Can't kick server admin. */
NativeVotesCallFail_ScramblePending = 13, /**< TF2/CS:GO: Team Scramble is pending.. */
NativeVotesCallFail_Spectators = 14, /**< TF2/CS:GO: Spectators aren't allowed to call votes. */
NativeVotesCallFail_LevelSet = 15, /**< TF2/CS:GO: Next level already set. */
NativeVotesCallFail_MapNotValid = 16, /**< ???: Map is invalid. */
NativeVotesCallFail_KickTime = 17, /**< ???: Cannot kick for time. */
NativeVotesCallFail_KickDuringRound = 18, /**< ???: Cannot kick during a round. */
NativeVotesCallFail_AlreadyActive = 19 /**< TF2: Cannot call vote because modification (Eternaween) is already active (may not work) */
};
/*
* Is a specific vote type supported by this game?
*
* @param voteType Vote type
*/
native bool:NativeVotes_IsVoteTypeSupported(NativeVotesType:voteType);
/**
* Creates a new, empty vote.
*
* @param handler Function which will receive vote actions.
* @param voteType Vote type, cannot be changed after set
* @param actions Optionally set which actions to receive. Start,
* 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 vote Handle on INVALID_HANDLE if a vote type is unsupported by this game.
*/
native Handle:NativeVotes_Create(MenuHandler:handler, NativeVotesType:voteType,
MenuAction:actions=NATIVEVOTES_ACTIONS_DEFAULT);
/**
* Frees all handles related to a vote.
*
* THIS MUST BE CALLED TO AVOID HANDLE LEAKS
*
* @param vote Vote handle
* @noreturn
*/
native Handle:NativeVotes_Close(Handle:vote);
/**
* Appends a new item to the end of a vote. Only valid for Multiple Choice votes
*
* @param vote NativeVotes Handle.
* @param info Item information string.
* @return True on success, false on failure.
* @error Invalid Handle, item limit reached, or if the vote is not multiple choice.
*/
native bool:NativeVotes_AddItem(Handle:vote, const String:info[], const String:display[]);
/**
* 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 vote Vote Handle.
* @param position Position, starting from 0.
* @param info Item information string.
* @return True on success, false on failure.
* @error Invalid Handle or vote position, or if the vote is not multiple choice.
*/
native bool:NativeVotes_InsertItem(Handle:vote, position, const String:info[], const String:display[]);
/**
* Removes an item from the menu.
*
* @param vote Vote Handle.
* @param position Position, starting from 0.
* @return True on success, false on failure.
* @error Invalid Handle or vote position, or if the vote is not multiple choice.
*/
native bool:NativeVotes_RemoveItem(Handle:vote, position);
/**
* Removes all items from a vote.
*
* @param vote Vote Handle.
* @noreturn
* @error Invalid Handle or vote position, or if the vote is not multiple choice.
*/
native NativeVotes_RemoveAllItems(Handle:vote);
/**
* Retrieves information about a vote item.
*
* @param vote Vote Handle.
* @param position Position, starting from 0.
* @param infoBuf Info buffer.
* @param infoBufLen Maximum length of the info buffer.
* @return True on success, false if position is invalid.
* @error Invalid Handlem
*/
native bool:NativeVotes_GetItem(Handle:vote,
position,
String:infoBuf[],
infoBufLen,
String:dispBuf[]="",
dispBufLen=0);
/**
* Returns the number of items in a vote.
*
* @param vote Vote Handle.
* @return Number of items in the vote.
* @error Invalid Handle.
*/
native NativeVotes_GetItemCount(Handle:vote);
/**
* Sets the vote's details for votes that support details
* If this is a custom vote, use NativeVotes_SetTitle to set the vote's title.
*
* @param vote Vote Handle.
* @param argument Details string. See vote types for what details stands for.
* @noreturn
* @error Invalid Handle.
*/
native NativeVotes_SetDetails(Handle:vote, const String:argument[]);
/**
* Returns the text of a vote's details if set.
*
* @param vote Vote Handle.
* @param buffer Buffer to store details.
* @param maxlength Maximum length of the buffer.
* @noreturn
* @error Invalid Handle.
*/
native NativeVotes_GetDetails(Handle:vote, String:buffer[], maxlength);
/**
* Sets a custom vote's title
*
* @param vote Vote Handle.
* @param title Vote title string.
* @noreturn
* @error Invalid Handle.
*/
native NativeVotes_SetTitle(Handle:vote, const String:argument[]);
/**
* Return the vote's Title.
* If not set, returns Details instead.
* This behavior is for compatibility with NativeVotes 0.8.0 and below.
*
* @param vote Vote Handle.
* @param buffer Buffer to store title.
* @param maxlength Maximum length of the buffer.
* @noreturn
* @error Invalid Handle.
*/
native NativeVotes_GetTitle(Handle:vote, String:buffer[], maxlength);
/**
* Sets the target userid for vote
* This should be used instead of SetArgument for votes that target players
*
* Also sets target SteamID
*
* @param vote Vote Handle.
* @param userid Client index of target player
* @param setDetails If true, also sets vote details to client's name
* @noreturn
* @error Invalid Handle.
*/
native NativeVotes_SetTarget(Handle:vote, client, bool:setDetails=true);
/**
* Returns the userid of a vote's target
*
* @param vote Vote Handle.
* @return Client index of target player or 0 for no target or target disconnected since vote started
* @error Invalid Handle.
*/
native NativeVotes_GetTarget(Handle:vote);
/**
* Get the Steam ID of a vote's target
* Useful if the target has disconnect from the server during a vote.
* This was added in specifically for Kick/Ban votes
*
* @param vote Vote Handle.
* @param buffer Buffer to store steamId. Should be 19 characters or more..
* @param maxlength Maximum length of the buffer.
* @noreturn
* @error Invalid Handle.
*/
native NativeVotes_GetTargetSteam(Handle:vote, String:buffer[], maxlength);
/**
* Returns whether a vote is in progress.
*
* @return True if a NativeVotes vote is in progress, false otherwise.
*/
native bool:NativeVotes_IsVoteInProgress();
/**
* Returns a style's maximum items
*
* @return Maximum items
*/
native NativeVotes_GetMaxItems();
/**
* Sets a vote's option flags.
*
* If a certain bit is not supported, it will be stripped before being set.
*
* NOTE: This is currently unused, but reserved for future use.
*
* @param menu Builtin Vote Handle.
* @param flags A new bitstring of VOTEFLAG bits.
* @noreturn
* @error Invalid Handle.
*/
native NativeVotes_SetOptionFlags(Handle:vote, flags);
/**
* Retrieves a menu's option flags.
*
* NOTE: This is currently unused, but reserved for future use.
*
* @param vote Builtin Vote Handle.
* @return A bitstring of VOTEFLAG bits.
* @error Invalid Handle.
*/
native NativeVotes_GetOptionFlags(Handle:vote);
/**
* Cancels the vote in progress.
*
* @noreturn
* @error If no vote is in progress.
*/
native NativeVotes_Cancel();
/**
* Callback for when a vote has ended and results are available.
*
* Due to SourceMod Forward limitations in plugins, multi-dimension arrays can't be passed
* to forwards. This means we have to split the client_info and item_info arrays into
* their components.
*
* @param vote The vote being voted on.
* @param num_votes Number of votes tallied in total.
* @param num_clients Number of clients who could vote.
* @param client_indexes Array of client indexes. Parallel with client_votes.
* @param client_votes Array of client votes. Parallel with client_indexes.
* @param num_items Number of unique items that were selected.
* @param item_indexes Array of vote item indexes. Parallel with item_votes..
* @param item_votes Array of vote vote counts. Parallel with item_indexes.
* @noreturn
*/
functag public NativeVotes_VoteHandler(Handle:vote,
num_votes,
num_clients,
const client_indexes[],
const client_votes[],
num_items,
const item_indexes[],
const item_votes[]);
/**
* Function to convert client/vote arrays into their two-dimensional versions,
* which can then be passed to a standard vote handler.
*
* client_info and item_info are the resulting arrays.
*
* Note: When declaring client_info and item_info, you'll probably want to declare them like this:
* new client_info[num_clients][2];
* new item_info[num_items][2];
*
* @param num_clients Number of clients who could vote.
* @param client_indexes Array of client indexes. Parallel with client_votes.
* @param client_votes Array of client votes. Parallel with client_indexes.
* @param num_items Number of unique items that were selected.
* @param item_indexes Array of vote item indexes. Parallel with item_votes..
* @param item_votes Array of vote vote counts. Parallel with item_indexes.
* @param client_info Array of clients. Use VOTEINFO_CLIENT_ defines.
* @param item_info Array of items, sorted by count. Use VOTEINFO_ITEM
* defines.
* @noreturn
*/
stock NativeVotes_FixResults(num_clients,
const client_indexes[],
const client_votes[],
num_items,
const item_indexes[],
const item_votes[],
client_info[][],
item_info[][])
{
for (new i = 0; i < num_clients; ++i)
{
client_info[i][VOTEINFO_CLIENT_INDEX] = client_indexes[i];
client_info[i][VOTEINFO_CLIENT_ITEM] = client_votes[i];
}
for (new i = 0; i < num_items; ++i)
{
item_info[i][VOTEINFO_ITEM_INDEX] = item_indexes[i];
item_info[i][VOTEINFO_ITEM_VOTES] = item_votes[i];
}
}
/**
* Sets an advanced vote handling callback. If this callback is set,
* MenuAction_VoteEnd will not be called.
*
* @param vote NativeVotes Handle.
* @param callback Callback function.
* @noreturn
* @error Invalid Handle or callback.
*/
native NativeVotes_SetResultCallback(Handle:vote, NativeVotes_VoteHandler:callback);
/**
* Returns the number of seconds you should "wait" before displaying
* a public vote. This number is the time remaining until
* (last_vote + sm_vote_delay).
*
* @return Number of seconds to wait, or 0 for none.
*/
native NativeVotes_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 NativeVotes_Display().
*
* @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:NativeVotes_IsClientInVotePool(client);
/**
* Redraws the current vote to a client in the voting pool.
*
* @param client Client index.
* @param revotes True to allow revotes, false otherwise.
* @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:NativeVotes_RedrawClientVote(client, bool:revotes=true);
/**
* Retrieve the vote type
*
* @param vote NativeVotes Handle.
* @return The built in vote type
* @error Invalid Handle
*/
native NativeVotesType:NativeVotes_GetType(Handle:vote);
/**
* Set the team this vote is for, or NATIVEVOTES_ALL_TEAMS for all teams.
*
* Defaults to NATIVEVOTES_ALL_TEAMS if not explicitly set.
*
* @param vote NativeVotes Handle.
* @param team Team number this vote is for
* @noreturn
* @error Invalid Handle
*/
native NativeVotes_SetTeam(Handle:vote, team);
/**
* Retrieve the team this vote is for
*
* @param vote NativeVotes Handle.
* @return Team index or NATIVEVOTES_ALL_TEAMS for all teams.
* @error Invalid Handle
*/
native NativeVotes_GetTeam(Handle:vote);
/**
* Set the client index of the player who initiated the vote.
* Use NATIVEVOTES_SERVER_INDEX if initiated by the server itself.
*
* Defaults to NATIVEVOTES_SERVER_INDEX if not explicitly set.
*
* @param vote NativeVotes Handle.
* @param client Client who initiated the vote or NATIVEVOTES_SERVER_INDEX
* @noreturn
* @error Invalid Handle
*/
native NativeVotes_SetInitiator(Handle:vote, client);
/**
* Retrieve the client index of the player who initiated the vote or NATIVEVOTES_SERVER_INDEX if
* initiated by the server itself.
*
* @param Vote handle
* @return Client index or NATIVEVOTES_SERVER_INDEX
* @error Invalid Handle
*/
native NativeVotes_GetInitiator(Handle:vote);
/**
* Broadcasts a vote to a list of clients. The most selected item will be
* returned through MenuAction_VoteEnd. On a tie, a random item will be returned
* from a list of the tied items.
*
* Note that MenuAction_VoteStart, MenuAction_VoteCancel, MenuAction_VoteEnd, and MenuAction_End are all
* default callbacks and do not need to be enabled.
*
* @param vote Vote 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 a vote is already in progress.
* @error Invalid Handle, or a vote is already in progress.
*/
native bool:NativeVotes_Display(Handle:vote, clients[], numClients, time);
/**
* Sends a vote menu to all clients. See NativeVotes_Display() for more information.
*
* @param vote Vote 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, or a vote is already in progress.
*/
stock bool:NativeVotes_DisplayToAll(Handle:vote, time)
{
new total = 0;
decl players[MaxClients];
for (new i=1; i<=MaxClients; i++)
{
if (!IsClientInGame(i) || IsFakeClient(i))
{
continue;
}
players[total++] = i;
}
return NativeVotes_Display(vote, players, total, time);
}
/**
* Sends a vote menu to a single team. See NativeVotes_Display() for more information.
*
* @param vote Vote Handle.
* @param team Team to send vote to. 1 = spectators, 2 = RED/Survivors/Terrorists, 3 = BLU/Infected/Counter-Terrorists
* @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.
*/
stock bool:NativeVotes_DisplayToTeam(Handle:vote, team, time)
{
NativeVotes_SetTeam(vote, team);
new total;
decl players[MaxClients];
for (new i=1; i<=MaxClients; i++)
{
if (!IsClientInGame(i) || IsFakeClient(i) || (GetClientTeam(i) != team))
{
continue;
}
players[total++] = i;
}
return NativeVotes_Display(vote, players, total, time);
}
/**
* Sends a vote menu to all clients who are not spectators or waiting to choose a team. See NativeVotes_Display() for more information.
*
* @param vote Vote 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, or a vote is already in progress.
*/
stock bool:NativeVotes_DisplayToAllNonSpectators(Handle:vote, time)
{
new total;
decl players[MaxClients];
for (new i=1; i<=MaxClients; i++)
{
if (!IsClientInGame(i) || IsFakeClient(i) || (GetClientTeam(i) < 2))
{
continue;
}
players[total++] = i;
}
return NativeVotes_Display(vote, players, total, time);
}
/**
* Display vote passed screen
*
* You MUST call one of the NativeVotesDisplayPass* or NativeVotes_DisplayFail functions
* to hide the vote screen for users who didn't vote, and to clear out their selection
* for the next vote.
*
* @param vote Vote handle
* @param details Normally the item that won the vote or format string. Also used for custom vote winners
* @param ... Variable number of format parameters.
* @noreturn
*/
native NativeVotes_DisplayPass(Handle:vote, const String:details[]="");
/**
* Display vote passed screen with custom text to a single user
*
* You MUST call one of the NativeVotesDisplayPass* or NativeVotes_DisplayFail functions
* to hide the vote screen for users who didn't vote, and to clear out their selection
* for the next vote.
*
* @param vote Vote handle
* @param client client to display to
* @param format A format string.
* @param any Variable number of format parameters
* @noreturn
*/
native NativeVotes_DisplayPassCustomToOne(Handle:vote, client, const String:format[], any:...);
/**
* Display vote passed screen with custom text
*
* You MUST call one of the NativeVotesDisplayPass* or NativeVotes_DisplayFail functions
* to hide the vote screen for users who didn't vote, and to clear out their selection
* for the next vote.
*
* @param vote Vote handle
* @param format A format string.
* @param any Variable number of format parameters
* @noreturn
*/
stock NativeVotes_DisplayPassCustom(Handle:vote, const String:format[], any:...)
{
decl String:buffer[192];
for (new i = 1; i <= MaxClients; ++i)
{
if (IsClientInGame(i))
{
SetGlobalTransTarget(i);
VFormat(buffer, sizeof(buffer), format, 3);
NativeVotes_DisplayPassCustomToOne(vote, i, "%s", buffer);
}
}
}
/**
* Display vote passed screen with a custom type.
*
* A sample usage of this would be if Extend won an RTV vote: NativeVotes_DisplayPassEx(vote, NativeVotesPass_Extend, map);
*
* You MUST call one of NativeVotes_DisplayPass, NativeVotes_DisplayPassEx,
* or NativeVotes_DisplayFail to hide the vote screen for users who didn't vote
* and to clear out their selection for the next vote.
*
* #param vote Vote handle
* @param passType The pass screen to display
* @param details Normally the item that won the vote. Also used for custom vote winners
* @noreturn
*/
native NativeVotes_DisplayPassEx(Handle:vote, NativeVotesPassType:passType, const String:details[]="");
/**
* Display failure screen.
*
* You MUST call one of NativeVotes_DisplayPass, NativeVotes_DisplayPassEx,
* or NativeVotes_DisplayFail to hide the vote screen for users who didn't vote,
* and to clear out their selection for the next vote.
*
* @param reason Vote failure reason from NativeVotesFailType enum
* @noreturn
*/
native NativeVotes_DisplayFail(Handle:vote, NativeVotesFailType:reason=NativeVotesFail_Generic);
/**
* 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:NativeVotes_IsNewVoteAllowed()
{
if (NativeVotes_IsVoteInProgress() || NativeVotes_CheckVoteDelay() != 0)
{
return false;
}
return true;
}
/**
* Used when callvote is called with no arguments.
*
* This is used to configure the VoteSetup usermessage on TF2 and CS:GO
*
* @param client Client, in case the votes are restricted by client
* @param voteTypes Populate this array with the vote types this server supports
* Custom and multiple choice votes are not supported from
* the GUI and are thus ignored.
* @return Plugin_Continue to allow the server itself (or another plugin) to process the callvote
* Plugin_Changed if you're changing the voteTypes,
* Plugin_Handled to return a blank VoteSetup usermessage
* Plugin_Stop to prevent VoteSetup usermessage (not recommended)
*/
//functag public Action:NativeVotes_CallVoteSetupHandler(client, NativeVotesType:voteTypes[]);
/**
* Forward for "callvote" handling
*
* You should respond to this by starting a vote or by calling NativeVotes_DisplayCallVoteFail
*
* @param client Client
* @param voteType Type of vote being called. This will NEVER be a multiple-choice or custom vote.
* @param voteArgument Vote argument or blank if the vote type has no argument.
* @param target target userid for kick votes or 0 for all other votes
* @return Plugin_Continue to allow the server itself (or another plugin) to process the callvote
* Plugin_Handled if you processed this vote type
* Plugin_Stop to block the vote type (not recommended)
*/
//functag public Action:NativeVotes_CallVoteHandler(client, NativeVotesType:voteType, const String:voteArgument[], target);
/**
* Register a plugin as a vote manager.
* This is used to abstract away the details of the callvote command.
*
* @param callHandler Handler for callvote commands.
* @param setupHandler Handler to override the which vote types your server supports. Only useful on TF2 and CS:GO.
* @noreturn
*/
//native NativeVotes_RegisterVoteManager(NativeVotes_CallVoteHandler:callHandler, NativeVotes_CallVoteSetupHandler:setupHandler=INVALID_FUNCTION);
/**
* Send a call vote fail screen to a user
* Used to respond to a callvote with invalid arguments or for other reasons
* (such as trying to target an admin for a kick/ban vote)
*
* @param client The client to display the fail screen to
* @param reason A vote call fail reason
* @param time For NativeVotesCallFail_Recent, the number of seconds until the vote
* can be called again
*/
native NativeVotes_DisplayCallVoteFail(client, NativeVotesCallFailType:reason, time);
/**
* Redraws the vote title from inside a MenuAction_Display callback
* Not supported on L4D
*
* @param text Vote title to draw
* @error If called from outside MenuAction_Display
* @return Plugin_Changed if the change is allowed, Plugin_Continue if it isn't.
*/
native Action:NativeVotes_RedrawVoteTitle(const String:text[]);
/**
* Redraws the vote text from inside a MenuAction_DisplayItem callback.
* Only supported on multiple-choice votes
*
* @param text Vote text to draw.
* @error If called from outside MenuAction_DisplayItem
* @return Plugin_Changed if the change is allowed, Plugin_Continue if it isn't.
*/
native Action:NativeVotes_RedrawVoteItem(const String:text[]);
/**
* 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 NativeVotes_GetInfo(param2, &winningVotes, &totalVotes)
{
winningVotes = param2 & 0xFFFF;
totalVotes = param2 >> 16;
}
/**
* Do not edit below this line!
*/
public SharedPlugin:__pl_nativevotes =
{
name = "nativevotes",
file = "nativevotes.smx",
#if defined REQUIRE_PLUGINS
required = 1,
#else
required = 0,
#endif
};
public __pl_nativevotes_SetNTVOptional()
{
MarkNativeAsOptional("NativeVotes_IsVoteTypeSupported");
MarkNativeAsOptional("NativeVotes_Create");
MarkNativeAsOptional("NativeVotes_Close");
MarkNativeAsOptional("NativeVotes_AddItem");
MarkNativeAsOptional("NativeVotes_InsertItem");
MarkNativeAsOptional("NativeVotes_RemoveItem");
MarkNativeAsOptional("NativeVotes_RemoveAllItems");
MarkNativeAsOptional("NativeVotes_GetItem");
MarkNativeAsOptional("NativeVotes_GetItemCount");
MarkNativeAsOptional("NativeVotes_SetDetails");
MarkNativeAsOptional("NativeVotes_GetDetails");
MarkNativeAsOptional("NativeVotes_SetTitle");
MarkNativeAsOptional("NativeVotes_GetTitle");
MarkNativeAsOptional("NativeVotes_SetTarget");
MarkNativeAsOptional("NativeVotes_GetTarget");
MarkNativeAsOptional("NativeVotes_GetTargetSteam");
MarkNativeAsOptional("NativeVotes_IsVoteInProgress");
MarkNativeAsOptional("NativeVotes_GetMaxItems");
MarkNativeAsOptional("NativeVotes_SetOptionFlags");
MarkNativeAsOptional("NativeVotes_GetOptionFlags");
MarkNativeAsOptional("NativeVotes_Cancel");
MarkNativeAsOptional("NativeVotes_SetResultCallback");
MarkNativeAsOptional("NativeVotes_CheckVoteDelay");
MarkNativeAsOptional("NativeVotes_IsClientInVotePool");
MarkNativeAsOptional("NativeVotes_RedrawClientVote");
MarkNativeAsOptional("NativeVotes_RedrawClientVote");
MarkNativeAsOptional("NativeVotes_GetType");
MarkNativeAsOptional("NativeVotes_SetTeam");
MarkNativeAsOptional("NativeVotes_GetTeam");
MarkNativeAsOptional("NativeVotes_SetInitiator");
MarkNativeAsOptional("NativeVotes_GetInitiator");
MarkNativeAsOptional("NativeVotes_Display");
MarkNativeAsOptional("NativeVotes_DisplayPass");
MarkNativeAsOptional("NativeVotes_DisplayPassCustomToOne");
MarkNativeAsOptional("NativeVotes_DisplayPassEx");
MarkNativeAsOptional("NativeVotes_DisplayFail");
MarkNativeAsOptional("NativeVotes_RegisterVoteManager");
MarkNativeAsOptional("NativeVotes_DisplayCallVoteFail");
MarkNativeAsOptional("NativeVotes_RedrawVoteTitle");
MarkNativeAsOptional("NativeVotes_RedrawVoteItem");
}

View File

@ -45,10 +45,10 @@
#include <sourcemod>
#include <mapchooser>
#include "include/mapchooser_extended"
#include <mapchooser_extended>
#include <nextmap>
#include <sdktools>
#include <colors>
#include <multicolors>
#undef REQUIRE_PLUGIN
#include <nativevotes>

View File

@ -32,14 +32,14 @@
* Version: $Id$
*/
#include <sourcemod>
#include <mapchooser>
#include "include/mapchooser_extended"
#include <colors>
#pragma semicolon 1
#pragma newdecls required
#include <sourcemod>
#include <mapchooser>
#include <mapchooser_extended>
#include <multicolors>
#define MCE_VERSION "1.13.0"
public Plugin myinfo =

View File

@ -31,14 +31,14 @@
* Version: $Id$
*/
#pragma semicolon 1
#pragma newdecls required
#include <sourcemod>
#include <sdktools_functions>
#include <mapchooser>
#include <nextmap>
#pragma semicolon 1
#pragma newdecls required
#define MCE_VERSION "1.13.0"
public Plugin myinfo =