From 1302ef44e3c632159378bc4042c753bcf36e9c63 Mon Sep 17 00:00:00 2001 From: lbsa71 Date: Mon, 24 Sep 2007 07:30:30 +0000 Subject: * Started major restructusing of comms to prepare for better grid and region functionality * Working towards one shared set of services * Killed off two projects with very little functionality --- OpenSim/Framework/Communications/CAPSService.cs | 38 ++ .../Communications/Cache/AssetTransactions.cs | 2 +- .../Communications/Cache/CachedUserInfo.cs | 6 +- .../Communications/Cache/UserProfileCache.cs | 6 +- .../Communications/CommunicationsManager.cs | 61 +- .../Framework/Communications/IInventoryServices.cs | 8 + OpenSim/Framework/Communications/IUserServices.cs | 5 + .../Communications/InventoryServiceBase.cs | 211 +++++++ OpenSim/Framework/Communications/LoginResponse.cs | 667 +++++++++++++++++++++ OpenSim/Framework/Communications/LoginService.cs | 287 +++++++++ .../Framework/Communications/UserManagerBase.cs | 379 ++++++++++++ 11 files changed, 1629 insertions(+), 41 deletions(-) create mode 100644 OpenSim/Framework/Communications/CAPSService.cs create mode 100644 OpenSim/Framework/Communications/InventoryServiceBase.cs create mode 100644 OpenSim/Framework/Communications/LoginResponse.cs create mode 100644 OpenSim/Framework/Communications/LoginService.cs create mode 100644 OpenSim/Framework/Communications/UserManagerBase.cs (limited to 'OpenSim/Framework/Communications') diff --git a/OpenSim/Framework/Communications/CAPSService.cs b/OpenSim/Framework/Communications/CAPSService.cs new file mode 100644 index 0000000..a8eac26 --- /dev/null +++ b/OpenSim/Framework/Communications/CAPSService.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using System.Security.Cryptography; +using libsecondlife; +using Nwc.XmlRpc; +using OpenSim.Framework.Console; +using OpenSim.Framework.Data; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Inventory; +using OpenSim.Framework.Utilities; +using OpenSim.Framework.Servers; + +namespace OpenSim.Framework.UserManagement +{ + public class CAPSService + { + private BaseHttpServer m_server; + + public CAPSService(BaseHttpServer httpServer) + { + m_server = httpServer; + this.AddCapsSeedHandler("/CapsSeed/", CapsRequest); + } + + private void AddCapsSeedHandler(string path, RestMethod restMethod) + { + m_server.AddStreamHandler(new RestStreamHandler("POST", path, restMethod)); + } + + public string CapsRequest(string request, string path, string param) + { + System.Console.WriteLine("new caps request " + request +" from path "+ path); + return ""; + } + } +} diff --git a/OpenSim/Framework/Communications/Cache/AssetTransactions.cs b/OpenSim/Framework/Communications/Cache/AssetTransactions.cs index 59a9e00..d0507d0 100644 --- a/OpenSim/Framework/Communications/Cache/AssetTransactions.cs +++ b/OpenSim/Framework/Communications/Cache/AssetTransactions.cs @@ -316,7 +316,7 @@ namespace OpenSim.Framework.Communications.Caches { //really need to fix this call, if lbsa71 saw this he would die. this.m_userTransactions.Manager.CommsManager.AssetCache.AddAsset(this.Asset); - CachedUserInfo userInfo = m_userTransactions.Manager.CommsManager.UserProfiles.GetUserDetails(ourClient.AgentId); + CachedUserInfo userInfo = m_userTransactions.Manager.CommsManager.UserProfileCache.GetUserDetails(ourClient.AgentId); if (userInfo != null) { InventoryItemBase item = new InventoryItemBase(); diff --git a/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs b/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs index acdb6db..99dc45a 100644 --- a/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs +++ b/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs @@ -101,7 +101,7 @@ namespace OpenSim.Framework.Communications.Caches if ((userID == this.UserProfile.UUID) && (this.RootFolder != null)) { this.ItemReceive(userID, itemInfo); - this.m_parentCommsManager.InventoryServer.AddNewInventoryItem(userID, itemInfo); + this.m_parentCommsManager.InventoryService.AddNewInventoryItem(userID, itemInfo); } } @@ -109,7 +109,7 @@ namespace OpenSim.Framework.Communications.Caches { if ((userID == this.UserProfile.UUID) && (this.RootFolder != null)) { - this.m_parentCommsManager.InventoryServer.AddNewInventoryItem(userID, itemInfo); + this.m_parentCommsManager.InventoryService.AddNewInventoryItem(userID, itemInfo); } } @@ -121,7 +121,7 @@ namespace OpenSim.Framework.Communications.Caches result = RootFolder.DeleteItem(item.inventoryID); if (result) { - this.m_parentCommsManager.InventoryServer.DeleteInventoryItem(userID, item); + this.m_parentCommsManager.InventoryService.DeleteInventoryItem(userID, item); } } return result; diff --git a/OpenSim/Framework/Communications/Cache/UserProfileCache.cs b/OpenSim/Framework/Communications/Cache/UserProfileCache.cs index 0c8c0f9..390b938 100644 --- a/OpenSim/Framework/Communications/Cache/UserProfileCache.cs +++ b/OpenSim/Framework/Communications/Cache/UserProfileCache.cs @@ -106,7 +106,7 @@ namespace OpenSim.Framework.Communications.Caches InventoryFolder createdFolder = info.RootFolder.CreateNewSubFolder(folderID, folderName, folderType); if (createdFolder != null) { - this.m_parent.InventoryServer.AddNewInventoryFolder(remoteClient.AgentId, createdFolder); + this.m_parent.InventoryService.AddNewInventoryFolder(remoteClient.AgentId, createdFolder); } } else @@ -181,7 +181,7 @@ namespace OpenSim.Framework.Communications.Caches /// private void RequestInventoryForUser(LLUUID userID, CachedUserInfo userInfo) { - this.m_parent.InventoryServer.RequestInventoryForUser(userID, userInfo.FolderReceive, userInfo.ItemReceive); + this.m_parent.InventoryService.RequestInventoryForUser(userID, userInfo.FolderReceive, userInfo.ItemReceive); } /// @@ -190,7 +190,7 @@ namespace OpenSim.Framework.Communications.Caches /// private UserProfileData RequestUserProfileForUser(LLUUID userID) { - return this.m_parent.UserServer.GetUserProfile(userID); + return this.m_parent.UserService.GetUserProfile(userID); } /// diff --git a/OpenSim/Framework/Communications/CommunicationsManager.cs b/OpenSim/Framework/Communications/CommunicationsManager.cs index 2a87306..6ea3c29 100644 --- a/OpenSim/Framework/Communications/CommunicationsManager.cs +++ b/OpenSim/Framework/Communications/CommunicationsManager.cs @@ -37,81 +37,74 @@ namespace OpenSim.Framework.Communications { public class CommunicationsManager { - protected AssetCache m_assetCache; - protected IGridServices m_gridServer; - protected IInterRegionCommunications m_interRegion; - protected IInventoryServices m_inventoryServer; - protected AssetTransactionManager m_transactionsManager; - protected UserProfileCache m_userProfiles; - protected IUserServices m_userServer; - protected NetworkServersInfo m_networkServersInfo; - - public CommunicationsManager(NetworkServersInfo serversInfo, BaseHttpServer httpServer, AssetCache assetCache) - { - m_networkServersInfo = serversInfo; - m_assetCache = assetCache; - m_userProfiles = new UserProfileCache(this); - m_transactionsManager = new AssetTransactionManager(this); - } - - public IUserServices UserServer + protected IUserServices m_userService; + public IUserServices UserService { - get { return m_userServer; } - set { m_userServer = value; } + get { return m_userService; } } - public IGridServices GridServer + protected IGridServices m_gridService; + public IGridServices GridService { - get { return m_gridServer; } + get { return m_gridService; } } - public IInventoryServices InventoryServer + protected IInventoryServices m_inventoryService; + public IInventoryServices InventoryService { - get { return m_inventoryServer; } - set { m_inventoryServer = value; } + get { return m_inventoryService; } } + protected IInterRegionCommunications m_interRegion; public IInterRegionCommunications InterRegion { get { return m_interRegion; } - set { m_interRegion = value; } } - public UserProfileCache UserProfiles + protected UserProfileCache m_userProfileCache; + public UserProfileCache UserProfileCache { - get { return m_userProfiles; } - set { m_userProfiles = value; } + get { return m_userProfileCache; } } + protected AssetTransactionManager m_transactionsManager; public AssetTransactionManager TransactionsManager { get { return m_transactionsManager; } - set { m_transactionsManager = value; } } + protected AssetCache m_assetCache; public AssetCache AssetCache { get { return m_assetCache; } - set { m_assetCache = value; } } + protected NetworkServersInfo m_networkServersInfo; public NetworkServersInfo NetworkServersInfo { get { return m_networkServersInfo; } - set { m_networkServersInfo = value; } } + public CommunicationsManager(NetworkServersInfo serversInfo, BaseHttpServer httpServer, AssetCache assetCache) + { + m_networkServersInfo = serversInfo; + m_assetCache = assetCache; + m_userProfileCache = new UserProfileCache(this); + m_transactionsManager = new AssetTransactionManager(this); + } + + #region Packet Handlers public void HandleUUIDNameRequest(LLUUID uuid, IClientAPI remote_client) { - if (uuid == m_userProfiles.libraryRoot.agentID) + if (uuid == m_userProfileCache.libraryRoot.agentID) { remote_client.SendNameReply(uuid, "Mr", "OpenSim"); } else { - UserProfileData profileData = m_userServer.GetUserProfile(uuid); + UserProfileData profileData = m_userService.GetUserProfile(uuid); if (profileData != null) { LLUUID profileId = profileData.UUID; diff --git a/OpenSim/Framework/Communications/IInventoryServices.cs b/OpenSim/Framework/Communications/IInventoryServices.cs index bd58756..80c2e64 100644 --- a/OpenSim/Framework/Communications/IInventoryServices.cs +++ b/OpenSim/Framework/Communications/IInventoryServices.cs @@ -17,5 +17,13 @@ namespace OpenSim.Framework.Communications void AddNewInventoryFolder(LLUUID userID, InventoryFolder folder); void AddNewInventoryItem(LLUUID userID, InventoryItemBase item); void DeleteInventoryItem(LLUUID userID, InventoryItemBase item); + void CreateNewUserInventory(LLUUID user); + + /// + /// Returns the root folder plus any folders in root (so down one level in the Inventory folders tree) + /// + /// + /// + List RequestFirstLevelFolders(LLUUID userID); } } diff --git a/OpenSim/Framework/Communications/IUserServices.cs b/OpenSim/Framework/Communications/IUserServices.cs index c1bea48..13dd378 100644 --- a/OpenSim/Framework/Communications/IUserServices.cs +++ b/OpenSim/Framework/Communications/IUserServices.cs @@ -40,5 +40,10 @@ namespace OpenSim.Framework.Communications UserProfileData SetupMasterUser(string firstName, string lastName); UserProfileData SetupMasterUser(string firstName, string lastName, string password); + /// + /// + /// + /// + void AddUserProfile(string firstName, string lastName, string pass, uint regX, uint regY); } } diff --git a/OpenSim/Framework/Communications/InventoryServiceBase.cs b/OpenSim/Framework/Communications/InventoryServiceBase.cs new file mode 100644 index 0000000..da7a0ce --- /dev/null +++ b/OpenSim/Framework/Communications/InventoryServiceBase.cs @@ -0,0 +1,211 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using libsecondlife; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Console; +using OpenSim.Framework.Data; +using InventoryFolder=OpenSim.Framework.Communications.Caches.InventoryFolder; + +namespace OpenSim.Framework.Communications +{ + public abstract class InventoryServiceBase : IInventoryServices + { + protected Dictionary m_plugins = new Dictionary(); + //protected IAssetServer m_assetServer; + + public InventoryServiceBase() + { + //m_assetServer = assetServer; + } + + /// + /// Adds a new user server plugin - plugins will be requested in the order they were loaded. + /// + /// The filename to the user server plugin DLL + public void AddPlugin(string FileName) + { + if (!String.IsNullOrEmpty(FileName)) + { + MainLog.Instance.Verbose("Inventory", "Inventorystorage: Attempting to load " + FileName); + Assembly pluginAssembly = Assembly.LoadFrom(FileName); + + foreach (Type pluginType in pluginAssembly.GetTypes()) + { + if (!pluginType.IsAbstract) + { + Type typeInterface = pluginType.GetInterface("IInventoryData", true); + + if (typeInterface != null) + { + IInventoryData plug = + (IInventoryData)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); + plug.Initialise(); + this.m_plugins.Add(plug.getName(), plug); + MainLog.Instance.Verbose("Inventorystorage: Added IInventoryData Interface"); + } + } + } + } + } + + /// + /// Returns the root folder plus any folders in root (so down one level in the Inventory folders tree) + /// + /// + /// + public List RequestFirstLevelFolders(LLUUID userID) + { + List inventoryList = new List(); + foreach (KeyValuePair plugin in m_plugins) + { + InventoryFolderBase rootFolder = plugin.Value.getUserRootFolder(userID); + if (rootFolder != null) + { + inventoryList = plugin.Value.getInventoryFolders(rootFolder.folderID); + inventoryList.Insert(0, rootFolder); + return inventoryList; + } + } + return inventoryList; + } + + /// + /// + /// + public InventoryFolderBase RequestUsersRoot(LLUUID userID) + { + foreach (KeyValuePair plugin in m_plugins) + { + return plugin.Value.getUserRootFolder(userID); + } + return null; + } + + /// + /// + /// + /// + /// + public List RequestSubFolders(LLUUID parentFolderID) + { + List inventoryList = new List(); + foreach (KeyValuePair plugin in m_plugins) + { + return plugin.Value.getInventoryFolders(parentFolderID); + } + return inventoryList; + } + + public List RequestFolderItems(LLUUID folderID) + { + List itemsList = new List(); + foreach (KeyValuePair plugin in m_plugins) + { + itemsList = plugin.Value.getInventoryInFolder(folderID); + return itemsList; + } + return itemsList; + } + + public void AddFolder(InventoryFolderBase folder) + { + foreach (KeyValuePair plugin in m_plugins) + { + plugin.Value.addInventoryFolder(folder); + } + } + + public void AddItem(InventoryItemBase item) + { + foreach (KeyValuePair plugin in m_plugins) + { + plugin.Value.addInventoryItem(item); + } + } + + public void deleteItem(InventoryItemBase item) + { + foreach (KeyValuePair plugin in m_plugins) + { + plugin.Value.deleteInventoryItem(item); + } + } + + /// + /// + /// + /// + public void AddNewInventorySet(UsersInventory inventory) + { + foreach (InventoryFolderBase folder in inventory.Folders.Values) + { + this.AddFolder(folder); + } + } + + public void CreateNewUserInventory(LLUUID user) + { + UsersInventory inven = new UsersInventory(); + inven.CreateNewInventorySet(user); + this.AddNewInventorySet(inven); + } + + public class UsersInventory + { + public Dictionary Folders = new Dictionary(); + public Dictionary Items = new Dictionary(); + + public UsersInventory() + { + + } + + public virtual void CreateNewInventorySet(LLUUID user) + { + InventoryFolderBase folder = new InventoryFolderBase(); + folder.parentID = LLUUID.Zero; + folder.agentID = user; + folder.folderID = LLUUID.Random(); + folder.name = "My Inventory"; + folder.type = 8; + folder.version = 1; + Folders.Add(folder.folderID, folder); + + LLUUID rootFolder = folder.folderID; + + folder = new InventoryFolderBase(); + folder.parentID = rootFolder; + folder.agentID = user; + folder.folderID = LLUUID.Random(); + folder.name = "Textures"; + folder.type = 0; + folder.version = 1; + Folders.Add(folder.folderID, folder); + + folder = new InventoryFolderBase(); + folder.parentID = rootFolder; + folder.agentID = user; + folder.folderID = LLUUID.Random(); + folder.name = "Objects"; + folder.type = 6; + folder.version = 1; + Folders.Add(folder.folderID, folder); + + folder = new InventoryFolderBase(); + folder.parentID = rootFolder; + folder.agentID = user; + folder.folderID = LLUUID.Random(); + folder.name = "Clothes"; + folder.type = 5; + folder.version = 1; + Folders.Add(folder.folderID, folder); + } + } + + public abstract void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack, InventoryItemInfo itemCallBack); + public abstract void AddNewInventoryFolder(LLUUID userID, InventoryFolder folder); + public abstract void AddNewInventoryItem(LLUUID userID, InventoryItemBase item); + public abstract void DeleteInventoryItem(LLUUID userID, InventoryItemBase item); + } +} \ No newline at end of file diff --git a/OpenSim/Framework/Communications/LoginResponse.cs b/OpenSim/Framework/Communications/LoginResponse.cs new file mode 100644 index 0000000..b5a4184 --- /dev/null +++ b/OpenSim/Framework/Communications/LoginResponse.cs @@ -0,0 +1,667 @@ +using System; +using System.Collections; +using libsecondlife; +using Nwc.XmlRpc; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.UserManagement +{ + + /// + /// A temp class to handle login response. + /// Should make use of UserProfileManager where possible. + /// + + public class LoginResponse + { + private Hashtable loginFlagsHash; + private Hashtable globalTexturesHash; + private Hashtable loginError; + private Hashtable uiConfigHash; + + private ArrayList loginFlags; + private ArrayList globalTextures; + private ArrayList eventCategories; + private ArrayList uiConfig; + private ArrayList classifiedCategories; + private ArrayList inventoryRoot; + private ArrayList initialOutfit; + private ArrayList agentInventory; + private ArrayList inventoryLibraryOwner; + private ArrayList inventoryLibrary; + + private UserInfo userProfile; + + private LLUUID agentID; + private LLUUID sessionID; + private LLUUID secureSessionID; + + // Login Flags + private string dst; + private string stipendSinceLogin; + private string gendered; + private string everLoggedIn; + private string login; + private int simPort; + private string simAddress; + private string agentAccess; + private Int32 circuitCode; + private uint regionX; + private uint regionY; + + // Login + private string firstname; + private string lastname; + + // Global Textures + private string sunTexture; + private string cloudTexture; + private string moonTexture; + + // Error Flags + private string errorReason; + private string errorMessage; + + // Response + private XmlRpcResponse xmlRpcResponse; + private XmlRpcResponse defaultXmlRpcResponse; + + private string welcomeMessage; + private string startLocation; + private string allowFirstLife; + private string home; + private string seedCapability; + private string lookAt; + + public LoginResponse() + { + this.loginFlags = new ArrayList(); + this.globalTextures = new ArrayList(); + this.eventCategories = new ArrayList(); + this.uiConfig = new ArrayList(); + this.classifiedCategories = new ArrayList(); + + this.loginError = new Hashtable(); + this.uiConfigHash = new Hashtable(); + + this.defaultXmlRpcResponse = new XmlRpcResponse(); + this.userProfile = new UserInfo(); + this.inventoryRoot = new ArrayList(); + this.initialOutfit = new ArrayList(); + this.agentInventory = new ArrayList(); + this.inventoryLibrary = new ArrayList(); + this.inventoryLibraryOwner = new ArrayList(); + + this.xmlRpcResponse = new XmlRpcResponse(); + this.defaultXmlRpcResponse = new XmlRpcResponse(); + + this.SetDefaultValues(); + } // LoginServer + + public void SetDefaultValues() + { + this.DST = "N"; + this.StipendSinceLogin = "N"; + this.Gendered = "Y"; + this.EverLoggedIn = "Y"; + this.login = "false"; + this.firstname = "Test"; + this.lastname = "User"; + this.agentAccess = "M"; + this.startLocation = "last"; + this.allowFirstLife = "Y"; + + this.SunTexture = "cce0f112-878f-4586-a2e2-a8f104bba271"; + this.CloudTexture = "fc4b9f0b-d008-45c6-96a4-01dd947ac621"; + this.MoonTexture = "fc4b9f0b-d008-45c6-96a4-01dd947ac621"; + + this.ErrorMessage = "You have entered an invalid name/password combination. Check Caps/lock."; + this.ErrorReason = "key"; + this.welcomeMessage = "Welcome to OpenSim!"; + this.seedCapability = ""; + this.home = "{'region_handle':[r" + (1000 * 256).ToString() + ",r" + (1000 * 256).ToString() + "], 'position':[r" + this.userProfile.homepos.X.ToString() + ",r" + this.userProfile.homepos.Y.ToString() + ",r" + this.userProfile.homepos.Z.ToString() + "], 'look_at':[r" + this.userProfile.homelookat.X.ToString() + ",r" + this.userProfile.homelookat.Y.ToString() + ",r" + this.userProfile.homelookat.Z.ToString() + "]}"; + this.lookAt = "[r0.99949799999999999756,r0.03166859999999999814,r0]"; + this.RegionX = (uint)255232; + this.RegionY = (uint)254976; + + // Classifieds; + this.AddClassifiedCategory((Int32)1, "Shopping"); + this.AddClassifiedCategory((Int32)2, "Land Rental"); + this.AddClassifiedCategory((Int32)3, "Property Rental"); + this.AddClassifiedCategory((Int32)4, "Special Attraction"); + this.AddClassifiedCategory((Int32)5, "New Products"); + this.AddClassifiedCategory((Int32)6, "Employment"); + this.AddClassifiedCategory((Int32)7, "Wanted"); + this.AddClassifiedCategory((Int32)8, "Service"); + this.AddClassifiedCategory((Int32)9, "Personal"); + + + this.SessionID = LLUUID.Random(); + this.SecureSessionID = LLUUID.Random(); + this.AgentID = LLUUID.Random(); + + Hashtable InitialOutfitHash = new Hashtable(); + InitialOutfitHash["folder_name"] = "Nightclub Female"; + InitialOutfitHash["gender"] = "female"; + this.initialOutfit.Add(InitialOutfitHash); + + + } // SetDefaultValues + + #region Login Failure Methods + public XmlRpcResponse GenerateFailureResponse(string reason, string message, string login) + { + // Overwrite any default values; + this.xmlRpcResponse = new XmlRpcResponse(); + + // Ensure Login Failed message/reason; + this.ErrorMessage = message; + this.ErrorReason = reason; + + this.loginError["reason"] = this.ErrorReason; + this.loginError["message"] = this.ErrorMessage; + this.loginError["login"] = login; + this.xmlRpcResponse.Value = this.loginError; + return (this.xmlRpcResponse); + } // GenerateResponse + + public XmlRpcResponse CreateFailedResponse() + { + return (this.CreateLoginFailedResponse()); + } // CreateErrorConnectingToGridResponse() + + public XmlRpcResponse CreateLoginFailedResponse() + { + return (this.GenerateFailureResponse("key", "Could not authenticate your avatar. Please check your username and password, and check the grid if problems persist.", "false")); + } // LoginFailedResponse + + public XmlRpcResponse CreateAlreadyLoggedInResponse() + { + return (this.GenerateFailureResponse("presence", "You appear to be already logged in, if this is not the case please wait for your session to timeout, if this takes longer than a few minutes please contact the grid owner", "false")); + } // CreateAlreadyLoggedInResponse() + + public XmlRpcResponse CreateDeadRegionResponse() + { + return (this.GenerateFailureResponse("key", "The region you are attempting to log into is not responding. Please select another region and try again.", "false")); + } + + public XmlRpcResponse CreateGridErrorResponse() + { + return (this.GenerateFailureResponse("key", "Error connecting to grid. Could not percieve credentials from login XML.", "false")); + } + + #endregion + + public XmlRpcResponse ToXmlRpcResponse() + { + try + { + + Hashtable responseData = new Hashtable(); + + this.loginFlagsHash = new Hashtable(); + this.loginFlagsHash["daylight_savings"] = this.DST; + this.loginFlagsHash["stipend_since_login"] = this.StipendSinceLogin; + this.loginFlagsHash["gendered"] = this.Gendered; + this.loginFlagsHash["ever_logged_in"] = this.EverLoggedIn; + this.loginFlags.Add(this.loginFlagsHash); + + responseData["first_name"] = this.Firstname; + responseData["last_name"] = this.Lastname; + responseData["agent_access"] = this.agentAccess; + + this.globalTexturesHash = new Hashtable(); + this.globalTexturesHash["sun_texture_id"] = this.SunTexture; + this.globalTexturesHash["cloud_texture_id"] = this.CloudTexture; + this.globalTexturesHash["moon_texture_id"] = this.MoonTexture; + this.globalTextures.Add(this.globalTexturesHash); + // this.eventCategories.Add(this.eventCategoriesHash); + + this.AddToUIConfig("allow_first_life", this.allowFirstLife); + this.uiConfig.Add(this.uiConfigHash); + + responseData["sim_port"] =(Int32) this.SimPort; + responseData["sim_ip"] = this.SimAddress; + + responseData["agent_id"] = this.AgentID.ToStringHyphenated(); + responseData["session_id"] = this.SessionID.ToStringHyphenated(); + responseData["secure_session_id"] = this.SecureSessionID.ToStringHyphenated(); + responseData["circuit_code"] = this.CircuitCode; + responseData["seconds_since_epoch"] = (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; + responseData["login-flags"] = this.loginFlags; + responseData["global-textures"] = this.globalTextures; + responseData["seed_capability"] = this.seedCapability; + + responseData["event_categories"] = this.eventCategories; + responseData["event_notifications"] = new ArrayList(); // todo + responseData["classified_categories"] = this.classifiedCategories; + responseData["ui-config"] = this.uiConfig; + + responseData["inventory-skeleton"] = this.agentInventory; + responseData["inventory-skel-lib"] = this.inventoryLibrary; + responseData["inventory-root"] = this.inventoryRoot; + responseData["gestures"] = new ArrayList(); // todo + responseData["inventory-lib-owner"] = this.inventoryLibraryOwner; + responseData["initial-outfit"] = this.initialOutfit; + responseData["start_location"] = this.startLocation; + responseData["seed_capability"] = this.seedCapability; + responseData["home"] = this.home; + responseData["look_at"] = this.lookAt; + responseData["message"] = this.welcomeMessage; + responseData["region_x"] = (Int32)this.RegionX * 256; + responseData["region_y"] = (Int32)this.RegionY * 256; + + //responseData["inventory-lib-root"] = new ArrayList(); // todo + //responseData["buddy-list"] = new ArrayList(); // todo + + responseData["login"] = "true"; + this.xmlRpcResponse.Value = responseData; + + return (this.xmlRpcResponse); + } + catch (Exception e) + { + MainLog.Instance.Warn( + "CLIENT", + "LoginResponse: Error creating XML-RPC Response: " + e.Message + ); + return (this.GenerateFailureResponse("Internal Error", "Error generating Login Response", "false")); + + } + + } // ToXmlRpcResponse + + public void SetEventCategories(string category, string value) + { + // this.eventCategoriesHash[category] = value; + //TODO + } // SetEventCategories + + public void AddToUIConfig(string itemName, string item) + { + this.uiConfigHash[itemName] = item; + } // SetUIConfig + + public void AddClassifiedCategory(Int32 ID, string categoryName) + { + Hashtable hash = new Hashtable(); + hash["category_name"] = categoryName; + hash["category_id"] = ID; + this.classifiedCategories.Add(hash); + // this.classifiedCategoriesHash.Clear(); + } // SetClassifiedCategory + + #region Properties + public string Login + { + get + { + return this.login; + } + set + { + this.login = value; + } + } // Login + + public string DST + { + get + { + return this.dst; + } + set + { + this.dst = value; + } + } // DST + + public string StipendSinceLogin + { + get + { + return this.stipendSinceLogin; + } + set + { + this.stipendSinceLogin = value; + } + } // StipendSinceLogin + + public string Gendered + { + get + { + return this.gendered; + } + set + { + this.gendered = value; + } + } // Gendered + + public string EverLoggedIn + { + get + { + return this.everLoggedIn; + } + set + { + this.everLoggedIn = value; + } + } // EverLoggedIn + + public int SimPort + { + get + { + return this.simPort; + } + set + { + this.simPort = value; + } + } // SimPort + + public string SimAddress + { + get + { + return this.simAddress; + } + set + { + this.simAddress = value; + } + } // SimAddress + + public LLUUID AgentID + { + get + { + return this.agentID; + } + set + { + this.agentID = value; + } + } // AgentID + + public LLUUID SessionID + { + get + { + return this.sessionID; + } + set + { + this.sessionID = value; + } + } // SessionID + + public LLUUID SecureSessionID + { + get + { + return this.secureSessionID; + } + set + { + this.secureSessionID = value; + } + } // SecureSessionID + + public Int32 CircuitCode + { + get + { + return this.circuitCode; + } + set + { + this.circuitCode = value; + } + } // CircuitCode + + public uint RegionX + { + get + { + return this.regionX; + } + set + { + this.regionX = value; + } + } // RegionX + + public uint RegionY + { + get + { + return this.regionY; + } + set + { + this.regionY = value; + } + } // RegionY + + public string SunTexture + { + get + { + return this.sunTexture; + } + set + { + this.sunTexture = value; + } + } // SunTexture + + public string CloudTexture + { + get + { + return this.cloudTexture; + } + set + { + this.cloudTexture = value; + } + } // CloudTexture + + public string MoonTexture + { + get + { + return this.moonTexture; + } + set + { + this.moonTexture = value; + } + } // MoonTexture + + public string Firstname + { + get + { + return this.firstname; + } + set + { + this.firstname = value; + } + } // Firstname + + public string Lastname + { + get + { + return this.lastname; + } + set + { + this.lastname = value; + } + } // Lastname + + public string AgentAccess + { + get + { + return this.agentAccess; + } + set + { + this.agentAccess = value; + } + } + + public string StartLocation + { + get + { + return this.startLocation; + } + set + { + this.startLocation = value; + } + } // StartLocation + + public string LookAt + { + get + { + return this.lookAt; + } + set + { + this.lookAt = value; + } + } + + public string SeedCapability + { + get + { + return this.seedCapability; + } + set + { + this.seedCapability = value; + } + } // SeedCapability + + public string ErrorReason + { + get + { + return this.errorReason; + } + set + { + this.errorReason = value; + } + } // ErrorReason + + public string ErrorMessage + { + get + { + return this.errorMessage; + } + set + { + this.errorMessage = value; + } + } // ErrorMessage + + public ArrayList InventoryRoot + { + get + { + return this.inventoryRoot; + } + set + { + this.inventoryRoot = value; + } + } + + public ArrayList InventorySkeleton + { + get + { + return this.agentInventory; + } + set + { + this.agentInventory = value; + } + } + + public ArrayList InventoryLibrary + { + get + { + return this.inventoryLibrary; + } + set + { + this.inventoryLibrary = value; + } + } + + public ArrayList InventoryLibraryOwner + { + get + { + return this.inventoryLibraryOwner; + } + set + { + this.inventoryLibraryOwner = value; + } + } + + public string Home + { + get + { + return this.home; + } + set + { + this.home = value; + } + } + + public string Message + { + get + { + return this.welcomeMessage; + } + set + { + this.welcomeMessage = value; + } + } + #endregion + + + public class UserInfo + { + public string firstname; + public string lastname; + public ulong homeregionhandle; + public LLVector3 homepos; + public LLVector3 homelookat; + } + } +} + diff --git a/OpenSim/Framework/Communications/LoginService.cs b/OpenSim/Framework/Communications/LoginService.cs new file mode 100644 index 0000000..8e7cf80 --- /dev/null +++ b/OpenSim/Framework/Communications/LoginService.cs @@ -0,0 +1,287 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using System.Security.Cryptography; +using libsecondlife; +using Nwc.XmlRpc; +using OpenSim.Framework.Console; +using OpenSim.Framework.Data; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Inventory; +using OpenSim.Framework.Utilities; + +using OpenSim.Framework.Configuration; +using InventoryFolder = OpenSim.Framework.Inventory.InventoryFolder; + +namespace OpenSim.Framework.UserManagement +{ + public class LoginService + { + protected string m_welcomeMessage = "Welcome to OpenSim"; + protected UserManagerBase m_userManager = null; + + public LoginService(UserManagerBase userManager, string welcomeMess) + { + m_userManager = userManager; + if (welcomeMess != "") + { + m_welcomeMessage = welcomeMess; + } + } + + /// + /// Main user login function + /// + /// The XMLRPC request + /// The response to send + public XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request) + { + + System.Console.WriteLine("Attempting login now..."); + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable requestData = (Hashtable)request.Params[0]; + + bool GoodXML = (requestData.Contains("first") && requestData.Contains("last") && requestData.Contains("passwd")); + bool GoodLogin = false; + + UserProfileData userProfile; + LoginResponse logResponse = new LoginResponse(); + + if (GoodXML) + { + string firstname = (string)requestData["first"]; + string lastname = (string)requestData["last"]; + string passwd = (string)requestData["passwd"]; + + userProfile = GetTheUser(firstname, lastname); + if (userProfile == null) + return logResponse.CreateLoginFailedResponse(); + + GoodLogin = AuthenticateUser(userProfile, passwd); + } + else + { + return logResponse.CreateGridErrorResponse(); + } + + if (!GoodLogin) + { + return logResponse.CreateLoginFailedResponse(); + } + else + { + // If we already have a session... + if (userProfile.currentAgent != null && userProfile.currentAgent.agentOnline) + { + // Reject the login + return logResponse.CreateAlreadyLoggedInResponse(); + } + // Otherwise... + // Create a new agent session + CreateAgent(userProfile, request); + + try + { + LLUUID agentID = userProfile.UUID; + + // Inventory Library Section + InventoryData inventData = this.CreateInventoryData(agentID); + ArrayList AgentInventoryArray = inventData.InventoryArray; + + Hashtable InventoryRootHash = new Hashtable(); + InventoryRootHash["folder_id"] = inventData.RootFolderID.ToStringHyphenated(); + ArrayList InventoryRoot = new ArrayList(); + InventoryRoot.Add(InventoryRootHash); + userProfile.rootInventoryFolderID = inventData.RootFolderID; + + // Circuit Code + uint circode = (uint)(Util.RandomClass.Next()); + + logResponse.Lastname = userProfile.surname; + logResponse.Firstname = userProfile.username; + logResponse.AgentID = agentID.ToStringHyphenated(); + logResponse.SessionID = userProfile.currentAgent.sessionID.ToStringHyphenated(); + logResponse.SecureSessionID = userProfile.currentAgent.secureSessionID.ToStringHyphenated(); + logResponse.InventoryRoot = InventoryRoot; + logResponse.InventorySkeleton = AgentInventoryArray; + logResponse.InventoryLibrary = this.GetInventoryLibrary(); + logResponse.InventoryLibraryOwner = this.GetLibraryOwner(); + logResponse.CircuitCode = (Int32)circode; + //logResponse.RegionX = 0; //overwritten + //logResponse.RegionY = 0; //overwritten + logResponse.Home = "!!null temporary value {home}!!"; // Overwritten + //logResponse.LookAt = "\n[r" + TheUser.homeLookAt.X.ToString() + ",r" + TheUser.homeLookAt.Y.ToString() + ",r" + TheUser.homeLookAt.Z.ToString() + "]\n"; + //logResponse.SimAddress = "127.0.0.1"; //overwritten + //logResponse.SimPort = 0; //overwritten + logResponse.Message = this.GetMessage(); + + try + { + this.CustomiseResponse(logResponse, userProfile); + } + catch (Exception e) + { + System.Console.WriteLine(e.ToString()); + return logResponse.CreateDeadRegionResponse(); + //return logResponse.ToXmlRpcResponse(); + } + CommitAgent(ref userProfile); + return logResponse.ToXmlRpcResponse(); + + } + + catch (Exception E) + { + System.Console.WriteLine(E.ToString()); + } + //} + } + return response; + + } + + /// + /// Customises the login response and fills in missing values. + /// + /// The existing response + /// The user profile + public virtual void CustomiseResponse(LoginResponse response, UserProfileData theUser) + { + } + + /// + /// Saves a target agent to the database + /// + /// The users profile + /// Successful? + public bool CommitAgent(ref UserProfileData profile) + { + // Saves the agent to database + return true; + } + + + /// + /// Checks a user against it's password hash + /// + /// The users profile + /// The supplied password + /// Authenticated? + public virtual bool AuthenticateUser(UserProfileData profile, string password) + { + + MainLog.Instance.Verbose( + "Authenticating " + profile.username + " " + profile.surname); + + password = password.Remove(0, 3); //remove $1$ + + string s = Util.Md5Hash(password + ":" + profile.passwordSalt); + + return profile.passwordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase); + } + + /// + /// + /// + /// + /// + public void CreateAgent(UserProfileData profile, XmlRpcRequest request) + { + this.m_userManager.CreateAgent(profile, request); + } + + /// + /// + /// + /// + /// + /// + public virtual UserProfileData GetTheUser(string firstname, string lastname) + { + return this.m_userManager.GetUserProfile(firstname, lastname); + } + + /// + /// + /// + /// + public virtual string GetMessage() + { + return m_welcomeMessage; + } + + /// + /// + /// + /// + protected virtual ArrayList GetInventoryLibrary() + { + //return new ArrayList(); + Hashtable TempHash = new Hashtable(); + TempHash["name"] = "OpenSim Library"; + TempHash["parent_id"] = LLUUID.Zero.ToStringHyphenated(); + TempHash["version"] = 1; + TempHash["type_default"] = -1; + TempHash["folder_id"] = "00000112-000f-0000-0000-000100bba000"; + ArrayList temp = new ArrayList(); + temp.Add(TempHash); + + TempHash = new Hashtable(); + TempHash["name"] = "Texture Library"; + TempHash["parent_id"] = "00000112-000f-0000-0000-000100bba000"; + TempHash["version"] = 1; + TempHash["type_default"] = -1; + TempHash["folder_id"] = "00000112-000f-0000-0000-000100bba001"; + temp.Add(TempHash); + return temp; + } + + /// + /// + /// + /// + 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; + } + + protected virtual InventoryData CreateInventoryData(LLUUID userID) + { + AgentInventory userInventory = new AgentInventory(); + userInventory.CreateRootFolder(userID, false); + + ArrayList AgentInventoryArray = new ArrayList(); + Hashtable TempHash; + foreach (InventoryFolder InvFolder in userInventory.InventoryFolders.Values) + { + TempHash = new Hashtable(); + TempHash["name"] = InvFolder.FolderName; + TempHash["parent_id"] = InvFolder.ParentID.ToStringHyphenated(); + TempHash["version"] = (Int32)InvFolder.Version; + TempHash["type_default"] = (Int32)InvFolder.DefaultType; + TempHash["folder_id"] = InvFolder.FolderID.ToStringHyphenated(); + AgentInventoryArray.Add(TempHash); + } + + return new InventoryData(AgentInventoryArray, userInventory.InventoryRoot.FolderID); + } + + public class InventoryData + { + public ArrayList InventoryArray = null; + public LLUUID RootFolderID = LLUUID.Zero; + + public InventoryData(ArrayList invList, LLUUID rootID) + { + InventoryArray = invList; + RootFolderID = rootID; + } + } + } +} diff --git a/OpenSim/Framework/Communications/UserManagerBase.cs b/OpenSim/Framework/Communications/UserManagerBase.cs new file mode 100644 index 0000000..d1bbde1 --- /dev/null +++ b/OpenSim/Framework/Communications/UserManagerBase.cs @@ -0,0 +1,379 @@ +/* +* 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 OpenSim 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; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using System.Security.Cryptography; +using libsecondlife; +using Nwc.XmlRpc; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Configuration; +using OpenSim.Framework.Console; +using OpenSim.Framework.Data; +using OpenSim.Framework.Utilities; + +namespace OpenSim.Framework.UserManagement +{ + public abstract class UserManagerBase : IUserServices + { + public UserConfig _config; + Dictionary _plugins = new Dictionary(); + + /// + /// Adds a new user server plugin - user servers will be requested in the order they were loaded. + /// + /// The filename to the user server plugin DLL + public void AddPlugin(string FileName) + { + if (!String.IsNullOrEmpty(FileName)) + { + MainLog.Instance.Verbose("Userstorage: Attempting to load " + FileName); + Assembly pluginAssembly = Assembly.LoadFrom(FileName); + + MainLog.Instance.Verbose("Userstorage: Found " + pluginAssembly.GetTypes().Length + " interfaces."); + foreach (Type pluginType in pluginAssembly.GetTypes()) + { + if (!pluginType.IsAbstract) + { + Type typeInterface = pluginType.GetInterface("IUserData", true); + + if (typeInterface != null) + { + IUserData plug = + (IUserData) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); + AddPlugin(plug); + } + } + } + } + } + + public void AddPlugin(IUserData plug) + { + plug.Initialise(); + this._plugins.Add(plug.getName(), plug); + MainLog.Instance.Verbose( "Userstorage: Added IUserData Interface"); + } + + #region Get UserProfile + /// + /// Loads a user profile from a database by UUID + /// + /// The target UUID + /// A user profile + public UserProfileData GetUserProfile(LLUUID uuid) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + UserProfileData profile = plugin.Value.GetUserByUUID(uuid); + profile.currentAgent = getUserAgent(profile.UUID); + return profile; + } + catch (Exception e) + { + MainLog.Instance.Verbose( "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + + return null; + } + + + /// + /// Loads a user profile by name + /// + /// The target name + /// A user profile + public UserProfileData GetUserProfile(string name) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + UserProfileData profile = plugin.Value.GetUserByName(name); + profile.currentAgent = getUserAgent(profile.UUID); + return profile; + } + catch (Exception e) + { + System.Console.WriteLine("EEK!"); + MainLog.Instance.Verbose( "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + + return null; + } + + /// + /// Loads a user profile by name + /// + /// First name + /// Last name + /// A user profile + public UserProfileData GetUserProfile(string fname, string lname) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + UserProfileData profile = plugin.Value.GetUserByName(fname,lname); + + profile.currentAgent = getUserAgent(profile.UUID); + + return profile; + } + catch (Exception e) + { + MainLog.Instance.Verbose( "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + + return null; + } + + /// + /// Set's user profile from object + /// + /// First name + /// Last name + /// A user profile + public bool setUserProfile(UserProfileData data) + { + foreach (KeyValuePair plugin in _plugins) + { + try { + plugin.Value.UpdateUserProfile(data); + return true; + } catch (Exception e) { + MainLog.Instance.Verbose( "Unable to set user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + + return false; + } + + #endregion + + #region Get UserAgent + /// + /// Loads a user agent by uuid (not called directly) + /// + /// The agents UUID + /// Agent profiles + public UserAgentData getUserAgent(LLUUID uuid) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + return plugin.Value.GetAgentByUUID(uuid); + } + catch (Exception e) + { + MainLog.Instance.Verbose( "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + + return null; + } + + /// + /// Loads a user agent by name (not called directly) + /// + /// The agents name + /// A user agent + public UserAgentData getUserAgent(string name) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + return plugin.Value.GetAgentByName(name); + } + catch (Exception e) + { + MainLog.Instance.Verbose( "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + + return null; + } + + // TODO: document + public void clearUserAgent(LLUUID agentID) + { + UserProfileData profile = GetUserProfile(agentID); + profile.currentAgent = null; + setUserProfile(profile); + } + + + /// + /// Loads a user agent by name (not called directly) + /// + /// The agents firstname + /// The agents lastname + /// A user agent + public UserAgentData getUserAgent(string fname, string lname) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + return plugin.Value.GetAgentByName(fname,lname); + } + catch (Exception e) + { + MainLog.Instance.Verbose( "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + + return null; + } + + #endregion + + #region CreateAgent + /// + /// Creates and initialises a new user agent - make sure to use CommitAgent when done to submit to the DB + /// + /// The users profile + /// The users loginrequest + public void CreateAgent(UserProfileData profile, XmlRpcRequest request) + { + Hashtable requestData = (Hashtable)request.Params[0]; + + UserAgentData agent = new UserAgentData(); + + // User connection + agent.agentOnline = true; + + // Generate sessions + RNGCryptoServiceProvider rand = new RNGCryptoServiceProvider(); + byte[] randDataS = new byte[16]; + byte[] randDataSS = new byte[16]; + rand.GetBytes(randDataS); + rand.GetBytes(randDataSS); + + agent.secureSessionID = new LLUUID(randDataSS, 0); + agent.sessionID = new LLUUID(randDataS, 0); + + // Profile UUID + agent.UUID = profile.UUID; + + // Current position (from Home) + agent.currentHandle = profile.homeRegion; + agent.currentPos = profile.homeLocation; + + // If user specified additional start, use that + if (requestData.ContainsKey("start")) + { + string startLoc = ((string)requestData["start"]).Trim(); + if (!(startLoc == "last" || startLoc == "home")) + { + // Format: uri:Ahern&162&213&34 + try + { + string[] parts = startLoc.Remove(0, 4).Split('&'); + string region = parts[0]; + + //////////////////////////////////////////////////// + //SimProfile SimInfo = new SimProfile(); + //SimInfo = SimInfo.LoadFromGrid(theUser.currentAgent.currentHandle, _config.GridServerURL, _config.GridSendKey, _config.GridRecvKey); + } + catch (Exception) + { + + } + } + } + + // What time did the user login? + agent.loginTime = Util.UnixTimeSinceEpoch(); + agent.logoutTime = 0; + + // Current location + agent.regionID = new LLUUID(); // Fill in later + agent.currentRegion = new LLUUID(); // Fill in later + + profile.currentAgent = agent; + } + + /// + /// Saves a target agent to the database + /// + /// The users profile + /// Successful? + public bool CommitAgent(ref UserProfileData profile) + { + // Saves the agent to database + return true; + } + + #endregion + + /// + /// + /// + /// + public void AddUserProfile(string firstName, string lastName, string pass, uint regX, uint regY) + { + UserProfileData user = new UserProfileData(); + user.homeLocation = new LLVector3(128, 128, 100); + user.UUID = LLUUID.Random(); + user.username = firstName; + user.surname = lastName; + user.passwordHash = pass; + user.passwordSalt = ""; + user.created = Util.UnixTimeSinceEpoch(); + user.homeLookAt = new LLVector3(100, 100, 100); + user.homeRegionX = regX; + user.homeRegionY = regY; + + foreach (KeyValuePair plugin in _plugins) + { + try + { + plugin.Value.AddNewUserProfile(user); + + } + catch (Exception e) + { + MainLog.Instance.Verbose("Unable to add user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + } + + public abstract UserProfileData SetupMasterUser(string firstName, string lastName); + public abstract UserProfileData SetupMasterUser(string firstName, string lastName, string password); + } +} -- cgit v1.1