# vi: set ts=4 sw=4 :
# vim: set tw=75 :

Configuration
=============

Plugins are described in a file "metamod.ini", in the game directory, and
each line describes a plugin to load:
	<platform>	<filepath>	<description>

Fields are whitespace delimited.  Platform is a keyword, either "linux" or
"win32".  Filepath is a path to the DLL/so file.  Relative paths are from
the game dir; absolute paths are also valid.  Description is a (short)
description of the plugin (whitespace _is_ allowed; quoting is
unnecessary).  Comments are recognized at _only_ the beginning of a line,
and can be in either shell style ("#") or c++ style ("//").

For instance, in "cstrike/metamod.ini" these are all valid lines:
	// linux dlls/mybot.so	My simple bot
	win32 dlls/mybot.dll	My simple bot
	#linux dlls/admin-wd_i386.so	Adminmod (wd)
	linux /tmp/mm_stub_i386.so	Stub plugin
	linux dlls/mm_trace_i386.so	API trace
	linux dlls/mm_admin_i386.so	Adminmod

Note that order in the metamod.ini file _is_ significant.

The game dll is auto-detected, along the same lines AdminMod operated
(looking at the "gamedir").


Operation
=========

The basic operation is, for each api call:
 - iterate through list of plugins
 - for each plugin, if it provides this api call, then call the
   function in the plugin
 - call the "real" function (in the game dll, or from the engine)
 - for each plugin, check for a "post" version of the function, and call
   if present

Also, for any api call, each plugin has the opportunity to replace the
real routine, in two ways:
 - prevent the real routine from being called (SUPERCEDE)
 - allow the real routine to be called, but change the value that's
   returned (OVERRIDE)

Thus after each plugin is called, its META_RETURN flag is checked, and
action taken appropriately.  Note that supercede/override only affects
the _real_ routine; other plugins will still be called.

In addition to the SUPERCEDE and OVERRIDE flags, there are two
additional flags a plugin can return:
 - HANDLED ("I did something here")
 - IGNORED ("I didn't really do anything")

These aren't used by metamod itself, but could be used by plugins to
get an idea if a previous plugin did anything.


Plugin coding requirements
==========================

Plugins MUST provide the following standard HLSDK "C" exported function:

	void GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals);

AS WELL AS the following new function:

	int Meta_Init(META_FUNCTIONS *pFunctionTable, meta_globals_t *pMGlobals, int *interfaceVersion);

Also, it must provide AT LEAST one function returning a standard HL
function table, from either the following standard HLSDK functions:

	int GetEntityAPI( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion );
	int GetEntityAPI2( DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion );
	int GetNewDLLFunctions( NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion );

or from the following new functions:

	int GetEntityAPI_Post(DLL_FUNCTIONS *pFunctionTable, int interfaceVersion);
	int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion ;
	int GetNewDLLFunctions_Post(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion);

	int GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion);
	int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion);

Thus, it needs to have (at least):
	GiveFnptrsToDll
	Meta_Init
	<some Get function>

Additional "Get" functions can also be provided, even all of them.

See the "stub_plugin" for an example of bare minimum code.  See
"trace_plugin" for an example of (virtually) complete functionality.


Operation Details
=================

Plugins are loaded when the engine calls GiveFnptrsToDll().  The config
file is parsed, and for each valid plugin (uncommented, platform relevant),
the operation is:
 - dlopen the file, store the handle
 - dlsym() and call:
    GiveFnptrsToDll
	MetaInit
 - if present, call function pointers, and store resulting function table:
	GetEntityAPI
	GetEntityAPI2
	GetNewDLLFunctions

	GetEntityAPI_Post
	GetEntityAPI2_Post
	GetNewDLLFunctions_Post

	GetEngineFunctions
	GetEngineFunctions_Post

