Add SourceTV_BroadcastChatMessage native

Add option to send messages to locally connected spectators only or to
replay proxies as well.
This commit is contained in:
Peace-Maker 2016-03-03 04:13:21 +01:00
parent c0eb6eb75f
commit d03b22abf6
4 changed files with 153 additions and 7 deletions

View File

@ -158,7 +158,48 @@ static cell_t Native_GetDelay(IPluginContext *pContext, const cell_t *params)
return sp_ftoc(hltvdirector->GetDelay());
}
// native bool:SourceTV_BroadcastScreenMessage(const String:format[], any:...);
static bool BroadcastEventLocal(IHLTVServer *server, IGameEvent *event, bool bReliable)
{
static ICallWrapper *pBroadcastEventLocal = nullptr;
if (!pBroadcastEventLocal)
{
void *addr = nullptr;
if (!g_pGameConf->GetMemSig("CHLTVServer::BroadcastEventLocal", &addr) || !addr)
{
smutils->LogError(myself, "Failed to get CHLTVServer::BroadcastEventLocal signature.");
return false;
}
PassInfo pass[2];
pass[0].flags = PASSFLAG_BYVAL;
pass[0].type = PassType_Basic;
pass[0].size = sizeof(IGameEvent *);
pass[1].flags = PASSFLAG_BYVAL;
pass[1].type = PassType_Basic;
pass[1].size = sizeof(bool);
pBroadcastEventLocal = bintools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 2);
}
if (pBroadcastEventLocal)
{
unsigned char vstk[sizeof(void *) + sizeof(IGameEvent *) + sizeof(bool)];
unsigned char *vptr = vstk;
*(void **)vptr = (void *)server;
vptr += sizeof(void *);
*(IGameEvent **)vptr = event;
vptr += sizeof(char *);
*(bool *)vptr = bReliable;
pBroadcastEventLocal->Execute(vstk, NULL);
return true;
}
return false;
}
// native bool:SourceTV_BroadcastScreenMessage(bool:bLocalOnly, const String:format[], any:...);
static cell_t Native_BroadcastScreenMessage(IPluginContext *pContext, const cell_t *params)
{
if (hltvserver == nullptr)
@ -168,7 +209,7 @@ static cell_t Native_BroadcastScreenMessage(IPluginContext *pContext, const cell
size_t len;
{
DetectExceptions eh(pContext);
len = smutils->FormatString(buffer, sizeof(buffer), pContext, params, 1);
len = smutils->FormatString(buffer, sizeof(buffer), pContext, params, 2);
if (eh.HasException())
return 0;
}
@ -178,10 +219,17 @@ static cell_t Native_BroadcastScreenMessage(IPluginContext *pContext, const cell
return 0;
msg->SetString("text", buffer);
hltvserver->BroadcastEvent(msg);
int ret = 1;
bool bLocalOnly = params[1] != 0;
if (bLocalOnly)
hltvserver->BroadcastEvent(msg);
else
ret = BroadcastEventLocal(hltvserver, msg, false);
gameevents->FreeEvent(msg);
return 1;
return ret;
}
// native bool:SourceTV_BroadcastConsoleMessage(const String:format[], any:...);
@ -250,6 +298,39 @@ static cell_t Native_BroadcastConsoleMessage(IPluginContext *pContext, const cel
return 1;
}
// native bool:SourceTV_BroadcastChatMessage(bool:bLocalOnly, const String:format[], any:...);
static cell_t Native_BroadcastChatMessage(IPluginContext *pContext, const cell_t *params)
{
if (hltvserver == nullptr)
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;
msg->SetString("text", buffer);
int ret = 1;
bool bLocalOnly = params[1] != 0;
if (bLocalOnly)
hltvserver->BroadcastEvent(msg);
else
ret = BroadcastEventLocal(hltvserver, msg, false);
gameevents->FreeEvent(msg);
return ret;
}
// native SourceTV_GetViewEntity();
static cell_t Native_GetViewEntity(IPluginContext *pContext, const cell_t *params)
{
@ -659,6 +740,7 @@ const sp_nativeinfo_t sourcetv_natives[] =
{ "SourceTV_GetDelay", Native_GetDelay },
{ "SourceTV_BroadcastScreenMessage", Native_BroadcastScreenMessage },
{ "SourceTV_BroadcastConsoleMessage", Native_BroadcastConsoleMessage },
{ "SourceTV_BroadcastChatMessage", Native_BroadcastChatMessage },
{ "SourceTV_GetViewEntity", Native_GetViewEntity },
{ "SourceTV_GetViewOrigin", Native_GetViewOrigin },
{ "SourceTV_ForceFixedCameraShot", Native_ForceFixedCameraShot },

View File

@ -15,6 +15,8 @@ public OnPluginStart()
RegConsoleCmd("sm_getdelay", Cmd_GetDelay);
RegConsoleCmd("sm_spectators", Cmd_Spectators);
RegConsoleCmd("sm_spechintmsg", Cmd_SendHintMessage);
RegConsoleCmd("sm_specchat", Cmd_SendChatMessage);
RegConsoleCmd("sm_specchatlocal", Cmd_SendChatMessageLocal);
RegConsoleCmd("sm_specmsg", Cmd_SendMessage);
RegConsoleCmd("sm_viewentity", Cmd_GetViewEntity);
RegConsoleCmd("sm_vieworigin", Cmd_GetViewOrigin);
@ -166,7 +168,7 @@ public Action:Cmd_SendHintMessage(client, args)
GetCmdArgString(sMsg, sizeof(sMsg));
StripQuotes(sMsg);
new bool:bSent = SourceTV_BroadcastScreenMessage("%s", sMsg);
new bool:bSent = SourceTV_BroadcastScreenMessage(false, "%s", sMsg);
ReplyToCommand(client, "SourceTV sending hint message (success %d): %s", bSent, sMsg);
return Plugin_Handled;
}
@ -188,6 +190,40 @@ public Action:Cmd_SendMessage(client, args)
return Plugin_Handled;
}
public Action:Cmd_SendChatMessage(client, args)
{
if (args < 1)
{
ReplyToCommand(client, "Usage: sm_specchat <message>");
return Plugin_Handled;
}
new String:sMsg[128];
GetCmdArgString(sMsg, sizeof(sMsg));
StripQuotes(sMsg);
new bool:bSent = SourceTV_BroadcastChatMessage(false, "%s", sMsg);
ReplyToCommand(client, "SourceTV sending chat message to all spectators (including relays) (success %d): %s", bSent, sMsg);
return Plugin_Handled;
}
public Action:Cmd_SendChatMessageLocal(client, args)
{
if (args < 1)
{
ReplyToCommand(client, "Usage: sm_specchatlocal <message>");
return Plugin_Handled;
}
new String:sMsg[128];
GetCmdArgString(sMsg, sizeof(sMsg));
StripQuotes(sMsg);
new bool:bSent = SourceTV_BroadcastChatMessage(true, "%s", sMsg);
ReplyToCommand(client, "SourceTV sending chat message to local spectators (success %d): %s", bSent, sMsg);
return Plugin_Handled;
}
public Action:Cmd_GetViewEntity(client, args)
{
ReplyToCommand(client, "SourceTV view entity: %d", SourceTV_GetViewEntity());

View File

@ -70,6 +70,14 @@
// ping(CCommand const&) "Client ping times:\n"
"windows" "\x55\x8B\xEC\x83\xE4\xC0\x83\xEC\x34\x83\x3D\x2A\x2A\x2A\x2A\x01\x53\x56\x57\x75\x2A"
}
"CHLTVServer::BroadcastEventLocal"
{
"library" "engine"
"linux" "@_ZN11CHLTVServer19BroadcastEventLocalEP10IGameEventb"
// "SourceTV broadcast local event: %s\n"
"windows" "\x55\x8B\xEC\x83\xEC\x4C\x53\x8B\xD9\xC7\x45\xB4\x2A\x2A\x2A\x2A\x56\x8D"
}
}
}
"cstrike"
@ -154,6 +162,14 @@
// ping(CCommand const&) "Client ping times:\n"
"windows" "\x55\x8B\xEC\x51\x83\x3D\x2A\x2A\x2A\x2A\x01\x75\x2A"
}
"CHLTVServer::BroadcastEventLocal"
{
"library" "engine"
"linux" "@_ZN11CHLTVServer19BroadcastEventLocalEP10IGameEventb"
// "SourceTV broadcast local event: %s\n"
"windows" "\x55\x8B\xEC\x81\xEC\x44\x04\x00\x00\x53"
}
}
}
}

View File

@ -92,11 +92,12 @@ native Float:SourceTV_GetDelay();
* Print a center message to all SourceTV spectators for ~2 seconds.
* Like the tv_msg command.
*
* @param bLocalOnly Send only to directly connected spectators or proxies as well?
* @param format The format string.
* @param ... Variable number of format string arguments.
* @return True if message was sent, false otherwise.
*/
native bool:SourceTV_BroadcastScreenMessage(const String:format[], any:...);
native bool:SourceTV_BroadcastScreenMessage(bool:bLocalOnly, const String:format[], any:...);
/**
* Prints text to the console of all connected SourceTV spectators.
@ -107,7 +108,15 @@ native bool:SourceTV_BroadcastScreenMessage(const String:format[], any:...);
*/
native bool:SourceTV_BroadcastConsoleMessage(const String:format[], any:...);
/**
* Print a chat message to all SourceTV spectators.
*
* @param bLocalOnly Send only to directly connected spectators or proxies as well?
* @param format The format string.
* @param ... Variable number of format string arguments.
* @return True if message was sent, false otherwise.
*/
native bool:SourceTV_BroadcastChatMessage(bool:bLocalOnly, const String:format[], any:...);
/********************************************************************************
@ -393,6 +402,7 @@ public __ext_stvmngr_SetNTVOptional()
MarkNativeAsOptional("SourceTV_GetDelay");
MarkNativeAsOptional("SourceTV_BroadcastScreenMessage");
MarkNativeAsOptional("SourceTV_BroadcastConsoleMessage");
MarkNativeAsOptional("SourceTV_BroadcastChatMessage");
MarkNativeAsOptional("SourceTV_GetViewEntity");
MarkNativeAsOptional("SourceTV_GetViewOrigin");
MarkNativeAsOptional("SourceTV_ForceFixedCameraShot");
@ -408,6 +418,8 @@ public __ext_stvmngr_SetNTVOptional()
MarkNativeAsOptional("SourceTV_GetClientCount");
MarkNativeAsOptional("SourceTV_IsClientConnected");
MarkNativeAsOptional("SourceTV_GetSpectatorName");
MarkNativeAsOptional("SourceTV_GetSpectatorIP");
MarkNativeAsOptional("SourceTV_GetSpectatorPassword");
MarkNativeAsOptional("SourceTV_KickClient");
}
#endif