Vytvárame IRC bota v PHP

Napsal O webu (») 20. 3. 2006 v kategorii PHP/HTML, přečteno: 2244×

Dnes si spravím jednoduchého IRC bota so zákoladnými funkciami ako kalkulačka, registrácia, login + práva užívateľov,

Ako tu celé funguje?

Takže v prvom rade sa skript pripojí pomocou fsockopen na daný server a na danom porte, odošle identifikačné príkazy USER a NICK popr. odpovie na PING. Potom sa spustí nekonečná slučka while (skončí vtedy, ak sa spojenie so serverom zruší) a v tejto slučke sú uložené všetky funkcie. Po každom novom pretočení slučky sa načíta ďalších 512 znakov z IRC (ak nejaké sú) a ďalej ich v slučke spracúvava vo funkciach.

Použité premenné

$CONFIG - pole, v ktorom sú zapísané všetky dôležité nastavenia pe chod bota ako napr. nick, server, port, atď.
$socket - handle socketu. Pomocou neho čítame a zapisujeme (resp. prímame a posilame) príkazy sieťou
$b - 512 precítaných znakov.

Zdrojové kódy

<?
$CONFIG = array(
"server" => "irc.2600.net", // Server, na ktorý sa budeme pripájať
"nick" => "LamaBot", // Nick
"port" => 6667, // Port servera
"channel" => "#moj_kanal", // Kanál/e, na ktoré sa budeme pripájať
"name" => "LamaBot", // Názov bota (potrebné, pre odoslanie príkazu USER)
"uptime" => time(), // Čas spustenia bota
"db_server" => "localhost", // SQL server
"db_user" => "root", // SQL používateľ
"db_pass" => "", // SQL heslo
"db_name" => "LamaBot" // SQL databáza
);

/* Pripojíme sa k SQL serveru */
mysql_connect($CONFIG['db_server'], $CONFIG['db_user'], $CONFIG['db_pass']) or die(mysql_error());
mysql_select_db($CONFIG['db_name']) or die(mysql_error());

set_time_limit(0); // Ignorujeme časový limit
ignore_user_abort(1); // Ignorujeme vypnutie užívatelovho browsera (ak užívateľ vypne browser, skript bude bežať ďalej)

$socket=fsockopen($CONFIG['server'], $CONFIG['port']); // Najdôležitejši časť bota! Pripojenie k IRC serveru
if ($socket) { // Ak sa podarilo pripojiť k IRC serveru
prikaz("USER ".$CONFIG['nick']." Bot by timbulko :". $CONFIG['name']); // Identifikujeme sa na serveri
prikaz("NICK ".$CONFIG['nick'].rand(0,1000)); // Pošleme nick v tvare: nick + náhodné číslo od 0 do 1000 (to je ochrana pred tým, keby bol už nick použitý)
$e=explode(",",$CONFIG['channel']); // Ak je zadaných viac ako jeden kanál, tak ich rozdelíme na časti
foreach ($e as $value) {
prikaz("JOIN ".$value); // Pripojíme sa na kanál/e
}
prikaz("NICK ".$CONFIG['nick']); // Zmeníme si nick na normálnu podobu (bez čísla na konci)
while (!feof($socket)) { // Opakuj, pokiaľ sa dá čítať zo socketu
$r=trim(FRead($socket, 512)); // Prečítame 512 znakov zo socketu
$riadok = ereg_replace(":([^!]*)!([^@]*)@([^ ]*) ([^ ]*) ([^:]*):(.*)","1?2?3?4?5?6",$r); // Rozdelíme riadok socketu na jednotlivé časti
funkcie($riadok); // Nasmerujeme na funkciu funkcie
flush(); // Vyprázdnime zásobník
}
}







function funkcie ($riadok) { // Definujeme funkciu funkcie
global $CONFIG,$socket,$r; // Definujeme si globálne premennú pre túto funkciu
list($nick,$id,$dns,$prikaz,$kanal,$text) = explode("?",$riadok); // Rozdelíme si rozsekaný riadok na jednotlivé premenné


if (eregi("PING :(.*)",$r)) { // Ak zacítí bot ping, odpovie na neho pongom
$e=explode(" ",$r);
for($i=0;$i<=count($e);$i++) {
if (eregi("^PING :(.*)$",$e[$i])) {
$e=explode(":",$e[$i]);
prikaz("PONG :".$e[1]);
}
}
}

if ($prikaz=="KICK") { // Ak bot zachití príkaz kickc, pokúsi sa pripojiť späť
prikaz("JOIN ".$kanal);
}

#################################
# Od tejto časti sa začína #
# funkčná/výkonná časť bota. #
# Tu môžete písať svoje vlastné #
# funkcie. Pre príklad som ich #
# sem zopár pridal :) #
#################################

/* Jednoduchý tvar funkcie:

if (eregi("^funkcia",$text)) {
príkazy funkcie
}
elseif (eregi("^iná funkcia",$text)) {
príkazy inej funkcie
}

*/



// užívateľské funkcie
if (eregi("^!up",$text)) {
$bezi = (time()-$CONFIG['uptime']);
$dni = floor($bezi/86400);
$bezi -= ($dni*86400);
$hodin = floor($bezi/3600);
$bezi -= ($hodin*3600);
$minut = floor($bezi/60);
$bezi -= ($minut*60);
$sekund = $bezi;
prikaz("PRIVMSG ".$kanal." :Bot je spusteny ".$dni." dni, ".$hodin." hodin, ".$minut." minut a ".$sekund." sekund");
}



elseif(eregi("^!cas",$text)) {
prikaz("PRIVMSG ".$kanal." :[cas] ".date("H:i:s"));
}





// admin funkcie
elseif (eregi("^#login",$text) && !isset($logins[$nick])) {
if ($text=="#login") {
$res=mysql_query("SELECT * FROM `uzivatelia` WHERE `dns` = '".$dns."'");
}
else {
list(,$login,$heslo)=explode(" ",$text);
$res=mysql_query("SELECT * FROM `uzivatelia` WHERE `login` = '".$login."' AND `pass` = '".$heslo."'");
}
if (mysql_num_rows($res)==1) {
$row=mysql_fetch_array($res);
$logins[$nick]['prava'] = $row['prava'];
$logins[$nick]['last_login'] = $row['last_login'];
$logins[$nick]['login'] = $row['login'];
$logins[$nick]['pass'] = $row['pass'];
$logins[$nick]['id'] = $row['id'];
$logins[$nick]['dns'] = $row['dns'];
$dl=date("j.n.Y o H:i:s",$logins[$nick]['last_login']);
mysql_query("
UPDATE `uzivatelia` SET
`last_login` = '".time()."',
`dns` = '".$dns."'
WHERE `id` = '".$row['id']."';
");
prikaz("NOTICE ".$nick." :Uzivatel ".$nick." bol uspesne prihlaseny! Naposledy ste boli prihlaseny dna ".$dl);
}
else {
prikaz("NOTICE ".$nick." :Uzivatela ".$nick." sa nepodarilo prihlasit!");
}
}



elseif (eregi("^#op",$text)) {
if ($logins[$nick]['prava']>=1) {
if ($text=="#op") {
prikaz("MODE ".$kanal." +o ".$nick);
}
else {
$e=explode(" ",$text);
prikaz("MODE ".$kanal." +o ".$e[1]);
}
}
else {
prikaz("NOTICE ".$nick." :Nie ste prihlaseny!");
}
}



elseif (eregi("^#deop",$text)) {
if ($logins[$nick]['prava']>=1) {
if ($text=="#deop") {
prikaz("MODE ".$kanal." -o ".$nick);
}
else {
$e=explode(" ",$text);
prikaz("MODE ".$kanal." -o ".$e[1]);
}
}
else {
prikaz("NOTICE ".$nick." :Nie ste prihlaseny!");
}
}



elseif (eregi("^#kick",$text)) {
if ($logins[$nick]['prava']>=1) {
$e=explode(" ",$text,3);
prikaz("KICK ".$kanal." ".$e[1]." :".$e[2]);
}
else {
prikaz("NOTICE ".$nick." :Nie ste prihlaseny!");
}
}





// SuperAdmin funkcie
elseif (eregi("^~quit",$text)) {
if ($logins[$nick]['prava']==2) {
prikaz("PRIVMSG ".$kanal." :Odchadzam...");
exit;
}
else {
prikaz("PRIVMSG ".$kanal." :Uzivatel ".$nick." nie je prihlaseny alebo nie je administratorom!");
}
}



elseif (eregi("^~join",$text)) {
if ($logins[$nick]['prava']==2) {
$e=explode(" ",$text);
prikaz("PRIVMSG ".$kanal." :Pripajam sa na kanal ".$e[1]."...");
if (file_exists("kluc.dat")) {
$open=FOpen("kluc.dat","r");
$read=FRead($open,filesize("kluc.dat"));
FClose($open);
prikaz("JOIN ".$e[1]." ".$read);
}
else {
prikaz("JOIN ".$e[1]);
}
prikaz("PRIVMSG ".$kanal." :Bol som pripojeny na kanal ".$e[1]."!");
}
else {
prikaz("PRIVMSG ".$kanal." :Uzivatel ".$nick." nie je prihláseny alebo nie je administratorom!");
}
}



elseif (eregi("^~part",$text)) {
if ($logins[$nick]['prava']==2) {
if ($text=="~part") {
prikaz("PRIVMSG ".$kanal." :Odchadzam...");
prikaz("PART ".$kanal);
}
else {
$e=explode(" ",$text);
prikaz("PRIVMSG ".$kanal." :Odpajam sa z kanalu ".$e[1]."...");
if ($kanal!=$e[1]) {
prikaz("PRIVMSG ".$e[1]." :Odchadzam...");
}
prikaz("PART ".$e[1]);
prikaz("PRIVMSG ".$kanal." :Bol som odpojeny z kanalu ".$e[1]."!");
}
}
else {
prikaz("PRIVMSG ".$kanal." :Uzivatel ".$nick." nie je prihlaseny alebo nie je administratorom!");
}
}
}



// a este fce prikaz, ktora odosle socket
function prikaz($prikaz) {
global $socket,$CONFIG,$bites;
FWrite($socket, $prikaz." ");
}
?>
a ešte zdrojový kód sql tabuliek CREATE TABLE `uzivatelia` (
`id` INT NOT NULL AUTO_INCREMENT,
`login` VARCHAR(50) NOT NULL DEFAULT '',
`pass` VARCHAR(50) NOT NULL DEFAULT '',
`last_login` INT DEFAULT '0',
`prava` INT NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
);


Euphoria.wz.cz - počítadlo, anketa, diskusné fórum, guestbook, návštevná kniha, chat board, mailer, easybox
Autor: timbulko
Facebook Twitter Topčlánky.cz Linkuj.cz

Komentáře

Zobrazit: standardní | od aktivních | poslední příspěvky | všechno
Článek ještě nebyl okomentován.


Nový komentář

Téma:
Jméno:
Notif. e-mail *:
Komentář:
  [b] [obr]
Odpovězte prosím číslicemi: Součet čísel čtyři a pět