| В этой статье мы рассмотрим работу с icq на php. Да, из php-скрипта можно отправить сообщение на асю. Делается это с помощью сокетов. Но это требует непосредственной работы с icq-протоколом, а для этого его надо хорошо знать. К счастью есть готовые реализации - классы, которые выполняют всю черновую работу с протоколом а нам предоставляют через удобные методы собственно делать то что нам нужно. Желательно выбирать надежный класс, которые регулярно поддерживается. Если, например, в протоколе icq произойдет изменение, то наш класс скорее всего перестанет работать, либо будет работать некорректно. В данном случае нам остается надеяться на то что автор класса которым мы пользуемся добросовестно его изменит чтоб он работал. Одно из довольно хороших решений, которое мы рассмотрим, это класс WebIcqLite. Скачать его можно на сайте http://wip.asminog.com/workshop/php2icq.html Последняя версия на данный момент - http://wip.asminog.com/projects/icq/WebIcqLite.class.phps Сохраняем скрипт например под названием WebIcqLite.class.php и затем используем его следующим образом (пример взят с сайта где лежит класс) Code <?php
include('WebIcqLite.class.php');
define('UIN', 111111111);
define('PASSWORD', 'password');
$icq = new WebIcqLite();
if($icq->connect(UIN, PASSWORD)){
if(!$icq->send_message('123456789', 'Hello from php!!!')){
echo $icq->error;
}else{
echo 'Message sent';
}
$icq->disconnect();
}else{
echo $icq->error;
}
?> Довольно просто, не так ли? Установите правильно константы и запустите скрипт, не забудьте чтоб номер с которого отправляется письмо было у вас в контакт-листе, так как если у вас стоит антифлуд то этот бот не введет ответ что доставить письмо. Пришло письмо на асю? Круто, да? Но не все так круто как кажется на первый взгляд. Если идет отправка на асю раз в 5-10 минут, то это приемлемо. Если же скрипт отсылает сообщения чаще, то с этого номера будет много подключений, так как скрипт запускается, подключается отправляет сообщение и отключается от сервера каждый раз, когда отправляет сообщение. Пару сообщений, и уже вылетает ошибка UIN blocked, please try again 20 min later. Решений тут несколько. Либо отправлять сообщения редко либо отправлять их не с одного номера, а с листа рандомно. Реализуется это примерно так: Code <?php
include('WebIcqLite.class.php'); $uinlist[] = '1112112'; $uinlist[] = '1111351'; $uinlist[] = '1345111'; $uinlist[] = '1111113'; $uinlist[] = '1111114'; $uinlist[] = '1111115'; $uinlist[] = '1111116'; $uinlist[] = '1111117'; $uinlist[] = '1111118'; $uinlist[] = '1111119'; $uinlist[] = '1151115';
$rand_num_icq = rand(0,10); $uin_to_use = "$uinlist[$rand_num_icq]";
define('UIN', $uin_to_use);
define('PASSWORD', 'pass');
$icq = new WebIcqLite();
if($icq->connect(UIN, PASSWORD)){
if(!$icq->send_message('123456789', 'Hello from php!!!')){
echo $icq->error;
}else{
echo 'Message sent';
}
$icq->disconnect();
}else{
echo $icq->error;
}
?> Чем больше номеров - тем лучше. Естественно если для каждого номера используется свой пароль, нужно подключить еще один массив. Можно конечно сделать механизм выбора номера сложнее, например проверять не совпал ли данный номер с тем который использовался только что, или если произошел ерор коннекта, сразу пробовать отправить сообщение с другого номера и т.д., но если номеров достаточно много не обязательно прописывать подобные алгоритмы. Но есть еще один способ, который я попробовал реализовать. Что если не завершать работу скрипта, а держать его исполняющимся и отправляющим сообщения на асю через определенный промежуток времени, и завершить скрипт только через определенное время. Можно сделать вообще бесконечный цикл, но тогда скрипт будет работать постоянно, и лично у меня почему-то даже при нажатии "стоп", сообщение все еще продолжали идти на асю, наверное потому что сам процесс это не убивало, а для того чтоб его убить приходилось запускать еще один скрипт с этими же данными который соединялся, отправлял месагу и отсоединялся, тогда тот первый скрипт переставал работать. Итак, сейчас я покажу как я это реализовал на рабочем примере Code <?php set_time_limit(0); include('WebIcqLite.class.php'); define('UIN', 578886090); define('PASSWORD', 'pass');
$icq = new WebIcqLite(); if($icq->connect(UIN, PASSWORD)){ $i = 0; while($i <= 10) { $rand_num_icq = rand(1,1000); $mes_to_send = 'test '.$rand_num_icq;
$icq->send_message('123123', $mes_to_send);
sleep(8); $i++; } $icq->disconnect();
} else { echo $icq->error; } echo 'end.';
?> Во-первых здесь очень важен параметр set_time_limit(0). Так как решение нестандартное, это может не работать на вашем хостинге, в зависимости от того поддерживается ли set_time_limit чтобы убрать лимит времени выполнения скрипта. Итак, запускаем скрипт обычным образом в браузере. Скрипт "зависает" на белом окне. В асю каждые 8 секунд идут сообщения - test и рандом число каждый раз. Всего 10 итераций, тобеж скрипт будет выполняться примерно 80 секунд, затем в браузере появится строка end. Можно так же модифицировать данный код под бесконечный цикл, все мы знаем как это делается Итак, думаю идея ясна. Но ее можно еще развить. Что если скрипт каждый раз при итерации цикла будет проверять текстовый файл, и если в нем есть какие-либо данные, отправлять их на асю, а если текстовый файл пуст, будет ждать определенное время (специальная задержка, желательно чтоб была стандартная во всех условиях) и начинать новую итерацию, когда в текстовом файле появятся данные для отправки бот их отправит на асю. Таким образом мы получаем бота который висит в фоне, и когда появляются новые данные отправляет их нам на icq! Неплохо, да? В свою очередь обновлять текстовый файл - дело совершенно другого скрипта, который поставляет нам данные, причем данные эти могут быть любого рода. Именно используя эту идею, я и запустил в бета-тестирование icq-бота, который отправлял новые записи в логе на онлайн сниффере пользователю на icq. Но я столкнулся с трудностями, причем трудностями довольно весомыми, в связи с чем лучше каждому пользователю реализовать своего бота на своем хосте, и запускать его когда ему нужно. Больше одного бота мне запустить не удалось, так как я так понял надо выделять свой порт каждому боту, кроме того я пытался реализовать чтобы каждый бот скажем каждые 19 минут завершал свою работу, а по крону запускался каждые 20 минут, тобеж постоянно висел в фоне, но это мне не удалось реализовать, вернее я реализовал но оно не работало, если еще первые 20 минут бот работал, после второго запуска просто затухал... в общем думаю если сильно постараться можно это реализовать, просто лучше будет каждому пользователю поставить своего бота на своем хосте, вместе со своими скриптами под наш онлайн сниффер, или свой какой-то движок, чем все боты держать на нашем сервере. Итак, собственно представляю сорцы, так сказать как это работает на практике. Я еще раз повторюсь, использовать бота можно фактически для любых целей, но здесь рассмотрен пример для отправки новых записей, поступающих на онлайн сниффер. Сначала рассмотрим самого бота Code <?php set_time_limit(0); $startscripttime = mktime(); $endscripttime = $startscripttime + 600; include('WebIcqLite.class.php'); define('UIN', 587943262); define('PASSWORD', 'pass'); $sniffer_alias = 'alias_hpc'; $icq = new WebIcqLite(); chdir('/var/site/dir/icqbot'); if($icq->connect(UIN, PASSWORD)){
while(true) { $nowtime = mktime(); if($endscripttime <= $nowtime) { $icq->disconnect(); exit; } $fileopen_icq = 'send_alias_hpc'; $fd = fopen($fileopen_icq, "r"); $mes_to_send = fread($fd, filesize($fileopen_icq)); fclose($fd); // Проверяем, есть ли месага для отправки, и если нету, начинаем цикл с начала if(strlen($mes_to_send) < 2) { sleep(8); continue; } $icq->send_message('123123', $mes_to_send); // После того, как месага отправлена, обрезаем файл до нулевой длины $fileopen_icq = 'send_alias_hpc'; $fd = fopen($fileopen_icq, "w"); fclose($fd); sleep(8); } $icq->disconnect(); exit;
} else { echo $icq->error; exit; }
?> Здесь предполагается что наш скрипт находится в дире /var/site/dir/icqbot а текстовый файл, куда пишутся новые записи, называется send_alias_hpc (не забудьте поставить на него права 777). alias_hpc - алиас на онлайн сниффере HPC. Code $endscripttime = $startscripttime + 600; 600 - одна минута. При этом сам цикл выполняется бесконечно, но идет контроль времени Code if($endscripttime <= $nowtime) { $icq->disconnect(); exit; } тобеж через 600 секунд в данном случае скрипт завершит свою работу. Если соединение с сервером прошло неудачно, скрипт сразу же завершается и выводит ошибку. В каждой итерации цикла задержка 8 секунд, тобеж примерно каждые 8 секунд скрипт проверяет новые записи. Делается это чтением файла Code $fileopen_icq = 'send_alias_hpc'; $fd = fopen($fileopen_icq, "r"); $mes_to_send = fread($fd, filesize($fileopen_icq)); fclose($fd); Можно еще модифицировать бота таким образом, чтоб если хотябы 1 сообщение не доставлено, прекращать работу бота и выводить сообщение об ошибке Code <?php set_time_limit(0); $startscripttime = mktime(); $endscripttime = $startscripttime + 600; include('WebIcqLite.class.php'); define('UIN', 587943262); define('PASSWORD', 'pass'); $sniffer_alias = 'alias_hpc'; $icq = new WebIcqLite(); chdir('/var/site/dir/icqbot'); if($icq->connect(UIN, PASSWORD)){
while(true) { $nowtime = mktime(); if($endscripttime <= $nowtime) { $icq->disconnect(); exit; } $fileopen_icq = 'send_alias_hpc'; $fd = fopen($fileopen_icq, "r"); $mes_to_send = fread($fd, filesize($fileopen_icq)); fclose($fd); // Проверяем, есть ли месага для отправки, и если нету, начинаем цикл с начала if(strlen($mes_to_send) < 2) { sleep(8); continue; } if(!$icq->send_message('123123', $mes_to_send)){ echo $icq->error; $icq->disconnect(); exit; } // После того, как месага отправлена, обрезаем файл до нулевой длины $fileopen_icq = 'send_alias_hpc'; $fd = fopen($fileopen_icq, "w"); fclose($fd); sleep(8); } $icq->disconnect(); exit;
} else { echo $icq->error; exit; }
?> и проверкой Code if(strlen($mes_to_send) < 2) { sleep(8); continue; } если длина файла меньше 2 символов, скрипт простаивает 8 секунд (функция sleep), и начинает итерацию с начала. В общем технология довольно интересная. Можно запускать скрипт как с браузера, так и с командной строки (если есть доступ к шеллу). Можно поставить скрипт чтоб он работал например 3 часа или час, и каждый час вручную перезапускать скрипт, тогда все будет работать. Можно отправлять не сами записи, а только уведомления, лично у меня текстовые стороки с файла длиной больше чем помоему 350-360 символов не доставлялись полностью, почему затрудняюсь ответить, может тут с кодировкой что не то, ну в общем надо поэкспериментировать, так в целом все должно работать. Само обновление файла, который бот регулярно читает, происходит примерно так: Code // Пишем данные в файл для отправки icq-ботом $send_to_icq_mes = $script_data; chdir('/var/site/dir/icqbot'); $fileopen_icq = 'send_alias_hpc'; $fd = fopen($fileopen_icq, "w"); $fout = fwrite($fd, $send_to_icq_mes); fclose($fd); Здесь $script_data - собственно строка которую мы хотим отправить себе на асю. Вот такой вот получается бот. Надеюсь идею вы поняли. Всем успехов. Если будут вопросы пишите в теме обсуждение статьи на Форуме или мне в ПМ. Автор: SokoL Источник: hacker-pro.net
fdsg
|