Merge pull request #266 from Arkshine/feature/autoexeccfg
Introduce automatic config file for plugins and two forwards
This commit is contained in:
commit
224239f5a1
|
@ -96,6 +96,7 @@ binary.sources = [
|
||||||
'CLibrarySys.cpp',
|
'CLibrarySys.cpp',
|
||||||
'CGameConfigs.cpp',
|
'CGameConfigs.cpp',
|
||||||
'gameconfigs.cpp',
|
'gameconfigs.cpp',
|
||||||
|
'CoreConfig.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
if builder.target_platform == 'windows':
|
if builder.target_platform == 'windows':
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "natives.h"
|
#include "natives.h"
|
||||||
#include "debugger.h"
|
#include "debugger.h"
|
||||||
#include "libraries.h"
|
#include "libraries.h"
|
||||||
|
#include <amxmodx_version.h>
|
||||||
|
|
||||||
extern const char *no_function;
|
extern const char *no_function;
|
||||||
|
|
||||||
|
@ -443,6 +444,49 @@ void CPluginMngr::CPlugin::unpausePlugin()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPluginMngr::CPlugin::AddConfig(bool create, const char *name, const char *folder)
|
||||||
|
{
|
||||||
|
// Do a check for duplicates to prevent double-execution
|
||||||
|
for (size_t i = 0; i < m_configs.length(); ++i)
|
||||||
|
{
|
||||||
|
AutoConfig *config = m_configs[i];
|
||||||
|
|
||||||
|
if (config->autocfg.compare(name) == 0 && config->folder.compare(folder) == 0)
|
||||||
|
{
|
||||||
|
if (!config->create)
|
||||||
|
{
|
||||||
|
config->create = create;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto c = new AutoConfig;
|
||||||
|
|
||||||
|
c->autocfg = name;
|
||||||
|
c->folder = folder;
|
||||||
|
c->create = create;
|
||||||
|
|
||||||
|
m_configs.append(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t CPluginMngr::CPlugin::GetConfigCount()
|
||||||
|
{
|
||||||
|
return m_configs.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoConfig *CPluginMngr::CPlugin::GetConfig(size_t i)
|
||||||
|
{
|
||||||
|
if (i >= GetConfigCount())
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_configs[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
char *CPluginMngr::ReadIntoOrFromCache(const char *file, size_t &bufsize)
|
char *CPluginMngr::ReadIntoOrFromCache(const char *file, size_t &bufsize)
|
||||||
{
|
{
|
||||||
List<plcache_entry *>::iterator iter;
|
List<plcache_entry *>::iterator iter;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "amx.h"
|
#include "amx.h"
|
||||||
#include "amxxfile.h"
|
#include "amxxfile.h"
|
||||||
#include <am-string.h>
|
#include <am-string.h>
|
||||||
|
#include <am-vector.h>
|
||||||
|
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class CPluginMngr
|
// class CPluginMngr
|
||||||
|
@ -29,6 +30,13 @@ enum
|
||||||
ps_running, //Plugin is running
|
ps_running, //Plugin is running
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AutoConfig
|
||||||
|
{
|
||||||
|
ke::AString autocfg;
|
||||||
|
ke::AString folder;
|
||||||
|
bool create;
|
||||||
|
};
|
||||||
|
|
||||||
class CPluginMngr
|
class CPluginMngr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -63,6 +71,7 @@ public:
|
||||||
bool m_Debug;
|
bool m_Debug;
|
||||||
cell* m_pNullStringOfs;
|
cell* m_pNullStringOfs;
|
||||||
cell* m_pNullVectorOfs;
|
cell* m_pNullVectorOfs;
|
||||||
|
ke::Vector<ke::AutoPtr<AutoConfig>> m_configs;
|
||||||
public:
|
public:
|
||||||
inline const char* getName() { return name.chars();}
|
inline const char* getName() { return name.chars();}
|
||||||
inline const char* getVersion() { return version.chars();}
|
inline const char* getVersion() { return version.chars();}
|
||||||
|
@ -94,6 +103,10 @@ public:
|
||||||
inline bool isDebug() const { return m_Debug; }
|
inline bool isDebug() const { return m_Debug; }
|
||||||
inline cell* getNullStringOfs() const { return m_pNullStringOfs; }
|
inline cell* getNullStringOfs() const { return m_pNullStringOfs; }
|
||||||
inline cell* getNullVectorOfs() const { return m_pNullVectorOfs; }
|
inline cell* getNullVectorOfs() const { return m_pNullVectorOfs; }
|
||||||
|
public:
|
||||||
|
void AddConfig(bool create, const char *name, const char *folder);
|
||||||
|
size_t GetConfigCount();
|
||||||
|
AutoConfig *GetConfig(size_t index);
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
333
amxmodx/CoreConfig.cpp
Normal file
333
amxmodx/CoreConfig.cpp
Normal file
|
@ -0,0 +1,333 @@
|
||||||
|
// vim: set ts=4 sw=4 tw=99 noet:
|
||||||
|
//
|
||||||
|
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
|
||||||
|
// Copyright (C) The AMX Mod X Development Team.
|
||||||
|
//
|
||||||
|
// This software is licensed under the GNU General Public License, version 3 or higher.
|
||||||
|
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
||||||
|
// https://alliedmods.net/amxmodx-license
|
||||||
|
|
||||||
|
#include "amxmodx.h"
|
||||||
|
#include "CoreConfig.h"
|
||||||
|
#include "CLibrarySys.h"
|
||||||
|
#include <amxmodx_version.h>
|
||||||
|
|
||||||
|
CoreConfig CoreCfg;
|
||||||
|
|
||||||
|
const char *MainConfigFile = "amxx.cfg";
|
||||||
|
const char *AutoConfigDir = "/plugins";
|
||||||
|
const char *MapConfigDir = "/maps";
|
||||||
|
const char *CommandFormat = "exec %s\n";
|
||||||
|
|
||||||
|
CoreConfig::CoreConfig()
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
CoreConfig::~CoreConfig()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreConfig::OnAmxxInitialized()
|
||||||
|
{
|
||||||
|
m_ConfigsBufferedForward = registerForward("OnAutoConfigsBuffered", ET_IGNORE, FP_DONE);
|
||||||
|
m_ConfigsExecutedForward = registerForward("OnConfigsExecuted", ET_IGNORE, FP_DONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreConfig::Clear()
|
||||||
|
{
|
||||||
|
m_ConfigsExecuted = false;
|
||||||
|
m_PendingForwardPush = false;
|
||||||
|
m_LegacyMainConfigExecuted = false;
|
||||||
|
m_LegacyMapConfigsExecuted = false,
|
||||||
|
m_legacyMapConfigNextTime = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreConfig::ExecuteMainConfig()
|
||||||
|
{
|
||||||
|
if (m_LegacyMainConfigExecuted)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char path[PLATFORM_MAX_PATH];
|
||||||
|
char command[PLATFORM_MAX_PATH + sizeof(CommandFormat)];
|
||||||
|
|
||||||
|
UTIL_Format(path, sizeof(path), "%s/%s/%s", g_mod_name.chars(), get_localinfo("amx_configdir", "addons/amxmodx/configs"), MainConfigFile);
|
||||||
|
UTIL_Format(command, sizeof(command), CommandFormat, path);
|
||||||
|
|
||||||
|
SERVER_COMMAND(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreConfig::ExecuteAutoConfigs()
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < static_cast<size_t>(g_plugins.getPluginsNum()); ++i)
|
||||||
|
{
|
||||||
|
auto plugin = g_plugins.findPlugin(i);
|
||||||
|
|
||||||
|
bool can_create = true;
|
||||||
|
|
||||||
|
for (size_t j = 0; j < plugin->GetConfigCount(); ++j)
|
||||||
|
{
|
||||||
|
can_create = ExecuteAutoConfig(plugin, plugin->GetConfig(j), can_create);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
executeForwards(m_ConfigsBufferedForward);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CoreConfig::ExecuteAutoConfig(CPluginMngr::CPlugin *plugin, AutoConfig *config, bool can_create)
|
||||||
|
{
|
||||||
|
bool will_create = false;
|
||||||
|
|
||||||
|
const char *configsDir = get_localinfo("amx_configdir", "addons/amxmodx/configs");
|
||||||
|
|
||||||
|
if (can_create && config->create)
|
||||||
|
{
|
||||||
|
will_create = true;
|
||||||
|
|
||||||
|
const char *folder = config->folder.chars();
|
||||||
|
|
||||||
|
char path[PLATFORM_MAX_PATH];
|
||||||
|
char build[PLATFORM_MAX_PATH];
|
||||||
|
|
||||||
|
build_pathname_r(path, sizeof(path), "%s%s/%s", configsDir, AutoConfigDir, folder);
|
||||||
|
|
||||||
|
if (!g_LibSys.IsPathDirectory(path))
|
||||||
|
{
|
||||||
|
char *cur_ptr = path;
|
||||||
|
|
||||||
|
g_LibSys.PathFormat(path, sizeof(path), "%s", folder);
|
||||||
|
build_pathname_r(build, sizeof(build), "%s%s", configsDir, AutoConfigDir);
|
||||||
|
|
||||||
|
size_t length = strlen(build);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
char *next_ptr = cur_ptr;
|
||||||
|
|
||||||
|
while (*next_ptr != '\0')
|
||||||
|
{
|
||||||
|
if (*next_ptr == PLATFORM_SEP_CHAR)
|
||||||
|
{
|
||||||
|
*next_ptr = '\0';
|
||||||
|
next_ptr++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
next_ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*next_ptr == '\0')
|
||||||
|
{
|
||||||
|
next_ptr = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
length += g_LibSys.PathFormat(&build[length], sizeof(build) - length, "/%s", cur_ptr);
|
||||||
|
|
||||||
|
if (!g_LibSys.CreateFolder(build))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_ptr = next_ptr;
|
||||||
|
|
||||||
|
} while (cur_ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char file[PLATFORM_MAX_PATH];
|
||||||
|
|
||||||
|
if (config->folder.length())
|
||||||
|
{
|
||||||
|
UTIL_Format(file, sizeof(file), "%s/%s%s/%s/%s.cfg", g_mod_name.chars(), configsDir, AutoConfigDir, config->folder.chars(), config->autocfg.chars());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UTIL_Format(file, sizeof(file), "%s/%s%s/%s.cfg", g_mod_name.chars(), configsDir, AutoConfigDir, config->autocfg.chars());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool file_exists = g_LibSys.IsPathFile(file);
|
||||||
|
|
||||||
|
if (!file_exists && will_create)
|
||||||
|
{
|
||||||
|
auto list = g_CvarManager.GetCvarsList();
|
||||||
|
|
||||||
|
if (list->empty())
|
||||||
|
{
|
||||||
|
return can_create;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *fp = fopen(file, "wt");
|
||||||
|
|
||||||
|
if (fp)
|
||||||
|
{
|
||||||
|
fprintf(fp, "// This file was auto-generated by AMX Mod X (v%s)\n", AMXX_VERSION);
|
||||||
|
|
||||||
|
if (*plugin->getTitle() && *plugin->getAuthor() && *plugin->getVersion())
|
||||||
|
{
|
||||||
|
fprintf(fp, "// Cvars for plugin \"%s\" by \"%s\" (%s, v%s)\n", plugin->getTitle(), plugin->getAuthor(), plugin->getName(), plugin->getVersion());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(fp, "// Cvars for plugin \"%s\"\n", plugin->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp, "\n\n");
|
||||||
|
|
||||||
|
for (auto iter = list->begin(); iter != list->end(); iter++)
|
||||||
|
{
|
||||||
|
auto info = (*iter);
|
||||||
|
|
||||||
|
if (info->pluginId == plugin->getId())
|
||||||
|
{
|
||||||
|
char description[255];
|
||||||
|
char *ptr = description;
|
||||||
|
|
||||||
|
// Print comments until there is no more
|
||||||
|
strncopy(description, info->description.chars(), sizeof(description));
|
||||||
|
|
||||||
|
while (*ptr != '\0')
|
||||||
|
{
|
||||||
|
// Find the next line
|
||||||
|
char *next_ptr = ptr;
|
||||||
|
|
||||||
|
while (*next_ptr != '\0')
|
||||||
|
{
|
||||||
|
if (*next_ptr == '\n')
|
||||||
|
{
|
||||||
|
*next_ptr = '\0';
|
||||||
|
next_ptr++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
next_ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp, "// %s\n", ptr);
|
||||||
|
|
||||||
|
ptr = next_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp, "// -\n");
|
||||||
|
fprintf(fp, "// Default: \"%s\"\n", info->defaultval.chars());
|
||||||
|
|
||||||
|
if (info->bound.hasMin)
|
||||||
|
{
|
||||||
|
fprintf(fp, "// Minimum: \"%02f\"\n", info->bound.minVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info->bound.hasMax)
|
||||||
|
{
|
||||||
|
fprintf(fp, "// Maximum: \"%02f\"\n", info->bound.maxVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp, "%s \"%s\"\n", info->var->name, info->defaultval.chars());
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
|
||||||
|
file_exists = true;
|
||||||
|
can_create = false;
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AMXXLOG_Error("Failed to auto generate config for %s, make sure the directory has write permission.", plugin->getName());
|
||||||
|
return can_create;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_exists)
|
||||||
|
{
|
||||||
|
char command[PLATFORM_MAX_PATH + sizeof(CommandFormat)];
|
||||||
|
UTIL_Format(command, sizeof(command), CommandFormat, file);
|
||||||
|
|
||||||
|
SERVER_COMMAND(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
return can_create;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreConfig::ExecuteMapConfig()
|
||||||
|
{
|
||||||
|
const char *configsDir = get_localinfo("amx_configdir", "addons/amxmodx/configs");
|
||||||
|
|
||||||
|
char cfgPath[PLATFORM_MAX_PATH];
|
||||||
|
char mapName[PLATFORM_MAX_PATH];
|
||||||
|
char command[PLATFORM_MAX_PATH + sizeof(CommandFormat)];
|
||||||
|
|
||||||
|
strncopy(mapName, STRING(gpGlobals->mapname), sizeof(mapName));
|
||||||
|
|
||||||
|
char *mapPrefix;
|
||||||
|
|
||||||
|
if ((mapPrefix = strtok(mapName, "_")))
|
||||||
|
{
|
||||||
|
UTIL_Format(cfgPath, sizeof(cfgPath), "%s/%s%s/prefix_%s.cfg", g_mod_name.chars(), configsDir, MapConfigDir, mapPrefix);
|
||||||
|
|
||||||
|
if (g_LibSys.IsPathFile(cfgPath))
|
||||||
|
{
|
||||||
|
UTIL_Format(command, sizeof(command), CommandFormat, cfgPath);
|
||||||
|
SERVER_COMMAND(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strncopy(mapName, STRING(gpGlobals->mapname), sizeof(mapName));
|
||||||
|
UTIL_Format(cfgPath, sizeof(cfgPath), "%s/%s%s/%s.cfg", g_mod_name.chars(), configsDir, MapConfigDir, mapName);
|
||||||
|
|
||||||
|
if (g_LibSys.IsPathFile(cfgPath))
|
||||||
|
{
|
||||||
|
UTIL_Format(command, sizeof(command), CommandFormat, cfgPath);
|
||||||
|
SERVER_COMMAND(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consider all configs be executed to the next frame.
|
||||||
|
m_PendingForwardPush = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CoreConfig::OnMapConfigTimer()
|
||||||
|
{
|
||||||
|
if (m_ConfigsExecuted)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_PendingForwardPush)
|
||||||
|
{
|
||||||
|
m_PendingForwardPush = false;
|
||||||
|
m_ConfigsExecuted = true;
|
||||||
|
|
||||||
|
executeForwards(m_ConfigsExecutedForward);
|
||||||
|
}
|
||||||
|
else if (!m_LegacyMapConfigsExecuted && m_legacyMapConfigNextTime <= gpGlobals->time)
|
||||||
|
{
|
||||||
|
ExecuteMapConfig();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreConfig::CheckLegacyBufferedCommand(char *command)
|
||||||
|
{
|
||||||
|
if (m_ConfigsExecuted)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_LegacyMainConfigExecuted && strstr(command, MainConfigFile))
|
||||||
|
{
|
||||||
|
m_LegacyMainConfigExecuted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_LegacyMapConfigsExecuted && strstr(command, MapConfigDir))
|
||||||
|
{
|
||||||
|
m_LegacyMapConfigsExecuted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreConfig::SetMapConfigTimer(float time)
|
||||||
|
{
|
||||||
|
m_legacyMapConfigNextTime = gpGlobals->time + time;
|
||||||
|
}
|
51
amxmodx/CoreConfig.h
Normal file
51
amxmodx/CoreConfig.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
// vim: set ts=4 sw=4 tw=99 noet:
|
||||||
|
//
|
||||||
|
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
|
||||||
|
// Copyright (C) The AMX Mod X Development Team.
|
||||||
|
//
|
||||||
|
// This software is licensed under the GNU General Public License, version 3 or higher.
|
||||||
|
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
||||||
|
// https://alliedmods.net/amxmodx-license
|
||||||
|
|
||||||
|
#ifndef _CORE_CONFIG_H_
|
||||||
|
#define _CORE_CONFIG_H_
|
||||||
|
|
||||||
|
#include "CPlugin.h"
|
||||||
|
|
||||||
|
class CoreConfig
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
CoreConfig();
|
||||||
|
~CoreConfig();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
void ExecuteMainConfig();
|
||||||
|
void ExecuteAutoConfigs();
|
||||||
|
bool ExecuteAutoConfig(CPluginMngr::CPlugin *plugin, AutoConfig *config, bool can_create);
|
||||||
|
void ExecuteMapConfig();
|
||||||
|
|
||||||
|
void OnAmxxInitialized();
|
||||||
|
void OnMapConfigTimer();
|
||||||
|
|
||||||
|
void CheckLegacyBufferedCommand(char *command);
|
||||||
|
void SetMapConfigTimer(float time);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool m_ConfigsExecuted; // Whether all configs have been executed
|
||||||
|
bool m_PendingForwardPush; // Whether OnConfigsExecuted forward should be triggered to the next frame
|
||||||
|
bool m_LegacyMainConfigExecuted; // Whether the old admin.sma is used and amxx.cfg was executed from there
|
||||||
|
bool m_LegacyMapConfigsExecuted; // Whether the old admin.sma is used and per-map config was executed from there
|
||||||
|
float m_legacyMapConfigNextTime; // Sets the next time that per-map configs should be executed
|
||||||
|
|
||||||
|
int m_ConfigsBufferedForward;
|
||||||
|
int m_ConfigsExecutedForward;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern CoreConfig CoreCfg;
|
||||||
|
|
||||||
|
#endif // _CORE_CONFIG_H_
|
|
@ -442,6 +442,11 @@ size_t CvarManager::GetRegCvarsCount()
|
||||||
return m_AmxmodxCvars;
|
return m_AmxmodxCvars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CvarsList* CvarManager::GetCvarsList()
|
||||||
|
{
|
||||||
|
return &m_Cvars;
|
||||||
|
}
|
||||||
|
|
||||||
ke::AutoString convertFlagsToString(int flags)
|
ke::AutoString convertFlagsToString(int flags)
|
||||||
{
|
{
|
||||||
ke::AutoString flagsName;
|
ke::AutoString flagsName;
|
||||||
|
|
|
@ -153,6 +153,7 @@ class CvarManager
|
||||||
void SetCvarMax(CvarInfo* info, bool set, float value, int pluginId);
|
void SetCvarMax(CvarInfo* info, bool set, float value, int pluginId);
|
||||||
|
|
||||||
size_t GetRegCvarsCount();
|
size_t GetRegCvarsCount();
|
||||||
|
CvarsList* GetCvarsList();
|
||||||
|
|
||||||
void OnConsoleCommand();
|
void OnConsoleCommand();
|
||||||
void OnPluginUnloaded();
|
void OnPluginUnloaded();
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
#include "CFlagManager.h"
|
#include "CFlagManager.h"
|
||||||
#include "nongpl_matches.h"
|
#include "nongpl_matches.h"
|
||||||
#include "format.h"
|
#include "format.h"
|
||||||
#include <amxmodx_version.h>
|
|
||||||
#include "CEvent.h"
|
|
||||||
|
|
||||||
extern CFlagManager FlagMan;
|
extern CFlagManager FlagMan;
|
||||||
ke::Vector<CAdminData *> DynamicAdmins;
|
ke::Vector<CAdminData *> DynamicAdmins;
|
||||||
|
@ -1918,6 +1916,8 @@ static cell AMX_NATIVE_CALL server_cmd(AMX *amx, cell *params) /* 1 param */
|
||||||
|
|
||||||
SERVER_COMMAND(cmd);
|
SERVER_COMMAND(cmd);
|
||||||
|
|
||||||
|
CoreCfg.CheckLegacyBufferedCommand(cmd);
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4484,6 +4484,38 @@ static cell AMX_NATIVE_CALL has_map_ent_class(AMX *amx, cell *params)
|
||||||
return len && !FNullEnt(FIND_ENTITY_BY_STRING(NULL, "classname", name));
|
return len && !FNullEnt(FIND_ENTITY_BY_STRING(NULL, "classname", name));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL AutoExecConfig(AMX *amx, cell *params)
|
||||||
|
{
|
||||||
|
int length;
|
||||||
|
bool autocreate = params[1] != 0;
|
||||||
|
const char *name = get_amxstring(amx, params[2], 0, length);
|
||||||
|
const char *folder = get_amxstring(amx, params[3], 1, length);
|
||||||
|
|
||||||
|
auto plugin = g_plugins.findPluginFast(amx);
|
||||||
|
|
||||||
|
if (*name == '\0')
|
||||||
|
{
|
||||||
|
char pluginName[PLATFORM_MAX_PATH];
|
||||||
|
strncopy(pluginName, plugin->getName(), sizeof(pluginName));
|
||||||
|
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
if ((ptr = strstr(pluginName, ".amxx")))
|
||||||
|
{
|
||||||
|
*ptr = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static char newName[PLATFORM_MAX_PATH];
|
||||||
|
UTIL_Format(newName, sizeof(newName), "plugin.%s", pluginName);
|
||||||
|
|
||||||
|
name = newName;
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin->AddConfig(autocreate, name, folder);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL is_rukia_a_hag(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL is_rukia_a_hag(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -4677,6 +4709,7 @@ AMX_NATIVE_INFO amxmodx_Natives[] =
|
||||||
{"SetGlobalTransTarget", SetGlobalTransTarget},
|
{"SetGlobalTransTarget", SetGlobalTransTarget},
|
||||||
{"PrepareArray", PrepareArray},
|
{"PrepareArray", PrepareArray},
|
||||||
{"ShowSyncHudMsg", ShowSyncHudMsg},
|
{"ShowSyncHudMsg", ShowSyncHudMsg},
|
||||||
|
{"AutoExecConfig", AutoExecConfig},
|
||||||
{"is_rukia_a_hag", is_rukia_a_hag},
|
{"is_rukia_a_hag", is_rukia_a_hag},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
|
@ -50,6 +50,8 @@
|
||||||
#include "fakemeta.h"
|
#include "fakemeta.h"
|
||||||
#include "amxxlog.h"
|
#include "amxxlog.h"
|
||||||
#include "CvarManager.h"
|
#include "CvarManager.h"
|
||||||
|
#include "CoreConfig.h"
|
||||||
|
#include <amxmodx_version.h>
|
||||||
|
|
||||||
#define AMXXLOG_Log g_log.Log
|
#define AMXXLOG_Log g_log.Log
|
||||||
#define AMXXLOG_Error g_log.LogError
|
#define AMXXLOG_Error g_log.LogError
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "CGameConfigs.h"
|
#include "CGameConfigs.h"
|
||||||
#include <engine_strucs.h>
|
#include <engine_strucs.h>
|
||||||
#include <CDetour/detours.h>
|
#include <CDetour/detours.h>
|
||||||
|
#include "CoreConfig.h"
|
||||||
|
|
||||||
plugin_info_t Plugin_info =
|
plugin_info_t Plugin_info =
|
||||||
{
|
{
|
||||||
|
@ -504,6 +505,8 @@ int C_Spawn(edict_t *pent)
|
||||||
FF_ClientAuthorized = registerForward("client_authorized", ET_IGNORE, FP_CELL, FP_DONE);
|
FF_ClientAuthorized = registerForward("client_authorized", ET_IGNORE, FP_CELL, FP_DONE);
|
||||||
FF_ChangeLevel = registerForward("server_changelevel", ET_STOP, FP_STRING, FP_DONE);
|
FF_ChangeLevel = registerForward("server_changelevel", ET_STOP, FP_STRING, FP_DONE);
|
||||||
|
|
||||||
|
CoreCfg.OnAmxxInitialized();
|
||||||
|
|
||||||
#if defined BINLOG_ENABLED
|
#if defined BINLOG_ENABLED
|
||||||
if (!g_BinLog.Open())
|
if (!g_BinLog.Open())
|
||||||
{
|
{
|
||||||
|
@ -628,6 +631,11 @@ void C_ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax)
|
||||||
executeForwards(FF_PluginInit);
|
executeForwards(FF_PluginInit);
|
||||||
executeForwards(FF_PluginCfg);
|
executeForwards(FF_PluginCfg);
|
||||||
|
|
||||||
|
CoreCfg.ExecuteMainConfig(); // Execute amxx.cfg
|
||||||
|
CoreCfg.ExecuteAutoConfigs(); // Execute configs created with AutoExecConfig native.
|
||||||
|
CoreCfg.SetMapConfigTimer(6.1); // Prepare per-map configs to be executed 6.1 seconds later.
|
||||||
|
// Original value which was used in admin.sma.
|
||||||
|
|
||||||
// Correct time in Counter-Strike and other mods (except DOD)
|
// Correct time in Counter-Strike and other mods (except DOD)
|
||||||
if (!g_bmod_dod)
|
if (!g_bmod_dod)
|
||||||
g_game_timeleft = 0;
|
g_game_timeleft = 0;
|
||||||
|
@ -692,6 +700,9 @@ void C_ServerDeactivate_Post()
|
||||||
modules_callPluginsUnloading();
|
modules_callPluginsUnloading();
|
||||||
|
|
||||||
detachReloadModules();
|
detachReloadModules();
|
||||||
|
|
||||||
|
CoreCfg.Clear();
|
||||||
|
|
||||||
g_auth.clear();
|
g_auth.clear();
|
||||||
g_commands.clear();
|
g_commands.clear();
|
||||||
g_forcemodels.clear();
|
g_forcemodels.clear();
|
||||||
|
@ -1187,6 +1198,8 @@ void C_StartFrame_Post(void)
|
||||||
g_task_time = gpGlobals->time + 0.1f;
|
g_task_time = gpGlobals->time + 0.1f;
|
||||||
g_tasksMngr.startFrame();
|
g_tasksMngr.startFrame();
|
||||||
|
|
||||||
|
CoreCfg.OnMapConfigTimer();
|
||||||
|
|
||||||
RETURN_META(MRES_IGNORED);
|
RETURN_META(MRES_IGNORED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -262,6 +262,7 @@
|
||||||
<ClCompile Include="..\CMenu.cpp" />
|
<ClCompile Include="..\CMenu.cpp" />
|
||||||
<ClCompile Include="..\CMisc.cpp" />
|
<ClCompile Include="..\CMisc.cpp" />
|
||||||
<ClCompile Include="..\CModule.cpp" />
|
<ClCompile Include="..\CModule.cpp" />
|
||||||
|
<ClCompile Include="..\CoreConfig.cpp" />
|
||||||
<ClCompile Include="..\CPlugin.cpp" />
|
<ClCompile Include="..\CPlugin.cpp" />
|
||||||
<ClCompile Include="..\CTask.cpp" />
|
<ClCompile Include="..\CTask.cpp" />
|
||||||
<ClCompile Include="..\CTextParsers.cpp" />
|
<ClCompile Include="..\CTextParsers.cpp" />
|
||||||
|
@ -348,6 +349,7 @@
|
||||||
<ClInclude Include="..\CMenu.h" />
|
<ClInclude Include="..\CMenu.h" />
|
||||||
<ClInclude Include="..\CMisc.h" />
|
<ClInclude Include="..\CMisc.h" />
|
||||||
<ClInclude Include="..\CModule.h" />
|
<ClInclude Include="..\CModule.h" />
|
||||||
|
<ClInclude Include="..\CoreConfig.h" />
|
||||||
<ClInclude Include="..\CPlugin.h" />
|
<ClInclude Include="..\CPlugin.h" />
|
||||||
<ClInclude Include="..\CQueue.h" />
|
<ClInclude Include="..\CQueue.h" />
|
||||||
<ClInclude Include="..\CTask.h" />
|
<ClInclude Include="..\CTask.h" />
|
||||||
|
|
|
@ -288,6 +288,9 @@
|
||||||
<ClCompile Include="..\gameconfigs.cpp">
|
<ClCompile Include="..\gameconfigs.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\CoreConfig.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\amx.h">
|
<ClInclude Include="..\amx.h">
|
||||||
|
@ -494,6 +497,9 @@
|
||||||
<ClInclude Include="..\gameconfigs.h">
|
<ClInclude Include="..\gameconfigs.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\CoreConfig.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="..\version.rc">
|
<ResourceCompile Include="..\version.rc">
|
||||||
|
|
|
@ -83,7 +83,6 @@ public plugin_init()
|
||||||
new configsDir[64]
|
new configsDir[64]
|
||||||
get_configsdir(configsDir, charsmax(configsDir))
|
get_configsdir(configsDir, charsmax(configsDir))
|
||||||
|
|
||||||
server_cmd("exec %s/amxx.cfg", configsDir) // Execute main configuration file
|
|
||||||
server_cmd("exec %s/sql.cfg", configsDir)
|
server_cmd("exec %s/sql.cfg", configsDir)
|
||||||
|
|
||||||
// Create a vector of 5 cells to store the info.
|
// Create a vector of 5 cells to store the info.
|
||||||
|
@ -351,45 +350,6 @@ AddAdmin(id, auth[], accessflags[], password[], flags[], comment[]="")
|
||||||
SQL_FreeHandle(info)
|
SQL_FreeHandle(info)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
|
||||||
public plugin_cfg()
|
|
||||||
{
|
|
||||||
set_task(6.1, "delayed_load")
|
|
||||||
}
|
|
||||||
|
|
||||||
public delayed_load()
|
|
||||||
{
|
|
||||||
new configFile[128], curMap[64], configDir[128]
|
|
||||||
|
|
||||||
get_configsdir(configDir, charsmax(configDir))
|
|
||||||
get_mapname(curMap, charsmax(curMap))
|
|
||||||
|
|
||||||
new i=0;
|
|
||||||
|
|
||||||
while (curMap[i] != '_' && curMap[i++] != '^0') {/*do nothing*/}
|
|
||||||
|
|
||||||
if (curMap[i]=='_')
|
|
||||||
{
|
|
||||||
// this map has a prefix
|
|
||||||
curMap[i]='^0';
|
|
||||||
formatex(configFile, charsmax(configFile), "%s/maps/prefix_%s.cfg", configDir, curMap);
|
|
||||||
|
|
||||||
if (file_exists(configFile))
|
|
||||||
{
|
|
||||||
server_cmd("exec %s", configFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get_mapname(curMap, charsmax(curMap))
|
|
||||||
|
|
||||||
|
|
||||||
formatex(configFile, charsmax(configFile), "%s/maps/%s.cfg", configDir, curMap)
|
|
||||||
|
|
||||||
if (file_exists(configFile))
|
|
||||||
{
|
|
||||||
server_cmd("exec %s", configFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadSettings(szFilename[])
|
loadSettings(szFilename[])
|
||||||
|
|
|
@ -3190,5 +3190,47 @@ native admins_flush();
|
||||||
*/
|
*/
|
||||||
native bool:has_map_ent_class(const classname[]);
|
native bool:has_map_ent_class(const classname[]);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the map has loaded, and all configs are done executing.
|
||||||
|
* This includes servercfgfile (server.cfg), amxx.cfg, plugin's config, and
|
||||||
|
* per-map config.
|
||||||
|
*
|
||||||
|
* @note This is best place to initialize plugin functions which are based on cvar data.
|
||||||
|
* @note This will always be called once and only once per map. It will be
|
||||||
|
* called few seconds after plugin_cfg().
|
||||||
|
*
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
forward OnConfigsExecuted();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the map has loaded, right after plugin_cfg() but any time
|
||||||
|
* before OnConfigsExecuted. It's called after amxx.cfg and all
|
||||||
|
* AutoExecConfig() exec commands have been added to the server command buffer.
|
||||||
|
*
|
||||||
|
* @note This will always be called once and only once per map.
|
||||||
|
*
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
forward OnAutoConfigsBuffered();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies that the given config file should be executed after plugin load.
|
||||||
|
*
|
||||||
|
* @note OnConfigsExecuted() will not be called until the config file has executed,
|
||||||
|
* but it will be called if the execution fails.
|
||||||
|
*
|
||||||
|
* @param autoCreate If true, and the config file does not exist, such a config
|
||||||
|
* file will be automatically created and populated with
|
||||||
|
* information from the plugin's registered cvars.
|
||||||
|
* @param name Name of the config file, excluding the .cfg extension.
|
||||||
|
* If empty, <plugin.filename.cfg> is assumed.
|
||||||
|
* @param folder Folder under plugins/ to use.
|
||||||
|
*
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native AutoExecConfig(bool:autoCreate = true, const name[] = "", const folder[] = "");
|
||||||
|
|
||||||
// Always keep this at the bottom of this file
|
// Always keep this at the bottom of this file
|
||||||
#include <message_stocks>
|
#include <message_stocks>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user