Skip to content

Commit feeb409

Browse files
Vladislav4KZa1batross
authored andcommitted
client: saytext: fix empty nicknames and strip indices; refactor to CUtlString
1 parent 4968d88 commit feeb409

1 file changed

Lines changed: 41 additions & 38 deletions

File tree

cl_dll/saytext.cpp

Lines changed: 41 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "vgui_parser.h"
2929
#include "draw_util.h"
3030
#include "com_weapons.h"
31+
#include "utlstring.h"
3132
//#include "vgui_TeamFortressViewport.h"
3233

3334
extern float *GetClientColor( int clientIndex );
@@ -268,29 +269,23 @@ int CHudSayText :: MsgFunc_SayText( const char *pszName, int iSize, void *pbuf )
268269
{
269270
BufferReader reader( pszName, pbuf, iSize );
270271
int client_index, argc, numArgs; // the client who spoke the message
271-
char *arg, *fmt, *argv[3] = {};
272+
CUtlString fmt;
273+
CUtlString argv[3];
272274
const char *fmt_tran = nullptr;
273275
bool allowDead, replaceFirstArgToName, swap;
274-
int len;
275276

276277
client_index = reader.ReadByte();
277278

278279
// find all arguments
279-
arg = reader.ReadString();
280-
len = strlen( arg );
281-
fmt = new char[len+1];
282-
strcpy(fmt, arg);
280+
fmt = reader.ReadString();
283281

284282
for( argc = 0; argc < 3; argc++ )
285283
{
286-
arg = reader.ReadString();
284+
const char *arg = reader.ReadString();
287285
if( !arg[0] && !reader.Valid() )
288286
break;
289287

290-
len = strlen( arg );
291-
argv[argc] = new char[len+1];
292-
strncpy( argv[argc], arg, len );
293-
argv[argc][len] = 0;
288+
argv[argc] = arg;
294289
}
295290

296291
// see if argv[0] is translatable
@@ -317,68 +312,76 @@ int CHudSayText :: MsgFunc_SayText( const char *pszName, int iSize, void *pbuf )
317312
// no translations
318313
if( !fmt_tran )
319314
{
320-
fmt_tran = fmt;
315+
fmt_tran = fmt.Get();
321316
numArgs = argc;
322317
allowDead = true;
323318
replaceFirstArgToName = false;
324319
swap = false;
325320
}
326321

322+
// Convert indexed placeholders (%s1, %s2) to standard C-format (%s)
323+
// to ensure compatibility with snprintf below.
324+
CUtlString fmt_local = fmt_tran;
325+
Localize_StripIndices( fmt_local.Access() );
326+
327327
// If text is sent from dead player or spectator
328328
// don't draw it, until local player isn't specator or dead.
329329
if( !allowDead && !CL_IsDead() && !g_iUser1 )
330330
{
331-
delete[] fmt;
331+
return 1;
332+
}
332333

333-
for( int i = 0; i < 3; i++ )
334-
if( argv[i] ) delete argv[i];
334+
bool nameArgReplaced = false;
335335

336-
return 1;
336+
// Resolve missing nickname locally via client_index mapping.
337+
if( !replaceFirstArgToName && client_index > 0 && numArgs > 0 && argv[0].Length() == 0 )
338+
{
339+
GetPlayerInfo( client_index, &g_PlayerInfoList[client_index] );
340+
argv[0] = g_PlayerInfoList[client_index].name;
341+
nameArgReplaced = true;
337342
}
338343

339344
if( replaceFirstArgToName )
340345
{
341346
GetPlayerInfo( client_index, &g_PlayerInfoList[client_index] );
342-
delete[] argv[0];
343-
344347
argv[0] = g_PlayerInfoList[client_index].name;
348+
nameArgReplaced = true;
345349
}
346350

347-
char dst[1024];
351+
// Strip indices from argument strings too (when not replaced by name)
352+
for( int i = 0; i < numArgs; ++i )
353+
{
354+
if( !(i == 0 && nameArgReplaced) )
355+
{
356+
Localize_StripIndices( argv[i].Access() );
357+
}
358+
}
359+
360+
CUtlString dst;
361+
char tmp[1024];
348362

349363
switch( numArgs )
350364
{
351365
case 3:
352366
if( swap )
353-
snprintf( dst, sizeof( dst ), fmt_tran, argv[0], argv[2], argv[1] );
367+
snprintf( tmp, sizeof( tmp ), fmt_local.Get(), argv[0].Get(), argv[2].Get(), argv[1].Get() );
354368
else
355-
snprintf( dst, sizeof( dst ), fmt_tran, argv[0], argv[1], argv[2] );
369+
snprintf( tmp, sizeof( tmp ), fmt_local.Get(), argv[0].Get(), argv[1].Get(), argv[2].Get() );
356370
break;
357371
case 2:
358-
snprintf( dst, sizeof( dst ), fmt_tran, argv[0], argv[1] );
372+
snprintf( tmp, sizeof( tmp ), fmt_local.Get(), argv[0].Get(), argv[1].Get() );
359373
break;
360374
case 1:
361-
snprintf( dst, sizeof( dst ), fmt_tran, argv[0] );
375+
snprintf( tmp, sizeof( tmp ), fmt_local.Get(), argv[0].Get() );
362376
break;
363377
case 0:
364-
strncpy( dst, fmt_tran, sizeof( dst ) );
365-
dst[sizeof(dst)-1] = 0;
378+
strncpy( tmp, fmt_local.Get(), sizeof( tmp ) );
379+
tmp[sizeof(tmp)-1] = 0;
366380
break;
367381
}
368382

369-
SayTextPrint( dst, strlen(dst), client_index );
370-
371-
delete[] fmt;
372-
373-
for( int i = 0; i < argc; i++ )
374-
{
375-
// skip second argument if it was replaced by name
376-
if( i == 0 && replaceFirstArgToName )
377-
continue;
378-
379-
if( argv[i] )
380-
delete[] argv[i];
381-
}
383+
dst = tmp;
384+
SayTextPrint( dst.Get(), dst.Length(), client_index );
382385

383386
return 1;
384387
}

0 commit comments

Comments
 (0)