1. Друзья, в это тяжёлое и непонятное для всех нас время мы просим вас воздержаться от любых упоминаний политики на форуме, - этим ситуации не поможешь, а только возникнут ненужные ссоры и обиды. Это касается также шуток и юмора на тему конфликта. Пусть войны будут только виртуальными, а политики решают разногласия дипломатическим путём. С уважением, администрация Old-Games.RU.

    Скрыть объявление
  2. Если Вы видите это сообщение, значит, вы ещё не зарегистрировались на нашем форуме.

    Зарегистрируйтесь, если вы хотите принять участие в обсуждениях. Перед регистрацией примите к сведению:
    1. Не регистрируйтесь с никами типа asdfdadhgd, 354621 и тому подобными, не несущими смысловой нагрузки (ник должен быть читаемым!): такие пользователи будут сразу заблокированы!
    2. Не регистрируйте больше одной учётной записи. Если у вас возникли проблемы при регистрации, то вы можете воспользоваться формой обратной связи внизу страницы.
    3. Регистрируйтесь с реально существующими E-mail адресами, иначе вы не сможете завершить регистрацию.
    4. Обязательно ознакомьтесь с правилами поведения на нашем форуме, чтобы избежать дальнейших конфликтов и непонимания.
    С уважением, администрация форума Old-Games.RU
    Скрыть объявление

Мастерим бота для чата ОГ

Автор: Helmut · 6 июн 2016 · ·
  1. В чате как-то уныло. Почему бы не населить его всякой живностью? Могло бы получиться забавно, если бы подключилось хотя бы несколько человек со своими зверушками. Предлагаю вариант, на основе которого можно сделать, в общем-то, любой алгоритм. Насколько хватит фантазии.

    Логиниться к чату приходится в три этапа:

    1. Открываем сессию:
    Код:
        my ($prehead, $content);
        my $curl = WWW::Curl::Easy->new;
        $curl->setopt(CURLOPT_HEADER, 1);
        $curl->setopt(CURLOPT_AUTOREFERER, 1);
        $curl->setopt(CURLOPT_COOKIESESSION, 1);
        $curl->setopt(CURLOPT_RETURNTRANSFER, 1);
        $curl->setopt(CURLOPT_FOLLOWLOCATION, 0);
        $curl->setopt(CURLOPT_CONNECTTIMEOUT, 30);
        $curl->setopt(CURLOPT_UNRESTRICTED_AUTH, 1);
        $curl->setopt(CURLOPT_WRITEDATA, \$content);
        $curl->setopt(CURLOPT_WRITEHEADER, \$prehead);
        $curl->setopt(CURLOPT_URL, 'http://www.old-games.ru/forum/chat/');
        $curl->setopt(CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
        my $retcode = $curl->perform;
        &error("cUrl error: $retcode ".$curl->strerror($retcode)." ".$curl->errbuf) if ($retcode != 0);
        my %cookie = ($prehead =~ m/Set-Cookie: (.*?)=(.*?);/ig);
        &error("ERROR LOGIN.") if ($cookie{xf_session} eq '');
        my $session = "xf_session=$cookie{xf_session}";
        return $session;
    
    2. Собственно логинимся, получаем id сессии и пользователя:
    Код:
        my $lgn = $_[0]; #ЗДЕСЬ ЛОГИН
        my $psw = $_[1]; #ЗДЕСЬ ПАРОЛЬ
        my ($prehead, $content);
        my $curl = WWW::Curl::Easy->new;
        $curl->setopt(CURLOPT_POST, 1);
        $curl->setopt(CURLOPT_HEADER, 1);
        $curl->setopt(CURLOPT_AUTOREFERER, 1);
        $curl->setopt(CURLOPT_COOKIESESSION, 1);
        $curl->setopt(CURLOPT_RETURNTRANSFER, 1);
        $curl->setopt(CURLOPT_FOLLOWLOCATION, 0);
        $curl->setopt(CURLOPT_CONNECTTIMEOUT, 30);
        $curl->setopt(CURLOPT_UNRESTRICTED_AUTH, 1);
        $curl->setopt(CURLOPT_COOKIE, $session);
        $curl->setopt(CURLOPT_WRITEDATA, \$content);
        $curl->setopt(CURLOPT_WRITEHEADER, \$prehead);
        $curl->setopt(CURLOPT_REFERER, 'http://www.old-games.ru/forum/chat/');
        $curl->setopt(CURLOPT_URL, 'http://www.old-games.ru/forum/login/login');
        $curl->setopt(CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
        $curl->setopt(CURLOPT_POSTFIELDS, "login=$lgn&register=0&password=$psw&remember=1&cookie_check=1&redirect=%2Fforum%2Fchat%2F&_xfToken=");
        my $retcode = $curl->perform;
        &error("cUrl error: $retcode ".$curl->strerror($retcode)." ".$curl->errbuf) if ($retcode != 0);
        my %cookie = ($prehead =~ m/Set-Cookie: (.*?)=(.*?);/ig);
        &error("ERROR LOGIN.") if ($cookie{xf_user} eq '');
        my $cookie = "xf_session=$cookie{xf_session}; xf_user=$cookie{xf_user};";
        return $cookie;
    
    3. Грузим чат и получаем метку безопасности:
    Код:
        my $response;
        my $curl = WWW::Curl::Easy->new;
        $curl->setopt(CURLOPT_HEADER, 0);
        $curl->setopt(CURLOPT_AUTOREFERER, 1);
        $curl->setopt(CURLOPT_RETURNTRANSFER, 1);
        $curl->setopt(CURLOPT_FOLLOWLOCATION, 0);
        $curl->setopt(CURLOPT_COOKIE, $cookie);
        $curl->setopt(CURLOPT_WRITEDATA, \$response);
        $curl->setopt(CURLOPT_REFERER, "http://www.old-games.ru/forum/chat/");
        $curl->setopt(CURLOPT_URL, "http://www.old-games.ru/forum/chat/");
        $curl->setopt(CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
        my $retcode = $curl->perform;
        &error("cUrl error: $retcode ".$curl->strerror($retcode)." ".$curl->errbuf) if ($retcode != 0);
    
        my ($index1, $index2);
        $index1 = index($response, 'chatLastId', 0);
        $index1 = index($response, '=', $index1);
        $index2 = index($response, ';', $index1);
        my $chatLastId = trim(substr($response, $index1+1, $index2-$index1-1));
        $index1 = index($response, 'chatActivityLastId', 0);
        $index1 = index($response, '=', $index1);
        $index2 = index($response, ';', $index1);
        my $chatActivityLastId = trim(substr($response, $index1+1, $index2-$index1-1));
        $index1 = index($response, 'chatActivityLastUpdate', 0);
        $index1 = index($response, '=', $index1);
        $index2 = index($response, ';', $index1);
        my $chatActivityLastUpdate = trim(substr($response, $index1+1, $index2-$index1-1));
        $index1 = index($response, 'name="_xfToken"', 0);
        $index1 = index($response, 'value', $index1);
        $index1 = index($response, '"', $index1);
        $index1++;
        $index2 = index($response, '"', $index1);
        my $xfToken = uri_escape(substr($response, $index1, $index2-$index1));
    
        my %token;
        $token{'room_id'} = 0;
        $token{'user_rooms%5B0%5D'} = $chatLastId;
        $token{'last_id'} = $chatLastId;
        $token{'activity_last_id'} = $chatActivityLastId;
        $token{'activity_last_update'} = $chatActivityLastUpdate;
        $token{'users_last_update'} = '';
        $token{'inverse'} = 0;
        $token{'hide_bot'} = 0;
        $token{'no_users'} = 0;
        $token{'show_ignored'} = 0;
        $token{'all_pages'} = 0;
        $token{'loading'} = 0;
        $token{'_xfRequestUri'} = '%2Fforum%2Fchat%2F';
        $token{'_xfNoRedirect'} = 1;
        $token{'_xfToken'} = $xfToken;
        $token{'_xfResponseType'} = 'json';
        return %token;
    
    Теперь, собственно, два скрипта. Один повесить в цикл с секундной паузой, чтобы получал сообщения из чата:
    Код:
        my $response;
        my $post = post_uri();
        my $curl = WWW::Curl::Easy->new;
        $curl->setopt(CURLOPT_POST, 1);
        $curl->setopt(CURLOPT_HEADER, 0);
        $curl->setopt(CURLOPT_AUTOREFERER, 1);
        $curl->setopt(CURLOPT_RETURNTRANSFER, 1);
        $curl->setopt(CURLOPT_FOLLOWLOCATION, 0);
        $curl->setopt(CURLOPT_COOKIE, $cookie);
        $curl->setopt(CURLOPT_WRITEDATA, \$response);
        $curl->setopt(CURLOPT_REFERER, "http://www.old-games.ru/forum/chat/");
        $curl->setopt(CURLOPT_URL, "http://www.old-games.ru/forum/index.php?chat/refresh");
        $curl->setopt(CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
        $curl->setopt(CURLOPT_POSTFIELDS, $post);
        my $retcode = $curl->perform;
        &error("cUrl error: $retcode ".$curl->strerror($retcode)." ".$curl->errbuf) if ($retcode != 0);
        my $tmpreq = decode_json($response);
        my %tmphsh = %$tmpreq;
        $token{'users_last_update'} = $tmphsh{'lastUpdate'};
        return %tmphsh;
    И второй, когда надо отправить сообщение в чат:
    Код:
        my $response;
        my $post = post_uri();
        my $message = uri_escape($_[0]);
        $post .= '&message=' . $message;
        my $curl = WWW::Curl::Easy->new;
        $curl->setopt(CURLOPT_POST, 1);
        $curl->setopt(CURLOPT_HEADER, 0);
        $curl->setopt(CURLOPT_AUTOREFERER, 1);
        $curl->setopt(CURLOPT_RETURNTRANSFER, 1);
        $curl->setopt(CURLOPT_FOLLOWLOCATION, 0);
        $curl->setopt(CURLOPT_COOKIE, $cookie);
        $curl->setopt(CURLOPT_WRITEDATA, \$response);
        $curl->setopt(CURLOPT_REFERER, "http://www.old-games.ru/forum/chat/");
        $curl->setopt(CURLOPT_URL, "http://www.old-games.ru/forum/index.php?chat/submit");
        $curl->setopt(CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
        $curl->setopt(CURLOPT_POSTFIELDS, $post);
        my $retcode = $curl->perform;
        &error("cUrl error: $retcode ".$curl->strerror($retcode)." ".$curl->errbuf) if ($retcode != 0);
        my $tmpreq = decode_json($response);
        my %tmphsh = %$tmpreq;
        $token{'users_last_update'} = $tmphsh{'lastUpdate'};
        return %tmphsh;
    Ну и, собственно, на основе этого можно придумать любой алгоритм анализа ситуации в чате и реакции на нее. Список свежих сообщений при обновлении приходит в виде HTML-тегов <li>, упакованных в JSON-контейнер {messages}. Там в виде параметра указывается автор сообщения, а если сообщение обращено к кому-то, то это ссылка на форумный id пользователя, что тоже совсем несложно парсить.

    Да, и маленькая подпрограммка для обратной сборки POSTFIELDS:
    Код:
    sub post_uri {
        my $i = 0;
        my ($key, $value, $post);
        while(($key,$value) = each %token) {
            unless ($key eq 'users_last_update' && $value eq '') {
                $post .= '&' if ($i > 0);
                $post .= "$key=$value";
            }
            $i++;
        }
        return $post;
    }
    Motar79, Steel Rat, nilegio и 7 другим нравится это.

Комментарии

  1. Вредный
    Я, канешна, ничо не понял, но звучит неплохо.
    @SAS уже благословил эту безумную идею? Или до первого бана?
  2. Mel Shlemming
    Блин, как тут дизлайк поставить?
      Steel Rat нравится это.
  3. SAS
    @Helmut, на перле - это жестоко :) Хотя именно этот код хорошо читаем.
      Motar79 и CY8R4Y нравится это.
  4. Helmut
    @SAS, просто надо уметь писать на перле, будет везде хорошо читаемый код )
  5. Вредный
    @SAS, ты скажи, это легально или нет?
  6. SAS
    @Вредный, да я вообще не вижу проблемы. Никто ведь не страдает.
  7. Steel Rat
    Ад какой-то.
      Pasha838 нравится это.
  8. YRuby
    O-G Police, arrest this man - he talks in maths.
  9. Helmut
    @Steel Rat, вот блин привередный опять недоволен.
  10. Steel Rat
    @Helmut, я доволен, не гони. Просто ад какой-то. Делай нормального бота давай.
Чтобы оставить комментарий просто зарегистрируйтесь и станьте участником!
  1. На этом сайте используются файлы cookie, чтобы персонализировать содержимое, хранить Ваши предпочтения и держать Вас авторизованным в системе, если Вы зарегистрировались.
    Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie.
    Скрыть объявление