[PHP] Wijzigingen binnen een draaiend script

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • m33p
  • Registratie: September 2002
  • Laatst online: 05-09 15:26
Ik ben bezig met een IRC bot in PHP. Dit werkt door gewoon commando's naar een socket te sturen.

De socket connectie blijft openstaan totdat er gedisconnect wordt van de IRC server:

PHP:
1
while (!feof($this->con['socket']))


Binnen deze while lus wordt elke regel afgevangen en geparsed.

Ik roep de boel op de volgende manier aan:

Index.php -> roept init functie aan in core.class.php. Hierin wordt de socket connectie geopend welke in een while lus mee gewerkt wordt.

Is er een manier (desnoods met includes ofzo) om binnen een draaiend PHP scipt code aan te passen? Nu moet ik steeds de bot opnieuw opstarten, maar dit is nogal ranzig. Ook kan ik de bot laten connecten door een IRC bouncer (proxy) zodat deze op IRC altijd online is, dit staat netter maar de bot zelf is dan alsnog offline.

[ Voor 3% gewijzigd door m33p op 30-05-2005 08:13 ]


Acties:
  • 0 Henk 'm!

  • Huppie
  • Registratie: Mei 2003
  • Laatst online: 02-09 09:59
Het zou in principe wel kunnen met includes, maar als er functies in zitten zul je dan de (PECL) override_function functie moeten gebruiken om je functies aan te maken.

Wat je natuurlijk ook zou kunnen doen is de filesize van alle bestanden die nodig zijn bij de init() opslaan en dan in je while lus controleren of dit nog hetzelfde is, is dit niet zo dan laat je de bot zichzelf exiten.
Vervolgens run je de bot binnen een while-lus (onder dos in een batch-scrippie, onder linux in een shell-scrippie) ;)
edit:
Nadeel is dan natuurlijk wel dat je dan weer even disconnect van irc.

[ Voor 7% gewijzigd door Huppie op 30-05-2005 08:38 ]

Proud member of TCF - D2OL is zooooo 2005


Acties:
  • 0 Henk 'm!

  • krvabo
  • Registratie: Januari 2003
  • Laatst online: 19-09 22:02

krvabo

MATERIALISE!

Maak een dir "modules". In die dir zet je al je modules (scripts) die niet tot de core functionaliteit van de bot behoren. voor je loop zet je
PHP:
1
$dircontents = Array();

In je loop vul je $dircontents met de inhoud van de dir "modules".
Voor de loop opnieuw begint, doe je
PHP:
1
$olddircontents = $dircontents;

Je loop begint opnieuw en vult de array weer met actuele dir-info.

In je loop maak je een simpele constructie a la
PHP:
1
2
3
4
5
for($i =0; $i < count($dircontents); $i++) {
    if (!in_array($dircontents[$i], $olddircontents)) {
        include $dircontents[$i];
    }
}

Natuurlijk wel even goede afhandeling maken :P

[ Voor 3% gewijzigd door krvabo op 30-05-2005 08:40 ]

Pong is probably the best designed shooter in the world.
It's the only one that is made so that if you camp, you die.


Acties:
  • 0 Henk 'm!

  • Huppie
  • Registratie: Mei 2003
  • Laatst online: 02-09 09:59
krvabo schreef op maandag 30 mei 2005 @ 08:39:
In je loop maak je een simpele constructie a la
PHP:
1
2
3
4
5
for($i =0; $i < count($dircontents); $i++) {
    if (!in_array($dircontents[$i], $olddircontents)) {
        include $dircontents[$i];
    }
}

Natuurlijk wel even goede afhandeling maken :P
Dit geeft je alleen de mogelijkheid nieuwe modules toe te voegen, helaas niet (zoals de TS aangeeft) code aan te passen :).

Proud member of TCF - D2OL is zooooo 2005


Acties:
  • 0 Henk 'm!

  • m33p
  • Registratie: September 2002
  • Laatst online: 05-09 15:26
In princiepe zou ik de loop in een core file kunnen gooien, en de functionaliteit (modules in Huppie's post) op die manier er in kunnen gooien, maar hoe zit dat met het geheugen gebruik? Gooit PHP de oude meuk uit z'n geheugen of houd PHP dit vast?

Het gewoon automatisch laten executen van het script (opnieuw) is wel een functionaliteit om in te bouwen, maar de bot disconnect dan (gaat uit de while lus) wat ik eigenlijk probeer te voorkomen.

edit:

Aan huppie, bot wordt ook gerund vanuit de commandline onder linux

[ Voor 11% gewijzigd door m33p op 30-05-2005 09:23 ]


Acties:
  • 0 Henk 'm!

  • Huppie
  • Registratie: Mei 2003
  • Laatst online: 02-09 09:59
m33p schreef op maandag 30 mei 2005 @ 09:18:
Het gewoon automatisch laten executen van het script (opnieuw) is wel een functionaliteit om in te bouwen, maar de bot disconnect dan (gaat uit de while lus) wat ik eigenlijk probeer te voorkomen.
Hoe vaak wijzig je dan wel niet in je source? Ik ben zelf ooit bezig geweest met een irc-bot maar alle testing in alpha fase en prive beta heb ik altijd op een lokale irc-server gedaan (is niet zo moeilijk op te zetten ;)) Imo is een reconnect niet erg op het moment dat je in je source aan het wijzigen bent.

Includen kan wel, maar functies redefinen niet, vandaar dat het imo slimmer is om de bot te restarten via een lus om de commandline in plaats van in je core.php

Proud member of TCF - D2OL is zooooo 2005


Acties:
  • 0 Henk 'm!

  • m33p
  • Registratie: September 2002
  • Laatst online: 05-09 15:26
Mja daar was ik al wel bang voor :( Developpen gaat ook niet in de live-bot gebeuren, maar het zou mooi zijn als ik de geupdate code in de live-bot kan knallen, en em de runtime code laat updaten zonder dat hij disconnect. Dat hij een paar seconden niet reageerd kan ik mee leven.

Ik ben ook bezig geweest om te kijken of include extra geheugen gebruikt, wat dus ook gebeurd (ook al overschrijf je de var).

http://exferno.3d-gamers.nl/Testcases/ircbot/

Deze code gebruik ik:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?PHP

function make_seed()
{
    list($usec, $sec) = explode(' ', microtime());
    return (float) $sec + ((float) $usec * 100000);
}

$testvar = 0;


echo "<br /><br /><b>Initial: " . memory_get_usage() . "</b><br /><br />";

for ($i=0; $i < 10000; $i++)
    include('memusage2.php');

echo $testvar;
echo "<br /><br /><b>1st pass: " . memory_get_usage() . "</b><br /><br />";

for ($j=0; $j < 10000; $j++)
    include('memusage2.php');

echo $testvar;
echo "<br /><br /><b>2nd pass: " . memory_get_usage() . "</b><br /><br />";


for ($k=0; $k < 10000; $k++)
    include('memusage2.php');

echo $testvar;
echo "<br /><br /><b>3rd pass: " . memory_get_usage() . "</b><br /><br />";

?>


en in memusage2.php
PHP:
1
2
3
4
5
6
<?PHP

srand(make_seed());
$testvar = rand();

?>


Met als resultaat

code:
1
2
3
4
5
6
7
Initial: 13648

895529428
1st pass: 14384

1034323397
2nd pass: 14440


Dit is dus een probleem, include_once kan ook niet aangezien de waardes van de variablen veranderen. Enig idee hoe ik dit kan doen zonder da mn geheugen vol raakt?

Iemand nog tips / ideen over hoe dit het makkelijkst / meest optimaal uit te voeren? De tip van hierboven, kijken of het bestand anders is kan, het zou ook via een irc command kunnen. Ik weet alleen niet wat er met de code die in gebruik is gebeurd als ik dit zou doen, of de data die er in verwerkt wordt maar daar kom ik maar op één manier achter denk ik. Alvast bedankt :)

[ Voor 47% gewijzigd door m33p op 30-05-2005 09:44 ]


Acties:
  • 0 Henk 'm!

  • LuCarD
  • Registratie: Januari 2000
  • Niet online

LuCarD

Certified BUFH

Je zou met create_function lambda-style functies kunnen maken en deze elke keer overschrijven als je een nieuwe module hebt gemaakt.

Programmer - an organism that turns coffee into software.


Acties:
  • 0 Henk 'm!

  • Radiant
  • Registratie: Juli 2003
  • Niet online

Radiant

Certified MS Bob Administrator

Je kan ook een netwerk deel bouwen, dat de verbinding met de IRC server onderhoudt en een deel waar dan de echte bot functionaliteit in zit, dat communiceert via iets wat je zelf bedenkt (simpel TCP via een zelfbedacht protocol oid).. Is wat meer werk maar je kan dan wel gewoon je bot restarten terwijl het netwerk deel gewoon online blijft en zodra de bot weer connect je wat info overstuurt.

Maar als het je alleen gaat om het feit dat je een quit en reconnect ziet zou je ook gebruik kunnen maken van een bouncer zoals psyBNC. Die behoudt je verbinding met de IRC server en als je er weer naar connect stuurt de bouncer gewoon weer joins, names, enz. overstuurt. Anderen op IRC zien verder niets gebeuren.

Acties:
  • 0 Henk 'm!

  • m33p
  • Registratie: September 2002
  • Laatst online: 05-09 15:26
Ja daar kwam ik ook mee in mn startpost, en zoals ik het nu zie is dat denk ik de 'oplossing' waar ik voor ga. Het restarten van de bot duurt nu zo'n 15 seconden denk ik (connecten naar IRC netwerk, synchroniseren van gebruikers / chan prefs etc, alles in de cache gooien, rss files updaten). Dit mag opzich best wel lang zijn aangezien er toch maar af en toe een grote update zal zijn op en duur.

Het mooiste was natuurlijk geweest om het in de run-time te updaten, maar dat wordt nogal omslachtig denk ik. Natuurlijk zijn mooie oplossingen hiervoor altijd welkom. Overigens denk ik het idee van Radiant met het protocol best werkbaar zou zijn, maar dan moet ik mn script behoorlijk om gooien. Mischien een idee voor in de volgende rebuild (zit nu op v2).

Acties:
  • 0 Henk 'm!

  • Radiant
  • Registratie: Juli 2003
  • Niet online

Radiant

Certified MS Bob Administrator

Ah dat wat je over bouncers had gezegt had ik ff gemist (snel doorheen gelezen O-) )

Je zou ook eens naar eggdrop kunnen kijken, dat is een bot die je in TCL kan scripten (en dynamisch reloaden) met erg veel mogelijkheden, hoewel dat natuurlijk wel weer betekend dat je alles opnieuw moet schrijven. Misschien ook een idee voor die versie 2 waar je het over had.

Acties:
  • 0 Henk 'm!

  • m33p
  • Registratie: September 2002
  • Laatst online: 05-09 15:26
[rml][ PHP / Sockets] IRC bot laten connecten via bouncer (proxy)[/rml]

[ Voor 110% gewijzigd door m33p op 30-05-2005 11:49 ]


Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-09 14:42
Je zou je PHP-bestanden kunnen uitlezen en door de eval()-functie knallen. Dat is volgens mij de enige methode;
PHP:
1
eval(file_get_contents("script.php"));

Lijkt me alleen wel een stapel overhead geven...

[ Voor 8% gewijzigd door frickY op 30-05-2005 15:18 ]

Pagina: 1