diff --git a/amxmodx/AMBuilder b/amxmodx/AMBuilder index f959ed90..0c85a3fa 100644 --- a/amxmodx/AMBuilder +++ b/amxmodx/AMBuilder @@ -98,6 +98,7 @@ binary.sources = [ 'CGameConfigs.cpp', 'gameconfigs.cpp', 'CoreConfig.cpp', + 'commandline.cpp', ] if builder.target_platform == 'windows': diff --git a/amxmodx/amxmodx.h b/amxmodx/amxmodx.h index 08fd8b21..e2a4ecc0 100755 --- a/amxmodx/amxmodx.h +++ b/amxmodx/amxmodx.h @@ -73,6 +73,7 @@ extern AMX_NATIVE_INFO g_StackNatives[]; extern AMX_NATIVE_INFO g_TextParserNatives[]; extern AMX_NATIVE_INFO g_CvarNatives[]; extern AMX_NATIVE_INFO g_GameConfigNatives[]; +extern AMX_NATIVE_INFO g_CommandLineNatives[]; #if defined PLATFORM_WINDOWS #define DLLOAD(path) (DLHANDLE)LoadLibrary(path) diff --git a/amxmodx/commandline.cpp b/amxmodx/commandline.cpp new file mode 100644 index 00000000..c2c93245 --- /dev/null +++ b/amxmodx/commandline.cpp @@ -0,0 +1,100 @@ +#include "amxmodx.h" + +#define CHECK_COMMANDLINE_AVAILABILITY() \ + if (!IsCommandLineAvailable()) \ + { \ + LogError(amx, AMX_ERR_NATIVE, "The command line is not available."); \ + return 0; \ + } + +static bool IsCommandLineAvailable() +{ + return g_engfuncs.pfnCheckParm != nullptr; +} + +// native bool:IsCommandLineAvailable(); +static cell AMX_NATIVE_CALL IsCommandLineAvailable(AMX *amx, cell *params) +{ + return static_cast(IsCommandLineAvailable()); +} + +// native bool:FindCommandLineParam(const param[]); +static cell AMX_NATIVE_CALL FindCommandLineParam(AMX *amx, cell *params) +{ + enum {arg_count, arg_param}; + + CHECK_COMMANDLINE_AVAILABILITY(); + + int length; + const char *param = get_amxstring(amx, params[arg_param], 0, length); + if (length == 0) + { + return 0; + } + return g_engfuncs.pfnCheckParm(param, nullptr); +} + +// native GetCommandLineParam(const param[], value[], maxlen, const defaultValue[]); +static cell AMX_NATIVE_CALL GetCommandLineParam(AMX *amx, cell *params) +{ + enum {arg_count, arg_param, arg_value, arg_maxlen, arg_defaultValue}; + + CHECK_COMMANDLINE_AVAILABILITY(); + + int length; + char *value; + const char *param = get_amxstring(amx, params[arg_param], 0, length); + if (length == 0 || !g_engfuncs.pfnCheckParm(param, &value)) + { + return set_amxstring(amx, params[arg_value], get_amxstring(amx, params[arg_defaultValue], 0, length), params[arg_maxlen]); + } + + return set_amxstring(amx, params[arg_value], value, params[arg_maxlen]); +} + +// native GetCommandLineParamInt(const param[], defaultValue); +static cell AMX_NATIVE_CALL GetCommandLineParamInt(AMX *amx, cell *params) +{ + enum {arg_count, arg_param, arg_defaultValue}; + + CHECK_COMMANDLINE_AVAILABILITY(); + + int length; + char *value; + const char *param = get_amxstring(amx, params[arg_param], 0, length); + if (length == 0 || !g_engfuncs.pfnCheckParm(param, &value)) + { + return params[arg_defaultValue]; + } + + return atoi(value); +} + +// native Float:GetCommandLineParamFloat(const param[], Float:defaultValue); +static cell AMX_NATIVE_CALL GetCommandLineParamFloat(AMX *amx, cell *params) +{ + enum {arg_count, arg_param, arg_defaultValue}; + + CHECK_COMMANDLINE_AVAILABILITY(); + + int length; + char *value; + const char *param = get_amxstring(amx, params[arg_param], 0, length); + if (length == 0 || !g_engfuncs.pfnCheckParm(param, &value)) + { + return params[arg_defaultValue]; + } + + float fValue = atof(value); + return amx_ftoc(fValue); +} + +AMX_NATIVE_INFO g_CommandLineNatives[] = +{ + {"IsCommandLineAvailable", IsCommandLineAvailable }, + {"FindCommandLineParam", FindCommandLineParam }, + {"GetCommandLineParam", GetCommandLineParam }, + {"GetCommandLineParamInt", GetCommandLineParamInt }, + {"GetCommandLineParamFloat", GetCommandLineParamFloat}, + {nullptr, nullptr} +}; diff --git a/amxmodx/modules.cpp b/amxmodx/modules.cpp index 60d14b85..3c36c5b1 100755 --- a/amxmodx/modules.cpp +++ b/amxmodx/modules.cpp @@ -533,6 +533,7 @@ int set_amxnatives(AMX* amx, char error[128]) amx_Register(amx, g_TextParserNatives, -1); amx_Register(amx, g_CvarNatives, -1); amx_Register(amx, g_GameConfigNatives, -1); + amx_Register(amx, g_CommandLineNatives, -1); //we're not actually gonna check these here anymore amx->flags |= AMX_FLAG_PRENIT; diff --git a/plugins/include/amxmodx.inc b/plugins/include/amxmodx.inc index 304d578f..46c78009 100755 --- a/plugins/include/amxmodx.inc +++ b/plugins/include/amxmodx.inc @@ -31,6 +31,7 @@ #include #include #include +#include /** * Called just after server activation. diff --git a/plugins/include/commandline.inc b/plugins/include/commandline.inc new file mode 100644 index 00000000..8c348e94 --- /dev/null +++ b/plugins/include/commandline.inc @@ -0,0 +1,55 @@ +#if defined _commandline_included + #endinput +#endif +#define _commandline_included + + +/** + * Determines if the command line can be queried for parameters. + * + * @note If this returns false other CommandLine natives will throw an error when used. + * + * @return True if the command line is available; otherwise, false. + */ +native bool:IsCommandLineAvailable(); + +/** + * Determines if a specific command line parameter is present. + * + * @param param The command line parameter to test. + * @return True if the command line parameter is specified; otherwise, false. + * @error If the command line is not available. + */ +native bool:FindCommandLineParam(const param[]); + +/** + * Gets the value of a command line parameter the server was launched with. + * + * @param param The command line parameter to get the value of. + * @param value Buffer to store the parameter value in. + * @param maxlen Maximum length of the value buffer. + * @param defaultValue The default value to return if the parameter wasn't specified. + * @return Number of characters written to value buffer. + * @error If the command line is not available. + */ +native GetCommandLineParam(const param[], value[], maxlen, const defaultValue[] = ""); + +/** + * Gets the integer value of a command line parameter the server was launched with. + * + * @param param The command line parameter to get the value of. + * @param defaultValue The default value to return if the parameter wasn't specified. + * @return The integer value of the command line parameter value. + * @error If the command line is not available. + */ +native GetCommandLineParamInt(const param[], defaultValue = 0); + +/** + * Gets the floating point value of a command line parameter the server was launched with. + * + * @param param The command line parameter to get the value of. + * @param defaultValue The default value to return if the parameter wasn't specified. + * @return The floating point value of the command line parameter value. + * @error If the command line is not available. + */ +native Float:GetCommandLineParamFloat(const param[], Float:defaultValue = 0.0);