Add SourceTV_PrintToChat native
Send chat message to one client only
This commit is contained in:
		
							parent
							
								
									31dd491033
								
							
						
					
					
						commit
						ef76571d74
					
				
							
								
								
									
										69
									
								
								natives.cpp
									
									
									
									
									
								
							
							
						
						
									
										69
									
								
								natives.cpp
									
									
									
									
									
								
							@ -38,11 +38,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
extern const sp_nativeinfo_t sourcetv_natives[];
 | 
					extern const sp_nativeinfo_t sourcetv_natives[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Print to client consoles
 | 
				
			||||||
SH_DECL_MANUALHOOK0_void_vafmt(CBaseServer_BroadcastPrintf, 0, 0, 0);
 | 
					SH_DECL_MANUALHOOK0_void_vafmt(CBaseServer_BroadcastPrintf, 0, 0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool g_bHasClientPrintfOffset = false;
 | 
					bool g_bHasClientPrintfOffset = false;
 | 
				
			||||||
 | 
					SH_DECL_MANUALHOOK1_void(CBaseClient_FireGameEvent, 0, 0, 0, IGameEvent *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SetupNativeCalls()
 | 
					void SetupNativeCalls()
 | 
				
			||||||
 | 
					bool g_bHasClientFireGameEventOffset = false;
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int offset = -1;
 | 
						int offset = -1;
 | 
				
			||||||
	if (!g_pGameConf->GetOffset("CBaseServer::BroadcastPrintf", &offset) || offset == -1)
 | 
						if (!g_pGameConf->GetOffset("CBaseServer::BroadcastPrintf", &offset) || offset == -1)
 | 
				
			||||||
@ -54,6 +57,17 @@ void SetupNativeCalls()
 | 
				
			|||||||
		SH_MANUALHOOK_RECONFIGURE(CBaseServer_BroadcastPrintf, offset, 0, 0);
 | 
							SH_MANUALHOOK_RECONFIGURE(CBaseServer_BroadcastPrintf, offset, 0, 0);
 | 
				
			||||||
		g_bHasClientPrintfOffset = true;
 | 
							g_bHasClientPrintfOffset = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						offset = -1;
 | 
				
			||||||
 | 
						if (!g_pGameConf->GetOffset("CBaseClient::FireGameEvent", &offset) || offset == -1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							smutils->LogError(myself, "Failed to get CBaseClient::FireGameEvent offset.");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SH_MANUALHOOK_RECONFIGURE(CBaseClient_FireGameEvent, offset, 0, 0);
 | 
				
			||||||
 | 
							g_bHasClientFireGameEventOffset = true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// native SourceTV_GetServerInstanceCount();
 | 
					// native SourceTV_GetServerInstanceCount();
 | 
				
			||||||
@ -786,6 +800,60 @@ static cell_t Native_KickClient(IPluginContext *pContext, const cell_t *params)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// native SourceTV_PrintToChat(client, const String:format[], any:...);
 | 
				
			||||||
 | 
					static cell_t Native_PrintToChat(IPluginContext *pContext, const cell_t *params)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (hltvserver == nullptr)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cell_t client = params[1];
 | 
				
			||||||
 | 
						if (client < 1 || client > hltvserver->GetBaseServer()->GetClientCount())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							pContext->ReportError("Invalid spectator client index %d.", client);
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						HLTVClientWrapper *pClient = hltvserver->GetClient(client);
 | 
				
			||||||
 | 
						if (!pClient->IsConnected())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							pContext->ReportError("Client %d is not connected.", client);
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char buffer[1024];
 | 
				
			||||||
 | 
						size_t len;
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							DetectExceptions eh(pContext);
 | 
				
			||||||
 | 
							len = smutils->FormatString(buffer, sizeof(buffer), pContext, params, 2);
 | 
				
			||||||
 | 
							if (eh.HasException())
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						IGameEvent *msg = gameevents->CreateEvent("hltv_chat", true);
 | 
				
			||||||
 | 
						if (!msg)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if SOURCE_ENGINE == SE_CSGO
 | 
				
			||||||
 | 
						wchar_t wBuffer[1024];
 | 
				
			||||||
 | 
						V_UTF8ToUnicode(buffer, wBuffer, sizeof(wBuffer));
 | 
				
			||||||
 | 
						msg->SetWString("text", wBuffer);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						msg->SetString("text", buffer);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (g_bHasClientFireGameEventOffset)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							void *pGameClient = pClient->BaseClient();
 | 
				
			||||||
 | 
							// The IClient vtable is +4 from the CBaseClient vtable due to multiple inheritance.
 | 
				
			||||||
 | 
							pGameClient = (void *)((intptr_t)pGameClient - 4);
 | 
				
			||||||
 | 
							SH_MCALL(pGameClient, CBaseClient_FireGameEvent)(msg);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gameevents->FreeEvent(msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const sp_nativeinfo_t sourcetv_natives[] =
 | 
					const sp_nativeinfo_t sourcetv_natives[] =
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	{ "SourceTV_GetServerInstanceCount", Native_GetServerInstanceCount },
 | 
						{ "SourceTV_GetServerInstanceCount", Native_GetServerInstanceCount },
 | 
				
			||||||
@ -822,5 +890,6 @@ const sp_nativeinfo_t sourcetv_natives[] =
 | 
				
			|||||||
	{ "SourceTV_GetClientIP", Native_GetClientIP },
 | 
						{ "SourceTV_GetClientIP", Native_GetClientIP },
 | 
				
			||||||
	{ "SourceTV_GetClientPassword", Native_GetClientPassword },
 | 
						{ "SourceTV_GetClientPassword", Native_GetClientPassword },
 | 
				
			||||||
	{ "SourceTV_KickClient", Native_KickClient },
 | 
						{ "SourceTV_KickClient", Native_KickClient },
 | 
				
			||||||
 | 
						{ "SourceTV_PrintToChat", Native_PrintToChat },
 | 
				
			||||||
	{ NULL, NULL },
 | 
						{ NULL, NULL },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -34,6 +34,7 @@ public OnPluginStart()
 | 
				
			|||||||
	RegConsoleCmd("sm_democonsole", Cmd_PrintDemoConsole);
 | 
						RegConsoleCmd("sm_democonsole", Cmd_PrintDemoConsole);
 | 
				
			||||||
	RegConsoleCmd("sm_botcmd", Cmd_ExecuteStringCommand);
 | 
						RegConsoleCmd("sm_botcmd", Cmd_ExecuteStringCommand);
 | 
				
			||||||
	RegConsoleCmd("sm_speckick", Cmd_KickClient);
 | 
						RegConsoleCmd("sm_speckick", Cmd_KickClient);
 | 
				
			||||||
 | 
						RegConsoleCmd("sm_specchatone", Cmd_PrintToChat);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public SourceTV_OnStartRecording(instance, const String:filename[])
 | 
					public SourceTV_OnStartRecording(instance, const String:filename[])
 | 
				
			||||||
@ -413,7 +414,7 @@ public Action:Cmd_ExecuteStringCommand(client, args)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
public Action:Cmd_KickClient(client, args)
 | 
					public Action:Cmd_KickClient(client, args)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (args < 1)
 | 
						if (args < 2)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		ReplyToCommand(client, "Usage: sm_speckick <index> <reason>");
 | 
							ReplyToCommand(client, "Usage: sm_speckick <index> <reason>");
 | 
				
			||||||
		return Plugin_Handled;
 | 
							return Plugin_Handled;
 | 
				
			||||||
@ -430,3 +431,23 @@ public Action:Cmd_KickClient(client, args)
 | 
				
			|||||||
	ReplyToCommand(client, "SourceTV kicking spectator %d with reason %s", iTarget, sMsg);
 | 
						ReplyToCommand(client, "SourceTV kicking spectator %d with reason %s", iTarget, sMsg);
 | 
				
			||||||
	return Plugin_Handled;
 | 
						return Plugin_Handled;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public Action:Cmd_PrintToChat(client, args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (args < 2)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ReplyToCommand(client, "Usage: sm_specchatone <index> <message>");
 | 
				
			||||||
 | 
							return Plugin_Handled;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						new String:sIndex[16], String:sMsg[1024];
 | 
				
			||||||
 | 
						GetCmdArg(1, sIndex, sizeof(sIndex));
 | 
				
			||||||
 | 
						StripQuotes(sIndex);
 | 
				
			||||||
 | 
						GetCmdArg(2, sMsg, sizeof(sMsg));
 | 
				
			||||||
 | 
						StripQuotes(sMsg);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						new iTarget = StringToInt(sIndex);
 | 
				
			||||||
 | 
						SourceTV_PrintToChat(iTarget, "%s", sMsg);
 | 
				
			||||||
 | 
						ReplyToCommand(client, "SourceTV sending chat message to spectator %d: %s", iTarget, sMsg);
 | 
				
			||||||
 | 
						return Plugin_Handled;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -63,6 +63,12 @@
 | 
				
			|||||||
				"linux"	"65"
 | 
									"linux"	"65"
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
 | 
								"CBaseClient::FireGameEvent"
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									"windows"	"1"
 | 
				
			||||||
 | 
									"linux"	"2"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
			"CBaseClient::Disconnect"
 | 
								"CBaseClient::Disconnect"
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				"linux"	"16"
 | 
									"linux"	"16"
 | 
				
			||||||
@ -230,6 +236,12 @@
 | 
				
			|||||||
				"linux"	"56"
 | 
									"linux"	"56"
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
 | 
								"CBaseClient::FireGameEvent"
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									"windows"	"1"
 | 
				
			||||||
 | 
									"linux"	"2"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
			"CBaseClient::Disconnect"
 | 
								"CBaseClient::Disconnect"
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				"linux"	"14"
 | 
									"linux"	"14"
 | 
				
			||||||
 | 
				
			|||||||
@ -393,6 +393,16 @@ native SourceTV_GetClientPassword(client, String:password[], maxlen);
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
native SourceTV_KickClient(client, const String:sReason[]);
 | 
					native SourceTV_KickClient(client, const String:sReason[]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Print a message to a single client's chat.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * @param client	The spectator client index.
 | 
				
			||||||
 | 
					 * @param format	The format string.
 | 
				
			||||||
 | 
					 * @param ...	Variable number of format string arguments.
 | 
				
			||||||
 | 
					 * @noreturn
 | 
				
			||||||
 | 
					 * @error	Invalid client index or not connected.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					native SourceTV_PrintToChat(client, const String:format[], any:...);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Called when a spectator wants to connect to the SourceTV server.
 | 
					 * Called when a spectator wants to connect to the SourceTV server.
 | 
				
			||||||
@ -520,5 +530,6 @@ public __ext_stvmngr_SetNTVOptional()
 | 
				
			|||||||
	MarkNativeAsOptional("SourceTV_GetClientIP");
 | 
						MarkNativeAsOptional("SourceTV_GetClientIP");
 | 
				
			||||||
	MarkNativeAsOptional("SourceTV_GetClientPassword");
 | 
						MarkNativeAsOptional("SourceTV_GetClientPassword");
 | 
				
			||||||
	MarkNativeAsOptional("SourceTV_KickClient");
 | 
						MarkNativeAsOptional("SourceTV_KickClient");
 | 
				
			||||||
 | 
						MarkNativeAsOptional("SourceTV_PrintToChat");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user