1.1 --- a/core/CoreConfig.cpp Mon Jun 18 03:39:15 2007 +0000
1.2 +++ b/core/CoreConfig.cpp Mon Jun 18 07:04:22 2007 +0000
1.3 @@ -16,9 +16,13 @@
1.4 #include "sourcemod.h"
1.5 #include "sourcemm_api.h"
1.6 #include "sm_srvcmds.h"
1.7 +#include "sm_version.h"
1.8 +#include "sm_stringutil.h"
1.9 #include "LibrarySys.h"
1.10 #include "TextParsers.h"
1.11 #include "Logger.h"
1.12 +#include "PluginSys.h"
1.13 +#include "ForwardSys.h"
1.14
1.15 #ifdef PLATFORM_WINDOWS
1.16 ConVar sm_corecfgfile("sm_corecfgfile", "addons\\sourcemod\\configs\\core.cfg", 0, "SourceMod core configuration file");
1.17 @@ -26,16 +30,28 @@
1.18 ConVar sm_corecfgfile("sm_corecfgfile", "addons/sourcemod/configs/core.cfg", 0, "SourceMod core configuration file");
1.19 #endif
1.20
1.21 +IForward *g_pOnServerCfg = NULL;
1.22 +IForward *g_pOnConfigsExecuted = NULL;
1.23 CoreConfig g_CoreConfig;
1.24 +bool g_bConfigsExecd = false;
1.25
1.26 void CoreConfig::OnSourceModAllInitialized()
1.27 {
1.28 g_RootMenu.AddRootConsoleCommand("config", "Set core configuration options", this);
1.29 + g_pOnServerCfg = g_Forwards.CreateForward("OnServerCfg", ET_Ignore, 0, NULL);
1.30 + g_pOnConfigsExecuted = g_Forwards.CreateForward("OnConfigsExecuted", ET_Ignore, 0, NULL);
1.31 }
1.32
1.33 void CoreConfig::OnSourceModShutdown()
1.34 {
1.35 g_RootMenu.RemoveRootConsoleCommand("config", this);
1.36 + g_Forwards.ReleaseForward(g_pOnServerCfg);
1.37 + g_Forwards.ReleaseForward(g_pOnConfigsExecuted);
1.38 +}
1.39 +
1.40 +void CoreConfig::OnSourceModLevelChange(const char *mapName)
1.41 +{
1.42 + g_bConfigsExecd = false;
1.43 }
1.44
1.45 void CoreConfig::OnRootConsoleCommand(const char *command, unsigned int argcount)
1.46 @@ -121,3 +137,258 @@
1.47
1.48 return ConfigResult_Ignore;
1.49 }
1.50 +
1.51 +bool SM_AreConfigsExecuted()
1.52 +{
1.53 + return g_bConfigsExecd;
1.54 +}
1.55 +
1.56 +inline bool IsPathSepChar(char c)
1.57 +{
1.58 +#if defined PLATFORM_WINDOWS
1.59 + return (c == '\\' || c == '/');
1.60 +#elif defined PLATFORM_LINUX
1.61 + return (c == '/');
1.62 +#endif
1.63 +}
1.64 +
1.65 +bool SM_ExecuteConfig(CPlugin *pl, AutoConfig *cfg, bool can_create)
1.66 +{
1.67 + bool will_create = false;
1.68 +
1.69 + /* See if we should be creating */
1.70 + if (can_create && cfg->create)
1.71 + {
1.72 + will_create = true;
1.73 +
1.74 + /* If the folder does not exist, attempt to create it.
1.75 + * We're awfully nice.
1.76 + */
1.77 + const char *folder = cfg->folder.c_str();
1.78 + char path[PLATFORM_MAX_PATH];
1.79 + char build[PLATFORM_MAX_PATH];
1.80 +
1.81 + g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "cfg/%s", folder);
1.82 +
1.83 + if (!g_LibSys.IsPathDirectory(path))
1.84 + {
1.85 + char *cur_ptr = path;
1.86 + size_t len;
1.87 +
1.88 + g_LibSys.PathFormat(path, sizeof(path), "%s", folder);
1.89 + len = g_SourceMod.BuildPath(Path_Game, build, sizeof(build), "cfg");
1.90 +
1.91 + do
1.92 + {
1.93 + /* Find next suitable path */
1.94 + char *next_ptr = cur_ptr;
1.95 + while (*next_ptr != '\0')
1.96 + {
1.97 + if (IsPathSepChar(*next_ptr))
1.98 + {
1.99 + *next_ptr = '\0';
1.100 + next_ptr++;
1.101 + break;
1.102 + }
1.103 + next_ptr++;
1.104 + }
1.105 + if (*next_ptr == '\0')
1.106 + {
1.107 + next_ptr = NULL;
1.108 + }
1.109 + len += g_LibSys.PathFormat(&build[len],
1.110 + sizeof(build)-len,
1.111 + "/%s",
1.112 + cur_ptr);
1.113 + if (!g_LibSys.CreateDirectory(build))
1.114 + {
1.115 + break;
1.116 + }
1.117 + cur_ptr = next_ptr;
1.118 + } while (cur_ptr);
1.119 + }
1.120 + }
1.121 +
1.122 + /* Check if the file exists. */
1.123 + char file[PLATFORM_MAX_PATH];
1.124 + char local[PLATFORM_MAX_PATH];
1.125 +
1.126 + if (cfg->folder.size())
1.127 + {
1.128 + g_LibSys.PathFormat(local,
1.129 + sizeof(local),
1.130 + "%s/%s.cfg",
1.131 + cfg->folder.c_str(),
1.132 + cfg->autocfg.c_str());
1.133 + } else {
1.134 + g_LibSys.PathFormat(local,
1.135 + sizeof(local),
1.136 + "%s.cfg",
1.137 + cfg->autocfg.c_str());
1.138 + }
1.139 +
1.140 + g_SourceMod.BuildPath(Path_Game, file, sizeof(file), "cfg/%s", local);
1.141 +
1.142 + bool file_exists = g_LibSys.IsPathFile(file);
1.143 + if (!file_exists && will_create)
1.144 + {
1.145 + List<const ConVar *> *convars = NULL;
1.146 + if (pl->GetProperty("ConVarList", (void **)&convars, false) && convars)
1.147 + {
1.148 + /* Attempt to create it */
1.149 + FILE *fp = fopen(file, "wt");
1.150 + if (fp)
1.151 + {
1.152 + fprintf(fp, "// This file was auto-generated by SourceMod (v%s)\n", SVN_FULL_VERSION);
1.153 + fprintf(fp, "// ConVars for plugin \"%s\"\n", pl->GetFilename());
1.154 + fprintf(fp, "\n\n");
1.155 +
1.156 + List<const ConVar *>::iterator iter;
1.157 + float x;
1.158 + for (iter = convars->begin(); iter != convars->end(); iter++)
1.159 + {
1.160 + const ConVar *cvar = (*iter);
1.161 + char descr[255];
1.162 + char *dptr = descr;
1.163 +
1.164 + /* Print comments until there is no more */
1.165 + strncopy(descr, cvar->GetHelpText(), sizeof(descr));
1.166 + while (*dptr != '\0')
1.167 + {
1.168 + /* Find the next line */
1.169 + char *next_ptr = dptr;
1.170 + while (*next_ptr != '\0')
1.171 + {
1.172 + if (*next_ptr == '\n')
1.173 + {
1.174 + *next_ptr = '\0';
1.175 + next_ptr++;
1.176 + break;
1.177 + }
1.178 + next_ptr++;
1.179 + }
1.180 + fprintf(fp, "// %s\n", dptr);
1.181 + dptr = next_ptr;
1.182 + }
1.183 +
1.184 + fprintf(fp, "// -\n");
1.185 + fprintf(fp, "// Default: \"%s\"\n", cvar->GetDefault());
1.186 + if (cvar->GetMin(x))
1.187 + {
1.188 + fprintf(fp, "// Minimum: \"%02f\"\n", x);
1.189 + }
1.190 + if (cvar->GetMax(x))
1.191 + {
1.192 + fprintf(fp, "// Maximum: \"%02f\"\n", x);
1.193 + }
1.194 + fprintf(fp, "%s \"%s\"\n", cvar->GetName(), cvar->GetDefault());
1.195 + fprintf(fp, "\n");
1.196 + }
1.197 + fprintf(fp, "\n");
1.198 +
1.199 + file_exists = true;
1.200 + can_create = false;
1.201 + fclose(fp);
1.202 + }
1.203 + }
1.204 + }
1.205 +
1.206 + if (file_exists)
1.207 + {
1.208 + char cmd[255];
1.209 + UTIL_Format(cmd, sizeof(cmd), "exec %s\n", local);
1.210 + engine->ServerCommand(cmd);
1.211 + }
1.212 +
1.213 + return can_create;
1.214 +}
1.215 +
1.216 +void SM_DoSingleExecFwds(IPluginContext *ctx)
1.217 +{
1.218 + IPluginFunction *pf;
1.219 +
1.220 + if ((pf = ctx->GetFunctionByName("OnServerCfg")) != NULL)
1.221 + {
1.222 + pf->Execute(NULL);
1.223 + }
1.224 +
1.225 + if ((pf = ctx->GetFunctionByName("OnConfigsExecuted")) != NULL)
1.226 + {
1.227 + pf->Execute(NULL);
1.228 + }
1.229 +}
1.230 +
1.231 +void SM_ConfigsExecuted_Plugin(unsigned int serial)
1.232 +{
1.233 + IPluginIterator *iter = g_PluginSys.GetPluginIterator();
1.234 + while (iter->MorePlugins())
1.235 + {
1.236 + CPlugin *plugin = (CPlugin *)(iter->GetPlugin());
1.237 + if (plugin->GetSerial() == serial)
1.238 + {
1.239 + SM_DoSingleExecFwds(plugin->GetBaseContext());
1.240 + break;
1.241 + }
1.242 + iter->NextPlugin();
1.243 + }
1.244 + iter->Release();
1.245 +}
1.246 +
1.247 +void SM_ExecuteForPlugin(IPluginContext *ctx)
1.248 +{
1.249 + CPlugin *plugin = (CPlugin *)g_PluginSys.GetPluginByCtx(ctx->GetContext());
1.250 +
1.251 + unsigned int num = plugin->GetConfigCount();
1.252 + if (!num)
1.253 + {
1.254 + SM_DoSingleExecFwds(ctx);
1.255 + } else {
1.256 + bool can_create = true;
1.257 + for (unsigned int i=0; i<num; i++)
1.258 + {
1.259 + can_create = SM_ExecuteConfig(plugin, plugin->GetConfig(i), can_create);
1.260 + }
1.261 + char cmd[255];
1.262 + UTIL_Format(cmd, sizeof(cmd), "sm internal 2 %d\n", plugin->GetSerial());
1.263 + engine->ServerCommand(cmd);
1.264 + }
1.265 +}
1.266 +
1.267 +void SM_ExecuteAllConfigs()
1.268 +{
1.269 + if (g_bConfigsExecd)
1.270 + {
1.271 + return;
1.272 + }
1.273 +
1.274 + engine->ServerCommand("exec cfg/sourcemod/sourcemod.cfg\n");
1.275 +
1.276 + IPluginIterator *iter = g_PluginSys.GetPluginIterator();
1.277 + while (iter->MorePlugins())
1.278 + {
1.279 + CPlugin *plugin = (CPlugin *)(iter->GetPlugin());
1.280 + unsigned int num = plugin->GetConfigCount();
1.281 + bool can_create = true;
1.282 + for (unsigned int i=0; i<num; i++)
1.283 + {
1.284 + can_create = SM_ExecuteConfig(plugin, plugin->GetConfig(i), can_create);
1.285 + }
1.286 + iter->NextPlugin();
1.287 + }
1.288 + iter->Release();
1.289 +
1.290 + engine->ServerCommand("sm internal 1\n");
1.291 +}
1.292 +
1.293 +void SM_ConfigsExecuted_Global()
1.294 +{
1.295 + if (g_bConfigsExecd)
1.296 + {
1.297 + return;
1.298 + }
1.299 +
1.300 + g_bConfigsExecd = true;
1.301 +
1.302 + g_pOnServerCfg->Execute(NULL);
1.303 + g_pOnConfigsExecuted->Execute(NULL);
1.304 +}