* Committing Lulurun's Cgi/Perl implementation of the UGAI servers.
* I love you long time.0.6.0-stable
parent
3d1b4f8578
commit
8c05b81d68
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
|
@ -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;
|
||||||
|
|
|
@ -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",
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
|
@ -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;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
|
@ -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");
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue