Difference between revisions of "Porting to Orange Box"
m (New page: __FORCETOC__ Porting Valve Server Plugins or Metamod:Source plugins to Orange Box is not very difficult. This article explores some of the changes and how to simplify them. Users of Met...) |
m (RegisterConCommandBase is a bool return type, added return to the function it calls...) |
||
(16 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
__FORCETOC__ | __FORCETOC__ | ||
− | |||
Porting Valve Server Plugins or Metamod:Source plugins to Orange Box is not very difficult. This article explores some of the changes and how to simplify them. | Porting Valve Server Plugins or Metamod:Source plugins to Orange Box is not very difficult. This article explores some of the changes and how to simplify them. | ||
− | Users of Metamod:Source | + | Users of Metamod:Source should upgrade to Metamod:Source 1.7 and use the 1.6+ API (see [[MM:S API Differences]]). |
This document will assume a single preprocessor macro, <tt>ORANGEBOX_BUILD</tt>, determines that an Orange Box build is being made. | This document will assume a single preprocessor macro, <tt>ORANGEBOX_BUILD</tt>, determines that an Orange Box build is being made. | ||
Line 65: | Line 64: | ||
=ConCommandBaseMgr Removed= | =ConCommandBaseMgr Removed= | ||
ConCommandBaseMgr has been removed. That means the normal call, <tt>ConCommandBaseMgr::OneTimeInit()</tt>, is no longer applicable. There are two other solutions to registering your ConVars and ConCommands: | ConCommandBaseMgr has been removed. That means the normal call, <tt>ConCommandBaseMgr::OneTimeInit()</tt>, is no longer applicable. There are two other solutions to registering your ConVars and ConCommands: | ||
− | *Use <tt> | + | *Use <tt>ConVar_Register</tt> instead. |
*Use <tt>META_REGCVAR</tt> on each pointer (it will work on any ConCommandBase *) pointer, or <tt>META_REGCMD</tt> on each individual command name. | *Use <tt>META_REGCVAR</tt> on each pointer (it will work on any ConCommandBase *) pointer, or <tt>META_REGCMD</tt> on each individual command name. | ||
− | It is highly recommended that Metamod:Source plugins go through Metamod:Source's | + | It is highly recommended that Metamod:Source plugins go through Metamod:Source's ConCommandBase registration process. This will make your plugin more compatible across engines and other plugins. Example: |
+ | |||
+ | <cpp> | ||
+ | class BaseAccessor : public IConCommandBaseAccessor | ||
+ | { | ||
+ | public: | ||
+ | bool RegisterConCommandBase(ConCommandBase *pVar) | ||
+ | { | ||
+ | return META_REGCVAR(pVar); | ||
+ | } | ||
+ | } s_BaseAccessor; | ||
+ | |||
+ | void SetupEverything() | ||
+ | { | ||
+ | #if defined ORANGEBOX_BUILD | ||
+ | /* NOTE! g_pCvar must be set to a valid ICvar instance first. */ | ||
+ | ConVar_Register(0, &s_BaseAccessor); | ||
+ | #else | ||
+ | ConCommandBaseMgr::OneTimeInit(&s_BaseAccessor); | ||
+ | #endif | ||
+ | }</cpp> | ||
+ | |||
+ | Note that Valve Server Plugins can pass <tt>NULL</tt> to use the default accessor. '''Metamod:Source plugins should not do this.''' Otherwise, Metamod:Source will not be able to keep track of the ConCommandBase allocations per-plugin. | ||
+ | |||
+ | |||
+ | =Renamings/Removals= | ||
+ | *<tt>VENGINE_CVAR_INTERFACE_VERSION</tt> was renamed to <tt>CVAR_INTERFACE_VERSION</tt>. | ||
+ | *<tt>FCVAR_PLUGIN</tt> was removed. It is probably no longer needed with the advent of <tt>ConVar_Unregister</tt>. | ||
+ | |||
+ | |||
+ | =Sample Port= | ||
+ | An example of a plugin that fully supports both versions is [http://www.bailopan.net/stripper Stripper:Source] ([http://svn.alliedmods.net/viewvc.cgi/sourcemm/stripper/?root=dvander SVN here]). | ||
+ | |||
+ | Note that this plugin uses the new "extended loading" API available in Metamod:Source 1.6.0. The thin-loader library runs on any Metamod:Source version, and will correctly pick one of 6 child plugins to load. This allows Stripper:Source to be distributed as one package with no configuration hassle. | ||
+ | |||
− | + | [[Category:Metamod:Source Development]] |
Latest revision as of 13:33, 30 August 2010
Porting Valve Server Plugins or Metamod:Source plugins to Orange Box is not very difficult. This article explores some of the changes and how to simplify them.
Users of Metamod:Source should upgrade to Metamod:Source 1.7 and use the 1.6+ API (see MM:S API Differences).
This document will assume a single preprocessor macro, ORANGEBOX_BUILD, determines that an Orange Box build is being made.
Command Callbacks
In the original Half-Life 2 engine, all commands used IVEngineServer::Cmd_Arg* in order to receive information about the current command's tokenization. However, these functions have been completely removed, and a new re-entrant version is in place.
Each of the following callbacks:
void IServerGameClients::ClientCommand(edict_t *pEdict); typedef void (*FnCommandCallback)(void);
Is now:
void IServerGameClients::ClientCommand(edict_t *pEdict, const CCommand &args); typedef void (*FnCommandCallback)(const CCommand &args);
Definitions for CCommand can be found in convar.h. A simple way to work around this change is to use wrapper functions. For example:
#if defined ORANGEBOX_BUILD SH_DECL_HOOK2_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *, const CCommand &); #else SH_DECL_HOOK1_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *); #endif #if !defined ORANGEBOX_BUILD class CCommand { public: const char *ArgS() { return engine->Cmd_Args(); } int ArgC() { return engine->Cmd_Argc(); } const char *Arg(int index) { return engine->Cmd_Argv(index); } }; #endif #if defined ORANGEBOX_BUILD void Hook_ClientCommand(edict_t *pEntity, const CCommand &args) #else void Hook_ClientCommand(edict_t *pEntity) #endif { #if !defined ORANGEBOX_BUILD CCommand args; #endif const char *cmd = args.Arg(0); /* ... stuff ... */ }
ConCommandBaseMgr Removed
ConCommandBaseMgr has been removed. That means the normal call, ConCommandBaseMgr::OneTimeInit(), is no longer applicable. There are two other solutions to registering your ConVars and ConCommands:
- Use ConVar_Register instead.
- Use META_REGCVAR on each pointer (it will work on any ConCommandBase *) pointer, or META_REGCMD on each individual command name.
It is highly recommended that Metamod:Source plugins go through Metamod:Source's ConCommandBase registration process. This will make your plugin more compatible across engines and other plugins. Example:
class BaseAccessor : public IConCommandBaseAccessor { public: bool RegisterConCommandBase(ConCommandBase *pVar) { return META_REGCVAR(pVar); } } s_BaseAccessor; void SetupEverything() { #if defined ORANGEBOX_BUILD /* NOTE! g_pCvar must be set to a valid ICvar instance first. */ ConVar_Register(0, &s_BaseAccessor); #else ConCommandBaseMgr::OneTimeInit(&s_BaseAccessor); #endif }
Note that Valve Server Plugins can pass NULL to use the default accessor. Metamod:Source plugins should not do this. Otherwise, Metamod:Source will not be able to keep track of the ConCommandBase allocations per-plugin.
Renamings/Removals
- VENGINE_CVAR_INTERFACE_VERSION was renamed to CVAR_INTERFACE_VERSION.
- FCVAR_PLUGIN was removed. It is probably no longer needed with the advent of ConVar_Unregister.
Sample Port
An example of a plugin that fully supports both versions is Stripper:Source (SVN here).
Note that this plugin uses the new "extended loading" API available in Metamod:Source 1.6.0. The thin-loader library runs on any Metamod:Source version, and will correctly pick one of 6 child plugins to load. This allows Stripper:Source to be distributed as one package with no configuration hassle.