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:
Asher Baker 2016-10-04 16:34:42 +01:00 committed by GitHub
parent 098a693c1a
commit ec7f1727e5
3 changed files with 56 additions and 27 deletions

View File

@ -30,12 +30,12 @@
"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" "!"
/**
* 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" "/"

View File

@ -38,6 +38,7 @@
#include "logic_bridge.h"
#include "sourcemod.h"
#include "provider.h"
#include <bridge/include/ILogger.h>
#include <amtl/am-string.h>
ChatTriggers g_ChatTriggers;
@ -61,6 +62,29 @@ ChatTriggers::~ChatTriggers()
m_ArgSBackup = NULL;
}
void ChatTriggers::SetChatTrigger(ChatTriggerType type, 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,
@ -69,12 +93,12 @@ ConfigResult ChatTriggers::OnSourceModConfigChanged(const char *key,
{
if (strcmp(key, "PublicChatTrigger") == 0)
{
m_PubTrigger = value;
SetChatTrigger(ChatTrigger_Public, value);
return ConfigResult_Accept;
}
else if (strcmp(key, "SilentChatTrigger") == 0)
{
m_PrivTrigger = value;
SetChatTrigger(ChatTrigger_Private, value);
return ConfigResult_Accept;
}
else if (strcmp(key, "SilentFailSuppress") == 0)
@ -250,17 +274,17 @@ bool ChatTriggers::OnSayCommand_Pre(int client, const ICommandArgs *command)
bool is_trigger = false;
bool is_silent = false;
/* Check for either trigger */
if (m_PubTrigger.length() && strncmp(m_ArgSBackup, m_PubTrigger.chars(), m_PubTrigger.length()) == 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)
{
// Prefer the silent trigger in case of clashes.
if (strchr(m_PrivTrigger.chars(), m_ArgSBackup[0])) {
is_trigger = 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];
}
/**

View File

@ -64,6 +64,11 @@ public:
bool IsChatTrigger();
bool WasFloodedMessage();
private:
enum ChatTriggerType {
ChatTrigger_Public,
ChatTrigger_Private,
};
void SetChatTrigger(ChatTriggerType type, const char *value);
bool PreProcessTrigger(edict_t *pEdict, const char *args);
bool ClientIsFlooding(int client);
cell_t CallOnClientSayCommand(int client);