diff --git a/core/smn_player.cpp b/core/smn_player.cpp index 33b5b826..7dcf79de 100644 --- a/core/smn_player.cpp +++ b/core/smn_player.cpp @@ -1467,6 +1467,90 @@ static cell_t ProcessTargetString(IPluginContext *pContext, const cell_t *params } } +static cell_t FormatActivitySource(IPluginContext *pContext, const cell_t *params) +{ + int value; + int client; + int target; + CPlayer *pTarget; + AdminId aidTarget; + const char *identity[2] = {"Console", "ADMIN"}; + + client = params[1]; + target = params[2]; + + if ((pTarget = g_Players.GetPlayerByIndex(target)) == NULL) + { + return pContext->ThrowNativeError("Invalid client index %d", target); + } + if (!pTarget->IsConnected()) + { + return pContext->ThrowNativeError("Client %d not connected", target); + } + + value = sm_show_activity.GetInt(); + + if (client != 0) + { + CPlayer *pPlayer; + + if ((pPlayer = g_Players.GetPlayerByIndex(client)) == NULL) + { + return pContext->ThrowNativeError("Invalid client index %d", client); + } + if (!pPlayer->IsConnected()) + { + return pContext->ThrowNativeError("Client %d not connected", client); + } + + identity[0] = pPlayer->GetName(); + + AdminId id = pPlayer->GetAdminId(); + if (id == INVALID_ADMIN_ID + || !g_Admins.GetAdminFlag(id, Admin_Generic, Access_Effective)) + { + identity[1] = "PLAYER"; + } + } + + int mode = 1; + bool bShowActivity = false; + + if ((aidTarget = pTarget->GetAdminId()) == INVALID_ADMIN_ID + || !g_Admins.GetAdminFlag(aidTarget, Admin_Generic, Access_Effective)) + { + /* Treat this as a normal user */ + if ((value & 1) || (value & 2)) + { + if ((value & 2) || (target == client)) + { + mode = 0; + } + bShowActivity = true; + } + } + else + { + /* Treat this as an admin user */ + bool is_root = g_Admins.GetAdminFlag(aidTarget, Admin_Root, Access_Effective); + if ((value & 4) + || (value & 8) + || ((value & 16) && is_root)) + { + if ((value & 8) || ((value & 16) && is_root) || (target == client)) + { + mode = 0; + } + bShowActivity = true; + } + } + + /* Otherwise, send it back to the script. */ + pContext->StringToLocalUTF8(params[3], params[4], identity[mode], NULL); + + return bShowActivity ? 1 : 0; +} + REGISTER_NATIVES(playernatives) { {"AddUserFlags", AddUserFlags}, @@ -1519,6 +1603,7 @@ REGISTER_NATIVES(playernatives) {"NotifyPostAdminCheck", NotifyPostAdminCheck}, {"IsClientInKickQueue", IsClientInKickQueue}, {"ProcessTargetString", ProcessTargetString}, + {"FormatActivitySource", FormatActivitySource}, {NULL, NULL} }; diff --git a/plugins/basechat.sp b/plugins/basechat.sp index f37a01df..3d968352 100644 --- a/plugins/basechat.sp +++ b/plugins/basechat.sp @@ -114,12 +114,12 @@ public Action:Command_SayChat(client, args) if (msgStart == 1 && CheckCommandAccess(client, "sm_say", ADMFLAG_CHAT)) // sm_say alias { - SendChatToAll(name, message); + SendChatToAll(client, message); LogAction(client, -1, "%L triggered sm_say (text %s)", client, message); } else if (msgStart == 3 && CheckCommandAccess(client, "sm_csay", ADMFLAG_CHAT)) // sm_csay alias { - PrintCenterTextAll("%s: %s", name, message); + DisplayCenterTextToAll(client, message); LogAction(client, -1, "%L triggered sm_csay (text %s)", client, text); } else if (msgStart == 2 && CheckCommandAccess(client, "sm_psay", ADMFLAG_CHAT)) // sm_psay alias @@ -200,10 +200,7 @@ public Action:Command_SmSay(client, args) decl String:text[192]; GetCmdArgString(text, sizeof(text)); - decl String:name[64]; - GetClientName(client, name, sizeof(name)); - - SendChatToAll(name, text); + SendChatToAll(client, text); LogAction(client, -1, "%L triggered sm_say (text %s)", client, text); return Plugin_Handled; @@ -219,11 +216,9 @@ public Action:Command_SmCsay(client, args) decl String:text[192]; GetCmdArgString(text, sizeof(text)); - - new String:name[64]; - GetClientName(client, name, sizeof(name)); - PrintCenterTextAll("%s: %s", name, text); + DisplayCenterTextToAll(client, text); + LogAction(client, -1, "%L triggered sm_csay (text %s)", client, text); return Plugin_Handled; @@ -236,17 +231,26 @@ public Action:Command_SmHsay(client, args) ReplyToCommand(client, "[SM] Usage: sm_hsay "); return Plugin_Handled; } - + decl String:text[192]; GetCmdArgString(text, sizeof(text)); - decl String:name[64]; - GetClientName(client, name, sizeof(name)); - - PrintHintTextToAll("%s: %s", name, text); + decl String:nameBuf[MAX_NAME_LENGTH]; + + new maxClients = GetMaxClients(); + for (new i = 1; i <= maxClients; i++) + { + if (!IsClientConnected(i) || IsFakeClient(i)) + { + continue; + } + FormatActivitySource(client, i, nameBuf, sizeof(nameBuf)); + PrintHintText(i, "%s: %s", nameBuf, text); + } + LogAction(client, -1, "%L triggered sm_hsay (text %s)", client, text); - - return Plugin_Handled; + + return Plugin_Handled; } public Action:Command_SmTsay(client, args) @@ -256,7 +260,7 @@ public Action:Command_SmTsay(client, args) ReplyToCommand(client, "[SM] Usage: sm_tsay "); return Plugin_Handled; } - + decl String:text[192], String:colorStr[16]; GetCmdArgString(text, sizeof(text)); @@ -266,15 +270,28 @@ public Action:Command_SmTsay(client, args) GetClientName(client, name, sizeof(name)); new color = FindColor(colorStr); - - if (color == -1) - SendDialogToAll(_, "%s: %s", name, text); - else - SendDialogToAll(color, "%s: %s", name, text[len]); + new maxClients = GetMaxClients(); + new String:nameBuf[MAX_NAME_LENGTH]; + + if (color == -1) + { + color = 0; + len = 0; + } + + for (new i = 1; i <= maxClients; i++) + { + if (!IsClientConnected(i) || IsFakeClient(i)) + { + continue; + } + FormatActivitySource(client, i, nameBuf, sizeof(nameBuf)); + SendDialogToOne(i, color, "%s: %s", nameBuf, text[len]); + } LogAction(client, -1, "%L triggered sm_tsay (text %s)", client, text); - - return Plugin_Handled; + + return Plugin_Handled; } public Action:Command_SmChat(client, args) @@ -388,15 +405,44 @@ FindColor(String:color[]) return -1; } -SendChatToAll(String:name[], String:message[]) +SendChatToAll(client, String:message[]) { - if (g_DoColor) + new maxClients; + new String:nameBuf[MAX_NAME_LENGTH]; + + maxClients = GetMaxClients(); + for (new i = 1; i <= maxClients; i++) { - PrintToChatAll("\x04(ALL) %s: \x01%s", name, message); + if (!IsClientConnected(i) || IsFakeClient(i)) + { + continue; + } + FormatActivitySource(client, i, nameBuf, sizeof(nameBuf)); + + if (g_DoColor) + { + PrintToChat(i, "\x04(ALL) %s: \x01%s", nameBuf, message); + } + else + { + PrintToChat(i, "%s: %s", nameBuf, message); + } } - else +} + +DisplayCenterTextToAll(client, String:message[]) +{ + new String:nameBuf[MAX_NAME_LENGTH]; + new maxClients = GetMaxClients(); + + for (new i = 1; i < maxClients; i++) { - PrintToChatAll("(ALL) %s: %s", name, message); + if (!IsClientConnected(i) || IsFakeClient(i)) + { + continue; + } + FormatActivitySource(client, i, nameBuf, sizeof(nameBuf)); + PrintCenterText(i, "%s: %s", nameBuf, message); } } @@ -423,26 +469,19 @@ SendChatToAdmins(String:name[], String:message[]) } } -SendDialogToAll(color = 0, String:text[], any:...) +SendDialogToOne(client, color, String:text[], any:...) { new String:message[100]; - VFormat(message, sizeof(message), text, 3); + VFormat(message, sizeof(message), text, 4); - new MaxClients = GetMaxClients(); - for(new i = 1; i < MaxClients; i++) - { - if(IsClientInGame(i)) - { - new Handle:kv = CreateKeyValues("Stuff", "title", message); - KvSetColor(kv, "color", g_Colors[color][0], g_Colors[color][1], g_Colors[color][2], 255); - KvSetNum(kv, "level", 1); - KvSetNum(kv, "time", 10); - - CreateDialog(i, kv, DialogType_Msg); - - CloseHandle(kv); - } - } + new Handle:kv = CreateKeyValues("Stuff", "title", message); + KvSetColor(kv, "color", g_Colors[color][0], g_Colors[color][1], g_Colors[color][2], 255); + KvSetNum(kv, "level", 1); + KvSetNum(kv, "time", 10); + + CreateDialog(client, kv, DialogType_Msg); + + CloseHandle(kv); } SendPanelToAll(String:name[], String:message[]) diff --git a/plugins/include/console.inc b/plugins/include/console.inc index 9b450f12..cded17c8 100644 --- a/plugins/include/console.inc +++ b/plugins/include/console.inc @@ -286,6 +286,24 @@ native ShowActivity(client, const String:format[], any:...); */ native ShowActivityEx(client, const String:tag[], const String:format[], any:...); +/** + * Given an originating client and a target client, returns the string + * that describes the originating client according to the sm_show_activity cvar. + * + * For example, "ADMIN", "PLAYER", or a player's name could be placed in this buffer. + * + * @param client Originating client; may be 0 for server console. + * @param target Targeted client. + * @param namebuf Name buffer. + * @param maxlength Maximum size of the name buffer. + * @return True if activity should be shown. False otherwise. In either + * case, the name buffer is filled. The return value can be used + * to broadcast a "safe" name to all players regardless of the + * sm_show_activity filters. + * @error Invalid client index or client not connected. + */ +native FormatActivitySource(client, target, const String:namebuf[], maxlength); + /** * Called when a server-only command is invoked. *