//// HOST_SAY // String comes in as // say blah blah blah // or as // blah blah blah // void Host_Say( edict_t *pEdict, const CCommand &args, MessageMode_t messageMode ) { CBasePlayer *client; int j; char *p; char szTemp[256]; char text[256]; const char *cpSay = "say"; const char *cpSayTeam = "say_team"; const char *cpSaySpec = "say_spec"; const char *pcmd = args[0]; bool bSenderDead = false; // We can get a raw string now, without the "say " prepended if ( args.ArgC() == 0 ) return; if ( !stricmp( pcmd, cpSay) || !stricmp( pcmd, cpSayTeam ) || !stricmp( pcmd, cpSaySpec ) ) { if ( args.ArgC() >= 2 ) { p = (char *)args.ArgS(); } else { // say with a blank message, nothing to do return; } } else // Raw text, need to prepend argv[0] { if ( args.ArgC() >= 2 ) { Q_snprintf( szTemp,sizeof(szTemp), "%s %s", ( char * )pcmd, (char *)args.ArgS() ); } else { // Just a one word command, use the first word...sigh Q_snprintf( szTemp,sizeof(szTemp), "%s", ( char * )pcmd ); } p = szTemp; } CBasePlayer *pPlayer = NULL; if ( pEdict ) { pPlayer = ((CBasePlayer *)CBaseEntity::Instance( pEdict )); Assert( pPlayer ); // make sure the text has valid content p = CheckChatText( pPlayer, p ); } if ( !p ) return; if ( pEdict ) { if ( !pPlayer->CanSpeak(messageMode) ) return; // See if the player wants to modify of check the text pPlayer->CheckChatText( p, 127 ); // though the buffer szTemp that p points to is 256, // chat text is capped to 127 in CheckChatText above Assert( strlen( pPlayer->GetPlayerName() ) > 0 ); bSenderDead = ( pPlayer->m_lifeState != LIFE_ALIVE ); } else { bSenderDead = false; } const char *pszFormat = NULL; const char *pszPrefix = NULL; char pszLocation[8]; if ( g_pGameRules ) { pszFormat = g_pGameRules->GetChatFormat( messageMode, pPlayer ); pszPrefix = g_pGameRules->GetChatPrefix( messageMode, pPlayer ); if (pPlayer && pPlayer->GetTeam() && pPlayer->GetTeam()->GetCaptain() == pPlayer) Q_snprintf(pszLocation, sizeof(pszLocation), "(%s)", g_pGameRules->GetChatLocation( messageMode, pPlayer )); else Q_snprintf(pszLocation, sizeof(pszLocation), "%s", g_pGameRules->GetChatLocation( messageMode, pPlayer )); } const char *pszPlayerName = pPlayer ? pPlayer->GetPlayerName() : "Stadium Announcer"; // loop through all players // Start with the first player. // This may return the world in single player if the client types something between levels or during spawn // so check it, or it will infinite loop client = NULL; for ( int i = 1; i <= gpGlobals->maxClients; i++ ) { client = ToBaseMultiplayerPlayer( UTIL_PlayerByIndex( i ) ); if ( !client || !client->edict() ) continue; if ( client->edict() == pEdict ) continue; if ( !(client->IsNetClient()) ) // Not a client ? (should never be true) continue; if ( messageMode != MM_SAY && !g_pGameRules->PlayerCanHearChat( client, pPlayer, messageMode ) ) continue; if ( pPlayer && !client->CanHearAndReadChatFrom( pPlayer ) ) continue; if ( pPlayer && GetVoiceGameMgr() && GetVoiceGameMgr()->IsPlayerIgnoringPlayer( pPlayer->entindex(), i ) ) continue; CSingleUserRecipientFilter user( client ); user.MakeReliable(); UTIL_SayText2Filter( user, pPlayer, true, pszFormat, pszPlayerName, p, pszLocation, pszPrefix ); } if ( pPlayer ) { // print to the sending client CSingleUserRecipientFilter user( pPlayer ); user.MakeReliable(); UTIL_SayText2Filter( user, pPlayer, true, pszFormat, pszPlayerName, p, pszLocation, pszPrefix ); } // echo to server console // Adrian: Only do this if we're running a dedicated server since we already print to console on the client. if ( engine->IsDedicatedServer() ) { Q_snprintf( text, sizeof(text), "%s: ", pszPlayerName ); j = sizeof(text) - 2 - strlen(text); // -2 for /n and null terminator if ( (int)strlen(p) > j ) p[j] = 0; Q_strncat( text, p, sizeof( text ), COPY_ALL_CHARACTERS ); Q_strncat( text, "\n", sizeof( text ), COPY_ALL_CHARACTERS ); Msg( "%s", text ); } Assert( p ); int userid = 0; const char *networkID = "Console"; const char *playerName = "Console"; const char *playerTeam = "Console"; if ( pPlayer ) { userid = pPlayer->GetUserID(); networkID = pPlayer->GetNetworkIDString(); playerName = pPlayer->GetPlayerName(); CTeam *team = pPlayer->GetTeam(); if ( team ) { playerTeam = team->GetKitName(); } } if ( messageMode == MM_SAY_TEAM ) UTIL_LogPrintf( "\"%s<%i><%s><%s>\" say_team \"%s\"\n", playerName, userid, networkID, playerTeam, p ); else if ( messageMode == MM_SAY_SPEC ) UTIL_LogPrintf( "\"%s<%i><%s><%s>\" say_spec \"%s\"\n", playerName, userid, networkID, playerTeam, p ); else UTIL_LogPrintf( "\"%s<%i><%s><%s>\" say \"%s\"\n", playerName, userid, networkID, playerTeam, p ); IGameEvent * event = gameeventmanager->CreateEvent( "player_say" ); if ( event ) // will be null if there are no listeners! { event->SetInt("userid", userid ); event->SetString("text", p ); event->SetInt("priority", 1 ); // HLTV event priority, not transmitted gameeventmanager->FireEvent( event ); } }