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[];
 | 
			
		||||
 | 
			
		||||
// Print to client consoles
 | 
			
		||||
SH_DECL_MANUALHOOK0_void_vafmt(CBaseServer_BroadcastPrintf, 0, 0, 0);
 | 
			
		||||
 | 
			
		||||
bool g_bHasClientPrintfOffset = false;
 | 
			
		||||
SH_DECL_MANUALHOOK1_void(CBaseClient_FireGameEvent, 0, 0, 0, IGameEvent *);
 | 
			
		||||
 | 
			
		||||
void SetupNativeCalls()
 | 
			
		||||
bool g_bHasClientFireGameEventOffset = false;
 | 
			
		||||
{
 | 
			
		||||
	int 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);
 | 
			
		||||
		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();
 | 
			
		||||
@ -786,6 +800,60 @@ static cell_t Native_KickClient(IPluginContext *pContext, const cell_t *params)
 | 
			
		||||
	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[] =
 | 
			
		||||
{
 | 
			
		||||
	{ "SourceTV_GetServerInstanceCount", Native_GetServerInstanceCount },
 | 
			
		||||
@ -822,5 +890,6 @@ const sp_nativeinfo_t sourcetv_natives[] =
 | 
			
		||||
	{ "SourceTV_GetClientIP", Native_GetClientIP },
 | 
			
		||||
	{ "SourceTV_GetClientPassword", Native_GetClientPassword },
 | 
			
		||||
	{ "SourceTV_KickClient", Native_KickClient },
 | 
			
		||||
	{ "SourceTV_PrintToChat", Native_PrintToChat },
 | 
			
		||||
	{ NULL, NULL },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -34,6 +34,7 @@ public OnPluginStart()
 | 
			
		||||
	RegConsoleCmd("sm_democonsole", Cmd_PrintDemoConsole);
 | 
			
		||||
	RegConsoleCmd("sm_botcmd", Cmd_ExecuteStringCommand);
 | 
			
		||||
	RegConsoleCmd("sm_speckick", Cmd_KickClient);
 | 
			
		||||
	RegConsoleCmd("sm_specchatone", Cmd_PrintToChat);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public SourceTV_OnStartRecording(instance, const String:filename[])
 | 
			
		||||
@ -413,7 +414,7 @@ public Action:Cmd_ExecuteStringCommand(client, args)
 | 
			
		||||
 | 
			
		||||
public Action:Cmd_KickClient(client, args)
 | 
			
		||||
{
 | 
			
		||||
	if (args < 1)
 | 
			
		||||
	if (args < 2)
 | 
			
		||||
	{
 | 
			
		||||
		ReplyToCommand(client, "Usage: sm_speckick <index> <reason>");
 | 
			
		||||
		return Plugin_Handled;
 | 
			
		||||
@ -430,3 +431,23 @@ public Action:Cmd_KickClient(client, args)
 | 
			
		||||
	ReplyToCommand(client, "SourceTV kicking spectator %d with reason %s", iTarget, sMsg);
 | 
			
		||||
	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"
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			"CBaseClient::FireGameEvent"
 | 
			
		||||
			{
 | 
			
		||||
				"windows"	"1"
 | 
			
		||||
				"linux"	"2"
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			"CBaseClient::Disconnect"
 | 
			
		||||
			{
 | 
			
		||||
				"linux"	"16"
 | 
			
		||||
@ -230,6 +236,12 @@
 | 
			
		||||
				"linux"	"56"
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			"CBaseClient::FireGameEvent"
 | 
			
		||||
			{
 | 
			
		||||
				"windows"	"1"
 | 
			
		||||
				"linux"	"2"
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			"CBaseClient::Disconnect"
 | 
			
		||||
			{
 | 
			
		||||
				"linux"	"14"
 | 
			
		||||
 | 
			
		||||
@ -393,6 +393,16 @@ native SourceTV_GetClientPassword(client, String:password[], maxlen);
 | 
			
		||||
 */
 | 
			
		||||
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.
 | 
			
		||||
@ -520,5 +530,6 @@ public __ext_stvmngr_SetNTVOptional()
 | 
			
		||||
	MarkNativeAsOptional("SourceTV_GetClientIP");
 | 
			
		||||
	MarkNativeAsOptional("SourceTV_GetClientPassword");
 | 
			
		||||
	MarkNativeAsOptional("SourceTV_KickClient");
 | 
			
		||||
	MarkNativeAsOptional("SourceTV_PrintToChat");
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user