Add SourceTV_PrintToChat native
Send chat message to one client only
This commit is contained in:
+69
@@ -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 },
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user