From f3ca920e1dff6932af342910816d56abfa7d5461 Mon Sep 17 00:00:00 2001 From: Alienmario Date: Sat, 20 Jul 2024 14:56:00 +0200 Subject: [PATCH] Add CI --- .github/workflows/plugin.yml | 44 + scripting/include/system2.inc | 462 ++++++++++ scripting/include/system2/legacy.inc | 284 +++++++ scripting/include/system2/request.inc | 944 +++++++++++++++++++++ scripting/{includes => include}/webcon.inc | 0 5 files changed, 1734 insertions(+) create mode 100644 .github/workflows/plugin.yml create mode 100644 scripting/include/system2.inc create mode 100644 scripting/include/system2/legacy.inc create mode 100644 scripting/include/system2/request.inc rename scripting/{includes => include}/webcon.inc (100%) diff --git a/.github/workflows/plugin.yml b/.github/workflows/plugin.yml new file mode 100644 index 0000000..cad5a40 --- /dev/null +++ b/.github/workflows/plugin.yml @@ -0,0 +1,44 @@ +name: CI + +on: [push, pull_request, workflow_dispatch] + +jobs: + build: + name: "Build" + runs-on: ubuntu-latest + strategy: + fail-fast: false + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Setup sourcemod compiler + id: setup-sp + uses: rumblefrog/setup-sp@master + with: + version: '1.12.7031' + + - name: Compile plugins + run: | + mkdir -p plugins + for file in scripting/*.sp + do + plugin="$(basename "${file%.*}")" + echo -e "\nCompiling $plugin\n" + spcomp -v2 -i scripting/include -o plugins/"$plugin" "$file" + done + + - name: Create package + run: | + OUT="/tmp/build" + SM="${OUT}/addons/sourcemod" + mkdir -p $SM + cp -R plugins $SM + cp -R scripting $SM + + - name: Upload package + uses: actions/upload-artifact@v4 + with: + name: sfdlr-${{ github.run_number }} + path: /tmp/build/ \ No newline at end of file diff --git a/scripting/include/system2.inc b/scripting/include/system2.inc new file mode 100644 index 0000000..91d03e1 --- /dev/null +++ b/scripting/include/system2.inc @@ -0,0 +1,462 @@ +/** + * ----------------------------------------------------- + * File system2.inc + * Authors David Ordnung + * License GPLv3 + * Web http://dordnung.de + * ----------------------------------------------------- + * + * Copyright (C) 2013-2020 David Ordnung + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + */ + +#if defined _system2_included + #endinput +#endif + +#define _system2_included + +// Include request stuff +#include + + +/** + * Max length of a command when using formatted natives. + */ +#define CMD_MAX_LENGTH 2048 + + +/** + * A list of possible compression levels for the System2_Compress native. + */ +enum CompressLevel +{ + LEVEL_1, // Weekest + LEVEL_3, + LEVEL_5, + LEVEL_7, + LEVEL_9 // Strongest +} + + +/** + * A list of possible archive formats for the System2_Compress native. + */ +enum CompressArchive +{ + ARCHIVE_ZIP, + ARCHIVE_7Z, + ARCHIVE_GZIP, + ARCHIVE_BZIP2, + ARCHIVE_TAR +} + + +/** + * A list of possible operating systems for the System2_GetOS native. + */ +enum OS +{ + OS_UNKNOWN, // OS couldn't be determined + OS_WINDOWS, // Windows + OS_UNIX, // Linux / Unix + OS_MAC // MAC +} + + + +/** + * Called when finished with the System2_CopyFile native. + * + * @param success Whether copying was successful (will fail if couldn't open 'from' or 'to' file). + * @param from Path to file that was copied. + * @param to Path to the new copied file. + * @param data Data passed to the copy native. + * + * @noreturn + */ +typeset System2CopyCallback +{ + function void (bool success, const char[] from, const char[] to, any data); + function void (bool success, const char[] from, const char[] to); +}; + + +/** + * Called when finished with System2_ExecuteThreaded or System2_ExecuteFormattedThreaded native. + * The output will only be valid in the callback and will be destroyed afterwards. + * + * @param success Whether the execution was successful or not. + * This not means that the command itself was successful! + * Check the ExitStatus of the output for this. + * @param command The executed command. + * @param output Output of the execution. Is null if success is false. + * Can't be deleted, as it will be destroyed after the callback! + * @param data Data passed to the execution native. + * + * @noreturn + */ +typeset System2ExecuteCallback +{ + function void (bool success, const char[] command, System2ExecuteOutput output, any data); + function void (bool success, const char[] command, System2ExecuteOutput output); +}; + + + +/** + * Methodmap for the output of an execution. + */ +methodmap System2ExecuteOutput < Handle { + /** + * Retrieves the output of the command execution. + * + * @param output Buffer to store the output in. + * @param maxlength Maxlength of the output buffer. + * @param start Start byte to start reading from. + * You can use this to retrieve the output step by step. + * @param delimiter Delimiter until which the content should be retrieved. + * @param include Whether the delimiter should be included or not. + * + * @return Number of read bytes. + * @error Invalid Output. + */ + public native int GetOutput(char[] output, int maxlength, int start = 0, const char[] delimiter = "", bool include = true); + + property int Length { + /** + * Returns the length of the complete output. + * + * @return Length of the output. + * @error Invalid Output. + */ + public native get(); + } + + property int ExitStatus { + /** + * Returns the exit status of the execution. + * + * @return The exit status. + * @error Invalid Output. + */ + public native get(); + } +} + + + +/** + * Copies a file to another location. + * + * @param callback Callback function when finished with copying. + * @param from Path to the file to copy. + * @param to Path to the file to copy to (including filename). File will be replaced if it exists. + * @param data Additional data to pass to the callback. + * + * @noreturn + */ +native void System2_CopyFile(System2CopyCallback callback, const char[] from, const char[] to, any data = 0); + + +/** + * Checks whether 7-ZIP was found and is executable. + * + * @param execPath Buffer which will store the path to the 7-ZIP executable. + * Can be used for example when showing an error message. + * @param maxlength Maxlength of the buffer. + * @param force32Bit Whether to force using the 32 bit version of 7-ZIP, otherwise the appropriate version will be used. + * + * @return True if 7-ZIP executable could be found and is executable, otherwise false. + */ +native bool System2_Check7ZIP(char[] execPath, int maxlength, bool force32Bit = false); + +/** + * Compresses a file or folder to an archive. + * + * @param callback Callback function when finished with compressing. + * @param path Path to the file / folder to compress. + * @param archive Path to the archive file to compress to (including filename). + * @param archiveType Archive type to use. + * @param level Compress level to use. + * @param data Additional data to pass to the callback. + * @param force32Bit Whether to force using the 32 bit version of 7-ZIP, otherwise the appropriate version will be used. + * + * @return True if compress command could be fired, false when 7-ZIP executable couldn't be found or is not executable. + */ +native bool System2_Compress(System2ExecuteCallback callback, const char[] path, const char[] archive, CompressArchive archiveType = ARCHIVE_ZIP, CompressLevel level = LEVEL_9, any data = 0, bool force32Bit = false); + +/** + * Extracts a lot of archive types with 7zip. + * + * @param callback Callback function when finished with extracting. + * @param archive Path to the archive file to extract. + * @param extractDir Path to the directory to extract to. + * @param data Additional data to pass to the callback. + * @param force32Bit Whether to force using the 32 bit version of 7-ZIP, otherwise the appropriate version will be used. + * + * @return True if extract command could be fired, false when 7-ZIP executable couldn't be found or is not executable. + */ +native bool System2_Extract(System2ExecuteCallback callback, const char[] archive, const char[] extractDir, any data = 0, bool force32Bit = false); + + + +/** + * Executes a threaded system command. + * Hint: Append 2>&1 to your command to retrieve also output to stderr. + * + * @param callback Callback function when command was executed. + * @param command Command to execute. + * @param data Data to pass to the callback. + * + * @noreturn + */ +native void System2_ExecuteThreaded(System2ExecuteCallback callback, const char[] command, any data = 0); + +/** + * Executes a threaded system command with support for a formatted command. + * Note that the maxlength of the command is CMD_MAX_LENGTH, use System2_ExecuteThreaded if you need more. + * Hint: Append 2>&1 to your command to retrieve also output to stderr. + * + * @param callback Callback function when command was executed. + * @param data Data to pass to the callback. + * @param command Command string format. + * @param ... Command string arguments. + * + * @noreturn + */ +native void System2_ExecuteFormattedThreaded(System2ExecuteCallback callback, any data, const char[] command, any ...); + +/** + * Executes a non threaded system command. + * Hint: Append 2>&1 to your command to retrieve also output to stderr. + * + * @param output Buffer to store the output in. + * @param maxlength Maxlength of the output buffer. + * @param command Command to execute. + * + * @return True on success, otherwise false. + */ +native bool System2_Execute(char[] output, int maxlength, const char[] command); + +/** + * Executes a non threaded system command with support for a formatted command. + * Note that the maxlength of the command is CMD_MAX_LENGTH, use System2_Execute if you need more. + * Hint: Append 2>&1 to your command to retrieve also output to stderr. + * + * @param output Buffer to store the output in. + * @param maxlength Maxlength of the output buffer. + * @param command Command string format. + * @param ... Command string arguments. + * + * @return True on success, otherwise false. + */ +native bool System2_ExecuteFormatted(char[] output, int maxlength, const char[] command, any ...); + + + +/** + * Retrieves the absolute path to the gamedir of the current running game (e.g. /home/.../.../cstrike). + * You may need this when executing system commands. + * + * @param gamedir Buffer to store gamedir in. + * @param maxlength Maxlength of the buffer. + * + * @noreturn + */ +native void System2_GetGameDir(char[] gamedir, int maxlength); + +/** + * Returns the server's operating system. + * + * @return OS_UNKNOWN, OS_WINDOWS, OS_UNIX, OS_MAC. + */ +native OS System2_GetOS(); + + + +/** + * Retrieves the MD5 hex hash of a string. + * + * @param string String to retrieve the MD5 hash of. + * @param buffer Buffer to store MD5 hash in. + * @param maxlength Maxlength of the buffer. Should be greater or equal to 33 (32 MD5 + 1 terminator). + * + * @noreturn + */ +native void System2_GetStringMD5(const char[] str, char[] buffer, int maxlength); + +/** + * Retrieves the MD5 hex hash of a files content. + * + * @param file The path to the file. + * @param buffer Buffer to store MD5 hash in. + * @param maxlength Maxlength of the buffer. Should be greater or equal to 33 (32 MD5 + 1 terminator). + * + * @return True on success, false when file couldn't be opened. + */ +native bool System2_GetFileMD5(const char[] file, char[] buffer, int maxlength); + +/** + * Retrieves the CRC32 hex hash of a string. + * + * @param string The string to retrieve the CRC32 hash of. + * @param buffer Buffer to store CRC32 hash in. + * @param maxlength Maxlength of the buffer. Should be greater or equal to 9 (8 CRC32 + 1 terminator). + * + * @noreturn + */ +native void System2_GetStringCRC32(const char[] str, char[] buffer, int maxlength); + +/** + * Retrieves the CRC32 hex hash of a files content. + * + * @param file The path to the file. + * @param buffer Buffer to store CRC32 hash in. + * @param maxlength Maxlength of the buffer. Should be greater or equal to 9 (8 CRC32 + 1 terminator). + * + * @return True on success, false when file couldn't be opened. + */ +native bool System2_GetFileCRC32(const char[] file, char[] buffer, int maxlength); + + +// Include legacy stuff +#include + + +public Extension __ext_system2 = +{ + name = "System2", + file = "system2.ext", + + #if defined AUTOLOAD_EXTENSIONS + autoload = 1, + #else + autoload = 0, + #endif + + #if defined REQUIRE_EXTENSIONS + required = 1, + #else + required = 0, + #endif +}; + + +#if !defined REQUIRE_EXTENSIONS + public void __ext_system2_SetNTVOptional() + { + MarkNativeAsOptional("System2Request.SetURL"); + MarkNativeAsOptional("System2Request.GetURL"); + MarkNativeAsOptional("System2Request.SetPort"); + MarkNativeAsOptional("System2Request.GetPort"); + MarkNativeAsOptional("System2Request.SetOutputFile"); + MarkNativeAsOptional("System2Request.GetOutputFile"); + MarkNativeAsOptional("System2Request.SetVerifySSL"); + MarkNativeAsOptional("System2Request.GetVerifySSL"); + MarkNativeAsOptional("System2Request.SetProxy"); + MarkNativeAsOptional("System2Request.SetProxyAuthentication"); + MarkNativeAsOptional("System2Request.Timeout.get"); + MarkNativeAsOptional("System2Request.Timeout.set"); + MarkNativeAsOptional("System2Request.Any.get"); + MarkNativeAsOptional("System2Request.Any.set"); + + MarkNativeAsOptional("System2HTTPRequest.System2HTTPRequest"); + MarkNativeAsOptional("System2HTTPRequest.SetProgressCallback"); + MarkNativeAsOptional("System2HTTPRequest.SetData"); + MarkNativeAsOptional("System2HTTPRequest.GetData"); + MarkNativeAsOptional("System2HTTPRequest.SetHeader"); + MarkNativeAsOptional("System2HTTPRequest.GetHeader"); + MarkNativeAsOptional("System2HTTPRequest.GetHeaderName"); + MarkNativeAsOptional("System2HTTPRequest.SetUserAgent"); + MarkNativeAsOptional("System2HTTPRequest.SetBasicAuthentication"); + MarkNativeAsOptional("System2HTTPRequest.GET"); + MarkNativeAsOptional("System2HTTPRequest.POST"); + MarkNativeAsOptional("System2HTTPRequest.PUT"); + MarkNativeAsOptional("System2HTTPRequest.PATCH"); + MarkNativeAsOptional("System2HTTPRequest.DELETE"); + MarkNativeAsOptional("System2HTTPRequest.HEAD"); + MarkNativeAsOptional("System2HTTPRequest.FollowRedirects.get"); + MarkNativeAsOptional("System2HTTPRequest.FollowRedirects.set"); + MarkNativeAsOptional("System2HTTPRequest.Headers.get"); + + MarkNativeAsOptional("System2FTPRequest.System2FTPRequest"); + MarkNativeAsOptional("System2FTPRequest.SetProgressCallback"); + MarkNativeAsOptional("System2FTPRequest.SetAuthentication"); + MarkNativeAsOptional("System2FTPRequest.SetInputFile"); + MarkNativeAsOptional("System2FTPRequest.GetInputFile"); + MarkNativeAsOptional("System2FTPRequest.StartRequest"); + MarkNativeAsOptional("System2FTPRequest.AppendToFile.get"); + MarkNativeAsOptional("System2FTPRequest.AppendToFile.set"); + MarkNativeAsOptional("System2FTPRequest.CreateMissingDirs.get"); + MarkNativeAsOptional("System2FTPRequest.CreateMissingDirs.set"); + MarkNativeAsOptional("System2FTPRequest.ListFilenamesOnly.get"); + MarkNativeAsOptional("System2FTPRequest.ListFilenamesOnly.set"); + + MarkNativeAsOptional("System2Response.GetLastURL"); + MarkNativeAsOptional("System2Response.GetContent"); + MarkNativeAsOptional("System2Response.ContentLength.get"); + MarkNativeAsOptional("System2Response.StatusCode.get"); + MarkNativeAsOptional("System2Response.TotalTime.get"); + MarkNativeAsOptional("System2Response.DownloadSize.get"); + MarkNativeAsOptional("System2Response.UploadSize.get"); + MarkNativeAsOptional("System2Response.DownloadSpeed.get"); + MarkNativeAsOptional("System2Response.UploadSpeed.get"); + + MarkNativeAsOptional("System2HTTPResponse.GetContentType"); + MarkNativeAsOptional("System2HTTPResponse.GetHeader"); + MarkNativeAsOptional("System2HTTPResponse.GetHeaderName"); + MarkNativeAsOptional("System2HTTPResponse.GetHeadersCount"); + MarkNativeAsOptional("System2HTTPResponse.HTTPVersion.get"); + MarkNativeAsOptional("System2HTTPResponse.Headers.get"); + + MarkNativeAsOptional("System2_URLEncode"); + MarkNativeAsOptional("System2_URLDecode"); + + MarkNativeAsOptional("System2_CopyFile"); + + MarkNativeAsOptional("System2_Check7ZIP"); + MarkNativeAsOptional("System2_Compress"); + MarkNativeAsOptional("System2_Extract"); + + MarkNativeAsOptional("System2_ExecuteThreaded"); + MarkNativeAsOptional("System2_ExecuteFormattedThreaded"); + MarkNativeAsOptional("System2ExecuteOutput.GetOutput"); + MarkNativeAsOptional("System2ExecuteOutput.Length.get"); + MarkNativeAsOptional("System2ExecuteOutput.ExitStatus.get"); + + MarkNativeAsOptional("System2_Execute"); + MarkNativeAsOptional("System2_ExecuteFormatted"); + + MarkNativeAsOptional("System2_GetGameDir"); + MarkNativeAsOptional("System2_GetOS"); + + MarkNativeAsOptional("System2_GetStringMD5"); + MarkNativeAsOptional("System2_GetFileMD5"); + MarkNativeAsOptional("System2_GetStringCRC32"); + MarkNativeAsOptional("System2_GetFileCRC32"); + + // Deprecated v2 stuff + MarkNativeAsOptional("System2_GetPage"); + MarkNativeAsOptional("System2_DownloadFile"); + MarkNativeAsOptional("System2_DownloadFTPFile"); + MarkNativeAsOptional("System2_UploadFTPFile"); + MarkNativeAsOptional("System2_CompressFile"); + MarkNativeAsOptional("System2_ExtractArchive"); + MarkNativeAsOptional("System2_RunThreadCommand"); + MarkNativeAsOptional("System2_RunThreadCommandWithData"); + MarkNativeAsOptional("System2_RunCommand"); + } +#endif \ No newline at end of file diff --git a/scripting/include/system2/legacy.inc b/scripting/include/system2/legacy.inc new file mode 100644 index 0000000..7827853 --- /dev/null +++ b/scripting/include/system2/legacy.inc @@ -0,0 +1,284 @@ +/** + * ----------------------------------------------------- + * File legacy.inc + * Authors David Ordnung + * License GPLv3 + * Web http://dordnung.de + * ----------------------------------------------------- + * + * Copyright (C) 2013-2020 David Ordnung + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + */ + +#if defined _system2_legacy_included + #endinput +#endif + +#define _system2_legacy_included + + +/** + * + * DEPRECATED v2 STUFF, do not use that anymore! + * + */ + +/** + * Max Size of the command or page output in CmdCallback. + */ +#define CMD_MAX_RETURN 4096 + + +/** + * A list of possible command return states + */ +enum CMDReturn +{ + CMD_SUCCESS, // Fully finished + CMD_EMPTY, // Result is empty (only System2_RunThreadCommand) + CMD_ERROR, // An error appeared + CMD_PROGRESS // Not finished yet -> Wait for other state +} + + +/** + * Called when finished with a command or when retrieving the content of a page. + * Maybe called more than once, if output is greater than 4096 bytes. + * Use status variable to check if it's the last call or not. + * + * @param output Output of the command / page. + * @param size Size of output string. + * @param status CMDReturn status. + * @param data Data passed. + * @param command The command that was executed. Will be empty with PageGet. + */ +typeset CmdCallback +{ + function void (const char[] output, const int size, CMDReturn status, any data, const char[] command); + function void (const char[] output, const int size, CMDReturn status, any data); + function void (const char[] output, const int size, CMDReturn status); +}; + + +/** + * Called on every update when downloading / uploading a file. + * + * @param finished Is downloading / uploading finished? + * @param error Error when finished. If no error string is empty. + * @param dltotal Total downloaded size in bytes. + * @param dlnow Current downloaded size in bytes. + * @param ultotal Total uploaded size in bytes. + * @param ulnow Current uploaded size in bytes. + * @param data Data passed. + */ +typeset TransferUpdated +{ + function void (bool finished, const char[] error, float dltotal, float dlnow, float ultotal, float ulnow, any data); + function void (bool finished, const char[] error, float dltotal, float dlnow, float ultotal, float ulnow); +}; + + +/** + * Gets the content of a page. + * + * @param callback Callback function when finished. Check callback.status to check if process is finished. + * @param url The URL of the page to load. Attach GET parameters here and leave post parameter empty to perform a GET request. + * @param post POST parameters (use like this: "name=test&pw=test2"). Leave empty to perform a GET request. + * @param userAgent Useragent to use. Leave empty for default one. + * @param data Additional data to pass to the callback. + * + * @noreturn + */ +#pragma deprecated Use System2HTTPRequest instead. +native void System2_GetPage(CmdCallback callback, const char[] url, const char[] post = "", const char[] userAgent = "", any data = INVALID_HANDLE); + + +/** + * Downloads a file from an URL. + * + * @param updateFunction Function to call on update. Check updateFunction.finished to check if downloading is finished. + * @param url File URL to download from. + * @param localFile Local file to save to. + * @param data Additional data to pass to the callback. + * + * @noreturn + */ +#pragma deprecated Use System2HTTPRequest instead. +native void System2_DownloadFile(TransferUpdated updateFunction, const char[] url, const char[] localFile, any data = INVALID_HANDLE); + + +/** + * Downloads a file from a FTP server. + * + * @param updateFunction Function to call on update. Check updateFunction.finished to check if downloading is finished. + * @param remoteFile Path to the file on the FTP server. + * @param localFile Local file to save to. + * @param host The FTP host. + * @param user The FTP username. + * @param pass The FTP password. + * @param port The FTP port (Default: 21). + * @param data Additional data to pass to the callback. + * + * @noreturn + */ +#pragma deprecated Use System2FTPRequest instead. +native void System2_DownloadFTPFile(TransferUpdated updateFunction, const char[] remoteFile, const char[] localFile, const char[] host, const char[] user = "", const char[] pass = "", int port = 21, any data = INVALID_HANDLE); + + +/** + * Uploads a file to a FTP server. + * + * @param updateFunction Function to call on update. Check updateFunction.finished to check if uploading is finished. + * @param localFile Local file to upload. + * @param remoteFile Path to the file on the FTP server. + * @param host The FTP host. + * @param user The FTP username. + * @param pass The FTP password. + * @param port The FTP port (Default: 21). + * @param data Additional data to pass to the callback. + * + * @noreturn + */ +#pragma deprecated Use System2FTPRequest instead. +native void System2_UploadFTPFile(TransferUpdated updateFunction, const char[] localFile, const char[] remoteFile, const char[] host, const char[] user = "", const char[] pass = "", int port = 21, any data = INVALID_HANDLE); + + +/** + * Compresses a file to an archive. + * + * @param callback Callback function when finished with compressing. Check callback.status to check if process is finished. + * @param pathToFile Path to the file / folder to compress. + * @param pathToCompress Path to save archive file to (including filename). + * @param archive Archive type to use. + * @param level Archive compress level to use. + * @param data Additional data to pass to the callback. + * + * @noreturn + */ +#pragma deprecated Use System2_Compress instead. +native void System2_CompressFile(CmdCallback callback, const char[] pathToFile, const char[] pathToArchive, CompressArchive archive = ARCHIVE_ZIP, CompressLevel level = LEVEL_9, any data = INVALID_HANDLE); + + +/** + * Extracts a lot of archive types with 7zip. + * + * @param callback Callback function when finished with extracting. Check callback.status to check if process is finished. + * @param pathToArchive Path to the archive file. + * @param pathToExtract Path to extract to. + * @param data Additional data to pass to the callback. + * + * @noreturn + */ +#pragma deprecated Use System2_Extract instead. +native void System2_ExtractArchive(CmdCallback callback, const char[] pathToArchive, const char[] pathToExtract, any data = INVALID_HANDLE); + + +/** + * Executes a threaded system command. + * + * @param callback Callback function when command was executed. Check callback.status to check if process is finished. + * @param command Command string format. + * @param ... Command string arguments. + * + * @noreturn + */ +#pragma deprecated Use System2_ExecuteThreaded instead. +native void System2_RunThreadCommand(CmdCallback callback, const char[] command, any ...); + + +/** + * Executes a threaded system command and allows to pass additional data. + * + * @param callback Callback function when command was executed. Check callback.status to check if process is finished. + * @param data Data to pass to the callback. + * @param command Command string format. + * @param ... Command string arguments. + * + * @noreturn + */ +#pragma deprecated Use System2_ExecuteThreaded instead. +native void System2_RunThreadCommandWithData(CmdCallback callback, any data, const char[] command, any ...); + + +/** + * Executes a non threaded system command. + * + * @param output Variable to store the command output. + * @param size Size of the output variable. + * @param command Command string format. + * @param ... Command string arguments. + * + * @return CMDReturn status. + */ +#pragma deprecated Use System2_Execute instead. +native CMDReturn System2_RunCommand(char[] output, int size, const char[] command, any ...); + + +/** + * Encodes a string for safe url transfer. + * Written by Peace-Maker (i guess), formatted for better readability. + * + * @param stringToEncode The string to encode. + * @param maxlength The maxlength of the string. + * @param safe Adding additional safe strings. + * @param format Is the string formatted. + */ +#pragma deprecated Use System2_URLEncode instead. +stock void URLEncode(char[] stringToEncode, int maxlength, char[] safe = "/", bool format = false) +{ + char sAlwaysSafe[256]; + Format(sAlwaysSafe, sizeof(sAlwaysSafe), "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.-%s", safe); + + // Need 2 '%' since sp's Format parses one as a parameter to replace + // http://wiki.alliedmods.net/Format_Class_Functions_%28SourceMod_Scripting%29 + if (format) + { + ReplaceString(stringToEncode, maxlength, "%", "%%25"); + } + else + { + ReplaceString(stringToEncode, maxlength, "%", "%25"); + } + + + char sChar[8]; + char sReplaceChar[8]; + + for (new int i = 1; i < 256; i++) + { + // Skip the '%' double replace ftw.. + if (i == 37) + { + continue; + } + + + Format(sChar, sizeof(sChar), "%c", i); + + if (StrContains(sAlwaysSafe, sChar) == -1 && StrContains(stringToEncode, sChar) != -1) + { + if (format) + { + Format(sReplaceChar, sizeof(sReplaceChar), "%%%%%02X", i); + } + else + { + Format(sReplaceChar, sizeof(sReplaceChar), "%%%02X", i); + } + + ReplaceString(stringToEncode, maxlength, sChar, sReplaceChar); + } + } +} \ No newline at end of file diff --git a/scripting/include/system2/request.inc b/scripting/include/system2/request.inc new file mode 100644 index 0000000..611a6d5 --- /dev/null +++ b/scripting/include/system2/request.inc @@ -0,0 +1,944 @@ +/** + * ----------------------------------------------------- + * File request.inc + * Authors David Ordnung + * License GPLv3 + * Web http://dordnung.de + * ----------------------------------------------------- + * + * Copyright (C) 2013-2020 David Ordnung + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + */ + +#if defined _system2_request_included + #endinput +#endif + +#define _system2_request_included + + +/** + * + * API for making HTTP and FTP requests. + * + */ + + +/** + * A list of possible HTTP request methods. + */ +enum HTTPRequestMethod +{ + METHOD_GET, + METHOD_POST, + METHOD_PUT, + METHOD_PATCH, + METHOD_DELETE, + METHOD_HEAD +} + +/** + * A list of possible HTTP versions. + */ +enum HTTPVersion +{ + VERSION_NONE, + VERSION_1_0, + VERSION_1_1, + VERSION_2_0 +} + + +/** + * Called when a HTTP request was finished. + * + * The response will only be valid in the callback and will be destroyed afterwards. + * The request is a copy of the original request and will be destroyed afterwards. + * The request can be modified and made again. + * + * @param success Whether the request could made. + * This not means that the request itself was successful, check the StatusCode of the response for that! + * @param error If success is false this will contain the error message. + * @param request A copy of the made HTTP request. + * Can't be deleted, as it will be destroyed after the callback! + * @param response HTTP response of the request. Is null if success is false. + * Can't be deleted, as it will be destroyed after the callback! + * @param method The HTTP request method that was made. + * + * @noreturn + */ +typeset System2HTTPResponseCallback +{ + function void (bool success, const char[] error, System2HTTPRequest request, System2HTTPResponse response, HTTPRequestMethod method); +}; + +/** + * Called when a FTP request was finished. + * + * The response will only be valid in the callback and will be destroyed afterwards. + * The request is a copy of the original request and will be destroyed afterwards. + * The request can be modified and made again. + * + * @param success Whether the request could made. + * This not means that the request itself was successful, check the StatusCode of the response for that! + * @param error If success is false this will contain the error message. + * @param request A copy of the made FTP request. + * Can't be deleted, as it will be destroyed after the callback! + * @param response FTP response of the request. Is null if success is false. + * Can't be deleted, as it will be destroyed after the callback! + * + * @noreturn + */ +typeset System2FTPResponseCallback +{ + function void (bool success, const char[] error, System2FTPRequest request, System2FTPResponse response); +}; + + +/** + * Called on a frequent interval while data of a HTTP request is being transferred. + * The request is a copy of the original request and will be destroyed afterwards. + * + * @param request A copy of the made HTTP request. + * Can't be deleted, as it will be destroyed after the callback! + * @param dlTotal Total expected download size in bytes. + * @param dlNow Downloaded bytes so far. + * @param ulTotal Total expected upload size in bytes. + * @param ulNow Uploaded bytes so far. + * + * @noreturn + */ +typeset System2HTTPProgressCallback +{ + function void (System2HTTPRequest request, int dlTotal, int dlNow, int ulTotal, int ulNow); +}; + +/** + * Called on a frequent interval while data of a FTP request is being transferred. + * The request is a copy of the original request and will be destroyed afterwards. + * + * @param request A copy of the made FTP request. + * Can't be deleted, as it will be destroyed after the callback! + * @param dlTotal Total expected download size in bytes. + * @param dlNow Downloaded bytes so far. + * @param ulTotal Total expected upload size in bytes. + * @param ulNow Uploaded bytes so far. + * + * @noreturn + */ +typeset System2FTPProgressCallback +{ + function void (System2FTPRequest request, int dlTotal, int dlNow, int ulTotal, int ulNow); +}; + + + +/** + * Basic methodmap for a request. + * Use System2HTTPRequest or System2FTPRequest to actually create a request. + */ +methodmap System2Request < Handle { + /** + * Sets the URL of the request. + * Query parameters have to be given directly in the URL. + * + * Must be URL-encoded (use System2_URLEncode) in the following format: + * scheme://host:port/path + * + * Host is a hostname or dotted numerical IP address. A numerical IPv6 address must be written within [brackets]. + * + * If the given URL is missing a scheme name (such as "http://" or "ftp://" etc) + * then system2 will make a guess based on the host. + * + * @param url URL to use for the request. + * @param ... URL format arguments. + * + * @noreturn + * @error Invalid request. + */ + public native void SetURL(const char[] url, any ...); + + /** + * Retrieves the URL of the request. + * + * @param url Buffer to store URL in. + * @param maxlength Maxlength of the buffer. + * + * @noreturn + * @error Invalid request. + */ + public native void GetURL(char[] url, int maxlength); + + /** + * Sets the remote port number to connect to, + * instead of the one specified in the URL or the default port for the used protocol + * + * @param port Port to use for the request. + * + * @noreturn + * @error Invalid request. + * @error Invalid port number. + */ + public native void SetPort(int port); + + /** + * Returns the port of the request. + * + * @return The port of the request or 0 if none set. + * @error Invalid request. + */ + public native int GetPort(); + + /** + * Sets the path to the file to which the output of the request will be written to. + * Use this to download the output of a response to a file. + * + * @param file File to write the output to. + * @param ... File format arguments. + * + * @noreturn + * @error Invalid request. + */ + public native void SetOutputFile(const char[] file, any ...); + + /** + * Retrieves the path to the file to which the output of the request will be written to. + * + * @param file Buffer to store file in. + * @param maxlength Maxlength of the buffer. + * + * @noreturn + * @error Invalid request. + */ + public native void GetOutputFile(char[] file, int maxlength); + + /** + * Sets whether to verify authenticity of the peer's certificate and server cert is for the server it is known as. + * Only disable this, when you know what you do! + * + * @param verify True to verify SSL certificates, otherwise false. + * + * @noreturn + * @error Invalid request. + */ + public native void SetVerifySSL(bool verify); + + /** + * Returns whether SSL certificates will be verified. + * + * @return True if SSL certificates will be verified, otherwise false. + * @error Invalid request. + */ + public native bool GetVerifySSL(); + + /** + * Sets proxy for the request. + * + * @param proxy Hostname or dotted numerical IP address. A numerical IPv6 address must be written within [brackets]. + * To specify port number in this string, append :[port] to the end of the host name (default: 1080). + * The proxy string may be prefixed with [scheme]:// to specify which kind of proxy is used. + * http:// + * HTTP Proxy. Default when no scheme is specified. + * https:// + * HTTPS Proxy. + * socks4:// + * SOCKS4 Proxy. + * socks4a:// + * SOCKS4a Proxy. Proxy resolves URL hostname. + * socks5:// + * SOCKS5 Proxy. + * socks5h:// + * SOCKS5 Proxy. Proxy resolves URL hostname. + * @param useHttpTunnel Tunnel all operations through the HTTP proxy (use http or https)- + * Tunneling means that an HTTP CONNECT request is sent to the proxy, asking it to connect to a remote host + * on a specific port number and then the traffic is just passed through the proxy. Proxies tend to white-list + * specific port numbers it allows CONNECT requests to and often only port 80 and 443 are allowed. + * + * @noreturn + * @error Invalid request. + */ + public native void SetProxy(const char[] proxy, bool useHttpTunnel = false); + + /** + * Sets the username and password to be used in protocol authentication with the proxy. + * + * @param username Username to use for proxy authentication. + * @param password Password to use for proxy authentication. + * + * @noreturn + * @error Invalid request. + */ + public native void SetProxyAuthentication(const char[] username, const char[] password); + + + property int Timeout { + /** + * Returns the timeout for the request. + * By default, there is no timeout. + * + * @return The timeout of the request in seconds or -1 if none set. + * @error Invalid request. + */ + public native get(); + + /** + * Sets the timeout for the request in seconds. + * By default, there is no timeout. + * + * @param seconds The timeout for the request in seconds. 0 to disable. + * + * @noreturn + * @error Invalid request. + * @error Invalid timeout. + */ + public native set(int seconds); + } + + property any Any { + /** + * Returns the any data that was bound to this request. + * + * @return The any data that was bound or 0 if none set. + * @error Invalid request. + */ + public native get(); + + /** + * Sets any data to bind to the request (which you can then use in callbacks). + * + * @param Any The any data to bind. + * + * @noreturn + * @error Invalid request. + */ + public native set(any Any); + } +} + + +/** + * Methodmap to create a HTTP request. + */ +methodmap System2HTTPRequest < System2Request { + /** + * Creates a new HTTP Request. + * + * @param callback Response callback to call when the request is finished. + * @param url URL to use for the request. + * Query parameters have to be given directly in the URL. + * + * Must be URL-encoded (use System2_URLEncode) in the following format: + * scheme://host:port/path + * + * Host is a hostname or dotted numerical IP address. A numerical IPv6 address must be written within [brackets]. + * If no scheme is given, HTTP will be used. + * @param ... URL format arguments. + * + * @noreturn + * @error Couldn't create request. + */ + public native System2HTTPRequest(System2HTTPResponseCallback callback, const char[] url, any ...); + + /** + * Sets the progress callback for the transfer of the request. + * This will be called frequently while data is being transferred. + * This is useful when downloading or uploading stuff. + * + * @param callback Progress callback to call for the transfer. + * + * @noreturn + * @error Invalid request. + */ + public native void SetProgressCallback(System2HTTPProgressCallback callback); + + + /** + * Sets the body data to send with the request. + * You must make sure that the data is formatted the way you want the server to receive it. + * Use System2_URLEncode to encode the data. + * + * For example: parameter=value¶meter2=value2 + * Or with JSON: {"parameter": "value", "parameter2": "value2"} + * + * @param data Body data to send with the request. + * @param ... Data format arguments. + * + * @noreturn + * @error Invalid request. + */ + public native void SetData(const char[] data, any ...); + + /** + * Retrieves the body data of the request. + * + * @param url Buffer to store data in. + * @param maxlength Maxlength of the buffer. + * + * @noreturn + * @error Invalid request. + */ + public native void GetData(char[] data, int maxlength); + + + /** + * Sets a HTTP request header. + * Use System2_URLEncode to encode the header. + * + * @param name Name of the header. + * @param value Value to set the header to. + * @param ... Value format arguments. + * + * @noreturn + * @error Invalid request. + */ + public native void SetHeader(const char[] header, const char[] value, any ...); + + /** + * Retrieves a HTTP request header. + * + * @param name Name of the header to retrieve. + * @param value Buffer to store value in. + * @param maxlength Maxlength of the buffer. + * + * @return True if header was set, otherwise false. + * @error Invalid request. + */ + public native bool GetHeader(const char[] header, char[] value, int maxlength); + + /** + * Retrieves the name of a header at a given index. + * Use Headers property to retrieve the maximum index. + * + * @param index Index of the header name. + * @param name Buffer to store name in. + * @param maxlength Maxlength of the buffer. + * + * @return True if header was found, otherwise false. + * @error Invalid request. + */ + public native bool GetHeaderName(int index, char[] name, int maxlength); + + property int Headers { + /** + * Returns the number of set headers. + * + * @return The number of set headers. + * @error Invalid response. + */ + public native get(); + } + + /** + * Returns all set header names of the request as ArrayList. + * Attention: ArrayList has to be deleted after use! + + * @param maxlength Maxlength of a header. + * + * @return ArrayList with all set request header names. Must be deleted afterwards! + * @error Invalid request. + */ + public ArrayList GetHeaders(int maxlength = 256) { + ArrayList headers = new ArrayList(maxlength); + + char[] headerName = new char[maxlength]; + for (int i=0; i < this.Headers; i++) { + this.GetHeaderName(i, headerName, maxlength); + headers.PushString(headerName); + } + + return headers; + } + + + /** + * Sets the user agent for the request. + * This will set the User-Agent header to the given value. + * + * @param userAgent User agent to use. + * @param ... User agent format arguments. + * + * @noreturn + * @error Invalid request. + */ + public native void SetUserAgent(const char[] userAgent, any ...); + + /** + * Sets basic authentication username and passowrd for the request. + * This will set the Authorization header to the given values. + * + * @param username Username to use for basic authentication. + * @param password Password to use for basic authentication. + * + * @noreturn + * @error Invalid request. + */ + public native void SetBasicAuthentication(const char[] username, const char[] password); + + /** + * Sends the request with the HTTP GET method. + * + * @noreturn + * @error Invalid request. + */ + public native void GET(); + + /** + * Sends the request with the HTTP POST method. + * + * @noreturn + * @error Invalid request. + */ + public native void POST(); + + /** + * Sends the request with the HTTP PUT method. + * + * @noreturn + * @error Invalid request. + */ + public native void PUT(); + + /** + * Sends the request with the HTTP PATCH method. + * + * @noreturn + * @error Invalid request. + */ + public native void PATCH(); + + /** + * Sends the request with the HTTP DELETE method. + * + * @noreturn + * @error Invalid request. + */ + public native void DELETE(); + + /** + * Sends the request with the HTTP HEAD method. + * + * @noreturn + * @error Invalid request. + */ + public native void HEAD(); + + + property bool FollowRedirects { + /** + * Returns whether the request follow redirects or not. + * By default, redirects will be followed. + * + * @return True if it follow redirects, otherwise false. + * @error Invalid request. + */ + public native get(); + + /** + * Sets to follow any Location: header that the server sends as part of an HTTP header in a 3xx response. + * For 301, 302 and 303 responses system2 will switch method to GET. All other 3xx codes will make system2 send the same method again. + * By default, redirects will be followed. + * + * @param follow True to follow redirects, otherwise false. + * + * @noreturn + * @error Invalid request. + */ + public native set(bool follow); + } +} + + +/** + * Methodmap to create a FTP request. + */ +methodmap System2FTPRequest < System2Request { + /** + * Creates a new FTP Request. + * + * @param callback Response callback to call when the request is finished. + * @param url URL to use for the request. + * + * Must be URL-encoded (use System2_URLEncode) in the following format: + * scheme://host:port/path + * + * Host is a hostname or dotted numerical IP address. A numerical IPv6 address must be written within [brackets]. + * If no scheme is given, FTP will be used. + * @param ... URL format arguments. + * + * @noreturn + * @error Couldn't create request. + */ + public native System2FTPRequest(System2FTPResponseCallback callback, const char[] url, any ...); + + /** + * Sets the progress callback for the transfer of the request. + * This will be called frequently while data is being transferred. + * + * @param callback Progress callback to call for the transfer. + * + * @noreturn + * @error Invalid request. + */ + public native void SetProgressCallback(System2FTPProgressCallback callback); + + + /** + * Sets authentication needed to access the FTP server. + * + * @param username Username to use for authentication. + * @param password Password to use for authentication. + * + * @noreturn + * @error Invalid request. + */ + public native void SetAuthentication(const char[] username, const char[] password); + + + /** + * Sets the path to the file which should be uploaded. + * If this is set, an upload approach will be used. + * + * @param file File to upload. + * @param ... File format arguments. + * + * @noreturn + * @error Invalid request. + */ + public native void SetInputFile(const char[] file, any ...); + + /** + * Retrieves the path to the file which should be uploaded. + * + * @param file Buffer to store file in. + * @param maxlength Maxlength of the buffer. + * + * @noreturn + * @error Invalid request. + */ + public native void GetInputFile(char[] file, int maxlength); + + + /** + * Starts the request. + * + * If a input file is set the request will upload this file. + * Otherwise it may result in a directory listing or a file download. + * + * @noreturn + * @error Invalid request. + */ + public native void StartRequest(); + + + property bool AppendToFile { + /** + * Returns whether the request appends to the FTP file or replaces it when uploading a file. + * By default, the file will be replaced. + * + * @return True if it appends to the file, false if the file will be replaced. + * @error Invalid request. + */ + public native get(); + + /** + * Sets whether to append to the FTP file or to replace it when uploading a file. + * By default, the file will be replaced. + * + * @param append True to append to file, false to replace it. + * + * @noreturn + * @error Invalid request. + */ + public native set(bool append); + } + + property bool CreateMissingDirs { + /** + * Returns whether the request creates missing dirs when uploading a file. + * By default, missing dirs will be created. + * + * @return True if it creates missing dirs, otherwise false. + * @error Invalid request. + */ + public native get(); + + /** + * Sets whether to create any remote directory that it fails to "move" into. + * By default, missing dirs will be created. + * + * @param create True to create missing dirs, otherwise false. + * + * @noreturn + * @error Invalid request. + */ + public native set(bool create); + } + + property bool ListFilenamesOnly { + /** + * Returns whether only file names should be fetched for directory listing. + * By default, all information will be fetched. + * + * @return True if only file names should be fetched, false for full directory listing. + * @error Invalid request. + */ + public native get(); + + /** + * Sets whether to list the names of files in a directory, + * rather than performing a full directory listing that would normally include file sizes, dates etc. + * By default, all information will be fetched. + * + * @param append True if only file names should be fetched, false for full directory listing. + * + * @noreturn + * @error Invalid request. + */ + public native set(bool append); + } +} + + + +/** + * Basic methodmap for a response of a request. + */ +methodmap System2Response < Handle { + /** + * Retrieves the last used effective URL. + * This may differ from the request URL, if a redirect was followed. + * + * @param url Buffer to store last URL in. + * @param maxlength Maxlength of the URL buffer. + * + * @noreturn + * @error Invalid response. + */ + public native void GetLastURL(char[] url, int maxlength); + + /** + * Retrieves the content of the response. + * This shouldn't be used when retrieved binary stuff. + * + * @param content Buffer to store the content in. + * @param maxlength Maxlength of the content buffer. + * @param start Start byte to start reading from. + * You can use this to retrieve the content step by step. + * @param delimiter Delimiter until which the content should be retrieved. + * @param include Whether the delimiter should be included or not. + * + * @return Number of read bytes. + * @error Invalid response. + */ + public native int GetContent(char[] content, int maxlength, int start = 0, const char[] delimiter = "", bool include = true); + + + property int ContentLength { + /** + * Returns the length of the complete response content. + * + * @return Length of the content. + * @error Invalid response. + */ + public native get(); + } + + property int StatusCode { + /** + * Returns the status code of the response. + * + * @return The status code. + * @error Invalid response. + */ + public native get(); + } + + property float TotalTime { + /** + * Returns the total time from the request until the response in seconds. + * Includs name resolving, TCP connect etc. + * + * @return Total time from the request until the response in seconds. + * @error Invalid response. + */ + public native get(); + } + + property int DownloadSize { + /** + * Returns the total amount of bytes that were downloaded. + * This counts actual payload data, what's also commonly called body. + * All meta and header data are excluded and will not be counted in this number. + * + * @return Total amount of bytes that were downloaded. + * @error Invalid response. + */ + public native get(); + } + + property int UploadSize { + /** + * Returns the total amount of bytes that were uploaded. + * + * @return Total amount of bytes that were uploaded. + * @error Invalid response. + */ + public native get(); + } + + property int DownloadSpeed { + /** + * Returns the average download speed measured for the complete download in bytes per second. + * + * @return Average download speed in bytes per second. + * @error Invalid response. + */ + public native get(); + } + + property int UploadSpeed { + /** + * Returns the average upload speed measured for the complete upload in bytes per second. + * + * @return Average upload speed in bytes per second. + * @error Invalid response. + */ + public native get(); + } +} + + +/** + * Methodmap for a response of a HTTP request. + */ +methodmap System2HTTPResponse < System2Response { + /** + * Retrieves the content type of the response. + * This is the value read from the Content-Type header. + * + * @param type Buffer to store content type in. + * @param maxlength Maxlength of the buffer. + * + * @noreturn + * @error Invalid response. + */ + public native void GetContentType(const char[] type, int maxlength); + + /** + * Retrieves a HTTP response header + * + * @param name Name of the header to retrieve. + * @param value Buffer to store value in. + * @param maxlength Maxlength of the buffer. + * + * @return True if header was set, otherwise false. + * @error Invalid response. + */ + public native bool GetHeader(const char[] name, char[] value, int maxlength); + + /** + * Retrieves the name of a header at a given index. + * Use Headers property to retrieve the maximum index. + * + * @param index Index of the header name. + * @param name Buffer to store name in. + * @param maxlength Maxlength of the buffer. + * + * @return True if header was found, otherwise false. + * @error Invalid response. + */ + public native bool GetHeaderName(int index, char[] name, int maxlength); + + property int Headers { + /** + * Returns the number of set headers in the response. + * + * @return The number of set headers. + * @error Invalid response. + */ + public native get(); + } + + /** + * Returns all header set names of the response as ArrayList. + * Attention: ArrayList has to be deleted after use! + + * @param maxlength Maxlength of a header. + * + * @return ArrayList with all set response header names. Must be deleted! + * @error Invalid request. + */ + public ArrayList GetHeaders(int maxlength = 256) { + ArrayList headers = new ArrayList(maxlength); + + char[] headerName = new char[maxlength]; + for (int i=0; i < this.Headers; i++) { + this.GetHeaderName(i, headerName, maxlength); + headers.PushString(headerName); + } + + return headers; + } + + + property HTTPVersion HTTPVersion { + /** + * Returns the HTTP version of the response. + * + * @return The HTTP version. + * @error Invalid response. + */ + public native get(); + } +} + + +/** + * Methodmap for a response of a FTP request. + * Currently there are no special methods for that. + */ +methodmap System2FTPResponse < System2Response { +} + + + +/** + * Converts a plain string to an URL encoded string. + * All input characters that are not a-z, A-Z, 0-9, '-', '.', '_' or '~' + * are converted to their "URL escaped" version (%NN where NN is a two-digit hexadecimal number). + * + * Be aware that the output string may be larger then the input string. + * + * @param output Buffer to store encoded string in. May point to the input string (will replace the input string). + * @param maxlength Maxlength of the output buffer. + * @param input String to encode. + * @param ... Input string format arguments + * + * @return True on success, false otherwise. + */ +native bool System2_URLEncode(char[] output, int maxlength, const char[] input, any ...); + +/** + * Converts an URL encoded string to a plain string. + * All input characters that are URL encoded (%XX where XX is a two-digit hexadecimal number) are converted to their binary versions. + * + * @param output Buffer to store decoded string in. May point to the input string (will replace the input string). + * @param maxlength Maxlength of the output buffer. + * @param input String to decode. + * @param ... Input string format arguments + * + * @return True on success, false otherwise. + */ +native bool System2_URLDecode(char[] output, int maxlength, const char[] input, any ...); \ No newline at end of file diff --git a/scripting/includes/webcon.inc b/scripting/include/webcon.inc similarity index 100% rename from scripting/includes/webcon.inc rename to scripting/include/webcon.inc