From 8c05b81d6860d8e0da4098cc6f59f630d7c53037 Mon Sep 17 00:00:00 2001
From: Adam Frisby
Date: Tue, 25 Mar 2008 16:29:54 +0000
Subject: * Committing Lulurun's Cgi/Perl implementation of the UGAI servers. *
I love you long time.
---
share/perl/lib/OpenSim/AssetServer.pm | 87 +++++++
share/perl/lib/OpenSim/AssetServer/AssetManager.pm | 34 +++
share/perl/lib/OpenSim/AssetServer/Config.pm | 24 ++
share/perl/lib/OpenSim/Config.pm | 41 ++++
share/perl/lib/OpenSim/GridServer.pm | 208 +++++++++++++++++
share/perl/lib/OpenSim/GridServer/Config.pm | 50 +++++
share/perl/lib/OpenSim/GridServer/GridManager.pm | 57 +++++
share/perl/lib/OpenSim/InventoryServer.pm | 249 +++++++++++++++++++++
share/perl/lib/OpenSim/InventoryServer/Config.pm | 51 +++++
.../OpenSim/InventoryServer/InventoryManager.pm | 86 +++++++
share/perl/lib/OpenSim/UserServer.pm | 239 ++++++++++++++++++++
share/perl/lib/OpenSim/UserServer/Config.pm | 125 +++++++++++
share/perl/lib/OpenSim/UserServer/UserManager.pm | 49 ++++
share/perl/lib/OpenSim/Utility.pm | 155 +++++++++++++
14 files changed, 1455 insertions(+)
create mode 100644 share/perl/lib/OpenSim/AssetServer.pm
create mode 100644 share/perl/lib/OpenSim/AssetServer/AssetManager.pm
create mode 100644 share/perl/lib/OpenSim/AssetServer/Config.pm
create mode 100644 share/perl/lib/OpenSim/Config.pm
create mode 100644 share/perl/lib/OpenSim/GridServer.pm
create mode 100644 share/perl/lib/OpenSim/GridServer/Config.pm
create mode 100644 share/perl/lib/OpenSim/GridServer/GridManager.pm
create mode 100644 share/perl/lib/OpenSim/InventoryServer.pm
create mode 100644 share/perl/lib/OpenSim/InventoryServer/Config.pm
create mode 100644 share/perl/lib/OpenSim/InventoryServer/InventoryManager.pm
create mode 100644 share/perl/lib/OpenSim/UserServer.pm
create mode 100644 share/perl/lib/OpenSim/UserServer/Config.pm
create mode 100644 share/perl/lib/OpenSim/UserServer/UserManager.pm
create mode 100644 share/perl/lib/OpenSim/Utility.pm
(limited to 'share/perl/lib/OpenSim')
diff --git a/share/perl/lib/OpenSim/AssetServer.pm b/share/perl/lib/OpenSim/AssetServer.pm
new file mode 100644
index 0000000..6418166
--- /dev/null
+++ b/share/perl/lib/OpenSim/AssetServer.pm
@@ -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";
+
+
+$asset_data
+
+
+ $asset->{assetUUID}
+
+ $asset->{assetType}
+ $asset->{invType}
+ $asset->{name}
+ $asset->{description}
+ $asset->{local}
+ $asset->{temporary}
+
+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",
+}
+
diff --git a/share/perl/lib/OpenSim/AssetServer/AssetManager.pm b/share/perl/lib/OpenSim/AssetServer/AssetManager.pm
new file mode 100644
index 0000000..f36ab1a
--- /dev/null
+++ b/share/perl/lib/OpenSim/AssetServer/AssetManager.pm
@@ -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;
diff --git a/share/perl/lib/OpenSim/AssetServer/Config.pm b/share/perl/lib/OpenSim/AssetServer/Config.pm
new file mode 100644
index 0000000..5598921
--- /dev/null
+++ b/share/perl/lib/OpenSim/AssetServer/Config.pm
@@ -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;
diff --git a/share/perl/lib/OpenSim/Config.pm b/share/perl/lib/OpenSim/Config.pm
new file mode 100644
index 0000000..246ef26
--- /dev/null
+++ b/share/perl/lib/OpenSim/Config.pm
@@ -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;
+
diff --git a/share/perl/lib/OpenSim/GridServer.pm b/share/perl/lib/OpenSim/GridServer.pm
new file mode 100644
index 0000000..7b21cd8
--- /dev/null
+++ b/share/perl/lib/OpenSim/GridServer.pm
@@ -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;
+
diff --git a/share/perl/lib/OpenSim/GridServer/Config.pm b/share/perl/lib/OpenSim/GridServer/Config.pm
new file mode 100644
index 0000000..dc72e5a
--- /dev/null
+++ b/share/perl/lib/OpenSim/GridServer/Config.pm
@@ -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;
diff --git a/share/perl/lib/OpenSim/GridServer/GridManager.pm b/share/perl/lib/OpenSim/GridServer/GridManager.pm
new file mode 100644
index 0000000..2170d74
--- /dev/null
+++ b/share/perl/lib/OpenSim/GridServer/GridManager.pm
@@ -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;
diff --git a/share/perl/lib/OpenSim/InventoryServer.pm b/share/perl/lib/OpenSim/InventoryServer.pm
new file mode 100644
index 0000000..184e19a
--- /dev/null
+++ b/share/perl/lib/OpenSim/InventoryServer.pm
@@ -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>/) {
+ return $1;
+ } else {
+ Carp::croak("can not find uuid: $data");
+ }
+}
+
+
+1;
+
diff --git a/share/perl/lib/OpenSim/InventoryServer/Config.pm b/share/perl/lib/OpenSim/InventoryServer/Config.pm
new file mode 100644
index 0000000..64dbdd1
--- /dev/null
+++ b/share/perl/lib/OpenSim/InventoryServer/Config.pm
@@ -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;
diff --git a/share/perl/lib/OpenSim/InventoryServer/InventoryManager.pm b/share/perl/lib/OpenSim/InventoryServer/InventoryManager.pm
new file mode 100644
index 0000000..97111b7
--- /dev/null
+++ b/share/perl/lib/OpenSim/InventoryServer/InventoryManager.pm
@@ -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;
+
diff --git a/share/perl/lib/OpenSim/UserServer.pm b/share/perl/lib/OpenSim/UserServer.pm
new file mode 100644
index 0000000..77117e1
--- /dev/null
+++ b/share/perl/lib/OpenSim/UserServer.pm
@@ -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=$user_id
+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;
diff --git a/share/perl/lib/OpenSim/UserServer/Config.pm b/share/perl/lib/OpenSim/UserServer/Config.pm
new file mode 100644
index 0000000..da628ed
--- /dev/null
+++ b/share/perl/lib/OpenSim/UserServer/Config.pm
@@ -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;
+
diff --git a/share/perl/lib/OpenSim/UserServer/UserManager.pm b/share/perl/lib/OpenSim/UserServer/UserManager.pm
new file mode 100644
index 0000000..ce35329
--- /dev/null
+++ b/share/perl/lib/OpenSim/UserServer/UserManager.pm
@@ -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;
diff --git a/share/perl/lib/OpenSim/Utility.pm b/share/perl/lib/OpenSim/Utility.pm
new file mode 100644
index 0000000..7fc91e7
--- /dev/null
+++ b/share/perl/lib/OpenSim/Utility.pm
@@ -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 () {
+ close(SOCK);
+ Carp::croak("can not connect to $url");
+ }
+ my $header = "";
+ while () {
+ $header .= $_;
+ last if ($_ eq $CRLF);
+ }
+ if ($header != /200/) {
+ return $ret;
+ }
+ while () {
+ $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 () {
+ close(SOCK);
+ Carp::croak("can not connect to $url");
+ }
+ while () {
+ last if ($_ eq $CRLF);
+ }
+ my $ret = "";
+ while () {
+ $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;
+
--
cgit v1.1