From 441ec285a5c3b40215177ec1447065118692ccfe Mon Sep 17 00:00:00 2001 From: Hugo Jeller Date: Sat, 15 Feb 2020 21:10:56 -0400 Subject: [PATCH] initial commit --- .github/workflows/compile-plugin-on-push.yml | 41 ++ .github/workflows/create-release-on-tag.yml | 90 +++ scripting/fps_booster.sp | 172 ++++++ scripting/include/csgocolors.inc | 558 +++++++++++++++++++ 4 files changed, 861 insertions(+) create mode 100644 .github/workflows/compile-plugin-on-push.yml create mode 100644 .github/workflows/create-release-on-tag.yml create mode 100644 scripting/fps_booster.sp create mode 100644 scripting/include/csgocolors.inc diff --git a/.github/workflows/compile-plugin-on-push.yml b/.github/workflows/compile-plugin-on-push.yml new file mode 100644 index 0000000..f97189c --- /dev/null +++ b/.github/workflows/compile-plugin-on-push.yml @@ -0,0 +1,41 @@ +name: Compile Plugin + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + sm-version: [ '1.10.x', '1.11.x' ] + + name: SM version ${{ matrix.sm-version }} + + steps: + - uses: actions/checkout@v2 + + - name: Setup SourcePawn Compiler + id: setup + uses: rumblefrog/setup-sp@v1.0.0 + with: + version: ${{ matrix.sm-version }} + + - name: Create plugins directory + run: mkdir plugins + + - name: Compile + run: spcomp -i scripting/include scripting/fps_booster.sp -o plugins/fps_booster.smx + + - name: Prepare files for artifact + run: | + mkdir artifact + mv plugins artifact + mv scripting artifact + mv LICENSE artifact + + - name: Upload compiled plugin + uses: actions/upload-artifact@v1 + with: + name: Compiled plugin with SM ${{ steps.setup.outputs.version }} + path: artifact \ No newline at end of file diff --git a/.github/workflows/create-release-on-tag.yml b/.github/workflows/create-release-on-tag.yml new file mode 100644 index 0000000..678d705 --- /dev/null +++ b/.github/workflows/create-release-on-tag.yml @@ -0,0 +1,90 @@ +name: Publish release + +on: + push: + tags: + - 'v*' + +jobs: + release: + name: Create GitHub release + runs-on: ubuntu-latest + steps: + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ github.ref }} + draft: false + prerelease: false + + - name: Output Release URL File + run: echo "${{ steps.create_release.outputs.upload_url }}" > release_url.txt + + - name: Save Release URL File for publish + uses: actions/upload-artifact@v1 + with: + name: release_url + path: release_url.txt + + compile: + runs-on: ubuntu-latest + needs: release + strategy: + matrix: + sm-version: [ '1.10.x', '1.11.x' ] + + name: SM version ${{ matrix.sm-version }} + + steps: + - uses: actions/checkout@v2 + + - name: Setup SourcePawn Compiler + id: setup + uses: rumblefrog/setup-sp@v1.0.0 + with: + version: ${{ matrix.sm-version }} + + - name: Create plugins directory + run: mkdir -p plugins + + - run: spcomp -i ./scripting/include ./scripting/fps_booster.sp -o ./plugins/fps_booster.smx + + - name: Prepare files for artifact + run: | + mkdir artifact + mv ./plugins ./artifact/ + mv ./scripting ./artifact/ + mv ./LICENSE ./artifact/ + + - name: Zip plugin + run : | + cd artifact + zip -r deathmatch-loader * + cd .. + mv artifact/fps-booster.zip . + + - name: Load Release URL File from release job + uses: actions/download-artifact@v1 + with: + name: release_url + + - name: Get Release File Name & Upload URL + id: release_url + run: | + value=`cat release_url/release_url.txt` + echo ::set-output name=upload_url::$value + + - name: Upload Release files + id: upload-release-files + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.release_url.outputs.upload_url }} + asset_path: ./fps-booster.zip + asset_name: fps-booster-sm${{ steps.setup.outputs.version }}.zip + asset_content_type: application/zip \ No newline at end of file diff --git a/scripting/fps_booster.sp b/scripting/fps_booster.sp new file mode 100644 index 0000000..3c66675 --- /dev/null +++ b/scripting/fps_booster.sp @@ -0,0 +1,172 @@ +#pragma semicolon 1 + +#include +#include +#include +#include + +#define PLUGIN_NAME "FPS boost" +#define PLUGIN_AUTHOR "GoD-Tony, de_nerdTV" +#define PLUGIN_VERSION "0.0.1" +#define PLUGIN_DESCRIPTION "Melhor performance client-side evitando transmissão de sons desnecessários" +#define PLUGIN_URL "https://denerdtv.com" + +bool g_bStopSound[MAXPLAYERS+1]; +bool g_bHooked; + +Handle g_hClientCookie = INVALID_HANDLE; + +public Plugin myinfo = +{ + name = PLUGIN_NAME, + author = PLUGIN_AUTHOR, + description = PLUGIN_DESCRIPTION, + version = PLUGIN_VERSION, + url = PLUGIN_URL +}; + +public OnPluginStart() +{ + LoadTranslations("common.phrases"); + + g_hClientCookie = RegClientCookie("sm_fps", "Controla boost de FPS", CookieAccess_Private); + SetCookieMenuItem(StopSoundCookieHandler, g_hClientCookie, "Boost de FPS"); + + // Detect game and hook appropriate tempent. + char sGame[32]; + GetGameFolderName(sGame, sizeof(sGame)); + + if (StrEqual(sGame, "cstrike") || StrEqual(sGame, "csgo")) { + AddTempEntHook("Shotgun Shot", CSS_Hook_ShotgunShot); + } + + RegConsoleCmd("sm_fps", Command_StopSound, "Controla boost de FPS"); + + for (new i = 1; i <= MaxClients; ++i) { + if (!AreClientCookiesCached(i)) { + continue; + } + + OnClientCookiesCached(i); + } +} + +public void StopSoundCookieHandler(int client, CookieMenuAction action, any info, char[] buffer, int maxlen) +{ + switch (action) + { + case CookieMenuAction_DisplayOption: + { + } + + case CookieMenuAction_SelectOption: + { + if (CheckCommandAccess(client, "sm_fpsboost", ADMFLAG_RESERVATION)) { + ToggleStopSound(client); + } else { + ReplyToCommand(client, "[SM] You have no access!"); + } + } + } +} + +void ToggleStopSound(int client) +{ + char info[1]; + int value = !g_bStopSound[client]; + + IntToString(value, info, sizeof(info)); + SetClientCookie(client, g_hClientCookie, info); + + g_bStopSound[client] = (value == 1) ? true : false; + CPrintToChat(client, "{default}[{darkred}FPS{default}] Boost de FPS: %s.", value ? "{green}ligado" : "{darkred}desligado"); + CheckHooks(); +} + +public void OnClientCookiesCached(client) +{ + char sValue[8]; + GetClientCookie(client, g_hClientCookie, sValue, sizeof(sValue)); + + g_bStopSound[client] = (sValue[0] != '\0' && StringToInt(sValue)); + CheckHooks(); +} + +public Action Command_StopSound(client, args) +{ + if (AreClientCookiesCached(client)) { + if (CheckCommandAccess(client, "sm_fpsboost", ADMFLAG_RESERVATION)) { + ToggleStopSound(client); + } else { + ReplyToCommand(client, "[SM] Você precisa ser subscriber para ter acesso ao boost de FPS!"); + } + } else { + ReplyToCommand(client, "[SM] Aguardando cookies, por favor tente novamente..."); + } + + return Plugin_Handled; +} + +public OnClientDisconnect_Post(client) +{ + g_bStopSound[client] = false; + CheckHooks(); +} + +void CheckHooks() +{ + bool bShouldHook = false; + + for (int i = 1; i <= MaxClients; i++) { + if (g_bStopSound[i]) { + bShouldHook = true; + break; + } + } + + // Fake (un)hook because toggling actual hooks will cause server instability. + g_bHooked = bShouldHook; +} + +public Action CSS_Hook_ShotgunShot(const char[] te_name, const Players[], numClients, float delay) +{ + if (!g_bHooked) { + return Plugin_Continue; + } + + // Check which clients need to be excluded. + int newClients[MAXPLAYERS]; + int client; + int newTotal = 0; + + for (int i = 0; i < numClients; i++) { + client = Players[i]; + + if (!g_bStopSound[client]) { + newClients[newTotal++] = client; + } + } + + if (newTotal == numClients) { // No clients were excluded. + return Plugin_Continue; + } else if (newTotal == 0) { // All clients were excluded and there is no need to broadcast. + return Plugin_Stop; + } + + // Re-broadcast to clients that still need it. + float vTemp[3]; + TE_Start("Shotgun Shot"); + TE_ReadVector("m_vecOrigin", vTemp); + TE_WriteVector("m_vecOrigin", vTemp); + TE_WriteFloat("m_vecAngles[0]", TE_ReadFloat("m_vecAngles[0]")); + TE_WriteFloat("m_vecAngles[1]", TE_ReadFloat("m_vecAngles[1]")); + TE_WriteNum("m_weapon", TE_ReadNum("m_weapon")); + TE_WriteNum("m_iMode", TE_ReadNum("m_iMode")); + TE_WriteNum("m_iSeed", TE_ReadNum("m_iSeed")); + TE_WriteNum("m_iPlayer", TE_ReadNum("m_iPlayer")); + TE_WriteFloat("m_fInaccuracy", TE_ReadFloat("m_fInaccuracy")); + TE_WriteFloat("m_fSpread", TE_ReadFloat("m_fSpread")); + TE_Send(newClients, newTotal, delay); + + return Plugin_Stop; +} \ No newline at end of file diff --git a/scripting/include/csgocolors.inc b/scripting/include/csgocolors.inc new file mode 100644 index 0000000..323aba3 --- /dev/null +++ b/scripting/include/csgocolors.inc @@ -0,0 +1,558 @@ +/************************************************************************** +* * +* Colored Chat Functions * +* Author: exvel, Editor: Popoklopsi, Powerlord, Bara * +* Version: 1.1.3 * +* * +**************************************************************************/ + + +#if defined _colors_included +#endinput +#endif +#define _colors_included + +#define MAX_MESSAGE_LENGTH 250 +#define MAX_COLORS 16 + +#define SERVER_INDEX 0 +#define NO_INDEX -1 +#define NO_PLAYER -2 + +enum Colors +{ + Color_Default = 0, + Color_Darkred, + Color_Pink, + Color_Green, + Color_Lightgreen, + Color_Lime, + Color_Red, + Color_Grey, + Color_Olive, + Color_A, + Color_Lightblue, + Color_Blue, + Color_D, + Color_Purple, + Color_Darkrange, + Color_Orange +} + +/* Colors' properties */ +new String:CTag[][] = {"{default}", "{darkred}", "{pink}", "{green}", "{lightgreen}", "{lime}", "{red}", "{grey}", "{olive}", "{a}", "{lightblue}", "{blue}", "{d}", "{purple}", "{darkorange}", "{orange}"}; +new String:CTagCode[][] = {"\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x08", "\x09", "\x0A", "\x0B", "\x0C", "\x0D", "\x0E", "\x0F", "\x10"}; +new bool:CTagReqSayText2[] = {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}; +new bool:CEventIsHooked = false; +new bool:CSkipList[MAXPLAYERS+1] = {false,...}; + +/* Game default profile */ +new bool:CProfile_Colors[] = {true, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false}; +new CProfile_TeamIndex[] = {NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX, NO_INDEX}; +new bool:CProfile_SayText2 = false; + +/** +* Prints a message to a specific client in the chat area. +* Supports color tags. +* +* @param client Client index. +* @param szMessage Message (formatting rules). +* @return No return +* +* On error/Errors: If the client is not connected an error will be thrown. +*/ +stock CPrintToChat(client, const String:szMessage[], any:...) +{ + if (client <= 0 || client > MaxClients) + ThrowError("Invalid client index %d", client); + + if (!IsClientInGame(client)) + ThrowError("Client %d is not in game", client); + + decl String:szBuffer[MAX_MESSAGE_LENGTH]; + decl String:szCMessage[MAX_MESSAGE_LENGTH]; + + SetGlobalTransTarget(client); + + Format(szBuffer, sizeof(szBuffer), "\x01%s", szMessage); + VFormat(szCMessage, sizeof(szCMessage), szBuffer, 3); + + new index = CFormat(szCMessage, sizeof(szCMessage)); + + if (index == NO_INDEX) + PrintToChat(client, "%s", szCMessage); + else + CSayText2(client, index, szCMessage); +} + +stock CReplyToCommand(client, const String:szMessage[], any:...) +{ + + decl String:szCMessage[MAX_MESSAGE_LENGTH]; + VFormat(szCMessage, sizeof(szCMessage), szMessage, 3); + + if (client == 0) + { + CRemoveTags(szCMessage, sizeof(szCMessage)); + PrintToServer("%s", szCMessage); + } + else if (GetCmdReplySource() == SM_REPLY_TO_CONSOLE) + { + CRemoveTags(szCMessage, sizeof(szCMessage)); + PrintToConsole(client, "%s", szCMessage); + } + else + { + CPrintToChat(client, "%s", szCMessage); + } +} + + +/** +* Prints a message to all clients in the chat area. +* Supports color tags. +* +* @param client Client index. +* @param szMessage Message (formatting rules) +* @return No return +*/ +stock CPrintToChatAll(const String:szMessage[], any:...) +{ + decl String:szBuffer[MAX_MESSAGE_LENGTH]; + + for (new i = 1; i <= MaxClients; i++) + { + if (IsClientInGame(i) && !IsFakeClient(i) && !CSkipList[i]) + { + SetGlobalTransTarget(i); + VFormat(szBuffer, sizeof(szBuffer), szMessage, 2); + + CPrintToChat(i, "%s", szBuffer); + } + + CSkipList[i] = false; + } +} + +/** +* Prints a message to a specific client in the chat area. +* Supports color tags and teamcolor tag. +* +* @param client Client index. +* @param author Author index whose color will be used for teamcolor tag. +* @param szMessage Message (formatting rules). +* @return No return +* +* On error/Errors: If the client or author are not connected an error will be thrown. +*/ +stock CPrintToChatEx(client, author, const String:szMessage[], any:...) +{ + if (client <= 0 || client > MaxClients) + ThrowError("Invalid client index %d", client); + + if (!IsClientInGame(client)) + ThrowError("Client %d is not in game", client); + + if (author < 0 || author > MaxClients) + ThrowError("Invalid client index %d", author); + + decl String:szBuffer[MAX_MESSAGE_LENGTH]; + decl String:szCMessage[MAX_MESSAGE_LENGTH]; + + SetGlobalTransTarget(client); + + Format(szBuffer, sizeof(szBuffer), "\x01%s", szMessage); + VFormat(szCMessage, sizeof(szCMessage), szBuffer, 4); + + new index = CFormat(szCMessage, sizeof(szCMessage), author); + + if (index == NO_INDEX) + PrintToChat(client, "%s", szCMessage); + else + CSayText2(client, author, szCMessage); +} + +/** +* Prints a message to all clients in the chat area. +* Supports color tags and teamcolor tag. +* +* @param author Author index whos color will be used for teamcolor tag. +* @param szMessage Message (formatting rules). +* @return No return +* +* On error/Errors: If the author is not connected an error will be thrown. +*/ +stock CPrintToChatAllEx(author, const String:szMessage[], any:...) +{ + if (author < 0 || author > MaxClients) + ThrowError("Invalid client index %d", author); + + if (!IsClientInGame(author)) + ThrowError("Client %d is not in game", author); + + decl String:szBuffer[MAX_MESSAGE_LENGTH]; + + for (new i = 1; i <= MaxClients; i++) + { + if (IsClientInGame(i) && !IsFakeClient(i) && !CSkipList[i]) + { + SetGlobalTransTarget(i); + VFormat(szBuffer, sizeof(szBuffer), szMessage, 3); + + CPrintToChatEx(i, author, "%s", szBuffer); + } + + CSkipList[i] = false; + } +} + +/** +* Removes color tags from the string. +* +* @param szMessage String. +* @return No return +*/ +stock CRemoveTags(String:szMessage[], maxlength) +{ + for (new i = 0; i < MAX_COLORS; i++) + ReplaceString(szMessage, maxlength, CTag[i], "", false); + + ReplaceString(szMessage, maxlength, "{teamcolor}", "", false); +} + +/** +* Checks whether a color is allowed or not +* +* @param tag Color Tag. +* @return True when color is supported, otherwise false +*/ +stock CColorAllowed(Colors:color) +{ + if (!CEventIsHooked) + { + CSetupProfile(); + + CEventIsHooked = true; + } + + return CProfile_Colors[color]; +} + +/** +* Replace the color with another color +* Handle with care! +* +* @param color color to replace. +* @param newColor color to replace with. +* @noreturn +*/ +stock CReplaceColor(Colors:color, Colors:newColor) +{ + if (!CEventIsHooked) + { + CSetupProfile(); + + CEventIsHooked = true; + } + + CProfile_Colors[color] = CProfile_Colors[newColor]; + CProfile_TeamIndex[color] = CProfile_TeamIndex[newColor]; + + CTagReqSayText2[color] = CTagReqSayText2[newColor]; + Format(CTagCode[color], sizeof(CTagCode[]), CTagCode[newColor]) +} + +/** +* This function should only be used right in front of +* CPrintToChatAll or CPrintToChatAllEx and it tells +* to those funcions to skip specified client when printing +* message to all clients. After message is printed client will +* no more be skipped. +* +* @param client Client index +* @return No return +*/ +stock CSkipNextClient(client) +{ + if (client <= 0 || client > MaxClients) + ThrowError("Invalid client index %d", client); + + CSkipList[client] = true; +} + +/** +* Replaces color tags in a string with color codes +* +* @param szMessage String. +* @param maxlength Maximum length of the string buffer. +* @return Client index that can be used for SayText2 author index +* +* On error/Errors: If there is more then one team color is used an error will be thrown. +*/ +stock CFormat(String:szMessage[], maxlength, author=NO_INDEX) +{ + decl String:szGameName[30]; + + GetGameFolderName(szGameName, sizeof(szGameName)); + + /* Hook event for auto profile setup on map start */ + if (!CEventIsHooked) + { + CSetupProfile(); + HookEvent("server_spawn", CEvent_MapStart, EventHookMode_PostNoCopy); + + CEventIsHooked = true; + } + + new iRandomPlayer = NO_INDEX; + + // On CS:GO set invisible precolor + if (StrEqual(szGameName, "csgo", false)) + Format(szMessage, maxlength, " \x01\x0B\x01%s", szMessage); + + /* If author was specified replace {teamcolor} tag */ + if (author != NO_INDEX) + { + if (CProfile_SayText2) + { + ReplaceString(szMessage, maxlength, "{teamcolor}", "\x03", false); + + iRandomPlayer = author; + } + /* If saytext2 is not supported by game replace {teamcolor} with green tag */ + else + ReplaceString(szMessage, maxlength, "{teamcolor}", CTagCode[Color_Green], false); + } + else + ReplaceString(szMessage, maxlength, "{teamcolor}", "", false); + + /* For other color tags we need a loop */ + for (new i = 0; i < MAX_COLORS; i++) + { + /* If tag not found - skip */ + if (StrContains(szMessage, CTag[i], false) == -1) + continue; + + /* If tag is not supported by game replace it with green tag */ + else if (!CProfile_Colors[i]) + ReplaceString(szMessage, maxlength, CTag[i], CTagCode[Color_Green], false); + + /* If tag doesn't need saytext2 simply replace */ + else if (!CTagReqSayText2[i]) + ReplaceString(szMessage, maxlength, CTag[i], CTagCode[i], false); + + /* Tag needs saytext2 */ + else + { + /* If saytext2 is not supported by game replace tag with green tag */ + if (!CProfile_SayText2) + ReplaceString(szMessage, maxlength, CTag[i], CTagCode[Color_Green], false); + + /* Game supports saytext2 */ + else + { + /* If random player for tag wasn't specified replace tag and find player */ + if (iRandomPlayer == NO_INDEX) + { + /* Searching for valid client for tag */ + iRandomPlayer = CFindRandomPlayerByTeam(CProfile_TeamIndex[i]); + + /* If player not found replace tag with green color tag */ + if (iRandomPlayer == NO_PLAYER) + ReplaceString(szMessage, maxlength, CTag[i], CTagCode[Color_Green], false); + + /* If player was found simply replace */ + else + ReplaceString(szMessage, maxlength, CTag[i], CTagCode[i], false); + + } + /* If found another team color tag throw error */ + else + { + //ReplaceString(szMessage, maxlength, CTag[i], ""); + ThrowError("Using two team colors in one message is not allowed"); + } + } + + } + } + + return iRandomPlayer; +} + +/** +* Founds a random player with specified team +* +* @param color_team Client team. +* @return Client index or NO_PLAYER if no player found +*/ +stock CFindRandomPlayerByTeam(color_team) +{ + if (color_team == SERVER_INDEX) + return 0; + else + { + for (new i = 1; i <= MaxClients; i++) + { + if (IsClientInGame(i) && GetClientTeam(i) == color_team) + return i; + } + } + + return NO_PLAYER; +} + +/** +* Sends a SayText2 usermessage to a client +* +* @param szMessage Client index +* @param maxlength Author index +* @param szMessage Message +* @return No return. +*/ +stock CSayText2(client, author, const String:szMessage[]) +{ + new Handle:hBuffer = StartMessageOne("SayText2", client, USERMSG_RELIABLE|USERMSG_BLOCKHOOKS); + + if(GetFeatureStatus(FeatureType_Native, "GetUserMessageType") == FeatureStatus_Available && GetUserMessageType() == UM_Protobuf) + { + PbSetInt(hBuffer, "ent_idx", author); + PbSetBool(hBuffer, "chat", true); + PbSetString(hBuffer, "msg_name", szMessage); + PbAddString(hBuffer, "params", ""); + PbAddString(hBuffer, "params", ""); + PbAddString(hBuffer, "params", ""); + PbAddString(hBuffer, "params", ""); + } + else + { + BfWriteByte(hBuffer, author); + BfWriteByte(hBuffer, true); + BfWriteString(hBuffer, szMessage); + } + + EndMessage(); +} + +/** +* Creates game color profile +* This function must be edited if you want to add more games support +* +* @return No return. +*/ +stock CSetupProfile() +{ + decl String:szGameName[30]; + GetGameFolderName(szGameName, sizeof(szGameName)); + + if (StrEqual(szGameName, "cstrike", false)) + { + CProfile_Colors[Color_Lightgreen] = true; + CProfile_Colors[Color_Red] = true; + CProfile_Colors[Color_Blue] = true; + CProfile_Colors[Color_Olive] = true; + CProfile_TeamIndex[Color_Lightgreen] = SERVER_INDEX; + CProfile_TeamIndex[Color_Red] = 2; + CProfile_TeamIndex[Color_Blue] = 3; + CProfile_SayText2 = true; + } + else if (StrEqual(szGameName, "csgo", false)) + { + CProfile_Colors[Color_Default] = true; + CProfile_Colors[Color_Darkred] = true; + CProfile_Colors[Color_Pink] = true; + CProfile_Colors[Color_Green] = true; + CProfile_Colors[Color_Lightgreen] = true; + CProfile_Colors[Color_Lime] = true; + CProfile_Colors[Color_Red] = true; + CProfile_Colors[Color_Grey] = true; + CProfile_Colors[Color_Olive] = true; + CProfile_Colors[Color_A] = true; + CProfile_Colors[Color_Lightblue] = true; + CProfile_Colors[Color_Blue] = true; + CProfile_Colors[Color_D] = true; + CProfile_Colors[Color_Purple] = true; + CProfile_Colors[Color_Darkrange] = true; + CProfile_Colors[Color_Orange] = true; + CProfile_Colors[Color_Red] = true; + CProfile_Colors[Color_Blue] = true; + CProfile_Colors[Color_Olive] = true; + CProfile_Colors[Color_Darkred] = true; + CProfile_Colors[Color_Lime] = true; + CProfile_Colors[Color_Purple] = true; + CProfile_Colors[Color_Grey] = true; + CProfile_Colors[Color_Orange] = true; + CProfile_TeamIndex[Color_Red] = 2; + CProfile_TeamIndex[Color_Blue] = 3; + CProfile_SayText2 = true; + } + else if (StrEqual(szGameName, "tf", false)) + { + CProfile_Colors[Color_Lightgreen] = true; + CProfile_Colors[Color_Red] = true; + CProfile_Colors[Color_Blue] = true; + CProfile_Colors[Color_Olive] = true; + CProfile_TeamIndex[Color_Lightgreen] = SERVER_INDEX; + CProfile_TeamIndex[Color_Red] = 2; + CProfile_TeamIndex[Color_Blue] = 3; + CProfile_SayText2 = true; + } + else if (StrEqual(szGameName, "left4dead", false) || StrEqual(szGameName, "left4dead2", false)) + { + CProfile_Colors[Color_Lightgreen] = true; + CProfile_Colors[Color_Red] = true; + CProfile_Colors[Color_Blue] = true; + CProfile_Colors[Color_Olive] = true; + CProfile_TeamIndex[Color_Lightgreen] = SERVER_INDEX; + CProfile_TeamIndex[Color_Red] = 3; + CProfile_TeamIndex[Color_Blue] = 2; + CProfile_SayText2 = true; + } + else if (StrEqual(szGameName, "hl2mp", false)) + { + /* hl2mp profile is based on mp_teamplay convar */ + if (GetConVarBool(FindConVar("mp_teamplay"))) + { + CProfile_Colors[Color_Red] = true; + CProfile_Colors[Color_Blue] = true; + CProfile_Colors[Color_Olive] = true; + CProfile_TeamIndex[Color_Red] = 3; + CProfile_TeamIndex[Color_Blue] = 2; + CProfile_SayText2 = true; + } + else + { + CProfile_SayText2 = false; + CProfile_Colors[Color_Olive] = true; + } + } + else if (StrEqual(szGameName, "dod", false)) + { + CProfile_Colors[Color_Olive] = true; + CProfile_SayText2 = false; + } + /* Profile for other games */ + else + { + if (GetUserMessageId("SayText2") == INVALID_MESSAGE_ID) + { + CProfile_SayText2 = false; + } + else + { + CProfile_Colors[Color_Red] = true; + CProfile_Colors[Color_Blue] = true; + CProfile_TeamIndex[Color_Red] = 2; + CProfile_TeamIndex[Color_Blue] = 3; + CProfile_SayText2 = true; + } + } +} + +public Action:CEvent_MapStart(Handle:event, const String:name[], bool:dontBroadcast) +{ + CSetupProfile(); + + for (new i = 1; i <= MaxClients; i++) + CSkipList[i] = false; +} \ No newline at end of file