summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTim Angus <tim@ngus.net>2009-11-03 23:38:49 +0000
committerTim Angus <tim@ngus.net>2013-01-03 00:17:17 +0000
commite9551ec91ffc7fb144eac71c5b65501c2c40f39d (patch)
tree0a975d9804f5f7a0940b6740061c1a098cb6c39a /src
parentc49ee670d39f11f5eea3bd621c7e918e41c20876 (diff)
* Indent wrapped chat lines to avoid potential imitation exploits
Diffstat (limited to 'src')
-rw-r--r--src/cgame/cg_servercmds.c20
-rw-r--r--src/client/cl_console.c2
-rw-r--r--src/qcommon/common.c2
-rw-r--r--src/qcommon/q_shared.c15
-rw-r--r--src/qcommon/q_shared.h3
-rw-r--r--src/ui/ui_shared.c70
6 files changed, 95 insertions, 17 deletions
diff --git a/src/cgame/cg_servercmds.c b/src/cgame/cg_servercmds.c
index 260ea5d4..8026f196 100644
--- a/src/cgame/cg_servercmds.c
+++ b/src/cgame/cg_servercmds.c
@@ -984,30 +984,30 @@ static void CG_Say( int clientNum, saymode_t mode, const char *text )
if( cg_teamChatsOnly.integer )
ignore = "[skipnotify]";
- CG_Printf( "%s%s%s" S_COLOR_WHITE "%s " S_COLOR_GREEN "%s\n",
- ignore, prefix, name, maybeColon, text );
+ CG_Printf( "%s%s%s" S_COLOR_WHITE "%s %c" S_COLOR_GREEN "%s\n",
+ ignore, prefix, name, maybeColon, INDENT_MARKER, text );
break;
case SAY_TEAM:
- CG_Printf( "%s%s(%s" S_COLOR_WHITE ")%s%s " S_COLOR_CYAN "%s\n",
- ignore, prefix, name, location, maybeColon, text );
+ CG_Printf( "%s%s(%s" S_COLOR_WHITE ")%s%s %c" S_COLOR_CYAN "%s\n",
+ ignore, prefix, name, location, maybeColon, INDENT_MARKER, text );
break;
case SAY_ADMINS:
case SAY_ADMINS_PUBLIC:
- CG_Printf( "%s%s%s%s" S_COLOR_WHITE "%s " S_COLOR_MAGENTA "%s\n",
+ CG_Printf( "%s%s%s%s" S_COLOR_WHITE "%s %c" S_COLOR_MAGENTA "%s\n",
ignore, prefix,
( mode == SAY_ADMINS ) ? "[ADMIN]" : "[PLAYER]",
- name, maybeColon, text );
+ name, maybeColon, INDENT_MARKER, text );
break;
case SAY_AREA:
- CG_Printf( "%s%s<%s" S_COLOR_WHITE ">%s%s " S_COLOR_BLUE "%s\n",
- ignore, prefix, name, location, maybeColon, text );
+ CG_Printf( "%s%s<%s" S_COLOR_WHITE ">%s%s %c" S_COLOR_BLUE "%s\n",
+ ignore, prefix, name, location, maybeColon, INDENT_MARKER, text );
break;
case SAY_PRIVMSG:
case SAY_TPRIVMSG:
color = ( mode == SAY_TPRIVMSG ) ? S_COLOR_CYAN : S_COLOR_GREEN;
- CG_Printf( "%s%s[%s" S_COLOR_WHITE " -> %s" S_COLOR_WHITE "]%s %s%s\n",
+ CG_Printf( "%s%s[%s" S_COLOR_WHITE " -> %s" S_COLOR_WHITE "]%s %c%s%s\n",
ignore, prefix, name, cgs.clientinfo[ cg.clientNum ].name,
- maybeColon, color, text );
+ maybeColon, INDENT_MARKER, color, text );
if( !ignore[0] )
CG_CenterPrint( va( "%sPrivate message from: " S_COLOR_WHITE "%s",
color, name ), 200, GIANTCHAR_WIDTH * 4 );
diff --git a/src/client/cl_console.c b/src/client/cl_console.c
index 939e003f..c2e59ea6 100644
--- a/src/client/cl_console.c
+++ b/src/client/cl_console.c
@@ -361,6 +361,8 @@ void CL_ConsolePrint( char *txt ) {
switch (c)
{
+ case INDENT_MARKER:
+ break;
case '\n':
Con_Linefeed (skipnotify);
break;
diff --git a/src/qcommon/common.c b/src/qcommon/common.c
index d4593e08..ddd3c023 100644
--- a/src/qcommon/common.c
+++ b/src/qcommon/common.c
@@ -164,6 +164,8 @@ void QDECL Com_Printf( const char *fmt, ... ) {
CL_ConsolePrint( msg );
#endif
+ Q_StripIndentMarker( msg );
+
// echo to dedicated console and early console
Sys_Print( msg );
diff --git a/src/qcommon/q_shared.c b/src/qcommon/q_shared.c
index 6da13ad0..71da2734 100644
--- a/src/qcommon/q_shared.c
+++ b/src/qcommon/q_shared.c
@@ -935,6 +935,21 @@ int Q_CountChar(const char *string, char tocount)
return count;
}
+void Q_StripIndentMarker(char *string)
+{
+ int i;
+
+ for (i = 0; i < strlen(string); i++) {
+ if (string[i] == INDENT_MARKER) {
+ int j;
+
+ for (j = i; j < strlen(string); j++) {
+ string[j] = string[j+1];
+ }
+ }
+ }
+}
+
void Q_ParseNewlines( char *dest, const char *src, int destsize )
{
for( ; *src && destsize > 1; src++, destsize-- )
diff --git a/src/qcommon/q_shared.h b/src/qcommon/q_shared.h
index 6eda5cd8..29cc4b9b 100644
--- a/src/qcommon/q_shared.h
+++ b/src/qcommon/q_shared.h
@@ -389,6 +389,9 @@ extern vec4_t colorDkGrey;
#define S_COLOR_MAGENTA "^6"
#define S_COLOR_WHITE "^7"
+#define INDENT_MARKER '\v'
+void Q_StripIndentMarker(char *string);
+
extern vec4_t g_color_table[8];
#define MAKERGB( v, r, g, b ) v[0]=r;v[1]=g;v[2]=b
diff --git a/src/ui/ui_shared.c b/src/ui/ui_shared.c
index fcf359f1..2e54df2b 100644
--- a/src/ui/ui_shared.c
+++ b/src/ui/ui_shared.c
@@ -1905,6 +1905,32 @@ qboolean UI_Text_IsEmoticon( const char *s, qboolean *escaped,
return qfalse;
}
+static float UI_Parse_Indent( const char **text )
+{
+ char indentWidth[ MAX_STRING_CHARS ];
+ char *p = indentWidth;
+ int numChars;
+ float pixels;
+
+ Q_strncpyz( indentWidth, *text, MAX_STRING_CHARS );
+
+ while( isdigit( *p ) || *p == '.' )
+ p++;
+
+ if( *p != INDENT_MARKER )
+ return 0.0f;
+
+ *p++ = '\0';
+ numChars = ( p - indentWidth );
+ p = indentWidth;
+
+ if( !Float_Parse( &p, &pixels ) )
+ return 0.0f;
+
+ (*text) += numChars;
+
+ return pixels;
+}
float UI_Text_Width( const char *text, float scale, int limit )
{
@@ -1919,6 +1945,7 @@ float UI_Text_Width( const char *text, float scale, int limit )
float emoticonW;
int emoticonWidth;
int emoticons = 0;
+ float indentWidth = 0.0f;
if( scale <= DC->getCVarValue( "ui_smallFont" ) )
font = &DC->Assets.smallFont;
@@ -1937,6 +1964,7 @@ float UI_Text_Width( const char *text, float scale, int limit )
len = limit;
count = 0;
+ indentWidth = UI_Parse_Indent( &s );
while( s && *s && count < len )
{
@@ -1948,6 +1976,12 @@ float UI_Text_Width( const char *text, float scale, int limit )
continue;
}
+ if( *s == INDENT_MARKER )
+ {
+ s++;
+ continue;
+ }
+
if( UI_Text_IsEmoticon( s, &emoticonEscaped, &emoticonLen,
NULL, &emoticonWidth ) )
{
@@ -1967,7 +2001,7 @@ float UI_Text_Width( const char *text, float scale, int limit )
}
}
- return ( out * useScale ) + ( emoticons * emoticonW );
+ return ( out * useScale ) + ( emoticons * emoticonW ) + indentWidth;
}
float UI_Text_Height( const char *text, float scale, int limit )
@@ -2114,6 +2148,8 @@ static void UI_Text_Paint_Generic( float x, float y, float scale, float gapAdjus
DC->setColor( color );
memcpy( &newColor[0], &color[0], sizeof( vec4_t ) );
+ x += UI_Parse_Indent( &s );
+
while( s && *s && count < len )
{
glyph = &font->glyphs[ (int)*s ];
@@ -2136,6 +2172,12 @@ static void UI_Text_Paint_Generic( float x, float y, float scale, float gapAdjus
continue;
}
+ if( *s == INDENT_MARKER )
+ {
+ s++;
+ continue;
+ }
+
if( UI_Text_IsEmoticon( s, &emoticonEscaped, &emoticonLen,
&emoticonHandle, &emoticonWidth ) )
{
@@ -4383,9 +4425,11 @@ const char *Item_Text_Wrap( const char *text, float scale, float width )
char c[ 3 ] = "";
const char *p = text;
const char *eol;
- const char *q = NULL, *qMinus1 = NULL;
+ const char *q = NULL;
unsigned int testLength;
unsigned int i;
+ float indentWidth = 0.0f;
+ float testWidth;
if( strlen( text ) >= sizeof( out ) )
return NULL;
@@ -4394,14 +4438,17 @@ const char *Item_Text_Wrap( const char *text, float scale, float width )
while( *p )
{
- testLength = 1;
eol = p;
q = p + 1;
+ testLength = 0;
+ testWidth = width - indentWidth;
SkipColorCodes( &q, c );
- while( UI_Text_Width( p, scale, testLength ) < width )
+ while( testLength == 0 || UI_Text_Width( p, scale, testLength ) < testWidth )
{
+ qboolean previousCharIsSpace = qfalse;
+
// Remaining string is too short to wrap
if( testLength >= strlen( p ) )
{
@@ -4415,10 +4462,13 @@ const char *Item_Text_Wrap( const char *text, float scale, float width )
SkipColorCodes( &q, c );
SkipEmoticons( &q );
- qMinus1 = q;
+ previousCharIsSpace = isspace( *q );
q++;
}
+ if( testLength > 0 && *q == INDENT_MARKER )
+ indentWidth = UI_Text_Width( p, scale, testLength );
+
// Some color escapes might still be present
SkipColorCodes( &q, c );
SkipEmoticons( &q );
@@ -4430,7 +4480,7 @@ const char *Item_Text_Wrap( const char *text, float scale, float width )
break;
}
- if( !isspace( *qMinus1 ) && isspace( *q ) )
+ if( !previousCharIsSpace && isspace( *q ) )
eol = q;
testLength++;
@@ -4450,14 +4500,20 @@ const char *Item_Text_Wrap( const char *text, float scale, float width )
if( out[ strlen( out ) - 1 ] == '\n' )
{
- // The line is deliberately broken, clear the color
+ // The line is deliberately broken, clear the color and
+ // any current indent
c[ 0 ] = '\0';
+ indentWidth = 0.0f;
}
else
{
// Add a \n if it's not there already
Q_strcat( out, sizeof( out ), "\n" );
+ // Insert a pixel indent on the next line
+ if( indentWidth > 0.0f )
+ Q_strcat( out, sizeof( out ), va( "%f%c", indentWidth, INDENT_MARKER ) );
+
// Skip leading whitespace on next line and save the
// last color code
SkipWhiteSpace( &p, c );