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); }
void ChatTriggers::OnSayCommand_Pre(const CCommand &command) { #else void ChatTriggers::OnSayCommand_Pre() { CCommand command; #endif int client; CPlayer *pPlayer; client = g_ConCmds.GetCommandClient(); m_bIsChatTrigger = false; m_bWasFloodedMessage = false; /* The server console cannot do this */ if (client == 0 || (pPlayer = g_Players.GetPlayerByIndex(client)) == NULL) { RETURN_META(MRES_IGNORED); } /* We guarantee the client is connected */ if (!pPlayer->IsConnected()) { RETURN_META(MRES_IGNORED); } const char *args = command.ArgS(); if (!args) { RETURN_META(MRES_IGNORED); } /* Check if we need to block this message from being sent */ if (ClientIsFlooding(client)) { char buffer[128]; /* :TODO: log an error? */ if (g_Translator.CoreTransEx(g_pFloodPhrases, client, buffer, sizeof(buffer), "Flooding the server", NULL, NULL) != Trans_Okay) { 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); } /* Handle quoted string sets */ bool is_quoted = false; if (args[0] == '"') { args++; is_quoted = true; } bool is_trigger = false; bool is_silent = false; /* Check for either trigger */ if (m_PubTriggerSize && strncmp(args, m_PubTrigger, m_PubTriggerSize) == 0) { is_trigger = true; args = &args[m_PubTriggerSize]; } else if (m_PrivTriggerSize && strncmp(args, m_PrivTrigger, m_PrivTriggerSize) == 0) { is_trigger = true; is_silent = true; args = &args[m_PrivTriggerSize]; } if (!is_trigger) { RETURN_META(MRES_IGNORED); } /** * Test if this is actually a command! */ if (!PreProcessTrigger(engine->PEntityOfEntIndex(client), args, is_quoted)) { CPlayer *pPlayer; if (is_silent && g_bSupressSilentFails && client != 0 && (pPlayer = g_Players.GetPlayerByIndex(client)) != NULL && pPlayer->GetAdminId() != INVALID_ADMIN_ID) { RETURN_META(MRES_SUPERCEDE); } RETURN_META(MRES_IGNORED); } m_bIsChatTrigger = true; /** * We'll execute it in post. */ m_bWillProcessInPost = true; m_bTriggerWasSilent = is_silent; /* If we're silent, block */ if (is_silent) { RETURN_META(MRES_SUPERCEDE); } /* Otherwise, let the command continue */ RETURN_META(MRES_IGNORED); }