Yeet some unmodified public plugins.

This commit is contained in:
zaCade 2019-03-03 13:18:37 +01:00
parent 236ef3126a
commit 8a2109c9fc
7 changed files with 0 additions and 3115 deletions

View File

@ -1,876 +0,0 @@
#if defined _autoexecconfig_included
#endinput
#endif
#define _autoexecconfig_included
#include <sourcemod>
// Append
#define AUTOEXEC_APPEND_BAD_FILENAME 0
#define AUTOEXEC_APPEND_FILE_NOT_FOUND 1
#define AUTOEXEC_APPEND_BAD_HANDLE 2
#define AUTOEXEC_APPEND_SUCCESS 3
// Find
#define AUTOEXEC_FIND_BAD_FILENAME 10
#define AUTOEXEC_FIND_FILE_NOT_FOUND 11
#define AUTOEXEC_FIND_BAD_HANDLE 12
#define AUTOEXEC_FIND_NOT_FOUND 13
#define AUTOEXEC_FIND_SUCCESS 14
// Clean
#define AUTOEXEC_CLEAN_FILE_NOT_FOUND 20
#define AUTOEXEC_CLEAN_BAD_HANDLE 21
#define AUTOEXEC_CLEAN_SUCCESS 22
// General
#define AUTOEXEC_NO_CONFIG 30
// Formatter
#define AUTOEXEC_FORMAT_BAD_FILENAME 40
#define AUTOEXEC_FORMAT_SUCCESS 41
// Global variables
static char g_sConfigFile[PLATFORM_MAX_PATH];
static char g_sRawFileName[PLATFORM_MAX_PATH];
static char g_sFolderPath[PLATFORM_MAX_PATH];
static StringMap g_hConvarTrie = null;
static bool g_bCacheEnabled = false;
static bool g_bCreateFile = false;
static Handle g_hPluginHandle = null;
// Workaround for now
static int g_iLastFindResult;
static int g_iLastAppendResult;
/**
* Returns the last result from the parser.
*
* @return Returns one of the AUTOEXEC_FIND values or -1 if not set.
*/
stock int AutoExecConfig_GetFindResult()
{
return g_iLastFindResult;
}
/**
* Returns the last result from the appender.
*
* @return Returns one of the AUTOEXEC_APPEND values or -1 if not set.
*/
stock int AutoExecConfig_GetAppendResult()
{
return g_iLastAppendResult;
}
/**
* Set if the config file should be created if it doesn't exist yet.
*
* @param create True if config file should be created, false otherwise.
* @noreturn
*/
stock void AutoExecConfig_SetCreateFile(bool create)
{
g_bCreateFile = create;
}
/**
* Returns if the config file should be created if it doesn't exist.
*
* @return Returns true, if the config file should be created or false if it should not.
*/
stock bool AutoExecConfig_GetCreateFile()
{
return g_bCreateFile;
}
/**
* Set the plugin for which the config file should be created.
* Set to null to use the calling plugin.
* Used to print the correct filename in the top comment when creating the file.
*
* @param plugin The plugin to create convars for or null to use the calling plugin.
* @noreturn
*/
stock void AutoExecConfig_SetPlugin(Handle plugin)
{
g_hPluginHandle = plugin;
}
/**
* Returns the plugin for which the config file is created.
*
* @return The plugin handle
*/
stock Handle AutoExecConfig_GetPlugin()
{
return g_hPluginHandle;
}
/**
* Set the global autoconfigfile used by functions of this file.
*
* @param file Name of the config file, path and .cfg extension is being added if not given.
* @param folder Folder under cfg/ to use. By default this is "sourcemod."
* @return True if formatter returned success, false otherwise.
*/
stock bool AutoExecConfig_SetFile(char[] file, char[] folder="sourcemod")
{
Format(g_sConfigFile, sizeof(g_sConfigFile), "%s", file);
// Global buffers for cfg execution
strcopy(g_sRawFileName, sizeof(g_sRawFileName), file);
strcopy(g_sFolderPath, sizeof(g_sFolderPath), folder);
// Format the filename
return AutoExecConfig_FormatFileName(g_sConfigFile, sizeof(g_sConfigFile), folder) == AUTOEXEC_FORMAT_SUCCESS;
}
/**
* Get the formatted autoconfigfile used by functions of this file.
*
* @param buffer String to format.
* @param size Maximum size of buffer
* @return True if filename was set, false otherwise.
*/
stock bool AutoExecConfig_GetFile(char[] buffer,int size)
{
if (strlen(g_sConfigFile) > 0)
{
strcopy(buffer, size, g_sConfigFile);
return true;
}
// Security for decl users
buffer[0] = '\0';
return false;
}
/**
* Creates a convar and appends it to the autoconfigfile if not found.
* FCVAR_DONTRECORD will be skipped.
*
* @param name Name of new convar.
* @param defaultValue String containing the default value of new convar.
* @param description Optional description of the convar.
* @param flags Optional bitstring of flags determining how the convar should be handled. See FCVAR_* constants for more details.
* @param hasMin Optional boolean that determines if the convar has a minimum value.
* @param min Minimum floating point value that the convar can have if hasMin is true.
* @param hasMax Optional boolean that determines if the convar has a maximum value.
* @param max Maximum floating point value that the convar can have if hasMax is true.
* @return A handle to the newly created convar. If the convar already exists, a handle to it will still be returned.
* @error Convar name is blank or is the same as an existing console command.
*/
stock ConVar AutoExecConfig_CreateConVar(const char[] name, const char[] defaultValue, const char[] description="", int flags=0, bool hasMin=false, float min=0.0, bool hasMax=false, float max=0.0)
{
// If configfile was set and convar has no dontrecord flag
if (!(flags & FCVAR_DONTRECORD) && strlen(g_sConfigFile) > 0)
{
// Reset the results
g_iLastFindResult = -1;
g_iLastAppendResult = -1;
// Add it if not found
char buffer[64];
g_iLastFindResult = AutoExecConfig_FindValue(name, buffer, sizeof(buffer), true);
// We only add this convar if it doesn't exist, or the file doesn't exist and it should be auto-generated
if (g_iLastFindResult == AUTOEXEC_FIND_NOT_FOUND || (g_iLastFindResult == AUTOEXEC_FIND_FILE_NOT_FOUND && g_bCreateFile))
{
g_iLastAppendResult = AutoExecConfig_AppendValue(name, defaultValue, description, flags, hasMin, min, hasMax, max);
}
}
// Create the convar
return CreateConVar(name, defaultValue, description, flags, hasMin, min, hasMax, max);
}
/**
* Executes the autoconfigfile, and adds it to the OnConfigsExecuted forward.
* If we didn't created it already we let SourceMod create it.
*
* @noreturn
*/
stock void AutoExecConfig_ExecuteFile()
{
// Only let sourcemod create the file, if we didn't do that already.
AutoExecConfig(!g_bCreateFile, g_sRawFileName, g_sFolderPath);
}
/**
* Formats a autoconfigfile, prefixes path and adds .cfg extension if missed.
*
* @param buffer String to format.
* @param size Maximum size of buffer.
* @return Returns one of the AUTOEXEC_FORMAT values..
*/
stock static int AutoExecConfig_FormatFileName(char[] buffer, int size, char[] folder="sourcemod")
{
// No config set
if (strlen(g_sConfigFile) < 1)
{
return AUTOEXEC_NO_CONFIG;
}
// Can't be an cfgfile
if (StrContains(g_sConfigFile, ".cfg") == -1 && strlen(g_sConfigFile) < 4)
{
return AUTOEXEC_FORMAT_BAD_FILENAME;
}
// Pathprefix
char pathprefixbuffer[PLATFORM_MAX_PATH];
if (strlen(folder) > 0)
{
Format(pathprefixbuffer, sizeof(pathprefixbuffer), "cfg/%s/", folder);
}
else
{
Format(pathprefixbuffer, sizeof(pathprefixbuffer), "cfg/");
}
char filebuffer[PLATFORM_MAX_PATH];
filebuffer[0] = '\0';
// Add path if file doesn't begin with it
if (StrContains(buffer, pathprefixbuffer) != 0)
{
StrCat(filebuffer, sizeof(filebuffer), pathprefixbuffer);
}
StrCat(filebuffer, sizeof(filebuffer), g_sConfigFile);
// Add .cfg extension if file doesn't end with it
if (StrContains(filebuffer[strlen(filebuffer) - 4], ".cfg") != 0)
{
StrCat(filebuffer, sizeof(filebuffer), ".cfg");
}
strcopy(buffer, size, filebuffer);
return AUTOEXEC_FORMAT_SUCCESS;
}
/**
* Appends a convar to the global autoconfigfile
*
* @param name Name of new convar.
* @param defaultValue String containing the default value of new convar.
* @param description Optional description of the convar.
* @param flags Optional bitstring of flags determining how the convar should be handled. See FCVAR_* constants for more details.
* @param hasMin Optional boolean that determines if the convar has a minimum value.
* @param min Minimum floating point value that the convar can have if hasMin is true.
* @param hasMax Optional boolean that determines if the convar has a maximum value.
* @param max Maximum floating point value that the convar can have if hasMax is true.
* @return Returns one of the AUTOEXEC_APPEND values
*/
stock int AutoExecConfig_AppendValue(const char[] name, const char[] defaultValue, const char[] description, int flags, bool hasMin, float min, bool hasMax, float max)
{
// No config set
if (strlen(g_sConfigFile) < 1)
{
return AUTOEXEC_NO_CONFIG;
}
char filebuffer[PLATFORM_MAX_PATH];
strcopy(filebuffer, sizeof(filebuffer), g_sConfigFile);
//PrintToServer("pathbuffer: %s", filebuffer);
bool bFileExists = FileExists(filebuffer);
if (g_bCreateFile || bFileExists)
{
// If the file already exists we open it in append mode, otherwise we use a write mode which creates the file
File fFile = OpenFile(filebuffer, (bFileExists ? "a" : "w"));
char writebuffer[2048];
if (fFile == null)
{
return AUTOEXEC_APPEND_BAD_HANDLE;
}
// We just created the file, so add some header about version and stuff
if (g_bCreateFile && !bFileExists)
{
fFile.WriteLine( "// This file was auto-generated by AutoExecConfig read and append beta");
GetPluginFilename(g_hPluginHandle, writebuffer, sizeof(writebuffer));
Format(writebuffer, sizeof(writebuffer), "// ConVars for plugin \"%s\"", writebuffer);
fFile.WriteLine(writebuffer);
}
// Spacer
fFile.WriteLine("\n");
// This is used for multiline comments
int newlines = GetCharCountInStr('\n', description);
if (newlines == 0)
{
// We have no newlines, we can write the description to the file as is
Format(writebuffer, sizeof(writebuffer), "// %s", description);
fFile.WriteLine(writebuffer);
}
else
{
char[][] newlineBuf = new char[newlines +1][2048];
ExplodeString(description, "\n", newlineBuf, newlines +1, 2048, false);
// Each newline gets a commented newline
for (int i; i <= newlines; i++)
{
if (strlen(newlineBuf[i]) > 0)
{
fFile.WriteLine("// %s", newlineBuf[i]);
}
}
}
// Descspacer
fFile.WriteLine("// -");
// Default
Format(writebuffer, sizeof(writebuffer), "// Default: \"%s\"", defaultValue);
fFile.WriteLine(writebuffer);
// Minimum
if (hasMin)
{
Format(writebuffer, sizeof(writebuffer), "// Minimum: \"%f\"", min);
fFile.WriteLine(writebuffer);
}
// Maximum
if (hasMax)
{
Format(writebuffer, sizeof(writebuffer), "// Maximum: \"%f\"", max);
fFile.WriteLine(writebuffer);
}
// Write end and defaultvalue
Format(writebuffer, sizeof(writebuffer), "%s \"%s\"", name, defaultValue);
fFile.WriteLine(writebuffer);
fFile.Close();
// Clean up the file
//AutoExecConfig_CleanFile(filebuffer, false);
return AUTOEXEC_APPEND_SUCCESS;
}
return AUTOEXEC_APPEND_FILE_NOT_FOUND;
}
/**
* Returns a convars value from the global autoconfigfile
*
* @param cvar Cvar to search for.
* @param value Buffer to store result into.
* @param size Maximum size of buffer.
* @param caseSensitive Whether or not the search should be case sensitive.
* @return Returns one of the AUTOEXEC_FIND values
*/
stock int AutoExecConfig_FindValue(const char[] cvar, char[] value, int size, bool caseSensitive=false)
{
// Security for decl users
value[0] = '\0';
// No config set
if (strlen(g_sConfigFile) < 1)
{
return AUTOEXEC_NO_CONFIG;
}
if (g_bCacheEnabled)
{
char sTrieValue[64];
if (g_hConvarTrie.GetString(cvar, sTrieValue, sizeof(sTrieValue)))
{
strcopy(value, size, sTrieValue);
return AUTOEXEC_FIND_SUCCESS;
}
return AUTOEXEC_FIND_NOT_FOUND;
}
char filebuffer[PLATFORM_MAX_PATH];
strcopy(filebuffer, sizeof(filebuffer), g_sConfigFile);
//PrintToServer("pathbuffer: %s", filebuffer);
bool bFileExists = FileExists(filebuffer);
// We want to create the config file and it doesn't exist yet.
if (g_bCreateFile && !bFileExists)
{
return AUTOEXEC_FIND_FILE_NOT_FOUND;
}
if (bFileExists)
{
File fFile = OpenFile(filebuffer, "r");
int valuestart;
int valueend;
int cvarend;
// Just an reminder to self, leave the values that high
char sConvar[64];
char sValue[64];
char readbuffer[2048];
char copybuffer[2048];
if (fFile == null)
{
return AUTOEXEC_FIND_BAD_HANDLE;
}
while (!fFile.EndOfFile() && fFile.ReadLine(readbuffer, sizeof(readbuffer)))
{
// Is a comment or not valid
if (IsCharSpace(readbuffer[0]) || readbuffer[0] == '/' || !IsCharAlpha(readbuffer[0]))
{
continue;
}
// Has not enough spaces, must have at least 1
if (GetCharCountInStr(' ', readbuffer) < 1)
{
continue;
}
// Ignore cvars which aren't quoted
if (GetCharCountInStr('"', readbuffer) != 2)
{
continue;
}
// Get the start of the value
if ( (valuestart = StrContains(readbuffer, "\"")) == -1 )
{
continue;
}
// Get the end of the value
if ( (valueend = StrContains(readbuffer[valuestart+1], "\"")) == -1 )
{
continue;
}
// Get the start of the cvar,
if ( (cvarend = StrContains(readbuffer, " ")) == -1 || cvarend >= valuestart)
{
continue;
}
// Skip if cvarendindex is before valuestartindex
if (cvarend >= valuestart)
{
continue;
}
// Convar
// Tempcopy for security
strcopy(copybuffer, sizeof(copybuffer), readbuffer);
copybuffer[cvarend] = '\0';
strcopy(sConvar, sizeof(sConvar), copybuffer);
// Value
// Tempcopy for security
strcopy(copybuffer, sizeof(copybuffer), readbuffer[valuestart+1]);
copybuffer[valueend] = '\0';
strcopy(sValue, sizeof(sValue), copybuffer);
//PrintToServer("Cvar %s has a value of %s", sConvar, sValue);
if (StrEqual(sConvar, cvar, caseSensitive))
{
Format(value, size, "%s", sConvar);
fFile.Close();
return AUTOEXEC_FIND_SUCCESS;
}
}
fFile.Close();
return AUTOEXEC_FIND_NOT_FOUND;
}
return AUTOEXEC_FIND_FILE_NOT_FOUND;
}
/**
* Cleans the global autoconfigfile from too much spaces
*
* @return One of the AUTOEXEC_CLEAN values.
*/
stock int AutoExecConfig_CleanFile()
{
// No config set
if (strlen(g_sConfigFile) < 1)
{
return AUTOEXEC_NO_CONFIG;
}
char sfile[PLATFORM_MAX_PATH];
strcopy(sfile, sizeof(sfile), g_sConfigFile);
// Security
if (!FileExists(sfile))
{
return AUTOEXEC_CLEAN_FILE_NOT_FOUND;
}
char sfile2[PLATFORM_MAX_PATH];
Format(sfile2, sizeof(sfile2), "%s_tempcopy", sfile);
char readbuffer[2048];
int count;
bool firstreached;
// Open files
File fFile1 = OpenFile(sfile, "r");
File fFile2 = OpenFile(sfile2, "w");
// Check filehandles
if (fFile1 == null || fFile2 == null)
{
if (fFile1 != null)
{
//PrintToServer("Handle1 invalid");
fFile1.Close();
}
if (fFile2 != null)
{
//PrintToServer("Handle2 invalid");
fFile2.Close();
}
return AUTOEXEC_CLEAN_BAD_HANDLE;
}
while (!fFile1.EndOfFile() && fFile1.ReadLine(readbuffer, sizeof(readbuffer)))
{
// Is space
if (IsCharSpace(readbuffer[0]))
{
count++;
}
// No space, count from start
else
{
count = 0;
}
// Don't write more than 1 space if seperation after informations have been reached
if (count < 2 || !firstreached)
{
ReplaceString(readbuffer, sizeof(readbuffer), "\n", "");
fFile2.WriteLine(readbuffer);
}
// First bigger seperation after informations has been reached
if (count == 2)
{
firstreached = true;
}
}
fFile1.Close();
fFile2.Close();
// This might be a risk, for now it works
DeleteFile(sfile);
RenameFile(sfile, sfile2);
return AUTOEXEC_CLEAN_SUCCESS;
}
/**
* Returns how many times the given char occures in the given string.
*
* @param str String to search for in.
* @return Occurences of the given char found in string.
*/
stock static int GetCharCountInStr(int character, const char[] str)
{
int len = strlen(str);
int count;
for (int i; i < len; i++)
{
if (str[i] == character)
{
count++;
}
}
return count;
}
/**
* Reads the existing config file and caches any convars and values that were found.
*
* @param str String to search for in.
* @return True when config existed and could be read, false otherwise.
*/
stock bool AutoExecConfig_CacheConvars()
{
if (g_hConvarTrie == null)
{
g_hConvarTrie = new StringMap();
}
// No config set
if (strlen(g_sConfigFile) < 1)
{
return false;
}
char filebuffer[PLATFORM_MAX_PATH];
strcopy(filebuffer, sizeof(filebuffer), g_sConfigFile);
//PrintToServer("pathbuffer: %s", filebuffer);
bool bFileExists = FileExists(filebuffer);
// We want to create the config file and it doesn't exist yet.
if (!bFileExists)
{
return false;
}
File fFile = OpenFile(filebuffer, "r");
int valuestart;
int valueend;
int cvarend;
// Just an reminder to self, leave the values that high
char sConvar[64];
char sValue[64];
char readbuffer[2048];
char copybuffer[2048];
if (fFile == null)
{
return false;
}
while (!fFile.EndOfFile() && fFile.ReadLine(readbuffer, sizeof(readbuffer)))
{
// Is a comment or not valid
if (IsCharSpace(readbuffer[0]) || readbuffer[0] == '/' || !IsCharAlpha(readbuffer[0]))
{
continue;
}
// Has not enough spaces, must have at least 1
if (GetCharCountInStr(' ', readbuffer) < 1)
{
continue;
}
// Ignore cvars which aren't quoted
if (GetCharCountInStr('"', readbuffer) != 2)
{
continue;
}
// Get the start of the value
if ( (valuestart = StrContains(readbuffer, "\"")) == -1 )
{
continue;
}
// Get the end of the value
if ( (valueend = StrContains(readbuffer[valuestart+1], "\"")) == -1 )
{
continue;
}
// Get the start of the cvar,
if ( (cvarend = StrContains(readbuffer, " ")) == -1 || cvarend >= valuestart)
{
continue;
}
// Skip if cvarendindex is before valuestartindex
if (cvarend >= valuestart)
{
continue;
}
// Convar
// Tempcopy for security
strcopy(copybuffer, sizeof(copybuffer), readbuffer);
copybuffer[cvarend] = '\0';
strcopy(sConvar, sizeof(sConvar), copybuffer);
// Value
// Tempcopy for security
strcopy(copybuffer, sizeof(copybuffer), readbuffer[valuestart+1]);
copybuffer[valueend] = '\0';
strcopy(sValue, sizeof(sValue), copybuffer);
//PrintToServer("Cvar %s has a value of %s", sConvar, sValue);
char sTrieValue[64];
if (!g_hConvarTrie.GetString(sConvar, sTrieValue, sizeof(sTrieValue)))
{
//PrintToServer("Adding convar %s to trie", sConvar);
g_hConvarTrie.SetString(sConvar, sValue);
}
}
fFile.Close();
g_bCacheEnabled = true;
return true;
}

View File

@ -1,674 +0,0 @@
// MOAR COLORS
// By Dr. McKay
// Inspired by: https://forums.alliedmods.net/showthread.php?t=96831
#if defined _colors_included
#endinput
#endif
#define _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 COLOR_RED 0xFF4040
#define COLOR_BLUE 0x99CCFF
#define COLOR_GRAY 0xCCCCCC
#define COLOR_GREEN 0x3EFF3E
#define 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
/**
* Prints a message to a specific client in the chat area.
* Supports color tags.
*
* @param client Client index.
* @param message Message (formatting rules).
* @noreturn
*
* On error/Errors: If the client is not connected an error will be thrown.
*/
stock CPrintToChat(client, const String:message[], any:...) {
CCheckTrie();
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];
SetGlobalTransTarget(client);
Format(buffer, sizeof(buffer), "\x01%s", message);
VFormat(buffer2, sizeof(buffer2), buffer, 3);
CReplaceColorCodes(buffer2);
CSendMessage(client, buffer2);
}
/**
* Prints a message to all clients in the chat area.
* Supports color tags.
*
* @param client Client index.
* @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;
continue;
}
SetGlobalTransTarget(i);
Format(buffer, sizeof(buffer), "\x01%s", message);
VFormat(buffer2, sizeof(buffer2), buffer, 2);
CReplaceColorCodes(buffer2);
CSendMessage(i, buffer2);
}
}
/**
* 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 message Message (formatting rules).
* @noreturn
*
* 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();
if(client <= 0 || client > MaxClients) {
ThrowError("Invalid client index %i", client);
}
if(!IsClientInGame(client)) {
ThrowError("Client %i is not in game", client);
}
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];
SetGlobalTransTarget(client);
Format(buffer, sizeof(buffer), "\x01%s", message);
VFormat(buffer2, sizeof(buffer2), buffer, 4);
CReplaceColorCodes(buffer2, author);
CSendMessage(client, buffer2, author);
}
/**
* Prints a message to all clients in the chat area.
* Supports color tags and teamcolor tag.
*
* @param author Author index whose color will be used for teamcolor tag.
* @param message Message (formatting rules).
* @noreturn
*
* On error/Errors: If the author is not connected an error will be thrown.
*/
stock CPrintToChatAllEx(author, const String:message[], any:...) {
CCheckTrie();
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;
continue;
}
SetGlobalTransTarget(i);
Format(buffer, sizeof(buffer), "\x01%s", message);
VFormat(buffer2, sizeof(buffer2), buffer, 3);
CReplaceColorCodes(buffer2, author);
CSendMessage(i, buffer2, author);
}
}
/**
* Sends a SayText2 usermessage
*
* @param client Client to send usermessage to
* @param message Message to send
* @noreturn
*/
stock CSendMessage(client, const String:message[], author=0) {
if(author == 0) {
author = client;
}
decl String:buffer[MAX_MESSAGE_LENGTH], String:game[16];
GetGameFolderName(game, sizeof(game));
strcopy(buffer, sizeof(buffer), message);
new UserMsg:index = GetUserMessageId("SayText2");
if(index == INVALID_MESSAGE_ID) {
if(StrEqual(game, "dod")) {
new 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]);
ReplaceString(buffer, sizeof(buffer), "\x03", temp, false);
}
}
PrintToChat(client, "%s", buffer);
return;
}
new 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);
PbSetString(buf, "msg_name", buffer);
PbAddString(buf, "params", "");
PbAddString(buf, "params", "");
PbAddString(buf, "params", "");
PbAddString(buf, "params", "");
} else {
BfWriteByte(buf, author); // Message author
BfWriteByte(buf, true); // Chat message
BfWriteString(buf, buffer); // Message text
}
EndMessage();
}
/**
* This function should only be used right in front of
* CPrintToChatAll or CPrintToChatAllEx. 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) {
if(client <= 0 || client > MaxClients) {
ThrowError("Invalid client index %i", client);
}
CSkipList[client] = true;
}
/**
* Checks if the colors trie is initialized and initializes it if it's not (used internally)
*
* @return No return
*/
stock CCheckTrie() {
if(CTrie == INVALID_HANDLE) {
CTrie = InitColorTrie();
}
}
/**
* Replaces color tags in a string with color codes (used internally by CPrintToChat, CPrintToChatAll, CPrintToChatEx, and CPrintToChatAllEx
*
* @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
* @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();
if(!removeTags) {
ReplaceString(buffer, maxlen, "{default}", "\x01", false);
} else {
ReplaceString(buffer, maxlen, "{default}", "", false);
ReplaceString(buffer, maxlen, "{teamcolor}", "", false);
}
if(author != 0 && !removeTags) {
if(author < 0 || author > MaxClients) {
ThrowError("Invalid client index %i", author);
}
if(!IsClientInGame(author)) {
ThrowError("Client %i is not in game", author);
}
ReplaceString(buffer, maxlen, "{teamcolor}", "\x03", false);
}
new cursor = 0;
new value;
decl String:tag[32], String:buff[32], String:output[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.
if(MatchRegex(regex, buffer[cursor]) < 1) {
CloseHandle(regex);
strcopy(buffer, maxlen, output);
return;
}
GetRegexSubString(regex, 0, tag, sizeof(tag));
CStrToLower(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)) {
continue;
}
if(removeTags) {
ReplaceString(output, maxlen, tag, "", false);
} else {
Format(buff, sizeof(buff), "\x07%06X", value);
ReplaceString(output, maxlen, tag, buff, false);
}
}
LogError("[MORE COLORS] Infinite loop broken.");
}
/**
* Gets a part of a string
*
* @param input String to get the part from
* @param output Buffer to write to
* @param maxlen Max length of output buffer
* @param start Position to start at
* @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;
for(;;) {
if(i == maxlen - 1 || i >= numChars || input[start + i] == '\0') {
output[i] = '\0';
return;
}
output[i] = input[start + i];
i++;
}
}
/**
* Converts a string to lowercase
*
* @param buffer String to convert
* @noreturn
*/
stock CStrToLower(String:buffer[]) {
new len = strlen(buffer);
for(new i = 0; i < len; i++) {
buffer[i] = CharToLower(buffer[i]);
}
}
/**
* Adds a color to the colors trie
*
* @param name Color name, without braces
* @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)) {
return false;
}
decl String:newName[64];
strcopy(newName, sizeof(newName), name);
CStrToLower(newName);
SetTrieValue(CTrie, newName, color);
return true;
}
/**
* Removes color tags from a message
*
* @param message Message to remove tags from
* @param maxlen Maximum buffer length
* @noreturn
*/
stock CRemoveTags(String:message[], maxlen) {
CReplaceColorCodes(message, 0, true, maxlen);
}
/**
* Replies to a command with colors
*
* @param client Client to reply to
* @param message Message (formatting rules)
* @noreturn
*/
stock CReplyToCommand(client, const String:message[], any:...) {
decl String:buffer[MAX_BUFFER_LENGTH];
SetGlobalTransTarget(client);
VFormat(buffer, sizeof(buffer), message, 3);
if(GetCmdReplySource() == SM_REPLY_TO_CONSOLE) {
CRemoveTags(buffer, sizeof(buffer));
PrintToConsole(client, "%s", buffer);
} else {
CPrintToChat(client, "%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 CReplyToCommandEx(client, author, const String:message[], any:...) {
decl String:buffer[MAX_BUFFER_LENGTH];
SetGlobalTransTarget(client);
VFormat(buffer, sizeof(buffer), message, 4);
if(GetCmdReplySource() == SM_REPLY_TO_CONSOLE) {
CRemoveTags(buffer, sizeof(buffer));
PrintToConsole(client, "%s", buffer);
} else {
CPrintToChatEx(client, author, "%s", buffer);
}
}
/**
* Shows admin activity with colors
*
* @param client Client performing an action
* @param message Message (formatting rules)
* @noreturn
*/
stock CShowActivity(client, const String:message[], any:...) {
CCheckTrie();
if(client < 0 || client > MaxClients) {
ThrowError("Invalid client index %d", client);
}
if(client != 0 && !IsClientInGame(client)) {
ThrowError("Client %d is not in game", client);
}
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);
}
/**
* 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)
* @noreturn
*/
stock CShowActivityEx(client, const String:tag[], const String:message[], any:...) {
CCheckTrie();
if(client < 0 || client > MaxClients) {
ThrowError("Invalid client index %d", client);
}
if(client != 0 && !IsClientInGame(client)) {
ThrowError("Client %d is not in game", client);
}
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);
}
/**
* 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)
* @noreturn
*/
stock CShowActivity2(client, const String:tag[], const String:message[], any:...) {
CCheckTrie();
if(client < 0 || client > MaxClients) {
ThrowError("Invalid client index %d", client);
}
if(client != 0 && !IsClientInGame(client)) {
ThrowError("Client %d is not in game", client);
}
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);
}
/**
* Determines whether a color name exists
*
* @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);
}
/**
* Returns the hexadecimal representation of a client's team color (will NOT initialize the trie)
*
* @param client Client to get the team color for
* @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) {
if(client <= 0 || client > MaxClients) {
ThrowError("Invalid client index %i", client);
}
if(!IsClientInGame(client)) {
ThrowError("Client %i is not in game", client);
}
new value;
switch(GetClientTeam(client)) {
case 1: {
value = COLOR_GRAY;
}
case 2: {
value = COLOR_RED;
}
case 3: {
value = COLOR_BLUE;
}
default: {
value = COLOR_GREEN;
}
}
return value;
}
stock Handle:InitColorTrie() {
new 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
SetTrieValue(hTrie, "antiquewhite", 0xFAEBD7);
SetTrieValue(hTrie, "aqua", 0x00FFFF);
SetTrieValue(hTrie, "aquamarine", 0x7FFFD4);
SetTrieValue(hTrie, "arcana", 0xADE55C); // same as Arcana item rarity in Dota 2
SetTrieValue(hTrie, "axis", 0xFF4040); // same as Axis team in DoD:S
SetTrieValue(hTrie, "azure", 0x007FFF);
SetTrieValue(hTrie, "beige", 0xF5F5DC);
SetTrieValue(hTrie, "bisque", 0xFFE4C4);
SetTrieValue(hTrie, "black", 0x000000);
SetTrieValue(hTrie, "blanchedalmond", 0xFFEBCD);
SetTrieValue(hTrie, "blue", 0x99CCFF); // same as BLU/Counter-Terrorist team color
SetTrieValue(hTrie, "blueviolet", 0x8A2BE2);
SetTrieValue(hTrie, "brown", 0xA52A2A);
SetTrieValue(hTrie, "burlywood", 0xDEB887);
SetTrieValue(hTrie, "cadetblue", 0x5F9EA0);
SetTrieValue(hTrie, "chartreuse", 0x7FFF00);
SetTrieValue(hTrie, "chocolate", 0xD2691E);
SetTrieValue(hTrie, "collectors", 0xAA0000); // same as Collector's item quality in TF2
SetTrieValue(hTrie, "common", 0xB0C3D9); // same as Common item rarity in Dota 2
SetTrieValue(hTrie, "community", 0x70B04A); // same as Community item quality in TF2
SetTrieValue(hTrie, "coral", 0xFF7F50);
SetTrieValue(hTrie, "cornflowerblue", 0x6495ED);
SetTrieValue(hTrie, "cornsilk", 0xFFF8DC);
SetTrieValue(hTrie, "corrupted", 0xA32C2E); // same as Corrupted item quality in Dota 2
SetTrieValue(hTrie, "crimson", 0xDC143C);
SetTrieValue(hTrie, "cyan", 0x00FFFF);
SetTrieValue(hTrie, "darkblue", 0x00008B);
SetTrieValue(hTrie, "darkcyan", 0x008B8B);
SetTrieValue(hTrie, "darkgoldenrod", 0xB8860B);
SetTrieValue(hTrie, "darkgray", 0xA9A9A9);
SetTrieValue(hTrie, "darkgrey", 0xA9A9A9);
SetTrieValue(hTrie, "darkgreen", 0x006400);
SetTrieValue(hTrie, "darkkhaki", 0xBDB76B);
SetTrieValue(hTrie, "darkmagenta", 0x8B008B);
SetTrieValue(hTrie, "darkolivegreen", 0x556B2F);
SetTrieValue(hTrie, "darkorange", 0xFF8C00);
SetTrieValue(hTrie, "darkorchid", 0x9932CC);
SetTrieValue(hTrie, "darkred", 0x8B0000);
SetTrieValue(hTrie, "darksalmon", 0xE9967A);
SetTrieValue(hTrie, "darkseagreen", 0x8FBC8F);
SetTrieValue(hTrie, "darkslateblue", 0x483D8B);
SetTrieValue(hTrie, "darkslategray", 0x2F4F4F);
SetTrieValue(hTrie, "darkslategrey", 0x2F4F4F);
SetTrieValue(hTrie, "darkturquoise", 0x00CED1);
SetTrieValue(hTrie, "darkviolet", 0x9400D3);
SetTrieValue(hTrie, "deeppink", 0xFF1493);
SetTrieValue(hTrie, "deepskyblue", 0x00BFFF);
SetTrieValue(hTrie, "dimgray", 0x696969);
SetTrieValue(hTrie, "dimgrey", 0x696969);
SetTrieValue(hTrie, "dodgerblue", 0x1E90FF);
SetTrieValue(hTrie, "exalted", 0xCCCCCD); // same as Exalted item quality in Dota 2
SetTrieValue(hTrie, "firebrick", 0xB22222);
SetTrieValue(hTrie, "floralwhite", 0xFFFAF0);
SetTrieValue(hTrie, "forestgreen", 0x228B22);
SetTrieValue(hTrie, "frozen", 0x4983B3); // same as Frozen item quality in Dota 2
SetTrieValue(hTrie, "fuchsia", 0xFF00FF);
SetTrieValue(hTrie, "fullblue", 0x0000FF);
SetTrieValue(hTrie, "fullred", 0xFF0000);
SetTrieValue(hTrie, "gainsboro", 0xDCDCDC);
SetTrieValue(hTrie, "genuine", 0x4D7455); // same as Genuine item quality in TF2
SetTrieValue(hTrie, "ghostwhite", 0xF8F8FF);
SetTrieValue(hTrie, "gold", 0xFFD700);
SetTrieValue(hTrie, "goldenrod", 0xDAA520);
SetTrieValue(hTrie, "gray", 0xCCCCCC); // same as spectator team color
SetTrieValue(hTrie, "grey", 0xCCCCCC);
SetTrieValue(hTrie, "green", 0x3EFF3E);
SetTrieValue(hTrie, "greenyellow", 0xADFF2F);
SetTrieValue(hTrie, "haunted", 0x38F3AB); // same as Haunted item quality in TF2
SetTrieValue(hTrie, "honeydew", 0xF0FFF0);
SetTrieValue(hTrie, "hotpink", 0xFF69B4);
SetTrieValue(hTrie, "immortal", 0xE4AE33); // same as Immortal item rarity in Dota 2
SetTrieValue(hTrie, "indianred", 0xCD5C5C);
SetTrieValue(hTrie, "indigo", 0x4B0082);
SetTrieValue(hTrie, "ivory", 0xFFFFF0);
SetTrieValue(hTrie, "khaki", 0xF0E68C);
SetTrieValue(hTrie, "lavender", 0xE6E6FA);
SetTrieValue(hTrie, "lavenderblush", 0xFFF0F5);
SetTrieValue(hTrie, "lawngreen", 0x7CFC00);
SetTrieValue(hTrie, "legendary", 0xD32CE6); // same as Legendary item rarity in Dota 2
SetTrieValue(hTrie, "lemonchiffon", 0xFFFACD);
SetTrieValue(hTrie, "lightblue", 0xADD8E6);
SetTrieValue(hTrie, "lightcoral", 0xF08080);
SetTrieValue(hTrie, "lightcyan", 0xE0FFFF);
SetTrieValue(hTrie, "lightgoldenrodyellow", 0xFAFAD2);
SetTrieValue(hTrie, "lightgray", 0xD3D3D3);
SetTrieValue(hTrie, "lightgrey", 0xD3D3D3);
SetTrieValue(hTrie, "lightgreen", 0x99FF99);
SetTrieValue(hTrie, "lightpink", 0xFFB6C1);
SetTrieValue(hTrie, "lightsalmon", 0xFFA07A);
SetTrieValue(hTrie, "lightseagreen", 0x20B2AA);
SetTrieValue(hTrie, "lightskyblue", 0x87CEFA);
SetTrieValue(hTrie, "lightslategray", 0x778899);
SetTrieValue(hTrie, "lightslategrey", 0x778899);
SetTrieValue(hTrie, "lightsteelblue", 0xB0C4DE);
SetTrieValue(hTrie, "lightyellow", 0xFFFFE0);
SetTrieValue(hTrie, "lime", 0x00FF00);
SetTrieValue(hTrie, "limegreen", 0x32CD32);
SetTrieValue(hTrie, "linen", 0xFAF0E6);
SetTrieValue(hTrie, "magenta", 0xFF00FF);
SetTrieValue(hTrie, "maroon", 0x800000);
SetTrieValue(hTrie, "mediumaquamarine", 0x66CDAA);
SetTrieValue(hTrie, "mediumblue", 0x0000CD);
SetTrieValue(hTrie, "mediumorchid", 0xBA55D3);
SetTrieValue(hTrie, "mediumpurple", 0x9370D8);
SetTrieValue(hTrie, "mediumseagreen", 0x3CB371);
SetTrieValue(hTrie, "mediumslateblue", 0x7B68EE);
SetTrieValue(hTrie, "mediumspringgreen", 0x00FA9A);
SetTrieValue(hTrie, "mediumturquoise", 0x48D1CC);
SetTrieValue(hTrie, "mediumvioletred", 0xC71585);
SetTrieValue(hTrie, "midnightblue", 0x191970);
SetTrieValue(hTrie, "mintcream", 0xF5FFFA);
SetTrieValue(hTrie, "mistyrose", 0xFFE4E1);
SetTrieValue(hTrie, "moccasin", 0xFFE4B5);
SetTrieValue(hTrie, "mythical", 0x8847FF); // same as Mythical item rarity in Dota 2
SetTrieValue(hTrie, "navajowhite", 0xFFDEAD);
SetTrieValue(hTrie, "navy", 0x000080);
SetTrieValue(hTrie, "normal", 0xB2B2B2); // same as Normal item quality in TF2
SetTrieValue(hTrie, "oldlace", 0xFDF5E6);
SetTrieValue(hTrie, "olive", 0x9EC34F);
SetTrieValue(hTrie, "olivedrab", 0x6B8E23);
SetTrieValue(hTrie, "orange", 0xFFA500);
SetTrieValue(hTrie, "orangered", 0xFF4500);
SetTrieValue(hTrie, "orchid", 0xDA70D6);
SetTrieValue(hTrie, "palegoldenrod", 0xEEE8AA);
SetTrieValue(hTrie, "palegreen", 0x98FB98);
SetTrieValue(hTrie, "paleturquoise", 0xAFEEEE);
SetTrieValue(hTrie, "palevioletred", 0xD87093);
SetTrieValue(hTrie, "papayawhip", 0xFFEFD5);
SetTrieValue(hTrie, "peachpuff", 0xFFDAB9);
SetTrieValue(hTrie, "peru", 0xCD853F);
SetTrieValue(hTrie, "pink", 0xFFC0CB);
SetTrieValue(hTrie, "plum", 0xDDA0DD);
SetTrieValue(hTrie, "powderblue", 0xB0E0E6);
SetTrieValue(hTrie, "purple", 0x800080);
SetTrieValue(hTrie, "rare", 0x4B69FF); // same as Rare item rarity in Dota 2
SetTrieValue(hTrie, "red", 0xFF4040); // same as RED/Terrorist team color
SetTrieValue(hTrie, "rosybrown", 0xBC8F8F);
SetTrieValue(hTrie, "royalblue", 0x4169E1);
SetTrieValue(hTrie, "saddlebrown", 0x8B4513);
SetTrieValue(hTrie, "salmon", 0xFA8072);
SetTrieValue(hTrie, "sandybrown", 0xF4A460);
SetTrieValue(hTrie, "seagreen", 0x2E8B57);
SetTrieValue(hTrie, "seashell", 0xFFF5EE);
SetTrieValue(hTrie, "selfmade", 0x70B04A); // same as Self-Made item quality in TF2
SetTrieValue(hTrie, "sienna", 0xA0522D);
SetTrieValue(hTrie, "silver", 0xC0C0C0);
SetTrieValue(hTrie, "skyblue", 0x87CEEB);
SetTrieValue(hTrie, "slateblue", 0x6A5ACD);
SetTrieValue(hTrie, "slategray", 0x708090);
SetTrieValue(hTrie, "slategrey", 0x708090);
SetTrieValue(hTrie, "snow", 0xFFFAFA);
SetTrieValue(hTrie, "springgreen", 0x00FF7F);
SetTrieValue(hTrie, "steelblue", 0x4682B4);
SetTrieValue(hTrie, "strange", 0xCF6A32); // same as Strange item quality in TF2
SetTrieValue(hTrie, "tan", 0xD2B48C);
SetTrieValue(hTrie, "teal", 0x008080);
SetTrieValue(hTrie, "thistle", 0xD8BFD8);
SetTrieValue(hTrie, "tomato", 0xFF6347);
SetTrieValue(hTrie, "turquoise", 0x40E0D0);
SetTrieValue(hTrie, "uncommon", 0xB0C3D9); // same as Uncommon item rarity in Dota 2
SetTrieValue(hTrie, "unique", 0xFFD700); // same as Unique item quality in TF2
SetTrieValue(hTrie, "unusual", 0x8650AC); // same as Unusual item quality in TF2
SetTrieValue(hTrie, "valve", 0xA50F79); // same as Valve item quality in TF2
SetTrieValue(hTrie, "vintage", 0x476291); // same as Vintage item quality in TF2
SetTrieValue(hTrie, "violet", 0xEE82EE);
SetTrieValue(hTrie, "wheat", 0xF5DEB3);
SetTrieValue(hTrie, "white", 0xFFFFFF);
SetTrieValue(hTrie, "whitesmoke", 0xF5F5F5);
SetTrieValue(hTrie, "yellow", 0xFFFF00);
SetTrieValue(hTrie, "yellowgreen", 0x9ACD32);
return hTrie;
}

View File

@ -1,34 +0,0 @@
#if defined _sourcebans_included
#endinput
#endif
#define _sourcebans_included
public SharedPlugin:__pl_sourcebans =
{
name = "SourceBans",
file = "sourcebans.smx",
#if defined REQUIRE_PLUGIN
required = 1
#else
required = 0
#endif
};
#if !defined REQUIRE_PLUGIN
public __pl_sourcebans_SetNTVOptional()
{
MarkNativeAsOptional("SBBanPlayer");
MarkNativeAsOptional("SBCheckBans");
}
#endif
/*********************************************************
* Ban Player from server
*
* @param client The client index of the admin who is banning the client
* @param target The client index of the player to ban
* @param time The time to ban the player for (in minutes, 0 = permanent)
* @param reason The reason to ban the player from the server
* @noreturn
*********************************************************/
native SBBanPlayer(client, target, time, String:reason[]);

File diff suppressed because it is too large Load Diff

View File

@ -1,90 +0,0 @@
#pragma semicolon 1
#include <sourcemod>
#include <zombiereloaded>
#define PLUGIN_NAME "ZR Repeat Kill Detector"
#define PLUGIN_VERSION "1.0.3"
new Handle:g_hCvar_RepeatKillDetectThreshold = INVALID_HANDLE;
new Float:g_fRepeatKillDetectThreshold;
new Handle:g_hRespawnDelay = INVALID_HANDLE;
new Float:g_fDeathTime[MAXPLAYERS+1];
new bool:g_bBlockRespawn = false;
public Plugin:myinfo =
{
name = PLUGIN_NAME,
author = "GoD-Tony + BotoX",
description = "Disables respawning on maps with repeat killers",
version = PLUGIN_VERSION,
url = "http://www.sourcemod.net/"
};
public OnAllPluginsLoaded()
{
if((g_hRespawnDelay = FindConVar("zr_respawn_delay")) == INVALID_HANDLE)
SetFailState("Failed to find zr_respawn_delay cvar.");
g_hCvar_RepeatKillDetectThreshold = CreateConVar("zr_repeatkill_threshold", "1.0", "Zombie Reloaded Repeat Kill Detector Threshold", 0, true, 0.0, true, 10.0);
g_fRepeatKillDetectThreshold = GetConVarFloat(g_hCvar_RepeatKillDetectThreshold);
HookConVarChange(g_hCvar_RepeatKillDetectThreshold, OnConVarChanged);
CreateConVar("zr_repeatkill_version", PLUGIN_VERSION, PLUGIN_NAME, FCVAR_NOTIFY|FCVAR_DONTRECORD);
HookEvent("round_start", Event_RoundStart, EventHookMode_PostNoCopy);
HookEvent("player_death", Event_PlayerDeath, EventHookMode_Post);
AutoExecConfig(true, "plugin.RepeatKillDetector");
}
public OnConVarChanged(Handle:cvar, const String:oldVal[], const String:newVal[])
{
if(cvar == g_hCvar_RepeatKillDetectThreshold)
{
g_fRepeatKillDetectThreshold = GetConVarFloat(g_hCvar_RepeatKillDetectThreshold);
}
}
public OnClientDisconnect(client)
{
g_fDeathTime[client] = 0.0;
}
public Event_RoundStart(Handle:event, const String:name[], bool:dontBroadcast)
{
g_bBlockRespawn = false;
}
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
if(g_bBlockRespawn)
return;
decl String:weapon[32];
GetEventString(event, "weapon", weapon, sizeof(weapon));
new victim = GetClientOfUserId(GetEventInt(event, "userid"));
new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
if(victim && !attacker && StrEqual(weapon, "trigger_hurt"))
{
new Float:fGameTime = GetGameTime();
if(fGameTime - g_fDeathTime[victim] - GetConVarFloat(g_hRespawnDelay) < g_fRepeatKillDetectThreshold)
{
PrintToChatAll("\x04[ZR]\x01 Repeat killer detected. Disabling respawn for this round.");
g_bBlockRespawn = true;
}
g_fDeathTime[victim] = fGameTime;
}
}
public Action:ZR_OnClientRespawn(&client, &ZR_RespawnCondition:condition)
{
if(g_bBlockRespawn)
return Plugin_Handled;
return Plugin_Continue;
}

View File

@ -1,110 +0,0 @@
/* Zombie:Reloaded additional native tools
*
* Copyright © 2013, FrozDark
*
* This file is provided as is (no warranties).
*
*/
/**
* Gets client class section name in the config
*
* @param client Client index.
* @param buffer Buffer to store the class section name in.
* @param maxlen Max length to store.
*
* @return Number of bytes written to the buffer.
* @error If the client is not in game or invalid.
*/
native ZRT_GetClientClassSectionName(client, String:buffer[], maxlen);
/**
* Gets attribute string of the player's class
*
* @param client Client index.
* @param attrib Attribute name.
* @param buffer Buffer to store the attribute string in.
* @param maxlen Max length to store.
* @param defvalue Optional default value to use if the attribute is not found.
*
* @return Number of bytes written to the buffer.
* @error If the client is not in game or invalid.
*/
native ZRT_GetClientAttributeString(client, const String:attrib[], String:buffer[], maxlen, const String:defvalue[] = "");
/**
* Gets attribute numeric value of the player's class
*
* @param client Client index.
* @param attrib Attribute name.
* @param defvalue Optional default value to use if the attribute is not found.
*
* @return Retrieves the numeric value.
* @error If the client is not in game or invalid.
*/
native ZRT_GetClientAttributeValue(client, const String:attrib[], defvalue = 0);
/**
* Gets attribute floating value of the player's class
*
* @param client Client index.
* @param attrib Attribute name.
* @param defvalue Optional default value to use if the attribute is not found.
*
* @return Retrieves the floating value.
* @error If the client is not in game or invalid.
*/
native Float:ZRT_GetClientAttributeValueFloat(client, const String:attrib[], Float:defvalue = 0.0);
/**
* Whether the player has attribute
*
* @param client Client index.
* @param attrib Attribute name.
*
* @return True on success, false otherwise.
* @error If the client is not in game or invalid.
*/
native bool:ZRT_PlayerHasAttribute(client, const String:attrib[]);
/**
* Whether the round is active
*
* @noparams
*
* @return True on round active, false otherwise
* @noerror
*/
native bool:ZRT_IsRoundActive();
/*----------------------------------
***********************************
** Don't edit below this line! **
***********************************
-----------------------------------*/
public SharedPlugin:__pl_zr_tools =
{
name = "zr_tools",
file = "zr_tools.smx",
#if defined REQUIRE_PLUGIN
required = 1,
#else
required = 0,
#endif
};
#if !defined REQUIRE_PLUGIN
public __pl_zr_tools_SetNTVOptional()
{
MarkNativeAsOptional("ZRT_GetClientClassSectionName");
MarkNativeAsOptional("ZRT_GetClientAttributeString");
MarkNativeAsOptional("ZRT_GetClientAttributeValue");
MarkNativeAsOptional("ZRT_GetClientAttributeValueFloat");
MarkNativeAsOptional("ZRT_PlayerHasAttribute");
MarkNativeAsOptional("ZRT_IsRoundActive");
}
#endif

View File

@ -1,271 +0,0 @@
#pragma semicolon 1
#include <sourcemod>
#include <zombiereloaded>
#define PLUGIN_VERSION "1.6.1"
new Handle:kv;
new Handle:hPlayerClasses, String:sClassPath[PLATFORM_MAX_PATH] = "configs/zr/playerclasses.txt";
new bool:g_RoundEnd = false;
public Plugin:myinfo =
{
name = "[ZR] Tools",
author = "FrozDark",
description = "Useful tools for Zombie:Reloaded",
version = PLUGIN_VERSION,
url = "www.hlmod.ru"
}
public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
{
CreateNative("ZRT_GetClientClassSectionName", Native_GetClientClassSectionName);
CreateNative("ZRT_GetClientAttributeString", Native_GetClientAttributeString);
CreateNative("ZRT_GetClientAttributeValue", Native_GetClientAttributeValue);
CreateNative("ZRT_GetClientAttributeValueFloat", Native_GetClientAttributeValueFloat);
CreateNative("ZRT_PlayerHasAttribute", Native_PlayerHasAttribute);
CreateNative("ZRT_IsRoundActive", Native_IsRoundActive);
RegPluginLibrary("zr_tools");
return APLRes_Success;
}
public OnPluginStart()
{
CreateConVar("zr_tools_version", PLUGIN_VERSION, "Zombie:Reloaded tools plugin version", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY|FCVAR_CHEAT|FCVAR_DONTRECORD);
RegAdminCmd("zr_tools_reload", Command_Reload, ADMFLAG_ROOT);
HookEvent("round_start", Event_RoundStart);
HookEvent("round_end", Event_RoundEnd);
}
public OnAllPluginsLoaded()
{
if (hPlayerClasses != INVALID_HANDLE)
{
UnhookConVarChange(hPlayerClasses, OnClassPathChange);
CloseHandle(hPlayerClasses);
}
if ((hPlayerClasses = FindConVar("zr_config_path_playerclasses")) == INVALID_HANDLE)
{
SetFailState("Zombie:Reloaded is not running on this server");
}
HookConVarChange(hPlayerClasses, OnClassPathChange);
}
public OnClassPathChange(Handle:convar, const String:oldValue[], const String:newValue[])
{
strcopy(sClassPath, sizeof(sClassPath), newValue);
OnConfigsExecuted();
}
public OnConfigsExecuted()
{
if (kv != INVALID_HANDLE)
{
CloseHandle(kv);
}
kv = CreateKeyValues("classes");
decl String:buffer[PLATFORM_MAX_PATH];
BuildPath(Path_SM, buffer, sizeof(buffer), "%s", sClassPath);
if (!FileToKeyValues(kv, buffer))
{
SetFailState("Class data file \"%s\" not found", buffer);
}
}
public Event_RoundStart(Handle:event, const String:name[], bool:dontBroadcast)
{
g_RoundEnd = false;
}
public Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
{
g_RoundEnd = true;
}
public Action:Command_Reload(client, args)
{
OnConfigsExecuted();
return Plugin_Handled;
}
public Native_IsRoundActive(Handle:plugin, numParams)
{
return !g_RoundEnd;
}
public Native_PlayerHasAttribute(Handle:plugin, numParams)
{
new client = GetNativeCell(1);
ValidateClient(client);
decl String:attrib[32];
GetNativeString(2, attrib, sizeof(attrib));
decl String:className[64], String:buffer[64];
ZR_GetClassDisplayName(client, className, sizeof(className), ZR_CLASS_CACHE_PLAYER);
new bool:result = false;
if (KvGotoFirstSubKey(kv))
{
do
{
KvGetString(kv, "name", buffer, sizeof(buffer));
if (StrEqual(buffer, className, false))
{
KvGetString(kv, attrib, buffer, sizeof(buffer), "0");
result = bool:(StrContains("yes|1|true", buffer, false) != -1);
break;
}
} while (KvGotoNextKey(kv));
}
KvRewind(kv);
return result;
}
public Native_GetClientAttributeString(Handle:plugin, numParams)
{
new client = GetNativeCell(1);
ValidateClient(client);
decl String:attrib[32];
GetNativeString(2, attrib, sizeof(attrib));
decl String:className[64], String:buffer[PLATFORM_MAX_PATH];
buffer[0] = '\0';
ZR_GetClassDisplayName(client, className, sizeof(className), ZR_CLASS_CACHE_PLAYER);
new bytes;
if (KvGotoFirstSubKey(kv))
{
do
{
KvGetString(kv, "name", buffer, sizeof(buffer));
if (StrEqual(buffer, className, false))
{
KvGetString(kv, attrib, buffer, sizeof(buffer), "");
SetNativeString(3, buffer, GetNativeCell(4), true, bytes);
break;
}
} while (KvGotoNextKey(kv));
}
KvRewind(kv);
if (!buffer[0])
{
GetNativeString(5, buffer, sizeof(buffer));
SetNativeString(3, buffer, GetNativeCell(4), true, bytes);
}
return bytes;
}
public Native_GetClientAttributeValue(Handle:plugin, numParams)
{
new client = GetNativeCell(1);
ValidateClient(client);
decl String:attrib[32];
GetNativeString(2, attrib, sizeof(attrib));
decl String:className[64], String:buffer[PLATFORM_MAX_PATH];
ZR_GetClassDisplayName(client, className, sizeof(className), ZR_CLASS_CACHE_PLAYER);
new result = -1;
if (KvGotoFirstSubKey(kv))
{
do
{
KvGetString(kv, "name", buffer, sizeof(buffer));
if (StrEqual(buffer, className, false))
{
result = KvGetNum(kv, attrib, GetNativeCell(3));
break;
}
} while (KvGotoNextKey(kv));
}
KvRewind(kv);
return result;
}
public Native_GetClientAttributeValueFloat(Handle:plugin, numParams)
{
new client = GetNativeCell(1);
ValidateClient(client);
decl String:attrib[32];
GetNativeString(2, attrib, sizeof(attrib));
decl String:className[64], String:buffer[PLATFORM_MAX_PATH];
ZR_GetClassDisplayName(client, className, sizeof(className), ZR_CLASS_CACHE_PLAYER);
new Float:result = -1.0;
if (KvGotoFirstSubKey(kv))
{
do
{
KvGetString(kv, "name", buffer, sizeof(buffer));
if (StrEqual(buffer, className, false))
{
result = KvGetFloat(kv, attrib, Float:GetNativeCell(3));
break;
}
} while (KvGotoNextKey(kv));
}
KvRewind(kv);
return _:result;
}
public Native_GetClientClassSectionName(Handle:plugin, numParams)
{
new client = GetNativeCell(1);
ValidateClient(client);
decl String:className[64], String:buffer[64];
ZR_GetClassDisplayName(client, className, sizeof(className), ZR_CLASS_CACHE_PLAYER);
new bytes;
if (KvGotoFirstSubKey(kv))
{
do
{
KvGetString(kv, "name", buffer, sizeof(buffer));
if (StrEqual(buffer, className, false))
{
KvGetSectionName(kv, buffer, sizeof(buffer));
SetNativeString(2, buffer, GetNativeCell(3), true, bytes);
break;
}
} while (KvGotoNextKey(kv));
}
KvRewind(kv);
return bytes;
}
ValidateClient(client)
{
if (client < 1 || client > MaxClients)
{
ThrowNativeError(SP_ERROR_INDEX, "Client index %i is invalid", client);
return;
}
else if (!IsClientInGame(client))
{
ThrowNativeError(SP_ERROR_NOT_FOUND, "Client %i is not in game", client);
return;
}
}