Allow setting multiple chat trigger characters (PR #449, bug 4341, bug 5668)
Special characters only, minus a couple of potentially-problematic characters. Technically this is a breaking change - but anyone using multi-char triggers is probably crazy anyway and has been driven off by now.
This commit is contained in:
parent
098a693c1a
commit
ec7f1727e5
@ -30,12 +30,12 @@
|
|||||||
"ServerLang" "en"
|
"ServerLang" "en"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* String to use as the public chat trigger. Set an empty string to disable.
|
* List of characters to use for public chat triggers. Set an empty list to disable.
|
||||||
*/
|
*/
|
||||||
"PublicChatTrigger" "!"
|
"PublicChatTrigger" "!"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* String to use as the silent chat trigger. Set an empty string to disable.
|
* List of characters to use for silent chat triggers. Set an empty list to disable.
|
||||||
*/
|
*/
|
||||||
"SilentChatTrigger" "/"
|
"SilentChatTrigger" "/"
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* This program is free software; you can redistribute it and/or modify it under
|
* This program is free software; you can redistribute it and/or modify it under
|
||||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||||
* Free Software Foundation.
|
* Free Software Foundation.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
@ -38,12 +38,13 @@
|
|||||||
#include "logic_bridge.h"
|
#include "logic_bridge.h"
|
||||||
#include "sourcemod.h"
|
#include "sourcemod.h"
|
||||||
#include "provider.h"
|
#include "provider.h"
|
||||||
|
#include <bridge/include/ILogger.h>
|
||||||
#include <amtl/am-string.h>
|
#include <amtl/am-string.h>
|
||||||
|
|
||||||
ChatTriggers g_ChatTriggers;
|
ChatTriggers g_ChatTriggers;
|
||||||
bool g_bSupressSilentFails = false;
|
bool g_bSupressSilentFails = false;
|
||||||
|
|
||||||
ChatTriggers::ChatTriggers() : m_bWillProcessInPost(false),
|
ChatTriggers::ChatTriggers() : m_bWillProcessInPost(false),
|
||||||
m_ReplyTo(SM_REPLY_CONSOLE), m_ArgSBackup(NULL)
|
m_ReplyTo(SM_REPLY_CONSOLE), m_ArgSBackup(NULL)
|
||||||
{
|
{
|
||||||
m_PubTrigger = "!";
|
m_PubTrigger = "!";
|
||||||
@ -61,20 +62,43 @@ ChatTriggers::~ChatTriggers()
|
|||||||
m_ArgSBackup = NULL;
|
m_ArgSBackup = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigResult ChatTriggers::OnSourceModConfigChanged(const char *key,
|
void ChatTriggers::SetChatTrigger(ChatTriggerType type, const char *value)
|
||||||
const char *value,
|
{
|
||||||
|
ke::AutoPtr<char[]> filtered(new char[strlen(value) + 1]);
|
||||||
|
|
||||||
|
const char *src = value;
|
||||||
|
char *dest = filtered.get();
|
||||||
|
char c;
|
||||||
|
while ((c = *src++) != '\0') {
|
||||||
|
if (c <= ' ' || c == '"' || c == '\'' || (c >= '0' && c <= '9') || c == ';' || (c >= 'A' && c <= 'Z') || c == '\\' || (c >= 'a' && c <= 'z') || c >= 0x7F) {
|
||||||
|
logger->LogError("Ignoring %s chat trigger character '%c', not in valid set: %s", (type == ChatTrigger_Private ? "silent" : "public"), c, "!#$%&()*+,-./:<=>?@[]^_`{|}~");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*dest++ = c;
|
||||||
|
}
|
||||||
|
*dest = '\0';
|
||||||
|
|
||||||
|
if (type == ChatTrigger_Private) {
|
||||||
|
m_PrivTrigger = filtered.get();
|
||||||
|
} else {
|
||||||
|
m_PubTrigger = filtered.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigResult ChatTriggers::OnSourceModConfigChanged(const char *key,
|
||||||
|
const char *value,
|
||||||
ConfigSource source,
|
ConfigSource source,
|
||||||
char *error,
|
char *error,
|
||||||
size_t maxlength)
|
size_t maxlength)
|
||||||
{
|
{
|
||||||
if (strcmp(key, "PublicChatTrigger") == 0)
|
if (strcmp(key, "PublicChatTrigger") == 0)
|
||||||
{
|
{
|
||||||
m_PubTrigger = value;
|
SetChatTrigger(ChatTrigger_Public, value);
|
||||||
return ConfigResult_Accept;
|
return ConfigResult_Accept;
|
||||||
}
|
}
|
||||||
else if (strcmp(key, "SilentChatTrigger") == 0)
|
else if (strcmp(key, "SilentChatTrigger") == 0)
|
||||||
{
|
{
|
||||||
m_PrivTrigger = value;
|
SetChatTrigger(ChatTrigger_Private, value);
|
||||||
return ConfigResult_Accept;
|
return ConfigResult_Accept;
|
||||||
}
|
}
|
||||||
else if (strcmp(key, "SilentFailSuppress") == 0)
|
else if (strcmp(key, "SilentFailSuppress") == 0)
|
||||||
@ -156,7 +180,7 @@ bool ChatTriggers::OnSayCommand_Pre(int client, const ICommandArgs *command)
|
|||||||
if (!args)
|
if (!args)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Save these off for post hook as the command data returned from the engine in older engine versions
|
/* Save these off for post hook as the command data returned from the engine in older engine versions
|
||||||
* can be NULL, despite the data still being there and valid. */
|
* can be NULL, despite the data still being there and valid. */
|
||||||
m_Arg0Backup = command->Arg(0);
|
m_Arg0Backup = command->Arg(0);
|
||||||
size_t len = strlen(args);
|
size_t len = strlen(args);
|
||||||
@ -182,7 +206,7 @@ bool ChatTriggers::OnSayCommand_Pre(int client, const ICommandArgs *command)
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
#if SOURCE_ENGINE == SE_EPISODEONE
|
#if SOURCE_ENGINE == SE_EPISODEONE
|
||||||
!m_bIsINS &&
|
!m_bIsINS &&
|
||||||
#endif
|
#endif
|
||||||
client != 0 && args[0] == '"' && args[len-1] == '"')
|
client != 0 && args[0] == '"' && args[len-1] == '"')
|
||||||
{
|
{
|
||||||
@ -250,17 +274,17 @@ bool ChatTriggers::OnSayCommand_Pre(int client, const ICommandArgs *command)
|
|||||||
bool is_trigger = false;
|
bool is_trigger = false;
|
||||||
bool is_silent = false;
|
bool is_silent = false;
|
||||||
|
|
||||||
/* Check for either trigger */
|
// Prefer the silent trigger in case of clashes.
|
||||||
if (m_PubTrigger.length() && strncmp(m_ArgSBackup, m_PubTrigger.chars(), m_PubTrigger.length()) == 0)
|
if (strchr(m_PrivTrigger.chars(), m_ArgSBackup[0])) {
|
||||||
{
|
|
||||||
is_trigger = true;
|
|
||||||
args = &m_ArgSBackup[m_PubTrigger.length()];
|
|
||||||
}
|
|
||||||
else if (m_PrivTrigger.length() && strncmp(m_ArgSBackup, m_PrivTrigger.chars(), m_PrivTrigger.length()) == 0)
|
|
||||||
{
|
|
||||||
is_trigger = true;
|
is_trigger = true;
|
||||||
is_silent = true;
|
is_silent = true;
|
||||||
args = &m_ArgSBackup[m_PrivTrigger.length()];
|
} else if (strchr(m_PubTrigger.chars(), m_ArgSBackup[0])) {
|
||||||
|
is_trigger = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_trigger) {
|
||||||
|
// Bump the args past the chat trigger - we only support single-character triggers now.
|
||||||
|
args = &m_ArgSBackup[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -318,8 +342,8 @@ bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args)
|
|||||||
char cmd_buf[64];
|
char cmd_buf[64];
|
||||||
size_t cmd_len = 0;
|
size_t cmd_len = 0;
|
||||||
const char *inptr = args;
|
const char *inptr = args;
|
||||||
while (*inptr != '\0'
|
while (*inptr != '\0'
|
||||||
&& !textparsers->IsWhitespace(inptr)
|
&& !textparsers->IsWhitespace(inptr)
|
||||||
&& *inptr != '"'
|
&& *inptr != '"'
|
||||||
&& cmd_len < sizeof(cmd_buf) - 1)
|
&& cmd_len < sizeof(cmd_buf) - 1)
|
||||||
{
|
{
|
||||||
@ -342,7 +366,7 @@ bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now, prepend. Don't worry about the buffers. This will
|
/* Now, prepend. Don't worry about the buffers. This will
|
||||||
* work because the sizes are limited from earlier.
|
* work because the sizes are limited from earlier.
|
||||||
*/
|
*/
|
||||||
char new_buf[80];
|
char new_buf[80];
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* This program is free software; you can redistribute it and/or modify it under
|
* This program is free software; you can redistribute it and/or modify it under
|
||||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||||
* Free Software Foundation.
|
* Free Software Foundation.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
@ -50,10 +50,10 @@ public: //SMGlobalClass
|
|||||||
void OnSourceModAllInitialized_Post();
|
void OnSourceModAllInitialized_Post();
|
||||||
void OnSourceModGameInitialized();
|
void OnSourceModGameInitialized();
|
||||||
void OnSourceModShutdown();
|
void OnSourceModShutdown();
|
||||||
ConfigResult OnSourceModConfigChanged(const char *key,
|
ConfigResult OnSourceModConfigChanged(const char *key,
|
||||||
const char *value,
|
const char *value,
|
||||||
ConfigSource source,
|
ConfigSource source,
|
||||||
char *error,
|
char *error,
|
||||||
size_t maxlength);
|
size_t maxlength);
|
||||||
private: //ConCommand
|
private: //ConCommand
|
||||||
bool OnSayCommand_Pre(int client, const ICommandArgs *args);
|
bool OnSayCommand_Pre(int client, const ICommandArgs *args);
|
||||||
@ -64,6 +64,11 @@ public:
|
|||||||
bool IsChatTrigger();
|
bool IsChatTrigger();
|
||||||
bool WasFloodedMessage();
|
bool WasFloodedMessage();
|
||||||
private:
|
private:
|
||||||
|
enum ChatTriggerType {
|
||||||
|
ChatTrigger_Public,
|
||||||
|
ChatTrigger_Private,
|
||||||
|
};
|
||||||
|
void SetChatTrigger(ChatTriggerType type, const char *value);
|
||||||
bool PreProcessTrigger(edict_t *pEdict, const char *args);
|
bool PreProcessTrigger(edict_t *pEdict, const char *args);
|
||||||
bool ClientIsFlooding(int client);
|
bool ClientIsFlooding(int client);
|
||||||
cell_t CallOnClientSayCommand(int client);
|
cell_t CallOnClientSayCommand(int client);
|
||||||
|
Loading…
Reference in New Issue
Block a user