More Windows build fix.
3 * =============================================================================
5 * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
6 * =============================================================================
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, version 3.0, as published by the
10 * Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to link the
21 * code of this program (as well as its derivative works) to "Half-Life 2," the
22 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
23 * by the Valve Corporation. You must obey the GNU General Public License in
24 * all respects for all other code used. Additionally, AlliedModders LLC grants
25 * this exception to all derivative works. AlliedModders LLC defines further
26 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
27 * or <http://www.sourcemod.net/license.php>.
32 #include "common_logic.h"
34 #include <IGameHelpers.h>
35 #include <IPlayerHelpers.h>
36 #include <IForwardSys.h>
37 #include "stringutil.h"
39 #define BANFLAG_AUTO (1<<0) /**< Auto-detects whether to ban by steamid or IP */
40 #define BANFLAG_IP (1<<1) /**< Always ban by IP address */
41 #define BANFLAG_AUTHID (1<<2) /**< Ban by SteamID */
42 #define BANFLAG_NOKICK (1<<3) /**< Does not kick the client */
43 #define BANFLAG_NOWRITE (1<<4) /**< Ban is not written to SourceDS's files if permanent */
45 IForward *g_pOnBanClient = NULL;
46 IForward *g_pOnBanIdentity = NULL;
47 IForward *g_pOnRemoveBan = NULL;
49 class BanNativeHelpers : public SMGlobalClass
52 void OnSourceModAllInitialized()
54 g_pOnBanClient = forwardsys->CreateForward(
66 g_pOnBanIdentity = forwardsys->CreateForward(
77 g_pOnRemoveBan = forwardsys->CreateForward(
87 void OnSourceModShutdown()
89 forwardsys->ReleaseForward(g_pOnBanClient);
90 forwardsys->ReleaseForward(g_pOnBanIdentity);
91 forwardsys->ReleaseForward(g_pOnRemoveBan);
93 g_pOnBanClient = NULL;
94 g_pOnBanIdentity = NULL;
95 g_pOnRemoveBan = NULL;
100 static cell_t BanIdentity(IPluginContext *pContext, const cell_t *params)
102 char *r_identity, *ban_reason, *ban_cmd;
103 int ban_time, ban_flags, ban_source;
105 pContext->LocalToString(params[1], &r_identity);
106 pContext->LocalToString(params[4], &ban_reason);
107 pContext->LocalToString(params[5], &ban_cmd);
108 ban_time = params[2];
109 ban_flags = params[3];
110 ban_source = params[6];
112 /* Make sure we can ban by one of the two methods! */
113 bool ban_by_ip = ((ban_flags & BANFLAG_IP) == BANFLAG_IP);
114 if (!ban_by_ip && ((ban_flags & BANFLAG_AUTHID) != BANFLAG_AUTHID))
116 return pContext->ThrowNativeError("No valid ban flags specified");
119 /* Sanitize the input */
121 strncopy(identity, r_identity, sizeof(identity));
122 UTIL_ReplaceAll(identity, sizeof(identity), ";", "", true);
125 if (ban_cmd[0] != '\0' && g_pOnBanIdentity->GetFunctionCount() > 0)
127 g_pOnBanIdentity->PushString(identity);
128 g_pOnBanIdentity->PushCell(ban_time);
129 g_pOnBanIdentity->PushCell(ban_flags);
130 g_pOnBanIdentity->PushString(ban_reason);
131 g_pOnBanIdentity->PushString(ban_cmd);
132 g_pOnBanIdentity->PushCell(ban_source);
133 g_pOnBanIdentity->Execute(&handled);
138 bool write_ban = ((ban_flags & BANFLAG_NOWRITE) != BANFLAG_NOWRITE);
149 engine->ServerCommand(command);
151 if (write_ban && ban_time == 0)
153 engine->ServerCommand("writeip\n");
156 else if (!gamehelpers->IsLANServer())
164 engine->ServerCommand(command);
166 if (write_ban && ban_time == 0)
168 engine->ServerCommand("writeid\n");
180 static cell_t RemoveBan(IPluginContext *pContext, const cell_t *params)
182 char *r_identity, *ban_cmd;
183 int ban_flags, ban_source;
185 pContext->LocalToString(params[1], &r_identity);
186 pContext->LocalToString(params[3], &ban_cmd);
187 ban_flags = params[2];
188 ban_source = params[4];
190 /* Make sure we can ban by one of the two methods! */
191 bool ban_by_ip = ((ban_flags & BANFLAG_IP) == BANFLAG_IP);
192 if (!ban_by_ip && ((ban_flags & BANFLAG_AUTHID) != BANFLAG_AUTHID))
194 return pContext->ThrowNativeError("No valid ban flags specified");
198 strncopy(identity, r_identity, sizeof(identity));
199 UTIL_ReplaceAll(identity, sizeof(identity), ";", "", true);
202 if (ban_cmd[0] != '\0' && g_pOnRemoveBan->GetFunctionCount() > 0)
204 g_pOnRemoveBan->PushString(identity);
205 g_pOnRemoveBan->PushCell(ban_flags);
206 g_pOnRemoveBan->PushString(ban_cmd);
207 g_pOnRemoveBan->PushCell(ban_source);
208 g_pOnRemoveBan->Execute(&handled);
221 engine->ServerCommand(command);
222 engine->ServerCommand("writeip\n");
225 else if (!gamehelpers->IsLANServer())
234 engine->ServerCommand(command);
235 engine->ServerCommand("writeid\n");
246 static cell_t BanClient(IPluginContext *pContext, const cell_t *params)
248 const char *kick_message;
249 char *ban_reason, *ban_cmd;
250 int client, ban_flags, ban_source, ban_time;
252 client = gamehelpers->ReferenceToIndex(params[1]);
254 IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
255 if (!pPlayer || !pPlayer->IsConnected())
257 return pContext->ThrowNativeError("Client index %d is invalid", client);
260 if (pPlayer->IsFakeClient())
262 return pContext->ThrowNativeError("Cannot ban fake client %d", client);
265 pContext->LocalToString(params[4], &ban_reason);
266 pContext->LocalToString(params[5], (char **)&kick_message);
267 pContext->LocalToString(params[6], &ban_cmd);
268 ban_time = params[2];
269 ban_flags = params[3];
270 ban_source = params[7];
272 /* Check how we should ban the player */
273 if (!strcmp(smcore.GetSourceEngineName(), "darkmessiah"))
275 /* Dark Messiah doesn't have Steam IDs so there is only one ban method to choose */
276 ban_flags |= BANFLAG_IP;
277 ban_flags &= ~BANFLAG_AUTHID;
279 else if ((ban_flags & BANFLAG_AUTO) == BANFLAG_AUTO)
281 if (gamehelpers->IsLANServer() || !pPlayer->IsAuthorized())
283 ban_flags |= BANFLAG_IP;
284 ban_flags &= ~BANFLAG_AUTHID;
288 ban_flags |= BANFLAG_AUTHID;
289 ban_flags &= ~BANFLAG_IP;
292 else if ((ban_flags & BANFLAG_IP) == BANFLAG_IP)
294 ban_flags |= BANFLAG_IP;
295 ban_flags &= ~BANFLAG_AUTHID;
297 else if ((ban_flags & BANFLAG_AUTHID) == BANFLAG_AUTHID)
299 if (pPlayer->IsAuthorized())
301 ban_flags |= BANFLAG_AUTHID;
302 ban_flags &= ~BANFLAG_IP;
311 return pContext->ThrowNativeError("No valid ban method flags specified");
315 if (ban_cmd[0] != '\0' && g_pOnBanClient->GetFunctionCount() > 0)
317 g_pOnBanClient->PushCell(client);
318 g_pOnBanClient->PushCell(ban_time);
319 g_pOnBanClient->PushCell(ban_flags);
320 g_pOnBanClient->PushString(ban_reason);
321 g_pOnBanClient->PushString(kick_message);
322 g_pOnBanClient->PushString(ban_cmd);
323 g_pOnBanClient->PushCell(ban_source);
324 g_pOnBanClient->Execute(&handled);
327 /* Sanitize the kick message */
328 if (kick_message[0] == '\0')
330 kick_message = "Kicked";
335 if ((ban_flags & BANFLAG_IP) == BANFLAG_IP)
337 /* Get the IP address and strip the port */
339 smcore.strncopy(ip, pPlayer->GetIPAddress(), sizeof(ip));
340 if ((ptr = strchr(ip, ':')) != NULL)
345 /* Tell the server to ban the ip */
355 if ((ban_flags & BANFLAG_NOKICK) != BANFLAG_NOKICK)
357 pPlayer->Kick(kick_message);
359 engine->ServerCommand(command);
361 /* Physically write the ban */
362 if ((ban_time == 0) && ((ban_flags & BANFLAG_NOWRITE) != BANFLAG_NOWRITE))
364 engine->ServerCommand("writeip\n");
367 else if ((ban_flags & BANFLAG_AUTHID) == BANFLAG_AUTHID)
369 /* Tell the server to ban the auth string */
376 pPlayer->GetAuthString());
379 if ((ban_flags & BANFLAG_NOKICK) != BANFLAG_NOKICK)
381 gamehelpers->AddDelayedKick(client, pPlayer->GetUserId(), kick_message);
383 engine->ServerCommand(command);
385 /* Physically write the ban if it's permanent */
386 if ((ban_time == 0) && ((ban_flags & BANFLAG_NOWRITE) != BANFLAG_NOWRITE))
388 engine->ServerCommand("writeid\n");
392 else if ((ban_flags & BANFLAG_NOKICK) != BANFLAG_NOKICK)
394 gamehelpers->AddDelayedKick(client, pPlayer->GetUserId(), kick_message);
401 REGISTER_NATIVES(banNatives)
403 {"BanClient", BanClient},
404 {"BanIdentity", BanIdentity},
405 {"RemoveBan", RemoveBan},