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;
|
||||||
@ -429,4 +430,24 @@ public Action:Cmd_KickClient(client, args)
|
|||||||
SourceTV_KickClient(iTarget, sMsg);
|
SourceTV_KickClient(iTarget, sMsg);
|
||||||
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