Games::Manager - Perl extension for easy management of multiplayer games in interactive environments.
SYNOPSIS
Code:
use Games::Manager;<br /><br /> # Create a new game manager.<br /> my $game = new Games::Manager ();<br /><br /> # Set up broadcast handler.<br /> $game->setHandler (broadcast => sub {<br /> my $self = shift;<br /> print "Got message for $self{to}: $self{message}\n\n";<br /> });<br /><br /> # Add a game and a player.<br /> $game->create (<br /> id => "tag",<br /> name => "The Game of Tag",<br /> );<br /><br /> # Add a player.<br /> $game->addPlayer ("tag",<br /> host => "Perl",<br /> name => "foo",<br /> );<br /><br /> # Drop that player.<br /> $game->dropPlayer ("tag", "foo");<br /><br /> # Destroy the game.<br /> $game->destroy ("tag");
DESCRIPTION
Games::Manager is a simple interface for creating and managing multiplayer games in interactive environments (for example, with IRC bots).
METHODS
new
Quote:
Create a new game manager. This method should be called only once (a single manager object can manage as many games as you need). You can also pass in default variables (try to avoid any that begin with an underscore).
my $manager = new Games::Manager (debug => 1);
version
Quote:
Returns the module's version.
my $version = $manager->version;
create
Quote:
Create a new game instance. Passed in are details on the game, which must include a unique identifier and a name (you can pass in any extra data if you want to, but not much else is used by the module itself).
This creates a new, empty game. To add players to it later, call the addPlayer method with the same ID that you created the game with.
This method will return 0 if there was an error (most likely the ID was already in use by another game).
$manager->create ( id => "tag", name => "The Game of Tag", );
destroy
Quote:
Destroy a game instance. Pass in arguments in hash form. The required element is the ID of the game to destroy. Optional arguments are "force" (boolean) to force any existing players out of the game. If that is true, another argument "alert" should be provided to define whether or not the players should be told about the game being terminated. You can also pass a "message" to be broadcasted to those players.
$manager->destroy ( id => "tag", force => 1, message => "Game terminated by an administrator.", alert => 1, );
setHandler
Quote:
Set a handler. Currently the only handler is for "broadcast" - your handler sub would receive a hash containing "to" and "message"
$manager->setHandler (broadcast => \&broadcast);
sendMessage
Quote:
Send a message to a single person. This method is usually called from within the module.
$manager->broadcast ("tag", "Soandso has been tagged!");
<*lazy*>** General Game Methods ***lazy*>
queryGame
Quote:
Check a game's existence. Pass in the Game ID. This method will return 1 if the game exists, or 0 if it does not.
my $exists = $manager->queryGame ("tag");
listGames
Quote:
Returns an array of every Game ID that is currently in existence under this manager. It will return 0 if there are no games.
my @games = $manager->listGames;
<*lazy*>** Player Methods ***lazy*>
addPlayer
Quote:
Add a player to an already created game. The first parameter is the Game ID, followed by a hash that must contain (at least) a unique name for the player.
$manager->addPlayer ("tag", name => "foo", );
dropPlayer
Quote:
Remove a player from a game. The game ID must exist, and a name must be defined.
$manager->dropPlayer ("tag", "foo");
findPlayer
Quote:
Searches every existing game for a certain player. This method returns an array of each Game ID that the player exists in.
my @ids = $manager->findPlayer ("foo");
queryPlayer
Quote:
Check a player's existence within a game. Returns true if they exist there.
my $exists = $manager->queryPlayer ("tag", "foo");
listPlayers
Quote:
Returns an array of players that exist in the passed in Game ID.
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
______________________________________________
That's the POD data, now for the more down-to-earth descriptions.
I made this module as a means of quickly and easily being able to create multiplayer "p4" or "p2p" games with your bots. In Juggernaut, there were a few p4 games (Azulian Tag and Chat for example), and each of those commands had to copy and paste tons of code for getting their messages out and keeping their data separate from the others.
This module will maintain all your games' data for you. All you need to do is set up a broadcast handler (the code for how you plan to get your messages out to the people) and then make a few commands that calls on these functions.
A broadcast handler's code can be as simple as this:
Code:
$manager->setHandler (broadcast => \&broadcast);<br /><br />sub broadcast {<br /> my %data = @_;<br /><br /> # To and Message.<br /> my $to = $data{to};<br /> my $msg = $data{msg};<br /><br /> # Call them!<br /> $msn->call ($to, $msg);<br />}
And in my Leviathan, that's basicly what it does too. __________________________
For an example of a command that tests this module thoroughly, I'll post my new Azulian Tag (for Leviathan) shortly after this post.
Anyway, this is the 1.0 beta of this module. If you find any bugs, report them here.
EDIT Reuploaded the zip. _________________ Current Site (2008) http://www.cuvou.com/
Just a little tip, you can use this for things other than games with maybe a little modification;
Such as users chatrooms: Where users can make there own chatrooms and people can join them;
My 100th Post =]
That's what I was thinking about when I first got the idea to make this module... have user-created room ID's all begin with "chat_" to not conflict with other games. _________________ Current Site (2008) http://www.cuvou.com/
I've made an update to Leviathan... if somebody playing a game on MSN closes their conversation, it wouldn't take them out of the game (so if anything new happened later, the bot would keep calling them).
So these are the updates:
Quote:
msn_answer.pl and msn_join.pl These updated handlers will keep the list of members in the current socket (because the Close handler can't get them).
msn_close.pl This will search each game that the user exists in, and drop them from it.
msn_close code:
Code:
sub msn_close {<br /> my ($self) = @_;<br /><br /> # Get this socket.<br /> my $sock = $self->getID;<br /><br /> # Our handle.<br /> my $sn = $self->{Msn}->{Handle};<br /> $sn = lc($sn);<br /> $sn =~ s/ //g;<br /><br /> # Get the client.<br /> my $client = $chaos->{bots}->{$sn}->{sock_members}->{$sock};<br /> my @mem = split(/\,/, $client);<br /><br /> print "Debug // \$client = $client\n"<br /> . "Debug // \@mem = @mem\n" if $chaos->{debug} == 1;<br /><br /> my $stamp = &get_timestamp();<br /> print "$stamp\n"<br /> . "ChaosMSN: Now closing socket #$sock.\n";<br /><br /> #############################################<br /> # See if this socket was used for anything. #<br /> #############################################<br /><br /> # See if this user participated in any games.<br /> print "Debug // Checking if this user was in any games...\n" if $chaos->{debug} == 1;<br /> foreach my $user (@mem) {<br /> $user = lc($user); $user =~ s/ //g;<br /> $user = 'MSN-' . $user;<br /><br /> print "Debug // Checking user $user...\n" if $chaos->{debug} == 1;<br /><br /> my @games = $chaos->{games}->findPlayer ($user);<br /> print "Debug // Games Array: @games\n" if $chaos->{debug} == 1;<br /> if (defined @games) {<br /> foreach my $id (@games) {<br /> next if $id == 0;<br /> print "Debug // Checking game $id...\n" if $chaos->{debug} == 1;<br /><br /> # Drop this player.<br /> $chaos->{games}->dropPlayer ($id, $user);<br /><br /> # Broadcast to this game.<br /> $chaos->{games}->broadcast ($id, "$user has been disconnected (idle).");<br /><br /> print "Debug // Dropped player from $id!\n" if $chaos->{debug} == 1;<br /> }<br /> }<br /> }<br /><br /> # A "Shut Up!" socket.<br /> if (exists $chaos->{bots}->{$sn}->{_shutup}->{$sock}) {<br /> delete $chaos->{bots}->{$sn}->{_shutup}->{$sock};<br /> print "Socket #$sock was a \"Shut Up!\" socket - now deleted!\n";<br /> }<br /><br /> print "\n";<br /> return 1;<br />}
The zip is attached, extract all its contents to your Leviathan/handlers/msn folder. _________________ Current Site (2008) http://www.cuvou.com/