mirror of
https://github.com/mumble-voip/mumble.git
synced 2025-10-26 11:19:16 +00:00
git-svn-id: https://mumble.svn.sourceforge.net/svnroot/mumble/trunk@1142 05730e5d-ab1b-0410-a4ac-84af385074fa
201 lines
4.7 KiB
Perl
201 lines
4.7 KiB
Perl
#! /usr/bin/perl -w
|
|
|
|
use strict;
|
|
use warnings;
|
|
use Carp;
|
|
use DBI;
|
|
use XML::LibXML;
|
|
|
|
# BF2 Link Script
|
|
#
|
|
# Links murmur to one or more BF2 servers, see the wiki for details.
|
|
#
|
|
|
|
our $dbpath = "murmur.sqlite";
|
|
our $basechannel = "Servers";
|
|
|
|
my %channame;
|
|
my %chanparent;
|
|
my %conid;
|
|
my %conplayerid;
|
|
my %conchannel;
|
|
|
|
sub findchannel($$) {
|
|
my ($parent, $name) = @_;
|
|
foreach my $id (keys %channame) {
|
|
if (($chanparent{$id} == $parent) && ($channame{$id} eq $name)) {
|
|
return $id;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
my $parser = new XML::LibXML();
|
|
my $doc = $parser->parse_file($ARGV[0]) or croak "failed read XML";
|
|
$doc->indexElements();
|
|
|
|
my $dbh = DBI->connect("dbi:SQLite:dbname=${dbpath}", "", "") or croak $DBI::errstr;
|
|
$dbh->{AutoCommit} = 0;
|
|
|
|
my $sth;
|
|
$sth = $dbh->prepare("SELECT count(*) AS num FROM commands");
|
|
$sth->execute();
|
|
my $r = $sth->fetchrow_hashref();
|
|
my $inlist = $$r{'num'};
|
|
$sth->finish();
|
|
croak "Unfinished commands in queue" if ($inlist > 0);
|
|
|
|
|
|
$sth = $dbh->prepare("SELECT channel_id, parent_id, name FROM channels");
|
|
$sth->execute();
|
|
while((my $r=$sth->fetchrow_hashref())) {
|
|
$channame{$$r{'channel_id'}}=$$r{'name'};
|
|
$chanparent{$$r{'channel_id'}}=$$r{'parent_id'};
|
|
}
|
|
$sth->finish();
|
|
|
|
|
|
$sth = $dbh->prepare("SELECT con_id, player_id, channel_id, player_name FROM connections");
|
|
$sth->execute();
|
|
while((my $r=$sth->fetchrow_hashref())) {
|
|
my $name = lc $$r{'player_name'};
|
|
$conid{$name} = $$r{'con_id'};
|
|
$conplayerid{$name} = $$r{'player_id'};
|
|
$conchannel{$name} = $$r{'channel_id'};
|
|
}
|
|
$sth->finish();
|
|
$dbh->commit();
|
|
|
|
my $parent = findchannel(0, $basechannel);
|
|
croak "Missing basechannel" if ($parent == -1);
|
|
|
|
$sth=$dbh->prepare("INSERT INTO commands (command,arg1,arg2,arg3) VALUES (?,?,?,?)");
|
|
|
|
our %watched;
|
|
our %checked;
|
|
|
|
foreach my $context ($doc->findnodes('qstat/server')) {
|
|
my $servname = $context->findvalue("name");
|
|
|
|
next if (! $servname);
|
|
|
|
my %rule;
|
|
|
|
foreach my $rulectx ($context->findnodes('rules/rule')) {
|
|
my @attr = $rulectx->attributes();
|
|
my $name=$attr[0]->getValue();
|
|
$rule{$name} = $rulectx->textContent();
|
|
}
|
|
|
|
if ($rule{'gamename'} ne "battlefield2") {
|
|
print "$servname: Skipping unknown game type";
|
|
next;
|
|
}
|
|
|
|
my $t1map = $rule{'team_t0'};
|
|
my $t2map = $rule{'team_t1'};
|
|
|
|
if (! $t1map || ! $t2map) {
|
|
print "$servname: Failed to find team mapping";
|
|
next;
|
|
}
|
|
|
|
my $chan = findchannel($parent, $servname);
|
|
if ($chan == -1 ) {
|
|
print "$servname: Missing server channel -- creating\n";
|
|
$sth->execute("createchannel", $parent, $servname, undef);
|
|
next;
|
|
}
|
|
|
|
my $team1 = findchannel($chan, "Team 1");
|
|
my $team2 = findchannel($chan, "Team 2");
|
|
|
|
if ($team1 == -1) {
|
|
print "$servname: Missing Team 1 channel -- creating\n";
|
|
$sth->execute("createchannel", $chan, "Team 1", undef);
|
|
next;
|
|
}
|
|
|
|
if ($team2 == -1) {
|
|
print "$servname: Missing Team 2 channel -- creating\n";
|
|
$sth->execute("createchannel", $chan, "Team 2", undef);
|
|
next;
|
|
}
|
|
|
|
my $missing = 0;
|
|
my @subchans;
|
|
|
|
foreach my $cname (1 .. 9, "Unassigned") {
|
|
my $id;
|
|
$id=findchannel($team1, $cname);
|
|
push @subchans, $id;
|
|
if ($id == -1) {
|
|
$sth->execute("createchannel", $team1, $cname, undef);
|
|
$missing = 1;
|
|
}
|
|
$id=findchannel($team2, $cname);
|
|
push @subchans, $id;
|
|
if ($id == -1) {
|
|
$sth->execute("createchannel", $team2, $cname, undef);
|
|
$missing = 1;
|
|
}
|
|
}
|
|
|
|
if ($missing) {
|
|
print "$servname: Created missing squad channels\n";
|
|
next;
|
|
}
|
|
|
|
foreach my $w ($chan,$team1,$team2,@subchans) {
|
|
$watched{$w} = 1;
|
|
}
|
|
|
|
my @t1list;
|
|
my @t2list;
|
|
|
|
foreach my $playerctx ($context->findnodes("players/player")) {
|
|
my $name = lc $playerctx->findvalue('name');
|
|
my $team = $playerctx->findvalue('team');
|
|
next if (! $name || ! $team);
|
|
next if (! defined($conid{$name}));
|
|
my $conid = $conid{$name};
|
|
my $chan = $conchannel{$name};
|
|
my $pchan = $chanparent{$chan};
|
|
my $id = $conplayerid{$name};
|
|
|
|
$checked{$name} = 1;
|
|
|
|
my $wchan;
|
|
if ($team eq $t1map) {
|
|
$wchan = $team1;
|
|
} elsif ($team eq $t2map) {
|
|
$wchan = $team2;
|
|
}
|
|
next if (! $wchan);
|
|
|
|
if (($wchan != $chan) && ($wchan != $pchan)) {
|
|
$sth->execute("moveplayer", $conid, findchannel($wchan, "Unassigned"), undef);
|
|
}
|
|
if ($id >= 0) {
|
|
if ($wchan == $team1) {
|
|
push @t1list, $id;
|
|
} else {
|
|
push @t2list, $id;
|
|
}
|
|
}
|
|
}
|
|
$sth->execute("setgroup", $team1, "players", join(",",@t1list));
|
|
$sth->execute("setgroup", $team2, "players", join(",",@t2list));
|
|
}
|
|
|
|
foreach my $name (keys %conid) {
|
|
next if $checked{$name};
|
|
if (defined($watched{$conchannel{$name}})) {
|
|
$sth->execute("moveplayer", $conid{$name}, 0, undef);
|
|
}
|
|
}
|
|
|
|
$sth->finish();
|
|
$dbh->commit();
|
|
$dbh->disconnect();
|