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("passwd") && requestData["passwd"] != null)
{
string first = requestData["first"].ToString();
string last = requestData["last"].ToString();
string passwd = requestData["passwd"].ToString();
string startLocation = string.Empty;
if (requestData.ContainsKey("start"))
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;
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();
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);
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();
}

View File

@ -28,6 +28,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using OpenMetaverse.StructuredData;
@ -45,7 +46,7 @@ namespace OpenSim.Services.Interfaces
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.Collections;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
using OpenSim.Framework;
using OpenSim.Framework.Capabilities;
using OpenSim.Services.Interfaces;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
using log4net;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
namespace OpenSim.Services.LLLoginService
{
@ -202,6 +210,132 @@ namespace OpenSim.Services.LLLoginService
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()
{
DST = TimeZone.CurrentTimeZone.IsDaylightSavingTime(DateTime.Now) ? "Y" : "N";
@ -465,6 +599,97 @@ namespace OpenSim.Services.LLLoginService
// 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
public string Login

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
using System.Text.RegularExpressions;
@ -8,6 +9,7 @@ using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Capabilities;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
@ -27,6 +29,8 @@ namespace OpenSim.Services.LLLoginService
private string m_DefaultRegionName;
private string m_RemoteSimulationDll;
private string m_WelcomeMessage;
private bool m_RequireInventory;
public LLLoginService(IConfigSource config, ISimulationService simService)
{
@ -42,6 +46,8 @@ namespace OpenSim.Services.LLLoginService
m_DefaultRegionName = serverConfig.GetString("DefaultRegion", 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
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;
// Get the account and check that it exists
UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, firstName, lastName);
if (account == null)
{
m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: user not found");
return LLFailedLoginResponse.UserProblem;
}
// Authenticate this user
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;
}
// Get the user's inventory
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;
}
// Login the presence
// We may want to check for user already logged in, to
// stay compatible with what people expect...
UUID session = UUID.Random();
PresenceInfo presence = null;
GridRegion home = null;
if (m_PresenceService != null)
{
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)
{
home = m_GridService.GetRegionByUUID(account.ScopeID, presence.HomeRegionID);
}
}
// Find the destination region/grid
string where = string.Empty;
Vector3 position = 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)
{
m_PresenceService.LogoutAgent(session);
m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: destination not found");
return LLFailedLoginResponse.GridProblem;
}
// Instantiate/get the simulation interface and launch an agent at the destination
ISimulationService simConnector = null;
success = false;
string reason = string.Empty;
uint circuitCode = 0;
AgentCircuitData aCircuit = null;
Object[] args = new Object[] { destination };
// HG standalones have both a localSimulatonDll and a remoteSimulationDll
// non-HG standalones have just a localSimulationDll
@ -117,20 +149,27 @@ namespace OpenSim.Services.LLLoginService
else if (m_RemoteSimulationDll != string.Empty)
simConnector = ServerUtils.LoadPlugin<ISimulationService>(m_RemoteSimulationDll, args);
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_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: {0}", reason);
return LLFailedLoginResponse.GridProblem;
}
// TODO: Get Friends list...
// 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;
}
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";
position = new Vector3(128, 128, 0);
@ -141,12 +180,11 @@ namespace OpenSim.Services.LLLoginService
if (m_PresenceService == null || m_GridService == 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)
return null;
GridRegion region = null;
if (pinfo.HomeRegionID.Equals(UUID.Zero))
region = m_GridService.GetRegionByName(account.ScopeID, m_DefaultRegionName);
else
@ -161,12 +199,11 @@ namespace OpenSim.Services.LLLoginService
if (m_PresenceService == null || m_GridService == 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)
return null;
GridRegion region = null;
if (pinfo.RegionID.Equals(UUID.Zero))
region = m_GridService.GetRegionByName(account.ScopeID, m_DefaultRegionName);
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;
AgentCircuitData aCircuit = new AgentCircuitData();
aCircuit.AgentID = account.PrincipalID;
//aCircuit.Appearance = optional
//aCircuit.BaseFolder = irrelevant
//aCircuit.CapsPath = required
aCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
aCircuit.child = false;
//aCircuit.circuitcode = required
aCircuit.circuitcode = circuit;
aCircuit.firstname = account.FirstName;
//aCircuit.InventoryFolder = irrelevant
aCircuit.lastname = account.LastName;
//aCircuit.SecureSessionID = required
aCircuit.SecureSessionID = secureSession;
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>
<Reference name="System"/>
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Capabilities"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Services.Interfaces"/>
<Reference name="OpenSim.Services.Base"/>