PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : hilfe: stringzerlegung...


EyeDacor
20.09.2004, 13:44:35
da mir netirc zu überladen und ircg zu teuer ist, habe ich nun selbst einen php irc bot programmiert... der connect zum server klappt wunderbar, register und nickset klappen auch, und der timestamp aus den pings wird einfach mit explode rausgefiltert und mit pong zurückgesendet, sowie modt werden abgefangen und anschließend wird der gewünschte channel gejoint...

wer sich mit raw connects ins irc auskennt (a la telnet und co) wird wissen, dass dort nicht wie in mIRC und co sachen wie "<Name> hallo" ankommen, sondern eher syntaktische sachen wie ":name!~meinident@mein.isp.de PRIVMSG #channel :hallo" ankommen...

seit längerer zeit beschäftige ich mich damit, dieses sauber zu unterteilen... perfekt wäre ein array der in etwa so aussieht
empfangenes['name'] = "name"
empfangenes['ident] = "meinident"
empfangenes['isp'] = "mein.isp.de"
empfangenes['action'] = "PRIVMSG"
empfangenes['channel'] = "#channel"
empfangenes['text'] = "hallo"

warum ich das so genau beschreibe? ich brauche hilfe, eventuell tip(p)s wie dies am besten zu lösen ist... mit explode bin ich gehscheitert, da, wenn trennzeichen im text vorkamen, eben diese dann auch abgetrennt wurden etc... blabla

jemand ne idee?




hier der gehirnbrand den ich bis jetzt zu stande gebracht habe...


<?php
$socket=fsockopen("irc.server.de",6667);
while($string=fgets($socket))
{
if (stristr($string,"ident"))
{
break;
}
}
fputs($socket,"user bot 0 0 botn");
fputs($socket,"nick botnamen");
$pingreply=fgets($socket);
$pingstamp=explode(" :",$pingreply);
fputs($socket,"PONG :".$pingstamp[1]."n");
while(true)
{
if (stristr(fgets($socket),"End of /MOTD command."))
{
break;
}
}
fputs($socket,"join #channeln");

while($string=fgets($socket))
{
//
//
// hier bräuchte ich die string zerlegung :)
// von $string ;)
//
//

// ...erstmal temporäre unsaubere abfrage nach einer privmsg
// nur damit der bot wenigstens anständig disconnected falls ich will
if (stristr($string,"privmsg"))
{
// wenn jemand quit sagt...
if (stristr($string,"quit"))
{
fputs($socket,"quitn");
}
}
// pings mit pong beantworten...
if (stristr($string,"ping"))
{
$pongsrv=explode(" :",$string);
fputs($socket,"PONG :".$pongsrv[1]."n");
}
}
?>


jaja, nicht sehr toll und sicher, aber für den anfang reichts erstmal imo... geht ja nur ums logging, soll kein talkbot werden...

yozek
21.09.2004, 00:28:27
Hmmm, daraus einen Array zu erzeugen sollte doch machbar sein...

Ich kenne mich zwar mit den genauen String der gesendet wird nicht aus, aber REGEX wäre wohl die beste Möglichkeit.

Desweiteren eine Idee mit einem Explode:

:name!~meinident@mein.isp.de PRIVMSG #channel :hallo


$ident_teil = explode('@', $string);
$name_teil = explode('~', §ident_teil[0]);

$name = $name_teil[0];
$ident = $name_teil[1]

$isp_teil = explode(' ', $ident_teil[1],1);

$isp = $ident_teil[0];

$channel_teil = explode('#', $string);
$channel_teil = explode(' ', $channel_teil[0],1);

$channel = $channel_teil[0];

$text = $channel_teil[1];


Musst dir mal das anschauen, hab das gerade so schnell runtergeschrieben. Können also noch fehler drin sein.
Aber ich empfehle dir auf jeden FAll REgExp zu verwenden, denn dazu sind die Regulären Ausdrücke wie geschaffen fpr..

Gruss

EyeDacor
21.09.2004, 16:45:18
... :)

habs mittleriweile schon gelöst:


$temp1 = preg_split("/[:,!~,@, , , :]+/",$string);
$temp2 = preg_split("/^:(.*?):/",$string);

echo "nick: $temp1[1]n";
echo "ident: $temp1[2]n";
echo "host: $temp1[3]n";
echo "action: $temp1[4]n";
echo "chan: $temp1[5]n";
echo "text: $temp2[1]nn";

yozek
21.09.2004, 22:44:54
Hab gar nicht an split gedacht in dem moment ;)

Good work und thx fuer die info

EyeDacor
21.09.2004, 23:00:49
jo, die sache geht gut vorran... code struktur hat sich auch verändert...

config.inc.php

<?php
$nick="Botname";
$channels="#botchannel,#meinchannel,#nochmehrchannels";
$server="irc.server.de";
$port="6667";
$password="passwort";
$ident="bot";
?>


bot.php

<?php
include("config.inc.php");
$socket=fsockopen($server,$port);
fputs($socket,"NICK $nickn");
fputs($socket,"USER $ident 0 * $identn");
while ($string=fgets($socket))
{
if (preg_match("/^PING :[^[:blank:]]{1,}$/",$string))
{
fputs($socket,preg_replace("/^PING :/","PONG ",$string)."n");
}
if (preg_match("/^:[[:alnum:],.]{1,} [[:digit:]]{3}(.*?)/",$string))
{
$temp1 = preg_split("/^:[[:alnum:],.]{1,} | | $nick /",$string, 2, PREG_SPLIT_NO_EMPTY);
switch($temp1[0])
{
case("332"):
$temp2=preg_split("/^(.*?) 332 $nick | :/",$string, 2, PREG_SPLIT_NO_EMPTY);
$topic=array("$temp2[0]"=>$temp2[1]);
$temp2[1]=str_replace("rn","",$temp2[1]);
fputs($socket,"PRIVMSG $temp2[0] :Ich bin in $temp2[0] mit dem Topic "$temp2[1]"n");
break;
case("376"):
$chans=explode(",",$channels);
foreach ($chans as $chan)
{
fputs($socket,"JOIN $chann");
}
break;
case("433"):
echo $string;
sleep(5);
fsockclose($socket);
break;
}
}
echo $string;
}
?>


außer channels joinen, sagen welches topic (wenn eins ist) und wo das ist, pings beantworten und bei "nick already in use" abbrechen (433) kann er nicht... fehlt halt noch eine ganze menge!

ich werd mich bei ineteresse mal melden wenn alles fertig ist... die irc rfcs sind einfach nur 'groß'...