A lot more beef on the login service. The LLLoginResponse is a MONSTER! Almost done...

slimupdates
Diva Canto 2009-12-31 17:18:55 -08:00
parent 0ce9be653d
commit 130c80efe0
5 changed files with 303 additions and 24 deletions

View File

@ -68,12 +68,22 @@ namespace OpenSim.Server.Handlers.Login
requestData.ContainsKey("last") && requestData["last"] != null && requestData.ContainsKey("last") && requestData["last"] != null &&
requestData.ContainsKey("passwd") && requestData["passwd"] != null) requestData.ContainsKey("passwd") && requestData["passwd"] != null)
{ {
string first = requestData["first"].ToString();
string last = requestData["last"].ToString();
string passwd = requestData["passwd"].ToString();
string startLocation = string.Empty; string startLocation = string.Empty;
if (requestData.ContainsKey("start")) if (requestData.ContainsKey("start"))
startLocation = requestData["start"].ToString(); startLocation = requestData["start"].ToString();
string clientVersion = "Unknown";
if (requestData.Contains("version"))
clientVersion = requestData["version"].ToString();
// We should do something interesting with the client version...
m_log.InfoFormat("[LOGIN]: XMLRPC Login Requested for {0} {1}, starting in {2}, using {3}", first, last, startLocation, clientVersion);
LoginResponse reply = null; LoginResponse reply = null;
reply = m_LocalService.Login(requestData["first"].ToString(), requestData["last"].ToString(), requestData["passwd"].ToString(), startLocation); reply = m_LocalService.Login(first, last, passwd, startLocation, remoteClient);
XmlRpcResponse response = new XmlRpcResponse(); XmlRpcResponse response = new XmlRpcResponse();
response.Value = reply.ToHashtable(); response.Value = reply.ToHashtable();
@ -102,7 +112,7 @@ namespace OpenSim.Server.Handlers.Login
m_log.Info("[LOGIN]: LLSD Login Requested for: '" + map["first"].AsString() + "' '" + map["last"].AsString() + "' / " + startLocation); m_log.Info("[LOGIN]: LLSD Login Requested for: '" + map["first"].AsString() + "' '" + map["last"].AsString() + "' / " + startLocation);
LoginResponse reply = null; LoginResponse reply = null;
reply = m_LocalService.Login(map["first"].AsString(), map["last"].AsString(), map["passwd"].AsString(), startLocation); reply = m_LocalService.Login(map["first"].AsString(), map["last"].AsString(), map["passwd"].AsString(), startLocation, remoteClient);
return reply.ToOSDMap(); return reply.ToOSDMap();
} }

View File

@ -28,6 +28,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
@ -45,7 +46,7 @@ namespace OpenSim.Services.Interfaces
public interface ILoginService public interface ILoginService
{ {
LoginResponse Login(string firstName, string lastName, string passwd, string startLocation); LoginResponse Login(string firstName, string lastName, string passwd, string startLocation, IPEndPoint clientIP);
} }

View File

@ -28,11 +28,19 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net;
using System.Reflection; using System.Reflection;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Capabilities;
using OpenSim.Services.Interfaces;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
using log4net; using log4net;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
namespace OpenSim.Services.LLLoginService namespace OpenSim.Services.LLLoginService
{ {
@ -202,6 +210,132 @@ namespace OpenSim.Services.LLLoginService
SetDefaultValues(); SetDefaultValues();
} }
public LLLoginResponse(UserAccount account, AgentCircuitData aCircuit, PresenceInfo pinfo,
GridRegion destination, List<InventoryFolderBase> invSkel,
string where, string startlocation, Vector3 position, Vector3 lookAt, string message,
GridRegion home, IPEndPoint clientIP)
: this()
{
FillOutInventoryData(invSkel);
CircuitCode = (int)aCircuit.circuitcode;
Lastname = account.LastName;
Firstname = account.FirstName;
AgentID = account.PrincipalID;
SessionID = aCircuit.SessionID;
SecureSessionID = aCircuit.SecureSessionID;
Message = message;
// While we don't have friends...
//BuddList = ConvertFriendListItem(m_userManager.GetUserFriendList(agentID));
BuddList = new LLLoginResponse.BuddyList();
StartLocation = where;
FillOutHomeData(pinfo, home);
LookAt = String.Format("[r{0},r{1},r{2}]", lookAt.X, lookAt.Y, lookAt.Z);
FillOutRegionData(destination);
FillOutSeedCap(aCircuit, destination, clientIP);
}
private void FillOutInventoryData(List<InventoryFolderBase> invSkel)
{
InventoryData inventData = null;
try
{
inventData = GetInventorySkeleton(invSkel);
}
catch (Exception e)
{
m_log.WarnFormat(
"[LLLOGIN SERVICE]: Error processing inventory skeleton of agent {0} - {1}",
agentID, e);
// ignore and continue
}
if (inventData != null)
{
ArrayList AgentInventoryArray = inventData.InventoryArray;
Hashtable InventoryRootHash = new Hashtable();
InventoryRootHash["folder_id"] = inventData.RootFolderID.ToString();
InventoryRoot = new ArrayList();
InventoryRoot.Add(InventoryRootHash);
InventorySkeleton = AgentInventoryArray;
}
// Inventory Library Section
Hashtable InventoryLibRootHash = new Hashtable();
InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000";
InventoryLibRoot = new ArrayList();
InventoryLibRoot.Add(InventoryLibRootHash);
InventoryLibraryOwner = GetLibraryOwner();
InventoryLibrary = GetInventoryLibrary();
}
private void FillOutHomeData(PresenceInfo pinfo, GridRegion home)
{
int x = 1000 * (int)Constants.RegionSize, y = 1000 * (int)Constants.RegionSize;
if (home != null)
{
x = home.RegionLocX;
y = home.RegionLocY;
}
Home = string.Format(
"{{'region_handle':[r{0},r{1}], 'position':[r{2},r{3},r{4}], 'look_at':[r{5},r{6},r{7}]}}",
home.RegionLocX,
home.RegionLocY,
pinfo.HomePosition.X, pinfo.HomePosition.Y, pinfo.HomePosition.Z,
pinfo.HomeLookAt.X, pinfo.HomeLookAt.Y, pinfo.HomeLookAt.Z);
}
private void FillOutRegionData(GridRegion destination)
{
IPEndPoint endPoint = destination.ExternalEndPoint;
SimAddress = endPoint.Address.ToString();
SimPort = (uint)endPoint.Port;
RegionX = (uint)destination.RegionLocX;
RegionY = (uint)destination.RegionLocY;
}
private void FillOutSeedCap(AgentCircuitData aCircuit, GridRegion destination, IPEndPoint ipepClient)
{
string capsSeedPath = String.Empty;
// Don't use the following! It Fails for logging into any region not on the same port as the http server!
// Kept here so it doesn't happen again!
// response.SeedCapability = regionInfo.ServerURI + capsSeedPath;
#region IP Translation for NAT
if (ipepClient != null)
{
capsSeedPath
= "http://"
+ NetworkUtil.GetHostFor(ipepClient.Address, destination.ExternalHostName)
+ ":"
+ destination.HttpPort
+ CapsUtil.GetCapsSeedPath(aCircuit.CapsPath);
}
else
{
capsSeedPath
= "http://"
+ destination.ExternalHostName
+ ":"
+ destination.HttpPort
+ CapsUtil.GetCapsSeedPath(aCircuit.CapsPath);
}
#endregion
SeedCapability = capsSeedPath;
}
private void SetDefaultValues() private void SetDefaultValues()
{ {
DST = TimeZone.CurrentTimeZone.IsDaylightSavingTime(DateTime.Now) ? "Y" : "N"; DST = TimeZone.CurrentTimeZone.IsDaylightSavingTime(DateTime.Now) ? "Y" : "N";
@ -465,6 +599,97 @@ namespace OpenSim.Services.LLLoginService
// this.classifiedCategoriesHash.Clear(); // this.classifiedCategoriesHash.Clear();
} }
private static LLLoginResponse.BuddyList ConvertFriendListItem(List<FriendListItem> LFL)
{
LLLoginResponse.BuddyList buddylistreturn = new LLLoginResponse.BuddyList();
foreach (FriendListItem fl in LFL)
{
LLLoginResponse.BuddyList.BuddyInfo buddyitem = new LLLoginResponse.BuddyList.BuddyInfo(fl.Friend);
buddyitem.BuddyID = fl.Friend;
buddyitem.BuddyRightsHave = (int)fl.FriendListOwnerPerms;
buddyitem.BuddyRightsGiven = (int)fl.FriendPerms;
buddylistreturn.AddNewBuddy(buddyitem);
}
return buddylistreturn;
}
private InventoryData GetInventorySkeleton(List<InventoryFolderBase> folders)
{
UUID rootID = UUID.Zero;
ArrayList AgentInventoryArray = new ArrayList();
Hashtable TempHash;
foreach (InventoryFolderBase InvFolder in folders)
{
if (InvFolder.ParentID == UUID.Zero)
{
rootID = InvFolder.ID;
}
TempHash = new Hashtable();
TempHash["name"] = InvFolder.Name;
TempHash["parent_id"] = InvFolder.ParentID.ToString();
TempHash["version"] = (Int32)InvFolder.Version;
TempHash["type_default"] = (Int32)InvFolder.Type;
TempHash["folder_id"] = InvFolder.ID.ToString();
AgentInventoryArray.Add(TempHash);
}
return new InventoryData(AgentInventoryArray, rootID);
}
/// <summary>
/// Converts the inventory library skeleton into the form required by the rpc request.
/// </summary>
/// <returns></returns>
protected virtual ArrayList GetInventoryLibrary()
{
// While we don't have library...
//Dictionary<UUID, InventoryFolderImpl> rootFolders
// = m_libraryRootFolder.RequestSelfAndDescendentFolders();
Dictionary<UUID, InventoryFolderImpl> rootFolders = new Dictionary<UUID,InventoryFolderImpl>();
ArrayList folderHashes = new ArrayList();
foreach (InventoryFolderBase folder in rootFolders.Values)
{
Hashtable TempHash = new Hashtable();
TempHash["name"] = folder.Name;
TempHash["parent_id"] = folder.ParentID.ToString();
TempHash["version"] = (Int32)folder.Version;
TempHash["type_default"] = (Int32)folder.Type;
TempHash["folder_id"] = folder.ID.ToString();
folderHashes.Add(TempHash);
}
return folderHashes;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
protected virtual ArrayList GetLibraryOwner()
{
//for now create random inventory library owner
Hashtable TempHash = new Hashtable();
TempHash["agent_id"] = "11111111-1111-0000-0000-000100bba000";
ArrayList inventoryLibOwner = new ArrayList();
inventoryLibOwner.Add(TempHash);
return inventoryLibOwner;
}
public class InventoryData
{
public ArrayList InventoryArray = null;
public UUID RootFolderID = UUID.Zero;
public InventoryData(ArrayList invList, UUID rootID)
{
InventoryArray = invList;
RootFolderID = rootID;
}
}
#region Properties #region Properties
public string Login public string Login

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net;
using System.Reflection; using System.Reflection;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@ -8,6 +9,7 @@ using Nini.Config;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Capabilities;
using OpenSim.Server.Base; using OpenSim.Server.Base;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using GridRegion = OpenSim.Services.Interfaces.GridRegion; using GridRegion = OpenSim.Services.Interfaces.GridRegion;
@ -27,6 +29,8 @@ namespace OpenSim.Services.LLLoginService
private string m_DefaultRegionName; private string m_DefaultRegionName;
private string m_RemoteSimulationDll; private string m_RemoteSimulationDll;
private string m_WelcomeMessage;
private bool m_RequireInventory;
public LLLoginService(IConfigSource config, ISimulationService simService) public LLLoginService(IConfigSource config, ISimulationService simService)
{ {
@ -42,6 +46,8 @@ namespace OpenSim.Services.LLLoginService
m_DefaultRegionName = serverConfig.GetString("DefaultRegion", String.Empty); m_DefaultRegionName = serverConfig.GetString("DefaultRegion", String.Empty);
m_RemoteSimulationDll = serverConfig.GetString("RemoteSimulationService", String.Empty); m_RemoteSimulationDll = serverConfig.GetString("RemoteSimulationService", String.Empty);
m_WelcomeMessage = serverConfig.GetString("WelcomeMessage", "Welcome to OpenSim!");
m_RequireInventory = serverConfig.GetBoolean("RequireInventory", true);
// These 3 are required; the other 2 aren't // These 3 are required; the other 2 aren't
if (accountService == string.Empty || authService == string.Empty || if (accountService == string.Empty || authService == string.Empty ||
@ -64,50 +70,76 @@ namespace OpenSim.Services.LLLoginService
{ {
} }
public LoginResponse Login(string firstName, string lastName, string passwd, string startLocation) public LoginResponse Login(string firstName, string lastName, string passwd, string startLocation, IPEndPoint clientIP)
{ {
bool success = false; bool success = false;
// Get the account and check that it exists // Get the account and check that it exists
UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, firstName, lastName); UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, firstName, lastName);
if (account == null) if (account == null)
{
m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: user not found");
return LLFailedLoginResponse.UserProblem; return LLFailedLoginResponse.UserProblem;
}
// Authenticate this user // Authenticate this user
string token = m_AuthenticationService.Authenticate(account.PrincipalID, passwd, 30); string token = m_AuthenticationService.Authenticate(account.PrincipalID, passwd, 30);
UUID secureSession = UUID.Zero; UUID secureSession = UUID.Zero;
if ((token == string.Empty) || (token != string.Empty && !UUID.TryParse(token, out secureSession))) 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; return LLFailedLoginResponse.UserProblem;
}
// Get the user's inventory // Get the user's inventory
List<InventoryFolderBase> inventorySkel = m_InventoryService.GetInventorySkeleton(account.PrincipalID); List<InventoryFolderBase> inventorySkel = m_InventoryService.GetInventorySkeleton(account.PrincipalID);
if ((inventorySkel == null) || (inventorySkel != null && inventorySkel.Count == 0)) 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; return LLFailedLoginResponse.InventoryProblem;
}
// Login the presence // Login the presence
// We may want to check for user already logged in, to
// stay compatible with what people expect...
UUID session = UUID.Random(); UUID session = UUID.Random();
PresenceInfo presence = null;
GridRegion home = null;
if (m_PresenceService != null) if (m_PresenceService != null)
{ {
success = m_PresenceService.LoginAgent(account.PrincipalID.ToString(), session, secureSession); success = m_PresenceService.LoginAgent(account.PrincipalID.ToString(), session, secureSession);
if (!success) if (!success)
{
m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: could not login presence");
return LLFailedLoginResponse.GridProblem; 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)
{
home = m_GridService.GetRegionByUUID(account.ScopeID, presence.HomeRegionID);
}
}
// Find the destination region/grid // Find the destination region/grid
string where = string.Empty; string where = string.Empty;
Vector3 position = Vector3.Zero; Vector3 position = Vector3.Zero;
Vector3 lookAt = Vector3.Zero; Vector3 lookAt = Vector3.Zero;
GridRegion destination = FindDestination(account, session, startLocation, out where, out position, out lookAt); GridRegion destination = FindDestination(account, presence, session, startLocation, out where, out position, out lookAt);
if (destination == null) if (destination == null)
{ {
m_PresenceService.LogoutAgent(session); m_PresenceService.LogoutAgent(session);
m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: destination not found");
return LLFailedLoginResponse.GridProblem; return LLFailedLoginResponse.GridProblem;
} }
// Instantiate/get the simulation interface and launch an agent at the destination // Instantiate/get the simulation interface and launch an agent at the destination
ISimulationService simConnector = null; ISimulationService simConnector = null;
success = false;
string reason = string.Empty; string reason = string.Empty;
uint circuitCode = 0;
AgentCircuitData aCircuit = null;
Object[] args = new Object[] { destination }; Object[] args = new Object[] { destination };
// HG standalones have both a localSimulatonDll and a remoteSimulationDll // HG standalones have both a localSimulatonDll and a remoteSimulationDll
// non-HG standalones have just a localSimulationDll // non-HG standalones have just a localSimulationDll
@ -117,20 +149,27 @@ namespace OpenSim.Services.LLLoginService
else if (m_RemoteSimulationDll != string.Empty) else if (m_RemoteSimulationDll != string.Empty)
simConnector = ServerUtils.LoadPlugin<ISimulationService>(m_RemoteSimulationDll, args); simConnector = ServerUtils.LoadPlugin<ISimulationService>(m_RemoteSimulationDll, args);
if (simConnector != null) if (simConnector != null)
success = LaunchAgent(simConnector, destination, account, session, out reason); {
if (!success) circuitCode = (uint)Util.RandomClass.Next(); ;
aCircuit = LaunchAgent(simConnector, destination, account, session, secureSession, circuitCode, position, out reason);
}
if (aCircuit == null)
{ {
m_PresenceService.LogoutAgent(session); m_PresenceService.LogoutAgent(session);
m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: {0}", reason);
return LLFailedLoginResponse.GridProblem; return LLFailedLoginResponse.GridProblem;
} }
// TODO: Get Friends list...
// Finally, fill out the response and return it // Finally, fill out the response and return it
LLLoginResponse response = new LLLoginResponse(); LLLoginResponse response = new LLLoginResponse(account, aCircuit, presence, destination, inventorySkel,
//.... where, startLocation, position, lookAt, m_WelcomeMessage, home, clientIP);
return response; return response;
} }
private GridRegion FindDestination(UserAccount account, UUID sessionID, string startLocation, out string where, out Vector3 position, out Vector3 lookAt) private GridRegion FindDestination(UserAccount account, PresenceInfo pinfo, UUID sessionID, string startLocation, out string where, out Vector3 position, out Vector3 lookAt)
{ {
where = "home"; where = "home";
position = new Vector3(128, 128, 0); position = new Vector3(128, 128, 0);
@ -141,12 +180,11 @@ namespace OpenSim.Services.LLLoginService
if (m_PresenceService == null || m_GridService == null) if (m_PresenceService == null || m_GridService == null)
return null; return null;
GridRegion region = null;
PresenceInfo pinfo = m_PresenceService.GetAgent(sessionID);
// this should succeed; if it doesn't there's something wrong with this grid
if (pinfo == null) if (pinfo == null)
return null; return null;
GridRegion region = null;
if (pinfo.HomeRegionID.Equals(UUID.Zero)) if (pinfo.HomeRegionID.Equals(UUID.Zero))
region = m_GridService.GetRegionByName(account.ScopeID, m_DefaultRegionName); region = m_GridService.GetRegionByName(account.ScopeID, m_DefaultRegionName);
else else
@ -161,12 +199,11 @@ namespace OpenSim.Services.LLLoginService
if (m_PresenceService == null || m_GridService == null) if (m_PresenceService == null || m_GridService == null)
return null; return null;
GridRegion region = null;
PresenceInfo pinfo = m_PresenceService.GetAgent(sessionID);
// this should succeed; if it doesn't there's something wrong with this grid
if (pinfo == null) if (pinfo == null)
return null; return null;
GridRegion region = null;
if (pinfo.RegionID.Equals(UUID.Zero)) if (pinfo.RegionID.Equals(UUID.Zero))
region = m_GridService.GetRegionByName(account.ScopeID, m_DefaultRegionName); region = m_GridService.GetRegionByName(account.ScopeID, m_DefaultRegionName);
else else
@ -250,24 +287,29 @@ namespace OpenSim.Services.LLLoginService
} }
private bool LaunchAgent(ISimulationService simConnector, GridRegion region, UserAccount account, UUID session, out string reason) private AgentCircuitData LaunchAgent(ISimulationService simConnector, GridRegion region, UserAccount account,
UUID session, UUID secureSession, uint circuit, Vector3 position, out string reason)
{ {
reason = string.Empty; reason = string.Empty;
AgentCircuitData aCircuit = new AgentCircuitData(); AgentCircuitData aCircuit = new AgentCircuitData();
aCircuit.AgentID = account.PrincipalID; aCircuit.AgentID = account.PrincipalID;
//aCircuit.Appearance = optional //aCircuit.Appearance = optional
//aCircuit.BaseFolder = irrelevant //aCircuit.BaseFolder = irrelevant
//aCircuit.CapsPath = required aCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
aCircuit.child = false; aCircuit.child = false;
//aCircuit.circuitcode = required aCircuit.circuitcode = circuit;
aCircuit.firstname = account.FirstName; aCircuit.firstname = account.FirstName;
//aCircuit.InventoryFolder = irrelevant //aCircuit.InventoryFolder = irrelevant
aCircuit.lastname = account.LastName; aCircuit.lastname = account.LastName;
//aCircuit.SecureSessionID = required aCircuit.SecureSessionID = secureSession;
aCircuit.SessionID = session; aCircuit.SessionID = session;
//aCircuit.startpos = required aCircuit.startpos = position;
return simConnector.CreateAgent(region.RegionHandle, aCircuit, 0, out reason); if (simConnector.CreateAgent(region.RegionHandle, aCircuit, 0, out reason))
return aCircuit;
return null;
} }
} }

View File

@ -1494,6 +1494,7 @@
<ReferencePath>../../../bin/</ReferencePath> <ReferencePath>../../../bin/</ReferencePath>
<Reference name="System"/> <Reference name="System"/>
<Reference name="OpenSim.Framework"/> <Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Capabilities"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/> <Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Services.Interfaces"/> <Reference name="OpenSim.Services.Interfaces"/>
<Reference name="OpenSim.Services.Base"/> <Reference name="OpenSim.Services.Base"/>