Initial commit
authorMegaBrutal <megabrutal+github@megabrutal.com>
Wed, 1 Feb 2023 00:30:00 +0000 (01:30 +0100)
committerMegaBrutal <megabrutal+github@megabrutal.com>
Wed, 1 Feb 2023 00:30:00 +0000 (01:30 +0100)
.gitignore [new file with mode: 0644]
Config.mak [new file with mode: 0644]
Makefile [new file with mode: 0644]
dllapi.cpp [new file with mode: 0644]
engine_api.cpp [new file with mode: 0644]
h_export.cpp [new file with mode: 0644]
info_name.h [new file with mode: 0644]
meta_api.cpp [new file with mode: 0644]
sdk_util.cpp [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..a60ad86
--- /dev/null
@@ -0,0 +1,8 @@
+debug.linux*
+debug.win32*
+opt.linux*
+opt.win32*
+msgs
+Rules.depend
+msvc
+*.bak
diff --git a/Config.mak b/Config.mak
new file mode 100644 (file)
index 0000000..e874ceb
--- /dev/null
@@ -0,0 +1,5 @@
+MODNAME = pmpc_mm
+
+EXTRA_CFLAGS =
+
+SRCFILES = dllapi.cpp engine_api.cpp h_export.cpp meta_api.cpp sdk_util.cpp
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..56f8ef3
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,6 @@
+# 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
diff --git a/dllapi.cpp b/dllapi.cpp
new file mode 100644 (file)
index 0000000..ca70879
--- /dev/null
@@ -0,0 +1,198 @@
+// 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);
+}
diff --git a/engine_api.cpp b/engine_api.cpp
new file mode 100644 (file)
index 0000000..20c3014
--- /dev/null
@@ -0,0 +1,264 @@
+// 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);
+}
diff --git a/h_export.cpp b/h_export.cpp
new file mode 100644 (file)
index 0000000..6f9bef8
--- /dev/null
@@ -0,0 +1,45 @@
+// 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;
+}
diff --git a/info_name.h b/info_name.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/meta_api.cpp b/meta_api.cpp
new file mode 100644 (file)
index 0000000..a3daa7c
--- /dev/null
@@ -0,0 +1,125 @@
+// 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);
+}
diff --git a/sdk_util.cpp b/sdk_util.cpp
new file mode 100644 (file)
index 0000000..5e58409
--- /dev/null
@@ -0,0 +1,50 @@
+// 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 );
+}