BeBot - An Anarchy Online and Age Of Conan chat automaton

Development => Coding and development discussion => Topic started by: Riccarr on January 17, 2010, 02:42:47 am

Title: Reloading custom modules
Post by: Riccarr on January 17, 2010, 02:42:47 am
Hello,

While working on a new module I find it a pain in the a$$ to have to stop/restart the bot each time I need to make adjustments to the custom module.  I'm not very php savvy, but I see that the main.php loops the custom dir and does a require_once() to load each module.

I thought perhaps making a call to a new function (in main.php) that would check the timestamp of the modules there and call require() again on any module whose timestamp was newer than the last time checked.

I got this all to work ... except that when it calls to reload the modified php file, it does not actually effect a change to the version that is already loaded.

What I mean is if a function in the custom mod returns "test1" when called via in-game command; and then I update the module so the function returns "test2" and save it, this causes the timestamp to update and it gets reloaded with a "require()" call. Then while still in game (and not restarting the bot) the same command still returns "test1". So the call to require() loaded the module however it didn't overwrite or replace the existing module in memory.

I hope your following me.  Maybe you all are already doing something like this and I'm missing the boat?

Here is the reload function I use; I place a call to it in the WHILE loop near the bottom of the main.php module, where it "listens for incoming events"

Code: [Select]

/*
Listen for incoming events...
*/
while(true)
{
if ($aoc -> wait_for_packet() == "disconnected")
$bot -> reconnect();

$bot -> cron();
   
    reloadCustoms();  //call our reload function
}


function reloadCustoms()
{
    global $bot;
    global $lastCustomLoad;   //this set in after custom modules loaded
    global $lastCustomCheck;  //this set in after custom modules loaded
   
    if (time() - $lastCustomCheck > 10)   //just to keep overhead low, this loop only runs every 10 seconds
    {
        // $bot -> log("MAIN", "LOG", "Checking reload list ...");
        $filesLoaded = false;
        $folder = dir("./custom/modules/");
        while ($mod = $folder->read())
        {
            $value = $bot -> core("ini") -> get($mod,"Custom_Modules");

            $fileTime = filemtime("./custom/modules/" . $mod);
            if (!is_dir($mod) && !preg_match("/^_/", $mod) && preg_match("/\.php$/i", $mod)
                && $value != "FALSE")
                if ($fileTime > $lastCustomLoad)
                {
                    require "custom/modules/" . $mod;
                    $bot -> log("MAIN","MOD LOAD", "RELOADING: ".$mod);
                    $filesLoaded = true;
                }
        }
       
        if ($filesLoaded)
            $lastCustomLoad = time();
           
        $lastCustomCheck = time();
    }
}
Title: Re: Reloading custom modules
Post by: Khalem on January 17, 2010, 02:48:04 pm
Loading a module is not an issue while the bot is running. However PHP provides no way for us to unload current functions and classes afaik.

This has been discussed internally in the past, and the verdict was that it's simply not possible to do within the constraints PHP gives us.
Title: Re: Reloading custom modules
Post by: Riccarr on January 18, 2010, 07:20:52 am
Pity ... was hoping it was workable as it would safe a lot of bot stops and restarting.

Thanks for letting me know.
Title: Re: Reloading custom modules
Post by: DJKRose on January 30, 2010, 06:02:43 pm
You could try runkit_import() (http://de.php.net/manual/de/function.runkit-import.php). It reads in a PHP file replacing all the existing functions and classes with the new definitions.
Note that everything outside functions/classes is ignored, so the new instantiation of modules (normally the first line) has to be done manually somehow.
SimplePortal 2.3.7 © 2008-2024, SimplePortal