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"
|
||||
|
||||
/**
|
||||
* 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" "/"
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
* 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
|
||||
* Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
@ -38,12 +38,13 @@
|
||||
#include "logic_bridge.h"
|
||||
#include "sourcemod.h"
|
||||
#include "provider.h"
|
||||
#include <bridge/include/ILogger.h>
|
||||
#include <amtl/am-string.h>
|
||||
|
||||
ChatTriggers g_ChatTriggers;
|
||||
bool g_bSupressSilentFails = false;
|
||||
|
||||
ChatTriggers::ChatTriggers() : m_bWillProcessInPost(false),
|
||||
ChatTriggers::ChatTriggers() : m_bWillProcessInPost(false),
|
||||
m_ReplyTo(SM_REPLY_CONSOLE), m_ArgSBackup(NULL)
|
||||
{
|
||||
m_PubTrigger = "!";
|
||||
@ -61,20 +62,43 @@ ChatTriggers::~ChatTriggers()
|
||||
m_ArgSBackup = NULL;
|
||||
}
|
||||
|
||||
ConfigResult ChatTriggers::OnSourceModConfigChanged(const char *key,
|
||||
const char *value,
|
||||
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,
|
||||
char *error,
|
||||
char *error,
|
||||
size_t maxlength)
|
||||
{
|
||||
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)
|
||||
@ -156,7 +180,7 @@ bool ChatTriggers::OnSayCommand_Pre(int client, const ICommandArgs *command)
|
||||
if (!args)
|
||||
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. */
|
||||
m_Arg0Backup = command->Arg(0);
|
||||
size_t len = strlen(args);
|
||||
@ -182,7 +206,7 @@ bool ChatTriggers::OnSayCommand_Pre(int client, const ICommandArgs *command)
|
||||
|
||||
if (
|
||||
#if SOURCE_ENGINE == SE_EPISODEONE
|
||||
!m_bIsINS &&
|
||||
!m_bIsINS &&
|
||||
#endif
|
||||
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_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];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -318,8 +342,8 @@ bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args)
|
||||
char cmd_buf[64];
|
||||
size_t cmd_len = 0;
|
||||
const char *inptr = args;
|
||||
while (*inptr != '\0'
|
||||
&& !textparsers->IsWhitespace(inptr)
|
||||
while (*inptr != '\0'
|
||||
&& !textparsers->IsWhitespace(inptr)
|
||||
&& *inptr != '"'
|
||||
&& cmd_len < sizeof(cmd_buf) - 1)
|
||||
{
|
||||
@ -342,7 +366,7 @@ bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args)
|
||||
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.
|
||||
*/
|
||||
char new_buf[80];
|
||||
|
@ -8,7 +8,7 @@
|
||||
* 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
|
||||
* Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
@ -50,10 +50,10 @@ public: //SMGlobalClass
|
||||
void OnSourceModAllInitialized_Post();
|
||||
void OnSourceModGameInitialized();
|
||||
void OnSourceModShutdown();
|
||||
ConfigResult OnSourceModConfigChanged(const char *key,
|
||||
const char *value,
|
||||
ConfigResult OnSourceModConfigChanged(const char *key,
|
||||
const char *value,
|
||||
ConfigSource source,
|
||||
char *error,
|
||||
char *error,
|
||||
size_t maxlength);
|
||||
private: //ConCommand
|
||||
bool OnSayCommand_Pre(int client, const ICommandArgs *args);
|
||||
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user