From c337bc512c2b622d74fc5cbb5ade9de2aa58e769 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 20 Jun 2008 05:22:10 +0000 Subject: [PATCH] fixed amb1750 - OnAutoConfigsBuffered() was executing before server.cfg fixed OnConfigsExecuted() having a race condition with exec server.cfg --HG-- branch : sourcemod-1.0.x extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/sourcemod-1.0.x%402261 --- core/CoreConfig.cpp | 86 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 5 deletions(-) diff --git a/core/CoreConfig.cpp b/core/CoreConfig.cpp index 5e28beb3..58e8293d 100644 --- a/core/CoreConfig.cpp +++ b/core/CoreConfig.cpp @@ -2,7 +2,7 @@ * vim: set ts=4 : * ============================================================================= * SourceMod - * Copyright (C) 2004-2007 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 @@ -52,6 +52,45 @@ IForward *g_pOnConfigsExecuted = NULL; IForward *g_pOnAutoConfigsBuffered = NULL; CoreConfig g_CoreConfig; bool g_bConfigsExecd = false; +bool g_bServerExecd = false; +bool g_bGotServerStart = false; +ConCommand *g_pExecPtr = NULL; +ConVar *g_ServerCfgFile = NULL; + +void CheckAndFinalizeConfigs(); + +/* :TODO: use PM's new macros. this is a fast patch so I don't have time to look them up. */ +#if defined ORANGEBOX_BUILD +bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelegate::FastDelegate1); +int __SourceHook_FHAddConCommandDispatch(void *,enum SourceHook::ISourceHook::AddHookMode,bool,class fastdelegate::FastDelegate1); +void Hook_ExecDispatch(const CCommand &cmd) +#else +extern bool __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0); +extern bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0); +void Hook_ExecDispatch() +#endif +{ +#if !defined ORANGEBOX_BUILD + CCommand cmd; +#endif + + const char *arg = cmd.Arg(1); + if (arg != NULL && strcmp(arg, g_ServerCfgFile->GetString()) == 0) + { + g_bServerExecd = true; + CheckAndFinalizeConfigs(); + } +} + +void CheckAndFinalizeConfigs() +{ + if ((g_bServerExecd || g_ServerCfgFile == NULL) && g_bGotServerStart) + { + /* Order is important here. We need to buffer things before we send the command out. */ + g_pOnAutoConfigsBuffered->Execute(NULL); + engine->ServerCommand("sm internal 1\n"); + } +} void CoreConfig::OnSourceModAllInitialized() { @@ -67,11 +106,49 @@ void CoreConfig::OnSourceModShutdown() g_Forwards.ReleaseForward(g_pOnServerCfg); g_Forwards.ReleaseForward(g_pOnConfigsExecuted); g_Forwards.ReleaseForward(g_pOnAutoConfigsBuffered); + + if (g_pExecPtr != NULL) + { + SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, g_pExecPtr, Hook_ExecDispatch, true); + g_pExecPtr = NULL; + } } void CoreConfig::OnSourceModLevelChange(const char *mapName) { + static bool already_checked = false; + + if (!already_checked) + { + g_ServerCfgFile = icvar->FindVar("servercfgfile"); + if (g_ServerCfgFile != NULL) + { + ConCommandBase *pBase = icvar->GetCommands(); + while (pBase != NULL) + { + if (pBase->IsCommand() && strcmp(pBase->GetName(), "exec") == 0) + { + break; + } + pBase = const_cast(pBase->GetNext()); + } + + g_pExecPtr = (ConCommand *)pBase; + if (g_pExecPtr != NULL) + { + SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, g_pExecPtr, Hook_ExecDispatch, true); + } + else + { + g_ServerCfgFile = NULL; + } + } + already_checked = true; + } + g_bConfigsExecd = false; + g_bServerExecd = false; + g_bGotServerStart = false; } void CoreConfig::OnRootConsoleCommand(const char *cmdname, const CCommand &command) @@ -385,7 +462,7 @@ void SM_ExecuteForPlugin(IPluginContext *ctx) void SM_ExecuteAllConfigs() { - if (g_bConfigsExecd) + if (g_bGotServerStart) { return; } @@ -406,9 +483,8 @@ void SM_ExecuteAllConfigs() } iter->Release(); - g_pOnAutoConfigsBuffered->Execute(NULL); - - engine->ServerCommand("sm internal 1\n"); + g_bGotServerStart = true; + CheckAndFinalizeConfigs(); } void SM_ConfigsExecuted_Global()