Strip quotes from chat forwards (bug 5986, r=psychonic).
authorSystematicMania <systematicmania@gmail.com>
Thu Feb 27 23:06:02 2014 -0500 (2014-02-27)
changeset 4260b2f7d97b1ea7
parent 4259 ca0fdabc2d92
child 4261 32e36d3570f0
Strip quotes from chat forwards (bug 5986, r=psychonic).
core/ChatTriggers.cpp
core/ChatTriggers.h
     1.1 --- a/core/ChatTriggers.cpp	Thu Feb 27 20:49:19 2014 -0700
     1.2 +++ b/core/ChatTriggers.cpp	Thu Feb 27 23:06:02 2014 -0500
     1.3 @@ -57,7 +57,7 @@
     1.4  bool g_bSupressSilentFails = false;
     1.5  
     1.6  ChatTriggers::ChatTriggers() : m_pSayCmd(NULL), m_bWillProcessInPost(false), 
     1.7 -	m_ReplyTo(SM_REPLY_CONSOLE)
     1.8 +	m_ReplyTo(SM_REPLY_CONSOLE), m_ArgSBackup(NULL)
     1.9  {
    1.10  	m_PubTrigger = sm_strdup("!");
    1.11  	m_PrivTrigger = sm_strdup("/");
    1.12 @@ -76,6 +76,8 @@
    1.13  	m_PubTrigger = NULL;
    1.14  	delete [] m_PrivTrigger;
    1.15  	m_PrivTrigger = NULL;
    1.16 +	delete [] m_ArgSBackup;
    1.17 +	m_ArgSBackup = NULL;
    1.18  }
    1.19  
    1.20  ConfigResult ChatTriggers::OnSourceModConfigChanged(const char *key, 
    1.21 @@ -219,7 +221,52 @@
    1.22  	/* Save these off for post hook as the command data returned from the engine in older engine versions 
    1.23  	 * can be NULL, despite the data still being there and valid. */
    1.24  	m_Arg0Backup = command.Arg(0);
    1.25 -	m_ArgSBackup = command.ArgS();
    1.26 +
    1.27 +	/* Handle quoted string sets */
    1.28 +	bool is_quoted = false;
    1.29 +	size_t len = strlen(args);
    1.30 +
    1.31 +	/* The engine does not display empty say commands.
    1.32 +	 * So to prevent forwarding it, let's block it. */
    1.33 +	if (len == 0)
    1.34 +	{
    1.35 +		RETURN_META(MRES_SUPERCEDE);
    1.36 +	}
    1.37 +
    1.38 +	/* The first pair of quotes are stripped from client say commands, but not console ones.
    1.39 +	 * We do not want the forwards to differ from what is displayed.
    1.40 +	 * So only strip the first pair of quotes from client say commands. */
    1.41 +	if (client != 0 && args[0] == '"' && args[len-1] == '"')
    1.42 +	{
    1.43 +		/* The server normally won't display empty say commands, but in this case it does.
    1.44 +		 * I don't think it's desired so let's block it. */
    1.45 +		if (len <= 2)
    1.46 +		{
    1.47 +			RETURN_META(MRES_SUPERCEDE);
    1.48 +		}
    1.49 +
    1.50 +		args++;
    1.51 +		len--;
    1.52 +		is_quoted = true;
    1.53 +	}
    1.54 +	
    1.55 +	/* Some? engines strip the last quote when printing the string to chat.
    1.56 +	 * This results in having a double-quoted message passed to the OnClientSayCommand ("message") forward,
    1.57 +	 * but losing the last quote in the OnClientSayCommand_Post ("message) forward.
    1.58 +	 * To compensate this, we copy the args into our own buffer where the engine won't mess with
    1.59 +	 * and strip the quotes. */
    1.60 +	delete [] m_ArgSBackup;
    1.61 +	m_ArgSBackup = new char[CCommand::MaxCommandLength()+1];
    1.62 +	memcpy(m_ArgSBackup, args, len+1);
    1.63 +
    1.64 +	/* Strip the quotes from the argument */
    1.65 +	if (is_quoted)
    1.66 +	{
    1.67 +		if (m_ArgSBackup[len-1] == '"')
    1.68 +		{
    1.69 +			m_ArgSBackup[--len] = '\0';
    1.70 +		}
    1.71 +	}
    1.72  
    1.73  	/* The server console cannot do this */
    1.74  	if (client == 0)
    1.75 @@ -259,14 +306,6 @@
    1.76  		RETURN_META(MRES_SUPERCEDE);
    1.77  	}
    1.78  
    1.79 -	/* Handle quoted string sets */
    1.80 -	bool is_quoted = false;
    1.81 -	if (args[0] == '"')
    1.82 -	{
    1.83 -		args++;
    1.84 -		is_quoted = true;
    1.85 -	}
    1.86 -
    1.87  #if SOURCE_ENGINE == SE_EPISODEONE
    1.88  	if (m_bIsINS && strcmp(m_Arg0Backup, "say2") == 0 && strlen(args) >= 4)
    1.89  	{
    1.90 @@ -293,7 +332,7 @@
    1.91  	/**
    1.92  	 * Test if this is actually a command!
    1.93  	 */
    1.94 -	if (is_trigger && PreProcessTrigger(PEntityOfEntIndex(client), args, is_quoted))
    1.95 +	if (is_trigger && PreProcessTrigger(PEntityOfEntIndex(client), args))
    1.96  	{
    1.97  		m_bIsChatTrigger = true;
    1.98  
    1.99 @@ -354,7 +393,7 @@
   1.100  	m_bWasFloodedMessage = false;
   1.101  }
   1.102  
   1.103 -bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args, bool is_quoted)
   1.104 +bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args)
   1.105  {
   1.106  	/* Extract a command.  This is kind of sloppy. */
   1.107  	char cmd_buf[64];
   1.108 @@ -401,7 +440,7 @@
   1.109  	}
   1.110  
   1.111  	/* See if we need to do extra string manipulation */
   1.112 -	if (is_quoted || prepended)
   1.113 +	if (prepended)
   1.114  	{
   1.115  		size_t len;
   1.116  
   1.117 @@ -412,15 +451,6 @@
   1.118  		} else {
   1.119  			len = strncopy(m_ToExecute, args, sizeof(m_ToExecute));
   1.120  		}
   1.121 -
   1.122 -		/* Check if we need to strip a quote */
   1.123 -		if (is_quoted)
   1.124 -		{
   1.125 -			if (m_ToExecute[len-1] == '"')
   1.126 -			{
   1.127 -				m_ToExecute[--len] = '\0';
   1.128 -			}
   1.129 -		}
   1.130  	} else {
   1.131  		strncopy(m_ToExecute, args, sizeof(m_ToExecute));
   1.132  	}
     2.1 --- a/core/ChatTriggers.h	Thu Feb 27 20:49:19 2014 -0700
     2.2 +++ b/core/ChatTriggers.h	Thu Feb 27 23:06:02 2014 -0500
     2.3 @@ -70,7 +70,7 @@
     2.4  	bool IsChatTrigger();
     2.5  	bool WasFloodedMessage();
     2.6  private:
     2.7 -	bool PreProcessTrigger(edict_t *pEdict, const char *args, bool is_quoted);
     2.8 +	bool PreProcessTrigger(edict_t *pEdict, const char *args);
     2.9  	bool ClientIsFlooding(int client);
    2.10  	cell_t CallOnClientSayCommand(int client);
    2.11  private:
    2.12 @@ -92,7 +92,7 @@
    2.13  	unsigned int m_ReplyTo;
    2.14  	char m_ToExecute[300];
    2.15  	const char *m_Arg0Backup;
    2.16 -	const char *m_ArgSBackup;
    2.17 +	char *m_ArgSBackup;
    2.18  	IForward *m_pShouldFloodBlock;
    2.19  	IForward *m_pDidFloodBlock;
    2.20  	IForward *m_pOnClientSayCmd;