예제 #1
0
int CoreProviderImpl::QueryClientConVar(int client, const char *cvar)
{
#if SOURCE_ENGINE != SE_DARKMESSIAH
	switch (hooks_.GetClientCvarQueryMode()) {
	case ClientCvarQueryMode::DLL:
		return ::engine->StartQueryCvarValue(PEntityOfEntIndex(client), cvar);
	case ClientCvarQueryMode::VSP:
		return serverpluginhelpers->StartQueryCvarValue(PEntityOfEntIndex(client), cvar);
	default:
		return InvalidQueryCvarCookie;
	}
#endif
	return -1;
}
예제 #2
0
void CHookManager::OnClientPutInServer(int client)
{
	if (!PRCH_enabled)
		return;

	if (!PRCH_used)
		return;

	edict_t *pEdict = PEntityOfEntIndex(client);
	if (!pEdict)
	{
		return;
	}

	IServerUnknown *pUnknown = pEdict->GetUnknown();
	if (!pUnknown)
	{
		return;
	}

	CBaseEntity *pEntity = pUnknown->GetBaseEntity();
	if (!pEntity)
	{
		return;
	}

	SH_ADD_MANUALHOOK(PlayerRunCmdHook, pEntity, SH_MEMBER(this, &CHookManager::PlayerRunCmd), false);
}
예제 #3
0
void MRecipientFilter::AddAllPlayers(int maxClients)
{
   m_Recipients.RemoveAll();
   int i;
   for ( i = 1; i <= maxClients; i++ )
   {
#if defined ( GAME_CSGO )
      edict_t *pPlayer = PEntityOfEntIndex(i);
#else
	   edict_t *pPlayer = engine->PEntityOfEntIndex(i);
#endif
      if ( !pPlayer || pPlayer->IsFree()) {
         continue;
      }

	  IPlayerInfo *playerinfo = playerinfomanager->GetPlayerInfo( pPlayer );
	  if (!playerinfo || !playerinfo->IsConnected())
	  {
		 continue;
	  }
		  
	  if (playerinfo->IsHLTV())
	  {
		  continue;
	  }

	  if (strcmp(playerinfo->GetNetworkIDString(),"BOT") == 0)
	  {
		  continue;
	  }

	  m_Recipients.AddToTail(i);
   }
} 
예제 #4
0
CPlayerInfo::CPlayerInfo( CEdict* edict_ptr )
{
	m_edict_ptr = edict_ptr;
	int index = m_edict_ptr->get_index();
	edict_t* edict = PEntityOfEntIndex(index);
	m_iplayerinfo_ptr = playerinfomanager->GetPlayerInfo(edict);
}
예제 #5
0
static cell_t SetClientViewEntity(IPluginContext *pContext, const cell_t *params)
{
	IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]);
	if (player == NULL)
	{
		return pContext->ThrowNativeError("Invalid client index %d", params[1]);
	}
	if (!player->IsInGame())
	{
		return pContext->ThrowNativeError("Client %d is not in game", params[1]);
	}

	edict_t *pEdict = PEntityOfEntIndex(gamehelpers->ReferenceToIndex(params[2]));
	if (!pEdict || pEdict->IsFree())
	{
		return pContext->ThrowNativeError("Entity %d is not valid", params[2]);
	}

#if SOURCE_ENGINE == SE_DOTA
	engine->SetView(params[1], params[2]);
#else
	engine->SetView(player->GetEdict(), pEdict);
#endif

	return 1;
}
예제 #6
0
/* Taken from Sourcemod Tf2 Extension */
CBaseEntity *UTIL_GetCBaseEntity(int num, bool onlyPlayers)
{
	edict_t *pEdict = PEntityOfEntIndex(num);
	if (!pEdict || pEdict->IsFree())
	{
		return NULL;
	}

	if (num > 0 && num <= playerhelpers->GetMaxClients())
	{
		IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(pEdict);
		if (!pPlayer || !pPlayer->IsConnected())
		{
			return NULL;
		}
	}
	else if (onlyPlayers)
	{
		return NULL;
	}

	IServerUnknown *pUnk;
	if ((pUnk=pEdict->GetUnknown()) == NULL)
	{
		return NULL;
	}

	return pUnk->GetBaseEntity();
}
예제 #7
0
void ChatTriggers::OnSayCommand_Post()
#endif
{
	int client = g_ConCmds.GetCommandClient();

	if (m_bWillProcessInPost)
	{
		/* Reset this for re-entrancy */
		m_bWillProcessInPost = false;

		/* Execute the cached command */
		unsigned int old = SetReplyTo(SM_REPLY_CHAT);
#if SOURCE_ENGINE == SE_DOTA
		engine->ClientCommand(client, "%s", m_ToExecute);
#else
		serverpluginhelpers->ClientCommand(PEntityOfEntIndex(client), m_ToExecute);
#endif
		SetReplyTo(old);
	}

	if (!m_bPluginIgnored && m_pOnClientSayCmd_Post->GetFunctionCount() != 0)
	{
		m_pOnClientSayCmd_Post->PushCell(client);
		m_pOnClientSayCmd_Post->PushString(m_Arg0Backup);
		m_pOnClientSayCmd_Post->PushString(m_ArgSBackup);
		m_pOnClientSayCmd_Post->Execute(NULL);
	}

	m_bIsChatTrigger = false;
	m_bWasFloodedMessage = false;
}
예제 #8
0
void CValveMenuDisplay::SendRawDisplay(int client, int priority, unsigned int time)
{
    m_pKv->SetInt("level", priority);
    m_pKv->SetInt("time", time ? time : 200);

    SH_CALL(g_pSPHCC, &IServerPluginHelpers::CreateMessage)(
        PEntityOfEntIndex(client),
        DIALOG_MENU,
        m_pKv,
        vsp_interface);
}
int	ManiReservedSlot::FindPlayerToKick ( ) {
	// FIRST LOOK FOR BOTS!
	for ( int i = 1; i <= max_players; i++ ) {
#if defined ( GAME_CSGO )
		edict_t *pEdict = PEntityOfEntIndex(i);
#else
		edict_t *pEdict = engine->PEntityOfEntIndex(i);
#endif

		IServerUnknown *unknown = pEdict->GetUnknown();
		if (!unknown)
			continue;

		CBaseEntity *base = unknown->GetBaseEntity();

		if (!base)
			continue;
		
		IPlayerInfo *pi_player = playerinfomanager->GetPlayerInfo( pEdict );

		if ( !pi_player )
			continue;

		if ( FStrEq(pi_player->GetNetworkIDString(), "BOT") ) 
			return i;
	}

	BuildPlayerKickList();

	if ( active_player_list_size == 0 )
		return 0;

	int KickMethod = mani_reserve_slots_kick_method.GetInt();
	//0 = by ping
	//1 = by connection time
	//2 = by kills per minute
	//3 = kill/death ratio

	if ( KickMethod == 0 ) {
		qsort(active_player_list, active_player_list_size, sizeof(active_player_t), sort_active_players_by_ping);
	} else if ( KickMethod == 1 ) {
		qsort(active_player_list, active_player_list_size, sizeof(active_player_t), sort_active_players_by_connect_time);
	} else if ( KickMethod == 2 ) {
		qsort(active_player_list, active_player_list_size, sizeof(active_player_t), sort_active_players_by_kill_rate);
	} else if ( KickMethod == 3 ) {
		qsort(active_player_list, active_player_list_size, sizeof(active_player_t), sort_active_players_by_kd_ratio);
	}

	return active_player_list[0].index;
}
예제 #10
0
void GetResourceEntity()
{
	g_ResourceEntity.Term();
	
#if SOURCE_ENGINE >= SE_ORANGEBOX
	const char *classname = g_pGameConf->GetKeyValue("ResourceEntityClassname");
	if (classname != NULL)
	{
		for (CBaseEntity *pEntity = (CBaseEntity *)servertools->FirstEntity(); pEntity; pEntity = (CBaseEntity *)servertools->NextEntity(pEntity))
		{
			if (!strcmp(gamehelpers->GetEntityClassname(pEntity), classname))
			{
				g_ResourceEntity = ((IHandleEntity *)pEntity)->GetRefEHandle();
				break;
			}
		}
	}
	else
#endif
	{
		int edictCount = gpGlobals->maxEntities;

		for (int i=0; i<edictCount; i++)
		{
			edict_t *pEdict = PEntityOfEntIndex(i);
			if (!pEdict || pEdict->IsFree())
			{
				continue;
			}
			if (!pEdict->GetNetworkable())
			{
				continue;
			}

			IHandleEntity *pHandleEnt = pEdict->GetNetworkable()->GetEntityHandle();
			if (!pHandleEnt)
			{
				continue;
			}

			ServerClass *pClass = pEdict->GetNetworkable()->GetServerClass();
			if (FindNestedDataTable(pClass->m_pTable, "DT_PlayerResource"))
			{
				g_ResourceEntity = pHandleEnt->GetRefEHandle();
				break;
			}
		}
	}
}
예제 #11
0
static cell_t smn_TRGetPointContentsEnt(IPluginContext *pContext, const cell_t *params)
{
	/* TODO: See if we can get the collidable with a prop and remove the reliance on edicts */
	edict_t *pEdict = PEntityOfEntIndex(gamehelpers->ReferenceToIndex(params[1]));
	if (!pEdict || pEdict->IsFree())
	{
		return pContext->ThrowNativeError("Entity %d is invalid", params[1]);
	}

	cell_t *addr;
	Vector pos;

	pContext->LocalToPhysAddr(params[2], &addr);

	pos.x = sp_ctof(addr[0]);
	pos.y = sp_ctof(addr[1]);
	pos.z = sp_ctof(addr[2]);

	return enginetrace->GetPointContents_Collideable(pEdict->GetCollideable(), pos);
}
예제 #12
0
void InitTeamNatives()
{
	g_Teams.clear();
	g_Teams.resize(1);

	int edictCount = gpGlobals->maxEntities;

	for (int i=0; i<edictCount; i++)
	{
		edict_t *pEdict = PEntityOfEntIndex(i);
		if (!pEdict || pEdict->IsFree())
		{
			continue;
		}
		if (!pEdict->GetNetworkable())
		{
			continue;
		}

		ServerClass *pClass = pEdict->GetNetworkable()->GetServerClass();
		if (FindNestedDataTable(pClass->m_pTable, "DT_Team"))
		{
			SendProp *pTeamNumProp = g_pGameHelpers->FindInSendTable(pClass->GetName(), "m_iTeamNum");

			if (pTeamNumProp != NULL)
			{
				int offset = pTeamNumProp->GetOffset();
				CBaseEntity *pEnt = pEdict->GetUnknown()->GetBaseEntity();
				int TeamIndex = *(int *)((unsigned char *)pEnt + offset);

				if (TeamIndex >= (int)g_Teams.size())
				{
					g_Teams.resize(TeamIndex+1);
				}
				g_Teams[TeamIndex].ClassName = pClass->GetName();
				g_Teams[TeamIndex].pEnt = pEnt;
			}
		}
	}
}
예제 #13
0
/**
 * Retrieves the CEntInfo pointer from g_EntList for a given entity index
 */
CEntInfo *CHalfLife2::LookupEntity(int entIndex)
{
	// Make sure that our index is within the bounds of the global ent array
	if (entIndex < 0 || entIndex >= NUM_ENT_ENTRIES)
	{
		return NULL;
	}

	CEntInfo *entInfos = EntInfoArray();

	if (!entInfos)
	{
		/* Attempt to use engine interface instead */
		static CEntInfo tempInfo;
		tempInfo.m_pNext = NULL;
		tempInfo.m_pPrev = NULL;

		edict_t *pEdict = PEntityOfEntIndex(entIndex);

		if (!pEdict)
		{
			return NULL;
		}

		IServerUnknown *pUnk = pEdict->GetUnknown();

		if (!pUnk)
		{
			return NULL;
		}

		tempInfo.m_pEntity = pUnk;
		tempInfo.m_SerialNumber = pUnk->GetRefEHandle().GetSerialNumber();

		return &tempInfo;
	}

	return &entInfos[entIndex];
}
예제 #14
0
void BaseMenuStyle::ClientPressedKey(int client, unsigned int key_press)
{
#if defined MENU_DEBUG
	g_Logger.LogMessage("[SM_MENU] ClientPressedKey() (client %d) (key_press %d)", client, key_press);
#endif
	CBaseMenuPlayer *player = GetMenuPlayer(client);

	/* First question: Are we in a menu? */
	if (!player->bInMenu)
	{
		return;
	}

	bool cancel = false;
	unsigned int item = 0;
	MenuCancelReason reason = MenuCancel_Exit;
	MenuEndReason end_reason = MenuEnd_Selected;
	menu_states_t &states = player->states;

	/* Save variables */
	IMenuHandler *mh = states.mh;
	IBaseMenu *menu = states.menu;

	unsigned int item_on_page = states.item_on_page;

	assert(mh != NULL);

	if (menu == NULL)
	{
		item = key_press;
	} else if (key_press < 1 || key_press > GetMaxPageItems()) {
		cancel = true;
	} else {
		ItemSelection type = states.slots[key_press].type;

		/* Check if we should play a sound about the type */
		if (g_Menus.MenuSoundsEnabled() && 
			(!menu || (menu->GetMenuOptionFlags() & MENUFLAG_NO_SOUND) != MENUFLAG_NO_SOUND))
		{
			CellRecipientFilter filter;
			cell_t clients[1];

			clients[0] = client;
			filter.Initialize(clients, 1);

			const char *sound = g_Menus.GetMenuSound(type);

			if (sound != NULL)
			{
				edict_t *pEdict = PEntityOfEntIndex(client);
				if (pEdict)
				{
					ICollideable *pCollideable = pEdict->GetCollideable();

					if (pCollideable)
					{
						const Vector & pos = pCollideable->GetCollisionOrigin();
						enginesound->EmitSound(filter, 
							client, 
							CHAN_AUTO, 
#if SOURCE_ENGINE >= SE_PORTAL2
							sound, 
							-1, 
#endif
							sound, 
							VOL_NORM, 
							ATTN_NORM, 
#if SOURCE_ENGINE >= SE_PORTAL2
							0, 
#endif
							0, 
							PITCH_NORM, 
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS \
	|| SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_TF2
							0,
#endif
							&pos);
					}
				}
			}
		}

		/* For navigational items, we're going to redisplay */
		if (type == ItemSel_Back)
		{
			if (!RedoClientMenu(client, ItemOrder_Descending))
			{
				cancel = true;
				reason = MenuCancel_NoDisplay;
				end_reason = MenuEnd_Cancelled;
			} else {
				return;
			}
		} else if (type == ItemSel_Next) {
			if (!RedoClientMenu(client, ItemOrder_Ascending))
			{
				cancel = true;						/* I like Saltines. */
				reason = MenuCancel_NoDisplay;
				end_reason = MenuEnd_Cancelled;
			} else {
				return;
			}
		} else if (type == ItemSel_Exit || type == ItemSel_None) {
			cancel = true;
			reason = MenuCancel_Exit;
			end_reason = MenuEnd_Exit;
		} else if (type == ItemSel_ExitBack) {
			cancel = true;
			reason = MenuCancel_ExitBack;
			end_reason = MenuEnd_ExitBack;
		} else {
			item = states.slots[key_press].item;
		}
	}

	/* Clear states */
	player->bInMenu = false;
	if (player->menuHoldTime)
	{
		RemoveClientFromWatch(client);
	}

	Handle_t hndl = menu ? menu->GetHandle() : BAD_HANDLE;
	AutoHandleRooter ahr(hndl);

	if (cancel)
	{
		mh->OnMenuCancel(menu, client, reason);
	} else {
		mh->OnMenuSelect(menu, client, item);
		if (mh->GetMenuAPIVersion2() >= 13)
		{
			mh->OnMenuSelect2(menu, client, item, item_on_page);
		}
	}

	/* Only fire end for valid menus */
	if (menu)
	{
		mh->OnMenuEnd(menu, end_reason);
	}
}
예제 #15
0
//---------------------------------------------------------------------------------
// Purpose: Builds up a list of players that are 'kickable'
//---------------------------------------------------------------------------------
void ManiReservedSlot::BuildPlayerKickList( player_t *player_ptr, int *players_on_server )
{
	player_t	temp_player;
	active_player_t active_player;

	FreeList((void **) &active_player_list, &active_player_list_size);

	for (int i = 1; i <= max_players; i ++)
	{
#if defined ( GAME_CSGO )
		edict_t *pEntity = PEntityOfEntIndex(i);
#else
		edict_t *pEntity = engine->PEntityOfEntIndex(i);
#endif
		if( pEntity && !pEntity->IsFree())
		{
			if ( player_ptr && ( pEntity == player_ptr->entity ) )
				continue;

			IPlayerInfo *playerinfo = playerinfomanager->GetPlayerInfo( pEntity );
			if (playerinfo && playerinfo->IsConnected())
			{
				Q_strcpy(active_player.steam_id, playerinfo->GetNetworkIDString());
				if (FStrEq("BOT", active_player.steam_id))
				{
					continue;
				}

				INetChannelInfo *nci = engine->GetPlayerNetInfo(i);
				if (!nci)
				{
					continue;
				}

				active_player.entity = pEntity;

				active_player.ping = nci->GetAvgLatency(0);
				const char * szCmdRate = engine->GetClientConVarValue( i, "cl_cmdrate" );
				int nCmdRate = (20 > Q_atoi( szCmdRate )) ? 20 : Q_atoi(szCmdRate);
				active_player.ping -= (0.5f/nCmdRate) + TICKS_TO_TIME( 1.0f ); // correct latency

				// in GoldSrc we had a different, not fixed tickrate. so we have to adjust
				// Source pings by half a tick to match the old GoldSrc pings.
				active_player.ping -= TICKS_TO_TIME( 0.5f );
				active_player.ping = active_player.ping * 1000.0f; // as msecs
				active_player.ping = ((5 > active_player.ping) ? 5:active_player.ping); // set bounds, dont show pings under 5 msecs

				active_player.time_connected = nci->GetTimeConnected();
				Q_strcpy(active_player.ip_address, nci->GetAddress());
				if (gpManiGameType->IsSpectatorAllowed() &&
					playerinfo->GetTeamIndex () == gpManiGameType->GetSpectatorIndex())
				{
					active_player.is_spectator = true;
				}
				else
				{
					active_player.is_spectator = false;
				}
				active_player.user_id = playerinfo->GetUserID();
				Q_strcpy(active_player.name, playerinfo->GetName());

				if ( players_on_server )
					*players_on_server = *players_on_server + 1;

				active_player.kills = playerinfo->GetFragCount();
				active_player.deaths = playerinfo->GetDeathCount();
				Q_strcpy(temp_player.steam_id, active_player.steam_id);
				Q_strcpy(temp_player.ip_address, active_player.ip_address);
				Q_strcpy(temp_player.name, active_player.name);
				temp_player.is_bot = false;

				if (IsPlayerInReserveList(&temp_player))
				{
					continue;
				}

				active_player.index = i;

				if (mani_reserve_slots_include_admin.GetInt() == 1 &&
					gpManiClient->HasAccess(active_player.index, ADMIN, ADMIN_BASIC_ADMIN))
				{
					continue;
				}

				if (gpManiClient->HasAccess(active_player.index, IMMUNITY, IMMUNITY_RESERVE))
				{
					continue;
				}

				AddToList((void **) &active_player_list, sizeof(active_player_t), &active_player_list_size);
				active_player_list[active_player_list_size - 1] = active_player;
			}
		}
	}
}
예제 #16
0
//---------------------------------------------------------------------------------
// Purpose: Process Game Frame
//---------------------------------------------------------------------------------
void ManiAutoMap::GameFrame(void)
{
	if (war_mode || 
		mani_automap.GetInt() == 0 || 
		ignore_this_map || 
		automap_list_size == 0) return;

	if (g_RealTime < trigger_time) return;

	trigger_time += 15;

	int	players = 0;
	bool include_bots = mani_automap_include_bots.GetBool();
	int	threshold = mani_automap_player_threshold.GetInt();

	// Count players
	for (int i = 1; i <= max_players; i++)
	{
		// Faster than FindPlayerByIndex()
#if defined ( GAME_CSGO )
		edict_t *pEntity = PEntityOfEntIndex(i);
#else
		edict_t *pEntity = engine->PEntityOfEntIndex(i);
#endif
		if(pEntity && !pEntity->IsFree() )
		{
			IPlayerInfo *playerinfo = playerinfomanager->GetPlayerInfo( pEntity );
			if (playerinfo && playerinfo->IsConnected())
			{
				if (playerinfo->IsHLTV()) continue;
				if (!include_bots && strcmp(playerinfo->GetNetworkIDString(), "BOT") == 0) continue;

				players ++;
				if (players > threshold)
				{
					// Broken threshold so just ignore, but reset the timeout
					this->ResetTimeout(mani_automap_timer.GetInt());
					return;
				}
			}
		}
	}

	// Need to change map
	if (mani_automap_set_nextmap.GetInt() != 0)
	{
		set_next_map = true;
	}
	else
	{
		set_next_map = false;
	}

	int map_choice = this->ChooseMap();

	override_changelevel = 0;
	override_setnextmap = false;
	ignore_this_map = true;
	LogCommand (NULL, "Autochange to map %s while server idle\n", automap_list[map_choice].map_name);
	SetChangeLevelReason("Automap changed map");

 	char	changelevel_command[128];
	snprintf(changelevel_command, sizeof(changelevel_command), "changelevel %s\n", automap_list[map_choice].map_name);
	engine->ServerCommand(changelevel_command);
}
예제 #17
0
void ChatTriggers::OnSayCommand_Pre(const CCommandContext &context, const CCommand &command)
{
#elif SOURCE_ENGINE >= SE_ORANGEBOX
void ChatTriggers::OnSayCommand_Pre(const CCommand &command)
{
#else
void ChatTriggers::OnSayCommand_Pre()
{
	CCommand command;
#endif
	int client = g_ConCmds.GetCommandClient();
	m_bIsChatTrigger = false;
	m_bWasFloodedMessage = false;
	m_bPluginIgnored = true;

	const char *args = command.ArgS();

	if (!args)
	{
		RETURN_META(MRES_IGNORED);
	}

	/* Save these off for post hook as the command data returned from the engine in older engine versions 
	 * can be NULL, despite the data still being there and valid. */
	m_Arg0Backup = command.Arg(0);
	size_t len = strlen(args);

#if SOURCE_ENGINE == SE_EPISODEONE
	if (m_bIsINS)
	{
		if (strcmp(m_Arg0Backup, "say2") == 0 && len >= 4)
		{
			args += 4;
			len -= 4;
		}

		if (len == 0)
		{
			RETURN_META(MRES_SUPERCEDE);
		}
	}
#endif

	/* The first pair of quotes are stripped from client say commands, but not console ones.
	 * We do not want the forwards to differ from what is displayed.
	 * So only strip the first pair of quotes from client say commands. */
	bool is_quoted = false;

	if (
#if SOURCE_ENGINE == SE_EPISODEONE
		!m_bIsINS && 
#endif
		client != 0 && args[0] == '"' && args[len-1] == '"')
	{
		/* The server normally won't display empty say commands, but in this case it does.
		 * I don't think it's desired so let's block it. */
		if (len <= 2)
		{
			RETURN_META(MRES_SUPERCEDE);
		}

		args++;
		len--;
		is_quoted = true;
	}

	/* Some? engines strip the last quote when printing the string to chat.
	 * This results in having a double-quoted message passed to the OnClientSayCommand ("message") forward,
	 * but losing the last quote in the OnClientSayCommand_Post ("message) forward.
	 * To compensate this, we copy the args into our own buffer where the engine won't mess with
	 * and strip the quotes. */
	delete [] m_ArgSBackup;
	m_ArgSBackup = new char[CCommand::MaxCommandLength()+1];
	memcpy(m_ArgSBackup, args, len+1);

	/* Strip the quotes from the argument */
	if (is_quoted)
	{
		if (m_ArgSBackup[len-1] == '"')
		{
			m_ArgSBackup[--len] = '\0';
		}
	}

	/* The server console cannot do this */
	if (client == 0)
	{
		if (CallOnClientSayCommand(client) >= Pl_Handled)
		{
			RETURN_META(MRES_SUPERCEDE);
		}

		RETURN_META(MRES_IGNORED);
	}

	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);

	/* We guarantee the client is connected */
	if (!pPlayer || !pPlayer->IsConnected())
	{
		RETURN_META(MRES_IGNORED);
	}

	/* Check if we need to block this message from being sent */
	if (ClientIsFlooding(client))
	{
		char buffer[128];

		if (!logicore.CoreTranslate(buffer, sizeof(buffer), "%T", 2, NULL, "Flooding the server", &client))
			UTIL_Format(buffer, sizeof(buffer), "You are flooding the server!");

		/* :TODO: we should probably kick people who spam too much. */

		char fullbuffer[192];
		UTIL_Format(fullbuffer, sizeof(fullbuffer), "[SM] %s", buffer);
		g_HL2.TextMsg(client, HUD_PRINTTALK, fullbuffer);

		m_bWasFloodedMessage = true;

		RETURN_META(MRES_SUPERCEDE);
	}

	bool is_trigger = false;
	bool is_silent = false;

	/* Check for either trigger */
	if (m_PubTriggerSize && strncmp(m_ArgSBackup, m_PubTrigger, m_PubTriggerSize) == 0)
	{
		is_trigger = true;
		args = &m_ArgSBackup[m_PubTriggerSize];
	} 
	else if (m_PrivTriggerSize && strncmp(m_ArgSBackup, m_PrivTrigger, m_PrivTriggerSize) == 0) 
	{
		is_trigger = true;
		is_silent = true;
		args = &m_ArgSBackup[m_PrivTriggerSize];
	}

	/**
	 * Test if this is actually a command!
	 */
	if (is_trigger && PreProcessTrigger(PEntityOfEntIndex(client), args))
	{
		m_bIsChatTrigger = true;

		/**
		 * We'll execute it in post.
		 */
		m_bWillProcessInPost = true;
	}

	if (is_silent && (m_bIsChatTrigger || (g_bSupressSilentFails && pPlayer->GetAdminId() != INVALID_ADMIN_ID)))
	{
		RETURN_META(MRES_SUPERCEDE);
	}

	if (CallOnClientSayCommand(client) >= Pl_Handled)
	{
		RETURN_META(MRES_SUPERCEDE);
	}

	/* Otherwise, let the command continue */
	RETURN_META(MRES_IGNORED);
}