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/UserServer.pm | 239 +++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 share/perl/lib/OpenSim/UserServer.pm (limited to 'share/perl/lib/OpenSim/UserServer.pm') 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; -- cgit v1.1