From ba99d0154b3bfe6afaff4cadd37d85b595e77994 Mon Sep 17 00:00:00 2001 From: SystematicMania Date: Thu, 27 Feb 2014 23:06:02 -0500 Subject: [PATCH] Strip quotes from chat forwards (bug 5986, r=psychonic). --- core/ChatTriggers.cpp | 74 ++++++++++++++++++++++++++++++------------- core/ChatTriggers.h | 4 +-- 2 files changed, 54 insertions(+), 24 deletions(-) diff --git a/core/ChatTriggers.cpp b/core/ChatTriggers.cpp index 5def944d..de32835c 100644 --- a/core/ChatTriggers.cpp +++ b/core/ChatTriggers.cpp @@ -57,7 +57,7 @@ ChatTriggers g_ChatTriggers; bool g_bSupressSilentFails = false; ChatTriggers::ChatTriggers() : m_pSayCmd(NULL), m_bWillProcessInPost(false), - m_ReplyTo(SM_REPLY_CONSOLE) + m_ReplyTo(SM_REPLY_CONSOLE), m_ArgSBackup(NULL) { m_PubTrigger = sm_strdup("!"); m_PrivTrigger = sm_strdup("/"); @@ -76,6 +76,8 @@ ChatTriggers::~ChatTriggers() m_PubTrigger = NULL; delete [] m_PrivTrigger; m_PrivTrigger = NULL; + delete [] m_ArgSBackup; + m_ArgSBackup = NULL; } ConfigResult ChatTriggers::OnSourceModConfigChanged(const char *key, @@ -219,7 +221,52 @@ void ChatTriggers::OnSayCommand_Pre() /* 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); - m_ArgSBackup = command.ArgS(); + + /* Handle quoted string sets */ + bool is_quoted = false; + size_t len = strlen(args); + + /* The engine does not display empty say commands. + * So to prevent forwarding it, let's block it. */ + if (len == 0) + { + RETURN_META(MRES_SUPERCEDE); + } + + /* The first pair of quotes are stripped from client say commands, but not console ones. + * We do not want the forwards to differ from what is displayed. + * So only strip the first pair of quotes from client say commands. */ + if (client != 0 && args[0] == '"' && args[len-1] == '"') + { + /* The server normally won't display empty say commands, but in this case it does. + * I don't think it's desired so let's block it. */ + if (len <= 2) + { + RETURN_META(MRES_SUPERCEDE); + } + + args++; + len--; + is_quoted = true; + } + + /* Some? engines strip the last quote when printing the string to chat. + * This results in having a double-quoted message passed to the OnClientSayCommand ("message") forward, + * but losing the last quote in the OnClientSayCommand_Post ("message) forward. + * To compensate this, we copy the args into our own buffer where the engine won't mess with + * and strip the quotes. */ + delete [] m_ArgSBackup; + m_ArgSBackup = new char[CCommand::MaxCommandLength()+1]; + memcpy(m_ArgSBackup, args, len+1); + + /* Strip the quotes from the argument */ + if (is_quoted) + { + if (m_ArgSBackup[len-1] == '"') + { + m_ArgSBackup[--len] = '\0'; + } + } /* The server console cannot do this */ if (client == 0) @@ -259,14 +306,6 @@ void ChatTriggers::OnSayCommand_Pre() RETURN_META(MRES_SUPERCEDE); } - /* Handle quoted string sets */ - bool is_quoted = false; - if (args[0] == '"') - { - args++; - is_quoted = true; - } - #if SOURCE_ENGINE == SE_EPISODEONE if (m_bIsINS && strcmp(m_Arg0Backup, "say2") == 0 && strlen(args) >= 4) { @@ -293,7 +332,7 @@ void ChatTriggers::OnSayCommand_Pre() /** * Test if this is actually a command! */ - if (is_trigger && PreProcessTrigger(PEntityOfEntIndex(client), args, is_quoted)) + if (is_trigger && PreProcessTrigger(PEntityOfEntIndex(client), args)) { m_bIsChatTrigger = true; @@ -354,7 +393,7 @@ void ChatTriggers::OnSayCommand_Post() m_bWasFloodedMessage = false; } -bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args, bool is_quoted) +bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args) { /* Extract a command. This is kind of sloppy. */ char cmd_buf[64]; @@ -401,7 +440,7 @@ bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args, bool is_ } /* See if we need to do extra string manipulation */ - if (is_quoted || prepended) + if (prepended) { size_t len; @@ -412,15 +451,6 @@ bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args, bool is_ } else { len = strncopy(m_ToExecute, args, sizeof(m_ToExecute)); } - - /* Check if we need to strip a quote */ - if (is_quoted) - { - if (m_ToExecute[len-1] == '"') - { - m_ToExecute[--len] = '\0'; - } - } } else { strncopy(m_ToExecute, args, sizeof(m_ToExecute)); } diff --git a/core/ChatTriggers.h b/core/ChatTriggers.h index 51a0aa1c..f87ec778 100644 --- a/core/ChatTriggers.h +++ b/core/ChatTriggers.h @@ -70,7 +70,7 @@ public: bool IsChatTrigger(); bool WasFloodedMessage(); private: - bool PreProcessTrigger(edict_t *pEdict, const char *args, bool is_quoted); + bool PreProcessTrigger(edict_t *pEdict, const char *args); bool ClientIsFlooding(int client); cell_t CallOnClientSayCommand(int client); private: @@ -92,7 +92,7 @@ private: unsigned int m_ReplyTo; char m_ToExecute[300]; const char *m_Arg0Backup; - const char *m_ArgSBackup; + char *m_ArgSBackup; IForward *m_pShouldFloodBlock; IForward *m_pDidFloodBlock; IForward *m_pOnClientSayCmd;