--- /dev/null
+debug.linux*
+debug.win32*
+opt.linux*
+opt.win32*
+msgs
+Rules.depend
+msvc
+*.bak
--- /dev/null
+MODNAME = pmpc_mm
+
+EXTRA_CFLAGS =
+
+SRCFILES = dllapi.cpp engine_api.cpp h_export.cpp meta_api.cpp sdk_util.cpp
--- /dev/null
+# Since this file is under CVS control and we cannot store
+# symbolic links in CVS (and neither under Windows) we
+# include the Makefile from the metamod directory instead
+# of linking to it.
+
+include ../metamod/Makefile
--- /dev/null
+// vi: set ts=4 sw=4 :
+// vim: set tw=75 :
+
+/*
+ * Copyright (c) 2001-2003 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 <unistd.h>
+
+#include <extdll.h>
+
+#include <dllapi.h>
+#include <meta_api.h>
+
+#define SAY(pEntity, text) {\
+ MESSAGE_BEGIN( MSG_ONE, GET_USER_MSG_ID(PLID, "SayText", NULL), NULL, pEntity );\
+ WRITE_BYTE( ENTINDEX(pEntity) );\
+ WRITE_STRING( text );\
+ MESSAGE_END();\
+}
+
+extern char gGamedir[];
+int gmsgSayText;
+
+#define MAXLENGTH_PLAYERNAME 64
+#define MAXLENGTH_MODELNAME 64
+#define MAXLENGTH_MODELPATH 256
+typedef struct {
+ char playername[MAXLENGTH_PLAYERNAME];
+ char modelname[MAXLENGTH_MODELNAME];
+ char modelpath[MAXLENGTH_MODELPATH];
+} precache_entry;
+
+#define MAX_PRECACHE_COUNT 32
+precache_entry precache_list[MAX_PRECACHE_COUNT];
+unsigned short int precache_count = 0;
+
+bool playerModelFileExists(const char* path) {
+ return access(path, R_OK) == 0;
+}
+
+bool addPrecacheEntry(const char* playername, const char* model) {
+ short int i = 0;
+ int streq = 1;
+ while ((i < precache_count) && ((streq = strcmp(precache_list[i].modelname, model)) != 0)) i++;
+ if ((i == precache_count) && (i < MAX_PRECACHE_COUNT) && (streq != 0)) {
+ strncpy(precache_list[i].playername, playername, MAXLENGTH_PLAYERNAME - 1);
+ strncpy(precache_list[i].modelname, model, MAXLENGTH_MODELNAME - 1);
+ snprintf(precache_list[i].modelpath, MAXLENGTH_MODELPATH, "models/player/%s/%s.mdl", model, model);
+ precache_list[i].playername[MAXLENGTH_PLAYERNAME - 1] = 0;
+ precache_list[i].modelname[MAXLENGTH_MODELNAME - 1] = 0;
+ precache_count++;
+ LOG_MESSAGE(PLID, "Precache entry %d: playername=\"%s\" modelname=\"%s\" modelpath=\"%s\"", i, precache_list[i].playername, precache_list[i].modelname, precache_list[i].modelpath);
+ return true;
+ }
+ else
+ return false;
+}
+
+void ClientPutInServer( edict_t *pEntity ) {
+ const char* playername = STRING(pEntity->v.netname);
+ char* modelname = g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pEntity ), "model" );
+ char modelfile[256];
+ snprintf(modelfile, sizeof(modelfile), "%s/models/player/%s/%s.mdl", &gGamedir[0], modelname, modelname);
+ LOG_MESSAGE(PLID, "Player %s is using model %s", playername, modelname);
+ if (playerModelFileExists( modelfile )) {
+ LOG_MESSAGE(PLID, "Model %s is present on server", modelname);
+ SAY(pEntity, "Your model is present on the server, it will be precached for the next round!");
+ if (addPrecacheEntry( playername, modelname ))
+ LOG_MESSAGE(PLID, "Added model %s to precache list", modelname);
+ else
+ LOG_MESSAGE(PLID, "Model %s will not be precached - reduntant or precache list is full", modelname);
+ }
+ else {
+ LOG_MESSAGE(PLID, "Unable to precache due to FILE MISSING: %s!", modelfile);
+ SAY(pEntity, "Your model is not present on the server, can't distribute for other players!");
+ }
+ RETURN_META(MRES_IGNORED);
+}
+
+void ServerActivate(edict_t *pEdictList, int edictCount, int clientMax) {
+ LOG_MESSAGE(PLID, "Precaching %d player models", precache_count);
+ for (int i = 0; i < precache_count; i++) {
+ LOG_MESSAGE(PLID, "Precaching model: %s (contributed by %s)", precache_list[i].modelname, precache_list[i].playername);
+ LOG_MESSAGE(PLID, "modelpath = %s", precache_list[i].modelpath);
+ g_engfuncs.pfnPrecacheModel( precache_list[i].modelpath );
+ }
+ precache_count = 0;
+ RETURN_META(MRES_HANDLED);
+}
+
+static DLL_FUNCTIONS gFunctionTable =
+{
+ NULL, // pfnGameInit
+ NULL, // pfnSpawn
+ NULL, // pfnThink
+ NULL, // pfnUse
+ NULL, // pfnTouch
+ NULL, // pfnBlocked
+ NULL, // pfnKeyValue
+ NULL, // pfnSave
+ NULL, // pfnRestore
+ NULL, // pfnSetAbsBox
+
+ NULL, // pfnSaveWriteFields
+ NULL, // pfnSaveReadFields
+
+ NULL, // pfnSaveGlobalState
+ NULL, // pfnRestoreGlobalState
+ NULL, // pfnResetGlobalState
+
+ NULL, // pfnClientConnect
+ NULL, // pfnClientDisconnect
+ NULL, // pfnClientKill
+ ClientPutInServer, // pfnClientPutInServer
+ NULL, // pfnClientCommand
+ NULL, // pfnClientUserInfoChanged
+ ServerActivate, // pfnServerActivate
+ NULL, // pfnServerDeactivate
+
+ NULL, // pfnPlayerPreThink
+ NULL, // pfnPlayerPostThink
+
+ NULL, // pfnStartFrame
+ NULL, // pfnParmsNewLevel
+ NULL, // pfnParmsChangeLevel
+
+ NULL, // pfnGetGameDescription
+ NULL, // pfnPlayerCustomization
+
+ NULL, // pfnSpectatorConnect
+ NULL, // pfnSpectatorDisconnect
+ NULL, // pfnSpectatorThink
+
+ NULL, // pfnSys_Error
+
+ NULL, // pfnPM_Move
+ NULL, // pfnPM_Init
+ NULL, // pfnPM_FindTextureType
+
+ NULL, // pfnSetupVisibility
+ NULL, // pfnUpdateClientData
+ NULL, // pfnAddToFullPack
+ NULL, // pfnCreateBaseline
+ NULL, // pfnRegisterEncoders
+ NULL, // pfnGetWeaponData
+ NULL, // pfnCmdStart
+ NULL, // pfnCmdEnd
+ NULL, // pfnConnectionlessPacket
+ NULL, // pfnGetHullBounds
+ NULL, // pfnCreateInstancedBaselines
+ NULL, // pfnInconsistentFile
+ NULL, // pfnAllowLagCompensation
+};
+
+C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable,
+ int *interfaceVersion)
+{
+ if(!pFunctionTable) {
+ UTIL_LogPrintf("GetEntityAPI2 called with null pFunctionTable");
+ return(FALSE);
+ }
+ else if(*interfaceVersion != INTERFACE_VERSION) {
+ UTIL_LogPrintf("GetEntityAPI2 version mismatch; requested=%d ours=%d", *interfaceVersion, INTERFACE_VERSION);
+ //! Tell metamod what version we had, so it can figure out who is out of date.
+ *interfaceVersion = INTERFACE_VERSION;
+ return(FALSE);
+ }
+ memcpy(pFunctionTable, &gFunctionTable, sizeof(DLL_FUNCTIONS));
+ return(TRUE);
+}
--- /dev/null
+// vi: set ts=4 sw=4 :
+// vim: set tw=75 :
+
+/*
+ * Copyright (c) 2001-2003 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 <meta_api.h>
+
+enginefuncs_t meta_engfuncs =
+{
+ NULL, // pfnPrecacheModel()
+ NULL, // pfnPrecacheSound()
+ NULL, // pfnSetModel()
+ NULL, // pfnModelIndex()
+ NULL, // pfnModelFrames()
+
+ NULL, // pfnSetSize()
+ NULL, // pfnChangeLevel()
+ NULL, // pfnGetSpawnParms()
+ NULL, // pfnSaveSpawnParms()
+
+ NULL, // pfnVecToYaw()
+ NULL, // pfnVecToAngles()
+ NULL, // pfnMoveToOrigin()
+ NULL, // pfnChangeYaw()
+ NULL, // pfnChangePitch()
+
+ NULL, // pfnFindEntityByString()
+ NULL, // pfnGetEntityIllum()
+ NULL, // pfnFindEntityInSphere()
+ NULL, // pfnFindClientInPVS()
+ NULL, // pfnEntitiesInPVS()
+
+ NULL, // pfnMakeVectors()
+ NULL, // pfnAngleVectors()
+
+ NULL, // pfnCreateEntity()
+ NULL, // pfnRemoveEntity()
+ NULL, // pfnCreateNamedEntity()
+
+ NULL, // pfnMakeStatic()
+ NULL, // pfnEntIsOnFloor()
+ NULL, // pfnDropToFloor()
+
+ NULL, // pfnWalkMove()
+ NULL, // pfnSetOrigin()
+
+ NULL, // pfnEmitSound()
+ NULL, // pfnEmitAmbientSound()
+
+ NULL, // pfnTraceLine()
+ NULL, // pfnTraceToss()
+ NULL, // pfnTraceMonsterHull()
+ NULL, // pfnTraceHull()
+ NULL, // pfnTraceModel()
+ NULL, // pfnTraceTexture()
+ NULL, // pfnTraceSphere()
+ NULL, // pfnGetAimVector()
+
+ NULL, // pfnServerCommand()
+ NULL, // pfnServerExecute()
+ NULL, // pfnClientCommand()
+
+ NULL, // pfnParticleEffect()
+ NULL, // pfnLightStyle()
+ NULL, // pfnDecalIndex()
+ NULL, // pfnPointContents()
+
+ NULL, // pfnMessageBegin()
+ NULL, // pfnMessageEnd()
+
+ NULL, // pfnWriteByte()
+ NULL, // pfnWriteChar()
+ NULL, // pfnWriteShort()
+ NULL, // pfnWriteLong()
+ NULL, // pfnWriteAngle()
+ NULL, // pfnWriteCoord()
+ NULL, // pfnWriteString()
+ NULL, // pfnWriteEntity()
+
+ NULL, // pfnCVarRegister()
+ NULL, // pfnCVarGetFloat()
+ NULL, // pfnCVarGetString()
+ NULL, // pfnCVarSetFloat()
+ NULL, // pfnCVarSetString()
+
+ NULL, // pfnAlertMessage()
+ NULL, // pfnEngineFprintf()
+
+ NULL, // pfnPvAllocEntPrivateData()
+ NULL, // pfnPvEntPrivateData()
+ NULL, // pfnFreeEntPrivateData()
+
+ NULL, // pfnSzFromIndex()
+ NULL, // pfnAllocString()
+
+ NULL, // pfnGetVarsOfEnt()
+ NULL, // pfnPEntityOfEntOffset()
+ NULL, // pfnEntOffsetOfPEntity()
+ NULL, // pfnIndexOfEdict()
+ NULL, // pfnPEntityOfEntIndex()
+ NULL, // pfnFindEntityByVars()
+ NULL, // pfnGetModelPtr()
+
+ NULL, // pfnRegUserMsg()
+
+ NULL, // pfnAnimationAutomove()
+ NULL, // pfnGetBonePosition()
+
+ NULL, // pfnFunctionFromName()
+ NULL, // pfnNameForFunction()
+
+ NULL, // pfnClientPrintf()
+ NULL, // pfnServerPrint()
+
+ NULL, // pfnCmd_Args()
+ NULL, // pfnCmd_Argv()
+ NULL, // pfnCmd_Argc()
+
+ NULL, // pfnGetAttachment()
+
+ NULL, // pfnCRC32_Init()
+ NULL, // pfnCRC32_ProcessBuffer()
+ NULL, // pfnCRC32_ProcessByte()
+ NULL, // pfnCRC32_Final()
+
+ NULL, // pfnRandomLong()
+ NULL, // pfnRandomFloat()
+
+ NULL, // pfnSetView()
+ NULL, // pfnTime()
+ NULL, // pfnCrosshairAngle()
+
+ NULL, // pfnLoadFileForMe()
+ NULL, // pfnFreeFile()
+
+ NULL, // pfnEndSection()
+ NULL, // pfnCompareFileTime()
+ NULL, // pfnGetGameDir()
+ NULL, // pfnCvar_RegisterVariable()
+ NULL, // pfnFadeClientVolume()
+ NULL, // pfnSetClientMaxspeed()
+ NULL, // pfnCreateFakeClient()
+ NULL, // pfnRunPlayerMove()
+ NULL, // pfnNumberOfEntities()
+
+ NULL, // pfnGetInfoKeyBuffer()
+ NULL, // pfnInfoKeyValue()
+ NULL, // pfnSetKeyValue()
+ NULL, // pfnSetClientKeyValue()
+
+ NULL, // pfnIsMapValid()
+ NULL, // pfnStaticDecal()
+ NULL, // pfnPrecacheGeneric()
+ NULL, // pfnGetPlayerUserId()
+ NULL, // pfnBuildSoundMsg()
+ NULL, // pfnIsDedicatedServer()
+ NULL, // pfnCVarGetPointer()
+ NULL, // pfnGetPlayerWONId()
+
+ NULL, // pfnInfo_RemoveKey()
+ NULL, // pfnGetPhysicsKeyValue()
+ NULL, // pfnSetPhysicsKeyValue()
+ NULL, // pfnGetPhysicsInfoString()
+ NULL, // pfnPrecacheEvent()
+ NULL, // pfnPlaybackEvent()
+
+ NULL, // pfnSetFatPVS()
+ NULL, // pfnSetFatPAS()
+
+ NULL, // pfnCheckVisibility()
+
+ NULL, // pfnDeltaSetField()
+ NULL, // pfnDeltaUnsetField()
+ NULL, // pfnDeltaAddEncoder()
+ NULL, // pfnGetCurrentPlayer()
+ NULL, // pfnCanSkipPlayer()
+ NULL, // pfnDeltaFindField()
+ NULL, // pfnDeltaSetFieldByIndex()
+ NULL, // pfnDeltaUnsetFieldByIndex()
+
+ NULL, // pfnSetGroupMask()
+
+ NULL, // pfnCreateInstancedBaseline()
+ NULL, // pfnCvar_DirectSet()
+
+ NULL, // pfnForceUnmodified()
+
+ NULL, // pfnGetPlayerStats()
+
+ NULL, // pfnAddServerCommand()
+
+ // Added in SDK 2.2:
+ NULL, // pfnVoice_GetClientListening()
+ NULL, // pfnVoice_SetClientListening()
+
+ // Added for HL 1109 (no SDK update):
+ NULL, // pfnGetPlayerAuthId()
+
+ // Added 2003-11-10 (no SDK update):
+ NULL, // pfnSequenceGet()
+ NULL, // pfnSequencePickSentence()
+ NULL, // pfnGetFileSize()
+ NULL, // pfnGetApproxWavePlayLen()
+ NULL, // pfnIsCareerMatch()
+ NULL, // pfnGetLocalizedStringLength()
+ NULL, // pfnRegisterTutorMessageShown()
+ NULL, // pfnGetTimesTutorMessageShown()
+ NULL, // pfnProcessTutorMessageDecayBuffer()
+ NULL, // pfnConstructTutorMessageDecayBuffer()
+ NULL, // pfnResetTutorMessageDecayData()
+
+ // Added Added 2005-08-11 (no SDK update)
+ NULL, // pfnQueryClientCvarValue()
+ // Added Added 2005-11-22 (no SDK update)
+ NULL, // pfnQueryClientCvarValue2()
+};
+
+C_DLLEXPORT int GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine,
+ int *interfaceVersion)
+{
+ if(!pengfuncsFromEngine) {
+ UTIL_LogPrintf("GetEngineFunctions called with null pengfuncsFromEngine");
+ return(FALSE);
+ }
+ else if(*interfaceVersion != ENGINE_INTERFACE_VERSION) {
+ UTIL_LogPrintf("GetEngineFunctions version mismatch; requested=%d ours=%d", *interfaceVersion, ENGINE_INTERFACE_VERSION);
+ // Tell metamod what version we had, so it can figure out who is out of date.
+ *interfaceVersion = ENGINE_INTERFACE_VERSION;
+ return(FALSE);
+ }
+ memcpy(pengfuncsFromEngine, &meta_engfuncs, sizeof(enginefuncs_t));
+ return(TRUE);
+}
--- /dev/null
+// vi: set ts=4 sw=4 :
+// vim: set tw=75 :
+
+// From SDK dlls/h_export.cpp:
+
+/***
+*
+* Copyright (c) 1999, 2000 Valve LLC. All rights reserved.
+*
+* This product contains software technology licensed from Id
+* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
+* All Rights Reserved.
+*
+* Use, distribution, and modification of this source code and/or resulting
+* object code is restricted to non-commercial enhancements to products from
+* Valve LLC. All other use, distribution, or modification is prohibited
+* without written permission from Valve LLC.
+*
+****/
+/*
+
+===== h_export.cpp ========================================================
+
+ Entity classes exported by Halflife.
+
+*/
+
+#include <extdll.h>
+
+#include <h_export.h>
+
+// From SDK dlls/h_export.cpp:
+
+//! Holds engine functionality callbacks
+enginefuncs_t g_engfuncs;
+globalvars_t *gpGlobals;
+
+// Receive engine function table from engine.
+// This appears to be the _first_ DLL routine called by the engine, so we
+// do some setup operations here.
+void WINAPI GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals )
+{
+ memcpy(&g_engfuncs, pengfuncsFromEngine, sizeof(enginefuncs_t));
+ gpGlobals = pGlobals;
+}
--- /dev/null
+// vi: set ts=4 sw=4 :
+// vim: set tw=75 :
+
+// meta_api.cpp - minimal implementation of metamod's plugin interface
+
+// This is intended to illustrate the (more or less) bare minimum code
+// required for a valid metamod plugin, and is targeted at those who want
+// to port existing HL/SDK DLL code to run as a metamod plugin.
+
+/*
+ * Copyright (c) 2001-2003 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> // always
+
+#include <meta_api.h> // of course
+
+#include "sdk_util.h" // UTIL_LogPrintf, etc
+
+// Must provide at least one of these..
+static META_FUNCTIONS gMetaFunctionTable = {
+ NULL, // pfnGetEntityAPI HL SDK; called before game DLL
+ NULL, // pfnGetEntityAPI_Post META; called after game DLL
+ GetEntityAPI2, // pfnGetEntityAPI2 HL SDK2; called before game DLL
+ NULL, // pfnGetEntityAPI2_Post META; called after game DLL
+ NULL, // pfnGetNewDLLFunctions HL SDK2; called before game DLL
+ NULL, // pfnGetNewDLLFunctions_Post META; called after game DLL
+ GetEngineFunctions, // pfnGetEngineFunctions META; called before HL engine
+ NULL, // pfnGetEngineFunctions_Post META; called after HL engine
+};
+
+// Description of plugin
+plugin_info_t Plugin_info = {
+ META_INTERFACE_VERSION, // ifvers
+ "PMPreCache", // name
+ "0.0", // version
+ "2022/03/29", // date
+ "MegaBrutal <megabrutal@gmail.com>", // author
+ "http://megabrutal.com/", // url
+ "PMPreCache", // logtag, all caps please
+ PT_ANYTIME, // (when) loadable
+ PT_ANYPAUSE, // (when) unloadable
+};
+
+// Global vars from metamod:
+meta_globals_t *gpMetaGlobals; // metamod globals
+gamedll_funcs_t *gpGamedllFuncs; // gameDLL function tables
+mutil_funcs_t *gpMetaUtilFuncs; // metamod utility functions
+char gGamedir[256];
+
+// 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)
+{
+ // Give metamod our plugin_info struct
+ *pPlugInfo=&Plugin_info;
+ // Get metamod utility function table.
+ gpMetaUtilFuncs=pMetaUtilFuncs;
+ return(TRUE);
+}
+
+// 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(!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 by %s", Plugin_info.name, Plugin_info.version, Plugin_info.author);
+ LOG_MESSAGE(PLID, "Attached.");
+ strncpy(&gGamedir[0], GET_GAME_INFO(PLID, GINFO_GAMEDIR), sizeof(gGamedir));
+ return(TRUE);
+}
+
+// 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 */)
+{
+ return(TRUE);
+}
--- /dev/null
+// vi: set ts=4 sw=4 :
+// vim: set tw=75 :
+
+// Selected portions of dlls/util.cpp from SDK 2.1.
+// Functions copied from there as needed...
+// And modified to avoid buffer overflows (argh).
+
+/***
+*
+* Copyright (c) 1999, 2000 Valve LLC. All rights reserved.
+*
+* This product contains software technology licensed from Id
+* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
+* All Rights Reserved.
+*
+* Use, distribution, and modification of this source code and/or resulting
+* object code is restricted to non-commercial enhancements to products from
+* Valve LLC. All other use, distribution, or modification is prohibited
+* without written permission from Valve LLC.
+*
+****/
+/*
+
+===== util.cpp ========================================================
+
+ Utility code. Really not optional after all.
+
+*/
+
+#include <extdll.h>
+#include <enginecallback.h> // ALERT()
+
+#include "osdep.h" // win32 vsnprintf, etc
+
+//=========================================================
+// UTIL_LogPrintf - Prints a logged message to console.
+// Preceded by LOG: ( timestamp ) < message >
+//=========================================================
+void UTIL_LogPrintf( char *fmt, ... )
+{
+ va_list argptr;
+ static char string[1024];
+
+ va_start ( argptr, fmt );
+ vsnprintf ( string, sizeof(string), fmt, argptr );
+ va_end ( argptr );
+
+ // Print to server console
+ ALERT( at_logged, "%s", string );
+}