* Committing Lulurun's Cgi/Perl implementation of the UGAI servers.

* I love you long time.
0.6.0-stable
Adam Frisby 2008-03-25 16:29:54 +00:00
parent 3d1b4f8578
commit 8c05b81d68
35 changed files with 7246 additions and 0 deletions

40
share/perl/README Normal file
View File

@ -0,0 +1,40 @@
INTRODUCTION
This is a Opensim UGAI server compatible implementation.
It is written in Perl, based on apache (CGI or mod_perl)
Not all of the functions of UGAI server are implemented, but currently,
it supports the whole user login process and most of the operations on
inventory, asset.
The main purpose of this implemetation is to improve UGAI server's
* stability - That's what Apache was born to do
* scability - You can use reliable technology such as load balancing,
clustering that have been used for years.
IMPLEMENTATION
"*.cgi" are the server programs, for example of user server:
opensim -> http://127.0.0.1:8002
here -> http://127.0.0.1/user.cgi
"lib" includes library file (*.pm) used by cgis.
"test" includes testcases. Instructions are included in "*.pl" files.
INSTALLNATION & CONFIGURATION
* additional perl packages (Fedora, Suse, CentOS rpms available)
DBI
DBD::mysql
Data::UUID
* A sample apache configuration file is included in "conf"
http-vhost.conf
mod_perl-startup.pl
* lib/OpenSim/Config.pm need to be configured to fit your environment.
Please follow the comment in that file.
CONTACT
lulurun@gmail.com

43
share/perl/asset.cgi Normal file
View File

@ -0,0 +1,43 @@
#!/usr/bin/perl -w
use strict;
use Carp;
use MyCGI;
use OpenSim::Config;
use OpenSim::Utility;
use OpenSim::AssetServer;
# !!
# TODO: ERROR code
#
my $param = &MyCGI::getParam();
my $response = "<ERROR />";
if ($ENV{REQUEST_METHOD} eq "POST") {
my $request = $param->{'POSTDATA'};
#&OpenSim::Utility::Log("asset", "request", $ENV{REQUEST_URI}, $request);
$response = &OpenSim::AssetServer::saveAsset($request);
} else { # get
eval {
my $rest_param = &getRestParam();
#&OpenSim::Utility::Log("asset", "request", $ENV{REQUEST_URI});
my $rest_param_count = @$rest_param;
if ($rest_param_count < 2) {
Carp::croak($OpenSim::Config::SYS_MSG{FATAL});
}
$response = &OpenSim::AssetServer::getAsset($rest_param->[$#$rest_param], $param);
};
if ($@) {
$response = "<ERROR>$@</ERROR>"; # TODO: better return message needed.
}
}
#&OpenSim::Utility::Log("asset", "response", $response);
&MyCGI::outputXml("utf-8", $response);
sub getRestParam {
my $uri = $ENV{REQUEST_URI} || Carp::croak($OpenSim::Config::SYS_MSG{FATAL});
my ($request_uri, undef) = split(/\?/, $uri);
$request_uri =~ s/\/$//;
my @param = split(/\//, $request_uri);
return \@param;
}

View File

@ -0,0 +1,25 @@
LoadModule perl_module modules/mod_perl.so
PerlRequire "conf/mod_perl-startup.pl"
NameVirtualHost *:80
<VirtualHost *:80>
ServerName opensim.lulu
ServerAdmin webmaster@opensim.lulu
DocumentRoot /home/lulu/temp/opensim
ErrorLog logs/opensim-error_log
CustomLog logs/opensim-access_log common
<Directory "/home/lulu/temp/opensim">
Options MultiViews All
AllowOverride None
Order allow,deny
Allow from all
</Directory>
<Files ~ "\.cgi$">
SetHandler perl-script
PerlResponseHandler ModPerl::Registry
PerlOptions +ParseHeaders
</Files>
</VirtualHost>

View File

@ -0,0 +1,34 @@
# Taken from http://perl.apache.org/docs/2.0/user/handlers/server.html#Startup_File
if ( ! $ENV{MOD_PERL}) { die "GATEWAY_INTERFACE not Perl!"; }
# !!! set this to your opensim's lib
use lib qw(/home/lulu/temp/opensim/lib);
# enable if the mod_perl 1.0 compatibility is needed
# use Apache2::compat ();
# preload all mp2 modules
# use ModPerl::MethodLookup;
# ModPerl::MethodLookup::preload_all_modules();
use ModPerl::Util (); #for CORE::GLOBAL::exit
use Apache2::RequestRec ();
use Apache2::RequestIO ();
use Apache2::RequestUtil ();
use Apache2::ServerRec ();
use Apache2::ServerUtil ();
use Apache2::Connection ();
use Apache2::Log ();
use APR::Table ();
use ModPerl::Registry ();
use Apache2::Const -compile => ':common';
use APR::Const -compile => ':common';
1;

27
share/perl/grid.cgi Normal file
View File

@ -0,0 +1,27 @@
#!/usr/bin/perl -w
use strict;
use Carp;
use XML::RPC;
use MyCGI;
use OpenSim::Utility;
use OpenSim::GridServer;
my $param = &MyCGI::getParam();
my $request = $param->{'POSTDATA'};
#&OpenSim::Utility::Log("grid", "request", $request);
my $xmlrpc = new XML::RPC();
my $response = $xmlrpc->receive($request, \&XMLRPCHandler);
#&OpenSim::Utility::Log("grid", "response", $response);
&MyCGI::outputXml("utf-8", $response);
sub XMLRPCHandler {
my ($methodname, @param) = @_;
my $handler_list = &OpenSim::GridServer::getHandlerList();
if (!$handler_list->{$methodname}) {
Carp::croak("?");
} else {
my $handler = $handler_list->{$methodname};
$handler->(@param);
}
}

39
share/perl/inventory.cgi Normal file
View File

@ -0,0 +1,39 @@
#!/usr/bin/perl -w
use strict;
use MyCGI;
use OpenSim::Config;
use OpenSim::InventoryServer;
use Carp;
my $request_uri = $ENV{REQUEST_URI} || Carp::croak($OpenSim::Config::SYS_MSG{FATAL});
my $request_method = "";
if ($request_uri =~ /([^\/]+)\/$/) {
$request_method = $1;
} else {
&MyCGI::outputXml("utf-8", $OpenSim::Config::SYS_MSG{FATAL});
}
my $param = &MyCGI::getParam();
my $post_data = $param->{'POSTDATA'};
&OpenSim::Utility::Log("inv", "request", $request_uri, $post_data);
my $response = "";
eval {
$response = &handleRequest($request_method, $post_data);
};
if ($@) {
$response = "<ERROR>$@</ERROR>";
}
&OpenSim::Utility::Log("inv", "response", $response);
&MyCGI::outputXml("utf-8", $response);
sub handleRequest {
my ($methodname, $post_data) = @_;
my $handler_list = &OpenSim::InventoryServer::getHandlerList();
if (!$handler_list->{$methodname}) {
Carp::croak("unknown method name");
} else {
my $handler = $handler_list->{$methodname};
return $handler->($post_data);
}
}

119
share/perl/lib/DBHandler.pm Normal file
View File

@ -0,0 +1,119 @@
use strict;
use DBI;
use Carp;
package DBHandler;
#our $dbh = undef;
use vars qw ($DB_CONNECTION);
sub getConnection {
my ($dsn, $user, $pass) = @_;
#return $DB_CONNECTION if ($DB_CONNECTION);
$DB_CONNECTION = DBI->connect($dsn, $user, $pass);
$DB_CONNECTION->{AutoCommit} = 1;
$DB_CONNECTION->{RaiseError} = 1;
return $DB_CONNECTION;
}
# #############
# Simple statement
package Statement;
sub new {
my ( $this, $dbh, $sql, $is_trans ) = @_;
# @@@ sql should be tested OK, so here just die
my $sth = $dbh->prepare($sql) || Carp::croak( $dbh->errstr );
my %fields = (
dbh => $dbh,
sql => $sql,
sth => $sth,
is_trans => $is_trans,
);
return bless \%fields, $this;
}
sub exec {
my ( $this, @param ) = @_;
my $dbh = $this->{dbh};
my $sth = $this->{sth};
my $sql = $this->{sql};
if ( !$sth->execute(@param) ) {
if ( $this->{is_trans} ) {
$dbh->rollback();
}
Carp::croak( $dbh->errstr );
}
my @ret = ();
if ( $sql =~ /^select/i ) {
# @@@ get result object
while ( my $res = $sth->fetchrow_hashref() ) {
push @ret, $res;
}
}
# @@@ $sth->finish();
return \@ret;
}
sub last_id {
my $this = shift;
my $dbh = $this->{dbh};
return $dbh->last_insert_id(undef, undef, undef, undef);
}
sub DESTROY {
my $this = shift;
my $sth = $this->{sth};
$sth->finish();
}
# #############
# Transaction
package Transaction;
my $IS_TRANS = 1;
sub new {
my ( $this, $dbh ) = @_;
# @@@ fatal error, just die
$dbh->begin_work() || Carp::croak( $dbh->errstr );
my %fields = (
dbh => $dbh,
Active => 1,
);
return bless \%fields, $this;
}
sub createStatement {
my ( $this, $sql) = @_;
# @@@ fatal error, just die
Carp::croak("transaction not begin") if ( !$this->{Active} );
my $dbh = $this->{dbh};
return new Statement($dbh, $sql, $IS_TRANS);
}
sub commit {
my $this = shift;
my $dbh = $this->{dbh};
if ( $this->{Active} && !$dbh->{AutoCommit} ) {
$dbh->commit || Carp::croak( $dbh->errstr );
}
$this->{Active} = 0;
}
sub rollback {
my $this = shift;
my $dbh = $this->{dbh};
if ( $this->{Active} && !$dbh->{AutoCommit} ) {
$dbh->rollback || Carp::croak( $dbh->errstr );
}
$this->{Active} = 0;
}
sub DESTROY {
my $this = shift;
$this->rollback;
}
1;

91
share/perl/lib/MyCGI.pm Normal file
View File

@ -0,0 +1,91 @@
package MyCGI;
use strict;
use CGI;
sub getParam {
my $cgi;
if ($ARGV[0]) {
$cgi = new CGI($ARGV[0]);
} else {
$cgi = new CGI;
}
my @param_names = $cgi->param();
my %param = ();
foreach (@param_names) {
$param{$_} = $cgi->param($_);
}
return \%param;
}
sub getCookie {
my $name = shift;
my $cookie_value = &CGI::cookie($name);
return &_parse($cookie_value);
}
sub outputHtml {
my ($charset, $html) = @_;
print &CGI::header(-charset => $charset);
print $html;
}
sub outputXml {
my ($charset, $xml) = @_;
print &CGI::header( -type => 'text/xml', -charset => $charset );
print $xml;
}
sub makeCookieValue {
my $param = shift;
my @data = ();
foreach(keys %$param) {
push(@data, $_ . "=" . $param->{$_});
}
return join("&", @data);
}
sub setCookie {
my $param = shift;
my $cookie = &CGI::cookie(
-name => $param->{name} || return,
-value => $param->{value},
-domain => $param->{domain},
-path => $param->{path},
-expires => $param->{expires},
);
return &CGI::header(-cookie => $cookie);
}
sub redirect {
my $dest = shift;
&CGI::redirect($dest);
}
sub urlEncode {
my $str = shift;
$str =~ s/([^\w ])/'%'.unpack('H2', $1)/eg;
$str =~ tr/ /+/;
return $str;
}
sub urlDecode {
my $str = shift;
$str =~ tr/+/ /;
$str =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;
return $str;
}
sub _parse {
my $value = shift;
my @pair = split(/&/, $value);
my %data = ();
foreach(@pair) {
my ($name, $value) = split(/=/, $_);
$data{$name} = $value;
}
return \%data;
}
1;

View File

@ -0,0 +1,87 @@
package OpenSim::AssetServer;
use strict;
use MIME::Base64;
use XML::Simple;
use OpenSim::Utility;
use OpenSim::AssetServer::AssetManager;
# !!
# TODO: delete asset
#
sub getAsset {
my ($asset_id, $param) = @_;
# get asset
my $asset_id_string = &OpenSim::Utility::UUID2HEX($asset_id);
my $asset = &OpenSim::AssetServer::AssetManager::getAssetByUUID($asset_id_string);
$asset->{assetUUID} = $asset_id;
# make response
return &_asset_to_xml($asset);
}
sub saveAsset {
my $xml = shift;
my $asset = &_xml_to_asset($xml);
&OpenSim::AssetServer::AssetManager::saveAsset($asset);
return ""; # TODO: temporary solution of "success!"
}
# ##################
# private functions
sub _asset_to_xml {
my $asset = shift;
my $asset_data = &MIME::Base64::encode_base64($asset->{data});
return << "ASSET_XML";
<AssetBase>
<Data>
$asset_data
</Data>
<FullID>
<UUID>$asset->{assetUUID}</UUID>
</FullID>
<Type>$asset->{assetType}</Type>
<InvType>$asset->{invType}</InvType>
<Name>$asset->{name}</Name>
<Description>$asset->{description}</Description>
<Local>$asset->{local}</Local>
<Temporary>$asset->{temporary}</Temporary>
</AssetBase>
ASSET_XML
}
sub _xml_to_asset {
my $xml = shift;
my $xs = new XML::Simple();
my $obj = $xs->XMLin($xml);
print STDERR $obj->{FullID}->{UUID} . "\n";
my %asset = (
"id" => &OpenSim::Utility::UUID2BIN($obj->{FullID}->{UUID}),
"name" => $obj->{Name},
"description" => $obj->{Description},
"assetType" => $obj->{Type},
"invType" => $obj->{InvType},
"local" => $obj->{Local},
"temporary" => $obj->{Temporary},
"data" => &MIME::Base64::decode_base64($obj->{Data}),
);
return \%asset;
}
1;
__END__
{
Data => "PFNjZW5lT2JqZWN0R3JvdXA+PFJvb3RQYXJ0PjxTY2VuZU9iamVjdFBhcnQgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeG1sbnM6eHNkPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSI+PExhc3RPd25lcklEPjxVVUlEPmI5Y2I1OGU4LWYzYzktNGFmNS1iZTQ3LTAyOTc2MmJhYTY4ZjwvVVVJRD48L0xhc3RPd25lcklEPjxPd25lcklEPjxVVUlEPmI5Y2I1OGU4LWYzYzktNGFmNS1iZTQ3LTAyOTc2MmJhYTY4ZjwvVVVJRD48L093bmVySUQ+PEdyb3VwSUQ+PFVVSUQ+MDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwPC9VVUlEPjwvR3JvdXBJRD48T3duZXJzaGlwQ29zdD4wPC9Pd25lcnNoaXBDb3N0PjxPYmplY3RTYWxlVHlwZT4wPC9PYmplY3RTYWxlVHlwZT48U2FsZVByaWNlPjA8L1NhbGVQcmljZT48Q2F0ZWdvcnk+MDwvQ2F0ZWdvcnk+PENyZWF0aW9uRGF0ZT4xMTk4NjQ5MjA5PC9DcmVhdGlvbkRhdGU+PFBhcmVudElEPjA8L1BhcmVudElEPjxPd25lck1hc2s+NTI2MDUzNjkyPC9Pd25lck1hc2s+PE5leHRPd25lck1hc2s+MjU3NDg3MTMyPC9OZXh0T3duZXJNYXNrPjxHcm91cE1hc2s+MDwvR3JvdXBNYXNrPjxFdmVyeW9uZU1hc2s+MDwvRXZlcnlvbmVNYXNrPjxCYXNlTWFzaz4yMTQ3NDgzNjQ3PC9CYXNlTWFzaz48Q3JlYXRvcklEPjxVVUlEPmI5Y2I1OGU4LWYzYzktNGFmNS1iZTQ3LTAyOTc2MmJhYTY4ZjwvVVVJRD48L0NyZWF0b3JJRD48VVVJRD48VVVJRD5hMGY3NmQzYi02MTlkLTRjNjktODVmOS0zNzhjMDExZDg2NzI8L1VVSUQ+PC9VVUlEPjxMb2NhbElEPjcwMjAwMTwvTG9jYWxJRD48TmFtZT5QcmltaXRpdmU8L05hbWU+PE9iamVjdEZsYWdzPjY1NjY2PC9PYmplY3RGbGFncz48TWF0ZXJpYWw+MDwvTWF0ZXJpYWw+PFJlZ2lvbkhhbmRsZT4xMDk5NTExNjI4MDMyMDAwPC9SZWdpb25IYW5kbGU+PEdyb3VwUG9zaXRpb24+PFg+MTMwLjA5OTQ8L1g+PFk+MTI4LjcxNTQ8L1k+PFo+MjEuMzM1NTI8L1o+PC9Hcm91cFBvc2l0aW9uPjxPZmZzZXRQb3NpdGlvbj48WD4wPC9YPjxZPjA8L1k+PFo+MDwvWj48L09mZnNldFBvc2l0aW9uPjxSb3RhdGlvbk9mZnNldD48WD4wPC9YPjxZPjA8L1k+PFo+MDwvWj48Vz4xPC9XPjwvUm90YXRpb25PZmZzZXQ+PFZlbG9jaXR5PjxYPjA8L1g+PFk+MDwvWT48Wj4wPC9aPjwvVmVsb2NpdHk+PFJvdGF0aW9uYWxWZWxvY2l0eT48WD4wPC9YPjxZPjA8L1k+PFo+MDwvWj48L1JvdGF0aW9uYWxWZWxvY2l0eT48QW5ndWxhclZlbG9jaXR5PjxYPjA8L1g+PFk+MDwvWT48Wj4wPC9aPjwvQW5ndWxhclZlbG9jaXR5PjxBY2NlbGVyYXRpb24+PFg+MDwvWD48WT4wPC9ZPjxaPjA8L1o+PC9BY2NlbGVyYXRpb24+PERlc2NyaXB0aW9uIC8+PENvbG9yIC8+PFRleHQgLz48U2l0TmFtZSAvPjxUb3VjaE5hbWUgLz48TGlua051bT4wPC9MaW5rTnVtPjxDbGlja0FjdGlvbj4wPC9DbGlja0FjdGlvbj48U2hhcGU+PFN0YXRlPjA8L1N0YXRlPjxQQ29kZT45PC9QQ29kZT48UGF0aEJlZ2luPjA8L1BhdGhCZWdpbj48UGF0aEVuZD4wPC9QYXRoRW5kPjxQYXRoU2NhbGVYPjIwMDwvUGF0aFNjYWxlWD48UGF0aFNjYWxlWT4yMDA8L1BhdGhTY2FsZVk+PFBhdGhTaGVhclg+MDwvUGF0aFNoZWFyWD48UGF0aFNoZWFyWT4wPC9QYXRoU2hlYXJZPjxQYXRoU2tldz4wPC9QYXRoU2tldz48UHJvZmlsZUJlZ2luPjA8L1Byb2ZpbGVCZWdpbj48UHJvZmlsZUVuZD4wPC9Qcm9maWxlRW5kPjxTY2FsZT48WD4wLjU8L1g+PFk+MC41PC9ZPjxaPjAuNTwvWj48L1NjYWxlPjxQYXRoQ3VydmU+MTY8L1BhdGhDdXJ2ZT48UHJvZmlsZUN1cnZlPjA8L1Byb2ZpbGVDdXJ2ZT48UHJvZmlsZUhvbGxvdz4wPC9Qcm9maWxlSG9sbG93PjxQYXRoUmFkaXVzT2Zmc2V0PjA8L1BhdGhSYWRpdXNPZmZzZXQ+PFBhdGhSZXZvbHV0aW9ucz4wPC9QYXRoUmV2b2x1dGlvbnM+PFBhdGhUYXBlclg+MDwvUGF0aFRhcGVyWD48UGF0aFRhcGVyWT4wPC9QYXRoVGFwZXJZPjxQYXRoVHdpc3Q+MDwvUGF0aFR3aXN0PjxQYXRoVHdpc3RCZWdpbj4wPC9QYXRoVHdpc3RCZWdpbj48VGV4dHVyZUVudHJ5PkFBQUFBQUFBQUFDWm1RQUFBQUFBQlFBQUFBQUFBQUFBZ0Q4QUFBQ0FQd0FBQUFBQUFBQUFBQUFBQUFBPTwvVGV4dHVyZUVudHJ5PjxFeHRyYVBhcmFtcz5BQT09PC9FeHRyYVBhcmFtcz48UHJvZmlsZVNoYXBlPkNpcmNsZTwvUHJvZmlsZVNoYXBlPjwvU2hhcGU+PFNjYWxlPjxYPjAuNTwvWD48WT4wLjU8L1k+PFo+MC41PC9aPjwvU2NhbGU+PFVwZGF0ZUZsYWc+MDwvVXBkYXRlRmxhZz48L1NjZW5lT2JqZWN0UGFydD48L1Jvb3RQYXJ0PjxPdGhlclBhcnRzIC8+PC9TY2VuZU9iamVjdEdyb3VwPgA=",
Description => {},
FullID => { UUID => "feb7e249-e462-499f-a881-553b9829539a" },
InvType => 6,
Local => "false",
Name => "Primitive",
Temporary => "false",
Type => 6,
"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
}

View File

@ -0,0 +1,34 @@
package OpenSim::AssetServer::AssetManager;
use strict;
use Carp;
use OpenSim::Utility;
use OpenSim::AssetServer::Config;
sub getAssetByUUID {
my $uuid = shift;
my $result = &OpenSim::Utility::getSimpleResult($OpenSim::AssetServer::Config::SYS_SQL{select_asset_by_uuid}, $uuid);
my $count = @$result;
if ($count > 0) {
return $result->[0];
}
Carp::croak("can not find asset($uuid)");
}
sub saveAsset {
my $asset = shift;
my $result = &OpenSim::Utility::getSimpleResult(
$OpenSim::AssetServer::Config::SYS_SQL{insert_asset},
$asset->{id},
$asset->{name},
$asset->{description},
$asset->{assetType},
$asset->{invType},
$asset->{"local"},
$asset->{temporary},
$asset->{data}
);
}
1;

View File

@ -0,0 +1,24 @@
package OpenSim::AssetServer::Config;
use strict;
our %SYS_SQL = (
select_asset_by_uuid =>
"SELECT * FROM assets WHERE id=X?",
insert_asset =>
"INSERT INTO assets VALUES (?,?,?,?,?,?,?,?)"
);
our @ASSETS_COLUMNS = (
"id",
"name",
"description",
"assetType",
"invType",
"local",
"temporary",
"data",
);
1;

View File

@ -0,0 +1,41 @@
package OpenSim::Config;
# REGION keys
our $SIM_RECV_KEY = "";
our $SIM_SEND_KEY = "";
# ASSET server url
#our $ASSET_SERVER_URL = "http://127.0.0.1:8003/";
our $ASSET_SERVER_URL = "http://opensim.wolfdrawer.net:80/asset.cgi";
our $ASSET_RECV_KEY = "";
our $ASSET_SEND_KEY = "";
# USER server url
#our $USER_SERVER_URL = "http://127.0.0.1:8001/";
our $USER_SERVER_URL = "http://opensim.wolfdrawer.net:80/user.cgi";
our $USER_RECV_KEY = "";
our $USER_SEND_KEY = "";
# GRID server url
#our $GRID_SERVER_URL = "http://127.0.0.1:8001/";
our $GRID_SERVER_URL = "http://opensim.wolfdrawer.net:80/grid.cgi";
our $GRID_RECV_KEY = "";
our $GRID_SEND_KEY = "";
# INVENTORY server url
#our $INVENTORY_SERVER_URL = "http://127.0.0.1:8004";
our $INVENTORY_SERVER_URL = "http://opensim.wolfdrawer.net:80/inventory.cgi";
# DB
our $DSN = "dbi:mysql:database=opensim;host=192.168.0.20";
our $DBUSER = "lulu";
our $DBPASS = "1234";
# DEBUG LOG
our $DEBUG_LOGDIR = "/home/lulu/temp/opensim";
# MSG
our %SYS_MSG = (
FATAL => "You must have been eaten by a wolf.",
FAIL => "Late! There is a wolf behind you",
LOGIN_WELCOME => "Do you fear the wolf ?",
);
1;

View File

@ -0,0 +1,208 @@
package OpenSim::GridServer;
use strict;
use OpenSim::Utility;
use OpenSim::GridServer::Config;
use OpenSim::GridServer::GridManager;
sub getHandlerList {
my %list = (
"simulator_login" => \&_simulator_login,
"simulator_data_request" => \&_simulator_data_request,
"map_block" => \&_map_block,
"map_block2" => \&_map_block2, # this is better for the Region Monitor
);
return \%list;
}
# #################
# XMLRPC Handlers
sub _simulator_login {
my $params = shift;
my $region_data = undef;
my %response = ();
if ($params->{"UUID"}) {
$region_data = &OpenSim::GridServer::GridManager::getRegionByUUID($params->{"UUID"});
} elsif ($params->{"region_handle"}) {
$region_data = &OpenSim::GridServer::GridManager::getRegionByHandle($params->{"region_handle"});
} else {
$response{"error"} = "No UUID or region_handle passed to grid server - unable to connect you";
return \%response;
}
if (!$region_data) {
my %new_region_data = (
uuid => undef,
regionHandle => OpenSim::Utility::UIntsToLong($params->{region_locx}*256, $params->{region_locx}*256),
regionName => $params->{sim_name},
regionRecvKey => $OpenSim::Config::SIM_RECV_KEY,
regionSendKey => $OpenSim::Config::SIM_SEND_KEY,
regionSecret => $OpenSim::Config::SIM_RECV_KEY,
regionDataURI => "",
serverIP => $params->{sim_ip},
serverPort => $params->{sim_port},
serverURI => "http://" + $params->{sim_ip} + ":" + $params->{sim_port} + "/",
LocX => $params->{region_locx},
LocY => $params->{region_locy},
LocZ => 0,
regionAssetURI => $OpenSim::Config::ASSET_SERVER_URL,
regionAssetRecvKey => $OpenSim::Config::ASSET_RECV_KEY,
regionAssetSendKey => $OpenSim::Config::ASSET_SEND_KEY,
regionUserURI => $OpenSim::Config::USER_SERVER_URL,
regionUserRecvKey => $OpenSim::Config::USER_RECV_KEY,
regionUserSendKey => $OpenSim::Config::USER_SEND_KEY,
regionMapTextureID => $params->{"map-image-id"},
serverHttpPort => $params->{http_port},
serverRemotingPort => $params->{remoting_port},
);
eval {
&OpenSim::GridServer::GridManager::addRegion(\%new_region_data);
};
if ($@) {
$response{"error"} = "unable to add region";
return \%response;
}
$region_data = \%new_region_data;
}
my @region_neighbours_data = ();
my $region_list = &OpenSim::GridServer::GridManager::getRegionList($region_data->{locX}-1, $region_data->{locY}-1, $region_data->{locX}+1, $region_data->{locY}+1);
foreach my $region (@$region_list) {
next if ($region->{regionHandle} eq $region_data->{regionHandle});
my %neighbour_block = (
"sim_ip" => $region->{serverIP},
"sim_port" => $region->{serverPort},
"region_locx" => $region->{locX},
"region_locy" => $region->{locY},
"UUID" => $region->{uuid},
"regionHandle" => $region->{regionHandle},
);
push @region_neighbours_data, \%neighbour_block;
}
%response = (
UUID => $region_data->{uuid},
region_locx => $region_data->{locX},
region_locy => $region_data->{locY},
regionname => $region_data->{regionName},
estate_id => "1", # TODO ???
neighbours => \@region_neighbours_data,
sim_ip => $region_data->{serverIP},
sim_port => $region_data->{serverPort},
asset_url => $region_data->{regionAssetURI},
asset_recvkey => $region_data->{regionAssetRecvKey},
asset_sendkey => $region_data->{regionAssetSendKey},
user_url => $region_data->{regionUserURI},
user_recvkey => $region_data->{regionUserRecvKey},
user_sendkey => $region_data->{regionUserSendKey},
authkey => $region_data->{regionSecret},
data_uri => $region_data->{regionDataURI},
"allow_forceful_banlines" => "TRUE",
);
return \%response;
}
sub _simulator_data_request {
my $params = shift;
my $region_data = undef;
my %response = ();
if ($params->{"region_UUID"}) {
$region_data = &OpenSim::GridServer::GridManager::getRegionByUUID($params->{"region_UUID"});
} elsif ($params->{"region_handle"}) {
$region_data = &OpenSim::GridServer::GridManager::getRegionByHandle($params->{"region_handle"});
}
if (!$region_data) {
$response{"error"} = "Sim does not exist";
return \%response;
}
$response{"sim_ip"} = $region_data->{serverIP};
$response{"sim_port"} = $region_data->{serverPort};
$response{"http_port"} = $region_data->{serverHttpPort};
$response{"remoting_port"} = $region_data->{serverRemotingPort};
$response{"region_locx"} = $region_data->{locX};
$response{"region_locy"} = $region_data->{locY};
$response{"region_UUID"} = $region_data->{uuid};
$response{"region_name"} = $region_data->{regionName};
$response{"regionHandle"} = $region_data->{regionHandle};
return \%response;
}
sub _map_block {
my $params = shift;
my $xmin = $params->{xmin} || 980;
my $ymin = $params->{ymin} || 980;
my $xmax = $params->{xmax} || 1020;
my $ymax = $params->{ymax} || 1020;
my @sim_block_list = ();
my $region_list = &OpenSim::GridServer::GridManager::getRegionList($xmin, $ymin, $xmax, $ymax);
foreach my $region (@$region_list) {
my %sim_block = (
"x" => $region->{locX},
"y" => $region->{locY},
"name" => $region->{regionName},
"access" => 0, # TODO ? meaning unknown
"region-flags" => 0, # TODO ? unknown
"water-height" => 20, # TODO ? get from a XML
"agents" => 1, # TODO
"map-image-id" => $region->{regionMapTexture},
"regionhandle" => $region->{regionHandle},
"sim_ip" => $region->{serverIP},
"sim_port" => $region->{serverPort},
"sim_uri" => $region->{serverURI},
"uuid" => $region->{uuid},
"remoting_port" => $region->{serverRemotingPort},
);
push @sim_block_list, \%sim_block;
}
my %response = (
"sim-profiles" => \@sim_block_list,
);
return \%response;
}
sub _map_block2 {
my $params = shift;
my $xmin = $params->{xmin} || 980;
my $ymin = $params->{ymin} || 980;
my $xmax = $params->{xmax} || 1020;
my $ymax = $params->{ymax} || 1020;
my @sim_block_list = ();
my $region_list = &OpenSim::GridServer::GridManager::getRegionList2($xmin, $ymin, $xmax, $ymax);
foreach my $region (@$region_list) {
my %sim_block = (
"x" => $region->{locX},
"y" => $region->{locY},
"name" => $region->{regionName},
"access" => 0, # TODO ? meaning unknown
"region-flags" => 0, # TODO ? unknown
"water-height" => 20, # TODO ? get from a XML
"agents" => 1, # TODO
"map-image-id" => $region->{regionMapTexture},
"regionhandle" => $region->{regionHandle},
"sim_ip" => $region->{serverIP},
"sim_port" => $region->{serverPort},
"sim_uri" => $region->{serverURI},
"uuid" => $region->{uuid},
"remoting_port" => $region->{serverRemotingPort},
);
push @sim_block_list, \%sim_block;
}
my %response = (
"sim-profiles" => \@sim_block_list,
);
return \%response;
}
1;

View File

@ -0,0 +1,50 @@
package OpenSim::GridServer::Config;
use strict;
our %SYS_SQL = (
select_region_by_uuid =>
"SELECT * FROM regions WHERE uuid=?",
select_region_by_handle =>
"SELECT * FROM regions WHERE regionHandle=?",
select_region_list =>
"SELECT * FROM regions WHERE locX>=? AND locX<? AND locY>=? AND locY<?",
select_region_list2 =>
"SELECT * FROM regions WHERE locX>=? AND locX<? AND locY>=? AND locY<?",
insert_region =>
"INSERT INTO regions VALUES (?????????)",
delete_all_regions =>
"delete from regions",
);
our @REGIONS_COLUMNS = (
"uuid",
"regionHandle",
"regionName",
"regionRecvKey",
"regionSendKey",
"regionSecret",
"regionDataURI",
"serverIP",
"serverPort",
"serverURI",
"locX",
"locY",
"locZ",
"eastOverrideHandle",
"westOverrideHandle",
"southOverrideHandle",
"northOverrideHandle",
"regionAssetURI",
"regionAssetRecvKey",
"regionAssetSendKey",
"regionUserURI",
"regionUserRecvKey",
"regionUserSendKey",
"regionMapTexture",
"serverHttpPort",
"serverRemotingPort",
);
1;

View File

@ -0,0 +1,57 @@
package OpenSim::GridServer::GridManager;
use strict;
use Carp;
use OpenSim::Utility;
use OpenSim::GridServer::Config;
sub getRegionByUUID {
my $uuid = shift;
my $result = &OpenSim::Utility::getSimpleResult($OpenSim::GridServer::Config::SYS_SQL{select_region_by_uuid}, $uuid);
my $count = @$result;
if ($count > 0) {
return $result->[0];
}
Carp::croak("can not find region");
}
sub getRegionByHandle {
my $handle = shift;
my $result = &OpenSim::Utility::getSimpleResult($OpenSim::GridServer::Config::SYS_SQL{select_region_by_handle}, $handle);
my $count = @$result;
if ($count > 0) {
return $result->[0];
}
Carp::croak("can not find region # $handle");
}
sub getRegionList {
my ($xmin, $ymin, $xmax, $ymax) = @_;
my $result = &OpenSim::Utility::getSimpleResult($OpenSim::GridServer::Config::SYS_SQL{select_region_list}, $xmin, $xmax, $ymin, $ymax);
my $count = @$result;
if ($count > 0) {
return $result;
}
Carp::croak("can not find region");
}
sub getRegionList2 {
my ($xmin, $ymin, $xmax, $ymax) = @_;
my $result = &OpenSim::Utility::getSimpleResult($OpenSim::GridServer::Config::SYS_SQL{select_region_list2}, $xmin, $xmax, $ymin, $ymax);
my $count = @$result;
if ($count > 0) {
return $result;
}
Carp::croak("can not find region");
}
sub deleteRegions {
my $result = &OpenSim::Utility::getSimpleResult($OpenSim::GridServer::Config::SYS_SQL{delete_all_regions});
my $count = @$result;
if ($count > 0) {
return $result;
}
Carp::croak("failed to delete regions");
}
1;

View File

@ -0,0 +1,249 @@
package OpenSim::InventoryServer;
use strict;
use XML::Serializer;
use OpenSim::Utility;
use OpenSim::Config;
use OpenSim::InventoryServer::Config;
use OpenSim::InventoryServer::InventoryManager;
my $METHOD_LIST = undef;
sub getHandlerList {
if (!$METHOD_LIST) {
my %list = (
"GetInventory" => \&_get_inventory,
"CreateInventory" => \&_create_inventory,
"NewFolder" => \&_new_folder,
"MoveFolder" => \&_move_folder,
"NewItem" => \&_new_item,
"DeleteItem" => \&_delete_item,
"RootFolders" => \&_root_folders,
);
$METHOD_LIST = \%list;
}
return $METHOD_LIST;
}
# #################
# Handlers
sub _get_inventory {
my $post_data = shift;
my $uuid = &_get_uuid($post_data);
my $inventry_folders = &OpenSim::InventoryServer::InventoryManager::getUserInventoryFolders($uuid);
my @response_folders = ();
foreach (@$inventry_folders) {
my $folder = &_convert_to_response_folder($_);
push @response_folders, $folder;
}
my $inventry_items = &OpenSim::InventoryServer::InventoryManager::getUserInventoryItems($uuid);
my @response_items = ();
foreach (@$inventry_items) {
my $item = &_convert_to_response_item($_);
push @response_items, $item;
}
my $response_obj = {
Folders => { InventoryFolderBase => \@response_folders },
AllItems => { InventoryItemBase => \@response_items },
UserID => { UUID => $uuid },
};
my $serializer = new XML::Serializer( $response_obj, "InventoryCollection");
return $serializer->to_formatted(XML::Serializer::WITH_HEADER); # TODO:
}
sub _create_inventory {
my $post_data = shift;
my $uuid = &_get_uuid($post_data);
my $InventoryFolders = &_create_default_inventory($uuid);
foreach (@$InventoryFolders) {
&OpenSim::InventoryServer::InventoryManager::saveInventoryFolder($_);
}
my $serializer = new XML::Serializer("true", "boolean");
return $serializer->to_formatted(XML::Serializer::WITH_HEADER); # TODO:
}
sub _new_folder {
my $post_data = shift;
my $request_obj = &OpenSim::Utility::XML2Obj($post_data);
my $folder = &_convert_to_db_folder($request_obj);
&OpenSim::InventoryServer::InventoryManager::saveInventoryFolder($folder);
my $serializer = new XML::Serializer("true", "boolean");
return $serializer->to_formatted(XML::Serializer::WITH_HEADER); # TODO:
}
sub _move_folder {
my $post_data = shift;
my $request_info = &OpenSim::Utility::XML2Obj($post_data);
&OpenSim::InventoryServer::InventoryManager::moveInventoryFolder($request_info);
my $serializer = new XML::Serializer("true", "boolean");
return $serializer->to_formatted(XML::Serializer::WITH_HEADER); # TODO:
}
sub _new_item {
my $post_data = shift;
my $request_obj = &OpenSim::Utility::XML2Obj($post_data);
my $item = &_convert_to_db_item($request_obj);
&OpenSim::InventoryServer::InventoryManager::saveInventoryItem($item);
my $serializer = new XML::Serializer("true", "boolean");
return $serializer->to_formatted(XML::Serializer::WITH_HEADER); # TODO:
}
sub _delete_item {
my $post_data = shift;
my $request_obj = &OpenSim::Utility::XML2Obj($post_data);
my $item_id = $request_obj->{inventoryID}->{UUID};
&OpenSim::InventoryServer::InventoryManager::deleteInventoryItem($item_id);
my $serializer = new XML::Serializer("true", "boolean");
return $serializer->to_formatted(XML::Serializer::WITH_HEADER); # TODO:
}
sub _root_folders {
my $post_data = shift;
my $uuid = &_get_uuid($post_data);
my $response = undef;
my $inventory_root_folder = &OpenSim::InventoryServer::InventoryManager::getRootFolder($uuid);
if ($inventory_root_folder) {
my $root_folder_id = $inventory_root_folder->{folderID};
my $root_folder = &_convert_to_response_folder($inventory_root_folder);
my $root_folders = &OpenSim::InventoryServer::InventoryManager::getChildrenFolders($root_folder_id);
my @folders = ($root_folder);
foreach(@$root_folders) {
my $folder = &_convert_to_response_folder($_);
push @folders, $folder;
}
$response = { InventoryFolderBase => \@folders };
} else {
$response = ""; # TODO: need better failed message
}
my $serializer = new XML::Serializer($response, "ArrayOfInventoryFolderBase");
return $serializer->to_formatted(XML::Serializer::WITH_HEADER); # TODO:
}
# #################
# subfunctions
sub _convert_to_db_item {
my $item = shift;
my $ret = {
inventoryID => $item->{inventoryID}->{UUID},
assetID => $item->{assetID}->{UUID},
assetType => $item->{assetType},
invType => $item->{invType},
parentFolderID => $item->{parentFolderID}->{UUID},
avatarID => $item->{avatarID}->{UUID},
creatorID => $item->{creatorsID}->{UUID}, # TODO: human error ???
inventoryName => $item->{inventoryName},
inventoryDescription => $item->{inventoryDescription} || "",
inventoryNextPermissions => $item->{inventoryNextPermissions},
inventoryCurrentPermissions => $item->{inventoryCurrentPermissions},
inventoryBasePermissions => $item->{inventoryBasePermissions},
inventoryEveryOnePermissions => $item->{inventoryEveryOnePermissions},
};
return $ret;
}
sub _convert_to_response_item {
my $item = shift;
my $ret = {
inventoryID => { UUID => $item->{inventoryID} },
assetID => { UUID => $item->{assetID} },
assetType => $item->{assetType},
invType => $item->{invType},
parentFolderID => { UUID => $item->{parentFolderID} },
avatarID => { UUID => $item->{avatarID} },
creatorsID => { UUID => $item->{creatorID} }, # TODO: human error ???
inventoryName => $item->{inventoryName},
inventoryDescription => $item->{inventoryDescription} || "",
inventoryNextPermissions => $item->{inventoryNextPermissions},
inventoryCurrentPermissions => $item->{inventoryCurrentPermissions},
inventoryBasePermissions => $item->{inventoryBasePermissions},
inventoryEveryOnePermissions => $item->{inventoryEveryOnePermissions},
};
return $ret;
}
sub _convert_to_db_folder {
my $folder = shift;
my $ret = {
folderName => $folder->{name},
agentID => $folder->{agentID}->{UUID},
parentFolderID => $folder->{parentID}->{UUID},
folderID => $folder->{folderID}->{UUID},
type => $folder->{type},
version => $folder->{version},
};
return $ret;
}
sub _convert_to_response_folder {
my $folder = shift;
my $ret = {
name => $folder->{folderName},
agentID => { UUID => $folder->{agentID} },
parentID => { UUID => $folder->{parentFolderID} },
folderID => { UUID => $folder->{folderID} },
type => $folder->{type},
version => $folder->{version},
};
return $ret;
}
sub _create_default_inventory {
my $uuid = shift;
my @InventoryFolders = ();
my $root_folder_id = &OpenSim::Utility::GenerateUUID();
push @InventoryFolders, {
"folderID" => $root_folder_id,
"agentID" => $uuid,
"parentFolderID" => &OpenSim::Utility::ZeroUUID(),
"folderName" => "My Inventory",
"type" => 8,
"version" => 1,
};
push @InventoryFolders, {
"folderID" => &OpenSim::Utility::GenerateUUID(),
"agentID" => $uuid,
"parentFolderID" => $root_folder_id,
"folderName" => "Textures",
"type" => 0,
"version" => 1,
};
push @InventoryFolders, {
"folderID" => &OpenSim::Utility::GenerateUUID(),
"agentID" => $uuid,
"parentFolderID" => $root_folder_id,
"folderName" => "Objects",
"type" => 6,
"version" => 1,
};
push @InventoryFolders, {
"folderID" => &OpenSim::Utility::GenerateUUID(),
"agentID" => $uuid,
"parentFolderID" => $root_folder_id,
"folderName" => "Clothes",
"type" => 5,
"version" => 1,
};
return \@InventoryFolders;
}
# #################
# Utilities
sub _get_uuid {
my $data = shift;
if ($data =~ /<guid\s*>([^<]+)<\/guid>/) {
return $1;
} else {
Carp::croak("can not find uuid: $data");
}
}
1;

View File

@ -0,0 +1,51 @@
package OpenSim::InventoryServer::Config;
use strict;
our %SYS_SQL = (
save_inventory_folder =>
"REPLACE INTO inventoryfolders VALUES (?,?,?,?,?,?)",
save_inventory_item =>
"REPLACE INTO inventoryitems VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
get_root_folder =>
"SELECT * FROM inventoryfolders WHERE parentFolderID=? AND agentId=?",
get_children_folders =>
"SELECT * FROM inventoryfolders WHERE parentFolderID=?",
get_user_inventory_folders =>
"SELECT * FROM inventoryfolders WHERE agentID=?",
get_user_inventory_items =>
"SELECT * FROM inventoryitems WHERE avatarID=?",
delete_inventory_item =>
"DELETE FROM inventoryitems WHERE inventoryID=?",
move_inventory_folder =>
"UPDATE inventoryfolders SET parentFolderID=? WHERE folderID=?",
);
our @INVENTORYFOLDERS_COLUMNS = (
"folderID",
"agentID",
"parentFolderID",
"folderName",
"type",
"version",
);
our @INVENTORYITEMS_COLUMNS = (
"inventoryID",
"assetID",
"type",
"parentFolderID",
"avatarID",
"inventoryName",
"inventoryDescription",
"inventoryNextPermissions",
"inventoryCurrentPermissions",
"assetType",
"invType",
"creatorID",
"inventoryBasePermissions",
"inventoryEveryOnePermissions",
);
1;

View File

@ -0,0 +1,86 @@
package OpenSim::InventoryServer::InventoryManager;
use strict;
use Carp;
use OpenSim::Utility;
use OpenSim::InventoryServer::Config;
sub saveInventoryFolder {
my $folder = shift;
my $result = &OpenSim::Utility::getSimpleResult($OpenSim::InventoryServer::Config::SYS_SQL{save_inventory_folder},
$folder->{"folderID"},
$folder->{"agentID"},
$folder->{"parentFolderID"},
$folder->{"folderName"},
$folder->{"type"},
$folder->{"version"});
}
sub saveInventoryItem {
my $item = shift;
my $result = &OpenSim::Utility::getSimpleResult($OpenSim::InventoryServer::Config::SYS_SQL{save_inventory_item},
$item->{"inventoryID"},
$item->{"assetID"},
$item->{"type"},
$item->{"parentFolderID"},
$item->{"avatarID"},
$item->{"inventoryName"},
$item->{"inventoryDescription"},
$item->{"inventoryNextPermissions"},
$item->{"inventoryCurrentPermissions"},
$item->{"assetType"},
$item->{"invType"},
$item->{"creatorID"},
$item->{"inventoryBasePermissions"},
$item->{"inventoryEveryOnePermissions"});
}
sub getRootFolder {
my $agent_id = shift;
my $result = &OpenSim::Utility::getSimpleResult($OpenSim::InventoryServer::Config::SYS_SQL{get_root_folder},
&OpenSim::Utility::ZeroUUID(),
$agent_id);
my $count = @$result;
if ($count > 0) {
return $result->[0];
} else {
return undef;
}
}
sub getChildrenFolders {
my $parent_id = shift;
my $result = &OpenSim::Utility::getSimpleResult($OpenSim::InventoryServer::Config::SYS_SQL{get_children_folders}, $parent_id);
return $result;
}
sub getUserInventoryFolders {
my $agent_id = shift;
my $result = &OpenSim::Utility::getSimpleResult($OpenSim::InventoryServer::Config::SYS_SQL{get_user_inventory_folders},
$agent_id);
return $result;
}
sub getUserInventoryItems {
my $agent_id = shift;
my $result = &OpenSim::Utility::getSimpleResult($OpenSim::InventoryServer::Config::SYS_SQL{get_user_inventory_items},
$agent_id);
return $result;
}
sub deleteInventoryItem {
my $item_id = shift;
&OpenSim::Utility::getSimpleResult($OpenSim::InventoryServer::Config::SYS_SQL{delete_inventory_item},
$item_id);
}
sub moveInventoryFolder {
my $info = shift;
&OpenSim::Utility::getSimpleResult($OpenSim::InventoryServer::Config::SYS_SQL{move_inventory_folder},
$info->{parentID}->{UUID}, # TODO: not good
$info->{folderID}->{UUID}, # TODO: not good UUID should be extracted in the higher level
);
}
1;

View File

@ -0,0 +1,239 @@
package OpenSim::UserServer;
use strict;
use OpenSim::Config;
use OpenSim::UserServer::Config;
use OpenSim::UserServer::UserManager;
sub getHandlerList {
my %list = (
"login_to_simulator" => \&_login_to_simulator,
"get_user_by_name" => \&_get_user_by_name,
"get_user_by_uuid" => \&_get_user_by_uuid,
"get_avatar_picker_avatar" => \&_get_avatar_picker_avatar,
);
return \%list;
}
# #################
# Handlers
sub _login_to_simulator {
my $params = shift;
# check params
if (!$params->{first} || !$params->{last} || !$params->{passwd}) {
return &_make_false_response("not enough params", $OpenSim::Config::SYS_MSG{FATAL});
}
# select user (check passwd)
my $user = &OpenSim::UserServer::UserManager::getUserByName($params->{first}, $params->{last});
if ($user->{passwordHash} ne $params->{passwd}) {
&_make_false_response("password not match", $OpenSim::Config::SYS_MSG{FAIL});
}
# contact with Grid server
my %grid_request_params = (
region_handle => $user->{homeRegion},
authkey => undef
);
my $grid_response = &OpenSim::Utility::XMLRPCCall($OpenSim::Config::GRID_SERVER_URL, "simulator_data_request", \%grid_request_params);
my $region_server_url = "http://" . $grid_response->{sim_ip} . ":" . $grid_response->{http_port};
# contact with Region server
my $session_id = &OpenSim::Utility::GenerateUUID;
my $secure_session_id = &OpenSim::Utility::GenerateUUID;
my $circuit_code = int(rand() * 1000000000); # just a random integer
my $caps_id = &OpenSim::Utility::GenerateUUID;
my %region_request_params = (
session_id => $session_id,
secure_session_id => $secure_session_id,
firstname => $user->{username},
lastname => $user->{lastname},
agent_id => $user->{UUID},
circuit_code => $circuit_code,
startpos_x => $user->{homeLocationX},
startpos_y => $user->{homeLocationY},
startpos_z => $user->{homeLocationZ},
regionhandle => $user->{homeRegion},
caps_path => $caps_id,
);
my $region_response = &OpenSim::Utility::XMLRPCCall($region_server_url, "expect_user", \%region_request_params);
# contact with Inventory server
my $inventory_data = &_create_inventory_data($user->{UUID});
# return to client
my %response = (
# login info
login => "true",
session_id => $session_id,
secure_session_id => $secure_session_id,
# agent
first_name => $user->{username},
last_name => $user->{lastname},
agent_id => $user->{UUID},
agent_access => "M", # TODO: do not know its meaning, hard coding in opensim
# grid
start_location => $params->{start},
sim_ip => $grid_response->{sim_ip},
sim_port => $grid_response->{sim_port},
#sim_port => 9001,
region_x => $grid_response->{region_locx} * 256,
region_y => $grid_response->{region_locy} * 256,
# other
inventory_host => undef, # inv13-mysql
circuit_code => $circuit_code,
message => $OpenSim::Config::SYS_MSG{LOGIN_WELCOME},
seconds_since_epoch => time,
seed_capability => $region_server_url . "/CAPS/" . $caps_id . "0000/", # https://sim2734.agni.lindenlab.com:12043/cap/61d6d8a0-2098-7eb4-2989-76265d80e9b6
look_at => &_make_r_string($user->{homeLookAtX}, $user->{homeLookAtY}, $user->{homeLookAtZ}),
home => &_make_home_string(
[$grid_response->{region_locx} * 256, $grid_response->{region_locy} * 256],
[$user->{homeLocationX}, $user->{homeLocationY}, $user->{homeLocationX}],
[$user->{homeLookAtX}, $user->{homeLookAtY}, $user->{homeLookAtZ}]),
"inventory-skeleton" => $inventory_data->{InventoryArray},
"inventory-root" => [ { folder_id => $inventory_data->{RootFolderID} } ],
"event_notifications" => \@OpenSim::UserServer::Config::event_notifications,
"event_categories" => \@OpenSim::UserServer::Config::event_categories,
"global-textures" => \@OpenSim::UserServer::Config::global_textures,
"inventory-lib-owner" => \@OpenSim::UserServer::Config::inventory_lib_owner,
"inventory-skel-lib" => \@OpenSim::UserServer::Config::inventory_skel_lib, # hard coding in OpenSim
"inventory-lib-root" => \@OpenSim::UserServer::Config::inventory_lib_root,
"classified_categories" => \@OpenSim::UserServer::Config::classified_categories,
"login-flags" => \@OpenSim::UserServer::Config::login_flags,
"initial-outfit" => \@OpenSim::UserServer::Config::initial_outfit,
"gestures" => \@OpenSim::UserServer::Config::gestures,
"ui-config" => \@OpenSim::UserServer::Config::ui_config,
);
return \%response;
}
sub _get_user_by_name {
my $param = shift;
if ($param->{avatar_name}) {
my ($first, $last) = split(/\s+/, $param->{avatar_name});
my $user = &OpenSim::UserServer::UserManager::getUserByName($first, $last);
if (!$user) {
return &_unknown_user_response;
}
return &_convert_to_response($user);
} else {
return &_unknown_user_response;
}
}
sub _get_user_by_uuid {
my $param = shift;
if ($param->{avatar_uuid}) {
my $user = &OpenSim::UserServer::UserManager::getUserByUUID($param->{avatar_uuid});
if (!$user) {
return &_unknown_user_response;
}
return &_convert_to_response($user);
} else {
return &_unknown_user_response;
}
}
sub _get_avatar_picker_avatar {
}
# #################
# sub functions
sub _create_inventory_data {
my $user_id = shift;
# TODO : too bad!! -> URI encoding
my $postdata =<< "POSTDATA";
POSTDATA=<?xml version="1.0" encoding="utf-8"?><guid>$user_id</guid>
POSTDATA
my $res = &OpenSim::Utility::HttpPostRequest($OpenSim::Config::INVENTORY_SERVER_URL . "/RootFolders/", $postdata);
my $res_obj = &OpenSim::Utility::XML2Obj($res);
if (!$res_obj->{InventoryFolderBase}) {
&OpenSim::Utility::HttpPostRequest($OpenSim::Config::INVENTORY_SERVER_URL . "/CreateInventory/", $postdata);
# Sleep(10000); # TODO: need not to do this
$res = &OpenSim::Utility::HttpPostRequest($OpenSim::Config::INVENTORY_SERVER_URL . "/RootFolders/", $postdata);
$res_obj = &OpenSim::Utility::XML2Obj($res);
}
my $folders = $res_obj->{InventoryFolderBase};
my $folders_count = @$folders;
if ($folders_count > 0) {
my @AgentInventoryFolders = ();
my $root_uuid = &OpenSim::Utility::ZeroUUID();
foreach my $folder (@$folders) {
if ($folder->{parentID}->{UUID} eq &OpenSim::Utility::ZeroUUID()) {
$root_uuid = $folder->{folderID}->{UUID};
}
my %folder_hash = (
name => $folder->{name},
parent_id => $folder->{parentID}->{UUID},
version => $folder->{version},
type_default => $folder->{type},
folder_id => $folder->{folderID}->{UUID},
);
push @AgentInventoryFolders, \%folder_hash;
}
return { InventoryArray => \@AgentInventoryFolders, RootFolderID => $root_uuid };
} else {
# TODO: impossible ???
}
return undef;
}
sub _convert_to_response {
my $user = shift;
my %response = (
firstname => $user->{username},
lastname => $user->{lastname},
uuid => $user->{UUID},
server_inventory => $user->{userInventoryURI},
server_asset => $user->{userAssetURI},
profile_about => $user->{profileAboutText},
profile_firstlife_about => $user->{profileFirstText},
profile_firstlife_image => $user->{profileFirstImage},
profile_can_do => $user->{profileCanDoMask} || "0",
profile_want_do => $user->{profileWantDoMask} || "0",
profile_image => $user->{profileImage},
profile_created => $user->{created},
profile_lastlogin => $user->{lastLogin} || "0",
home_coordinates_x => $user->{homeLocationX},
home_coordinates_y => $user->{homeLocationY},
home_coordinates_z => $user->{homeLocationZ},
home_region => $user->{homeRegion} || 0,
home_look_x => $user->{homeLookAtX},
home_look_y => $user->{homeLookAtY},
home_look_z => $user->{homeLookAtZ},
);
return \%response;
}
# #################
# Utility Functions
sub _make_false_response {
my ($reason, $message) = @_;
return { reason => $reason, login => "false", message => $message };
}
sub _unknown_user_response {
return {
error_type => "unknown_user",
error_desc => "The user requested is not in the database",
};
}
sub _make_home_string {
my ($region_handle, $position, $look_at) = @_;
my $region_handle_string = "'region_handle':" . &_make_r_string(@$region_handle);
my $position_string = "'position':" . &_make_r_string(@$position);
my $look_at_string = "'look_at':" . &_make_r_string(@$look_at);
return "{" . $region_handle_string . ", " . $position_string . ", " . $look_at_string . "}";
}
sub _make_r_string {
my @params = @_;
foreach (@params) {
$_ = "r" . $_;
}
return "[" . join(",", @params) . "]";
}
1;

View File

@ -0,0 +1,125 @@
package OpenSim::UserServer::Config;
use strict;
our %SYS_SQL = (
select_user_by_name =>
"select * from users where username=? and lastname=?",
select_user_by_uuid =>
"select * from users where uuid=?",
create_user =>
"insert into users values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
);
our @USERS_COLUMNS = (
"UUID",
"username",
"lastname",
"passwordHash",
"passwordSalt",
"homeRegion",
"homeLocationX",
"homeLocationY",
"homeLocationZ",
"homeLookAtX",
"homeLookAtY",
"homeLookAtZ",
"created",
"lastLogin",
"userInventoryURI",
"userAssetURI",
"profileCanDoMask",
"profileWantDoMask",
"profileAboutText",
"profileFirstText",
"profileImage",
"profileFirstImage",
);
# copied from opensim
our @classified_categories = (
{ category_id => 1, category_name => "Shopping" },
{ category_id => 2, category_name => "Land Rental" },
{ category_id => 3, category_name => "Property Rental" },
{ category_id => 4, category_name => "Special Attraction" },
{ category_id => 5, category_name => "New Products" },
{ category_id => 6, category_name => "Employment" },
{ category_id => 7, category_name => "Wanted" },
{ category_id => 8, category_name => "Service" },
{ category_id => 9, category_name => "Personal" },
);
our @event_categories = ();
our @event_notifications = ();
our @gestures =();
our @global_textures = (
{
cloud_texture_id => "dc4b9f0b-d008-45c6-96a4-01dd947ac621",
moon_texture_id => "ec4b9f0b-d008-45c6-96a4-01dd947ac621",
sun_texture_id => "cce0f112-878f-4586-a2e2-a8f104bba271",
},
);
our @initial_outfit = (
{ folder_name => "Nightclub Female", gender => "female" }
);
our @inventory_lib_owner = ({ agent_id => "11111111-1111-0000-0000-000100bba000" });
our @inventory_lib_root = ({ folder_id => "00000112-000f-0000-0000-000100bba000" });
our @inventory_root = ({ folder_id => "2eb27bc2-22ee-48db-b2e9-5c79a6582919" });
our @inventory_skel_lib = (
{
folder_id => "00000112-000f-0000-0000-000100bba000",
name => "OpenSim Library",
parent_id => "00000000-0000-0000-0000-000000000000",
type_default => -1,
version => 1,
},
{
folder_id => "00000112-000f-0000-0000-000100bba001",
name => "Texture Library",
parent_id => "00000112-000f-0000-0000-000100bba000",
type_default => -1,
version => 1,
},
);
our @inventory_skeleton = (
{
folder_id => "2eb27bc2-22ee-48db-b2e9-5c79a6582919",
name => "My Inventory",
parent_id => "00000000-0000-0000-0000-000000000000",
type_default => 8,
version => 1,
},
{
folder_id => "6cc20d86-9945-4997-a102-959348d56821",
name => "Textures",
parent_id => "2eb27bc2-22ee-48db-b2e9-5c79a6582919",
type_default => 0,
version => 1,
},
{
folder_id => "840b747f-bb7d-465e-ab5a-58badc953484",
name => "Clothes",
parent_id => "2eb27bc2-22ee-48db-b2e9-5c79a6582919",
type_default => 5,
version => 1,
},
{
folder_id => "37039005-7bbe-42a2-aa12-6bda453f37fd",
name => "Objects",
parent_id => "2eb27bc2-22ee-48db-b2e9-5c79a6582919",
type_default => 6,
version => 1,
},
);
our @login_flags = (
{
daylight_savings => "N",
ever_logged_in => "Y",
gendered => "Y",
stipend_since_login => "N",
},
);
our @ui_config = ({ allow_first_life => "Y" });
1;

View File

@ -0,0 +1,49 @@
package OpenSim::UserServer::UserManager;
use strict;
use Carp;
use OpenSim::Utility;
use OpenSim::UserServer::Config;
sub getUserByName {
my ($first, $last) = @_;
my $res = &OpenSim::Utility::getSimpleResult($OpenSim::UserServer::Config::SYS_SQL{select_user_by_name}, $first, $last);
my $count = @$res;
my %user = ();
if ($count == 1) {
my $user_row = $res->[0];
foreach (@OpenSim::UserServer::Config::USERS_COLUMNS) {
$user{$_} = $user_row->{$_} || "";
}
} else {
Carp::croak("user not found");
}
return \%user;
}
sub getUserByUUID {
my ($uuid) = @_;
my $res = &OpenSim::Utility::getSimpleResult($OpenSim::UserServer::Config::SYS_SQL{select_user_by_uuid}, $uuid);
my $count = @$res;
my %user = ();
if ($count == 1) {
my $user_row = $res->[0];
foreach (@OpenSim::UserServer::Config::USERS_COLUMNS) {
$user{$_} = $user_row->{$_} || "";
}
} else {
Carp::croak("user not found");
}
return \%user;
}
sub createUser {
my $user = shift;
my @params = ();
foreach (@OpenSim::UserServer::Config::USERS_COLUMNS) {
push @params, $user->{$_};
}
my $res = &OpenSim::Utility::getSimpleResult($OpenSim::UserServer::Config::SYS_SQL{create_user}, @params);
}
1;

View File

@ -0,0 +1,155 @@
package OpenSim::Utility;
use strict;
use XML::RPC;
use XML::Simple;
use Data::UUID;
use DBHandler;
use OpenSim::Config;
use Socket;
sub XMLRPCCall {
my ($url, $methodname, $param) = @_;
my $xmlrpc = new XML::RPC($url);
my $result = $xmlrpc->call($methodname, $param);
return $result;
}
sub XMLRPCCall_array {
my ($url, $methodname, $param) = @_;
my $xmlrpc = new XML::RPC($url);
my $result = $xmlrpc->call($methodname, @$param);
return $result;
}
sub UIntsToLong {
my ($int1, $int2) = @_;
return $int1 * 4294967296 + $int2;
}
sub getSimpleResult {
my ($sql, @args) = @_;
my $dbh = &DBHandler::getConnection($OpenSim::Config::DSN, $OpenSim::Config::DBUSER, $OpenSim::Config::DBPASS);
my $st = new Statement($dbh, $sql);
return $st->exec(@args);
}
sub GenerateUUID {
my $ug = new Data::UUID();
my $uuid = $ug->create();
return $ug->to_string($uuid);
}
sub ZeroUUID {
return "00000000-0000-0000-0000-000000000000";
}
sub HEX2UUID {
my $hex = shift;
Carp::croak("$hex is not a uuid") if (length($hex) != 32);
my @sub_uuids = ($hex =~ /(\w{8})(\w{4})(\w{4})(\w{4})(\w{12})/);
return join("-", @sub_uuids);
}
sub BIN2UUID {
# TODO:
}
sub UUID2HEX {
my $uuid = shift;
$uuid =~ s/-//g;
return $uuid;
}
sub UUID2BIN {
my $uuid = shift;
return pack("H*", &UUID2HEX($uuid));
}
sub HttpPostRequest {
my ($url, $postdata) = @_;
$url =~ /http:\/\/([^:\/]+)(:([0-9]+))?(\/.*)?/;
my ($host, $port, $path) = ($1, $3, $4);
$port ||= 80;
$path ||= "/";
my $CRLF= "\015\012";
my $addr = (gethostbyname($host))[4];
my $name = pack('S n a4 x8', 2, $port, $addr);
my $data_len = length($postdata);
socket(SOCK, PF_INET, SOCK_STREAM, 0);
connect(SOCK, $name) ;
select(SOCK); $| = 1; select(STDOUT);
print SOCK "POST $path HTTP/1.0$CRLF";
print SOCK "Host: $host:$port$CRLF";
print SOCK "Content-Length: $data_len$CRLF";
print SOCK "$CRLF";
print SOCK $postdata;
my $ret = "";
unless (<SOCK>) {
close(SOCK);
Carp::croak("can not connect to $url");
}
my $header = "";
while (<SOCK>) {
$header .= $_;
last if ($_ eq $CRLF);
}
if ($header != /200/) {
return $ret;
}
while (<SOCK>) {
$ret .= $_;
}
return $ret;
}
# TODO : merge with POST
sub HttpGetRequest {
my ($url) = @_;
$url =~ /http:\/\/([^:\/]+)(:([0-9]+))?(\/.*)?/;
my ($host, $port, $path) = ($1, $3, $4);
$port ||= 80;
$path ||= "/";
my $CRLF= "\015\012";
my $addr = (gethostbyname($host))[4];
my $name = pack('S n a4 x8', 2, $port, $addr);
socket(SOCK, PF_INET, SOCK_STREAM, 0);
connect(SOCK, $name) ;
select(SOCK); $| = 1; select(STDOUT);
print SOCK "GET $path HTTP/1.0$CRLF";
print SOCK "Host: $host:$port$CRLF";
print SOCK "$CRLF";
unless (<SOCK>) {
close(SOCK);
Carp::croak("can not connect to $url");
}
while (<SOCK>) {
last if ($_ eq $CRLF);
}
my $ret = "";
while (<SOCK>) {
$ret .= $_;
}
return $ret;
}
sub XML2Obj {
my $xml = shift;
my $xs = new XML::Simple( keyattr=>[] );
return $xs->XMLin($xml);
}
sub Log {
my $server_name = shift;
my @param = @_;
open(FILE, ">>" . $OpenSim::Config::DEBUG_LOGDIR . "/" . $server_name . ".log");
foreach(@param) {
print FILE $_ . "\n";
}
print FILE "<<<<<<<<<<<=====================\n\n";
close(FILE);
}
1;

217
share/perl/lib/XML/RPC.pm Normal file
View File

@ -0,0 +1,217 @@
package XML::RPC;
use strict;
use XML::TreePP;
use Data::Dumper;
use vars qw($VERSION $faultCode);
no strict 'refs';
$VERSION = 0.5;
sub new {
my $package = shift;
my $self = { };
bless $self, $package;
$self->{url} = shift;
$self->{tpp} = XML::TreePP->new(@_);
return $self;
}
sub call {
my $self = shift;
my ( $methodname, @params ) = @_;
die 'no url' if ( !$self->{url} );
$faultCode = 0;
my $xml = $self->create_call_xml( $methodname, @params );
#print STDERR $xml;
my $result = $self->{tpp}->parsehttp(
POST => $self->{url},
$xml,
{
'Content-Type' => 'text/xml',
'User-Agent' => 'XML-RPC/' . $VERSION,
'Content-Length' => length($xml)
}
);
my @data = $self->unparse_response($result);
return @data == 1 ? $data[0] : @data;
}
sub receive {
my $self = shift;
my $result = eval {
my $xml = shift || die 'no xml';
my $handler = shift || die 'no handler';
my $hash = $self->{tpp}->parse($xml);
my ( $methodname, @params ) = $self->unparse_call($hash);
$self->create_response_xml( $handler->( $methodname, @params ) );
};
return $self->create_fault_xml($@) if ($@);
return $result;
}
sub create_fault_xml {
my $self = shift;
my $error = shift;
chomp($error);
return $self->{tpp}
->write( { methodResponse => { fault => $self->parse( { faultString => $error, faultCode => $faultCode } ) } } );
}
sub create_call_xml {
my $self = shift;
my ( $methodname, @params ) = @_;
return $self->{tpp}->write(
{
methodCall => {
methodName => $methodname,
params => { param => [ map { $self->parse($_) } @params ] }
}
}
);
}
sub create_response_xml {
my $self = shift;
my @params = @_;
return $self->{tpp}->write( { methodResponse => { params => { param => [ map { $self->parse($_) } @params ] } } } );
}
sub parse {
my $self = shift;
my $p = shift;
my $result;
if ( ref($p) eq 'HASH' ) {
$result = $self->parse_struct($p);
}
elsif ( ref($p) eq 'ARRAY' ) {
$result = $self->parse_array($p);
}
else {
$result = $self->parse_scalar($p);
}
return { value => $result };
}
sub parse_scalar {
my $self = shift;
my $scalar = shift;
local $^W = undef;
if ( ( $scalar =~ m/^[\-+]?\d+$/ )
&& ( abs($scalar) <= ( 0xffffffff >> 1 ) ) )
{
return { i4 => $scalar };
}
elsif ( $scalar =~ m/^[\-+]?\d+\.\d+$/ ) {
return { double => $scalar };
}
else {
return { string => \$scalar };
}
}
sub parse_struct {
my $self = shift;
my $hash = shift;
my @members;
while ( my ( $k, $v ) = each(%$hash) ) {
push @members, { name => $k, %{ $self->parse($v) } };
}
return { struct => { member => \@members } };
}
sub parse_array {
my $self = shift;
my $array = shift;
return { array => { data => { value => [ map { $self->parse($_)->{value} } $self->list($array) ] } } };
}
sub unparse_response {
my $self = shift;
my $hash = shift;
my $response = $hash->{methodResponse} || die 'no data';
if ( $response->{fault} ) {
return $self->unparse_value( $response->{fault}->{value} );
}
else {
return map { $self->unparse_value( $_->{value} ) } $self->list( $response->{params}->{param} );
}
}
sub unparse_call {
my $self = shift;
my $hash = shift;
my $response = $hash->{methodCall} || die 'no data';
my $methodname = $response->{methodName};
my @args =
map { $self->unparse_value( $_->{value} ) } $self->list( $response->{params}->{param} );
return ( $methodname, @args );
}
sub unparse_value {
my $self = shift;
my $value = shift;
my $result;
return $value if ( ref($value) ne 'HASH' ); # for unspecified params
if ( $value->{struct} ) {
$result = $self->unparse_struct( $value->{struct} );
return !%$result
? undef
: $result; # fix for empty hashrefs from XML::TreePP
}
elsif ( $value->{array} ) {
return $self->unparse_array( $value->{array} );
}
else {
return $self->unparse_scalar($value);
}
}
sub unparse_scalar {
my $self = shift;
my $scalar = shift;
my ($result) = values(%$scalar);
return ( ref($result) eq 'HASH' && !%$result )
? undef
: $result; # fix for empty hashrefs from XML::TreePP
}
sub unparse_struct {
my $self = shift;
my $struct = shift;
return { map { $_->{name} => $self->unparse_value( $_->{value} ) } $self->list( $struct->{member} ) };
}
sub unparse_array {
my $self = shift;
my $array = shift;
my $data = $array->{data};
return [ map { $self->unparse_value($_) } $self->list( $data->{value} ) ];
}
sub list {
my $self = shift;
my $param = shift;
return () if ( !$param );
return @$param if ( ref($param) eq 'ARRAY' );
return ($param);
}
1;

View File

@ -0,0 +1,163 @@
package XML::Serializer;
use strict;
my $root_element = "root";
my $indent = " ";
#my $XML_HEADER = << "XMLHEADER";
#<?xml version="1.0" encoding="__CHARSET__"?>
#<?xml-stylesheet type="text/xsl" href="__XSLT__" ?>
#XMLHEADER
my $XML_HEADER = << "XMLHEADER";
<?xml version="1.0" encoding="__CHARSET__"?>
XMLHEADER
sub WITH_HEADER {
return 1;
}
sub new {
my ($this, $data, $root_name, $xslt) = @_;
my %fields = (
_charset => "utf-8",
_data => "",
_output => "",
_root_name => $root_name ? $root_name : "root",
_xslt => $xslt ? $xslt : ""
);
if (defined $data) {
$fields{_data} = $data;
}
return bless \%fields, $this;
}
sub set_root_name {
my ($this, $root_name) = @_;
$this->{_root_name} = $root_name;
}
sub set_data {
my ($this, $data) = @_;
$this->{_data} = $data;
}
sub set_charset {
my ($this, $charset) = @_;
$this->{_charset} = $charset;
}
sub set_xslt {
my ($this, $xslt) = @_;
$this->{_xslt} = $xslt;
}
sub to_string{
my ($this, $header) = @_;
if ($header) {
$this->{_output} = &_make_xml_header($this->{_charset}, $this->{_xslt});
}
$this->{_output} .= &_to_string($this->{_data}, $this->{_root_name});
}
sub to_formatted{
my ($this, $header) = @_;
if ($header) {
$this->{_output} = &_make_xml_header($this->{_charset}, $this->{_xslt});
}
$this->{_output} .= &_to_formatted($this->{_root_name}, $this->{_data});
}
sub _make_xml_header {
my $header = $XML_HEADER;
$header =~ s/__CHARSET__/$_[0]/;
$header =~ s/__XSLT__/$_[1]/;
return $header;
}
sub _to_string {
my ($obj, $name) = @_;
my $output = "";
if (ref($obj) eq "HASH") {
my $attr_list = "";
my $tmp_mid = "";
foreach (sort keys %$obj) {
if ($_ =~ /^@/) {
$attr_list = &_to_string($_, $obj->{$_});
}
$tmp_mid .= &_to_string($_, $obj->{$_});
}
$output = &_start_node($name, $attr_list) . $tmp_mid . &_end_node($name);
}
elsif (ref($obj) eq "ARRAY") {
foreach (@$obj) {
$output .= &_to_string($_, $name);
}
}
else {
if ($_ =~ /^@(.+)$/) {
return "$1=\"$obj\" ";
} else {
$output = &_start_node($name) . $obj . &_end_node($name);
}
}
return $output;
}
sub _to_formatted {
my ($name, $obj, $depth) = @_;
# if (!$obj) { $obj = ""; }
if (!defined($depth)) { $depth = 0; }
my $output = "";
if (ref($obj) eq "HASH") {
my $attr_list = "";
my $tmp_mid = "";
foreach (sort keys %$obj) {
if ($_ =~ /^@/) {
$attr_list = &_to_string($_, $obj->{$_});
}
$tmp_mid .= &_to_formatted($_, $obj->{$_}, $depth+1);
}
$output = &_start_node($name, $attr_list, $depth) . "\n" . $tmp_mid . &_end_node($name, $depth);
}
elsif (ref($obj) eq "ARRAY") {
foreach (@$obj) {
$output .= &_to_formatted($name, $_, $depth);
}
}
else {
if ($_ =~ /^@(.+)$/) {
#return "$1=\"$obj\" ";
} else {
$output .= &_start_node($name, "", $depth);
$output .= $obj;
$output .= &_end_node($name);
}
}
return $output;
}
sub _start_node {
my $ret = "";
if (defined $_[2]) {
for(1..$_[2]) { $ret .= $indent; }
}
my $tag = $_[0] ? $_[0] : "";
my $attr = $_[1] ? $_[1] : "";
$ret .= "<$tag $attr>";
return $ret;
}
sub _end_node {
my $ret = "";
if (defined $_[1]) {
for(1..$_[1]) { $ret .= $indent; }
}
if (defined $_[0]) {
$ret .= "</$_[0]>\n";
}
return $ret;
}
1;

3284
share/perl/lib/XML/Simple.pm Normal file

File diff suppressed because it is too large Load Diff

1228
share/perl/lib/XML/TreePP.pm Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,53 @@
package OpenSimTest;
use strict;
use PerformanceTest;
use OpenSimTest::Config;
use OpenSimTest::UserTester;
use OpenSimTest::GridTester;
use OpenSimTest::AssetTester;
use OpenSimTest::InventoryTester;
sub init {
UserTester::init();
GridTester::init();
AssetTester::init();
InventoryTester::init();
}
sub SingleTest {
my $url = shift;
my $methodname = shift;
my @ARGS = @_;
if (!$OpenSimTest::Config::HANDLER_LIST{$methodname}) {
Carp::croak("unknown handler name: [$methodname]");
} else {
my $handler = $OpenSimTest::Config::HANDLER_LIST{$methodname};
my $result = $handler->($url, @ARGS);
return $result;
}
}
sub PerformanceCompare {
my $server_name = shift;
my $count = shift;
my @args = @_;
my $test = new PerformanceTest();
{
my @params = @args;
unshift(@params, $OpenSimTest::Config::APACHE_SERVERS{$server_name});
$test->add_test("APACHE::$args[0]", \&OpenSimTest::SingleTest, \@params);
}
{
my @params = @args;
unshift(@params, $OpenSimTest::Config::OPENSIM_SERVERS{$server_name});
$test->add_test("OPENSIM::$args[0]", \&OpenSimTest::SingleTest, \@params);
}
$test->set_count($count);
$test->start();
print "\n\n";
#$test->bref_result();
}
1;

View File

@ -0,0 +1,17 @@
package AssetTester;
use strict;
use XML::Serializer;
use OpenSim::Utility;
sub init {
&OpenSimTest::Config::registerHandler("get_asset", \&_get_asset);
}
sub _get_asset {
my $url = shift || $OpenSimTest::Config::ASSET_SERVER_URL;
my $asset_id = shift;
my $res = &OpenSim::Utility::HttpGetRequest($url . "/assets/" . $asset_id) . "\n";
}
1;

View File

@ -0,0 +1,53 @@
package OpenSimTest::Config;
use strict;
my $apache_server_host = "localhost";
my $opensim_server_host = "localhost";
# REGION
our $SIM_RECV_KEY = "";
our $SIM_SEND_KEY = "";
# ASSET
#our $ASSET_SERVER_URL = "http://127.0.0.1:8003/";
our $ASSET_SERVER_URL = "http://$apache_server_host/opensim/asset.cgi";
our $ASSET_RECV_KEY = "";
our $ASSET_SEND_KEY = "";
# USER
#our $USER_SERVER_URL = "http://127.0.0.1:8001/";
our $USER_SERVER_URL = "http://$apache_server_host/opensim/user.cgi";
our $USER_RECV_KEY = "";
our $USER_SEND_KEY = "";
# GRID
#our $GRID_SERVER_URL = "http://127.0.0.1:8001/";
our $GRID_SERVER_URL = "http://$apache_server_host/opensim/grid.cgi";
our $GRID_RECV_KEY = "";
our $GRID_SEND_KEY = "";
# INVENTORY
#our $INVENTORY_SERVER_URL = "http://127.0.0.1:8004";
our $INVENTORY_SERVER_URL = "http://$apache_server_host/opensim/inventory.cgi";
# handler list
our %HANDLER_LIST = ();
our %APACHE_SERVERS = (
user => "http://$apache_server_host/opensim/user.cgi",
grid => "http://$apache_server_host/opensim/grid.cgi",
asset => "http://$apache_server_host/opensim/asset.cgi",
inventory => "http://$apache_server_host/opensim/inventory.cgi",
);
our %OPENSIM_SERVERS = (
user => "http://$opensim_server_host:8002",
grid => "http://$opensim_server_host:8001",
asset => "http://$opensim_server_host:8003",
inventory => "http://$opensim_server_host:8004",
);
sub registerHandler {
my ($name, $func) = @_;
$HANDLER_LIST{$name} = $func;
}
1;

View File

@ -0,0 +1,62 @@
package GridTester;
use strict;
use OpenSim::Utility;
sub init {
&OpenSimTest::Config::registerHandler("simulator_login", \&_simulator_login);
&OpenSimTest::Config::registerHandler("simulator_data_request", \&_simulator_data_request);
&OpenSimTest::Config::registerHandler("simulator_after_region_moved", \&_simulator_after_region_moved);
&OpenSimTest::Config::registerHandler("map_block", \&_map_block);
}
sub _simulator_login {
my $url = shift || $OpenSimTest::Config::GRID_SERVER_URL;
my @param = @_;
my %xml_rpc_param = (
"authkey" => "null",
"UUID" => $param[0],
"sim_ip" => $param[1],
"sim_port" => $param[2],
"region_locx" => 1000,
"region_locy" => 1000,
"sim_name" => "OpenTest",
"http_port" => 9000,
"remoting_port" => 8895,
"map-image-id" => "0e5a5e87-08d9-4b37-9b8e-a4c3c4e409ab",
);
return &OpenSim::Utility::XMLRPCCall($url, "simulator_login", \%xml_rpc_param);
}
sub _map_block {
my $url = shift || $OpenSimTest::Config::GRID_SERVER_URL;
my @param = @_;
my %xml_rpc_param = (
xmin => $param[0],
ymin => $param[1],
xmax => $param[2],
ymax => $param[3],
);
return &OpenSim::Utility::XMLRPCCall($url, "map_block", \%xml_rpc_param);
}
sub _simulator_data_request {
my $url = shift || $OpenSimTest::Config::GRID_SERVER_URL;
my @param = @_;
my %xml_rpc_param = (
region_handle => $param[0],
authkey => undef,
);
return &OpenSim::Utility::XMLRPCCall($url, "simulator_data_request", \%xml_rpc_param);
}
sub _simulator_after_region_moved {
my $url = shift || $OpenSimTest::Config::GRID_SERVER_URL;
my @param = @_;
my %xml_rpc_param = (
UUID => $param[0],
);
return &OpenSim::Utility::XMLRPCCall($url, "simulator_after_region_moved", \%xml_rpc_param);
}
1;

View File

@ -0,0 +1,116 @@
package InventoryTester;
use strict;
use XML::Serializer;
use OpenSim::Utility;
sub init {
&OpenSimTest::Config::registerHandler("create_inventory", \&_create_inventory);
&OpenSimTest::Config::registerHandler("root_folders", \&_root_folders);
&OpenSimTest::Config::registerHandler("get_inventory", \&_get_inventory);
&OpenSimTest::Config::registerHandler("new_item", \&_new_item);
&OpenSimTest::Config::registerHandler("new_folder", \&_new_folder);
}
sub _apache_flag {
my $url = shift;
return $url =~ /inventory.cgi/ ? 1 : 0;
}
sub _new_folder {
my $url = shift || $OpenSimTest::Config::INVENTORY_SERVER_URL;
my $post_data =<<"POSTDATA";
<InventoryFolderBase>
<name>New Folder</name>
<agentID>
<UUID>b9cb58e8-f3c9-4af5-be47-029762baa68f</UUID>
</agentID>
<parentID>
<UUID>500ea141-2967-49e2-9e18-fcdedffe68df</UUID>
</parentID>
<folderID>
<UUID>aa6f9220-c945-0b23-6141-43c9ef734100</UUID>
</folderID>
<type>-1</type>
<version>0</version>
</InventoryFolderBase>
POSTDATA
if (&_apache_flag($url)) {
$post_data = "POSTDATA=" . $post_data; # TODO: bad temporary solution
}
my $res = &OpenSim::Utility::HttpPostRequest($url . "/NewFolder/", $post_data) . "\n";
}
sub _new_item {
my $url = shift || $OpenSimTest::Config::INVENTORY_SERVER_URL;
my $post_data =<<"POSTDATA";
<InventoryItemBase>
<inventoryID>
<UUID>f975d038-3bd7-4e8b-a945-f46b0c962ee3</UUID>
</inventoryID>
<assetID>
<UUID>5f50f162-1cc6-4907-99be-a4c81d7f5e10</UUID>
</assetID>
<assetType>6</assetType>
<invType>6</invType>
<parentFolderID>
<UUID>7018dc23-43a9-493f-b3f7-869a6bbad0f3</UUID>
</parentFolderID>
<avatarID>
<UUID>b9cb58e8-f3c9-4af5-be47-029762baa68f</UUID>
</avatarID>
<creatorsID>
<UUID>b9cb58e8-f3c9-4af5-be47-029762baa68f</UUID>
</creatorsID>
<inventoryName>Primitive</inventoryName>
<inventoryDescription/>
<inventoryNextPermissions>2147483647</inventoryNextPermissions>
<inventoryCurrentPermissions>526053692</inventoryCurrentPermissions>
<inventoryBasePermissions>2147483647</inventoryBasePermissions>
<inventoryEveryOnePermissions>0</inventoryEveryOnePermissions>
</InventoryItemBase>
POSTDATA
if (&_apache_flag($url)) {
$post_data = "POSTDATA=" . $post_data;
}
my $res = &OpenSim::Utility::HttpPostRequest($url . "/NewItem/", $post_data) . "\n";
}
sub _get_inventory {
my $url = shift || $OpenSimTest::Config::INVENTORY_SERVER_URL;
my $uuid = shift;
my $serializer = new XML::Serializer($uuid, "guid");
my $post_data = $serializer->to_string(XML::Serializer::WITH_HEADER);
if (&_apache_flag($url)) {
$post_data = "POSTDATA=" . $post_data;
}
my $res = &OpenSim::Utility::HttpPostRequest($url . "/GetInventory/", $post_data) . "\n";
return 1;
}
sub _create_inventory {
my $url = shift || $OpenSimTest::Config::INVENTORY_SERVER_URL;
my $uuid = shift;
my $serializer = new XML::Serializer($uuid, "guid");
my $post_data = $serializer->to_string(XML::Serializer::WITH_HEADER);
if (&_apache_flag($url)) {
$post_data = "POSTDATA=" . $post_data;
}
my $res = &OpenSim::Utility::HttpPostRequest($url . "/CreateInventory/", $post_data) . "\n";
return 1;
}
sub _root_folders {
my $url = shift || $OpenSimTest::Config::INVENTORY_SERVER_URL;
my $uuid = shift;
my $serializer = new XML::Serializer($uuid, "guid");
my $post_data = $serializer->to_string(XML::Serializer::WITH_HEADER);
if (&_apache_flag($url)) {
$post_data = "POSTDATA=" . $post_data;
}
my $res = &OpenSim::Utility::HttpPostRequest($url . "/RootFolders/", $post_data) . "\n";
return 1;
}
1;

View File

@ -0,0 +1,53 @@
package UserTester;
use strict;
use Digest::MD5;
use OpenSim::Utility;
my $user_server_url;
sub init {
&OpenSimTest::Config::registerHandler("login_to_simulator", \&_login_to_simulator);
&OpenSimTest::Config::registerHandler("get_user_by_name", \&_get_user_by_name);
&OpenSimTest::Config::registerHandler("get_user_by_uuid", \&_get_user_by_uuid);
&OpenSimTest::Config::registerHandler("get_avatar_picker_avatar", \&_get_avatar_picker_avatar);
}
sub _login_to_simulator {
my $url = shift || $OpenSimTest::Config::USER_SERVER_URL;
my @param = @_;
my %xml_rpc_param = (
first => $param[0],
last => $param[1],
passwd => "\$1\$" . Digest::MD5::md5_hex($param[2]),
start => "last",
version => "1.18.3.5",
mac => "cc82e1e2bfd24e5424d66b4fd3f70d55",
);
return &OpenSim::Utility::XMLRPCCall($url, "login_to_simulator", \%xml_rpc_param);
}
sub _get_user_by_name {
my $url = shift || $OpenSimTest::Config::USER_SERVER_URL;
my @param = @_;
my %xml_rpc_param = (
avatar_name => $param[0],
);
return &OpenSim::Utility::XMLRPCCall($url, "get_user_by_name", \%xml_rpc_param);
}
# sample uuid:
# db836502-de98-49c9-9edc-b90a67beb0a8
sub _get_user_by_uuid {
my $url = shift || $OpenSimTest::Config::USER_SERVER_URL;
my @param = @_;
my %xml_rpc_param = (
avatar_uuid => $param[0],
);
return &OpenSim::Utility::XMLRPCCall($url, "get_user_by_uuid", \%xml_rpc_param);
}
sub _get_avatar_picker_avatar {
}
1;

View File

@ -0,0 +1,78 @@
#!/usr/bin/perl
# Usage:
# ./PerformanceTest.pl
# 2 variables should be changed:
# Line 14: $fork_limit
# Line 13: $benchmark_loop_count
#
use strict;
use OpenSimTest;
my $script = "./PerformanceTest.pl";
my $fork_limit = 50; # the number of process
my $benchmark_loop_count = 10000; # the number of requests sent by each process
my @child_pid = ();
for(1..$fork_limit) {
my $pid = fork;
if ($pid) {
&parent_do($pid);
} elsif ($pid == 0) {
&child_do;
exit(0);
} else {
die "could not fork";
}
}
foreach (@child_pid) {
waitpid($_, 0);
}
sub parent_do {
my $pid = shift;
push(@child_pid, $pid);
}
sub child_do {
#for(1..10000) {
# print "$_ ";
#}
&OpenSimTest::init();
# user
&OpenSimTest::PerformanceCompare("user", $benchmark_loop_count, "get_user_by_name", "Test User");
&OpenSimTest::PerformanceCompare("user", $benchmark_loop_count, "get_user_by_uuid", "db836502-de98-49c9-9edc-b90a67beb0a8");
# grid
&OpenSimTest::PerformanceCompare("grid", $benchmark_loop_count, "simulator_login", "3507f395-88e5-468c-a45f-d4fd96a1c668", "10.8.1.148", 9000);
&OpenSimTest::PerformanceCompare("grid", $benchmark_loop_count, "simulator_data_request", "1099511628032000");
&OpenSimTest::PerformanceCompare("grid", $benchmark_loop_count, "map_block", 999, 999, 1001, 1001);
# asset
&OpenSimTest::PerformanceCompare("asset", $benchmark_loop_count, "get_asset", "00000000000022223333000000000001");
# inventory
&OpenSimTest::PerformanceCompare("inventory", $benchmark_loop_count, "root_folders", "b9cb58e8-f3c9-4af5-be47-029762baa68f");
&OpenSimTest::PerformanceCompare("inventory", $benchmark_loop_count, "get_inventory", "b9cb58e8-f3c9-4af5-be47-029762baa68f");
}
__END__
my $count = 10000;
&OpenSimTest::init();
# user
#&OpenSimTest::PerformanceCompare("user", $count, "get_user_by_name", "Test User");
#&OpenSimTest::PerformanceCompare("user", $count, "get_user_by_uuid", "db836502-de98-49c9-9edc-b90a67beb0a8");
# grid
#&OpenSimTest::PerformanceCompare("grid", $count, "simulator_login", "3507f395-88e5-468c-a45f-d4fd96a1c668", "10.8.1.148", 9000);
#&OpenSimTest::PerformanceCompare("grid", $count, "simulator_data_request", "1099511628032000");
#&OpenSimTest::PerformanceCompare("grid", $count, "map_block", 999, 999, 1001, 1001);
# asset
&OpenSimTest::PerformanceCompare("asset", $count, "get_asset", "00000000000022223333000000000001");
# inventory
#&OpenSimTest::PerformanceCompare("inventory", $count, "create_inventory", "b9cb58e8-f3c9-4af5-be47-029762baa68f");
#&OpenSimTest::PerformanceCompare("inventory", $count, "root_folders", "b9cb58e8-f3c9-4af5-be47-029762baa68f");
#&OpenSimTest::PerformanceCompare("inventory", $count, "get_inventory", "b9cb58e8-f3c9-4af5-be47-029762baa68f");
#&OpenSimTest::PerformanceCompare("inventory", $count, "new_item");
#&OpenSimTest::PerformanceCompare("inventory", $count, "new_folder");

View File

@ -0,0 +1,21 @@
#!/usr/bin/perl
# usage:
# ./SingleTest.pl $URL $METHOD @PARAMETERS
# example
# ./SingleTest.pl http://127.0.0.1/user.cgi get_user_by_name "Test User"
# ./SingleTest.pl http://127.0.0.1/grid.cgi simulator_login 3507f395-88e5-468c-a45f-d4fd96a1c668 10.8.1.148 9000
# ./SingleTest.pl http://127.0.0.1/grid.cgi map_block 999 999 1001 1001
# ./SingleTest.pl http://127.0.0.1/asset.cgi get_asset 00000000000022223333000000000001
#
use strict;
use Data::Dump;
use OpenSimTest;
&OpenSimTest::init();
my $url = shift @ARGV;
#my $url = "http://localhost:8002";
my $result = &OpenSimTest::SingleTest($url, @ARGV);
Data::Dump::dump($result);

28
share/perl/user.cgi Normal file
View File

@ -0,0 +1,28 @@
#!/usr/bin/perl -w
use strict;
use Carp;
use XML::RPC;
use MyCGI;
use OpenSim::Utility;
use OpenSim::UserServer;
my $param = &MyCGI::getParam();
my $request = $param->{'POSTDATA'};
&OpenSim::Utility::Log("user", "request", $request);
my $xmlrpc = new XML::RPC();
my $response = $xmlrpc->receive($request, \&XMLRPCHandler);
&OpenSim::Utility::Log("user", "response", $response);
&MyCGI::outputXml("utf-8", $response);
sub XMLRPCHandler {
my ($methodname, @param) = @_;
my $handler_list = &OpenSim::UserServer::getHandlerList();
if (!$handler_list->{$methodname}) {
Carp::croak("?");
} else {
my $handler = $handler_list->{$methodname};
$handler->(@param);
}
}