Move banning natives from core to logic (bug 4406 part 3, r=fyren).
1.1 --- a/core/AMBuilder Fri May 14 17:46:19 2010 -0700
1.2 +++ b/core/AMBuilder Fri May 14 18:22:03 2010 -0700
1.3 @@ -49,7 +49,6 @@
1.4 'ConVarManager.cpp',
1.5 'LibrarySys.cpp',
1.6 'PlayerManager.cpp',
1.7 - 'smn_banning.cpp',
1.8 'smn_gameconfigs.cpp',
1.9 'smn_string.cpp',
1.10 'TimerSys.cpp',
2.1 --- a/core/Makefile Fri May 14 17:46:19 2010 -0700
2.2 +++ b/core/Makefile Fri May 14 18:22:03 2010 -0700
2.3 @@ -25,7 +25,7 @@
2.4 OBJECTS += smn_bitbuffer.cpp smn_console.cpp smn_core.cpp \
2.5 smn_datapacks.cpp smn_entities.cpp smn_events.cpp smn_fakenatives.cpp \
2.6 smn_filesystem.cpp smn_gameconfigs.cpp smn_halflife.cpp \
2.7 - smn_handles.cpp smn_keyvalues.cpp smn_banning.cpp \
2.8 + smn_handles.cpp smn_keyvalues.cpp \
2.9 smn_lang.cpp smn_player.cpp smn_string.cpp \
2.10 smn_usermsgs.cpp smn_menus.cpp smn_database.cpp smn_vector.cpp \
2.11 smn_hudtext.cpp smn_nextmap.cpp
3.1 --- a/core/logic/AMBuilder Fri May 14 17:46:19 2010 -0700
3.2 +++ b/core/logic/AMBuilder Fri May 14 18:22:03 2010 -0700
3.3 @@ -34,6 +34,7 @@
3.4 'smn_players.cpp',
3.5 'MemoryUtils.cpp',
3.6 'smn_admin.cpp',
3.7 + 'smn_banning.cpp',
3.8 'sm_crc32.cpp'
3.9 ]
3.10 if AMBuild.target['platform'] == 'windows':
4.1 --- a/core/logic/Makefile Fri May 14 17:46:19 2010 -0700
4.2 +++ b/core/logic/Makefile Fri May 14 18:22:03 2010 -0700
4.3 @@ -30,6 +30,7 @@
4.4 smn_timers.cpp \
4.5 MemoryUtils.cpp \
4.6 smn_admin.cpp \
4.7 + smn_banning.cpp \
4.8 smn_players.cpp
4.9
4.10 ##############################################
5.1 --- a/core/logic/common_logic.cpp Fri May 14 17:46:19 2010 -0700
5.2 +++ b/core/logic/common_logic.cpp Fri May 14 18:22:03 2010 -0700
5.3 @@ -55,6 +55,7 @@
5.4 ServerGlobals serverGlobals;
5.5 IPlayerManager *playerhelpers;
5.6 IAdminSystem *adminsys;
5.7 +IGameHelpers *gamehelpers;
5.8
5.9 static sm_logic_t logic =
5.10 {
6.1 --- a/core/logic/common_logic.h Fri May 14 17:46:19 2010 -0700
6.2 +++ b/core/logic/common_logic.h Fri May 14 18:22:03 2010 -0700
6.3 @@ -51,6 +51,7 @@
6.4 extern ServerGlobals serverGlobals;
6.5 extern IPlayerManager *playerhelpers;
6.6 extern IAdminSystem *adminsys;
6.7 +extern IGameHelpers *gamehelpers;
6.8
6.9 #endif /* _INCLUDE_SOURCEMOD_COMMON_LOGIC_H_ */
6.10
7.1 --- a/core/logic/intercom.h Fri May 14 17:46:19 2010 -0700
7.2 +++ b/core/logic/intercom.h Fri May 14 18:22:03 2010 -0700
7.3 @@ -42,7 +42,7 @@
7.4 * Add 1 to the RHS of this expression to bump the intercom file
7.5 * This is to prevent mismatching core/logic binaries
7.6 */
7.7 -#define SM_LOGIC_MAGIC (0x0F47C0DE - 7)
7.8 +#define SM_LOGIC_MAGIC (0x0F47C0DE - 8)
7.9
7.10 #if defined SM_LOGIC
7.11 class IVEngineServer
7.12 @@ -52,6 +52,7 @@
7.13 {
7.14 public:
7.15 virtual bool IsMapValid(const char *map) = 0;
7.16 + virtual void ServerCommand(const char *cmd) = 0;
7.17 };
7.18
7.19 namespace SourceMod
7.20 @@ -67,6 +68,7 @@
7.21 class IPlayerManager;
7.22 class IMemoryUtils;
7.23 class IAdminSystem;
7.24 + class IGameHelpers;
7.25 }
7.26
7.27 class IVEngineServer;
7.28 @@ -94,6 +96,7 @@
7.29 ITimerSystem *timersys;
7.30 IPlayerManager *playerhelpers;
7.31 IAdminSystem *adminsys;
7.32 + IGameHelpers *gamehelers;
7.33 /* Functions */
7.34 void (*AddNatives)(sp_nativeinfo_t* nlist);
7.35 ConVar * (*FindConVar)(const char*);
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/core/logic/smn_banning.cpp Fri May 14 18:22:03 2010 -0700
8.3 @@ -0,0 +1,407 @@
8.4 +/**
8.5 + * vim: set ts=4 :
8.6 + * =============================================================================
8.7 + * SourceMod
8.8 + * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
8.9 + * =============================================================================
8.10 + *
8.11 + * This program is free software; you can redistribute it and/or modify it under
8.12 + * the terms of the GNU General Public License, version 3.0, as published by the
8.13 + * Free Software Foundation.
8.14 + *
8.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
8.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
8.18 + * details.
8.19 + *
8.20 + * You should have received a copy of the GNU General Public License along with
8.21 + * this program. If not, see <http://www.gnu.org/licenses/>.
8.22 + *
8.23 + * As a special exception, AlliedModders LLC gives you permission to link the
8.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
8.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
8.26 + * by the Valve Corporation. You must obey the GNU General Public License in
8.27 + * all respects for all other code used. Additionally, AlliedModders LLC grants
8.28 + * this exception to all derivative works. AlliedModders LLC defines further
8.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
8.30 + * or <http://www.sourcemod.net/license.php>.
8.31 + *
8.32 + * Version: $Id$
8.33 + */
8.34 +
8.35 +#include "common_logic.h"
8.36 +#include <string.h>
8.37 +#include <IGameHelpers.h>
8.38 +#include <IPlayerHelpers.h>
8.39 +#include <IForwardSys.h>
8.40 +
8.41 +#define BANFLAG_AUTO (1<<0) /**< Auto-detects whether to ban by steamid or IP */
8.42 +#define BANFLAG_IP (1<<1) /**< Always ban by IP address */
8.43 +#define BANFLAG_AUTHID (1<<2) /**< Ban by SteamID */
8.44 +#define BANFLAG_NOKICK (1<<3) /**< Does not kick the client */
8.45 +#define BANFLAG_NOWRITE (1<<4) /**< Ban is not written to SourceDS's files if permanent */
8.46 +
8.47 +IForward *g_pOnBanClient = NULL;
8.48 +IForward *g_pOnBanIdentity = NULL;
8.49 +IForward *g_pOnRemoveBan = NULL;
8.50 +
8.51 +class BanNativeHelpers : public SMGlobalClass
8.52 +{
8.53 +public:
8.54 + void OnSourceModAllInitialized()
8.55 + {
8.56 + g_pOnBanClient = forwardsys->CreateForward(
8.57 + "OnBanClient",
8.58 + ET_Event,
8.59 + 7,
8.60 + NULL,
8.61 + Param_Cell,
8.62 + Param_Cell,
8.63 + Param_Cell,
8.64 + Param_String,
8.65 + Param_String,
8.66 + Param_String,
8.67 + Param_Cell);
8.68 + g_pOnBanIdentity = forwardsys->CreateForward(
8.69 + "OnBanIdentity",
8.70 + ET_Event,
8.71 + 6,
8.72 + NULL,
8.73 + Param_String,
8.74 + Param_Cell,
8.75 + Param_Cell,
8.76 + Param_String,
8.77 + Param_String,
8.78 + Param_Cell);
8.79 + g_pOnRemoveBan = forwardsys->CreateForward(
8.80 + "OnRemoveBan",
8.81 + ET_Event,
8.82 + 4,
8.83 + NULL,
8.84 + Param_String,
8.85 + Param_Cell,
8.86 + Param_String,
8.87 + Param_Cell);
8.88 + }
8.89 + void OnSourceModShutdown()
8.90 + {
8.91 + forwardsys->ReleaseForward(g_pOnBanClient);
8.92 + forwardsys->ReleaseForward(g_pOnBanIdentity);
8.93 + forwardsys->ReleaseForward(g_pOnRemoveBan);
8.94 +
8.95 + g_pOnBanClient = NULL;
8.96 + g_pOnBanIdentity = NULL;
8.97 + g_pOnRemoveBan = NULL;
8.98 + }
8.99 +} s_BanNativeHelpers;
8.100 +
8.101 +
8.102 +static cell_t BanIdentity(IPluginContext *pContext, const cell_t *params)
8.103 +{
8.104 + char *r_identity, *ban_reason, *ban_cmd;
8.105 + int ban_time, ban_flags, ban_source;
8.106 +
8.107 + pContext->LocalToString(params[1], &r_identity);
8.108 + pContext->LocalToString(params[4], &ban_reason);
8.109 + pContext->LocalToString(params[5], &ban_cmd);
8.110 + ban_time = params[2];
8.111 + ban_flags = params[3];
8.112 + ban_source = params[6];
8.113 +
8.114 + /* Make sure we can ban by one of the two methods! */
8.115 + bool ban_by_ip = ((ban_flags & BANFLAG_IP) == BANFLAG_IP);
8.116 + if (!ban_by_ip && ((ban_flags & BANFLAG_AUTHID) != BANFLAG_AUTHID))
8.117 + {
8.118 + return pContext->ThrowNativeError("No valid ban flags specified");
8.119 + }
8.120 +
8.121 + /* Sanitize the input */
8.122 + char identity[64];
8.123 + smcore.strncopy(identity, r_identity, sizeof(identity));
8.124 + smcore.ReplaceAll(identity, sizeof(identity), ";", "", true);
8.125 +
8.126 + cell_t handled = 0;
8.127 + if (ban_cmd[0] != '\0' && g_pOnBanIdentity->GetFunctionCount() > 0)
8.128 + {
8.129 + g_pOnBanIdentity->PushString(identity);
8.130 + g_pOnBanIdentity->PushCell(ban_time);
8.131 + g_pOnBanIdentity->PushCell(ban_flags);
8.132 + g_pOnBanIdentity->PushString(ban_reason);
8.133 + g_pOnBanIdentity->PushString(ban_cmd);
8.134 + g_pOnBanIdentity->PushCell(ban_source);
8.135 + g_pOnBanIdentity->Execute(&handled);
8.136 + }
8.137 +
8.138 + if (!handled)
8.139 + {
8.140 + bool write_ban = ((ban_flags & BANFLAG_NOWRITE) != BANFLAG_NOWRITE);
8.141 +
8.142 + char command[256];
8.143 + if (ban_by_ip)
8.144 + {
8.145 + smcore.Format(
8.146 + command,
8.147 + sizeof(command),
8.148 + "addip %d %s\n",
8.149 + ban_time,
8.150 + identity);
8.151 + engine->ServerCommand(command);
8.152 +
8.153 + if (write_ban && ban_time == 0)
8.154 + {
8.155 + engine->ServerCommand("writeip\n");
8.156 + }
8.157 + }
8.158 + else if (!gamehelpers->IsLANServer())
8.159 + {
8.160 + smcore.Format(
8.161 + command,
8.162 + sizeof(command),
8.163 + "banid %d %s\n",
8.164 + ban_time,
8.165 + identity);
8.166 + engine->ServerCommand(command);
8.167 +
8.168 + if (write_ban && ban_time == 0)
8.169 + {
8.170 + engine->ServerCommand("writeid\n");
8.171 + }
8.172 + }
8.173 + else
8.174 + {
8.175 + return 0;
8.176 + }
8.177 + }
8.178 +
8.179 + return 1;
8.180 +}
8.181 +
8.182 +static cell_t RemoveBan(IPluginContext *pContext, const cell_t *params)
8.183 +{
8.184 + char *r_identity, *ban_cmd;
8.185 + int ban_flags, ban_source;
8.186 +
8.187 + pContext->LocalToString(params[1], &r_identity);
8.188 + pContext->LocalToString(params[3], &ban_cmd);
8.189 + ban_flags = params[2];
8.190 + ban_source = params[4];
8.191 +
8.192 + /* Make sure we can ban by one of the two methods! */
8.193 + bool ban_by_ip = ((ban_flags & BANFLAG_IP) == BANFLAG_IP);
8.194 + if (!ban_by_ip && ((ban_flags & BANFLAG_AUTHID) != BANFLAG_AUTHID))
8.195 + {
8.196 + return pContext->ThrowNativeError("No valid ban flags specified");
8.197 + }
8.198 +
8.199 + char identity[64];
8.200 + smcore.strncopy(identity, r_identity, sizeof(identity));
8.201 + smcore.ReplaceAll(identity, sizeof(identity), ";", "", true);
8.202 +
8.203 + cell_t handled = 0;
8.204 + if (ban_cmd[0] != '\0' && g_pOnRemoveBan->GetFunctionCount() > 0)
8.205 + {
8.206 + g_pOnRemoveBan->PushString(identity);
8.207 + g_pOnRemoveBan->PushCell(ban_flags);
8.208 + g_pOnRemoveBan->PushString(ban_cmd);
8.209 + g_pOnRemoveBan->PushCell(ban_source);
8.210 + g_pOnRemoveBan->Execute(&handled);
8.211 + }
8.212 +
8.213 + char command[256];
8.214 + if (ban_by_ip)
8.215 + {
8.216 + if (!handled)
8.217 + {
8.218 + smcore.Format(
8.219 + command,
8.220 + sizeof(command),
8.221 + "removeip %s\n",
8.222 + identity);
8.223 + engine->ServerCommand(command);
8.224 + engine->ServerCommand("writeip\n");
8.225 + }
8.226 + }
8.227 + else if (!gamehelpers->IsLANServer())
8.228 + {
8.229 + if (!handled)
8.230 + {
8.231 + smcore.Format(
8.232 + command,
8.233 + sizeof(command),
8.234 + "removeid %s\n",
8.235 + identity);
8.236 + engine->ServerCommand(command);
8.237 + engine->ServerCommand("writeid\n");
8.238 + }
8.239 + }
8.240 + else
8.241 + {
8.242 + return 0;
8.243 + }
8.244 +
8.245 + return 1;
8.246 +}
8.247 +
8.248 +static cell_t BanClient(IPluginContext *pContext, const cell_t *params)
8.249 +{
8.250 + const char *kick_message;
8.251 + char *ban_reason, *ban_cmd;
8.252 + int client, ban_flags, ban_source, ban_time;
8.253 +
8.254 + client = gamehelpers->ReferenceToIndex(params[1]);
8.255 +
8.256 + IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
8.257 + if (!pPlayer || !pPlayer->IsConnected())
8.258 + {
8.259 + return pContext->ThrowNativeError("Client index %d is invalid", client);
8.260 + }
8.261 +
8.262 + if (pPlayer->IsFakeClient())
8.263 + {
8.264 + return pContext->ThrowNativeError("Cannot ban fake client %d", client);
8.265 + }
8.266 +
8.267 + pContext->LocalToString(params[4], &ban_reason);
8.268 + pContext->LocalToString(params[5], (char **)&kick_message);
8.269 + pContext->LocalToString(params[6], &ban_cmd);
8.270 + ban_time = params[2];
8.271 + ban_flags = params[3];
8.272 + ban_source = params[7];
8.273 +
8.274 +#if SOURCE_ENGINE != SE_DARKMESSIAH
8.275 + /* Check how we should ban the player */
8.276 + if ((ban_flags & BANFLAG_AUTO) == BANFLAG_AUTO)
8.277 + {
8.278 + if (gamehelpers->IsLANServer() || !pPlayer->IsAuthorized())
8.279 + {
8.280 + ban_flags |= BANFLAG_IP;
8.281 + ban_flags &= ~BANFLAG_AUTHID;
8.282 + }
8.283 + else
8.284 + {
8.285 + ban_flags |= BANFLAG_AUTHID;
8.286 + ban_flags &= ~BANFLAG_IP;
8.287 + }
8.288 + }
8.289 + else if ((ban_flags & BANFLAG_IP) == BANFLAG_IP)
8.290 + {
8.291 + ban_flags |= BANFLAG_IP;
8.292 + ban_flags &= ~BANFLAG_AUTHID;
8.293 + }
8.294 + else if ((ban_flags & BANFLAG_AUTHID) == BANFLAG_AUTHID)
8.295 + {
8.296 + if (pPlayer->IsAuthorized())
8.297 + {
8.298 + ban_flags |= BANFLAG_AUTHID;
8.299 + ban_flags &= ~BANFLAG_IP;
8.300 + }
8.301 + else
8.302 + {
8.303 + return 0;
8.304 + }
8.305 + }
8.306 + else
8.307 + {
8.308 + return pContext->ThrowNativeError("No valid ban method flags specified");
8.309 + }
8.310 +#else
8.311 + /* Dark Messiah doesn't have Steam IDs so there is only one ban method to choose */
8.312 + ban_flags |= BANFLAG_IP;
8.313 + ban_flags &= ~BANFLAG_AUTHID;
8.314 +#endif
8.315 +
8.316 + cell_t handled = 0;
8.317 + if (ban_cmd[0] != '\0' && g_pOnBanClient->GetFunctionCount() > 0)
8.318 + {
8.319 + g_pOnBanClient->PushCell(client);
8.320 + g_pOnBanClient->PushCell(ban_time);
8.321 + g_pOnBanClient->PushCell(ban_flags);
8.322 + g_pOnBanClient->PushString(ban_reason);
8.323 + g_pOnBanClient->PushString(kick_message);
8.324 + g_pOnBanClient->PushString(ban_cmd);
8.325 + g_pOnBanClient->PushCell(ban_source);
8.326 + g_pOnBanClient->Execute(&handled);
8.327 + }
8.328 +
8.329 + /* Sanitize the kick message */
8.330 + if (kick_message[0] == '\0')
8.331 + {
8.332 + kick_message = "Kicked";
8.333 + }
8.334 +
8.335 + if (!handled)
8.336 + {
8.337 + if ((ban_flags & BANFLAG_IP) == BANFLAG_IP)
8.338 + {
8.339 + /* Get the IP address and strip the port */
8.340 + char ip[24], *ptr;
8.341 + smcore.strncopy(ip, pPlayer->GetIPAddress(), sizeof(ip));
8.342 + if ((ptr = strchr(ip, ':')) != NULL)
8.343 + {
8.344 + *ptr = '\0';
8.345 + }
8.346 +
8.347 + /* Tell the server to ban the ip */
8.348 + char command[256];
8.349 + smcore.Format(
8.350 + command,
8.351 + sizeof(command),
8.352 + "addip %d %s\n",
8.353 + ban_time,
8.354 + ip);
8.355 +
8.356 + /* Kick, then ban */
8.357 + if ((ban_flags & BANFLAG_NOKICK) != BANFLAG_NOKICK)
8.358 + {
8.359 + pPlayer->Kick(kick_message);
8.360 + }
8.361 + engine->ServerCommand(command);
8.362 +
8.363 + /* Physically write the ban */
8.364 + if ((ban_time == 0) && ((ban_flags & BANFLAG_NOWRITE) != BANFLAG_NOWRITE))
8.365 + {
8.366 + engine->ServerCommand("writeip\n");
8.367 + }
8.368 + }
8.369 + else if ((ban_flags & BANFLAG_AUTHID) == BANFLAG_AUTHID)
8.370 + {
8.371 + /* Tell the server to ban the auth string */
8.372 + char command[256];
8.373 + smcore.Format(
8.374 + command,
8.375 + sizeof(command),
8.376 + "banid %d %s\n",
8.377 + ban_time,
8.378 + pPlayer->GetAuthString());
8.379 +
8.380 + /* Kick, then ban */
8.381 + if ((ban_flags & BANFLAG_NOKICK) != BANFLAG_NOKICK)
8.382 + {
8.383 + gamehelpers->AddDelayedKick(client, pPlayer->GetUserId(), kick_message);
8.384 + }
8.385 + engine->ServerCommand(command);
8.386 +
8.387 + /* Physically write the ban if it's permanent */
8.388 + if ((ban_time == 0) && ((ban_flags & BANFLAG_NOWRITE) != BANFLAG_NOWRITE))
8.389 + {
8.390 + engine->ServerCommand("writeid\n");
8.391 + }
8.392 + }
8.393 + }
8.394 + else if ((ban_flags & BANFLAG_NOKICK) != BANFLAG_NOKICK)
8.395 + {
8.396 + gamehelpers->AddDelayedKick(client, pPlayer->GetUserId(), kick_message);
8.397 + }
8.398 +
8.399 +
8.400 + return 1;
8.401 +}
8.402 +
8.403 +REGISTER_NATIVES(banNatives)
8.404 +{
8.405 + {"BanClient", BanClient},
8.406 + {"BanIdentity", BanIdentity},
8.407 + {"RemoveBan", RemoveBan},
8.408 + {NULL, NULL}
8.409 +};
8.410 +
9.1 --- a/core/logic_bridge.cpp Fri May 14 17:46:19 2010 -0700
9.2 +++ b/core/logic_bridge.cpp Fri May 14 18:22:03 2010 -0700
9.3 @@ -48,6 +48,7 @@
9.4 #include "DebugReporter.h"
9.5 #include "PlayerManager.h"
9.6 #include "AdminCache.h"
9.7 +#include "HalfLife2.h"
9.8
9.9 static ILibrary *g_pLogic = NULL;
9.10 static LogicInitFunction logic_init_fn;
9.11 @@ -64,6 +65,11 @@
9.12 {
9.13 return engine->IsMapValid(map);
9.14 }
9.15 +
9.16 + virtual void ServerCommand(const char *cmd)
9.17 + {
9.18 + engine->ServerCommand(cmd);
9.19 + }
9.20 };
9.21
9.22 static VEngineServer_Logic logic_engine;
9.23 @@ -118,6 +124,7 @@
9.24 &g_Timers,
9.25 &g_Players,
9.26 &g_Admins,
9.27 + &g_HL2,
9.28 /* Functions */
9.29 add_natives,
9.30 find_convar,
10.1 --- a/core/smn_banning.cpp Fri May 14 17:46:19 2010 -0700
10.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
10.3 @@ -1,407 +0,0 @@
10.4 -/**
10.5 - * vim: set ts=4 :
10.6 - * =============================================================================
10.7 - * SourceMod
10.8 - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
10.9 - * =============================================================================
10.10 - *
10.11 - * This program is free software; you can redistribute it and/or modify it under
10.12 - * the terms of the GNU General Public License, version 3.0, as published by the
10.13 - * Free Software Foundation.
10.14 - *
10.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
10.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
10.18 - * details.
10.19 - *
10.20 - * You should have received a copy of the GNU General Public License along with
10.21 - * this program. If not, see <http://www.gnu.org/licenses/>.
10.22 - *
10.23 - * As a special exception, AlliedModders LLC gives you permission to link the
10.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
10.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
10.26 - * by the Valve Corporation. You must obey the GNU General Public License in
10.27 - * all respects for all other code used. Additionally, AlliedModders LLC grants
10.28 - * this exception to all derivative works. AlliedModders LLC defines further
10.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
10.30 - * or <http://www.sourcemod.net/license.php>.
10.31 - *
10.32 - * Version: $Id$
10.33 - */
10.34 -
10.35 -#include "sm_globals.h"
10.36 -#include "sm_stringutil.h"
10.37 -#include "HalfLife2.h"
10.38 -#include "PlayerManager.h"
10.39 -#include "ForwardSys.h"
10.40 -
10.41 -#define BANFLAG_AUTO (1<<0) /**< Auto-detects whether to ban by steamid or IP */
10.42 -#define BANFLAG_IP (1<<1) /**< Always ban by IP address */
10.43 -#define BANFLAG_AUTHID (1<<2) /**< Ban by SteamID */
10.44 -#define BANFLAG_NOKICK (1<<3) /**< Does not kick the client */
10.45 -#define BANFLAG_NOWRITE (1<<4) /**< Ban is not written to SourceDS's files if permanent */
10.46 -
10.47 -IForward *g_pOnBanClient = NULL;
10.48 -IForward *g_pOnBanIdentity = NULL;
10.49 -IForward *g_pOnRemoveBan = NULL;
10.50 -
10.51 -class BanNativeHelpers : public SMGlobalClass
10.52 -{
10.53 -public:
10.54 - void OnSourceModAllInitialized()
10.55 - {
10.56 - g_pOnBanClient = g_Forwards.CreateForward(
10.57 - "OnBanClient",
10.58 - ET_Event,
10.59 - 7,
10.60 - NULL,
10.61 - Param_Cell,
10.62 - Param_Cell,
10.63 - Param_Cell,
10.64 - Param_String,
10.65 - Param_String,
10.66 - Param_String,
10.67 - Param_Cell);
10.68 - g_pOnBanIdentity = g_Forwards.CreateForward(
10.69 - "OnBanIdentity",
10.70 - ET_Event,
10.71 - 6,
10.72 - NULL,
10.73 - Param_String,
10.74 - Param_Cell,
10.75 - Param_Cell,
10.76 - Param_String,
10.77 - Param_String,
10.78 - Param_Cell);
10.79 - g_pOnRemoveBan = g_Forwards.CreateForward(
10.80 - "OnRemoveBan",
10.81 - ET_Event,
10.82 - 4,
10.83 - NULL,
10.84 - Param_String,
10.85 - Param_Cell,
10.86 - Param_String,
10.87 - Param_Cell);
10.88 - }
10.89 - void OnSourceModShutdown()
10.90 - {
10.91 - g_Forwards.ReleaseForward(g_pOnBanClient);
10.92 - g_Forwards.ReleaseForward(g_pOnBanIdentity);
10.93 - g_Forwards.ReleaseForward(g_pOnRemoveBan);
10.94 -
10.95 - g_pOnBanClient = NULL;
10.96 - g_pOnBanIdentity = NULL;
10.97 - g_pOnRemoveBan = NULL;
10.98 - }
10.99 -} s_BanNativeHelpers;
10.100 -
10.101 -
10.102 -static cell_t BanIdentity(IPluginContext *pContext, const cell_t *params)
10.103 -{
10.104 - char *r_identity, *ban_reason, *ban_cmd;
10.105 - int ban_time, ban_flags, ban_source;
10.106 -
10.107 - pContext->LocalToString(params[1], &r_identity);
10.108 - pContext->LocalToString(params[4], &ban_reason);
10.109 - pContext->LocalToString(params[5], &ban_cmd);
10.110 - ban_time = params[2];
10.111 - ban_flags = params[3];
10.112 - ban_source = params[6];
10.113 -
10.114 - /* Make sure we can ban by one of the two methods! */
10.115 - bool ban_by_ip = ((ban_flags & BANFLAG_IP) == BANFLAG_IP);
10.116 - if (!ban_by_ip && ((ban_flags & BANFLAG_AUTHID) != BANFLAG_AUTHID))
10.117 - {
10.118 - return pContext->ThrowNativeError("No valid ban flags specified");
10.119 - }
10.120 -
10.121 - /* Sanitize the input */
10.122 - char identity[64];
10.123 - strncopy(identity, r_identity, sizeof(identity));
10.124 - UTIL_ReplaceAll(identity, sizeof(identity), ";", "");
10.125 -
10.126 - cell_t handled = 0;
10.127 - if (ban_cmd[0] != '\0' && g_pOnBanIdentity->GetFunctionCount() > 0)
10.128 - {
10.129 - g_pOnBanIdentity->PushString(identity);
10.130 - g_pOnBanIdentity->PushCell(ban_time);
10.131 - g_pOnBanIdentity->PushCell(ban_flags);
10.132 - g_pOnBanIdentity->PushString(ban_reason);
10.133 - g_pOnBanIdentity->PushString(ban_cmd);
10.134 - g_pOnBanIdentity->PushCell(ban_source);
10.135 - g_pOnBanIdentity->Execute(&handled);
10.136 - }
10.137 -
10.138 - if (!handled)
10.139 - {
10.140 - bool write_ban = ((ban_flags & BANFLAG_NOWRITE) != BANFLAG_NOWRITE);
10.141 -
10.142 - char command[256];
10.143 - if (ban_by_ip)
10.144 - {
10.145 - UTIL_Format(
10.146 - command,
10.147 - sizeof(command),
10.148 - "addip %d %s\n",
10.149 - ban_time,
10.150 - identity);
10.151 - engine->ServerCommand(command);
10.152 -
10.153 - if (write_ban && ban_time == 0)
10.154 - {
10.155 - engine->ServerCommand("writeip\n");
10.156 - }
10.157 - }
10.158 - else if (!g_HL2.IsLANServer())
10.159 - {
10.160 - UTIL_Format(
10.161 - command,
10.162 - sizeof(command),
10.163 - "banid %d %s\n",
10.164 - ban_time,
10.165 - identity);
10.166 - engine->ServerCommand(command);
10.167 -
10.168 - if (write_ban && ban_time == 0)
10.169 - {
10.170 - engine->ServerCommand("writeid\n");
10.171 - }
10.172 - }
10.173 - else
10.174 - {
10.175 - return 0;
10.176 - }
10.177 - }
10.178 -
10.179 - return 1;
10.180 -}
10.181 -
10.182 -static cell_t RemoveBan(IPluginContext *pContext, const cell_t *params)
10.183 -{
10.184 - char *r_identity, *ban_cmd;
10.185 - int ban_flags, ban_source;
10.186 -
10.187 - pContext->LocalToString(params[1], &r_identity);
10.188 - pContext->LocalToString(params[3], &ban_cmd);
10.189 - ban_flags = params[2];
10.190 - ban_source = params[4];
10.191 -
10.192 - /* Make sure we can ban by one of the two methods! */
10.193 - bool ban_by_ip = ((ban_flags & BANFLAG_IP) == BANFLAG_IP);
10.194 - if (!ban_by_ip && ((ban_flags & BANFLAG_AUTHID) != BANFLAG_AUTHID))
10.195 - {
10.196 - return pContext->ThrowNativeError("No valid ban flags specified");
10.197 - }
10.198 -
10.199 - char identity[64];
10.200 - strncopy(identity, r_identity, sizeof(identity));
10.201 - UTIL_ReplaceAll(identity, sizeof(identity), ";", "");
10.202 -
10.203 - cell_t handled = 0;
10.204 - if (ban_cmd[0] != '\0' && g_pOnRemoveBan->GetFunctionCount() > 0)
10.205 - {
10.206 - g_pOnRemoveBan->PushString(identity);
10.207 - g_pOnRemoveBan->PushCell(ban_flags);
10.208 - g_pOnRemoveBan->PushString(ban_cmd);
10.209 - g_pOnRemoveBan->PushCell(ban_source);
10.210 - g_pOnRemoveBan->Execute(&handled);
10.211 - }
10.212 -
10.213 - char command[256];
10.214 - if (ban_by_ip)
10.215 - {
10.216 - if (!handled)
10.217 - {
10.218 - UTIL_Format(
10.219 - command,
10.220 - sizeof(command),
10.221 - "removeip %s\n",
10.222 - identity);
10.223 - engine->ServerCommand(command);
10.224 - engine->ServerCommand("writeip\n");
10.225 - }
10.226 - }
10.227 - else if (!g_HL2.IsLANServer())
10.228 - {
10.229 - if (!handled)
10.230 - {
10.231 - UTIL_Format(
10.232 - command,
10.233 - sizeof(command),
10.234 - "removeid %s\n",
10.235 - identity);
10.236 - engine->ServerCommand(command);
10.237 - engine->ServerCommand("writeid\n");
10.238 - }
10.239 - }
10.240 - else
10.241 - {
10.242 - return 0;
10.243 - }
10.244 -
10.245 - return 1;
10.246 -}
10.247 -
10.248 -static cell_t BanClient(IPluginContext *pContext, const cell_t *params)
10.249 -{
10.250 - const char *kick_message;
10.251 - char *ban_reason, *ban_cmd;
10.252 - int client, ban_flags, ban_source, ban_time;
10.253 -
10.254 - client = g_HL2.ReferenceToIndex(params[1]);
10.255 -
10.256 - CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
10.257 - if (!pPlayer || !pPlayer->IsConnected())
10.258 - {
10.259 - return pContext->ThrowNativeError("Client index %d is invalid", client);
10.260 - }
10.261 -
10.262 - if (pPlayer->IsFakeClient())
10.263 - {
10.264 - return pContext->ThrowNativeError("Cannot ban fake client %d", client);
10.265 - }
10.266 -
10.267 - pContext->LocalToString(params[4], &ban_reason);
10.268 - pContext->LocalToString(params[5], (char **)&kick_message);
10.269 - pContext->LocalToString(params[6], &ban_cmd);
10.270 - ban_time = params[2];
10.271 - ban_flags = params[3];
10.272 - ban_source = params[7];
10.273 -
10.274 -#if SOURCE_ENGINE != SE_DARKMESSIAH
10.275 - /* Check how we should ban the player */
10.276 - if ((ban_flags & BANFLAG_AUTO) == BANFLAG_AUTO)
10.277 - {
10.278 - if (g_HL2.IsLANServer() || !pPlayer->IsAuthorized())
10.279 - {
10.280 - ban_flags |= BANFLAG_IP;
10.281 - ban_flags &= ~BANFLAG_AUTHID;
10.282 - }
10.283 - else
10.284 - {
10.285 - ban_flags |= BANFLAG_AUTHID;
10.286 - ban_flags &= ~BANFLAG_IP;
10.287 - }
10.288 - }
10.289 - else if ((ban_flags & BANFLAG_IP) == BANFLAG_IP)
10.290 - {
10.291 - ban_flags |= BANFLAG_IP;
10.292 - ban_flags &= ~BANFLAG_AUTHID;
10.293 - }
10.294 - else if ((ban_flags & BANFLAG_AUTHID) == BANFLAG_AUTHID)
10.295 - {
10.296 - if (pPlayer->IsAuthorized())
10.297 - {
10.298 - ban_flags |= BANFLAG_AUTHID;
10.299 - ban_flags &= ~BANFLAG_IP;
10.300 - }
10.301 - else
10.302 - {
10.303 - return 0;
10.304 - }
10.305 - }
10.306 - else
10.307 - {
10.308 - return pContext->ThrowNativeError("No valid ban method flags specified");
10.309 - }
10.310 -#else
10.311 - /* Dark Messiah doesn't have Steam IDs so there is only one ban method to choose */
10.312 - ban_flags |= BANFLAG_IP;
10.313 - ban_flags &= ~BANFLAG_AUTHID;
10.314 -#endif
10.315 -
10.316 - cell_t handled = 0;
10.317 - if (ban_cmd[0] != '\0' && g_pOnBanClient->GetFunctionCount() > 0)
10.318 - {
10.319 - g_pOnBanClient->PushCell(client);
10.320 - g_pOnBanClient->PushCell(ban_time);
10.321 - g_pOnBanClient->PushCell(ban_flags);
10.322 - g_pOnBanClient->PushString(ban_reason);
10.323 - g_pOnBanClient->PushString(kick_message);
10.324 - g_pOnBanClient->PushString(ban_cmd);
10.325 - g_pOnBanClient->PushCell(ban_source);
10.326 - g_pOnBanClient->Execute(&handled);
10.327 - }
10.328 -
10.329 - /* Sanitize the kick message */
10.330 - if (kick_message[0] == '\0')
10.331 - {
10.332 - kick_message = "Kicked";
10.333 - }
10.334 -
10.335 - if (!handled)
10.336 - {
10.337 - if ((ban_flags & BANFLAG_IP) == BANFLAG_IP)
10.338 - {
10.339 - /* Get the IP address and strip the port */
10.340 - char ip[24], *ptr;
10.341 - strncopy(ip, pPlayer->GetIPAddress(), sizeof(ip));
10.342 - if ((ptr = strchr(ip, ':')) != NULL)
10.343 - {
10.344 - *ptr = '\0';
10.345 - }
10.346 -
10.347 - /* Tell the server to ban the ip */
10.348 - char command[256];
10.349 - UTIL_Format(
10.350 - command,
10.351 - sizeof(command),
10.352 - "addip %d %s\n",
10.353 - ban_time,
10.354 - ip);
10.355 -
10.356 - /* Kick, then ban */
10.357 - if ((ban_flags & BANFLAG_NOKICK) != BANFLAG_NOKICK)
10.358 - {
10.359 - pPlayer->Kick(kick_message);
10.360 - }
10.361 - engine->ServerCommand(command);
10.362 -
10.363 - /* Physically write the ban */
10.364 - if ((ban_time == 0) && ((ban_flags & BANFLAG_NOWRITE) != BANFLAG_NOWRITE))
10.365 - {
10.366 - engine->ServerCommand("writeip\n");
10.367 - }
10.368 - }
10.369 - else if ((ban_flags & BANFLAG_AUTHID) == BANFLAG_AUTHID)
10.370 - {
10.371 - /* Tell the server to ban the auth string */
10.372 - char command[256];
10.373 - UTIL_Format(
10.374 - command,
10.375 - sizeof(command),
10.376 - "banid %d %s\n",
10.377 - ban_time,
10.378 - pPlayer->GetAuthString());
10.379 -
10.380 - /* Kick, then ban */
10.381 - if ((ban_flags & BANFLAG_NOKICK) != BANFLAG_NOKICK)
10.382 - {
10.383 - g_HL2.AddDelayedKick(client, pPlayer->GetUserId(), kick_message);
10.384 - }
10.385 - engine->ServerCommand(command);
10.386 -
10.387 - /* Physically write the ban if it's permanent */
10.388 - if ((ban_time == 0) && ((ban_flags & BANFLAG_NOWRITE) != BANFLAG_NOWRITE))
10.389 - {
10.390 - engine->ServerCommand("writeid\n");
10.391 - }
10.392 - }
10.393 - }
10.394 - else if ((ban_flags & BANFLAG_NOKICK) != BANFLAG_NOKICK)
10.395 - {
10.396 - g_HL2.AddDelayedKick(client, pPlayer->GetUserId(), kick_message);
10.397 - }
10.398 -
10.399 -
10.400 - return 1;
10.401 -}
10.402 -
10.403 -REGISTER_NATIVES(banNatives)
10.404 -{
10.405 - {"BanClient", BanClient},
10.406 - {"BanIdentity", BanIdentity},
10.407 - {"RemoveBan", RemoveBan},
10.408 - {NULL, NULL}
10.409 -};
10.410 -