Тема: PHP IRC bot
Показать сообщение отдельно

  #9  
Старый 09.08.2007, 15:53
Rast1k
Banned
Регистрация: 09.08.2007
Сообщений: 56
Провел на форуме:
372630

Репутация: -63
По умолчанию

нет самый простой ботег у меня
Код:
#!/usr/local/bin/php
<?php
// Параметры IRC сервера
$irc_server["ip"]='XXX.XXX.XXX.XXX';
$irc_server["port"]=6669;
$irc_server["name"]='irc.mine.net';

// Список каналов на которых будет присутствовать бот
$channels[0]="somechannel0";
$channels[1]="somechannel1";
$channels[2]="somechannel2";

// Таймер для отсчета времни чтобы выдать случайную фразу
$timer=0;

$privates=Array();

// Параметры бота
$bot["nick"]='PHP_Bot';
$bot["user"]='PHP_Bot';
$bot["host"]='bot.mine.net';
$bot["ip"]='XXX.XXX.XXX.XXX';
$bot["hz"]='PHP_Bot';

// Функция из мана используемая для получения "наиболее случайных чисел"
function make_seed() {
    list($usec, $sec) = explode(' ', microtime());
    return (float) $sec + ((float) $usec * 100000);
}

// Функция установки коннекта к IRC серверу
// Устанавливает начальный коннект
function connect_IRC () {
    global $irc_server, $bot, $fp;
    // Открываем сокет с заданым сервером и портом
    $fp = fsockopen($irc_server["ip"], $irc_server["port"], $errno, $errstr,30);
    $flag=0;
    // Вычитываем все что даст нам сервер, до ключевой фразы, после которой,
    // можно отсылать данные о пользователе
    while (!$flag && !feof($fp)) {
        $line=fgets ($fp);
        if (preg_match("/bFoundsyourshostnameb/", $line)) {
            $flag=1;
        }
    }
    // Пишем в сокет данные о авторизации бота
    fputs ($fp, sprintf ("NICK %sn", $bot["nick"]));
    fputs ($fp, sprintf ("USER %s "%s" "%s" :%sn",
                         $bot["user"], $bot["host"], $bot["ip"], $bot["hz"]));
    $flag=0;
    // Снова вычитываем все до ключевого номера 700, после которого можно
    // начинать заходить в каналы
    while (!$flag && !feof($fp)) {
        $line=fgets ($fp);
        if (preg_match("/b700b/", $line)) {
            $flag=1;
        }
    }
    // Возвращаем указатель на открытый сокет основной части
    return ($fp);
}

// Функция для подготовки вывода в канал
// одного из предопределенных случайных выражений
function is_time($chan) {
global $timer, $log_file, $bot;
    // Полный путь к текстовому файл в котором определены возможные выражения
    $texts=file('/home/myaccount/bot_conf/lyaps');
    $message='';
    $now=mktime(date ("H"), date("i"), date("s"), date ("m"),
                date ("d"), date ("Y"));
    // Определяем интервал с которым бот будет что-то говорить в канал
    // (в этом примере - 10 минут)
    $time_to_say=mktime(date ("H"), date("i")-10, date("s"),
                        date ("m"), date ("d"), date ("Y"));
    // Если пора что-то говорить - формируем фразу,
    // если нет - возвращаем пустое значение
    if ($timer<$time_to_say) {
        // Сбрасываем таймер
        $timer=$now;
        // Определяем фразу
        srand(make_seed());
        $mess=rand(1, sizeof($texts));
        $texts[$mess]=trim($texts[$mess]);
        // Форматируем строку для отсылки серверу
        $message = sprintf ("PRIVMSG #%s :%sn",$chan,$texts[$mess]);
        // Если выражение не пустое пишем в лог
        if ($texts[$mess]!='') {
            $log_file='/home/myaccount/irc_log/#'.$chan.date("Ymd").'.log';
            $lf=fopen($log_file,"a");
            fputs ($lf, sprintf("[%s] <%s> %sn",
                         date("H:i"), $bot["nick"], $texts[$mess]));
            fclose ($lf);
        }
    }
    //Возвращаем подготовленую строку
    return ($message);
}

// Функция отсылки привествия для зашедших на канал пользователей
// берет одно из предопределенных приветствий и подставляет ник
function hello ($str) {
    global $bot;
    // Полный путь к текстовому файл в котором определены возможные выражения
    $texts=file('/home/myaccount/bot_conf/hello');
    // Определяем фразу
    srand(make_seed());
    $mess=rand(1, sizeof($texts));
    // Форматируем строку для отсылки серверу
    $message = sprintf ("PRIVMSG #%s :%s%s!n",$str[2],$texts[$mess], $str[1]);
    // Пишем в лог
    $log_file='/home/myaccount/irc_log/#'.$str[2].date("Ymd").'.log';
    $lf=fopen($log_file,"a");
    fputs ($lf, sprintf("[%s] <%s> %s%s!n",
                        date("H:i"), $bot["nick"], $texts[$mess], $str[1]));
    fclose ($lf);
    // Возвращаем подготовленую строку
    return ($message);
}

// Устанавливаем соединение с сервером
if ($sp=connect_IRC()) {
    reset ($channels); // Думаю что не нужен, но... на всяк пожарный
    while (list(,$channel_name)=each($channels)) {
        // Заходим во все определенные каналы
        fputs ($sp, sprintf("JOIN #%sn", $channel_name));
        fputs ($sp, sprintf("MODE #%sn", $channel_name));
        // Ниже бот берет на себя права оператора сервера, для этого
        // для него должны быть определены соответствующие настройки сервера
        // (см. документацию к серверной части)
        fputs ($sp, sprintf("OPER %s PHP_BOT_oper_passwordn", $bot["nick"]));
        fputs ($sp, sprintf("MODE %s +an", $bot["nick"]));
        fputs ($sp, sprintf("MODE %s +An", $bot["nick"]));
        fputs ($sp, sprintf("SAMODE #%s +o %sn", $channel_name, $bot["nick"]));
        // Определение регэкспов для отслеживания ключевых выражений
        // Вход пользователя на канал
        $joined[$channel_name]=
            '/:(.+)!.+sJOINs:#('.$channel_name.')/';
        // Сообщение от пользователя в канал
        $privmsg[$channel_name]=
            '/:(.+)!.+sPRIVMSGs#('.$channel_name.')s:(.+)/';
        // Выход пользователя с канала
        $partmsg[$channel_name]='/:(.+)!.+sPARTs#('.$channel_name.')/';
        // Установка темы канала
        $topic[$channel_name]=
            '/:(.+)!.+sTOPICs#('.$channel_name.')s:(.+)s/';
        // Отключение пользователя от сервера
        $quitmsg='/:(.+)!.+sQUITs:Quit:s(.*)s/';
        // Сообщение в приват боту
        $private_me='/:(.+)!.+sPRIVMSGs('.$bot["nick"].')s:(.+)/';
        // Смена ника юзером
        $nick='/:(.+)!.+sNICKs:(.+)s/';
    }
}

$flag=0;
// В принципе - бесконечный цикл (если не оборветься связь с сервером)
while (!$flag && !feof($fp)) {
$line=fgets($sp);
reset($joined);
// Проверяем - если идет команда PING от сервера - отвечаем PONG
$ping='/^(PING)b/';
if (preg_match($ping, $line)) {
    fputs ($fp, "PONG :".$irc_server["name"]."n");
}
else {
// Флаг для определения того что бот уже нашел ключевую фразу
    $stop=0;
    // Запускаем цикл по всем нужным каналам
    while ((list($keys, $values)=each($joined)) && !$stop) {
         // Проверяем не время ли сказать чего-нибудь в канал
        $str_=is_time($keys);
        fputs($fp, $str_);
        // Проверка на вход кого-либо на канал
        if (preg_match($joined[$keys], $line, $matches)) {
           $stop=1;
           if ($matches[1]!=$bot["nick"]) {
                   // Пишем в лог
                $log_file='/home/myaccount/irc_log/#'.
                            $matches[2].date("Ymd").'.log';
                $lf=fopen($log_file,"a");
                fputs ($lf, sprintf("[%s] * <%s> вошел на канал %sn",
                            date("H:i"$matches[1], $matches[2]));
                fclose ($lf);
                // Получаем строку приветствия
                $str_=hello($matches);
                // Отсылаем фразу серверу
                fputs ($fp, $str_);
            }
        }
        else {
            // если это просто фраза в канал, либо в приват боту
            if (!preg_match($action[$keys], $line, $matches)
                && (preg_match($privmsg[$keys], $line, $matches)
                   || preg_match($private_me, $line, $matches))) {
                    $stop=1;
                    // Отсылаем функции обработки сообщений
                    // не рассматривается (в данной статье)
                    $str_=analyze_msg($matches);
                    // Выводим результат
                    fputs ($fp, $str_);
                }
                else {
                // Если пользователь покинул канал
                if (preg_match($partmsg[$keys], $line, $matches)) {
                    // Просто пишем в лог
                    $log_file='/home/myaccount/irc_log/#'.
                                $matches[2].date("Ymd").'.log';
                    $lf=fopen($log_file,"a");
                    fputs ($lf, sprintf("[%s] * <%s> покинул канал %sn",
                                 date("H:i"), $matches[1], $matches[2]));
                    fclose ($lf);
                    }
                    else {
                        // Если пользователь покинул сервер
                        if (preg_match($quitmsg, $line, $matches)) {
                            // Просто пишем в лог
                            $log_file='/home/myaccount/irc_log/#'.
                                        $keys.date("Ymd").'.log';
                            $textq='';
                            // Определяем причину выхода (если указана)
                            if (trim($matches[2])!='') {
                                $textq="(".trim($matches[2]).")";
                            }
                            $lf=fopen($log_file,"a");
                            fputs ($lf, sprintf(
                                        "[%s] * <%s> покинул IRC сервер %sn",
                                         date("H:i"), $matches[1], $textq));
                            fclose ($lf);
                        }
                        else {
                            // Если пользователь сменил ник
                            if (preg_match($nick, $line, $matches)) {
                                // Пишем в лог
                                $log_file='/home/myaccount/irc_log/#'.
                                            $keys.date("Ymd").'.log';
                                $lf=fopen($log_file,"a");
                                fputs ($lf, sprintf("[%s] * %s взял имя %sn",
                                        date("H:i"),
                                        $matches[1],
                                        $matches[2]));
                                fclose ($lf);
                            }
                            else {
                                // Если установлена тема
                                if (preg_match($topic[$keys],$line,$matches)) {
                                    // Пишем в лог
                                    $log_file='/home/myaccount/irc_log/#'.
                                                $keys.date("Ymd").'.log';
                                    $lf=fopen($log_file,"a");
                                    fputs ($lf, sprintf("............",
                                        date("H:i"),
                                        $matches[1],
                                        $matches[3]));
                                    fclose ($lf);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
// Пауза 1 сек. - чтобы меньше грузить сервер
sleep(1);
}
// Закрытие сокета
fclose ($sp);
?>
Взято с inattack.ru (C)
 
Ответить с цитированием