summaryrefslogtreecommitdiff
path: root/src/game
diff options
context:
space:
mode:
Diffstat (limited to 'src/game')
-rw-r--r--src/game/bg_misc.c61
-rw-r--r--src/game/bg_public.h1
-rw-r--r--src/game/g_client.c57
-rw-r--r--src/game/g_local.h5
-rw-r--r--src/game/g_main.c6
5 files changed, 127 insertions, 3 deletions
diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c
index 9f8ce9e4..244ee482 100644
--- a/src/game/bg_misc.c
+++ b/src/game/bg_misc.c
@@ -31,6 +31,7 @@ void trap_FS_Read( void *buffer, int len, fileHandle_t f );
void trap_FS_Write( const void *buffer, int len, fileHandle_t f );
void trap_FS_FCloseFile( fileHandle_t f );
void trap_FS_Seek( fileHandle_t f, long offset, fsOrigin_t origin ); // fsOrigin_t
+int trap_FS_GetFileList( const char *path, const char *extension, char *listbuf, int bufsize );
static const buildableAttributes_t bg_buildableList[ ] =
{
@@ -3855,3 +3856,63 @@ weapon_t BG_PrimaryWeapon( int stats[ ] )
return WP_NONE;
}
+/*
+============
+BG_LoadEmoticons
+============
+*/
+int BG_LoadEmoticons( char names[ ][ MAX_EMOTICON_NAME_LEN ] )
+{
+ int numFiles;
+ char fileList[ MAX_EMOTICONS * ( MAX_EMOTICON_NAME_LEN + 5 ) ] = {""};
+ int i;
+ char *filePtr;
+ int fileLen;
+ char emoticon[ MAX_EMOTICON_NAME_LEN + 5 ] = {""};
+ int loaded = 0;
+ int count;
+
+ numFiles = trap_FS_GetFileList( "emoticons", ".tga", fileList,
+ sizeof( fileList ) );
+
+ if( numFiles < 1 )
+ return 0;
+
+ filePtr = fileList;
+ fileLen = 0;
+ count = 0;
+ for( i = 0; i < numFiles; i++, filePtr += fileLen + 1 )
+ {
+ if( count >= MAX_EMOTICONS )
+ {
+ count++;
+ continue;
+ }
+
+ fileLen = strlen( filePtr );
+ if( fileLen > MAX_EMOTICON_NAME_LEN + 5 )
+ {
+ Com_Printf( S_COLOR_YELLOW "WARNING: MAX_EMOTICON_NAME_LEN is %d. "
+ "skipping \"%s\", filename too long", MAX_EMOTICON_NAME_LEN, filePtr );
+ continue;
+ }
+ if( !trap_FS_FOpenFile( va( "emoticons/%s", filePtr ), NULL, FS_READ ) )
+ {
+ Com_Printf( S_COLOR_YELLOW "WARNING: BG_LoadEmoticons(): detected "
+ " an unreadable .tga file name \"emoticons/%s\" in emoticon detection",
+ filePtr );
+ break;
+ }
+ Q_strncpyz( emoticon, filePtr, sizeof( emoticon ) );
+ emoticon[ fileLen - 4 ] = '\0';
+
+ Q_strncpyz( names[ count ], emoticon, sizeof( names[ count ] ) );
+ count++;
+ loaded = count;
+ }
+
+ Com_Printf( "Loaded %d of %d emoticons (MAX_EMOTICONS is %d)\n",
+ loaded, count, MAX_EMOTICONS );
+ return loaded;
+}
+
diff --git a/src/game/bg_public.h b/src/game/bg_public.h
index 1e1c98ac..2a6f1874 100644
--- a/src/game/bg_public.h
+++ b/src/game/bg_public.h
@@ -1298,3 +1298,4 @@ voiceTrack_t *BG_VoiceTrackFind( voiceTrack_t *head, team_t team,
class_t class, weapon_t weapon,
int enthusiasm, int *trackNum );
+int BG_LoadEmoticons( char names[ ][ MAX_EMOTICON_NAME_LEN ] );
diff --git a/src/game/g_client.c b/src/game/g_client.c
index 0e8051b8..4d674905 100644
--- a/src/game/g_client.c
+++ b/src/game/g_client.c
@@ -764,16 +764,54 @@ void respawn( gentity_t *ent )
}
}
+static qboolean G_IsEmoticon( const char *s, qboolean *escaped )
+{
+ int i, j;
+ const char *p = s;
+ char emoticon[ MAX_EMOTICON_NAME_LEN ] = {""};
+ qboolean escape = qfalse;
+
+ if( *p != '[' )
+ return qfalse;
+ p++;
+ if( *p == '[' )
+ {
+ escape = qtrue;
+ p++;
+ }
+ i = 0;
+ while( *p && i < ( MAX_EMOTICON_NAME_LEN - 1 ) )
+ {
+ if( *p == ']' )
+ {
+ for( j = 0; j < level.emoticonCount; j++ )
+ {
+ if( !Q_stricmp( emoticon, level.emoticons[ j ] ) )
+ {
+ *escaped = escape;
+ return qtrue;
+ }
+ }
+ return qfalse;
+ }
+ emoticon[ i++ ] = *p;
+ emoticon[ i ] = '\0';
+ p++;
+ }
+ return qfalse;
+}
+
/*
===========
-ClientCleanName
+G_ClientCleanName
============
*/
-static void ClientCleanName( const char *in, char *out, int outSize )
+static void G_ClientCleanName( const char *in, char *out, int outSize )
{
int len, colorlessLen;
char *p;
int spaces;
+ qboolean escaped;
//save room for trailing null byte
outSize--;
@@ -808,6 +846,19 @@ static void ClientCleanName( const char *in, char *out, int outSize )
len += 2;
continue;
}
+ else if( !g_emoticonsAllowedInNames.integer && G_IsEmoticon( in, &escaped ) )
+ {
+ // make sure room in dest for both chars
+ if( len > outSize - 2 )
+ break;
+
+ *out++ = '[';
+ *out++ = '[';
+ len += 2;
+ if( escaped )
+ in++;
+ continue;
+ }
// don't allow too many consecutive spaces
if( *in == ' ' )
@@ -942,7 +993,7 @@ void ClientUserinfoChanged( int clientNum )
// set name
Q_strncpyz( oldname, client->pers.netname, sizeof( oldname ) );
s = Info_ValueForKey( userinfo, "name" );
- ClientCleanName( s, newname, sizeof( newname ) );
+ G_ClientCleanName( s, newname, sizeof( newname ) );
if( strcmp( oldname, newname ) )
{
diff --git a/src/game/g_local.h b/src/game/g_local.h
index db15d208..05f1fe21 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -619,6 +619,9 @@ typedef struct
team_t surrenderTeam;
voice_t *voices;
+
+ char emoticons[ MAX_EMOTICONS ][ MAX_EMOTICON_NAME_LEN ];
+ int emoticonCount;
} level_locals_t;
#define CMD_CHEAT 0x01
@@ -1142,6 +1145,8 @@ extern vmCvar_t g_mapConfigs;
extern vmCvar_t g_layouts;
extern vmCvar_t g_layoutAuto;
+extern vmCvar_t g_emoticonsAllowedInNames;
+
extern vmCvar_t g_admin;
extern vmCvar_t g_adminLog;
extern vmCvar_t g_adminParseSay;
diff --git a/src/game/g_main.c b/src/game/g_main.c
index 34793cb2..e3db3c23 100644
--- a/src/game/g_main.c
+++ b/src/game/g_main.c
@@ -124,6 +124,8 @@ vmCvar_t g_chatTeamPrefix;
vmCvar_t g_layouts;
vmCvar_t g_layoutAuto;
+vmCvar_t g_emoticonsAllowedInNames;
+
vmCvar_t g_admin;
vmCvar_t g_adminLog;
vmCvar_t g_adminParseSay;
@@ -244,6 +246,8 @@ static cvarTable_t gameCvarTable[ ] =
{ &g_layouts, "g_layouts", "", CVAR_LATCH, 0, qfalse },
{ &g_layoutAuto, "g_layoutAuto", "1", CVAR_ARCHIVE, 0, qfalse },
+
+ { &g_emoticonsAllowedInNames, "g_emoticonsAllowedInNames", "1", CVAR_LATCH|CVAR_ARCHIVE, 0, qfalse },
{ &g_admin, "g_admin", "admin.dat", CVAR_ARCHIVE, 0, qfalse },
{ &g_adminLog, "g_adminLog", "admin.log", CVAR_ARCHIVE, 0, qfalse },
@@ -603,6 +607,8 @@ void G_InitGame( int levelTime, int randomSeed, int restart )
trap_LocateGameData( level.gentities, level.num_entities, sizeof( gentity_t ),
&level.clients[ 0 ].ps, sizeof( level.clients[ 0 ] ) );
+ level.emoticonCount = BG_LoadEmoticons( level.emoticons );
+
trap_SetConfigstring( CS_INTERMISSION, "0" );
// test to see if a custom buildable layout will be loaded