Merge pull request #266 from Arkshine/feature/autoexeccfg
Introduce automatic config file for plugins and two forwards
This commit is contained in:
		| @@ -96,6 +96,7 @@ binary.sources = [ | ||||
|   'CLibrarySys.cpp', | ||||
|   'CGameConfigs.cpp', | ||||
|   'gameconfigs.cpp', | ||||
|   'CoreConfig.cpp', | ||||
| ] | ||||
|  | ||||
| if builder.target_platform == 'windows': | ||||
|   | ||||
| @@ -14,6 +14,7 @@ | ||||
| #include "natives.h" | ||||
| #include "debugger.h" | ||||
| #include "libraries.h" | ||||
| #include <amxmodx_version.h> | ||||
|  | ||||
| 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) | ||||
| { | ||||
| 	List<plcache_entry *>::iterator iter; | ||||
|   | ||||
| @@ -14,6 +14,7 @@ | ||||
| #include "amx.h" | ||||
| #include "amxxfile.h" | ||||
| #include <am-string.h> | ||||
| #include <am-vector.h> | ||||
|  | ||||
| // ***************************************************** | ||||
| // class CPluginMngr | ||||
| @@ -29,6 +30,13 @@ enum | ||||
| 	ps_running,	//Plugin is running | ||||
| }; | ||||
|  | ||||
| struct AutoConfig | ||||
| { | ||||
| 	ke::AString autocfg; | ||||
| 	ke::AString folder; | ||||
| 	bool create; | ||||
| }; | ||||
|  | ||||
| class CPluginMngr | ||||
| { | ||||
| public: | ||||
| @@ -63,6 +71,7 @@ public: | ||||
| 		bool m_Debug; | ||||
| 		cell* m_pNullStringOfs; | ||||
| 		cell* m_pNullVectorOfs; | ||||
| 		ke::Vector<ke::AutoPtr<AutoConfig>> m_configs; | ||||
| 	public: | ||||
| 		inline const char* getName() { return name.chars();} | ||||
| 		inline const char* getVersion() { return version.chars();} | ||||
| @@ -94,6 +103,10 @@ public: | ||||
| 		inline bool isDebug() const { return m_Debug; } | ||||
| 		inline cell* getNullStringOfs() const { return m_pNullStringOfs; } | ||||
| 		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:	 | ||||
|   | ||||
							
								
								
									
										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; | ||||
| } | ||||
|  | ||||
| CvarsList* CvarManager::GetCvarsList() | ||||
| { | ||||
| 	return &m_Cvars; | ||||
| } | ||||
|  | ||||
| ke::AutoString convertFlagsToString(int flags) | ||||
| { | ||||
| 	ke::AutoString flagsName; | ||||
|   | ||||
| @@ -153,6 +153,7 @@ class CvarManager | ||||
| 		void          SetCvarMax(CvarInfo* info, bool set, float value, int pluginId); | ||||
|  | ||||
| 		size_t    GetRegCvarsCount(); | ||||
| 		CvarsList* GetCvarsList(); | ||||
|  | ||||
| 		void      OnConsoleCommand(); | ||||
| 		void      OnPluginUnloaded(); | ||||
|   | ||||
| @@ -18,8 +18,6 @@ | ||||
| #include "CFlagManager.h" | ||||
| #include "nongpl_matches.h" | ||||
| #include "format.h" | ||||
| #include <amxmodx_version.h> | ||||
| #include "CEvent.h" | ||||
|  | ||||
| extern CFlagManager FlagMan; | ||||
| ke::Vector<CAdminData *> DynamicAdmins; | ||||
| @@ -1918,6 +1916,8 @@ static cell AMX_NATIVE_CALL server_cmd(AMX *amx, cell *params) /* 1 param */ | ||||
|  | ||||
| 	SERVER_COMMAND(cmd); | ||||
|  | ||||
| 	CoreCfg.CheckLegacyBufferedCommand(cmd); | ||||
| 	 | ||||
| 	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)); | ||||
| }; | ||||
|  | ||||
| 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) | ||||
| { | ||||
| 	return 1; | ||||
| @@ -4677,6 +4709,7 @@ AMX_NATIVE_INFO amxmodx_Natives[] = | ||||
| 	{"SetGlobalTransTarget",	SetGlobalTransTarget}, | ||||
| 	{"PrepareArray",			PrepareArray}, | ||||
| 	{"ShowSyncHudMsg",			ShowSyncHudMsg}, | ||||
| 	{"AutoExecConfig",			AutoExecConfig}, | ||||
| 	{"is_rukia_a_hag",			is_rukia_a_hag}, | ||||
| 	{NULL,						NULL} | ||||
| }; | ||||
|   | ||||
| @@ -50,6 +50,8 @@ | ||||
| #include "fakemeta.h" | ||||
| #include "amxxlog.h" | ||||
| #include "CvarManager.h" | ||||
| #include "CoreConfig.h" | ||||
| #include <amxmodx_version.h> | ||||
|  | ||||
| #define AMXXLOG_Log g_log.Log | ||||
| #define AMXXLOG_Error g_log.LogError | ||||
|   | ||||
| @@ -31,6 +31,7 @@ | ||||
| #include "CGameConfigs.h" | ||||
| #include <engine_strucs.h> | ||||
| #include <CDetour/detours.h> | ||||
| #include "CoreConfig.h" | ||||
|  | ||||
| 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_ChangeLevel = registerForward("server_changelevel", ET_STOP, FP_STRING, FP_DONE); | ||||
|  | ||||
| 	CoreCfg.OnAmxxInitialized(); | ||||
|  | ||||
| #if defined BINLOG_ENABLED | ||||
| 	if (!g_BinLog.Open()) | ||||
| 	{ | ||||
| @@ -628,6 +631,11 @@ void C_ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax) | ||||
| 	executeForwards(FF_PluginInit); | ||||
| 	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) | ||||
| 	if (!g_bmod_dod) | ||||
| 		g_game_timeleft = 0; | ||||
| @@ -692,6 +700,9 @@ void C_ServerDeactivate_Post() | ||||
| 	modules_callPluginsUnloading(); | ||||
| 	 | ||||
| 	detachReloadModules(); | ||||
|  | ||||
| 	CoreCfg.Clear(); | ||||
|  | ||||
| 	g_auth.clear(); | ||||
| 	g_commands.clear(); | ||||
| 	g_forcemodels.clear(); | ||||
| @@ -1187,6 +1198,8 @@ void C_StartFrame_Post(void) | ||||
| 	g_task_time = gpGlobals->time + 0.1f; | ||||
| 	g_tasksMngr.startFrame(); | ||||
|  | ||||
| 	CoreCfg.OnMapConfigTimer(); | ||||
|  | ||||
| 	RETURN_META(MRES_IGNORED); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -262,6 +262,7 @@ | ||||
|     <ClCompile Include="..\CMenu.cpp" /> | ||||
|     <ClCompile Include="..\CMisc.cpp" /> | ||||
|     <ClCompile Include="..\CModule.cpp" /> | ||||
|     <ClCompile Include="..\CoreConfig.cpp" /> | ||||
|     <ClCompile Include="..\CPlugin.cpp" /> | ||||
|     <ClCompile Include="..\CTask.cpp" /> | ||||
|     <ClCompile Include="..\CTextParsers.cpp" /> | ||||
| @@ -348,6 +349,7 @@ | ||||
|     <ClInclude Include="..\CMenu.h" /> | ||||
|     <ClInclude Include="..\CMisc.h" /> | ||||
|     <ClInclude Include="..\CModule.h" /> | ||||
|     <ClInclude Include="..\CoreConfig.h" /> | ||||
|     <ClInclude Include="..\CPlugin.h" /> | ||||
|     <ClInclude Include="..\CQueue.h" /> | ||||
|     <ClInclude Include="..\CTask.h" /> | ||||
|   | ||||
| @@ -288,6 +288,9 @@ | ||||
|     <ClCompile Include="..\gameconfigs.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\CoreConfig.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClInclude Include="..\amx.h"> | ||||
| @@ -494,6 +497,9 @@ | ||||
|     <ClInclude Include="..\gameconfigs.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="..\CoreConfig.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ResourceCompile Include="..\version.rc"> | ||||
|   | ||||
| @@ -83,7 +83,6 @@ public plugin_init() | ||||
| 	new configsDir[64] | ||||
| 	get_configsdir(configsDir, charsmax(configsDir)) | ||||
|  | ||||
| 	server_cmd("exec %s/amxx.cfg", configsDir)	// Execute main configuration file | ||||
| 	server_cmd("exec %s/sql.cfg", configsDir) | ||||
|  | ||||
| 	// Create a vector of 5 cells to store the info. | ||||
| @@ -351,45 +350,6 @@ AddAdmin(id, auth[], accessflags[], password[], flags[], comment[]="") | ||||
| 	SQL_FreeHandle(info) | ||||
| #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[]) | ||||
|   | ||||
| @@ -3190,5 +3190,47 @@ native admins_flush(); | ||||
|  */ | ||||
| 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 | ||||
| #include <message_stocks> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user