plugins/basechat.sp
author David Anderson <dvander@alliedmods.net>
Tue May 12 19:06:57 2009 -0400 (2009-05-12)
changeset 2723 d8cde305bb14
parent 2583 d3b2571c378b
child 2759 67086a60e829
permissions -rw-r--r--
Central place to mark releases so buildbot symbols aren't scrapped by purge script (bug 3809, r=me, a12=NPOTB).
     1 /**
     2  * vim: set ts=4 :
     3  * =============================================================================
     4  * SourceMod Basic Chat Plugin
     5  * Implements basic communication commands.
     6  *
     7  * SourceMod (C)2004-2008 AlliedModders LLC.  All rights reserved.
     8  * =============================================================================
     9  *
    10  * This program is free software; you can redistribute it and/or modify it under
    11  * the terms of the GNU General Public License, version 3.0, as published by the
    12  * Free Software Foundation.
    13  * 
    14  * This program is distributed in the hope that it will be useful, but WITHOUT
    15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    16  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    17  * details.
    18  *
    19  * You should have received a copy of the GNU General Public License along with
    20  * this program.  If not, see <http://www.gnu.org/licenses/>.
    21  *
    22  * As a special exception, AlliedModders LLC gives you permission to link the
    23  * code of this program (as well as its derivative works) to "Half-Life 2," the
    24  * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    25  * by the Valve Corporation.  You must obey the GNU General Public License in
    26  * all respects for all other code used.  Additionally, AlliedModders LLC grants
    27  * this exception to all derivative works.  AlliedModders LLC defines further
    28  * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    29  * or <http://www.sourcemod.net/license.php>.
    30  *
    31  * Version: $Id$
    32  */
    33 
    34 #pragma semicolon 1
    35 
    36 #include <sourcemod>
    37 
    38 public Plugin:myinfo = 
    39 {
    40 	name = "Basic Chat",
    41 	author = "AlliedModders LLC",
    42 	description = "Basic Communication Commands",
    43 	version = SOURCEMOD_VERSION,
    44 	url = "http://www.sourcemod.net/"
    45 };
    46 
    47 #define CHAT_SYMBOL '@'
    48 
    49 new String:g_ColorNames[13][10] = {"White", "Red", "Green", "Blue", "Yellow", "Purple", "Cyan", "Orange", "Pink", "Olive", "Lime", "Violet", "Lightblue"};
    50 new g_Colors[13][3] = {{255,255,255},{255,0,0},{0,255,0},{0,0,255},{255,255,0},{255,0,255},{0,255,255},{255,128,0},{255,0,128},{128,255,0},{0,255,128},{128,0,255},{0,128,255}};
    51 
    52 new Handle:g_Cvar_Chatmode = INVALID_HANDLE;
    53 
    54 new bool:g_DoColor = true;
    55 
    56 new g_GameEngine = SOURCE_SDK_UNKNOWN;
    57 
    58 public OnPluginStart()
    59 {
    60 	LoadTranslations("common.phrases");
    61 	
    62 	g_GameEngine = GuessSDKVersion();
    63 
    64 	g_Cvar_Chatmode = CreateConVar("sm_chat_mode", "1", "Allows player's to send messages to admin chat.", 0, true, 0.0, true, 1.0);
    65 
    66 	RegConsoleCmd("say", Command_SayChat);
    67 	RegConsoleCmd("say_team", Command_SayAdmin);		
    68 	RegAdminCmd("sm_say", Command_SmSay, ADMFLAG_CHAT, "sm_say <message> - sends message to all players");
    69 	RegAdminCmd("sm_csay", Command_SmCsay, ADMFLAG_CHAT, "sm_csay <message> - sends centered message to all players");
    70 	
    71 	/* HintText does not work on Dark Messiah */
    72 	if (g_GameEngine != SOURCE_SDK_DARKMESSIAH)
    73 	{
    74 		RegAdminCmd("sm_hsay", Command_SmHsay, ADMFLAG_CHAT, "sm_hsay <message> - sends hint message to all players");	
    75 	}
    76 	
    77 	RegAdminCmd("sm_tsay", Command_SmTsay, ADMFLAG_CHAT, "sm_tsay [color] <message> - sends top-left message to all players");
    78 	RegAdminCmd("sm_chat", Command_SmChat, ADMFLAG_CHAT, "sm_chat <message> - sends message to admins");
    79 	RegAdminCmd("sm_psay", Command_SmPsay, ADMFLAG_CHAT, "sm_psay <name or #userid> <message> - sends private message");
    80 	RegAdminCmd("sm_msay", Command_SmMsay, ADMFLAG_CHAT, "sm_msay <message> - sends message as a menu panel");
    81 	
    82 	decl String:modname[64];
    83 	GetGameFolderName(modname, sizeof(modname));
    84 	
    85 	if (strcmp(modname, "hl2mp") == 0)
    86 	{
    87 		g_DoColor = false;
    88 	}
    89 }
    90 
    91 public Action:Command_SayChat(client, args)
    92 {	
    93 	decl String:text[192];
    94 	if (IsChatTrigger() || GetCmdArgString(text, sizeof(text)) < 1)
    95 	{
    96 		return Plugin_Continue;
    97 	}
    98 	
    99 	new startidx;
   100 	if (text[strlen(text)-1] == '"')
   101 	{
   102 		text[strlen(text)-1] = '\0';
   103 		startidx = 1;
   104 	}
   105 	
   106 	if (text[startidx] != CHAT_SYMBOL)
   107 		return Plugin_Continue;
   108 	
   109 	new msgStart = 1;
   110 	
   111 	if (text[startidx+1] == CHAT_SYMBOL)
   112 	{
   113 		msgStart = 2;
   114 		
   115 		if (text[startidx+2] == CHAT_SYMBOL)
   116 			msgStart = 3;
   117 	}
   118 	
   119 	decl String:message[192];
   120 	strcopy(message, 192, text[startidx+msgStart]);
   121 	
   122 	decl String:name[64];
   123 	GetClientName(client, name, sizeof(name));
   124 	
   125 	if (msgStart == 1 && CheckCommandAccess(client, "sm_say", ADMFLAG_CHAT)) // sm_say alias
   126 	{
   127 		SendChatToAll(client, message);
   128 		LogAction(client, -1, "%L triggered sm_say (text %s)", client, message);
   129 	}
   130 	else if (msgStart == 3 && CheckCommandAccess(client, "sm_csay", ADMFLAG_CHAT)) // sm_csay alias
   131 	{
   132 		DisplayCenterTextToAll(client, message);
   133 		LogAction(client, -1, "%L triggered sm_csay (text %s)", client, text);		
   134 	}	
   135 	else if (msgStart == 2 && CheckCommandAccess(client, "sm_psay", ADMFLAG_CHAT)) // sm_psay alias
   136 	{
   137 		decl String:arg[64];
   138 	
   139 		new len = BreakString(message, arg, sizeof(arg));
   140 		new target = FindTarget(client, arg, true, false);
   141 		
   142 		if (target == -1 || len == -1)
   143 			return Plugin_Handled;
   144 		
   145 		decl String:name2[64];
   146 		GetClientName(target, name2, sizeof(name2));
   147 	
   148 		if (g_DoColor)
   149 		{
   150 			PrintToChat(client, "\x04(Private to %s) %s: \x01%s", name2, name, message[len]);
   151 			PrintToChat(target, "\x04(Private to %s) %s: \x01%s", name2, name, message[len]);
   152 		}
   153 		else
   154 		{
   155 			PrintToChat(client, "(Private to %s) %s: %s", name2, name, message[len]);
   156 			PrintToChat(target, "(Private to %s) %s: %s", name2, name, message[len]);			
   157 		}
   158 
   159 		LogAction(client, -1, "%L triggered sm_psay to %L (text %s)", client, target, message);		
   160 	}
   161 	else
   162 		return Plugin_Continue;
   163 	
   164 	return Plugin_Handled;	
   165 }
   166 
   167 public Action:Command_SayAdmin(client, args)
   168 {
   169 	if (!CheckCommandAccess(client, "sm_chat", ADMFLAG_CHAT) && !GetConVarBool(g_Cvar_Chatmode))
   170 	{
   171 		return Plugin_Continue;	
   172 	}
   173 	
   174 	decl String:text[192];
   175 	if (IsChatTrigger() || GetCmdArgString(text, sizeof(text)) < 1)
   176 	{
   177 		return Plugin_Continue;
   178 	}
   179 	
   180 	new startidx;
   181 	if (text[strlen(text)-1] == '"')
   182 	{
   183 		text[strlen(text)-1] = '\0';
   184 		startidx = 1;
   185 	}
   186 	
   187 	if (text[startidx] != CHAT_SYMBOL)
   188 		return Plugin_Continue;
   189 	
   190 	decl String:message[192];
   191 	strcopy(message, 192, text[startidx+1]);
   192 
   193 	decl String:name[64];
   194 	GetClientName(client, name, sizeof(name));
   195 	
   196 	SendChatToAdmins(name, message);
   197 	LogAction(client, -1, "%L triggered sm_chat (text %s)", client, message);
   198 	
   199 	return Plugin_Handled;	
   200 }
   201 
   202 public Action:Command_SmSay(client, args)
   203 {
   204 	if (args < 1)
   205 	{
   206 		ReplyToCommand(client, "[SM] Usage: sm_say <message>");
   207 		return Plugin_Handled;	
   208 	}
   209 	
   210 	decl String:text[192];
   211 	GetCmdArgString(text, sizeof(text));
   212 
   213 	SendChatToAll(client, text);
   214 	LogAction(client, -1, "%L triggered sm_say (text %s)", client, text);
   215 	
   216 	return Plugin_Handled;		
   217 }
   218 
   219 public Action:Command_SmCsay(client, args)
   220 {
   221 	if (args < 1)
   222 	{
   223 		ReplyToCommand(client, "[SM] Usage: sm_csay <message>");
   224 		return Plugin_Handled;	
   225 	}
   226 	
   227 	decl String:text[192];
   228 	GetCmdArgString(text, sizeof(text));
   229 	
   230 	DisplayCenterTextToAll(client, text);
   231 	
   232 	LogAction(client, -1, "%L triggered sm_csay (text %s)", client, text);
   233 	
   234 	return Plugin_Handled;		
   235 }
   236 
   237 public Action:Command_SmHsay(client, args)
   238 {
   239 	if (args < 1)
   240 	{
   241 		ReplyToCommand(client, "[SM] Usage: sm_hsay <message>");
   242 		return Plugin_Handled;  
   243 	}
   244 	
   245 	decl String:text[192];
   246 	GetCmdArgString(text, sizeof(text));
   247  
   248 	decl String:nameBuf[MAX_NAME_LENGTH];
   249 	
   250 	for (new i = 1; i <= MaxClients; i++)
   251 	{
   252 		if (!IsClientInGame(i) || IsFakeClient(i))
   253 		{
   254 			continue;
   255 		}
   256 		FormatActivitySource(client, i, nameBuf, sizeof(nameBuf));
   257 		PrintHintText(i, "%s: %s", nameBuf, text);
   258 	}
   259 	
   260 	LogAction(client, -1, "%L triggered sm_hsay (text %s)", client, text);
   261 	
   262 	return Plugin_Handled;	
   263 }
   264 
   265 public Action:Command_SmTsay(client, args)
   266 {
   267 	if (args < 1)
   268 	{
   269 		ReplyToCommand(client, "[SM] Usage: sm_tsay <message>");
   270 		return Plugin_Handled;  
   271 	}
   272 	
   273 	decl String:text[192], String:colorStr[16];
   274 	GetCmdArgString(text, sizeof(text));
   275 	
   276 	new len = BreakString(text, colorStr, 16);
   277  
   278 	decl String:name[64];
   279 	GetClientName(client, name, sizeof(name));
   280 		
   281 	new color = FindColor(colorStr);
   282 	new String:nameBuf[MAX_NAME_LENGTH];
   283 	
   284 	if (color == -1)
   285 	{
   286 		color = 0;
   287 		len = 0;
   288 	}
   289 	
   290 	for (new i = 1; i <= MaxClients; i++)
   291 	{
   292 		if (!IsClientInGame(i) || IsFakeClient(i))
   293 		{
   294 			continue;
   295 		}
   296 		FormatActivitySource(client, i, nameBuf, sizeof(nameBuf));
   297 		SendDialogToOne(i, color, "%s: %s", nameBuf, text[len]);
   298 	}
   299 
   300 	LogAction(client, -1, "%L triggered sm_tsay (text %s)", client, text);
   301 	
   302 	return Plugin_Handled;	
   303 }
   304 
   305 public Action:Command_SmChat(client, args)
   306 {
   307 	if (args < 1)
   308 	{
   309 		ReplyToCommand(client, "[SM] Usage: sm_chat <message>");
   310 		return Plugin_Handled;	
   311 	}	
   312 	
   313 	decl String:text[192];
   314 	GetCmdArgString(text, sizeof(text));
   315 
   316 	decl String:name[64];
   317 	GetClientName(client, name, sizeof(name));
   318 	
   319 	SendChatToAdmins(name, text);
   320 	LogAction(client, -1, "%L triggered sm_chat (text %s)", client, text);
   321 	
   322 	return Plugin_Handled;	
   323 }
   324 
   325 public Action:Command_SmPsay(client, args)
   326 {
   327 	if (args < 2)
   328 	{
   329 		ReplyToCommand(client, "[SM] Usage: sm_psay <name or #userid> <message>");
   330 		return Plugin_Handled;	
   331 	}	
   332 	
   333 	decl String:text[192], String:arg[64], String:message[192];
   334 	GetCmdArgString(text, sizeof(text));
   335 
   336 	new len = BreakString(text, arg, sizeof(arg));
   337 	BreakString(text[len], message, sizeof(message));
   338 	
   339 	new target = FindTarget(client, arg, true, false);
   340 		
   341 	if (target == -1)
   342 		return Plugin_Handled;	
   343 		
   344 	decl String:name[64], String:name2[64];
   345 
   346 	if (client == 0)
   347 	{
   348 		name = "Console";
   349 	}
   350 	else
   351 	{
   352 		GetClientName(client, name, sizeof(name));
   353 	}
   354 
   355 	GetClientName(target, name2, sizeof(name2));
   356 
   357 	if (client == 0)
   358 	{
   359 		PrintToServer("(Private: %s) %s: %s", name2, name, message);
   360 	}
   361 	else if (g_DoColor)
   362 	{
   363 		PrintToChat(client, "\x04(Private: %s) %s: \x01%s", name2, name, message);
   364 	}
   365 	else
   366 	{
   367 		PrintToChat(client, "(Private: %s) %s: %s", name2, name, message);
   368 	}
   369 
   370 	if (g_DoColor)
   371 	{
   372 		PrintToChat(target, "\x04(Private: %s) %s: \x01%s", name2, name, message);
   373 	}
   374 	else
   375 	{
   376 		PrintToChat(target, "(Private: %s) %s: %s", name2, name, message);		
   377 	}
   378 
   379 	LogAction(client, -1, "%L triggered sm_psay to %L (text %s)", client, target, message);
   380 	
   381 	return Plugin_Handled;	
   382 }
   383 
   384 public Action:Command_SmMsay(client, args)
   385 {
   386 	if (args < 1)
   387 	{
   388 		ReplyToCommand(client, "[SM] Usage: sm_msay <message>");
   389 		return Plugin_Handled;	
   390 	}
   391 	
   392 	decl String:text[192];
   393 	GetCmdArgString(text, sizeof(text));
   394 
   395 	decl String:name[64];
   396 	GetClientName(client, name, sizeof(name));
   397 		
   398 	SendPanelToAll(name, text);
   399 
   400 	LogAction(client, -1, "%L triggered sm_msay (text %s)", client, text);
   401 	
   402 	return Plugin_Handled;		
   403 }
   404 
   405 FindColor(String:color[])
   406 {
   407 	for (new i = 0; i < 13; i++)
   408 	{
   409 		if (strcmp(color, g_ColorNames[i], false) == 0)
   410 			return i;
   411 	}
   412 	
   413 	return -1;
   414 }
   415 
   416 SendChatToAll(client, String:message[])
   417 {
   418 	new String:nameBuf[MAX_NAME_LENGTH];
   419 	
   420 	for (new i = 1; i <= MaxClients; i++)
   421 	{
   422 		if (!IsClientInGame(i) || IsFakeClient(i))
   423 		{
   424 			continue;
   425 		}
   426 		FormatActivitySource(client, i, nameBuf, sizeof(nameBuf));
   427 		
   428 		if (g_DoColor)
   429 		{
   430 			PrintToChat(i, "\x04(ALL) %s: \x01%s", nameBuf, message);
   431 		}
   432 		else
   433 		{
   434 			PrintToChat(i, "%s: %s", nameBuf, message);
   435 		}
   436 	}
   437 }
   438 
   439 DisplayCenterTextToAll(client, String:message[])
   440 {
   441 	new String:nameBuf[MAX_NAME_LENGTH];
   442 	
   443 	for (new i = 1; i < MaxClients; i++)
   444 	{
   445 		if (!IsClientInGame(i) || IsFakeClient(i))
   446 		{
   447 			continue;
   448 		}
   449 		FormatActivitySource(client, i, nameBuf, sizeof(nameBuf));
   450 		PrintCenterText(i, "%s: %s", nameBuf, message);
   451 	}
   452 }
   453 
   454 SendChatToAdmins(String:name[], String:message[])
   455 {
   456 	for (new i = 1; i <= MaxClients; i++)
   457 	{
   458 		if (IsClientInGame(i))
   459 		{
   460 			if (CheckCommandAccess(i, "sm_chat", ADMFLAG_CHAT))
   461 			{
   462 				if (g_DoColor)
   463 				{
   464 					PrintToChat(i, "\x04(ADMINS) %s: \x01%s", name, message);
   465 				}
   466 				else
   467 				{
   468 					PrintToChat(i, "(ADMINS) %s: %s", name, message);
   469 				}
   470 			}
   471 		}	
   472 	}
   473 }
   474 
   475 SendDialogToOne(client, color, String:text[], any:...)
   476 {
   477 	new String:message[100];
   478 	VFormat(message, sizeof(message), text, 4);	
   479 	
   480 	new Handle:kv = CreateKeyValues("Stuff", "title", message);
   481 	KvSetColor(kv, "color", g_Colors[color][0], g_Colors[color][1], g_Colors[color][2], 255);
   482 	KvSetNum(kv, "level", 1);
   483 	KvSetNum(kv, "time", 10);
   484 	
   485 	CreateDialog(client, kv, DialogType_Msg);
   486 	
   487 	CloseHandle(kv);	
   488 }
   489 
   490 SendPanelToAll(String:name[], String:message[])
   491 {
   492 	decl String:title[100];
   493 	Format(title, 64, "%s:", name);
   494 	
   495 	ReplaceString(message, 192, "\\n", "\n");
   496 	
   497 	new Handle:mSayPanel = CreatePanel();
   498 	SetPanelTitle(mSayPanel, title);
   499 	DrawPanelItem(mSayPanel, "", ITEMDRAW_SPACER);
   500 	DrawPanelText(mSayPanel, message);
   501 	DrawPanelItem(mSayPanel, "", ITEMDRAW_SPACER);
   502 
   503 	SetPanelCurrentKey(mSayPanel, 10);
   504 	DrawPanelItem(mSayPanel, "Exit", ITEMDRAW_CONTROL);
   505 
   506 	for(new i = 1; i <= MaxClients; i++)
   507 	{
   508 		if(IsClientInGame(i) && !IsFakeClient(i))
   509 		{
   510 			SendPanelToClient(mSayPanel, i, Handler_DoNothing, 10);
   511 		}
   512 	}
   513 
   514 	CloseHandle(mSayPanel);
   515 }
   516 
   517 public Handler_DoNothing(Handle:menu, MenuAction:action, param1, param2)
   518 {
   519 	/* Do nothing */
   520 }