| 195 | } |
| 196 | |
| 197 | bool ConCmdManager::InternalDispatch(int client, const ICommandArgs *args) |
| 198 | { |
| 199 | if (client) |
| 200 | { |
| 201 | CPlayer *pPlayer = g_Players.GetPlayerByIndex(client); |
| 202 | if (!pPlayer || !pPlayer->IsConnected()) |
| 203 | return false; |
| 204 | } |
| 205 | |
| 206 | /** |
| 207 | * Note: Console commands will EITHER go through IServerGameDLL::ClientCommand, |
| 208 | * OR this dispatch. They will NEVER go through both. |
| 209 | * -- |
| 210 | * Whether or not it goes through the callback is determined by FCVAR_GAMEDLL |
| 211 | */ |
| 212 | const char *cmd = g_HL2.CurrentCommandName(); |
| 213 | |
| 214 | ConCmdInfo *pInfo = FindInTrie(cmd); |
| 215 | if (pInfo == NULL) |
| 216 | { |
| 217 | return false; |
| 218 | } |
| 219 | |
| 220 | /* This is a hack to prevent say triggers from firing on messages that were |
| 221 | * blocked because of flooding. We won't remove this, but the hack will get |
| 222 | * "nicer" when we expose explicit say hooks. |
| 223 | */ |
| 224 | if (g_ChatTriggers.WasFloodedMessage()) |
| 225 | return false; |
| 226 | |
| 227 | cell_t result = Pl_Continue; |
| 228 | int argc = args->ArgC() - 1; |
| 229 | |
| 230 | // On a listen server, sometimes the server host's client index can be set |
| 231 | // as 0. So index 1 is passed to the command callback to correct this |
| 232 | // potential problem. |
| 233 | int realClient = (!engine->IsDedicatedServer() && client == 0) |
| 234 | ? g_Players.ListenClient() |
| 235 | : client; |
| 236 | int dedicatedClient = engine->IsDedicatedServer() ? 0 : g_Players.ListenClient(); |
| 237 | |
| 238 | for (CmdHookList::iterator iter = pInfo->hooks.begin(); iter != pInfo->hooks.end(); iter++) |
| 239 | { |
| 240 | CmdHook *hook = *iter; |
| 241 | |
| 242 | if (!hook->pf->IsRunnable()) |
| 243 | continue; |
| 244 | |
| 245 | if (hook->type == CmdHook::Server) |
| 246 | { |
| 247 | // Don't execute unless we're in the server console. |
| 248 | if (realClient != dedicatedClient) |
| 249 | continue; |
| 250 | } else { |
| 251 | // Check admin rights if needed. realClient isn't needed since we |
| 252 | // should bypass admin checks if client == 0 anyway. |
| 253 | if (client && hook->admin && !CheckAccess(client, cmd, hook->admin.get())) |
| 254 | { |
no test coverage detected