Merge pull request #397 from alliedmodders/rm-old-mms

Remove code that handles long-dead Metamod:Source versions.
This commit is contained in:
David Anderson 2015-09-18 14:38:52 -07:00
commit c66d14605a
18 changed files with 72 additions and 521 deletions

View File

@ -67,7 +67,7 @@ void ConCmdManager::OnSourceModShutdown()
rootmenu->RemoveRootConsoleCommand("cmds", this); rootmenu->RemoveRootConsoleCommand("cmds", this);
} }
void ConCmdManager::OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe) void ConCmdManager::OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name)
{ {
/* Whoa, first get its information struct */ /* Whoa, first get its information struct */
ConCmdInfo *pInfo; ConCmdInfo *pInfo;
@ -102,7 +102,7 @@ void ConCmdManager::OnUnlinkConCommandBase(ConCommandBase *pBase, const char *na
delete hook; delete hook;
} }
RemoveConCmd(pInfo, name, is_read_safe, false); RemoveConCmd(pInfo, name, false);
} }
void ConCmdManager::OnPluginDestroyed(IPlugin *plugin) void ConCmdManager::OnPluginDestroyed(IPlugin *plugin)
@ -121,7 +121,7 @@ void ConCmdManager::OnPluginDestroyed(IPlugin *plugin)
hook->admin->group->hooks.remove(hook); hook->admin->group->hooks.remove(hook);
if (hook->info->hooks.empty()) if (hook->info->hooks.empty())
RemoveConCmd(hook->info, hook->info->pCmd->GetName(), true, true); RemoveConCmd(hook->info, hook->info->pCmd->GetName(), true);
iter = pList->erase(iter); iter = pList->erase(iter);
delete hook; delete hook;
@ -502,7 +502,7 @@ void ConCmdManager::UpdateAdminCmdFlags(const char *cmd, OverrideType type, Flag
} }
} }
void ConCmdManager::RemoveConCmd(ConCmdInfo *info, const char *name, bool is_read_safe, bool untrack) void ConCmdManager::RemoveConCmd(ConCmdInfo *info, const char *name, bool untrack)
{ {
/* Remove from the trie */ /* Remove from the trie */
m_Cmds.remove(name); m_Cmds.remove(name);
@ -525,10 +525,6 @@ void ConCmdManager::RemoveConCmd(ConCmdInfo *info, const char *name, bool is_rea
} }
else else
{ {
// If it's not safe to read the pointer, we zap the SourceHook hook so it
// doesn't attempt to access the pointer's vtable.
if (!is_read_safe)
info->sh_hook->Zap();
if (untrack) if (untrack)
UntrackConCommandBase(info->pCmd, this); UntrackConCommandBase(info->pCmd, this);
} }

View File

@ -129,7 +129,7 @@ public: //IPluginsListener
public: //IRootConsoleCommand public: //IRootConsoleCommand
void OnRootConsoleCommand(const char *cmdname, const ICommandArgs *command) override; void OnRootConsoleCommand(const char *cmdname, const ICommandArgs *command) override;
public: //IConCommandTracker public: //IConCommandTracker
void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe); void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name) override;
public: public:
bool AddServerCommand(IPluginFunction *pFunction, const char *name, const char *description, int flags); bool AddServerCommand(IPluginFunction *pFunction, const char *name, const char *description, int flags);
bool AddAdminCommand(IPluginFunction *pFunction, bool AddAdminCommand(IPluginFunction *pFunction,
@ -147,7 +147,7 @@ private:
ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args); ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args);
ConCmdInfo *AddOrFindCommand(const char *name, const char *description, int flags); ConCmdInfo *AddOrFindCommand(const char *name, const char *description, int flags);
void AddToCmdList(ConCmdInfo *info); void AddToCmdList(ConCmdInfo *info);
void RemoveConCmd(ConCmdInfo *info, const char *cmd, bool is_read_safe, bool untrack); void RemoveConCmd(ConCmdInfo *info, const char *cmd, bool untrack);
bool CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin); bool CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin);
// Case insensitive // Case insensitive

View File

@ -167,7 +167,7 @@ bool convar_cache_lookup(const char *name, ConVarInfo **pVar)
return convar_cache.retrieve(name, pVar); return convar_cache.retrieve(name, pVar);
} }
void ConVarManager::OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe) void ConVarManager::OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name)
{ {
/* Only check convars that have not been created by SourceMod's core */ /* Only check convars that have not been created by SourceMod's core */
ConVarInfo *pInfo; ConVarInfo *pInfo;

View File

@ -103,7 +103,7 @@ public: // IPluginsListener
public: //IRootConsoleCommand public: //IRootConsoleCommand
void OnRootConsoleCommand(const char *cmdname, const ICommandArgs *command) override; void OnRootConsoleCommand(const char *cmdname, const ICommandArgs *command) override;
public: //IConCommandTracker public: //IConCommandTracker
void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe); void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name) override;
public: //IClientListener public: //IClientListener
void OnClientDisconnected(int client); void OnClientDisconnected(int client);
public: public:

View File

@ -71,17 +71,11 @@
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false); SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
# endif # endif
#else #else
# if SH_IMPL_VERSION >= 4 extern int __SourceHook_FHVPAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>,bool);
extern int __SourceHook_FHVPAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>,bool); extern int __SourceHook_FHAddConCommandDispatch(void *, bool, class fastdelegate::FastDelegate0<void>);
extern int __SourceHook_FHAddConCommandDispatch(void *, bool, class fastdelegate::FastDelegate0<void>);
# else
extern bool __SourceHook_FHAddConCommandDispatch(void *, bool, class fastdelegate::FastDelegate0<void>);
# endif
extern bool __SourceHook_FHRemoveConCommandDispatch(void *, bool, class fastdelegate::FastDelegate0<void>); extern bool __SourceHook_FHRemoveConCommandDispatch(void *, bool, class fastdelegate::FastDelegate0<void>);
#endif #endif
#if SH_IMPL_VERSION >= 4
class GenericCommandHooker : public IConCommandLinkListener class GenericCommandHooker : public IConCommandLinkListener
{ {
struct HackInfo struct HackInfo
@ -137,18 +131,18 @@ class GenericCommandHooker : public IConCommandLinkListener
} }
} }
# if SOURCE_ENGINE == SE_DOTA #if SOURCE_ENGINE == SE_DOTA
void Dispatch(const CCommandContext &context, const CCommand& args) void Dispatch(const CCommandContext &context, const CCommand& args)
# elif SOURCE_ENGINE >= SE_ORANGEBOX #elif SOURCE_ENGINE >= SE_ORANGEBOX
void Dispatch(const CCommand& args) void Dispatch(const CCommand& args)
# else #else
void Dispatch() void Dispatch()
# endif #endif
{ {
cell_t res = ConsoleDetours::Dispatch(META_IFACEPTR(ConCommand) cell_t res = ConsoleDetours::Dispatch(META_IFACEPTR(ConCommand)
# if SOURCE_ENGINE >= SE_ORANGEBOX #if SOURCE_ENGINE >= SE_ORANGEBOX
, args , args
# endif #endif
); );
if (res >= Pl_Handled) if (res >= Pl_Handled)
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
@ -265,308 +259,6 @@ public:
} }
}; };
/**
* END DVP HOOK VERSION
*/
#else /* SH_IMPL_VERSION >= 4 */
/**
* BEGIN ENGINE DETOUR VERSION
*/
# include <jit/jit_helpers.h>
# include <jit/x86/x86_macros.h>
class GenericCommandHooker
{
struct Patch
{
Patch() : applied(false)
{
}
bool applied;
void *base;
unsigned char search[16];
size_t search_len;
size_t offset;
size_t saveat;
int regparam;
void *detour;
};
Patch ces;
Patch cgc;
public:
static void DelayedActivation(void *inparam)
{
GenericCommandHooker *cdtrs = reinterpret_cast<GenericCommandHooker*>(inparam);
/* Safe to re-enter because the frame queue is lock+swapped. */
if ((!cdtrs->ces.applied || !cdtrs->cgc.applied) &&
g_HL2.PeekCommandStack() != NULL)
{
g_SourceMod.AddFrameAction(GenericCommandHooker::DelayedActivation, cdtrs);
return;
}
if (!cdtrs->ces.applied)
cdtrs->ApplyPatch(&cdtrs->ces);
if (!cdtrs->cgc.applied)
cdtrs->ApplyPatch(&cdtrs->cgc);
}
bool Enable()
{
const char *platform = NULL;
# if defined(PLATFORM_WINDOWS)
platform = "Windows";
# else
void *addrInBase = (void *)g_SMAPI->GetEngineFactory(false);
Dl_info info;
if (!dladdr(addrInBase, &info))
{
g_Logger.LogError("Command filter could not find engine name");
return false;
}
if (strstr(info.dli_fname, "engine_i486"))
{
platform = "Linux_486";
}
else if (strstr(info.dli_fname, "engine_i686"))
{
platform = "Linux_686";
}
else if (strstr(info.dli_fname, "engine_amd"))
{
platform = "Linux_AMD";
}
else
{
g_Logger.LogError("Command filter could not determine engine (%s)", info.dli_fname);
return false;
}
# endif
if (!PrepPatch("Cmd_ExecuteString", "CES", platform, &ces))
return false;
if (!PrepPatch("CGameClient::ExecuteString", "CGC", platform, &cgc))
return false;
if (g_HL2.PeekCommandStack() != NULL)
{
g_SourceMod.AddFrameAction(GenericCommandHooker::DelayedActivation, this);
return true;
}
ApplyPatch(&ces);
ApplyPatch(&cgc);
return true;
}
void Disable()
{
UndoPatch(&ces);
UndoPatch(&cgc);
}
private:
# if !defined PLATFORM_WINDOWS
# define PAGE_READWRITE PROT_READ|PROT_WRITE
# define PAGE_EXECUTE_READ PROT_READ|PROT_EXEC
static inline uintptr_t AddrToPage(uintptr_t address)
{
return (address & ~(uintptr_t(sysconf(_SC_PAGE_SIZE) - 1)));
}
# endif
void Protect(void *addr, size_t length, int prot)
{
# if defined PLATFORM_WINDOWS
DWORD ignore;
VirtualProtect(addr, length, prot, &ignore);
# else
uintptr_t startPage = AddrToPage(uintptr_t(addr));
length += (uintptr_t(addr) - startPage);
mprotect((void*)startPage, length, prot);
# endif
}
void UndoPatch(Patch *patch)
{
if (!patch->applied || patch->detour == NULL)
return;
g_pSourcePawn->FreePageMemory(patch->detour);
unsigned char *source = (unsigned char *)patch->base + patch->offset;
Protect(source, patch->search_len, PAGE_READWRITE);
for (size_t i = 0; i < patch->search_len; i++)
source[i] = patch->search[i];
Protect(source, patch->search_len, PAGE_EXECUTE_READ);
}
void ApplyPatch(Patch *patch)
{
assert(!patch->applied);
size_t length = 0;
void *callback = (void*)&ConsoleDetours::Dispatch;
/* Bogus assignment to make compiler is doing the right thing. */
patch->detour = callback;
/* Assemgle the detour. */
JitWriter writer;
writer.outbase = NULL;
writer.outptr = NULL;
do
{
/* Need a specific register, or value on stack? */
if (patch->regparam != -1)
IA32_Push_Reg(&writer, patch->regparam);
/* Call real function. */
IA32_Write_Jump32_Abs(&writer, IA32_Call_Imm32(&writer, 0), callback);
/* Restore stack. */
if (patch->regparam != -1)
IA32_Pop_Reg(&writer, patch->regparam);
/* Copy any saved bytes */
if (patch->saveat)
{
for (size_t i = patch->saveat; i < patch->search_len; i++)
{
writer.write_ubyte(patch->search[i]);
}
}
/* Jump back to the caller. */
unsigned char *target = (unsigned char *)patch->base + patch->offset + patch->search_len;
IA32_Jump_Imm32_Abs(&writer, target);
/* Assemble, if we can. */
if (writer.outbase == NULL)
{
length = writer.outptr - writer.outbase;
patch->detour = g_pSourcePawn->AllocatePageMemory(length);
if (patch->detour == NULL)
{
g_Logger.LogError("Ran out of memory!");
return;
}
g_pSourcePawn->SetReadWrite(patch->detour);
writer.outbase = (jitcode_t)patch->detour;
writer.outptr = writer.outbase;
}
else
{
break;
}
} while (true);
g_pSourcePawn->SetReadExecute(patch->detour);
unsigned char *source = (unsigned char *)patch->base + patch->offset;
Protect(source, 6, PAGE_READWRITE);
source[0] = 0xFF;
source[1] = 0x25;
*(void **)&source[2] = &patch->detour;
Protect(source, 6, PAGE_EXECUTE_READ);
patch->applied = true;
}
bool PrepPatch(const char *signature, const char *name, const char *platform, Patch *patch)
{
/* Get the base address of the function. */
if (!g_pGameConf->GetMemSig(signature, &patch->base) || patch->base == NULL)
{
g_Logger.LogError("Command filter could not find signature: %s", signature);
return false;
}
const char *value;
char keyname[255];
/* Get the verification bytes that will be written over. */
UTIL_Format(keyname, sizeof(keyname), "%s_Patch_%s", name, platform);
if ((value = g_pGameConf->GetKeyValue(keyname)) == NULL)
{
g_Logger.LogError("Command filter could not find key: %s", keyname);
return false;
}
patch->search_len = UTIL_DecodeHexString(patch->search, sizeof(patch->search), value);
if (patch->search_len < 6)
{
g_Logger.LogError("Error decoding %s value, or not long enough", keyname);
return false;
}
/* Get the offset into the function. */
UTIL_Format(keyname, sizeof(keyname), "%s_Offset_%s", name, platform);
if ((value = g_pGameConf->GetKeyValue(keyname)) == NULL)
{
g_Logger.LogError("Command filter could not find key: %s", keyname);
return false;
}
patch->offset = atoi(value);
if (patch->offset > 20000)
{
g_Logger.LogError("Command filter %s value is bogus", keyname);
return false;
}
/* Get the number of bytes to save from what was written over. */
patch->saveat = 0;
UTIL_Format(keyname, sizeof(keyname), "%s_Save_%s", name, platform);
if ((value = g_pGameConf->GetKeyValue(keyname)) != NULL)
{
patch->saveat = atoi(value);
if (patch->saveat >= patch->search_len)
{
g_Logger.LogError("Command filter %s value is too large", keyname);
return false;
}
}
/* Get register for parameter, if any. */
patch->regparam = -1;
UTIL_Format(keyname, sizeof(keyname), "%s_Reg_%s", name, platform);
if ((value = g_pGameConf->GetKeyValue(keyname)) != NULL)
{
patch->regparam = atoi(value);
}
/* Everything loaded from gamedata, make sure the patch will succeed. */
unsigned char *address = (unsigned char *)patch->base + patch->offset;
for (size_t i = 0; i < patch->search_len; i++)
{
if (address[i] != patch->search[i])
{
g_Logger.LogError("Command filter %s has changed (byte %x is not %x sub-offset %d)",
name, address[i], patch->search[i], i);
return false;
}
}
return true;
}
};
static bool dummy_hook_set = false;
void DummyHook()
{
if (dummy_hook_set)
{
dummy_hook_set = false;
RETURN_META(MRES_SUPERCEDE);
}
}
#endif
/** /**
* BEGIN THE ACTUALLY GENERIC CODE. * BEGIN THE ACTUALLY GENERIC CODE.
*/ */
@ -723,23 +415,5 @@ cell_t ConsoleDetours::Dispatch(ConCommand *pBase)
res = g_ConsoleDetours.InternalDispatch(sCoreProviderImpl.CommandClient(), &cargs); res = g_ConsoleDetours.InternalDispatch(sCoreProviderImpl.CommandClient(), &cargs);
} }
#if SH_IMPL_VERSION < 4
if (res >= Pl_Handled)
{
/* See bug 4020 - we can't optimize this because looking at the vtable
* is probably more expensive, since there's no SH_GET_ORIG_VFNPTR_ENTRY.
*/
SH_ADD_HOOK(ConCommand, Dispatch, pBase, SH_STATIC(DummyHook), false);
dummy_hook_set = true;
pBase->Dispatch();
SH_REMOVE_HOOK(ConCommand, Dispatch, pBase, SH_STATIC(DummyHook), false);
}
else
{
/* Make sure the command gets invoked. See bug 4019 on making this better. */
pBase->Dispatch();
}
#endif
return res; return res;
} }

View File

@ -77,11 +77,7 @@ void Hook_ExecDispatchPre(const CCommand &cmd)
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false); SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
void Hook_ExecDispatchPre() void Hook_ExecDispatchPre()
#else #else
# if SH_IMPL_VERSION >= 4 extern int __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
extern int __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
# else
extern bool __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
# endif
extern bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>); extern bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
void Hook_ExecDispatchPre() void Hook_ExecDispatchPre()
#endif #endif

View File

@ -85,14 +85,8 @@ void GameHooks::OnVSPReceived()
if (client_cvar_query_mode_ != ClientCvarQueryMode::Unavailable) if (client_cvar_query_mode_ != ClientCvarQueryMode::Unavailable)
return; return;
// For later MM:S versions, use the updated API, since it's cleaner.
#if defined METAMOD_PLAPI_VERSION || PLAPI_VERSION >= 11
if (g_SMAPI->GetSourceEngineBuild() == SOURCE_ENGINE_ORIGINAL || vsp_version < 2) if (g_SMAPI->GetSourceEngineBuild() == SOURCE_ENGINE_ORIGINAL || vsp_version < 2)
return; return;
#else
if (g_HL2.IsOriginalEngine() || vsp_version < 2)
return;
#endif
#if SOURCE_ENGINE != SE_DARKMESSIAH && SOURCE_ENGINE != SE_DOTA #if SOURCE_ENGINE != SE_DARKMESSIAH && SOURCE_ENGINE != SE_DOTA
hooks_ += SH_ADD_HOOK(IServerPluginCallbacks, OnQueryCvarValueFinished, vsp_interface, SH_MEMBER(this, &GameHooks::OnQueryCvarValueFinished), false); hooks_ += SH_ADD_HOOK(IServerPluginCallbacks, OnQueryCvarValueFinished, vsp_interface, SH_MEMBER(this, &GameHooks::OnQueryCvarValueFinished), false);

View File

@ -114,24 +114,10 @@ CHalfLife2::~CHalfLife2()
CSharedEdictChangeInfo *g_pSharedChangeInfo = NULL; CSharedEdictChangeInfo *g_pSharedChangeInfo = NULL;
#endif #endif
#if !defined METAMOD_PLAPI_VERSION || PLAPI_VERSION < 11
bool is_original_engine = false;
#endif
void CHalfLife2::OnSourceModStartup(bool late) void CHalfLife2::OnSourceModStartup(bool late)
{ {
#if SOURCE_ENGINE != SE_DARKMESSIAH #if SOURCE_ENGINE != SE_DARKMESSIAH
if (g_SMAPI->GetSourceEngineBuild() != SOURCE_ENGINE_ORIGINAL && !g_pSharedChangeInfo)
/* The Ship currently is the only known game to use an older version of the engine */
#if defined METAMOD_PLAPI_VERSION || PLAPI_VERSION >= 11
if (g_SMAPI->GetSourceEngineBuild() == SOURCE_ENGINE_ORIGINAL)
#else
if (strcasecmp(g_SourceMod.GetGameFolderName(), "ship") == 0)
#endif
{
is_original_engine = true;
}
else if (g_pSharedChangeInfo == NULL)
{ {
g_pSharedChangeInfo = engine->GetSharedEdictChangeInfo(); g_pSharedChangeInfo = engine->GetSharedEdictChangeInfo();
} }
@ -238,7 +224,7 @@ void CHalfLife2::InitCommandLine()
{ {
char error[256]; char error[256];
#if SOURCE_ENGINE != SE_DARKMESSIAH #if SOURCE_ENGINE != SE_DARKMESSIAH
if (!is_original_engine) if (g_SMAPI->GetSourceEngineBuild() != SOURCE_ENGINE_ORIGINAL)
{ {
ke::Ref<ke::SharedLib> lib = ke::SharedLib::Open(TIER0_NAME, error, sizeof(error)); ke::Ref<ke::SharedLib> lib = ke::SharedLib::Open(TIER0_NAME, error, sizeof(error));
if (!lib) { if (!lib) {
@ -280,13 +266,6 @@ ICommandLine *CHalfLife2::GetValveCommandLine()
return ((FakeGetCommandLine)((FakeGetCommandLine *)m_pGetCommandLine))(); return ((FakeGetCommandLine)((FakeGetCommandLine *)m_pGetCommandLine))();
} }
#if !defined METAMOD_PLAPI_VERSION || PLAPI_VERSION < 11
bool CHalfLife2::IsOriginalEngine()
{
return is_original_engine;
}
#endif
#if SOURCE_ENGINE != SE_DARKMESSIAH #if SOURCE_ENGINE != SE_DARKMESSIAH
IChangeInfoAccessor *CBaseEdict::GetChangeAccessor() IChangeInfoAccessor *CBaseEdict::GetChangeAccessor()
{ {
@ -786,11 +765,7 @@ bool CHalfLife2::IsLANServer()
bool CHalfLife2::KVLoadFromFile(KeyValues *kv, IBaseFileSystem *filesystem, const char *resourceName, const char *pathID) bool CHalfLife2::KVLoadFromFile(KeyValues *kv, IBaseFileSystem *filesystem, const char *resourceName, const char *pathID)
{ {
#if defined METAMOD_PLAPI_VERSION || PLAPI_VERSION >= 11
if (g_SMAPI->GetSourceEngineBuild() == SOURCE_ENGINE_ORIGINAL) if (g_SMAPI->GetSourceEngineBuild() == SOURCE_ENGINE_ORIGINAL)
#else
if (strcasecmp(g_SourceMod.GetGameFolderName(), "ship") == 0)
#endif
{ {
Assert(filesystem); Assert(filesystem);
#ifdef _MSC_VER #ifdef _MSC_VER

View File

@ -199,9 +199,6 @@ public:
const char *CurrentCommandName(); const char *CurrentCommandName();
void AddDelayedKick(int client, int userid, const char *msg); void AddDelayedKick(int client, int userid, const char *msg);
void ProcessDelayedKicks(); void ProcessDelayedKicks();
#if !defined METAMOD_PLAPI_VERSION || PLAPI_VERSION < 11
bool IsOriginalEngine();
#endif
private: private:
void PushCommandStack(const ICommandArgs *cmd); void PushCommandStack(const ICommandArgs *cmd);
void PopCommandStack(); void PopCommandStack();

View File

@ -55,11 +55,7 @@ SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &)
#elif SOURCE_ENGINE == SE_DARKMESSIAH #elif SOURCE_ENGINE == SE_DARKMESSIAH
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false); SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
#else #else
# if SH_IMPL_VERSION >= 4 extern int __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
extern int __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
# else
extern bool __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
#endif
extern bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>); extern bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
#endif #endif

View File

@ -105,11 +105,7 @@ SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &)
#elif SOURCE_ENGINE == SE_DARKMESSIAH #elif SOURCE_ENGINE == SE_DARKMESSIAH
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false); SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
#else #else
# if SH_IMPL_VERSION >= 4 extern int __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
extern int __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
# else
extern bool __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
# endif
extern bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>); extern bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
#endif #endif

View File

@ -1,33 +1,29 @@
/** // vim: set ts=4 sw=4 tw=99 et:
* vim: set ts=4 sw=4 tw=99 noet : // =============================================================================
* ============================================================================= // SourceMod
* SourceMod // Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. // =============================================================================
* ============================================================================= //
* // This program is free software; you can redistribute it and/or modify it under
* This program is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License, version 3.0, as published by the
* the terms of the GNU General Public License, version 3.0, as published by the // Free Software Foundation.
* Free Software Foundation. //
* // This program is distributed in the hope that it will be useful, but WITHOUT
* This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more // details.
* details. //
* // You should have received a copy of the GNU General Public License along with
* You should have received a copy of the GNU General Public License along with // this program. If not, see <http://www.gnu.org/licenses/>.
* this program. If not, see <http://www.gnu.org/licenses/>. //
* // As a special exception, AlliedModders LLC gives you permission to link the
* As a special exception, AlliedModders LLC gives you permission to link the // code of this program (as well as its derivative works) to "Half-Life 2," the
* code of this program (as well as its derivative works) to "Half-Life 2," the // "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software // by the Valve Corporation. You must obey the GNU General Public License in
* by the Valve Corporation. You must obey the GNU General Public License in // all respects for all other code used. Additionally, AlliedModders LLC grants
* all respects for all other code used. Additionally, AlliedModders LLC grants // this exception to all derivative works. AlliedModders LLC defines further
* this exception to all derivative works. AlliedModders LLC defines further // exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), // or <http://www.sourcemod.net/license.php>.
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#include "sm_globals.h" #include "sm_globals.h"
#include <sh_list.h> #include <sh_list.h>
@ -104,41 +100,20 @@ public:
listener = listener->next; listener = listener->next;
} }
if (pBase) while (iter != tracked_bases.end())
{ {
while (iter != tracked_bases.end()) if ((*iter)->pBase == pBase)
{ {
if ((*iter)->pBase == pBase) pInfo = (*iter);
{ iter = tracked_bases.erase(iter);
pInfo = (*iter); pInfo->cls->OnUnlinkConCommandBase(pBase, pBase->GetName());
iter = tracked_bases.erase(iter); delete pInfo;
pInfo->cls->OnUnlinkConCommandBase(pBase, pBase->GetName(), true); }
delete pInfo; else
} {
else iter++;
{ }
iter++; }
}
}
}
else
{
while (iter != tracked_bases.end())
{
/* This is just god-awful! */
if (FindCommandBase((*iter)->name) != (*iter)->pBase)
{
pInfo = (*iter);
iter = tracked_bases.erase(iter);
pInfo->cls->OnUnlinkConCommandBase(pBase, pInfo->name, false);
delete pInfo;
}
else
{
iter++;
}
}
}
} }
void AddTarget(ConCommandBase *pBase, IConCommandTracker *cls) void AddTarget(ConCommandBase *pBase, IConCommandTracker *cls)

View File

@ -35,7 +35,7 @@
class IConCommandTracker class IConCommandTracker
{ {
public: public:
virtual void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe) = 0; virtual void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name) = 0;
}; };
void TrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me); void TrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me);

View File

@ -131,7 +131,7 @@ public:
class CommandFlagsHelper : public IConCommandTracker class CommandFlagsHelper : public IConCommandTracker
{ {
public: public:
void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe) void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name) override
{ {
m_CmdFlags.remove(name); m_CmdFlags.remove(name);
} }

View File

@ -495,7 +495,6 @@ static cell_t smn_IsPlayerAlive(IPluginContext *pContext, const cell_t *params)
static cell_t GuessSDKVersion(IPluginContext *pContext, const cell_t *params) static cell_t GuessSDKVersion(IPluginContext *pContext, const cell_t *params)
{ {
#if defined METAMOD_PLAPI_VERSION || PLAPI_VERSION >= 11
int version = g_SMAPI->GetSourceEngineBuild(); int version = g_SMAPI->GetSourceEngineBuild();
switch (version) switch (version)
@ -505,7 +504,7 @@ static cell_t GuessSDKVersion(IPluginContext *pContext, const cell_t *params)
case SOURCE_ENGINE_EPISODEONE: case SOURCE_ENGINE_EPISODEONE:
return 20; return 20;
# if defined METAMOD_PLAPI_VERSION #if defined METAMOD_PLAPI_VERSION
/* Newer games. */ /* Newer games. */
case SOURCE_ENGINE_DARKMESSIAH: case SOURCE_ENGINE_DARKMESSIAH:
return 15; return 15;
@ -538,18 +537,8 @@ static cell_t GuessSDKVersion(IPluginContext *pContext, const cell_t *params)
return 80; return 80;
case SOURCE_ENGINE_DOTA: case SOURCE_ENGINE_DOTA:
return 90; return 90;
# endif
}
#else
if (g_HL2.IsOriginalEngine())
{
return 10;
}
else
{
return 20;
}
#endif #endif
}
return 0; return 0;
} }

View File

@ -63,6 +63,13 @@ int vsp_version = 0;
PLUGIN_EXPOSE(SourceMod, g_SourceMod_Core); PLUGIN_EXPOSE(SourceMod, g_SourceMod_Core);
#if !defined(METAMOD_PLAPI_VERSION) && PLAPI_VERSION < 11
# error "SourceMod requires Metamod:Source 1.8 or higher."
#endif
#if SH_IMPL_VERSION < 4
# error "SourceMod requires a newer version of SourceHook."
#endif
ConVar sourcemod_version("sourcemod_version", SOURCEMOD_VERSION, FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY, "SourceMod Version"); ConVar sourcemod_version("sourcemod_version", SOURCEMOD_VERSION, FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY, "SourceMod Version");
bool SourceMod_Core::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late) bool SourceMod_Core::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late)
@ -121,9 +128,7 @@ bool SourceMod_Core::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen
ismm->AddListener(this, this); ismm->AddListener(this, this);
#if defined METAMOD_PLAPI_VERSION || PLAPI_VERSION >= 11
if ((vsp_interface = g_SMAPI->GetVSPInfo(&vsp_version)) == NULL) if ((vsp_interface = g_SMAPI->GetVSPInfo(&vsp_version)) == NULL)
#endif
{ {
g_SMAPI->EnableVSPListener(); g_SMAPI->EnableVSPListener();
} }
@ -211,31 +216,15 @@ void SourceMod_Core::OnVSPListening(IServerPluginCallbacks *iface)
return; return;
} }
#if defined METAMOD_PLAPI_VERSION || PLAPI_VERSION >= 11
if (vsp_version == 0) if (vsp_version == 0)
{ {
g_SMAPI->GetVSPInfo(&vsp_version); g_SMAPI->GetVSPInfo(&vsp_version);
} }
#else
if (vsp_version == 0)
{
if (strcmp(g_SourceMod.GetGameFolderName(), "ship") == 0)
{
vsp_version = 1;
}
else
{
vsp_version = 2;
}
}
#endif
/* Notify! */ /* Notify! */
sCoreProviderImpl.OnVSPReceived(); sCoreProviderImpl.OnVSPReceived();
} }
#if defined METAMOD_PLAPI_VERSION || PLAPI_VERSION >= 11
void SourceMod_Core::OnUnlinkConCommandBase(PluginId id, ConCommandBase *pCommand) void SourceMod_Core::OnUnlinkConCommandBase(PluginId id, ConCommandBase *pCommand)
{ {
#if SOURCE_ENGINE < SE_ORANGEBOX #if SOURCE_ENGINE < SE_ORANGEBOX
@ -243,15 +232,6 @@ void SourceMod_Core::OnUnlinkConCommandBase(PluginId id, ConCommandBase *pComman
#endif #endif
} }
#else
void SourceMod_Core::OnPluginUnload(PluginId id)
{
Global_OnUnlinkConCommandBase(NULL);
}
#endif
void *SourceMod_Core::OnMetamodQuery(const char *iface, int *ret) void *SourceMod_Core::OnMetamodQuery(const char *iface, int *ret)
{ {
void *ptr = NULL; void *ptr = NULL;

View File

@ -80,11 +80,7 @@ public:
const char *GetLogTag(); const char *GetLogTag();
public: public:
void OnVSPListening(IServerPluginCallbacks *iface); void OnVSPListening(IServerPluginCallbacks *iface);
#if defined METAMOD_PLAPI_VERSION || PLAPI_VERSION >= 11
void OnUnlinkConCommandBase(PluginId id, ConCommandBase *pCommand); void OnUnlinkConCommandBase(PluginId id, ConCommandBase *pCommand);
#else
void OnPluginUnload(PluginId id);
#endif
void *OnMetamodQuery(const char *iface, int *ret); void *OnMetamodQuery(const char *iface, int *ret);
}; };

View File

@ -242,24 +242,11 @@ void GetIServer()
return; return;
} }
#if defined METAMOD_PLAPI_VERSION || PLAPI_VERSION >= 11
/* Get the CreateFakeClient function pointer */ /* Get the CreateFakeClient function pointer */
if (!(vfunc=SH_GET_ORIG_VFNPTR_ENTRY(engine, &IVEngineServer::CreateFakeClient))) if (!(vfunc=SH_GET_ORIG_VFNPTR_ENTRY(engine, &IVEngineServer::CreateFakeClient)))
{ {
return; return;
} }
#else
/* Get the interface manually */
SourceHook::MemFuncInfo info = {true, -1, 0, 0};
SourceHook::GetFuncInfo(&IVEngineServer::CreateFakeClient, info);
vfunc = enginePatch->GetOrigFunc(info.vtbloffs, info.vtblindex);
if (!vfunc)
{
void **vtable = *reinterpret_cast<void ***>(enginePatch->GetThisPtr() + info.thisptroffs + info.vtbloffs);
vfunc = vtable[info.vtblindex];
}
#endif
/* Get signature string for IVEngineServer::CreateFakeClient() */ /* Get signature string for IVEngineServer::CreateFakeClient() */
sigstr = g_pGameConf->GetKeyValue(FAKECLIENT_KEY); sigstr = g_pGameConf->GetKeyValue(FAKECLIENT_KEY);