2
0
mirror of https://github.com/rehlds/metamod-r.git synced 2024-12-28 15:45:37 +03:00
metamod-r/src/mutil.cpp

348 lines
9.1 KiB
C++
Raw Normal View History

2016-07-04 09:07:29 +03:00
#include <stdio.h> // vsnprintf(), etc
#include <stdarg.h> // vs_start(), etc
#include <stdlib.h> // strtol()
#include <extdll.h> // always
#include "meta_api.h" //
#include "mutil.h" // me
#include "linkent.h" // ENTITY_FN, etc
#include "metamod.h" // Hooks, etc
#include "types_meta.h" // mBOOL
#include "osdep.h" // win32 vsnprintf, etc
#include "sdk_util.h" // ALERT, etc
static hudtextparms_t default_csay_tparms = {
-1, 0.25, // x, y
2, // effect
0, 255, 0, 0, // r, g, b, a1
0, 0, 0, 0, // r2, g2, b2, a2
0, 0, 10, 10, // fadein, fadeout, hold, fxtime
1 // channel
};
// Log to console; newline added.
static void mutil_LogConsole(plid_t /* plid */, const char *fmt, ...) {
va_list ap;
char buf[MAX_LOGMSG_LEN];
unsigned int len;
va_start(ap, fmt);
safevoid_vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
// end msg with newline
2016-07-04 10:11:20 +03:00
len=Q_strlen(buf);
2016-07-04 09:07:29 +03:00
if(len < sizeof(buf)-2) // -1 null, -1 for newline
2016-07-04 10:11:20 +03:00
Q_strcat(buf, "\n");
2016-07-04 09:07:29 +03:00
else
buf[len-1] = '\n';
SERVER_PRINT(buf);
}
// Log regular message to logs; newline added.
static void mutil_LogMessage(plid_t plid, const char *fmt, ...) {
va_list ap;
char buf[MAX_LOGMSG_LEN];
plugin_info_t *plinfo;
plinfo=(plugin_info_t *)plid;
va_start(ap, fmt);
safevoid_vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
ALERT(at_logged, "[%s] %s\n", plinfo->logtag, buf);
}
// Log an error message to logs; newline added.
static void mutil_LogError(plid_t plid, const char *fmt, ...) {
va_list ap;
char buf[MAX_LOGMSG_LEN];
plugin_info_t *plinfo;
plinfo=(plugin_info_t *)plid;
va_start(ap, fmt);
safevoid_vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
ALERT(at_logged, "[%s] ERROR: %s\n", plinfo->logtag, buf);
}
// Log a message only if cvar "developer" set; newline added.
static void mutil_LogDeveloper(plid_t plid, const char *fmt, ...) {
va_list ap;
char buf[MAX_LOGMSG_LEN];
plugin_info_t *plinfo;
if((int)CVAR_GET_FLOAT("developer") == 0)
return;
plinfo=(plugin_info_t *)plid;
va_start(ap, fmt);
safevoid_vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
ALERT(at_logged, "[%s] dev: %s\n", plinfo->logtag, buf);
}
// Print a center-message, with text parameters and varargs. Provides
// functionality to the above center_say interfaces.
static void mutil_CenterSayVarargs(plid_t plid, hudtextparms_t tparms,
const char *fmt, va_list ap)
{
char buf[MAX_LOGMSG_LEN];
int n;
edict_t *pEntity;
safevoid_vsnprintf(buf, sizeof(buf), fmt, ap);
mutil_LogMessage(plid, "(centersay) %s", buf);
for(n=1; n <= gpGlobals->maxClients; n++) {
pEntity=INDEXENT(n);
META_UTIL_HudMessage(pEntity, tparms, buf);
}
}
// Print message on center of all player's screens. Uses default text
// parameters (color green, 10 second fade-in).
static void mutil_CenterSay(plid_t plid, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
mutil_CenterSayVarargs(plid, default_csay_tparms, fmt, ap);
va_end(ap);
}
// Print a center-message, with given text parameters.
static void mutil_CenterSayParms(plid_t plid, hudtextparms_t tparms, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
mutil_CenterSayVarargs(plid, tparms, fmt, ap);
va_end(ap);
}
// Allow plugins to call the entity functions in the GameDLL. In
// particular, calling "player()" as needed by most Bots. Suggested by
// Jussi Kivilinna.
static qboolean mutil_CallGameEntity(plid_t plid, const char *entStr, entvars_t *pev) {
plugin_info_t *plinfo;
ENTITY_FN pfnEntity;
plinfo=(plugin_info_t *)plid;
META_DEBUG(8, ("Looking up game entity '%s' for plugin '%s'", entStr,
plinfo->name));
pfnEntity = (ENTITY_FN) DLSYM(GameDLL.handle, entStr);
if(!pfnEntity) {
META_WARNING("Couldn't find game entity '%s' in game DLL '%s' for plugin '%s'", entStr, GameDLL.name, plinfo->name);
return(false);
}
META_DEBUG(7, ("Calling game entity '%s' for plugin '%s'", entStr,
plinfo->name));
(*pfnEntity)(pev);
return(true);
}
// Find a usermsg, registered by the gamedll, with the corresponding
// msgname, and return remaining info about it (msgid, size).
static int mutil_GetUserMsgID(plid_t plid, const char *msgname, int *size) {
plugin_info_t *plinfo;
MRegMsg *umsg;
plinfo=(plugin_info_t *)plid;
META_DEBUG(8, ("Looking up usermsg name '%s' for plugin '%s'", msgname,
plinfo->name));
umsg=RegMsgs->find(msgname);
if(umsg) {
if(size)
*size=umsg->size;
return(umsg->msgid);
}
else
return(0);
}
// Find a usermsg, registered by the gamedll, with the corresponding
// msgid, and return remaining info about it (msgname, size).
static const char *mutil_GetUserMsgName(plid_t plid, int msgid, int *size) {
plugin_info_t *plinfo;
MRegMsg *umsg;
plinfo=(plugin_info_t *)plid;
META_DEBUG(8, ("Looking up usermsg id '%d' for plugin '%s'", msgid,
plinfo->name));
// Guess names for any built-in Engine messages mentioned in the SDK;
// from dlls/util.h.
if(msgid < 64) {
switch(msgid) {
case SVC_TEMPENTITY:
if(size) *size=-1;
return("tempentity?");
case SVC_INTERMISSION:
if(size) *size=-1;
return("intermission?");
case SVC_CDTRACK:
if(size) *size=-1;
return("cdtrack?");
case SVC_WEAPONANIM:
if(size) *size=-1;
return("weaponanim?");
case SVC_ROOMTYPE:
if(size) *size=-1;
return("roomtype?");
case SVC_DIRECTOR:
if(size) *size=-1;
return("director?");
}
}
umsg=RegMsgs->find(msgid);
if(umsg) {
if(size)
*size=umsg->size;
// 'name' is assumed to be a constant string, allocated in the
// gamedll.
return(umsg->name);
}
else
return(NULL);
}
// Return the full path of the plugin's loaded dll/so file.
static const char *mutil_GetPluginPath(plid_t plid) {
static char buf[PATH_MAX];
MPlugin *plug;
plug=Plugins->find(plid);
if(!plug) {
META_WARNING("GetPluginPath: couldn't find plugin '%s'",
plid->name);
return(NULL);
}
STRNCPY(buf, plug->pathname, sizeof(buf));
return(buf);
}
// Return various string-based info about the game/MOD/gamedll.
static const char *mutil_GetGameInfo(plid_t plid, ginfo_t type) {
static char buf[MAX_STRBUF_LEN];
const char *cp;
switch(type) {
case GINFO_NAME:
cp=GameDLL.name;
break;
case GINFO_DESC:
cp=GameDLL.desc;
break;
case GINFO_GAMEDIR:
cp=GameDLL.gamedir;
break;
case GINFO_DLL_FULLPATH:
cp=GameDLL.pathname;
break;
case GINFO_DLL_FILENAME:
cp=GameDLL.file;
break;
case GINFO_REALDLL_FULLPATH:
cp=GameDLL.real_pathname;
break;
default:
META_WARNING("GetGameInfo: invalid request '%d' from plugin '%s'",
type, plid->name);
return(NULL);
}
STRNCPY(buf, cp, sizeof(buf));
return(buf);
}
static int mutil_LoadMetaPlugin(plid_t plid, const char *fname, PLUG_LOADTIME now, void **plugin_handle)
{
MPlugin *pl_loaded;
if(NULL == fname) {
return(ME_ARGUMENT);
}
meta_errno = ME_NOERROR;
if(!(pl_loaded=Plugins->plugin_addload(plid, fname, now))) {
if(plugin_handle)
*plugin_handle = NULL;
return(meta_errno);
} else {
if(plugin_handle)
*plugin_handle = (void*)pl_loaded->handle;
return(0);
}
}
static int mutil_UnloadMetaPlugin(plid_t plid, const char *fname, PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
{
MPlugin *findp = NULL;
int pindex;
char* endptr;
if(NULL == fname) {
return(ME_ARGUMENT);
}
pindex = strtol(fname, &endptr, 10);
if(*fname != '\0' && *endptr == '\0')
findp = Plugins->find(pindex);
else
findp = Plugins->find_match(fname);
if(!findp)
return(meta_errno);
meta_errno = ME_NOERROR;
if(findp->plugin_unload(plid, now, reason))
return(0);
return(meta_errno);
}
static int mutil_UnloadMetaPluginByHandle(plid_t plid, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
{
MPlugin *findp;
if(NULL == plugin_handle) {
return(ME_ARGUMENT);
}
if(!(findp=Plugins->find((DLHANDLE)plugin_handle)))
return(ME_NOTFOUND);
meta_errno = ME_NOERROR;
if(findp->plugin_unload(plid, now, reason))
return(0);
return(meta_errno);
}
// Check if player is being queried for cvar
static const char * mutil_IsQueryingClientCvar(plid_t /*plid*/, const edict_t *player) {
return(g_Players.is_querying_cvar(player));
}
//
static int mutil_MakeRequestID(plid_t /*plid*/) {
return(abs(0xbeef<<16) + (++requestid_counter));
}
//
static void mutil_GetHookTables(plid_t plid, enginefuncs_t **peng, DLL_FUNCTIONS **pdll, NEW_DLL_FUNCTIONS **pnewdll) {
if (peng)
*peng = &meta_engfuncs;
if (pdll)
*pdll = g_pHookedDllFunctions;
if (pnewdll)
*pnewdll = g_pHookedNewDllFunctions;
}
// Meta Utility Function table.
mutil_funcs_t MetaUtilFunctions = {
mutil_LogConsole, // pfnLogConsole
mutil_LogMessage, // pfnLogMessage
mutil_LogError, // pfnLogError
mutil_LogDeveloper, // pfnLogDeveloper
mutil_CenterSay, // pfnCenterSay
mutil_CenterSayParms, // pfnCenterSayParms
mutil_CenterSayVarargs, // pfnCenterSayVarargs
mutil_CallGameEntity, // pfnCallGameEntity
mutil_GetUserMsgID, // pfnGetUserMsgID
mutil_GetUserMsgName, // pfnGetUserMsgName
mutil_GetPluginPath, // pfnGetPluginPath
mutil_GetGameInfo, // pfnGetGameInfo
mutil_LoadMetaPlugin, // pfnLoadPlugin
mutil_UnloadMetaPlugin, // pfnUnloadPlugin
mutil_UnloadMetaPluginByHandle, // pfnUnloadPluginByHandle
mutil_IsQueryingClientCvar, // pfnIsQueryingClientCvar
mutil_MakeRequestID, // pfnMakeRequestID
mutil_GetHookTables, // pfnGetHookTables
};