mirror of
https://github.com/shavitush/bhoptimer.git
synced 2025-12-07 10:28:26 +00:00
Chat plugin rewrite. (#436)
This commit is contained in:
parent
066f60c057
commit
8ff72fed0a
@ -17,6 +17,12 @@ Zones are trigger based and are very lightweight.
|
|||||||
|
|
||||||
The zones plugin includes some less common features such as: Multiple tracks (main/bonus), zone editing (after setup), snapping zones to walls/corners/grid, zone setup using the cursor's position, configurable sprite/colors for zone types, zone tracks (main/bonus - can be extended), manual adjustments of coordinates before confirmations, teleport zones, glitch zones, no-limit zones (for styles like 400-velocity), flat/3D boxes for zone rendering, an API and more.
|
The zones plugin includes some less common features such as: Multiple tracks (main/bonus), zone editing (after setup), snapping zones to walls/corners/grid, zone setup using the cursor's position, configurable sprite/colors for zone types, zone tracks (main/bonus - can be extended), manual adjustments of coordinates before confirmations, teleport zones, glitch zones, no-limit zones (for styles like 400-velocity), flat/3D boxes for zone rendering, an API and more.
|
||||||
|
|
||||||
|
#### shavit-chat
|
||||||
|
The chat plugin manipulates chat messages sent by players.
|
||||||
|
It includes custom chat names, tags, colors and all can be defined by the players/admins.
|
||||||
|
Admins need the chat flag, or the "shavit_chat" override (good for a donator perk).
|
||||||
|
There's a user-friendly command named !cchelp so the users can easily understand what's going on.
|
||||||
|
|
||||||
#### shavit-hud
|
#### shavit-hud
|
||||||
The HUD plugin is `bhoptimer`'s OSD frontend.
|
The HUD plugin is `bhoptimer`'s OSD frontend.
|
||||||
It shows most (if not all) of the information that the player needs to see.
|
It shows most (if not all) of the information that the player needs to see.
|
||||||
|
|||||||
@ -22,6 +22,7 @@ Including a records system, map zones (start/end marks etc), bonuses, HUD with u
|
|||||||
* [DHooks](http://users.alliedmods.net/~drifter/builds/dhooks/2.0/) - required for 250/260 runspeed for all weapons.
|
* [DHooks](http://users.alliedmods.net/~drifter/builds/dhooks/2.0/) - required for 250/260 runspeed for all weapons.
|
||||||
* [Bunnyhop Statistics](https://forums.alliedmods.net/showthread.php?t=286135) - to show amount of scrolls for non-auto styles in the key display. CS:S only!
|
* [Bunnyhop Statistics](https://forums.alliedmods.net/showthread.php?t=286135) - to show amount of scrolls for non-auto styles in the key display. CS:S only!
|
||||||
* [SteamWorks](https://forums.alliedmods.net/showthread.php?t=229556) - for the `{serverip}` advertisement variable.
|
* [SteamWorks](https://forums.alliedmods.net/showthread.php?t=229556) - for the `{serverip}` advertisement variable.
|
||||||
|
* [Chat-Processor](https://github.com/Drixevel/Chat-Processor) - if you're enabling the `shavit-chat` module.
|
||||||
|
|
||||||
# Installation:
|
# Installation:
|
||||||
1. If you want to use MySQL (**VERY RECOMMENDED**) add a database entry in addons/sourcemod/configs/databases.cfg, call it "shavit". The plugin also supports the "sqlite" driver. You can also skip this step and not modify databases.cfg.
|
1. If you want to use MySQL (**VERY RECOMMENDED**) add a database entry in addons/sourcemod/configs/databases.cfg, call it "shavit". The plugin also supports the "sqlite" driver. You can also skip this step and not modify databases.cfg.
|
||||||
|
|||||||
@ -1,110 +0,0 @@
|
|||||||
// Use SteamID3 for a value if you want a per-client setting.
|
|
||||||
// "Custom" is for per-client settings.
|
|
||||||
// "Ranks" is for rank range settings. It is limited to 64 entries and the way you sort this file will be also sorted in-game when a player uses /ranks.
|
|
||||||
//
|
|
||||||
// Available settings:
|
|
||||||
// "rank_from" - rank range to start with
|
|
||||||
// "rank_to" - rank range to end with; you can use "infinity" if it's for every player below "rank_from".
|
|
||||||
//
|
|
||||||
// "prefix" - prefix before the name (don't add a space after it)
|
|
||||||
// "name" - custom name appearance (color from prefix will be applied here too)
|
|
||||||
// "message" - the message itself
|
|
||||||
// "clantag" - custom clan tag
|
|
||||||
//
|
|
||||||
// Global variables:
|
|
||||||
// {default} - default color
|
|
||||||
// {team} - team color
|
|
||||||
// {green} - green color
|
|
||||||
// {name} - player name
|
|
||||||
// {clan} - clan tag
|
|
||||||
// {message} - message text
|
|
||||||
//
|
|
||||||
// If you use variables that aren't compatible with the game, it might break some stuff.
|
|
||||||
// The default config will work with both CS:S and CS:GO, you can modify it for your needs.
|
|
||||||
// Use `sm_reloadchat` in your server to reload this config.
|
|
||||||
//
|
|
||||||
// For CS:S, you have the following variables available: (NOTE: The format for colors is like HTML. RRGGBBAA)
|
|
||||||
// {RGB} - like \x07, usage: "{RGB}FF0000" for red
|
|
||||||
// {RGBA} - like \x08, usage: "{RGBA}FF0000FE" for 254 alpha red
|
|
||||||
// {RGBX} - random rgb color
|
|
||||||
// {RGBAX} - random rgba color
|
|
||||||
//
|
|
||||||
// CS:GO colors:
|
|
||||||
// {team} will become purple for spectators
|
|
||||||
// {blue}
|
|
||||||
// {bluegrey}
|
|
||||||
// {darkblue}
|
|
||||||
// {darkred}
|
|
||||||
// {gold}
|
|
||||||
// {grey}
|
|
||||||
// {grey2}
|
|
||||||
// {lightgreen}
|
|
||||||
// {lightred}
|
|
||||||
// {lime}
|
|
||||||
// {orchid}
|
|
||||||
// {yellow}
|
|
||||||
//
|
|
||||||
"Chat"
|
|
||||||
{
|
|
||||||
"[U:1:204506329]" // my steamid for example, use steamid3
|
|
||||||
{
|
|
||||||
"prefix" "{green}/dev/"
|
|
||||||
"name" "{default}{team}{clan}{name}"
|
|
||||||
"clantag" "shave"
|
|
||||||
}
|
|
||||||
|
|
||||||
"-1" // lookup is due, shouldn't happen unless there's some error!
|
|
||||||
{
|
|
||||||
"rank_from" "-1"
|
|
||||||
"rank_to" "-1"
|
|
||||||
|
|
||||||
"prefix" ""
|
|
||||||
"name" "{team}{name}"
|
|
||||||
"message" "{message}"
|
|
||||||
}
|
|
||||||
|
|
||||||
"0" // unranked
|
|
||||||
{
|
|
||||||
"rank_from" "0"
|
|
||||||
"rank_to" "0"
|
|
||||||
|
|
||||||
"prefix" "[Unranked]"
|
|
||||||
"name" "{team}{name}"
|
|
||||||
"message" "{message}"
|
|
||||||
}
|
|
||||||
|
|
||||||
"1"
|
|
||||||
{
|
|
||||||
"rank_from" "1"
|
|
||||||
"rank_to" "1"
|
|
||||||
|
|
||||||
"prefix" "{green}ONE TRUE GOD"
|
|
||||||
"name" "{clan}{team}{name}"
|
|
||||||
}
|
|
||||||
|
|
||||||
"2"
|
|
||||||
{
|
|
||||||
"rank_from" "2"
|
|
||||||
"rank_to" "2"
|
|
||||||
|
|
||||||
"prefix" "LEGENDARY"
|
|
||||||
"name" "{name}"
|
|
||||||
}
|
|
||||||
|
|
||||||
"3"
|
|
||||||
{
|
|
||||||
"rank_from" "3"
|
|
||||||
"rank_to" "3"
|
|
||||||
|
|
||||||
"prefix" "HERO"
|
|
||||||
"name" "{team}{name}"
|
|
||||||
}
|
|
||||||
|
|
||||||
"4"
|
|
||||||
{
|
|
||||||
"rank_from" "4"
|
|
||||||
"rank_to" "infinity"
|
|
||||||
|
|
||||||
"prefix" "scrub!"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,857 +0,0 @@
|
|||||||
/*
|
|
||||||
* shavit's Timer - Chat
|
|
||||||
* by: shavit
|
|
||||||
*
|
|
||||||
* This file is part of shavit's Timer.
|
|
||||||
*
|
|
||||||
* 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/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <cstrike>
|
|
||||||
|
|
||||||
#undef REQUIRE_PLUGIN
|
|
||||||
#include <basecomm>
|
|
||||||
#include <rtler>
|
|
||||||
#include <chat-processor>
|
|
||||||
#define USES_CHAT_COLORS
|
|
||||||
#include <shavit>
|
|
||||||
|
|
||||||
#pragma newdecls required
|
|
||||||
#pragma semicolon 1
|
|
||||||
#pragma dynamic 131072
|
|
||||||
|
|
||||||
// cache
|
|
||||||
float gF_LastMessage[MAXPLAYERS+1];
|
|
||||||
|
|
||||||
char gS_Cached_Prefix[MAXPLAYERS+1][32];
|
|
||||||
char gS_Cached_Name[MAXPLAYERS+1][MAX_NAME_LENGTH*2];
|
|
||||||
char gS_Cached_Message[MAXPLAYERS+1][255];
|
|
||||||
char gS_Cached_ClanTag[MAXPLAYERS+1][32];
|
|
||||||
|
|
||||||
StringMap gSM_Custom_Prefix = null;
|
|
||||||
StringMap gSM_Custom_Name = null;
|
|
||||||
StringMap gSM_Custom_Message = null;
|
|
||||||
StringMap gSM_Custom_ClanTag = null;
|
|
||||||
|
|
||||||
int gI_TotalChatRanks = 0;
|
|
||||||
int gI_UnassignedTitle = -1;
|
|
||||||
int gI_UnrankedTitle = -1;
|
|
||||||
|
|
||||||
Dynamic gD_ChatRanks[64]; // limited to 64 chat ranks right now, i really don't think there's a need for more.
|
|
||||||
|
|
||||||
// modules
|
|
||||||
bool gB_BaseComm = false;
|
|
||||||
bool gB_RTLer = false;
|
|
||||||
bool gB_ChatProcessor = false;
|
|
||||||
|
|
||||||
// game-related
|
|
||||||
EngineVersion gEV_Type = Engine_Unknown;
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "[shavit] Chat",
|
|
||||||
author = "shavit",
|
|
||||||
description = "Chat handler for shavit's bhop timer.",
|
|
||||||
version = SHAVIT_VERSION,
|
|
||||||
url = "https://github.com/shavitush/bhoptimer"
|
|
||||||
}
|
|
||||||
|
|
||||||
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
|
|
||||||
{
|
|
||||||
// natives
|
|
||||||
CreateNative("Shavit_FormatChat", Native_FormatChat);
|
|
||||||
|
|
||||||
// registers library, check "bool LibraryExists(const char[] name)" in order to use with other plugins
|
|
||||||
RegPluginLibrary("shavit-chat");
|
|
||||||
|
|
||||||
return APLRes_Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnAllPluginsLoaded()
|
|
||||||
{
|
|
||||||
if(!LibraryExists("shavit-rankings"))
|
|
||||||
{
|
|
||||||
SetFailState("shavit-rankings is required for the plugin to work.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// modules
|
|
||||||
gB_BaseComm = LibraryExists("basecomm");
|
|
||||||
gB_RTLer = LibraryExists("rtler");
|
|
||||||
gB_ChatProcessor = LibraryExists("chat-processor");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
LoadTranslations("shavit-chat.phrases");
|
|
||||||
|
|
||||||
// game specific
|
|
||||||
gEV_Type = GetEngineVersion();
|
|
||||||
|
|
||||||
// commands
|
|
||||||
RegAdminCmd("sm_reloadchat", Command_ReloadChat, ADMFLAG_ROOT, "Reload chat config.");
|
|
||||||
|
|
||||||
RegConsoleCmd("sm_chatranks", Command_ChatRanks, "Shows a list of all the possible chat ranks.");
|
|
||||||
RegConsoleCmd("sm_ranks", Command_ChatRanks, "Shows a list of all the possible chat ranks. Alias for sm_chatranks.");
|
|
||||||
|
|
||||||
// hooks
|
|
||||||
HookEvent("player_spawn", Player_Spawn);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPluginEnd()
|
|
||||||
{
|
|
||||||
ResetCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnMapStart()
|
|
||||||
{
|
|
||||||
LoadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientPutInServer(int client)
|
|
||||||
{
|
|
||||||
gF_LastMessage[client] = GetEngineTime();
|
|
||||||
|
|
||||||
if(gI_TotalChatRanks >= 1 && gD_ChatRanks[0].IsValid)
|
|
||||||
{
|
|
||||||
gD_ChatRanks[0].GetString("prefix", gS_Cached_Prefix[client], 32);
|
|
||||||
gD_ChatRanks[0].GetString("name", gS_Cached_Name[client], MAX_NAME_LENGTH*2);
|
|
||||||
gD_ChatRanks[0].GetString("message", gS_Cached_Message[client], 255);
|
|
||||||
gD_ChatRanks[0].GetString("clantag", gS_Cached_ClanTag[client], 32);
|
|
||||||
|
|
||||||
UpdateClanTag(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientSettingsChanged(int client)
|
|
||||||
{
|
|
||||||
UpdateClanTag(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateClanTag(int client)
|
|
||||||
{
|
|
||||||
if(IsValidClient(client) && strlen(gS_Cached_ClanTag[client]) > 0)
|
|
||||||
{
|
|
||||||
CS_SetClientClanTag(client, gS_Cached_ClanTag[client]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientAuthorized(int client, const char[] auth)
|
|
||||||
{
|
|
||||||
LoadChatCache(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnLibraryAdded(const char[] name)
|
|
||||||
{
|
|
||||||
if(StrEqual(name, "basecomm"))
|
|
||||||
{
|
|
||||||
gB_BaseComm = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(StrEqual(name, "rtler"))
|
|
||||||
{
|
|
||||||
gB_RTLer = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(StrEqual(name, "chat-processor"))
|
|
||||||
{
|
|
||||||
gB_ChatProcessor = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnLibraryRemoved(const char[] name)
|
|
||||||
{
|
|
||||||
if(StrEqual(name, "basecomm"))
|
|
||||||
{
|
|
||||||
gB_BaseComm = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(StrEqual(name, "rtler"))
|
|
||||||
{
|
|
||||||
gB_RTLer = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(StrEqual(name, "chat-processor"))
|
|
||||||
{
|
|
||||||
gB_ChatProcessor = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Shavit_OnRankUpdated(int client)
|
|
||||||
{
|
|
||||||
LoadChatCache(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadChatCache(int client)
|
|
||||||
{
|
|
||||||
// assign rank properties
|
|
||||||
int iRank = Shavit_GetRank(client);
|
|
||||||
int iTitle = (iRank == -1)? gI_UnassignedTitle:gI_UnrankedTitle;
|
|
||||||
|
|
||||||
if(iRank <= 0)
|
|
||||||
{
|
|
||||||
gD_ChatRanks[iTitle].GetString("prefix", gS_Cached_Prefix[client], 32);
|
|
||||||
gD_ChatRanks[iTitle].GetString("name", gS_Cached_Name[client], MAX_NAME_LENGTH*2);
|
|
||||||
gD_ChatRanks[iTitle].GetString("message", gS_Cached_Message[client], 255);
|
|
||||||
gD_ChatRanks[iTitle].GetString("clantag", gS_Cached_ClanTag[client], 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(int i = 0; i < gI_TotalChatRanks; i++)
|
|
||||||
{
|
|
||||||
if(gD_ChatRanks[i].IsValid)
|
|
||||||
{
|
|
||||||
int iFrom = gD_ChatRanks[i].GetInt("rank_from");
|
|
||||||
int iTo = gD_ChatRanks[i].GetInt("rank_to");
|
|
||||||
|
|
||||||
if(iRank < iFrom || (iRank > iTo && iTo != -3))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
gD_ChatRanks[i].GetString("prefix", gS_Cached_Prefix[client], 32);
|
|
||||||
gD_ChatRanks[i].GetString("name", gS_Cached_Name[client], MAX_NAME_LENGTH*2);
|
|
||||||
gD_ChatRanks[i].GetString("message", gS_Cached_Message[client], 255);
|
|
||||||
gD_ChatRanks[i].GetString("clantag", gS_Cached_ClanTag[client], 255);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char[] sAuthID = new char[32];
|
|
||||||
|
|
||||||
if(GetClientAuthId(client, AuthId_Steam3, sAuthID, 32))
|
|
||||||
{
|
|
||||||
char[] sBuffer = new char[255];
|
|
||||||
|
|
||||||
if(gSM_Custom_Prefix.GetString(sAuthID, sBuffer, 255))
|
|
||||||
{
|
|
||||||
strcopy(gS_Cached_Prefix[client], 32, sBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(gSM_Custom_Name.GetString(sAuthID, sBuffer, 255))
|
|
||||||
{
|
|
||||||
strcopy(gS_Cached_Name[client], MAX_NAME_LENGTH*2, sBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(gSM_Custom_Message.GetString(sAuthID, sBuffer, 255))
|
|
||||||
{
|
|
||||||
strcopy(gS_Cached_Message[client], 255, sBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(gSM_Custom_ClanTag.GetString(sAuthID, sBuffer, 255))
|
|
||||||
{
|
|
||||||
strcopy(gS_Cached_ClanTag[client], 32, sBuffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateClanTag(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResetCache()
|
|
||||||
{
|
|
||||||
for(int i = 0; i < 64; i++)
|
|
||||||
{
|
|
||||||
if(gD_ChatRanks[i].IsValid)
|
|
||||||
{
|
|
||||||
gD_ChatRanks[i].Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gI_TotalChatRanks = 0;
|
|
||||||
gI_UnassignedTitle = -1;
|
|
||||||
gI_UnrankedTitle = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadConfig()
|
|
||||||
{
|
|
||||||
delete gSM_Custom_Prefix;
|
|
||||||
delete gSM_Custom_Name;
|
|
||||||
delete gSM_Custom_Message;
|
|
||||||
delete gSM_Custom_ClanTag;
|
|
||||||
|
|
||||||
gSM_Custom_Prefix = new StringMap();
|
|
||||||
gSM_Custom_Name = new StringMap();
|
|
||||||
gSM_Custom_Message = new StringMap();
|
|
||||||
gSM_Custom_ClanTag = new StringMap();
|
|
||||||
|
|
||||||
ResetCache();
|
|
||||||
|
|
||||||
KeyValues kvConfig = new KeyValues("Chat");
|
|
||||||
|
|
||||||
char[] sFile = new char[PLATFORM_MAX_PATH];
|
|
||||||
BuildPath(Path_SM, sFile, PLATFORM_MAX_PATH, "configs/shavit-chat.cfg");
|
|
||||||
|
|
||||||
if(!kvConfig.ImportFromFile(sFile))
|
|
||||||
{
|
|
||||||
SetFailState("File %s could not be found or accessed.", sFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(kvConfig.GotoFirstSubKey())
|
|
||||||
{
|
|
||||||
char[] sBuffer = new char[255];
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
kvConfig.GetSectionName(sBuffer, 255);
|
|
||||||
|
|
||||||
char[] sPrefix = new char[32];
|
|
||||||
kvConfig.GetString("prefix", sPrefix, 32);
|
|
||||||
|
|
||||||
char[] sName = new char[MAX_NAME_LENGTH*2];
|
|
||||||
kvConfig.GetString("name", sName, MAX_NAME_LENGTH*2);
|
|
||||||
|
|
||||||
char[] sMessage = new char[255];
|
|
||||||
kvConfig.GetString("message", sMessage, 255);
|
|
||||||
|
|
||||||
char[] sCustomClanTag = new char[32];
|
|
||||||
kvConfig.GetString("clantag", sCustomClanTag, 32);
|
|
||||||
|
|
||||||
// custom
|
|
||||||
if(StrContains(sBuffer[0], "[U:") != -1)
|
|
||||||
{
|
|
||||||
if(strlen(sPrefix) > 0)
|
|
||||||
{
|
|
||||||
gSM_Custom_Prefix.SetString(sBuffer, sPrefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(strlen(sName) > 0)
|
|
||||||
{
|
|
||||||
gSM_Custom_Name.SetString(sBuffer, sName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(strlen(sMessage) > 0)
|
|
||||||
{
|
|
||||||
gSM_Custom_Message.SetString(sBuffer, sMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(strlen(sCustomClanTag) > 0)
|
|
||||||
{
|
|
||||||
gSM_Custom_ClanTag.SetString(sBuffer, sCustomClanTag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ranks
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int iFrom = kvConfig.GetNum("rank_from", -2);
|
|
||||||
|
|
||||||
if(iFrom == -2)
|
|
||||||
{
|
|
||||||
LogError("Invalid \"rank_from\" value for \"%s\": %d or non-existant.", sBuffer, iFrom);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
char[] sTo = new char[16];
|
|
||||||
kvConfig.GetString("rank_to", sTo, 16, "-2");
|
|
||||||
int iTo = StrEqual(sTo, "infinity", false)? -3:StringToInt(sTo);
|
|
||||||
|
|
||||||
if(iTo == -2)
|
|
||||||
{
|
|
||||||
LogError("Invalid \"rank_to\" value for \"%s\": %d or non-existant.", sBuffer, iTo);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
gD_ChatRanks[gI_TotalChatRanks] = Dynamic();
|
|
||||||
gD_ChatRanks[gI_TotalChatRanks].SetInt("rank_from", iFrom);
|
|
||||||
gD_ChatRanks[gI_TotalChatRanks].SetInt("rank_to", iTo);
|
|
||||||
gD_ChatRanks[gI_TotalChatRanks].SetString("prefix", sPrefix, 32);
|
|
||||||
gD_ChatRanks[gI_TotalChatRanks].SetString("name", (strlen(sName) > 0)? sName:"{name}", MAX_NAME_LENGTH*2);
|
|
||||||
gD_ChatRanks[gI_TotalChatRanks].SetString("message", (strlen(sMessage) > 0)? sMessage:"{message}", 255);
|
|
||||||
gD_ChatRanks[gI_TotalChatRanks].SetString("clantag", (strlen(sCustomClanTag) > 0)? sCustomClanTag:"", 32);
|
|
||||||
|
|
||||||
if(iFrom == -1 && gI_UnassignedTitle == -1)
|
|
||||||
{
|
|
||||||
gI_UnassignedTitle = gI_TotalChatRanks;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(iFrom == 0 && gI_UnrankedTitle == -1)
|
|
||||||
{
|
|
||||||
gI_UnrankedTitle = gI_TotalChatRanks;
|
|
||||||
}
|
|
||||||
|
|
||||||
gI_TotalChatRanks++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while(kvConfig.GotoNextKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogError("File %s might be empty?", sFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete kvConfig;
|
|
||||||
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(IsValidClient(i)) // late loading
|
|
||||||
{
|
|
||||||
OnClientPutInServer(i);
|
|
||||||
|
|
||||||
char[] sAuth = new char[32];
|
|
||||||
|
|
||||||
if(GetClientAuthId(i, AuthId_Steam3, sAuth, 32))
|
|
||||||
{
|
|
||||||
OnClientAuthorized(i, sAuth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_ChatRanks(int client, int args)
|
|
||||||
{
|
|
||||||
if(!IsValidClient(client))
|
|
||||||
{
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
// dummies
|
|
||||||
// char[] sExample = "Example."; // I tried using this variable, but it seemed to pick up "List of Chat ranks:" instead, I wonder why..
|
|
||||||
int[] clients = new int[1];
|
|
||||||
clients[0] = client;
|
|
||||||
char[] sChatMessage = new char[64];
|
|
||||||
FormatEx(sChatMessage, 64, "\x01%T", "ChatRankList", client);
|
|
||||||
|
|
||||||
ChatMessage(client, clients, 1, sChatMessage);
|
|
||||||
|
|
||||||
for(int i = gI_TotalChatRanks - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
if(gD_ChatRanks[i].IsValid)
|
|
||||||
{
|
|
||||||
int iFrom = gD_ChatRanks[i].GetInt("rank_from");
|
|
||||||
|
|
||||||
if(iFrom <= 0)
|
|
||||||
{
|
|
||||||
continue; // don't show unranked/due-lookup 'chat ranks'
|
|
||||||
}
|
|
||||||
|
|
||||||
int iTo = gD_ChatRanks[i].GetInt("rank_to");
|
|
||||||
char[] sRankText = new char[16];
|
|
||||||
|
|
||||||
if(iFrom == iTo)
|
|
||||||
{
|
|
||||||
FormatEx(sRankText, 16, "#%d", iFrom);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PrintToConsole(client, "%d", iTo);
|
|
||||||
|
|
||||||
if(iTo == -3)
|
|
||||||
{
|
|
||||||
FormatEx(sRankText, 16, "#%d - ∞", iFrom, iTo);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FormatEx(sRankText, 16, "#%d - #%d", iFrom, iTo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
char[] sExampleMessage = new char[32];
|
|
||||||
FormatEx(sExampleMessage, 64, "\x01%T", "ExampleMessage", client);
|
|
||||||
|
|
||||||
char[] sPrefix = new char[32];
|
|
||||||
gD_ChatRanks[i].GetString("prefix", sPrefix, 32);
|
|
||||||
FormatVariables(client, sPrefix, 32, sPrefix, sExampleMessage);
|
|
||||||
|
|
||||||
char[] sName = new char[MAX_NAME_LENGTH*2];
|
|
||||||
gD_ChatRanks[i].GetString("name", sName, MAX_NAME_LENGTH*2);
|
|
||||||
FormatVariables(client, sName, MAX_NAME_LENGTH*2, sName, sExampleMessage);
|
|
||||||
|
|
||||||
char[] sMessage = new char[255];
|
|
||||||
gD_ChatRanks[i].GetString("message", sMessage, 255);
|
|
||||||
FormatVariables(client, sMessage, 255, sMessage, sExampleMessage);
|
|
||||||
|
|
||||||
char[] sBuffer = new char[300];
|
|
||||||
FormatEx(sBuffer, 300, "%s\x04[%s]\x01 %s%s %s %s %s", gEV_Type == Engine_CSGO? " ":"", sRankText, strlen(sPrefix) == 0? "\x03":"", sPrefix, sName, gEV_Type == Engine_CSGO? ":\x01":"\x01:", sMessage);
|
|
||||||
|
|
||||||
ChatMessage(client, clients, 1, sBuffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_ReloadChat(int client, int args)
|
|
||||||
{
|
|
||||||
LoadConfig();
|
|
||||||
|
|
||||||
ReplyToCommand(client, "%T", "ReloadChat", client);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action OnChatMessage(int &author, ArrayList recipients, eChatFlags &flag, char[] name, char[] message, bool &bProcessColors, bool &bRemoveColors)
|
|
||||||
{
|
|
||||||
if(!gB_ChatProcessor)
|
|
||||||
{
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
char[] sBuffer = new char[255];
|
|
||||||
char[] sPrefix = new char[32];
|
|
||||||
|
|
||||||
if(strlen(gS_Cached_Prefix[author]) > 0)
|
|
||||||
{
|
|
||||||
FormatVariables(author, sBuffer, 255, gS_Cached_Prefix[author], message);
|
|
||||||
int iLen = strlen(sBuffer);
|
|
||||||
sBuffer[iLen] = (iLen > 0)? ' ':'\0';
|
|
||||||
strcopy(sPrefix, 32, sBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
char[] sName = new char[MAX_NAME_LENGTH*2];
|
|
||||||
|
|
||||||
if(strlen(gS_Cached_Name[author]) > 0)
|
|
||||||
{
|
|
||||||
FormatVariables(author, sBuffer, 255, gS_Cached_Name[author], message);
|
|
||||||
strcopy(sName, MAX_NAME_LENGTH*2, sBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FormatEx(sName, MAX_NAME_LENGTH*2, "\x03%N", author);
|
|
||||||
}
|
|
||||||
|
|
||||||
char[] sFormattedText = new char[MAXLENGTH_MESSAGE];
|
|
||||||
strcopy(sFormattedText, MAXLENGTH_MESSAGE, message);
|
|
||||||
|
|
||||||
// solve shitty exploits
|
|
||||||
ReplaceString(sFormattedText, MAXLENGTH_MESSAGE, "\n", "");
|
|
||||||
ReplaceString(sFormattedText, MAXLENGTH_MESSAGE, "\t", "");
|
|
||||||
ReplaceString(sFormattedText, MAXLENGTH_MESSAGE, " ", " ");
|
|
||||||
TrimString(sFormattedText);
|
|
||||||
|
|
||||||
if(strlen(gS_Cached_Message[author]) > 0)
|
|
||||||
{
|
|
||||||
FormatVariables(author, sBuffer, 255, gS_Cached_Message[author], sFormattedText);
|
|
||||||
strcopy(sFormattedText, 255, sBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strcopy(sFormattedText, 255, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
FormatEx(name, MAXLENGTH_NAME, "%s%s%s", (gEV_Type == Engine_CSGO)? " ":"", sPrefix, sName);
|
|
||||||
strcopy(message, MAXLENGTH_MESSAGE, sFormattedText);
|
|
||||||
|
|
||||||
return Plugin_Changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action OnClientSayCommand(int client, const char[] command, const char[] sArgs)
|
|
||||||
{
|
|
||||||
if(gB_ChatProcessor || !IsValidClient(client) || !IsClientAuthorized(client) || (gB_BaseComm && BaseComm_IsClientGagged(client)))
|
|
||||||
{
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(GetEngineTime() - gF_LastMessage[client] < 0.70)
|
|
||||||
{
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool bTeam = StrEqual(command, "say_team");
|
|
||||||
|
|
||||||
if(bTeam || (CheckCommandAccess(client, "sm_say", ADMFLAG_CHAT) && sArgs[0] == '@'))
|
|
||||||
{
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
char[] sMessage = new char[300];
|
|
||||||
strcopy(sMessage, 300, sArgs);
|
|
||||||
|
|
||||||
if(ReplaceString(sMessage[0], 4, "!", "sm_") > 0 || ReplaceString(sMessage[0], 4, "/", "sm_") > 0)
|
|
||||||
{
|
|
||||||
bool bCmd = false;
|
|
||||||
Handle hCon = FindFirstConCommand(sMessage, 300, bCmd);
|
|
||||||
|
|
||||||
if(hCon != null)
|
|
||||||
{
|
|
||||||
FindNextConCommand(hCon, sMessage, 300, bCmd);
|
|
||||||
delete hCon;
|
|
||||||
|
|
||||||
if(bCmd)
|
|
||||||
{
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gF_LastMessage[client] = GetEngineTime();
|
|
||||||
|
|
||||||
int iTeam = GetClientTeam(client);
|
|
||||||
|
|
||||||
FormatChatLine(client, sArgs, IsPlayerAlive(client), iTeam, bTeam, sMessage, 300);
|
|
||||||
|
|
||||||
int[] clients = new int[MaxClients];
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
PrintToServer("%N: %s", client, sArgs);
|
|
||||||
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(IsValidClient(i))
|
|
||||||
{
|
|
||||||
if(GetClientTeam(i) == iTeam || !bTeam)
|
|
||||||
{
|
|
||||||
clients[count++] = i;
|
|
||||||
|
|
||||||
PrintToConsole(i, "%N: %s", client, sArgs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ChatMessage(client, clients, count, sMessage);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FormatChatLine(int client, const char[] sMessage, bool bAlive, int iTeam, bool bTeam, char[] buffer, int maxlen)
|
|
||||||
{
|
|
||||||
char[] sTeam = new char[32];
|
|
||||||
char[] sTeamName = new char[32];
|
|
||||||
|
|
||||||
if(!bTeam)
|
|
||||||
{
|
|
||||||
if(iTeam == CS_TEAM_SPECTATOR)
|
|
||||||
{
|
|
||||||
FormatEx(sTeamName, 32, "%T", "TeamSpec", client);
|
|
||||||
strcopy(sTeam, 32, sTeamName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch(iTeam)
|
|
||||||
{
|
|
||||||
case CS_TEAM_SPECTATOR:
|
|
||||||
{
|
|
||||||
FormatEx(sTeamName, 32, "%T", "TeamSpectator", client);
|
|
||||||
strcopy(sTeam, 32, sTeamName);
|
|
||||||
}
|
|
||||||
|
|
||||||
case CS_TEAM_T:
|
|
||||||
{
|
|
||||||
FormatEx(sTeamName, 32, "%T", "TeamT", client);
|
|
||||||
strcopy(sTeam, 32, sTeamName);
|
|
||||||
}
|
|
||||||
|
|
||||||
case CS_TEAM_CT:
|
|
||||||
{
|
|
||||||
FormatEx(sTeamName, 32, "%T", "TeamCT", client);
|
|
||||||
strcopy(sTeam, 32, sTeamName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char[] sAuthID = new char[32];
|
|
||||||
GetClientAuthId(client, AuthId_Steam3, sAuthID, 32);
|
|
||||||
|
|
||||||
char[] sBuffer = new char[255];
|
|
||||||
char[] sNewPrefix = new char[32];
|
|
||||||
|
|
||||||
if(strlen(gS_Cached_Prefix[client]) > 0)
|
|
||||||
{
|
|
||||||
FormatVariables(client, sBuffer, 255, gS_Cached_Prefix[client], sMessage);
|
|
||||||
int iLen = strlen(sBuffer);
|
|
||||||
sBuffer[iLen] = (iLen > 0)? ' ':'\0';
|
|
||||||
strcopy(sNewPrefix, 32, sBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
char[] sNewName = new char[MAX_NAME_LENGTH*2];
|
|
||||||
|
|
||||||
if(strlen(gS_Cached_Name[client]) > 0)
|
|
||||||
{
|
|
||||||
FormatVariables(client, sBuffer, 255, gS_Cached_Name[client], sMessage);
|
|
||||||
strcopy(sNewName, MAX_NAME_LENGTH*2, sBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FormatEx(sNewName, MAX_NAME_LENGTH*2, "\x03%N", client);
|
|
||||||
}
|
|
||||||
|
|
||||||
char[] sFormattedText = new char[maxlen];
|
|
||||||
strcopy(sFormattedText, maxlen, sMessage);
|
|
||||||
|
|
||||||
// solve shitty exploits
|
|
||||||
ReplaceString(sFormattedText, maxlen, "\n", "");
|
|
||||||
ReplaceString(sFormattedText, maxlen, "\t", "");
|
|
||||||
ReplaceString(sFormattedText, maxlen, " ", " ");
|
|
||||||
TrimString(sFormattedText);
|
|
||||||
|
|
||||||
if(gB_RTLer)
|
|
||||||
{
|
|
||||||
char[][] sExploded = new char[96][96]; // fixed size from RTLer
|
|
||||||
ExplodeString(sFormattedText, " ", sExploded, 96, 96);
|
|
||||||
|
|
||||||
bool bRTLify = true;
|
|
||||||
|
|
||||||
for(int i = 0; i < 96; i++)
|
|
||||||
{
|
|
||||||
if(strlen(sExploded[i]) > 32)
|
|
||||||
{
|
|
||||||
bRTLify = false;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(bRTLify)
|
|
||||||
{
|
|
||||||
RTLify(sFormattedText, maxlen, sFormattedText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(strlen(gS_Cached_Message[client]) > 0)
|
|
||||||
{
|
|
||||||
FormatVariables(client, sBuffer, 255, gS_Cached_Message[client], sFormattedText);
|
|
||||||
strcopy(sFormattedText, 255, sBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
FormatEx(buffer, maxlen, "\x01%s%s%s\x03%s%s %s %s", gEV_Type == Engine_CSGO? " ":"", (bAlive || iTeam == CS_TEAM_SPECTATOR)? "":"*DEAD* ", sTeam, sNewPrefix, sNewName, gEV_Type == Engine_CSGO? ":\x01":"\x01:", sFormattedText);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FormatVariables(int client, char[] buffer, int maxlen, const char[] formattingrules, const char[] message)
|
|
||||||
{
|
|
||||||
char[] sTempFormattingRules = new char[maxlen];
|
|
||||||
strcopy(sTempFormattingRules, maxlen, formattingrules);
|
|
||||||
|
|
||||||
for(int i = 0; i < sizeof(gS_GlobalColorNames); i++)
|
|
||||||
{
|
|
||||||
ReplaceString(sTempFormattingRules, maxlen, gS_GlobalColorNames[i], gS_GlobalColors[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(gEV_Type == Engine_CSS)
|
|
||||||
{
|
|
||||||
ReplaceString(sTempFormattingRules, maxlen, "{RGB}", "\x07");
|
|
||||||
ReplaceString(sTempFormattingRules, maxlen, "{RGBA}", "\x08");
|
|
||||||
|
|
||||||
char[] sColorBuffer = new char[16];
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
Format(sColorBuffer, 16, "\x07%x%x%x", RealRandomInt(1, 255), RealRandomInt(1, 255), RealRandomInt(1, 255));
|
|
||||||
}
|
|
||||||
|
|
||||||
while(ReplaceStringEx(sTempFormattingRules, maxlen, "{RGBX}", sColorBuffer) > 0);
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
Format(sColorBuffer, 16, "\x08%x%x%x%x", RealRandomInt(1, 255), RealRandomInt(1, 255), RealRandomInt(1, 255), RealRandomInt(1, 255));
|
|
||||||
}
|
|
||||||
|
|
||||||
while(ReplaceStringEx(sTempFormattingRules, maxlen, "{RGBAX}", sColorBuffer) > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(int i = 0; i < sizeof(gS_CSGOColorNames); i++)
|
|
||||||
{
|
|
||||||
ReplaceString(sTempFormattingRules, maxlen, gS_CSGOColorNames[i], gS_CSGOColors[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char[] sName = new char[MAX_NAME_LENGTH];
|
|
||||||
GetClientName(client, sName, MAX_NAME_LENGTH);
|
|
||||||
ReplaceString(sTempFormattingRules, maxlen, "{name}", sName);
|
|
||||||
|
|
||||||
char[] sCustomClanTag = new char[32];
|
|
||||||
CS_GetClientClanTag(client, sCustomClanTag, 32);
|
|
||||||
int iLen = strlen(sCustomClanTag);
|
|
||||||
sCustomClanTag[iLen] = (iLen > 0)? ' ':'\0';
|
|
||||||
ReplaceString(sTempFormattingRules, maxlen, "{clan}", sCustomClanTag);
|
|
||||||
|
|
||||||
ReplaceString(sTempFormattingRules, maxlen, "{message}", message);
|
|
||||||
|
|
||||||
strcopy(buffer, maxlen, sTempFormattingRules);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChatMessage(int from, int[] clients, int count, const char[] sMessage)
|
|
||||||
{
|
|
||||||
Handle hSayText2 = StartMessage("SayText2", clients, count);
|
|
||||||
|
|
||||||
if(hSayText2 != null)
|
|
||||||
{
|
|
||||||
if(gEV_Type == Engine_CSGO)
|
|
||||||
{
|
|
||||||
PbSetInt(hSayText2, "ent_idx", from);
|
|
||||||
PbSetBool(hSayText2, "chat", true);
|
|
||||||
PbSetString(hSayText2, "msg_name", sMessage);
|
|
||||||
|
|
||||||
for(int i = 1; i <= 4; i++)
|
|
||||||
{
|
|
||||||
PbAddString(hSayText2, "params", "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BfWriteByte(hSayText2, from);
|
|
||||||
BfWriteByte(hSayText2, true);
|
|
||||||
BfWriteString(hSayText2, sMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
EndMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Player_Spawn(Event event, const char[] name, bool dontBroadcast)
|
|
||||||
{
|
|
||||||
int client = GetClientOfUserId(event.GetInt("userid"));
|
|
||||||
|
|
||||||
if(!IsFakeClient(client))
|
|
||||||
{
|
|
||||||
LoadChatCache(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Native_FormatChat(Handle handler, int numParams)
|
|
||||||
{
|
|
||||||
int client = GetNativeCell(1);
|
|
||||||
|
|
||||||
if(!IsValidClient(client))
|
|
||||||
{
|
|
||||||
ThrowNativeError(200, "Invalid client index %d", client);
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char[] sMessage = new char[255];
|
|
||||||
GetNativeString(2, sMessage, 255);
|
|
||||||
|
|
||||||
char[] sBuffer = new char[300];
|
|
||||||
FormatChatLine(client, sMessage, IsPlayerAlive(client), GetClientTeam(client), view_as<bool>(GetNativeCell(3)), sBuffer, 300);
|
|
||||||
|
|
||||||
int maxlength = GetNativeCell(5);
|
|
||||||
|
|
||||||
return SetNativeString(6, sBuffer, maxlength);
|
|
||||||
}
|
|
||||||
|
|
||||||
// from SMLib
|
|
||||||
int RealRandomInt(int min, int max)
|
|
||||||
{
|
|
||||||
int random = GetURandomInt();
|
|
||||||
|
|
||||||
if(random == 0)
|
|
||||||
{
|
|
||||||
random++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RoundToCeil(float(random) / (float(2147483647) / float(max - min + 1))) + min - 1;
|
|
||||||
}
|
|
||||||
79
scripting/include/chat-processor.inc
Normal file
79
scripting/include/chat-processor.inc
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#if defined _chat_processor_included
|
||||||
|
#endinput
|
||||||
|
#endif
|
||||||
|
#define _chat_processor_included
|
||||||
|
|
||||||
|
//Globals
|
||||||
|
#define MAXLENGTH_FLAG 32
|
||||||
|
#define MAXLENGTH_NAME 128
|
||||||
|
#define MAXLENGTH_MESSAGE 128
|
||||||
|
#define MAXLENGTH_BUFFER 255
|
||||||
|
|
||||||
|
//Natives
|
||||||
|
/**
|
||||||
|
* Retrieves the current format string assigned from a flag string.
|
||||||
|
* Example: "Cstrike_Chat_All" = "{1} : {2}"
|
||||||
|
* You can find the config formats in either the translations or the configs.
|
||||||
|
*
|
||||||
|
* param sFlag Flag string to retrieve the format string from.
|
||||||
|
* param sBuffer Format string from the flag string.
|
||||||
|
* param iSize Size of the format string buffer.
|
||||||
|
*
|
||||||
|
* noreturn
|
||||||
|
**/
|
||||||
|
native void ChatProcessor_GetFlagFormatString(const char[] sFlag, char[] sBuffer, int iSize);
|
||||||
|
|
||||||
|
//Forwards
|
||||||
|
/**
|
||||||
|
* Called while sending a chat message before It's sent.
|
||||||
|
* Limits on the name and message strings can be found above.
|
||||||
|
*
|
||||||
|
* param author Author that created the message.
|
||||||
|
* param recipients Array of clients who will receive the message.
|
||||||
|
* param flagstring Flag string to determine the type of message.
|
||||||
|
* param name Name string of the author to be pushed.
|
||||||
|
* param message Message string from the author to be pushed.
|
||||||
|
* param processcolors Toggle to process colors in the buffer strings.
|
||||||
|
* param removecolors Toggle to remove colors in the buffer strings. (Requires bProcessColors = true)
|
||||||
|
*
|
||||||
|
* return types
|
||||||
|
* - Plugin_Continue Stops the message.
|
||||||
|
* - Plugin_Stop Stops the message.
|
||||||
|
* - Plugin_Changed Fires the post-forward below and prints out a message.
|
||||||
|
* - Plugin_Handled Fires the post-forward below but doesn't print a message.
|
||||||
|
**/
|
||||||
|
forward Action CP_OnChatMessage(int& author, ArrayList recipients, char[] flagstring, char[] name, char[] message, bool& processcolors, bool& removecolors);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after the chat message is sent to the designated clients by the author.
|
||||||
|
*
|
||||||
|
* param author Author that sent the message.
|
||||||
|
* param recipients Array of clients who received the message.
|
||||||
|
* param flagstring Flag string to determine the type of message.
|
||||||
|
* param formatstring Format string used in the message based on the flag string.
|
||||||
|
* param name Name string of the author.
|
||||||
|
* param message Message string from the author.
|
||||||
|
* param processcolors Check if colors were processed in the buffer strings.
|
||||||
|
* param removecolors Check if colors were removed from the buffer strings.
|
||||||
|
*
|
||||||
|
* noreturn
|
||||||
|
**/
|
||||||
|
forward void CP_OnChatMessagePost(int author, ArrayList recipients, const char[] flagstring, const char[] formatstring, const char[] name, const char[] message, bool processcolors, bool removecolors);
|
||||||
|
|
||||||
|
#if !defined REQUIRE_PLUGIN
|
||||||
|
public __pl_chat_processor_SetNTVOptional()
|
||||||
|
{
|
||||||
|
MarkNativeAsOptional("ChatProcessor_GetFlagFormatString");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public SharedPlugin __pl_chat_processor =
|
||||||
|
{
|
||||||
|
name = "chat-processor",
|
||||||
|
file = "chat-processor.smx",
|
||||||
|
#if defined REQUIRE_PLUGIN
|
||||||
|
required = 1
|
||||||
|
#else
|
||||||
|
required = 0
|
||||||
|
#endif
|
||||||
|
};
|
||||||
@ -803,21 +803,6 @@ native int Shavit_GetRankedPlayers();
|
|||||||
*/
|
*/
|
||||||
native int Shavit_ForceHUDUpdate(int client, bool spectators);
|
native int Shavit_ForceHUDUpdate(int client, bool spectators);
|
||||||
|
|
||||||
/**
|
|
||||||
* Formats chats exactly like the chat handler does.
|
|
||||||
* Takes team, alive status, rank and all those stuff into account.
|
|
||||||
* Called from shavit-chat
|
|
||||||
*
|
|
||||||
* @param client Client index.
|
|
||||||
* @param message Message to use.
|
|
||||||
* @param team Simulate a team chat message?
|
|
||||||
* @param buffer Buffer to store the formatted line on.
|
|
||||||
* @param maxlen Length of 'buffer'
|
|
||||||
* @error Error code 200 if client isn't valid.
|
|
||||||
* @return -1 on error, SP_ERROR_NONE on success.
|
|
||||||
*/
|
|
||||||
native int Shavit_FormatChat(int client, const char[] message, const bool team, char[] buffer, int maxlen);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the stats menu for a client.
|
* Opens the stats menu for a client.
|
||||||
*
|
*
|
||||||
|
|||||||
507
scripting/shavit-chat.sp
Normal file
507
scripting/shavit-chat.sp
Normal file
@ -0,0 +1,507 @@
|
|||||||
|
/*
|
||||||
|
* shavit's Timer - Chat
|
||||||
|
* by: shavit
|
||||||
|
*
|
||||||
|
* This file is part of shavit's Timer.
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Note: For donator perks, give donators a custom flag and then override it to have "shavit_chat".
|
||||||
|
|
||||||
|
#include <sourcemod>
|
||||||
|
#include <chat-processor>
|
||||||
|
|
||||||
|
#undef REQUIRE_PLUGIN
|
||||||
|
#define USES_CHAT_COLORS
|
||||||
|
#include <shavit>
|
||||||
|
|
||||||
|
// database
|
||||||
|
Database gH_SQL = null;
|
||||||
|
char gS_MySQLPrefix[32];
|
||||||
|
|
||||||
|
// cache
|
||||||
|
EngineVersion gEV_Type = Engine_Unknown;
|
||||||
|
|
||||||
|
bool gB_AllowCustom[MAXPLAYERS+1];
|
||||||
|
|
||||||
|
bool gB_NameEnabled[MAXPLAYERS+1];
|
||||||
|
char gS_CustomName[MAXPLAYERS+1][128];
|
||||||
|
|
||||||
|
bool gB_MessageEnabled[MAXPLAYERS+1];
|
||||||
|
char gS_CustomMessage[MAXPLAYERS+1][16];
|
||||||
|
|
||||||
|
public void OnPluginStart()
|
||||||
|
{
|
||||||
|
gEV_Type = GetEngineVersion();
|
||||||
|
|
||||||
|
LoadTranslations("shavit-common.phrases");
|
||||||
|
LoadTranslations("shavit-chat.phrases");
|
||||||
|
|
||||||
|
RegConsoleCmd("sm_cchelp", Command_CCHelp, "Provides help with setting a custom chat name/message color.");
|
||||||
|
RegConsoleCmd("sm_ccname", Command_CCName, "Toggles/sets a custom chat name. Usage: sm_ccname <text> or sm_ccname \"off\" to disable.");
|
||||||
|
RegConsoleCmd("sm_ccmsg", Command_CCMessage, "Toggles/sets a custom chat message color. Usage: sm_ccmsg <color> or sm_ccmsg \"off\" to disable.");
|
||||||
|
RegConsoleCmd("sm_ccmessage", Command_CCMessage, "Toggles/sets a custom chat message color. Usage: sm_ccmessage <color> or sm_ccmessage \"off\" to disable.");
|
||||||
|
|
||||||
|
RegAdminCmd("sm_cclist", Command_CCList, ADMFLAG_CHAT, "Print the custom chat setting of all online players.");
|
||||||
|
|
||||||
|
for(int i = 1; i <= MaxClients; i++)
|
||||||
|
{
|
||||||
|
if(IsClientInGame(i) && !IsFakeClient(i))
|
||||||
|
{
|
||||||
|
OnClientPostAdminCheck(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(LibraryExists("shavit"))
|
||||||
|
{
|
||||||
|
Shavit_GetDB(gH_SQL);
|
||||||
|
SQL_SetPrefix();
|
||||||
|
SetSQLInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnLibraryAdded(const char[] name)
|
||||||
|
{
|
||||||
|
if(StrEqual(name, "shavit"))
|
||||||
|
{
|
||||||
|
Shavit_GetDB(gH_SQL);
|
||||||
|
SQL_SetPrefix();
|
||||||
|
SetSQLInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnLibraryRemoved(const char[] name)
|
||||||
|
{
|
||||||
|
if(StrEqual(name, "shavit"))
|
||||||
|
{
|
||||||
|
gH_SQL = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Shavit_OnDatabaseLoaded(Database db)
|
||||||
|
{
|
||||||
|
gH_SQL = db;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action CheckForSQLInfo(Handle Timer)
|
||||||
|
{
|
||||||
|
return SetSQLInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
Action SetSQLInfo()
|
||||||
|
{
|
||||||
|
if(gH_SQL == null)
|
||||||
|
{
|
||||||
|
Shavit_GetDB(gH_SQL);
|
||||||
|
|
||||||
|
CreateTimer(0.5, CheckForSQLInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SQL_DBConnect();
|
||||||
|
|
||||||
|
return Plugin_Stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Plugin_Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SQL_SetPrefix()
|
||||||
|
{
|
||||||
|
char[] sFile = new char[PLATFORM_MAX_PATH];
|
||||||
|
BuildPath(Path_SM, sFile, PLATFORM_MAX_PATH, "configs/shavit-prefix.txt");
|
||||||
|
|
||||||
|
File fFile = OpenFile(sFile, "r");
|
||||||
|
|
||||||
|
if(fFile == null)
|
||||||
|
{
|
||||||
|
SetFailState("Cannot open \"configs/shavit-prefix.txt\". Make sure this file exists and that the server has read permissions to it.");
|
||||||
|
}
|
||||||
|
|
||||||
|
char[] sLine = new char[PLATFORM_MAX_PATH*2];
|
||||||
|
|
||||||
|
while(fFile.ReadLine(sLine, PLATFORM_MAX_PATH*2))
|
||||||
|
{
|
||||||
|
TrimString(sLine);
|
||||||
|
strcopy(gS_MySQLPrefix, 32, sLine);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete fFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnClientDisconnect(int client)
|
||||||
|
{
|
||||||
|
gB_AllowCustom[client] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnClientPutInServer(int client)
|
||||||
|
{
|
||||||
|
gB_AllowCustom[client] = false;
|
||||||
|
|
||||||
|
gB_NameEnabled[client] = false;
|
||||||
|
strcopy(gS_CustomName[client], 128, "");
|
||||||
|
|
||||||
|
gB_MessageEnabled[client] = false;
|
||||||
|
strcopy(gS_CustomMessage[client], 128, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnClientPostAdminCheck(int client)
|
||||||
|
{
|
||||||
|
gB_AllowCustom[client] = CheckCommandAccess(client, "shavit_chat", ADMFLAG_CHAT);
|
||||||
|
|
||||||
|
if(gH_SQL != null)
|
||||||
|
{
|
||||||
|
LoadFromDatabase(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action Command_CCHelp(int client, int args)
|
||||||
|
{
|
||||||
|
if(client == 0)
|
||||||
|
{
|
||||||
|
ReplyToCommand(client, "%t", "NoConsole");
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
Shavit_PrintToChat(client, "%T", "CheckConsole", client);
|
||||||
|
|
||||||
|
PrintToConsole(client, "%T\n", "CCHelp_Intro", client);
|
||||||
|
PrintToConsole(client, "%T", "CCHelp_Generic", client);
|
||||||
|
PrintToConsole(client, "%T", "CCHelp_GenericVariables", client);
|
||||||
|
|
||||||
|
if(gEV_Type == Engine_CSS)
|
||||||
|
{
|
||||||
|
PrintToConsole(client, "%T", "CCHelp_CSS_1", client);
|
||||||
|
PrintToConsole(client, "%T", "CCHelp_CSS_2", client);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PrintToConsole(client, "%T", "CCHelp_CSGO_1", client);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action Command_CCName(int client, int args)
|
||||||
|
{
|
||||||
|
if(client == 0)
|
||||||
|
{
|
||||||
|
ReplyToCommand(client, "%t", "NoConsole");
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!gB_AllowCustom[client])
|
||||||
|
{
|
||||||
|
Shavit_PrintToChat(client, "%T", "NoCommandAccess", client);
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
char[] sArgs = new char[128];
|
||||||
|
GetCmdArgString(sArgs, 128);
|
||||||
|
TrimString(sArgs);
|
||||||
|
FormatColors(sArgs, 128, true, true);
|
||||||
|
|
||||||
|
if(args == 0 || strlen(sArgs) == 0)
|
||||||
|
{
|
||||||
|
Shavit_PrintToChat(client, "%T", "ArgumentsMissing", client, "sm_ccname <text>");
|
||||||
|
Shavit_PrintToChat(client, "%T", "ChatCurrent", client, sArgs);
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(StrEqual(sArgs, "off"))
|
||||||
|
{
|
||||||
|
Shavit_PrintToChat(client, "%T", "NameOff", client, sArgs);
|
||||||
|
|
||||||
|
gB_NameEnabled[client] = false;
|
||||||
|
|
||||||
|
SaveToDatabase(client);
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
Shavit_PrintToChat(client, "%T", "ChatUpdated", client);
|
||||||
|
|
||||||
|
gB_NameEnabled[client] = true;
|
||||||
|
strcopy(gS_CustomName[client], 128, sArgs);
|
||||||
|
|
||||||
|
SaveToDatabase(client);
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action Command_CCMessage(int client, int args)
|
||||||
|
{
|
||||||
|
if(client == 0)
|
||||||
|
{
|
||||||
|
ReplyToCommand(client, "%t", "NoConsole");
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!gB_AllowCustom[client])
|
||||||
|
{
|
||||||
|
Shavit_PrintToChat(client, "%T", "NoCommandAccess", client);
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
char[] sArgs = new char[32];
|
||||||
|
GetCmdArgString(sArgs, 32);
|
||||||
|
TrimString(sArgs);
|
||||||
|
FormatColors(sArgs, 32, true, true);
|
||||||
|
|
||||||
|
if(args == 0 || strlen(sArgs) == 0)
|
||||||
|
{
|
||||||
|
Shavit_PrintToChat(client, "%T", "ArgumentsMissing", client, "sm_ccmsg <text>");
|
||||||
|
Shavit_PrintToChat(client, "%T", "ChatCurrent", client, sArgs);
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(StrEqual(sArgs, "off"))
|
||||||
|
{
|
||||||
|
Shavit_PrintToChat(client, "%T", "MessageOff", client, sArgs);
|
||||||
|
|
||||||
|
gB_MessageEnabled[client] = false;
|
||||||
|
|
||||||
|
SaveToDatabase(client);
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
Shavit_PrintToChat(client, "%T", "ChatUpdated", client);
|
||||||
|
|
||||||
|
gB_MessageEnabled[client] = true;
|
||||||
|
strcopy(gS_CustomMessage[client], 16, sArgs);
|
||||||
|
|
||||||
|
SaveToDatabase(client);
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action Command_CCList(int client, int args)
|
||||||
|
{
|
||||||
|
ReplyToCommand(client, "%T", "CheckConsole", client);
|
||||||
|
|
||||||
|
for(int i = 1; i <= MaxClients; i++)
|
||||||
|
{
|
||||||
|
if(gB_AllowCustom[i])
|
||||||
|
{
|
||||||
|
PrintToConsole(client, "%N (%d/%d) (name: \"%s\"; message: \"%s\")", i, i, GetClientUserId(i), gS_CustomName[i], gS_CustomMessage[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action CP_OnChatMessage(int &author, ArrayList recipients, char[] flagstring, char[] name, char[] message, bool &processcolors, bool &removecolors)
|
||||||
|
{
|
||||||
|
if(!gB_AllowCustom[author])
|
||||||
|
{
|
||||||
|
return Plugin_Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Action retvalue = Plugin_Continue;
|
||||||
|
|
||||||
|
if(gB_NameEnabled[author] && strlen(gS_CustomName[author]) > 0)
|
||||||
|
{
|
||||||
|
char[] sName = new char[MAX_NAME_LENGTH];
|
||||||
|
GetClientName(author, sName, MAX_NAME_LENGTH);
|
||||||
|
ReplaceString(gS_CustomName[author], MAXLENGTH_NAME, "{name}", sName);
|
||||||
|
|
||||||
|
strcopy(name, MAXLENGTH_NAME, gS_CustomName[author]);
|
||||||
|
FormatRandom(name, MAXLENGTH_NAME);
|
||||||
|
|
||||||
|
retvalue = Plugin_Changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(gB_MessageEnabled[author] && strlen(gS_CustomMessage[author]) > 0)
|
||||||
|
{
|
||||||
|
Format(message, MAXLENGTH_MESSAGE, "%s%s", gS_CustomMessage[author], message);
|
||||||
|
FormatRandom(message, MAXLENGTH_MESSAGE);
|
||||||
|
|
||||||
|
retvalue = Plugin_Changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
removecolors = true;
|
||||||
|
processcolors = false;
|
||||||
|
|
||||||
|
return retvalue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FormatColors(char[] buffer, int size, bool colors, bool escape)
|
||||||
|
{
|
||||||
|
if(colors)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < sizeof(gS_GlobalColorNames); i++)
|
||||||
|
{
|
||||||
|
ReplaceString(buffer, size, gS_GlobalColorNames[i], gS_GlobalColors[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < sizeof(gS_CSGOColorNames); i++)
|
||||||
|
{
|
||||||
|
ReplaceString(buffer, size, gS_CSGOColorNames[i], gS_CSGOColors[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReplaceString(buffer, size, "^", "\x07");
|
||||||
|
ReplaceString(buffer, size, "{RGB}", "\x07");
|
||||||
|
ReplaceString(buffer, size, "&", "\x08");
|
||||||
|
ReplaceString(buffer, size, "{RGBA}", "\x08");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(escape)
|
||||||
|
{
|
||||||
|
ReplaceString(buffer, size, "%%", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FormatRandom(char[] buffer, int size)
|
||||||
|
{
|
||||||
|
char[] temp = new char[8];
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int color = ((RealRandomInt(0, 255) & 0xFF) << 16);
|
||||||
|
color |= ((RealRandomInt(0, 255) & 0xFF) << 8);
|
||||||
|
color |= (RealRandomInt(0, 255) & 0xFF);
|
||||||
|
|
||||||
|
FormatEx(temp, 16, "\x07%06X", color);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(ReplaceStringEx(buffer, size, "{rand}", temp) > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int RealRandomInt(int min, int max)
|
||||||
|
{
|
||||||
|
int random = GetURandomInt();
|
||||||
|
|
||||||
|
if(random == 0)
|
||||||
|
{
|
||||||
|
random++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (RoundToCeil(float(random) / (float(2147483647) / float(max - min + 1))) + min - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SQL_DBConnect()
|
||||||
|
{
|
||||||
|
if(gH_SQL != null)
|
||||||
|
{
|
||||||
|
char[] sQuery = new char[512];
|
||||||
|
FormatEx(sQuery, 512, "CREATE TABLE IF NOT EXISTS `%schat` (`auth` VARCHAR(32) NOT NULL, `name` INT NOT NULL DEFAULT 0, `ccname` VARCHAR(128), `message` INT NOT NULL DEFAULT 0, `ccmessage` VARCHAR(16), PRIMARY KEY (`auth`));", gS_MySQLPrefix);
|
||||||
|
|
||||||
|
gH_SQL.Query(SQL_CreateTable_Callback, sQuery, 0, DBPrio_High);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SQL_CreateTable_Callback(Database db, DBResultSet results, const char[] error, any data)
|
||||||
|
{
|
||||||
|
if(results == null)
|
||||||
|
{
|
||||||
|
LogError("Timer error! Chat table creation failed. Reason: %s", error);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 1; i <= MaxClients; i++)
|
||||||
|
{
|
||||||
|
if(gB_AllowCustom[i])
|
||||||
|
{
|
||||||
|
LoadFromDatabase(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveToDatabase(int client)
|
||||||
|
{
|
||||||
|
char[] sAuthID3 = new char[32];
|
||||||
|
|
||||||
|
if(!GetClientAuthId(client, AuthId_Steam3, sAuthID3, 32))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iLength = ((strlen(gS_CustomName[client]) * 2) + 1);
|
||||||
|
char[] sEscapedName = new char[iLength];
|
||||||
|
gH_SQL.Escape(gS_CustomName[client], sEscapedName, iLength);
|
||||||
|
|
||||||
|
iLength = ((strlen(gS_CustomMessage[client]) * 2) + 1);
|
||||||
|
char[] sEscapedMessage = new char[iLength];
|
||||||
|
gH_SQL.Escape(gS_CustomMessage[client], sEscapedMessage, iLength);
|
||||||
|
|
||||||
|
char[] sQuery = new char[512];
|
||||||
|
FormatEx(sQuery, 512, "REPLACE INTO %schat (auth, name, ccname, message, ccmessage) VALUES ('%s', %d, '%s', %d, '%s');", gS_MySQLPrefix, sAuthID3, gB_NameEnabled[client], sEscapedName, gB_MessageEnabled[client], sEscapedMessage);
|
||||||
|
|
||||||
|
gH_SQL.Query(SQL_UpdateUser_Callback, sQuery, 0, DBPrio_High);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SQL_UpdateUser_Callback(Database db, DBResultSet results, const char[] error, any data)
|
||||||
|
{
|
||||||
|
if(results == null)
|
||||||
|
{
|
||||||
|
LogError("Timer error! Failed to insert chat data. Reason: %s", error);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadFromDatabase(int client)
|
||||||
|
{
|
||||||
|
char[] sAuthID3 = new char[32];
|
||||||
|
|
||||||
|
if(!GetClientAuthId(client, AuthId_Steam3, sAuthID3, 32))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char sQuery[256];
|
||||||
|
FormatEx(sQuery, 256, "SELECT name, ccname, message, ccmessage FROM %schat WHERE auth = '%s';", gS_MySQLPrefix, sAuthID3);
|
||||||
|
|
||||||
|
gH_SQL.Query(SQL_GetChat_Callback, sQuery, GetClientSerial(client), DBPrio_Low);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SQL_GetChat_Callback(Database db, DBResultSet results, const char[] error, any data)
|
||||||
|
{
|
||||||
|
if(results == null)
|
||||||
|
{
|
||||||
|
LogError("Timer (Chat cache update) SQL query failed. Reason: %s", error);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int client = GetClientFromSerial(data);
|
||||||
|
|
||||||
|
if(client == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(results.FetchRow())
|
||||||
|
{
|
||||||
|
gB_NameEnabled[client] = view_as<bool>(results.FetchInt(0));
|
||||||
|
results.FetchString(1, gS_CustomName[client], 128);
|
||||||
|
|
||||||
|
gB_MessageEnabled[client] = view_as<bool>(results.FetchInt(2));
|
||||||
|
results.FetchString(3, gS_CustomMessage[client], 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -190,9 +190,6 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max
|
|||||||
|
|
||||||
public void OnPluginStart()
|
public void OnPluginStart()
|
||||||
{
|
{
|
||||||
LoadTranslations("shavit-common.phrases");
|
|
||||||
LoadTranslations("shavit-misc.phrases");
|
|
||||||
|
|
||||||
// cache
|
// cache
|
||||||
gEV_Type = GetEngineVersion();
|
gEV_Type = GetEngineVersion();
|
||||||
|
|
||||||
@ -262,6 +259,8 @@ public void OnPluginStart()
|
|||||||
|
|
||||||
// phrases
|
// phrases
|
||||||
LoadTranslations("common.phrases");
|
LoadTranslations("common.phrases");
|
||||||
|
LoadTranslations("shavit-common.phrases");
|
||||||
|
LoadTranslations("shavit-misc.phrases");
|
||||||
|
|
||||||
// advertisements
|
// advertisements
|
||||||
gA_Advertisements = new ArrayList(300);
|
gA_Advertisements = new ArrayList(300);
|
||||||
|
|||||||
49
translations/shavit-chat.phrases.txt
Normal file
49
translations/shavit-chat.phrases.txt
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
"Phrases"
|
||||||
|
{
|
||||||
|
// ---------- Commands ---------- //
|
||||||
|
"ChatUpdated"
|
||||||
|
{
|
||||||
|
"en" "Setting updated."
|
||||||
|
}
|
||||||
|
"ChatCurrent"
|
||||||
|
{
|
||||||
|
"#format" "{1:s}"
|
||||||
|
"en" "Current setting: {1}"
|
||||||
|
}
|
||||||
|
"NameOff"
|
||||||
|
{
|
||||||
|
"en" "Custom chat name is now off."
|
||||||
|
}
|
||||||
|
"MessageOff"
|
||||||
|
{
|
||||||
|
"en" "Custom chat text color is now off."
|
||||||
|
}
|
||||||
|
"CheckConsole"
|
||||||
|
{
|
||||||
|
"en" "Check your console."
|
||||||
|
}
|
||||||
|
"CCHelp_Intro"
|
||||||
|
{
|
||||||
|
"en" "- You have access to custom chat.\nUsage information:"
|
||||||
|
}
|
||||||
|
"CCHelp_Generic"
|
||||||
|
{
|
||||||
|
"en" "- !ccname can be used to change your custom chat name. Use \"!ccname off\" to toggle it off.\n- !ccmsg can be used to change your custom message prefix/color. Use \"!ccmsgg off\" to toggle it off.\nThere are custom variables, such as:"
|
||||||
|
}
|
||||||
|
"CCHelp_GenericVariables"
|
||||||
|
{
|
||||||
|
"en" "- {name} - your in-game name.\n- {rand} - a random color.\n- {team} - your team color.\n- {green} - green color."
|
||||||
|
}
|
||||||
|
"CCHelp_CSS_1"
|
||||||
|
{
|
||||||
|
"en" "- To use a custom color, write ^RRGGBB (HEX/HTML colors). For example, ^FFFFFF is white and ^000000 is black."
|
||||||
|
}
|
||||||
|
"CCHelp_CSS_2"
|
||||||
|
{
|
||||||
|
"en" "- You can also use a set alpha (opacity in HEX, where FF is 255). &RRGGBBAA. For example, &FFFFFF7F is 127 alpha, so all text after the color will have 50% opacity."
|
||||||
|
}
|
||||||
|
"CCHelp_CSGO_1"
|
||||||
|
{
|
||||||
|
"en" "- The following colors are also available: {blue}, {bluegrey}, {darkblue}, {darkred}, {gold}, {grey}, {grey2}, {lightgreen}, {lightred}, {lime}, {orchid}, {yellow} and {palered}."
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -17,4 +17,18 @@
|
|||||||
{
|
{
|
||||||
"en" "Bonus"
|
"en" "Bonus"
|
||||||
}
|
}
|
||||||
|
// ---------- Commands ---------- //
|
||||||
|
"NoCommandAccess"
|
||||||
|
{
|
||||||
|
"en" "You do not have access to this command."
|
||||||
|
}
|
||||||
|
"NoConsole"
|
||||||
|
{
|
||||||
|
"en" "Run this command from inside the game."
|
||||||
|
}
|
||||||
|
"ArgumentsMissing"
|
||||||
|
{
|
||||||
|
"#format" "{1:s}"
|
||||||
|
"en" "Usage: {1}"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user