From 1bc342a6926a7ea96f7c72482cb1a67744a997be Mon Sep 17 00:00:00 2001 From: KAWAI Date: Fri, 29 May 2020 13:37:40 +0300 Subject: [PATCH] Public vars for plugin data (#714) * Add public vars for plugin data and small refactoring get_xvar_id native * Add new command to display info about the plugin and add url to amxx plugins command * Add optional args to register_plugin native (url, description) * Add enum of args for register_plugin native * Creating a variable inside an if statement (C++17) * Displaying the URL of the plugin if it is present * Getting an ID only with more than three arguments * Creating a variable inside an if statement (C++17) * Fix typo * Revert "Creating a variable inside an if statement (C++17)" This reverts commit 835e0bc6c413f11b1bbf964daea87b57f653f5d7. * Revert "Creating a variable inside an if statement (C++17)" This reverts commit b2c1e7c77576c02a00c8c3f103457000d3298ceb. * Revert "Displaying the URL of the plugin if it is present" This reverts commit 9e31230368449966d16635c696d97c04adadeaa9. * Binary compatibility for previously compiled plugins * Displaying the URL of the plugin if it is present * Quotation marks replaced by square brackets and change arg name to id * Fix getting url * The 'atoi' function replaced to 'stoi' * Add likely/unlikely defines for using built-in function provided by GCC * Small fixes with auto and inconsistent var name * Replace stoi to strtol function * Removed explicit buffer id * Revert "Add likely/unlikely defines for using built-in function provided by GCC" This reverts commit 94cee479ed245b98195501466850d01a3f08fd13. * Add url and description params to get_plugin function --- amxmodx/CPlugin.cpp | 27 +++++++++++++ amxmodx/CPlugin.h | 6 +++ amxmodx/amxmodx.cpp | 77 ++++++++++++++++++++++++------------- amxmodx/srvcmd.cpp | 52 ++++++++++++++++++++++++- plugins/include/amxmodx.inc | 11 ++++-- 5 files changed, 141 insertions(+), 32 deletions(-) diff --git a/amxmodx/CPlugin.cpp b/amxmodx/CPlugin.cpp index 93058a7d..c1fb5939 100755 --- a/amxmodx/CPlugin.cpp +++ b/amxmodx/CPlugin.cpp @@ -160,6 +160,32 @@ int CPluginMngr::loadPluginsFromFile(const char* filename, bool warn) set_amxstring(plugin->getAMX(), addr, STRING(gpGlobals->mapname), MAX_MAPNAME_LENGTH - 1); } + auto length = 0; + if (amx_FindPubVar(plugin->getAMX(), "PluginName", &addr) != AMX_ERR_NOTFOUND) + { + plugin->setTitle(get_amxstring(plugin->getAMX(), addr, 0, length)); + } + + if (amx_FindPubVar(plugin->getAMX(), "PluginVersion", &addr) != AMX_ERR_NOTFOUND) + { + plugin->setVersion(get_amxstring(plugin->getAMX(), addr, 0, length)); + } + + if (amx_FindPubVar(plugin->getAMX(), "PluginAuthor", &addr) != AMX_ERR_NOTFOUND) + { + plugin->setAuthor(get_amxstring(plugin->getAMX(), addr, 0, length)); + } + + if (amx_FindPubVar(plugin->getAMX(), "PluginURL", &addr) != AMX_ERR_NOTFOUND) + { + plugin->setUrl(get_amxstring(plugin->getAMX(), addr, 0, length)); + } + + if (amx_FindPubVar(plugin->getAMX(), "PluginDescription", &addr) != AMX_ERR_NOTFOUND) + { + plugin->setDescription(get_amxstring(plugin->getAMX(), addr, 0, length)); + } + if (amx_FindPubVar(plugin->getAMX(), "NULL_STRING", &addr) != AMX_ERR_NOTFOUND) { plugin->m_pNullStringOfs = get_amxaddr(plugin->getAMX(), addr); @@ -281,6 +307,7 @@ CPluginMngr::CPlugin::CPlugin(int i, const char* p, const char* n, char* e, size title = unk; author = unk; version = unk; + url = unk; char file[PLATFORM_MAX_PATH]; char* path = build_pathname_r(file, sizeof(file), "%s/%s", p, n); diff --git a/amxmodx/CPlugin.h b/amxmodx/CPlugin.h index 849ce4ca..0ad53f58 100755 --- a/amxmodx/CPlugin.h +++ b/amxmodx/CPlugin.h @@ -56,6 +56,8 @@ public: ke::AString version; ke::AString title; ke::AString author; + ke::AString url; + ke::AString description; ke::AString errorMsg; unsigned int failcounter; @@ -78,6 +80,8 @@ public: inline const char* getVersion() { return version.chars();} inline const char* getTitle() { return title.chars();} inline const char* getAuthor() { return author.chars();} + inline const char* getUrl() { return url.chars(); } + inline const char* getDescription() { return description.chars(); } inline const char* getError() { return errorMsg.chars();} inline int getStatusCode() { return status; } inline int getId() const { return id; } @@ -86,6 +90,8 @@ public: inline void setTitle(const char* n) { title = n; } inline void setAuthor(const char* n) { author =n; } inline void setVersion(const char* n) { version = n; } + inline void setUrl(const char* n) { url = n; } + inline void setDescription(const char* n) { description = n; } inline void setError(const char* n) { errorMsg = n; } inline bool isValid() const { return (status >= ps_paused); } inline bool isPaused() const { return ((status == ps_paused) || (status == ps_stopped)); } diff --git a/amxmodx/amxmodx.cpp b/amxmodx/amxmodx.cpp index 098bce53..55914ec1 100755 --- a/amxmodx/amxmodx.cpp +++ b/amxmodx/amxmodx.cpp @@ -23,15 +23,30 @@ extern CFlagManager FlagMan; ke::Vector DynamicAdmins; +const char *g_sInaccessibleXVars[] = +{ + "MaxClients", + "MapName", + "PluginName", + "PluginVersion", + "PluginAuthor", + "PluginURL", + "NULL_STRING", + "NULL_VECTOR" +}; + static cell AMX_NATIVE_CALL get_xvar_id(AMX *amx, cell *params) { int len; char* sName = get_amxstring(amx, params[1], 0, len); cell ptr; - if (!strcmp(sName, "MaxClients") || !strcmp(sName, "MapName") || !strcmp(sName, "NULL_STRING") || !strcmp(sName, "NULL_VECTOR")) + for (auto name : g_sInaccessibleXVars) { - return -1; + if (!strcmp(sName, name)) + { + return -1; + } } for (CPluginMngr::iterator a = g_plugins.begin(); a ; ++a) @@ -1433,29 +1448,34 @@ static cell AMX_NATIVE_CALL show_menu(AMX *amx, cell *params) /* 3 param */ return 1; } -static cell AMX_NATIVE_CALL register_plugin(AMX *amx, cell *params) /* 3 param */ +static cell AMX_NATIVE_CALL register_plugin(AMX *amx, cell *params) /* 5 param */ { + enum { arg_count, arg_title, arg_version, arg_author, arg_url, arg_description }; + CPluginMngr::CPlugin* a = g_plugins.findPluginFast(amx); int i; - char *title = get_amxstring(amx, params[1], 0, i); - char *vers = get_amxstring(amx, params[2], 1, i); - char *author = get_amxstring(amx, params[3], 2, i); + + a->setTitle(get_amxstring(amx, params[arg_title], 0, i)); + a->setVersion(get_amxstring(amx, params[arg_version], 0, i)); + a->setAuthor(get_amxstring(amx, params[arg_author], 0, i)); #if defined BINLOG_ENABLED - g_BinLog.WriteOp(BinLog_Registered, a->getId(), title, vers); + g_BinLog.WriteOp(BinLog_Registered, a->getId(), a->getTitle(), a->getVersion()); #endif - a->setTitle(title); - a->setVersion(vers); - a->setAuthor(author); + if (params[arg_count] / sizeof(cell) > arg_author) + { + a->setUrl(get_amxstring(amx, params[arg_url], 0, i)); + a->setDescription(get_amxstring(amx, params[arg_description], 0, i)); + } /* Check if we need to add fail counters */ i = 0; unsigned int counter = 0; while (NONGPL_PLUGIN_LIST[i].author != NULL) { - if (strcmp(NONGPL_PLUGIN_LIST[i].author, author) == 0) + if (strcmp(NONGPL_PLUGIN_LIST[i].author, a->getAuthor()) == 0) { counter++; } @@ -1463,7 +1483,7 @@ static cell AMX_NATIVE_CALL register_plugin(AMX *amx, cell *params) /* 3 param * { counter++; } - if (stricmp(NONGPL_PLUGIN_LIST[i].title, title) == 0) + if (stricmp(NONGPL_PLUGIN_LIST[i].title, a->getTitle()) == 0) { counter++; } @@ -1497,31 +1517,34 @@ static cell AMX_NATIVE_CALL register_menucmd(AMX *amx, cell *params) /* 3 param return 1; } -static cell AMX_NATIVE_CALL get_plugin(AMX *amx, cell *params) /* 11 param */ +static cell AMX_NATIVE_CALL get_plugin(AMX *amx, cell *params) /* 15 param */ { + enum + { + arg_count, arg_plugin, arg_name, arg_namelen, arg_title, arg_titlelen, + arg_version, arg_versionlen, arg_author, arg_authorlen, arg_status, arg_statuslen, + arg_url, arg_urllen, arg_description, arg_descriptionlen + }; + CPluginMngr::CPlugin* a; - if (params[1] < 0) + if (params[arg_plugin] < 0) a = g_plugins.findPluginFast(amx); else - a = g_plugins.findPlugin((int)params[1]); + a = g_plugins.findPlugin((int)params[arg_plugin]); if (a) { - set_amxstring(amx, params[2], a->getName(), params[3]); - set_amxstring(amx, params[4], a->getTitle(), params[5]); - set_amxstring(amx, params[6], a->getVersion(), params[7]); - set_amxstring(amx, params[8], a->getAuthor(), params[9]); - set_amxstring(amx, params[10], a->getStatus(), params[11]); + set_amxstring(amx, params[arg_name], a->getName(), params[arg_namelen]); + set_amxstring(amx, params[arg_title], a->getTitle(), params[arg_titlelen]); + set_amxstring(amx, params[arg_version], a->getVersion(), params[arg_versionlen]); + set_amxstring(amx, params[arg_author], a->getAuthor(), params[arg_authorlen]); + set_amxstring(amx, params[arg_status], a->getStatus(), params[arg_statuslen]); - if (params[0] / sizeof(cell) >= 12) + if (params[arg_count] / sizeof(cell) > arg_url) { - cell *jit_info = get_amxaddr(amx, params[12]); -#if defined AMD64 || !defined JIT - *jit_info = 0; -#else - *jit_info = a->isDebug() ? 0 : 1; -#endif + set_amxstring(amx, params[arg_url], a->getUrl(), params[arg_urllen]); + set_amxstring(amx, params[arg_description], a->getDescription(), params[arg_descriptionlen]); } return a->getId(); diff --git a/amxmodx/srvcmd.cpp b/amxmodx/srvcmd.cpp index 4993ef08..1fa95425 100755 --- a/amxmodx/srvcmd.cpp +++ b/amxmodx/srvcmd.cpp @@ -9,6 +9,7 @@ #include "amxmodx.h" #include +#include void amx_command() { @@ -25,7 +26,7 @@ void amx_command() if (!strcmp(cmd, "plugins") || !strcmp(cmd, "list")) { print_srvconsole("Currently loaded plugins:\n"); - print_srvconsole(" %-23.22s %-11.10s %-17.16s %-16.15s %-9.8s\n", "name", "version", "author", "file", "status"); + print_srvconsole(" %-3.2s %-23.22s %-11.10s %-17.16s %-32.31s %-12.11s %-9.8s\n", "id", "name", "version", "author", "url", "file", "status"); int plugins = 0; int running = 0; @@ -40,7 +41,7 @@ void amx_command() if ((*a).isValid() && !(*a).isPaused()) ++running; - print_srvconsole(" [%3d] %-23.22s %-11.10s %-17.16s %-16.15s %-9.8s\n", plugins, (*a).getTitle(), (*a).getVersion(), (*a).getAuthor(), (*a).getName(), (*a).getStatus()); + print_srvconsole(" [%3d] %-3i %-23.22s %-11.10s %-17.16s %-32.31s %-12.11s %-9.8s\n", plugins, (*a).getId(), (*a).getTitle(), (*a).getVersion(), (*a).getAuthor(), (*a).getUrl(), (*a).getName(), (*a).getStatus()); } ++a; } @@ -63,6 +64,52 @@ void amx_command() print_srvconsole("%d plugins, %d running\n", plugins, running); } + else if (!strcmp(cmd, "plugin")) + { + if (CMD_ARGC() < 3) + { + print_srvconsole("Usage: amxx plugin [ id ]\nFor a list of plugins, use the \"amxx plugins\" command\n"); + } + else + { + char *pEnd; + auto id = strtol(CMD_ARGV(2), &pEnd, 10); + + if (!pEnd) + { + print_srvconsole("Invalid plugin index %i.\n", id); + return; + } + + auto plugin = g_plugins.findPlugin(id); + + if (plugin && plugin->isValid()) + { + print_srvconsole(" Name: %s\n", plugin->getTitle()); + print_srvconsole(" Version: %s\n", plugin->getVersion()); + print_srvconsole(" Author: %s\n", plugin->getAuthor()); + + auto url = plugin->getUrl(); + if (url[0]) + { + print_srvconsole(" URL: %s\n", url); + } + + auto description = plugin->getDescription(); + if (description[0]) + { + print_srvconsole(" Description: %s\n", description); + } + + print_srvconsole(" Filename: %s\n", plugin->getName()); + print_srvconsole(" Status: %s\n", plugin->getStatus()); + } + else + { + print_srvconsole("Plugin index %i not found.\n", id); + } + } + } else if (!strcmp(cmd, "pause") && CMD_ARGC() > 2) { const char* sPlugin = CMD_ARGV(2); @@ -244,6 +291,7 @@ void amx_command() print_srvconsole(" version - display amxx version info\n"); print_srvconsole(" gpl - print the license\n"); print_srvconsole(" plugins [ criteria ] - list plugins currently loaded or ones matching given search criteria\n"); + print_srvconsole(" plugin [ id ] - information about a plugin\n"); print_srvconsole(" modules - list modules currently loaded\n"); print_srvconsole(" cvars [ plugin ] [ index ] - list cvars handled by amxx or show information about a cvar if index is provided\n"); print_srvconsole(" cmds [ plugin ] - list commands registered by plugins\n"); diff --git a/plugins/include/amxmodx.inc b/plugins/include/amxmodx.inc index cfa0faa1..ed1f3ec5 100755 --- a/plugins/include/amxmodx.inc +++ b/plugins/include/amxmodx.inc @@ -243,10 +243,12 @@ forward client_putinserver(id); * @param plugin_name Name of the plugin * @param version Version of the plugin * @param author Author of the plugin + * @param url URL of the plugin + * @param description Description of the plugin * * @return Plugin id of the calling plugin */ -native register_plugin(const plugin_name[], const version[], const author[]); +native register_plugin(const plugin_name[], const version[], const author[], const url[] = "", const description[] = ""); /** * Precaches a model file. @@ -2329,12 +2331,15 @@ native is_plugin_loaded(const name[], bool:usefilename = false); * @param len4 Maximum author buffer size * @param status Buffer to copy plugin status flags to * @param len5 Maximum status buffer size - * @param ... Unused and ignored + * @param url Buffer to copy plugin url to + * @param len6 Maximum url buffer size + * @param desc Buffer to copy plugin description to + * @param len7 Maximum description buffer size * * @return Plugin index on success, -1 if there is no plugin with given * index */ -native get_plugin(index, filename[] = "", len1 = 0, name[] = "", len2 = 0, version[] = "", len3 = 0, author[] = "", len4 = 0, status[] = "", len5 = 0, ...); +native get_plugin(index, filename[] = "", len1 = 0, name[] = "", len2 = 0, version[] = "", len3 = 0, author[] = "", len4 = 0, status[] = "", len5 = 0, url[] = "", len6 = 0, desc[] = "", len7 = 0); /** * Returns the number of loaded AMXX plugins.