/** * vim: set ts=4 : * ============================================================================= * SourceMod * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * ============================================================================= * * 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 * Free Software Foundation. * * 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 * 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 * this program. If not, see . * * 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 * "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 * all respects for all other code used. Additionally, AlliedModders LLC grants * this exception to all derivative works. AlliedModders LLC defines further * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), * or . * * Version: $Id$ */ #include #include "CoreConfig.h" #include "sourcemod.h" #include "sourcemm_api.h" #include "sm_srvcmds.h" #include #include "sm_stringutil.h" #include "LibrarySys.h" #include "Logger.h" #include "PluginSys.h" #include "ForwardSys.h" #include "frame_hooks.h" #ifdef PLATFORM_WINDOWS ConVar sm_corecfgfile("sm_corecfgfile", "addons\\sourcemod\\configs\\core.cfg", 0, "SourceMod core configuration file"); #elif defined PLATFORM_LINUX || defined PLATFORM_APPLE ConVar sm_corecfgfile("sm_corecfgfile", "addons/sourcemod/configs/core.cfg", 0, "SourceMod core configuration file"); #endif IForward *g_pOnServerCfg = NULL; IForward *g_pOnConfigsExecuted = NULL; IForward *g_pOnAutoConfigsBuffered = NULL; CoreConfig g_CoreConfig; bool g_bConfigsExecd = false; bool g_bServerExecd = false; bool g_bGotServerStart = false; bool g_bGotTrigger = false; ConCommand *g_pExecPtr = NULL; ConVar *g_ServerCfgFile = NULL; void CheckAndFinalizeConfigs(); #if SOURCE_ENGINE >= SE_ORANGEBOX SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &); void Hook_ExecDispatchPre(const CCommand &cmd) #elif SOURCE_ENGINE == SE_DARKMESSIAH SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false); void Hook_ExecDispatchPre() #else # if SH_IMPL_VERSION >= 4 extern int __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0); # else extern bool __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0); # endif extern bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0); void Hook_ExecDispatchPre() #endif { #if SOURCE_ENGINE <= SE_DARKMESSIAH CCommand cmd; #endif const char *arg = cmd.Arg(1); if (!g_bServerExecd && arg != NULL && strcmp(arg, g_ServerCfgFile->GetString()) == 0) { g_bGotTrigger = true; } } #if SOURCE_ENGINE >= SE_ORANGEBOX void Hook_ExecDispatchPost(const CCommand &cmd) #else void Hook_ExecDispatchPost() #endif { if (g_bGotTrigger) { g_bGotTrigger = false; g_bServerExecd = true; CheckAndFinalizeConfigs(); } } void CheckAndFinalizeConfigs() { if ((g_bServerExecd || g_ServerCfgFile == NULL) && g_bGotServerStart) { g_PendingInternalPush = true; } } void CoreConfig::OnSourceModAllInitialized() { g_RootMenu.AddRootConsoleCommand("config", "Set core configuration options", this); g_pOnServerCfg = g_Forwards.CreateForward("OnServerCfg", ET_Ignore, 0, NULL); g_pOnConfigsExecuted = g_Forwards.CreateForward("OnConfigsExecuted", ET_Ignore, 0, NULL); g_pOnAutoConfigsBuffered = g_Forwards.CreateForward("OnAutoConfigsBuffered", ET_Ignore, 0, NULL); } CoreConfig::CoreConfig() : m_Strings(512) { } CoreConfig::~CoreConfig() { } void CoreConfig::OnSourceModShutdown() { g_RootMenu.RemoveRootConsoleCommand("config", this); 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_ExecDispatchPre, false); SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, g_pExecPtr, Hook_ExecDispatchPost, true); g_pExecPtr = NULL; } } void CoreConfig::OnSourceModLevelChange(const char *mapName) { static bool already_checked = false; if (!already_checked) { if (engine->IsDedicatedServer()) { g_ServerCfgFile = icvar->FindVar("servercfgfile"); } else { g_ServerCfgFile = icvar->FindVar("lservercfgfile"); } if (g_ServerCfgFile != NULL) { g_pExecPtr = FindCommand("exec"); if (g_pExecPtr != NULL) { SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, g_pExecPtr, Hook_ExecDispatchPre, false); SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, g_pExecPtr, Hook_ExecDispatchPost, true); } else { g_ServerCfgFile = NULL; } } already_checked = true; } g_bConfigsExecd = false; g_bServerExecd = false; g_bGotServerStart = false; g_bGotTrigger = false; } void CoreConfig::OnRootConsoleCommand(const char *cmdname, const CCommand &command) { int argcount = command.ArgC(); if (argcount >= 4) { const char *option = command.Arg(2); const char *value = command.Arg(3); char error[255]; ConfigResult res = SetConfigOption(option, value, ConfigSource_Console, error, sizeof(error)); if (res == ConfigResult_Reject) { g_RootMenu.ConsolePrint("[SM] Could not set config option \"%s\" to \"%s\". (%s)", option, value, error); } else if (res == ConfigResult_Ignore) { g_RootMenu.ConsolePrint("[SM] No such config option \"%s\" exists.", option); } else { g_RootMenu.ConsolePrint("[SM] Config option \"%s\" successfully set to \"%s\".", option, value); } return; } else if (argcount >= 3) { const char *option = command.Arg(2); const char *value = GetCoreConfigValue(option); if (value == NULL) { g_RootMenu.ConsolePrint("[SM] No such config option \"%s\" exists.", option); } else { g_RootMenu.ConsolePrint("[SM] Config option \"%s\" is set to \"%s\".", option, value); } return; } g_RootMenu.ConsolePrint("[SM] Usage: sm config