Archív Inet.sk Pôvodný autor: Michal Pirchala
16. 12. 2010 o 21:00 16x

IRC bot v PHP - 3. časť

Minule sme si naprogramovali základné pripojenie na IRC sieť. Po pripojení na server sme dostali od frigg-a (bot IRC siete) správu, ktorou si vyžadoval verziu nášho IRC klienta. Dnes doprogramujeme automatickú odpoveď na túto správu, odpovede na PING-y, ktoré sme nemuseli riešiť keďže sme neboli dlhšiu dobu neaktívni a moduly.
IRC bot v PHP - 3. časť

Najprv z jadra odstránime riadky, ktoré slúžili iba na testovacie účely:

if (empty($msg)){
    send("JOIN $channel");sleep(3);
    send("PRIVMSG $channel :text odoslaný do kanála");
    send("QUIT");
    die();
}

Správa VERSION

Túto správu nemusíme dostať iba po pripojení na IRC server od frigg-a, ale aj od ostatných užívateľov, ktorí požiadajú o verziu nášho klienta. Preto bude vhodné kontrolovať každú správu, ktorú dostaneme od servera. Teda overovať sa bude pri každom cykle. Pod riadok „if (!empty($msg)) echo $msg."\n"; „ pridáme toto:

//VERSION
if (preg_match("/^\:(.*)\!.* PRIVMSG $nick \:VERSION/", $msg, $matches)){
    Send("NOTICE {$matches[1]} :VERSION VERZIA KLIENTA\n\r");
}

Najprv si musíme vysvetliť v akej forme k nám budú chodiť správy:

:NICK!HOST PRIVMSG NÁŠ_NICK/KANÁL :OBSAH SPRÁVY

Podľa tohto vzoru máme zostavený regulárny výraz. Do premennej $matches si odchytíme nick odosielateľa správy. $nick v regulárnom výraze je náš nick, aby sme neodpovedali na version správy, ktoré napríklad niekto pošle do kanála. Odpovieme príkazom NOTICE. Namiesto „VERZIA KLIENTA“ si môžete doplniť niečo vlastné. Vo fantázii sa medze nekladú.

PING

Či nejde o ping, budeme tiež overovať pri každom cykle a hneď naň odpovieme. Parameter získame pomocou funkcie substr (namiesto preg_match).

//PING
if (substr($msg, 0, 6) == "PING :"){
    Send("PONG :".substr($msg, 6)."\n\r");
}

Moduly

Moduly vyriešime pomerne jednoducho. Vytvoríme si priečinok modules v priečinku kde máme jadro, kde budeme moduly ukladať. Pri každom cykle prejdeme celý tento priečinok a všetky moduly (skrtipy) vložíme a vykonáme pomocou funkcie include.

//MODULES
$d = dir("modules");
while (false !== ($entry = $d->read())) {
    if ($entry!='.' && $entry!='..') include('modules/'.$entry);     //ak sa prave includovany subor nerovna .. (nadradeny priecinok), alebo . (aktualny priecinok)
}
$d->close();

V moduloch budeme pravdepodobne využívať údaje ako nick odosielateľa, host odosielateľa, aktuálny kanál a správu. Aby sme získanie týchto údajov neriešili v každom module samostatne, spravíme to ešte pred vykonaním prvého modulu. Ešte raz vzor správ, podľa ktorého zostavíme regulárny výraz:

:NICK!HOST PRIVMSG NÁŠ_NICK/KANÁL :OBSAH SPRÁVY

//SPRAVA
if (preg_match("/^\:(.*)\!(.*) PRIVMSG (.*) \:(.*)$/", $msg, $matches)){
    $sender = $matches[1];
    $host = $matches[2];
    $act_chan = $matches[3];
    $message = $matches[4];
     
    if ($act_chan[0]!='#') $act_chan = $sender;
}

Do premennej $matches si uložíme subvýrazy. Prvý je nick odosielateľa ($sender), druhý host odosielaťeľa ($host), tretí aktuálny kanál ($act_chan) a štvrtý obsahuje samotnú správu ($message). Pozor na rozdiel medzi $message a $msg. $message obsahuje obsah správy (v príkaze PRIVMSG) a $msg obsahuje jeden riadok dát, ktorý sme dostali od servera. Všimnite si podmienku ktorá nasleduje. Tretí subvýraz ktorý dostaneme z nášho regulárneho výrazu obsahuje vždy kam sa má správa dostať. Ak má ísť do kanálu bude tam #kanál. Ale ak má ísť konkrétnemu užívateľovi, obsahuje jeho nick.  Keby sme dostali správu, obsahovala by premenná $act_chan náš nick. A keďže tam budeme odpovedať, písali by sme správy sami sebe. Táto podmienka zaistí, že ak sa nebude prvý znak premennej $act_chan rovnať „#“ (teda to nieje správa do kanála ale správa smerovaná nám), tak sa do $act_chan vloží nick odosielateľa. Teda pri odpovedi už budeme odpovedať jemu a nie sami sebe.

Ak by sa do týchto premenných uložili nejaké hodnoty, ubehol by ďalší cyklus a od servera by sme nedostali žiadnu správu, tieto hodnoty by sa nezmenili a bot by napríklad vykonával stále ten istý príkaz. Preto ich na konci každého cyklu vyprázdnime.

$msg='';
$message='';
$host='';
$sender='';

Automatické pripojenie do kanálu

Ak chceme, aby sa náš bot pripojil do vopred určeného kanálu, pridáme do jadra tento kód:

if (preg_match("/^\:.* 376 $NICK/", $msg, $matches)){
    Send("JOIN $channel $pass\n\r");
}

Teda po ukončení správy MOTD (ako sa môžeme dočítať v dokumentácii, táto správa má čislo 376) sa pripojíme do kanála uloženého v premennej $channel. Ak by sme do jadra nepridali túto funkciu, náš bot by po pripojení na server nevstúpil do žiadneho kanála a mohol by vykonávať iba príkazy poslané cez súkromné správy. V niektorej z ďalších častí si ukážeme, ako prinútiť bota, aby sa pripojil do ďalších kanálov.

Jadro

//Pripojenie k MySQL databaze
define('SQL_NAME', 'meno');
define('SQL_PASS', 'heslo');
define('SQL_HOST', 'server');
define('SQL_DBNM', 'databaza');
$dbc = mysql_connect(SQL_HOST, SQL_NAME, SQL_PASS);
if (!$dbc) die('Nedá sa pripojiť k databázovému serveru');
mysql_select_db(SQL_DBNM) or die ('Nedá sa vybrať databáza.');
mysql_query('SET NAMES UTF8');     //kodovanie v UTF-8

//Neobmedzeny casovy limit na vykonanie skriptu
set_time_limit(0);

//Nastavenie
$channel = '#naskanal';
$nick = 'mojbot';

//Funkcie
function Send ($cmd){
    $cmd = $cmd."\n\r";
    global $server;
    fwrite($server['SOCKET'], $cmd, strlen($cmd));
    echo "< $cmd";
}

//Pripojenie na server
$server = array();
$server['SOCKET'] = fsockopen("irc.freenode.net", 6667, $errno, $errstr);

if ($server['SOCKET']){

    Send("NICK $nick");
    Send("USER $nick $nick irc.freenode.net :$nick");
    stream_set_timeout($server['SOCKET'], 1);     //na spravu od servera budeme cakat maximalne jednu sekundu

    while(true){
        $msg = trim(fgets($server['SOCKET'], 1024));
        if (!empty($msg)) echo ">".$msg."\n";
     
        //VERSION
        if (preg_match("/^\:(.*)\!.* PRIVMSG $nick \:VERSION/", $msg, $matches)){
            Send("NOTICE {$matches[1]} :VERSION VERZIA KLIENTA\n\r");
        }

        //AUTOMATICKE PRIPOJENIE NA KANAL
        if (preg_match("/^\:.* 376 $NICK/", $msg, $matches)){
            Send("JOIN $channel $pass\n\r");
        }

        //PING
        if (substr($msg, 0, 6) == "PING :"){
            Send("PONG :".substr($msg, 6)."\n\r");
        }

        //SPRAVA
        if (preg_match("/^\:(.*)\!(.*) PRIVMSG (.*) \:(.*)$/", $msg, $matches)){
            $sender = $matches[1];
            $host = $matches[2];
            $act_chan = $matches[3];
            $message = $matches[4];
     
            if ($act_chan[0]!='#') $act_chan = $sender;
        }

        //MODULES
        $d = dir("modules");
        while (false !== ($entry = $d->read())) {
            if ($entry!='.' && $entry!='..') include('modules/'.$entry);     //ak sa prave includovany subor nerovna .. (nadradeny priecinok) alebo . (aktualny priecinok)
        }
        $d->close();

        $msg='';
        $message='';
        $host='';
        $sender='';
    }

} else echo "Nemôžem sa pripojiť na server";
?>

Záver

Momentálne je bot trocha nepraktický, keďže ho nemôžeme nijako ukončiť. Odporúčam ho preto spúšťať zo shellu, kde ho kedykoľvek môžete vypnúť stlačením Ctrl+C (v Linuxe). Nabudúce doprogramujeme modul na vykonavánie príkazov a nejaké príkazy.

Novinky a inšpirácie

Z nášho blogu

Prečítajte si novinky, inšpirácie a dôležité informácie zo sveta webhostingu a technológií.

Bezpečnostné aktualizácie PHP: Chráňte svoj web pred hrozbami Oznamy
21. 10. 2026

Bezpečnostné aktualizácie PHP: Chráňte svoj web pred hrozbami

Vývojársky tím PHP vydal dôležité bezpečnostné záplaty pre všetky oficiálne podporované verzie PHP 8. Na našich serveroch sme nezaváhali ...

Čítať viac
Gmail končí s funkciou „Odoslať ako“ pre cudzie e-mailové adresy. Čo to znamená pre vás? Oznamy
01. 10. 2026

Gmail končí s funkciou „Odoslať ako“ pre cudzie e-mailové adresy. Čo to znamená pre vás?

Google oznámil, že v januári 2027 zruší v Gmaile funkciu „Odoslať ako“ (Send as) pre e-mailové adresy od iných poskytovateľov. Ak ste si ...

Čítať viac
Večerná „prestávka“ pre server VIP033 Oznamy
25. 09. 2026

Večerná „prestávka“ pre server VIP033

Neustále pracujeme na tom, aby vaše weby bežali hladko, rýchlo a bezpečne. Technológie idú míľovými krokmi vpred a my v Inet.sk s nimi dr...

Čítať viac
Novinky na Inet.sk (09 / 2026) Novinky
09. 09. 2026

Novinky na Inet.sk (09 / 2026)

Posledné mesiace sme v Inet.sk nevenovali len stabilite serverov, ale najmä počúvaniu vašich reálnych skúseností z každodennej praxe. Výs...

Čítať viac

Podpora klientom

Máte ďalšie otázky?

Nezúfajte, pripravili sme pre Vás jednoduché odpovede na najdôležitejšie otázky, ktoré od našich klientov dostávame.

Zistiť viac

Naše výhody

Prečo si nás vybrať?

Našim klientom ponúkame až 30-dňovú záruku vrátenia peňazí.

Sme skutočný slovenský webhosting

Slovenská
firma

Nepatríme pod žiadnu nadnárodnú spoločnosť, sme malá rodinná firma.

Na nás sa môžete kedykoľvek spoľahnúť

Dlhoročné
skúsenosti

Na slovenskom trhu pôsobíme už viac ako 20 rokov, sme overená značka.

Naši prví zákazníci sú stále s nami

Spokojní
zákazníci

Naši zákazníci sú ako naša rodina, preto nám verí už viac ako 1250 klientov.

Maximálna bezpečnosť

Maximálna
bezpečnosť

Chránime Vás pred útokmi i SPAMom. U nás sú Vaše dáta v bezpečí.

Prozákaznícka podpora

Ochotná
podpora

Zakladáme si na individuálnom prístupe, preto Vám vždy radi pomôžeme.

Kvalita a dobrá cena

Férová
cena

Cena pri obnove je rovnaká ako pri objednávke. Nezdražujeme po prvom roku a bez skrytých poplatkov.

U nás sa Vám nič nestratí

Pravidelné
zálohovanie

Vaše dáta zálohujeme každý deň, dostupné sú aj zálohy z pred niekoľkých mesiacov.

Svižný Admin Panel nájdete len u nás

Prehľadný
Admin Panel

Máme rýchly a prehľadný Admin Panel, ktorý zvládne používať naozaj každý.

Správa používateľov

Správa
používateľov

Spravujte svoje projekty bez akýchkoľvek obáv s kolegami alebo externými partnermi.

Máme zľavy pre verných klientov

Vernostné
zľavy

Verní klienti u nás automaticky získavajú 15 % zľavu na každú ďalšiu objednávku.

My Vás nebudeme obmedzovať

Bez
obmedzení

Neobmedzujeme počet databáz, e-mailov, ftp a ani prenos dát.

Hosting pre WordPress

WordPress
na 1 klik

Nainštalujte si obľúbené redakčné systémy rýchlo a jednoducho.

Referencie

Spokojní zákazníci

Pozrite sa, čo o nás povedali naši klienti. Neváhajte a pridajte sa k nám ešte dnes.

Auto 100
Bystricoviny
eCall Slovakia
Filip Jančík
Frost
Merkury Broker
Mi:Su Design
Mesto Nitra
Pro Clienta
Schneider Lekáreň
Vego Marketing
Mesto Zlaté Moravce

Všetky ceny sú uvádzané bez DPH
© 2006 - 2026, Inet.sk, s. r. o., Všetky práva vyhradené

Na našej stránke používame "cookies". Vďaka nim sledujeme návštevnosť, prispôsobujeme reklamu a používateľské nastavenia, čo zlepšuje Váš zážitok z našej stránky. Súhlasíte s ich spracovaním?
Vlastné nastavenia cookies