Русское сообщество по скриптингу

[Модуль AMXX] Curl

Файлы и модули, которые пригодятся при скриптинге для AMX Mod X или SourceMod.
Правила форума
1. Запрещено материться и оскорблять других участников форума.
2. Запрещен флуд, оффтоп, дабл постинг во всех разделах форума, кроме раздела "Болтовня".
3. Запрещено взламывать сайт/форум или наносить любой вред проекту.
4. Запрещено рекламировать другие ресурсы.
5. Запрещено создавать темы без информативного названия. Название темы должно отображать ее смысл.

В данном разделе форума разрешено выкладывать файлы или модули для AMXX/SM, которые пригодятся при программировании.

[Модуль AMXX] Curl

Сообщение Morning Rainbow » 08 авг 2014, 23:07

Автор: Morning Rainbow
Версия: 0.2.1b (beta)
Описание:
Модуль является обёрткой над библиотекой libcurl, которая предназначена для того, чтобы взаимодействовать с различными серверами по множеству различных протоколов с синтаксисом URL.
Поддерживаемые протоколы: FTP, FTPS, HTTP, HTTPS, TFTP, SCP, SFTP, Telnet, DICT, LDAP, POP3, IMAP и SMTP.

Слинкованные библиотеки (win):
libcurl/7.37.1
OpenSSL/1.0.1h
zlib/1.2.8
WinIDN
libssh2/1.4.3

История изменений:
0.1b - Первая версия
0.2b
1) Изменён прототип функции колбэка, которая указывается в curl_easy_perform, теперь он такой
complite(CURLcode:code, CURL:curl, data[], data_size);
2) Фикс функции curl_slist_append и curl_slist_free_all;
3) curl_easy_cleanup теперь можно вызывать в колбэке для curl_easy_perform
4) Модуль теперь сам НЕ очищает curl дескрипторы при смене карты! Вы должны сами следить за тем чтобы всё дескрипторы были освобождены;
5) Установка колбэка для curl_easy_perform является обязательным условием.
0.2.1b
1) Фикс неверных размеров массивов передаваемых в качестве параметров некоторым колбэкам.

Функции:
Вы должны зарегистрироваться, чтобы видеть ссылки.(CURL:handle, url[], escapedUrl[], len)
Кодирует для URL выбранную строку.
Функция немного отличается от оригинальной. handle - curl дескриптор, url - строка для кодирования, escapedUrl - закодированная строка, len - размер escapedUrl. Возвращает реальный размер закодированной строки.
Примечание: Вам не нужно вызывать curl_free, как указано в документации. Это делает модуль.

Вы должны зарегистрироваться, чтобы видеть ссылки.()
Начинает новую easy-сессию libcurl.
Возвращает дескриптор curl.

Вы должны зарегистрироваться, чтобы видеть ссылки.(CURL:handle)
Завершает libcurl easy сессию.

CURLcode:Вы должны зарегистрироваться, чтобы видеть ссылки.(CURL:handle, CURLINFO:info, ...)
Получает информацию для указанного curl дескриптора. Информация записывается в переменную указанную 3-им аргументом.
handle - curl дескриптор, info - значение определяет какую информацию нужно получить, 3 аргумент - массив-строка (в этом случае 4-ым аргументом указывается размер), либо числовая переменная, либо переменная типа Float, либо числовая переменная с тэгом curl_slist (ставить тэг не обязательно, но вам будет проще ориентироваться в коде, тэг curl_slist означает, что в переменной содержится указатель на структуру curl_slist)

CURLcode:Вы должны зарегистрироваться, чтобы видеть ссылки.(CURL:handle, bitmask)
Приостанавливает или возобновляет передачу данных.
handle - curl дескриптор, bitmask - указывает новое состояние соединения.

Вы должны зарегистрироваться, чтобы видеть ссылки.(CURL:handle, callbackComplite[], data[] = {}, data_len = 0)
Начинает передачу данных.
Имеет отличие от оригинальной функции. Так во 2-ом параметре нужно указать имя функции, которая вызовется по завершении передачи, в 3-ем параметре можно указать массив, который будет передан в функцию колбэк (в этом случае необходимо указать 4-ый параметр - размер массива).
Прототип функции колбэка: public CurlCallback(CURLcode:code, CURL:curl, data[], data_size)
Примечание: Вызов функции не блокирует сервер, выполнение передачи идёт в отдельном потоке.

CURLcode:Вы должны зарегистрироваться, чтобы видеть ссылки.(CURL:handle, buffer[], len, &n)
Получает "сырые" (raw) данные.
buffer[] - здесь будут содержаться принятые данные, len - размер буфера, n - здесь будет содержаться реальное количество принятых байт.
Примечание: Эта функция уже работает в блокирующем режиме.

Вы должны зарегистрироваться, чтобы видеть ссылки.(CURL:handle)
Сбрасывает все параметры сессии.
CURLcode:Вы должны зарегистрироваться, чтобы видеть ссылки.(CURL:handle, buffer[], len, &n)
Передаёт "сырые" (raw) данные.
buffer[] - буфер с данными, которые необходимо отправить, len - размер буфера (укажите меньше, если требуется), n - будет содержать реальное количество отправленных байт.
Примечание: Функция работает в блокирующем режиме.

CURLcode:Вы должны зарегистрироваться, чтобы видеть ссылки.(CURL:handle, CURLoption:option, ...)
Смотрите в описании на сайте. Примечания под спойлером.
Неподдерживаемые опции:
CURLOPT_CONV_TO_NETWORK_FUNCTION
CURLOPT_CONV_FROM_NETWORK_FUNCTION
CURLOPT_CONV_FROM_UTF8_FUNCTION
CURLOPT_ERRORBUFFER (используйте CURLOPT_VERBOSE и CURLOPT_DEBUGFUNCTION)
CURLOPT_STDERR (используйте CURLOPT_DEBUGFUNCTION)
CURLOPT_POSTFIELDS (используйте CURLOPT_COPYPOSTFIELDS)
CURLOPT_RESUME_FROM_LARGE
CURLOPT_INFILESIZE_LARGE
CURLOPT_MAXFILESIZE_LARGE
CURLOPT_MAX_SEND_SPEED_LARGE
CURLOPT_MAX_RECV_SPEED_LARGE
CURLOPT_SSH_KEYFUNCTION
CURLOPT_SSH_KEYDATA
CURLOPT_SHARE
Поддержка опций с постфиксом _LARGE будет добавлена позднее, когда сделаю поддержку типа curl_off_t (8 байтовые целые).
CURLOPT_SSH_KEYFUNCTION - Этот колбэк скорее всего добавлю позднее.
У функции колбэка для опции CURLOPT_XFERINFOFUNCTION в параметрах аргументы типа curl_off_t, это значит значения не всегда будут корректными.
В качестве параметра т.н. датаопции (например CURLOPT_WRITEDATA) можно указать только число (например дескриптор файла).


Вы должны зарегистрироваться, чтобы видеть ссылки.(CURLcode:code, errorBuf[], len)
Возвращает строку, которая описывает код ошибки.
Отличается от оригинальной функции, 2-ым параметром укажите буфер, куда будет записано описание ошибки, параметр len - размер буфера.

Вы должны зарегистрироваться, чтобы видеть ссылки.(CURL:handle, url[], unescapedUrl[], len)
Возвращает декодированную строку URL-кодированной строки. :)
Немного отличается от оригинальной функции. url - строка для декодирования, unescapedUrl - здесь укажите буфер, куда будет записана декодированная строка, len - размер unescapedUrl.
Возвращает реальный размер декодированной строки.
Примечание: Вам не нужно вызывать curl_free, как указано в документации. Это делает модуль.

CURLFORMcode:Вы должны зарегистрироваться, чтобы видеть ссылки.(&curl_httppost:first, &curl_httppost:last, ...)
Добавляет раздел в multipart/formdata HTTP POST.
Подробное описание смотрите на сайте. Примечания под спойлером.
Неподдерживаемые опции:
CURLFORM_PTRNAME (используйте CURLFORM_COPYNAME)
CURLFORM_PTRCONTENTS (используйте CURLFORM_COPYCONTENTS)
CURLFORM_BUFFER (используйте CURLFORM_STREAM)
CURLFORM_BUFFERPTR (см выше)
CURLFORM_ARRAY
Поддержка CURLFORM_ARRAY будет добавлена позднее.
Так же из-за некоторых ограничений (не более 32 параметров для функции) вы не сможете передать более 14 опций.
Вы должны обязательно вызвать curl_formfree для первого curl_httppost, как и написано в документации. В будущем возможно сделаю чтобы после смены карты все чистилось, на случай если забудете.


Вы должны зарегистрироваться, чтобы видеть ссылки.(&curl_httppost:first)
Освобождает память, выделенную под список multipart/formdata HTTP POST параметров.

curl_slist:Вы должны зарегистрироваться, чтобы видеть ссылки.(curl_slist:list, buffer[])
Добавляет строку в конец связного списка curl_slist.
list - указатель на последний элемент списка, buffer - строка для добавления.
Возвращает указатель на новый последний элемент списка.
Вы должны обязательно вызвать curl_slist_free_all, после того как curl завершит работу со структурой.

Вы должны зарегистрироваться, чтобы видеть ссылки.(curl_slist:list)
Освобождает весь список curl_slist.

Вы должны зарегистрироваться, чтобы видеть ссылки.(buf[], len)
Возвращает версию curl, включенные библиотеки и их версии.
buf - буфер, куда положить информацию о версиях, len - размер буфера.

Общие примечания:
0) Модуль сам НЕ очищает curl дескрипторы, вы должны сами контролировать очистку (вызов curl_easy_cleanup для каждого открытого дескриптора), все курлы должны быть очищены к моменту смены карты. Так же, если есть активные передачи к моменту смены карты, то модуль попытается сгенерировать ошибку передачи чтобы как можно скорее завершить поток в котором выполняется передача и вызвать колбэк curl_easy_perform (вызовется после plugin_end()).
Проще всего проводить очистку в колбэке curl_easy_perform.
1) Вы НЕ должны вызывать curl_easy_cleanup и другие функции очистки пока передача не завершилась!
2) Пока нет возможности реально установить/получить значение переменной типа curl_off_t, сейчас происходит преобразование типа к cell (обычная ячейка amxx), но это не очень правильно. Значения зачастую будут некорректными.
3) Всегда определяйте опцию CURLOPT_BUFFERSIZE, если используете колбэк WRITEFUNCTION укажите в качестве параметра размер буфера не более 1024, иначе рискуете получить ошибки stack error, возможно даже повесить сервер. Если вы получаете ошибки stack error при использовании других колбэков, то можно определить в плагине #pragma dynamic 30000.
4) Не забывайте, что вам необходимо очищать память по указателям для curl_slist и curl_httppost с помощью функций curl_slist_free_all и curl_formfree соответственно.
5) Если будет что-то не так с опциями CURLAUTH_*, то сообщайте :)

Рекомендации:
1) Если планируется "долгосрочная" передача, то можно временно убрать лимит игры на карте, когда передача завершится восстановить;
2) Вы можете использовать 1 дескриптор curl несколько раз для одного url, однако при текущей реализации логики модуля будет сложнее очистить дескриптор в месте отличном от колбэка curl_easy_perform;
3) Используйте curl_easy_setopt(curl, CURLOPT_VERBOSE, 1) для отладки плагина, если затрудняетесь определить причину неполадки в плагине. (По-умолчания вывод дебаг информации будет осуществляться в консоль сервера, вы можете определить колбэк CURLOPT_DEBUGFUNCTION для изменения вывода)

Примеры кода:
1) Вы должны зарегистрироваться, чтобы видеть ссылки.;
2) Вы должны зарегистрироваться, чтобы видеть ссылки.;
3) Вы должны зарегистрироваться, чтобы видеть ссылки..

Для компиляции под linux нужно написать Makefile, в архиве с исходным кодом уже есть статическая библиотека libcurl и по идее код должен компилироваться под linux без допилов.

Windows версия не будет работать на Windows Server 2003 и Windows XP.
Последний раз редактировалось Morning Rainbow 10 окт 2014, 13:32, всего редактировалось 12 раз(а).
Аватара пользователя
Morning Rainbow
 
Сообщения: 73
Зарегистрирован: 28 июл 2013, 00:35
Откуда: ??chan
Благодарил (а): 7 раз.
Поблагодарили: 50 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6

Re: [Модуль AMXX] Curl

Сообщение Sulky » 13 авг 2014, 17:56

Отлично! :thumbs_up
- Люди делятся на 2 части, - сказал Петя и взял бензопилу...
Аватара пользователя
Sulky
 
Сообщения: 25
Зарегистрирован: 17 май 2014, 21:18
Забанен
Благодарил (а): 8 раз.
Поблагодарили: 11 раз.
Опыт программирования: Около 6 месяцев
Языки программирования: Valve Hammer Editor

Re: [Модуль AMXX] Curl

Сообщение Morning Rainbow » 13 авг 2014, 18:57

Sulky, Спасибо! Конечно отлично!
Но я не ожидал такой вялой (никакой) реакции, на такой полезный модуль.
Кста, я его не просто так писал же, в скором времени выложу плагин для автоматического приглашения стим игроков в стим группу.
Аватара пользователя
Morning Rainbow
 
Сообщения: 73
Зарегистрирован: 28 июл 2013, 00:35
Откуда: ??chan
Благодарил (а): 7 раз.
Поблагодарили: 50 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6

Re: [Модуль AMXX] Curl

Сообщение Safety1st » 13 авг 2014, 21:39

Morning Rainbow, было бы чудесно увидеть перечень конкретных практических задач, где может модуль применяться. Ну и простенький плагин-пример.
GoldSrc Gaming Community
Аватара пользователя
Safety1st
 
Сообщения: 1958
Зарегистрирован: 08 окт 2011, 05:41
Откуда: Moscow
Благодарил (а): 1690 раз.
Поблагодарили: 933 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6
Half-Life

Re: [Модуль AMXX] Curl

Сообщение Morning Rainbow » 14 авг 2014, 00:32

Safety1st, ну как же я буду придумывать задачи под инструмент)

Однако можно смело использовать этот модуль вместо сырых сокетов для работы с http запросами и не думать над тем как составить заголовок запроса и парсить куки. Ну а возможность использовать шифрованное соединения без этого модуля вообще отсутствовала.

Можно например получать/отправлять письма, закачивать на удалённый ftp сервер какие-нибудь файлы, логи или ещё что. Кстати модуль можно было бы использовать для реализации идеи из темы Вы должны зарегистрироваться, чтобы видеть ссылки.

Примеры обязательно добавлю, но немного позже (когда сделаю linux версию)

ЗЫ Похоже придётся писать больше чем 1 плагин, для продвижения модуля :-D
Аватара пользователя
Morning Rainbow
 
Сообщения: 73
Зарегистрирован: 28 июл 2013, 00:35
Откуда: ??chan
Благодарил (а): 7 раз.
Поблагодарили: 50 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6

Re: [Модуль AMXX] Curl

Сообщение Sulky » 15 авг 2014, 19:11

Safety1st писал(а):Morning Rainbow, было бы чудесно увидеть перечень конкретных практических задач, где может модуль применяться. Ну и простенький плагин-пример.

Согласен. Всем нужен пример, многие могут не совсем врубиться в тему.
- Люди делятся на 2 части, - сказал Петя и взял бензопилу...
Аватара пользователя
Sulky
 
Сообщения: 25
Зарегистрирован: 17 май 2014, 21:18
Забанен
Благодарил (а): 8 раз.
Поблагодарили: 11 раз.
Опыт программирования: Около 6 месяцев
Языки программирования: Valve Hammer Editor

Re: [Модуль AMXX] Curl

Сообщение Leonidddd » 19 авг 2014, 13:15

Отлично, спасибо.
[spoiler]
return -1; // и чо это

:-D[/spoiler]
Аватара пользователя
Leonidddd
Модератор
 
Сообщения: 2557
Зарегистрирован: 08 апр 2012, 18:13
Откуда: г. Запорожье
Благодарил (а): 192 раз.
Поблагодарили: 718 раз.

Re: [Модуль AMXX] Curl

Сообщение Morning Rainbow » 20 авг 2014, 01:05

Модуль обновлён до версии 0.2b, в шапке список небольших изменений.

Пример 1
Плагин позволяет игроку введя в чат команду
Код: Выделить всё
/statsmail [email protected]

выслать себе на почту краткую статистику по своей игре.

Пример такого письма:
Без имени-1.png


Для работы нужно настроить
SMTP_USERNAME - имя пользователя на smtp сервере
SMTP_PASSWORD - пароль
SMTP_URL - собственно url, smtps значит, что будет использоваться шифрованное соединение
SMTP_PORT - порт smtp сервера

Сейчас настройки справедливы для smtp сервера google, вам нужно только поменять имя пользователя и пароль, если используйте двухэтапную авторизацию, то в аккаунте гугла нужно сделать пароль для приложения.

[pawn]
  1. #include <amxmodx>

  2. #include <csstats>

  3. #include <curl>

  4.  

  5. #define PLUGIN  "Curl Example SMTP"

  6. #define AUTHOR  "Morning Rainbow"

  7. #define VERSION "0.1"

  8.  

  9. #define MAX_PLAYERS 32

  10.  

  11. #define SMTP_USERNAME   "[email protected]"

  12. #define SMTP_PASSWORD   "password"

  13. #define SMTP_URL                "smtps://smtp.gmail.com"

  14. #define SMTP_PORT               465

  15.  

  16. #define SEND_FROM       SMTP_USERNAME

  17. #define SENDER_NAME             "Stats Bot"

  18.  

  19. static const c_payload_template[][] = {

  20.   {"To: <%s>^r^n"},

  21.   {"From: <%s>(%s)^r^n"},

  22.   {"Message-ID: <%s>^r^n"},

  23.   {"Subject: %s^r^n"},

  24.   {"Content-Type: text/html^r^n"},

  25.   {"^r^n"}, /* empty line to divide headers from body, see RFC5322 */

  26.  

  27.   {"Сервер <strong>%s</strong><br>^r^n"},

  28.   {"Адрес <strong>%s</strong><br>^r^n"},

  29.   {"Статистика для игрока <strong>%s</strong><br>^r^n"},

  30.   {"<br>^r^n"},

  31.   {"<table><tr><th>Убийства</th><th>В голову</th><th>Смерти</th><th>Выстрелов</th><th>Попадания</th><th>Урон</th></tr>^r^n"},

  32.   {"<tr><td>%d</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td></tr></table>^r^n"}

  33. }

  34.  

  35. enum _:TUserData {

  36.         usdat_Email[64]

  37. }

  38.  

  39. new g_udUserData[MAX_PLAYERS+1][TUserData]

  40.  

  41. new g_iLinesRead[MAX_PLAYERS+1]

  42. new bool:g_bLock[MAX_PLAYERS+1] // может ли игрок опять запросить статистику

  43.  

  44. new g_szServerName[64], g_szServerAddr[64]

  45.  

  46. public plugin_init() {

  47.         register_plugin(PLUGIN, VERSION, AUTHOR)

  48.        

  49.         get_cvar_string("hostname", g_szServerName, charsmax(g_szServerName))

  50.         get_user_ip(0, g_szServerAddr, charsmax(g_szServerAddr))

  51.        

  52.         register_concmd("say", "say_callback")

  53.         register_concmd("say_team", "say_callback")

  54. }

  55.  

  56. public say_callback(id) {

  57.         new buf[128]

  58.        

  59.         read_argv(1, buf, charsmax(buf))

  60.         if(!equal(buf, "/statsmail", 10)) {

  61.                 return PLUGIN_CONTINUE

  62.         }

  63.        

  64.         new mail[117]

  65.         copy(mail, strlen(buf) - 10, buf[10])

  66.        

  67.         trim(mail)

  68.        

  69.         if(strlen(mail) == 0) {

  70.                 client_print(id, print_chat, "Ошибка, не указан email, вы должны указать email после команды /statsmail")

  71.                

  72.                 return PLUGIN_CONTINUE

  73.         }

  74.        

  75.         send_mail(id, mail)

  76.        

  77.         return PLUGIN_HANDLED

  78. }

  79.  

  80. send_mail(id, mail[]) {

  81.         if(g_bLock[id]) {

  82.                 client_print(id, print_chat, "Вы не можете запросить статистику, пока не обработался предыдущий запрос.")

  83.                

  84.                 return

  85.         }

  86.         g_bLock[id] = true

  87.         g_iLinesRead[id] = 0

  88.  

  89.         client_print(id, print_chat, "Отправка статистики на email ^"%s^"", mail)

  90.        

  91.         new CURL:curl

  92.         new curl_slist:recipients

  93.        

  94.         if((curl = curl_easy_init())) {

  95.                 curl_easy_setopt(curl, CURLOPT_USERNAME, SMTP_USERNAME)

  96.                 curl_easy_setopt(curl, CURLOPT_PASSWORD, SMTP_PASSWORD)

  97.                

  98.                 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0) // отключает проверку сертификата, если включить обратно, то нужно в какой-то другой опции указать путь к папке с сертификатами

  99.                 curl_easy_setopt(curl, CURLOPT_PORT, SMTP_PORT)

  100.                 curl_easy_setopt(curl, CURLOPT_URL, SMTP_URL)

  101.                

  102.                 curl_easy_setopt(curl, CURLOPT_MAIL_FROM, SEND_FROM) // угловые скобки < > добавятся автоматически

  103.                

  104.                 recipients = curl_slist_append(recipients, mail)

  105.                 curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients)

  106.                

  107.                 curl_easy_setopt(curl, CURLOPT_READFUNCTION, "payload_source")

  108.                 curl_easy_setopt(curl, CURLOPT_READDATA, id)

  109.                 curl_easy_setopt(curl, CURLOPT_UPLOAD, 1)

  110.                

  111.                 //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1) // вывод дебаг информации в консоль сервера

  112.                

  113.                 copy(g_udUserData[id][usdat_Email], strlen(mail), mail)

  114.                

  115.                 new data[2]

  116.                 data[0] = id

  117.                 data[1] = recipients

  118.                 curl_easy_perform(curl, "payload_complite", data, sizeof(data))

  119.         }

  120. }

  121.  

  122. public payload_source(buffer[], size, nmemb, player) {

  123.         if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {

  124.                 return 0

  125.         }

  126.        

  127.         if(g_iLinesRead[player] > (sizeof(c_payload_template) - 1)) {

  128.                 return 0

  129.         }

  130.        

  131.         if(!is_user_connected(player)) {

  132.                 return 0

  133.         }

  134.        

  135.         new text[512]

  136.         new len

  137.        

  138.         switch(g_iLinesRead[player]) {

  139.                 case 0: formatex(text, charsmax(text), c_payload_template[g_iLinesRead[player]], g_udUserData[player][usdat_Email])

  140.                

  141.                 case 1: formatex(text, charsmax(text), c_payload_template[g_iLinesRead[player]], SEND_FROM, SENDER_NAME)

  142.                

  143.                 case 2: {

  144.                         new uid[40]

  145.                         generate_uid(uid, SEND_FROM)

  146.                         formatex(text, charsmax(text), c_payload_template[g_iLinesRead[player]], uid)

  147.                 }

  148.                

  149.                 case 3: {

  150.                         new subj[128]

  151.                         get_user_name(player, subj, charsmax(subj))

  152.                         format(subj, charsmax(subj), "[%s] Stats for %s", g_szServerName, subj)

  153.                         formatex(text, charsmax(text), c_payload_template[g_iLinesRead[player]], subj)

  154.                 }

  155.                

  156.                 case 6: formatex(text, charsmax(text), c_payload_template[g_iLinesRead[player]], g_szServerName)

  157.                

  158.                 case 7: formatex(text, charsmax(text), c_payload_template[g_iLinesRead[player]], g_szServerAddr)

  159.                

  160.                 case 8: {

  161.                         new name[32]

  162.                         get_user_name(player, name, charsmax(name))

  163.                         formatex(text, charsmax(text), c_payload_template[g_iLinesRead[player]], name)

  164.                 }

  165.                

  166.                 case 11: {

  167.                         new stats[8], hits[8], name[32]

  168.                         get_stats(player, stats, hits, name, charsmax(name))

  169.                         formatex(text, charsmax(text), c_payload_template[g_iLinesRead[player]], stats[0], stats[2], stats[1], stats[4], stats[5], stats[6])

  170.                 }

  171.                

  172.                 default: copy(text, charsmax(text), c_payload_template[g_iLinesRead[player]])

  173.         }

  174.        

  175.         g_iLinesRead[player]++

  176.        

  177.         len = strlen(text)

  178.        

  179.         if(len > nmemb) {

  180.                 log_amx("[%s] Размер буфера (%d) для записи превышает допустимый максимум (%d)", len, nmemb)

  181.                

  182.                 g_iLinesRead[player] = 0

  183.                 return 0

  184.         }

  185.        

  186.         copy(buffer, len, text)

  187.        

  188.         return len

  189. }

  190.  

  191. public payload_complite(CURLcode:code, CURL:curl, data[], data_size) {

  192.         new id = data[0]

  193.         new curl_slist:recipients = curl_slist:data[1]

  194.        

  195.         if(is_user_connected(id)) {

  196.                 if(code != CURLE_OK) {

  197.                         new error[256]

  198.                         curl_easy_strerror(code, error, charsmax(error))

  199.                         client_print(id, print_chat, "Ошибка отправки: %s", error)

  200.                 }

  201.                 else {

  202.                         client_print(id, print_chat, "Письмо успешно отправлено! Проверьте папку ^"Спам^", если не найдёте письмо в папке ^"Принятые^"")

  203.                 }

  204.         }

  205.  

  206.         curl_slist_free_all(recipients)

  207.         curl_easy_cleanup(curl)

  208.         g_bLock[id] = false

  209. }

  210.  

  211. generate_uid(buf[40], const mail[]) {

  212.         static const chars[] = {'a', 'A', 'b', 'B', 'c', 'C', 'd', 'D', 'i', 'I', 'k', 'K', 'o', '2', '4', '_', '-'} // ok

  213.        

  214.         new gen_size = charsmax(buf) - strlen(mail)-1

  215.        

  216.         for(new i = 0; i < gen_size; i++) {

  217.                 buf[i] = chars[random(sizeof chars)]

  218.         }

  219.        

  220.         add(buf, charsmax(buf), ".")

  221.         add(buf, charsmax(buf), mail, strlen(mail))

  222. }
[/pawn]

Плагин основан на примере отсюда Вы должны зарегистрироваться, чтобы видеть ссылки.

Добавлено спустя 1 минуту 3 секунды:
Leonidddd, напоминание себе, что код никогда не выполнится)
Последний раз редактировалось Morning Rainbow 20 авг 2014, 09:49, всего редактировалось 1 раз.
Аватара пользователя
Morning Rainbow
 
Сообщения: 73
Зарегистрирован: 28 июл 2013, 00:35
Откуда: ??chan
Благодарил (а): 7 раз.
Поблагодарили: 50 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6

Re: [Модуль AMXX] Curl

Сообщение Safety1st » 20 авг 2014, 01:09

Morning Rainbow, насколько целесообразно использовать модуль для простых HTTP GET-запросов? Стоит оно того по-вашему, чтобы разбираться в новой диковине? Вопрос не праздный: мне нужно сделать API для статы gameME.
GoldSrc Gaming Community
Аватара пользователя
Safety1st
 
Сообщения: 1958
Зарегистрирован: 08 окт 2011, 05:41
Откуда: Moscow
Благодарил (а): 1690 раз.
Поблагодарили: 933 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6
Half-Life

Re: [Модуль AMXX] Curl

Сообщение Dmitry Beast » 20 авг 2014, 02:19

хорошая вещь, но, честно говоря немного бесполезная(я про плагин) ;)
Аватара пользователя
Dmitry Beast
 
Сообщения: 1560
Зарегистрирован: 24 дек 2010, 10:35
Откуда: Египет
Благодарил (а): 440 раз.
Поблагодарили: 207 раз.
Опыт программирования: Больше трех лет
Языки программирования: All Languages

След.

Вернуться в Файлы и модули

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1