2
0
mirror of https://github.com/rehlds/metamod-r.git synced 2025-07-21 12:46:20 +03:00
metamod-r/trace_plugin/meta_api.cpp
2016-07-04 12:07:29 +06:00

170 lines
6.2 KiB
C++

// vi: set ts=4 sw=4 :
// vim: set tw=75 :
// meta_api.cpp - common implementation of Metamod's plugin interface
// This file is intended to provide a decent common codebase for the
// Metamod plugins that I maintain, so everything is set up to be very
// generalized, with the things specific for each plugin handled in
// plugin.{h,cpp} and elsewhere.
/*
* Copyright (c) 2001-2006 Will Day <willday@hpgx.net>
*
* This file is part of Metamod.
*
* Metamod is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* Metamod 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 Metamod; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#include <extdll.h>
#include <dllapi.h>
#include <meta_api.h>
#include <vdate.h>
#include "plugin.h"
#include "info_name.h"
#include "log_plugin.h"
extern META_FUNCTIONS gMetaFunctionTable;
// Description of plugin.
// (V* info from info_name.h)
plugin_info_t Plugin_info = {
META_INTERFACE_VERSION, // ifvers
VNAME, // name
VVERSION, // version
VDATE, // date
VAUTHOR, // author
VURL, // url
VLOGTAG, // logtag
PT_ANYTIME, // loadable
PT_ANYPAUSE, // unloadable
};
// Global variables from metamod. These variable names are referenced by
// various macros.
meta_globals_t *gpMetaGlobals; // metamod globals
gamedll_funcs_t *gpGamedllFuncs; // gameDLL function tables
mutil_funcs_t *gpMetaUtilFuncs; // metamod utility functions
// Metamod requesting info about this plugin
// ifvers (given) interface_version metamod is using
// pPlugInfo (requested) struct with info about plugin
// pMetaUtilFuncs (given) table of utility functions provided by metamod
C_DLLEXPORT int Meta_Query(char *ifvers, plugin_info_t **pPlugInfo,
mutil_funcs_t *pMetaUtilFuncs)
{
if ((int) CVAR_GET_FLOAT("developer") != 0)
UTIL_LogPrintf("[%s] dev: called: Meta_Query; version=%s, ours=%s\n",
Plugin_info.logtag, ifvers, Plugin_info.ifvers);
// Check for valid pMetaUtilFuncs before we continue.
if(!pMetaUtilFuncs) {
UTIL_LogPrintf("[%s] ERROR: Meta_Query called with null pMetaUtilFuncs\n", Plugin_info.logtag);
return(FALSE);
}
gpMetaUtilFuncs=pMetaUtilFuncs;
// Give metamod our plugin_info struct.
*pPlugInfo=&Plugin_info;
// Check for interface version compatibility.
if(!FStrEq(ifvers, Plugin_info.ifvers)) {
int mmajor=0, mminor=0, pmajor=0, pminor=0;
LOG_MESSAGE(PLID, "WARNING: meta-interface version mismatch; requested=%s ours=%s",
Plugin_info.logtag, ifvers);
// If plugin has later interface version, it's incompatible (update
// metamod).
sscanf(ifvers, "%d:%d", &mmajor, &mminor);
sscanf(META_INTERFACE_VERSION, "%d:%d", &pmajor, &pminor);
if(pmajor > mmajor || (pmajor==mmajor && pminor > mminor)) {
LOG_ERROR(PLID, "metamod version is too old for this plugin; update metamod");
return(FALSE);
}
// If plugin has older major interface version, it's incompatible
// (update plugin).
else if(pmajor < mmajor) {
LOG_ERROR(PLID, "metamod version is incompatible with this plugin; please find a newer version of this plugin");
return(FALSE);
}
// Minor interface is older, but this is guaranteed to be backwards
// compatible, so we warn, but we still accept it.
else if(pmajor==mmajor && pminor < mminor)
LOG_MESSAGE(PLID, "WARNING: metamod version is newer than expected; consider finding a newer version of this plugin");
else
LOG_ERROR(PLID, "unexpected version comparison; metavers=%s, mmajor=%d, mminor=%d; plugvers=%s, pmajor=%d, pminor=%d", ifvers, mmajor, mminor, META_INTERFACE_VERSION, pmajor, pminor);
}
return (plugin_query());
}
// Metamod attaching plugin to the server.
// now (given) current phase, ie during map, during changelevel, or at startup
// pFunctionTable (requested) table of function tables this plugin catches
// pMGlobals (given) global vars from metamod
// pGamedllFuncs (given) copy of function tables from game dll
C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable,
meta_globals_t *pMGlobals, gamedll_funcs_t *pGamedllFuncs)
{
if(now > Plugin_info.loadable) {
LOG_ERROR(PLID, "Can't load plugin right now");
return(FALSE);
}
if(!pMGlobals) {
LOG_ERROR(PLID, "Meta_Attach called with null pMGlobals");
return(FALSE);
}
gpMetaGlobals=pMGlobals;
if(!pFunctionTable) {
LOG_ERROR(PLID, "Meta_Attach called with null pFunctionTable");
return(FALSE);
}
memcpy(pFunctionTable, &gMetaFunctionTable, sizeof(META_FUNCTIONS));
gpGamedllFuncs=pGamedllFuncs;
LOG_MESSAGE(PLID, "%s v%s %s", Plugin_info.name, Plugin_info.version,
Plugin_info.date);
LOG_MESSAGE(PLID, "by %s", Plugin_info.author);
LOG_MESSAGE(PLID, " %s", Plugin_info.url);
LOG_MESSAGE(PLID, "compiled: %s Eastern (%s)", COMPILE_TIME, OPT_TYPE);
// Let's go.
return(plugin_attach());
}
// Metamod detaching plugin from the server.
// now (given) current phase, ie during map, etc
// reason (given) why detaching (refresh, console unload, forced unload, etc)
C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason) {
if(now > Plugin_info.unloadable && reason != PNL_CMD_FORCED) {
LOG_ERROR(PLID, "Can't unload plugin right now");
return(FALSE);
}
// Done!
return(plugin_detach());
}