From a00a574b4a56d933febb9f7ac1dd5c2ebe23bb88 Mon Sep 17 00:00:00 2001 From: Marco Hladik Date: Fri, 14 Aug 2020 22:13:03 +0200 Subject: [PATCH] Plugins: Added ClientConnect and ClientDisconnect hooks --- src/server/defs.h | 1 + src/server/plugins.c | 74 ++++++++++++++++++++++++++++++++-- src/server/plugins.h | 25 ++++++++++++ src/server/valve/gamerules.cpp | 9 +++-- 4 files changed, 103 insertions(+), 6 deletions(-) create mode 100644 src/server/plugins.h diff --git a/src/server/defs.h b/src/server/defs.h index c3b85bd5..f74706d4 100644 --- a/src/server/defs.h +++ b/src/server/defs.h @@ -23,6 +23,7 @@ #include "spawn.h" #include "flashlight.h" #include "weapons.h" +#include "plugins.h" #define CLASSEXPORT(classname,classa) void classname(void) { spawnfunc_##classa(); } diff --git a/src/server/plugins.c b/src/server/plugins.c index 0b7ca614..be0654da 100644 --- a/src/server/plugins.c +++ b/src/server/plugins.c @@ -14,9 +14,6 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -var int g_plugins_enabled; -var int autocvar_sv_plugins = 1; - typedef struct { string m_strPath; @@ -156,3 +153,74 @@ Plugin_ParseClientCommand(string msg) return rval; } + +/* +================= +Plugin_PlayerConnect + +Called whenever a new client connect to the game +================= +*/ +int +Plugin_PlayerConnect(entity cl) +{ + int rval; + int tval; + int(entity) vFunc; + + if (g_plugins_enabled == 0) + return FALSE; + + /* rval = final return value, tval = temporary return value. + if at least one of the plugins returns TRUE, then RunClientCommand + will not be called by the engine, as it should be */ + rval = FALSE; + tval = FALSE; + + for (int i = 0; i < g_plugincount; i++) { + vFunc = externvalue(g_plugindb[i].m_flProgsID, "FMX_PlayerConnect"); + + if (vFunc) { + tval = vFunc(cl); + rval |= tval; + } + } + + return rval; +} + + +/* +================= +Plugin_PlayerDisconnect + +Called whenever a client leaves the game +================= +*/ +int +Plugin_PlayerDisconnect(entity cl) +{ + int rval; + int tval; + int(entity) vFunc; + + if (g_plugins_enabled == 0) + return FALSE; + + /* rval = final return value, tval = temporary return value. + if at least one of the plugins returns TRUE, then RunClientCommand + will not be called by the engine, as it should be */ + rval = FALSE; + tval = FALSE; + + for (int i = 0; i < g_plugincount; i++) { + vFunc = externvalue(g_plugindb[i].m_flProgsID, "FMX_PlayerDisconnect"); + + if (vFunc) { + tval = vFunc(cl); + rval |= tval; + } + } + + return rval; +} diff --git a/src/server/plugins.h b/src/server/plugins.h new file mode 100644 index 00000000..9300aa0c --- /dev/null +++ b/src/server/plugins.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +var int g_plugins_enabled; +var int autocvar_sv_plugins = 1; + +void Plugin_Init(void); +void Plugin_Shutdown(void); +int Plugin_RunClientCommand(void); +int Plugin_ParseClientCommand(string msg); +int Plugin_PlayerConnect(entity cl); +int Plugin_PlayerDisconnect(entity cl); diff --git a/src/server/valve/gamerules.cpp b/src/server/valve/gamerules.cpp index 89489b47..450f9a99 100644 --- a/src/server/valve/gamerules.cpp +++ b/src/server/valve/gamerules.cpp @@ -208,7 +208,9 @@ void HLGameRules::PlayerConnect(entity pl) { entity a; - bprint(PRINT_HIGH, sprintf("%s connected\n", pl.netname)); + + if (Plugin_PlayerConnect(pl) == FALSE) + bprint(PRINT_HIGH, sprintf("%s connected\n", pl.netname)); int playercount = 0; for (a = world; (a = find(a, ::classname, "player"));) { @@ -228,7 +230,8 @@ HLGameRules::PlayerConnect(entity pl) void HLGameRules::PlayerDisconnect(entity pl) { - bprint(PRINT_HIGH, sprintf("%s disconnected\n", pl.netname)); + if (Plugin_PlayerDisconnect(pl) == FALSE) + bprint(PRINT_HIGH, sprintf("%s disconnected\n", pl.netname)); /* Make this unusable */ pl.solid = SOLID_NOT; @@ -236,7 +239,7 @@ HLGameRules::PlayerDisconnect(entity pl) pl.modelindex = 0; pl.health = 0; pl.takedamage = 0; - pl.SendFlags = PLAYER_MODELINDEX; + pl.SendFlags = -1; } void