BeBot - An Anarchy Online and Age Of Conan chat automaton

Development => Coding and development discussion => Topic started by: Alreadythere on February 27, 2008, 11:36:51 am

Title: Some thoughts about a new structure
Post by: Alreadythere on February 27, 2008, 11:36:51 am
I've experimented with a possible new structure for BeBot, taking advantage of the PHP 5.2 object system. Before I do anything besides simple testing I want to put the ideas up to discussion, as the changes would require a modification of almost every file of the bot.

The underlying idea of all the changes is to take advantage of the PHP 5.2 object system to make the code easier to support, easier to read and easier to change, as well as offering the possibility for some new features. Here a first list of the changes, I may have forgotten some I already thought about.
Title: Re: Some thoughts about a new structure
Post by: Temar on February 28, 2008, 05:36:45 am
And there are a couple if disadvantages in it, mainly the serial nature of PHP. This means that if one of several bots in a single instance is delayed in any command execution it would lock all other bots till it is done. Queueing all operations as far as possible could reduce this of course.

with the Onlineorg.php orgs.php modules im working on
i plan on implimenting anti lag stuff
i have already done it on orgs.php
this module gets entire list list 1 letter at time
i changed to to do 1 letter at a time then take a few seconds break useing cron which is easy done by adding the cron $this -> bot -> cron["5sec"]["orgs"] or something :p, i think i added a min time too (just incase 5sec ran as i entered it)
Title: Re: Some thoughts about a new structure
Post by: Blueeagle on February 28, 2008, 06:42:35 am
Bot manager:
This could be implemented as a single php-process that spawns one php process for each bot. That way you get ($num_bots+1) processes instead of ($num_bots * 2) as it is today. This avoids the bottle neck of the serial process while not adding any processes in any scenario.

Register modules with bot manager:
I'm not quite sure if I think this is the way to go. I think having the abillity to have separate module-directories for each bot is a good thing. That way you can have fail-over bots run in case some experimental module craps up on the cutting edge bot.

Module loading and unloading:
This would be activating and deactivating. This is in general a good idea. The default should IMO be a minimum of modules activated when a bot is first started. Then the owner would configure which modules that should be activated.

Abstract base class:
I definetly advocate this. Not only will it help when writing modules but it will also make modules more uniform. I have been working on something and it currently looks like this
Code: [Select]
<?php

abstract class BaseModule
{
protected $bot// A reference to the bot
public $help//A window containing help text for this module
public $module_name//Name of the module extending this class

//This would be called in the constructor of the extending module
function __construct (&$bot$module_name)
{
//Save reference to bot
$this -> bot = &$bot;
$this -> module_name $module_name;
}

//Prototype for the command_handler
abstract protected function command_handler($name$msg$origin);

//Interface to register command. Now with checks for duplicate command definitions.
//(I'm not sure if this can be moved into Bot.php as it needs access to $this -> module_name;
protected function register_command($channel$command$access="SUPERADMIN"//Upgraded default level as SUPERADMIN to maintain security.
{
if(!isset($this -> bot -> commands[$channel][$command]))
{
$this -> bot -> commands[$channel][$command] = &$this;
$this -> bot -> accesscontrol -> create($channel$command$access);
}
else
{
//Say something useful for modules not registering commands properly. (THIS IS BUGGED)
if (!empty($this -> bot -> commands[$channel][$command] -> module_name))
{
$old_module "an old module";
}
else
{
$old_module $this -> bot -> commands[$channel][$command] -> module_name;
}
$this -> bot -> log("CMD""ERROR""Duplicate command definition! The command '$command' for channel '$channel'".
" has already been registered by $old_module and is attempted re-registered by {$this -> module_name}");
}
}

protected function register_event($event)
{
$this -> bot -> commands[$event][] = &$this;
}

protected function parse_com($command$pattern = array('com''sub''args'))
{
$num_pieces=count($pattern);
$pieces explode(' '$command$num_pieces);
$com array_combine($pattern$pieces);
return ($com);
}

/************************************************************************
 Default to replying in the same channel as the command has been recieved
*************************************************************************/

public function tell($name$msg)
{
$reply $this -> command_handler($name$msg"tell");
if ($reply !== FALSE)
$this -> bot -> send_tell($name"##normal## $reply ##end##");
}

public function gc($name$msg)
{
$reply $this -> command_handler($name$msg"gc");
if ($reply !== FALSE)
$this -> bot -> send_gc("##normal## $reply ##end##");
}

public function pgmsg($name$msg)
{
$reply $this -> command_handler($name$msg"pgmsg");
if ($reply !== FALSE)
$this -> bot -> send_pgroup("##normal## $reply ##end##");
}
}
?>

As you can see the three responding functions are public to allow for a module to re-define their behaviour. This is mainly to allow control over where the reply would be going.

Make core modules private:
I think protecting the core and making a uniform API a good idea. However I haven't given the implementation for this much thought.
Title: Re: Some thoughts about a new structure
Post by: Alreadythere on February 28, 2008, 11:23:50 am
Bot manager:
This could be implemented as a single php-process that spawns one php process for each bot. That way you get ($num_bots+1) processes instead of ($num_bots * 2) as it is today. This avoids the bottle neck of the serial process while not adding any processes in any scenario.
Sounds nice, I just haven't found any functions to allow for non-blocking sub-execution which work on all platforms...
Stuff like system() or exec() is blocking, process forking would be nice, but isn't supported under windows.
Besides, fully seperated processes would deal with any possible deadlock problems but would remove a few of the added possibilities I was thinking about. If all is in one process controlled by a central manager we could make an easier to use relay for example, by directly putting the chat into the functions that have to handle them. This would need no sent chat on the chatservers at all. Was just a thought I had though :)

Register modules with bot manager:
I'm not quite sure if I think this is the way to go. I think having the abillity to have separate module-directories for each bot is a good thing. That way you can have fail-over bots run in case some experimental module craps up on the cutting edge bot.
We could add the directory name to the module name, dividing the modules in some categories that way. This would allow the loading of two modules with the same name for worst cases. Though my ideas won't remove the need to restart the whole bot manager if you want some changes in files to take effect.
This would pretty much only be of advantage in a production environment, testbeds most likely won't really profit of it much. It won't prevent anything in them though, there won't be any lost functionality compared with today.

Module loading and unloading:
This would be activating and deactivating. This is in general a good idea. The default should IMO be a minimum of modules activated when a bot is first started. Then the owner would configure which modules that should be activated.
Something like that, yes. We just have to make sure the required core modules are always active, and I guess we should make sure that the most important user interfaces can't be disabled too.

Abstract base class:
I definetly advocate this. Not only will it help when writing modules but it will also make modules more uniform. I have been working on something and it currently looks like this [...]
As you can see the three responding functions are public to allow for a module to re-define their behaviour. This is mainly to allow control over where the reply would be going.
Yes, I was thinking about something like your class. I was thinking about a simple check for command/channel combos in the tell/gc/pgmsg functions, but basically we are thinking about the same thing.
Title: Re: Some thoughts about a new structure
Post by: clashbot on February 28, 2008, 02:33:51 pm
currently right now I am running 5 bots, which means 5 command windows in Windows. As this is a nuisance, I deal with it as I do like final control and being able to see what is going on with any of the bots, which is why I do not have them running as a service. With those 5 command windows, that also means I have 5 instances of the logs etc, one per bot. With this bot man that you are talking about, I am assuming all bots would run from a single command window, which means line monitoring will be harder. That I can deal with, are you still going to maintain a directory structure where multiple bots will be able to output it's log independantly of the other bot and not be a uniform log of all bots in one log file? Also, if there is an ability to turn modules on and off inside the bot ingame, then the only reason you would have to reload everything to implement a change would be a mod to any of the core files, not the module files, or customs, as these you would be able to unload via bot config, update, reload via bot config, and depending how you are implementing the base calls, should allow for the new module to load straight way, or am I totally off base here?
Title: Re: Some thoughts about a new structure
Post by: Alreadythere on February 28, 2008, 06:54:22 pm
The idea is just to reduce the number of php instances running. This would mean you could go down to one window, but in my plans I don't want to mess in any way with the current structure of the log files.

About modules loading/unloading: I'm not sure if it is possible to reload class definitions, I think we'd always end with a "Class already defined" fatal error if we try. That's assuming we find a reliable way to load the same file in different versions. So to get a new version of the same module working you would have to restart the whole php instance. Which would mean all bots managed by that BotManager instance. Loading new module files in an already running bot should be possible though.
Title: Re: Some thoughts about a new structure
Post by: Khalem on February 28, 2008, 07:55:16 pm
Reducing the number of PHP instances running alone is worth the change ;)

Having a bot manager will also open up other avenues that could be fun, including allowing external management, be it a web interface or a windows/linux GUI app.

As for the the lack of process forking on Windows, we already detect if we are running on windows or not, and if there are real benefits to it, it would be worth allowing linux users to take advantage of it. Forking would be a necessity if we where to do external management for example.

One important thing in all this would be what happens with the bot manager and the other bots if one of the bots crashes if it's the same process versus being a child of the bot manager?
Title: Re: Some thoughts about a new structure
Post by: Alreadythere on February 28, 2008, 08:14:23 pm
Afaik with fork only the child process crashes on a critical error. So I think it would be the same with the php version, though I've never tested it. If all is running in the same process without any childs all bots managed by that instance of the BotManager will crash. At least I think that would be the case. Guess I should test it sometimes.

Normal disconnects or shutdowns wouldn't be a problem though.
SimplePortal 2.3.7 © 2008-2024, SimplePortal