├── .gitignore ├── LICENSE ├── ReadMe.md └── addons └── sourcemod ├── configs └── RemoteTargets.cfg ├── extensions ├── SteamWorks.ext.so ├── curl.autoload ├── curl.ext.so ├── smbz2.ext.dll └── smbz2.ext.so ├── plugins ├── curl_self_test.smx ├── discord.smx ├── tAutoDemoUpload.smx └── tEasyFTP.smx └── scripting ├── curl_self_test.sp ├── discord.sp ├── include ├── SteamWorks.inc ├── bzip2.inc ├── cURL.inc ├── cURL_header.inc ├── discord.inc └── easyftp.inc ├── tAutoDemoUpload.sp └── tEasyFTP.sp /.gitignore: -------------------------------------------------------------------------------- 1 | settings.json -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 MoritzLoewenstein 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | ## Intro 2 | This Plugin is based on [tEasyFtp](https://forums.alliedmods.net/showthread.php?p=1629724) & [tAutoDemoUpload](https://forums.alliedmods.net/showthread.php?p=1517461), which are both not longer supported. 3 | Credits to Thrawn, this wouldnt exist without his work. 4 | 5 | This is also the reason why the syntax is mixed & weird at times, I mostly fixed compilation erros and minorly changed behaviour in some cases. 6 | 7 | One interesting additional feature is the ability to send the download link of every demo to a discord textchannel. 8 | 9 | ## How to use 10 | 1. Confirm you have [SourceMod](https://www.sourcemod.net/downloads.php) and [MetaMod:Source](https://metamodsource.net/downloads.php) running on your server. 11 | 2. Download this [repository](https://github.com/MoritzLoewenstein/AutoDemoUpload/archive/master.zip) and unzip it to your /csgo folder on your server. 12 | 3. Set your FTP options in `addons/sourcemod/configs/RemoteTargets.cfg` in `"demos"`. 13 | 4. Make sure the plugin is running (`sm plugins list`) 14 | 5. It should start uploading the demo after executing `tv_record` and `tv_stoprecord` and 15 | announce the download link in allchat after completing the upload. 16 | 17 | 18 | ## Options 19 | 20 | ### FTP Server 21 | The FTP Server options are stored in `addons/sourcemod/configs/RemoteTargets.cfg` 22 | 23 | 1. Add your data in these self-explanatory options: 24 | ``` 25 | "RemoteTargets" 26 | { 27 | "demos" 28 | { 29 | "host" "" 30 | "port" "21" 31 | "user" "" 32 | "password" "" 33 | "path" "/demos" 34 | "ssl" "try" 35 | "CreateMissingDirs" "1" 36 | } 37 | } 38 | ``` 39 | 40 | 2. If you changed `demos` to another name (e.g. `new_name`), then set `sm_tautodemoupload_ftptarget "new_name"`. 41 | 42 | ### Demo compression 43 | Bzip is already included, you just have to set `sm_tautodemoupload_bzip2` to a value between `0-9`. 44 | `0` -> no compression 45 | `9` -> max compression 46 | 47 | ### Delete Demo after upload 48 | To delete the demo after upload (and the compressed demo), set `sm_tautodemoupload_delete 1`. 49 | 50 | ### Send Download Link to Discord Channel 51 | 1. create a discord textchannel and set up a webhook. 52 | 2. set these two convars: 53 | - `sm_teasyftp_discord_webhook ` 54 | - `sm_teasyftp_announce_on_discord 1` 55 | 56 | ### Change Format of Message 57 | `sm_teasyftp_announce_format "%map: %dl_url"` 58 | use `%map`, `%dl_url` & `%host` 59 | 60 | ### Enable/Disable 61 | You can enable and disable this Plugin with `sm_tautodemoupload_enable`. 62 | `1` -> enabled 63 | `0` -> disabled 64 | 65 | ## FAQ 66 | 67 | ### How can I set the local demo path? 68 | The demo path gets parsed from the `tv_record` command, e. g. `tv_record a/b/c/demoname.dem`. 69 | Make sure the directory exists. When uploading, the demo will be in `targetfolder/demoname.dem`, 70 | NOT `targetfolder/a/b/c/demoname.dem`. 71 | 72 | ### How can I fix the `SSL connect error`? 73 | Try setting `ssl` to `none` in your RemoteTargets.cfg. 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /addons/sourcemod/configs/RemoteTargets.cfg: -------------------------------------------------------------------------------- 1 | "RemoteTargets" 2 | { 3 | "demos" 4 | { 5 | "host" "" 6 | "port" "21" 7 | "user" "" 8 | "password" "" 9 | "path" "/" 10 | "ssl" "try" 11 | "CreateMissingDirs" "1" 12 | "format" "ftp://%user:%pw@%host:%port%path%file" 13 | "dl_url" "http://example.org/your/path" 14 | } 15 | } -------------------------------------------------------------------------------- /addons/sourcemod/extensions/SteamWorks.ext.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoritzLoewenstein/AutoDemoUpload/0c050e62310b7253743620469a5220708ea7a15c/addons/sourcemod/extensions/SteamWorks.ext.so -------------------------------------------------------------------------------- /addons/sourcemod/extensions/curl.autoload: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoritzLoewenstein/AutoDemoUpload/0c050e62310b7253743620469a5220708ea7a15c/addons/sourcemod/extensions/curl.autoload -------------------------------------------------------------------------------- /addons/sourcemod/extensions/curl.ext.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoritzLoewenstein/AutoDemoUpload/0c050e62310b7253743620469a5220708ea7a15c/addons/sourcemod/extensions/curl.ext.so -------------------------------------------------------------------------------- /addons/sourcemod/extensions/smbz2.ext.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoritzLoewenstein/AutoDemoUpload/0c050e62310b7253743620469a5220708ea7a15c/addons/sourcemod/extensions/smbz2.ext.dll -------------------------------------------------------------------------------- /addons/sourcemod/extensions/smbz2.ext.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoritzLoewenstein/AutoDemoUpload/0c050e62310b7253743620469a5220708ea7a15c/addons/sourcemod/extensions/smbz2.ext.so -------------------------------------------------------------------------------- /addons/sourcemod/plugins/curl_self_test.smx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoritzLoewenstein/AutoDemoUpload/0c050e62310b7253743620469a5220708ea7a15c/addons/sourcemod/plugins/curl_self_test.smx -------------------------------------------------------------------------------- /addons/sourcemod/plugins/discord.smx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoritzLoewenstein/AutoDemoUpload/0c050e62310b7253743620469a5220708ea7a15c/addons/sourcemod/plugins/discord.smx -------------------------------------------------------------------------------- /addons/sourcemod/plugins/tAutoDemoUpload.smx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoritzLoewenstein/AutoDemoUpload/0c050e62310b7253743620469a5220708ea7a15c/addons/sourcemod/plugins/tAutoDemoUpload.smx -------------------------------------------------------------------------------- /addons/sourcemod/plugins/tEasyFTP.smx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoritzLoewenstein/AutoDemoUpload/0c050e62310b7253743620469a5220708ea7a15c/addons/sourcemod/plugins/tEasyFTP.smx -------------------------------------------------------------------------------- /addons/sourcemod/scripting/curl_self_test.sp: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ============================================================================= 4 | * cURL Self Test 5 | * 6 | * ============================================================================= 7 | * 8 | * This program is free software; you can redistribute it and/or modify it under 9 | * the terms of the GNU General Public License, version 3.0, as published by the 10 | * Free Software Foundation. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 15 | * details. 16 | * 17 | * You should have received a copy of the GNU General Public License along with 18 | * this program. If not, see . 19 | * 20 | * As a special exception, AlliedModders LLC gives you permission to link the 21 | * code of this program (as well as its derivative works) to "Half-Life 2," the 22 | * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 23 | * by the Valve Corporation. You must obey the GNU General Public License in 24 | * all respects for all other code used. Additionally, AlliedModders LLC grants 25 | * this exception to all derivative works. AlliedModders LLC defines further 26 | * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 27 | * or . 28 | * 29 | * Version: $Id$ 30 | */ 31 | 32 | 33 | /* 34 | Usage: 35 | curl_self_test 36 | curl_hash_test 37 | 38 | All output test files in addons/sourcemod/data/curl_test 39 | Test #1 Get cURL version & supported protocols 40 | Test #2 Get a web page 41 | Test #3 Get ca-bundle.crt for #4 42 | Test #4 Verify a https website using ca-bundle.crt 43 | Test #5 Get a web page body & header content to file 44 | Test #6 Download a image for #7 45 | Test #7 Upload image using curl_httppost() & get the uploaded image url 46 | Test #8 Download a file using ftps:// 47 | 48 | */ 49 | 50 | #pragma semicolon 1 51 | #include 52 | #include 53 | #include 54 | 55 | public Plugin:myinfo = 56 | { 57 | name = "cURL self test", 58 | author = "Raydan", 59 | description = "cURL self test", 60 | version = "1.1.0.0", 61 | url = "http://www.ZombieX2.net/" 62 | }; 63 | 64 | 65 | #define USE_THREAD 1 66 | #define TEST_FOLDER "data/curl_test" 67 | 68 | #define TOTAL_TEST_CASE 8 69 | 70 | #define TEST_3_CERT_URL "http://curl.haxx.se/ca/cacert.pem" 71 | #define TEST_3_CERT_FILE "ca-bundle.crt" 72 | 73 | #define TEST_4_VERIFY_SITE "https://encrypted.google.com/search?q=sourcemod" 74 | 75 | #define TEST_6_UPLOAD_FILE "test_6_for_upload.png" 76 | #define TEST_6_IMAGE_URL "http://www.google.com/images/logos/ps_logo2.png" 77 | 78 | #define TEST_6_UPLOAD_URL "http://www.image-upload.net/upload.php" 79 | #define TEST_7_OUT_FILE "test_7_output.html" 80 | #define TEST_7_REGEX " ?" 81 | #define TEST_7_TARGET_URL "http://www.image-upload.net/images" 82 | 83 | /* http://www.secureftp-test.com/ */ 84 | #define TEST_8_FTPS_USERPW "test:test" 85 | #define TEST_8_FTPS_URL "ftps://ftp.secureftp-test.com:990/bookstore.xml" 86 | #define TEST_8_FILE "test_8_bookstore.xml" 87 | 88 | 89 | 90 | new CURL_Default_opt[][2] = { 91 | #if USE_THREAD 92 | {_:CURLOPT_NOSIGNAL,1}, 93 | #endif 94 | {_:CURLOPT_NOPROGRESS,1}, 95 | {_:CURLOPT_TIMEOUT,30}, 96 | {_:CURLOPT_CONNECTTIMEOUT,60}, 97 | {_:CURLOPT_VERBOSE,0} 98 | }; 99 | 100 | #define CURL_DEFAULT_OPT(%1) curl_easy_setopt_int_array(%1, CURL_Default_opt, sizeof(CURL_Default_opt)) 101 | 102 | #define TESTCASE_CLOSEHANDLE(%1) if(%1 != INVALID_HANDLE) { CloseHandle(%1); %1 = INVALID_HANDLE; } 103 | 104 | new bool:g_test_running = false; 105 | new g_testcase_runned; 106 | 107 | 108 | new String:curl_test_path[512]; 109 | 110 | 111 | 112 | /* static data */ 113 | static String:test_md5[][] = { 114 | "", 115 | "a", 116 | "abc", 117 | "message digest", 118 | "abcdefghijklmnopqrstuvwxyz", 119 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 120 | "12345678901234567890123456789012345678901234567890123456789012345678901234567890" 121 | }; 122 | 123 | static String:ret_md5[][] = { 124 | "d41d8cd98f00b204e9800998ecf8427e", 125 | "0cc175b9c0f1b6a831c399e269772661", 126 | "900150983cd24fb0d6963f7d28e17f72", 127 | "f96b697d7cb7938d525a2f31aaf161d0", 128 | "c3fcd3d76192e4007dfb496cca67e13b", 129 | "d174ab98d277d9f5a5611c2c9f419d9f", 130 | "57edf4a22be3c955ac49da2e2107b67a" 131 | }; 132 | 133 | static String:test_md4[][] = { 134 | "", 135 | "a", 136 | "abc", 137 | "message digest", 138 | "abcdefghijklmnopqrstuvwxyz", 139 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 140 | "12345678901234567890123456789012345678901234567890123456789012345678901234567890" 141 | }; 142 | 143 | static String:ret_md4[][] = { 144 | "31d6cfe0d16ae931b73c59d7e0c089c0", 145 | "bde52cb31de33e46245e05fbdbd6fb24", 146 | "a448017aaf21d8525fc10ae87aa6729d", 147 | "d9130a8164549fe818874806e1c7014b", 148 | "d79e1c308aa5bbcdeea8ed63df412da9", 149 | "043f8582f241db351ce627e153e7f0e4", 150 | "e33b4ddc9c38f2199c3e7b164fcc0536" 151 | }; 152 | 153 | static String:test_md2[][] = { 154 | "", 155 | "a", 156 | "abc", 157 | "message digest", 158 | "abcdefghijklmnopqrstuvwxyz", 159 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 160 | "12345678901234567890123456789012345678901234567890123456789012345678901234567890" 161 | }; 162 | 163 | static String:ret_md2[][] = { 164 | "8350e5a3e24c153df2275c9f80692773", 165 | "32ec01ec4a6dac72c0ab96fb34c0b5d1", 166 | "da853b0d3f88d99b30283a69e6ded6bb", 167 | "ab4f496bfb2a530b219ff33031fe06b0", 168 | "4e8ddff3650292ab5a4108c3aa47940b", 169 | "da33def2a42df13975352846c30338cd", 170 | "d5976f79d83d3a0dc9806c3c66f3efd8" 171 | }; 172 | 173 | static String:test_sha[][] = { 174 | "abc", 175 | "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 176 | }; 177 | 178 | static String:ret_sha[][] = { 179 | "0164b8a914cd2a5e74c4f7ff082c4d97f1edf880", 180 | "d2516ee1acfa5baf33dfc1c471e438449ef134c8" 181 | }; 182 | 183 | static String:test_sha1[][] = { 184 | "abc", 185 | "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 186 | }; 187 | 188 | static String:ret_sha1[][] = { 189 | "a9993e364706816aba3e25717850c26c9cd0d89d", 190 | "84983e441c3bd26ebaae4aa1f95129e5e54670f1" 191 | }; 192 | 193 | 194 | static String:test_sha224_to_512[][] = { 195 | "", 196 | "a", 197 | "abc", 198 | "message digest", 199 | "abcdefghijklmnopqrstuvwxyz", 200 | "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 201 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 202 | "12345678901234567890123456789012345678901234567890123456789012345678901234567890" 203 | }; 204 | 205 | static String:ret_sha224[][] = { 206 | "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", 207 | "abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5", 208 | "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", 209 | "2cb21c83ae2f004de7e81c3c7019cbcb65b71ab656b22d6d0c39b8eb", 210 | "45a5f72c39c5cff2522eb3429799e49e5f44b356ef926bcf390dccc2", 211 | "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525", 212 | "bff72b4fcb7d75e5632900ac5f90d219e05e97a7bde72e740db393d9", 213 | "b50aecbe4e9bb0b57bc5f3ae760a8e01db24f203fb3cdcd13148046e" 214 | }; 215 | 216 | static String:ret_sha256[][] = { 217 | "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 218 | "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", 219 | "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", 220 | "f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650", 221 | "71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73", 222 | "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1", 223 | "db4bfcbd4da0cd85a60c3c37d3fbd8805c77f15fc6b1fdfe614ee0a7c8fdb4c0", 224 | "f371bc4a311f2b009eef952dd83ca80e2b60026c8e935592d0f9c308453c813e" 225 | }; 226 | 227 | static String:ret_sha384[][] = { 228 | "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", 229 | "54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31", 230 | "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7", 231 | "473ed35167ec1f5d8e550368a3db39be54639f828868e9454c239fc8b52e3c61dbd0d8b4de1390c256dcbb5d5fd99cd5", 232 | "feb67349df3db6f5924815d6c3dc133f091809213731fe5c7b5f4999e463479ff2877f5f2936fa63bb43784b12f3ebb4", 233 | "3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b", 234 | "1761336e3f7cbfe51deb137f026f89e01a448e3b1fafa64039c1464ee8732f11a5341a6f41e0c202294736ed64db1a84", 235 | "b12932b0627d1c060942f5447764155655bd4da0c9afa6dd9b9ef53129af1b8fb0195996d2de9ca0df9d821ffee67026" 236 | }; 237 | 238 | static String:ret_sha512[][] = { 239 | "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", 240 | "1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75", 241 | "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f", 242 | "107dbf389d9e9f71a3a95f6c055b9251bc5268c2be16d6c13492ea45b0199f3309e16455ab1e96118e8a905d5597b72038ddb372a89826046de66687bb420e7c", 243 | "4dbff86cc2ca1bae1e16468a05cb9881c97f1753bce3619034898faa1aabe429955a1bf8ec483d7421fe3c1646613a59ed5441fb0f321389f77f48a879c7b1f1", 244 | "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445", 245 | "1e07be23c26a86ea37ea810c8ec7809352515a970e9253c26f536cfc7a9996c45c8370583e0a78fa4a90041d71a4ceab7423f19c71b9d5a3e01249f0bebd5894", 246 | "72ec1ef1124a45b047e8b7c75a932195135bb61de24ec0d1914042246e0aec3a2354e093d76f3048b456764346900cb130d2a4fd5dd16abb5e30bcb850dee843" 247 | }; 248 | 249 | static String:test_ripemd160[][] = { 250 | "", 251 | "a", 252 | "abc", 253 | "message digest", 254 | "abcdefghijklmnopqrstuvwxyz", 255 | "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 256 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 257 | "12345678901234567890123456789012345678901234567890123456789012345678901234567890" 258 | }; 259 | 260 | static String:ret_ripemd160[][] = { 261 | "9c1185a5c5e9fc54612808977ee8f548b2258d31", 262 | "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe", 263 | "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc", 264 | "5d0689ef49d2fae572b881b123a85ffa21595f36", 265 | "f71c27109c692c1b56bbdceb5b9d2865b3708dbc", 266 | "12a053384a9c0c88e405a06c27dcf49ada62eb2b", 267 | "b0e20b6e3116640286ed3a87a5713079b21f5189", 268 | "9b752e45573d4b39f4dbd3323cab82bf63326bfb" 269 | }; 270 | 271 | 272 | 273 | new Handle:test_3_file = INVALID_HANDLE; 274 | 275 | new Handle:test_5_file_body = INVALID_HANDLE; 276 | new Handle:test_5_file_header = INVALID_HANDLE; 277 | 278 | new Handle:test_6_file = INVALID_HANDLE; 279 | 280 | new Handle:test_7_form = INVALID_HANDLE; 281 | new Handle:test_7_file = INVALID_HANDLE; 282 | 283 | new Handle:test_8_file = INVALID_HANDLE; 284 | 285 | 286 | /* Plugin Start */ 287 | 288 | public OnPluginStart() 289 | { 290 | PluginInit(); 291 | 292 | RegConsoleCmd("curl_self_test", curl_self_test); 293 | RegConsoleCmd("curl_hash_test", curl_hash_test); 294 | g_test_running = false; 295 | } 296 | 297 | public PluginInit() 298 | { 299 | g_testcase_runned = 0; 300 | BuildPath(Path_SM, curl_test_path, sizeof(curl_test_path), TEST_FOLDER); 301 | new Handle:test_folder_handle = OpenDirectory(curl_test_path); 302 | if(test_folder_handle == INVALID_HANDLE) 303 | { 304 | if(!CreateDirectory(curl_test_path, 557)) 305 | { 306 | SetFailState("Unable Create folder %s",TEST_FOLDER); 307 | return; 308 | } 309 | } else { 310 | new String:buffer[128]; 311 | new String:path[512]; 312 | new FileType:type; 313 | while(ReadDirEntry(test_folder_handle, buffer, sizeof(buffer), type)) 314 | { 315 | if(type != FileType_File) 316 | continue; 317 | 318 | BuildPath(Path_SM, path, sizeof(path), "%s/%s", TEST_FOLDER, buffer); 319 | DeleteFile(path); 320 | } 321 | CloseHandle(test_folder_handle); 322 | } 323 | } 324 | 325 | 326 | /* Test Case */ 327 | public Test_1() 328 | { 329 | new current_test = 1; 330 | new String:version[256]; 331 | new String:protocols[256]; 332 | curl_version(version,sizeof(version)); 333 | curl_protocols(protocols, sizeof(protocols)); 334 | PrintTestCaseDebug(current_test,"Get cUrl Version"); 335 | PrintTestCaseDebug(current_test, "Version: %s",version); 336 | PrintTestCaseDebug(current_test, "Protocols: %s",protocols); 337 | 338 | onComplete(INVALID_HANDLE, CURLE_OK, current_test); 339 | } 340 | 341 | public Test_2() 342 | { 343 | new current_test = 2; 344 | PrintTestCaseDebug(current_test,"simple get a remote web page"); 345 | new Handle:curl = curl_easy_init(); 346 | if(curl != INVALID_HANDLE) 347 | { 348 | CURL_DEFAULT_OPT(curl); 349 | curl_easy_setopt_string(curl, CURLOPT_URL, "http://www.google.com"); 350 | ExecCURL(curl,current_test); 351 | } else { 352 | PrintCreatecUrlError(current_test); 353 | } 354 | } 355 | 356 | public Test_3() 357 | { 358 | new current_test = 3; 359 | PrintTestCaseDebug(current_test,"download %s for test #4",TEST_3_CERT_URL); 360 | new Handle:curl = curl_easy_init(); 361 | if(curl != INVALID_HANDLE) 362 | { 363 | test_3_file = CreateTestFile(TEST_3_CERT_FILE, "w"); 364 | CURL_DEFAULT_OPT(curl); 365 | curl_easy_setopt_handle(curl, CURLOPT_WRITEDATA, test_3_file); 366 | curl_easy_setopt_string(curl, CURLOPT_URL, TEST_3_CERT_URL); 367 | ExecCURL(curl,current_test); 368 | } else { 369 | PrintCreatecUrlError(current_test); 370 | } 371 | } 372 | public Test_4() 373 | { 374 | new current_test = 4; 375 | PrintTestCaseDebug(current_test,"using #3 cert file to verify %s", TEST_4_VERIFY_SITE); 376 | new Handle:curl = curl_easy_init(); 377 | if(curl != INVALID_HANDLE) 378 | { 379 | new String:path[512]; 380 | BuildPath(Path_SM, path, sizeof(path), "%s/%s", TEST_FOLDER, TEST_3_CERT_FILE); 381 | CURL_DEFAULT_OPT(curl); 382 | curl_easy_setopt_string(curl,CURLOPT_CAINFO, path); 383 | curl_easy_setopt_int(curl, CURLOPT_SSL_VERIFYPEER, 1); 384 | curl_easy_setopt_int(curl, CURLOPT_SSL_VERIFYHOST, 2); 385 | curl_easy_setopt_string(curl, CURLOPT_URL, TEST_4_VERIFY_SITE); 386 | ExecCURL(curl, current_test); 387 | } else { 388 | PrintCreatecUrlError(current_test); 389 | } 390 | } 391 | 392 | public Test_5() 393 | { 394 | new current_test = 5; 395 | PrintTestCaseDebug(current_test,"download a web page & header"); 396 | new Handle:curl = curl_easy_init(); 397 | if(curl != INVALID_HANDLE) 398 | { 399 | CURL_DEFAULT_OPT(curl); 400 | test_5_file_body = CreateTestFile("test5_body.txt", "w"); 401 | test_5_file_header = CreateTestFile("test5_header.txt", "w"); 402 | curl_easy_setopt_handle(curl, CURLOPT_WRITEDATA, test_5_file_body); 403 | curl_easy_setopt_handle(curl, CURLOPT_HEADERDATA, test_5_file_header); 404 | curl_easy_setopt_string(curl, CURLOPT_URL, "http://www.google.co.uk/index.html"); 405 | ExecCURL(curl,current_test); 406 | } else { 407 | PrintCreatecUrlError(current_test); 408 | } 409 | } 410 | 411 | public Test_6() 412 | { 413 | new current_test = 6; 414 | PrintTestCaseDebug(current_test,"download google logo for test #7"); 415 | new Handle:curl = curl_easy_init(); 416 | if(curl != INVALID_HANDLE) 417 | { 418 | CURL_DEFAULT_OPT(curl); 419 | test_6_file = CreateTestFile(TEST_6_UPLOAD_FILE, "wb"); 420 | curl_easy_setopt_handle(curl, CURLOPT_WRITEDATA, test_6_file); 421 | curl_easy_setopt_string(curl, CURLOPT_URL, TEST_6_IMAGE_URL); 422 | ExecCURL(curl, current_test); 423 | } else { 424 | PrintCreatecUrlError(current_test); 425 | } 426 | } 427 | 428 | 429 | public Test_7() 430 | { 431 | new current_test = 7; 432 | PrintTestCaseDebug(current_test,"upload test #6 image to image-upload.net"); 433 | new Handle:curl = curl_easy_init(); 434 | if(curl != INVALID_HANDLE) 435 | { 436 | CURL_DEFAULT_OPT(curl); 437 | new String:path[512]; 438 | BuildPath(Path_SM, path, sizeof(path), "%s/%s", TEST_FOLDER, TEST_6_UPLOAD_FILE); 439 | test_7_form = curl_httppost(); 440 | curl_formadd(test_7_form, CURLFORM_COPYNAME, "userfile[]", CURLFORM_FILE, path, CURLFORM_END); 441 | curl_formadd(test_7_form, CURLFORM_COPYNAME, "private_upload", CURLFORM_COPYCONTENTS, "0", CURLFORM_END); 442 | curl_easy_setopt_handle(curl, CURLOPT_HTTPPOST, test_7_form); 443 | 444 | test_7_file = CreateTestFile(TEST_7_OUT_FILE, "w"); 445 | curl_easy_setopt_handle(curl, CURLOPT_WRITEDATA, test_7_file); 446 | curl_easy_setopt_string(curl, CURLOPT_URL, TEST_6_UPLOAD_URL); 447 | 448 | ExecCURL(curl, current_test); 449 | } else { 450 | PrintCreatecUrlError(current_test); 451 | } 452 | } 453 | 454 | 455 | public Test_8() 456 | { 457 | new current_test = 8; 458 | PrintTestCaseDebug(current_test,"sftp test - %s",TEST_8_FTPS_URL); 459 | new Handle:curl = curl_easy_init(); 460 | if(curl != INVALID_HANDLE) 461 | { 462 | CURL_DEFAULT_OPT(curl); 463 | test_8_file = CreateTestFile(TEST_8_FILE, "w"); 464 | curl_easy_setopt_handle(curl, CURLOPT_WRITEDATA, test_8_file); 465 | curl_easy_setopt_int(curl, CURLOPT_SSL_VERIFYPEER, 0); 466 | curl_easy_setopt_int(curl, CURLOPT_SSL_VERIFYHOST, 2); 467 | curl_easy_setopt_string(curl, CURLOPT_USERPWD, TEST_8_FTPS_USERPW); 468 | curl_easy_setopt_string(curl, CURLOPT_URL, TEST_8_FTPS_URL); 469 | ExecCURL(curl, current_test); 470 | } else { 471 | PrintCreatecUrlError(current_test); 472 | } 473 | } 474 | 475 | public onComplete(Handle:hndl, CURLcode: code, any:data) 476 | { 477 | new current_test = data; 478 | if(hndl != INVALID_HANDLE && code != CURLE_OK) 479 | { 480 | new String:error_buffer[256]; 481 | curl_easy_strerror(code, error_buffer, sizeof(error_buffer)); 482 | PrintTestCaseDebug(current_test, "FAIL - %s", error_buffer); 483 | CloseHandle(hndl); 484 | g_test_running = false; 485 | return; 486 | } 487 | 488 | PrintTestCaseDebug(current_test, "*Passed*"); 489 | 490 | TestCaseEndPreClose(current_test); 491 | 492 | TESTCASE_CLOSEHANDLE(hndl) 493 | 494 | TestCaseEndPostClose(current_test); 495 | 496 | g_testcase_runned++; 497 | 498 | if(g_testcase_runned == TOTAL_TEST_CASE) 499 | { 500 | PrintTestMessage("YA! Passed All Test~"); 501 | g_test_running = false; 502 | } 503 | 504 | #if !USE_THREAD 505 | switch(g_testcase_runned) 506 | { 507 | case 1: Test_2(); 508 | case 2: Test_3(); 509 | //case 4: Test_4(); 510 | case 4: Test_5(); 511 | case 5: Test_6(); 512 | //case 7: Test_7(); 513 | case 7: Test_8(); 514 | } 515 | #endif 516 | } 517 | 518 | public Action:curl_self_test(client, args) 519 | { 520 | if(g_test_running) 521 | { 522 | PrintTestMessage("cURL Test is running, Please wait..."); 523 | return Plugin_Handled; 524 | } 525 | 526 | g_test_running = true; 527 | g_testcase_runned = 0; 528 | 529 | #if USE_THREAD 530 | Test_1(); 531 | Test_2(); 532 | Test_3(); 533 | //Test_4(); 534 | Test_5(); 535 | Test_6(); 536 | //Test_7(); 537 | Test_8(); 538 | #else 539 | Test_1(); 540 | #endif 541 | 542 | return Plugin_Handled; 543 | } 544 | 545 | stock ExecCURL(Handle:curl, current_test) 546 | { 547 | #if USE_THREAD 548 | curl_easy_perform_thread(curl, onComplete, current_test); 549 | #else 550 | new CURLcode:code = curl_load_opt(curl); 551 | if(code != CURLE_OK) { 552 | PrintTestCaseDebug(current_test, "curl_load_opt Error"); 553 | PrintcUrlError(code); 554 | CloseHandle(curl); 555 | return; 556 | } 557 | 558 | code = curl_easy_perform(curl); 559 | 560 | onComplete(curl, code, current_test); 561 | 562 | #endif 563 | } 564 | 565 | public TestCaseEndPreClose(current_test) 566 | { 567 | 568 | } 569 | 570 | public TestCaseEndPostClose(current_test) 571 | { 572 | switch(current_test) 573 | { 574 | case 3: 575 | { 576 | TESTCASE_CLOSEHANDLE(test_3_file) 577 | Test_4(); 578 | } 579 | case 5: 580 | { 581 | TESTCASE_CLOSEHANDLE(test_5_file_body) 582 | TESTCASE_CLOSEHANDLE(test_5_file_header) 583 | } 584 | case 6: 585 | { 586 | TESTCASE_CLOSEHANDLE(test_6_file) 587 | Test_7(); 588 | } 589 | case 7: 590 | { 591 | TESTCASE_CLOSEHANDLE(test_7_form) 592 | TESTCASE_CLOSEHANDLE(test_7_file) 593 | Test_7_Action(); 594 | } 595 | case 8: 596 | { 597 | TESTCASE_CLOSEHANDLE(test_8_file) 598 | } 599 | } 600 | } 601 | 602 | public Test_7_Action() 603 | { 604 | new Handle:regex = CompileRegex(TEST_7_REGEX); 605 | if(regex == INVALID_HANDLE) 606 | { 607 | PrintTestCaseDebug(7, "WARNING - unable create regex"); 608 | return; 609 | } 610 | new String:file_path[512]; 611 | Format(file_path, sizeof(file_path),"%s/%s",curl_test_path, TEST_7_OUT_FILE); 612 | new Handle:file = OpenFile(file_path,"r"); 613 | if(file == INVALID_HANDLE) 614 | { 615 | CloseHandle(regex); 616 | PrintTestCaseDebug(7, "WARNING - %s not found",TEST_7_OUT_FILE); 617 | return; 618 | } 619 | 620 | new bool:found = false; 621 | new String:buffer[1024]; 622 | while(ReadFileLine(file, buffer, sizeof(buffer))) 623 | { 624 | new RegexError:ret; 625 | new pos = MatchRegex(regex, buffer, ret); 626 | if(ret == REGEX_ERROR_NONE && pos == 2) 627 | { 628 | new String:the_image[64]; 629 | GetRegexSubString(regex, 1, the_image, sizeof(the_image)); 630 | PrintTestCaseDebug(7, "Uploaded image - %s/%s", TEST_7_TARGET_URL,the_image); 631 | found = true; 632 | break; 633 | } 634 | } 635 | 636 | if(!found) 637 | { 638 | PrintTestCaseDebug(7, "WARNING - upload may be fail..."); 639 | } 640 | 641 | CloseHandle(regex); 642 | CloseHandle(file); 643 | } 644 | 645 | 646 | public Action:curl_hash_test(client, args) 647 | { 648 | for(new i=0;i 2 | #include 3 | 4 | ArrayList g_aMsgs = null; 5 | ArrayList g_aWebhook = null; 6 | 7 | Handle g_hTimer = null; 8 | 9 | bool g_bSending; 10 | bool g_bSlowdown; 11 | 12 | public Plugin myinfo = { 13 | name = "Discord API", 14 | author = "MoritzLoewenstein", 15 | description = "This plugin lets you send messages to discord", 16 | version = "0.5", 17 | url = "https://github.com/MoritzLoewenstein/sourcemod_discord" 18 | }; 19 | 20 | public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) { 21 | CreateNative("Discord_SendMessage", Native_SendMessage); 22 | RegPluginLibrary("discord"); 23 | return APLRes_Success; 24 | } 25 | 26 | public void OnPluginStart() { 27 | //empty 28 | } 29 | 30 | public void OnMapStart() { 31 | RestartMessageTimer(false); 32 | } 33 | 34 | public void OnMapEnd() { 35 | g_hTimer = null; 36 | } 37 | 38 | public int Native_SendMessage(Handle plugin, int numParams) { 39 | char sUrl[512] 40 | GetNativeString(1, sUrl, sizeof(sUrl)); 41 | 42 | char sMessage[4096]; 43 | GetNativeString(2, sMessage, sizeof(sMessage)); 44 | 45 | // If the message dosn't start with a '{' it's not for a JSON formated message, lets fix that! 46 | if(StrContains(sMessage, "{") != 0) 47 | Format(sMessage, sizeof(sMessage), "{\"content\":\"%s\"}", sMessage); 48 | 49 | if (g_aMsgs == null) { 50 | g_aWebhook = new ArrayList(64); 51 | g_aMsgs = new ArrayList(4096); 52 | } 53 | 54 | g_aWebhook.PushString(sUrl); 55 | g_aMsgs.PushString(sMessage); 56 | } 57 | 58 | public Action Timer_SendNextMessage(Handle timer, any data) { 59 | SendNextMsg(); 60 | return Plugin_Continue; 61 | } 62 | 63 | public void SendNextMsg() { 64 | // We are still waiting for a reply from our last msg 65 | if(g_bSending) 66 | return; 67 | 68 | // Nothing to send 69 | if(g_aMsgs == null || g_aMsgs.Length < 1) 70 | return; 71 | 72 | char sUrl[512] 73 | g_aWebhook.GetString(0, sUrl, sizeof(sUrl)); 74 | 75 | char sMessage[4096]; 76 | g_aMsgs.GetString(0, sMessage, sizeof(sMessage)); 77 | 78 | Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodPOST, sUrl); 79 | if(!hRequest || !SteamWorks_SetHTTPCallbacks(hRequest, view_as(OnRequestComplete)) 80 | || !SteamWorks_SetHTTPRequestRawPostBody(hRequest, "application/json", sMessage, strlen(sMessage)) 81 | || !SteamWorks_SendHTTPRequest(hRequest)) { 82 | delete hRequest; 83 | LogError("SendNextMsg: Failed To Send Message"); 84 | return; 85 | } 86 | 87 | // Don't Send new messages aslong we wait for a reply from this one 88 | g_bSending = true; 89 | } 90 | 91 | public int OnRequestComplete(Handle hRequest, bool bFailed, bool bRequestSuccessful, EHTTPStatusCode eStatusCode) { 92 | // This should not happen! 93 | if(bFailed || !bRequestSuccessful) { 94 | LogError("[OnRequestComplete] Request failed"); 95 | } 96 | // Seems like the API is busy or too many message send recently 97 | else if(eStatusCode == k_EHTTPStatusCode429TooManyRequests || eStatusCode == k_EHTTPStatusCode500InternalServerError) { 98 | if(!g_bSlowdown) RestartMessageTimer(true); 99 | } 100 | // Wrong msg format, API doesn't like it 101 | else if(eStatusCode == k_EHTTPStatusCode400BadRequest) { 102 | char sMessage[4096]; 103 | g_aMsgs.GetString(0, sMessage, sizeof(sMessage)); 104 | 105 | LogError("[OnRequestComplete] Bad Request! Error Code: [400]. Check your message, the API doesn't like it! Message: \"%s\"", sMessage); 106 | 107 | // Remove it, the API will never accept it like this. 108 | g_aWebhook.Erase(0); 109 | g_aMsgs.Erase(0); 110 | } 111 | else if(eStatusCode == k_EHTTPStatusCode200OK || eStatusCode == k_EHTTPStatusCode204NoContent) { 112 | if(g_bSlowdown) RestartMessageTimer(false); 113 | g_aWebhook.Erase(0); 114 | g_aMsgs.Erase(0); 115 | } 116 | // Unknown error 117 | else { 118 | LogError("[OnRequestComplete] Error Code: [%d]", eStatusCode); 119 | g_aWebhook.Erase(0); 120 | g_aMsgs.Erase(0); 121 | } 122 | 123 | delete hRequest; 124 | g_bSending = false; 125 | } 126 | 127 | public void RestartMessageTimer(bool slowdown) { 128 | g_bSlowdown = slowdown; 129 | 130 | if(g_hTimer != null) delete g_hTimer; 131 | g_hTimer = CreateTimer(g_bSlowdown ? 1.0 : 0.1, Timer_SendNextMessage, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE); 132 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/include/SteamWorks.inc: -------------------------------------------------------------------------------- 1 | #if defined _SteamWorks_Included 2 | #endinput 3 | #endif 4 | #define _SteamWorks_Included 5 | 6 | /* results from UserHasLicenseForApp */ 7 | enum EUserHasLicenseForAppResult 8 | { 9 | k_EUserHasLicenseResultHasLicense = 0, // User has a license for specified app 10 | k_EUserHasLicenseResultDoesNotHaveLicense = 1, // User does not have a license for the specified app 11 | k_EUserHasLicenseResultNoAuth = 2, // User has not been authenticated 12 | }; 13 | 14 | /* General result codes */ 15 | enum EResult 16 | { 17 | k_EResultOK = 1, // success 18 | k_EResultFail = 2, // generic failure 19 | k_EResultNoConnection = 3, // no/failed network connection 20 | // k_EResultNoConnectionRetry = 4, // OBSOLETE - removed 21 | k_EResultInvalidPassword = 5, // password/ticket is invalid 22 | k_EResultLoggedInElsewhere = 6, // same user logged in elsewhere 23 | k_EResultInvalidProtocolVer = 7, // protocol version is incorrect 24 | k_EResultInvalidParam = 8, // a parameter is incorrect 25 | k_EResultFileNotFound = 9, // file was not found 26 | k_EResultBusy = 10, // called method busy - action not taken 27 | k_EResultInvalidState = 11, // called object was in an invalid state 28 | k_EResultInvalidName = 12, // name is invalid 29 | k_EResultInvalidEmail = 13, // email is invalid 30 | k_EResultDuplicateName = 14, // name is not unique 31 | k_EResultAccessDenied = 15, // access is denied 32 | k_EResultTimeout = 16, // operation timed out 33 | k_EResultBanned = 17, // VAC2 banned 34 | k_EResultAccountNotFound = 18, // account not found 35 | k_EResultInvalidSteamID = 19, // steamID is invalid 36 | k_EResultServiceUnavailable = 20, // The requested service is currently unavailable 37 | k_EResultNotLoggedOn = 21, // The user is not logged on 38 | k_EResultPending = 22, // Request is pending (may be in process, or waiting on third party) 39 | k_EResultEncryptionFailure = 23, // Encryption or Decryption failed 40 | k_EResultInsufficientPrivilege = 24, // Insufficient privilege 41 | k_EResultLimitExceeded = 25, // Too much of a good thing 42 | k_EResultRevoked = 26, // Access has been revoked (used for revoked guest passes) 43 | k_EResultExpired = 27, // License/Guest pass the user is trying to access is expired 44 | k_EResultAlreadyRedeemed = 28, // Guest pass has already been redeemed by account, cannot be acked again 45 | k_EResultDuplicateRequest = 29, // The request is a duplicate and the action has already occurred in the past, ignored this time 46 | k_EResultAlreadyOwned = 30, // All the games in this guest pass redemption request are already owned by the user 47 | k_EResultIPNotFound = 31, // IP address not found 48 | k_EResultPersistFailed = 32, // failed to write change to the data store 49 | k_EResultLockingFailed = 33, // failed to acquire access lock for this operation 50 | k_EResultLogonSessionReplaced = 34, 51 | k_EResultConnectFailed = 35, 52 | k_EResultHandshakeFailed = 36, 53 | k_EResultIOFailure = 37, 54 | k_EResultRemoteDisconnect = 38, 55 | k_EResultShoppingCartNotFound = 39, // failed to find the shopping cart requested 56 | k_EResultBlocked = 40, // a user didn't allow it 57 | k_EResultIgnored = 41, // target is ignoring sender 58 | k_EResultNoMatch = 42, // nothing matching the request found 59 | k_EResultAccountDisabled = 43, 60 | k_EResultServiceReadOnly = 44, // this service is not accepting content changes right now 61 | k_EResultAccountNotFeatured = 45, // account doesn't have value, so this feature isn't available 62 | k_EResultAdministratorOK = 46, // allowed to take this action, but only because requester is admin 63 | k_EResultContentVersion = 47, // A Version mismatch in content transmitted within the Steam protocol. 64 | k_EResultTryAnotherCM = 48, // The current CM can't service the user making a request, user should try another. 65 | k_EResultPasswordRequiredToKickSession = 49,// You are already logged in elsewhere, this cached credential login has failed. 66 | k_EResultAlreadyLoggedInElsewhere = 50, // You are already logged in elsewhere, you must wait 67 | k_EResultSuspended = 51, // Long running operation (content download) suspended/paused 68 | k_EResultCancelled = 52, // Operation canceled (typically by user: content download) 69 | k_EResultDataCorruption = 53, // Operation canceled because data is ill formed or unrecoverable 70 | k_EResultDiskFull = 54, // Operation canceled - not enough disk space. 71 | k_EResultRemoteCallFailed = 55, // an remote call or IPC call failed 72 | k_EResultPasswordUnset = 56, // Password could not be verified as it's unset server side 73 | k_EResultExternalAccountUnlinked = 57, // External account (int PSN, Facebook...) is not linked to a Steam account 74 | k_EResultPSNTicketInvalid = 58, // PSN ticket was invalid 75 | k_EResultExternalAccountAlreadyLinked = 59, // External account (int PSN, Facebook...) is already linked to some other account, must explicitly request to replace/delete the link first 76 | k_EResultRemoteFileConflict = 60, // The sync cannot resume due to a conflict between the local and remote files 77 | k_EResultIllegalPassword = 61, // The requested new password is not legal 78 | k_EResultSameAsPreviousValue = 62, // new value is the same as the old one ( secret question and answer ) 79 | k_EResultAccountLogonDenied = 63, // account login denied due to 2nd factor authentication failure 80 | k_EResultCannotUseOldPassword = 64, // The requested new password is not legal 81 | k_EResultInvalidLoginAuthCode = 65, // account login denied due to auth code invalid 82 | k_EResultAccountLogonDeniedNoMail = 66, // account login denied due to 2nd factor auth failure - and no mail has been sent 83 | k_EResultHardwareNotCapableOfIPT = 67, // 84 | k_EResultIPTInitError = 68, // 85 | k_EResultParentalControlRestricted = 69, // operation failed due to parental control restrictions for current user 86 | k_EResultFacebookQueryError = 70, // Facebook query returned an error 87 | k_EResultExpiredLoginAuthCode = 71, // account login denied due to auth code expired 88 | k_EResultIPLoginRestrictionFailed = 72, 89 | k_EResultAccountLockedDown = 73, 90 | k_EResultAccountLogonDeniedVerifiedEmailRequired = 74, 91 | k_EResultNoMatchingURL = 75, 92 | k_EResultBadResponse = 76, // parse failure, missing field, etc. 93 | k_EResultRequirePasswordReEntry = 77, // The user cannot complete the action until they re-enter their password 94 | k_EResultValueOutOfRange = 78, // the value entered is outside the acceptable range 95 | k_EResultUnexpectedError = 79, // something happened that we didn't expect to ever happen 96 | k_EResultDisabled = 80, // The requested service has been configured to be unavailable 97 | k_EResultInvalidCEGSubmission = 81, // The set of files submitted to the CEG server are not valid ! 98 | k_EResultRestrictedDevice = 82, // The device being used is not allowed to perform this action 99 | k_EResultRegionLocked = 83, // The action could not be complete because it is region restricted 100 | k_EResultRateLimitExceeded = 84, // Temporary rate limit exceeded, try again later, different from k_EResultLimitExceeded which may be permanent 101 | k_EResultAccountLoginDeniedNeedTwoFactor = 85, // Need two-factor code to login 102 | k_EResultItemDeleted = 86, // The thing we're trying to access has been deleted 103 | k_EResultAccountLoginDeniedThrottle = 87, // login attempt failed, try to throttle response to possible attacker 104 | k_EResultTwoFactorCodeMismatch = 88, // two factor code mismatch 105 | k_EResultTwoFactorActivationCodeMismatch = 89, // activation code for two-factor didn't match 106 | k_EResultAccountAssociatedToMultiplePartners = 90, // account has been associated with multiple partners 107 | k_EResultNotModified = 91, // data not modified 108 | k_EResultNoMobileDevice = 92, // the account does not have a mobile device associated with it 109 | k_EResultTimeNotSynced = 93, // the time presented is out of range or tolerance 110 | k_EResultSmsCodeFailed = 94, // SMS code failure (no match, none pending, etc.) 111 | k_EResultAccountLimitExceeded = 95, // Too many accounts access this resource 112 | k_EResultAccountActivityLimitExceeded = 96, // Too many changes to this account 113 | k_EResultPhoneActivityLimitExceeded = 97, // Too many changes to this phone 114 | k_EResultRefundToWallet = 98, // Cannot refund to payment method, must use wallet 115 | k_EResultEmailSendFailure = 99, // Cannot send an email 116 | k_EResultNotSettled = 100, // Can't perform operation till payment has settled 117 | k_EResultNeedCaptcha = 101, // Needs to provide a valid captcha 118 | k_EResultGSLTDenied = 102, // a game server login token owned by this token's owner has been banned 119 | k_EResultGSOwnerDenied = 103, // game server owner is denied for other reason (account lock, community ban, vac ban, missing phone) 120 | k_EResultInvalidItemType = 104 // the type of thing we were requested to act on is invalid 121 | }; 122 | 123 | /* This enum is used in client API methods, do not re-number existing values. */ 124 | enum EHTTPMethod 125 | { 126 | k_EHTTPMethodInvalid = 0, 127 | k_EHTTPMethodGET, 128 | k_EHTTPMethodHEAD, 129 | k_EHTTPMethodPOST, 130 | k_EHTTPMethodPUT, 131 | k_EHTTPMethodDELETE, 132 | k_EHTTPMethodOPTIONS, 133 | 134 | // The remaining HTTP methods are not yet supported, per rfc2616 section 5.1.1 only GET and HEAD are required for 135 | // a compliant general purpose server. We'll likely add more as we find uses for them. 136 | 137 | // k_EHTTPMethodTRACE, 138 | // k_EHTTPMethodCONNECT 139 | }; 140 | 141 | 142 | /* HTTP Status codes that the server can send in response to a request, see rfc2616 section 10.3 for descriptions 143 | of each of these. */ 144 | enum EHTTPStatusCode 145 | { 146 | // Invalid status code (this isn't defined in HTTP, used to indicate unset in our code) 147 | k_EHTTPStatusCodeInvalid = 0, 148 | 149 | // Informational codes 150 | k_EHTTPStatusCode100Continue = 100, 151 | k_EHTTPStatusCode101SwitchingProtocols = 101, 152 | 153 | // Success codes 154 | k_EHTTPStatusCode200OK = 200, 155 | k_EHTTPStatusCode201Created = 201, 156 | k_EHTTPStatusCode202Accepted = 202, 157 | k_EHTTPStatusCode203NonAuthoritative = 203, 158 | k_EHTTPStatusCode204NoContent = 204, 159 | k_EHTTPStatusCode205ResetContent = 205, 160 | k_EHTTPStatusCode206PartialContent = 206, 161 | 162 | // Redirection codes 163 | k_EHTTPStatusCode300MultipleChoices = 300, 164 | k_EHTTPStatusCode301MovedPermanently = 301, 165 | k_EHTTPStatusCode302Found = 302, 166 | k_EHTTPStatusCode303SeeOther = 303, 167 | k_EHTTPStatusCode304NotModified = 304, 168 | k_EHTTPStatusCode305UseProxy = 305, 169 | //k_EHTTPStatusCode306Unused = 306, (used in old HTTP spec, now unused in 1.1) 170 | k_EHTTPStatusCode307TemporaryRedirect = 307, 171 | 172 | // Error codes 173 | k_EHTTPStatusCode400BadRequest = 400, 174 | k_EHTTPStatusCode401Unauthorized = 401, // You probably want 403 or something else. 401 implies you're sending a WWW-Authenticate header and the client can sent an Authorization header in response. 175 | k_EHTTPStatusCode402PaymentRequired = 402, // This is reserved for future HTTP specs, not really supported by clients 176 | k_EHTTPStatusCode403Forbidden = 403, 177 | k_EHTTPStatusCode404NotFound = 404, 178 | k_EHTTPStatusCode405MethodNotAllowed = 405, 179 | k_EHTTPStatusCode406NotAcceptable = 406, 180 | k_EHTTPStatusCode407ProxyAuthRequired = 407, 181 | k_EHTTPStatusCode408RequestTimeout = 408, 182 | k_EHTTPStatusCode409Conflict = 409, 183 | k_EHTTPStatusCode410Gone = 410, 184 | k_EHTTPStatusCode411LengthRequired = 411, 185 | k_EHTTPStatusCode412PreconditionFailed = 412, 186 | k_EHTTPStatusCode413RequestEntityTooLarge = 413, 187 | k_EHTTPStatusCode414RequestURITooLong = 414, 188 | k_EHTTPStatusCode415UnsupportedMediaType = 415, 189 | k_EHTTPStatusCode416RequestedRangeNotSatisfiable = 416, 190 | k_EHTTPStatusCode417ExpectationFailed = 417, 191 | k_EHTTPStatusCode4xxUnknown = 418, // 418 is reserved, so we'll use it to mean unknown 192 | k_EHTTPStatusCode429TooManyRequests = 429, 193 | 194 | // Server error codes 195 | k_EHTTPStatusCode500InternalServerError = 500, 196 | k_EHTTPStatusCode501NotImplemented = 501, 197 | k_EHTTPStatusCode502BadGateway = 502, 198 | k_EHTTPStatusCode503ServiceUnavailable = 503, 199 | k_EHTTPStatusCode504GatewayTimeout = 504, 200 | k_EHTTPStatusCode505HTTPVersionNotSupported = 505, 201 | k_EHTTPStatusCode5xxUnknown = 599, 202 | }; 203 | 204 | /* list of possible return values from the ISteamGameCoordinator API */ 205 | enum EGCResults 206 | { 207 | k_EGCResultOK = 0, 208 | k_EGCResultNoMessage = 1, // There is no message in the queue 209 | k_EGCResultBufferTooSmall = 2, // The buffer is too small for the requested message 210 | k_EGCResultNotLoggedOn = 3, // The client is not logged onto Steam 211 | k_EGCResultInvalidMessage = 4, // Something was wrong with the message being sent with SendMessage 212 | }; 213 | 214 | native bool SteamWorks_IsVACEnabled(); 215 | native bool SteamWorks_GetPublicIP(ipaddr[4]); 216 | native int SteamWorks_GetPublicIPCell(); 217 | native bool SteamWorks_IsLoaded(); 218 | native bool SteamWorks_SetGameDescription(const char[] sDesc); 219 | native bool SteamWorks_SetMapName(const char[] sMapName); 220 | native bool SteamWorks_IsConnected(); 221 | native bool SteamWorks_SetRule(const char[] sKey, const char[] sValue); 222 | native bool SteamWorks_ClearRules(); 223 | native bool SteamWorks_ForceHeartbeat(); 224 | native bool SteamWorks_GetUserGroupStatus(int client, int groupid); 225 | native bool SteamWorks_GetUserGroupStatusAuthID(int authid, int groupid); 226 | 227 | native EUserHasLicenseForAppResult SteamWorks_HasLicenseForApp(int client, int app); 228 | native EUserHasLicenseForAppResult SteamWorks_HasLicenseForAppId(int authid, int app); 229 | native int SteamWorks_GetClientSteamID(int client, char[] sSteamID, int length); 230 | 231 | native bool SteamWorks_RequestStatsAuthID(int authid, int appid); 232 | native bool SteamWorks_RequestStats(int client, int appid); 233 | native bool SteamWorks_GetStatCell(int client, const char[] sKey, int &value); 234 | native bool SteamWorks_GetStatAuthIDCell(int authid, const char[] sKey, int &value); 235 | native bool SteamWorks_GetStatFloat(int client, const char[] sKey, float &value); 236 | native bool SteamWorks_GetStatAuthIDFloat(int authid, const char[] sKey, float &value); 237 | 238 | native Handle SteamWorks_CreateHTTPRequest(EHTTPMethod method, const char[] sURL); 239 | native bool SteamWorks_SetHTTPRequestContextValue(Handle hHandle, any data1, any data2=0); 240 | native bool SteamWorks_SetHTTPRequestNetworkActivityTimeout(Handle hHandle, int timeout); 241 | native bool SteamWorks_SetHTTPRequestHeaderValue(Handle hHandle, const char[] sName, const char[] sValue); 242 | native bool SteamWorks_SetHTTPRequestGetOrPostParameter(Handle hHandle, const char[] sName, const char[] sValue); 243 | native bool SteamWorks_SetHTTPRequestUserAgentInfo(Handle hHandle, const char[] sUserAgentInfo); 244 | native bool SteamWorks_SetHTTPRequestRequiresVerifiedCertificate(Handle hHandle, bool bRequireVerifiedCertificate); 245 | native bool SteamWorks_SetHTTPRequestAbsoluteTimeoutMS(Handle hHandle, int unMilliseconds); 246 | 247 | 248 | typeset SteamWorksHTTPRequestCompleted 249 | { 250 | function void (Handle hRequest, bool bFailure, bool bRequestSuccessful, EHTTPStatusCode eStatusCode); 251 | function void (Handle hRequest, bool bFailure, bool bRequestSuccessful, EHTTPStatusCode eStatusCode, any data1); 252 | function void (Handle hRequest, bool bFailure, bool bRequestSuccessful, EHTTPStatusCode eStatusCode, any data1, any data2); 253 | }; 254 | 255 | typeset SteamWorksHTTPHeadersReceived 256 | { 257 | function void (Handle hRequest, bool bFailure); 258 | function void (Handle hRequest, bool bFailure, any data1); 259 | function void (Handle hRequest, bool bFailure, any data1, any data2); 260 | }; 261 | 262 | typeset SteamWorksHTTPDataReceived 263 | { 264 | function void (Handle hRequest, bool bFailure, int offset, int bytesreceived); 265 | function void (Handle hRequest, bool bFailure, int offset, int bytesreceived, any data1); 266 | function void (Handle hRequest, bool bFailure, int offset, int bytesreceived, any data1, any data2); 267 | }; 268 | 269 | native bool SteamWorks_SetHTTPCallbacks(Handle hHandle, SteamWorksHTTPRequestCompleted fCompleted = INVALID_FUNCTION, SteamWorksHTTPHeadersReceived fHeaders = INVALID_FUNCTION, SteamWorksHTTPDataReceived fData = INVALID_FUNCTION, Handle hCalling = INVALID_HANDLE); 270 | native bool SteamWorks_SendHTTPRequest(Handle hRequest); 271 | native bool SteamWorks_SendHTTPRequestAndStreamResponse(Handle hRequest); 272 | native bool SteamWorks_DeferHTTPRequest(Handle hRequest); 273 | native bool SteamWorks_PrioritizeHTTPRequest(Handle hRequest); 274 | native bool SteamWorks_GetHTTPResponseHeaderSize(Handle hRequest, const char[] sHeader, int &size); 275 | native bool SteamWorks_GetHTTPResponseHeaderValue(Handle hRequest, const char[] sHeader, char[] sValue, int size); 276 | native bool SteamWorks_GetHTTPResponseBodySize(Handle hRequest, int &size); 277 | native bool SteamWorks_GetHTTPResponseBodyData(Handle hRequest, char[] sBody, int length); 278 | native bool SteamWorks_GetHTTPStreamingResponseBodyData(Handle hRequest, int cOffset, char[] sBody, int length); 279 | native bool SteamWorks_GetHTTPDownloadProgressPct(Handle hRequest, float &percent); 280 | native bool SteamWorks_GetHTTPRequestWasTimedOut(Handle hRequest, bool &bWasTimedOut); 281 | native bool SteamWorks_SetHTTPRequestRawPostBody(Handle hRequest, const char[] sContentType, const char[] sBody, int bodylen); 282 | 283 | typeset SteamWorksHTTPBodyCallback 284 | { 285 | function void (const char[] sData); 286 | function void (const char[] sData, any value); 287 | function void (const int[] data, any value, int datalen); 288 | }; 289 | 290 | native bool SteamWorks_GetHTTPResponseBodyCallback(Handle hRequest, SteamWorksHTTPBodyCallback fCallback, any data = 0, Handle hPlugin = INVALID_HANDLE); 291 | native bool SteamWorks_WriteHTTPResponseBodyToFile(Handle hRequest, const char[] sFileName); 292 | 293 | forward void SW_OnValidateClient(int ownerauthid, int authid); 294 | forward void SteamWorks_OnValidateClient(int ownerauthid, int authid); 295 | forward void SteamWorks_SteamServersConnected(); 296 | forward void SteamWorks_SteamServersConnectFailure(EResult result); 297 | forward void SteamWorks_SteamServersDisconnected(EResult result); 298 | 299 | forward Action SteamWorks_RestartRequested(); 300 | forward void SteamWorks_TokenRequested(char[] sToken, int maxlen); 301 | 302 | forward void SteamWorks_OnClientGroupStatus(int authid, int groupid, bool isMember, bool isOfficer); 303 | 304 | forward EGCResults SteamWorks_GCSendMessage(int unMsgType, const char[] pubData, int cubData); 305 | forward void SteamWorks_GCMsgAvailable(int cubData); 306 | forward EGCResults SteamWorks_GCRetrieveMessage(int punMsgType, const char[] pubDest, int cubDest, int pcubMsgSize); 307 | 308 | native EGCResults SteamWorks_SendMessageToGC(int unMsgType, const char[] pubData, int cubData); 309 | 310 | public Extension __ext_SteamWorks = 311 | { 312 | name = "SteamWorks", 313 | file = "SteamWorks.ext", 314 | #if defined AUTOLOAD_EXTENSIONS 315 | autoload = 1, 316 | #else 317 | autoload = 0, 318 | #endif 319 | #if defined REQUIRE_EXTENSIONS 320 | required = 1, 321 | #else 322 | required = 0, 323 | #endif 324 | }; 325 | 326 | #if !defined REQUIRE_EXTENSIONS 327 | public void __ext_SteamWorks_SetNTVOptional() 328 | { 329 | MarkNativeAsOptional("SteamWorks_IsVACEnabled"); 330 | MarkNativeAsOptional("SteamWorks_GetPublicIP"); 331 | MarkNativeAsOptional("SteamWorks_GetPublicIPCell"); 332 | MarkNativeAsOptional("SteamWorks_IsLoaded"); 333 | MarkNativeAsOptional("SteamWorks_SetGameDescription"); 334 | MarkNativeAsOptional("SteamWorks_IsConnected"); 335 | MarkNativeAsOptional("SteamWorks_SetRule"); 336 | MarkNativeAsOptional("SteamWorks_ClearRules"); 337 | MarkNativeAsOptional("SteamWorks_ForceHeartbeat"); 338 | MarkNativeAsOptional("SteamWorks_GetUserGroupStatus"); 339 | MarkNativeAsOptional("SteamWorks_GetUserGroupStatusAuthID"); 340 | 341 | MarkNativeAsOptional("SteamWorks_HasLicenseForApp"); 342 | MarkNativeAsOptional("SteamWorks_HasLicenseForAppId"); 343 | MarkNativeAsOptional("SteamWorks_GetClientSteamID"); 344 | 345 | MarkNativeAsOptional("SteamWorks_RequestStatsAuthID"); 346 | MarkNativeAsOptional("SteamWorks_RequestStats"); 347 | MarkNativeAsOptional("SteamWorks_GetStatCell"); 348 | MarkNativeAsOptional("SteamWorks_GetStatAuthIDCell"); 349 | MarkNativeAsOptional("SteamWorks_GetStatFloat"); 350 | MarkNativeAsOptional("SteamWorks_GetStatAuthIDFloat"); 351 | 352 | MarkNativeAsOptional("SteamWorks_SendMessageToGC"); 353 | 354 | MarkNativeAsOptional("SteamWorks_CreateHTTPRequest"); 355 | MarkNativeAsOptional("SteamWorks_SetHTTPRequestContextValue"); 356 | MarkNativeAsOptional("SteamWorks_SetHTTPRequestNetworkActivityTimeout"); 357 | MarkNativeAsOptional("SteamWorks_SetHTTPRequestHeaderValue"); 358 | MarkNativeAsOptional("SteamWorks_SetHTTPRequestGetOrPostParameter"); 359 | 360 | MarkNativeAsOptional("SteamWorks_SetHTTPCallbacks"); 361 | MarkNativeAsOptional("SteamWorks_SendHTTPRequest"); 362 | MarkNativeAsOptional("SteamWorks_SendHTTPRequestAndStreamResponse"); 363 | MarkNativeAsOptional("SteamWorks_DeferHTTPRequest"); 364 | MarkNativeAsOptional("SteamWorks_PrioritizeHTTPRequest"); 365 | MarkNativeAsOptional("SteamWorks_GetHTTPResponseHeaderSize"); 366 | MarkNativeAsOptional("SteamWorks_GetHTTPResponseHeaderValue"); 367 | MarkNativeAsOptional("SteamWorks_GetHTTPResponseBodySize"); 368 | MarkNativeAsOptional("SteamWorks_GetHTTPResponseBodyData"); 369 | MarkNativeAsOptional("SteamWorks_GetHTTPStreamingResponseBodyData"); 370 | MarkNativeAsOptional("SteamWorks_GetHTTPDownloadProgressPct"); 371 | MarkNativeAsOptional("SteamWorks_SetHTTPRequestRawPostBody"); 372 | 373 | MarkNativeAsOptional("SteamWorks_GetHTTPResponseBodyCallback"); 374 | MarkNativeAsOptional("SteamWorks_WriteHTTPResponseBodyToFile"); 375 | } 376 | #endif -------------------------------------------------------------------------------- /addons/sourcemod/scripting/include/bzip2.inc: -------------------------------------------------------------------------------- 1 | #if defined _bzip2_included 2 | #endinput 3 | #endif 4 | #define _bzip2_included 5 | 6 | enum BZ_Error { 7 | BZ_OK = 0, 8 | BZ_RUN_OK = 1, 9 | BZ_FLUSH_OK = 2, 10 | BZ_FINISH_OK = 3, 11 | BZ_STREAM_END = 4, 12 | BZ_SEQUENCE_ERROR = -1, 13 | BZ_PARAM_ERROR = -2, 14 | BZ_MEM_ERROR = -3, 15 | BZ_DATA_ERROR = -4, 16 | BZ_DATA_ERROR_MAGIC = -5, 17 | BZ_IO_ERROR = -6, 18 | BZ_UNEXPECTED_EOF = -7, 19 | BZ_OUTBUFF_FULL = -8, 20 | BZ_CONFIG_ERROR = -9, 21 | BZ_IO_ERROR_INPUT = -101, 22 | BZ_IO_ERROR_OUTPUT = -102, 23 | } 24 | 25 | typeset BZ2Callback { 26 | function int (BZ_Error iError, char[] inFile, char[] outFile, any data); 27 | }; 28 | 29 | native void BZ2_DecompressFile(char[] inFile, char[] outFile, BZ2Callback cb, any data = 0); 30 | native void BZ2_CompressFile(char[] inFile, char[] outFile, int iCompressionLevel, BZ2Callback cb, any data = 0); 31 | 32 | stock void BZ2_Error(BZ_Error iError, char[] sError, int iErrorStringLength) { 33 | switch(iError) { 34 | case BZ_OK: strcopy(sError, iErrorStringLength, "BZ_OK"); 35 | case BZ_RUN_OK: strcopy(sError, iErrorStringLength, "BZ_RUN_OK"); 36 | case BZ_FLUSH_OK: strcopy(sError, iErrorStringLength, "BZ_FLUSH_OK"); 37 | case BZ_FINISH_OK: strcopy(sError, iErrorStringLength, "BZ_FINISH_OK"); 38 | case BZ_STREAM_END: strcopy(sError, iErrorStringLength, "BZ_STREAM_END"); 39 | case BZ_SEQUENCE_ERROR: strcopy(sError, iErrorStringLength, "BZ_SEQUENCE_ERROR"); 40 | case BZ_PARAM_ERROR: strcopy(sError, iErrorStringLength, "BZ_PARAM_ERROR"); 41 | case BZ_MEM_ERROR: strcopy(sError, iErrorStringLength, "BZ_MEM_ERROR"); 42 | case BZ_DATA_ERROR: strcopy(sError, iErrorStringLength, "BZ_DATA_ERROR"); 43 | case BZ_DATA_ERROR_MAGIC: strcopy(sError, iErrorStringLength, "BZ_DATA_ERROR_MAGIC"); 44 | case BZ_IO_ERROR: strcopy(sError, iErrorStringLength, "BZ_IO_ERROR"); 45 | case BZ_UNEXPECTED_EOF: strcopy(sError, iErrorStringLength, "BZ_UNEXPECTED_EOF"); 46 | case BZ_OUTBUFF_FULL: strcopy(sError, iErrorStringLength, "BZ_OUTBUFF_FULL"); 47 | case BZ_CONFIG_ERROR: strcopy(sError, iErrorStringLength, "BZ_CONFIG_ERROR"); 48 | case BZ_IO_ERROR_INPUT: strcopy(sError, iErrorStringLength, "BZ_IO_ERROR_INPUT"); 49 | case BZ_IO_ERROR_OUTPUT: strcopy(sError, iErrorStringLength, "BZ_IO_ERROR_OUTPUT"); 50 | } 51 | } 52 | 53 | stock void LogBZ2Error(BZ_Error iError, const char[] sSuffix = "") { 54 | char sError[255]; 55 | BZ2_Error(iError, sError, sizeof(sError)); 56 | LogError("bzip2 Error: %s %s", sError, sSuffix); 57 | } 58 | 59 | /** 60 | * Do not edit below this line! 61 | */ 62 | public Extension __ext_bzip2 = 63 | { 64 | name = "SMbz2", 65 | file = "smbz2.ext", 66 | #if defined AUTOLOAD_EXTENSIONS 67 | autoload = 1, 68 | #else 69 | autoload = 0, 70 | #endif 71 | #if defined REQUIRE_EXTENSIONS 72 | required = 1, 73 | #else 74 | required = 0, 75 | #endif 76 | }; 77 | 78 | #if !defined REQUIRE_EXTENSIONS 79 | public __ext_bzip2_SetNTVOptional() 80 | { 81 | MarkNativeAsOptional("BZ2_DecompressFile"); 82 | MarkNativeAsOptional("BZ2_CompressFile"); 83 | } 84 | #endif -------------------------------------------------------------------------------- /addons/sourcemod/scripting/include/cURL.inc: -------------------------------------------------------------------------------- 1 | 2 | #if defined _cURL_included 3 | #endinput 4 | #endif 5 | #define _cURL_included 6 | 7 | #include 8 | 9 | 10 | /* 11 | ======================================== 12 | The Following CURLOPT_* NOT support 13 | ERRORBUFFER // use curl_get_error_buffer 14 | WRITEINFO // ??? 15 | PROGRESSFUNCTION // unused 16 | PROGRESSDATA // same 17 | HEADERFUNCTION // unused 18 | DEBUGFUNCTION // unused 19 | DEBUGDATA // same 20 | SHARE // unsupport 21 | PRIVATE // unsupport 22 | SSL_CTX_FUNC // unused 23 | SSL_CTX_DATA // same 24 | IOCTLFUNCTION // unused 25 | IOCTLDATA // same 26 | CONV_FROM_NETWORK_FUNC // unused 27 | CONV_TO_NETWORK_FUNC // unused 28 | CONV_FROM_UTF8_FUNC // unused 29 | SOCKOPTFUNCTION // unused 30 | SOCKOPTDATA // unused 31 | OPENSOCKETFUNCTION // used 32 | OPENSOCKETDATA // used 33 | COPYPOSTFIELDS // unsupport 34 | SEEKFUNCTION // unused 35 | SEEKDATA // unused 36 | SOCKS5_GSSAPI_SERVICE // unsupport 37 | SOCKS5_GSSAPI_NEC // unsupport 38 | SSH_KEYFUNCTION // unsupport 39 | SSH_KEYDATA // unsupport 40 | INTERLEAVEFUNCTION // unsupport 41 | CHUNK_BGN_FUNC // unsupport 42 | CHUNK_END_FUNC // unsupport 43 | FNMATCH_FUNC // unsupport 44 | CHUNK_DATA // unsupport 45 | FNMATCH_DATA // unsupport 46 | TLSAUTH_USERNAME // unsupport, require tls-srp 47 | TLSAUTH_PASSWORD // unsupport, require tls-srp 48 | TLSAUTH_TYPE // unsupport, require tls-srp 49 | CLOSESOCKETFUNCTION // unsupport 50 | CLOSESOCKETDATA // unsupport 51 | ========================================*/ 52 | 53 | /* 54 | ======================================== 55 | The Following CURLOPT_* supports the "file //" notation. 56 | COOKIEFILE 57 | COOKIEJAR 58 | RANDOM_FILE 59 | EGDSOCKET 60 | SSLKEY 61 | CAPATH 62 | NETRC_FILE 63 | SSH_PUBLIC_KEYFILE 64 | SSH_PRIVATE_KEYFILE 65 | _CRLFILE 66 | ISSUERCERT 67 | SSH_KNOWNHOSTS 68 | 69 | ========================================*/ 70 | 71 | /* 72 | ======================================== 73 | The Following CURLINFO_* NOT support 74 | CURLINFO_SLIST 75 | 76 | ========================================*/ 77 | 78 | /* 79 | ======================================== 80 | The Following CURLFORM_* NOT support 81 | CURLFORM_PTRNAME 82 | CURLFORM_PTRCONTENTS 83 | CURLFORM_ARRAY 84 | CURLFORM_BUFFER 85 | CURLFORM_BUFFERPTR 86 | CURLFORM_BUFFERLENGTH 87 | CURLFORM_STREAM 88 | 89 | ========================================*/ 90 | 91 | 92 | 93 | 94 | /*************************************************************************************************/ 95 | /******************************************** OPTIONS ********************************************/ 96 | /*************************************************************************************************/ 97 | 98 | 99 | /** 100 | * The Send & Receive Action 101 | * Using on CURL_OnSend, CURL_OnReceive 102 | * SendRecv_Act_GOTO_SEND = go to send 103 | * SendRecv_Act_GOTO_RECV = go to receive 104 | * SendRecv_Act_GOTO_WAIT = go to wait 105 | * SendRecv_Act_GOTO_END = end the connection 106 | * SendRecv_Act_GOTO_SEND_NO_WAIT = go to send but no select 107 | * SendRecv_Act_GOTO_RECV_NO_WAIT = go to receive but no select 108 | * To see how it work? see curl_echo_test.sp & curl_rcon_test.sp examples 109 | */ 110 | enum SendRecv_Act { 111 | SendRecv_Act_NOTHING = 0, 112 | 113 | SendRecv_Act_GOTO_SEND, 114 | SendRecv_Act_GOTO_RECV, 115 | SendRecv_Act_GOTO_WAIT, 116 | SendRecv_Act_GOTO_END, 117 | SendRecv_Act_GOTO_SEND_NO_WAIT, 118 | SendRecv_Act_GOTO_RECV_NO_WAIT, 119 | 120 | SendRecv_Act_LAST, 121 | }; 122 | 123 | /** 124 | * Hash type for curl_hash_file, curl_hash_string 125 | */ 126 | enum Openssl_Hash { 127 | Openssl_Hash_MD5 = 0, 128 | Openssl_Hash_MD4, 129 | Openssl_Hash_MD2, 130 | Openssl_Hash_SHA, 131 | Openssl_Hash_SHA1, 132 | Openssl_Hash_SHA224, 133 | Openssl_Hash_SHA256, 134 | Openssl_Hash_SHA384, 135 | Openssl_Hash_SHA512, 136 | Openssl_Hash_RIPEMD160, 137 | }; 138 | 139 | 140 | /*************************************************************************************************/ 141 | /******************************************* CALLBACKS *******************************************/ 142 | /*************************************************************************************************/ 143 | 144 | 145 | /** 146 | * called if curl_easy_perform_thread() or curl_easy_send_recv() Complete 147 | * @ param Handle hndl The curl handle 148 | * @ param CURLcode code The CURLcode code, see cURL_header.inc 149 | * @ param any data Data passed to curl_easy_perform_thread() 150 | * @ noreturn 151 | */ 152 | typeset CURL_OnComplete 153 | { 154 | function void (Handle hndl, CURLcode code); 155 | function void (Handle hndl, CURLcode code , any data); 156 | }; 157 | 158 | /** 159 | * called if curl_easy_send_recv() before sending data 160 | * @ param Handle hndl The curl handle 161 | * @ param CURLcode code The last CURLcode code, see cURL_header.inc 162 | * @ param cell_t last_sent_dataSize The last sent datasize 163 | * @ param any data Data passed to curl_easy_send_recv() 164 | * @ return SendRecv_Act 165 | */ 166 | typeset CURL_OnSend 167 | { 168 | function SendRecv_Act (Handle hndl, CURLcode code, const int last_sent_dataSize); 169 | function SendRecv_Act (Handle hndl, CURLcode code, const int last_sent_dataSize, any data); 170 | } 171 | 172 | /** 173 | * called if curl_easy_send_recv() after received data 174 | * @ param Handle hndl The curl handle 175 | * @ param CURLcode code The CURLcode code, see cURL_header.inc 176 | * @ param String dataSize The received datasize 177 | * @ param any data Data passed to curl_easy_send_recv() 178 | * @ return SendRecv_Act 179 | */ 180 | typeset CURL_OnReceive 181 | { 182 | function SendRecv_Act (Handle hndl, CURLcode code, const char[] receiveData, const int dataSize); 183 | function SendRecv_Act (Handle hndl, CURLcode code, const char[] receiveData, const int dataSize, any data); 184 | } 185 | 186 | /** 187 | * called if Openssl_Hash_file() after hashed the file 188 | * @ param bool success True on success, false if hash file fail 189 | * @ param String buffer The hash string 190 | * @ param any data Data passed to Openssl_Hash_file() 191 | * @ noreturn 192 | */ 193 | typeset Openssl_Hash_Complete 194 | { 195 | function void (const bool success, const char[] buffer); 196 | function void (const bool success, const char[] buffer, any data); 197 | } 198 | 199 | 200 | typeset CURL_Function_CB 201 | { 202 | // CURLOPT_WRITEFUNCTION 203 | function void (Handle hndl, const char[] buffer, const int bytes, const int nmemb); 204 | function void (Handle hndl, const char[] buffer, const int bytes, const int nmemb, any data); 205 | 206 | // CURLOPT_READFUNCTION 207 | function void (Handle hndl, const int bytes, const int nmemb); 208 | function void (Handle hndl, const int bytes, const int nmemb, any data); 209 | } 210 | 211 | /*************************************************************************************************/ 212 | /******************************************** NATIVES ********************************************/ 213 | /*************************************************************************************************/ 214 | 215 | 216 | /** 217 | * Create a curl handle 218 | * @ return Handle The curl handle. Returns INVALID_HANDLE on failure 219 | */ 220 | native Handle curl_easy_init(); 221 | 222 | /** 223 | * Set a curl option for CURLOPTTYPE_OBJECTPOINT type 224 | * 225 | * @ param Handle hndl The handle of the curl to be used. May be INVALID_HANDLE if not essential. 226 | * @ param CURLoption opt The option to add (see enum CURLoption for details). 227 | * @ param String buffer The value to set the option to. 228 | * @ return bool 1 on success. 0 = The option not accept string or unsupport. 229 | */ 230 | native bool curl_easy_setopt_string(Handle hndl, CURLoption opt, const char[] buffer); 231 | 232 | /** 233 | * Set a curl option for CURLOPTTYPE_LONG type 234 | * 235 | * @ param Handle hndl The handle of the curl to be used. May be INVALID_HANDLE if not essential. 236 | * @ param CURLoption opt The option to add (see enum CURLoption for details). 237 | * @ param cell_t value The value to set the option to. 238 | * @ return bool 1 on success. 0 = The option not accept integer or unsupport. 239 | */ 240 | native bool curl_easy_setopt_int(Handle hndl, CURLoption opt, int value); 241 | 242 | /** 243 | * Set a curl option for CURLOPTTYPE_LONG type 244 | * @ example" 245 | new opt[][2] = { 246 | {_ CURLOPT_NOPROGRESS,1}, 247 | {_ CURLOPT_VERBOSE,0} 248 | }; 249 | * 250 | * @ param Handle hndl The handle of the curl to be used. May be INVALID_HANDLE if not essential. 251 | * @ param cell_t array The option array to add (see enum CURLoption for details). 252 | * @ param cell_t array_size The array size. 253 | * @ return bool 1 on success. 0 = The option not accept integer or unsupport. 254 | */ 255 | native bool curl_easy_setopt_int_array(Handle hndl, int[][] array, int array_size); // int array[][2] 256 | 257 | /** 258 | * Set a curl option for CURLOPTTYPE_OFF_T type 259 | * 260 | * @ param Handle hndl The handle of the curl to be used. May be INVALID_HANDLE if not essential. 261 | * @ param CURLoption opt The option to add (see enum CURLoption for details). 262 | * @ param String buffer The value to set the option to. 263 | * @ return bool 1 on success. 0 = The option not accept string or unsupport. 264 | */ 265 | native bool curl_easy_setopt_int64(Handle hndl, CURLoption opt, const char buffer); 266 | 267 | /** 268 | * Set a curl option for CURLOPTTYPE_OBJECTPOINT type 269 | * @ note only accept the following handle type 270 | curl_OpenFile() 271 | curl_httppost() 272 | curl_slist() 273 | * 274 | * @ param Handle hndl The handle of the curl to be used. May be INVALID_HANDLE if not essential. 275 | * @ param CURLoption opt The option to add (see enum CURLoption for details). 276 | * @ param Handle other_hndl The other handle to set the option to. 277 | * @ return bool 1 on success. 0 = The option not accept string or unsupport. 278 | */ 279 | native bool curl_easy_setopt_handle(Handle hndl, CURLoption opt, Handle other_hndl); 280 | 281 | /** 282 | * Set a curl option for CURLOPTTYPE_FUNCTIONPOINT type 283 | * 284 | * @ param Handle hndl The handle of the curl to be used. May be INVALID_HANDLE if not essential. 285 | * @ param CURLoption opt The option to add (see enum CURLoption for details). 286 | * @ param CURL_Function_CB callback The value to set the option to. 287 | * @ param cell_t value Value to set. 288 | * @ return bool 1 on success. 0 = The option unsupport or invalid callback function. 289 | */ 290 | native bool curl_easy_setopt_function(Handle hndl, CURLoption opt, CURL_Function_CB callback, any value=0); 291 | 292 | /** 293 | * Load all CURLoption to curl Handle 294 | * @ note 295 | * Using curl_easy_perform_thread() will load option in thread 296 | * Use this on curl_easy_perform or check all CURLoption are valid or not 297 | * Only can use one time for each curl handle 298 | * @ return The CURLcode code, see cURL_header.inc 299 | */ 300 | native CURLcode curl_load_opt(Handle hndl); 301 | 302 | /** 303 | * Perform a file transfer 304 | * @ return The CURLcode code, see cURL_header.inc 305 | */ 306 | native CURLcode curl_easy_perform(Handle hndl); 307 | 308 | /** 309 | * Perform a file transfer, using thread 310 | * @ param Handle hndl The handle of the curl to be used. May be INVALID_HANDLE if not essential. 311 | * @ param CURL_OnComplete perform_callback The complete callback. 312 | * @ param cell_t value Value to set. 313 | * @ noreturn 314 | */ 315 | native void curl_easy_perform_thread(Handle hndl, CURL_OnComplete perform_callback, any value=0); 316 | 317 | /** 318 | * Create a send & receive function for a connected curl handle 319 | * @ param Handle hndl The handle of the curl to be used. 320 | * @ param CURL_OnSend send_callback The send callback. 321 | * @ param CURL_OnReceive receive_callback The receive callback. 322 | * @ param CURL_OnComplete complete_callback The complete callback. 323 | * @ param SendRecv_Act act The first SendRecv_Act action 324 | * @ param cell_t send_timeout Send timeout value in milliseconds. 325 | * @ param cell_t recv_timeout Receive timeout value in milliseconds. 326 | * @ param cenn_t recv_buffer_Size Receive buffer size. 327 | * @ param cell_t value Value to set. 328 | * @ noreturn 329 | */ 330 | native void curl_easy_send_recv(Handle hndl, CURL_OnSend send_callback, CURL_OnReceive receive_callback, CURL_OnComplete complete_callback, SendRecv_Act act, int send_timeout, int recv_timeout, int recv_buffer_Size = 1024, any value=0); 331 | 332 | /** 333 | * Send a signal to a send & receive curl handle 334 | * @ param Handle hndl The handle of the send & receive curl to be used. 335 | * @ param SendRecv_Act act The SendRecv_Act action after the singal 336 | * @ return bool 1 on success. 0 = not a curl_easy_send_recv() curl, or not running/waiting 337 | */ 338 | native bool curl_send_recv_Signal(Handle hndl, SendRecv_Act act); 339 | 340 | /** 341 | * Check send & receive curl handle is Waiting or not 342 | * @ param Handle hndl The handle of the send & receive curl to be used. 343 | * @ return bool 1 = is waiting. 0 = not a curl_easy_send_recv() curl, or not running/waiting 344 | */ 345 | native bool curl_send_recv_IsWaiting(Handle hndl); 346 | 347 | /** 348 | * Send the send buffer for send & receive curl handle 349 | * @ param Handle hndl The handle of the send & receive curl to be used. 350 | * @ param cell_t data The data to send 351 | * @ param cell_t size if specified the \0 terminator will not be included 352 | * @ noreturn 353 | */ 354 | native void curl_set_send_buffer(Handle hndl, const char[] data, int size=-1); 355 | 356 | /** 357 | * Send the receive data size for send & receive curl handle 358 | * @ param Handle hndl The handle of the send & receive curl to be used. 359 | * @ param cell_t size The receive size 360 | * @ noreturn 361 | */ 362 | native void curl_set_receive_size(Handle hndl, int size); 363 | 364 | /** 365 | * Set send timeout for curl_easy_send_recv() 366 | * @ param Handle hndl The handle of the send & receive curl to be used. 367 | * @ param cell_t timeout How long will try to send data before it timeout (milliseconds). 368 | * @ noreturn 369 | */ 370 | native void curl_set_send_timeout(Handle hndl, int timeout); 371 | 372 | /** 373 | * Set receive timeout for curl_easy_send_recv() 374 | * @ param Handle hndl The handle of the send & receive curl to be used. 375 | * @ param cell_t timeout How long will try to receive data before it timeout (milliseconds). 376 | * @ noreturn 377 | */ 378 | native void curl_set_recv_timeout(Handle hndl, int timeout); 379 | 380 | /** 381 | * Get CURLOPT_ERRORBUFFER error string in curl handle 382 | * @ param Handle hndl The handle of the curl to be used. 383 | * @ param String buffer Destination string buffer to copy to. 384 | * @ param cell_t maxlen Destination buffer length (includes null terminator). 385 | * @ noreturn 386 | */ 387 | native void curl_get_error_buffer(Handle hndl, char[] buffer, int maxlen); 388 | 389 | /** 390 | * Extract information from a curl handle. (CURLINFO_STRING only) 391 | * @ param Handle hndl The handle of the curl to be used. 392 | * @ param CURLINFO info The enum CURLINFO, see cURL_header.inc 393 | * @ param String buffer Destination string buffer to copy to. 394 | * @ param cell_t maxlen Destination buffer length (includes null terminator). 395 | * @ return The CURLcode code, see cURL_header.inc 396 | */ 397 | native CURLcode curl_easy_getinfo_string(Handle hndl, CURLINFO info, char[] buffer, int maxlen); 398 | 399 | /** 400 | * Extract information from a curl handle. (CURLINFO_LONG, CURLINFO_DOUBLE only) 401 | * @ param Handle hndl The handle of the curl to be used. 402 | * @ param CURLINFO info The enum CURLINFO, see cURL_header.inc 403 | * @ param value Variable to store the value. 404 | * @ return The CURLcode code, see cURL_header.inc 405 | */ 406 | native CURLcode curl_easy_getinfo_int(Handle hndl, CURLINFO info, any &value); 407 | 408 | /** 409 | * URL encodes the given string 410 | * @ param Handle hndl The handle of the curl to be used. 411 | * @ param String url The string to encodes. 412 | * @ param String buffer Destination string buffer to copy to. 413 | * @ param cell_t maxlen Destination buffer length (includes null terminator). 414 | * @ return 1 on success. 415 | */ 416 | native bool curl_easy_escape(Handle hndl, const char[] url, char[] buffer, int maxlen); 417 | 418 | /** 419 | * URL decodes the given string 420 | * @ param Handle hndl The handle of the curl to be used. 421 | * @ param String url The string to dencodes. 422 | * @ param String buffer Destination string buffer to copy to. 423 | * @ param cell_t maxlen Destination buffer length (includes null terminator). 424 | * @ return The output length. 425 | */ 426 | native int curl_easy_unescape(Handle hndl, const char[] url, char[] buffer, int maxlen); 427 | 428 | /** 429 | * Return string describing error code 430 | * @ param CURLcode code The CURLcode code, see cURL_header.inc 431 | * @ param String buffer Destination string buffer to copy to. 432 | * @ param cell_t maxlen Destination buffer length (includes null terminator). 433 | * @ noreturn 434 | */ 435 | native void curl_easy_strerror(CURLcode code, char[] buffer, int maxlen); 436 | 437 | /** 438 | * Returns the libcurl version string 439 | * @ param String buffer Destination string buffer to copy to. 440 | * @ param cell_t maxlen Destination buffer length (includes null terminator). 441 | * @ noreturn 442 | */ 443 | native void curl_version(char[] buffer, int maxlen); 444 | 445 | /** 446 | * Returns the libcurl supported protocols string 447 | * @ param String buffer Destination string buffer to copy to. 448 | * @ param cell_t maxlen Destination buffer length (includes null terminator). 449 | * @ noreturn 450 | */ 451 | native void curl_protocols(char[] buffer, int maxlen); 452 | 453 | /** 454 | * Returns the libcurl supported features 455 | * @ return The currently features bits. see CURL_VERSION_* 456 | */ 457 | native int curl_features(); 458 | 459 | /** 460 | * This funcitopn same as Sourcemod OpenFile() 461 | * For the following CUROPT_* only 462 | * CURLOPT_WRITEDATA 463 | * CURLOPT_HEADERDATA 464 | * CURLOPT_READDATA 465 | * CURLOPT_STDERR 466 | * CURLOPT_INTERLEAVEDATA 467 | * 468 | * @ note 469 | * Should not share to another threaded curl handle. 470 | * 471 | * @ param file File to open. 472 | * @ param mode Open mode. 473 | * @ return A Handle to the file, INVALID_HANDLE on open error. 474 | */ 475 | native Handle curl_OpenFile(const char[] file, const char[] mode); 476 | 477 | 478 | /** 479 | * Create a curl_httppost struct 480 | * For the following CUROPT_* only 481 | * CURLOPT_HTTPPOST 482 | * @ note 483 | * Should not share to another threaded curl handle. 484 | * 485 | * @ return A Handle to the curl_httppost, INVALID_HANDLE on error. 486 | */ 487 | native Handle curl_httppost(); 488 | 489 | /** 490 | * Add a section to a multipart/formdata HTTP POST 491 | * @ note 492 | * Check enum CURLformoption (cURL_head.inc) to see which option supported 493 | * 494 | * @ param Handle hndl The handle of the curl_httppost to be used. 495 | * @ param ... Variable number of format parameters. 496 | * @ return The CURLFORMcode code, see cURL_header.inc 497 | */ 498 | native CURLFORMcode curl_formadd(Handle handl, any ...); 499 | 500 | /** 501 | * Create a curl_slist struct 502 | * For the following CUROPT_* only 503 | * CURLOPT_QUOTE 504 | * CURLOPT_HTTPHEADER 505 | * CURLOPT_POSTQUOTE 506 | * CURLOPT_TELNETOPTIONS 507 | * CURLOPT_PREQUOTE 508 | * CURLOPT_HTTP200ALIASES 509 | * CURLOPT_MAIL_RCPT 510 | * CURLOPT_RESOLVE 511 | * 512 | * @ note 513 | * Should not share to another threaded curl handle. 514 | * 515 | * @ return A Handle to the curl_slist, INVALID_HANDLE on error. 516 | */ 517 | native Handle curl_slist(); 518 | 519 | /** 520 | * Add a string to an slist 521 | * @ param Handle hndl The handle of the curl_slist to be used. 522 | * @ param String buffer The string to add 523 | * @ noreturn 524 | */ 525 | native void curl_slist_append(Handle hndl, const char[] buffer); 526 | 527 | /** 528 | * Hash a file 529 | * @ parma String file The file path. supports the "file //" notation. 530 | * @ param Openssl_Hash algorithm Hash Algorithm. 531 | * @ param Openssl_Hash_Complete complete_callback The complete callback. 532 | * @ param cell_t value Value to set. 533 | * @ noreturn 534 | */ 535 | native void curl_hash_file(const char[] file, Openssl_Hash algorithm, Openssl_Hash_Complete complete_callback, any value=0); 536 | 537 | /** 538 | * Hash a string 539 | * @ parma String input The string to hash. 540 | * @ param cell_t dataSize The input string size. 541 | * @ param Openssl_Hash algorithm Hash Algorithm. 542 | * @ param String buffer Destination string buffer to copy to. 543 | * @ param cell_t maxlen Destination buffer length (includes null terminator). 544 | * @ return 1 on success 545 | */ 546 | native bool curl_hash_string(const char[] input, int dataSize, Openssl_Hash algorithm, char[] buffer, int maxlength); 547 | 548 | 549 | /** 550 | * Do not edit below this line! 551 | */ 552 | public Extension __ext_curl = { 553 | name = "curl", 554 | file = "curl.ext", 555 | #if defined AUTOLOAD_EXTENSIONS 556 | autoload = 1, 557 | #else 558 | autoload = 0, 559 | #endif 560 | #if defined REQUIRE_EXTENSIONS 561 | required = 1, 562 | #else 563 | required = 0, 564 | #endif 565 | }; 566 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/include/cURL_header.inc: -------------------------------------------------------------------------------- 1 | #if defined _cURL_header_included 2 | #endinput 3 | #endif 4 | #define _cURL_header_included 5 | 6 | 7 | /* SourceMod */ 8 | #define LONG CURLOPTTYPE_LONG 9 | #define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT 10 | #define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT 11 | #define OFF_T CURLOPTTYPE_OFF_T 12 | 13 | 14 | #define CURL_MAX_WRITE_SIZE 16384 15 | 16 | #define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ 17 | #define CURL_VERSION_KERBEROS4 (1<<1) /* kerberos auth is supported */ 18 | #define CURL_VERSION_SSL (1<<2) /* SSL options are present */ 19 | #define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ 20 | #define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ 21 | #define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth support */ 22 | #define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */ 23 | #define CURL_VERSION_ASYNCHDNS (1<<7) /* asynchronous dns resolves */ 24 | #define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth */ 25 | #define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */ 26 | #define CURL_VERSION_IDN (1<<10) /* International Domain Names support */ 27 | #define CURL_VERSION_SSPI (1<<11) /* SSPI is supported */ 28 | #define CURL_VERSION_CONV (1<<12) /* character conversions supported */ 29 | #define CURL_VERSION_CURLDEBUG (1<<13) /* debug memory tracking supported */ 30 | #define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */ 31 | #define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegating to winbind helper */ 32 | 33 | 34 | #define CURLOPTTYPE_LONG 0 35 | #define CURLOPTTYPE_OBJECTPOINT 10000 36 | #define CURLOPTTYPE_FUNCTIONPOINT 20000 37 | #define CURLOPTTYPE_OFF_T 30000 38 | 39 | #define CINIT(%1,%2,%3) CURLOPT_%1 = %2 + %3 40 | 41 | /* three convenient "aliases" that follow the name scheme better */ 42 | #define CURLOPT_WRITEDATA CURLOPT_FILE 43 | #define CURLOPT_READDATA CURLOPT_INFILE 44 | #define CURLOPT_HEADERDATA CURLOPT_WRITEHEADER 45 | #define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER 46 | 47 | /* This was added in version 7.19.1 */ 48 | #define CURLOPT_POST301 CURLOPT_POSTREDIR 49 | 50 | /* The following were added in 7.17.0 */ 51 | #define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD 52 | #define CURLOPT_FTPAPPEND CURLOPT_APPEND 53 | #define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY 54 | #define CURLOPT_FTP_SSL CURLOPT_USE_SSL 55 | 56 | /* The following were added earlier */ 57 | 58 | #define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD 59 | #define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL 60 | 61 | enum CURLoption { 62 | /* This is the FILE * or void * the regular output should be written to. */ 63 | CINIT(FILE, OBJECTPOINT, 1), 64 | 65 | /* The full URL to get/put */ 66 | CINIT(URL, OBJECTPOINT, 2), 67 | 68 | /* Port number to connect to, if other than default. */ 69 | CINIT(PORT, LONG, 3), 70 | 71 | /* Name of proxy to use. */ 72 | CINIT(PROXY, OBJECTPOINT, 4), 73 | 74 | /* "name:password" to use when fetching. */ 75 | CINIT(USERPWD, OBJECTPOINT, 5), 76 | 77 | /* "name:password" to use with proxy. */ 78 | CINIT(PROXYUSERPWD, OBJECTPOINT, 6), 79 | 80 | /* Range to get, specified as an ASCII string. */ 81 | CINIT(RANGE, OBJECTPOINT, 7), 82 | 83 | /* not used */ 84 | 85 | /* Specified file stream to upload from (use as input): */ 86 | CINIT(INFILE, OBJECTPOINT, 9), 87 | 88 | /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE 89 | * bytes big. If this is not used, error messages go to stderr instead: */ 90 | CINIT(ERRORBUFFER, OBJECTPOINT, 10), 91 | 92 | /* Function that will be called to store the output (instead of fwrite). The 93 | * parameters will use fwrite() syntax, make sure to follow them. */ 94 | CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11), 95 | 96 | /* Function that will be called to read the input (instead of fread). The 97 | * parameters will use fread() syntax, make sure to follow them. */ 98 | CINIT(READFUNCTION, FUNCTIONPOINT, 12), 99 | 100 | /* Time-out the read operation after this amount of seconds */ 101 | CINIT(TIMEOUT, LONG, 13), 102 | 103 | /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about 104 | * how large the file being sent really is. That allows better error 105 | * checking and better verifies that the upload was successful. -1 means 106 | * unknown size. 107 | * 108 | * For large file support, there is also a _LARGE version of the key 109 | * which takes an OFF_T type, allowing platforms with larger OFF_T 110 | * sizes to handle larger files. See below for INFILESIZE_LARGE. 111 | */ 112 | CINIT(INFILESIZE, LONG, 14), 113 | 114 | /* POST static input fields. */ 115 | CINIT(POSTFIELDS, OBJECTPOINT, 15), 116 | 117 | /* Set the referrer page (needed by some CGIs) */ 118 | CINIT(REFERER, OBJECTPOINT, 16), 119 | 120 | /* Set the FTP PORT string (interface name, named or numerical IP address) 121 | Use i.e '-' to use default address. */ 122 | CINIT(FTPPORT, OBJECTPOINT, 17), 123 | 124 | /* Set the User-Agent string (examined by some CGIs) */ 125 | CINIT(USERAGENT, OBJECTPOINT, 18), 126 | 127 | /* If the download receives less than "low speed limit" bytes/second 128 | * during "low speed time" seconds, the operations is aborted. 129 | * You could i.e if you have a pretty high speed connection, abort if 130 | * it is less than 2000 bytes/sec during 20 seconds. 131 | */ 132 | 133 | /* Set the "low speed limit" */ 134 | CINIT(LOW_SPEED_LIMIT, LONG, 19), 135 | 136 | /* Set the "low speed time" */ 137 | CINIT(LOW_SPEED_TIME, LONG, 20), 138 | 139 | /* Set the continuation offset. 140 | * 141 | * Note there is also a _LARGE version of this key which uses 142 | * OFF_T types, allowing for large file offsets on platforms which 143 | * use larger-than-32-bit OFF_T's. Look below for RESUME_FROM_LARGE. 144 | */ 145 | CINIT(RESUME_FROM, LONG, 21), 146 | 147 | /* Set cookie in request: */ 148 | CINIT(COOKIE, OBJECTPOINT, 22), 149 | 150 | /* This points to a linked list of headers, struct curl_slist kind */ 151 | CINIT(HTTPHEADER, OBJECTPOINT, 23), 152 | 153 | /* This points to a linked list of post entries, struct curl_httppost */ 154 | CINIT(HTTPPOST, OBJECTPOINT, 24), 155 | 156 | /* name of the file keeping your private SSL-certificate */ 157 | CINIT(SSLCERT, OBJECTPOINT, 25), 158 | 159 | /* password for the SSL or SSH private key */ 160 | CINIT(KEYPASSWD, OBJECTPOINT, 26), 161 | 162 | /* send TYPE parameter? */ 163 | CINIT(CRLF, LONG, 27), 164 | 165 | /* send linked-list of QUOTE commands */ 166 | CINIT(QUOTE, OBJECTPOINT, 28), 167 | 168 | /* send FILE * or void * to store headers to, if you use a callback it 169 | is simply passed to the callback unmodified */ 170 | CINIT(WRITEHEADER, OBJECTPOINT, 29), 171 | 172 | /* point to a file to read the initial cookies from, also enables 173 | "cookie awareness" */ 174 | CINIT(COOKIEFILE, OBJECTPOINT, 31), 175 | 176 | /* What version to specifically try to use. 177 | See CURL_SSLVERSION defines below. */ 178 | CINIT(SSLVERSION, LONG, 32), 179 | 180 | /* What kind of HTTP time condition to use, see defines */ 181 | CINIT(TIMECONDITION, LONG, 33), 182 | 183 | /* Time to use with the above condition. Specified in number of seconds 184 | since 1 Jan 1970 */ 185 | CINIT(TIMEVALUE, LONG, 34), 186 | 187 | /* 35 = OBSOLETE */ 188 | 189 | /* Custom request, for customizing the get command like 190 | HTTP: DELETE, TRACE and others 191 | FTP: to use a different list command 192 | */ 193 | CINIT(CUSTOMREQUEST, OBJECTPOINT, 36), 194 | 195 | /* HTTP request, for odd commands like DELETE, TRACE and others */ 196 | CINIT(STDERR, OBJECTPOINT, 37), 197 | 198 | /* 38 is not used */ 199 | 200 | /* send linked-list of post-transfer QUOTE commands */ 201 | CINIT(POSTQUOTE, OBJECTPOINT, 39), 202 | 203 | /* Pass a pointer to string of the output using full variable-replacement 204 | as described elsewhere. */ 205 | CINIT(WRITEINFO, OBJECTPOINT, 40), /* DEPRECATED, do not use! */ 206 | 207 | CINIT(VERBOSE, LONG, 41), /* talk a lot */ 208 | CINIT(HEADER, LONG, 42), /* throw the header out too */ 209 | CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ 210 | CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ 211 | CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 300 */ 212 | CINIT(UPLOAD, LONG, 46), /* this is an upload */ 213 | CINIT(POST, LONG, 47), /* HTTP POST method */ 214 | CINIT(DIRLISTONLY, LONG, 48), /* bare names when listing directories */ 215 | 216 | CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */ 217 | 218 | /* Specify whether to read the user+password from the .netrc or the URL. 219 | * This must be one of the CURL_NETRC_* enums below. */ 220 | CINIT(NETRC, LONG, 51), 221 | 222 | CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */ 223 | 224 | CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */ 225 | CINIT(PUT, LONG, 54), /* HTTP PUT */ 226 | 227 | /* 55 = OBSOLETE */ 228 | 229 | /* Function that will be called instead of the internal progress display 230 | * function. This function should be defined as the curl_progress_callback 231 | * prototype defines. */ 232 | CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56), 233 | 234 | /* Data passed to the progress callback */ 235 | CINIT(PROGRESSDATA, OBJECTPOINT, 57), 236 | 237 | /* We want the referrer field set automatically when following locations */ 238 | CINIT(AUTOREFERER, LONG, 58), 239 | 240 | /* Port of the proxy, can be set in the proxy string as well with: 241 | "[host]:[port]" */ 242 | CINIT(PROXYPORT, LONG, 59), 243 | 244 | /* size of the POST input data, if strlen() is not good to use */ 245 | CINIT(POSTFIELDSIZE, LONG, 60), 246 | 247 | /* tunnel non-http operations through a HTTP proxy */ 248 | CINIT(HTTPPROXYTUNNEL, LONG, 61), 249 | 250 | /* Set the interface string to use as outgoing network interface */ 251 | CINIT(INTERFACE, OBJECTPOINT, 62), 252 | 253 | /* Set the krb4/5 security level, this also enables krb4/5 awareness. This 254 | * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string 255 | * is set but doesn't match one of these, 'private' will be used. */ 256 | CINIT(KRBLEVEL, OBJECTPOINT, 63), 257 | 258 | /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ 259 | CINIT(SSL_VERIFYPEER, LONG, 64), 260 | 261 | /* The CApath or CAfile used to validate the peer certificate 262 | this option is used only if SSL_VERIFYPEER is true */ 263 | CINIT(CAINFO, OBJECTPOINT, 65), 264 | 265 | /* 66 = OBSOLETE */ 266 | /* 67 = OBSOLETE */ 267 | 268 | /* Maximum number of http redirects to follow */ 269 | CINIT(MAXREDIRS, LONG, 68), 270 | 271 | /* Pass a LONG set to 1 to get the date of the requested document (if 272 | possible)! Pass a zero to shut it off. */ 273 | CINIT(FILETIME, LONG, 69), 274 | 275 | /* This points to a linked list of telnet options */ 276 | CINIT(TELNETOPTIONS, OBJECTPOINT, 70), 277 | 278 | /* Max amount of cached alive connections */ 279 | CINIT(MAXCONNECTS, LONG, 71), 280 | 281 | CINIT(CLOSEPOLICY, LONG, 72), /* DEPRECATED, do not use! */ 282 | 283 | /* 73 = OBSOLETE */ 284 | 285 | /* Set to explicitly use a new connection for the upcoming transfer. 286 | Do not use this unless you're absolutely sure of this, as it makes the 287 | operation slower and is less friendly for the network. */ 288 | CINIT(FRESH_CONNECT, LONG, 74), 289 | 290 | /* Set to explicitly forbid the upcoming transfer's connection to be re-used 291 | when done. Do not use this unless you're absolutely sure of this, as it 292 | makes the operation slower and is less friendly for the network. */ 293 | CINIT(FORBID_REUSE, LONG, 75), 294 | 295 | /* Set to a file name that contains random data for libcurl to use to 296 | seed the random engine when doing SSL connects. */ 297 | CINIT(RANDOM_FILE, OBJECTPOINT, 76), 298 | 299 | /* Set to the Entropy Gathering Daemon socket pathname */ 300 | CINIT(EGDSOCKET, OBJECTPOINT, 77), 301 | 302 | /* Time-out connect operations after this amount of seconds, if connects 303 | are OK within this time, then fine... This only aborts the connect 304 | phase. [Only works on unix-style/SIGALRM operating systems] */ 305 | CINIT(CONNECTTIMEOUT, LONG, 78), 306 | 307 | /* Function that will be called to store headers (instead of fwrite). The 308 | * parameters will use fwrite() syntax, make sure to follow them. */ 309 | CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79), 310 | 311 | /* Set this to force the HTTP request to get back to GET. Only really usable 312 | if POST, PUT or a custom request have been used first. 313 | */ 314 | CINIT(HTTPGET, LONG, 80), 315 | 316 | /* Set if we should verify the Common name from the peer certificate in ssl 317 | * handshake, set 1 to check existence, 2 to ensure that it matches the 318 | * provided hostname. */ 319 | CINIT(SSL_VERIFYHOST, LONG, 81), 320 | 321 | /* Specify which file name to write all known cookies in after completed 322 | operation. Set file name to "-" (dash) to make it go to stdout. */ 323 | CINIT(COOKIEJAR, OBJECTPOINT, 82), 324 | 325 | /* Specify which SSL ciphers to use */ 326 | CINIT(SSL_CIPHER_LIST, OBJECTPOINT, 83), 327 | 328 | /* Specify which HTTP version to use! This must be set to one of the 329 | CURL_HTTP_VERSION* enums set below. */ 330 | CINIT(HTTP_VERSION, LONG, 84), 331 | 332 | /* Specifically switch on or off the FTP engine's use of the EPSV command. By 333 | default, that one will always be attempted before the more traditional 334 | PASV command. */ 335 | CINIT(FTP_USE_EPSV, LONG, 85), 336 | 337 | /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ 338 | CINIT(SSLCERTTYPE, OBJECTPOINT, 86), 339 | 340 | /* name of the file keeping your private SSL-key */ 341 | CINIT(SSLKEY, OBJECTPOINT, 87), 342 | 343 | /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ 344 | CINIT(SSLKEYTYPE, OBJECTPOINT, 88), 345 | 346 | /* crypto engine for the SSL-sub system */ 347 | CINIT(SSLENGINE, OBJECTPOINT, 89), 348 | 349 | /* set the crypto engine for the SSL-sub system as default 350 | the param has no meaning... 351 | */ 352 | CINIT(SSLENGINE_DEFAULT, LONG, 90), 353 | 354 | /* Non-zero value means to use the global dns cache */ 355 | CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */ 356 | 357 | /* DNS cache timeout */ 358 | CINIT(DNS_CACHE_TIMEOUT, LONG, 92), 359 | 360 | /* send linked-list of pre-transfer QUOTE commands */ 361 | CINIT(PREQUOTE, OBJECTPOINT, 93), 362 | 363 | /* set the debug function */ 364 | CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), 365 | 366 | /* set the data for the debug function */ 367 | CINIT(DEBUGDATA, OBJECTPOINT, 95), 368 | 369 | /* mark this as start of a cookie session */ 370 | CINIT(COOKIESESSION, LONG, 96), 371 | 372 | /* The CApath directory used to validate the peer certificate 373 | this option is used only if SSL_VERIFYPEER is true */ 374 | CINIT(CAPATH, OBJECTPOINT, 97), 375 | 376 | /* Instruct libcurl to use a smaller receive buffer */ 377 | CINIT(BUFFERSIZE, LONG, 98), 378 | 379 | /* Instruct libcurl to not use any signal/alarm handlers, even when using 380 | timeouts. This option is useful for multi-threaded applications. 381 | See libcurl-the-guide for more background information. */ 382 | CINIT(NOSIGNAL, LONG, 99), 383 | 384 | /* Provide a CURLShare for mutexing non-ts data */ 385 | CINIT(SHARE, OBJECTPOINT, 100), 386 | 387 | /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), 388 | CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */ 389 | CINIT(PROXYTYPE, LONG, 101), 390 | 391 | /* Set the Accept-Encoding string. Use this to tell a server you would like 392 | the response to be compressed. Before 7.21.6, this was known as 393 | CURLOPT_ENCODING */ 394 | CINIT(ACCEPT_ENCODING, OBJECTPOINT, 102), 395 | 396 | /* Set pointer to private data */ 397 | CINIT(PRIVATE, OBJECTPOINT, 103), 398 | 399 | /* Set aliases for HTTP 200 in the HTTP Response header */ 400 | CINIT(HTTP200ALIASES, OBJECTPOINT, 104), 401 | 402 | /* Continue to send authentication (user+password) when following locations, 403 | even when hostname changed. This can potentially send off the name 404 | and password to whatever host the server decides. */ 405 | CINIT(UNRESTRICTED_AUTH, LONG, 105), 406 | 407 | /* Specifically switch on or off the FTP engine's use of the EPRT command ( 408 | it also disables the LPRT attempt). By default, those ones will always be 409 | attempted before the good old traditional PORT command. */ 410 | CINIT(FTP_USE_EPRT, LONG, 106), 411 | 412 | /* Set this to a bitmask value to enable the particular authentications 413 | methods you like. Use this in combination with CURLOPT_USERPWD. 414 | Note that setting multiple bits may cause extra network round-trips. */ 415 | CINIT(HTTPAUTH, LONG, 107), 416 | 417 | /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx 418 | in second argument. The function must be matching the 419 | curl_ssl_ctx_callback proto. */ 420 | CINIT(SSL_CTX_FUNC, FUNCTIONPOINT, 108), 421 | 422 | /* Set the userdata for the ssl context callback function's third 423 | argument */ 424 | CINIT(SSL_CTX_DATA, OBJECTPOINT, 109), 425 | 426 | /* FTP Option that causes missing dirs to be created on the remote server. 427 | In 7.19.4 we introduced the convenience enums for this option using the 428 | CURLFTP_CREATE_DIR prefix. 429 | */ 430 | CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110), 431 | 432 | /* Set this to a bitmask value to enable the particular authentications 433 | methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. 434 | Note that setting multiple bits may cause extra network round-trips. */ 435 | CINIT(PROXYAUTH, LONG, 111), 436 | 437 | /* FTP option that changes the timeout, in seconds, associated with 438 | getting a response. This is different from transfer timeout time and 439 | essentially places a demand on the FTP server to acknowledge commands 440 | in a timely manner. */ 441 | CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112), 442 | #define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT 443 | 444 | /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to 445 | tell libcurl to resolve names to those IP versions only. This only has 446 | affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ 447 | CINIT(IPRESOLVE, LONG, 113), 448 | 449 | /* Set this option to limit the size of a file that will be downloaded from 450 | an HTTP or FTP server. 451 | 452 | Note there is also _LARGE version which adds large file support for 453 | platforms which have larger OFF_T sizes. See MAXFILESIZE_LARGE below. */ 454 | CINIT(MAXFILESIZE, LONG, 114), 455 | 456 | /* See the comment for INFILESIZE above, but in short, specifies 457 | * the size of the file being uploaded. -1 means unknown. 458 | */ 459 | CINIT(INFILESIZE_LARGE, OFF_T, 115), 460 | 461 | /* Sets the continuation offset. There is also a LONG version of this; 462 | * look above for RESUME_FROM. 463 | */ 464 | CINIT(RESUME_FROM_LARGE, OFF_T, 116), 465 | 466 | /* Sets the maximum size of data that will be downloaded from 467 | * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. 468 | */ 469 | CINIT(MAXFILESIZE_LARGE, OFF_T, 117), 470 | 471 | /* Set this option to the file name of your .netrc file you want libcurl 472 | to parse (using the CURLOPT_NETRC option). If not set, libcurl will do 473 | a poor attempt to find the user's home directory and check for a .netrc 474 | file in there. */ 475 | CINIT(NETRC_FILE, OBJECTPOINT, 118), 476 | 477 | /* Enable SSL/TLS for FTP, pick one of: 478 | CURLFTPSSL_TRY - try using SSL, proceed anyway otherwise 479 | CURLFTPSSL_CONTROL - SSL for the control connection or fail 480 | CURLFTPSSL_ALL - SSL for all communication or fail 481 | */ 482 | CINIT(USE_SSL, LONG, 119), 483 | 484 | /* The _LARGE version of the standard POSTFIELDSIZE option */ 485 | CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120), 486 | 487 | /* Enable/disable the TCP Nagle algorithm */ 488 | CINIT(TCP_NODELAY, LONG, 121), 489 | 490 | /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ 491 | /* 123 OBSOLETE. Gone in 7.16.0 */ 492 | /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ 493 | /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ 494 | /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ 495 | /* 127 OBSOLETE. Gone in 7.16.0 */ 496 | /* 128 OBSOLETE. Gone in 7.16.0 */ 497 | 498 | /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option 499 | can be used to change libcurl's default action which is to first try 500 | "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK 501 | response has been received. 502 | 503 | Available parameters are: 504 | CURLFTPAUTH_DEFAULT - let libcurl decide 505 | CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS 506 | CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL 507 | */ 508 | CINIT(FTPSSLAUTH, LONG, 129), 509 | 510 | CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130), 511 | CINIT(IOCTLDATA, OBJECTPOINT, 131), 512 | 513 | /* 132 OBSOLETE. Gone in 7.16.0 */ 514 | /* 133 OBSOLETE. Gone in 7.16.0 */ 515 | 516 | /* zero terminated string for pass on to the FTP server when asked for 517 | "account" info */ 518 | CINIT(FTP_ACCOUNT, OBJECTPOINT, 134), 519 | 520 | /* feed cookies into cookie engine */ 521 | CINIT(COOKIELIST, OBJECTPOINT, 135), 522 | 523 | /* ignore Content-Length */ 524 | CINIT(IGNORE_CONTENT_LENGTH, LONG, 136), 525 | 526 | /* Set to non-zero to skip the IP address received in a 227 PASV FTP server 527 | response. Typically used for FTP-SSL purposes but is not restricted to 528 | that. libcurl will then instead use the same IP address it used for the 529 | control connection. */ 530 | CINIT(FTP_SKIP_PASV_IP, LONG, 137), 531 | 532 | /* Select "file method" to use when doing FTP, see the curl_ftpmethod 533 | above. */ 534 | CINIT(FTP_FILEMETHOD, LONG, 138), 535 | 536 | /* Local port number to bind the socket to */ 537 | CINIT(LOCALPORT, LONG, 139), 538 | 539 | /* Number of ports to try, including the first one set with LOCALPORT. 540 | Thus, setting it to 1 will make no additional attempts but the first. 541 | */ 542 | CINIT(LOCALPORTRANGE, LONG, 140), 543 | 544 | /* no transfer, set up connection and let application use the socket by 545 | extracting it with CURLINFO_LASTSOCKET */ 546 | CINIT(CONNECT_ONLY, LONG, 141), 547 | 548 | /* Function that will be called to convert from the 549 | network encoding (instead of using the iconv calls in libcurl) */ 550 | CINIT(CONV_FROM_NETWORK_FUNC, FUNCTIONPOINT, 142), 551 | 552 | /* Function that will be called to convert to the 553 | network encoding (instead of using the iconv calls in libcurl) */ 554 | CINIT(CONV_TO_NETWORK_FUNC, FUNCTIONPOINT, 143), 555 | 556 | /* Function that will be called to convert from UTF8 557 | (instead of using the iconv calls in libcurl) 558 | Note that this is used only for SSL certificate processing */ 559 | CINIT(CONV_FROM_UTF8_FUNC, FUNCTIONPOINT, 144), 560 | 561 | /* if the connection proceeds too quickly then need to slow it down */ 562 | /* limit-rate: maximum number of bytes per second to send or receive */ 563 | CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145), 564 | CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146), 565 | 566 | /* Pointer to command string to send if USER/PASS fails. */ 567 | CINIT(FTP_ALTERNATIVE_TO_USER, OBJECTPOINT, 147), 568 | 569 | /* callback function for setting socket options */ 570 | CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148), 571 | CINIT(SOCKOPTDATA, OBJECTPOINT, 149), 572 | 573 | /* set to 0 to disable session ID re-use for this transfer, default is 574 | enabled (== 1) */ 575 | CINIT(SSL_SESSIONID_CACHE, LONG, 150), 576 | 577 | /* allowed SSH authentication methods */ 578 | CINIT(SSH_AUTH_TYPES, LONG, 151), 579 | 580 | /* Used by scp/sftp to do public/private key authentication */ 581 | CINIT(SSH_PUBLIC_KEYFILE, OBJECTPOINT, 152), 582 | CINIT(SSH_PRIVATE_KEYFILE, OBJECTPOINT, 153), 583 | 584 | /* Send CCC (Clear Command Channel) after authentication */ 585 | CINIT(FTP_SSL_CCC, LONG, 154), 586 | 587 | /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ 588 | CINIT(TIMEOUT_MS, LONG, 155), 589 | CINIT(CONNECTTIMEOUT_MS, LONG, 156), 590 | 591 | /* set to zero to disable the libcurl's decoding and thus pass the raw body 592 | data to the application even when it is encoded/compressed */ 593 | CINIT(HTTP_TRANSFER_DECODING, LONG, 157), 594 | CINIT(HTTP_CONTENT_DECODING, LONG, 158), 595 | 596 | /* Permission used when creating new files and directories on the remote 597 | server for protocols that support it, SFTP/SCP/FILE */ 598 | CINIT(NEW_FILE_PERMS, LONG, 159), 599 | CINIT(NEW_DIRECTORY_PERMS, LONG, 160), 600 | 601 | /* Set the behaviour of POST when redirecting. Values must be set to one 602 | of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ 603 | CINIT(POSTREDIR, LONG, 161), 604 | 605 | /* used by scp/sftp to verify the host's public key */ 606 | CINIT(SSH_HOST_PUBLIC_KEY_MD5, OBJECTPOINT, 162), 607 | 608 | /* Callback function for opening socket (instead of socket(2)). Optionally, 609 | callback is able change the address or refuse to connect returning 610 | CURL_SOCKET_BAD. The callback should have type 611 | curl_opensocket_callback */ 612 | CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163), 613 | CINIT(OPENSOCKETDATA, OBJECTPOINT, 164), 614 | 615 | /* POST volatile input fields. */ 616 | CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165), 617 | 618 | /* set transfer mode (;type=) when doing FTP via an HTTP proxy */ 619 | CINIT(PROXY_TRANSFER_MODE, LONG, 166), 620 | 621 | /* Callback function for seeking in the input stream */ 622 | CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167), 623 | CINIT(SEEKDATA, OBJECTPOINT, 168), 624 | 625 | /* CRL file */ 626 | CINIT(CRLFILE, OBJECTPOINT, 169), 627 | 628 | /* Issuer certificate */ 629 | CINIT(ISSUERCERT, OBJECTPOINT, 170), 630 | 631 | /* (IPv6) Address scope */ 632 | CINIT(ADDRESS_SCOPE, LONG, 171), 633 | 634 | /* Collect certificate chain info and allow it to get retrievable with 635 | CURLINFO_CERTINFO after the transfer is complete. (Unfortunately) only 636 | working with OpenSSL-powered builds. */ 637 | CINIT(CERTINFO, LONG, 172), 638 | 639 | /* "name" and "pwd" to use when fetching. */ 640 | CINIT(USERNAME, OBJECTPOINT, 173), 641 | CINIT(PASSWORD, OBJECTPOINT, 174), 642 | 643 | /* "name" and "pwd" to use with Proxy when fetching. */ 644 | CINIT(PROXYUSERNAME, OBJECTPOINT, 175), 645 | CINIT(PROXYPASSWORD, OBJECTPOINT, 176), 646 | 647 | /* Comma separated list of hostnames defining no-proxy zones. These should 648 | match both hostnames directly, and hostnames within a domain. For 649 | example, local.com will match local.com and www.local.com, but NOT 650 | notlocal.com or www.notlocal.com. For compatibility with other 651 | implementations of this, .local.com will be considered to be the same as 652 | local.com. A single * is the only valid wildcard, and effectively 653 | disables the use of proxy. */ 654 | CINIT(NOPROXY, OBJECTPOINT, 177), 655 | 656 | /* block size for TFTP transfers */ 657 | CINIT(TFTP_BLKSIZE, LONG, 178), 658 | 659 | /* Socks Service */ 660 | CINIT(SOCKS5_GSSAPI_SERVICE, OBJECTPOINT, 179), 661 | 662 | /* Socks Service */ 663 | CINIT(SOCKS5_GSSAPI_NEC, LONG, 180), 664 | 665 | /* set the bitmask for the protocols that are allowed to be used for the 666 | transfer, which thus helps the app which takes URLs from users or other 667 | external inputs and want to restrict what protocol(s) to deal 668 | with. Defaults to CURLPROTO_ALL. */ 669 | CINIT(PROTOCOLS, LONG, 181), 670 | 671 | /* set the bitmask for the protocols that libcurl is allowed to follow to, 672 | as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs 673 | to be set in both bitmasks to be allowed to get redirected to. Defaults 674 | to all protocols except FILE and SCP. */ 675 | CINIT(REDIR_PROTOCOLS, LONG, 182), 676 | 677 | /* set the SSH knownhost file name to use */ 678 | CINIT(SSH_KNOWNHOSTS, OBJECTPOINT, 183), 679 | 680 | /* set the SSH host key callback, must point to a curl_sshkeycallback 681 | function */ 682 | CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184), 683 | 684 | /* set the SSH host key callback custom pointer */ 685 | CINIT(SSH_KEYDATA, OBJECTPOINT, 185), 686 | 687 | /* set the SMTP mail originator */ 688 | CINIT(MAIL_FROM, OBJECTPOINT, 186), 689 | 690 | /* set the SMTP mail receiver(s) */ 691 | CINIT(MAIL_RCPT, OBJECTPOINT, 187), 692 | 693 | /* FTP: send PRET before PASV */ 694 | CINIT(FTP_USE_PRET, LONG, 188), 695 | 696 | /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */ 697 | CINIT(RTSP_REQUEST, LONG, 189), 698 | 699 | /* The RTSP session identifier */ 700 | CINIT(RTSP_SESSION_ID, OBJECTPOINT, 190), 701 | 702 | /* The RTSP stream URI */ 703 | CINIT(RTSP_STREAM_URI, OBJECTPOINT, 191), 704 | 705 | /* The Transport: header to use in RTSP requests */ 706 | CINIT(RTSP_TRANSPORT, OBJECTPOINT, 192), 707 | 708 | /* Manually initialize the client RTSP CSeq for this handle */ 709 | CINIT(RTSP_CLIENT_CSEQ, LONG, 193), 710 | 711 | /* Manually initialize the server RTSP CSeq for this handle */ 712 | CINIT(RTSP_SERVER_CSEQ, LONG, 194), 713 | 714 | /* The stream to pass to INTERLEAVEFUNCTION. */ 715 | CINIT(INTERLEAVEDATA, OBJECTPOINT, 195), 716 | 717 | /* Let the application define a custom write method for RTP data */ 718 | CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196), 719 | 720 | /* Turn on wildcard matching */ 721 | CINIT(WILDCARDMATCH, LONG, 197), 722 | 723 | /* Directory matching callback called before downloading of an 724 | individual file (chunk) started */ 725 | CINIT(CHUNK_BGN_FUNC, FUNCTIONPOINT, 198), 726 | 727 | /* Directory matching callback called after the file (chunk) 728 | was downloaded, or skipped */ 729 | CINIT(CHUNK_END_FUNC, FUNCTIONPOINT, 199), 730 | 731 | /* Change match (fnmatch-like) callback for wildcard matching */ 732 | CINIT(FNMATCH_FUNC, FUNCTIONPOINT, 200), 733 | 734 | /* Let the application define custom chunk data pointer */ 735 | CINIT(CHUNK_DATA, OBJECTPOINT, 201), 736 | 737 | /* FNMATCH_FUNC user pointer */ 738 | CINIT(FNMATCH_DATA, OBJECTPOINT, 202), 739 | 740 | /* send linked-list of name:port:address sets */ 741 | CINIT(RESOLVE, OBJECTPOINT, 203), 742 | 743 | /* Set a username for authenticated TLS */ 744 | CINIT(TLSAUTH_USERNAME, OBJECTPOINT, 204), 745 | 746 | /* Set a password for authenticated TLS */ 747 | CINIT(TLSAUTH_PASSWORD, OBJECTPOINT, 205), 748 | 749 | /* Set authentication type for authenticated TLS */ 750 | CINIT(TLSAUTH_TYPE, OBJECTPOINT, 206), 751 | 752 | /* Set to 1 to enable the "TE:" header in HTTP requests to ask for 753 | compressed transfer-encoded responses. Set to 0 to disable the use of TE: 754 | in outgoing requests. The current default is 0, but it might change in a 755 | future libcurl release. 756 | 757 | libcurl will ask for the compressed methods it knows of, and if that 758 | isn't any, it will not ask for transfer-encoding at all even if this 759 | option is set to 1. 760 | 761 | */ 762 | CINIT(TRANSFER_ENCODING, LONG, 207), 763 | 764 | /* Callback function for closing socket (instead of close(2)). The callback 765 | should have type curl_closesocket_callback */ 766 | CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208), 767 | CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209), 768 | 769 | /* allow GSSAPI credential delegation */ 770 | CINIT(GSSAPI_DELEGATION, LONG, 210), 771 | 772 | CURLOPT_LASTENTRY /* the last unused */ 773 | }; 774 | 775 | 776 | enum CURLcode { 777 | CURLE_OK = 0, 778 | CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ 779 | CURLE_FAILED_INIT, /* 2 */ 780 | CURLE_URL_MALFORMAT, /* 3 */ 781 | CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for 782 | 7.17.0, reused in April 2011 for 7.21.5] */ 783 | CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ 784 | CURLE_COULDNT_RESOLVE_HOST, /* 6 */ 785 | CURLE_COULDNT_CONNECT, /* 7 */ 786 | CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */ 787 | CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server 788 | due to lack of access - when login fails 789 | this is not returned. */ 790 | CURLE_OBSOLETE10, /* 10 - NOT USED */ 791 | CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ 792 | CURLE_OBSOLETE12, /* 12 - NOT USED */ 793 | CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ 794 | CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ 795 | CURLE_FTP_CANT_GET_HOST, /* 15 */ 796 | CURLE_OBSOLETE16, /* 16 - NOT USED */ 797 | CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ 798 | CURLE_PARTIAL_FILE, /* 18 */ 799 | CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ 800 | CURLE_OBSOLETE20, /* 20 - NOT USED */ 801 | CURLE_QUOTE_ERROR, /* 21 - quote command failure */ 802 | CURLE_HTTP_RETURNED_ERROR, /* 22 */ 803 | CURLE_WRITE_ERROR, /* 23 */ 804 | CURLE_OBSOLETE24, /* 24 - NOT USED */ 805 | CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ 806 | CURLE_READ_ERROR, /* 26 - couldn't open/read from file */ 807 | CURLE_OUT_OF_MEMORY, /* 27 */ 808 | /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error 809 | instead of a memory allocation error if CURL_DOES_CONVERSIONS 810 | is defined 811 | */ 812 | CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */ 813 | CURLE_OBSOLETE29, /* 29 - NOT USED */ 814 | CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ 815 | CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ 816 | CURLE_OBSOLETE32, /* 32 - NOT USED */ 817 | CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ 818 | CURLE_HTTP_POST_ERROR, /* 34 */ 819 | CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ 820 | CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ 821 | CURLE_FILE_COULDNT_READ_FILE, /* 37 */ 822 | CURLE_LDAP_CANNOT_BIND, /* 38 */ 823 | CURLE_LDAP_SEARCH_FAILED, /* 39 */ 824 | CURLE_OBSOLETE40, /* 40 - NOT USED */ 825 | CURLE_FUNCTION_NOT_FOUND, /* 41 */ 826 | CURLE_ABORTED_BY_CALLBACK, /* 42 */ 827 | CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ 828 | CURLE_OBSOLETE44, /* 44 - NOT USED */ 829 | CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ 830 | CURLE_OBSOLETE46, /* 46 - NOT USED */ 831 | CURLE_TOO_MANY_REDIRECTS , /* 47 - catch endless re-direct loops */ 832 | CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */ 833 | CURLE_TELNET_OPTION_SYNTAX , /* 49 - Malformed telnet option */ 834 | CURLE_OBSOLETE50, /* 50 - NOT USED */ 835 | CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint 836 | wasn't verified fine */ 837 | CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ 838 | CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ 839 | CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as 840 | default */ 841 | CURLE_SEND_ERROR, /* 55 - failed sending network data */ 842 | CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ 843 | CURLE_OBSOLETE57, /* 57 - NOT IN USE */ 844 | CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ 845 | CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ 846 | CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ 847 | CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */ 848 | CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ 849 | CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ 850 | CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ 851 | CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind 852 | that failed */ 853 | CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ 854 | CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not 855 | accepted and we failed to login */ 856 | CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ 857 | CURLE_TFTP_PERM, /* 69 - permission problem on server */ 858 | CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */ 859 | CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ 860 | CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ 861 | CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ 862 | CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ 863 | CURLE_CONV_FAILED, /* 75 - conversion failed */ 864 | CURLE_CONV_REQD, /* 76 - caller must register conversion 865 | callbacks using curl_easy_setopt options 866 | CURLOPT_CONV_FROM_NETWORK_FUNCTION, 867 | CURLOPT_CONV_TO_NETWORK_FUNCTION, and 868 | CURLOPT_CONV_FROM_UTF8_FUNCTION */ 869 | CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing 870 | or wrong format */ 871 | CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ 872 | CURLE_SSH, /* 79 - error from the SSH layer, somewhat 873 | generic so the error message will be of 874 | interest when this has happened */ 875 | 876 | CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL 877 | connection */ 878 | CURLE_AGAIN, /* 81 - socket is not ready for send/recv, 879 | wait till it's ready and try again (Added 880 | in 7.18.2) */ 881 | CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or 882 | wrong format (Added in 7.19.0) */ 883 | CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in 884 | 7.19.0) */ 885 | CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */ 886 | CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */ 887 | CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */ 888 | CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */ 889 | CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */ 890 | 891 | CURL_LAST /* never use! */ 892 | }; 893 | 894 | /* compatibility with older names */ 895 | #define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING 896 | 897 | /* The following were added in 7.21.5, April 2011 */ 898 | #define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION 899 | 900 | enum curl_TimeCond { 901 | CURL_TIMECOND_NONE, 902 | 903 | CURL_TIMECOND_IFMODSINCE, 904 | CURL_TIMECOND_IFUNMODSINCE, 905 | CURL_TIMECOND_LASTMOD, 906 | 907 | CURL_TIMECOND_LAST 908 | }; 909 | 910 | /* These enums are for use with the CURLOPT_NETRC option. */ 911 | enum CURL_NETRC_OPTION { 912 | CURL_NETRC_IGNORED, /* The .netrc will never be read. 913 | * This is the default. */ 914 | CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred 915 | * to one in the .netrc. */ 916 | CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored. 917 | * Unless one is set programmatically, the .netrc 918 | * will be queried. */ 919 | CURL_NETRC_LAST 920 | }; 921 | 922 | enum curl_closepolicy { 923 | CURLCLOSEPOLICY_NONE, /* first, never use this */ 924 | 925 | CURLCLOSEPOLICY_OLDEST, 926 | CURLCLOSEPOLICY_LEAST_RECENTLY, // CURLCLOSEPOLICY_LEAST_RECENTLY_USED 927 | CURLCLOSEPOLICY_LEAST_TRAFFIC, 928 | CURLCLOSEPOLICY_SLOWEST, 929 | CURLCLOSEPOLICY_CALLBACK, 930 | 931 | CURLCLOSEPOLICY_LAST /* last, never use this */ 932 | }; 933 | 934 | enum { 935 | CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd 936 | like the library to choose the best possible 937 | for us! */ 938 | CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ 939 | CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ 940 | 941 | CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ 942 | }; 943 | 944 | 945 | #define CURLAUTH_NONE 0 /* nothing */ 946 | #define CURLAUTH_BASIC (1<<0) /* Basic (default) */ 947 | #define CURLAUTH_DIGEST (1<<1) /* Digest */ 948 | #define CURLAUTH_GSSNEGOTIATE (1<<2) /* GSS-Negotiate */ 949 | #define CURLAUTH_NTLM (1<<3) /* NTLM */ 950 | #define CURLAUTH_DIGEST_IE (1<<4) /* Digest with IE flavour */ 951 | #define CURLAUTH_NTLM_WB (1<<5) /* NTLM delegating to winbind helper */ 952 | #define CURLAUTH_ONLY (1<<31) /* used together with a single other 953 | type to force no auth or just that 954 | single type */ 955 | #define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) /* all fine types set */ 956 | #define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) 957 | 958 | 959 | /* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */ 960 | enum curl_ftpcreatedir { 961 | CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */ 962 | CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD 963 | again if MKD succeeded, for SFTP this does 964 | similar magic */ 965 | CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD 966 | again even if MKD failed! */ 967 | CURLFTP_CREATE_DIR_LAST /* not an option, never use */ 968 | }; 969 | 970 | 971 | /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host 972 | name resolves addresses using more than one IP protocol version, this 973 | option might be handy to force libcurl to use a specific IP version. */ 974 | #define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP 975 | versions that your system allows */ 976 | #define CURL_IPRESOLVE_V4 1 /* resolve to ipv4 addresses */ 977 | #define CURL_IPRESOLVE_V6 2 /* resolve to ipv6 addresses */ 978 | 979 | 980 | /* parameter for the CURLOPT_USE_SSL option */ 981 | enum curl_usessl { 982 | CURLUSESSL_NONE, /* do not attempt to use SSL */ 983 | CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */ 984 | CURLUSESSL_CONTROL, /* SSL for the control connection or fail */ 985 | CURLUSESSL_ALL, /* SSL for all communication or fail */ 986 | CURLUSESSL_LAST /* not an option, never use */ 987 | }; 988 | 989 | 990 | enum { 991 | CURL_SSLVERSION_DEFAULT, 992 | CURL_SSLVERSION_TLSv1, 993 | CURL_SSLVERSION_SSLv2, 994 | CURL_SSLVERSION_SSLv3, 995 | 996 | CURL_SSLVERSION_LAST /* never use, keep last */ 997 | }; 998 | 999 | 1000 | /* parameter for the CURLOPT_FTPSSLAUTH option */ 1001 | enum curl_ftpauth { 1002 | CURLFTPAUTH_DEFAULT, /* let libcurl decide */ 1003 | CURLFTPAUTH_SSL, /* use "AUTH SSL" */ 1004 | CURLFTPAUTH_TLS, /* use "AUTH TLS" */ 1005 | CURLFTPAUTH_LAST /* not an option, never use */ 1006 | }; 1007 | 1008 | 1009 | enum curl_ftpfile { 1010 | FTPFILE_MULTICWD = 1, /* as defined by RFC1738 */ 1011 | FTPFILE_NOCWD = 2, /* use SIZE / RETR / STOR on the full path */ 1012 | FTPFILE_SINGLECWD = 3 /* make one CWD, then SIZE / RETR / STOR on the file */ 1013 | }; 1014 | 1015 | 1016 | #define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ 1017 | #define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ 1018 | #define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */ 1019 | #define CURLSSH_AUTH_PASSWORD (1<<1) /* password */ 1020 | #define CURLSSH_AUTH_HOST (1<<2) /* host key files */ 1021 | #define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ 1022 | #define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY 1023 | 1024 | #define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */ 1025 | #define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */ 1026 | #define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */ 1027 | 1028 | 1029 | /* parameter for the CURLOPT_FTP_SSL_CCC option */ 1030 | enum curl_ftpccc { 1031 | CURLFTPSSL_CCC_NONE, /* do not send CCC */ 1032 | CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */ 1033 | CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */ 1034 | CURLFTPSSL_CCC_LAST /* not an option, never use */ 1035 | }; 1036 | 1037 | 1038 | /* symbols to use with CURLOPT_POSTREDIR. 1039 | CURL_REDIR_POST_301 and CURL_REDIR_POST_302 can be bitwise ORed so that 1040 | CURL_REDIR_POST_301 | CURL_REDIR_POST_302 == CURL_REDIR_POST_ALL */ 1041 | 1042 | #define CURL_REDIR_GET_ALL 0 1043 | #define CURL_REDIR_POST_301 1 1044 | #define CURL_REDIR_POST_302 2 1045 | #define CURL_REDIR_POST_ALL (CURL_REDIR_POST_301|CURL_REDIR_POST_302) 1046 | 1047 | 1048 | /* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */ 1049 | #define CURLPROTO_HTTP (1<<0) 1050 | #define CURLPROTO_HTTPS (1<<1) 1051 | #define CURLPROTO_FTP (1<<2) 1052 | #define CURLPROTO_FTPS (1<<3) 1053 | #define CURLPROTO_SCP (1<<4) 1054 | #define CURLPROTO_SFTP (1<<5) 1055 | #define CURLPROTO_TELNET (1<<6) 1056 | #define CURLPROTO_LDAP (1<<7) 1057 | #define CURLPROTO_LDAPS (1<<8) 1058 | #define CURLPROTO_DICT (1<<9) 1059 | #define CURLPROTO_FILE (1<<10) 1060 | #define CURLPROTO_TFTP (1<<11) 1061 | #define CURLPROTO_IMAP (1<<12) 1062 | #define CURLPROTO_IMAPS (1<<13) 1063 | #define CURLPROTO_POP3 (1<<14) 1064 | #define CURLPROTO_POP3S (1<<15) 1065 | #define CURLPROTO_SMTP (1<<16) 1066 | #define CURLPROTO_SMTPS (1<<17) 1067 | #define CURLPROTO_RTSP (1<<18) 1068 | #define CURLPROTO_RTMP (1<<19) 1069 | #define CURLPROTO_RTMPT (1<<20) 1070 | #define CURLPROTO_RTMPE (1<<21) 1071 | #define CURLPROTO_RTMPTE (1<<22) 1072 | #define CURLPROTO_RTMPS (1<<23) 1073 | #define CURLPROTO_RTMPTS (1<<24) 1074 | #define CURLPROTO_GOPHER (1<<25) 1075 | #define CURLPROTO_ALL (~0) /* enable everything */ 1076 | 1077 | 1078 | /* 1079 | * Public API enums for RTSP requests 1080 | */ 1081 | enum { 1082 | CURL_RTSPREQ_NONE, /* first in list */ 1083 | CURL_RTSPREQ_OPTIONS, 1084 | CURL_RTSPREQ_DESCRIBE, 1085 | CURL_RTSPREQ_ANNOUNCE, 1086 | CURL_RTSPREQ_SETUP, 1087 | CURL_RTSPREQ_PLAY, 1088 | CURL_RTSPREQ_PAUSE, 1089 | CURL_RTSPREQ_TEARDOWN, 1090 | CURL_RTSPREQ_GET_PARAMETER, 1091 | CURL_RTSPREQ_SET_PARAMETER, 1092 | CURL_RTSPREQ_RECORD, 1093 | CURL_RTSPREQ_RECEIVE, 1094 | CURL_RTSPREQ_LAST /* last in list */ 1095 | }; 1096 | 1097 | 1098 | 1099 | #define CURLINFO_STRING 0x100000 1100 | #define CURLINFO_LONG 0x200000 1101 | #define CURLINFO_DOUBLE 0x300000 1102 | #define CURLINFO_SLIST 0x400000 1103 | #define CURLINFO_MASK 0x0fffff 1104 | #define CURLINFO_TYPEMASK 0xf00000 1105 | 1106 | enum CURLINFO { 1107 | CURLINFO_NONE, /* first, never use this */ 1108 | CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, 1109 | CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, 1110 | CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, 1111 | CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, 1112 | CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, 1113 | CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, 1114 | CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, 1115 | CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, 1116 | CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, 1117 | CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, 1118 | CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, 1119 | CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, 1120 | CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, 1121 | CURLINFO_FILETIME = CURLINFO_LONG + 14, 1122 | CURLINFO_CONTENT_LEN_DOWNLOAD = CURLINFO_DOUBLE + 15, 1123 | CURLINFO_CONTENT_LEN_UPLOAD = CURLINFO_DOUBLE + 16, 1124 | CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, 1125 | CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, 1126 | CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, 1127 | CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, 1128 | CURLINFO_PRIVATE = CURLINFO_STRING + 21, 1129 | CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, 1130 | CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, 1131 | CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, 1132 | CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, 1133 | CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, 1134 | CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, 1135 | CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, 1136 | CURLINFO_LASTSOCKET = CURLINFO_LONG + 29, 1137 | CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, 1138 | CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, 1139 | CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, 1140 | CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, 1141 | CURLINFO_CERTINFO = CURLINFO_SLIST + 34, 1142 | CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, 1143 | CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36, 1144 | CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, 1145 | CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38, 1146 | CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39, 1147 | CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, 1148 | CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, 1149 | CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, 1150 | /* Fill in new entries below here! */ 1151 | 1152 | CURLINFO_LASTONE = 42 1153 | }; 1154 | 1155 | 1156 | enum curl_proxytype { 1157 | CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use 1158 | CONNECT HTTP/1.1 */ 1159 | CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT 1160 | HTTP/1.0 */ 1161 | CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already 1162 | in 7.10 */ 1163 | CURLPROXY_SOCKS5 = 5, /* added in 7.10 */ 1164 | CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */ 1165 | CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the 1166 | host name rather than the IP address. added 1167 | in 7.18.0 */ 1168 | }; 1169 | 1170 | 1171 | enum CURLformoption { 1172 | CURLFORM_NOTHING, /********* the first one is unused ************/ 1173 | /* */ 1174 | CURLFORM_COPYNAME, // char 1175 | CURLFORM_PTRNAME, // not support 1176 | CURLFORM_NAMELENGTH, // long 1177 | CURLFORM_COPYCONTENTS, // char 1178 | CURLFORM_PTRCONTENTS, // not support 1179 | CURLFORM_CONTENTSLENGTH, // long 1180 | CURLFORM_FILECONTENT, // char 1181 | CURLFORM_ARRAY, // not support 1182 | CURLFORM_OBSOLETE, 1183 | CURLFORM_FILE, // char 1184 | CURLFORM_BUFFER, // not support 1185 | CURLFORM_BUFFERPTR, // not support 1186 | CURLFORM_BUFFERLENGTH, // not support 1187 | CURLFORM_CONTENTTYPE, // char 1188 | CURLFORM_CONTENTHEADER, // curl_slist 1189 | CURLFORM_FILENAME, // char 1190 | CURLFORM_END, // !! 1191 | CURLFORM_OBSOLETE2, 1192 | CURLFORM_STREAM, // not support 1193 | CURLFORM_LASTENTRY /* the last unused */ 1194 | }; 1195 | 1196 | enum CURLFORMcode { 1197 | CURL_FORMADD_OK, /* first, no error */ 1198 | CURL_FORMADD_MEMORY, 1199 | CURL_FORMADD_OPTION_TWICE, 1200 | CURL_FORMADD_NULL, 1201 | CURL_FORMADD_UNKNOWN_OPTION, 1202 | CURL_FORMADD_INCOMPLETE, 1203 | CURL_FORMADD_ILLEGAL_ARRAY, 1204 | CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */ 1205 | CURL_FORMADD_LAST /* last */ 1206 | }; 1207 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/include/discord.inc: -------------------------------------------------------------------------------- 1 | #if defined _discord_included 2 | #endinput 3 | #endif 4 | #define _discord_included 5 | 6 | native void Discord_SendMessage(const char[] webhook, const char[] message); 7 | 8 | public SharedPlugin __pl_discord = 9 | { 10 | name = "discord", 11 | file = "discord.smx", 12 | #if defined REQUIRE_PLUGIN 13 | required = 1, 14 | #else 15 | required = 0, 16 | #endif 17 | }; 18 | 19 | #if !defined REQUIRE_PLUGIN 20 | 21 | public __pl_discord_SetNTVOptional() { 22 | MarkNativeAsOptional("Discord_SendMessage"); 23 | } 24 | 25 | #endif 26 | 27 | stock void Discord_EscapeString(char[] string, int maxlen) { 28 | ReplaceString(string, maxlen, "@", "@"); 29 | ReplaceString(string, maxlen, "'", "'"); 30 | ReplaceString(string, maxlen, "\"", """); 31 | } 32 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/include/easyftp.inc: -------------------------------------------------------------------------------- 1 | #if defined _teftp_included_ 2 | #endinput 3 | #endif 4 | #define _teftp_included_ 5 | 6 | 7 | typedef EasyFTP_FileUploaded = function void(const char[] sTarget, const char[] sLocalFile, const char[] sRemoteFile, int iErrorCode, any data); 8 | native void EasyFTP_UploadFile(const char[] sTarget, const char[] sLocalFile, const char[] sRemoteFile, EasyFTP_FileUploaded func, any data = 0); -------------------------------------------------------------------------------- /addons/sourcemod/scripting/tAutoDemoUpload.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | #include 3 | #include 4 | #undef REQUIRE_EXTENSIONS 5 | #include 6 | 7 | #define VERSION "0.0.4" 8 | 9 | new Handle:g_hCvarEnabled = INVALID_HANDLE; 10 | new bool:g_bEnabled = false; 11 | 12 | new Handle:g_hCvarBzip = INVALID_HANDLE; 13 | new g_iBzip2 = 9; 14 | 15 | new Handle:g_hCvarFtpTarget = INVALID_HANDLE; 16 | new String:g_sFtpTarget[255]; 17 | 18 | new Handle:g_hCvarDelete = INVALID_HANDLE; 19 | new bool:g_bDelete = false; 20 | 21 | new String:g_sDemoPath[PLATFORM_MAX_PATH]; 22 | new bool:g_bRecording = false; 23 | 24 | public Plugin:myinfo = 25 | { 26 | name = "tAutoDemoUpload", 27 | author = "Thrawn", 28 | description = "Uploads demo files to a remote ftp server", 29 | version = VERSION, 30 | }; 31 | 32 | public OnPluginStart() { 33 | CreateConVar("sm_tautodemoupload_version", VERSION, "Uploads demo files to a remote ftp server", FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY|FCVAR_DONTRECORD); 34 | 35 | g_hCvarEnabled = CreateConVar("sm_tautodemoupload_enable", "1", "Automatically upload demos when finished recording.", _, true, 0.0, true, 1.0); 36 | HookConVarChange(g_hCvarEnabled, Cvar_Changed); 37 | 38 | g_hCvarBzip = CreateConVar("sm_tautodemoupload_bzip2", "9", "Compression level. If set > 0 demos will be compressed before uploading. (Requires bzip2 extension.)", _, true, 0.0, true, 9.0); 39 | HookConVarChange(g_hCvarBzip, Cvar_Changed); 40 | 41 | g_hCvarDelete = CreateConVar("sm_tautodemoupload_delete", "0", "Delete the demo (and the bz2) if upload was successful.", _, true, 0.0, true, 1.0); 42 | HookConVarChange(g_hCvarDelete, Cvar_Changed); 43 | 44 | g_hCvarFtpTarget = CreateConVar("sm_tautodemoupload_ftptarget", "demos", "The ftp target to use for uploads."); 45 | HookConVarChange(g_hCvarFtpTarget, Cvar_Changed); 46 | 47 | AddCommandListener(CommandListener_Record, "tv_record"); 48 | AddCommandListener(CommandListener_StopRecord, "tv_stoprecord"); 49 | } 50 | 51 | public OnConfigsExecuted() { 52 | g_bEnabled = GetConVarBool(g_hCvarEnabled); 53 | g_iBzip2 = GetConVarBool(g_hCvarBzip); 54 | g_bDelete = GetConVarBool(g_hCvarDelete); 55 | 56 | GetConVarString(g_hCvarFtpTarget, g_sFtpTarget, sizeof(g_sFtpTarget)); 57 | } 58 | 59 | public Cvar_Changed(Handle:convar, const String:oldValue[], const String:newValue[]) { 60 | OnConfigsExecuted(); 61 | } 62 | 63 | 64 | public OnMapStart() { 65 | if(GetConVarValueInt("tv_enable") != 1) { 66 | SetFailState("SourceTV System is disabled. You don't need this plugin."); 67 | return; 68 | } 69 | 70 | g_bRecording = false; 71 | } 72 | 73 | public Action:CommandListener_Record(client, const String:command[], argc) { 74 | if(!g_bEnabled)return; 75 | if(g_bRecording)return; 76 | 77 | GetCmdArg(1, g_sDemoPath, sizeof(g_sDemoPath)); 78 | 79 | if(!StrEqual(g_sDemoPath, "")) { 80 | g_bRecording = true; 81 | } 82 | 83 | // Append missing .dem 84 | if(strlen(g_sDemoPath) < 4 || strncmp(g_sDemoPath[strlen(g_sDemoPath)-4], ".dem", 4, false) != 0) { 85 | Format(g_sDemoPath, sizeof(g_sDemoPath), "%s.dem", g_sDemoPath); 86 | } 87 | } 88 | 89 | public Action:CommandListener_StopRecord(client, const String:command[], argc) { 90 | if(!g_bEnabled)return; 91 | if(g_bRecording) { 92 | new Handle:hDataPack = CreateDataPack(); 93 | CreateDataTimer(5.0, Timer_UploadDemo, hDataPack); 94 | WritePackString(hDataPack, g_sDemoPath); 95 | 96 | Format(g_sDemoPath, sizeof(g_sDemoPath), ""); 97 | } 98 | 99 | g_bRecording = false; 100 | } 101 | 102 | public Action:Timer_UploadDemo(Handle:timer, Handle:hDataPack) { 103 | ResetPack(hDataPack); 104 | 105 | decl String:sDemoPath[PLATFORM_MAX_PATH]; 106 | ReadPackString(hDataPack, sDemoPath, sizeof(sDemoPath)); 107 | 108 | if(g_iBzip2 > 0 && g_iBzip2 < 10 && LibraryExists("bzip2")) { 109 | decl String:sBzipPath[PLATFORM_MAX_PATH]; 110 | Format(sBzipPath, sizeof(sBzipPath), "%s.bz2", sDemoPath); 111 | BZ2_CompressFile(sDemoPath, sBzipPath, g_iBzip2, CompressionComplete); 112 | } else { 113 | EasyFTP_UploadFile(g_sFtpTarget, sDemoPath, "/", UploadComplete); 114 | } 115 | } 116 | 117 | public CompressionComplete(BZ_Error:iError, String:inFile[], String:outFile[], any:data) { 118 | LogMessage("Compression completed: %i", iError); 119 | if(iError == BZ_OK) { 120 | LogMessage("%s compressed to %s", inFile, outFile); 121 | EasyFTP_UploadFile(g_sFtpTarget, outFile, "/", UploadComplete); 122 | } else { 123 | LogBZ2Error(iError); 124 | } 125 | } 126 | 127 | public UploadComplete(const String:sTarget[], const String:sLocalFile[], const String:sRemoteFile[], iErrorCode, any:data) { 128 | LogMessage("Upload completed: %d", iErrorCode); 129 | if(iErrorCode == 0 && g_bDelete) { 130 | DeleteFile(sLocalFile); 131 | if(StrEqual(sLocalFile[strlen(sLocalFile)-4], ".bz2")) { 132 | new String:sLocalNoCompressFile[PLATFORM_MAX_PATH]; 133 | strcopy(sLocalNoCompressFile, strlen(sLocalFile)-3, sLocalFile); 134 | DeleteFile(sLocalNoCompressFile); 135 | } 136 | } 137 | } 138 | 139 | public GetConVarValueInt(const String:sConVar[]) { 140 | new Handle:hConVar = FindConVar(sConVar); 141 | new iResult = GetConVarInt(hConVar); 142 | CloseHandle(hConVar); 143 | return iResult; 144 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/tEasyFTP.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | #pragma dynamic 32767 // Without this line will crash server!! 3 | #include 4 | #include 5 | #include 6 | 7 | #define VERSION "0.0.2" 8 | 9 | #define CURL_DEFAULT_OPT(%1) curl_easy_setopt_int_array(%1, CURL_Default_opt, sizeof(CURL_Default_opt)) 10 | new CURL_Default_opt[][2] = { 11 | {_:CURLOPT_NOSIGNAL,1}, 12 | {_:CURLOPT_NOPROGRESS,1}, 13 | {_:CURLOPT_TIMEOUT,90}, 14 | {_:CURLOPT_CONNECTTIMEOUT,60}, 15 | {_:CURLOPT_VERBOSE,0} 16 | }; 17 | 18 | new Handle:g_hUploadForward = INVALID_HANDLE; 19 | 20 | new Handle:g_hKv_FtpTargets = INVALID_HANDLE; 21 | new Handle:g_hTrie_Data = INVALID_HANDLE; 22 | 23 | new Handle:g_hFile = INVALID_HANDLE; 24 | 25 | new bool:g_bUploading = false; 26 | 27 | new Handle:g_hCvarDiscordWebhook = INVALID_HANDLE; 28 | new String:g_sDiscordWebhook[255]; 29 | 30 | new Handle:g_hCvarAnnounceMessageFormat = INVALID_HANDLE; 31 | 32 | new Handle:g_hCvarAnnounceOnDiscord = INVALID_HANDLE; 33 | 34 | public Plugin:myinfo = 35 | { 36 | name = "tEasyFTP", 37 | author = "Thrawn", 38 | description = "Provides natives for easy FTP access", 39 | version = VERSION, 40 | }; 41 | 42 | public OnPluginStart() { 43 | CreateConVar("sm_teasyftp_version", VERSION, "", FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY|FCVAR_DONTRECORD); 44 | 45 | g_hCvarDiscordWebhook = CreateConVar("sm_teasyftp_discord_webhook", "", "The Discord Webhook to use for announcing uploads."); 46 | 47 | g_hCvarAnnounceOnDiscord = CreateConVar("sm_teasyftp_announce_on_discord", "0", "Announce download link on discord.", _, true, 0.0, true, 1.0); 48 | 49 | g_hCvarAnnounceMessageFormat = CreateConVar("sm_teasyftp_announce_format", "%map: %dl_url", "Announce message format."); 50 | 51 | g_hUploadForward = CreateForward(ET_Event, Param_String, Param_String, Param_String, Param_Cell, Param_Cell); 52 | 53 | ReloadFtpTargetKV(); 54 | } 55 | 56 | #if SOURCEMOD_V_MAJOR >= 1 && SOURCEMOD_V_MINOR >= 3 57 | public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max) 58 | #else 59 | public bool:AskPluginLoad(Handle:myself, bool:late, String:error[], err_max) 60 | #endif 61 | { 62 | RegPluginLibrary("teftp"); 63 | 64 | CreateNative("EasyFTP_UploadFile", NativeUploadFile); 65 | 66 | #if SOURCEMOD_V_MAJOR >= 1 && SOURCEMOD_V_MINOR >= 3 67 | return APLRes_Success; 68 | #else 69 | return true; 70 | #endif 71 | } 72 | 73 | public Action:Command_ReloadTargets(client,args) { 74 | if(g_bUploading) { 75 | ReplyToCommand(client, "Uploads are running. Can't reload remote target configuration."); 76 | return Plugin_Handled; 77 | } 78 | 79 | new iCount = ReloadFtpTargetKV(); 80 | if(iCount == -1) { 81 | ReplyToCommand(client, "Could not read remote target configuration."); 82 | } else { 83 | ReplyToCommand(client, "Reloaded remote target configuration. Found %i target(s).", iCount); 84 | } 85 | 86 | return Plugin_Handled; 87 | } 88 | 89 | public NativeUploadFile(Handle:hPlugin, iNumParams) { 90 | decl String:sTarget[128]; 91 | GetNativeString(1, sTarget, sizeof(sTarget)); 92 | 93 | decl String:sLocalFile[128]; 94 | GetNativeString(2, sLocalFile, sizeof(sLocalFile)); 95 | 96 | decl String:sRemoteFile[128]; 97 | GetNativeString(3, sRemoteFile, sizeof(sRemoteFile)); 98 | 99 | new Function:myFunc = GetNativeFunction(4); 100 | 101 | new anyData = GetNativeCell(5); 102 | 103 | new Handle:hArray_Queue = INVALID_HANDLE; 104 | if(GetTrieValue(g_hTrie_Data, sTarget, hArray_Queue)) { 105 | new Handle:hTrie_UploadEntry = CreateTrie(); 106 | SetTrieString(hTrie_UploadEntry, "local", sLocalFile); 107 | SetTrieString(hTrie_UploadEntry, "remote", sRemoteFile); 108 | SetTrieString(hTrie_UploadEntry, "target", sTarget); 109 | SetTrieValue(hTrie_UploadEntry, "plugin", hPlugin); 110 | new Handle:hPack = CreateDataPack(); 111 | WritePackFunction(hPack, myFunc); 112 | SetTrieValue(hTrie_UploadEntry, "func", hPack); 113 | SetTrieValue(hTrie_UploadEntry, "data", anyData); 114 | 115 | PushArrayCell(hArray_Queue, hTrie_UploadEntry); 116 | } else { 117 | LogError("Target %s does not exist", sTarget); 118 | } 119 | 120 | if(!g_bUploading) ProcessQueue(); 121 | } 122 | 123 | public ReloadFtpTargetKV() { 124 | decl String:sPath[PLATFORM_MAX_PATH]; 125 | BuildPath(Path_SM, sPath, sizeof(sPath), "configs/RemoteTargets.cfg"); 126 | 127 | if(!FileExists(sPath)) { 128 | LogError("RemoteTargets.cfg does not exist"); 129 | return -1; 130 | } 131 | 132 | // Clear Queue-Array(Trie) for every target 133 | if(g_hKv_FtpTargets != INVALID_HANDLE && KvGotoFirstSubKey(g_hKv_FtpTargets, false)) { 134 | do { 135 | new String:sTarget[64]; 136 | KvGetSectionName(g_hKv_FtpTargets, sTarget, sizeof(sTarget)); 137 | 138 | new Handle:hArray_Queue = INVALID_HANDLE; 139 | GetTrieValue(g_hTrie_Data, sTarget, hArray_Queue); 140 | 141 | while(GetArraySize(hArray_Queue) > 0) { 142 | new Handle:hTrie_UploadEntry = GetArrayCell(hArray_Queue, 0); 143 | RemoveFromArray(hArray_Queue, 0); 144 | CloseTrieUploadEntry(hTrie_UploadEntry); 145 | } 146 | 147 | ClearHandle(hArray_Queue); 148 | } while (KvGotoNextKey(g_hKv_FtpTargets, false)); 149 | } 150 | 151 | // Reinitialize Queue. 152 | ClearHandle(g_hTrie_Data); 153 | g_hTrie_Data = CreateTrie(); 154 | 155 | // Reload KV-File to Handle 156 | ClearHandle(g_hKv_FtpTargets); 157 | g_hKv_FtpTargets = CreateKeyValues("RockNRoll"); 158 | if(!FileToKeyValues(g_hKv_FtpTargets, sPath)) { 159 | return -1; 160 | } 161 | 162 | // Rebuild Queue-Array(Trie) for every target 163 | new iCount = 0; 164 | if(KvGotoFirstSubKey(g_hKv_FtpTargets, false)) { 165 | do { 166 | new String:sTarget[64]; 167 | KvGetSectionName(g_hKv_FtpTargets, sTarget, sizeof(sTarget)); 168 | 169 | new String:sHost[64]; 170 | KvGetString(g_hKv_FtpTargets, "host", sHost, sizeof(sHost)); 171 | 172 | LogMessage("Found target: %s (%s)", sTarget, sHost); 173 | 174 | new Handle:hArray_Queue = CreateArray(4); 175 | SetTrieValue(g_hTrie_Data, sTarget, hArray_Queue); 176 | iCount++; 177 | } while (KvGotoNextKey(g_hKv_FtpTargets, false)); 178 | } 179 | 180 | return iCount; 181 | } 182 | 183 | public ProcessQueue() { 184 | g_bUploading = true; 185 | KvRewind(g_hKv_FtpTargets); 186 | if(KvGotoFirstSubKey(g_hKv_FtpTargets, false)) { 187 | do { 188 | new String:sTarget[64]; 189 | KvGetSectionName(g_hKv_FtpTargets, sTarget, sizeof(sTarget)); 190 | 191 | new Handle:hArray_Queue = INVALID_HANDLE; 192 | GetTrieValue(g_hTrie_Data, sTarget, hArray_Queue); 193 | 194 | if(GetArraySize(hArray_Queue) > 0) { 195 | new Handle:hTrie_UploadEntry = GetArrayCell(hArray_Queue, 0); 196 | RemoveFromArray(hArray_Queue, 0); 197 | 198 | decl String:sLocalFile[PLATFORM_MAX_PATH]; 199 | GetTrieString(hTrie_UploadEntry, "local", sLocalFile, sizeof(sLocalFile)); 200 | 201 | if(!FileExists(sLocalFile)) { 202 | LogError("Upload failed. File does not exists: %s", sLocalFile); 203 | CloseTrieUploadEntry(hTrie_UploadEntry); 204 | continue; 205 | } 206 | 207 | decl String:sLocalFileBasename[PLATFORM_MAX_PATH]; 208 | GetFileBasename(sLocalFile, sLocalFileBasename, sizeof(sLocalFileBasename)); 209 | 210 | decl String:sRemoteFile[PLATFORM_MAX_PATH]; 211 | GetTrieString(hTrie_UploadEntry, "remote", sRemoteFile, sizeof(sRemoteFile)); 212 | 213 | // Prepend missing slash 214 | if(strncmp(sRemoteFile, "/", 1) != 0) { 215 | Format(sRemoteFile, sizeof(sRemoteFile), "/%s", sRemoteFile); 216 | } 217 | 218 | // Prepend missing filename 219 | if(strncmp(sRemoteFile[strlen(sRemoteFile)-1], "/", 1) == 0) { 220 | Format(sRemoteFile, sizeof(sRemoteFile), "%s%s", sRemoteFile, sLocalFileBasename); 221 | } 222 | 223 | // Get the server info from the ftp-targets config file 224 | decl String:sHost[128]; 225 | KvGetString(g_hKv_FtpTargets, "host", sHost, sizeof(sHost)); 226 | 227 | decl String:sUser[64]; 228 | KvGetString(g_hKv_FtpTargets, "user", sUser, sizeof(sUser)); 229 | 230 | decl String:sPassword[32]; 231 | KvGetString(g_hKv_FtpTargets, "password", sPassword, sizeof(sPassword)); 232 | 233 | decl String:sForcePath[128]; 234 | KvGetString(g_hKv_FtpTargets, "path", sForcePath, sizeof(sForcePath), ""); 235 | 236 | decl String:sSSLMode[128]; 237 | KvGetString(g_hKv_FtpTargets, "ssl", sSSLMode, sizeof(sSSLMode), "none"); 238 | new curl_usessl:iSSLMode = SSLModeStringToEnum(sSSLMode); 239 | 240 | new bool:bCreateMissingDirs = bool:KvGetNum(g_hKv_FtpTargets, "CreateMissingDirs", 0); 241 | 242 | // Prepend missing slash 243 | if(strncmp(sForcePath[0], "/", 1) != 0) { 244 | Format(sForcePath, sizeof(sForcePath), "/%s", sForcePath); 245 | } 246 | 247 | // Remove trailing slash (it's added in remotefile if necessary) 248 | if(strncmp(sForcePath[strlen(sForcePath)-1], "/", 1) == 0) { 249 | sForcePath[strlen(sForcePath)-1] = 0; 250 | } 251 | 252 | decl String:sPort[8]; 253 | KvGetString(g_hKv_FtpTargets, "port", sPort, sizeof(sPort), "21"); 254 | 255 | decl String:sDlUrl[256]; 256 | KvGetString(g_hKv_FtpTargets, "dl_url", sDlUrl, sizeof(sDlUrl)); 257 | 258 | decl String:sFtpURL[512]; 259 | KvGetString(g_hKv_FtpTargets, "format", sFtpURL, sizeof(sFtpURL), "ftp://%user:%pw@%host:%port%path%file"); 260 | FormatFTPUrl(sUser, sPassword, sHost, sPort, sForcePath, sRemoteFile, sFtpURL, sizeof(sFtpURL)); 261 | LogMessage("sFtpUrl: %s", sFtpURL); 262 | 263 | decl String:sDownloadURL[512]; 264 | Format(sDownloadURL, sizeof(sDownloadURL), "%s%s", sDlUrl, sRemoteFile); 265 | LogMessage("sDownloadUrl: %s | sFtpUrl: %s", sDownloadURL, sFtpURL); 266 | 267 | LogMessage("sLocalFile: %s", sLocalFile); 268 | 269 | decl String:sAnnounceMessage[512]; 270 | FormatAnnounceMessage(sDownloadURL, sAnnounceMessage, sizeof(sAnnounceMessage)); 271 | if (GetConVarBool(g_hCvarAnnounceOnDiscord)) { 272 | GetConVarString(g_hCvarDiscordWebhook, g_sDiscordWebhook, sizeof(g_sDiscordWebhook)); 273 | Discord_SendMessage(g_sDiscordWebhook, sAnnounceMessage); 274 | } 275 | else PrintToChatAll(sAnnounceMessage); 276 | LogMessage("Uploading file %s (%i byte) to target %s", sLocalFileBasename, FileSize(sLocalFile), sTarget); 277 | new Handle:hCurl = curl_easy_init(); 278 | if(hCurl == INVALID_HANDLE) { 279 | LogError("Upload failed. Can't initialize cURL."); 280 | CloseTrieUploadEntry(hTrie_UploadEntry); 281 | return; 282 | } 283 | 284 | CURL_DEFAULT_OPT(hCurl); 285 | g_hFile = OpenFile(sLocalFile, "rb"); 286 | 287 | // Tell curl we want to upload something 288 | curl_easy_setopt_int(hCurl, CURLOPT_UPLOAD, 1); 289 | curl_easy_setopt_function(hCurl, CURLOPT_READFUNCTION, ReadFunction); 290 | 291 | if(bCreateMissingDirs) { 292 | curl_easy_setopt_int(hCurl, CURLOPT_FTP_CREATE_MISSING_DIRS, CURLFTP_CREATE_DIR); 293 | } 294 | 295 | if(iSSLMode != CURLUSESSL_NONE) { 296 | curl_easy_setopt_int(hCurl, CURLOPT_USE_SSL, iSSLMode); 297 | } 298 | 299 | // Set the URL to the ftp path 300 | curl_easy_setopt_string(hCurl, CURLOPT_URL, sFtpURL); 301 | 302 | // Do it threaded 303 | curl_easy_perform_thread(hCurl, onComplete, hTrie_UploadEntry); 304 | 305 | return; 306 | } 307 | } while (KvGotoNextKey(g_hKv_FtpTargets, false)); 308 | } 309 | g_bUploading = false; 310 | } 311 | 312 | public curl_usessl:SSLModeStringToEnum(const String:sSSLMode[]) { 313 | if(StrEqual(sSSLMode, "none", false))return CURLUSESSL_NONE; 314 | if(StrEqual(sSSLMode, "try", false))return CURLUSESSL_TRY; 315 | if(StrEqual(sSSLMode, "control", false))return CURLUSESSL_CONTROL; 316 | if(StrEqual(sSSLMode, "all", false))return CURLUSESSL_ALL; 317 | return CURLUSESSL_NONE; 318 | } 319 | 320 | public ReadFunction(Handle:hCurl, const bytes, const nmemb) 321 | { 322 | // We are told to read 0 bytes... return 0. 323 | if((bytes*nmemb) < 1) 324 | return 0; 325 | 326 | // We've already read everything... return 0. 327 | if(IsEndOfFile(g_hFile)) 328 | return 0; 329 | 330 | new iBytesToRead = bytes * nmemb; 331 | 332 | // This is slow as hell, but ReadFile always read 4 byte blocks, even though 333 | // it was told explicitely to read 'bytes' * 'nmemb' bytes. 334 | // XXX: Revisit this and try to do it right... 335 | new String:items[iBytesToRead]; 336 | new iPos = 0; 337 | new iCell = 0; 338 | for(; iPos < iBytesToRead && ReadFileCell(g_hFile, iCell, 1) == 1; iPos++) { 339 | items[iPos] = iCell; 340 | } 341 | 342 | curl_set_send_buffer(hCurl, items, iPos); 343 | 344 | return iPos; 345 | } 346 | 347 | public onComplete(Handle:hndl, CURLcode: code, any:hTrie_UploadEntry) { 348 | ClearHandle(g_hFile); 349 | 350 | decl String:sLocalFile[PLATFORM_MAX_PATH]; 351 | GetTrieString(hTrie_UploadEntry, "local", sLocalFile, sizeof(sLocalFile)); 352 | 353 | decl String:sRemoteFile[PLATFORM_MAX_PATH]; 354 | GetTrieString(hTrie_UploadEntry, "remote", sRemoteFile, sizeof(sRemoteFile)); 355 | 356 | decl String:sTarget[128]; 357 | GetTrieString(hTrie_UploadEntry, "target", sTarget, sizeof(sTarget)); 358 | 359 | new Handle:hPlugin; 360 | GetTrieValue(hTrie_UploadEntry, "plugin", hPlugin); 361 | 362 | new anyData; 363 | GetTrieValue(hTrie_UploadEntry, "data", anyData); 364 | 365 | new Handle:hPack, Function:hFunc; 366 | GetTrieValue(hTrie_UploadEntry, "func", hPack); 367 | ResetPack(hPack); 368 | hFunc = ReadPackFunction(hPack); 369 | 370 | if(IsValidPlugin(hPlugin) && GetPluginStatus(hPlugin) == Plugin_Running) { 371 | AddToForward(g_hUploadForward, hPlugin, hFunc); 372 | 373 | /* Start function call */ 374 | Call_StartForward(g_hUploadForward); 375 | 376 | /* Push parameters one at a time */ 377 | Call_PushString(sTarget); 378 | Call_PushString(sLocalFile); 379 | Call_PushString(sRemoteFile); 380 | Call_PushCell(code); 381 | Call_PushCell(anyData); 382 | 383 | /* Finish the call, get the result */ 384 | new iResult; 385 | Call_Finish(_:iResult); 386 | 387 | RemoveFromForward(g_hUploadForward, hPlugin, hFunc); 388 | } else { 389 | LogError("Plugin requesting the upload of %s is not loaded anymore.", sLocalFile); 390 | } 391 | 392 | if(code != CURLE_OK) { 393 | new String:error_buffer[256]; 394 | curl_easy_strerror(code, error_buffer, sizeof(error_buffer)); 395 | LogError("Failed uploading %s (%s).", sLocalFile, error_buffer); 396 | } else { 397 | LogMessage("Finished uploading %s to %s", sLocalFile, sTarget); 398 | } 399 | 400 | CloseHandle(hTrie_UploadEntry); 401 | CloseHandle(hndl); 402 | 403 | g_bUploading = false; 404 | ProcessQueue(); 405 | } 406 | 407 | 408 | public ClearHandle(&Handle:hndl) { 409 | if(hndl != INVALID_HANDLE) { 410 | CloseHandle(hndl); 411 | hndl = INVALID_HANDLE; 412 | } 413 | } 414 | 415 | public GetFileBasename(const String:sFilename[], String:sOutput[], maxlength) { 416 | new iPos = FindCharInString(sFilename, '/', true); 417 | 418 | if(iPos != -1) { 419 | strcopy(sOutput, maxlength, sFilename[iPos+1]); 420 | } else { 421 | strcopy(sOutput, maxlength, sFilename); 422 | } 423 | } 424 | 425 | public FormatAnnounceMessage(const String:sDownloadUrl[], String:sBuffer[], maxlength) { 426 | GetConVarString(g_hCvarAnnounceMessageFormat, sBuffer, maxlength); 427 | if(StrContains(sBuffer, "%host", false) != -1) { 428 | decl String:sServerHostname[128]; 429 | GetHostName(sServerHostname, sizeof(sServerHostname)); 430 | ReplaceString(sBuffer, maxlength, "%host", sServerHostname, false); 431 | } 432 | if(StrContains(sBuffer, "%map", false) != -1) { 433 | decl String:sCurrentMap[64]; 434 | GetCurrentMap(sCurrentMap, sizeof(sCurrentMap)); 435 | ReplaceString(sBuffer, maxlength, "%map", sCurrentMap, false); 436 | } 437 | if(StrContains(sBuffer, "%dl_url", false) != -1) { 438 | ReplaceString(sBuffer, maxlength, "%dl_url", sDownloadUrl, false); 439 | } 440 | } 441 | 442 | public FormatFTPUrl(const String:sUser[], const String:sPassword[], const String:sHost[], const String:sPort[], const String:sPath[], const String:sFile[], String:sBuffer[], maxlength) { 443 | // ftp://%user:%pw@%host:%port%path%file 444 | if(StrContains(sBuffer, "%user", false) != -1) { 445 | ReplaceString(sBuffer, maxlength, "%user", sUser, false); 446 | } 447 | if(StrContains(sBuffer, "%pw", false) != -1) { 448 | ReplaceString(sBuffer, maxlength, "%pw", sPassword, false); 449 | } 450 | if(StrContains(sBuffer, "%host", false) != -1) { 451 | ReplaceString(sBuffer, maxlength, "%host", sHost, false); 452 | } 453 | if(StrContains(sBuffer, "%port", false) != -1) { 454 | ReplaceString(sBuffer, maxlength, "%port", sPort, false); 455 | } 456 | if(StrContains(sBuffer, "%path", false) != -1) { 457 | ReplaceString(sBuffer, maxlength, "%path", sPath, false); 458 | } 459 | if(StrContains(sBuffer, "%file", false) != -1) { 460 | ReplaceString(sBuffer, maxlength, "%file", sFile, false); 461 | } 462 | } 463 | 464 | stock CloseTrieUploadEntry(Handle:hTrie_UploadEntry) 465 | { 466 | new Handle:hPack; 467 | GetTrieValue(hTrie_UploadEntry, "func", hPack); 468 | CloseHandle(hPack); 469 | CloseHandle(hTrie_UploadEntry); 470 | } 471 | 472 | // IsValidHandle() is deprecated, let's do a real check then... 473 | stock bool:IsValidPlugin(Handle:hPlugin) { 474 | if(hPlugin == INVALID_HANDLE)return false; 475 | 476 | new Handle:hIterator = GetPluginIterator(); 477 | 478 | new bool:bPluginExists = false; 479 | while(MorePlugins(hIterator)) { 480 | new Handle:hLoadedPlugin = ReadPlugin(hIterator); 481 | if(hLoadedPlugin == hPlugin) { 482 | bPluginExists = true; 483 | break; 484 | } 485 | } 486 | 487 | CloseHandle(hIterator); 488 | 489 | return bPluginExists; 490 | } 491 | 492 | stock bool GetHostName(char[] buffer, int size) { 493 | static ConVar cvHostname = null; 494 | 495 | if (cvHostname == null) { 496 | cvHostname = FindConVar("hostname"); 497 | } 498 | 499 | if (cvHostname == null) { 500 | buffer[0] = '\0'; 501 | return false; 502 | } 503 | 504 | cvHostname.GetString(buffer, size); 505 | 506 | return true; 507 | } --------------------------------------------------------------------------------