2010-03-10 04:15:36 +00:00
/ *
* Copyright ( c ) Contributors , http : //opensimulator.org/
* See CONTRIBUTORS . TXT for a full list of copyright holders .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are met :
* * Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* * Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ` ` AS IS ' ' AND ANY
* EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED . IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES
* ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;
* LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* /
using System ;
2010-05-05 21:06:36 +00:00
using System.Collections ;
2009-12-31 05:00:16 +00:00
using System.Collections.Generic ;
2010-01-01 01:18:55 +00:00
using System.Net ;
2009-12-31 05:00:16 +00:00
using System.Reflection ;
2009-12-31 19:42:33 +00:00
using System.Text.RegularExpressions ;
2009-12-31 05:00:16 +00:00
using log4net ;
using Nini.Config ;
using OpenMetaverse ;
using OpenSim.Framework ;
2010-01-01 01:18:55 +00:00
using OpenSim.Framework.Capabilities ;
2010-01-11 04:17:37 +00:00
using OpenSim.Framework.Console ;
2009-12-31 05:00:16 +00:00
using OpenSim.Server.Base ;
using OpenSim.Services.Interfaces ;
2009-12-31 19:42:33 +00:00
using GridRegion = OpenSim . Services . Interfaces . GridRegion ;
2010-02-26 00:11:04 +00:00
using FriendInfo = OpenSim . Services . Interfaces . FriendInfo ;
2010-01-29 03:19:42 +00:00
using OpenSim.Services.Connectors.Hypergrid ;
2009-12-31 05:00:16 +00:00
namespace OpenSim.Services.LLLoginService
{
public class LLLoginService : ILoginService
{
2009-12-31 19:42:33 +00:00
private static readonly ILog m_log = LogManager . GetLogger ( MethodBase . GetCurrentMethod ( ) . DeclaringType ) ;
2010-01-11 04:17:37 +00:00
private static bool Initialized = false ;
2009-12-31 19:42:33 +00:00
2010-03-10 12:44:53 +00:00
protected IUserAccountService m_UserAccountService ;
protected IAuthenticationService m_AuthenticationService ;
protected IInventoryService m_InventoryService ;
protected IGridService m_GridService ;
protected IPresenceService m_PresenceService ;
2009-12-31 22:59:26 +00:00
private ISimulationService m_LocalSimulationService ;
2010-01-03 19:44:57 +00:00
private ISimulationService m_RemoteSimulationService ;
2010-03-10 12:44:53 +00:00
protected ILibraryService m_LibraryService ;
protected IFriendsService m_FriendsService ;
protected IAvatarService m_AvatarService ;
2010-01-29 03:19:42 +00:00
private IUserAgentService m_UserAgentService ;
private GatekeeperServiceConnector m_GatekeeperConnector ;
2009-12-31 05:00:16 +00:00
2009-12-31 19:42:33 +00:00
private string m_DefaultRegionName ;
2010-03-10 12:44:53 +00:00
protected string m_WelcomeMessage ;
2010-01-01 01:18:55 +00:00
private bool m_RequireInventory ;
2010-03-10 12:44:53 +00:00
protected int m_MinLoginLevel ;
2010-01-29 03:19:42 +00:00
private string m_GatekeeperURL ;
2010-05-05 21:06:36 +00:00
private bool m_AllowRemoteSetLoginLevel ;
2009-12-31 19:42:33 +00:00
2010-01-17 19:33:47 +00:00
IConfig m_LoginServerConfig ;
2010-01-02 05:12:46 +00:00
public LLLoginService ( IConfigSource config , ISimulationService simService , ILibraryService libraryService )
2009-12-31 05:00:16 +00:00
{
2010-01-17 19:33:47 +00:00
m_LoginServerConfig = config . Configs [ "LoginService" ] ;
if ( m_LoginServerConfig = = null )
2009-12-31 05:00:16 +00:00
throw new Exception ( String . Format ( "No section LoginService in config file" ) ) ;
2010-01-17 19:33:47 +00:00
string accountService = m_LoginServerConfig . GetString ( "UserAccountService" , String . Empty ) ;
2010-01-29 03:19:42 +00:00
string agentService = m_LoginServerConfig . GetString ( "UserAgentService" , String . Empty ) ;
2010-01-17 19:33:47 +00:00
string authService = m_LoginServerConfig . GetString ( "AuthenticationService" , String . Empty ) ;
string invService = m_LoginServerConfig . GetString ( "InventoryService" , String . Empty ) ;
string gridService = m_LoginServerConfig . GetString ( "GridService" , String . Empty ) ;
string presenceService = m_LoginServerConfig . GetString ( "PresenceService" , String . Empty ) ;
string libService = m_LoginServerConfig . GetString ( "LibraryService" , String . Empty ) ;
2010-02-26 00:11:04 +00:00
string friendsService = m_LoginServerConfig . GetString ( "FriendsService" , String . Empty ) ;
2010-01-17 19:33:47 +00:00
string avatarService = m_LoginServerConfig . GetString ( "AvatarService" , String . Empty ) ;
string simulationService = m_LoginServerConfig . GetString ( "SimulationService" , String . Empty ) ;
2009-12-31 05:00:16 +00:00
2010-01-17 19:33:47 +00:00
m_DefaultRegionName = m_LoginServerConfig . GetString ( "DefaultRegion" , String . Empty ) ;
m_WelcomeMessage = m_LoginServerConfig . GetString ( "WelcomeMessage" , "Welcome to OpenSim!" ) ;
m_RequireInventory = m_LoginServerConfig . GetBoolean ( "RequireInventory" , true ) ;
2010-05-05 21:06:36 +00:00
m_AllowRemoteSetLoginLevel = m_LoginServerConfig . GetBoolean ( "AllowRemoteSetLoginLevel" , false ) ;
m_MinLoginLevel = m_LoginServerConfig . GetInt ( "MinLoginLevel" , 0 ) ;
2010-01-29 03:19:42 +00:00
m_GatekeeperURL = m_LoginServerConfig . GetString ( "GatekeeperURI" , string . Empty ) ;
2009-12-31 19:42:33 +00:00
2010-01-03 00:26:40 +00:00
// These are required; the others aren't
if ( accountService = = string . Empty | | authService = = string . Empty )
2009-12-31 05:00:16 +00:00
throw new Exception ( "LoginService is missing service specifications" ) ;
Object [ ] args = new Object [ ] { config } ;
m_UserAccountService = ServerUtils . LoadPlugin < IUserAccountService > ( accountService , args ) ;
m_AuthenticationService = ServerUtils . LoadPlugin < IAuthenticationService > ( authService , args ) ;
m_InventoryService = ServerUtils . LoadPlugin < IInventoryService > ( invService , args ) ;
if ( gridService ! = string . Empty )
m_GridService = ServerUtils . LoadPlugin < IGridService > ( gridService , args ) ;
if ( presenceService ! = string . Empty )
m_PresenceService = ServerUtils . LoadPlugin < IPresenceService > ( presenceService , args ) ;
2010-01-03 00:26:40 +00:00
if ( avatarService ! = string . Empty )
m_AvatarService = ServerUtils . LoadPlugin < IAvatarService > ( avatarService , args ) ;
2010-02-26 00:11:04 +00:00
if ( friendsService ! = string . Empty )
m_FriendsService = ServerUtils . LoadPlugin < IFriendsService > ( friendsService , args ) ;
2010-01-03 19:44:57 +00:00
if ( simulationService ! = string . Empty )
m_RemoteSimulationService = ServerUtils . LoadPlugin < ISimulationService > ( simulationService , args ) ;
2010-01-29 03:19:42 +00:00
if ( agentService ! = string . Empty )
m_UserAgentService = ServerUtils . LoadPlugin < IUserAgentService > ( agentService , args ) ;
2010-01-02 05:12:46 +00:00
/ /
// deal with the services given as argument
/ /
2009-12-31 22:59:26 +00:00
m_LocalSimulationService = simService ;
2010-01-02 05:12:46 +00:00
if ( libraryService ! = null )
{
m_log . DebugFormat ( "[LLOGIN SERVICE]: Using LibraryService given as argument" ) ;
m_LibraryService = libraryService ;
}
else if ( libService ! = string . Empty )
{
m_log . DebugFormat ( "[LLOGIN SERVICE]: Using instantiated LibraryService" ) ;
m_LibraryService = ServerUtils . LoadPlugin < ILibraryService > ( libService , args ) ;
}
2009-12-31 05:00:16 +00:00
2010-01-29 03:19:42 +00:00
m_GatekeeperConnector = new GatekeeperServiceConnector ( ) ;
2010-01-11 04:17:37 +00:00
if ( ! Initialized )
{
Initialized = true ;
RegisterCommands ( ) ;
}
2010-01-01 04:51:35 +00:00
m_log . DebugFormat ( "[LLOGIN SERVICE]: Starting..." ) ;
2009-12-31 05:00:16 +00:00
}
2010-01-02 05:12:46 +00:00
public LLLoginService ( IConfigSource config ) : this ( config , null , null )
2009-12-31 22:59:26 +00:00
{
}
2010-05-05 21:06:36 +00:00
public Hashtable SetLevel ( string firstName , string lastName , string passwd , int level , IPEndPoint clientIP )
{
Hashtable response = new Hashtable ( ) ;
response [ "success" ] = "false" ;
if ( ! m_AllowRemoteSetLoginLevel )
return response ;
try
{
UserAccount account = m_UserAccountService . GetUserAccount ( UUID . Zero , firstName , lastName ) ;
if ( account = = null )
{
m_log . InfoFormat ( "[LLOGIN SERVICE]: Set Level failed, user {0} {1} not found" , firstName , lastName ) ;
return response ;
}
if ( account . UserLevel < 200 )
{
m_log . InfoFormat ( "[LLOGIN SERVICE]: Set Level failed, reason: user level too low" ) ;
return response ;
}
/ /
// Authenticate this user
/ /
// We don't support clear passwords here
/ /
string token = m_AuthenticationService . Authenticate ( account . PrincipalID , passwd , 30 ) ;
UUID secureSession = UUID . Zero ;
if ( ( token = = string . Empty ) | | ( token ! = string . Empty & & ! UUID . TryParse ( token , out secureSession ) ) )
{
m_log . InfoFormat ( "[LLOGIN SERVICE]: SetLevel failed, reason: authentication failed" ) ;
return response ;
}
}
catch ( Exception e )
{
m_log . Error ( "[LLOGIN SERVICE]: SetLevel failed, exception " + e . ToString ( ) ) ;
return response ;
}
m_MinLoginLevel = level ;
m_log . InfoFormat ( "[LLOGIN SERVICE]: Login level set to {0} by {1} {2}" , level , firstName , lastName ) ;
response [ "success" ] = true ;
return response ;
}
2010-04-27 02:48:49 +00:00
public LoginResponse Login ( string firstName , string lastName , string passwd , string startLocation , UUID scopeID , IPEndPoint clientIP )
2009-12-31 05:00:16 +00:00
{
2009-12-31 22:59:26 +00:00
bool success = false ;
2010-01-02 00:54:24 +00:00
UUID session = UUID . Random ( ) ;
2009-12-31 22:59:26 +00:00
2010-01-02 00:54:24 +00:00
try
2010-01-01 01:18:55 +00:00
{
2010-01-14 02:30:33 +00:00
/ /
2010-01-02 00:54:24 +00:00
// Get the account and check that it exists
2010-01-14 02:30:33 +00:00
/ /
2010-04-27 02:48:49 +00:00
UserAccount account = m_UserAccountService . GetUserAccount ( scopeID , firstName , lastName ) ;
2010-01-02 00:54:24 +00:00
if ( account = = null )
{
m_log . InfoFormat ( "[LLOGIN SERVICE]: Login failed, reason: user not found" ) ;
return LLFailedLoginResponse . UserProblem ;
}
2009-12-31 05:00:16 +00:00
2010-04-30 04:33:45 +00:00
if ( account . UserLevel < 0 )
{
m_log . InfoFormat ( "[LLOGIN SERVICE]: Login failed, reason: Unverified account" ) ;
return LLFailedLoginResponse . UnverifiedAccountProblem ;
}
2010-01-11 04:17:37 +00:00
if ( account . UserLevel < m_MinLoginLevel )
{
m_log . InfoFormat ( "[LLOGIN SERVICE]: Login failed, reason: login is blocked for user level {0}" , account . UserLevel ) ;
return LLFailedLoginResponse . LoginBlockedProblem ;
}
2010-04-27 02:48:49 +00:00
// If a scope id is requested, check that the account is in
// that scope, or unscoped.
/ /
if ( scopeID ! = UUID . Zero )
{
if ( account . ScopeID ! = scopeID & & account . ScopeID ! = UUID . Zero )
{
m_log . InfoFormat ( "[LLOGIN SERVICE]: Login failed, reason: user not found" ) ;
return LLFailedLoginResponse . UserProblem ;
}
}
else
{
scopeID = account . ScopeID ;
}
2010-01-14 02:30:33 +00:00
/ /
2010-01-02 00:54:24 +00:00
// Authenticate this user
2010-01-14 02:30:33 +00:00
/ /
2010-01-02 00:54:24 +00:00
if ( ! passwd . StartsWith ( "$1$" ) )
passwd = "$1$" + Util . Md5Hash ( passwd ) ;
passwd = passwd . Remove ( 0 , 3 ) ; //remove $1$
string token = m_AuthenticationService . Authenticate ( account . PrincipalID , passwd , 30 ) ;
UUID secureSession = UUID . Zero ;
if ( ( token = = string . Empty ) | | ( token ! = string . Empty & & ! UUID . TryParse ( token , out secureSession ) ) )
{
m_log . InfoFormat ( "[LLOGIN SERVICE]: Login failed, reason: authentication failed" ) ;
return LLFailedLoginResponse . UserProblem ;
}
2009-12-31 05:00:16 +00:00
2010-01-14 02:30:33 +00:00
/ /
2010-01-02 00:54:24 +00:00
// Get the user's inventory
2010-01-14 02:30:33 +00:00
/ /
2010-01-03 00:26:40 +00:00
if ( m_RequireInventory & & m_InventoryService = = null )
{
m_log . WarnFormat ( "[LLOGIN SERVICE]: Login failed, reason: inventory service not set up" ) ;
return LLFailedLoginResponse . InventoryProblem ;
}
2010-01-02 00:54:24 +00:00
List < InventoryFolderBase > inventorySkel = m_InventoryService . GetInventorySkeleton ( account . PrincipalID ) ;
if ( m_RequireInventory & & ( ( inventorySkel = = null ) | | ( inventorySkel ! = null & & inventorySkel . Count = = 0 ) ) )
{
m_log . InfoFormat ( "[LLOGIN SERVICE]: Login failed, reason: unable to retrieve user inventory" ) ;
return LLFailedLoginResponse . InventoryProblem ;
}
2009-12-31 05:00:16 +00:00
2010-01-14 02:30:33 +00:00
/ /
2010-01-02 00:54:24 +00:00
// Login the presence
2010-01-14 02:30:33 +00:00
/ /
2010-01-02 00:54:24 +00:00
PresenceInfo presence = null ;
GridRegion home = null ;
if ( m_PresenceService ! = null )
2010-01-01 01:18:55 +00:00
{
2010-01-02 00:54:24 +00:00
success = m_PresenceService . LoginAgent ( account . PrincipalID . ToString ( ) , session , secureSession ) ;
if ( ! success )
{
m_log . InfoFormat ( "[LLOGIN SERVICE]: Login failed, reason: could not login presence" ) ;
return LLFailedLoginResponse . GridProblem ;
}
// Get the updated presence info
presence = m_PresenceService . GetAgent ( session ) ;
// Get the home region
if ( ( presence . HomeRegionID ! = UUID . Zero ) & & m_GridService ! = null )
{
2010-04-27 02:48:49 +00:00
home = m_GridService . GetRegionByUUID ( scopeID , presence . HomeRegionID ) ;
2010-01-02 00:54:24 +00:00
}
}
2010-01-14 02:30:33 +00:00
/ /
2010-01-02 00:54:24 +00:00
// Find the destination region/grid
2010-01-14 02:30:33 +00:00
/ /
2010-01-02 00:54:24 +00:00
string where = string . Empty ;
Vector3 position = Vector3 . Zero ;
Vector3 lookAt = Vector3 . Zero ;
2010-01-29 03:19:42 +00:00
GridRegion gatekeeper = null ;
2010-04-27 02:48:49 +00:00
GridRegion destination = FindDestination ( account , scopeID , presence , session , startLocation , out gatekeeper , out where , out position , out lookAt ) ;
2010-01-02 00:54:24 +00:00
if ( destination = = null )
{
2010-01-10 23:34:56 +00:00
m_PresenceService . LogoutAgent ( session , presence . Position , presence . LookAt ) ;
2010-01-02 00:54:24 +00:00
m_log . InfoFormat ( "[LLOGIN SERVICE]: Login failed, reason: destination not found" ) ;
2009-12-31 19:42:33 +00:00
return LLFailedLoginResponse . GridProblem ;
2010-01-01 01:18:55 +00:00
}
2010-01-14 02:30:33 +00:00
/ /
2010-01-03 00:26:40 +00:00
// Get the avatar
2010-01-14 02:30:33 +00:00
/ /
2010-01-03 00:26:40 +00:00
AvatarData avatar = null ;
if ( m_AvatarService ! = null )
{
avatar = m_AvatarService . GetAvatar ( account . PrincipalID ) ;
}
2010-01-14 02:30:33 +00:00
/ /
2010-01-02 00:54:24 +00:00
// Instantiate/get the simulation interface and launch an agent at the destination
2010-01-14 02:30:33 +00:00
/ /
2010-01-02 00:54:24 +00:00
string reason = string . Empty ;
2010-01-29 03:19:42 +00:00
AgentCircuitData aCircuit = LaunchAgentAtGrid ( gatekeeper , destination , account , avatar , session , secureSession , position , where , out where , out reason ) ;
2010-01-02 00:54:24 +00:00
if ( aCircuit = = null )
{
2010-01-29 03:19:42 +00:00
m_PresenceService . LogoutAgent ( session , presence . Position , presence . LookAt ) ;
m_log . InfoFormat ( "[LLOGIN SERVICE]: Login failed, reason: {0}" , reason ) ;
return LLFailedLoginResponse . AuthorizationProblem ;
2010-01-14 02:30:33 +00:00
2010-01-01 01:18:55 +00:00
}
2010-02-26 00:11:04 +00:00
// Get Friends list
FriendInfo [ ] friendsList = new FriendInfo [ 0 ] ;
if ( m_FriendsService ! = null )
{
friendsList = m_FriendsService . GetFriends ( account . PrincipalID ) ;
m_log . DebugFormat ( "[LLOGIN SERVICE]: Retrieved {0} friends" , friendsList . Length ) ;
}
2009-12-31 19:42:33 +00:00
2010-01-14 02:30:33 +00:00
/ /
2010-01-02 00:54:24 +00:00
// Finally, fill out the response and return it
2010-01-14 02:30:33 +00:00
/ /
2010-02-26 00:11:04 +00:00
LLLoginResponse response = new LLLoginResponse ( account , aCircuit , presence , destination , inventorySkel , friendsList , m_LibraryService ,
2010-01-02 00:54:24 +00:00
where , startLocation , position , lookAt , m_WelcomeMessage , home , clientIP ) ;
2010-03-03 06:20:44 +00:00
m_log . DebugFormat ( "[LLOGIN SERVICE]: All clear. Sending login response to client." ) ;
2010-01-02 00:54:24 +00:00
return response ;
2010-01-01 01:18:55 +00:00
}
2010-01-02 00:54:24 +00:00
catch ( Exception e )
2009-12-31 22:59:26 +00:00
{
2010-03-03 04:17:25 +00:00
m_log . WarnFormat ( "[LLOGIN SERVICE]: Exception processing login for {0} {1}: {2} {3}" , firstName , lastName , e . ToString ( ) , e . StackTrace ) ;
2010-01-02 00:54:24 +00:00
if ( m_PresenceService ! = null )
2010-01-10 23:34:56 +00:00
m_PresenceService . LogoutAgent ( session , new Vector3 ( 128 , 128 , 0 ) , new Vector3 ( 0 , 1 , 0 ) ) ;
2010-01-02 00:54:24 +00:00
return LLFailedLoginResponse . InternalError ;
2009-12-31 22:59:26 +00:00
}
2009-12-31 05:00:16 +00:00
}
2009-12-31 19:42:33 +00:00
2010-04-27 02:48:49 +00:00
protected GridRegion FindDestination ( UserAccount account , UUID scopeID , PresenceInfo pinfo , UUID sessionID , string startLocation , out GridRegion gatekeeper , out string where , out Vector3 position , out Vector3 lookAt )
2009-12-31 19:42:33 +00:00
{
2010-01-02 00:54:24 +00:00
m_log . DebugFormat ( "[LLOGIN SERVICE]: FindDestination for start location {0}" , startLocation ) ;
2010-01-29 03:19:42 +00:00
gatekeeper = null ;
2009-12-31 19:42:33 +00:00
where = "home" ;
position = new Vector3 ( 128 , 128 , 0 ) ;
lookAt = new Vector3 ( 0 , 1 , 0 ) ;
2010-01-14 02:30:33 +00:00
if ( m_GridService = = null )
return null ;
2009-12-31 19:42:33 +00:00
if ( startLocation . Equals ( "home" ) )
{
// logging into home region
if ( pinfo = = null )
return null ;
2010-01-01 01:18:55 +00:00
GridRegion region = null ;
2010-03-04 22:43:30 +00:00
bool tryDefaults = false ;
if ( pinfo . HomeRegionID . Equals ( UUID . Zero ) )
{
m_log . WarnFormat (
"[LLOGIN SERVICE]: User {0} {1} tried to login to a 'home' start location but they have none set" ,
account . FirstName , account . LastName ) ;
tryDefaults = true ;
}
else
{
2010-04-27 02:48:49 +00:00
region = m_GridService . GetRegionByUUID ( scopeID , pinfo . HomeRegionID ) ;
2010-03-04 22:43:30 +00:00
if ( null = = region )
{
m_log . WarnFormat (
"[LLOGIN SERVICE]: User {0} {1} has a recorded home region of {2} but this cannot be found by the grid service" ,
account . FirstName , account . LastName , pinfo . HomeRegionID ) ;
tryDefaults = true ;
}
}
if ( tryDefaults )
2010-01-02 00:54:24 +00:00
{
2010-04-27 02:48:49 +00:00
List < GridRegion > defaults = m_GridService . GetDefaultRegions ( scopeID ) ;
2010-03-26 20:13:33 +00:00
if ( defaults ! = null & & defaults . Count > 0 )
{
region = defaults [ 0 ] ;
where = "safe" ;
}
else
{
m_log . WarnFormat ( "[LLOGIN SERVICE]: User {0} {1} does not have a valid home and this grid does not have default locations. Attempting to find random region" ,
account . FirstName , account . LastName ) ;
2010-04-27 02:48:49 +00:00
defaults = m_GridService . GetRegionsByName ( scopeID , "" , 1 ) ;
2010-03-26 20:13:33 +00:00
if ( defaults ! = null & & defaults . Count > 0 )
{
region = defaults [ 0 ] ;
where = "safe" ;
}
2010-01-02 00:54:24 +00:00
}
}
2009-12-31 19:42:33 +00:00
return region ;
}
else if ( startLocation . Equals ( "last" ) )
{
// logging into last visited region
where = "last" ;
if ( pinfo = = null )
return null ;
2010-01-01 01:18:55 +00:00
GridRegion region = null ;
2010-04-27 02:48:49 +00:00
if ( pinfo . RegionID . Equals ( UUID . Zero ) | | ( region = m_GridService . GetRegionByUUID ( scopeID , pinfo . RegionID ) ) = = null )
2010-01-02 00:54:24 +00:00
{
2010-04-27 02:48:49 +00:00
List < GridRegion > defaults = m_GridService . GetDefaultRegions ( scopeID ) ;
2010-01-13 23:28:46 +00:00
if ( defaults ! = null & & defaults . Count > 0 )
{
region = defaults [ 0 ] ;
where = "safe" ;
2010-03-26 20:13:33 +00:00
}
else
{
m_log . Info ( "[LLOGIN SERVICE]: Last Region Not Found Attempting to find random region" ) ;
2010-04-27 02:48:49 +00:00
defaults = m_GridService . GetRegionsByName ( scopeID , "" , 1 ) ;
2010-03-26 20:13:33 +00:00
if ( defaults ! = null & & defaults . Count > 0 )
{
region = defaults [ 0 ] ;
where = "safe" ;
}
2010-01-13 23:28:46 +00:00
}
2010-03-26 19:16:41 +00:00
2010-01-02 00:54:24 +00:00
}
2009-12-31 19:42:33 +00:00
else
{
position = pinfo . Position ;
lookAt = pinfo . LookAt ;
}
2010-03-04 22:43:30 +00:00
2009-12-31 19:42:33 +00:00
return region ;
}
else
2010-03-26 20:13:33 +00:00
{
2009-12-31 19:42:33 +00:00
// free uri form
// e.g. New Moon&135&46 New Moon@osgrid.org:8002&153&34
where = "url" ;
Regex reURI = new Regex ( @"^uri:(?<region>[^&]+)&(?<x>\d+)&(?<y>\d+)&(?<z>\d+)$" ) ;
Match uriMatch = reURI . Match ( startLocation ) ;
if ( uriMatch = = null )
{
m_log . InfoFormat ( "[LLLOGIN SERVICE]: Got Custom Login URI {0}, but can't process it" , startLocation ) ;
return null ;
}
else
{
2010-04-22 15:47:47 +00:00
position = new Vector3 ( float . Parse ( uriMatch . Groups [ "x" ] . Value , Culture . NumberFormatInfo ) ,
float . Parse ( uriMatch . Groups [ "y" ] . Value , Culture . NumberFormatInfo ) ,
float . Parse ( uriMatch . Groups [ "z" ] . Value , Culture . NumberFormatInfo ) ) ;
2009-12-31 19:42:33 +00:00
string regionName = uriMatch . Groups [ "region" ] . ToString ( ) ;
if ( regionName ! = null )
{
if ( ! regionName . Contains ( "@" ) )
2010-03-26 20:13:33 +00:00
{
2010-04-27 02:48:49 +00:00
List < GridRegion > regions = m_GridService . GetRegionsByName ( scopeID , regionName , 1 ) ;
2009-12-31 19:42:33 +00:00
if ( ( regions = = null ) | | ( regions ! = null & & regions . Count = = 0 ) )
{
2010-01-13 23:28:46 +00:00
m_log . InfoFormat ( "[LLLOGIN SERVICE]: Got Custom Login URI {0}, can't locate region {1}. Trying defaults." , startLocation , regionName ) ;
2010-04-27 02:48:49 +00:00
regions = m_GridService . GetDefaultRegions ( scopeID ) ;
2010-01-13 23:28:46 +00:00
if ( regions ! = null & & regions . Count > 0 )
{
where = "safe" ;
return regions [ 0 ] ;
}
else
{
m_log . InfoFormat ( "[LLLOGIN SERVICE]: Got Custom Login URI {0}, Grid does not provide default regions." , startLocation ) ;
return null ;
}
2009-12-31 19:42:33 +00:00
}
return regions [ 0 ] ;
}
else
2010-03-26 20:13:33 +00:00
{
2010-01-29 03:19:42 +00:00
if ( m_UserAgentService = = null )
{
m_log . WarnFormat ( "[LLLOGIN SERVICE]: This llogin service is not running a user agent service, as such it can't lauch agents at foreign grids" ) ;
return null ;
}
2009-12-31 19:42:33 +00:00
string [ ] parts = regionName . Split ( new char [ ] { '@' } ) ;
if ( parts . Length < 2 )
{
m_log . InfoFormat ( "[LLLOGIN SERVICE]: Got Custom Login URI {0}, can't locate region {1}" , startLocation , regionName ) ;
return null ;
}
2010-03-26 20:13:33 +00:00
// Valid specification of a remote grid
2010-03-26 19:16:41 +00:00
2009-12-31 19:42:33 +00:00
regionName = parts [ 0 ] ;
string domainLocator = parts [ 1 ] ;
parts = domainLocator . Split ( new char [ ] { ':' } ) ;
string domainName = parts [ 0 ] ;
uint port = 0 ;
if ( parts . Length > 1 )
UInt32 . TryParse ( parts [ 1 ] , out port ) ;
2010-03-26 19:16:41 +00:00
2010-01-29 03:19:42 +00:00
GridRegion region = FindForeignRegion ( domainName , port , regionName , out gatekeeper ) ;
2009-12-31 19:42:33 +00:00
return region ;
}
}
else
{
2010-04-27 02:48:49 +00:00
List < GridRegion > defaults = m_GridService . GetDefaultRegions ( scopeID ) ;
2010-01-13 23:28:46 +00:00
if ( defaults ! = null & & defaults . Count > 0 )
{
where = "safe" ;
return defaults [ 0 ] ;
}
else
return null ;
2009-12-31 19:42:33 +00:00
}
}
//response.LookAt = "[r0,r1,r0]";
//// can be: last, home, safe, url
//response.StartLocation = "url";
}
}
2009-12-31 22:59:26 +00:00
2010-01-29 03:19:42 +00:00
private GridRegion FindForeignRegion ( string domainName , uint port , string regionName , out GridRegion gatekeeper )
{
gatekeeper = new GridRegion ( ) ;
gatekeeper . ExternalHostName = domainName ;
gatekeeper . HttpPort = port ;
gatekeeper . RegionName = regionName ;
2010-01-31 00:09:40 +00:00
gatekeeper . InternalEndPoint = new IPEndPoint ( IPAddress . Parse ( "0.0.0.0" ) , 0 ) ;
2010-01-29 03:19:42 +00:00
UUID regionID ;
ulong handle ;
string imageURL = string . Empty , reason = string . Empty ;
if ( m_GatekeeperConnector . LinkRegion ( gatekeeper , out regionID , out handle , out domainName , out imageURL , out reason ) )
{
GridRegion destination = m_GatekeeperConnector . GetHyperlinkRegion ( gatekeeper , regionID ) ;
return destination ;
}
return null ;
}
private string hostName = string . Empty ;
private int port = 0 ;
private void SetHostAndPort ( string url )
{
try
{
Uri uri = new Uri ( url ) ;
hostName = uri . Host ;
port = uri . Port ;
}
catch
{
m_log . WarnFormat ( "[LLLogin SERVICE]: Unable to parse GatekeeperURL {0}" , url ) ;
}
}
2010-03-10 12:44:53 +00:00
protected AgentCircuitData LaunchAgentAtGrid ( GridRegion gatekeeper , GridRegion destination , UserAccount account , AvatarData avatar ,
2010-01-29 03:19:42 +00:00
UUID session , UUID secureSession , Vector3 position , string currentWhere , out string where , out string reason )
2009-12-31 22:59:26 +00:00
{
2010-01-29 03:19:42 +00:00
where = currentWhere ;
ISimulationService simConnector = null ;
2009-12-31 22:59:26 +00:00
reason = string . Empty ;
2010-01-29 03:19:42 +00:00
uint circuitCode = 0 ;
AgentCircuitData aCircuit = null ;
if ( m_UserAgentService = = null )
{
// HG standalones have both a localSimulatonDll and a remoteSimulationDll
// non-HG standalones have just a localSimulationDll
// independent login servers have just a remoteSimulationDll
if ( m_LocalSimulationService ! = null )
simConnector = m_LocalSimulationService ;
else if ( m_RemoteSimulationService ! = null )
simConnector = m_RemoteSimulationService ;
}
else // User Agent Service is on
{
if ( gatekeeper = = null ) // login to local grid
{
if ( hostName = = string . Empty )
SetHostAndPort ( m_GatekeeperURL ) ;
gatekeeper = new GridRegion ( destination ) ;
gatekeeper . ExternalHostName = hostName ;
gatekeeper . HttpPort = ( uint ) port ;
}
else // login to foreign grid
{
}
}
bool success = false ;
if ( m_UserAgentService = = null & & simConnector ! = null )
{
circuitCode = ( uint ) Util . RandomClass . Next ( ) ; ;
aCircuit = MakeAgent ( destination , account , avatar , session , secureSession , circuitCode , position ) ;
success = LaunchAgentDirectly ( simConnector , destination , aCircuit , out reason ) ;
if ( ! success & & m_GridService ! = null )
{
// Try the fallback regions
List < GridRegion > fallbacks = m_GridService . GetFallbackRegions ( account . ScopeID , destination . RegionLocX , destination . RegionLocY ) ;
if ( fallbacks ! = null )
{
foreach ( GridRegion r in fallbacks )
{
success = LaunchAgentDirectly ( simConnector , r , aCircuit , out reason ) ;
if ( success )
{
where = "safe" ;
destination = r ;
break ;
}
}
}
}
}
if ( m_UserAgentService ! = null )
{
circuitCode = ( uint ) Util . RandomClass . Next ( ) ; ;
aCircuit = MakeAgent ( destination , account , avatar , session , secureSession , circuitCode , position ) ;
success = LaunchAgentIndirectly ( gatekeeper , destination , aCircuit , out reason ) ;
if ( ! success & & m_GridService ! = null )
{
// Try the fallback regions
List < GridRegion > fallbacks = m_GridService . GetFallbackRegions ( account . ScopeID , destination . RegionLocX , destination . RegionLocY ) ;
if ( fallbacks ! = null )
{
foreach ( GridRegion r in fallbacks )
{
success = LaunchAgentIndirectly ( gatekeeper , r , aCircuit , out reason ) ;
if ( success )
{
where = "safe" ;
destination = r ;
break ;
}
}
}
}
}
if ( success )
return aCircuit ;
else
return null ;
}
private AgentCircuitData MakeAgent ( GridRegion region , UserAccount account ,
AvatarData avatar , UUID session , UUID secureSession , uint circuit , Vector3 position )
{
2009-12-31 22:59:26 +00:00
AgentCircuitData aCircuit = new AgentCircuitData ( ) ;
2010-01-01 01:18:55 +00:00
2009-12-31 22:59:26 +00:00
aCircuit . AgentID = account . PrincipalID ;
2010-01-03 00:26:40 +00:00
if ( avatar ! = null )
2010-01-12 01:30:05 +00:00
aCircuit . Appearance = avatar . ToAvatarAppearance ( account . PrincipalID ) ;
2010-01-13 18:20:02 +00:00
else
aCircuit . Appearance = new AvatarAppearance ( account . PrincipalID ) ;
2009-12-31 22:59:26 +00:00
//aCircuit.BaseFolder = irrelevant
2010-01-01 01:18:55 +00:00
aCircuit . CapsPath = CapsUtil . GetRandomCapsObjectPath ( ) ;
2010-01-03 00:26:40 +00:00
aCircuit . child = false ; // the first login agent is root
2010-01-03 19:44:57 +00:00
aCircuit . ChildrenCapSeeds = new Dictionary < ulong , string > ( ) ;
2010-01-01 01:18:55 +00:00
aCircuit . circuitcode = circuit ;
2009-12-31 22:59:26 +00:00
aCircuit . firstname = account . FirstName ;
//aCircuit.InventoryFolder = irrelevant
aCircuit . lastname = account . LastName ;
2010-01-01 01:18:55 +00:00
aCircuit . SecureSessionID = secureSession ;
2009-12-31 22:59:26 +00:00
aCircuit . SessionID = session ;
2010-01-01 01:18:55 +00:00
aCircuit . startpos = position ;
2010-01-17 19:33:47 +00:00
SetServiceURLs ( aCircuit , account ) ;
2010-01-01 01:18:55 +00:00
2010-01-29 03:19:42 +00:00
return aCircuit ;
2009-12-31 22:59:26 +00:00
2010-01-29 03:19:42 +00:00
//m_UserAgentService.LoginAgentToGrid(aCircuit, GatekeeperServiceConnector, region, out reason);
//if (simConnector.CreateAgent(region, aCircuit, 0, out reason))
// return aCircuit;
//return null;
2009-12-31 22:59:26 +00:00
}
2010-01-11 04:17:37 +00:00
2010-01-17 19:33:47 +00:00
private void SetServiceURLs ( AgentCircuitData aCircuit , UserAccount account )
{
aCircuit . ServiceURLs = new Dictionary < string , object > ( ) ;
if ( account . ServiceURLs = = null )
return ;
foreach ( KeyValuePair < string , object > kvp in account . ServiceURLs )
{
if ( kvp . Value = = null | | ( kvp . Value ! = null & & kvp . Value . ToString ( ) = = string . Empty ) )
{
aCircuit . ServiceURLs [ kvp . Key ] = m_LoginServerConfig . GetString ( kvp . Key , string . Empty ) ;
}
else
{
aCircuit . ServiceURLs [ kvp . Key ] = kvp . Value ;
}
}
}
2010-01-29 03:19:42 +00:00
private bool LaunchAgentDirectly ( ISimulationService simConnector , GridRegion region , AgentCircuitData aCircuit , out string reason )
{
return simConnector . CreateAgent ( region , aCircuit , ( int ) Constants . TeleportFlags . ViaLogin , out reason ) ;
}
private bool LaunchAgentIndirectly ( GridRegion gatekeeper , GridRegion destination , AgentCircuitData aCircuit , out string reason )
{
2010-02-26 00:11:04 +00:00
m_log . Debug ( "[LLOGIN SERVICE] Launching agent at " + destination . RegionName ) ;
2010-01-29 03:19:42 +00:00
return m_UserAgentService . LoginAgentToGrid ( aCircuit , gatekeeper , destination , out reason ) ;
}
2010-01-11 04:17:37 +00:00
#region Console Commands
private void RegisterCommands ( )
{
//MainConsole.Instance.Commands.AddCommand
MainConsole . Instance . Commands . AddCommand ( "loginservice" , false , "login level" ,
"login level <level>" ,
"Set the minimum user level to log in" , HandleLoginCommand ) ;
MainConsole . Instance . Commands . AddCommand ( "loginservice" , false , "login reset" ,
"login reset" ,
"Reset the login level to allow all users" ,
HandleLoginCommand ) ;
MainConsole . Instance . Commands . AddCommand ( "loginservice" , false , "login text" ,
"login text <text>" ,
"Set the text users will see on login" , HandleLoginCommand ) ;
}
private void HandleLoginCommand ( string module , string [ ] cmd )
{
string subcommand = cmd [ 1 ] ;
switch ( subcommand )
{
case "level" :
// Set the minimum level to allow login
// Useful to allow grid update without worrying about users.
// or fixing critical issues
/ /
if ( cmd . Length > 2 )
Int32 . TryParse ( cmd [ 2 ] , out m_MinLoginLevel ) ;
break ;
case "reset" :
m_MinLoginLevel = 0 ;
break ;
case "text" :
if ( cmd . Length > 2 )
m_WelcomeMessage = cmd [ 2 ] ;
break ;
}
}
2009-12-31 05:00:16 +00:00
}
2010-01-11 04:17:37 +00:00
# endregion
2009-12-31 05:00:16 +00:00
}