From 74b23aebfee6560d4075922e0a3584eca176f044 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 14 Sep 2007 02:11:10 +0000 Subject: [PATCH] - added 3 new natives for banning/unbanning and interception - moved banning commands into new plugin, basebans - improved quality and input methods of ban commands - corrected svn props on a few files - added an IsLANServer() to IGameHelpers API - completely deprecated and removed old banning forwards --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401429 --- core/HalfLife2.cpp | 14 ++ core/HalfLife2.h | 1 + core/Makefile | 3 +- core/smn_banning.cpp | 378 ++++++++++++++++++++++++++++++++ core/smn_player.cpp | 1 + plugins/basebans.sp | 284 ++++++++++++++++++++++++ plugins/basecommands.sp | 269 ----------------------- plugins/include/banning.inc | 156 +++++++++++++ plugins/include/clients.inc | 1 + plugins/include/helpers.inc | 31 --- plugins/include/sourcemod.inc | 1 + public/IGameHelpers.h | 9 +- tools/builder/PkgCore.cs | 3 +- translations/common.phrases.txt | 6 + 14 files changed, 854 insertions(+), 303 deletions(-) create mode 100644 core/smn_banning.cpp create mode 100644 plugins/basebans.sp create mode 100644 plugins/include/banning.inc diff --git a/core/HalfLife2.cpp b/core/HalfLife2.cpp index 3265756d..c1f7cf46 100644 --- a/core/HalfLife2.cpp +++ b/core/HalfLife2.cpp @@ -37,6 +37,7 @@ CHalfLife2 g_HL2; bool g_IsOriginalEngine = false; +ConVar *sv_lan = NULL; namespace SourceHook { @@ -369,3 +370,16 @@ void CHalfLife2::ProcessFakeCliCmdQueue() m_CmdQueue.pop(); } } + +bool CHalfLife2::IsLANServer() +{ + sv_lan = icvar->FindVar("sv_lan"); + + if (!sv_lan) + { + return false; + } + + return (sv_lan->GetInt() != 0); +} + diff --git a/core/HalfLife2.h b/core/HalfLife2.h index a617fcf4..23664fc3 100644 --- a/core/HalfLife2.h +++ b/core/HalfLife2.h @@ -86,6 +86,7 @@ public: //IGameHelpers bool TextMsg(int client, int dest, const char *msg); bool HintTextMsg(int client, const char *msg); bool ShowVGUIMenu(int client, const char *name, KeyValues *data, bool show); + bool IsLANServer(); public: void AddToFakeCliCmdQueue(int client, int userid, const char *cmd); void ProcessFakeCliCmdQueue(); diff --git a/core/Makefile b/core/Makefile index c9022815..8af985e1 100644 --- a/core/Makefile +++ b/core/Makefile @@ -27,7 +27,8 @@ OBJECTS = AdminCache.cpp CDataPack.cpp ConCmdManager.cpp ConVarManager.cpp CoreC frame_hooks.cpp OBJECTS += smn_admin.cpp smn_bitbuffer.cpp smn_console.cpp smn_core.cpp \ smn_datapacks.cpp smn_entities.cpp smn_events.cpp smn_fakenatives.cpp \ - smn_filesystem.cpp smn_float.cpp smn_functions.cpp smn_gameconfigs.cpp smn_halflife.cpp smn_handles.cpp smn_keyvalues.cpp \ + smn_filesystem.cpp smn_float.cpp smn_functions.cpp smn_gameconfigs.cpp smn_halflife.cpp \ + smn_handles.cpp smn_keyvalues.cpp smn_banning.cpp \ smn_lang.cpp smn_player.cpp smn_string.cpp smn_sorting.cpp smn_textparse.cpp smn_timers.cpp \ smn_usermsgs.cpp smn_menus.cpp smn_database.cpp smn_vector.cpp smn_adt_array.cpp OBJECTS += systems/ExtensionSys.cpp systems/ForwardSys.cpp systems/HandleSys.cpp \ diff --git a/core/smn_banning.cpp b/core/smn_banning.cpp new file mode 100644 index 00000000..6984e71e --- /dev/null +++ b/core/smn_banning.cpp @@ -0,0 +1,378 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod + * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved. + * ============================================================================= + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, version 3.0, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + * As a special exception, AlliedModders LLC gives you permission to link the + * code of this program (as well as its derivative works) to "Half-Life 2," the + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software + * by the Valve Corporation. You must obey the GNU General Public License in + * all respects for all other code used. Additionally, AlliedModders LLC grants + * this exception to all derivative works. AlliedModders LLC defines further + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), + * or . + * + * Version: $Id$ + */ + +#include "sm_globals.h" +#include "sm_stringutil.h" +#include "HalfLife2.h" +#include "PlayerManager.h" +#include "ForwardSys.h" +#include +#include + +#define BANFLAG_AUTO (1<<0) /**< Auto-detects whether to ban by steamid or IP */ +#define BANFLAG_IP (1<<1) /**< Always ban by IP address */ +#define BANFLAG_AUTHID (1<<2) /**< Ban by SteamID */ +#define BANFLAG_NOKICK (1<<3) /**< Does not kick the client */ +#define BANFLAG_NOWRITE (1<<4) /**< Ban is not written to SourceDS's files if permanent */ + +IForward *g_pOnBanClient = NULL; +IForward *g_pOnBanIdentity = NULL; +IForward *g_pOnRemoveBan = NULL; + +class BanNativeHelpers : public SMGlobalClass +{ +public: + void OnSourceModAllInitialized() + { + g_pOnBanClient = g_Forwards.CreateForward( + "OnBanClient", + ET_Ignore, + 7, + NULL, + Param_Cell, + Param_Cell, + Param_Cell, + Param_String, + Param_String, + Param_String, + Param_Cell); + g_pOnBanIdentity = g_Forwards.CreateForward( + "OnBanIdentity", + ET_Ignore, + 6, + NULL, + Param_String, + Param_Cell, + Param_Cell, + Param_String, + Param_String, + Param_Cell); + g_pOnRemoveBan = g_Forwards.CreateForward( + "OnRemoveBan", + ET_Ignore, + 4, + NULL, + Param_String, + Param_Cell, + Param_String, + Param_Cell); + } + void OnSourceModShutdown() + { + g_Forwards.ReleaseForward(g_pOnBanClient); + g_Forwards.ReleaseForward(g_pOnBanIdentity); + g_Forwards.ReleaseForward(g_pOnRemoveBan); + + g_pOnBanClient = NULL; + g_pOnBanIdentity = NULL; + g_pOnRemoveBan = NULL; + } +} s_BanNativeHelpers; + + +static cell_t BanIdentity(IPluginContext *pContext, const cell_t *params) +{ + char *r_identity, *ban_reason, *ban_cmd; + int ban_time, ban_flags, ban_source; + + pContext->LocalToString(params[1], &r_identity); + pContext->LocalToString(params[4], &ban_reason); + pContext->LocalToString(params[5], &ban_cmd); + ban_time = params[2]; + ban_flags = params[3]; + ban_source = params[6]; + + /* Make sure we can ban by one of the two methods! */ + bool ban_by_ip = ((ban_flags & BANFLAG_IP) == BANFLAG_IP); + if (!ban_by_ip && ((ban_flags & BANFLAG_AUTHID) != BANFLAG_AUTHID)) + { + return pContext->ThrowNativeError("No valid ban flags specified"); + } + + /* Sanitize the input */ + char identity[64]; + strncopy(identity, r_identity, sizeof(identity)); + UTIL_ReplaceAll(identity, sizeof(identity), ";", ""); + + if (ban_cmd[0] != '\0' && g_pOnBanIdentity->GetFunctionCount() > 0) + { + g_pOnBanIdentity->PushString(identity); + g_pOnBanIdentity->PushCell(ban_time); + g_pOnBanIdentity->PushCell(ban_flags); + g_pOnBanIdentity->PushString(ban_reason); + g_pOnBanIdentity->PushString(ban_cmd); + g_pOnBanIdentity->PushCell(ban_source); + g_pOnBanIdentity->Execute(NULL); + } + + bool write_ban = ((ban_flags & BANFLAG_NOWRITE) != BANFLAG_NOWRITE); + + char command[256]; + if (ban_by_ip) + { + UTIL_Format( + command, + sizeof(command), + "addip %d %s\n", + ban_time, + identity); + engine->ServerCommand(command); + + if (write_ban && ban_time == 0) + { + engine->ServerCommand("writeip\n"); + } + } + else if (!g_HL2.IsLANServer()) + { + UTIL_Format( + command, + sizeof(command), + "banid %d %s\n", + ban_time, + identity); + engine->ServerCommand(command); + + if (write_ban && ban_time == 0) + { + engine->ServerCommand("writeid\n"); + } + } + else + { + return 0; + } + + return 1; +} + +static cell_t RemoveBan(IPluginContext *pContext, const cell_t *params) +{ + char *r_identity, *ban_cmd; + int ban_flags, ban_source; + + pContext->LocalToString(params[1], &r_identity); + pContext->LocalToString(params[3], &ban_cmd); + ban_flags = params[2]; + ban_source = params[4]; + + /* Make sure we can ban by one of the two methods! */ + bool ban_by_ip = ((ban_flags & BANFLAG_IP) == BANFLAG_IP); + if (!ban_by_ip && ((ban_flags & BANFLAG_AUTHID) != BANFLAG_AUTHID)) + { + return pContext->ThrowNativeError("No valid ban flags specified"); + } + + char identity[64]; + strncopy(identity, r_identity, sizeof(identity)); + UTIL_ReplaceAll(identity, sizeof(identity), ";", ""); + + if (ban_cmd[0] != '\0' && g_pOnRemoveBan->GetFunctionCount() > 0) + { + g_pOnRemoveBan->PushString(identity); + g_pOnRemoveBan->PushCell(ban_flags); + g_pOnRemoveBan->PushString(ban_cmd); + g_pOnRemoveBan->PushCell(ban_source); + g_pOnRemoveBan->Execute(NULL); + } + + char command[256]; + if (ban_by_ip) + { + UTIL_Format( + command, + sizeof(command), + "removeip %s\n", + identity); + engine->ServerCommand(command); + engine->ServerCommand("writeip\n"); + } + else if (!g_HL2.IsLANServer()) + { + UTIL_Format( + command, + sizeof(command), + "removeid %s\n", + identity); + engine->ServerCommand(command); + engine->ServerCommand("writeid\n"); + } + else + { + return 0; + } + + return 1; +} + +static cell_t BanClient(IPluginContext *pContext, const cell_t *params) +{ + const char *kick_message; + char *ban_reason, *ban_cmd; + int client, ban_flags, ban_source, ban_time; + + client = params[1]; + + CPlayer *pPlayer = g_Players.GetPlayerByIndex(client); + if (!pPlayer || !pPlayer->IsConnected()) + { + return pContext->ThrowNativeError("Client index %d is invalid", client); + } + + pContext->LocalToString(params[4], &ban_reason); + pContext->LocalToString(params[5], (char **)&kick_message); + pContext->LocalToString(params[6], &ban_cmd); + ban_time = params[2]; + ban_flags = params[3]; + ban_source = params[7]; + + INetChannel *pNetChan = static_cast(engine->GetPlayerNetInfo(params[1])); + IClient *pClient = static_cast(pNetChan->GetMsgHandler()); + + /* Check how we should ban the player */ + if ((ban_flags & BANFLAG_AUTO) == BANFLAG_AUTO) + { + if (g_HL2.IsLANServer() || !pPlayer->IsAuthorized()) + { + ban_flags |= BANFLAG_IP; + ban_flags &= BANFLAG_AUTHID; + } + else + { + ban_flags |= BANFLAG_AUTHID; + ban_flags &= BANFLAG_IP; + } + } + else if ((ban_flags & BANFLAG_IP) == BANFLAG_IP) + { + ban_flags |= BANFLAG_IP; + ban_flags &= BANFLAG_AUTHID; + } + else if ((ban_flags & BANFLAG_AUTHID) == BANFLAG_AUTHID) + { + if (pPlayer->IsAuthorized()) + { + ban_flags |= BANFLAG_AUTHID; + ban_flags &= BANFLAG_IP; + } + else + { + return 0; + } + } + else + { + return pContext->ThrowNativeError("No valid ban method flags specified"); + } + + if (ban_cmd[0] != '\0' && g_pOnBanClient->GetFunctionCount() > 0) + { + g_pOnBanClient->PushCell(client); + g_pOnBanClient->PushCell(ban_time); + g_pOnBanClient->PushCell(ban_flags); + g_pOnBanClient->PushString(ban_reason); + g_pOnBanClient->PushString(kick_message); + g_pOnBanClient->PushString(ban_cmd); + g_pOnBanClient->PushCell(ban_source); + g_pOnBanClient->Execute(NULL); + } + + if ((ban_flags & BANFLAG_NOKICK) != BANFLAG_NOKICK) + { + /* Build a kick message */ + const char *kick_message = ""; + pContext->LocalToString(params[5], (char **)&kick_message); + if (kick_message[0] == '\0') + { + kick_message = "Kicked"; + } + + /* Disconnect the client now */ + pClient->Disconnect("%s", kick_message); + } + + if ((ban_flags & BANFLAG_IP) == BANFLAG_IP) + { + /* Get the IP address and strip the port */ + char ip[24], *ptr; + strncopy(ip, pPlayer->GetIPAddress(), sizeof(ip)); + if ((ptr = strchr(ip, ':')) != NULL) + { + *ptr = '\0'; + } + + /* Tell the server to ban the ip */ + char command[256]; + UTIL_Format( + command, + sizeof(command), + "addip %d %s\n", + ban_time, + ip); + engine->ServerCommand(command); + + /* Physically write the ban */ + if ((ban_time == 0) && ((ban_flags & BANFLAG_NOWRITE) != BANFLAG_NOWRITE)) + { + engine->ServerCommand("writeip\n"); + } + } + else if ((ban_flags & BANFLAG_AUTHID) == BANFLAG_AUTHID) + { + /* Tell the server to ban the auth string */ + char command[256]; + UTIL_Format( + command, + sizeof(command), + "banid %d %s\n", + ban_time, + pPlayer->GetAuthString()); + engine->ServerCommand(command); + + /* Physically write the ban if it's permanent */ + if ((ban_time == 0) && ((ban_flags & BANFLAG_NOWRITE) != BANFLAG_NOWRITE)) + { + engine->ServerCommand("writeid\n"); + } + } + + + return 1; +} + +REGISTER_NATIVES(banNatives) +{ + {"BanClient", BanClient}, + {"BanIdentity", BanIdentity}, + {"RemoveBan", RemoveBan}, + {NULL, NULL} +}; + diff --git a/core/smn_player.cpp b/core/smn_player.cpp index d7d686e6..a82f71db 100644 --- a/core/smn_player.cpp +++ b/core/smn_player.cpp @@ -1142,3 +1142,4 @@ REGISTER_NATIVES(playernatives) {"NotifyPostAdminCheck", NotifyPostAdminCheck}, {NULL, NULL} }; + diff --git a/plugins/basebans.sp b/plugins/basebans.sp new file mode 100644 index 00000000..90ec2d24 --- /dev/null +++ b/plugins/basebans.sp @@ -0,0 +1,284 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Basic Commands Plugin + * Implements basic admin commands. + * + * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved. + * ============================================================================= + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, version 3.0, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + * As a special exception, AlliedModders LLC gives you permission to link the + * code of this program (as well as its derivative works) to "Half-Life 2," the + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software + * by the Valve Corporation. You must obey the GNU General Public License in + * all respects for all other code used. Additionally, AlliedModders LLC grants + * this exception to all derivative works. AlliedModders LLC defines further + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), + * or . + * + * Version: $Id$ + */ + +#pragma semicolon 1 + +#include + +public Plugin:myinfo = +{ + name = "Basic Ban Commands", + author = "AlliedModders LLC", + description = "Basic Banning Commands", + version = SOURCEMOD_VERSION, + url = "http://www.sourcemod.net/" +}; + +public OnPluginStart() +{ + LoadTranslations("common.phrases"); + + RegAdminCmd("sm_ban", Command_Ban, ADMFLAG_BAN, "sm_ban <#userid|name> [reason]"); + RegAdminCmd("sm_unban", Command_Unban, ADMFLAG_UNBAN, "sm_unban "); + RegAdminCmd("sm_addban", Command_AddBan, ADMFLAG_RCON, "sm_addban