2019-08-31 19:18:15 -07:00
|
|
|
/*
|
2022-07-07 09:10:14 -07:00
|
|
|
* Copyright (c) 2016-2022 Vera Visions LLC.
|
2019-08-31 19:18:15 -07:00
|
|
|
*
|
|
|
|
* 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.
|
2022-07-07 09:10:14 -07:00
|
|
|
*/
|
2019-08-14 02:43:43 -07:00
|
|
|
|
2020-08-14 12:16:47 -07:00
|
|
|
typedef struct
|
2020-04-12 06:50:42 -07:00
|
|
|
{
|
2020-08-14 12:16:47 -07:00
|
|
|
string m_strPath;
|
|
|
|
float m_flProgsID;
|
|
|
|
} plugin_t;
|
|
|
|
|
|
|
|
plugin_t *g_plugindb;
|
|
|
|
var int g_plugincount;
|
|
|
|
|
|
|
|
void
|
|
|
|
Plugin_Init(void)
|
|
|
|
{
|
|
|
|
filestream pdb;
|
|
|
|
string tmp;
|
|
|
|
int i;
|
|
|
|
|
2019-08-14 02:43:43 -07:00
|
|
|
if (autocvar_sv_plugins) {
|
|
|
|
g_plugins_enabled = 1;
|
|
|
|
} else {
|
|
|
|
g_plugins_enabled = 0;
|
2020-08-14 12:16:47 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-03-02 00:40:08 -08:00
|
|
|
InitStart();
|
|
|
|
|
2020-08-14 12:16:47 -07:00
|
|
|
pdb = fopen("plugins.txt", FILE_READ);
|
|
|
|
|
|
|
|
if (pdb < 0) {
|
2024-03-02 00:40:08 -08:00
|
|
|
NSWarning("No plugins.txt found. Plugins disabled.\n");
|
2020-08-14 12:16:47 -07:00
|
|
|
g_plugins_enabled = 0;
|
2024-03-02 00:40:08 -08:00
|
|
|
InitEnd();
|
2020-08-14 12:16:47 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* count valid progs */
|
|
|
|
g_plugincount = 0;
|
|
|
|
while ((tmp = fgets(pdb))) {
|
2021-05-07 05:15:08 -07:00
|
|
|
int argc = tokenize_console(tmp);
|
|
|
|
|
|
|
|
/* check for valid entries/comments */
|
|
|
|
if (argc <= 0)
|
|
|
|
continue;
|
|
|
|
|
2020-08-14 12:16:47 -07:00
|
|
|
g_plugincount++;
|
2019-08-14 02:43:43 -07:00
|
|
|
}
|
2020-08-14 12:16:47 -07:00
|
|
|
|
|
|
|
g_plugindb = memalloc(sizeof(plugin_t) * g_plugincount);
|
|
|
|
fseek(pdb, 0);
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
while ((tmp = fgets(pdb))) {
|
2021-05-07 05:15:08 -07:00
|
|
|
int a = tokenize_console(tmp);
|
|
|
|
|
|
|
|
/* check for valid entries/comments */
|
|
|
|
if (a <= 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
g_plugindb[i].m_strPath = strcat("plugins/", argv(0));
|
|
|
|
g_plugindb[i].m_flProgsID = addprogs(g_plugindb[i].m_strPath);
|
2020-08-14 12:16:47 -07:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose(pdb);
|
|
|
|
|
|
|
|
void(void) vFunc;
|
|
|
|
for (i = 0; i < g_plugincount; i++) {
|
|
|
|
vFunc = externvalue(g_plugindb[i].m_flProgsID, "FMX_Init");
|
|
|
|
|
|
|
|
if (vFunc) {
|
|
|
|
vFunc();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-02 00:40:08 -08:00
|
|
|
NSLog("...initialized %i plugins.", g_plugincount);
|
|
|
|
InitEnd();
|
2020-08-14 12:16:47 -07:00
|
|
|
}
|
|
|
|
|
2020-08-15 16:04:20 -07:00
|
|
|
/*
|
|
|
|
=================
|
|
|
|
Plugin_Shutdown
|
|
|
|
|
|
|
|
Allows every plugin to properly free and unallocate whatever it is they've done
|
|
|
|
=================
|
|
|
|
*/
|
2020-08-14 12:16:47 -07:00
|
|
|
void
|
|
|
|
Plugin_Shutdown(void)
|
|
|
|
{
|
2020-08-15 16:04:20 -07:00
|
|
|
void(void) vFunc;
|
|
|
|
|
|
|
|
if (g_plugincount <= 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (int i = 0; i < g_plugincount; i++) {
|
|
|
|
vFunc = externvalue(g_plugindb[i].m_flProgsID, "FMX_Shutdown");
|
|
|
|
|
|
|
|
if (vFunc) {
|
|
|
|
vFunc();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-14 12:16:47 -07:00
|
|
|
memfree(g_plugindb);
|
|
|
|
g_plugincount = 0;
|
2019-08-14 02:43:43 -07:00
|
|
|
}
|
|
|
|
|
2020-08-15 16:04:20 -07:00
|
|
|
/*
|
|
|
|
=================
|
|
|
|
Plugin_InitEnts
|
|
|
|
|
|
|
|
Called once entity slots are available for use.
|
|
|
|
=================
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
Plugin_InitEnts(void)
|
|
|
|
{
|
|
|
|
void(void) vFunc;
|
|
|
|
|
|
|
|
if (g_plugins_enabled == 0)
|
2021-05-10 02:33:31 -07:00
|
|
|
return (0);
|
2020-08-15 16:04:20 -07:00
|
|
|
|
|
|
|
for (int i = 0; i < g_plugincount; i++) {
|
|
|
|
vFunc = externvalue(g_plugindb[i].m_flProgsID, "FMX_InitEnts");
|
|
|
|
|
|
|
|
if (vFunc) {
|
|
|
|
vFunc();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-17 19:35:31 -07:00
|
|
|
/*
|
|
|
|
=================
|
|
|
|
Plugin_RunClientCommand
|
|
|
|
|
|
|
|
Funtion that can interrupt client commands before physics are run
|
|
|
|
=================
|
|
|
|
*/
|
2020-08-14 12:16:47 -07:00
|
|
|
int
|
|
|
|
Plugin_RunClientCommand(void)
|
2019-08-14 02:43:43 -07:00
|
|
|
{
|
2020-08-14 12:16:47 -07:00
|
|
|
int rval;
|
|
|
|
int tval;
|
|
|
|
int(void) vFunc;
|
2019-08-14 02:43:43 -07:00
|
|
|
|
2020-08-14 12:16:47 -07:00
|
|
|
if (g_plugins_enabled == 0)
|
2021-05-10 02:33:31 -07:00
|
|
|
return (0);
|
2020-08-14 12:16:47 -07:00
|
|
|
|
|
|
|
/* 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_RunClientCommand");
|
|
|
|
|
|
|
|
if (vFunc) {
|
|
|
|
tval = vFunc();
|
|
|
|
rval |= tval;
|
|
|
|
}
|
2019-08-14 02:43:43 -07:00
|
|
|
}
|
|
|
|
|
2020-08-14 12:16:47 -07:00
|
|
|
return rval;
|
2019-08-14 02:43:43 -07:00
|
|
|
}
|
|
|
|
|
2019-08-17 19:35:31 -07:00
|
|
|
/*
|
|
|
|
=================
|
|
|
|
Plugin_ParseClientCommand
|
|
|
|
|
|
|
|
Intercepts 'cmd' calls. We use it to intercept
|
|
|
|
chat messages and handle distribution ourselves.
|
|
|
|
=================
|
|
|
|
*/
|
2020-11-06 04:04:22 -08:00
|
|
|
string
|
2020-08-14 12:16:47 -07:00
|
|
|
Plugin_ParseClientCommand(string msg)
|
2019-08-14 02:43:43 -07:00
|
|
|
{
|
2020-11-06 04:04:22 -08:00
|
|
|
string(string msg) vFunc;
|
2020-08-14 12:16:47 -07:00
|
|
|
|
|
|
|
if (g_plugins_enabled == 0)
|
2021-05-10 02:33:31 -07:00
|
|
|
return (0);
|
2020-08-14 12:16:47 -07:00
|
|
|
|
|
|
|
for (int i = 0; i < g_plugincount; i++) {
|
|
|
|
vFunc = externvalue(g_plugindb[i].m_flProgsID, "FMX_ParseClientCommand");
|
2019-08-14 02:43:43 -07:00
|
|
|
|
2020-08-14 12:16:47 -07:00
|
|
|
if (vFunc) {
|
2020-11-06 04:04:22 -08:00
|
|
|
string new;
|
|
|
|
new = vFunc(msg);
|
|
|
|
|
|
|
|
/* pass valid overrides forward */
|
|
|
|
if (new != __NULL__)
|
|
|
|
msg = new;
|
2020-08-14 12:16:47 -07:00
|
|
|
}
|
2019-08-14 02:43:43 -07:00
|
|
|
}
|
|
|
|
|
2020-11-06 04:04:22 -08:00
|
|
|
return msg;
|
2019-08-17 19:35:31 -07:00
|
|
|
}
|
2020-08-14 13:13:03 -07:00
|
|
|
|
|
|
|
/*
|
|
|
|
=================
|
|
|
|
Plugin_PlayerConnect
|
|
|
|
|
|
|
|
Called whenever a new client connect to the game
|
|
|
|
=================
|
|
|
|
*/
|
|
|
|
int
|
2022-05-11 12:49:04 -07:00
|
|
|
Plugin_PlayerConnect(NSClientPlayer cl)
|
2020-08-14 13:13:03 -07:00
|
|
|
{
|
|
|
|
int rval;
|
|
|
|
int tval;
|
|
|
|
int(entity) vFunc;
|
|
|
|
|
|
|
|
if (g_plugins_enabled == 0)
|
2021-05-10 02:33:31 -07:00
|
|
|
return (0);
|
2020-08-14 13:13:03 -07:00
|
|
|
|
|
|
|
/* 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
|
2022-05-11 12:49:04 -07:00
|
|
|
Plugin_PlayerDisconnect(NSClientPlayer cl)
|
2020-08-14 13:13:03 -07:00
|
|
|
{
|
|
|
|
int rval;
|
|
|
|
int tval;
|
|
|
|
int(entity) vFunc;
|
|
|
|
|
|
|
|
if (g_plugins_enabled == 0)
|
2021-05-10 02:33:31 -07:00
|
|
|
return (0);
|
2020-08-14 13:13:03 -07:00
|
|
|
|
|
|
|
/* 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;
|
|
|
|
}
|
2020-08-14 14:51:59 -07:00
|
|
|
|
2021-02-14 12:05:10 -08:00
|
|
|
/*
|
|
|
|
=================
|
|
|
|
Plugin_PlayerEntered
|
|
|
|
|
|
|
|
Called when a player has fully connected and entered the server
|
|
|
|
=================
|
|
|
|
*/
|
|
|
|
int
|
2022-05-11 12:49:04 -07:00
|
|
|
Plugin_PlayerEntered(NSClientPlayer cl)
|
2021-02-14 12:05:10 -08:00
|
|
|
{
|
|
|
|
int rval;
|
|
|
|
int tval;
|
|
|
|
int(entity) vFunc;
|
|
|
|
|
|
|
|
if (g_plugins_enabled == 0)
|
2021-05-10 02:33:31 -07:00
|
|
|
return (0);
|
2021-02-14 12:05:10 -08:00
|
|
|
|
|
|
|
/* 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_PlayerEntered");
|
|
|
|
|
|
|
|
if (vFunc) {
|
|
|
|
tval = vFunc(cl);
|
|
|
|
rval |= tval;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return rval;
|
|
|
|
}
|
|
|
|
|
2020-08-14 14:51:59 -07:00
|
|
|
/*
|
|
|
|
=================
|
|
|
|
Plugin_PlayerObituary
|
|
|
|
|
|
|
|
Deathmessage hook
|
|
|
|
=================
|
|
|
|
*/
|
|
|
|
void
|
2021-05-08 08:44:16 -07:00
|
|
|
Plugin_PlayerObituary(entity attk, entity targ, int weapon, bodyType_t body, int dmg)
|
2020-08-14 14:51:59 -07:00
|
|
|
{
|
|
|
|
void(entity,entity,int,int,int) vFunc;
|
|
|
|
|
|
|
|
if (g_plugins_enabled == 0)
|
2021-05-10 02:33:31 -07:00
|
|
|
return (0);
|
2020-08-14 14:51:59 -07:00
|
|
|
|
|
|
|
for (int i = 0; i < g_plugincount; i++) {
|
|
|
|
vFunc = externvalue(g_plugindb[i].m_flProgsID, "FMX_PlayerObituary");
|
|
|
|
|
|
|
|
if (vFunc) {
|
|
|
|
vFunc(attk, targ, weapon, body, dmg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|