diff --git a/OpenSim/Framework/ACL.cs b/OpenSim/Framework/ACL.cs index 0e9df19f2f..a205217bcb 100644 --- a/OpenSim/Framework/ACL.cs +++ b/OpenSim/Framework/ACL.cs @@ -1,263 +1,263 @@ -/* -* 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.Generic; - -namespace OpenSim.Framework -{ - // ACL Class - // Modelled after the structure of the Zend ACL Framework Library - // with one key difference - the tree will search for all matching - // permissions rather than just the first. Deny permissions will - // override all others. - - #region ACL Core Class - - /// - /// Access Control List Engine - /// - public class ACL - { - private Dictionary Roles = new Dictionary(); - private Dictionary Resources = new Dictionary(); - - public ACL AddRole(Role role) - { - if (Roles.ContainsKey(role.Name)) - throw new AlreadyContainsRoleException(role); - - Roles.Add(role.Name, role); - - return this; - } - - public ACL AddResource(Resource resource) - { - Resources.Add(resource.Name, resource); - - return this; - } - - public Permission HasPermission(string role, string resource) - { - if (!Roles.ContainsKey(role)) - throw new KeyNotFoundException(); - - if (!Resources.ContainsKey(resource)) - throw new KeyNotFoundException(); - - return Roles[role].RequestPermission(resource); - } - - public ACL GrantPermission(string role, string resource) - { - if (!Roles.ContainsKey(role)) - throw new KeyNotFoundException(); - - if (!Resources.ContainsKey(resource)) - throw new KeyNotFoundException(); - - Roles[role].GivePermission(resource, Permission.Allow); - - return this; - } - - public ACL DenyPermission(string role, string resource) - { - if (!Roles.ContainsKey(role)) - throw new KeyNotFoundException(); - - if (!Resources.ContainsKey(resource)) - throw new KeyNotFoundException(); - - Roles[role].GivePermission(resource, Permission.Deny); - - return this; - } - - public ACL ResetPermission(string role, string resource) - { - if (!Roles.ContainsKey(role)) - throw new KeyNotFoundException(); - - if (!Resources.ContainsKey(resource)) - throw new KeyNotFoundException(); - - Roles[role].GivePermission(resource, Permission.None); - - return this; - } - } - - #endregion - - #region Exceptions - - /// - /// Thrown when an ACL attempts to add a duplicate role. - /// - public class AlreadyContainsRoleException : Exception - { - protected Role m_role; - - public Role ErrorRole - { - get { return m_role; } - } - - public AlreadyContainsRoleException(Role role) - { - m_role = role; - } - - public override string ToString() - { - return "This ACL already contains a role called '" + m_role.Name + "'."; - } - } - - #endregion - - #region Roles and Resources - - /// - /// Does this Role have permission to access a specified Resource? - /// - public enum Permission - { - Deny, - None, - Allow - } ; - - /// - /// A role class, for use with Users or Groups - /// - public class Role - { - private string m_name; - private Role[] m_parents; - private Dictionary m_resources = new Dictionary(); - - public string Name - { - get { return m_name; } - } - - public Permission RequestPermission(string resource) - { - return RequestPermission(resource, Permission.None); - } - - public Permission RequestPermission(string resource, Permission current) - { - // Deny permissions always override any others - if (current == Permission.Deny) - return current; - - Permission temp = Permission.None; - - // Pickup non-None permissions - if (m_resources.ContainsKey(resource) && m_resources[resource] != Permission.None) - temp = m_resources[resource]; - - if (m_parents != null) - { - foreach (Role parent in m_parents) - { - temp = parent.RequestPermission(resource, temp); - } - } - - return temp; - } - - public void GivePermission(string resource, Permission perm) - { - m_resources[resource] = perm; - } - - public Role(string name) - { - m_name = name; - m_parents = null; - } - - public Role(string name, Role[] parents) - { - m_name = name; - m_parents = parents; - } - } - - public class Resource - { - private string m_name; - - public string Name - { - get { return m_name; } - } - - public Resource(string name) - { - m_name = name; - } - } - - #endregion - - #region Tests - - internal class ACLTester - { - public ACLTester() - { - ACL acl = new ACL(); - - Role Guests = new Role("Guests"); - acl.AddRole(Guests); - - Role[] parents = new Role[0]; - parents[0] = Guests; - - Role JoeGuest = new Role("JoeGuest", parents); - acl.AddRole(JoeGuest); - - Resource CanBuild = new Resource("CanBuild"); - acl.AddResource(CanBuild); - - - acl.GrantPermission("Guests", "CanBuild"); - - acl.HasPermission("JoeGuest", "CanBuild"); - } - } - - #endregion -} \ No newline at end of file +/* +* 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.Generic; + +namespace OpenSim.Framework +{ + // ACL Class + // Modelled after the structure of the Zend ACL Framework Library + // with one key difference - the tree will search for all matching + // permissions rather than just the first. Deny permissions will + // override all others. + + #region ACL Core Class + + /// + /// Access Control List Engine + /// + public class ACL + { + private Dictionary Roles = new Dictionary(); + private Dictionary Resources = new Dictionary(); + + public ACL AddRole(Role role) + { + if (Roles.ContainsKey(role.Name)) + throw new AlreadyContainsRoleException(role); + + Roles.Add(role.Name, role); + + return this; + } + + public ACL AddResource(Resource resource) + { + Resources.Add(resource.Name, resource); + + return this; + } + + public Permission HasPermission(string role, string resource) + { + if (!Roles.ContainsKey(role)) + throw new KeyNotFoundException(); + + if (!Resources.ContainsKey(resource)) + throw new KeyNotFoundException(); + + return Roles[role].RequestPermission(resource); + } + + public ACL GrantPermission(string role, string resource) + { + if (!Roles.ContainsKey(role)) + throw new KeyNotFoundException(); + + if (!Resources.ContainsKey(resource)) + throw new KeyNotFoundException(); + + Roles[role].GivePermission(resource, Permission.Allow); + + return this; + } + + public ACL DenyPermission(string role, string resource) + { + if (!Roles.ContainsKey(role)) + throw new KeyNotFoundException(); + + if (!Resources.ContainsKey(resource)) + throw new KeyNotFoundException(); + + Roles[role].GivePermission(resource, Permission.Deny); + + return this; + } + + public ACL ResetPermission(string role, string resource) + { + if (!Roles.ContainsKey(role)) + throw new KeyNotFoundException(); + + if (!Resources.ContainsKey(resource)) + throw new KeyNotFoundException(); + + Roles[role].GivePermission(resource, Permission.None); + + return this; + } + } + + #endregion + + #region Exceptions + + /// + /// Thrown when an ACL attempts to add a duplicate role. + /// + public class AlreadyContainsRoleException : Exception + { + protected Role m_role; + + public Role ErrorRole + { + get { return m_role; } + } + + public AlreadyContainsRoleException(Role role) + { + m_role = role; + } + + public override string ToString() + { + return "This ACL already contains a role called '" + m_role.Name + "'."; + } + } + + #endregion + + #region Roles and Resources + + /// + /// Does this Role have permission to access a specified Resource? + /// + public enum Permission + { + Deny, + None, + Allow + } ; + + /// + /// A role class, for use with Users or Groups + /// + public class Role + { + private string m_name; + private Role[] m_parents; + private Dictionary m_resources = new Dictionary(); + + public string Name + { + get { return m_name; } + } + + public Permission RequestPermission(string resource) + { + return RequestPermission(resource, Permission.None); + } + + public Permission RequestPermission(string resource, Permission current) + { + // Deny permissions always override any others + if (current == Permission.Deny) + return current; + + Permission temp = Permission.None; + + // Pickup non-None permissions + if (m_resources.ContainsKey(resource) && m_resources[resource] != Permission.None) + temp = m_resources[resource]; + + if (m_parents != null) + { + foreach (Role parent in m_parents) + { + temp = parent.RequestPermission(resource, temp); + } + } + + return temp; + } + + public void GivePermission(string resource, Permission perm) + { + m_resources[resource] = perm; + } + + public Role(string name) + { + m_name = name; + m_parents = null; + } + + public Role(string name, Role[] parents) + { + m_name = name; + m_parents = parents; + } + } + + public class Resource + { + private string m_name; + + public string Name + { + get { return m_name; } + } + + public Resource(string name) + { + m_name = name; + } + } + + #endregion + + #region Tests + + internal class ACLTester + { + public ACLTester() + { + ACL acl = new ACL(); + + Role Guests = new Role("Guests"); + acl.AddRole(Guests); + + Role[] parents = new Role[0]; + parents[0] = Guests; + + Role JoeGuest = new Role("JoeGuest", parents); + acl.AddRole(JoeGuest); + + Resource CanBuild = new Resource("CanBuild"); + acl.AddResource(CanBuild); + + + acl.GrantPermission("Guests", "CanBuild"); + + acl.HasPermission("JoeGuest", "CanBuild"); + } + } + + #endregion +} diff --git a/OpenSim/Framework/AgentCircuitData.cs b/OpenSim/Framework/AgentCircuitData.cs index 0821407a5e..20ce97c326 100644 --- a/OpenSim/Framework/AgentCircuitData.cs +++ b/OpenSim/Framework/AgentCircuitData.cs @@ -1,111 +1,111 @@ -/* -* 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 libsecondlife; - -namespace OpenSim.Framework -{ - public class AgentCircuitData - { - public AgentCircuitData() - { - } - - public AgentCircuitData(sAgentCircuitData cAgent) - { - AgentID = new LLUUID(cAgent.AgentID); - SessionID = new LLUUID(cAgent.SessionID); - SecureSessionID = new LLUUID(cAgent.SecureSessionID); - startpos = new LLVector3(cAgent.startposx, cAgent.startposy, cAgent.startposz); - firstname = cAgent.firstname; - lastname = cAgent.lastname; - circuitcode = cAgent.circuitcode; - child = cAgent.child; - InventoryFolder = new LLUUID(cAgent.InventoryFolder); - BaseFolder = new LLUUID(cAgent.BaseFolder); - CapsPath = cAgent.CapsPath; - ClientVersion = cAgent.ClientVersion; //rex - } - - public LLUUID AgentID; - public LLUUID SessionID; - public LLUUID SecureSessionID; - public LLVector3 startpos; - public string firstname; - public string lastname; - public uint circuitcode; - public bool child; - public LLUUID InventoryFolder; - public LLUUID BaseFolder; - public string CapsPath = ""; - public string ClientVersion = "not set"; //rex - public string authenticationAddr; - public string asAddress = ""; - } - - [Serializable] - public class sAgentCircuitData - { - public sAgentCircuitData() - { - } - - public sAgentCircuitData(AgentCircuitData cAgent) - { - AgentID = cAgent.AgentID.UUID; - SessionID = cAgent.SessionID.UUID; - SecureSessionID = cAgent.SecureSessionID.UUID; - startposx = cAgent.startpos.X; - startposy = cAgent.startpos.Y; - startposz = cAgent.startpos.Z; - firstname = cAgent.firstname; - lastname = cAgent.lastname; - circuitcode = cAgent.circuitcode; - child = cAgent.child; - InventoryFolder = cAgent.InventoryFolder.UUID; - BaseFolder = cAgent.BaseFolder.UUID; - CapsPath = cAgent.CapsPath; - ClientVersion = cAgent.ClientVersion; //rex - } - - public Guid AgentID; - public Guid SessionID; - public Guid SecureSessionID; - public float startposx; - public float startposy; - public float startposz; - public string firstname; - public string lastname; - public uint circuitcode; - public bool child; - public Guid InventoryFolder; - public Guid BaseFolder; - public string CapsPath = ""; - public string ClientVersion = "not set"; //rex - } -} \ No newline at end of file +/* +* 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 libsecondlife; + +namespace OpenSim.Framework +{ + public class AgentCircuitData + { + public AgentCircuitData() + { + } + + public AgentCircuitData(sAgentCircuitData cAgent) + { + AgentID = new LLUUID(cAgent.AgentID); + SessionID = new LLUUID(cAgent.SessionID); + SecureSessionID = new LLUUID(cAgent.SecureSessionID); + startpos = new LLVector3(cAgent.startposx, cAgent.startposy, cAgent.startposz); + firstname = cAgent.firstname; + lastname = cAgent.lastname; + circuitcode = cAgent.circuitcode; + child = cAgent.child; + InventoryFolder = new LLUUID(cAgent.InventoryFolder); + BaseFolder = new LLUUID(cAgent.BaseFolder); + CapsPath = cAgent.CapsPath; + ClientVersion = cAgent.ClientVersion; //rex + } + + public LLUUID AgentID; + public LLUUID SessionID; + public LLUUID SecureSessionID; + public LLVector3 startpos; + public string firstname; + public string lastname; + public uint circuitcode; + public bool child; + public LLUUID InventoryFolder; + public LLUUID BaseFolder; + public string CapsPath = String.Empty; + public string ClientVersion = "not set"; //rex + public string authenticationAddr; + public string asAddress = ""; + } + + [Serializable] + public class sAgentCircuitData + { + public sAgentCircuitData() + { + } + + public sAgentCircuitData(AgentCircuitData cAgent) + { + AgentID = cAgent.AgentID.UUID; + SessionID = cAgent.SessionID.UUID; + SecureSessionID = cAgent.SecureSessionID.UUID; + startposx = cAgent.startpos.X; + startposy = cAgent.startpos.Y; + startposz = cAgent.startpos.Z; + firstname = cAgent.firstname; + lastname = cAgent.lastname; + circuitcode = cAgent.circuitcode; + child = cAgent.child; + InventoryFolder = cAgent.InventoryFolder.UUID; + BaseFolder = cAgent.BaseFolder.UUID; + CapsPath = cAgent.CapsPath; + ClientVersion = cAgent.ClientVersion; //rex + } + + public Guid AgentID; + public Guid SessionID; + public Guid SecureSessionID; + public float startposx; + public float startposy; + public float startposz; + public string firstname; + public string lastname; + public uint circuitcode; + public bool child; + public Guid InventoryFolder; + public Guid BaseFolder; + public string CapsPath = String.Empty; + public string ClientVersion = "not set"; //rex + } +} diff --git a/OpenSim/Framework/AgentInventory.cs b/OpenSim/Framework/AgentInventory.cs index 71f6025772..f3cd59cba0 100644 --- a/OpenSim/Framework/AgentInventory.cs +++ b/OpenSim/Framework/AgentInventory.cs @@ -1,258 +1,258 @@ -/* -* 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.Collections.Generic; -using libsecondlife; -using libsecondlife.Packets; - -namespace OpenSim.Framework -{ - public class AgentInventory - { - //Holds the local copy of Inventory info for a agent - public Dictionary InventoryFolders; - public Dictionary InventoryItems; - public InventoryFolder InventoryRoot; - public int LastCached; //maybe used by opensim app, time this was last stored/compared to user server - public LLUUID AgentID; - public AvatarWearable[] Wearables; - - public AgentInventory() - { - InventoryFolders = new Dictionary(); - InventoryItems = new Dictionary(); - Initialise(); - } - - public virtual void Initialise() - { - Wearables = new AvatarWearable[13]; - for (int i = 0; i < 13; i++) - { - Wearables[i] = new AvatarWearable(); - } - } - - public bool CreateNewFolder(LLUUID folderID, ushort type) - { - InventoryFolder Folder = new InventoryFolder(); - Folder.FolderID = folderID; - Folder.OwnerID = AgentID; - Folder.DefaultType = type; - InventoryFolders.Add(Folder.FolderID, Folder); - return (true); - } - - public void CreateRootFolder(LLUUID newAgentID, bool createTextures) - { - AgentID = newAgentID; - InventoryRoot = new InventoryFolder(); - InventoryRoot.FolderID = LLUUID.Random(); - InventoryRoot.ParentID = LLUUID.Zero; - InventoryRoot.Version = 1; - InventoryRoot.DefaultType = 8; - InventoryRoot.OwnerID = AgentID; - InventoryRoot.FolderName = "My Inventory"; - InventoryFolders.Add(InventoryRoot.FolderID, InventoryRoot); - InventoryRoot.OwnerID = AgentID; - if (createTextures) - { - CreateNewFolder(LLUUID.Random(), 0, "Textures", InventoryRoot.FolderID); - } - } - - public bool CreateNewFolder(LLUUID folderID, ushort type, string folderName) - { - InventoryFolder Folder = new InventoryFolder(); - Folder.FolderID = folderID; - Folder.OwnerID = AgentID; - Folder.DefaultType = type; - Folder.FolderName = folderName; - InventoryFolders.Add(Folder.FolderID, Folder); - return (true); - } - - public bool CreateNewFolder(LLUUID folderID, ushort type, string folderName, LLUUID parentID) - { - if (!InventoryFolders.ContainsKey(folderID)) - { - System.Console.WriteLine("creating new folder called " + folderName + " in agents inventory"); - InventoryFolder Folder = new InventoryFolder(); - Folder.FolderID = folderID; - Folder.OwnerID = AgentID; - Folder.DefaultType = type; - Folder.FolderName = folderName; - Folder.ParentID = parentID; - InventoryFolders.Add(Folder.FolderID, Folder); - } - return (true); - } - - public bool HasFolder(LLUUID folderID) - { - if (InventoryFolders.ContainsKey(folderID)) - { - return true; - } - return false; - } - - public LLUUID GetFolderID(string folderName) - { - foreach (InventoryFolder inv in InventoryFolders.Values) - { - if (inv.FolderName == folderName) - { - return inv.FolderID; - } - } - return LLUUID.Zero; - } - - public bool UpdateItemAsset(LLUUID itemID, AssetBase asset) - { - if (InventoryItems.ContainsKey(itemID)) - { - InventoryItem Item = InventoryItems[itemID]; - Item.AssetID = asset.FullID; - System.Console.WriteLine("updated inventory item " + itemID.ToString() + - " so it now is set to asset " + asset.FullID.ToString()); - //TODO need to update the rest of the info - } - return true; - } - - public bool UpdateItemDetails(LLUUID itemID, UpdateInventoryItemPacket.InventoryDataBlock packet) - { - System.Console.WriteLine("updating inventory item details"); - if (InventoryItems.ContainsKey(itemID)) - { - System.Console.WriteLine("changing name to " + Util.FieldToString(packet.Name)); - InventoryItem Item = InventoryItems[itemID]; - Item.Name = Util.FieldToString(packet.Name); - System.Console.WriteLine("updated inventory item " + itemID.ToString()); - //TODO need to update the rest of the info - } - return true; - } - - public LLUUID AddToInventory(LLUUID folderID, AssetBase asset) - { - if (InventoryFolders.ContainsKey(folderID)) - { - LLUUID NewItemID = LLUUID.Random(); - - InventoryItem Item = new InventoryItem(); - Item.FolderID = folderID; - Item.OwnerID = AgentID; - Item.AssetID = asset.FullID; - Item.ItemID = NewItemID; - Item.Type = asset.Type; - Item.Name = asset.Name; - Item.Description = asset.Description; - Item.InvType = asset.InvType; - InventoryItems.Add(Item.ItemID, Item); - InventoryFolder Folder = InventoryFolders[Item.FolderID]; - Folder.Items.Add(Item); - return (Item.ItemID); - } - else - { - return (null); - } - } - - public bool DeleteFromInventory(LLUUID itemID) - { - bool res = false; - if (InventoryItems.ContainsKey(itemID)) - { - InventoryItem item = InventoryItems[itemID]; - InventoryItems.Remove(itemID); - foreach (InventoryFolder fold in InventoryFolders.Values) - { - if (fold.Items.Contains(item)) - { - fold.Items.Remove(item); - break; - } - } - res = true; - } - return res; - } - } - - public class InventoryFolder - { - public List Items; - //public List Subfolders; - public LLUUID FolderID; - public LLUUID OwnerID; - public LLUUID ParentID = LLUUID.Zero; - public string FolderName; - public ushort DefaultType; - public ushort Version; - - public InventoryFolder() - { - Items = new List(); - //Subfolders = new List(); - } - } - - public class InventoryItem - { - public LLUUID FolderID; - public LLUUID OwnerID; - public LLUUID ItemID; - public LLUUID AssetID; - public LLUUID CreatorID; - public sbyte InvType; - public sbyte Type; - public string Name = ""; - public string Description; - - public InventoryItem() - { - CreatorID = LLUUID.Zero; - } - - public string ExportString() - { - string typ = "notecard"; - string result = ""; - result += "\tinv_object\t0\n\t{\n"; - result += "\t\tobj_id\t%s\n"; - result += "\t\tparent_id\t" + ItemID.ToString() + "\n"; - result += "\t\ttype\t" + typ + "\n"; - result += "\t\tname\t" + Name + "|\n"; - result += "\t}\n"; - return result; - } - } -} \ No newline at end of file +/* +* 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.Collections.Generic; +using libsecondlife; +using libsecondlife.Packets; + +namespace OpenSim.Framework +{ + public class AgentInventory + { + //Holds the local copy of Inventory info for a agent + public Dictionary InventoryFolders; + public Dictionary InventoryItems; + public InventoryFolder InventoryRoot; + public int LastCached; //maybe used by opensim app, time this was last stored/compared to user server + public LLUUID AgentID; + public AvatarWearable[] Wearables; + + public AgentInventory() + { + InventoryFolders = new Dictionary(); + InventoryItems = new Dictionary(); + Initialise(); + } + + public virtual void Initialise() + { + Wearables = new AvatarWearable[13]; + for (int i = 0; i < 13; i++) + { + Wearables[i] = new AvatarWearable(); + } + } + + public bool CreateNewFolder(LLUUID folderID, ushort type) + { + InventoryFolder Folder = new InventoryFolder(); + Folder.FolderID = folderID; + Folder.OwnerID = AgentID; + Folder.DefaultType = type; + InventoryFolders.Add(Folder.FolderID, Folder); + return (true); + } + + public void CreateRootFolder(LLUUID newAgentID, bool createTextures) + { + AgentID = newAgentID; + InventoryRoot = new InventoryFolder(); + InventoryRoot.FolderID = LLUUID.Random(); + InventoryRoot.ParentID = LLUUID.Zero; + InventoryRoot.Version = 1; + InventoryRoot.DefaultType = 8; + InventoryRoot.OwnerID = AgentID; + InventoryRoot.FolderName = "My Inventory"; + InventoryFolders.Add(InventoryRoot.FolderID, InventoryRoot); + InventoryRoot.OwnerID = AgentID; + if (createTextures) + { + CreateNewFolder(LLUUID.Random(), 0, "Textures", InventoryRoot.FolderID); + } + } + + public bool CreateNewFolder(LLUUID folderID, ushort type, string folderName) + { + InventoryFolder Folder = new InventoryFolder(); + Folder.FolderID = folderID; + Folder.OwnerID = AgentID; + Folder.DefaultType = type; + Folder.FolderName = folderName; + InventoryFolders.Add(Folder.FolderID, Folder); + return (true); + } + + public bool CreateNewFolder(LLUUID folderID, ushort type, string folderName, LLUUID parentID) + { + if (!InventoryFolders.ContainsKey(folderID)) + { + System.Console.WriteLine("creating new folder called " + folderName + " in agents inventory"); + InventoryFolder Folder = new InventoryFolder(); + Folder.FolderID = folderID; + Folder.OwnerID = AgentID; + Folder.DefaultType = type; + Folder.FolderName = folderName; + Folder.ParentID = parentID; + InventoryFolders.Add(Folder.FolderID, Folder); + } + return (true); + } + + public bool HasFolder(LLUUID folderID) + { + if (InventoryFolders.ContainsKey(folderID)) + { + return true; + } + return false; + } + + public LLUUID GetFolderID(string folderName) + { + foreach (InventoryFolder inv in InventoryFolders.Values) + { + if (inv.FolderName == folderName) + { + return inv.FolderID; + } + } + return LLUUID.Zero; + } + + public bool UpdateItemAsset(LLUUID itemID, AssetBase asset) + { + if (InventoryItems.ContainsKey(itemID)) + { + InventoryItem Item = InventoryItems[itemID]; + Item.AssetID = asset.FullID; + System.Console.WriteLine("updated inventory item " + itemID.ToString() + + " so it now is set to asset " + asset.FullID.ToString()); + //TODO need to update the rest of the info + } + return true; + } + + public bool UpdateItemDetails(LLUUID itemID, UpdateInventoryItemPacket.InventoryDataBlock packet) + { + System.Console.WriteLine("updating inventory item details"); + if (InventoryItems.ContainsKey(itemID)) + { + System.Console.WriteLine("changing name to " + Util.FieldToString(packet.Name)); + InventoryItem Item = InventoryItems[itemID]; + Item.Name = Util.FieldToString(packet.Name); + System.Console.WriteLine("updated inventory item " + itemID.ToString()); + //TODO need to update the rest of the info + } + return true; + } + + public LLUUID AddToInventory(LLUUID folderID, AssetBase asset) + { + if (InventoryFolders.ContainsKey(folderID)) + { + LLUUID NewItemID = LLUUID.Random(); + + InventoryItem Item = new InventoryItem(); + Item.FolderID = folderID; + Item.OwnerID = AgentID; + Item.AssetID = asset.FullID; + Item.ItemID = NewItemID; + Item.Type = asset.Type; + Item.Name = asset.Name; + Item.Description = asset.Description; + Item.InvType = asset.InvType; + InventoryItems.Add(Item.ItemID, Item); + InventoryFolder Folder = InventoryFolders[Item.FolderID]; + Folder.Items.Add(Item); + return (Item.ItemID); + } + else + { + return (null); + } + } + + public bool DeleteFromInventory(LLUUID itemID) + { + bool res = false; + if (InventoryItems.ContainsKey(itemID)) + { + InventoryItem item = InventoryItems[itemID]; + InventoryItems.Remove(itemID); + foreach (InventoryFolder fold in InventoryFolders.Values) + { + if (fold.Items.Contains(item)) + { + fold.Items.Remove(item); + break; + } + } + res = true; + } + return res; + } + } + + public class InventoryFolder + { + public List Items; + //public List Subfolders; + public LLUUID FolderID; + public LLUUID OwnerID; + public LLUUID ParentID = LLUUID.Zero; + public string FolderName; + public ushort DefaultType; + public ushort Version; + + public InventoryFolder() + { + Items = new List(); + //Subfolders = new List(); + } + } + + public class InventoryItem + { + public LLUUID FolderID; + public LLUUID OwnerID; + public LLUUID ItemID; + public LLUUID AssetID; + public LLUUID CreatorID; + public sbyte InvType; + public sbyte Type; + public string Name = System.String.Empty; + public string Description; + + public InventoryItem() + { + CreatorID = LLUUID.Zero; + } + + public string ExportString() + { + string typ = "notecard"; + string result = System.String.Empty; + result += "\tinv_object\t0\n\t{\n"; + result += "\t\tobj_id\t%s\n"; + result += "\t\tparent_id\t" + ItemID.ToString() + "\n"; + result += "\t\ttype\t" + typ + "\n"; + result += "\t\tname\t" + Name + "|\n"; + result += "\t}\n"; + return result; + } + } +} diff --git a/OpenSim/Framework/AssemblyInfo.cs b/OpenSim/Framework/AssemblyInfo.cs index 9c13d1fe99..60c9024dfc 100644 --- a/OpenSim/Framework/AssemblyInfo.cs +++ b/OpenSim/Framework/AssemblyInfo.cs @@ -1,36 +1,64 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. - -[assembly : AssemblyTitle("OpenSim.FrameWork")] -[assembly : AssemblyDescription("")] -[assembly : AssemblyConfiguration("")] -[assembly : AssemblyCompany("")] -[assembly : AssemblyProduct("OpenSim.FrameWork")] -[assembly : AssemblyCopyright("Copyright © 2007")] -[assembly : AssemblyTrademark("")] -[assembly : AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. - -[assembly : ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM - -[assembly : Guid("a08e20c7-f191-4137-b1f0-9291408fa521")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// - -[assembly : AssemblyVersion("1.0.0.0")] -[assembly : AssemblyFileVersion("1.0.0.0")] \ No newline at end of file +/* +* 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.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. + +[assembly : AssemblyTitle("OpenSim.FrameWork")] +[assembly : AssemblyDescription("")] +[assembly : AssemblyConfiguration("")] +[assembly : AssemblyCompany("")] +[assembly : AssemblyProduct("OpenSim.FrameWork")] +[assembly : AssemblyCopyright("Copyright © OpenSimulator.org Developers 2007-2008")] +[assembly : AssemblyTrademark("")] +[assembly : AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. + +[assembly : ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM + +[assembly : Guid("a08e20c7-f191-4137-b1f0-9291408fa521")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// + +[assembly : AssemblyVersion("1.0.0.0")] +[assembly : AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/AssetBase.cs b/OpenSim/Framework/AssetBase.cs index d28f536bea..4d5adea667 100644 --- a/OpenSim/Framework/AssetBase.cs +++ b/OpenSim/Framework/AssetBase.cs @@ -1,56 +1,56 @@ -/* -* 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 libsecondlife; - -namespace OpenSim.Framework -{ - [Serializable] - public class AssetBase - { - public byte[] Data; - public LLUUID FullID; - public sbyte Type; - public sbyte InvType; - public string Name = ""; - public string Description = ""; - public string MediaURL = "";//rex - public bool Local = false; - public bool Temporary = false; - - public AssetBase() - { - } - - public AssetBase(LLUUID assetId, string name) - { - FullID = assetId; - Name = name; - } - } -} \ No newline at end of file +/* +* 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 libsecondlife; + +namespace OpenSim.Framework +{ + [Serializable] + public class AssetBase + { + public byte[] Data; + public LLUUID FullID; + public sbyte Type; + public sbyte InvType; + public string Name = String.Empty; + public string Description = String.Empty; + public string MediaURL = "";//rex + public bool Local = false; + public bool Temporary = false; + + public AssetBase() + { + } + + public AssetBase(LLUUID assetId, string name) + { + FullID = assetId; + Name = name; + } + } +} diff --git a/OpenSim/Framework/AssetConfig.cs b/OpenSim/Framework/AssetConfig.cs index c43097084a..68c6ca12e9 100644 --- a/OpenSim/Framework/AssetConfig.cs +++ b/OpenSim/Framework/AssetConfig.cs @@ -1,83 +1,86 @@ -/* -* 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. -* -*/ - -namespace OpenSim.Framework -{ - /// - /// UserConfig -- For User Server Configuration - /// - public class AssetConfig - { - public string DefaultStartupMsg = ""; - - public string DatabaseProvider = ""; - - public static uint DefaultHttpPort = 8003; - public uint HttpPort = DefaultHttpPort; - - private ConfigurationMember configMember; - - public AssetConfig(string description, string filename) - { - configMember = - new ConfigurationMember(filename, description, loadConfigurationOptions, handleIncomingConfiguration, true); - configMember.performConfigurationRetrieve(); - } - - public void loadConfigurationOptions() - { - configMember.addConfigurationOption("default_startup_message", - ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, - "Default Startup Message", "Welcome to OGS", false); - - configMember.addConfigurationOption("database_provider", ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "DLL for database provider", "OpenSim.Framework.Data.MySQL.dll", false); - - configMember.addConfigurationOption("http_port", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, - "Http Listener port", DefaultHttpPort.ToString(), false); - } - - public bool handleIncomingConfiguration(string configuration_key, object configuration_result) - { - switch (configuration_key) - { - case "default_startup_message": - DefaultStartupMsg = (string) configuration_result; - break; - case "database_provider": - DatabaseProvider = (string) configuration_result; - break; - case "http_port": - HttpPort = (uint) configuration_result; - break; - } - - return true; - } - } -} \ No newline at end of file +/* +* 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 OpenSim.Framework.Console; + +namespace OpenSim.Framework +{ + /// + /// UserConfig -- For User Server Configuration + /// + public class AssetConfig + { + public string DefaultStartupMsg = String.Empty; + + public string DatabaseProvider = String.Empty; + + public static uint DefaultHttpPort = 8003; + public uint HttpPort = DefaultHttpPort; + + private ConfigurationMember configMember; + + public AssetConfig(string description, string filename) + { + configMember = + new ConfigurationMember(filename, description, loadConfigurationOptions, handleIncomingConfiguration, true); + configMember.performConfigurationRetrieve(); + } + + public void loadConfigurationOptions() + { + configMember.addConfigurationOption("default_startup_message", + ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "Default Startup Message", "Welcome to OGS", false); + + configMember.addConfigurationOption("database_provider", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "DLL for database provider", "OpenSim.Framework.Data.MySQL.dll", false); + + configMember.addConfigurationOption("http_port", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Http Listener port", DefaultHttpPort.ToString(), false); + } + + public bool handleIncomingConfiguration(string configuration_key, object configuration_result) + { + switch (configuration_key) + { + case "default_startup_message": + DefaultStartupMsg = (string) configuration_result; + break; + case "database_provider": + DatabaseProvider = (string) configuration_result; + break; + case "http_port": + HttpPort = (uint) configuration_result; + break; + } + + return true; + } + } +} diff --git a/OpenSim/Framework/AssetLoader/Filesystem/AssetLoaderFileSystem.cs b/OpenSim/Framework/AssetLoader/Filesystem/AssetLoaderFileSystem.cs index b064d2cb3c..d1f704402d 100644 --- a/OpenSim/Framework/AssetLoader/Filesystem/AssetLoaderFileSystem.cs +++ b/OpenSim/Framework/AssetLoader/Filesystem/AssetLoaderFileSystem.cs @@ -1,164 +1,164 @@ -/* -* 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.Generic; -using System.IO; -using System.Xml; - -using libsecondlife; -using Nini.Config; - -using OpenSim.Framework; -using OpenSim.Framework.Console; - -/// -/// Loads assets from the filesystem location. Not yet a plugin, though it should be. -/// -namespace OpenSim.Framework.AssetLoader.Filesystem -{ - public class AssetLoaderFileSystem : IAssetLoader - { - protected AssetBase CreateAsset(string assetIdStr, string name, string path, bool isImage) - { - AssetBase asset = new AssetBase( - new LLUUID(assetIdStr), - name - ); - - if (!String.IsNullOrEmpty(path)) - { - MainLog.Instance.Verbose("ASSETS", "Loading: [{0}][{1}]", name, path); - - LoadAsset(asset, isImage, path); - } - else - { - MainLog.Instance.Verbose("ASSETS", "Instantiated: [{0}]", name); - } - - return asset; - } - - protected void LoadAsset(AssetBase info, bool image, string path) - { - FileInfo fInfo = new FileInfo(path); - long numBytes = fInfo.Length; - FileStream fStream = new FileStream(path, FileMode.Open, FileAccess.Read); - byte[] idata = new byte[numBytes]; - BinaryReader br = new BinaryReader(fStream); - idata = br.ReadBytes((int) numBytes); - br.Close(); - fStream.Close(); - info.Data = idata; - //info.loaded=true; - } - - public void ForEachDefaultXmlAsset(Action action) - { - string assetSetFilename = Path.Combine(Util.assetsDir(), "AssetSets.xml"); - - ForEachDefaultXmlAsset(assetSetFilename, action); - } - - public void ForEachDefaultXmlAsset(string assetSetFilename, Action action) - { - List assets = new List(); - if (File.Exists(assetSetFilename)) - { - string assetSetPath = "ERROR"; - - try - { - XmlConfigSource source = new XmlConfigSource(assetSetFilename); - - for (int i = 0; i < source.Configs.Count; i++) - { - assetSetPath = source.Configs[i].GetString("file", ""); - - LoadXmlAssetSet(Path.Combine(Util.assetsDir(), assetSetPath), assets); - } - } - catch (XmlException e) - { - MainLog.Instance.Error("ASSETS", "Error loading {0} : {1}", assetSetPath, e); - } - } - else - { - MainLog.Instance.Error( - "ASSETS", - "Asset set control file assets/AssetSets.xml does not exist! No assets loaded."); - } - - assets.ForEach(action); - } - - /// - /// Use the asset set information at path to load assets - /// - /// - /// - protected void LoadXmlAssetSet(string assetSetPath, List assets) - { - MainLog.Instance.Verbose("ASSETS", "Loading asset set {0}", assetSetPath); - - if (File.Exists(assetSetPath)) - { - try - { - XmlConfigSource source = new XmlConfigSource(assetSetPath); - String dir = Path.GetDirectoryName(assetSetPath); - - for (int i = 0; i < source.Configs.Count; i++) - { - string assetIdStr = source.Configs[i].GetString("assetID", LLUUID.Random().ToString()); - string name = source.Configs[i].GetString("name", ""); - sbyte type = (sbyte) source.Configs[i].GetInt("assetType", 0); - sbyte invType = (sbyte) source.Configs[i].GetInt("inventoryType", 0); - string assetPath = Path.Combine(dir, source.Configs[i].GetString("fileName", "")); - - AssetBase newAsset = CreateAsset(assetIdStr, name, assetPath, false); - - newAsset.Type = type; - newAsset.InvType = invType; - assets.Add(newAsset); - } - } - catch (XmlException e) - { - MainLog.Instance.Error("ASSETS", "Error loading {0} : {1}", assetSetPath, e); - } - } - else - { - MainLog.Instance.Error("ASSETS", "Asset set file {0} does not exist!", assetSetPath); - } - } - } -} +/* +* 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.Generic; +using System.IO; +using System.Xml; + +using libsecondlife; +using Nini.Config; + +using OpenSim.Framework; +using OpenSim.Framework.Console; + +/// +/// Loads assets from the filesystem location. Not yet a plugin, though it should be. +/// +namespace OpenSim.Framework.AssetLoader.Filesystem +{ + public class AssetLoaderFileSystem : IAssetLoader + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + protected AssetBase CreateAsset(string assetIdStr, string name, string path, bool isImage) + { + AssetBase asset = new AssetBase( + new LLUUID(assetIdStr), + name + ); + + if (!String.IsNullOrEmpty(path)) + { + m_log.InfoFormat("[ASSETS]: Loading: [{0}][{1}]", name, path); + + LoadAsset(asset, isImage, path); + } + else + { + m_log.InfoFormat("[ASSETS]: Instantiated: [{0}]", name); + } + + return asset; + } + + protected void LoadAsset(AssetBase info, bool image, string path) + { + FileInfo fInfo = new FileInfo(path); + long numBytes = fInfo.Length; + FileStream fStream = new FileStream(path, FileMode.Open, FileAccess.Read); + byte[] idata = new byte[numBytes]; + BinaryReader br = new BinaryReader(fStream); + idata = br.ReadBytes((int) numBytes); + br.Close(); + fStream.Close(); + info.Data = idata; + //info.loaded=true; + } + + public void ForEachDefaultXmlAsset(Action action) + { + string assetSetFilename = Path.Combine(Util.assetsDir(), "AssetSets.xml"); + + ForEachDefaultXmlAsset(assetSetFilename, action); + } + + public void ForEachDefaultXmlAsset(string assetSetFilename, Action action) + { + List assets = new List(); + if (File.Exists(assetSetFilename)) + { + string assetSetPath = "ERROR"; + + try + { + XmlConfigSource source = new XmlConfigSource(assetSetFilename); + + for (int i = 0; i < source.Configs.Count; i++) + { + assetSetPath = source.Configs[i].GetString("file", String.Empty); + + LoadXmlAssetSet(Path.Combine(Util.assetsDir(), assetSetPath), assets); + } + } + catch (XmlException e) + { + m_log.ErrorFormat("[ASSETS]: Error loading {0} : {1}", assetSetPath, e); + } + } + else + { + m_log.Error("[ASSETS]: Asset set control file assets/AssetSets.xml does not exist! No assets loaded."); + } + + assets.ForEach(action); + } + + /// + /// Use the asset set information at path to load assets + /// + /// + /// + protected void LoadXmlAssetSet(string assetSetPath, List assets) + { + m_log.InfoFormat("[ASSETS]: Loading asset set {0}", assetSetPath); + + if (File.Exists(assetSetPath)) + { + try + { + XmlConfigSource source = new XmlConfigSource(assetSetPath); + String dir = Path.GetDirectoryName(assetSetPath); + + for (int i = 0; i < source.Configs.Count; i++) + { + string assetIdStr = source.Configs[i].GetString("assetID", LLUUID.Random().ToString()); + string name = source.Configs[i].GetString("name", String.Empty); + sbyte type = (sbyte) source.Configs[i].GetInt("assetType", 0); + sbyte invType = (sbyte) source.Configs[i].GetInt("inventoryType", 0); + string assetPath = Path.Combine(dir, source.Configs[i].GetString("fileName", String.Empty)); + + AssetBase newAsset = CreateAsset(assetIdStr, name, assetPath, false); + + newAsset.Type = type; + newAsset.InvType = invType; + assets.Add(newAsset); + } + } + catch (XmlException e) + { + m_log.ErrorFormat("[ASSETS]: Error loading {0} : {1}", assetSetPath, e); + } + } + else + { + m_log.ErrorFormat("[ASSETS]: Asset set file {0} does not exist!", assetSetPath); + } + } + } +} diff --git a/OpenSim/Framework/AssetRequest.cs b/OpenSim/Framework/AssetRequest.cs index 163ab701df..68a5f8132f 100644 --- a/OpenSim/Framework/AssetRequest.cs +++ b/OpenSim/Framework/AssetRequest.cs @@ -1,10 +1,38 @@ -using libsecondlife; - -namespace OpenSim.Framework -{ - public struct AssetRequest - { - public LLUUID AssetID; - public bool IsTexture; - } -} \ No newline at end of file +/* +* 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 libsecondlife; + +namespace OpenSim.Framework +{ + public struct AssetRequest + { + public LLUUID AssetID; + public bool IsTexture; + } +} diff --git a/OpenSim/Framework/BlockingQueue.cs b/OpenSim/Framework/BlockingQueue.cs index b065d7a629..e72884c013 100644 --- a/OpenSim/Framework/BlockingQueue.cs +++ b/OpenSim/Framework/BlockingQueue.cs @@ -1,68 +1,73 @@ -/* -* 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.Collections.Generic; -using System.Threading; - -namespace OpenSim.Framework -{ - public class BlockingQueue - { - private readonly Queue m_queue = new Queue(); - private readonly object m_queueSync = new object(); - - public void Enqueue(T value) - { - lock (m_queueSync) - { - m_queue.Enqueue(value); - Monitor.Pulse(m_queueSync); - } - } - - public T Dequeue() - { - lock (m_queueSync) - { - if (m_queue.Count < 1) - { - Monitor.Wait(m_queueSync); - } - - return m_queue.Dequeue(); - } - } - - public bool Contains(T item) - { - lock (m_queueSync) - { - return m_queue.Contains(item); - } - } - } -} \ No newline at end of file +/* +* 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.Collections.Generic; +using System.Threading; + +namespace OpenSim.Framework +{ + public class BlockingQueue + { + private readonly Queue m_queue = new Queue(); + private readonly object m_queueSync = new object(); + + public void Enqueue(T value) + { + lock (m_queueSync) + { + m_queue.Enqueue(value); + Monitor.Pulse(m_queueSync); + } + } + + public T Dequeue() + { + lock (m_queueSync) + { + if (m_queue.Count < 1) + { + Monitor.Wait(m_queueSync); + } + + return m_queue.Dequeue(); + } + } + + public bool Contains(T item) + { + lock (m_queueSync) + { + return m_queue.Contains(item); + } + } + + public int Count() + { + return m_queue.Count; + } + } +} diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index 60e9be3368..bae61cdbd9 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -1,50 +1,53 @@ -/* -* 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; - -namespace OpenSim.Framework -{ - [Serializable] - public class ChildAgentDataUpdate - { - public ChildAgentDataUpdate() - { - } - - public sLLVector3 Position; - public ulong regionHandle; - public float drawdistance; - public sLLVector3 cameraPosition; - public sLLVector3 Velocity; - public float AVHeight; - public Guid AgentID; - public float godlevel; - public byte[] throttles; - } -} \ No newline at end of file +/* +* 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; + +namespace OpenSim.Framework +{ + [Serializable] + public class ChildAgentDataUpdate + { + public ChildAgentDataUpdate() + { + } + + public sLLVector3 Position; + public ulong regionHandle; + public float drawdistance; + public sLLVector3 cameraPosition; + public sLLVector3 Velocity; + public float AVHeight; + public Guid AgentID; + public float godlevel; + public byte[] throttles; + public bool alwaysrun; + public Guid ActiveGroupID; + public uint GroupAccess; + } +} diff --git a/OpenSim/Framework/ClientManager.cs b/OpenSim/Framework/ClientManager.cs index 9e8e91c40b..cfdcbf05a6 100644 --- a/OpenSim/Framework/ClientManager.cs +++ b/OpenSim/Framework/ClientManager.cs @@ -1,181 +1,197 @@ -/* -* 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.Collections.Generic; -using libsecondlife; -using libsecondlife.Packets; - -namespace OpenSim.Framework -{ - public delegate void ForEachClientDelegate(IClientAPI client); - - public class ClientManager - { - private Dictionary m_clients; - - public void ForEachClient(ForEachClientDelegate whatToDo) - { - - // Wasteful, I know - IClientAPI[] LocalClients = new IClientAPI[0]; - lock (m_clients) - { - LocalClients = new IClientAPI[m_clients.Count]; - m_clients.Values.CopyTo(LocalClients, 0); - } - - for (int i = 0; i < LocalClients.Length; i++) - { - try - { - whatToDo(LocalClients[i]); - } - catch (System.Exception e) - { - OpenSim.Framework.Console.MainLog.Instance.Warn("CLIENT", "Unable to do ForEachClient for one of the clients" + "\n Reason: " + e.ToString()); - } - } - } - - public ClientManager() - { - m_clients = new Dictionary(); - } - - private void Remove(uint id) - { - m_clients.Remove(id); - } - - public void Add(uint id, IClientAPI client) - { - m_clients.Add(id, client); - } - - public void InPacket(uint circuitCode, Packet packet) - { - IClientAPI client; - - if (m_clients.TryGetValue(circuitCode, out client)) - { - client.InPacket(packet); - } - } - - public void CloseAllAgents(uint circuitCode) - { - IClientAPI client; - - if (m_clients.TryGetValue(circuitCode, out client)) - { - CloseAllCircuits(client.AgentId); - } - } - - public void CloseAllCircuits(LLUUID agentId) - { - uint[] circuits = GetAllCircuits(agentId); - // We're using a for loop here so changes to the circuits don't cause it to completely fail. - - for (int i = 0; i < circuits.Length; i++) - { - IClientAPI client; - try - { - - if (m_clients.TryGetValue(circuits[i], out client)) - { - Remove(client.CircuitCode); - client.Close(false); - } - } - catch (System.Exception e) - { - OpenSim.Framework.Console.MainLog.Instance.Error("CLIENT", string.Format("Unable to shutdown circuit for: {0}\n Reason: {1}", agentId, e)); - } - } - - - } - - private uint[] GetAllCircuits(LLUUID agentId) - { - List circuits = new List(); - // Wasteful, I know - IClientAPI[] LocalClients = new IClientAPI[0]; - lock (m_clients) - { - LocalClients = new IClientAPI[m_clients.Count]; - m_clients.Values.CopyTo(LocalClients, 0); - } - - - for (int i = 0; i < LocalClients.Length; i++ ) - { - if (LocalClients[i].AgentId == agentId) - { - circuits.Add(LocalClients[i].CircuitCode); - } - } - return circuits.ToArray(); - } - - - public void ViewerEffectHandler(IClientAPI sender, ViewerEffectPacket.EffectBlock[] effectBlock) - { - ViewerEffectPacket packet = (ViewerEffectPacket) PacketPool.Instance.GetPacket(PacketType.ViewerEffect); - // TODO: don't create new blocks if recycling an old packet - packet.Effect = effectBlock; - - // Wasteful, I know - IClientAPI[] LocalClients = new IClientAPI[0]; - lock (m_clients) - { - LocalClients = new IClientAPI[m_clients.Count]; - m_clients.Values.CopyTo(LocalClients, 0); - } - - - for (int i = 0; i < LocalClients.Length; i++) - { - if (LocalClients[i].AgentId != sender.AgentId) - { - packet.AgentData.AgentID = LocalClients[i].AgentId; - packet.AgentData.SessionID = LocalClients[i].SessionId; - LocalClients[i].OutPacket(packet, ThrottleOutPacketType.Task); - } - - } - } - - public bool TryGetClient(uint circuitId, out IClientAPI user) - { - return m_clients.TryGetValue(circuitId, out user); - } - } -} +/* +* 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.Generic; +using libsecondlife; +using libsecondlife.Packets; + +namespace OpenSim.Framework +{ + public delegate void ForEachClientDelegate(IClientAPI client); + + public class ClientManager + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private Dictionary m_clients; + + public void ForEachClient(ForEachClientDelegate whatToDo) + { + // Wasteful, I know + IClientAPI[] LocalClients = new IClientAPI[0]; + lock (m_clients) + { + LocalClients = new IClientAPI[m_clients.Count]; + m_clients.Values.CopyTo(LocalClients, 0); + } + + for (int i = 0; i < LocalClients.Length; i++) + { + try + { + whatToDo(LocalClients[i]); + } + catch (System.Exception e) + { + m_log.Warn("[CLIENT]: Unable to do ForEachClient for one of the clients" + "\n Reason: " + e.ToString()); + } + } + } + + public ClientManager() + { + m_clients = new Dictionary(); + } + + public void Remove(uint id) + { + //m_log.InfoFormat("[CLIENT]: Removing client with code {0}, current count {1}", id, m_clients.Count); + lock (m_clients) + { + m_clients.Remove(id); + } + m_log.InfoFormat("[CLIENT]: Removed client with code {0}, new client count {1}", id, m_clients.Count); + } + + public void Add(uint id, IClientAPI client) + { + lock (m_clients) + { + m_clients.Add(id, client); + } + } + + public void InPacket(uint circuitCode, Packet packet) + { + IClientAPI client; + bool tryGetRet = false; + lock (m_clients) + tryGetRet = m_clients.TryGetValue(circuitCode, out client); + if(tryGetRet) + { + client.InPacket(packet); + } + } + + public void CloseAllAgents(uint circuitCode) + { + IClientAPI client; + bool tryGetRet = false; + lock (m_clients) + tryGetRet = m_clients.TryGetValue(circuitCode, out client); + if (tryGetRet) + { + CloseAllCircuits(client.AgentId); + } + } + + public void CloseAllCircuits(LLUUID agentId) + { + uint[] circuits = GetAllCircuits(agentId); + // We're using a for loop here so changes to the circuits don't cause it to completely fail. + + for (int i = 0; i < circuits.Length; i++) + { + IClientAPI client; + try + { + bool tryGetRet = false; + lock (m_clients) + tryGetRet = m_clients.TryGetValue(circuits[i], out client); + if(tryGetRet) + { + Remove(client.CircuitCode); + client.Close(false); + } + } + catch (System.Exception e) + { + m_log.Error(string.Format("[CLIENT]: Unable to shutdown circuit for: {0}\n Reason: {1}", agentId, e)); + } + } + } + + private uint[] GetAllCircuits(LLUUID agentId) + { + List circuits = new List(); + // Wasteful, I know + IClientAPI[] LocalClients = new IClientAPI[0]; + lock (m_clients) + { + LocalClients = new IClientAPI[m_clients.Count]; + m_clients.Values.CopyTo(LocalClients, 0); + } + + for (int i = 0; i < LocalClients.Length; i++ ) + { + if (LocalClients[i].AgentId == agentId) + { + circuits.Add(LocalClients[i].CircuitCode); + } + } + return circuits.ToArray(); + } + + + public void ViewerEffectHandler(IClientAPI sender, ViewerEffectPacket.EffectBlock[] effectBlock) + { + ViewerEffectPacket packet = (ViewerEffectPacket) PacketPool.Instance.GetPacket(PacketType.ViewerEffect); + // TODO: don't create new blocks if recycling an old packet + packet.Effect = effectBlock; + + // Wasteful, I know + IClientAPI[] LocalClients = new IClientAPI[0]; + lock (m_clients) + { + LocalClients = new IClientAPI[m_clients.Count]; + m_clients.Values.CopyTo(LocalClients, 0); + } + + for (int i = 0; i < LocalClients.Length; i++) + { + if (LocalClients[i].AgentId != sender.AgentId) + { + packet.AgentData.AgentID = LocalClients[i].AgentId; + packet.AgentData.SessionID = LocalClients[i].SessionId; + packet.Header.Reliable = false; + LocalClients[i].OutPacket(packet, ThrottleOutPacketType.Task); + } + + } + } + + public bool TryGetClient(uint circuitId, out IClientAPI user) + { + lock (m_clients) + { + return m_clients.TryGetValue(circuitId, out user); + } + } + } +} diff --git a/OpenSim/Framework/Communications/CAPSService.cs b/OpenSim/Framework/Communications/CAPSService.cs index d49aba5977..f83f0da6ac 100644 --- a/OpenSim/Framework/Communications/CAPSService.cs +++ b/OpenSim/Framework/Communications/CAPSService.cs @@ -1,54 +1,54 @@ -/* -* 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 OpenSim.Framework.Servers; - -namespace OpenSim.Framework.Communications -{ - public class CAPSService - { - private BaseHttpServer m_server; - - public CAPSService(BaseHttpServer httpServer) - { - m_server = httpServer; - 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 ""; - } - } -} \ No newline at end of file +/* +* 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 OpenSim.Framework.Servers; + +namespace OpenSim.Framework.Communications +{ + public class CAPSService + { + private readonly BaseHttpServer m_server; + + public CAPSService(BaseHttpServer httpServer) + { + m_server = httpServer; + 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 System.String.Empty; + } + } +} diff --git a/OpenSim/Framework/Communications/Cache/AssetTransactions.cs b/OpenSim/Framework/Communications/Cache/AgentAssetTransactions.cs similarity index 71% rename from OpenSim/Framework/Communications/Cache/AssetTransactions.cs rename to OpenSim/Framework/Communications/Cache/AgentAssetTransactions.cs index 328bba8947..4aefe833da 100644 --- a/OpenSim/Framework/Communications/Cache/AssetTransactions.cs +++ b/OpenSim/Framework/Communications/Cache/AgentAssetTransactions.cs @@ -1,444 +1,558 @@ -/* -* 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.Generic; -using System.IO; -using libsecondlife; -using libsecondlife.Packets; -using OpenSim.Framework.Servers; -using OpenSim.Region.Capabilities; - -namespace OpenSim.Framework.Communications.Cache -{ - public class AgentAssetTransactions - { - // Fields - public List CapsUploaders = new List(); - public List NotecardUpdaters = new List(); - public LLUUID UserID; - public Dictionary XferUploaders = new Dictionary(); - public AssetTransactionManager Manager; - private bool m_dumpAssetsToFile; - - // Methods - public AgentAssetTransactions(LLUUID agentID, AssetTransactionManager manager, bool dumpAssetsToFile) - { - UserID = agentID; - Manager = manager; - m_dumpAssetsToFile = dumpAssetsToFile; - } - - public AssetCapsUploader RequestCapsUploader() - { - AssetCapsUploader uploader = new AssetCapsUploader(); - CapsUploaders.Add(uploader); - return uploader; - } - - public NoteCardCapsUpdate RequestNoteCardUpdater() - { - NoteCardCapsUpdate update = new NoteCardCapsUpdate(); - NotecardUpdaters.Add(update); - return update; - } - - public AssetXferUploader RequestXferUploader(LLUUID transactionID) - { - if (!XferUploaders.ContainsKey(transactionID)) - { - AssetXferUploader uploader = new AssetXferUploader(this, m_dumpAssetsToFile); - - XferUploaders.Add(transactionID, uploader); - return uploader; - } - return null; - } - - public void HandleXfer(ulong xferID, uint packetID, byte[] data) - { - foreach (AssetXferUploader uploader in XferUploaders.Values) - { - if (uploader.XferID == xferID) - { - uploader.HandleXferPacket(xferID, packetID, data); - break; - } - } - } - - public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, - uint callbackID, string description, string name, sbyte invType, - sbyte type, byte wearableType, uint nextOwnerMask) - { - if (XferUploaders.ContainsKey(transactionID)) - { - XferUploaders[transactionID].RequestCreateInventoryItem(remoteClient, transactionID, folderID, - callbackID, description, name, invType, type, - wearableType, nextOwnerMask); - } - } - - public AssetBase GetTransactionAsset(LLUUID transactionID) - { - if (XferUploaders.ContainsKey(transactionID)) - { - return XferUploaders[transactionID].GetAssetData(); - } - return null; - } - - // Nested Types - public class AssetXferUploader - { - // Fields - public bool AddToInventory; - public AssetBase Asset; - public LLUUID InventFolder = LLUUID.Zero; - private IClientAPI ourClient; - public LLUUID TransactionID = LLUUID.Zero; - public bool UploadComplete; - public ulong XferID; - private string m_name = ""; - private string m_description = ""; - private sbyte type = 0; - private sbyte invType = 0; - private uint nextPerm = 0; - private bool m_finished = false; - private bool m_createItem = false; - private AgentAssetTransactions m_userTransactions; - private bool m_storeLocal; - private bool m_dumpAssetToFile; - - public AssetXferUploader(AgentAssetTransactions transactions, bool dumpAssetToFile) - { - m_userTransactions = transactions; - m_dumpAssetToFile = dumpAssetToFile; - } - - // Methods - public void HandleXferPacket(ulong xferID, uint packetID, byte[] data) - { - if (XferID == xferID) - { - if (Asset.Data.Length > 1) - { - byte[] destinationArray = new byte[Asset.Data.Length + data.Length]; - Array.Copy(Asset.Data, 0, destinationArray, 0, Asset.Data.Length); - Array.Copy(data, 0, destinationArray, Asset.Data.Length, data.Length); - Asset.Data = destinationArray; - } - else - { - byte[] buffer2 = new byte[data.Length - 4]; - Array.Copy(data, 4, buffer2, 0, data.Length - 4); - Asset.Data = buffer2; - } - ConfirmXferPacketPacket newPack = new ConfirmXferPacketPacket(); - newPack.XferID.ID = xferID; - newPack.XferID.Packet = packetID; - ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); - if ((packetID & 0x80000000) != 0) - { - SendCompleteMessage(); - } - } - } - - public void Initialise(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data, - bool storeLocal, bool tempFile) - { - ourClient = remoteClient; - Asset = new AssetBase(); - Asset.FullID = assetID; - Asset.InvType = type; - Asset.Type = type; - Asset.Data = data; - Asset.Name = "blank"; - Asset.Description = "empty"; - Asset.Local = storeLocal; - Asset.Temporary = tempFile; - - TransactionID = transaction; - m_storeLocal = storeLocal; - if (Asset.Data.Length > 2) - { - SendCompleteMessage(); - } - else - { - ReqestStartXfer(); - } - } - - protected void ReqestStartXfer() - { - UploadComplete = false; - XferID = Util.GetNextXferID(); - RequestXferPacket newPack = new RequestXferPacket(); - newPack.XferID.ID = XferID; - newPack.XferID.VFileType = Asset.Type; - newPack.XferID.VFileID = Asset.FullID; - newPack.XferID.FilePath = 0; - newPack.XferID.Filename = new byte[0]; - ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); - } - - protected void SendCompleteMessage() - { - UploadComplete = true; - AssetUploadCompletePacket newPack = new AssetUploadCompletePacket(); - newPack.AssetBlock.Type = Asset.Type; - newPack.AssetBlock.Success = true; - newPack.AssetBlock.UUID = Asset.FullID; - ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); - m_finished = true; - if (m_createItem) - { - DoCreateItem(); - } - else if (m_storeLocal) - { - m_userTransactions.Manager.CommsManager.AssetCache.AddAsset(Asset); - } - - // Console.WriteLine("upload complete "+ this.TransactionID); - - if (m_dumpAssetToFile) - { - DateTime now = DateTime.Now; - string filename = - String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat", now.Year, now.Month, now.Day, - now.Hour, now.Minute, now.Second, Asset.Name, Asset.Type); - SaveAssetToFile(filename, Asset.Data); - } - } - ///Left this in and commented in case there are unforseen issues - //private void SaveAssetToFile(string filename, byte[] data) - //{ - // FileStream fs = File.Create(filename); - // BinaryWriter bw = new BinaryWriter(fs); - // bw.Write(data); - // bw.Close(); - // fs.Close(); - //} - private void SaveAssetToFile(string filename, byte[] data) - { - string assetPath = "UserAssets"; - if (!Directory.Exists(assetPath)) - { - Directory.CreateDirectory(assetPath); - } - FileStream fs = File.Create(Path.Combine(assetPath, filename)); - BinaryWriter bw = new BinaryWriter(fs); - bw.Write(data); - bw.Close(); - fs.Close(); - } - - public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, - uint callbackID, string description, string name, sbyte invType, - sbyte type, byte wearableType, uint nextOwnerMask) - { - if (TransactionID == transactionID) - { - InventFolder = folderID; - m_name = name; - m_description = description; - this.type = type; - this.invType = invType; - nextPerm = nextOwnerMask; - Asset.Name = name; - Asset.Description = description; - Asset.Type = type; - Asset.InvType = invType; - m_createItem = true; - if (m_finished) - { - DoCreateItem(); - } - } - } - - private void DoCreateItem() - { - //really need to fix this call, if lbsa71 saw this he would die. - m_userTransactions.Manager.CommsManager.AssetCache.AddAsset(Asset); - CachedUserInfo userInfo = - m_userTransactions.Manager.CommsManager.UserProfileCacheService.GetUserDetails(ourClient.AgentId); - if (userInfo != null) - { - InventoryItemBase item = new InventoryItemBase(); - item.avatarID = ourClient.AgentId; - item.creatorsID = ourClient.AgentId; - item.inventoryID = LLUUID.Random(); - item.assetID = Asset.FullID; - item.inventoryDescription = m_description; - item.inventoryName = m_name; - item.assetType = type; - item.invType = invType; - item.parentFolderID = InventFolder; - item.inventoryCurrentPermissions = 2147483647; - item.inventoryNextPermissions = nextPerm; - - userInfo.AddItem(ourClient.AgentId, item); - ourClient.SendInventoryItemCreateUpdate(item); - } - } - - public void UpdateInventoryItem(LLUUID itemID) - { - } - - public AssetBase GetAssetData() - { - if (m_finished) - { - return Asset; - } - return null; - } - } - - #region Nested Classes currently not in use (waiting for them to be enabled) - - public class AssetCapsUploader - { - // Fields - private BaseHttpServer httpListener; - private LLUUID inventoryItemID; - private string m_assetDescription = ""; - private string m_assetName = ""; - private LLUUID m_folderID; - private LLUUID newAssetID; - private bool m_dumpImageToFile; - private string uploaderPath = ""; - - // Events - public event UpLoadedAsset OnUpLoad; - - // Methods - public void Initialise(string assetName, string assetDescription, LLUUID assetID, LLUUID inventoryItem, - LLUUID folderID, string path, BaseHttpServer httpServer, bool dumpImageToFile) - { - m_assetName = assetName; - m_assetDescription = assetDescription; - m_folderID = folderID; - newAssetID = assetID; - inventoryItemID = inventoryItem; - uploaderPath = path; - httpListener = httpServer; - m_dumpImageToFile = dumpImageToFile; - } - - private void SaveImageToFile(string filename, byte[] data) - { - FileStream output = File.Create(filename); - BinaryWriter writer = new BinaryWriter(output); - writer.Write(data); - writer.Close(); - output.Close(); - } - - public string uploaderCaps(byte[] data, string path, string param) - { - LLUUID inventoryItemID = this.inventoryItemID; - string text = ""; - LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete(); - complete.new_asset = newAssetID.ToString(); - complete.new_inventory_item = inventoryItemID; - complete.state = "complete"; - text = LLSDHelpers.SerialiseLLSDReply(complete); - httpListener.RemoveStreamHandler("POST", uploaderPath); - if (m_dumpImageToFile) - { - SaveImageToFile(m_assetName + ".jp2", data); - } - if (OnUpLoad != null) - { - OnUpLoad(m_assetName, "description", newAssetID, inventoryItemID, LLUUID.Zero, data, "", ""); - } - return text; - } - } - - public class NoteCardCapsUpdate - { - // Fields - private BaseHttpServer httpListener; - private LLUUID inventoryItemID; - private string m_assetName = ""; - private LLUUID newAssetID; - private bool SaveImages = false; - private string uploaderPath = ""; - - // Events - public event UpLoadedAsset OnUpLoad; - - // Methods - public void Initialise(LLUUID inventoryItem, string path, BaseHttpServer httpServer) - { - inventoryItemID = inventoryItem; - uploaderPath = path; - httpListener = httpServer; - newAssetID = LLUUID.Random(); - } - - private void SaveImageToFile(string filename, byte[] data) - { - FileStream output = File.Create(filename); - BinaryWriter writer = new BinaryWriter(output); - writer.Write(data); - writer.Close(); - output.Close(); - } - - public string uploaderCaps(byte[] data, string path, string param) - { - LLUUID inventoryItemID = this.inventoryItemID; - string text = ""; - LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete(); - complete.new_asset = newAssetID.ToString(); - complete.new_inventory_item = inventoryItemID; - complete.state = "complete"; - text = LLSDHelpers.SerialiseLLSDReply(complete); - httpListener.RemoveStreamHandler("POST", uploaderPath); - if (SaveImages) - { - SaveImageToFile(m_assetName + "notecard.txt", data); - } - if (OnUpLoad != null) - { - OnUpLoad(m_assetName, "description", newAssetID, inventoryItemID, LLUUID.Zero, data, "", ""); - } - return text; - } - } - - #endregion - } -} +/* +* 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. +* +*/ +//moved to a module, left here until the module is found to have no problems +/* +using System; +using System.Collections.Generic; +using System.IO; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Servers; +using OpenSim.Region.Capabilities; + +namespace OpenSim.Framework.Communications.Cache +{ + /// + /// Manage asset transactions for a single agent. + /// + public class AgentAssetTransactions + { + private static readonly log4net.ILog m_log + = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + // Fields + public List CapsUploaders = new List(); + public List NotecardUpdaters = new List(); + public LLUUID UserID; + public Dictionary XferUploaders = new Dictionary(); + public AgentAssetTransactionsManager Manager; + private bool m_dumpAssetsToFile; + + // Methods + public AgentAssetTransactions(LLUUID agentID, AgentAssetTransactionsManager manager, bool dumpAssetsToFile) + { + UserID = agentID; + Manager = manager; + m_dumpAssetsToFile = dumpAssetsToFile; + } + + public AssetCapsUploader RequestCapsUploader() + { + AssetCapsUploader uploader = new AssetCapsUploader(); + CapsUploaders.Add(uploader); + return uploader; + } + + public NoteCardCapsUpdate RequestNoteCardUpdater() + { + NoteCardCapsUpdate update = new NoteCardCapsUpdate(); + NotecardUpdaters.Add(update); + return update; + } + + public AssetXferUploader RequestXferUploader(LLUUID transactionID) + { + if (!XferUploaders.ContainsKey(transactionID)) + { + AssetXferUploader uploader = new AssetXferUploader(this, m_dumpAssetsToFile); + + lock (XferUploaders) + { + XferUploaders.Add(transactionID, uploader); + } + + return uploader; + } + return null; + } + + public void HandleXfer(ulong xferID, uint packetID, byte[] data) + { + AssetXferUploader uploaderFound = null; + + lock (XferUploaders) + { + foreach (AssetXferUploader uploader in XferUploaders.Values) + { + if (uploader.XferID == xferID) + { + if (uploader.HandleXferPacket(xferID, packetID, data)) + { + uploaderFound = uploader; + } + + break; + } + } + + // Remove the uploader once the uploader is complete + //[don't think we can be sure a upload has finished from here, uploads are multi part things] + // [or maybe we can if we do more checking like data lenght checks] + if (uploaderFound != null) + { +// m_log.InfoFormat( +// "[ASSET TRANSACTIONS] Removing asset xfer uploader with transfer id {0}, transaction {1}", +// xferID, uploaderFound.TransactionID); + + // XferUploaders.Remove(uploaderFound.TransactionID); + + //m_log.InfoFormat("[ASSET TRANSACTIONS] Current uploaders: {0}", XferUploaders.Count); + } + } + } + + public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, + uint callbackID, string description, string name, sbyte invType, + sbyte type, byte wearableType, uint nextOwnerMask) + { + if (XferUploaders.ContainsKey(transactionID)) + { + XferUploaders[transactionID].RequestCreateInventoryItem(remoteClient, transactionID, folderID, + callbackID, description, name, invType, type, + wearableType, nextOwnerMask); + } + } + + public void RequestUpdateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, + InventoryItemBase item) + { + if (XferUploaders.ContainsKey(transactionID)) + { + XferUploaders[transactionID].RequestUpdateInventoryItem(remoteClient, transactionID, item); + } + } + + /// + /// Get an uploaded asset. If the data is successfully retrieved, the transaction will be removed. + /// + /// + /// The asset if the upload has completed, null if it has not. + public AssetBase GetTransactionAsset(LLUUID transactionID) + { + if (XferUploaders.ContainsKey(transactionID)) + { + AssetXferUploader uploader = XferUploaders[transactionID]; + AssetBase asset = uploader.GetAssetData(); + + lock (XferUploaders) + { + XferUploaders.Remove(transactionID); + } + + return asset; + } + + return null; + } + + // Nested Types + public class AssetXferUploader + { + // Fields + public bool AddToInventory; + public AssetBase Asset; + public LLUUID InventFolder = LLUUID.Zero; + private IClientAPI ourClient; + public LLUUID TransactionID = LLUUID.Zero; + public bool UploadComplete; + public ulong XferID; + private string m_name = String.Empty; + private string m_description = String.Empty; + private sbyte type = 0; + private sbyte invType = 0; + private uint nextPerm = 0; + private bool m_finished = false; + private bool m_createItem = false; + private AgentAssetTransactions m_userTransactions; + private bool m_storeLocal; + private bool m_dumpAssetToFile; + + public AssetXferUploader(AgentAssetTransactions transactions, bool dumpAssetToFile) + { + m_userTransactions = transactions; + m_dumpAssetToFile = dumpAssetToFile; + } + + /// + /// Process transfer data received from the client. + /// + /// + /// + /// + /// True if the transfer is complete, false otherwise or if the xferID was not valid + public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data) + { + if (XferID == xferID) + { + if (Asset.Data.Length > 1) + { + byte[] destinationArray = new byte[Asset.Data.Length + data.Length]; + Array.Copy(Asset.Data, 0, destinationArray, 0, Asset.Data.Length); + Array.Copy(data, 0, destinationArray, Asset.Data.Length, data.Length); + Asset.Data = destinationArray; + } + else + { + byte[] buffer2 = new byte[data.Length - 4]; + Array.Copy(data, 4, buffer2, 0, data.Length - 4); + Asset.Data = buffer2; + } + ConfirmXferPacketPacket newPack = new ConfirmXferPacketPacket(); + newPack.XferID.ID = xferID; + newPack.XferID.Packet = packetID; + ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); + if ((packetID & 0x80000000) != 0) + { + SendCompleteMessage(); + return true; + } + } + + return false; + } + + /// + /// Initialise asset transfer from the client + /// + /// + /// + /// + /// True if the transfer is complete, false otherwise + public bool Initialise(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data, + bool storeLocal, bool tempFile) + { + ourClient = remoteClient; + Asset = new AssetBase(); + Asset.FullID = assetID; + Asset.InvType = type; + Asset.Type = type; + Asset.Data = data; + Asset.Name = "blank"; + Asset.Description = "empty"; + Asset.Local = storeLocal; + Asset.Temporary = tempFile; + + TransactionID = transaction; + m_storeLocal = storeLocal; + if (Asset.Data.Length > 2) + { + SendCompleteMessage(); + return true; + } + else + { + RequestStartXfer(); + } + + return false; + } + + protected void RequestStartXfer() + { + UploadComplete = false; + XferID = Util.GetNextXferID(); + RequestXferPacket newPack = new RequestXferPacket(); + newPack.XferID.ID = XferID; + newPack.XferID.VFileType = Asset.Type; + newPack.XferID.VFileID = Asset.FullID; + newPack.XferID.FilePath = 0; + newPack.XferID.Filename = new byte[0]; + ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); + } + + protected void SendCompleteMessage() + { + UploadComplete = true; + AssetUploadCompletePacket newPack = new AssetUploadCompletePacket(); + newPack.AssetBlock.Type = Asset.Type; + newPack.AssetBlock.Success = true; + newPack.AssetBlock.UUID = Asset.FullID; + ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); + m_finished = true; + if (m_createItem) + { + DoCreateItem(); + } + else if (m_storeLocal) + { + m_userTransactions.Manager.CommsManager.AssetCache.AddAsset(Asset); + } + + // Console.WriteLine("upload complete "+ this.TransactionID); + + if (m_dumpAssetToFile) + { + DateTime now = DateTime.Now; + string filename = + String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat", now.Year, now.Month, now.Day, + now.Hour, now.Minute, now.Second, Asset.Name, Asset.Type); + SaveAssetToFile(filename, Asset.Data); + } + } + + ///Left this in and commented in case there are unforseen issues + //private void SaveAssetToFile(string filename, byte[] data) + //{ + // FileStream fs = File.Create(filename); + // BinaryWriter bw = new BinaryWriter(fs); + // bw.Write(data); + // bw.Close(); + // fs.Close(); + //} + private void SaveAssetToFile(string filename, byte[] data) + { + string assetPath = "UserAssets"; + if (!Directory.Exists(assetPath)) + { + Directory.CreateDirectory(assetPath); + } + FileStream fs = File.Create(Path.Combine(assetPath, filename)); + BinaryWriter bw = new BinaryWriter(fs); + bw.Write(data); + bw.Close(); + fs.Close(); + } + + public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, + uint callbackID, string description, string name, sbyte invType, + sbyte type, byte wearableType, uint nextOwnerMask) + { + if (TransactionID == transactionID) + { + InventFolder = folderID; + m_name = name; + m_description = description; + this.type = type; + this.invType = invType; + nextPerm = nextOwnerMask; + Asset.Name = name; + Asset.Description = description; + Asset.Type = type; + Asset.InvType = invType; + m_createItem = true; + if (m_finished) + { + DoCreateItem(); + } + } + } + + public void RequestUpdateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, + InventoryItemBase item) + { + if (TransactionID == transactionID) + { + CachedUserInfo userInfo = + m_userTransactions.Manager.CommsManager.UserProfileCacheService.GetUserDetails( + remoteClient.AgentId); + + if (userInfo != null) + { + LLUUID assetID = LLUUID.Combine(transactionID, remoteClient.SecureSessionId); + + AssetBase asset + = m_userTransactions.Manager.CommsManager.AssetCache.GetAsset( + assetID, (item.assetType == (int) AssetType.Texture ? true : false)); + + if (asset == null) + { + asset = m_userTransactions.GetTransactionAsset(transactionID); + } + + if (asset != null && asset.FullID == assetID) + { + asset.Name = item.inventoryName; + asset.Description = item.inventoryDescription; + asset.InvType = (sbyte) item.invType; + asset.Type = (sbyte) item.assetType; + item.assetID = asset.FullID; + + m_userTransactions.Manager.CommsManager.AssetCache.AddAsset(Asset); + } + + userInfo.UpdateItem(remoteClient.AgentId, item); + } + } + } + + private void DoCreateItem() + { + //really need to fix this call, if lbsa71 saw this he would die. + m_userTransactions.Manager.CommsManager.AssetCache.AddAsset(Asset); + CachedUserInfo userInfo = + m_userTransactions.Manager.CommsManager.UserProfileCacheService.GetUserDetails(ourClient.AgentId); + if (userInfo != null) + { + InventoryItemBase item = new InventoryItemBase(); + item.avatarID = ourClient.AgentId; + item.creatorsID = ourClient.AgentId; + item.inventoryID = LLUUID.Random(); + item.assetID = Asset.FullID; + item.inventoryDescription = m_description; + item.inventoryName = m_name; + item.assetType = type; + item.invType = invType; + item.parentFolderID = InventFolder; + item.inventoryBasePermissions = 2147483647; + item.inventoryCurrentPermissions = 2147483647; + item.inventoryNextPermissions = nextPerm; + + userInfo.AddItem(ourClient.AgentId, item); + ourClient.SendInventoryItemCreateUpdate(item); + } + } + + public AssetBase GetAssetData() + { + if (m_finished) + { + return Asset; + } + return null; + } + } + + #region Nested Classes currently not in use (waiting for them to be enabled) + + public class AssetCapsUploader + { + // Fields + private BaseHttpServer httpListener; + private LLUUID inventoryItemID; + private string m_assetDescription = String.Empty; + private string m_assetName = String.Empty; + private LLUUID m_folderID; + private LLUUID newAssetID; + private bool m_dumpImageToFile; + private string uploaderPath = String.Empty; + + // Events + public event UpLoadedAsset OnUpLoad; + + // Methods + public void Initialise(string assetName, string assetDescription, LLUUID assetID, LLUUID inventoryItem, + LLUUID folderID, string path, BaseHttpServer httpServer, bool dumpImageToFile) + { + m_assetName = assetName; + m_assetDescription = assetDescription; + m_folderID = folderID; + newAssetID = assetID; + inventoryItemID = inventoryItem; + uploaderPath = path; + httpListener = httpServer; + m_dumpImageToFile = dumpImageToFile; + } + + private void SaveImageToFile(string filename, byte[] data) + { + FileStream output = File.Create(filename); + BinaryWriter writer = new BinaryWriter(output); + writer.Write(data); + writer.Close(); + output.Close(); + } + + public string uploaderCaps(byte[] data, string path, string param) + { + LLUUID inventoryItemID = this.inventoryItemID; + string text = String.Empty; + LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete(); + complete.new_asset = newAssetID.ToString(); + complete.new_inventory_item = inventoryItemID; + complete.state = "complete"; + text = LLSDHelpers.SerialiseLLSDReply(complete); + httpListener.RemoveStreamHandler("POST", uploaderPath); + if (m_dumpImageToFile) + { + SaveImageToFile(m_assetName + ".jp2", data); + } + if (OnUpLoad != null) + { + OnUpLoad(m_assetName, "description", newAssetID, inventoryItemID, LLUUID.Zero, data, String.Empty, String.Empty); + } + return text; + } + } + + public class NoteCardCapsUpdate + { + // Fields + private BaseHttpServer httpListener; + private LLUUID inventoryItemID; + private string m_assetName = String.Empty; + private LLUUID newAssetID; + private bool SaveImages = false; + private string uploaderPath = String.Empty; + + // Events + public event UpLoadedAsset OnUpLoad; + + // Methods + public void Initialise(LLUUID inventoryItem, string path, BaseHttpServer httpServer) + { + inventoryItemID = inventoryItem; + uploaderPath = path; + httpListener = httpServer; + newAssetID = LLUUID.Random(); + } + + private void SaveImageToFile(string filename, byte[] data) + { + FileStream output = File.Create(filename); + BinaryWriter writer = new BinaryWriter(output); + writer.Write(data); + writer.Close(); + output.Close(); + } + + public string uploaderCaps(byte[] data, string path, string param) + { + LLUUID inventoryItemID = this.inventoryItemID; + string text = String.Empty; + LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete(); + complete.new_asset = newAssetID.ToString(); + complete.new_inventory_item = inventoryItemID; + complete.state = "complete"; + text = LLSDHelpers.SerialiseLLSDReply(complete); + httpListener.RemoveStreamHandler("POST", uploaderPath); + if (SaveImages) + { + SaveImageToFile(m_assetName + "notecard.txt", data); + } + if (OnUpLoad != null) + { + OnUpLoad(m_assetName, "description", newAssetID, inventoryItemID, LLUUID.Zero, data, String.Empty, String.Empty); + } + return text; + } + } + + #endregion + } +} +*/ \ No newline at end of file diff --git a/OpenSim/Framework/Communications/Cache/AgentAssetTransactionsManager.cs b/OpenSim/Framework/Communications/Cache/AgentAssetTransactionsManager.cs new file mode 100644 index 0000000000..97b716c87e --- /dev/null +++ b/OpenSim/Framework/Communications/Cache/AgentAssetTransactionsManager.cs @@ -0,0 +1,206 @@ +/* +* 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. +* +*/ + +//moved to a module, left here until the module is found to have no problems +/* +using System; +using System.Collections.Generic; + +using libsecondlife; + +namespace OpenSim.Framework.Communications.Cache +{ + /// + /// Provider handlers for processing asset transactions originating from the agent. This encompasses + /// clothing creation and update as well as asset uploads. + /// + public class AgentAssetTransactionsManager + { + private static readonly log4net.ILog m_log + = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + // Fields + public CommunicationsManager CommsManager; + + /// + /// Each agent has its own singleton collection of transactions + /// + private Dictionary AgentTransactions = + new Dictionary(); + + /// + /// Should we dump uploaded assets to the filesystem? + /// + private bool m_dumpAssetsToFile; + + public AgentAssetTransactionsManager(CommunicationsManager commsManager, bool dumpAssetsToFile) + { + CommsManager = commsManager; + m_dumpAssetsToFile = dumpAssetsToFile; + } + + /// + /// Get the collection of asset transactions for the given user. If one does not already exist, it + /// is created. + /// + /// + /// + private AgentAssetTransactions GetUserTransactions(LLUUID userID) + { + lock (AgentTransactions) + { + if (!AgentTransactions.ContainsKey(userID)) + { + AgentAssetTransactions transactions + = new AgentAssetTransactions(userID, this, m_dumpAssetsToFile); + AgentTransactions.Add(userID, transactions); + } + + return AgentTransactions[userID]; + } + } + + /// + /// Remove the given agent asset transactions. This should be called when a client is departing + /// from a scene (and hence won't be making any more transactions here). + /// + /// + public void RemoveAgentAssetTransactions(LLUUID userID) + { + m_log.DebugFormat("Removing agent asset transactions structure for agent {0}", userID); + + lock (AgentTransactions) + { + AgentTransactions.Remove(userID); + } + } + + /// + /// Create an inventory item from data that has been received through a transaction. + /// + /// This is called when new clothing or body parts are created. It may also be called in other + /// situations. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public void HandleItemCreationFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, + uint callbackID, string description, string name, sbyte invType, + sbyte type, byte wearableType, uint nextOwnerMask) + { + m_log.DebugFormat( + "[TRANSACTIONS MANAGER] Called HandleItemCreationFromTransaction with item {0}", name); + + AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); + + transactions.RequestCreateInventoryItem( + remoteClient, transactionID, folderID, callbackID, description, + name, invType, type, wearableType, nextOwnerMask); + } + + /// + /// Update an inventory item with data that has been received through a transaction. + /// + /// This is called when clothing or body parts are updated (for instance, with new textures or + /// colours). It may also be called in other situations. + /// + /// + /// + /// + public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, LLUUID transactionID, + InventoryItemBase item) + { + m_log.DebugFormat( + "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}", + item.inventoryName); + + AgentAssetTransactions transactions + = CommsManager.TransactionsManager.GetUserTransactions(remoteClient.AgentId); + + transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item); + } + + /// + /// Request that a client (agent) begin an asset transfer. + /// + /// + /// + /// + /// + /// + /// + public void HandleUDPUploadRequest(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, + byte[] data, bool storeLocal, bool tempFile) + { + // Console.WriteLine("asset upload of " + assetID); + AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); + + AgentAssetTransactions.AssetXferUploader uploader = transactions.RequestXferUploader(transaction); + if (uploader != null) + { + // Upload has already compelted uploading... + + if (uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal, tempFile)) + { + //[commenting out as this removal breaks uploads] + /*lock (transactions.XferUploaders) + { + + // XXX Weak ass way of doing this by directly manipulating this public dictionary, purely temporary + transactions.XferUploaders.Remove(uploader.TransactionID); + + //m_log.InfoFormat("[ASSET TRANSACTIONS] Current uploaders: {0}", transactions.XferUploaders.Count); + }*/ + /* } + } + } + + /// + /// Handle asset transfer data packets received in response to the asset upload request in + /// HandleUDPUploadRequest() + /// + /// + /// + /// + /// + public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data) + { + AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); + + transactions.HandleXfer(xferID, packetID, data); + } + } +} +*/ \ No newline at end of file diff --git a/OpenSim/Framework/Communications/Cache/AssetCache.cs b/OpenSim/Framework/Communications/Cache/AssetCache.cs index dc43e87457..c6977c133d 100644 --- a/OpenSim/Framework/Communications/Cache/AssetCache.cs +++ b/OpenSim/Framework/Communications/Cache/AssetCache.cs @@ -1,725 +1,886 @@ -/* -* 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.Generic; -using System.Threading; -using libsecondlife; -using libsecondlife.Packets; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.Communications.Cache -{ - public delegate void AssetRequestCallback(LLUUID assetID, AssetBase asset); - - /// - /// Manages local cache of assets and their sending to viewers. - /// - public class AssetCache : IAssetReceiver - { - public Dictionary Assets; - public Dictionary Textures; - - public List AssetRequests = new List(); //assets ready to be sent to viewers - public List TextureRequests = new List(); //textures ready to be sent - - public Dictionary RequestedAssets = new Dictionary(); - //Assets requested from the asset server - - public Dictionary RequestedTextures = new Dictionary(); - //Textures requested from the asset server - - public Dictionary RequestLists = new Dictionary(); - - private readonly IAssetServer m_assetServer; - - private readonly Thread m_assetCacheThread; - private readonly LogBase m_log; - - /// - /// - /// - public AssetCache(IAssetServer assetServer, LogBase log) - { - log.Verbose("ASSETSTORAGE", "Creating Asset cache"); - m_assetServer = assetServer; - m_assetServer.SetReceiver(this); - Assets = new Dictionary(); - Textures = new Dictionary(); - m_assetCacheThread = new Thread(new ThreadStart(RunAssetManager)); - m_assetCacheThread.IsBackground = true; - m_assetCacheThread.Start(); - - m_log = log; - } - - /// - /// - /// - public void RunAssetManager() - { - while (true) - { - try - { - ProcessAssetQueue(); - Thread.Sleep(500); - } - catch (Exception e) - { - m_log.Error("ASSETCACHE", e.ToString()); - } - } - } - - /// - /// Only get an asset if we already have it in the cache. - /// - /// - /// - private AssetBase GetCachedAsset(LLUUID assetID) - { - AssetBase asset = null; - if (Textures.ContainsKey(assetID)) - { - asset = Textures[assetID]; - } - else if (Assets.ContainsKey(assetID)) - { - asset = Assets[assetID]; - } - return asset; - } - - public void GetAsset(LLUUID assetID, AssetRequestCallback callback) - { - AssetBase asset = null; - if (Textures.ContainsKey(assetID)) - { - asset = Textures[assetID]; - } - else if (Assets.ContainsKey(assetID)) - { - asset = Assets[assetID]; - } - - if (asset != null) - { - callback(assetID, asset); - } - else - { - NewAssetRequest req = new NewAssetRequest(assetID, callback); - if (RequestLists.ContainsKey(assetID)) - { - lock (RequestLists) - { - RequestLists[assetID].Requests.Add(req); - } - } - else - { - AssetRequestsList reqList = new AssetRequestsList(assetID); - reqList.Requests.Add(req); - lock (RequestLists) - { - RequestLists.Add(assetID, reqList); - } - } - m_assetServer.RequestAsset(assetID, false); - } - } - - /// - /// Get an asset. If the asset isn't in the cache, a request will be made to the persistent store to - /// load it into the cache. - /// - /// XXX We'll keep polling the cache until we get the asset or we exceed - /// the allowed number of polls. This isn't a very good way of doing things since a single thread - /// is processing inbound packets, so if the asset server is slow, we could block this for up to - /// the timeout period. What we might want to do is register asynchronous callbacks on asset - /// receipt in the same manner as the nascent (but not yet active) TextureDownloadModule. Of course, - /// a timeout before asset receipt usually isn't fatal, the operation will work on the retry when the - /// asset is much more likely to have made it into the cache. - /// - /// - /// - /// null if the asset could not be retrieved - public AssetBase GetAsset(LLUUID assetID, bool isTexture) - { - // I'm not going over 3 seconds since this will be blocking processing of all the other inbound - // packets from the client. - int pollPeriod = 200; - int maxPolls = 15; - - AssetBase asset = GetCachedAsset(assetID); - if (asset != null) - { - return asset; - } - - m_assetServer.RequestAsset(assetID, isTexture); - - do - { - Thread.Sleep(pollPeriod); - - asset = GetCachedAsset(assetID); - if (asset != null) - { - return asset; - } - } while (--maxPolls > 0); - - MainLog.Instance.Warn( - "ASSETCACHE", "Asset {0} was not received before the retrieval timeout was reached"); - - return null; - } - - // rex, new function - public List GetAssetList(int vAssetType) - { - return m_assetServer.GetAssetList(vAssetType); - } - - // rex, new function - public AssetBase FetchAsset(LLUUID assetID) - { - return m_assetServer.FetchAsset(assetID); - } - - /// - /// Add an asset to both the persistent store and the cache. - /// - /// - public void AddAsset(AssetBase asset) - { - string temporary = asset.Temporary ? "temporary" : ""; - string type = asset.Type == 0 ? "texture" : "asset"; - - string result = "Ignored"; - - if (asset.Type == 0) - { - if (Textures.ContainsKey(asset.FullID)) - { - result = "Duplicate ignored."; - } - else - { - TextureImage textur = new TextureImage(asset); - Textures.Add(textur.FullID, textur); - if (asset.Temporary) - { - result = "Added to cache"; - } - else - { - m_assetServer.StoreAndCommitAsset(asset); - result = "Added to server"; - } - } - } - else - { - if (Assets.ContainsKey(asset.FullID)) - { - result = "Duplicate ignored."; - } - else - { - AssetInfo assetInf = new AssetInfo(asset); - Assets.Add(assetInf.FullID, assetInf); - if (asset.Temporary) - { - result = "Added to cache"; - } - else - { - m_assetServer.StoreAndCommitAsset(asset); - result = "Added to server"; - } - } - } - - m_log.Verbose("ASSETCACHE", "Adding {0} {1} [{2}]: {3}.", temporary, type, asset.FullID, result); - } - - // rex, new function for "replace asset" functionality - public void ReplaceAsset(AssetBase asset) - { - string temporary = asset.Temporary ? "temporary" : ""; - string type = asset.Type == 0 ? "texture" : "asset"; - - string result = "Ignored"; - - if (asset.Type == 0) - { - if (Textures.ContainsKey(asset.FullID)) - { - Textures.Remove(asset.FullID); - } - - TextureImage textur = new TextureImage(asset); - Textures.Add(textur.FullID, textur); - - if (asset.Temporary) - { - result = "Replaced old asset in cache"; - } - else - { - m_assetServer.UpdateAsset(asset); - result = "Replaced old asset on server"; - } - } - else - { - if (Assets.ContainsKey(asset.FullID)) - { - Assets.Remove(asset.FullID); - } - - AssetInfo assetInf = new AssetInfo(asset); - Assets.Add(assetInf.FullID, assetInf); - - if (asset.Temporary) - { - result = "Replaced old asset in cache"; - } - else - { - m_assetServer.UpdateAsset(asset); - result = "Replaced old asset on server"; - } - } - - m_log.Verbose("ASSETCACHE", "Adding {0} {1} [{2}]: {3}.", temporary, type, asset.FullID, result); - } - - // rex new function - public bool ExistsAsset(LLUUID assetID) - { - if (Textures.ContainsKey(assetID)) - return true; - if (Assets.ContainsKey(assetID)) - return true; - return m_assetServer.ExistsAsset(assetID); - } - - // rex new function for "replace asset" functionality - public LLUUID ExistsAsset(sbyte type, string name) - { - // First check locally cached assets - // Texture or other asset? - if (type == 0) - { - foreach (KeyValuePair kvp in Textures) - { - TextureImage t = kvp.Value; - if (t != null) - { - if ((t.Name == name) && (t.Type == type)) - { - return t.FullID; - } - } - } - } - else - { - foreach (KeyValuePair kvp in Assets) - { - AssetInfo a = kvp.Value; - if (a != null) - { - if ((a.Name == name) && (a.Type == type)) - { - return a.FullID; - } - } - } - } - - // Then have to check asset server - return m_assetServer.ExistsAsset(type, name); - } - - public void DeleteAsset(LLUUID assetID) - { - // this.m_assetServer.DeleteAsset(assetID); - - //Todo should delete it from memory too - } - - public AssetBase CopyAsset(LLUUID assetID) - { - AssetBase asset = GetCachedAsset(assetID); - if (asset == null) - return null; - - asset.FullID = LLUUID.Random(); // TODO: check for conflicts - AddAsset(asset); - return asset; - } - - public void AssetReceived(AssetBase asset, bool IsTexture) - { - if (asset.FullID != LLUUID.Zero) // if it is set to zero then the asset wasn't found by the server - { - //check if it is a texture or not - //then add to the correct cache list - //then check for waiting requests for this asset/texture (in the Requested lists) - //and move those requests into the Requests list. - - if (IsTexture) - { - //Console.WriteLine("asset received from asset server"); - - TextureImage image = new TextureImage(asset); - if (!Textures.ContainsKey(image.FullID)) - { - Textures.Add(image.FullID, image); - if (RequestedTextures.ContainsKey(image.FullID)) - { - AssetRequest req = RequestedTextures[image.FullID]; - req.ImageInfo = image; - - req.NumPackets = CalculateNumPackets(image.Data); - - RequestedTextures.Remove(image.FullID); - TextureRequests.Add(req); - } - } - } - else - { - AssetInfo assetInf = new AssetInfo(asset); - if (!Assets.ContainsKey(assetInf.FullID)) - { - Assets.Add(assetInf.FullID, assetInf); - if (RequestedAssets.ContainsKey(assetInf.FullID)) - { - AssetRequest req = RequestedAssets[assetInf.FullID]; - req.AssetInf = assetInf; - req.NumPackets = CalculateNumPackets(assetInf.Data); - RequestedAssets.Remove(assetInf.FullID); - AssetRequests.Add(req); - } - } - } - - if (RequestLists.ContainsKey(asset.FullID)) - { - AssetRequestsList reqList = RequestLists[asset.FullID]; - foreach (NewAssetRequest req in reqList.Requests) - { - req.Callback(asset.FullID, asset); - } - - lock (RequestLists) - { - RequestLists.Remove(asset.FullID); - reqList.Requests.Clear(); - } - } - } - } - - public void AssetNotFound(LLUUID assetID) - { - //if (this.RequestedTextures.ContainsKey(assetID)) - //{ - // MainLog.Instance.Warn("ASSET CACHE", "sending image not found for {0}", assetID); - // AssetRequest req = this.RequestedTextures[assetID]; - // ImageNotInDatabasePacket notFound = new ImageNotInDatabasePacket(); - // notFound.ImageID.ID = assetID; - // req.RequestUser.OutPacket(notFound); - // this.RequestedTextures.Remove(assetID); - //} - //else - //{ - // MainLog.Instance.Error("ASSET CACHE", "Cound not send image not found for {0}", assetID); - //} - } - - private int CalculateNumPackets(byte[] data) - { - const uint m_maxPacketSize = 600; - int numPackets = 1; - - if (data.LongLength > m_maxPacketSize) - { - // over max number of bytes so split up file - long restData = data.LongLength - m_maxPacketSize; - int restPackets = (int) ((restData + m_maxPacketSize - 1)/m_maxPacketSize); - numPackets += restPackets; - } - - return numPackets; - } - - #region Assets - - /// - /// - /// - /// - /// - public void AddAssetRequest(IClientAPI userInfo, TransferRequestPacket transferRequest) - { - LLUUID requestID = null; - byte source = 2; - if (transferRequest.TransferInfo.SourceType == 2) - { - //direct asset request - requestID = new LLUUID(transferRequest.TransferInfo.Params, 0); - } - else if (transferRequest.TransferInfo.SourceType == 3) - { - //inventory asset request - requestID = new LLUUID(transferRequest.TransferInfo.Params, 80); - source = 3; - //Console.WriteLine("asset request " + requestID); - } - //check to see if asset is in local cache, if not we need to request it from asset server. - //Console.WriteLine("asset request " + requestID); - if (!Assets.ContainsKey(requestID)) - { - //not found asset - // so request from asset server - if (!RequestedAssets.ContainsKey(requestID)) - { - AssetRequest request = new AssetRequest(); - request.RequestUser = userInfo; - request.RequestAssetID = requestID; - request.TransferRequestID = transferRequest.TransferInfo.TransferID; - request.AssetRequestSource = source; - request.Params = transferRequest.TransferInfo.Params; - RequestedAssets.Add(requestID, request); - m_assetServer.RequestAsset(requestID, false); - } - return; - } - //it is in our cache - AssetInfo asset = Assets[requestID]; - - // add to the AssetRequests list - AssetRequest req = new AssetRequest(); - req.RequestUser = userInfo; - req.RequestAssetID = requestID; - req.TransferRequestID = transferRequest.TransferInfo.TransferID; - req.AssetRequestSource = source; - req.Params = transferRequest.TransferInfo.Params; - req.AssetInf = asset; - req.NumPackets = CalculateNumPackets(asset.Data); - AssetRequests.Add(req); - } - - /// - /// - /// - private void ProcessAssetQueue() - { - //should move the asset downloading to a module, like has been done with texture downloading - if (AssetRequests.Count == 0) - { - //no requests waiting - return; - } - // if less than 5, do all of them - int num = Math.Min(5, AssetRequests.Count); - - AssetRequest req; - for (int i = 0; i < num; i++) - { - req = (AssetRequest) AssetRequests[i]; - //Console.WriteLine("sending asset " + req.RequestAssetID); - TransferInfoPacket Transfer = new TransferInfoPacket(); - Transfer.TransferInfo.ChannelType = 2; - Transfer.TransferInfo.Status = 0; - Transfer.TransferInfo.TargetType = 0; - if (req.AssetRequestSource == 2) - { - Transfer.TransferInfo.Params = new byte[20]; - Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); - int assType = (int) req.AssetInf.Type; - Array.Copy(Helpers.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4); - } - else if (req.AssetRequestSource == 3) - { - Transfer.TransferInfo.Params = req.Params; - // Transfer.TransferInfo.Params = new byte[100]; - //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); - //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16); - } - Transfer.TransferInfo.Size = (int) req.AssetInf.Data.Length; - Transfer.TransferInfo.TransferID = req.TransferRequestID; - req.RequestUser.OutPacket(Transfer, ThrottleOutPacketType.Asset); - - if (req.NumPackets == 1) - { - TransferPacketPacket TransferPacket = new TransferPacketPacket(); - TransferPacket.TransferData.Packet = 0; - TransferPacket.TransferData.ChannelType = 2; - TransferPacket.TransferData.TransferID = req.TransferRequestID; - TransferPacket.TransferData.Data = req.AssetInf.Data; - TransferPacket.TransferData.Status = 1; - req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset); - } - else - { - int processedLength = 0; - // libsecondlife hardcodes 1500 as the maximum data chunk size - int maxChunkSize = 1500; - int packetNumber = 0; - - while (processedLength < req.AssetInf.Data.Length) - { - TransferPacketPacket TransferPacket = new TransferPacketPacket(); - TransferPacket.TransferData.Packet = packetNumber; - TransferPacket.TransferData.ChannelType = 2; - TransferPacket.TransferData.TransferID = req.TransferRequestID; - - int chunkSize = Math.Min(req.AssetInf.Data.Length - processedLength, maxChunkSize); - byte[] chunk = new byte[chunkSize]; - Array.Copy(req.AssetInf.Data, processedLength, chunk, 0, chunk.Length); - - TransferPacket.TransferData.Data = chunk; - - // 0 indicates more packets to come, 1 indicates last packet - if (req.AssetInf.Data.Length - processedLength > maxChunkSize) - { - TransferPacket.TransferData.Status = 0; - } - else - { - TransferPacket.TransferData.Status = 1; - } - - req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset); - - processedLength += chunkSize; - packetNumber++; - } - } - } - - //remove requests that have been completed - for (int i = 0; i < num; i++) - { - AssetRequests.RemoveAt(0); - } - } - - #endregion - - public class AssetRequest - { - public IClientAPI RequestUser; - public LLUUID RequestAssetID; - public AssetInfo AssetInf; - public TextureImage ImageInfo; - public LLUUID TransferRequestID; - public long DataPointer = 0; - public int NumPackets = 0; - public int PacketCounter = 0; - public bool IsTextureRequest; - public byte AssetRequestSource = 2; - public byte[] Params = null; - //public bool AssetInCache; - //public int TimeRequested; - public int DiscardLevel = -1; - - public AssetRequest() - { - } - } - - public class AssetInfo : AssetBase - { - public AssetInfo() - { - } - - public AssetInfo(AssetBase aBase) - { - Data = aBase.Data; - FullID = aBase.FullID; - Type = aBase.Type; - InvType = aBase.InvType; - Name = aBase.Name; - Description = aBase.Description; - MediaURL = aBase.MediaURL; //rex - } - } - - public class TextureImage : AssetBase - { - public TextureImage() - { - } - - public TextureImage(AssetBase aBase) - { - Data = aBase.Data; - FullID = aBase.FullID; - Type = aBase.Type; - InvType = aBase.InvType; - Name = aBase.Name; - Description = aBase.Description; - MediaURL = aBase.MediaURL; //rex - } - } - - - public class AssetRequestsList - { - public LLUUID AssetID; - public List Requests = new List(); - - public AssetRequestsList(LLUUID assetID) - { - AssetID = assetID; - } - } - - public class NewAssetRequest - { - public LLUUID AssetID; - public AssetRequestCallback Callback; - - public NewAssetRequest(LLUUID assetID, AssetRequestCallback callback) - { - AssetID = assetID; - Callback = callback; - } - } - } -} \ No newline at end of file +/* +* 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.Generic; +using System.Threading; +using libsecondlife; +using libsecondlife.Packets; + +using OpenSim.Framework.Console; +using OpenSim.Framework.Statistics; + +namespace OpenSim.Framework.Communications.Cache +{ + public delegate void AssetRequestCallback(LLUUID assetID, AssetBase asset); + + /// + /// Manages local cache of assets and their sending to viewers. + /// + /// This class actually encapsulates two largely separate mechanisms. One mechanism fetches assets either + /// synchronously or async and passes the data back to the requester. The second mechanism fetches assets and + /// sends packetised data directly back to the client. The only point where they meet is AssetReceived() and + /// AssetNotFound(), which means they do share the same asset and texture caches. + /// + /// TODO Assets in this cache are effectively immortal (they are never disposed off through old age). + /// This is not a huge problem at the moment since other memory use usually dwarfs that used by assets + /// but it's something to bear in mind. + /// + public class AssetCache : IAssetReceiver + { + private static readonly log4net.ILog m_log + = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// The cache of assets. This does not include textures. + /// + private Dictionary Assets; + + /// + /// The cache of textures. + /// + private Dictionary Textures; + + /// + /// Assets requests which are waiting for asset server data. This includes texture requests + /// + private Dictionary RequestedAssets; + + /// + /// Asset requests with data which are ready to be sent back to requesters. This includes textures. + /// + private List AssetRequests; + + /// + /// Until the asset request is fulfilled, each asset request is associated with a list of requesters + /// + private Dictionary RequestLists; + + private readonly IAssetServer m_assetServer; + + private readonly Thread m_assetCacheThread; + + /// + /// Report statistical data. + /// + public void ShowState() + { + m_log.InfoFormat("Assets:{0} Textures:{1} AssetRequests:{2} RequestedAssets:{3} RequestLists:{4}", + Assets.Count, + Textures.Count, + AssetRequests.Count, + RequestedAssets.Count, + RequestLists.Count); + + int temporaryImages = 0; + int temporaryAssets = 0; + + long imageBytes = 0; + long assetBytes = 0; + + foreach (TextureImage texture in Textures.Values) + { + if (texture.Temporary) + { + temporaryImages++; + } + + imageBytes += texture.Data.GetLongLength(0); + } + + foreach (AssetInfo asset in Assets.Values) + { + if (asset.Temporary) + { + temporaryAssets++; + } + + assetBytes += asset.Data.GetLongLength(0); + } + + m_log.InfoFormat("Temporary Images: {0} Temporary Assets: {1}", + temporaryImages, + temporaryAssets); + + m_log.InfoFormat("Image data: {0}kb Asset data: {1}kb", + imageBytes / 1024, + assetBytes / 1024); + + } + + /// + /// Clear the asset cache. + /// + public void Clear() + { + m_log.Info("[ASSET CACHE]: Clearing Asset cache"); + Initialize(); + } + + /// + /// Initialize the cache. + /// + private void Initialize() + { + Assets = new Dictionary(); + Textures = new Dictionary(); + AssetRequests = new List(); + + RequestedAssets = new Dictionary(); + RequestLists = new Dictionary(); + } + + /// + /// Constructor. Initialize will need to be called separately. + /// + /// + public AssetCache(IAssetServer assetServer) + { + m_log.Info("[ASSET CACHE]: Creating Asset cache"); + Initialize(); + + m_assetServer = assetServer; + m_assetServer.SetReceiver(this); + + m_assetCacheThread = new Thread(new ThreadStart(RunAssetManager)); + m_assetCacheThread.Name = "AssetCacheThread"; + m_assetCacheThread.IsBackground = true; + m_assetCacheThread.Start(); + OpenSim.Framework.ThreadTracker.Add(m_assetCacheThread); + } + + /// + /// Process the asset queue which holds data which is packeted up and sent + /// directly back to the client. + /// + public void RunAssetManager() + { + while (true) + { + try + { + ProcessAssetQueue(); + Thread.Sleep(500); + } + catch (Exception e) + { + m_log.Error("[ASSET CACHE]: " + e.ToString()); + } + } + } + + /// + /// Only get an asset if we already have it in the cache. + /// + /// + /// + //private AssetBase GetCachedAsset(LLUUID assetId) + //{ + // AssetBase asset = null; + + // if (Textures.ContainsKey(assetId)) + // { + // asset = Textures[assetId]; + // } + // else if (Assets.ContainsKey(assetId)) + // { + // asset = Assets[assetId]; + // } + + // return asset; + //} + + private bool TryGetCachedAsset(LLUUID assetId, out AssetBase asset) + { + if (Textures.ContainsKey(assetId)) + { + asset = Textures[assetId]; + return true; + } + else if (Assets.ContainsKey(assetId)) + { + asset = Assets[assetId]; + return true; + } + + asset = null; + return false; + } + + /// + /// Asynchronously retrieve an asset. + /// + /// + /// + /// A callback invoked when the asset has either been found or not found. + /// If the asset was found this is called with the asset UUID and the asset data + /// If the asset was not found this is still called with the asset UUID but with a null asset data reference + public void GetAsset(LLUUID assetId, AssetRequestCallback callback, bool isTexture) + { + AssetBase asset; + + if (TryGetCachedAsset(assetId, out asset)) + { + callback(assetId, asset); + } + else + { + #if DEBUG + //m_log.DebugFormat("[ASSET CACHE]: Adding request for {0} {1}", isTexture ? "texture" : "asset", assetId); + #endif + + NewAssetRequest req = new NewAssetRequest(assetId, callback); + + // Make sure we always have a request list to which to add the asset + AssetRequestsList requestList; + lock (RequestLists) + { + if (RequestLists.TryGetValue(assetId, out requestList)) + { + } + else + { + requestList = new AssetRequestsList(assetId); + RequestLists.Add(assetId, requestList); + } + } + + requestList.Requests.Add(req); + + m_assetServer.RequestAsset(assetId, isTexture); + } + } + + /// + /// Synchronously retreive an asset. If the asset isn't in the cache, a request will be made to the persistent store to + /// load it into the cache. + /// + /// XXX We'll keep polling the cache until we get the asset or we exceed + /// the allowed number of polls. This isn't a very good way of doing things since a single thread + /// is processing inbound packets, so if the asset server is slow, we could block this for up to + /// the timeout period. What we might want to do is register asynchronous callbacks on asset + /// receipt in the same manner as the TextureDownloadModule. Of course, + /// a timeout before asset receipt usually isn't fatal, the operation will work on the retry when the + /// asset is much more likely to have made it into the cache. + /// + /// + /// + /// null if the asset could not be retrieved + public AssetBase GetAsset(LLUUID assetID, bool isTexture) + { + // I'm not going over 3 seconds since this will be blocking processing of all the other inbound + // packets from the client. + int pollPeriod = 200; + int maxPolls = 15; + + AssetBase asset; + + if (TryGetCachedAsset(assetID, out asset)) + { + return asset; + } + else + { + m_assetServer.RequestAsset(assetID, isTexture); + + do + { + Thread.Sleep(pollPeriod); + + if (TryGetCachedAsset(assetID, out asset)) + { + return asset; + } + } while (--maxPolls > 0); + + m_log.WarnFormat("[ASSET CACHE]: {0} {1} was not received before the retrieval timeout was reached", + isTexture ? "texture" : "asset", assetID.ToString()); + + return null; + } + } + + // rex, new function + public List GetAssetList(int vAssetType) + { + return m_assetServer.GetAssetList(vAssetType); + } + + // rex, new function + public AssetBase FetchAsset(LLUUID assetID) + { + return m_assetServer.FetchAsset(assetID); + } + + /// + /// Add an asset to both the persistent store and the cache. + /// + /// + public void AddAsset(AssetBase asset) + { + string temporary = asset.Temporary ? "temporary" : String.Empty; + string type = asset.Type == 0 ? "texture" : "asset"; + + string result = "Ignored"; + + if (asset.Type == 0) + { + if (Textures.ContainsKey(asset.FullID)) + { + result = "Duplicate ignored."; + } + else + { + TextureImage textur = new TextureImage(asset); + Textures.Add(textur.FullID, textur); + + if (StatsManager.SimExtraStats != null) + StatsManager.SimExtraStats.AddTexture(textur); + + if (asset.Temporary) + { + result = "Added to cache"; + } + else + { + m_assetServer.StoreAndCommitAsset(asset); + result = "Added to server"; + } + } + } + else + { + if (Assets.ContainsKey(asset.FullID)) + { + result = "Duplicate ignored."; + } + else + { + AssetInfo assetInf = new AssetInfo(asset); + Assets.Add(assetInf.FullID, assetInf); + + if (StatsManager.SimExtraStats != null) + StatsManager.SimExtraStats.AddAsset(assetInf); + + if (asset.Temporary) + { + result = "Added to cache"; + } + else + { + m_assetServer.StoreAndCommitAsset(asset); + result = "Added to server"; + } + } + } + #if DEBUG + //m_log.DebugFormat("[ASSET CACHE]: Adding {0} {1} [{2}]: {3}.", temporary, type, asset.FullID, result); + #endif + } + + // rex, new function for "replace asset" functionality + public void ReplaceAsset(AssetBase asset) + { + string temporary = asset.Temporary ? "temporary" : ""; + string type = asset.Type == 0 ? "texture" : "asset"; + + string result = "Ignored"; + + if (asset.Type == 0) + { + if (Textures.ContainsKey(asset.FullID)) + { + Textures.Remove(asset.FullID); + } + + TextureImage textur = new TextureImage(asset); + Textures.Add(textur.FullID, textur); + + if (asset.Temporary) + { + result = "Replaced old asset in cache"; + } + else + { + m_assetServer.UpdateAsset(asset); + result = "Replaced old asset on server"; + } + } + else + { + if (Assets.ContainsKey(asset.FullID)) + { + Assets.Remove(asset.FullID); + } + + AssetInfo assetInf = new AssetInfo(asset); + Assets.Add(assetInf.FullID, assetInf); + + if (asset.Temporary) + { + result = "Replaced old asset in cache"; + } + else + { + m_assetServer.UpdateAsset(asset); + result = "Replaced old asset on server"; + } + } + + m_log.Verbose("ASSETCACHE", "Adding {0} {1} [{2}]: {3}.", temporary, type, asset.FullID, result); + } + + // rex new function + public bool ExistsAsset(LLUUID assetID) + { + if (Textures.ContainsKey(assetID)) + return true; + if (Assets.ContainsKey(assetID)) + return true; + return m_assetServer.ExistsAsset(assetID); + } + + // rex new function for "replace asset" functionality + public LLUUID ExistsAsset(sbyte type, string name) + { + // First check locally cached assets + // Texture or other asset? + if (type == 0) + { + foreach (KeyValuePair kvp in Textures) + { + TextureImage t = kvp.Value; + if (t != null) + { + if ((t.Name == name) && (t.Type == type)) + { + return t.FullID; + } + } + } + } + else + { + foreach (KeyValuePair kvp in Assets) + { + AssetInfo a = kvp.Value; + if (a != null) + { + if ((a.Name == name) && (a.Type == type)) + { + return a.FullID; + } + } + } + } + + // Then have to check asset server + return m_assetServer.ExistsAsset(type, name); + } + + public void DeleteAsset(LLUUID assetID) + // See IAssetReceiver + public void AssetReceived(AssetBase asset, bool IsTexture) + { + #if DEBUG + m_log.DebugFormat("[ASSET CACHE]: Received {0} [{1}]", IsTexture ? "texture" : "asset", asset.FullID); + #endif + + if (asset.FullID != LLUUID.Zero) // if it is set to zero then the asset wasn't found by the server + { + //check if it is a texture or not + //then add to the correct cache list + //then check for waiting requests for this asset/texture (in the Requested lists) + //and move those requests into the Requests list. + + if (IsTexture) + { + TextureImage image = new TextureImage(asset); + if (Textures.ContainsKey(image.FullID)) + { + #if DEBUG + //m_log.DebugFormat("[ASSET CACHE]: There's already an texture {0} in memory. Skipping.", asset.FullID); + #endif + } + else + { + Textures.Add(image.FullID, image); + + if (StatsManager.SimExtraStats != null) + { + StatsManager.SimExtraStats.AddTexture(image); + } + } + } + else + { + AssetInfo assetInf = new AssetInfo(asset); + if (Assets.ContainsKey(assetInf.FullID)) + { + #if DEBUG + //m_log.DebugFormat("[ASSET CACHE]: There's already an asset {0} in memory. Skipping.", asset.FullID); + #endif + } + else + { + Assets.Add(assetInf.FullID, assetInf); + + if (StatsManager.SimExtraStats != null) + { + StatsManager.SimExtraStats.AddAsset(assetInf); + } + + if (RequestedAssets.ContainsKey(assetInf.FullID)) + { + #if DEBUG + //m_log.DebugFormat("[ASSET CACHE]: Moving {0} from RequestedAssets to AssetRequests", asset.FullID); + #endif + + AssetRequest req = RequestedAssets[assetInf.FullID]; + req.AssetInf = assetInf; + req.NumPackets = CalculateNumPackets(assetInf.Data); + + RequestedAssets.Remove(assetInf.FullID); + AssetRequests.Add(req); + } + } + } + + // Notify requesters for this asset + if (RequestLists.ContainsKey(asset.FullID)) + { + lock (RequestLists) + { + AssetRequestsList reqList = RequestLists[asset.FullID]; + foreach (NewAssetRequest req in reqList.Requests) + { + req.Callback(asset.FullID, asset); + } + + RequestLists.Remove(asset.FullID); + reqList.Requests.Clear(); + } + } + } + } + + // See IAssetReceiver + public void AssetNotFound(LLUUID assetID) + { + //m_log.ErrorFormat("[ASSET CACHE]: AssetNotFound for {0}", assetID); + + // The 'image not found' packet needs to happen, but RequestedTextures is not actually used (should be cleaned up) + // It might also be better to do this in the TextureDownloadModule + /* + * + AssetRequest req; + + if (RequestedTextures.TryGetValue(assetID, out req)) + { + m_log.WarnFormat("[ASSET CACHE]: sending image not found for {0}", assetID); + ImageNotInDatabasePacket notFound = new ImageNotInDatabasePacket(); + notFound.ImageID.ID = assetID; + req.RequestUser.OutPacket(notFound, ThrottleOutPacketType.Unknown); + RequestedTextures.Remove(assetID); + } + else + { + m_log.ErrorFormat("[ASSET CACHE]: Asset [{0}] not found, but couldn't find any users to send to ", assetID); + } + */ + + // Notify requesters for this asset + lock (RequestLists) + { + if (RequestLists.ContainsKey(assetID)) + { + AssetRequestsList reqList = RequestLists[assetID]; + foreach (NewAssetRequest req in reqList.Requests) + { + req.Callback(assetID, null); + } + + RequestLists.Remove(assetID); + } + } + } + + /// + /// Calculate the number of packets required to send the asset to the client. + /// + /// + /// + private int CalculateNumPackets(byte[] data) + { + const uint m_maxPacketSize = 600; + int numPackets = 1; + + if (data.LongLength > m_maxPacketSize) + { + // over max number of bytes so split up file + long restData = data.LongLength - m_maxPacketSize; + int restPackets = (int)((restData + m_maxPacketSize - 1) / m_maxPacketSize); + numPackets += restPackets; + } + + return numPackets; + } + + /// + /// Make an asset request the result of which will be packeted up and sent directly back to the client. + /// + /// + /// + public void AddAssetRequest(IClientAPI userInfo, TransferRequestPacket transferRequest) + { + LLUUID requestID = null; + byte source = 2; + if (transferRequest.TransferInfo.SourceType == 2) + { + //direct asset request + requestID = new LLUUID(transferRequest.TransferInfo.Params, 0); + } + else if (transferRequest.TransferInfo.SourceType == 3) + { + //inventory asset request + requestID = new LLUUID(transferRequest.TransferInfo.Params, 80); + source = 3; + //Console.WriteLine("asset request " + requestID); + } + //check to see if asset is in local cache, if not we need to request it from asset server. + //Console.WriteLine("asset request " + requestID); + if (!Assets.ContainsKey(requestID)) + { + //not found asset + // so request from asset server + if (!RequestedAssets.ContainsKey(requestID)) + { + AssetRequest request = new AssetRequest(); + request.RequestUser = userInfo; + request.RequestAssetID = requestID; + request.TransferRequestID = transferRequest.TransferInfo.TransferID; + request.AssetRequestSource = source; + request.Params = transferRequest.TransferInfo.Params; + RequestedAssets.Add(requestID, request); + m_assetServer.RequestAsset(requestID, false); + } + return; + } + //it is in our cache + AssetInfo asset = Assets[requestID]; + + // add to the AssetRequests list + AssetRequest req = new AssetRequest(); + req.RequestUser = userInfo; + req.RequestAssetID = requestID; + req.TransferRequestID = transferRequest.TransferInfo.TransferID; + req.AssetRequestSource = source; + req.Params = transferRequest.TransferInfo.Params; + req.AssetInf = asset; + req.NumPackets = CalculateNumPackets(asset.Data); + AssetRequests.Add(req); + } + + /// + /// Process the asset queue which sends packets directly back to the client. + /// + private void ProcessAssetQueue() + { + //should move the asset downloading to a module, like has been done with texture downloading + if (AssetRequests.Count == 0) + { + //no requests waiting + return; + } + // if less than 5, do all of them + int num = Math.Min(5, AssetRequests.Count); + + AssetRequest req; + for (int i = 0; i < num; i++) + { + req = (AssetRequest)AssetRequests[i]; + //Console.WriteLine("sending asset " + req.RequestAssetID); + TransferInfoPacket Transfer = new TransferInfoPacket(); + Transfer.TransferInfo.ChannelType = 2; + Transfer.TransferInfo.Status = 0; + Transfer.TransferInfo.TargetType = 0; + if (req.AssetRequestSource == 2) + { + Transfer.TransferInfo.Params = new byte[20]; + Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); + int assType = (int)req.AssetInf.Type; + Array.Copy(Helpers.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4); + } + else if (req.AssetRequestSource == 3) + { + Transfer.TransferInfo.Params = req.Params; + // Transfer.TransferInfo.Params = new byte[100]; + //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); + //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16); + } + Transfer.TransferInfo.Size = (int)req.AssetInf.Data.Length; + Transfer.TransferInfo.TransferID = req.TransferRequestID; + req.RequestUser.OutPacket(Transfer, ThrottleOutPacketType.Asset); + + if (req.NumPackets == 1) + { + TransferPacketPacket TransferPacket = new TransferPacketPacket(); + TransferPacket.TransferData.Packet = 0; + TransferPacket.TransferData.ChannelType = 2; + TransferPacket.TransferData.TransferID = req.TransferRequestID; + TransferPacket.TransferData.Data = req.AssetInf.Data; + TransferPacket.TransferData.Status = 1; + req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset); + } + else + { + int processedLength = 0; + // libsecondlife hardcodes 1500 as the maximum data chunk size + int maxChunkSize = 1250; + int packetNumber = 0; + + while (processedLength < req.AssetInf.Data.Length) + { + TransferPacketPacket TransferPacket = new TransferPacketPacket(); + TransferPacket.TransferData.Packet = packetNumber; + TransferPacket.TransferData.ChannelType = 2; + TransferPacket.TransferData.TransferID = req.TransferRequestID; + + int chunkSize = Math.Min(req.AssetInf.Data.Length - processedLength, maxChunkSize); + byte[] chunk = new byte[chunkSize]; + Array.Copy(req.AssetInf.Data, processedLength, chunk, 0, chunk.Length); + + TransferPacket.TransferData.Data = chunk; + + // 0 indicates more packets to come, 1 indicates last packet + if (req.AssetInf.Data.Length - processedLength > maxChunkSize) + { + TransferPacket.TransferData.Status = 0; + } + else + { + TransferPacket.TransferData.Status = 1; + } + + req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset); + + processedLength += chunkSize; + packetNumber++; + } + } + } + + //remove requests that have been completed + for (int i = 0; i < num; i++) + { + AssetRequests.RemoveAt(0); + } + } + + public class AssetRequest + { + public IClientAPI RequestUser; + public LLUUID RequestAssetID; + public AssetInfo AssetInf; + public TextureImage ImageInfo; + public LLUUID TransferRequestID; + public long DataPointer = 0; + public int NumPackets = 0; + public int PacketCounter = 0; + public bool IsTextureRequest; + public byte AssetRequestSource = 2; + public byte[] Params = null; + //public bool AssetInCache; + //public int TimeRequested; + public int DiscardLevel = -1; + + public AssetRequest() + { + } + } + + public class AssetInfo : AssetBase + { + public AssetInfo() + { + } + + public AssetInfo(AssetBase aBase) + { + Data = aBase.Data; + FullID = aBase.FullID; + Type = aBase.Type; + InvType = aBase.InvType; + Name = aBase.Name; + Description = aBase.Description; + MediaURL = aBase.MediaURL; //rex + } + } + + public class TextureImage : AssetBase + { + public TextureImage() + { + } + + public TextureImage(AssetBase aBase) + { + Data = aBase.Data; + FullID = aBase.FullID; + Type = aBase.Type; + InvType = aBase.InvType; + Name = aBase.Name; + Description = aBase.Description; + MediaURL = aBase.MediaURL; //rex + } + } + + public class AssetRequestsList + { + public LLUUID AssetID; + public List Requests = new List(); + + public AssetRequestsList(LLUUID assetID) + { + AssetID = assetID; + } + } + + public class NewAssetRequest + { + public LLUUID AssetID; + public AssetRequestCallback Callback; + + public NewAssetRequest(LLUUID assetID, AssetRequestCallback callback) + { + AssetID = assetID; + Callback = callback; + } + } + } +} diff --git a/OpenSim/Framework/Communications/Cache/AssetServer.cs b/OpenSim/Framework/Communications/Cache/AssetServer.cs index 0ab560fda5..565b8e5da4 100644 --- a/OpenSim/Framework/Communications/Cache/AssetServer.cs +++ b/OpenSim/Framework/Communications/Cache/AssetServer.cs @@ -1,234 +1,236 @@ -/* -* 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.IO; -using Db4objects.Db4o; -using Db4objects.Db4o.Query; -using libsecondlife; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.Communications.Cache -{ - public class LocalAssetServer : AssetServerBase - { - private IObjectContainer db; - - public LocalAssetServer() - { - bool yapfile; - yapfile = File.Exists(Path.Combine(Util.dataDir(), "regionassets.yap")); - - db = Db4oFactory.OpenFile(Path.Combine(Util.dataDir(), "regionassets.yap")); - MainLog.Instance.Verbose("ASSETS", "Db4 Asset database creation"); - - if (!yapfile) - { - SetUpAssetDatabase(); - } - } - - public void CreateAndCommitAsset(AssetBase asset) - { - AssetStorage store = new AssetStorage(); - store.Data = asset.Data; - store.Name = asset.Name; - store.UUID = asset.FullID; - db.Set(store); - db.Commit(); - } - - public override void Close() - { - base.Close(); - - if (db != null) - { - MainLog.Instance.Verbose("ASSETSERVER", "Closing local asset server database"); - db.Close(); - } - } - - // rex new function for "replace assets" functionality - public override LLUUID ExistsAsset(sbyte assetType, string name) - { - IObjectSet result = db.Query(new AssetTypeNameQuery(assetType, name)); - AssetStorage foundAsset = null; - if (result.Count > 0) - { - foundAsset = (AssetStorage)result.Next(); - return foundAsset.UUID; - } - return LLUUID.Zero; - } - - // rex new function - public override bool ExistsAsset(LLUUID assetID) - { - IObjectSet result = db.Query(new AssetUUIDQuery(assetID)); - if (result.Count > 0) - return true; - else - return false; - } - - // rex new function - public override AssetBase FetchAsset(LLUUID assetID) - { - byte[] idata = null; - bool found = false; - AssetStorage foundAsset = null; - IObjectSet result = db.Query(new AssetUUIDQuery(assetID)); - if (result.Count > 0) - { - foundAsset = (AssetStorage)result.Next(); - found = true; - } - - AssetBase asset = new AssetBase(); - if (found) - { - asset.FullID = foundAsset.UUID; - asset.Type = foundAsset.Type; - asset.InvType = foundAsset.Type; - asset.Name = foundAsset.Name; - idata = foundAsset.Data; - asset.Data = idata; - - return asset; - } - else - { - return null; - } - } - - protected override AssetBase GetAsset(AssetRequest req) - { - byte[] idata = null; - bool found = false; - AssetStorage foundAsset = null; - IObjectSet result = db.Query(new AssetUUIDQuery(req.AssetID)); - if (result.Count > 0) - { - foundAsset = (AssetStorage) result.Next(); - found = true; - } - - AssetBase asset = new AssetBase(); - if (found) - { - asset.FullID = foundAsset.UUID; - asset.Type = foundAsset.Type; - asset.InvType = foundAsset.Type; - asset.Name = foundAsset.Name; - idata = foundAsset.Data; - asset.Data = idata; - - return asset; - } - else - { - return null; - } - } - - protected override void StoreAsset(AssetBase asset) - { - AssetStorage store = new AssetStorage(); - store.Data = asset.Data; - store.Name = asset.Name; - store.UUID = asset.FullID; - db.Set(store); - - CommitAssets(); - } - - // rex overrided function for "replace assets" functionality to work with local assetserver - public override void UpdateAsset(AssetBase asset) - { - lock (m_syncLock) - { - IObjectSet result = db.Query(new AssetUUIDQuery(asset.FullID)); - AssetStorage foundAsset = null; - - int i; - for (i = 0; i < result.Count; i++) - { - foundAsset = (AssetStorage)result.Next(); - db.Delete(foundAsset); - } - - StoreAsset(asset); - } - } - - protected override void CommitAssets() - { - db.Commit(); - } - - protected virtual void SetUpAssetDatabase() - { - MainLog.Instance.Verbose("LOCAL ASSET SERVER", "Setting up asset database"); - - base.LoadDefaultAssets(); - } - } - - public class AssetUUIDQuery : Predicate - { - private LLUUID _findID; - - public AssetUUIDQuery(LLUUID find) - { - _findID = find; - } - - public bool Match(AssetStorage asset) - { - return (asset.UUID == _findID); - } - } - - // rex new class for "replace assets" functionality - public class AssetTypeNameQuery : Predicate - { - private sbyte _findType; - private string _findName; - - public AssetTypeNameQuery(sbyte type, string name) - { - _findType = type; - _findName = name; - } - - public bool Match(AssetStorage asset) - { - return ((asset.Type == _findType) && (asset.Name == _findName)); - } - } -} \ No newline at end of file +/* +* 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.IO; +using Db4objects.Db4o; +using Db4objects.Db4o.Query; +using libsecondlife; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Communications.Cache +{ + public class LocalAssetServer : AssetServerBase + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private IObjectContainer db; + + public LocalAssetServer() + { + bool yapfile; + yapfile = File.Exists(Path.Combine(Util.dataDir(), "regionassets.yap")); + + db = Db4oFactory.OpenFile(Path.Combine(Util.dataDir(), "regionassets.yap")); + m_log.Info("[ASSETS]: Db4 Asset database creation"); + + if (!yapfile) + { + SetUpAssetDatabase(); + } + } + + public void CreateAndCommitAsset(AssetBase asset) + { + AssetStorage store = new AssetStorage(); + store.Data = asset.Data; + store.Name = asset.Name; + store.UUID = asset.FullID; + db.Set(store); + db.Commit(); + } + + public override void Close() + { + base.Close(); + + if (db != null) + { + m_log.Info("[ASSETSERVER]: Closing local asset server database"); + db.Close(); + } + } + + // rex new function for "replace assets" functionality + public override LLUUID ExistsAsset(sbyte assetType, string name) + { + IObjectSet result = db.Query(new AssetTypeNameQuery(assetType, name)); + AssetStorage foundAsset = null; + if (result.Count > 0) + { + foundAsset = (AssetStorage)result.Next(); + return foundAsset.UUID; + } + return LLUUID.Zero; + } + + // rex new function + public override bool ExistsAsset(LLUUID assetID) + { + IObjectSet result = db.Query(new AssetUUIDQuery(assetID)); + if (result.Count > 0) + return true; + else + return false; + } + + // rex new function + public override AssetBase FetchAsset(LLUUID assetID) + { + byte[] idata = null; + bool found = false; + AssetStorage foundAsset = null; + IObjectSet result = db.Query(new AssetUUIDQuery(assetID)); + if (result.Count > 0) + { + foundAsset = (AssetStorage)result.Next(); + found = true; + } + + AssetBase asset = new AssetBase(); + if (found) + { + asset.FullID = foundAsset.UUID; + asset.Type = foundAsset.Type; + asset.InvType = foundAsset.Type; + asset.Name = foundAsset.Name; + idata = foundAsset.Data; + asset.Data = idata; + + return asset; + } + else + { + return null; + } + } + + protected override AssetBase GetAsset(AssetRequest req) + { + byte[] idata = null; + bool found = false; + AssetStorage foundAsset = null; + IObjectSet result = db.Query(new AssetUUIDQuery(req.AssetID)); + if (result.Count > 0) + { + foundAsset = (AssetStorage) result.Next(); + found = true; + } + + AssetBase asset = new AssetBase(); + if (found) + { + asset.FullID = foundAsset.UUID; + asset.Type = foundAsset.Type; + asset.InvType = foundAsset.Type; + asset.Name = foundAsset.Name; + idata = foundAsset.Data; + asset.Data = idata; + + return asset; + } + else + { + return null; + } + } + + protected override void StoreAsset(AssetBase asset) + { + AssetStorage store = new AssetStorage(); + store.Data = asset.Data; + store.Name = asset.Name; + store.UUID = asset.FullID; + db.Set(store); + + CommitAssets(); + } + + // rex overrided function for "replace assets" functionality to work with local assetserver + public override void UpdateAsset(AssetBase asset) + { + lock (m_syncLock) + { + IObjectSet result = db.Query(new AssetUUIDQuery(asset.FullID)); + AssetStorage foundAsset = null; + + int i; + for (i = 0; i < result.Count; i++) + { + foundAsset = (AssetStorage)result.Next(); + db.Delete(foundAsset); + } + + StoreAsset(asset); + } + } + + protected override void CommitAssets() + { + db.Commit(); + } + + protected virtual void SetUpAssetDatabase() + { + m_log.Info("[LOCAL ASSET SERVER]: Setting up asset database"); + + base.LoadDefaultAssets(); + } + } + + public class AssetUUIDQuery : Predicate + { + private LLUUID _findID; + + public AssetUUIDQuery(LLUUID find) + { + _findID = find; + } + + public bool Match(AssetStorage asset) + { + return (asset.UUID == _findID); + } + } + + // rex new class for "replace assets" functionality + public class AssetTypeNameQuery : Predicate + { + private sbyte _findType; + private string _findName; + + public AssetTypeNameQuery(sbyte type, string name) + { + _findType = type; + _findName = name; + } + + public bool Match(AssetStorage asset) + { + return ((asset.Type == _findType) && (asset.Name == _findName)); + } + } +} diff --git a/OpenSim/Framework/Communications/Cache/AssetServerBase.cs b/OpenSim/Framework/Communications/Cache/AssetServerBase.cs index 8c6750ab7e..e261aa5841 100644 --- a/OpenSim/Framework/Communications/Cache/AssetServerBase.cs +++ b/OpenSim/Framework/Communications/Cache/AssetServerBase.cs @@ -1,193 +1,201 @@ -/* -* 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.Generic; -using System.Threading; -using libsecondlife; -using OpenSim.Framework.Console; -using OpenSim.Framework.AssetLoader.Filesystem; - -namespace OpenSim.Framework.Communications.Cache -{ - public abstract class AssetServerBase : IAssetServer - { - protected IAssetReceiver m_receiver; - protected BlockingQueue m_assetRequests; - protected Thread m_localAssetServerThread; - protected IAssetProvider m_assetProvider; - protected object m_syncLock = new object(); - - // Temporarily hardcoded - should be a plugin - protected IAssetLoader assetLoader = new AssetLoaderFileSystem(); - - protected abstract void StoreAsset(AssetBase asset); - protected abstract void CommitAssets(); - - public abstract LLUUID ExistsAsset(sbyte assetType, string name); // rex new function for "replace assets" functionality - - /// - /// This method must be implemented by a subclass to retrieve the asset named in the - /// AssetRequest. If the asset is not found, null should be returned. - /// - /// - /// - protected abstract AssetBase GetAsset(AssetRequest req); - - /// - /// Process an asset request. This method will call GetAsset(AssetRequest req) - /// on the subclass. - /// - /// - protected virtual void ProcessRequest(AssetRequest req) - { - AssetBase asset = GetAsset(req); - - if (asset != null) - { - MainLog.Instance.Verbose( - "ASSET", "Asset {0} received from asset server", req.AssetID); - - m_receiver.AssetReceived(asset, req.IsTexture); - } - else - { - MainLog.Instance.Error( - "ASSET", "Asset {0} not found by asset server", req.AssetID); - - m_receiver.AssetNotFound(req.AssetID); - } - } - - public virtual void LoadDefaultAssets() - { - MainLog.Instance.Verbose("ASSETSERVER", "Setting up asset database"); - - assetLoader.ForEachDefaultXmlAsset(StoreAsset); - - CommitAssets(); - } - - - public AssetServerBase() - { - MainLog.Instance.Verbose("ASSETSERVER", "Starting asset storage system"); - m_assetRequests = new BlockingQueue(); - - m_localAssetServerThread = new Thread(RunRequests); - m_localAssetServerThread.IsBackground = true; - m_localAssetServerThread.Start(); - } - - private void RunRequests() - { - while (true) // Since it's a 'blocking queue' - { - try - { - AssetRequest req = m_assetRequests.Dequeue(); - - ProcessRequest(req); - } - catch (Exception e) - { - MainLog.Instance.Error("ASSETSERVER", e.Message); - } - } - } - - public void SetReceiver(IAssetReceiver receiver) - { - m_receiver = receiver; - } - - public void RequestAsset(LLUUID assetID, bool isTexture) - { - AssetRequest req = new AssetRequest(); - req.AssetID = assetID; - req.IsTexture = isTexture; - m_assetRequests.Enqueue(req); - - MainLog.Instance.Verbose("ASSET", "Added {0} to request queue", assetID); - } - - public virtual void UpdateAsset(AssetBase asset) - { - lock (m_syncLock) - { - m_assetProvider.UpdateAsset(asset); - m_assetProvider.CommitAssets(); - } - } - - public void StoreAndCommitAsset(AssetBase asset) - { - lock (m_syncLock) - { - StoreAsset(asset); - CommitAssets(); - } - } - - // rex, new function - public List GetAssetList(int vAssetType) - { - lock (m_syncLock) - { - return m_assetProvider.GetAssetList(vAssetType); - } - } - - // rex, new function - public virtual AssetBase FetchAsset(LLUUID assetID) - { - lock (m_syncLock) - { - return m_assetProvider.FetchAsset(assetID); - } - } - - // rex, new function - public virtual bool ExistsAsset(LLUUID assetID) - { - lock (m_syncLock) - { - return m_assetProvider.ExistsAsset(assetID); - } - } - - public virtual void Close() - { - m_localAssetServerThread.Abort(); - } - - public void SetServerInfo(string ServerUrl, string ServerKey) - { - } - } -} \ No newline at end of file +/* +* 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.Generic; +using System.Threading; +using libsecondlife; +using OpenSim.Framework.Console; +using OpenSim.Framework.AssetLoader.Filesystem; + +namespace OpenSim.Framework.Communications.Cache +{ + public abstract class AssetServerBase : IAssetServer + { + private static readonly log4net.ILog m_log + = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + protected IAssetReceiver m_receiver; + protected BlockingQueue m_assetRequests; + protected Thread m_localAssetServerThread; + protected IAssetProvider m_assetProvider; + protected object m_syncLock = new object(); + + // Temporarily hardcoded - should be a plugin + protected IAssetLoader assetLoader = new AssetLoaderFileSystem(); + + protected abstract void StoreAsset(AssetBase asset); + protected abstract void CommitAssets(); + + public abstract LLUUID ExistsAsset(sbyte assetType, string name); // rex new function for "replace assets" functionality + + /// + /// This method must be implemented by a subclass to retrieve the asset named in the + /// AssetRequest. If the asset is not found, null should be returned. + /// + /// + /// + protected abstract AssetBase GetAsset(AssetRequest req); + + /// + /// Process an asset request. This method will call GetAsset(AssetRequest req) + /// on the subclass. + /// + /// + protected virtual void ProcessRequest(AssetRequest req) + { + AssetBase asset = GetAsset(req); + + if (asset != null) + { + //m_log.InfoFormat("[ASSETSERVER]: Asset {0} received from asset server", req.AssetID); + + m_receiver.AssetReceived(asset, req.IsTexture); + } + else + { + m_log.ErrorFormat("[ASSET SERVER]: Asset {0} not found by asset server", req.AssetID); + + m_receiver.AssetNotFound(req.AssetID); + } + } + + public virtual void LoadDefaultAssets() + { + m_log.Info("[ASSET SERVER]: Setting up asset database"); + + assetLoader.ForEachDefaultXmlAsset(StoreAsset); + + CommitAssets(); + } + + public AssetServerBase() + { + m_log.Info("[ASSET SERVER]: Starting asset storage system"); + m_assetRequests = new BlockingQueue(); + + m_localAssetServerThread = new Thread(RunRequests); + m_localAssetServerThread.Name = "LocalAssetServerThread"; + m_localAssetServerThread.IsBackground = true; + m_localAssetServerThread.Start(); + OpenSim.Framework.ThreadTracker.Add(m_localAssetServerThread); + } + + private void RunRequests() + { + while (true) // Since it's a 'blocking queue' + { + try + { + AssetRequest req = m_assetRequests.Dequeue(); + + ProcessRequest(req); + } + catch (Exception e) + { + m_log.Error("[ASSET SERVER]: " + e.ToString()); + } + } + } + + /// + /// The receiver will be called back with asset data once it comes in. + /// + /// + public void SetReceiver(IAssetReceiver receiver) + { + m_receiver = receiver; + } + + public void RequestAsset(LLUUID assetID, bool isTexture) + { + AssetRequest req = new AssetRequest(); + req.AssetID = assetID; + req.IsTexture = isTexture; + m_assetRequests.Enqueue(req); + + #if DEBUG + m_log.InfoFormat("[ASSET SERVER]: Added {0} to request queue", assetID); + #endif + } + + public virtual void UpdateAsset(AssetBase asset) + { + lock (m_syncLock) + { + m_assetProvider.UpdateAsset(asset); + m_assetProvider.CommitAssets(); + } + } + + public void StoreAndCommitAsset(AssetBase asset) + { + lock (m_syncLock) + { + StoreAsset(asset); + CommitAssets(); + } + } + + // rex, new function + public List GetAssetList(int vAssetType) + { + lock (m_syncLock) + { + return m_assetProvider.GetAssetList(vAssetType); + } + } + + // rex, new function + public virtual AssetBase FetchAsset(LLUUID assetID) + { + lock (m_syncLock) + { + return m_assetProvider.FetchAsset(assetID); + } + } + + // rex, new function + public virtual bool ExistsAsset(LLUUID assetID) + { + lock (m_syncLock) + { + return m_assetProvider.ExistsAsset(assetID); + } + } + + public virtual void Close() + { + m_localAssetServerThread.Abort(); + } + + public void SetServerInfo(string ServerUrl, string ServerKey) + { + } + } +} diff --git a/OpenSim/Framework/Communications/Cache/AssetTransactionManager.cs b/OpenSim/Framework/Communications/Cache/AssetTransactionManager.cs deleted file mode 100644 index 94fa218b6d..0000000000 --- a/OpenSim/Framework/Communications/Cache/AssetTransactionManager.cs +++ /dev/null @@ -1,109 +0,0 @@ -/* -* 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.Collections.Generic; -using libsecondlife; - -namespace OpenSim.Framework.Communications.Cache -{ - public class AssetTransactionManager - { - // Fields - public CommunicationsManager CommsManager; - - public Dictionary AgentTransactions = - new Dictionary(); - - private bool m_dumpAssetsToFile; - - public AssetTransactionManager(CommunicationsManager commsManager, bool dumpAssetsToFile) - { - CommsManager = commsManager; - m_dumpAssetsToFile = dumpAssetsToFile; - } - - // Methods - public AgentAssetTransactions AddUser(LLUUID userID) - { - lock (AgentTransactions) - { - if (!AgentTransactions.ContainsKey(userID)) - { - AgentAssetTransactions transactions = new AgentAssetTransactions(userID, this, m_dumpAssetsToFile); - AgentTransactions.Add(userID, transactions); - return transactions; - } - } - return null; - } - - public AgentAssetTransactions GetUserTransActions(LLUUID userID) - { - if (AgentTransactions.ContainsKey(userID)) - { - return AgentTransactions[userID]; - } - return null; - } - - public void HandleInventoryFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, - uint callbackID, string description, string name, sbyte invType, - sbyte type, byte wearableType, uint nextOwnerMask) - { - AgentAssetTransactions transactions = GetUserTransActions(remoteClient.AgentId); - if (transactions != null) - { - transactions.RequestCreateInventoryItem(remoteClient, transactionID, folderID, callbackID, description, - name, invType, type, wearableType, nextOwnerMask); - } - } - - public void HandleUDPUploadRequest(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, - byte[] data, bool storeLocal, bool tempFile) - { - // Console.WriteLine("asset upload of " + assetID); - AgentAssetTransactions transactions = GetUserTransActions(remoteClient.AgentId); - if (transactions != null) - { - AgentAssetTransactions.AssetXferUploader uploader = transactions.RequestXferUploader(transaction); - if (uploader != null) - { - uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal, tempFile); - } - } - } - - public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data) - { - AgentAssetTransactions transactions = GetUserTransActions(remoteClient.AgentId); - if (transactions != null) - { - transactions.HandleXfer(xferID, packetID, data); - } - } - } -} \ No newline at end of file diff --git a/OpenSim/Framework/Communications/Cache/GridAssetClient.cs b/OpenSim/Framework/Communications/Cache/GridAssetClient.cs index 181aea6ea7..ad6dc0c8f8 100644 --- a/OpenSim/Framework/Communications/Cache/GridAssetClient.cs +++ b/OpenSim/Framework/Communications/Cache/GridAssetClient.cs @@ -1,128 +1,134 @@ -/* -* Copyright (c) Contributors, http://www.openmetaverse.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.IO; -using System.Xml.Serialization; -using OpenSim.Framework.Console; -using OpenSim.Framework.Servers; - -namespace OpenSim.Framework.Communications.Cache -{ - public class GridAssetClient : AssetServerBase - { - private string _assetServerUrl; - - public GridAssetClient(string serverUrl) - { - _assetServerUrl = serverUrl; - } - - #region IAssetServer Members - - protected override AssetBase GetAsset(AssetRequest req) - { - Stream s = null; - try - { - MainLog.Instance.Debug("ASSETCACHE", "Querying for {0}", req.AssetID.ToString()); - - RestClient rc = new RestClient(_assetServerUrl); - rc.AddResourcePath("assets"); - rc.AddResourcePath(req.AssetID.ToString()); - if (req.IsTexture) - rc.AddQueryParameter("texture"); - - rc.RequestMethod = "GET"; - s = rc.Request(); - - if (s.Length > 0) - { - XmlSerializer xs = new XmlSerializer(typeof (AssetBase)); - - return (AssetBase) xs.Deserialize(s); - } - } - catch (Exception e) - { - MainLog.Instance.Error("ASSETCACHE", e.Message); - MainLog.Instance.Debug("ASSETCACHE", "Getting asset {0}", req.AssetID.ToString()); - MainLog.Instance.Error("ASSETCACHE", e.StackTrace); - } - - return null; - } - - - public override void UpdateAsset(AssetBase asset) - { - throw new Exception("The method or operation is not implemented."); - } - - protected override void StoreAsset(AssetBase asset) - { - try - { - // MemoryStream s = new MemoryStream(); - - // XmlSerializer xs = new XmlSerializer(typeof(AssetBase)); - // xs.Serialize(s, asset); - // RestClient rc = new RestClient(_assetServerUrl); - MainLog.Instance.Verbose("ASSET", "Storing asset"); - //rc.AddResourcePath("assets"); - // rc.RequestMethod = "POST"; - // rc.Request(s); - //MainLog.Instance.Verbose("ASSET", "Stored {0}", rc); - MainLog.Instance.Verbose("ASSET", "Sending to " + _assetServerUrl + "/assets/"); - RestObjectPoster.BeginPostObject(_assetServerUrl + "/assets/", asset); - } - catch (Exception e) - { - MainLog.Instance.Error("ASSETS", e.Message); - } - } - - protected override void CommitAssets() - { - } - - public override void Close() - { - throw new Exception("The method or operation is not implemented."); - } - - // rex new function for "replace assets" functionality - // TODO: implementation by someone - public override libsecondlife.LLUUID ExistsAsset(sbyte assetType, string name) - { - throw new Exception("The method or operation is not implemented."); - } - - #endregion - } -} \ No newline at end of file +/* +* Copyright (c) Contributors, http://www.openmetaverse.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.IO; +using System.Xml.Serialization; +using OpenSim.Framework.Console; +using OpenSim.Framework.Servers; + +namespace OpenSim.Framework.Communications.Cache +{ + public class GridAssetClient : AssetServerBase + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private string _assetServerUrl; + + public GridAssetClient(string serverUrl) + { + _assetServerUrl = serverUrl; + } + + #region IAssetServer Members + + protected override AssetBase GetAsset(AssetRequest req) + { + Stream s = null; + try + { + #if DEBUG + //m_log.DebugFormat("[GRID ASSET CLIENT]: Querying for {0}", req.AssetID.ToString()); + #endif + + RestClient rc = new RestClient(_assetServerUrl); + rc.AddResourcePath("assets"); + rc.AddResourcePath(req.AssetID.ToString()); + if (req.IsTexture) + rc.AddQueryParameter("texture"); + + rc.RequestMethod = "GET"; + s = rc.Request(); + + if (s.Length > 0) + { + XmlSerializer xs = new XmlSerializer(typeof (AssetBase)); + + return (AssetBase) xs.Deserialize(s); + } + } + catch (Exception e) + { + m_log.Error("[GRID ASSET CLIENT]: " + e.Message); + m_log.DebugFormat("[GRID ASSET CLIENT]: Getting asset {0}", req.AssetID.ToString()); + m_log.Error("[GRID ASSET CLIENT]: " + e.StackTrace); + } + + return null; + } + + + public override void UpdateAsset(AssetBase asset) + { + throw new Exception("The method or operation is not implemented."); + } + + protected override void StoreAsset(AssetBase asset) + { + try + { + // MemoryStream s = new MemoryStream(); + + // XmlSerializer xs = new XmlSerializer(typeof(AssetBase)); + // xs.Serialize(s, asset); + // RestClient rc = new RestClient(_assetServerUrl); + m_log.Info("[GRID ASSET CLIENT]: Storing asset"); + //rc.AddResourcePath("assets"); + + // rc.RequestMethod = "POST"; + // rc.Request(s); + //m_log.InfoFormat("[ASSET]: Stored {0}", rc); + m_log.Info("[GRID ASSET CLIENT]: Sending to " + _assetServerUrl + "/assets/"); + RestObjectPoster.BeginPostObject(_assetServerUrl + "/assets/", asset); + + } + catch (Exception e) + { + m_log.Error("[GRID ASSET CLIENT]: " + e.Message); + } + } + + protected override void CommitAssets() + { + } + + public override void Close() + { + throw new Exception("The method or operation is not implemented."); + } + + // rex new function for "replace assets" functionality + // TODO: implementation by someone + public override libsecondlife.LLUUID ExistsAsset(sbyte assetType, string name) + { + throw new Exception("The method or operation is not implemented."); + } + + #endregion + } +} diff --git a/OpenSim/Framework/Communications/Cache/LibraryRootFolder.cs b/OpenSim/Framework/Communications/Cache/LibraryRootFolder.cs index a8af86931d..a164e1147f 100644 --- a/OpenSim/Framework/Communications/Cache/LibraryRootFolder.cs +++ b/OpenSim/Framework/Communications/Cache/LibraryRootFolder.cs @@ -1,281 +1,278 @@ -/* -* 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.Collections.Generic; -using System.IO; -using System.Xml; -using libsecondlife; -using Nini.Config; - -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.Communications.Cache -{ - /// - /// Basically a hack to give us a Inventory library while we don't have a inventory server - /// once the server is fully implemented then should read the data from that - /// - public class LibraryRootFolder : InventoryFolderImpl - { - private LLUUID libOwner = new LLUUID("11111111-1111-0000-0000-000100bba000"); - - /// - /// Holds the root library folder and all its descendents. This is really only used during inventory - /// setup so that we don't have to repeatedly search the tree of library folders. - /// - protected Dictionary libraryFolders - = new Dictionary(); - - public LibraryRootFolder() - { - MainLog.Instance.Verbose("LIBRARYINVENTORY", "Loading library inventory"); - - agentID = libOwner; - folderID = new LLUUID("00000112-000f-0000-0000-000100bba000"); - name = "OpenSim Library"; - parentID = LLUUID.Zero; - type = (short) 8; - version = (ushort) 1; - - libraryFolders.Add(folderID, this); - - LoadLibraries(Path.Combine(Util.inventoryDir(), "Libraries.xml")); - - // CreateLibraryItems(); - } - - /// - /// Hardcoded item creation. Please don't add any more items here - future items should be created - /// in the xml in the bin/inventory folder. - /// - /// - /// Commented the following out due to sending it all through xml, remove this section once this is provin to work stable. - /// - //private void CreateLibraryItems() - //{ - // InventoryItemBase item = - // CreateItem(new LLUUID("66c41e39-38f9-f75a-024e-585989bfaba9"), - // new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73"), "Default Shape", "Default Shape", - // (int) AssetType.Bodypart, (int) InventoryType.Wearable, folderID); - // item.inventoryCurrentPermissions = 0; - // item.inventoryNextPermissions = 0; - // Items.Add(item.inventoryID, item); - - // item = - // CreateItem(new LLUUID("77c41e39-38f9-f75a-024e-585989bfabc9"), - // new LLUUID("77c41e39-38f9-f75a-024e-585989bbabbb"), "Default Skin", "Default Skin", - // (int) AssetType.Bodypart, (int) InventoryType.Wearable, folderID); - // item.inventoryCurrentPermissions = 0; - // item.inventoryNextPermissions = 0; - // Items.Add(item.inventoryID, item); - - // item = - // CreateItem(new LLUUID("77c41e39-38f9-f75a-0000-585989bf0000"), - // new LLUUID("00000000-38f9-1111-024e-222222111110"), "Default Shirt", "Default Shirt", - // (int) AssetType.Clothing, (int) InventoryType.Wearable, folderID); - // item.inventoryCurrentPermissions = 0; - // item.inventoryNextPermissions = 0; - // Items.Add(item.inventoryID, item); - - // item = - // CreateItem(new LLUUID("77c41e39-38f9-f75a-0000-5859892f1111"), - // new LLUUID("00000000-38f9-1111-024e-222222111120"), "Default Pants", "Default Pants", - // (int) AssetType.Clothing, (int) InventoryType.Wearable, folderID); - // item.inventoryCurrentPermissions = 0; - // item.inventoryNextPermissions = 0; - // Items.Add(item.inventoryID, item); - //} - - public InventoryItemBase CreateItem(LLUUID inventoryID, LLUUID assetID, string name, string description, - int assetType, int invType, LLUUID parentFolderID) - { - InventoryItemBase item = new InventoryItemBase(); - item.avatarID = libOwner; - item.creatorsID = libOwner; - item.inventoryID = inventoryID; - item.assetID = assetID; - item.inventoryDescription = description; - item.inventoryName = name; - item.assetType = assetType; - item.invType = invType; - item.parentFolderID = parentFolderID; - item.inventoryBasePermissions = 0x7FFFFFFF; - item.inventoryEveryOnePermissions = 0x7FFFFFFF; - item.inventoryCurrentPermissions = 0x7FFFFFFF; - item.inventoryNextPermissions = 0x7FFFFFFF; - return item; - } - - /// - /// Use the asset set information at path to load assets - /// - /// - /// - protected void LoadLibraries(string librariesControlPath) - { - MainLog.Instance.Verbose( - "LIBRARYINVENTORY", "Loading libraries control file {0}", librariesControlPath); - - LoadFromFile(librariesControlPath, "Libraries control", ReadLibraryFromConfig); - } - - /// - /// Read a library set from config - /// - /// - protected void ReadLibraryFromConfig(IConfig config) - { - string foldersPath - = Path.Combine( - Util.inventoryDir(), config.GetString("foldersFile", "")); - - LoadFromFile(foldersPath, "Library folders", ReadFolderFromConfig); - - string itemsPath - = Path.Combine( - Util.inventoryDir(), config.GetString("itemsFile", "")); - - LoadFromFile(itemsPath, "Library items", ReadItemFromConfig); - } - - /// - /// Read a library inventory folder from a loaded configuration - /// - /// - private void ReadFolderFromConfig(IConfig config) - { - InventoryFolderImpl folderInfo = new InventoryFolderImpl(); - - folderInfo.folderID = new LLUUID(config.GetString("folderID", folderID.ToString())); - folderInfo.name = config.GetString("name", "unknown"); - folderInfo.parentID = new LLUUID(config.GetString("parentFolderID", folderID.ToString())); - folderInfo.type = (short)config.GetInt("type", 8); - - folderInfo.agentID = libOwner; - folderInfo.version = 1; - - if (libraryFolders.ContainsKey(folderInfo.parentID)) - { - InventoryFolderImpl parentFolder = libraryFolders[folderInfo.parentID]; - - libraryFolders.Add(folderInfo.folderID, folderInfo); - parentFolder.SubFolders.Add(folderInfo.folderID, folderInfo); - -// MainLog.Instance.Verbose( -// "LIBRARYINVENTORY", "Adding folder {0} ({1})", folderInfo.name, folderInfo.folderID); - } - else - { - MainLog.Instance.Warn( - "LIBRARYINVENTORY", - "Couldn't add folder {0} ({1}) since parent folder with ID {2} does not exist!", - folderInfo.name, folderInfo.folderID, folderInfo.parentID); - } - } - - /// - /// Read a library inventory item metadata from a loaded configuration - /// - /// - private void ReadItemFromConfig(IConfig config) - { - InventoryItemBase item = new InventoryItemBase(); - item.avatarID = libOwner; - item.creatorsID = libOwner; - item.inventoryID = new LLUUID(config.GetString("inventoryID", folderID.ToString())); - item.assetID = new LLUUID(config.GetString("assetID", LLUUID.Random().ToString())); - item.parentFolderID = new LLUUID(config.GetString("folderID", folderID.ToString())); - item.inventoryDescription = config.GetString("description", ""); - item.inventoryName = config.GetString("name", ""); - item.assetType = config.GetInt("assetType", 0); - item.invType = config.GetInt("inventoryType", 0); - item.inventoryCurrentPermissions = (uint)config.GetLong("currentPermissions", 0x7FFFFFFF); - item.inventoryNextPermissions = (uint)config.GetLong("nextPermissions", 0x7FFFFFFF); - item.inventoryEveryOnePermissions = (uint)config.GetLong("everyonePermissions", 0x7FFFFFFF); - item.inventoryBasePermissions = (uint)config.GetLong("basePermissions", 0x7FFFFFFF); - - if (libraryFolders.ContainsKey(item.parentFolderID)) - { - InventoryFolderImpl parentFolder = libraryFolders[item.parentFolderID]; - - parentFolder.Items.Add(item.inventoryID, item); - } - else - { - MainLog.Instance.Warn( - "LIBRARYINVENTORY", - "Couldn't add item {0} ({1}) since parent folder with ID {2} does not exist!", - item.inventoryName, item.inventoryID, item.parentFolderID); - } - } - - private delegate void ConfigAction(IConfig config); - - /// - /// Load the given configuration at a path and perform an action on each Config contained within it - /// - /// - /// - /// - private void LoadFromFile(string path, string fileDescription, ConfigAction action) - { - if (File.Exists(path)) - { - try - { - XmlConfigSource source = new XmlConfigSource(path); - - for (int i = 0; i < source.Configs.Count; i++) - { - action(source.Configs[i]); - } - } - catch (XmlException e) - { - MainLog.Instance.Error( - "LIBRARYINVENTORY", "Error loading {0} : {1}", path, e); - } - } - else - { - MainLog.Instance.Error( - "LIBRARYINVENTORY", "{0} file {1} does not exist!", fileDescription, path); - } - } - - /// - /// Looks like a simple getter, but is written like this for some consistency with the other Request - /// methods in the superclass - /// - /// - public Dictionary RequestSelfAndDescendentFolders() - { - return libraryFolders; - } - } -} +/* +* 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.Generic; +using System.IO; +using System.Xml; +using libsecondlife; +using Nini.Config; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Communications.Cache +{ + /// + /// Basically a hack to give us a Inventory library while we don't have a inventory server + /// once the server is fully implemented then should read the data from that + /// + public class LibraryRootFolder : InventoryFolderImpl + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private LLUUID libOwner = new LLUUID("11111111-1111-0000-0000-000100bba000"); + + /// + /// Holds the root library folder and all its descendents. This is really only used during inventory + /// setup so that we don't have to repeatedly search the tree of library folders. + /// + protected Dictionary libraryFolders + = new Dictionary(); + + public LibraryRootFolder() + { + m_log.Info("[LIBRARY INVENTORY]: Loading library inventory"); + + agentID = libOwner; + folderID = new LLUUID("00000112-000f-0000-0000-000100bba000"); + name = "OpenSim Library"; + parentID = LLUUID.Zero; + type = (short) 8; + version = (ushort) 1; + + libraryFolders.Add(folderID, this); + + LoadLibraries(Path.Combine(Util.inventoryDir(), "Libraries.xml")); + + // CreateLibraryItems(); + } + + /// + /// Hardcoded item creation. Please don't add any more items here - future items should be created + /// in the xml in the bin/inventory folder. + /// + /// + /// Commented the following out due to sending it all through xml, remove this section once this is provin to work stable. + /// + //private void CreateLibraryItems() + //{ + // InventoryItemBase item = + // CreateItem(new LLUUID("66c41e39-38f9-f75a-024e-585989bfaba9"), + // new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73"), "Default Shape", "Default Shape", + // (int) AssetType.Bodypart, (int) InventoryType.Wearable, folderID); + // item.inventoryCurrentPermissions = 0; + // item.inventoryNextPermissions = 0; + // Items.Add(item.inventoryID, item); + + // item = + // CreateItem(new LLUUID("77c41e39-38f9-f75a-024e-585989bfabc9"), + // new LLUUID("77c41e39-38f9-f75a-024e-585989bbabbb"), "Default Skin", "Default Skin", + // (int) AssetType.Bodypart, (int) InventoryType.Wearable, folderID); + // item.inventoryCurrentPermissions = 0; + // item.inventoryNextPermissions = 0; + // Items.Add(item.inventoryID, item); + + // item = + // CreateItem(new LLUUID("77c41e39-38f9-f75a-0000-585989bf0000"), + // new LLUUID("00000000-38f9-1111-024e-222222111110"), "Default Shirt", "Default Shirt", + // (int) AssetType.Clothing, (int) InventoryType.Wearable, folderID); + // item.inventoryCurrentPermissions = 0; + // item.inventoryNextPermissions = 0; + // Items.Add(item.inventoryID, item); + + // item = + // CreateItem(new LLUUID("77c41e39-38f9-f75a-0000-5859892f1111"), + // new LLUUID("00000000-38f9-1111-024e-222222111120"), "Default Pants", "Default Pants", + // (int) AssetType.Clothing, (int) InventoryType.Wearable, folderID); + // item.inventoryCurrentPermissions = 0; + // item.inventoryNextPermissions = 0; + // Items.Add(item.inventoryID, item); + //} + + public InventoryItemBase CreateItem(LLUUID inventoryID, LLUUID assetID, string name, string description, + int assetType, int invType, LLUUID parentFolderID) + { + InventoryItemBase item = new InventoryItemBase(); + item.avatarID = libOwner; + item.creatorsID = libOwner; + item.inventoryID = inventoryID; + item.assetID = assetID; + item.inventoryDescription = description; + item.inventoryName = name; + item.assetType = assetType; + item.invType = invType; + item.parentFolderID = parentFolderID; + item.inventoryBasePermissions = 0x7FFFFFFF; + item.inventoryEveryOnePermissions = 0x7FFFFFFF; + item.inventoryCurrentPermissions = 0x7FFFFFFF; + item.inventoryNextPermissions = 0x7FFFFFFF; + return item; + } + + /// + /// Use the asset set information at path to load assets + /// + /// + /// + protected void LoadLibraries(string librariesControlPath) + { + m_log.InfoFormat( + "[LIBRARY INVENTORY]: Loading libraries control file {0}", librariesControlPath); + + LoadFromFile(librariesControlPath, "Libraries control", ReadLibraryFromConfig); + } + + /// + /// Read a library set from config + /// + /// + protected void ReadLibraryFromConfig(IConfig config) + { + string foldersPath + = Path.Combine( + Util.inventoryDir(), config.GetString("foldersFile", System.String.Empty)); + + LoadFromFile(foldersPath, "Library folders", ReadFolderFromConfig); + + string itemsPath + = Path.Combine( + Util.inventoryDir(), config.GetString("itemsFile", System.String.Empty)); + + LoadFromFile(itemsPath, "Library items", ReadItemFromConfig); + } + + /// + /// Read a library inventory folder from a loaded configuration + /// + /// + private void ReadFolderFromConfig(IConfig config) + { + InventoryFolderImpl folderInfo = new InventoryFolderImpl(); + + folderInfo.folderID = new LLUUID(config.GetString("folderID", folderID.ToString())); + folderInfo.name = config.GetString("name", "unknown"); + folderInfo.parentID = new LLUUID(config.GetString("parentFolderID", folderID.ToString())); + folderInfo.type = (short)config.GetInt("type", 8); + + folderInfo.agentID = libOwner; + folderInfo.version = 1; + + if (libraryFolders.ContainsKey(folderInfo.parentID)) + { + InventoryFolderImpl parentFolder = libraryFolders[folderInfo.parentID]; + + libraryFolders.Add(folderInfo.folderID, folderInfo); + parentFolder.SubFolders.Add(folderInfo.folderID, folderInfo); + +// m_log.InfoFormat("[LIBRARY INVENTORY]: Adding folder {0} ({1})", folderInfo.name, folderInfo.folderID); + } + else + { + m_log.WarnFormat( + "[LIBRARY INVENTORY]: Couldn't add folder {0} ({1}) since parent folder with ID {2} does not exist!", + folderInfo.name, folderInfo.folderID, folderInfo.parentID); + } + } + + /// + /// Read a library inventory item metadata from a loaded configuration + /// + /// + private void ReadItemFromConfig(IConfig config) + { + InventoryItemBase item = new InventoryItemBase(); + item.avatarID = libOwner; + item.creatorsID = libOwner; + item.inventoryID = new LLUUID(config.GetString("inventoryID", folderID.ToString())); + item.assetID = new LLUUID(config.GetString("assetID", LLUUID.Random().ToString())); + item.parentFolderID = new LLUUID(config.GetString("folderID", folderID.ToString())); + item.inventoryDescription = config.GetString("description", System.String.Empty); + item.inventoryName = config.GetString("name", System.String.Empty); + item.assetType = config.GetInt("assetType", 0); + item.invType = config.GetInt("inventoryType", 0); + item.inventoryCurrentPermissions = (uint)config.GetLong("currentPermissions", 0x7FFFFFFF); + item.inventoryNextPermissions = (uint)config.GetLong("nextPermissions", 0x7FFFFFFF); + item.inventoryEveryOnePermissions = (uint)config.GetLong("everyonePermissions", 0x7FFFFFFF); + item.inventoryBasePermissions = (uint)config.GetLong("basePermissions", 0x7FFFFFFF); + + if (libraryFolders.ContainsKey(item.parentFolderID)) + { + InventoryFolderImpl parentFolder = libraryFolders[item.parentFolderID]; + + parentFolder.Items.Add(item.inventoryID, item); + } + else + { + m_log.WarnFormat( + "[LIBRARY INVENTORY]: Couldn't add item {0} ({1}) since parent folder with ID {2} does not exist!", + item.inventoryName, item.inventoryID, item.parentFolderID); + } + } + + private delegate void ConfigAction(IConfig config); + + /// + /// Load the given configuration at a path and perform an action on each Config contained within it + /// + /// + /// + /// + private void LoadFromFile(string path, string fileDescription, ConfigAction action) + { + if (File.Exists(path)) + { + try + { + XmlConfigSource source = new XmlConfigSource(path); + + for (int i = 0; i < source.Configs.Count; i++) + { + action(source.Configs[i]); + } + } + catch (XmlException e) + { + m_log.ErrorFormat("[LIBRARY INVENTORY]: Error loading {0} : {1}", path, e); + } + } + else + { + m_log.ErrorFormat("[LIBRARY INVENTORY]: {0} file {1} does not exist!", fileDescription, path); + } + } + + /// + /// Looks like a simple getter, but is written like this for some consistency with the other Request + /// methods in the superclass + /// + /// + public Dictionary RequestSelfAndDescendentFolders() + { + return libraryFolders; + } + } +} diff --git a/OpenSim/Framework/Communications/Cache/SQLAssetServer.cs b/OpenSim/Framework/Communications/Cache/SQLAssetServer.cs index a95463c648..e83eb8ead1 100644 --- a/OpenSim/Framework/Communications/Cache/SQLAssetServer.cs +++ b/OpenSim/Framework/Communications/Cache/SQLAssetServer.cs @@ -1,107 +1,108 @@ -/* -* Copyright (c) Contributors, http://www.openmetaverse.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.Reflection; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.Communications.Cache -{ - public class SQLAssetServer : AssetServerBase - { - public SQLAssetServer(string pluginName) - { - AddPlugin(pluginName); - } - - public SQLAssetServer(IAssetProvider assetProvider) - { - m_assetProvider = assetProvider; - } - - public void AddPlugin(string FileName) - { - MainLog.Instance.Verbose("SQLAssetServer", "AssetStorage: Attempting to load " + FileName); - Assembly pluginAssembly = Assembly.LoadFrom(FileName); - - foreach (Type pluginType in pluginAssembly.GetTypes()) - { - if (!pluginType.IsAbstract) - { - Type typeInterface = pluginType.GetInterface("IAssetProvider", true); - - if (typeInterface != null) - { - IAssetProvider plug = - (IAssetProvider) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); - m_assetProvider = plug; - m_assetProvider.Initialise(); - - MainLog.Instance.Verbose("AssetStorage", - "Added " + m_assetProvider.Name + " " + - m_assetProvider.Version); - } - } - } - } - - - public override void Close() - { - base.Close(); - - m_assetProvider.CommitAssets(); - } - - // rex new function for "replace assets" functionality - public override libsecondlife.LLUUID ExistsAsset(sbyte assetType, string name) - { - return m_assetProvider.ExistsAsset(assetType, name); - } - - protected override AssetBase GetAsset(AssetRequest req) - { - AssetBase asset; - lock (m_syncLock) - { - asset = m_assetProvider.FetchAsset(req.AssetID); - } - - return asset; - } - - protected override void StoreAsset(AssetBase asset) - { - m_assetProvider.CreateAsset(asset); - } - - protected override void CommitAssets() - { - m_assetProvider.CommitAssets(); - } - } -} \ No newline at end of file +/* +* Copyright (c) Contributors, http://www.openmetaverse.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.Reflection; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Communications.Cache +{ + public class SQLAssetServer : AssetServerBase + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + public SQLAssetServer(string pluginName) + { + AddPlugin(pluginName); + } + + public SQLAssetServer(IAssetProvider assetProvider) + { + m_assetProvider = assetProvider; + } + + public void AddPlugin(string FileName) + { + m_log.Info("[SQLAssetServer]: AssetStorage: Attempting to load " + FileName); + Assembly pluginAssembly = Assembly.LoadFrom(FileName); + + foreach (Type pluginType in pluginAssembly.GetTypes()) + { + if (!pluginType.IsAbstract) + { + Type typeInterface = pluginType.GetInterface("IAssetProvider", true); + + if (typeInterface != null) + { + IAssetProvider plug = + (IAssetProvider) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); + m_assetProvider = plug; + m_assetProvider.Initialise(); + + m_log.Info("[AssetStorage]: " + + "Added " + m_assetProvider.Name + " " + + m_assetProvider.Version); + } + } + } + } + + public override void Close() + { + base.Close(); + + m_assetProvider.CommitAssets(); + } + + // rex new function for "replace assets" functionality + public override libsecondlife.LLUUID ExistsAsset(sbyte assetType, string name) + { + return m_assetProvider.ExistsAsset(assetType, name); + } + + protected override AssetBase GetAsset(AssetRequest req) + { + AssetBase asset; + lock (m_syncLock) + { + asset = m_assetProvider.FetchAsset(req.AssetID); + } + + return asset; + } + + protected override void StoreAsset(AssetBase asset) + { + m_assetProvider.CreateAsset(asset); + } + + protected override void CommitAssets() + { + m_assetProvider.CommitAssets(); + } + } +} diff --git a/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs b/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs index 7741885527..8d10334cf2 100644 --- a/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs +++ b/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs @@ -1,368 +1,372 @@ -/* -* 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.Collections.Generic; -using libsecondlife; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.Communications.Cache -{ - public class UserProfileCacheService - { - // Fields - private readonly CommunicationsManager m_parent; - private readonly Dictionary m_userProfiles = new Dictionary(); - - public LibraryRootFolder libraryRoot = new LibraryRootFolder(); - public RexWorldAssetsFolder worldlibraryRoot = null; // rex added - - // Methods - public UserProfileCacheService(CommunicationsManager parent) - { - m_parent = parent; - // rex, added worldlibrary - if (GlobalSettings.Instance.ConfigSource.Configs["Startup"].GetBoolean("worldlibraryfolder", true)) - { - worldlibraryRoot = new RexWorldAssetsFolder(m_parent.AssetCache); - libraryRoot.CreateNewSubFolder(new LLUUID("00000112-000f-0000-0000-000100bba005"), "World Library", (ushort)8); - } - // rexend - } - - /// - /// A new user has moved into a region in this instance - /// so get info from servers - /// - /// - public void AddNewUser(LLUUID userID) - { - // Potential fix - Multithreading issue. - lock (m_userProfiles) - { - if (!m_userProfiles.ContainsKey(userID)) - { - CachedUserInfo userInfo = new CachedUserInfo(m_parent); - userInfo.UserProfile = m_parent.UserService.GetUserProfile(userID, ""); - - if (userInfo.UserProfile != null) - { - // The request itself will occur when the agent finishes logging on to the region - // so there's no need to do it here. - //RequestInventoryForUser(userID, userInfo); - m_userProfiles.Add(userID, userInfo); - } - else - { - MainLog.Instance.Error("USERCACHE", "User profile for user {0} not found", userID); - } - } - } - } - - //Rex mode - /// - /// A new user has moved into a region in this instance - /// so get info from servers - /// - /// - public void AddNewUser(LLUUID userID, string authAddr) - { - // Potential fix - Multithreading issue. - lock (m_userProfiles) - { - if (!m_userProfiles.ContainsKey(userID)) - { - CachedUserInfo userInfo = new CachedUserInfo(m_parent); - userInfo.UserProfile = m_parent.UserService.GetUserProfile(userID, authAddr); - - if (userInfo.UserProfile != null) - { - //RequestInventoryForUser(userID, userInfo); - // The request itself will occur when the agent finishes logging on to the region - // so there's no need to do it here. - //RequestInventoryForUser(userID, userInfo); - m_userProfiles.Add(userID, userInfo); - } - else - { - System.Console.WriteLine("CACHE", "User profile for user not found"); - } - } - } - } - - - public void UpdateUserInventory(LLUUID userID) - { - CachedUserInfo userInfo = GetUserDetails(userID); - if (userInfo != null) - { - RequestInventoryForUser(userID, userInfo); - } - } - - public CachedUserInfo GetUserDetails(LLUUID userID) - { - if (m_userProfiles.ContainsKey(userID)) - return m_userProfiles[userID]; - else - return null; - } - - public void HandleCreateInventoryFolder(IClientAPI remoteClient, LLUUID folderID, ushort folderType, - string folderName, LLUUID parentID) - { - CachedUserInfo userProfile; - - if (m_userProfiles.TryGetValue(remoteClient.AgentId, out userProfile)) - { - if (userProfile.RootFolder != null) - { - if (userProfile.RootFolder.folderID == parentID) - { - InventoryFolderImpl createdFolder = - userProfile.RootFolder.CreateNewSubFolder(folderID, folderName, folderType); - - if (createdFolder != null) - { - InventoryFolderBase createdBaseFolder = new InventoryFolderBase(); - createdBaseFolder.agentID = createdFolder.agentID; - createdBaseFolder.folderID = createdFolder.folderID; - createdBaseFolder.name = createdFolder.name; - createdBaseFolder.parentID = createdFolder.parentID; - createdBaseFolder.type = createdFolder.type; - createdBaseFolder.version = createdFolder.version; - m_parent.InventoryService.AddNewInventoryFolder(remoteClient.AgentId, createdBaseFolder); - } - } - else - { - InventoryFolderImpl folder = userProfile.RootFolder.HasSubFolder(parentID); - if (folder != null) - { - folder.CreateNewSubFolder(folderID, folderName, folderType); - } - } - } - } - } - - public void HandleUpdateInventoryFolder(IClientAPI remoteClient, LLUUID folderID, ushort type, string name, - LLUUID parentID) - { - CachedUserInfo userProfile; - - if (m_userProfiles.TryGetValue(remoteClient.AgentId, out userProfile)) - { - if (userProfile.RootFolder != null) - { - InventoryFolderBase baseFolder = new InventoryFolderBase(); - baseFolder.agentID = remoteClient.AgentId; - baseFolder.folderID = folderID; - baseFolder.name = name; - baseFolder.parentID = parentID; - baseFolder.type = (short) type; - baseFolder.version = userProfile.RootFolder.version; - m_parent.InventoryService.AddNewInventoryFolder(remoteClient.AgentId, baseFolder); - } - } - } - - public void HandleMoveInventoryFolder(IClientAPI remoteClient, LLUUID folderID, LLUUID parentID) - { - CachedUserInfo userProfile; - - if (m_userProfiles.TryGetValue(remoteClient.AgentId, out userProfile)) - { - if (userProfile.RootFolder != null) - { - InventoryFolderBase baseFolder = new InventoryFolderBase(); - baseFolder.agentID = remoteClient.AgentId; - baseFolder.folderID = folderID; - baseFolder.parentID = parentID; - m_parent.InventoryService.MoveInventoryFolder(remoteClient.AgentId, baseFolder); - } - } - } - - /// - /// Tell the client about the various child items and folders contained in the requested folder. - /// - /// - /// - /// - /// - /// - /// - public void HandleFetchInventoryDescendents(IClientAPI remoteClient, LLUUID folderID, LLUUID ownerID, - bool fetchFolders, bool fetchItems, int sortOrder) - { - // XXX We're not handling sortOrder yet! - - InventoryFolderImpl fold = null; - - // rex, added worldassetfolder - if (worldlibraryRoot != null) - { - if (folderID == worldlibraryRoot.folderID) - { - remoteClient.SendInventoryFolderDetails( - worldlibraryRoot.agentID, worldlibraryRoot.folderID, worldlibraryRoot.RequestListOfItems(), - worldlibraryRoot.RequestListOfFolders(), fetchFolders, fetchItems); - return; - } - if ((fold = worldlibraryRoot.HasSubFolder(folderID)) != null) - { - worldlibraryRoot.UpdateWorldAssetFolders(); - remoteClient.SendInventoryFolderDetails( - worldlibraryRoot.agentID, folderID, fold.RequestListOfItems(), - fold.RequestListOfFolders(), fetchFolders, fetchItems); - - return; - } - } - // rex-end - - if (folderID == libraryRoot.folderID) - { - remoteClient.SendInventoryFolderDetails( - libraryRoot.agentID, libraryRoot.folderID, libraryRoot.RequestListOfItems(), - libraryRoot.RequestListOfFolders(), fetchFolders, fetchItems); - - return; - } - - if ((fold = libraryRoot.HasSubFolder(folderID)) != null) - { - remoteClient.SendInventoryFolderDetails( - libraryRoot.agentID, folderID, fold.RequestListOfItems(), - fold.RequestListOfFolders(), fetchFolders, fetchItems); - - return; - } - - CachedUserInfo userProfile; - if (m_userProfiles.TryGetValue(remoteClient.AgentId, out userProfile)) - { - if (userProfile.RootFolder != null) - { - if (userProfile.RootFolder.folderID == folderID) - { - remoteClient.SendInventoryFolderDetails( - remoteClient.AgentId, folderID, userProfile.RootFolder.RequestListOfItems(), - userProfile.RootFolder.RequestListOfFolders(), - fetchFolders, fetchItems); - - return; - } - else - { - if ((fold = userProfile.RootFolder.HasSubFolder(folderID)) != null) - { - remoteClient.SendInventoryFolderDetails( - remoteClient.AgentId, folderID, fold.RequestListOfItems(), - fold.RequestListOfFolders(), fetchFolders, fetchItems); - - return; - } - } - } - else - { - MainLog.Instance.Error( - "INVENTORYCACHE", "Could not find root folder for user {0}", remoteClient.Name); - - return; - } - } - else - { - MainLog.Instance.Error( - "INVENTORYCACHE", - "Could not find user profile for {0} for folder {1}", - remoteClient.Name, folderID); - - return; - } - - // If we've reached this point then we couldn't find the folder, even though the client thinks - // it exists - MainLog.Instance.Error( - "INVENTORYCACHE", - "Could not find folder {0} for user {1}", - folderID, remoteClient.Name); - } - - public void HandlePurgeInventoryDescendents(IClientAPI remoteClient, LLUUID folderID) - { - CachedUserInfo userProfile; - if (m_userProfiles.TryGetValue(remoteClient.AgentId, out userProfile)) - { - if (userProfile.RootFolder != null) - { - InventoryFolderImpl subFolder = userProfile.RootFolder.HasSubFolder(folderID); - if (subFolder != null) - { - List items = subFolder.RequestListOfItems(); - foreach (InventoryItemBase item in items) - { - userProfile.DeleteItem(remoteClient.AgentId, item); - } - } - } - } - } - - public void HandleFetchInventory(IClientAPI remoteClient, LLUUID itemID, LLUUID ownerID) - { - if (ownerID == libraryRoot.agentID) - { - //Console.WriteLine("request info for library item"); - - return; - } - - CachedUserInfo userProfile; - if (m_userProfiles.TryGetValue(remoteClient.AgentId, out userProfile)) - { - if (userProfile.RootFolder != null) - { - InventoryItemBase item = userProfile.RootFolder.HasItem(itemID); - if (item != null) - { - remoteClient.SendInventoryItemDetails(ownerID, item); - } - } - } - } - - private void RequestInventoryForUser(LLUUID userID, CachedUserInfo userInfo) - { - m_parent.InventoryService.RequestInventoryForUser(userID, userInfo.FolderReceive, userInfo.ItemReceive); - } - } -} \ No newline at end of file +/* +* 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.Generic; +using libsecondlife; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Communications.Cache +{ + public class UserProfileCacheService + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + // Fields + private readonly CommunicationsManager m_parent; + private readonly Dictionary m_userProfiles = new Dictionary(); + + public LibraryRootFolder libraryRoot = new LibraryRootFolder(); + public RexWorldAssetsFolder worldlibraryRoot = null; // rex added + + // Methods + public UserProfileCacheService(CommunicationsManager parent) + { + m_parent = parent; + // rex, added worldlibrary + if (GlobalSettings.Instance.ConfigSource.Configs["Startup"].GetBoolean("worldlibraryfolder", true)) + { + worldlibraryRoot = new RexWorldAssetsFolder(m_parent.AssetCache); + libraryRoot.CreateNewSubFolder(new LLUUID("00000112-000f-0000-0000-000100bba005"), "World Library", (ushort)8); + } + // rexend + } + + /// + /// A new user has moved into a region in this instance + /// so get info from servers + /// + /// + public void AddNewUser(LLUUID userID) + { + // Potential fix - Multithreading issue. + lock (m_userProfiles) + { + if (!m_userProfiles.ContainsKey(userID)) + { + CachedUserInfo userInfo = new CachedUserInfo(m_parent); + userInfo.UserProfile = m_parent.UserService.GetUserProfile(userID, ""); + + if (userInfo.UserProfile != null) + { + // The request itself will occur when the agent finishes logging on to the region + // so there's no need to do it here. + //RequestInventoryForUser(userID, userInfo); + m_userProfiles.Add(userID, userInfo); + } + else + { + m_log.ErrorFormat("[USERCACHE]: User profile for user {0} not found", userID); + } + } + } + } + + //Rex mode + /// + /// A new user has moved into a region in this instance + /// so get info from servers + /// + /// + public void AddNewUser(LLUUID userID, string authAddr) + { + // Potential fix - Multithreading issue. + lock (m_userProfiles) + { + if (!m_userProfiles.ContainsKey(userID)) + { + CachedUserInfo userInfo = new CachedUserInfo(m_parent); + userInfo.UserProfile = m_parent.UserService.GetUserProfile(userID, authAddr); + + if (userInfo.UserProfile != null) + { + //RequestInventoryForUser(userID, userInfo); + // The request itself will occur when the agent finishes logging on to the region + // so there's no need to do it here. + //RequestInventoryForUser(userID, userInfo); + m_userProfiles.Add(userID, userInfo); + } + else + { + System.Console.WriteLine("CACHE", "User profile for user not found"); + } + } + } + } + + + public void UpdateUserInventory(LLUUID userID) + { + CachedUserInfo userInfo = GetUserDetails(userID); + if (userInfo != null) + { + RequestInventoryForUser(userID, userInfo); + } + } + + public CachedUserInfo GetUserDetails(LLUUID userID) + { + if (m_userProfiles.ContainsKey(userID)) + return m_userProfiles[userID]; + else + return null; + } + + public void HandleCreateInventoryFolder(IClientAPI remoteClient, LLUUID folderID, ushort folderType, + string folderName, LLUUID parentID) + { + CachedUserInfo userProfile; + + if (m_userProfiles.TryGetValue(remoteClient.AgentId, out userProfile)) + { + if (userProfile.RootFolder != null) + { + if (userProfile.RootFolder.folderID == parentID) + { + InventoryFolderImpl createdFolder = + userProfile.RootFolder.CreateNewSubFolder(folderID, folderName, folderType); + + if (createdFolder != null) + { + InventoryFolderBase createdBaseFolder = new InventoryFolderBase(); + createdBaseFolder.agentID = createdFolder.agentID; + createdBaseFolder.folderID = createdFolder.folderID; + createdBaseFolder.name = createdFolder.name; + createdBaseFolder.parentID = createdFolder.parentID; + createdBaseFolder.type = createdFolder.type; + createdBaseFolder.version = createdFolder.version; + m_parent.InventoryService.AddNewInventoryFolder(remoteClient.AgentId, createdBaseFolder); + } + } + else + { + InventoryFolderImpl folder = userProfile.RootFolder.HasSubFolder(parentID); + if (folder != null) + { + folder.CreateNewSubFolder(folderID, folderName, folderType); + } + } + } + } + } + + public void HandleUpdateInventoryFolder(IClientAPI remoteClient, LLUUID folderID, ushort type, string name, + LLUUID parentID) + { + CachedUserInfo userProfile; + + if (m_userProfiles.TryGetValue(remoteClient.AgentId, out userProfile)) + { + if (userProfile.RootFolder != null) + { + InventoryFolderBase baseFolder = new InventoryFolderBase(); + baseFolder.agentID = remoteClient.AgentId; + baseFolder.folderID = folderID; + baseFolder.name = name; + baseFolder.parentID = parentID; + baseFolder.type = (short) type; + baseFolder.version = userProfile.RootFolder.version; + m_parent.InventoryService.AddNewInventoryFolder(remoteClient.AgentId, baseFolder); + } + } + } + + public void HandleMoveInventoryFolder(IClientAPI remoteClient, LLUUID folderID, LLUUID parentID) + { + CachedUserInfo userProfile; + + if (m_userProfiles.TryGetValue(remoteClient.AgentId, out userProfile)) + { + if (userProfile.RootFolder != null) + { + InventoryFolderBase baseFolder = new InventoryFolderBase(); + baseFolder.agentID = remoteClient.AgentId; + baseFolder.folderID = folderID; + baseFolder.parentID = parentID; + m_parent.InventoryService.MoveInventoryFolder(remoteClient.AgentId, baseFolder); + } + } + } + + /// + /// Tell the client about the various child items and folders contained in the requested folder. + /// + /// + /// + /// + /// + /// + /// + public void HandleFetchInventoryDescendents(IClientAPI remoteClient, LLUUID folderID, LLUUID ownerID, + bool fetchFolders, bool fetchItems, int sortOrder) + { + // XXX We're not handling sortOrder yet! + + InventoryFolderImpl fold = null; + + // rex, added worldassetfolder + if (worldlibraryRoot != null) + { + if (folderID == worldlibraryRoot.folderID) + { + remoteClient.SendInventoryFolderDetails( + worldlibraryRoot.agentID, worldlibraryRoot.folderID, worldlibraryRoot.RequestListOfItems(), + worldlibraryRoot.RequestListOfFolders(), fetchFolders, fetchItems); + return; + } + if ((fold = worldlibraryRoot.HasSubFolder(folderID)) != null) + { + worldlibraryRoot.UpdateWorldAssetFolders(); + remoteClient.SendInventoryFolderDetails( + worldlibraryRoot.agentID, folderID, fold.RequestListOfItems(), + fold.RequestListOfFolders(), fetchFolders, fetchItems); + + return; + } + } + // rex-end + + if (folderID == libraryRoot.folderID) + { + remoteClient.SendInventoryFolderDetails( + libraryRoot.agentID, libraryRoot.folderID, libraryRoot.RequestListOfItems(), + libraryRoot.RequestListOfFolders(), fetchFolders, fetchItems); + + return; + } + + if ((fold = libraryRoot.HasSubFolder(folderID)) != null) + { + remoteClient.SendInventoryFolderDetails( + libraryRoot.agentID, folderID, fold.RequestListOfItems(), + fold.RequestListOfFolders(), fetchFolders, fetchItems); + + return; + } + + CachedUserInfo userProfile; + if (m_userProfiles.TryGetValue(remoteClient.AgentId, out userProfile)) + { + if (userProfile.RootFolder != null) + { + if (userProfile.RootFolder.folderID == folderID) + { + remoteClient.SendInventoryFolderDetails( + remoteClient.AgentId, folderID, userProfile.RootFolder.RequestListOfItems(), + userProfile.RootFolder.RequestListOfFolders(), + fetchFolders, fetchItems); + + return; + } + else + { + if ((fold = userProfile.RootFolder.HasSubFolder(folderID)) != null) + { + remoteClient.SendInventoryFolderDetails( + remoteClient.AgentId, folderID, fold.RequestListOfItems(), + fold.RequestListOfFolders(), fetchFolders, fetchItems); + + return; + } + } + } + else + { + m_log.ErrorFormat("[INVENTORYCACHE]: Could not find root folder for user {0}", remoteClient.Name); + + return; + } + } + else + { + m_log.ErrorFormat("[INVENTORYCACHE]: " + + "Could not find user profile for {0} for folder {1}", + remoteClient.Name, folderID); + + return; + } + + // If we've reached this point then we couldn't find the folder, even though the client thinks + // it exists + m_log.ErrorFormat("[INVENTORYCACHE]: " + + "Could not find folder {0} for user {1}", + folderID, remoteClient.Name); + } + + public void HandlePurgeInventoryDescendents(IClientAPI remoteClient, LLUUID folderID) + { +// m_log.InfoFormat("[INVENTORYCACHE]: Purging folder {0} for {1} uuid {2}", +// folderID, remoteClient.Name, remoteClient.AgentId); + + CachedUserInfo userProfile; + if (m_userProfiles.TryGetValue(remoteClient.AgentId, out userProfile)) + { + if (userProfile.RootFolder != null) + { + InventoryFolderImpl subFolder = userProfile.RootFolder.HasSubFolder(folderID); + if (subFolder != null) + { + List items = subFolder.RequestListOfItems(); + foreach (InventoryItemBase item in items) + { + userProfile.DeleteItem(remoteClient.AgentId, item); + } + } + } + } + } + + public void HandleFetchInventory(IClientAPI remoteClient, LLUUID itemID, LLUUID ownerID) + { + if (ownerID == libraryRoot.agentID) + { + //Console.WriteLine("request info for library item"); + + return; + } + + CachedUserInfo userProfile; + if (m_userProfiles.TryGetValue(remoteClient.AgentId, out userProfile)) + { + if (userProfile.RootFolder != null) + { + InventoryItemBase item = userProfile.RootFolder.HasItem(itemID); + if (item != null) + { + remoteClient.SendInventoryItemDetails(ownerID, item); + } + } + } + } + + private void RequestInventoryForUser(LLUUID userID, CachedUserInfo userInfo) + { + m_parent.InventoryService.RequestInventoryForUser(userID, userInfo.FolderReceive, userInfo.ItemReceive); + } + } +} diff --git a/OpenSim/Framework/Communications/Capabilities/Caps.cs b/OpenSim/Framework/Communications/Capabilities/Caps.cs index 8034f5ba05..c127699af0 100644 --- a/OpenSim/Framework/Communications/Capabilities/Caps.cs +++ b/OpenSim/Framework/Communications/Capabilities/Caps.cs @@ -1,812 +1,817 @@ -/* -* 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.IO; -using libsecondlife; -using OpenSim.Framework; -using OpenSim.Framework.Communications.Cache; -using OpenSim.Framework.Console; -using OpenSim.Framework.Servers; - -namespace OpenSim.Region.Capabilities -{ - public delegate void UpLoadedAsset( - string assetName, string description, LLUUID assetID, LLUUID inventoryItem, LLUUID parentFolder, - byte[] data, string inventoryType, string assetType); - - public delegate LLUUID UpdateItem(LLUUID itemID, byte[] data); - - public delegate void UpdateTaskScript(LLUUID itemID, LLUUID primID, bool isScriptRunning, byte[] data); - - public delegate void NewInventoryItem(LLUUID userID, InventoryItemBase item); - - // rex, added for asset replace functionality - public delegate bool InventoryAssetCheck(LLUUID userID, LLUUID assetID); - - public delegate LLUUID ItemUpdatedCallback(LLUUID userID, LLUUID itemID, byte[] data); - - public delegate void TaskScriptUpdatedCallback(LLUUID userID, LLUUID itemID, LLUUID primID, - bool isScriptRunning, byte[] data); - - public class Caps - { - private string m_httpListenerHostName; - private uint m_httpListenPort; - - private string m_capsObjectPath = "00001-"; - private string m_requestPath = "0000/"; - private string m_mapLayerPath = "0001/"; - private string m_newInventory = "0002/"; - //private string m_requestTexture = "0003/"; - private string m_notecardUpdatePath = "0004/"; - private string m_notecardTaskUpdatePath = "0005/"; - - //private string eventQueue = "0100/"; - private BaseHttpServer m_httpListener; - private LLUUID m_agentID; - private AssetCache m_assetCache; - private int m_eventQueueCount = 1; - private Queue m_capsEventQueue = new Queue(); - private bool m_dumpAssetsToFile; - private bool m_replaceAssets; - - // These are callbacks which will be setup by the scene so that we can update scene data when we - // receive capability calls - public NewInventoryItem AddNewInventoryItem = null; - public InventoryAssetCheck CheckInventoryForAsset = null; - public ItemUpdatedCallback ItemUpdatedCall = null; - public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null; - - public Caps(AssetCache assetCache, BaseHttpServer httpServer, string httpListen, uint httpPort, string capsPath, - LLUUID agent, bool dumpAssetsToFile) - { - m_assetCache = assetCache; - m_capsObjectPath = capsPath; - m_httpListener = httpServer; - m_httpListenerHostName = httpListen; - m_httpListenPort = httpPort; - m_agentID = agent; - m_dumpAssetsToFile = dumpAssetsToFile; - - m_replaceAssets = (GlobalSettings.Instance.ConfigSource.Configs["Startup"].GetBoolean("replace_assets", true)); - } - - /// - /// - /// - public void RegisterHandlers() - { - MainLog.Instance.Verbose("CAPS", "Registering CAPS handlers"); - string capsBase = "/CAPS/" + m_capsObjectPath; - try - { - m_httpListener.AddStreamHandler( - new LLSDStreamhandler("POST", capsBase + m_mapLayerPath, - GetMapLayer)); - m_httpListener.AddStreamHandler( - new LLSDStreamhandler("POST", - capsBase + m_newInventory, - NewAgentInventoryRequest)); - - AddLegacyCapsHandler(m_httpListener, m_requestPath, CapsRequest); - //AddLegacyCapsHandler(m_httpListener, m_requestTexture , RequestTexture); - AddLegacyCapsHandler(m_httpListener, m_notecardUpdatePath, NoteCardAgentInventory); - AddLegacyCapsHandler(m_httpListener, m_notecardTaskUpdatePath, ScriptTaskInventory); - } - catch (Exception e) - { - MainLog.Instance.Error("CAPS", e.ToString()); - } - } - - - //[Obsolete("Use BaseHttpServer.AddStreamHandler(new LLSDStreamHandler( LLSDMethod delegate )) instead.")] - //Commented out the obsolete as at this time the first caps request can not use the new Caps method - //as the sent type is a array and not a map and the deserialising doesn't deal properly with arrays. - private void AddLegacyCapsHandler(BaseHttpServer httpListener, string path, RestMethod restMethod) - { - string capsBase = "/CAPS/" + m_capsObjectPath; - httpListener.AddStreamHandler(new RestStreamHandler("POST", capsBase + path, restMethod)); - } - - /// - /// Construct a client response detailing all the capabilities this server can provide. - /// - /// - /// - /// - /// - public string CapsRequest(string request, string path, string param) - { - //Console.WriteLine("caps request " + request); - string result = LLSDHelpers.SerialiseLLSDReply(GetCapabilities()); - return result; - } - - /// - /// Return an LLSDCapsDetails listing all the capabilities this server can provide - /// - /// - protected LLSDCapsDetails GetCapabilities() - { - LLSDCapsDetails caps = new LLSDCapsDetails(); - string capsBaseUrl = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + "/CAPS/" + - m_capsObjectPath; - caps.MapLayer = capsBaseUrl + m_mapLayerPath; - // caps.RequestTextureDownload = capsBaseUrl + m_requestTexture; - caps.NewFileAgentInventory = capsBaseUrl + m_newInventory; - caps.UpdateNotecardAgentInventory = capsBaseUrl + m_notecardUpdatePath; - caps.UpdateScriptAgentInventory = capsBaseUrl + m_notecardUpdatePath; - caps.UpdateScriptTaskInventory = capsBaseUrl + m_notecardTaskUpdatePath; - return caps; - } - - /// - /// - /// - /// - /// - public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq) - { - LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); - mapResponse.LayerData.Array.Add(GetLLSDMapLayerResponse()); - return mapResponse; - } - - /// - /// - /// - /// - protected LLSDMapLayer GetLLSDMapLayerResponse() - { - LLSDMapLayer mapLayer = new LLSDMapLayer(); - mapLayer.Right = 5000; - mapLayer.Top = 5000; - mapLayer.ImageID = new LLUUID("00000000-0000-0000-9999-000000000006"); - return mapLayer; - } - - /// - /// - /// - /// - /// - /// - /// - public string RequestTexture(string request, string path, string param) - { - Console.WriteLine("texture request " + request); - // Needs implementing (added to remove compiler warning) - return ""; - } - - #region EventQueue (Currently not enabled) - - /// - /// - /// - /// - /// - /// - /// - public string ProcessEventQueue(string request, string path, string param) - { - string res = ""; - - if (m_capsEventQueue.Count > 0) - { - lock (m_capsEventQueue) - { - string item = m_capsEventQueue.Dequeue(); - res = item; - } - } - else - { - res = CreateEmptyEventResponse(); - } - return res; - } - - /// - /// - /// - /// - /// - /// - public string CreateEstablishAgentComms(string caps, string ipAddressPort) - { - LLSDCapEvent eventItem = new LLSDCapEvent(); - eventItem.id = m_eventQueueCount; - //should be creating a EstablishAgentComms item, but there isn't a class for it yet - eventItem.events.Array.Add(new LLSDEmpty()); - string res = LLSDHelpers.SerialiseLLSDReply(eventItem); - m_eventQueueCount++; - - m_capsEventQueue.Enqueue(res); - return res; - } - - /// - /// - /// - /// - public string CreateEmptyEventResponse() - { - LLSDCapEvent eventItem = new LLSDCapEvent(); - eventItem.id = m_eventQueueCount; - eventItem.events.Array.Add(new LLSDEmpty()); - string res = LLSDHelpers.SerialiseLLSDReply(eventItem); - m_eventQueueCount++; - return res; - } - - #endregion - - /// - /// Callback for a client request for an upload url for a script task - /// inventory update - /// - /// - /// - /// - /// - public string ScriptTaskInventory(string request, string path, string param) - { - try - { -// MainLog.Instance.Debug("CAPS", "request: {0}, path: {1}, param: {2}", request, path, param); - - Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(Helpers.StringToField(request)); - LLSDTaskScriptUpdate llsdUpdateRequest = new LLSDTaskScriptUpdate(); - LLSDHelpers.DeserialiseLLSDMap(hash, llsdUpdateRequest); - - string capsBase = "/CAPS/" + m_capsObjectPath; - string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); - - TaskInventoryScriptUpdater uploader = - new TaskInventoryScriptUpdater( - llsdUpdateRequest.item_id, - llsdUpdateRequest.task_id, - llsdUpdateRequest.is_script_running, - capsBase + uploaderPath, - m_httpListener, - m_dumpAssetsToFile); - uploader.OnUpLoad += TaskScriptUpdated; - - m_httpListener.AddStreamHandler( - new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); - string uploaderURL = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase + - uploaderPath; - - LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); - uploadResponse.uploader = uploaderURL; - uploadResponse.state = "upload"; - -// MainLog.Instance.Verbose( -// "CAPS", -// "ScriptTaskInventory response: {0}", -// LLSDHelpers.SerialiseLLSDReply(uploadResponse)); - - return LLSDHelpers.SerialiseLLSDReply(uploadResponse); - } - catch (Exception e) - { - MainLog.Instance.Error("CAPS", e.ToString()); - } - - return null; - } - - /// - /// Callback for a client request for an upload url for a notecard (or script) - /// agent inventory update - /// - /// - /// - /// - /// - public string NoteCardAgentInventory(string request, string path, string param) - { - //libsecondlife.StructuredData.LLSDMap hash = (libsecondlife.StructuredData.LLSDMap)libsecondlife.StructuredData.LLSDParser.DeserializeBinary(Helpers.StringToField(request)); - Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(Helpers.StringToField(request)); - LLSDItemUpdate llsdRequest = new LLSDItemUpdate(); - LLSDHelpers.DeserialiseLLSDMap(hash, llsdRequest); - - string capsBase = "/CAPS/" + m_capsObjectPath; - string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); - - ItemUpdater uploader = - new ItemUpdater(llsdRequest.item_id, capsBase + uploaderPath, m_httpListener, m_dumpAssetsToFile); - uploader.OnUpLoad += ItemUpdated; - - m_httpListener.AddStreamHandler( - new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); - string uploaderURL = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase + - uploaderPath; - - LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); - uploadResponse.uploader = uploaderURL; - uploadResponse.state = "upload"; - -// MainLog.Instance.Verbose( -// "CAPS", -// "NoteCardAgentInventory response: {0}", -// LLSDHelpers.SerialiseLLSDReply(uploadResponse)); - - return LLSDHelpers.SerialiseLLSDReply(uploadResponse); - } - - /// - /// - /// - /// - /// - public LLSDAssetUploadResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest) - { - //Console.WriteLine("asset upload request via CAPS" + llsdRequest.inventory_type +" , "+ llsdRequest.asset_type); - - string assetName = llsdRequest.name; - string assetDes = llsdRequest.description; - string capsBase = "/CAPS/" + m_capsObjectPath; - LLUUID newAsset = LLUUID.Random(); - LLUUID newInvItem = LLUUID.Random(); - LLUUID parentFolder = llsdRequest.folder_id; - string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); - - // rex, modified for "replace assets" functionality - if (m_replaceAssets) - { - // Check for asset replace upload - sbyte assType = 0; - sbyte inType = 0; - ParseAssetAndInventoryType(llsdRequest.asset_type, llsdRequest.inventory_type, out assType, out inType); - LLUUID dupID = m_assetCache.ExistsAsset(assType, llsdRequest.name); - if (dupID != LLUUID.Zero) - { - // If duplicate (same name and same assettype) found, use old asset UUID - newAsset = dupID; - // If user already has this asset in inventory, create no item - if (CheckInventoryForAsset != null) - { - if (CheckInventoryForAsset(m_agentID, dupID)) - newInvItem = LLUUID.Zero; - } - } - } - // rexend - - AssetUploader uploader = - new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, - llsdRequest.asset_type, capsBase + uploaderPath, m_httpListener, m_dumpAssetsToFile); - m_httpListener.AddStreamHandler( - new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); - string uploaderURL = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase + - uploaderPath; - - LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); - uploadResponse.uploader = uploaderURL; - uploadResponse.state = "upload"; - uploader.OnUpLoad += UploadCompleteHandler; - return uploadResponse; - } - - /// - /// - /// - /// - /// - /// - public void UploadCompleteHandler(string assetName, string assetDescription, LLUUID assetID, - LLUUID inventoryItem, LLUUID parentFolder, byte[] data, string inventoryType, - string assetType) - { - sbyte assType = 0; - sbyte inType = 0; - - // rex, modified to use extracted method, because needed in multiple places - ParseAssetAndInventoryType(assetType, inventoryType, out assType, out inType); - - AssetBase asset; - asset = new AssetBase(); - asset.FullID = assetID; - asset.Type = assType; - asset.InvType = inType; - asset.Name = assetName; - asset.Data = data; - - // rex, modified for "replace assets" functionality - bool replace = (m_assetCache.ExistsAsset(assetID)); - if (replace) - { - m_assetCache.ReplaceAsset(asset); - } - else - { - m_assetCache.AddAsset(asset); - } - - if (inventoryItem != LLUUID.Zero) - { - InventoryItemBase item = new InventoryItemBase(); - item.avatarID = m_agentID; - item.creatorsID = m_agentID; - item.inventoryID = inventoryItem; - item.assetID = asset.FullID; - item.inventoryDescription = assetDescription; - item.inventoryName = assetName; - item.assetType = assType; - item.invType = inType; - item.parentFolderID = parentFolder; - item.inventoryCurrentPermissions = 2147483647; - item.inventoryNextPermissions = 2147483647; - - if (AddNewInventoryItem != null) - { - AddNewInventoryItem(m_agentID, item); - } - } - // rexend - } - - // rex, new function (extracted method) with added Ogre asset support - private void ParseAssetAndInventoryType(string assetType, string inventoryType, out sbyte assType, out sbyte inType) - { - inType = 0; - assType = 0; - - if (inventoryType == "sound") - { - inType = 1; - assType = 1; - } - else if (inventoryType == "animation") - { - inType = 19; - assType = 20; - } - - if (assetType == "ogremesh") - { - inType = 6; - assType = 43; - } - - if (assetType == "ogrepart") - { - inType = 41; - assType = 47; - } - } - - - /// - /// Called when new asset data for an agent inventory item update has been uploaded. - /// - /// Item to update - /// New asset data - /// - public LLUUID ItemUpdated(LLUUID itemID, byte[] data) - { - if (ItemUpdatedCall != null) - { - return ItemUpdatedCall(m_agentID, itemID, data); - } - - return LLUUID.Zero; - } - - /// - /// Called when new asset data for an agent inventory item update has been uploaded. - /// - /// Item to update - /// Prim containing item to update - /// Signals whether the script to update is currently running - /// New asset data - public void TaskScriptUpdated(LLUUID itemID, LLUUID primID, bool isScriptRunning, byte[] data) - { - if (TaskScriptUpdatedCall != null) - { - TaskScriptUpdatedCall(m_agentID, itemID, primID, isScriptRunning, data); - } - } - - public class AssetUploader - { - public event UpLoadedAsset OnUpLoad; - - private string uploaderPath = ""; - private LLUUID newAssetID; - private LLUUID inventoryItemID; - private LLUUID parentFolder; - private BaseHttpServer httpListener; - private bool m_dumpAssetsToFile; - private string m_assetName = ""; - private string m_assetDes = ""; - - private string m_invType = ""; - private string m_assetType = ""; - - public AssetUploader(string assetName, string description, LLUUID assetID, LLUUID inventoryItem, - LLUUID parentFolderID, string invType, string assetType, string path, - BaseHttpServer httpServer, bool dumpAssetsToFile) - { - m_assetName = assetName; - m_assetDes = description; - newAssetID = assetID; - inventoryItemID = inventoryItem; - uploaderPath = path; - httpListener = httpServer; - parentFolder = parentFolderID; - m_assetType = assetType; - m_invType = invType; - m_dumpAssetsToFile = dumpAssetsToFile; - } - - /// - /// - /// - /// - /// - /// - /// - public string uploaderCaps(byte[] data, string path, string param) - { - LLUUID inv = inventoryItemID; - string res = ""; - LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); - uploadComplete.new_asset = newAssetID.ToString(); - uploadComplete.new_inventory_item = inv; - uploadComplete.state = "complete"; - - res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); - - httpListener.RemoveStreamHandler("POST", uploaderPath); - - if (m_dumpAssetsToFile) - { - SaveAssetToFile(m_assetName + ".jp2", data); - } - - if (OnUpLoad != null) - { - OnUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType); - } - - return res; - } - ///Left this in and commented in case there are unforseen issues - //private void SaveAssetToFile(string filename, byte[] data) - //{ - // FileStream fs = File.Create(filename); - // BinaryWriter bw = new BinaryWriter(fs); - // bw.Write(data); - // bw.Close(); - // fs.Close(); - //} - private void SaveAssetToFile(string filename, byte[] data) - { - string assetPath = "UserAssets"; - if (!Directory.Exists(assetPath)) - { - Directory.CreateDirectory(assetPath); - } - FileStream fs = File.Create(Path.Combine(assetPath, filename)); - BinaryWriter bw = new BinaryWriter(fs); - bw.Write(data); - bw.Close(); - fs.Close(); - } - } - - /// - /// This class is a callback invoked when a client sends asset data to - /// an agent inventory notecard update url - /// - public class ItemUpdater - { - public event UpdateItem OnUpLoad; - - private string uploaderPath = ""; - private LLUUID inventoryItemID; - private BaseHttpServer httpListener; - private bool m_dumpAssetToFile; - - public ItemUpdater(LLUUID inventoryItem, string path, BaseHttpServer httpServer, bool dumpAssetToFile) - { - m_dumpAssetToFile = dumpAssetToFile; - - inventoryItemID = inventoryItem; - uploaderPath = path; - httpListener = httpServer; - } - - /// - /// - /// - /// - /// - /// - /// - public string uploaderCaps(byte[] data, string path, string param) - { - LLUUID inv = inventoryItemID; - string res = ""; - LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); - LLUUID assetID = LLUUID.Zero; - - if (OnUpLoad != null) - { - assetID = OnUpLoad(inv, data); - } - - uploadComplete.new_asset = assetID.ToString(); - uploadComplete.new_inventory_item = inv; - uploadComplete.state = "complete"; - - res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); - - httpListener.RemoveStreamHandler("POST", uploaderPath); - - if (m_dumpAssetToFile) - { - SaveAssetToFile("updateditem" + Util.RandomClass.Next(1, 1000) + ".dat", data); - } - - return res; - } - ///Left this in and commented in case there are unforseen issues - //private void SaveAssetToFile(string filename, byte[] data) - //{ - // FileStream fs = File.Create(filename); - // BinaryWriter bw = new BinaryWriter(fs); - // bw.Write(data); - // bw.Close(); - // fs.Close(); - //} - private void SaveAssetToFile(string filename, byte[] data) - { - string assetPath = "UserAssets"; - if (!Directory.Exists(assetPath)) - { - Directory.CreateDirectory(assetPath); - } - FileStream fs = File.Create(Path.Combine(assetPath, filename)); - BinaryWriter bw = new BinaryWriter(fs); - bw.Write(data); - bw.Close(); - fs.Close(); - } - } - - /// - /// This class is a callback invoked when a client sends asset data to - /// a task inventory script update url - /// - public class TaskInventoryScriptUpdater - { - public event UpdateTaskScript OnUpLoad; - - private string uploaderPath = ""; - private LLUUID inventoryItemID; - private LLUUID primID; - private bool isScriptRunning; - private BaseHttpServer httpListener; - private bool m_dumpAssetToFile; - - public TaskInventoryScriptUpdater(LLUUID inventoryItemID, LLUUID primID, int isScriptRunning, - string path, BaseHttpServer httpServer, bool dumpAssetToFile) - { - m_dumpAssetToFile = dumpAssetToFile; - - this.inventoryItemID = inventoryItemID; - this.primID = primID; - - // This comes in over the packet as an integer, but actually appears to be treated as a bool - this.isScriptRunning = (0 == isScriptRunning ? false : true); - - uploaderPath = path; - httpListener = httpServer; - } - - /// - /// - /// - /// - /// - /// - /// - public string uploaderCaps(byte[] data, string path, string param) - { - try - { -// MainLog.Instance.Verbose( -// "CAPS", -// "TaskInventoryScriptUpdater received data: {0}, path: {1}, param: {2}", -// data, path, param); - - string res = ""; - LLSDTaskInventoryUploadComplete uploadComplete = new LLSDTaskInventoryUploadComplete(); - - if (OnUpLoad != null) - { - OnUpLoad(inventoryItemID, primID, isScriptRunning, data); - } - - uploadComplete.item_id = inventoryItemID; - uploadComplete.task_id = primID; - uploadComplete.state = "complete"; - - res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); - - httpListener.RemoveStreamHandler("POST", uploaderPath); - - if (m_dumpAssetToFile) - { - SaveAssetToFile("updatedtaskscript" + Util.RandomClass.Next(1, 1000) + ".dat", data); - } - -// MainLog.Instance.Verbose("CAPS", "TaskInventoryScriptUpdater.uploaderCaps res: {0}", res); - - return res; - } - catch (Exception e) - { - MainLog.Instance.Error("CAPS", e.ToString()); - } - - // XXX Maybe this should be some meaningful error packet - return null; - } - ///Left this in and commented in case there are unforseen issues - //private void SaveAssetToFile(string filename, byte[] data) - //{ - // FileStream fs = File.Create(filename); - // BinaryWriter bw = new BinaryWriter(fs); - // bw.Write(data); - // bw.Close(); - // fs.Close(); - //} - private void SaveAssetToFile(string filename, byte[] data) - { - string assetPath = "UserAssets"; - if (!Directory.Exists(assetPath)) - { - Directory.CreateDirectory(assetPath); - } - FileStream fs = File.Create(Path.Combine(assetPath, filename)); - BinaryWriter bw = new BinaryWriter(fs); - bw.Write(data); - bw.Close(); - fs.Close(); - } - } - } -} +/* +* 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.IO; +using libsecondlife; +using OpenSim.Framework; +using OpenSim.Framework.Communications.Cache; +using OpenSim.Framework.Console; +using OpenSim.Framework.Servers; + +namespace OpenSim.Region.Capabilities +{ + public delegate void UpLoadedAsset( + string assetName, string description, LLUUID assetID, LLUUID inventoryItem, LLUUID parentFolder, + byte[] data, string inventoryType, string assetType); + + public delegate LLUUID UpdateItem(LLUUID itemID, byte[] data); + + public delegate void UpdateTaskScript(LLUUID itemID, LLUUID primID, bool isScriptRunning, byte[] data); + + public delegate void NewInventoryItem(LLUUID userID, InventoryItemBase item); + + // rex, added for asset replace functionality + public delegate bool InventoryAssetCheck(LLUUID userID, LLUUID assetID); + + public delegate LLUUID ItemUpdatedCallback(LLUUID userID, LLUUID itemID, byte[] data); + + public delegate void TaskScriptUpdatedCallback(LLUUID userID, LLUUID itemID, LLUUID primID, + bool isScriptRunning, byte[] data); + + public class Caps + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private string m_httpListenerHostName; + private uint m_httpListenPort; + + private string m_capsObjectPath = "00001-"; + private string m_requestPath = "0000/"; + private string m_mapLayerPath = "0001/"; + private string m_newInventory = "0002/"; + //private string m_requestTexture = "0003/"; + private string m_notecardUpdatePath = "0004/"; + private string m_notecardTaskUpdatePath = "0005/"; + + //private string eventQueue = "0100/"; + private BaseHttpServer m_httpListener; + private LLUUID m_agentID; + private AssetCache m_assetCache; + private int m_eventQueueCount = 1; + private Queue m_capsEventQueue = new Queue(); + private bool m_dumpAssetsToFile; + private bool m_replaceAssets; + + // These are callbacks which will be setup by the scene so that we can update scene data when we + // receive capability calls + public NewInventoryItem AddNewInventoryItem = null; + public InventoryAssetCheck CheckInventoryForAsset = null; + public ItemUpdatedCallback ItemUpdatedCall = null; + public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null; + + public Caps(AssetCache assetCache, BaseHttpServer httpServer, string httpListen, uint httpPort, string capsPath, + LLUUID agent, bool dumpAssetsToFile) + { + m_assetCache = assetCache; + m_capsObjectPath = capsPath; + m_httpListener = httpServer; + m_httpListenerHostName = httpListen; + m_httpListenPort = httpPort; + m_agentID = agent; + m_dumpAssetsToFile = dumpAssetsToFile; + + m_replaceAssets = (GlobalSettings.Instance.ConfigSource.Configs["Startup"].GetBoolean("replace_assets", true)); + } + + /// + /// + /// + public void RegisterHandlers() + { + m_log.Info("[CAPS]: Registering CAPS handlers"); + string capsBase = "/CAPS/" + m_capsObjectPath; + try + { + m_httpListener.AddStreamHandler( + new LLSDStreamhandler("POST", capsBase + m_mapLayerPath, + GetMapLayer)); + m_httpListener.AddStreamHandler( + new LLSDStreamhandler("POST", + capsBase + m_newInventory, + NewAgentInventoryRequest)); + + AddLegacyCapsHandler(m_httpListener, m_requestPath, CapsRequest); + //AddLegacyCapsHandler(m_httpListener, m_requestTexture , RequestTexture); + AddLegacyCapsHandler(m_httpListener, m_notecardUpdatePath, NoteCardAgentInventory); + AddLegacyCapsHandler(m_httpListener, m_notecardTaskUpdatePath, ScriptTaskInventory); + } + catch (Exception e) + { + m_log.Error("[CAPS]: " + e.ToString()); + } + } + + + //[Obsolete("Use BaseHttpServer.AddStreamHandler(new LLSDStreamHandler( LLSDMethod delegate )) instead.")] + //Commented out the obsolete as at this time the first caps request can not use the new Caps method + //as the sent type is a array and not a map and the deserialising doesn't deal properly with arrays. + private void AddLegacyCapsHandler(BaseHttpServer httpListener, string path, RestMethod restMethod) + { + string capsBase = "/CAPS/" + m_capsObjectPath; + httpListener.AddStreamHandler(new RestStreamHandler("POST", capsBase + path, restMethod)); + } + + /// + /// Construct a client response detailing all the capabilities this server can provide. + /// + /// + /// + /// + /// + public string CapsRequest(string request, string path, string param) + { + //Console.WriteLine("caps request " + request); + string result = LLSDHelpers.SerialiseLLSDReply(GetCapabilities()); + return result; + } + + /// + /// Return an LLSDCapsDetails listing all the capabilities this server can provide + /// + /// + protected LLSDCapsDetails GetCapabilities() + { + LLSDCapsDetails caps = new LLSDCapsDetails(); + string capsBaseUrl = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + "/CAPS/" + + m_capsObjectPath; + caps.MapLayer = capsBaseUrl + m_mapLayerPath; + // caps.RequestTextureDownload = capsBaseUrl + m_requestTexture; + caps.NewFileAgentInventory = capsBaseUrl + m_newInventory; + caps.UpdateNotecardAgentInventory = capsBaseUrl + m_notecardUpdatePath; + caps.UpdateScriptAgentInventory = capsBaseUrl + m_notecardUpdatePath; + caps.UpdateScriptTaskInventory = capsBaseUrl + m_notecardTaskUpdatePath; + return caps; + } + + /// + /// + /// + /// + /// + public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq) + { + LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); + mapResponse.LayerData.Array.Add(GetLLSDMapLayerResponse()); + return mapResponse; + } + + /// + /// + /// + /// + protected LLSDMapLayer GetLLSDMapLayerResponse() + { + LLSDMapLayer mapLayer = new LLSDMapLayer(); + mapLayer.Right = 5000; + mapLayer.Top = 5000; + mapLayer.ImageID = new LLUUID("00000000-0000-0000-9999-000000000006"); + return mapLayer; + } + + /// + /// + /// + /// + /// + /// + /// + public string RequestTexture(string request, string path, string param) + { + Console.WriteLine("texture request " + request); + // Needs implementing (added to remove compiler warning) + return String.Empty; + } + + #region EventQueue (Currently not enabled) + + /// + /// + /// + /// + /// + /// + /// + public string ProcessEventQueue(string request, string path, string param) + { + string res = String.Empty; + + if (m_capsEventQueue.Count > 0) + { + lock (m_capsEventQueue) + { + string item = m_capsEventQueue.Dequeue(); + res = item; + } + } + else + { + res = CreateEmptyEventResponse(); + } + return res; + } + + /// + /// + /// + /// + /// + /// + public string CreateEstablishAgentComms(string caps, string ipAddressPort) + { + LLSDCapEvent eventItem = new LLSDCapEvent(); + eventItem.id = m_eventQueueCount; + //should be creating a EstablishAgentComms item, but there isn't a class for it yet + eventItem.events.Array.Add(new LLSDEmpty()); + string res = LLSDHelpers.SerialiseLLSDReply(eventItem); + m_eventQueueCount++; + + m_capsEventQueue.Enqueue(res); + return res; + } + + /// + /// + /// + /// + public string CreateEmptyEventResponse() + { + LLSDCapEvent eventItem = new LLSDCapEvent(); + eventItem.id = m_eventQueueCount; + eventItem.events.Array.Add(new LLSDEmpty()); + string res = LLSDHelpers.SerialiseLLSDReply(eventItem); + m_eventQueueCount++; + return res; + } + + #endregion + + /// + /// Callback for a client request for an upload url for a script task + /// inventory update + /// + /// + /// + /// + /// + public string ScriptTaskInventory(string request, string path, string param) + { + try + { +// m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param); + + Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(Helpers.StringToField(request)); + LLSDTaskScriptUpdate llsdUpdateRequest = new LLSDTaskScriptUpdate(); + LLSDHelpers.DeserialiseLLSDMap(hash, llsdUpdateRequest); + + string capsBase = "/CAPS/" + m_capsObjectPath; + string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); + + TaskInventoryScriptUpdater uploader = + new TaskInventoryScriptUpdater( + llsdUpdateRequest.item_id, + llsdUpdateRequest.task_id, + llsdUpdateRequest.is_script_running, + capsBase + uploaderPath, + m_httpListener, + m_dumpAssetsToFile); + uploader.OnUpLoad += TaskScriptUpdated; + + m_httpListener.AddStreamHandler( + new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); + string uploaderURL = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase + + uploaderPath; + + LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); + uploadResponse.uploader = uploaderURL; + uploadResponse.state = "upload"; + +// m_log.InfoFormat("[CAPS]: " + +// "ScriptTaskInventory response: {0}", +// LLSDHelpers.SerialiseLLSDReply(uploadResponse))); + + return LLSDHelpers.SerialiseLLSDReply(uploadResponse); + } + catch (Exception e) + { + m_log.Error("[CAPS]: " + e.ToString()); + } + + return null; + } + + /// + /// Callback for a client request for an upload url for a notecard (or script) + /// agent inventory update + /// + /// + /// + /// + /// + public string NoteCardAgentInventory(string request, string path, string param) + { + //libsecondlife.StructuredData.LLSDMap hash = (libsecondlife.StructuredData.LLSDMap)libsecondlife.StructuredData.LLSDParser.DeserializeBinary(Helpers.StringToField(request)); + Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(Helpers.StringToField(request)); + LLSDItemUpdate llsdRequest = new LLSDItemUpdate(); + LLSDHelpers.DeserialiseLLSDMap(hash, llsdRequest); + + string capsBase = "/CAPS/" + m_capsObjectPath; + string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); + + ItemUpdater uploader = + new ItemUpdater(llsdRequest.item_id, capsBase + uploaderPath, m_httpListener, m_dumpAssetsToFile); + uploader.OnUpLoad += ItemUpdated; + + m_httpListener.AddStreamHandler( + new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); + string uploaderURL = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase + + uploaderPath; + + LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); + uploadResponse.uploader = uploaderURL; + uploadResponse.state = "upload"; + +// m_log.InfoFormat("[CAPS]: " + +// "NoteCardAgentInventory response: {0}", +// LLSDHelpers.SerialiseLLSDReply(uploadResponse))); + + return LLSDHelpers.SerialiseLLSDReply(uploadResponse); + } + + /// + /// + /// + /// + /// + public LLSDAssetUploadResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest) + { + //Console.WriteLine("asset upload request via CAPS" + llsdRequest.inventory_type +" , "+ llsdRequest.asset_type); + + string assetName = llsdRequest.name; + string assetDes = llsdRequest.description; + string capsBase = "/CAPS/" + m_capsObjectPath; + LLUUID newAsset = LLUUID.Random(); + LLUUID newInvItem = LLUUID.Random(); + LLUUID parentFolder = llsdRequest.folder_id; + string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); + + // rex, modified for "replace assets" functionality + if (m_replaceAssets) + { + // Check for asset replace upload + sbyte assType = 0; + sbyte inType = 0; + ParseAssetAndInventoryType(llsdRequest.asset_type, llsdRequest.inventory_type, out assType, out inType); + LLUUID dupID = m_assetCache.ExistsAsset(assType, llsdRequest.name); + if (dupID != LLUUID.Zero) + { + // If duplicate (same name and same assettype) found, use old asset UUID + newAsset = dupID; + // If user already has this asset in inventory, create no item + if (CheckInventoryForAsset != null) + { + if (CheckInventoryForAsset(m_agentID, dupID)) + newInvItem = LLUUID.Zero; + } + } + } + // rexend + + AssetUploader uploader = + new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, + llsdRequest.asset_type, capsBase + uploaderPath, m_httpListener, m_dumpAssetsToFile); + m_httpListener.AddStreamHandler( + new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); + string uploaderURL = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase + + uploaderPath; + + LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); + uploadResponse.uploader = uploaderURL; + uploadResponse.state = "upload"; + uploader.OnUpLoad += UploadCompleteHandler; + return uploadResponse; + } + + /// + /// + /// + /// + /// + /// + public void UploadCompleteHandler(string assetName, string assetDescription, LLUUID assetID, + LLUUID inventoryItem, LLUUID parentFolder, byte[] data, string inventoryType, + string assetType) + { + sbyte assType = 0; + sbyte inType = 0; + + // rex, modified to use extracted method, because needed in multiple places + ParseAssetAndInventoryType(assetType, inventoryType, out assType, out inType); + + AssetBase asset; + asset = new AssetBase(); + asset.FullID = assetID; + asset.Type = assType; + asset.InvType = inType; + asset.Name = assetName; + asset.Data = data; + + // rex, modified for "replace assets" functionality + bool replace = (m_assetCache.ExistsAsset(assetID)); + if (replace) + { + m_assetCache.ReplaceAsset(asset); + } + else + { + m_assetCache.AddAsset(asset); + } + + if (inventoryItem != LLUUID.Zero) + { + InventoryItemBase item = new InventoryItemBase(); + item.avatarID = m_agentID; + item.creatorsID = m_agentID; + item.inventoryID = inventoryItem; + item.assetID = asset.FullID; + item.inventoryDescription = assetDescription; + item.inventoryName = assetName; + item.assetType = assType; + item.invType = inType; + item.parentFolderID = parentFolder; + item.inventoryCurrentPermissions = 2147483647; + item.inventoryNextPermissions = 2147483647; + + if (AddNewInventoryItem != null) + { + AddNewInventoryItem(m_agentID, item); + } + } + // rexend + } + + // rex, new function (extracted method) with added Ogre asset support + private void ParseAssetAndInventoryType(string assetType, string inventoryType, out sbyte assType, out sbyte inType) + { + inType = 0; + assType = 0; + + if (inventoryType == "sound") + { + inType = 1; + assType = 1; + } + else if (inventoryType == "animation") + { + inType = 19; + assType = 20; + } + + if (assetType == "ogremesh") + { + inType = 6; + assType = 43; + } + + if (assetType == "ogrepart") + { + inType = 41; + assType = 47; + } + } + + + /// + /// Called when new asset data for an agent inventory item update has been uploaded. + /// + /// Item to update + /// New asset data + /// + public LLUUID ItemUpdated(LLUUID itemID, byte[] data) + { + if (ItemUpdatedCall != null) + { + return ItemUpdatedCall(m_agentID, itemID, data); + } + + return LLUUID.Zero; + } + + /// + /// Called when new asset data for an agent inventory item update has been uploaded. + /// + /// Item to update + /// Prim containing item to update + /// Signals whether the script to update is currently running + /// New asset data + public void TaskScriptUpdated(LLUUID itemID, LLUUID primID, bool isScriptRunning, byte[] data) + { + if (TaskScriptUpdatedCall != null) + { + TaskScriptUpdatedCall(m_agentID, itemID, primID, isScriptRunning, data); + } + } + + public class AssetUploader + { + public event UpLoadedAsset OnUpLoad; + private UpLoadedAsset handler001 = null; + + private string uploaderPath = String.Empty; + private LLUUID newAssetID; + private LLUUID inventoryItemID; + private LLUUID parentFolder; + private BaseHttpServer httpListener; + private bool m_dumpAssetsToFile; + private string m_assetName = String.Empty; + private string m_assetDes = String.Empty; + + private string m_invType = String.Empty; + private string m_assetType = String.Empty; + + public AssetUploader(string assetName, string description, LLUUID assetID, LLUUID inventoryItem, + LLUUID parentFolderID, string invType, string assetType, string path, + BaseHttpServer httpServer, bool dumpAssetsToFile) + { + m_assetName = assetName; + m_assetDes = description; + newAssetID = assetID; + inventoryItemID = inventoryItem; + uploaderPath = path; + httpListener = httpServer; + parentFolder = parentFolderID; + m_assetType = assetType; + m_invType = invType; + m_dumpAssetsToFile = dumpAssetsToFile; + } + + /// + /// + /// + /// + /// + /// + /// + public string uploaderCaps(byte[] data, string path, string param) + { + LLUUID inv = inventoryItemID; + string res = String.Empty; + LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); + uploadComplete.new_asset = newAssetID.ToString(); + uploadComplete.new_inventory_item = inv; + uploadComplete.state = "complete"; + + res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); + + httpListener.RemoveStreamHandler("POST", uploaderPath); + + if (m_dumpAssetsToFile) + { + SaveAssetToFile(m_assetName + ".jp2", data); + } + handler001 = OnUpLoad; + if (handler001 != null) + { + handler001(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType); + } + + return res; + } + ///Left this in and commented in case there are unforseen issues + //private void SaveAssetToFile(string filename, byte[] data) + //{ + // FileStream fs = File.Create(filename); + // BinaryWriter bw = new BinaryWriter(fs); + // bw.Write(data); + // bw.Close(); + // fs.Close(); + //} + private void SaveAssetToFile(string filename, byte[] data) + { + string assetPath = "UserAssets"; + if (!Directory.Exists(assetPath)) + { + Directory.CreateDirectory(assetPath); + } + FileStream fs = File.Create(Path.Combine(assetPath, filename)); + BinaryWriter bw = new BinaryWriter(fs); + bw.Write(data); + bw.Close(); + fs.Close(); + } + } + + /// + /// This class is a callback invoked when a client sends asset data to + /// an agent inventory notecard update url + /// + public class ItemUpdater + { + public event UpdateItem OnUpLoad; + + private UpdateItem handler001 = null; + + private string uploaderPath = String.Empty; + private LLUUID inventoryItemID; + private BaseHttpServer httpListener; + private bool m_dumpAssetToFile; + + public ItemUpdater(LLUUID inventoryItem, string path, BaseHttpServer httpServer, bool dumpAssetToFile) + { + m_dumpAssetToFile = dumpAssetToFile; + + inventoryItemID = inventoryItem; + uploaderPath = path; + httpListener = httpServer; + } + + /// + /// + /// + /// + /// + /// + /// + public string uploaderCaps(byte[] data, string path, string param) + { + LLUUID inv = inventoryItemID; + string res = String.Empty; + LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); + LLUUID assetID = LLUUID.Zero; + handler001 = OnUpLoad; + if (handler001 != null) + { + assetID = handler001(inv, data); + } + + uploadComplete.new_asset = assetID.ToString(); + uploadComplete.new_inventory_item = inv; + uploadComplete.state = "complete"; + + res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); + + httpListener.RemoveStreamHandler("POST", uploaderPath); + + if (m_dumpAssetToFile) + { + SaveAssetToFile("updateditem" + Util.RandomClass.Next(1, 1000) + ".dat", data); + } + + return res; + } + ///Left this in and commented in case there are unforseen issues + //private void SaveAssetToFile(string filename, byte[] data) + //{ + // FileStream fs = File.Create(filename); + // BinaryWriter bw = new BinaryWriter(fs); + // bw.Write(data); + // bw.Close(); + // fs.Close(); + //} + private void SaveAssetToFile(string filename, byte[] data) + { + string assetPath = "UserAssets"; + if (!Directory.Exists(assetPath)) + { + Directory.CreateDirectory(assetPath); + } + FileStream fs = File.Create(Path.Combine(assetPath, filename)); + BinaryWriter bw = new BinaryWriter(fs); + bw.Write(data); + bw.Close(); + fs.Close(); + } + } + + /// + /// This class is a callback invoked when a client sends asset data to + /// a task inventory script update url + /// + public class TaskInventoryScriptUpdater + { + public event UpdateTaskScript OnUpLoad; + + private UpdateTaskScript handler001 = null; + + private string uploaderPath = String.Empty; + private LLUUID inventoryItemID; + private LLUUID primID; + private bool isScriptRunning; + private BaseHttpServer httpListener; + private bool m_dumpAssetToFile; + + public TaskInventoryScriptUpdater(LLUUID inventoryItemID, LLUUID primID, int isScriptRunning, + string path, BaseHttpServer httpServer, bool dumpAssetToFile) + { + m_dumpAssetToFile = dumpAssetToFile; + + this.inventoryItemID = inventoryItemID; + this.primID = primID; + + // This comes in over the packet as an integer, but actually appears to be treated as a bool + this.isScriptRunning = (0 == isScriptRunning ? false : true); + + uploaderPath = path; + httpListener = httpServer; + } + + /// + /// + /// + /// + /// + /// + /// + public string uploaderCaps(byte[] data, string path, string param) + { + try + { +// m_log.InfoFormat("[CAPS]: " + +// "TaskInventoryScriptUpdater received data: {0}, path: {1}, param: {2}", +// data, path, param)); + + string res = String.Empty; + LLSDTaskInventoryUploadComplete uploadComplete = new LLSDTaskInventoryUploadComplete(); + + handler001 = OnUpLoad; + if (handler001 != null) + { + handler001(inventoryItemID, primID, isScriptRunning, data); + } + + uploadComplete.item_id = inventoryItemID; + uploadComplete.task_id = primID; + uploadComplete.state = "complete"; + + res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); + + httpListener.RemoveStreamHandler("POST", uploaderPath); + + if (m_dumpAssetToFile) + { + SaveAssetToFile("updatedtaskscript" + Util.RandomClass.Next(1, 1000) + ".dat", data); + } + +// m_log.InfoFormat("[CAPS]: TaskInventoryScriptUpdater.uploaderCaps res: {0}", res); + + return res; + } + catch (Exception e) + { + m_log.Error("[CAPS]: " + e.ToString()); + } + + // XXX Maybe this should be some meaningful error packet + return null; + } + ///Left this in and commented in case there are unforseen issues + //private void SaveAssetToFile(string filename, byte[] data) + //{ + // FileStream fs = File.Create(filename); + // BinaryWriter bw = new BinaryWriter(fs); + // bw.Write(data); + // bw.Close(); + // fs.Close(); + //} + private void SaveAssetToFile(string filename, byte[] data) + { + string assetPath = "UserAssets"; + if (!Directory.Exists(assetPath)) + { + Directory.CreateDirectory(assetPath); + } + FileStream fs = File.Create(Path.Combine(assetPath, filename)); + BinaryWriter bw = new BinaryWriter(fs); + bw.Write(data); + bw.Close(); + fs.Close(); + } + } + } +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDAssetUploadComplete.cs b/OpenSim/Framework/Communications/Capabilities/LLSDAssetUploadComplete.cs index 849c1c2b95..65c3a27598 100644 --- a/OpenSim/Framework/Communications/Capabilities/LLSDAssetUploadComplete.cs +++ b/OpenSim/Framework/Communications/Capabilities/LLSDAssetUploadComplete.cs @@ -1,44 +1,45 @@ -/* -* 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 libsecondlife; - -namespace OpenSim.Region.Capabilities -{ - [LLSDType("MAP")] - public class LLSDAssetUploadComplete - { - public string new_asset = ""; - public LLUUID new_inventory_item = LLUUID.Zero; - public string state = ""; - //public bool success = false; - - public LLSDAssetUploadComplete() - { - } - } -} \ No newline at end of file +/* +* 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 libsecondlife; +using System; + +namespace OpenSim.Region.Capabilities +{ + [LLSDType("MAP")] + public class LLSDAssetUploadComplete + { + public string new_asset = String.Empty; + public LLUUID new_inventory_item = LLUUID.Zero; + public string state = String.Empty; + //public bool success = false; + + public LLSDAssetUploadComplete() + { + } + } +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDAssetUploadRequest.cs b/OpenSim/Framework/Communications/Capabilities/LLSDAssetUploadRequest.cs index 99620b0ba1..6d627a6016 100644 --- a/OpenSim/Framework/Communications/Capabilities/LLSDAssetUploadRequest.cs +++ b/OpenSim/Framework/Communications/Capabilities/LLSDAssetUploadRequest.cs @@ -1,46 +1,46 @@ -/* -* 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 libsecondlife; - -namespace OpenSim.Region.Capabilities -{ - [LLSDMap] - public class LLSDAssetUploadRequest - { - public string asset_type = ""; - public string description = ""; - public LLUUID folder_id = LLUUID.Zero; - public string inventory_type = ""; - public string name = ""; - - public LLSDAssetUploadRequest() - { - } - } -} \ No newline at end of file +/* +* 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 libsecondlife; + +namespace OpenSim.Region.Capabilities +{ + [LLSDMap] + public class LLSDAssetUploadRequest + { + public string asset_type = System.String.Empty; + public string description = System.String.Empty; + public LLUUID folder_id = LLUUID.Zero; + public string inventory_type = System.String.Empty; + public string name = System.String.Empty; + + public LLSDAssetUploadRequest() + { + } + } +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDAssetUploadResponse.cs b/OpenSim/Framework/Communications/Capabilities/LLSDAssetUploadResponse.cs index 8424d27b45..246af3ca3b 100644 --- a/OpenSim/Framework/Communications/Capabilities/LLSDAssetUploadResponse.cs +++ b/OpenSim/Framework/Communications/Capabilities/LLSDAssetUploadResponse.cs @@ -1,41 +1,41 @@ -/* -* 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. -* -*/ - -namespace OpenSim.Region.Capabilities -{ - [LLSDMap] - public class LLSDAssetUploadResponse - { - public string uploader = ""; - public string state = ""; - - public LLSDAssetUploadResponse() - { - } - } -} \ No newline at end of file +/* +* 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. +* +*/ + +namespace OpenSim.Region.Capabilities +{ + [LLSDMap] + public class LLSDAssetUploadResponse + { + public string uploader = System.String.Empty; + public string state = System.String.Empty; + + public LLSDAssetUploadResponse() + { + } + } +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDCapsDetails.cs b/OpenSim/Framework/Communications/Capabilities/LLSDCapsDetails.cs index 3b528b67a1..e83c0e1676 100644 --- a/OpenSim/Framework/Communications/Capabilities/LLSDCapsDetails.cs +++ b/OpenSim/Framework/Communications/Capabilities/LLSDCapsDetails.cs @@ -1,48 +1,50 @@ -/* -* 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. -* -*/ - -namespace OpenSim.Region.Capabilities -{ - [LLSDType("MAP")] - public class LLSDCapsDetails - { - public string MapLayer = ""; - public string NewFileAgentInventory = ""; - //public string EventQueueGet = ""; - // public string RequestTextureDownload = ""; - // public string ChatSessionRequest = ""; - public string UpdateNotecardAgentInventory = ""; - public string UpdateScriptAgentInventory = ""; - public string UpdateScriptTaskInventory = ""; - // public string ParcelVoiceInfoRequest = ""; - - public LLSDCapsDetails() - { - } - } -} \ No newline at end of file +/* +* 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; + +namespace OpenSim.Region.Capabilities +{ + [LLSDType("MAP")] + public class LLSDCapsDetails + { + public string MapLayer = String.Empty; + public string NewFileAgentInventory = String.Empty; + //public string EventQueueGet = String.Empty; + // public string RequestTextureDownload = String.Empty; + // public string ChatSessionRequest = String.Empty; + public string UpdateNotecardAgentInventory = String.Empty; + public string UpdateScriptAgentInventory = String.Empty; + public string UpdateScriptTaskInventory = String.Empty; + // public string ParcelVoiceInfoRequest = String.Empty; + + public LLSDCapsDetails() + { + } + } +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDItemUpdate.cs b/OpenSim/Framework/Communications/Capabilities/LLSDItemUpdate.cs index 6c8e9b8c88..536efdad82 100644 --- a/OpenSim/Framework/Communications/Capabilities/LLSDItemUpdate.cs +++ b/OpenSim/Framework/Communications/Capabilities/LLSDItemUpdate.cs @@ -1,42 +1,42 @@ -/* -* 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 libsecondlife; - -namespace OpenSim.Region.Capabilities -{ - [LLSDMap] - public class LLSDItemUpdate - { - public LLUUID item_id; - - public LLSDItemUpdate() - { - } - } -} \ No newline at end of file +/* +* 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 libsecondlife; + +namespace OpenSim.Region.Capabilities +{ + [LLSDMap] + public class LLSDItemUpdate + { + public LLUUID item_id; + + public LLSDItemUpdate() + { + } + } +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDMapRequest.cs b/OpenSim/Framework/Communications/Capabilities/LLSDMapRequest.cs index 8c7a3c96dc..ddcab50615 100644 --- a/OpenSim/Framework/Communications/Capabilities/LLSDMapRequest.cs +++ b/OpenSim/Framework/Communications/Capabilities/LLSDMapRequest.cs @@ -1,40 +1,40 @@ -/* -* 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. -* -*/ - -namespace OpenSim.Region.Capabilities -{ - [LLSDType("MAP")] - public class LLSDMapRequest - { - public int Flags = 0; - - public LLSDMapRequest() - { - } - } -} \ No newline at end of file +/* +* 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. +* +*/ + +namespace OpenSim.Region.Capabilities +{ + [LLSDType("MAP")] + public class LLSDMapRequest + { + public int Flags = 0; + + public LLSDMapRequest() + { + } + } +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDMethod.cs b/OpenSim/Framework/Communications/Capabilities/LLSDMethod.cs index 262c9fc293..1f25c571ea 100644 --- a/OpenSim/Framework/Communications/Capabilities/LLSDMethod.cs +++ b/OpenSim/Framework/Communications/Capabilities/LLSDMethod.cs @@ -1,32 +1,32 @@ -/* -* 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. -* -*/ - -namespace OpenSim.Region.Capabilities -{ - public delegate TResponse LLSDMethod(TRequest request); -} \ No newline at end of file +/* +* 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. +* +*/ + +namespace OpenSim.Region.Capabilities +{ + public delegate TResponse LLSDMethod(TRequest request); +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDStreamHandler.cs b/OpenSim/Framework/Communications/Capabilities/LLSDStreamHandler.cs index c46e4d6cb0..13d14878d7 100644 --- a/OpenSim/Framework/Communications/Capabilities/LLSDStreamHandler.cs +++ b/OpenSim/Framework/Communications/Capabilities/LLSDStreamHandler.cs @@ -1,69 +1,69 @@ -/* -* 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.Collections; -using System.IO; -using System.Text; -using OpenSim.Framework.Servers; - -namespace OpenSim.Region.Capabilities -{ - public class LLSDStreamhandler : BaseStreamHandler - where TRequest : new() - { - private LLSDMethod m_method; - - public LLSDStreamhandler(string httpMethod, string path, LLSDMethod method) - : base(httpMethod, path) - { - m_method = method; - } - - public override byte[] Handle(string path, Stream request) - { - //Encoding encoding = Encoding.UTF8; - //StreamReader streamReader = new StreamReader(request, false); - - //string requestBody = streamReader.ReadToEnd(); - //streamReader.Close(); - - // libsecondlife.StructuredData.LLSDMap hash = (libsecondlife.StructuredData.LLSDMap) - // libsecondlife.StructuredData.LLSDParser.DeserializeXml(new XmlTextReader(request)); - - Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(request); - TRequest llsdRequest = new TRequest(); - LLSDHelpers.DeserialiseLLSDMap(hash, llsdRequest); - - TResponse response = m_method(llsdRequest); - - Encoding encoding = new UTF8Encoding(false); - - return encoding.GetBytes(LLSDHelpers.SerialiseLLSDReply(response)); - } - } -} \ No newline at end of file +/* +* 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.Collections; +using System.IO; +using System.Text; +using OpenSim.Framework.Servers; + +namespace OpenSim.Region.Capabilities +{ + public class LLSDStreamhandler : BaseStreamHandler + where TRequest : new() + { + private LLSDMethod m_method; + + public LLSDStreamhandler(string httpMethod, string path, LLSDMethod method) + : base(httpMethod, path) + { + m_method = method; + } + + public override byte[] Handle(string path, Stream request) + { + //Encoding encoding = Encoding.UTF8; + //StreamReader streamReader = new StreamReader(request, false); + + //string requestBody = streamReader.ReadToEnd(); + //streamReader.Close(); + + // libsecondlife.StructuredData.LLSDMap hash = (libsecondlife.StructuredData.LLSDMap) + // libsecondlife.StructuredData.LLSDParser.DeserializeXml(new XmlTextReader(request)); + + Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(request); + TRequest llsdRequest = new TRequest(); + LLSDHelpers.DeserialiseLLSDMap(hash, llsdRequest); + + TResponse response = m_method(llsdRequest); + + Encoding encoding = new UTF8Encoding(false); + + return encoding.GetBytes(LLSDHelpers.SerialiseLLSDReply(response)); + } + } +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDTaskScriptUpdate.cs b/OpenSim/Framework/Communications/Capabilities/LLSDTaskScriptUpdate.cs index 0e10abc396..f7c452905e 100644 --- a/OpenSim/Framework/Communications/Capabilities/LLSDTaskScriptUpdate.cs +++ b/OpenSim/Framework/Communications/Capabilities/LLSDTaskScriptUpdate.cs @@ -1,51 +1,51 @@ -/* -* 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 libsecondlife; - -namespace OpenSim.Region.Capabilities -{ - [LLSDMap] - public class LLSDTaskScriptUpdate - { - /// - /// The item containing the script to update - /// - public LLUUID item_id; - - /// - /// The task containing the script - /// - public LLUUID task_id; - - /// - /// Signals whether the script is currently active - /// - public int is_script_running; - } -} \ No newline at end of file +/* +* 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 libsecondlife; + +namespace OpenSim.Region.Capabilities +{ + [LLSDMap] + public class LLSDTaskScriptUpdate + { + /// + /// The item containing the script to update + /// + public LLUUID item_id; + + /// + /// The task containing the script + /// + public LLUUID task_id; + + /// + /// Signals whether the script is currently active + /// + public int is_script_running; + } +} diff --git a/OpenSim/Framework/Communications/CommunicationsManager.cs b/OpenSim/Framework/Communications/CommunicationsManager.cs index f9da9e763d..cbaf51fde2 100644 --- a/OpenSim/Framework/Communications/CommunicationsManager.cs +++ b/OpenSim/Framework/Communications/CommunicationsManager.cs @@ -1,228 +1,260 @@ -/* -* 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.Generic; -using libsecondlife; -using OpenSim.Framework.Communications.Cache; -using OpenSim.Framework.Console; -using OpenSim.Framework.Servers; - -namespace OpenSim.Framework.Communications -{ - public class CommunicationsManager - { - protected IUserService m_userService; - - public IUserService UserService - { - get { return m_userService; } - } - - protected IGridServices m_gridService; - - public IGridServices GridService - { - get { return m_gridService; } - } - - protected IInventoryServices m_inventoryService; - - public IInventoryServices InventoryService - { - get { return m_inventoryService; } - } - - protected IInterRegionCommunications m_interRegion; - - public IInterRegionCommunications InterRegion - { - get { return m_interRegion; } - } - - protected UserProfileCacheService m_userProfileCacheService; - - public UserProfileCacheService UserProfileCacheService - { - get { return m_userProfileCacheService; } - } - - protected AssetTransactionManager m_transactionsManager; - - public AssetTransactionManager TransactionsManager - { - get { return m_transactionsManager; } - } - - protected AssetCache m_assetCache; - - public AssetCache AssetCache - { - get { return m_assetCache; } - } - - protected NetworkServersInfo m_networkServersInfo; - - public NetworkServersInfo NetworkServersInfo - { - get { return m_networkServersInfo; } - } - - public CommunicationsManager(NetworkServersInfo serversInfo, BaseHttpServer httpServer, AssetCache assetCache, - bool dumpAssetsToFile) - { - m_networkServersInfo = serversInfo; - m_assetCache = assetCache; - m_userProfileCacheService = new UserProfileCacheService(this); - m_transactionsManager = new AssetTransactionManager(this, dumpAssetsToFile); - } - - public void doCreate(string[] cmmdParams) - { - switch (cmmdParams[0]) - { - case "user": - string firstName; - string lastName; - string password; - uint regX = 1000; - uint regY = 1000; - - if (cmmdParams.Length < 2) - { - firstName = MainLog.Instance.CmdPrompt("First name", "Default"); - lastName = MainLog.Instance.CmdPrompt("Last name", "User"); - password = MainLog.Instance.PasswdPrompt("Password"); - regX = Convert.ToUInt32(MainLog.Instance.CmdPrompt("Start Region X", "1000")); - regY = Convert.ToUInt32(MainLog.Instance.CmdPrompt("Start Region Y", "1000")); - } - else - { - firstName = cmmdParams[1]; - lastName = cmmdParams[2]; - password = cmmdParams[3]; - regX = Convert.ToUInt32(cmmdParams[4]); - regY = Convert.ToUInt32(cmmdParams[5]); - } - - AddUser(firstName, lastName, password, regX, regY); - break; - } - } - - public LLUUID AddUser(string firstName, string lastName, string password, uint regX, uint regY) - { - string md5PasswdHash = Util.Md5Hash(Util.Md5Hash(password) + ":" + ""); - - m_userService.AddUserProfile(firstName, lastName, md5PasswdHash, regX, regY); - UserProfileData userProf = UserService.GetUserProfile(firstName, lastName, ""); - if (userProf == null) - { - return LLUUID.Zero; - } - else - { - m_inventoryService.CreateNewUserInventory(userProf.UUID); - System.Console.WriteLine("Created new inventory set for " + firstName + " " + lastName); - return userProf.UUID; - } - } - - #region Friend Methods - /// - /// Adds a new friend to the database for XUser - /// - /// The agent that who's friends list is being added to - /// The agent that being added to the friends list of the friends list owner - /// A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects - public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms) - { - m_userService.AddNewUserFriend(friendlistowner, friend, perms); - } - - /// - /// Delete friend on friendlistowner's friendlist. - /// - /// The agent that who's friends list is being updated - /// The Ex-friend agent - public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend) - { - m_userService.RemoveUserFriend(friendlistowner, friend); - } - - /// - /// Update permissions for friend on friendlistowner's friendlist. - /// - /// The agent that who's friends list is being updated - /// The agent that is getting or loosing permissions - /// A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects - public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms) - { - m_userService.UpdateUserFriendPerms(friendlistowner, friend, perms); - } - /// - /// Returns a list of FriendsListItems that describe the friends and permissions in the friend relationship for LLUUID friendslistowner - /// - /// The agent that we're retreiving the friends Data. - public List GetUserFriendList(LLUUID friendlistowner) - { - return m_userService.GetUserFriendList(friendlistowner); - } - - #endregion - - #region Packet Handlers - - public void HandleUUIDNameRequest(LLUUID uuid, IClientAPI remote_client) - { - if (uuid == m_userProfileCacheService.libraryRoot.agentID) - { - remote_client.SendNameReply(uuid, "Mr", "OpenSim"); - } - else - { - UserProfileData profileData = m_userService.GetUserProfile(uuid, ""); - if (profileData != null) - { - LLUUID profileId = profileData.UUID; - string firstname = profileData.username; - string lastname = profileData.surname; - - remote_client.SendNameReply(profileId, firstname, lastname); - } - } - } - - public List GenerateAgentPickerRequestResponse(LLUUID queryID, string query) - { - List pickerlist = m_userService.GenerateAgentPickerRequestResponse(queryID, query); - return pickerlist; - } - - #endregion - } -} \ No newline at end of file +/* +* 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.Generic; +using libsecondlife; +using OpenSim.Framework.Communications.Cache; +using OpenSim.Framework.Console; +using OpenSim.Framework.Servers; + +namespace OpenSim.Framework.Communications +{ + public class CommunicationsManager + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + protected IUserService m_userService; + + public IUserService UserService + { + get { return m_userService; } + } + + protected IGridServices m_gridService; + + public IGridServices GridService + { + get { return m_gridService; } + } + + protected IInventoryServices m_inventoryService; + + public IInventoryServices InventoryService + { + get { return m_inventoryService; } + } + + protected IInterRegionCommunications m_interRegion; + + public IInterRegionCommunications InterRegion + { + get { return m_interRegion; } + } + + protected UserProfileCacheService m_userProfileCacheService; + + public UserProfileCacheService UserProfileCacheService + { + get { return m_userProfileCacheService; } + } + + // protected AgentAssetTransactionsManager m_transactionsManager; + + // public AgentAssetTransactionsManager TransactionsManager + // { + // get { return m_transactionsManager; } + // } + + protected AssetCache m_assetCache; + + public AssetCache AssetCache + { + get { return m_assetCache; } + } + + protected NetworkServersInfo m_networkServersInfo; + + public NetworkServersInfo NetworkServersInfo + { + get { return m_networkServersInfo; } + } + + public CommunicationsManager(NetworkServersInfo serversInfo, BaseHttpServer httpServer, AssetCache assetCache, + bool dumpAssetsToFile) + { + m_networkServersInfo = serversInfo; + m_assetCache = assetCache; + m_userProfileCacheService = new UserProfileCacheService(this); + // m_transactionsManager = new AgentAssetTransactionsManager(this, dumpAssetsToFile); + } + + public void doCreate(string[] cmmdParams) + { + switch (cmmdParams[0]) + { + case "user": + string firstName; + string lastName; + string password; + uint regX = 1000; + uint regY = 1000; + + if (cmmdParams.Length < 2) + { + firstName = MainConsole.Instance.CmdPrompt("First name", "Default"); + lastName = MainConsole.Instance.CmdPrompt("Last name", "User"); + password = MainConsole.Instance.PasswdPrompt("Password"); + regX = Convert.ToUInt32(MainConsole.Instance.CmdPrompt("Start Region X", "1000")); + regY = Convert.ToUInt32(MainConsole.Instance.CmdPrompt("Start Region Y", "1000")); + } + else + { + firstName = cmmdParams[1]; + lastName = cmmdParams[2]; + password = cmmdParams[3]; + regX = Convert.ToUInt32(cmmdParams[4]); + regY = Convert.ToUInt32(cmmdParams[5]); + } + + if (null == m_userService.GetUserProfile(firstName, lastName)) + { + AddUser(firstName, lastName, password, regX, regY); + } + else + { + m_log.ErrorFormat("[USERS]: A user with the name {0} {1} already exists!", firstName, lastName); + } + break; + } + } + + /// + /// Persistently adds a user to OpenSim. + /// + /// + /// + /// + /// + /// + /// The UUID of the added user. Returns null if the add was unsuccessful + public LLUUID AddUser(string firstName, string lastName, string password, uint regX, uint regY) + { + string md5PasswdHash = Util.Md5Hash(Util.Md5Hash(password) + ":" + String.Empty); + + m_userService.AddUserProfile(firstName, lastName, md5PasswdHash, regX, regY); + UserProfileData userProf = UserService.GetUserProfile(firstName, lastName, ""); + if (userProf == null) + { + return LLUUID.Zero; + } + else + { + m_inventoryService.CreateNewUserInventory(userProf.UUID); + System.Console.WriteLine("[USERS]: Created new inventory set for " + firstName + " " + lastName); + return userProf.UUID; + } + } + + #region Friend Methods + /// + /// Adds a new friend to the database for XUser + /// + /// The agent that who's friends list is being added to + /// The agent that being added to the friends list of the friends list owner + /// A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects + public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms) + { + m_userService.AddNewUserFriend(friendlistowner, friend, perms); + } + /// + /// Logs off a user and does the appropriate communications + /// + /// + /// + /// + /// + /// + /// + public void LogOffUser(LLUUID userid, LLUUID regionid, ulong regionhandle, float posx, float posy, float posz) + { + m_userService.LogOffUser(userid, regionid, regionhandle, posx, posy, posz); + + } + + /// + /// Delete friend on friendlistowner's friendlist. + /// + /// The agent that who's friends list is being updated + /// The Ex-friend agent + public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend) + { + m_userService.RemoveUserFriend(friendlistowner, friend); + } + + /// + /// Update permissions for friend on friendlistowner's friendlist. + /// + /// The agent that who's friends list is being updated + /// The agent that is getting or loosing permissions + /// A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects + public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms) + { + m_userService.UpdateUserFriendPerms(friendlistowner, friend, perms); + } + /// + /// Returns a list of FriendsListItems that describe the friends and permissions in the friend relationship for LLUUID friendslistowner + /// + /// The agent that we're retreiving the friends Data. + public List GetUserFriendList(LLUUID friendlistowner) + { + return m_userService.GetUserFriendList(friendlistowner); + } + + #endregion + + #region Packet Handlers + + public void HandleUUIDNameRequest(LLUUID uuid, IClientAPI remote_client) + { + if (uuid == m_userProfileCacheService.libraryRoot.agentID) + { + remote_client.SendNameReply(uuid, "Mr", "OpenSim"); + } + else + { + UserProfileData profileData = m_userService.GetUserProfile(uuid, ""); + if (profileData != null) + { + LLUUID profileId = profileData.UUID; + string firstname = profileData.username; + string lastname = profileData.surname; + + remote_client.SendNameReply(profileId, firstname, lastname); + } + } + } + + public List GenerateAgentPickerRequestResponse(LLUUID queryID, string query) + { + List pickerlist = m_userService.GenerateAgentPickerRequestResponse(queryID, query); + return pickerlist; + } + + #endregion + } +} diff --git a/OpenSim/Framework/Communications/IInterRegionCommunications.cs b/OpenSim/Framework/Communications/IInterRegionCommunications.cs index e13352bf6c..79bf1d5e1b 100644 --- a/OpenSim/Framework/Communications/IInterRegionCommunications.cs +++ b/OpenSim/Framework/Communications/IInterRegionCommunications.cs @@ -1,48 +1,50 @@ -/* -* 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 libsecondlife; - -namespace OpenSim.Framework.Communications -{ - public interface IInterRegionCommunications - { - string rdebugRegionName { get; set; } - bool InformRegionOfChildAgent(ulong regionHandle, AgentCircuitData agentData); - bool InformRegionOfPrimCrossing(ulong regionHandle, LLUUID primID, string objData); - bool RegionUp(SearializableRegionInfo region, ulong regionhandle); - bool ChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData); - - bool ExpectAvatarCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying); - bool ExpectPrimCrossing(ulong regionHandle, LLUUID primID, LLVector3 position, bool isFlying); - - bool AcknowledgeAgentCrossed(ulong regionHandle, LLUUID agentId); - bool AcknowledgePrimCrossed(ulong regionHandle, LLUUID primID); - - void TellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID); - } -} \ No newline at end of file +/* +* 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 libsecondlife; + +namespace OpenSim.Framework.Communications +{ + public interface IInterRegionCommunications + { + string rdebugRegionName { get; set; } + bool Available { get; } + void CheckRegion(string address, uint port); + bool InformRegionOfChildAgent(ulong regionHandle, AgentCircuitData agentData); + bool InformRegionOfPrimCrossing(ulong regionHandle, LLUUID primID, string objData); + bool RegionUp(SearializableRegionInfo region, ulong regionhandle); + bool ChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData); + + bool ExpectAvatarCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying); + bool ExpectPrimCrossing(ulong regionHandle, LLUUID primID, LLVector3 position, bool isFlying); + + bool AcknowledgeAgentCrossed(ulong regionHandle, LLUUID agentId); + bool AcknowledgePrimCrossed(ulong regionHandle, LLUUID primID); + + bool TellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID); + } +} diff --git a/OpenSim/Framework/Communications/IInventoryServices.cs b/OpenSim/Framework/Communications/IInventoryServices.cs index f80ae35424..9876a3f23f 100644 --- a/OpenSim/Framework/Communications/IInventoryServices.cs +++ b/OpenSim/Framework/Communications/IInventoryServices.cs @@ -1,55 +1,100 @@ -/* -* 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.Collections.Generic; -using libsecondlife; -using OpenSim.Framework.Communications.Cache; - -namespace OpenSim.Framework.Communications -{ - public delegate void InventoryFolderInfo(LLUUID userID, InventoryFolderImpl folderInfo); - - public delegate void InventoryItemInfo(LLUUID userID, InventoryItemBase itemInfo); - - public interface IInventoryServices - { - void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack, InventoryItemInfo itemCallBack); - void AddNewInventoryFolder(LLUUID userID, InventoryFolderBase folder); - void MoveInventoryFolder(LLUUID userID, InventoryFolderBase 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); - } -} \ No newline at end of file +/* +* 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.Collections.Generic; +using libsecondlife; +using OpenSim.Framework.Communications.Cache; + +namespace OpenSim.Framework.Communications +{ + public delegate void InventoryFolderInfo(LLUUID userID, InventoryFolderImpl folderInfo); + + public delegate void InventoryItemInfo(LLUUID userID, InventoryItemBase itemInfo); + + /// + /// Defines all the operations one can perform on a user's inventory. + /// + public interface IInventoryServices + { + void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack, InventoryItemInfo itemCallBack); + + /// + /// Add a new folder to the given user's inventory + /// + /// + /// + void AddNewInventoryFolder(LLUUID userID, InventoryFolderBase folder); + + void MoveInventoryFolder(LLUUID userID, InventoryFolderBase folder); + + /// + /// Add a new item to the given user's inventory + /// + /// + /// + void AddNewInventoryItem(LLUUID userID, InventoryItemBase item); + + /// + /// Delete an item from the given user's inventory + /// + /// + /// + void DeleteInventoryItem(LLUUID userID, InventoryItemBase item); + + /// + /// Create a new inventory for the given user + /// + /// + void CreateNewUserInventory(LLUUID user); + + bool HasInventoryForUser(LLUUID userID); + + /// + /// Retrieve the root inventory folder for the given user. + /// + /// + /// null if no root folder was found + InventoryFolderBase RequestRootFolder(LLUUID userID); + + /// + /// Returns the root folder plus any folders in root (so down one level in the Inventory folders tree) + /// for the given user. + /// + /// + /// + List RequestFirstLevelFolders(LLUUID userID); + + /// + /// Returns the named folder in that users inventory, returns null if folder is not found. + /// + /// + /// + /// + InventoryFolderBase RequestNamedFolder(LLUUID userID, string folderName); + } +} diff --git a/OpenSim/Framework/Communications/InventoryServiceBase.cs b/OpenSim/Framework/Communications/InventoryServiceBase.cs index 414752ce1d..4d3f16ebee 100644 --- a/OpenSim/Framework/Communications/InventoryServiceBase.cs +++ b/OpenSim/Framework/Communications/InventoryServiceBase.cs @@ -1,390 +1,389 @@ -/* -* 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.Generic; -using System.Reflection; -using libsecondlife; -using OpenSim.Framework.Console; - -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("AGENTINVENTORY", "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(); - m_plugins.Add(plug.getName(), plug); - MainLog.Instance.Verbose("AGENTINVENTORY", "Added IInventoryData Interface"); - } - } - } - } - } - - public List RequestFirstLevelFolders(Guid rawUserID) - { - LLUUID userID = new LLUUID(rawUserID); - return RequestFirstLevelFolders(userID); - } - - /// - /// 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(); - InventoryFolderBase rootFolder = null; - - foreach (KeyValuePair plugin in m_plugins) - { - rootFolder = plugin.Value.getUserRootFolder(userID); - if (rootFolder != null) - { - MainLog.Instance.Verbose( - "INVENTORY", - "Found root folder for user with ID " + userID + ". Retrieving inventory contents."); - - inventoryList = plugin.Value.getInventoryFolders(rootFolder.folderID); - inventoryList.Insert(0, rootFolder); - return inventoryList; - } - } - - MainLog.Instance.Warn( - "INVENTORY", "Could not find a root folder belonging to user with ID " + userID); - - return inventoryList; - } - - /// - /// Get the root folder for a user - /// - /// - /// null if no root folder was found - public InventoryFolderBase RequestUsersRoot(LLUUID userID) - { - foreach (KeyValuePair plugin in m_plugins) - { - return plugin.Value.getUserRootFolder(userID); - } - return null; - } - - /// - /// - /// - public void MoveInventoryFolder(LLUUID userID, InventoryFolderBase folder) - { - foreach (KeyValuePair plugin in m_plugins) - { - plugin.Value.moveInventoryFolder(folder); - } - } - - /// - /// - /// - /// - /// - 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 MoveFolder(InventoryFolderBase folder) - { - foreach (KeyValuePair plugin in m_plugins) - { - plugin.Value.moveInventoryFolder(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.inventoryID); - } - } - - /// - /// - /// - /// - public void AddNewInventorySet(UsersInventory inventory) - { - foreach (InventoryFolderBase folder in inventory.Folders.Values) - { - AddFolder(folder); - } - } - - /// - /// Create a new set of inventory folders for the given user. - /// - /// - public void CreateNewUserInventory(LLUUID user) - { - InventoryFolderBase existingRootFolder = RequestUsersRoot(user); - - if (null != existingRootFolder) - { - MainLog.Instance.Error( - "AGENTINVENTORY", - "Did not create a new inventory for user {0} since they already have " - + "a root inventory folder with id {1}", user, existingRootFolder); - } - else - { - UsersInventory inven = new UsersInventory(); - inven.CreateNewInventorySet(user); - 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 = "Accessories"; - folder.type = 8; - folder.version = 1; - Folders.Add(folder.folderID, folder); - - folder = new InventoryFolderBase(); - folder.parentID = rootFolder; - folder.agentID = user; - folder.folderID = LLUUID.Random(); - folder.name = "Animations"; - folder.type = 20; - folder.version = 1; - Folders.Add(folder.folderID, folder); - - folder = new InventoryFolderBase(); - folder.parentID = rootFolder; - folder.agentID = user; - folder.folderID = LLUUID.Random(); - folder.name = "BodyParts"; - folder.type = 13; - folder.version = 1; - Folders.Add(folder.folderID, folder); - - folder = new InventoryFolderBase(); - folder.parentID = rootFolder; - folder.agentID = user; - folder.folderID = LLUUID.Random(); - folder.name = "Clothing"; - folder.type = 5; - folder.version = 1; - Folders.Add(folder.folderID, folder); - - folder = new InventoryFolderBase(); - folder.parentID = rootFolder; - folder.agentID = user; - folder.folderID = LLUUID.Random(); - folder.name = "Gestures"; - folder.type = 21; - folder.version = 1; - Folders.Add(folder.folderID, folder); - - folder = new InventoryFolderBase(); - folder.parentID = rootFolder; - folder.agentID = user; - folder.folderID = LLUUID.Random(); - folder.name = "Landmarks"; - folder.type = 3; - folder.version = 1; - Folders.Add(folder.folderID, folder); - - folder = new InventoryFolderBase(); - folder.parentID = rootFolder; - folder.agentID = user; - folder.folderID = LLUUID.Random(); - folder.name = "Lost And Found"; - folder.type = 3; - folder.version = 1; - Folders.Add(folder.folderID, folder); - - folder = new InventoryFolderBase(); - folder.parentID = rootFolder; - folder.agentID = user; - folder.folderID = LLUUID.Random(); - folder.name = "Notecards"; - folder.type = 7; - 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 = "Photo Album"; - folder.type = 15; - folder.version = 1; - Folders.Add(folder.folderID, folder); - - folder = new InventoryFolderBase(); - folder.parentID = rootFolder; - folder.agentID = user; - folder.folderID = LLUUID.Random(); - folder.name = "Scripts"; - folder.type = 10; - folder.version = 1; - Folders.Add(folder.folderID, folder); - - folder = new InventoryFolderBase(); - folder.parentID = rootFolder; - folder.agentID = user; - folder.folderID = LLUUID.Random(); - folder.name = "Sounds"; - folder.type = 1; - folder.version = 1; - Folders.Add(folder.folderID, folder); - - 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 = "Trash"; - folder.type = 14; - folder.version = 1; - Folders.Add(folder.folderID, folder); - } - } - - public abstract void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack, - InventoryItemInfo itemCallBack); - - public abstract void AddNewInventoryFolder(LLUUID userID, InventoryFolderBase folder); - public abstract void MoveExistingInventoryFolder(InventoryFolderBase folder); - public abstract void AddNewInventoryItem(LLUUID userID, InventoryItemBase item); - public abstract void DeleteInventoryItem(LLUUID userID, InventoryItemBase item); - } -} \ No newline at end of file +/* +* 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.Generic; +using System.Reflection; +using libsecondlife; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Communications +{ + public abstract class InventoryServiceBase : IInventoryServices + { + private static readonly log4net.ILog m_log + = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + protected Dictionary m_plugins = new Dictionary(); + + #region Plugin methods + + /// + /// 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)) + { + m_log.Info("[AGENTINVENTORY]: 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(); + m_plugins.Add(plug.getName(), plug); + m_log.Info("[AGENTINVENTORY]: Added IInventoryData Interface"); + } + } + } + } + } + + #endregion + + #region IInventoryServices methods + + // See IInventoryServices + public List RequestFirstLevelFolders(Guid rawUserID) + { + LLUUID userID = new LLUUID(rawUserID); + return RequestFirstLevelFolders(userID); + } + + // See IInventoryServices + public List RequestFirstLevelFolders(LLUUID userID) + { + List inventoryList = new List(); + InventoryFolderBase rootFolder = null; + + foreach (KeyValuePair plugin in m_plugins) + { + rootFolder = plugin.Value.getUserRootFolder(userID); + if (rootFolder != null) + { + m_log.Info( + "[INVENTORY]: Found root folder for user with ID " + userID + ". Retrieving inventory contents."); + + inventoryList = plugin.Value.getInventoryFolders(rootFolder.folderID); + inventoryList.Insert(0, rootFolder); + return inventoryList; + } + } + + m_log.Warn( + "[INVENTORY]: Could not find a root folder belonging to user with ID " + userID); + + return inventoryList; + } + + // See IInventoryServices + public InventoryFolderBase RequestUsersRoot(LLUUID userID) + { + foreach (KeyValuePair plugin in m_plugins) + { + return plugin.Value.getUserRootFolder(userID); + } + return null; + } + + // See IInventoryServices + public void MoveInventoryFolder(LLUUID userID, InventoryFolderBase folder) + { + foreach (KeyValuePair plugin in m_plugins) + { + plugin.Value.moveInventoryFolder(folder); + } + } + + public virtual bool HasInventoryForUser(LLUUID userID) + { + return false; + } + + // See IInventoryServices + public InventoryFolderBase RequestRootFolder(LLUUID userID) + { + return RequestUsersRoot(userID); + } + + // See IInventoryServices + public virtual InventoryFolderBase RequestNamedFolder(LLUUID userID, string folderName) + { + return null; + } + + // See IInventoryServices + public void CreateNewUserInventory(LLUUID user) + { + InventoryFolderBase existingRootFolder = RequestUsersRoot(user); + + if (null != existingRootFolder) + { + m_log.ErrorFormat("[AGENTINVENTORY]: " + + "Did not create a new inventory for user {0} since they already have " + + "a root inventory folder with id {1}", user, existingRootFolder); + } + else + { + UsersInventory inven = new UsersInventory(); + inven.CreateNewInventorySet(user); + AddNewInventorySet(inven); + } + } + + public abstract void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack, + InventoryItemInfo itemCallBack); + public abstract void AddNewInventoryFolder(LLUUID userID, InventoryFolderBase folder); + public abstract void MoveExistingInventoryFolder(InventoryFolderBase folder); + public abstract void AddNewInventoryItem(LLUUID userID, InventoryItemBase item); + public abstract void DeleteInventoryItem(LLUUID userID, InventoryItemBase item); + + #endregion + + #region Methods used by GridInventoryService + + 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; + } + + #endregion + + protected void AddFolder(InventoryFolderBase folder) + { + foreach (KeyValuePair plugin in m_plugins) + { + plugin.Value.addInventoryFolder(folder); + } + } + + protected void MoveFolder(InventoryFolderBase folder) + { + foreach (KeyValuePair plugin in m_plugins) + { + plugin.Value.moveInventoryFolder(folder); + } + } + + protected void AddItem(InventoryItemBase item) + { + foreach (KeyValuePair plugin in m_plugins) + { + plugin.Value.addInventoryItem(item); + } + } + + protected void DeleteItem(InventoryItemBase item) + { + foreach (KeyValuePair plugin in m_plugins) + { + plugin.Value.deleteInventoryItem(item.inventoryID); + } + } + + private void AddNewInventorySet(UsersInventory inventory) + { + foreach (InventoryFolderBase folder in inventory.Folders.Values) + { + AddFolder(folder); + } + } + + private class UsersInventory + { + public Dictionary Folders = new Dictionary(); + public Dictionary Items = new Dictionary(); + + 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 = "Accessories"; + folder.type = 8; + folder.version = 1; + Folders.Add(folder.folderID, folder); + + folder = new InventoryFolderBase(); + folder.parentID = rootFolder; + folder.agentID = user; + folder.folderID = LLUUID.Random(); + folder.name = "Animations"; + folder.type = 20; + folder.version = 1; + Folders.Add(folder.folderID, folder); + + folder = new InventoryFolderBase(); + folder.parentID = rootFolder; + folder.agentID = user; + folder.folderID = LLUUID.Random(); + folder.name = "BodyParts"; + folder.type = 13; + folder.version = 1; + Folders.Add(folder.folderID, folder); + + folder = new InventoryFolderBase(); + folder.parentID = rootFolder; + folder.agentID = user; + folder.folderID = LLUUID.Random(); + folder.name = "Clothing"; + folder.type = 5; + folder.version = 1; + Folders.Add(folder.folderID, folder); + + folder = new InventoryFolderBase(); + folder.parentID = rootFolder; + folder.agentID = user; + folder.folderID = LLUUID.Random(); + folder.name = "Gestures"; + folder.type = 21; + folder.version = 1; + Folders.Add(folder.folderID, folder); + + folder = new InventoryFolderBase(); + folder.parentID = rootFolder; + folder.agentID = user; + folder.folderID = LLUUID.Random(); + folder.name = "Landmarks"; + folder.type = 3; + folder.version = 1; + Folders.Add(folder.folderID, folder); + + folder = new InventoryFolderBase(); + folder.parentID = rootFolder; + folder.agentID = user; + folder.folderID = LLUUID.Random(); + folder.name = "Lost And Found"; + folder.type = 3; + folder.version = 1; + Folders.Add(folder.folderID, folder); + + folder = new InventoryFolderBase(); + folder.parentID = rootFolder; + folder.agentID = user; + folder.folderID = LLUUID.Random(); + folder.name = "Notecards"; + folder.type = 7; + 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 = "Photo Album"; + folder.type = 15; + folder.version = 1; + Folders.Add(folder.folderID, folder); + + folder = new InventoryFolderBase(); + folder.parentID = rootFolder; + folder.agentID = user; + folder.folderID = LLUUID.Random(); + folder.name = "Scripts"; + folder.type = 10; + folder.version = 1; + Folders.Add(folder.folderID, folder); + + folder = new InventoryFolderBase(); + folder.parentID = rootFolder; + folder.agentID = user; + folder.folderID = LLUUID.Random(); + folder.name = "Sounds"; + folder.type = 1; + folder.version = 1; + Folders.Add(folder.folderID, folder); + + 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 = "Trash"; + folder.type = 14; + folder.version = 1; + Folders.Add(folder.folderID, folder); + } + } + } +} diff --git a/OpenSim/Framework/Communications/LoginResponse.cs b/OpenSim/Framework/Communications/LoginResponse.cs index 19cb0a54fa..ed949be6fc 100644 --- a/OpenSim/Framework/Communications/LoginResponse.cs +++ b/OpenSim/Framework/Communications/LoginResponse.cs @@ -1,768 +1,766 @@ -/* -* 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 libsecondlife; -using libsecondlife.StructuredData; -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 inventoryLibRoot; - 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 uint simPort; - private string simAddress; - private string agentAccess; - private Int32 circuitCode; - private uint regionX; - private uint regionY; - - // Login - private string firstname; - private string lastname; - - // REX (client version string) - private string clientVersion = "not set"; - - // 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; - - private BuddyList m_buddyList = null; - - public LoginResponse() - { - loginFlags = new ArrayList(); - globalTextures = new ArrayList(); - eventCategories = new ArrayList(); - uiConfig = new ArrayList(); - classifiedCategories = new ArrayList(); - - loginError = new Hashtable(); - uiConfigHash = new Hashtable(); - - defaultXmlRpcResponse = new XmlRpcResponse(); - userProfile = new UserInfo(); - inventoryRoot = new ArrayList(); - initialOutfit = new ArrayList(); - agentInventory = new ArrayList(); - inventoryLibrary = new ArrayList(); - inventoryLibraryOwner = new ArrayList(); - - xmlRpcResponse = new XmlRpcResponse(); - defaultXmlRpcResponse = new XmlRpcResponse(); - - SetDefaultValues(); - } // LoginServer - - public void SetDefaultValues() - { - DST = "N"; - StipendSinceLogin = "N"; - Gendered = "Y"; - EverLoggedIn = "Y"; - login = "false"; - firstname = "Test"; - lastname = "User"; - agentAccess = "M"; - startLocation = "last"; - allowFirstLife = "Y"; - - SunTexture = "cce0f112-878f-4586-a2e2-a8f104bba271"; - CloudTexture = "dc4b9f0b-d008-45c6-96a4-01dd947ac621"; - MoonTexture = "ec4b9f0b-d008-45c6-96a4-01dd947ac621"; - - ErrorMessage = "You have entered an invalid name/password combination. Check Caps/lock."; - ErrorReason = "key"; - welcomeMessage = "Welcome to OpenSim!"; - seedCapability = ""; - home = "{'region_handle':[r" + (1000*256).ToString() + ",r" + (1000*256).ToString() + "], 'position':[r" + - userProfile.homepos.X.ToString() + ",r" + userProfile.homepos.Y.ToString() + ",r" + - userProfile.homepos.Z.ToString() + "], 'look_at':[r" + userProfile.homelookat.X.ToString() + ",r" + - userProfile.homelookat.Y.ToString() + ",r" + userProfile.homelookat.Z.ToString() + "]}"; - lookAt = "[r0.99949799999999999756,r0.03166859999999999814,r0]"; - RegionX = (uint) 255232; - RegionY = (uint) 254976; - - clientVersion = "not set"; //rex - - // Classifieds; - AddClassifiedCategory((Int32) 1, "Shopping"); - AddClassifiedCategory((Int32) 2, "Land Rental"); - AddClassifiedCategory((Int32) 3, "Property Rental"); - AddClassifiedCategory((Int32) 4, "Special Attraction"); - AddClassifiedCategory((Int32) 5, "New Products"); - AddClassifiedCategory((Int32) 6, "Employment"); - AddClassifiedCategory((Int32) 7, "Wanted"); - AddClassifiedCategory((Int32) 8, "Service"); - AddClassifiedCategory((Int32) 9, "Personal"); - - - SessionID = LLUUID.Random(); - SecureSessionID = LLUUID.Random(); - AgentID = LLUUID.Random(); - - Hashtable InitialOutfitHash = new Hashtable(); - InitialOutfitHash["folder_name"] = "Nightclub Female"; - InitialOutfitHash["gender"] = "female"; - initialOutfit.Add(InitialOutfitHash); - } // SetDefaultValues - - #region Login Failure Methods - - public XmlRpcResponse GenerateFailureResponse(string reason, string message, string login) - { - // Overwrite any default values; - xmlRpcResponse = new XmlRpcResponse(); - - // Ensure Login Failed message/reason; - ErrorMessage = message; - ErrorReason = reason; - - loginError["reason"] = ErrorReason; - loginError["message"] = ErrorMessage; - loginError["login"] = login; - xmlRpcResponse.Value = loginError; - return (xmlRpcResponse); - } // GenerateResponse - - public LLSD GenerateFailureResponseLLSD(string reason, string message, string login) - { - LLSDMap map = new LLSDMap(); - - // Ensure Login Failed message/reason; - ErrorMessage = message; - ErrorReason = reason; - - map["reason"] = LLSD.FromString(ErrorReason); - map["message"] = LLSD.FromString(ErrorMessage); - map["login"] = LLSD.FromString(login); - - return map; - } - - public XmlRpcResponse CreateFailedResponse() - { - return (CreateLoginFailedResponse()); - } // CreateErrorConnectingToGridResponse() - - public LLSD CreateFailedResponseLLSD() - { - return CreateLoginFailedResponseLLSD(); - } - - public XmlRpcResponse CreateLoginFailedResponse() - { - return - (GenerateFailureResponse("key", - "Could not authenticate your avatar. Please check your username and password, and check the grid if problems persist.", - "false")); - } // LoginFailedResponse - - public LLSD CreateLoginFailedResponseLLSD() - { - return GenerateFailureResponseLLSD( - "key", - "Could not authenticate your avatar. Please check your username and password, and check the grid if problems persist.", - "false"); - } - - public XmlRpcResponse CreateAlreadyLoggedInResponse() - { - return - (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 LLSD CreateAlreadyLoggedInResponseLLSD() - { - return GenerateFailureResponseLLSD( - "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"); - } - - public XmlRpcResponse CreateDeadRegionResponse() - { - return - (GenerateFailureResponse("key", - "The region you are attempting to log into is not responding. Please select another region and try again.", - "false")); - } - - public LLSD CreateDeadRegionResponseLLSD() - { - return GenerateFailureResponseLLSD( - "key", - "The region you are attempting to log into is not responding. Please select another region and try again.", - "false"); - } - - public XmlRpcResponse CreateGridErrorResponse() - { - return - (GenerateFailureResponse("key", - "Error connecting to grid. Could not percieve credentials from login XML.", - "false")); - } - - public LLSD CreateGridErrorResponseLLSD() - { - return GenerateFailureResponseLLSD( - "key", - "Error connecting to grid. Could not percieve credentials from login XML.", - "false"); - } - - #endregion - - public XmlRpcResponse ToXmlRpcResponse() - { - try - { - Hashtable responseData = new Hashtable(); - - loginFlagsHash = new Hashtable(); - loginFlagsHash["daylight_savings"] = DST; - loginFlagsHash["stipend_since_login"] = StipendSinceLogin; - loginFlagsHash["gendered"] = Gendered; - loginFlagsHash["ever_logged_in"] = EverLoggedIn; - loginFlags.Add(loginFlagsHash); - - responseData["first_name"] = Firstname; - responseData["last_name"] = Lastname; - responseData["agent_access"] = agentAccess; - - globalTexturesHash = new Hashtable(); - globalTexturesHash["sun_texture_id"] = SunTexture; - globalTexturesHash["cloud_texture_id"] = CloudTexture; - globalTexturesHash["moon_texture_id"] = MoonTexture; - globalTextures.Add(globalTexturesHash); - // this.eventCategories.Add(this.eventCategoriesHash); - - AddToUIConfig("allow_first_life", allowFirstLife); - uiConfig.Add(uiConfigHash); - - responseData["sim_port"] = (Int32) SimPort; - responseData["sim_ip"] = SimAddress; - - responseData["agent_id"] = AgentID.ToString(); - responseData["session_id"] = SessionID.ToString(); - responseData["secure_session_id"] = SecureSessionID.ToString(); - responseData["circuit_code"] = CircuitCode; - responseData["seconds_since_epoch"] = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; - responseData["login-flags"] = loginFlags; - responseData["global-textures"] = globalTextures; - responseData["seed_capability"] = seedCapability; - - responseData["event_categories"] = eventCategories; - responseData["event_notifications"] = new ArrayList(); // todo - responseData["classified_categories"] = classifiedCategories; - responseData["ui-config"] = uiConfig; - - responseData["inventory-skeleton"] = agentInventory; - responseData["inventory-skel-lib"] = inventoryLibrary; - responseData["inventory-root"] = inventoryRoot; - responseData["inventory-lib-root"] = inventoryLibRoot; - responseData["gestures"] = new ArrayList(); // todo - responseData["inventory-lib-owner"] = inventoryLibraryOwner; - responseData["initial-outfit"] = initialOutfit; - responseData["start_location"] = startLocation; - responseData["seed_capability"] = seedCapability; - responseData["home"] = home; - responseData["look_at"] = lookAt; - responseData["message"] = welcomeMessage; - responseData["region_x"] = (Int32) RegionX*256; - responseData["region_y"] = (Int32) RegionY*256; - - responseData["version"] = clientVersion; //rex - - //responseData["inventory-lib-root"] = new ArrayList(); // todo - - if (m_buddyList != null) - { - responseData["buddy-list"] = m_buddyList.ToArray(); - } - - responseData["login"] = "true"; - xmlRpcResponse.Value = responseData; - - return (xmlRpcResponse); - } - catch (Exception e) - { - MainLog.Instance.Warn( - "CLIENT", - "LoginResponse: Error creating XML-RPC Response: " + e.Message - ); - return (GenerateFailureResponse("Internal Error", "Error generating Login Response", "false")); - } - } // ToXmlRpcResponse - - public LLSD ToLLSDResponse() - { - try - { - LLSDMap map = new LLSDMap(); - - map["first_name"] = LLSD.FromString(Firstname); - map["last_name"] = LLSD.FromString(Lastname); - map["agent_access"] = LLSD.FromString(agentAccess); - - map["sim_port"] = LLSD.FromInteger(SimPort); - map["sim_ip"] = LLSD.FromString(SimAddress); - - map["agent_id"] = LLSD.FromUUID(AgentID); - map["session_id"] = LLSD.FromUUID(SessionID); - map["secure_session_id"] = LLSD.FromUUID(SecureSessionID); - map["circuit_code"] = LLSD.FromInteger(CircuitCode); - map["seconds_since_epoch"] = LLSD.FromInteger((int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds); - - #region Login Flags - - LLSDMap loginFlagsLLSD = new LLSDMap(); - loginFlagsLLSD["daylight_savings"] = LLSD.FromString(DST); - loginFlagsLLSD["stipend_since_login"] = LLSD.FromString(StipendSinceLogin); - loginFlagsLLSD["gendered"] = LLSD.FromString(Gendered); - loginFlagsLLSD["ever_logged_in"] = LLSD.FromString(EverLoggedIn); - map["login-flags"] = WrapLLSDMap(loginFlagsLLSD); - - #endregion Login Flags - - #region Global Textures - - LLSDMap globalTexturesLLSD = new LLSDMap(); - globalTexturesLLSD["sun_texture_id"] = LLSD.FromString(SunTexture); - globalTexturesLLSD["cloud_texture_id"] = LLSD.FromString(CloudTexture); - globalTexturesLLSD["moon_texture_id"] = LLSD.FromString(MoonTexture); - - map["global-textures"] = WrapLLSDMap(globalTexturesLLSD); - - #endregion Global Textures - - map["seed_capability"] = LLSD.FromString(seedCapability); - - // FIXME: Need a function that will convert these ArrayLists in to LLSDArrays, - // and convert the data inside them to LLSD objects as well - - //map["event_categories"] = eventCategories; - //map["event_notifications"] = new LLSDArray(); // todo - //map["classified_categories"] = classifiedCategories; - - #region UI Config - - LLSDMap uiConfigLLSD = new LLSDMap(); - uiConfigLLSD["allow_first_life"] = LLSD.FromString(allowFirstLife); - map["ui-config"] = WrapLLSDMap(uiConfigLLSD); - - #endregion UI Config - - #region Inventory - - //map["inventory-skeleton"] = agentInventory; - //map["inventory-skel-lib"] = inventoryLibrary; - //map["inventory-root"] = inventoryRoot; - //map["inventory-lib-root"] = inventoryLibRoot; - //map["inventory-lib-owner"] = inventoryLibraryOwner; - - #endregion Inventory - - map["gestures"] = new LLSDArray(); // todo - - //responseData["initial-outfit"] = initialOutfit; - //responseData["start_location"] = startLocation; - - map["seed_capability"] = LLSD.FromString(seedCapability); - map["home"] = LLSD.FromString(home); - map["look_at"] = LLSD.FromString(lookAt); - map["message"] = LLSD.FromString(welcomeMessage); - map["region_x"] = LLSD.FromInteger(RegionX * 256); - map["region_y"] = LLSD.FromInteger(RegionY * 256); - - map["version"] = LLSD.FromString(clientVersion); //rex - - if (m_buddyList != null) - { - //map["buddy-list"] = m_buddyList.ToArray(); - } - - map["login"] = LLSD.FromString("true"); - - return map; - } - catch (Exception e) - { - MainLog.Instance.Warn( - "CLIENT", - "LoginResponse: Error creating XML-RPC Response: " + e.Message - ); - return GenerateFailureResponseLLSD("Internal Error", "Error generating Login Response", "false"); - } - } - - private LLSDArray WrapLLSDMap(LLSDMap wrapMe) - { - LLSDArray array = new LLSDArray(); - array.Add(wrapMe); - return array; - } - - public void SetEventCategories(string category, string value) - { - // this.eventCategoriesHash[category] = value; - //TODO - } // SetEventCategories - - public void AddToUIConfig(string itemName, string item) - { - uiConfigHash[itemName] = item; - } // SetUIConfig - - public void AddClassifiedCategory(Int32 ID, string categoryName) - { - Hashtable hash = new Hashtable(); - hash["category_name"] = categoryName; - hash["category_id"] = ID; - classifiedCategories.Add(hash); - // this.classifiedCategoriesHash.Clear(); - } // SetClassifiedCategory - - #region Properties - - public string Login - { - get { return login; } - set { login = value; } - } // Login - - public string DST - { - get { return dst; } - set { dst = value; } - } // DST - - public string StipendSinceLogin - { - get { return stipendSinceLogin; } - set { stipendSinceLogin = value; } - } // StipendSinceLogin - - public string Gendered - { - get { return gendered; } - set { gendered = value; } - } // Gendered - - public string EverLoggedIn - { - get { return everLoggedIn; } - set { everLoggedIn = value; } - } // EverLoggedIn - - public uint SimPort - { - get { return simPort; } - set { simPort = value; } - } // SimPort - - public string SimAddress - { - get { return simAddress; } - set { simAddress = value; } - } // SimAddress - - public LLUUID AgentID - { - get { return agentID; } - set { agentID = value; } - } // AgentID - - public LLUUID SessionID - { - get { return sessionID; } - set { sessionID = value; } - } // SessionID - - public LLUUID SecureSessionID - { - get { return secureSessionID; } - set { secureSessionID = value; } - } // SecureSessionID - - public Int32 CircuitCode - { - get { return circuitCode; } - set { circuitCode = value; } - } // CircuitCode - - public uint RegionX - { - get { return regionX; } - set { regionX = value; } - } // RegionX - - public uint RegionY - { - get { return regionY; } - set { regionY = value; } - } // RegionY - - public string SunTexture - { - get { return sunTexture; } - set { sunTexture = value; } - } // SunTexture - - public string CloudTexture - { - get { return cloudTexture; } - set { cloudTexture = value; } - } // CloudTexture - - public string MoonTexture - { - get { return moonTexture; } - set { moonTexture = value; } - } // MoonTexture - - public string Firstname - { - get { return firstname; } - set { firstname = value; } - } // Firstname - - public string Lastname - { - get { return lastname; } - set { lastname = value; } - } // Lastname - - public string ClientVersion - { - get { return clientVersion; } - set { clientVersion = value; } - } //REX ClientVersion - - public string AgentAccess - { - get { return agentAccess; } - set { agentAccess = value; } - } - - public string StartLocation - { - get { return startLocation; } - set { startLocation = value; } - } // StartLocation - - public string LookAt - { - get { return lookAt; } - set { lookAt = value; } - } - - public string SeedCapability - { - get { return seedCapability; } - set { seedCapability = value; } - } // SeedCapability - - public string ErrorReason - { - get { return errorReason; } - set { errorReason = value; } - } // ErrorReason - - public string ErrorMessage - { - get { return errorMessage; } - set { errorMessage = value; } - } // ErrorMessage - - public ArrayList InventoryRoot - { - get { return inventoryRoot; } - set { inventoryRoot = value; } - } - - public ArrayList InventorySkeleton - { - get { return agentInventory; } - set { agentInventory = value; } - } - - public ArrayList InventoryLibrary - { - get { return inventoryLibrary; } - set { inventoryLibrary = value; } - } - - public ArrayList InventoryLibraryOwner - { - get { return inventoryLibraryOwner; } - set { inventoryLibraryOwner = value; } - } - - public ArrayList InventoryLibRoot - { - get { return inventoryLibRoot; } - set { inventoryLibRoot = value; } - } - - public string Home - { - get { return home; } - set { home = value; } - } - - public string Message - { - get { return welcomeMessage; } - set { welcomeMessage = value; } - } - - public BuddyList BuddList - { - get { return m_buddyList; } - set { m_buddyList = value; } - } - - #endregion - - public class UserInfo - { - public string firstname; - public string lastname; - public ulong homeregionhandle; - public LLVector3 homepos; - public LLVector3 homelookat; - } - - public class BuddyList - { - public List Buddies = new List(); - - public void AddNewBuddy(BuddyInfo buddy) - { - if (!Buddies.Contains(buddy)) - { - Buddies.Add(buddy); - } - } - - public ArrayList ToArray() - { - ArrayList buddyArray = new ArrayList(); - foreach (BuddyInfo buddy in Buddies) - { - buddyArray.Add(buddy.ToHashTable()); - } - return buddyArray; - } - - public class BuddyInfo - { - public int BuddyRightsHave = 1; - public int BuddyRightsGiven = 1; - public LLUUID BuddyID; - - public BuddyInfo(string buddyID) - { - BuddyID = new LLUUID(buddyID); - } - - public BuddyInfo(LLUUID buddyID) - { - BuddyID = buddyID; - } - - public Hashtable ToHashTable() - { - Hashtable hTable = new Hashtable(); - hTable["buddy_rights_has"] = BuddyRightsHave; - hTable["buddy_rights_given"] = BuddyRightsGiven; - hTable["buddy_id"] = BuddyID.ToString(); - return hTable; - } - } - } - } -} +/* +* 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 libsecondlife; +using libsecondlife.StructuredData; +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 static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + 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 inventoryLibRoot; + 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 uint simPort; + private string simAddress; + private string agentAccess; + private Int32 circuitCode; + private uint regionX; + private uint regionY; + + // Login + private string firstname; + private string lastname; + + // REX (client version string) + private string clientVersion = "not set"; + + // 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; + + private BuddyList m_buddyList = null; + + public LoginResponse() + { + loginFlags = new ArrayList(); + globalTextures = new ArrayList(); + eventCategories = new ArrayList(); + uiConfig = new ArrayList(); + classifiedCategories = new ArrayList(); + + loginError = new Hashtable(); + uiConfigHash = new Hashtable(); + + defaultXmlRpcResponse = new XmlRpcResponse(); + userProfile = new UserInfo(); + inventoryRoot = new ArrayList(); + initialOutfit = new ArrayList(); + agentInventory = new ArrayList(); + inventoryLibrary = new ArrayList(); + inventoryLibraryOwner = new ArrayList(); + + xmlRpcResponse = new XmlRpcResponse(); + defaultXmlRpcResponse = new XmlRpcResponse(); + + SetDefaultValues(); + } + + public void SetDefaultValues() + { + DST = "N"; + StipendSinceLogin = "N"; + Gendered = "Y"; + EverLoggedIn = "Y"; + login = "false"; + firstname = "Test"; + lastname = "User"; + agentAccess = "M"; + startLocation = "last"; + allowFirstLife = "Y"; + + SunTexture = "cce0f112-878f-4586-a2e2-a8f104bba271"; + CloudTexture = "dc4b9f0b-d008-45c6-96a4-01dd947ac621"; + MoonTexture = "ec4b9f0b-d008-45c6-96a4-01dd947ac621"; + + ErrorMessage = "You have entered an invalid name/password combination. Check Caps/lock."; + ErrorReason = "key"; + welcomeMessage = "Welcome to OpenSim!"; + seedCapability = String.Empty; + home = "{'region_handle':[r" + (1000*Constants.RegionSize).ToString() + ",r" + (1000*Constants.RegionSize).ToString() + "], 'position':[r" + + userProfile.homepos.X.ToString() + ",r" + userProfile.homepos.Y.ToString() + ",r" + + userProfile.homepos.Z.ToString() + "], 'look_at':[r" + userProfile.homelookat.X.ToString() + ",r" + + userProfile.homelookat.Y.ToString() + ",r" + userProfile.homelookat.Z.ToString() + "]}"; + lookAt = "[r0.99949799999999999756,r0.03166859999999999814,r0]"; + RegionX = (uint) 255232; + RegionY = (uint) 254976; + + clientVersion = "not set"; //rex + + // Classifieds; + AddClassifiedCategory((Int32) 1, "Shopping"); + AddClassifiedCategory((Int32) 2, "Land Rental"); + AddClassifiedCategory((Int32) 3, "Property Rental"); + AddClassifiedCategory((Int32) 4, "Special Attraction"); + AddClassifiedCategory((Int32) 5, "New Products"); + AddClassifiedCategory((Int32) 6, "Employment"); + AddClassifiedCategory((Int32) 7, "Wanted"); + AddClassifiedCategory((Int32) 8, "Service"); + AddClassifiedCategory((Int32) 9, "Personal"); + + + SessionID = LLUUID.Random(); + SecureSessionID = LLUUID.Random(); + AgentID = LLUUID.Random(); + + Hashtable InitialOutfitHash = new Hashtable(); + InitialOutfitHash["folder_name"] = "Nightclub Female"; + InitialOutfitHash["gender"] = "female"; + initialOutfit.Add(InitialOutfitHash); + } + + #region Login Failure Methods + + public XmlRpcResponse GenerateFailureResponse(string reason, string message, string login) + { + // Overwrite any default values; + xmlRpcResponse = new XmlRpcResponse(); + + // Ensure Login Failed message/reason; + ErrorMessage = message; + ErrorReason = reason; + + loginError["reason"] = ErrorReason; + loginError["message"] = ErrorMessage; + loginError["login"] = login; + xmlRpcResponse.Value = loginError; + return (xmlRpcResponse); + } + + public LLSD GenerateFailureResponseLLSD(string reason, string message, string login) + { + LLSDMap map = new LLSDMap(); + + // Ensure Login Failed message/reason; + ErrorMessage = message; + ErrorReason = reason; + + map["reason"] = LLSD.FromString(ErrorReason); + map["message"] = LLSD.FromString(ErrorMessage); + map["login"] = LLSD.FromString(login); + + return map; + } + + public XmlRpcResponse CreateFailedResponse() + { + return (CreateLoginFailedResponse()); + } + + public LLSD CreateFailedResponseLLSD() + { + return CreateLoginFailedResponseLLSD(); + } + + public XmlRpcResponse CreateLoginFailedResponse() + { + return + (GenerateFailureResponse("key", + "Could not authenticate your avatar. Please check your username and password, and check the grid if problems persist.", + "false")); + } + + public LLSD CreateLoginFailedResponseLLSD() + { + return GenerateFailureResponseLLSD( + "key", + "Could not authenticate your avatar. Please check your username and password, and check the grid if problems persist.", + "false"); + } + + public XmlRpcResponse CreateAlreadyLoggedInResponse() + { + return + (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")); + } + + public LLSD CreateAlreadyLoggedInResponseLLSD() + { + return GenerateFailureResponseLLSD( + "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"); + } + + public XmlRpcResponse CreateDeadRegionResponse() + { + return + (GenerateFailureResponse("key", + "The region you are attempting to log into is not responding. Please select another region and try again.", + "false")); + } + + public LLSD CreateDeadRegionResponseLLSD() + { + return GenerateFailureResponseLLSD( + "key", + "The region you are attempting to log into is not responding. Please select another region and try again.", + "false"); + } + + public XmlRpcResponse CreateGridErrorResponse() + { + return + (GenerateFailureResponse("key", + "Error connecting to grid. Could not percieve credentials from login XML.", + "false")); + } + + public LLSD CreateGridErrorResponseLLSD() + { + return GenerateFailureResponseLLSD( + "key", + "Error connecting to grid. Could not percieve credentials from login XML.", + "false"); + } + + #endregion + + public XmlRpcResponse ToXmlRpcResponse() + { + try + { + Hashtable responseData = new Hashtable(); + + loginFlagsHash = new Hashtable(); + loginFlagsHash["daylight_savings"] = DST; + loginFlagsHash["stipend_since_login"] = StipendSinceLogin; + loginFlagsHash["gendered"] = Gendered; + loginFlagsHash["ever_logged_in"] = EverLoggedIn; + loginFlags.Add(loginFlagsHash); + + responseData["first_name"] = Firstname; + responseData["last_name"] = Lastname; + responseData["agent_access"] = agentAccess; + + globalTexturesHash = new Hashtable(); + globalTexturesHash["sun_texture_id"] = SunTexture; + globalTexturesHash["cloud_texture_id"] = CloudTexture; + globalTexturesHash["moon_texture_id"] = MoonTexture; + globalTextures.Add(globalTexturesHash); + // this.eventCategories.Add(this.eventCategoriesHash); + + AddToUIConfig("allow_first_life", allowFirstLife); + uiConfig.Add(uiConfigHash); + + responseData["sim_port"] = (Int32) SimPort; + responseData["sim_ip"] = SimAddress; + + responseData["agent_id"] = AgentID.ToString(); + responseData["session_id"] = SessionID.ToString(); + responseData["secure_session_id"] = SecureSessionID.ToString(); + responseData["circuit_code"] = CircuitCode; + responseData["seconds_since_epoch"] = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; + responseData["login-flags"] = loginFlags; + responseData["global-textures"] = globalTextures; + responseData["seed_capability"] = seedCapability; + + responseData["event_categories"] = eventCategories; + responseData["event_notifications"] = new ArrayList(); // todo + responseData["classified_categories"] = classifiedCategories; + responseData["ui-config"] = uiConfig; + + responseData["inventory-skeleton"] = agentInventory; + responseData["inventory-skel-lib"] = inventoryLibrary; + responseData["inventory-root"] = inventoryRoot; + responseData["inventory-lib-root"] = inventoryLibRoot; + responseData["gestures"] = new ArrayList(); // todo + responseData["inventory-lib-owner"] = inventoryLibraryOwner; + responseData["initial-outfit"] = initialOutfit; + responseData["start_location"] = startLocation; + responseData["seed_capability"] = seedCapability; + responseData["home"] = home; + responseData["look_at"] = lookAt; + responseData["message"] = welcomeMessage; + responseData["region_x"] = (Int32)(RegionX * Constants.RegionSize); + responseData["region_y"] = (Int32)(RegionY * Constants.RegionSize); + + responseData["version"] = clientVersion; //rex + + //responseData["inventory-lib-root"] = new ArrayList(); // todo + + if (m_buddyList != null) + { + responseData["buddy-list"] = m_buddyList.ToArray(); + } + + responseData["login"] = "true"; + xmlRpcResponse.Value = responseData; + + return (xmlRpcResponse); + } + catch (Exception e) + { + m_log.Warn("[CLIENT]: LoginResponse: Error creating XML-RPC Response: " + e.Message); + + return (GenerateFailureResponse("Internal Error", "Error generating Login Response", "false")); + } + } + + public LLSD ToLLSDResponse() + { + try + { + LLSDMap map = new LLSDMap(); + + map["first_name"] = LLSD.FromString(Firstname); + map["last_name"] = LLSD.FromString(Lastname); + map["agent_access"] = LLSD.FromString(agentAccess); + + map["sim_port"] = LLSD.FromInteger(SimPort); + map["sim_ip"] = LLSD.FromString(SimAddress); + + map["agent_id"] = LLSD.FromUUID(AgentID); + map["session_id"] = LLSD.FromUUID(SessionID); + map["secure_session_id"] = LLSD.FromUUID(SecureSessionID); + map["circuit_code"] = LLSD.FromInteger(CircuitCode); + map["seconds_since_epoch"] = LLSD.FromInteger((int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds); + + #region Login Flags + + LLSDMap loginFlagsLLSD = new LLSDMap(); + loginFlagsLLSD["daylight_savings"] = LLSD.FromString(DST); + loginFlagsLLSD["stipend_since_login"] = LLSD.FromString(StipendSinceLogin); + loginFlagsLLSD["gendered"] = LLSD.FromString(Gendered); + loginFlagsLLSD["ever_logged_in"] = LLSD.FromString(EverLoggedIn); + map["login-flags"] = WrapLLSDMap(loginFlagsLLSD); + + #endregion Login Flags + + #region Global Textures + + LLSDMap globalTexturesLLSD = new LLSDMap(); + globalTexturesLLSD["sun_texture_id"] = LLSD.FromString(SunTexture); + globalTexturesLLSD["cloud_texture_id"] = LLSD.FromString(CloudTexture); + globalTexturesLLSD["moon_texture_id"] = LLSD.FromString(MoonTexture); + + map["global-textures"] = WrapLLSDMap(globalTexturesLLSD); + + #endregion Global Textures + + map["seed_capability"] = LLSD.FromString(seedCapability); + + // FIXME: Need a function that will convert these ArrayLists in to LLSDArrays, + // and convert the data inside them to LLSD objects as well + + //map["event_categories"] = eventCategories; + //map["event_notifications"] = new LLSDArray(); // todo + //map["classified_categories"] = classifiedCategories; + + #region UI Config + + LLSDMap uiConfigLLSD = new LLSDMap(); + uiConfigLLSD["allow_first_life"] = LLSD.FromString(allowFirstLife); + map["ui-config"] = WrapLLSDMap(uiConfigLLSD); + + #endregion UI Config + + #region Inventory + + //map["inventory-skeleton"] = agentInventory; + //map["inventory-skel-lib"] = inventoryLibrary; + //map["inventory-root"] = inventoryRoot; + //map["inventory-lib-root"] = inventoryLibRoot; + //map["inventory-lib-owner"] = inventoryLibraryOwner; + + #endregion Inventory + + map["gestures"] = new LLSDArray(); // todo + + //responseData["initial-outfit"] = initialOutfit; + //responseData["start_location"] = startLocation; + + map["seed_capability"] = LLSD.FromString(seedCapability); + map["home"] = LLSD.FromString(home); + map["look_at"] = LLSD.FromString(lookAt); + map["message"] = LLSD.FromString(welcomeMessage); + map["region_x"] = LLSD.FromInteger(RegionX * Constants.RegionSize); + map["region_y"] = LLSD.FromInteger(RegionY * Constants.RegionSize); + + map["version"] = LLSD.FromString(clientVersion); //rex + + if (m_buddyList != null) + { + //map["buddy-list"] = m_buddyList.ToArray(); + } + + map["login"] = LLSD.FromString("true"); + + return map; + } + catch (Exception e) + { + m_log.Warn("[CLIENT]: LoginResponse: Error creating XML-RPC Response: " + e.Message); + + return GenerateFailureResponseLLSD("Internal Error", "Error generating Login Response", "false"); + } + } + + private LLSDArray WrapLLSDMap(LLSDMap wrapMe) + { + LLSDArray array = new LLSDArray(); + array.Add(wrapMe); + return array; + } + + public void SetEventCategories(string category, string value) + { + // this.eventCategoriesHash[category] = value; + //TODO + } + + public void AddToUIConfig(string itemName, string item) + { + uiConfigHash[itemName] = item; + } + + public void AddClassifiedCategory(Int32 ID, string categoryName) + { + Hashtable hash = new Hashtable(); + hash["category_name"] = categoryName; + hash["category_id"] = ID; + classifiedCategories.Add(hash); + // this.classifiedCategoriesHash.Clear(); + } + + #region Properties + + public string Login + { + get { return login; } + set { login = value; } + } + + public string DST + { + get { return dst; } + set { dst = value; } + } + + public string StipendSinceLogin + { + get { return stipendSinceLogin; } + set { stipendSinceLogin = value; } + } + + public string Gendered + { + get { return gendered; } + set { gendered = value; } + } + + public string EverLoggedIn + { + get { return everLoggedIn; } + set { everLoggedIn = value; } + } + + public uint SimPort + { + get { return simPort; } + set { simPort = value; } + } + + public string SimAddress + { + get { return simAddress; } + set { simAddress = value; } + } + + public LLUUID AgentID + { + get { return agentID; } + set { agentID = value; } + } + + public LLUUID SessionID + { + get { return sessionID; } + set { sessionID = value; } + } + + public LLUUID SecureSessionID + { + get { return secureSessionID; } + set { secureSessionID = value; } + } + + public Int32 CircuitCode + { + get { return circuitCode; } + set { circuitCode = value; } + } + + public uint RegionX + { + get { return regionX; } + set { regionX = value; } + } + + public uint RegionY + { + get { return regionY; } + set { regionY = value; } + } + + public string SunTexture + { + get { return sunTexture; } + set { sunTexture = value; } + } + + public string CloudTexture + { + get { return cloudTexture; } + set { cloudTexture = value; } + } + + public string MoonTexture + { + get { return moonTexture; } + set { moonTexture = value; } + } + + public string Firstname + { + get { return firstname; } + set { firstname = value; } + } + + public string Lastname + { + get { return lastname; } + set { lastname = value; } + } + + public string ClientVersion + { + get { return clientVersion; } + set { clientVersion = value; } + } //REX ClientVersion + + public string AgentAccess + { + get { return agentAccess; } + set { agentAccess = value; } + } + + public string StartLocation + { + get { return startLocation; } + set { startLocation = value; } + } + + public string LookAt + { + get { return lookAt; } + set { lookAt = value; } + } + + public string SeedCapability + { + get { return seedCapability; } + set { seedCapability = value; } + } + + public string ErrorReason + { + get { return errorReason; } + set { errorReason = value; } + } + + public string ErrorMessage + { + get { return errorMessage; } + set { errorMessage = value; } + } + + public ArrayList InventoryRoot + { + get { return inventoryRoot; } + set { inventoryRoot = value; } + } + + public ArrayList InventorySkeleton + { + get { return agentInventory; } + set { agentInventory = value; } + } + + public ArrayList InventoryLibrary + { + get { return inventoryLibrary; } + set { inventoryLibrary = value; } + } + + public ArrayList InventoryLibraryOwner + { + get { return inventoryLibraryOwner; } + set { inventoryLibraryOwner = value; } + } + + public ArrayList InventoryLibRoot + { + get { return inventoryLibRoot; } + set { inventoryLibRoot = value; } + } + + public string Home + { + get { return home; } + set { home = value; } + } + + public string Message + { + get { return welcomeMessage; } + set { welcomeMessage = value; } + } + + public BuddyList BuddList + { + get { return m_buddyList; } + set { m_buddyList = value; } + } + + #endregion + + public class UserInfo + { + public string firstname; + public string lastname; + public ulong homeregionhandle; + public LLVector3 homepos; + public LLVector3 homelookat; + } + + public class BuddyList + { + public List Buddies = new List(); + + public void AddNewBuddy(BuddyInfo buddy) + { + if (!Buddies.Contains(buddy)) + { + Buddies.Add(buddy); + } + } + + public ArrayList ToArray() + { + ArrayList buddyArray = new ArrayList(); + foreach (BuddyInfo buddy in Buddies) + { + buddyArray.Add(buddy.ToHashTable()); + } + return buddyArray; + } + + public class BuddyInfo + { + public int BuddyRightsHave = 1; + public int BuddyRightsGiven = 1; + public LLUUID BuddyID; + + public BuddyInfo(string buddyID) + { + BuddyID = new LLUUID(buddyID); + } + + public BuddyInfo(LLUUID buddyID) + { + BuddyID = buddyID; + } + + public Hashtable ToHashTable() + { + Hashtable hTable = new Hashtable(); + hTable["buddy_rights_has"] = BuddyRightsHave; + hTable["buddy_rights_given"] = BuddyRightsGiven; + hTable["buddy_id"] = BuddyID.ToString(); + return hTable; + } + } + } + } +} diff --git a/OpenSim/Framework/Communications/LoginService.cs b/OpenSim/Framework/Communications/LoginService.cs index 237a524e48..aeffdbcdec 100644 --- a/OpenSim/Framework/Communications/LoginService.cs +++ b/OpenSim/Framework/Communications/LoginService.cs @@ -1,620 +1,882 @@ -/* -* 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.Threading; -using libsecondlife; -using libsecondlife.StructuredData; -using Nwc.XmlRpc; - -using OpenSim.Framework.Communications.Cache; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.UserManagement -{ - public class LoginService - { - protected string m_welcomeMessage = "Welcome to OpenSim"; - protected UserManagerBase m_userManager = null; - protected Mutex m_loginMutex = new Mutex(false); - protected Boolean m_rexMode; - protected RexLoginHandler m_rexLoginHandler; - - - /// - /// Used during login to send the skeleton of the OpenSim Library to the client. - /// - protected LibraryRootFolder m_libraryRootFolder; - - public LoginService( - UserManagerBase userManager, LibraryRootFolder libraryRootFolder, string welcomeMess, Boolean rexMode) - { - m_userManager = userManager; - m_libraryRootFolder = libraryRootFolder; - m_rexMode = rexMode; - m_userManager.RexMode = rexMode; - if (m_rexMode) - m_rexLoginHandler = new RexLoginHandler(this, m_userManager); - - if (welcomeMess != "") - { - m_welcomeMessage = welcomeMess; - } - } - - /// - /// Main user login function - /// - /// The XMLRPC request - /// The response to send - public XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request) - { - // Temporary fix - m_loginMutex.WaitOne(); - try - { - if (!m_rexMode) - { - //CFK: CustomizeResponse contains sufficient strings to alleviate the need for this. - //CKF: MainLog.Instance.Verbose("LOGIN", "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) - { - MainLog.Instance.Verbose( - "LOGIN", - "Could not find a profile for " + firstname + " " + lastname); - - 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) - { - userProfile.currentAgent = null; - m_userManager.CommitAgent(ref userProfile); - - // 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 = CreateInventoryData(agentID); - ArrayList AgentInventoryArray = inventData.InventoryArray; - - Hashtable InventoryRootHash = new Hashtable(); - InventoryRootHash["folder_id"] = inventData.RootFolderID.ToString(); - ArrayList InventoryRoot = new ArrayList(); - InventoryRoot.Add(InventoryRootHash); - userProfile.rootInventoryFolderID = inventData.RootFolderID; - - // Circuit Code - uint circode = (uint) (Util.RandomClass.Next()); - - //REX: Get client version - if (requestData.ContainsKey("version")) - { - logResponse.ClientVersion = (string)requestData["version"]; - } - - logResponse.Lastname = userProfile.surname; - logResponse.Firstname = userProfile.username; - logResponse.AgentID = agentID.ToString(); - logResponse.SessionID = userProfile.currentAgent.sessionID.ToString(); - logResponse.SecureSessionID = userProfile.currentAgent.secureSessionID.ToString(); - logResponse.InventoryRoot = InventoryRoot; - logResponse.InventorySkeleton = AgentInventoryArray; - logResponse.InventoryLibrary = GetInventoryLibrary(); - - Hashtable InventoryLibRootHash = new Hashtable(); - InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000"; - ArrayList InventoryLibRoot = new ArrayList(); - InventoryLibRoot.Add(InventoryLibRootHash); - logResponse.InventoryLibRoot = InventoryLibRoot; - - logResponse.InventoryLibraryOwner = 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 = GetMessage(); - logResponse.BuddList = ConvertFriendListItem(m_userManager.GetUserFriendList(agentID)); - - try - { - CustomiseResponse(logResponse, userProfile, null); - } - catch (Exception e) - { - MainLog.Instance.Verbose("LOGIN", e.ToString()); - return logResponse.CreateDeadRegionResponse(); - //return logResponse.ToXmlRpcResponse(); - } - CommitAgent(ref userProfile); - return logResponse.ToXmlRpcResponse(); - } - - catch (Exception E) - { - MainLog.Instance.Verbose("LOGIN", E.ToString()); - } - //} - } - return response; - } - else - { - return m_rexLoginHandler.XmlRpcLoginMethod(request); - } - } - finally - { - m_loginMutex.ReleaseMutex(); - } - } - - public LLSD LLSDLoginMethod(LLSD request) - { - - // Temporary fix - m_loginMutex.WaitOne(); - - try - { - if (!m_rexMode) - { - bool GoodLogin = false; - string clientVersion = "not set"; //rex - - UserProfileData userProfile = null; - LoginResponse logResponse = new LoginResponse(); - - if (request.Type == LLSDType.Map) - { - LLSDMap map = (LLSDMap)request; - - if (map.ContainsKey("first") && map.ContainsKey("last") && map.ContainsKey("passwd")) - { - string firstname = map["first"].AsString(); - string lastname = map["last"].AsString(); - string passwd = map["passwd"].AsString(); - - //REX: Client version - if (map.ContainsKey("version")) - { - clientVersion = map["version"].AsString(); - } - - userProfile = GetTheUser(firstname, lastname, ""); - if (userProfile == null) - { - MainLog.Instance.Verbose( - "LOGIN", - "Could not find a profile for " + firstname + " " + lastname); - - return logResponse.CreateLoginFailedResponseLLSD(); - } - - GoodLogin = AuthenticateUser(userProfile, passwd); - } - } - - if (!GoodLogin) - { - return logResponse.CreateLoginFailedResponseLLSD(); - } - else - { - // If we already have a session... - if (userProfile.currentAgent != null && userProfile.currentAgent.agentOnline) - { - userProfile.currentAgent = null; - m_userManager.CommitAgent(ref userProfile); - - // Reject the login - return logResponse.CreateAlreadyLoggedInResponseLLSD(); - } - - // Otherwise... - // Create a new agent session - CreateAgent(userProfile, request); - - try - { - LLUUID agentID = userProfile.UUID; - - // Inventory Library Section - InventoryData inventData = CreateInventoryData(agentID); - ArrayList AgentInventoryArray = inventData.InventoryArray; - - Hashtable InventoryRootHash = new Hashtable(); - InventoryRootHash["folder_id"] = inventData.RootFolderID.ToString(); - ArrayList InventoryRoot = new ArrayList(); - InventoryRoot.Add(InventoryRootHash); - userProfile.rootInventoryFolderID = inventData.RootFolderID; - - // Circuit Code - uint circode = (uint)(Util.RandomClass.Next()); - - // REX: Set client version - logResponse.ClientVersion = clientVersion; - - logResponse.Lastname = userProfile.surname; - logResponse.Firstname = userProfile.username; - logResponse.AgentID = agentID.ToString(); - logResponse.SessionID = userProfile.currentAgent.sessionID.ToString(); - logResponse.SecureSessionID = userProfile.currentAgent.secureSessionID.ToString(); - logResponse.InventoryRoot = InventoryRoot; - logResponse.InventorySkeleton = AgentInventoryArray; - logResponse.InventoryLibrary = GetInventoryLibrary(); - - Hashtable InventoryLibRootHash = new Hashtable(); - InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000"; - ArrayList InventoryLibRoot = new ArrayList(); - InventoryLibRoot.Add(InventoryLibRootHash); - logResponse.InventoryLibRoot = InventoryLibRoot; - - logResponse.InventoryLibraryOwner = 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 = GetMessage(); - logResponse.BuddList = ConvertFriendListItem(m_userManager.GetUserFriendList(agentID)); - - try - { - CustomiseResponse(logResponse, userProfile, null); - } - catch (Exception ex) - { - MainLog.Instance.Verbose("LOGIN", ex.ToString()); - return logResponse.CreateDeadRegionResponseLLSD(); - } - - CommitAgent(ref userProfile); - - return logResponse.ToLLSDResponse(); - } - catch (Exception ex) - { - MainLog.Instance.Verbose("LOGIN", ex.ToString()); - return logResponse.CreateFailedResponseLLSD(); - } - } - } - else - { - return m_rexLoginHandler.LLSDLoginMethod(request); - } - - } - finally - { - m_loginMutex.ReleaseMutex(); - } - } - - /* - /// - /// Remove agent - /// - /// The XMLRPC request - /// The response to send - public XmlRpcResponse XmlRpcRemoveAgentMethod(XmlRpcRequest request) - { - // Temporary fix - m_loginMutex.WaitOne(); - try - { - MainLog.Instance.Verbose("REMOVE AGENT", "Attempting to remove agent..."); - XmlRpcResponse response = new XmlRpcResponse(); - Hashtable requestData = (Hashtable)request.Params[0]; - - bool parametersValid = (requestData.Contains("agentID")); - - UserProfileData user; - LoginResponse logResponse = new LoginResponse(); - - if (parametersValid) - { - string agentID = (string)requestData["agentID"]; - user = GetTheUser((libsecondlife.LLUUID)agentID); - - if (user == null) - { - MainLog.Instance.Verbose("REMOVE AGENT", "Failed. UserProfile not found."); - return logResponse.CreateAgentRemoveFailedResponse(); - } - - if (user != null) - { - ClearUserAgent(ref user, user.authenticationAddr); - MainLog.Instance.Verbose("REMOVE AGENT", "Success. Agent removed from database. UUID = " + user.UUID); - return logResponse.GenerateAgentRemoveSuccessResponse(); - - } - } - - MainLog.Instance.Verbose("REMOVE AGENT", "Failed. Parameters invalid."); - return logResponse.CreateAgentRemoveFailedResponse(); - - } - finally - { - m_loginMutex.ReleaseMutex(); - } - - return null; - - }//*/ - - public void ClearUserAgent(ref UserProfileData profile, string authAddr) - { - m_userManager.clearUserAgent(profile.UUID, authAddr); - - } - - - /// - /// Customises the login response and fills in missing values. - /// - /// The existing response - /// The user profile - public virtual void CustomiseResponse(LoginResponse response, UserProfileData theUser, string ASaddress) - { - } - - /// - /// Saves a target agent to the database - /// - /// The users profile - /// Successful? - public void UpdateAgent(UserAgentData agent, string authAddr) - { - // Saves the agent to database - //return true; - m_userManager.UpdateUserAgentData(agent.UUID, agent.agentOnline, agent.currentPos, agent.logoutTime, authAddr); - } - - - /// - /// Saves a target agent to the database - /// - /// The users profile - /// Successful? - public bool CommitAgent(ref UserProfileData profile) - { - return m_userManager.CommitAgent(ref profile); - } - - - /// - /// 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( - "LOGIN", "Authenticating {0} {1} ({2})", profile.username, profile.surname, profile.UUID); - - 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) - { - m_userManager.CreateAgent(profile, request); - } - - public void CreateAgent(UserProfileData profile, LLSD request) - { - m_userManager.CreateAgent(profile, request); - } - - /// - /// - /// - /// - /// - /// - public virtual UserProfileData GetTheUser(string firstname, string lastname, string authAddr) - { - return m_userManager.GetUserProfile(firstname, lastname, authAddr); - } - - /// - /// Get user according to uid - /// - /// - /// - public virtual UserProfileData GetTheUser(LLUUID userUID) - { - return this.m_userManager.GetUserProfile(userUID, ""); - } - - /// - /// Get user according to account - /// - /// - /// - public virtual UserProfileData GetTheUserByAccount(string account) - { - return this.m_userManager.GetUserProfileByAccount(account); - } - - /// - /// - /// - /// - public virtual string GetMessage() - { - return m_welcomeMessage; - } - - private LoginResponse.BuddyList ConvertFriendListItem(List LFL) - { - LoginResponse.BuddyList buddylistreturn = new LoginResponse.BuddyList(); - foreach (FriendListItem fl in LFL) - { - LoginResponse.BuddyList.BuddyInfo buddyitem = new LoginResponse.BuddyList.BuddyInfo(fl.Friend); - buddyitem.BuddyID = fl.Friend; - buddyitem.BuddyRightsHave = (int)fl.FriendListOwnerPerms; - buddyitem.BuddyRightsGiven = (int) fl.FriendPerms; - buddylistreturn.AddNewBuddy(buddyitem); - - } - return buddylistreturn; - } - - /// - /// Converts the inventory library skeleton into the form required by the rpc request. - /// - /// - protected internal virtual ArrayList GetInventoryLibrary() - { - Dictionary rootFolders - = m_libraryRootFolder.RequestSelfAndDescendentFolders(); - 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.folderID.ToString(); - folderHashes.Add(TempHash); - } - - return folderHashes; - } - - /// - /// - /// - /// - protected internal 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 internal 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.ToString(); - TempHash["version"] = (Int32) InvFolder.Version; - TempHash["type_default"] = (Int32) InvFolder.DefaultType; - TempHash["folder_id"] = InvFolder.FolderID.ToString(); - 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; - } - } - } -} +/* +* 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.IO; +using System.Text.RegularExpressions; +using System.Threading; +using libsecondlife; +using libsecondlife.StructuredData; +using Nwc.XmlRpc; + +using OpenSim.Framework.Communications.Cache; +using OpenSim.Framework.Console; +using OpenSim.Framework.Statistics; + +namespace OpenSim.Framework.UserManagement +{ + public class LoginService + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + protected string m_welcomeMessage = "Welcome to OpenSim"; + protected UserManagerBase m_userManager = null; + protected Mutex m_loginMutex = new Mutex(false); + protected Boolean m_rexMode; + protected RexLoginHandler m_rexLoginHandler; + + + /// + /// Used during login to send the skeleton of the OpenSim Library to the client. + /// + protected LibraryRootFolder m_libraryRootFolder; + + public LoginService( + UserManagerBase userManager, LibraryRootFolder libraryRootFolder, string welcomeMess, Boolean rexMode) + { + m_userManager = userManager; + m_libraryRootFolder = libraryRootFolder; + m_rexMode = rexMode; + m_userManager.RexMode = rexMode; + if (m_rexMode) + m_rexLoginHandler = new RexLoginHandler(this, m_userManager); + + if (welcomeMess != String.Empty) + { + m_welcomeMessage = welcomeMess; + } + } + + /// + /// Main user login function + /// + /// The XMLRPC request + /// The response to send + public XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request) + { + // Temporary fix + m_loginMutex.WaitOne(); + try + { + //CFK: CustomizeResponse contains sufficient strings to alleviate the need for this. + //CKF: m_log.Info("[LOGIN]: Attempting login now..."); + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable requestData = (Hashtable) request.Params[0]; + + bool GoodXML = (requestData.Contains("first") && requestData.Contains("last") && + (requestData.Contains("passwd") || requestData.Contains("web_login_key"))); + bool GoodLogin = false; + + UserProfileData userProfile; + LoginResponse logResponse = new LoginResponse(); + + if (GoodXML) + { + string firstname = (string) requestData["first"]; + string lastname = (string) requestData["last"]; + + if( requestData.Contains("version")) + { + string clientversion = (string)requestData["version"]; + m_log.Info("[LOGIN]: Client Version " + clientversion + " for " + firstname + " " + lastname); + } + + + userProfile = GetTheUser(firstname, lastname); + if (userProfile == null) + { + m_log.Info("[LOGIN]: Could not find a profile for " + firstname + " " + lastname); + + if (!GoodLogin) + { + return logResponse.CreateLoginFailedResponse(); + } + if (requestData.Contains("passwd")) + { + string passwd = (string)requestData["passwd"]; + GoodLogin = AuthenticateUser(userProfile, passwd); + } + else if (requestData.Contains("web_login_key")) + { + LLUUID webloginkey = null; + try + { + webloginkey = new LLUUID((string)requestData["web_login_key"]); + } + catch (System.Exception) + { + return logResponse.CreateFailedResponse(); + } + GoodLogin = AuthenticateUser(userProfile, webloginkey); + + } + else + { + return logResponse.CreateFailedResponse(); + } + } + else + { + return logResponse.CreateGridErrorResponse(); + } + + // 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 = CreateInventoryData(agentID); + ArrayList AgentInventoryArray = inventData.InventoryArray; + + Hashtable InventoryRootHash = new Hashtable(); + InventoryRootHash["folder_id"] = inventData.RootFolderID.ToString(); + ArrayList InventoryRoot = new ArrayList(); + InventoryRoot.Add(InventoryRootHash); + userProfile.rootInventoryFolderID = inventData.RootFolderID; + + // Circuit Code + uint circode = (uint) (Util.RandomClass.Next()); + + //REX: Get client version + if (requestData.ContainsKey("version")) + { + logResponse.ClientVersion = (string)requestData["version"]; + } + + logResponse.Lastname = userProfile.surname; + logResponse.Firstname = userProfile.username; + logResponse.AgentID = agentID.ToString(); + logResponse.SessionID = userProfile.currentAgent.sessionID.ToString(); + logResponse.SecureSessionID = userProfile.currentAgent.secureSessionID.ToString(); + logResponse.InventoryRoot = InventoryRoot; + logResponse.InventorySkeleton = AgentInventoryArray; + logResponse.InventoryLibrary = GetInventoryLibrary(); + + Hashtable InventoryLibRootHash = new Hashtable(); + InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000"; + ArrayList InventoryLibRoot = new ArrayList(); + InventoryLibRoot.Add(InventoryLibRootHash); + logResponse.InventoryLibRoot = InventoryLibRoot; + + logResponse.InventoryLibraryOwner = 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 = GetMessage(); + logResponse.BuddList = ConvertFriendListItem(m_userManager.GetUserFriendList(agentID)); + + try + { + CustomiseResponse(logResponse, userProfile, null); + } + catch (Exception e) + { + MainLog.Instance.Verbose("LOGIN", e.ToString()); + return logResponse.CreateDeadRegionResponse(); + //return logResponse.ToXmlRpcResponse(); + } + CommitAgent(ref userProfile); + return logResponse.ToXmlRpcResponse(); + } + + catch (Exception E) + { + MainLog.Instance.Verbose("LOGIN", E.ToString()); + } + catch (Exception e) + { + m_log.Info("[LOGIN]: " + e.ToString()); + return logResponse.CreateDeadRegionResponse(); + //return logResponse.ToXmlRpcResponse(); + } + CommitAgent(ref userProfile); + + // If we reach this point, then the login has successfully logged onto the grid + if (StatsManager.UserStats != null) + StatsManager.UserStats.AddSuccessfulLogin(); + + return logResponse.ToXmlRpcResponse(); + } + catch (Exception e) + { + m_log.Info("[LOGIN]: " + e.ToString()); + } + //} + } + else + { + return m_rexLoginHandler.XmlRpcLoginMethod(request); + } + } + finally + { + m_loginMutex.ReleaseMutex(); + } + } + + public LLSD LLSDLoginMethod(LLSD request) + { + + // Temporary fix + m_loginMutex.WaitOne(); + + try + { + if (!m_rexMode) + { + bool GoodLogin = false; + string clientVersion = "not set"; //rex + + UserProfileData userProfile = null; + LoginResponse logResponse = new LoginResponse(); + + if (request.Type == LLSDType.Map) + { + LLSDMap map = (LLSDMap)request; + + if (map.ContainsKey("first") && map.ContainsKey("last") && map.ContainsKey("passwd")) + { + m_log.Info("[LOGIN]: Could not find a profile for " + firstname + " " + lastname); + + //REX: Client version + if (map.ContainsKey("version")) + { + clientVersion = map["version"].AsString(); + } + + userProfile = GetTheUser(firstname, lastname, ""); + if (userProfile == null) + { + MainLog.Instance.Verbose( + "LOGIN", + "Could not find a profile for " + firstname + " " + lastname); + + return logResponse.CreateLoginFailedResponseLLSD(); + } + + GoodLogin = AuthenticateUser(userProfile, passwd); + } + } + + if (!GoodLogin) + { + return logResponse.CreateLoginFailedResponseLLSD(); + } + else + { + // If we already have a session... + if (userProfile.currentAgent != null && userProfile.currentAgent.agentOnline) + { + userProfile.currentAgent = null; + m_userManager.CommitAgent(ref userProfile); + + // Reject the login + return logResponse.CreateAlreadyLoggedInResponseLLSD(); + } + + // Otherwise... + // Create a new agent session + CreateAgent(userProfile, request); + + try + { + LLUUID agentID = userProfile.UUID; + + // Inventory Library Section + InventoryData inventData = CreateInventoryData(agentID); + ArrayList AgentInventoryArray = inventData.InventoryArray; + + Hashtable InventoryRootHash = new Hashtable(); + InventoryRootHash["folder_id"] = inventData.RootFolderID.ToString(); + ArrayList InventoryRoot = new ArrayList(); + InventoryRoot.Add(InventoryRootHash); + userProfile.rootInventoryFolderID = inventData.RootFolderID; + + // Circuit Code + uint circode = (uint)(Util.RandomClass.Next()); + + // REX: Set client version + logResponse.ClientVersion = clientVersion; + + logResponse.Lastname = userProfile.surname; + logResponse.Firstname = userProfile.username; + logResponse.AgentID = agentID.ToString(); + logResponse.SessionID = userProfile.currentAgent.sessionID.ToString(); + logResponse.SecureSessionID = userProfile.currentAgent.secureSessionID.ToString(); + logResponse.InventoryRoot = InventoryRoot; + logResponse.InventorySkeleton = AgentInventoryArray; + logResponse.InventoryLibrary = GetInventoryLibrary(); + + Hashtable InventoryLibRootHash = new Hashtable(); + InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000"; + ArrayList InventoryLibRoot = new ArrayList(); + InventoryLibRoot.Add(InventoryLibRootHash); + logResponse.InventoryLibRoot = InventoryLibRoot; + + logResponse.InventoryLibraryOwner = 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 = GetMessage(); + logResponse.BuddList = ConvertFriendListItem(m_userManager.GetUserFriendList(agentID)); + + try + { + CustomiseResponse(logResponse, userProfile, null); + } + catch (Exception ex) + { + MainLog.Instance.Verbose("LOGIN", ex.ToString()); + return logResponse.CreateDeadRegionResponseLLSD(); + } + + CommitAgent(ref userProfile); + + return logResponse.ToLLSDResponse(); + } + catch (Exception ex) + { + m_log.Info("[LOGIN]: " + ex.ToString()); + return logResponse.CreateFailedResponseLLSD(); + } + } + } + else + { + return m_rexLoginHandler.LLSDLoginMethod(request); + } + + } + finally + { + m_loginMutex.ReleaseMutex(); + } + } + + // If we reach this point, then the login has successfully logged onto the grid + if (StatsManager.UserStats != null) + StatsManager.UserStats.AddSuccessfulLogin(); + + /* + /// + /// Remove agent + /// + /// The XMLRPC request + /// The response to send + public XmlRpcResponse XmlRpcRemoveAgentMethod(XmlRpcRequest request) + { + // Temporary fix + m_loginMutex.WaitOne(); + try + { + MainLog.Instance.Verbose("REMOVE AGENT", "Attempting to remove agent..."); + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable requestData = (Hashtable)request.Params[0]; + + bool parametersValid = (requestData.Contains("agentID")); + + UserProfileData user; + LoginResponse logResponse = new LoginResponse(); + + if (parametersValid) + { + string agentID = (string)requestData["agentID"]; + user = GetTheUser((libsecondlife.LLUUID)agentID); + + if (user == null) + { + MainLog.Instance.Verbose("REMOVE AGENT", "Failed. UserProfile not found."); + return logResponse.CreateAgentRemoveFailedResponse(); + } + + if (user != null) + { + m_log.Info("[LOGIN]: " + ex.ToString()); + return logResponse.CreateFailedResponseLLSD(); + } + } + + MainLog.Instance.Verbose("REMOVE AGENT", "Failed. Parameters invalid."); + return logResponse.CreateAgentRemoveFailedResponse(); + + } + finally + { + m_loginMutex.ReleaseMutex(); + } + + return null; + + }//*/ + + public void ClearUserAgent(ref UserProfileData profile, string authAddr) + { + m_userManager.clearUserAgent(profile.UUID, authAddr); + + } + + + /// + /// Customises the login response and fills in missing values. + /// + /// The existing response + /// The user profile + public virtual void CustomiseResponse(LoginResponse response, UserProfileData theUser, string ASaddress) + { + } + + public Hashtable ProcessHTMLLogin(Hashtable keysvals) + { + + // Matches all unspecified characters + // Currently specified,; lowercase letters, upper case letters, numbers, underline + // period, space, parens, and dash. + + Regex wfcut = new Regex("[^a-zA-Z0-9_\\.\\$ \\(\\)\\-]"); + + Hashtable returnactions = new Hashtable(); + int statuscode = 200; + + string firstname = String.Empty; + string lastname = String.Empty; + string location = String.Empty; + string region =String.Empty; + string grid = String.Empty; + string channel = String.Empty; + string version = String.Empty; + string lang = String.Empty; + string password = String.Empty; + string errormessages = String.Empty; + + // the client requires the HTML form field be named 'username' + // however, the data it sends when it loads the first time is 'firstname' + // another one of those little nuances. + + + if (keysvals.Contains("firstname")) + firstname = wfcut.Replace((string)keysvals["firstname"],String.Empty,99999); + if (keysvals.Contains("username")) + firstname = wfcut.Replace((string)keysvals["username"],String.Empty,99999); + + if (keysvals.Contains("lastname")) + lastname = wfcut.Replace((string)keysvals["lastname"],String.Empty,99999); + + if (keysvals.Contains("location")) + location = wfcut.Replace((string)keysvals["location"],String.Empty,99999); + + if (keysvals.Contains("region")) + region = wfcut.Replace((string)keysvals["region"],String.Empty,99999); + + if (keysvals.Contains("grid")) + grid = wfcut.Replace((string)keysvals["grid"],String.Empty,99999); + + if (keysvals.Contains("channel")) + channel = wfcut.Replace((string)keysvals["channel"],String.Empty,99999); + + if (keysvals.Contains("version")) + version = wfcut.Replace((string)keysvals["version"],String.Empty,99999); + + if (keysvals.Contains("lang")) + lang = wfcut.Replace((string)keysvals["lang"],String.Empty,99999); + + if (keysvals.Contains("password")) + password = wfcut.Replace((string)keysvals["password"], String.Empty, 99999); + + + // load our login form. + string loginform = GetLoginForm(firstname,lastname,location,region,grid,channel,version,lang,password,errormessages); + + if (keysvals.ContainsKey("show_login_form")) + { + + UserProfileData user = GetTheUser(firstname, lastname); + bool goodweblogin = false; + + if (user != null) + goodweblogin = AuthenticateUser(user, password); + + if (goodweblogin) + { + LLUUID webloginkey = LLUUID.Random(); + m_userManager.StoreWebLoginKey(user.UUID, webloginkey); + statuscode = 301; + + string redirectURL = "about:blank?redirect-http-hack=" + System.Web.HttpUtility.UrlEncode("secondlife:///app/login?first_name=" + firstname + "&last_name=" + + lastname + + "&location=" + location + "&grid=Other&web_login_key=" + webloginkey.ToString()); + //m_log.Info("[WEB]: R:" + redirectURL); + returnactions["int_response_code"] = statuscode; + returnactions["str_redirect_location"] = redirectURL; + returnactions["str_response_string"] = "GoodLogin"; + } + else + { + errormessages = "The Username and password supplied did not match our records. Check your caps lock and try again"; + + loginform = GetLoginForm(firstname, lastname, location, region, grid, channel, version, lang, password, errormessages); + returnactions["int_response_code"] = statuscode; + returnactions["str_response_string"] = loginform; + + } + + + + } + else + { + returnactions["int_response_code"] = statuscode; + returnactions["str_response_string"] = loginform; + } + return returnactions; + + } + + public string GetLoginForm(string firstname, string lastname, string location, string region, + string grid, string channel, string version, string lang, + string password, string errormessages) + { + // inject our values in the form at the markers + + string loginform=String.Empty; + string file = Path.Combine(Util.configDir(), "http_loginform.html"); + if (!File.Exists(file)) + { + loginform = GetDefaultLoginForm(); + } + else + { + StreamReader sr = File.OpenText(file); + loginform = sr.ReadToEnd(); + sr.Close(); + } + + loginform = loginform.Replace("[$firstname]", firstname); + loginform = loginform.Replace("[$lastname]", lastname); + loginform = loginform.Replace("[$location]", location); + loginform = loginform.Replace("[$region]", region); + loginform = loginform.Replace("[$grid]", grid); + loginform = loginform.Replace("[$channel]", channel); + loginform = loginform.Replace("[$version]", version); + loginform = loginform.Replace("[$lang]", lang); + loginform = loginform.Replace("[$password]", password); + loginform = loginform.Replace("[$errors]", errormessages); + return loginform; + } + + public string GetDefaultLoginForm() + { + string responseString = + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + "OpenSim Login"; + responseString = responseString + "
"; + responseString = responseString + "
"; + + responseString = responseString + "
"; + + responseString = responseString + "
[$errors]
"; + responseString = responseString + "
"; + responseString = responseString + "First Name:"; + responseString = responseString + ""; + responseString = responseString + "
"; + responseString = responseString + "
"; + responseString = responseString + "Last Name:"; + responseString = responseString + ""; + responseString = responseString + "
"; + responseString = responseString + "
"; + responseString = responseString + "Password:"; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + "
"; + responseString = responseString + "
"; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + "
"; + responseString = responseString + ""; + responseString = responseString + "
"; + responseString = responseString + "
Connecting...
"; + + responseString = responseString + "
"; + responseString = responseString + " | "; + responseString = responseString + ""; + responseString = responseString + "
"; + + responseString = responseString + "
[$channel] | [$version]=[$lang]
"; + responseString = responseString + "
"; + responseString = responseString + ""; + responseString = responseString + "
"; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + ""; + return responseString; + } + + /// + /// Saves a target agent to the database + /// + /// The users profile + /// Successful? + public void UpdateAgent(UserAgentData agent, string authAddr) + { + // Saves the agent to database + //return true; + m_userManager.UpdateUserAgentData(agent.UUID, agent.agentOnline, agent.currentPos, agent.logoutTime, authAddr); + } + + + /// + /// Saves a target agent to the database + /// + /// The users profile + /// Successful? + public bool CommitAgent(ref UserProfileData profile) + { + return m_userManager.CommitAgent(ref profile); + } + + + /// + /// Checks a user against it's password hash + /// + /// The users profile + /// The supplied password + /// Authenticated? + public virtual bool AuthenticateUser(UserProfileData profile, string password) + { + bool passwordSuccess = false; + m_log.InfoFormat("[LOGIN]: Authenticating {0} {1} ({2})", profile.username, profile.surname, profile.UUID); + + // Web Login method seems to also occasionally send the hashed password itself + + // we do this to get our hash in a form that the server password code can consume + // when the web-login-form submits the password in the clear (supposed to be over SSL!) + if (!password.StartsWith("$1$")) + password = "$1$" + Util.Md5Hash(password); + + password = password.Remove(0, 3); //remove $1$ + + string s = Util.Md5Hash(password + ":" + profile.passwordSalt); + // Testing... + //m_log.Info("[LOGIN]: SubHash:" + s + " userprofile:" + profile.passwordHash); + //m_log.Info("[LOGIN]: userprofile:" + profile.passwordHash + " SubCT:" + password); + + passwordSuccess = (profile.passwordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase) + || profile.passwordHash.Equals(password,StringComparison.InvariantCultureIgnoreCase)); + + return passwordSuccess; + } + + public virtual bool AuthenticateUser(UserProfileData profile, LLUUID webloginkey) + { + bool passwordSuccess = false; + m_log.InfoFormat("[LOGIN]: Authenticating {0} {1} ({2})", profile.username, profile.surname, profile.UUID); + + // Match web login key unless it's the default weblogin key LLUUID.Zero + passwordSuccess = ((profile.webLoginKey==webloginkey) && profile.webLoginKey != LLUUID.Zero); + + return passwordSuccess; + } + + /// + /// + /// + /// + /// + public void CreateAgent(UserProfileData profile, XmlRpcRequest request) + { + m_userManager.CreateAgent(profile, request); + } + + public void CreateAgent(UserProfileData profile, LLSD request) + { + m_userManager.CreateAgent(profile, request); + } + + /// + /// + /// + /// + /// + /// + public virtual UserProfileData GetTheUser(string firstname, string lastname, string authAddr) + { + return m_userManager.GetUserProfile(firstname, lastname, authAddr); + } + + /// + /// Get user according to uid + /// + /// + /// + public virtual UserProfileData GetTheUser(LLUUID userUID) + { + return this.m_userManager.GetUserProfile(userUID, ""); + } + + /// + /// Get user according to account + /// + /// + /// + public virtual UserProfileData GetTheUserByAccount(string account) + { + return this.m_userManager.GetUserProfileByAccount(account); + } + + /// + /// + /// + /// + public virtual string GetMessage() + { + return m_welcomeMessage; + } + + private LoginResponse.BuddyList ConvertFriendListItem(List LFL) + { + LoginResponse.BuddyList buddylistreturn = new LoginResponse.BuddyList(); + foreach (FriendListItem fl in LFL) + { + LoginResponse.BuddyList.BuddyInfo buddyitem = new LoginResponse.BuddyList.BuddyInfo(fl.Friend); + buddyitem.BuddyID = fl.Friend; + buddyitem.BuddyRightsHave = (int)fl.FriendListOwnerPerms; + buddyitem.BuddyRightsGiven = (int) fl.FriendPerms; + buddylistreturn.AddNewBuddy(buddyitem); + + } + return buddylistreturn; + } + + /// + /// Converts the inventory library skeleton into the form required by the rpc request. + /// + /// + protected internal virtual ArrayList GetInventoryLibrary() + { + Dictionary rootFolders + = m_libraryRootFolder.RequestSelfAndDescendentFolders(); + 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.folderID.ToString(); + folderHashes.Add(TempHash); + } + + return folderHashes; + } + + /// + /// + /// + /// + protected internal 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 internal 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.ToString(); + TempHash["version"] = (Int32) InvFolder.Version; + TempHash["type_default"] = (Int32) InvFolder.DefaultType; + TempHash["folder_id"] = InvFolder.FolderID.ToString(); + 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/Properties/AssemblyInfo.cs b/OpenSim/Framework/Communications/Properties/AssemblyInfo.cs index 3d9c8c10ff..e865cda6e5 100644 --- a/OpenSim/Framework/Communications/Properties/AssemblyInfo.cs +++ b/OpenSim/Framework/Communications/Properties/AssemblyInfo.cs @@ -1,65 +1,65 @@ -/* -* 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.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. - -[assembly : AssemblyTitle("OpenGrid.Framework.Communications")] -[assembly : AssemblyDescription("")] -[assembly : AssemblyConfiguration("")] -[assembly : AssemblyCompany("")] -[assembly : AssemblyProduct("OpenGrid.Framework.Communications")] -[assembly : AssemblyCopyright("Copyright © 2007")] -[assembly : AssemblyTrademark("")] -[assembly : AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. - -[assembly : ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM - -[assembly : Guid("13e7c396-78a9-4a5c-baf2-6f980ea75d95")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: - -[assembly : AssemblyVersion("1.0.0.0")] -[assembly : AssemblyFileVersion("1.0.0.0")] \ No newline at end of file +/* +* 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.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. + +[assembly : AssemblyTitle("OpenGrid.Framework.Communications")] +[assembly : AssemblyDescription("")] +[assembly : AssemblyConfiguration("")] +[assembly : AssemblyCompany("")] +[assembly : AssemblyProduct("OpenGrid.Framework.Communications")] +[assembly : AssemblyCopyright("Copyright © OpenSimulator.org Developers 2007-2008")] +[assembly : AssemblyTrademark("")] +[assembly : AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. + +[assembly : ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM + +[assembly : Guid("13e7c396-78a9-4a5c-baf2-6f980ea75d95")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly : AssemblyVersion("1.0.0.0")] +[assembly : AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/Communications/RestClient/RestClient.cs b/OpenSim/Framework/Communications/RestClient/RestClient.cs index e6ff30f2f7..4e1b1b0321 100644 --- a/OpenSim/Framework/Communications/RestClient/RestClient.cs +++ b/OpenSim/Framework/Communications/RestClient/RestClient.cs @@ -1,443 +1,446 @@ -/* -* 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.Generic; -using System.IO; -using System.Net; -using System.Text; -using System.Threading; -using System.Web; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.Communications -{ - /// - /// Implementation of a generic REST client - /// - /// - /// This class is a generic implementation of a REST (Representational State Transfer) web service. This - /// class is designed to execute both synchroneously and asynchroneously. - /// - /// Internally the implementation works as a two stage asynchroneous web-client. - /// When the request is initiated, RestClient will query asynchroneously for for a web-response, - /// sleeping until the initial response is returned by the server. Once the initial response is retrieved - /// the second stage of asynchroneous requests will be triggered, in an attempt to read of the response - /// object into a memorystream as a sequence of asynchroneous reads. - /// - /// The asynchronisity of RestClient is designed to move as much processing into the back-ground, allowing - /// other threads to execute, while it waits for a response from the web-service. RestClient it self, can be - /// invoked by the caller in either synchroneous mode or asynchroneous mode. - /// - public class RestClient - { - private string realuri; - - #region member variables - - /// - /// The base Uri of the web-service e.g. http://www.google.com - /// - private string _url; - - /// - /// Path elements of the query - /// - private List _pathElements = new List(); - - /// - /// Parameter elements of the query, e.g. min=34 - /// - private Dictionary _parameterElements = new Dictionary(); - - /// - /// Request method. E.g. GET, POST, PUT or DELETE - /// - private string _method; - - /// - /// Temporary buffer used to store bytes temporarily as they come in from the server - /// - private byte[] _readbuf; - - /// - /// MemoryStream representing the resultiong resource - /// - private Stream _resource; - - /// - /// WebRequest object, held as a member variable - /// - private HttpWebRequest _request; - - /// - /// WebResponse object, held as a member variable, so we can close it - /// - private HttpWebResponse _response; - - /// - /// This flag will help block the main synchroneous method, in case we run in synchroneous mode - /// - public static ManualResetEvent _allDone = new ManualResetEvent(false); - - /// - /// Default time out period - /// - private const int DefaultTimeout = 10*1000; // 10 seconds timeout - - /// - /// Default Buffer size of a block requested from the web-server - /// - private const int BufferSize = 4096; // Read blocks of 4 KB. - - - /// - /// if an exception occours during async processing, we need to save it, so it can be - /// rethrown on the primary thread; - /// - private Exception _asyncException; - - #endregion member variables - - #region constructors - - /// - /// Instantiate a new RestClient - /// - /// Web-service to query, e.g. http://osgrid.org:8003 - public RestClient(string url) - { - _url = url; - _readbuf = new byte[BufferSize]; - _resource = new MemoryStream(); - _request = null; - _response = null; - _lock = new object(); - } - - private object _lock; - - #endregion constructors - - /// - /// Add a path element to the query, e.g. assets - /// - /// path entry - public void AddResourcePath(string element) - { - if (isSlashed(element)) - _pathElements.Add(element.Substring(0, element.Length - 1)); - else - _pathElements.Add(element); - } - - /// - /// Add a query parameter to the Url - /// - /// Name of the parameter, e.g. min - /// Value of the parameter, e.g. 42 - public void AddQueryParameter(string name, string value) - { - _parameterElements.Add(HttpUtility.UrlEncode(name), HttpUtility.UrlEncode(value)); - } - - /// - /// Add a query parameter to the Url - /// - /// Name of the parameter, e.g. min - public void AddQueryParameter(string name) - { - _parameterElements.Add(HttpUtility.UrlEncode(name), null); - } - - /// - /// Web-Request method, e.g. GET, PUT, POST, DELETE - /// - public string RequestMethod - { - get { return _method; } - set { _method = value; } - } - - /// - /// True if string contains a trailing slash '/' - /// - /// string to be examined - /// true if slash is present - private bool isSlashed(string s) - { - return s.Substring(s.Length - 1, 1) == "/"; - } - - /// - /// return a slash or blank. A slash will be returned if the string does not contain one - /// - /// stromg to be examined - /// slash '/' if not already present - private string slash(string s) - { - return isSlashed(s) ? "" : "/"; - } - - /// - /// Build a Uri based on the initial Url, path elements and parameters - /// - /// fully constructed Uri - private Uri buildUri() - { - StringBuilder sb = new StringBuilder(); - sb.Append(_url); - - foreach (string e in _pathElements) - { - sb.Append("/"); - sb.Append(e); - } - - bool firstElement = true; - foreach (KeyValuePair kv in _parameterElements) - { - if (firstElement) - { - sb.Append("?"); - firstElement = false; - } - else - sb.Append("&"); - - sb.Append(kv.Key); - if (kv.Value != null && kv.Value.Length != 0) - { - sb.Append("="); - sb.Append(kv.Value); - } - } - realuri = sb.ToString(); - MainLog.Instance.Verbose("REST", "RestURL: {0}", realuri); - return new Uri(sb.ToString()); - } - - #region Async communications with server - - /// - /// Async method, invoked when a block of data has been received from the service - /// - /// - private void StreamIsReadyDelegate(IAsyncResult ar) - { - try - { - Stream s = (Stream) ar.AsyncState; - int read = s.EndRead(ar); - - if (read > 0) - { - _resource.Write(_readbuf, 0, read); - IAsyncResult asynchronousResult = - s.BeginRead(_readbuf, 0, BufferSize, new AsyncCallback(StreamIsReadyDelegate), s); - - // TODO! Implement timeout, without killing the server - //ThreadPool.RegisterWaitForSingleObject(asynchronousResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true); - } - else - { - s.Close(); - _allDone.Set(); - } - } - catch (Exception e) - { - _allDone.Set(); - _asyncException = e; - } - } - - /// - /// Async method, invoked when the initial response if received from the server - /// - /// - private void ResponseIsReadyDelegate(IAsyncResult ar) - { - try - { - // grab response - WebRequest wr = (WebRequest) ar.AsyncState; - _response = (HttpWebResponse) wr.EndGetResponse(ar); - - // get response stream, and setup async reading - Stream s = _response.GetResponseStream(); - IAsyncResult asynchronousResult = - s.BeginRead(_readbuf, 0, BufferSize, new AsyncCallback(StreamIsReadyDelegate), s); - - // TODO! Implement timeout, without killing the server - // wait until completed, or we timed out - // ThreadPool.RegisterWaitForSingleObject(asynchronousResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true); - } - catch (Exception e) - { - _allDone.Set(); - _asyncException = e; - } - } - - // Abort the request if the timer fires. - private static void TimeoutCallback(object state, bool timedOut) - { - if (timedOut) - { - HttpWebRequest request = state as HttpWebRequest; - if (request != null) - { - request.Abort(); - } - } - } - - #endregion Async communications with server - - /// - /// Perform synchroneous request - /// - public Stream Request() - { - lock (_lock) - { - _request = (HttpWebRequest) WebRequest.Create(buildUri()); - _request.KeepAlive = false; - _request.ContentType = "application/xml"; - _request.Timeout = 200000; - _asyncException = null; - -// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request); - _response = (HttpWebResponse) _request.GetResponse(); - Stream src = _response.GetResponseStream(); - int length = src.Read(_readbuf, 0, BufferSize); - while (length > 0) - { - _resource.Write(_readbuf, 0, length); - length = src.Read(_readbuf, 0, BufferSize); - } - - - // TODO! Implement timeout, without killing the server - // this line implements the timeout, if there is a timeout, the callback fires and the request becomes aborted - //ThreadPool.RegisterWaitForSingleObject(responseAsyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true); - -// _allDone.WaitOne(); - if (_response != null) - _response.Close(); - if (_asyncException != null) - throw _asyncException; - - if (_resource != null) - { - _resource.Flush(); - _resource.Seek(0, SeekOrigin.Begin); - } - - return _resource; - } - } - - public Stream Request(Stream src) - { - _request = (HttpWebRequest) WebRequest.Create(buildUri()); - _request.KeepAlive = false; - _request.ContentType = "application/xml"; - _request.Timeout = 900000; - _request.Method = RequestMethod; - _asyncException = null; - _request.ContentLength = src.Length; - - MainLog.Instance.Verbose("REST", "Request Length {0}", _request.ContentLength); - MainLog.Instance.Verbose("REST", "Sending Web Request {0}", buildUri()); - src.Seek(0, SeekOrigin.Begin); - MainLog.Instance.Verbose("REST", "Seek is ok"); - Stream dst = _request.GetRequestStream(); - MainLog.Instance.Verbose("REST", "GetRequestStream is ok"); - - byte[] buf = new byte[1024]; - int length = src.Read(buf, 0, 1024); - MainLog.Instance.Verbose("REST", "First Read is ok"); - while (length > 0) - { - dst.Write(buf, 0, length); - length = src.Read(buf, 0, 1024); - } - _response = (HttpWebResponse) _request.GetResponse(); - -// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request); - - // TODO! Implement timeout, without killing the server - // this line implements the timeout, if there is a timeout, the callback fires and the request becomes aborted - //ThreadPool.RegisterWaitForSingleObject(responseAsyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true); - - return null; - } - - #region Async Invocation - - public IAsyncResult BeginRequest(AsyncCallback callback, object state) - { - /// - /// In case, we are invoked asynchroneously this object will keep track of the state - /// - AsyncResult ar = new AsyncResult(callback, state); - ThreadPool.QueueUserWorkItem(RequestHelper, ar); - return ar; - } - - public Stream EndRequest(IAsyncResult asyncResult) - { - AsyncResult ar = (AsyncResult) asyncResult; - - // Wait for operation to complete, then return result or - // throw exception - return ar.EndInvoke(); - } - - private void RequestHelper(Object asyncResult) - { - // We know that it's really an AsyncResult object - AsyncResult ar = (AsyncResult) asyncResult; - try - { - // Perform the operation; if sucessful set the result - Stream s = Request(); - ar.SetAsCompleted(s, false); - } - catch (Exception e) - { - // If operation fails, set the exception - ar.HandleException(e, false); - } - } - - #endregion Async Invocation - } -} \ No newline at end of file +/* +* 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.Generic; +using System.IO; +using System.Net; +using System.Text; +using System.Threading; +using System.Web; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Communications +{ + /// + /// Implementation of a generic REST client + /// + /// + /// This class is a generic implementation of a REST (Representational State Transfer) web service. This + /// class is designed to execute both synchroneously and asynchroneously. + /// + /// Internally the implementation works as a two stage asynchroneous web-client. + /// When the request is initiated, RestClient will query asynchroneously for for a web-response, + /// sleeping until the initial response is returned by the server. Once the initial response is retrieved + /// the second stage of asynchroneous requests will be triggered, in an attempt to read of the response + /// object into a memorystream as a sequence of asynchroneous reads. + /// + /// The asynchronisity of RestClient is designed to move as much processing into the back-ground, allowing + /// other threads to execute, while it waits for a response from the web-service. RestClient it self, can be + /// invoked by the caller in either synchroneous mode or asynchroneous mode. + /// + public class RestClient + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private string realuri; + + #region member variables + + /// + /// The base Uri of the web-service e.g. http://www.google.com + /// + private string _url; + + /// + /// Path elements of the query + /// + private List _pathElements = new List(); + + /// + /// Parameter elements of the query, e.g. min=34 + /// + private Dictionary _parameterElements = new Dictionary(); + + /// + /// Request method. E.g. GET, POST, PUT or DELETE + /// + private string _method; + + /// + /// Temporary buffer used to store bytes temporarily as they come in from the server + /// + private byte[] _readbuf; + + /// + /// MemoryStream representing the resultiong resource + /// + private Stream _resource; + + /// + /// WebRequest object, held as a member variable + /// + private HttpWebRequest _request; + + /// + /// WebResponse object, held as a member variable, so we can close it + /// + private HttpWebResponse _response; + + /// + /// This flag will help block the main synchroneous method, in case we run in synchroneous mode + /// + public static ManualResetEvent _allDone = new ManualResetEvent(false); + + /// + /// Default time out period + /// + private const int DefaultTimeout = 10*1000; // 10 seconds timeout + + /// + /// Default Buffer size of a block requested from the web-server + /// + private const int BufferSize = 4096; // Read blocks of 4 KB. + + + /// + /// if an exception occours during async processing, we need to save it, so it can be + /// rethrown on the primary thread; + /// + private Exception _asyncException; + + #endregion member variables + + #region constructors + + /// + /// Instantiate a new RestClient + /// + /// Web-service to query, e.g. http://osgrid.org:8003 + public RestClient(string url) + { + _url = url; + _readbuf = new byte[BufferSize]; + _resource = new MemoryStream(); + _request = null; + _response = null; + _lock = new object(); + } + + private object _lock; + + #endregion constructors + + /// + /// Add a path element to the query, e.g. assets + /// + /// path entry + public void AddResourcePath(string element) + { + if (isSlashed(element)) + _pathElements.Add(element.Substring(0, element.Length - 1)); + else + _pathElements.Add(element); + } + + /// + /// Add a query parameter to the Url + /// + /// Name of the parameter, e.g. min + /// Value of the parameter, e.g. 42 + public void AddQueryParameter(string name, string value) + { + _parameterElements.Add(HttpUtility.UrlEncode(name), HttpUtility.UrlEncode(value)); + } + + /// + /// Add a query parameter to the Url + /// + /// Name of the parameter, e.g. min + public void AddQueryParameter(string name) + { + _parameterElements.Add(HttpUtility.UrlEncode(name), null); + } + + /// + /// Web-Request method, e.g. GET, PUT, POST, DELETE + /// + public string RequestMethod + { + get { return _method; } + set { _method = value; } + } + + /// + /// True if string contains a trailing slash '/' + /// + /// string to be examined + /// true if slash is present + private bool isSlashed(string s) + { + return s.Substring(s.Length - 1, 1) == "/"; + } + + /// + /// return a slash or blank. A slash will be returned if the string does not contain one + /// + /// stromg to be examined + /// slash '/' if not already present + private string slash(string s) + { + return isSlashed(s) ? String.Empty : "/"; + } + + /// + /// Build a Uri based on the initial Url, path elements and parameters + /// + /// fully constructed Uri + private Uri buildUri() + { + StringBuilder sb = new StringBuilder(); + sb.Append(_url); + + foreach (string e in _pathElements) + { + sb.Append("/"); + sb.Append(e); + } + + bool firstElement = true; + foreach (KeyValuePair kv in _parameterElements) + { + if (firstElement) + { + sb.Append("?"); + firstElement = false; + } + else + sb.Append("&"); + + sb.Append(kv.Key); + if (kv.Value != null && kv.Value.Length != 0) + { + sb.Append("="); + sb.Append(kv.Value); + } + } + realuri = sb.ToString(); + m_log.InfoFormat("[REST]: RestURL: {0}", realuri); + return new Uri(sb.ToString()); + } + + #region Async communications with server + + /// + /// Async method, invoked when a block of data has been received from the service + /// + /// + private void StreamIsReadyDelegate(IAsyncResult ar) + { + try + { + Stream s = (Stream) ar.AsyncState; + int read = s.EndRead(ar); + + if (read > 0) + { + _resource.Write(_readbuf, 0, read); + IAsyncResult asynchronousResult = + s.BeginRead(_readbuf, 0, BufferSize, new AsyncCallback(StreamIsReadyDelegate), s); + + // TODO! Implement timeout, without killing the server + //ThreadPool.RegisterWaitForSingleObject(asynchronousResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true); + } + else + { + s.Close(); + _allDone.Set(); + } + } + catch (Exception e) + { + _allDone.Set(); + _asyncException = e; + } + } + + /// + /// Async method, invoked when the initial response if received from the server + /// + /// + private void ResponseIsReadyDelegate(IAsyncResult ar) + { + try + { + // grab response + WebRequest wr = (WebRequest) ar.AsyncState; + _response = (HttpWebResponse) wr.EndGetResponse(ar); + + // get response stream, and setup async reading + Stream s = _response.GetResponseStream(); + IAsyncResult asynchronousResult = + s.BeginRead(_readbuf, 0, BufferSize, new AsyncCallback(StreamIsReadyDelegate), s); + + // TODO! Implement timeout, without killing the server + // wait until completed, or we timed out + // ThreadPool.RegisterWaitForSingleObject(asynchronousResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true); + } + catch (Exception e) + { + _allDone.Set(); + _asyncException = e; + } + } + + // Abort the request if the timer fires. + private static void TimeoutCallback(object state, bool timedOut) + { + if (timedOut) + { + HttpWebRequest request = state as HttpWebRequest; + if (request != null) + { + request.Abort(); + } + } + } + + #endregion Async communications with server + + /// + /// Perform synchroneous request + /// + public Stream Request() + { + lock (_lock) + { + _request = (HttpWebRequest) WebRequest.Create(buildUri()); + _request.KeepAlive = false; + _request.ContentType = "application/xml"; + _request.Timeout = 200000; + _asyncException = null; + +// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request); + _response = (HttpWebResponse) _request.GetResponse(); + Stream src = _response.GetResponseStream(); + int length = src.Read(_readbuf, 0, BufferSize); + while (length > 0) + { + _resource.Write(_readbuf, 0, length); + length = src.Read(_readbuf, 0, BufferSize); + } + + + // TODO! Implement timeout, without killing the server + // this line implements the timeout, if there is a timeout, the callback fires and the request becomes aborted + //ThreadPool.RegisterWaitForSingleObject(responseAsyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true); + +// _allDone.WaitOne(); + if (_response != null) + _response.Close(); + if (_asyncException != null) + throw _asyncException; + + if (_resource != null) + { + _resource.Flush(); + _resource.Seek(0, SeekOrigin.Begin); + } + + return _resource; + } + } + + public Stream Request(Stream src) + { + _request = (HttpWebRequest) WebRequest.Create(buildUri()); + _request.KeepAlive = false; + _request.ContentType = "application/xml"; + _request.Timeout = 900000; + _request.Method = RequestMethod; + _asyncException = null; + _request.ContentLength = src.Length; + + m_log.InfoFormat("[REST]: Request Length {0}", _request.ContentLength); + m_log.InfoFormat("[REST]: Sending Web Request {0}", buildUri()); + src.Seek(0, SeekOrigin.Begin); + m_log.Info("[REST]: Seek is ok"); + Stream dst = _request.GetRequestStream(); + m_log.Info("[REST]: GetRequestStream is ok"); + + byte[] buf = new byte[1024]; + int length = src.Read(buf, 0, 1024); + m_log.Info("[REST]: First Read is ok"); + while (length > 0) + { + dst.Write(buf, 0, length); + length = src.Read(buf, 0, 1024); + } + + _response = (HttpWebResponse) _request.GetResponse(); + +// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request); + + // TODO! Implement timeout, without killing the server + // this line implements the timeout, if there is a timeout, the callback fires and the request becomes aborted + //ThreadPool.RegisterWaitForSingleObject(responseAsyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true); + + return null; + } + + #region Async Invocation + + public IAsyncResult BeginRequest(AsyncCallback callback, object state) + { + /// + /// In case, we are invoked asynchroneously this object will keep track of the state + /// + AsyncResult ar = new AsyncResult(callback, state); + ThreadPool.QueueUserWorkItem(RequestHelper, ar); + return ar; + } + + public Stream EndRequest(IAsyncResult asyncResult) + { + AsyncResult ar = (AsyncResult) asyncResult; + + // Wait for operation to complete, then return result or + // throw exception + return ar.EndInvoke(); + } + + private void RequestHelper(Object asyncResult) + { + // We know that it's really an AsyncResult object + AsyncResult ar = (AsyncResult) asyncResult; + try + { + // Perform the operation; if sucessful set the result + Stream s = Request(); + ar.SetAsCompleted(s, false); + } + catch (Exception e) + { + // If operation fails, set the exception + ar.HandleException(e, false); + } + } + + #endregion Async Invocation + } +} diff --git a/OpenSim/Framework/Communications/UserManagerBase.cs b/OpenSim/Framework/Communications/UserManagerBase.cs index e2194298ce..85670f9897 100644 --- a/OpenSim/Framework/Communications/UserManagerBase.cs +++ b/OpenSim/Framework/Communications/UserManagerBase.cs @@ -1,701 +1,780 @@ -/* -* 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.Generic; -using System.Reflection; -using System.Security.Cryptography; -using libsecondlife; -using libsecondlife.StructuredData; -using Nwc.XmlRpc; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.UserManagement -{ - /// - /// Base class for user management (create, read, etc) - /// - public abstract class UserManagerBase : IUserService - { - public UserConfig _config; - private Dictionary _plugins = new Dictionary(); - public bool RexMode = false; // _config is not initiated in local mode - - /// - /// 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(); - _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. Returns null if no user profile is found. - public UserProfileData GetUserProfile(LLUUID uuid, string authAddr) - { - if (!RexMode) - { - foreach (KeyValuePair plugin in _plugins) - { - try - { - UserProfileData profile = plugin.Value.GetUserByUUID(uuid); - if (null != profile) - { - profile.currentAgent = getUserAgent(profile.UUID); - return profile; - } - } - catch (Exception e) - { - MainLog.Instance.Verbose("USERSTORAGE", "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); - } - } - return null; - } - else - { - try - { - UserProfileData userpd = null; - System.Collections.Hashtable param = new System.Collections.Hashtable(); - param["avatar_uuid"] = uuid.ToString(); - param["AuthenticationAddress"] = authAddr; - System.Collections.Hashtable resp = MakeCommonRequest("get_user_by_uuid", param, authAddr, 3000); - userpd = RexLoginHandler.HashtableToUserProfileData(resp); - return userpd; - } - catch (Exception e) - { - System.Console.WriteLine("Error when trying to fetch profile data by uuid from remote authentication server: " + - e.Message); - } - return null; - } - } - - public System.Collections.Hashtable MakeCommonRequest(string method, System.Collections.Hashtable param, string addr, int timeout)//rex - { - System.Collections.IList parameters = new System.Collections.ArrayList(); - parameters.Add(param); - XmlRpcRequest req = new XmlRpcRequest(method, parameters); - if (!addr.StartsWith("http://")) - addr = "http://" + addr; - XmlRpcResponse resp = req.Send(addr, timeout); - return (System.Collections.Hashtable)resp.Value; - } - - - /// - /// Loads a user profile by name - /// - /// The target name - /// A user profile - public UserProfileData GetUserProfileByAccount(string account) - { - foreach (KeyValuePair plugin in _plugins) - { - try - { - UserProfileData profile = plugin.Value.GetUserByAccount(account); - profile.currentAgent = getUserAgent(profile.UUID); - return profile; - } - catch (Exception e) - { - MainLog.Instance.Verbose("USERSTORAGE", "Unable to find user by account via " + plugin.Key + "(" + e.ToString() + ")"); - } - } - - return null; - } - - - public List GenerateAgentPickerRequestResponse(LLUUID queryID, string query) - { - List pickerlist = new List(); - foreach (KeyValuePair plugin in _plugins) - { - try - { - pickerlist = plugin.Value.GeneratePickerResults(queryID, query); - } - catch (Exception) - { - MainLog.Instance.Verbose("USERSTORAGE", - "Unable to generate AgentPickerData via " + plugin.Key + "(" + query + ")"); - return new List(); - } - } - return pickerlist; - } - - /// - /// Loads a user profile by name - /// - /// First name - /// Last name - /// A user profile. Returns null if no profile is found - public UserProfileData GetUserProfile(string fname, string lname, string authAddr) - { - if (!RexMode) - { - foreach (KeyValuePair plugin in _plugins) - { - try - { - UserProfileData profile = plugin.Value.GetUserByName(fname, lname); - - if (profile != null) - { - profile.currentAgent = getUserAgent(profile.UUID); - return profile; - } - } - catch (Exception e) - { - MainLog.Instance.Verbose("USERSTORAGE", "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); - } - } - } - else - { - try - { - UserProfileData userpd = null; - System.Collections.Hashtable param = new System.Collections.Hashtable(); - param["avatar_name"] = fname + " "+lname; - param["AuthenticationAddress"] = authAddr; - System.Collections.Hashtable resp = MakeCommonRequest("get_user_by_name", param, authAddr, 3000); - if (resp.Contains("error_type")) - { - return null; - } - else - { - userpd = RexLoginHandler.HashtableToUserProfileData(resp); - return userpd; - } - } - catch (Exception e) - { - System.Console.WriteLine("Error when trying to fetch profile data by firstname, lastname from remote authentication server: " + - e.Message); - } - } - - 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("USERSTORAGE", - "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 agent's 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("USERSTORAGE", - "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); - } - } - - return null; - } - - /// - /// Loads a user's friend list - /// - /// the UUID of the friend list owner - /// A List of FriendListItems that contains info about the user's friends - public List GetUserFriendList(LLUUID ownerID) - { - - foreach (KeyValuePair plugin in _plugins) - { - try - { - return plugin.Value.GetUserFriendList(ownerID); - } - catch (Exception e) - { - MainLog.Instance.Verbose("USERSTORAGE", - "Unable to GetUserFriendList via " + plugin.Key + "(" + e.ToString() + ")"); - } - } - - return null; - - } - - public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms) - { - foreach (KeyValuePair plugin in _plugins) - { - try - { - plugin.Value.AddNewUserFriend(friendlistowner,friend,perms); - } - catch (Exception e) - { - MainLog.Instance.Verbose("USERSTORAGE", - "Unable to AddNewUserFriend via " + plugin.Key + "(" + e.ToString() + ")"); - } - } - - } - - - public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend) - { - foreach (KeyValuePair plugin in _plugins) - { - try - { - plugin.Value.RemoveUserFriend(friendlistowner, friend); - } - catch (Exception e) - { - MainLog.Instance.Verbose("USERSTORAGE", - "Unable to RemoveUserFriend via " + plugin.Key + "(" + e.ToString() + ")"); - } - } - } - - public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms) - { - foreach (KeyValuePair plugin in _plugins) - { - try - { - plugin.Value.UpdateUserFriendPerms(friendlistowner, friend, perms); - } - catch (Exception e) - { - MainLog.Instance.Verbose("USERSTORAGE", - "Unable to UpdateUserFriendPerms via " + plugin.Key + "(" + e.ToString() + ")"); - } - } - } - /// - /// Loads a user agent by name (not called directly) - /// - /// The agent's 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("USERSTORAGE", - "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); - } - } - - return null; - } - - // TODO: document - public void clearUserAgent(LLUUID agentID, string authAddr) - { - UserProfileData profile = GetUserProfile(agentID, authAddr); - if (profile != null) - { - profile.currentAgent = null; - if (!RexMode) - { - setUserProfile(profile); - } - else - { - try - { - System.Collections.Hashtable param = new System.Collections.Hashtable(); - param["agentID"] = profile.UUID.ToString(); - System.Collections.Hashtable resp = MakeCommonRequest("remove_user_agent", param, authAddr, 3000); - } - catch (Exception e) - { - System.Console.WriteLine("Error when trying to fetch agent data by uuid from remote authentication server: " + - e.Message); - } - } - - } - else - { - MainLog.Instance.Verbose("USERSTORAGE", "Unable to clear user agent with agentID : " + agentID); - } - } - - /// - /// Loads a user agent by name (not called directly) - /// - /// The agent's firstname - /// The agent's 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("USERSTORAGE", - "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 = LLUUID.Zero; // Fill in later - agent.currentRegion = LLUUID.Zero; // Fill in later - - profile.currentAgent = agent; - } - - public void CreateAgent(UserProfileData profile, LLSD request) - { - 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; - - // What time did the user login? - agent.loginTime = Util.UnixTimeSinceEpoch(); - agent.logoutTime = 0; - - // Current location - agent.regionID = LLUUID.Zero; // Fill in later - agent.currentRegion = LLUUID.Zero; // Fill in later - - profile.currentAgent = agent; - } - - /// - /// Saves a target agent to the database - /// - /// The users profile - /// Successful? - public bool CommitAgent(ref UserProfileData profile) - { - // TODO: how is this function different from setUserProfile? - return setUserProfile(profile); - } - - #endregion - - /// - /// - /// - /// - public LLUUID 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("USERSTORAGE", - "Unable to add user via " + plugin.Key + "(" + e.ToString() + ")"); - } - } - - return user.UUID; - } - - public abstract UserProfileData SetupMasterUser(string firstName, string lastName); - public abstract UserProfileData SetupMasterUser(string firstName, string lastName, string password); - public abstract UserProfileData SetupMasterUser(LLUUID uuid); - - - public bool AuthenticateUser(LLUUID agentId, string sessionhash, out String avatarstorage) - { - avatarstorage = ""; - return true; - } - - /// - /// Loads a user profile by name - /// - /// The target name - /// A user profile - public UserProfileData GetUserProfile(string name, string authAddr) - { - foreach (KeyValuePair plugin in _plugins) - { - try - { - UserProfileData profile = plugin.Value.GetUserByName(name, authAddr); - profile.currentAgent = getUserAgent(profile.UUID); - return profile; - } - catch (Exception e) - { - MainLog.Instance.Verbose("USERSTORAGE", "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); - } - } - - return null; - } - - public void UpdateUserAgentData(LLUUID agentId, bool agentOnline, LLVector3 currentPos, int logoutTime, string authAddr) - { - // Saves the agent to database - //return true; - if (!RexMode) - { - foreach (KeyValuePair plugin in _plugins) - { - try - { - UserAgentData agent = plugin.Value.GetAgentByUUID(agentId); - if (agent != null) - { - agent.agentOnline = agentOnline; - agent.logoutTime = logoutTime; - agent.currentPos = currentPos; - agent.currentPos = new LLVector3( - Convert.ToSingle(currentPos.X), - Convert.ToSingle(currentPos.Y), - Convert.ToSingle(currentPos.Z)); - plugin.Value.AddNewUserAgent(agent); - MainLog.Instance.Verbose("USERSTORAGE", "Agent updated UUID = " + agent.UUID.ToString()); - } - else - { - MainLog.Instance.Verbose("USERSTORAGE", "Agent update, agent not found with UUID = " + agentId); - } - - } - catch (Exception e) - { - MainLog.Instance.Verbose("USERSTORAGE", "Unable to add or update agent via " + plugin.Key + "(" + e.ToString() + ")"); - } - } - } - else - { - - try - { - System.Collections.Hashtable param = new System.Collections.Hashtable(); - param["agentID"] = agentId.ToString(); - param["agentOnline"] = agentOnline.ToString(); - param["logoutTime"] = logoutTime.ToString(); - param["agent_currentPosX"] = Convert.ToSingle(currentPos.X).ToString(); - param["agent_currentPosY"] = Convert.ToSingle(currentPos.Y).ToString(); - param["agent_currentPosZ"] = Convert.ToSingle(currentPos.Z).ToString(); - param["AuthenticationAddress"] = authAddr; - System.Collections.Hashtable resp = MakeCommonRequest("update_user_agent", param, authAddr, 3000); - } - catch (Exception e) - { - System.Console.WriteLine("Error when trying to update user agent data to remote authentication server: " + - e.Message); - } - - } - - } - - } -} +/* +* 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.Generic; +using System.Reflection; +using System.Security.Cryptography; +using libsecondlife; +using libsecondlife.StructuredData; +using Nwc.XmlRpc; +using OpenSim.Framework.Console; +using OpenSim.Framework.Statistics; + +namespace OpenSim.Framework.UserManagement +{ + /// + /// Base class for user management (create, read, etc) + /// + public abstract class UserManagerBase : IUserService + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + public UserConfig _config; + private Dictionary _plugins = new Dictionary(); + public bool RexMode = false; // _config is not initiated in local mode + + /// + /// 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)) + { + m_log.Info("[USERSTORAGE]: Attempting to load " + FileName); + Assembly pluginAssembly = Assembly.LoadFrom(FileName); + + m_log.Info("[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(); + _plugins.Add(plug.getName(), plug); + m_log.Info("[USERSTORAGE]: Added IUserData Interface"); + } + + #region Get UserProfile + + // see IUserService + public UserProfileData GetUserProfile(string fname, string lname) + { + foreach (KeyValuePair plugin in _plugins) + { + UserProfileData profile = plugin.Value.GetUserByName(fname, lname); + + if (profile != null) + { + profile.currentAgent = getUserAgent(profile.UUID); + return profile; + } + } + + return null; + } + + // see IUserService + public UserProfileData GetUserProfile(LLUUID uuid, string authAddr) + { + if (!RexMode) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + UserProfileData profile = plugin.Value.GetUserByUUID(uuid); + if (null != profile) + { + profile.currentAgent = getUserAgent(profile.UUID); + return profile; + } + } + catch (Exception e) + { + MainLog.Instance.Verbose("USERSTORAGE", "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + return null; + } + else + { + try + { + UserProfileData userpd = null; + System.Collections.Hashtable param = new System.Collections.Hashtable(); + param["avatar_uuid"] = uuid.ToString(); + param["AuthenticationAddress"] = authAddr; + System.Collections.Hashtable resp = MakeCommonRequest("get_user_by_uuid", param, authAddr, 3000); + userpd = RexLoginHandler.HashtableToUserProfileData(resp); + return userpd; + } + catch (Exception e) + { + System.Console.WriteLine("Error when trying to fetch profile data by uuid from remote authentication server: " + + e.Message); + } + return null; + } + } + + public System.Collections.Hashtable MakeCommonRequest(string method, System.Collections.Hashtable param, string addr, int timeout)//rex + { + System.Collections.IList parameters = new System.Collections.ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest(method, parameters); + if (!addr.StartsWith("http://")) + addr = "http://" + addr; + XmlRpcResponse resp = req.Send(addr, timeout); + return (System.Collections.Hashtable)resp.Value; + } + + + /// + /// Loads a user profile by name + /// + /// The target name + /// A user profile + public UserProfileData GetUserProfileByAccount(string account) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + UserProfileData profile = plugin.Value.GetUserByAccount(account); + profile.currentAgent = getUserAgent(profile.UUID); + return profile; + } + catch (Exception e) + { + MainLog.Instance.Verbose("USERSTORAGE", "Unable to find user by account via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + + return null; + } + + + public List GenerateAgentPickerRequestResponse(LLUUID queryID, string query) + { + List pickerlist = new List(); + foreach (KeyValuePair plugin in _plugins) + { + try + { + pickerlist = plugin.Value.GeneratePickerResults(queryID, query); + } + catch (Exception) + { + m_log.Info("[USERSTORAGE]: Unable to generate AgentPickerData via " + plugin.Key + "(" + query + ")"); + return new List(); + } + } + return pickerlist; + } + + /// + /// Loads a user profile by name + /// + /// First name + /// Last name + /// A user profile. Returns null if no profile is found + public UserProfileData GetUserProfile(string fname, string lname, string authAddr) + { + if (!RexMode) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + UserProfileData profile = plugin.Value.GetUserByName(fname, lname); + + if (profile != null) + { + profile.currentAgent = getUserAgent(profile.UUID); + return profile; + } + } + catch (Exception e) + { + MainLog.Instance.Verbose("USERSTORAGE", "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + } + else + { + try + { + UserProfileData userpd = null; + System.Collections.Hashtable param = new System.Collections.Hashtable(); + param["avatar_name"] = fname + " "+lname; + param["AuthenticationAddress"] = authAddr; + System.Collections.Hashtable resp = MakeCommonRequest("get_user_by_name", param, authAddr, 3000); + if (resp.Contains("error_type")) + { + return null; + } + else + { + userpd = RexLoginHandler.HashtableToUserProfileData(resp); + return userpd; + } + } + catch (Exception e) + { + System.Console.WriteLine("Error when trying to fetch profile data by firstname, lastname from remote authentication server: " + + e.Message); + } + } + + 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) + { + m_log.Info("[USERSTORAGE]: 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 agent's UUID + /// Agent profiles + public UserAgentData getUserAgent(LLUUID uuid) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + return plugin.Value.GetAgentByUUID(uuid); + } + catch (Exception e) + { + m_log.Info("[USERSTORAGE]: Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + + return null; + } + + /// + /// Loads a user's friend list + /// + /// the UUID of the friend list owner + /// A List of FriendListItems that contains info about the user's friends + public List GetUserFriendList(LLUUID ownerID) + { + + foreach (KeyValuePair plugin in _plugins) + { + try + { + return plugin.Value.GetUserFriendList(ownerID); + } + catch (Exception e) + { + m_log.Info("[USERSTORAGE]: Unable to GetUserFriendList via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + + return null; + + } + + public void StoreWebLoginKey(LLUUID agentID, LLUUID webLoginKey) + { + + foreach (KeyValuePair plugin in _plugins) + { + try + { + plugin.Value.StoreWebLoginKey(agentID, webLoginKey); + } + catch (Exception e) + { + m_log.Info("[USERSTORAGE]: Unable to Store WebLoginKey via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + } + + public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + plugin.Value.AddNewUserFriend(friendlistowner,friend,perms); + } + catch (Exception e) + { + m_log.Info("[USERSTORAGE]: Unable to AddNewUserFriend via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + + } + + + public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + plugin.Value.RemoveUserFriend(friendlistowner, friend); + } + catch (Exception e) + { + m_log.Info("[USERSTORAGE]: Unable to RemoveUserFriend via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + } + + public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + plugin.Value.UpdateUserFriendPerms(friendlistowner, friend, perms); + } + catch (Exception e) + { + m_log.Info("[USERSTORAGE]: Unable to UpdateUserFriendPerms via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + } + /// + /// Loads a user agent by name (not called directly) + /// + /// The agent's name + /// A user agent + public UserAgentData getUserAgent(string name) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + return plugin.Value.GetAgentByName(name); + } + catch (Exception e) + { + m_log.Info("[USERSTORAGE]: Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + + return null; + } + + // TODO: document + public void clearUserAgent(LLUUID agentID, string authAddr) + { + UserProfileData profile = GetUserProfile(agentID, authAddr); + if (profile != null) + { + profile.currentAgent = null; + if (!RexMode) + { + setUserProfile(profile); + } + else + { + try + { + System.Collections.Hashtable param = new System.Collections.Hashtable(); + param["agentID"] = profile.UUID.ToString(); + System.Collections.Hashtable resp = MakeCommonRequest("remove_user_agent", param, authAddr, 3000); + } + catch (Exception e) + { + System.Console.WriteLine("Error when trying to fetch agent data by uuid from remote authentication server: " + + e.Message); + } + } + + } + else + { + MainLog.Instance.Verbose("USERSTORAGE", "Unable to clear user agent with agentID : " + agentID); + } + } + + /// + /// Loads a user agent by name (not called directly) + /// + /// The agent's firstname + /// The agent's 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) + { + m_log.Info("[USERSTORAGE]: 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 = LLUUID.Zero; // Fill in later + agent.currentRegion = LLUUID.Zero; // Fill in later + + profile.currentAgent = agent; + } + + /// + /// Process a user logoff from OpenSim. + /// + /// + /// + /// + /// + /// + /// + public void LogOffUser(LLUUID userid, LLUUID regionid, ulong regionhandle, float posx, float posy, float posz) + { + if (StatsManager.UserStats != null) + StatsManager.UserStats.AddLogout(); + + UserProfileData userProfile; + UserAgentData userAgent; + LLVector3 currentPos = new LLVector3(posx, posy, posz); + + userProfile = GetUserProfile(userid); + + if (userProfile != null) + { + // This line needs to be in side the above if statement or the UserServer will crash on some logouts. + m_log.Info("[LOGOUT]: " + userProfile.username + " " + userProfile.surname + " from " + regionhandle + "(" + posx + "," + posy + "," + posz + ")"); + + userAgent = userProfile.currentAgent; + if (userAgent != null) + { + userAgent.agentOnline = false; + userAgent.logoutTime = Util.UnixTimeSinceEpoch(); + userAgent.sessionID = LLUUID.Zero; + if (regionid != null) + { + userAgent.currentRegion = regionid; + } + userAgent.currentHandle = regionhandle; + + userAgent.currentPos = currentPos; + + userProfile.currentAgent = userAgent; + + + CommitAgent(ref userProfile); + } + else + { + // If currentagent is null, we can't reference it here or the UserServer crashes! + m_log.Info("[LOGOUT]: didn't save logout position: " + userid.ToString()); + } + + } + else + { + m_log.Warn("[LOGOUT]: Unknown User logged out"); + } + } + + public void CreateAgent(UserProfileData profile, LLSD request) + { + 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; + + // What time did the user login? + agent.loginTime = Util.UnixTimeSinceEpoch(); + agent.logoutTime = 0; + + // Current location + agent.regionID = LLUUID.Zero; // Fill in later + agent.currentRegion = LLUUID.Zero; // Fill in later + + profile.currentAgent = agent; + } + + /// + /// Saves a target agent to the database + /// + /// The users profile + /// Successful? + public bool CommitAgent(ref UserProfileData profile) + { + // TODO: how is this function different from setUserProfile? + return setUserProfile(profile); + } + + #endregion + + /// + /// + /// + /// + public LLUUID 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 = String.Empty; + 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) + { + m_log.Info("[USERSTORAGE]: Unable to add user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + + return user.UUID; + } + + public abstract UserProfileData SetupMasterUser(string firstName, string lastName); + public abstract UserProfileData SetupMasterUser(string firstName, string lastName, string password); + public abstract UserProfileData SetupMasterUser(LLUUID uuid); + + + public bool AuthenticateUser(LLUUID agentId, string sessionhash, out String avatarstorage) + { + avatarstorage = ""; + return true; + } + + /// + /// Loads a user profile by name + /// + /// The target name + /// A user profile + public UserProfileData GetUserProfile(string name, string authAddr) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + UserProfileData profile = plugin.Value.GetUserByName(name, authAddr); + profile.currentAgent = getUserAgent(profile.UUID); + return profile; + } + catch (Exception e) + { + MainLog.Instance.Verbose("USERSTORAGE", "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + + return null; + } + + public void UpdateUserAgentData(LLUUID agentId, bool agentOnline, LLVector3 currentPos, int logoutTime, string authAddr) + { + // Saves the agent to database + //return true; + if (!RexMode) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + UserAgentData agent = plugin.Value.GetAgentByUUID(agentId); + if (agent != null) + { + agent.agentOnline = agentOnline; + agent.logoutTime = logoutTime; + agent.currentPos = currentPos; + agent.currentPos = new LLVector3( + Convert.ToSingle(currentPos.X), + Convert.ToSingle(currentPos.Y), + Convert.ToSingle(currentPos.Z)); + plugin.Value.AddNewUserAgent(agent); + MainLog.Instance.Verbose("USERSTORAGE", "Agent updated UUID = " + agent.UUID.ToString()); + } + else + { + MainLog.Instance.Verbose("USERSTORAGE", "Agent update, agent not found with UUID = " + agentId); + } + + } + catch (Exception e) + { + MainLog.Instance.Verbose("USERSTORAGE", "Unable to add or update agent via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + } + else + { + + try + { + System.Collections.Hashtable param = new System.Collections.Hashtable(); + param["agentID"] = agentId.ToString(); + param["agentOnline"] = agentOnline.ToString(); + param["logoutTime"] = logoutTime.ToString(); + param["agent_currentPosX"] = Convert.ToSingle(currentPos.X).ToString(); + param["agent_currentPosY"] = Convert.ToSingle(currentPos.Y).ToString(); + param["agent_currentPosZ"] = Convert.ToSingle(currentPos.Z).ToString(); + param["AuthenticationAddress"] = authAddr; + System.Collections.Hashtable resp = MakeCommonRequest("update_user_agent", param, authAddr, 3000); + } + catch (Exception e) + { + System.Console.WriteLine("Error when trying to update user agent data to remote authentication server: " + + e.Message); + } + + } + + } + + } +} diff --git a/OpenSim/Framework/Configuration/HTTP/HTTPConfiguration.cs b/OpenSim/Framework/Configuration/HTTP/HTTPConfiguration.cs index d6ed88c710..fe08ec6bd6 100644 --- a/OpenSim/Framework/Configuration/HTTP/HTTPConfiguration.cs +++ b/OpenSim/Framework/Configuration/HTTP/HTTPConfiguration.cs @@ -1,115 +1,117 @@ -/* -* 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.IO; -using System.Net; -using System.Text; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.Configuration.HTTP -{ - public class HTTPConfiguration : IGenericConfig - { - private RemoteConfigSettings remoteConfigSettings; - - private XmlConfiguration xmlConfig; - - private string configFileName = ""; - - public HTTPConfiguration() - { - remoteConfigSettings = new RemoteConfigSettings("remoteconfig.xml"); - xmlConfig = new XmlConfiguration(); - } - - public void SetFileName(string fileName) - { - configFileName = fileName; - } - - public void LoadData() - { - try - { - StringBuilder sb = new StringBuilder(); - - byte[] buf = new byte[8192]; - HttpWebRequest request = - (HttpWebRequest) WebRequest.Create(remoteConfigSettings.baseConfigURL + configFileName); - HttpWebResponse response = (HttpWebResponse) request.GetResponse(); - - Stream resStream = response.GetResponseStream(); - - string tempString = null; - int count = 0; - - do - { - count = resStream.Read(buf, 0, buf.Length); - if (count != 0) - { - tempString = Encoding.ASCII.GetString(buf, 0, count); - sb.Append(tempString); - } - } while (count > 0); - LoadDataFromString(sb.ToString()); - } - catch (WebException) - { - MainLog.Instance.Warn("Unable to connect to remote configuration file (" + - remoteConfigSettings.baseConfigURL + configFileName + - "). Creating local file instead."); - xmlConfig.SetFileName(configFileName); - xmlConfig.LoadData(); - } - } - - public void LoadDataFromString(string data) - { - xmlConfig.LoadDataFromString(data); - } - - public string GetAttribute(string attributeName) - { - return xmlConfig.GetAttribute(attributeName); - } - - public bool SetAttribute(string attributeName, string attributeValue) - { - return true; - } - - public void Commit() - { - } - - public void Close() - { - } - } -} \ No newline at end of file +/* +* 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.IO; +using System.Net; +using System.Text; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Configuration.HTTP +{ + public class HTTPConfiguration : IGenericConfig + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private RemoteConfigSettings remoteConfigSettings; + + private XmlConfiguration xmlConfig; + + private string configFileName = System.String.Empty; + + public HTTPConfiguration() + { + remoteConfigSettings = new RemoteConfigSettings("remoteconfig.xml"); + xmlConfig = new XmlConfiguration(); + } + + public void SetFileName(string fileName) + { + configFileName = fileName; + } + + public void LoadData() + { + try + { + StringBuilder sb = new StringBuilder(); + + byte[] buf = new byte[8192]; + HttpWebRequest request = + (HttpWebRequest) WebRequest.Create(remoteConfigSettings.baseConfigURL + configFileName); + HttpWebResponse response = (HttpWebResponse) request.GetResponse(); + + Stream resStream = response.GetResponseStream(); + + string tempString = null; + int count = 0; + + do + { + count = resStream.Read(buf, 0, buf.Length); + if (count != 0) + { + tempString = Encoding.ASCII.GetString(buf, 0, count); + sb.Append(tempString); + } + } while (count > 0); + LoadDataFromString(sb.ToString()); + } + catch (WebException) + { + m_log.Warn("Unable to connect to remote configuration file (" + + remoteConfigSettings.baseConfigURL + configFileName + + "). Creating local file instead."); + xmlConfig.SetFileName(configFileName); + xmlConfig.LoadData(); + } + } + + public void LoadDataFromString(string data) + { + xmlConfig.LoadDataFromString(data); + } + + public string GetAttribute(string attributeName) + { + return xmlConfig.GetAttribute(attributeName); + } + + public bool SetAttribute(string attributeName, string attributeValue) + { + return true; + } + + public void Commit() + { + } + + public void Close() + { + } + } +} diff --git a/OpenSim/Framework/Configuration/HTTP/RemoteConfigSettings.cs b/OpenSim/Framework/Configuration/HTTP/RemoteConfigSettings.cs index 7d610b098c..4da58dec78 100644 --- a/OpenSim/Framework/Configuration/HTTP/RemoteConfigSettings.cs +++ b/OpenSim/Framework/Configuration/HTTP/RemoteConfigSettings.cs @@ -1,62 +1,62 @@ -/* -* 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. -* -*/ - -namespace OpenSim.Framework.Configuration.HTTP -{ - public class RemoteConfigSettings - { - private ConfigurationMember configMember; - - public string baseConfigURL = ""; - - public RemoteConfigSettings(string filename) - { - configMember = - new ConfigurationMember(filename, "REMOTE CONFIG SETTINGS", loadConfigurationOptions, - handleIncomingConfiguration,true); - configMember.forceConfigurationPluginLibrary("OpenSim.Framework.Configuration.XML.dll"); - configMember.performConfigurationRetrieve(); - } - - public void loadConfigurationOptions() - { - configMember.addConfigurationOption("base_config_url", - ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, - "URL Containing Configuration Files", "http://localhost/", false); - } - - public bool handleIncomingConfiguration(string configuration_key, object configuration_result) - { - if (configuration_key == "base_config_url") - { - baseConfigURL = (string) configuration_result; - } - return true; - } - } -} \ No newline at end of file +/* +* 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. +* +*/ + +namespace OpenSim.Framework.Configuration.HTTP +{ + public class RemoteConfigSettings + { + private ConfigurationMember configMember; + + public string baseConfigURL = System.String.Empty; + + public RemoteConfigSettings(string filename) + { + configMember = + new ConfigurationMember(filename, "REMOTE CONFIG SETTINGS", loadConfigurationOptions, + handleIncomingConfiguration,true); + configMember.forceConfigurationPluginLibrary("OpenSim.Framework.Configuration.XML.dll"); + configMember.performConfigurationRetrieve(); + } + + public void loadConfigurationOptions() + { + configMember.addConfigurationOption("base_config_url", + ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "URL Containing Configuration Files", "http://localhost/", false); + } + + public bool handleIncomingConfiguration(string configuration_key, object configuration_result) + { + if (configuration_key == "base_config_url") + { + baseConfigURL = (string) configuration_result; + } + return true; + } + } +} diff --git a/OpenSim/Framework/Configuration/XML/XmlConfiguration.cs b/OpenSim/Framework/Configuration/XML/XmlConfiguration.cs index 7b404c0223..dd80aded34 100644 --- a/OpenSim/Framework/Configuration/XML/XmlConfiguration.cs +++ b/OpenSim/Framework/Configuration/XML/XmlConfiguration.cs @@ -1,139 +1,139 @@ -/* -* 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.IO; -using System.Xml; - -namespace OpenSim.Framework.Configuration -{ - public class XmlConfiguration : IGenericConfig - { - private XmlDocument doc; - private XmlNode rootNode; - private XmlNode configNode; - private string fileName; - private bool createdFile = false; - - public void SetFileName(string file) - { - fileName = file; - } - - private void LoadDataToClass() - { - rootNode = doc.FirstChild; - if (rootNode.Name != "Root") - throw new Exception("Error: Invalid .xml File. Missing "); - - configNode = rootNode.FirstChild; - if (configNode.Name != "Config") - throw new Exception("Error: Invalid .xml File. first child should be "); - } - - public void LoadData() - { - lock (this) - { - doc = new XmlDocument(); - if (File.Exists(fileName)) - { - XmlTextReader reader = new XmlTextReader(fileName); - reader.WhitespaceHandling = WhitespaceHandling.None; - doc.Load(reader); - reader.Close(); - } - else - { - createdFile = true; - rootNode = doc.CreateNode(XmlNodeType.Element, "Root", ""); - doc.AppendChild(rootNode); - configNode = doc.CreateNode(XmlNodeType.Element, "Config", ""); - rootNode.AppendChild(configNode); - } - - LoadDataToClass(); - - if (createdFile) - { - Commit(); - } - } - } - - public void LoadDataFromString(string data) - { - doc = new XmlDocument(); - doc.LoadXml(data); - - LoadDataToClass(); - } - - public string GetAttribute(string attributeName) - { - string result = null; - if (configNode.Attributes[attributeName] != null) - { - result = ((XmlAttribute) configNode.Attributes.GetNamedItem(attributeName)).Value; - } - return result; - } - - public bool SetAttribute(string attributeName, string attributeValue) - { - if (configNode.Attributes[attributeName] != null) - { - ((XmlAttribute) configNode.Attributes.GetNamedItem(attributeName)).Value = attributeValue; - } - else - { - XmlAttribute attri; - attri = doc.CreateAttribute(attributeName); - attri.Value = attributeValue; - configNode.Attributes.Append(attri); - } - return true; - } - - public void Commit() - { - if (!Directory.Exists(Util.configDir())) - { - Directory.CreateDirectory(Util.configDir()); - } - doc.Save(fileName); - } - - public void Close() - { - configNode = null; - rootNode = null; - doc = null; - } - } -} \ No newline at end of file +/* +* 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.IO; +using System.Xml; + +namespace OpenSim.Framework.Configuration +{ + public class XmlConfiguration : IGenericConfig + { + private XmlDocument doc; + private XmlNode rootNode; + private XmlNode configNode; + private string fileName; + private bool createdFile = false; + + public void SetFileName(string file) + { + fileName = file; + } + + private void LoadDataToClass() + { + rootNode = doc.FirstChild; + if (rootNode.Name != "Root") + throw new Exception("Error: Invalid .xml File. Missing "); + + configNode = rootNode.FirstChild; + if (configNode.Name != "Config") + throw new Exception("Error: Invalid .xml File. first child should be "); + } + + public void LoadData() + { + lock (this) + { + doc = new XmlDocument(); + if (File.Exists(fileName)) + { + XmlTextReader reader = new XmlTextReader(fileName); + reader.WhitespaceHandling = WhitespaceHandling.None; + doc.Load(reader); + reader.Close(); + } + else + { + createdFile = true; + rootNode = doc.CreateNode(XmlNodeType.Element, "Root", String.Empty); + doc.AppendChild(rootNode); + configNode = doc.CreateNode(XmlNodeType.Element, "Config", String.Empty); + rootNode.AppendChild(configNode); + } + + LoadDataToClass(); + + if (createdFile) + { + Commit(); + } + } + } + + public void LoadDataFromString(string data) + { + doc = new XmlDocument(); + doc.LoadXml(data); + + LoadDataToClass(); + } + + public string GetAttribute(string attributeName) + { + string result = null; + if (configNode.Attributes[attributeName] != null) + { + result = ((XmlAttribute) configNode.Attributes.GetNamedItem(attributeName)).Value; + } + return result; + } + + public bool SetAttribute(string attributeName, string attributeValue) + { + if (configNode.Attributes[attributeName] != null) + { + ((XmlAttribute) configNode.Attributes.GetNamedItem(attributeName)).Value = attributeValue; + } + else + { + XmlAttribute attri; + attri = doc.CreateAttribute(attributeName); + attri.Value = attributeValue; + configNode.Attributes.Append(attri); + } + return true; + } + + public void Commit() + { + if (!Directory.Exists(Util.configDir())) + { + Directory.CreateDirectory(Util.configDir()); + } + doc.Save(fileName); + } + + public void Close() + { + configNode = null; + rootNode = null; + doc = null; + } + } +} diff --git a/OpenSim/Framework/ConfigurationMember.cs b/OpenSim/Framework/ConfigurationMember.cs index 5142106ece..f3386ad174 100644 --- a/OpenSim/Framework/ConfigurationMember.cs +++ b/OpenSim/Framework/ConfigurationMember.cs @@ -1,505 +1,503 @@ -/* -* 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.Generic; -using System.Globalization; -using System.Net; -using System.Reflection; -using System.Xml; -using libsecondlife; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework -{ - public class ConfigurationMember - { - public delegate bool ConfigurationOptionResult(string configuration_key, object configuration_result); - - public delegate void ConfigurationOptionsLoad(); - - private List configurationOptions = new List(); - private string configurationFilename = ""; - private string configurationDescription = ""; - private XmlNode configurationFromXMLNode = null; - private ConfigurationOptionsLoad loadFunction; - private ConfigurationOptionResult resultFunction; - - private IGenericConfig configurationPlugin = null; - private bool useConsoleToPromptOnError = true; - /// - /// This is the default configuration DLL loaded - /// - private string configurationPluginFilename = "OpenSim.Framework.Configuration.XML.dll"; - - public ConfigurationMember(string configuration_filename, string configuration_description, - ConfigurationOptionsLoad load_function, ConfigurationOptionResult result_function, bool use_console_to_prompt_on_error) - { - configurationFilename = configuration_filename; - configurationDescription = configuration_description; - loadFunction = load_function; - resultFunction = result_function; - useConsoleToPromptOnError = use_console_to_prompt_on_error; - } - - public ConfigurationMember(XmlNode configuration_xml, string configuration_description, - ConfigurationOptionsLoad load_function, ConfigurationOptionResult result_function, bool use_console_to_prompt_on_error) - { - configurationFilename = ""; - configurationFromXMLNode = configuration_xml; - configurationDescription = configuration_description; - loadFunction = load_function; - resultFunction = result_function; - useConsoleToPromptOnError = use_console_to_prompt_on_error; - } - - public void setConfigurationFilename(string filename) - { - configurationFilename = filename; - } - - public void setConfigurationDescription(string desc) - { - configurationDescription = desc; - } - - public void setConfigurationResultFunction(ConfigurationOptionResult result) - { - resultFunction = result; - } - - public void forceConfigurationPluginLibrary(string dll_filename) - { - configurationPluginFilename = dll_filename; - } - - private void checkAndAddConfigOption(ConfigurationOption option) - { - if ((option.configurationKey != "" && option.configurationQuestion != "") || - (option.configurationKey != "" && option.configurationUseDefaultNoPrompt)) - { - if (!configurationOptions.Contains(option)) - { - configurationOptions.Add(option); - } - } - else - { - MainLog.Instance.Notice( - "Required fields for adding a configuration option is invalid. Will not add this option (" + - option.configurationKey + ")"); - } - } - - public void addConfigurationOption(string configuration_key, - ConfigurationOption.ConfigurationTypes configuration_type, - string configuration_question, string configuration_default, - bool use_default_no_prompt) - { - ConfigurationOption configOption = new ConfigurationOption(); - configOption.configurationKey = configuration_key; - configOption.configurationQuestion = configuration_question; - configOption.configurationDefault = configuration_default; - configOption.configurationType = configuration_type; - configOption.configurationUseDefaultNoPrompt = use_default_no_prompt; - configOption.shouldIBeAsked = null; //Assumes true, I can ask whenever - checkAndAddConfigOption(configOption); - } - - public void addConfigurationOption(string configuration_key, - ConfigurationOption.ConfigurationTypes configuration_type, - string configuration_question, string configuration_default, - bool use_default_no_prompt, - ConfigurationOption.ConfigurationOptionShouldBeAsked shouldIBeAskedDelegate) - { - ConfigurationOption configOption = new ConfigurationOption(); - configOption.configurationKey = configuration_key; - configOption.configurationQuestion = configuration_question; - configOption.configurationDefault = configuration_default; - configOption.configurationType = configuration_type; - configOption.configurationUseDefaultNoPrompt = use_default_no_prompt; - configOption.shouldIBeAsked = shouldIBeAskedDelegate; - checkAndAddConfigOption(configOption); - } - - - // TEMP - REMOVE - private int cE = 0; - public void performConfigurationRetrieve() - { - if (cE > 1) - MainLog.Instance.Error("READING CONFIGURATION COUT: " + cE.ToString()); - - - configurationPlugin = LoadConfigDll(configurationPluginFilename); - configurationOptions.Clear(); - if (loadFunction == null) - { - MainLog.Instance.Error("Load Function for '" + configurationDescription + - "' is null. Refusing to run configuration."); - return; - } - - if (resultFunction == null) - { - MainLog.Instance.Error("Result Function for '" + configurationDescription + - "' is null. Refusing to run configuration."); - return; - } - - MainLog.Instance.Verbose("CONFIG", "Calling Configuration Load Function..."); - loadFunction(); - - if (configurationOptions.Count <= 0) - { - MainLog.Instance.Error("CONFIG", - "No configuration options were specified for '" + configurationOptions + - "'. Refusing to continue configuration."); - return; - } - - bool useFile = true; - if (configurationPlugin == null) - { - MainLog.Instance.Error("CONFIG", "Configuration Plugin NOT LOADED!"); - return; - } - - if (configurationFilename.Trim() != "") - { - configurationPlugin.SetFileName(configurationFilename); - try - { - configurationPlugin.LoadData(); - useFile = true; - } - catch (XmlException e) - { - MainLog.Instance.Error("Error loading " + configurationFilename + ": " + e.ToString()); - useFile = false; - } - } - else - { - if (configurationFromXMLNode != null) - { - MainLog.Instance.Notice("Loading from XML Node, will not save to the file"); - configurationPlugin.LoadDataFromString(configurationFromXMLNode.OuterXml); - } - - MainLog.Instance.Notice("XML Configuration Filename is not valid; will not save to the file."); - useFile = false; - } - - foreach (ConfigurationOption configOption in configurationOptions) - { - bool convertSuccess = false; - object return_result = null; - string errorMessage = ""; - bool ignoreNextFromConfig = false; - while (convertSuccess == false) - { - string console_result = ""; - string attribute = null; - if (useFile || configurationFromXMLNode != null) - { - if (!ignoreNextFromConfig) - { - attribute = configurationPlugin.GetAttribute(configOption.configurationKey); - } - else - { - ignoreNextFromConfig = false; - } - } - - if (attribute == null) - { - if (configOption.configurationUseDefaultNoPrompt || useConsoleToPromptOnError == false) - { - console_result = configOption.configurationDefault; - } - else - { - if ((configOption.shouldIBeAsked != null && - configOption.shouldIBeAsked(configOption.configurationKey)) || - configOption.shouldIBeAsked == null) - { - if (configurationDescription.Trim() != "") - { - console_result = - MainLog.Instance.CmdPrompt( - configurationDescription + ": " + configOption.configurationQuestion, - configOption.configurationDefault); - } - else - { - console_result = - MainLog.Instance.CmdPrompt(configOption.configurationQuestion, - configOption.configurationDefault); - } - } - else - { - //Dont Ask! Just use default - console_result = configOption.configurationDefault; - } - } - } - else - { - console_result = attribute; - } - - switch (configOption.configurationType) - { - case ConfigurationOption.ConfigurationTypes.TYPE_STRING: - return_result = console_result; - convertSuccess = true; - break; - case ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY: - if (console_result.Length > 0) - { - return_result = console_result; - convertSuccess = true; - } - errorMessage = "a string that is not empty"; - break; - case ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN: - bool boolResult; - if (Boolean.TryParse(console_result, out boolResult)) - { - convertSuccess = true; - return_result = boolResult; - } - errorMessage = "'true' or 'false' (Boolean)"; - break; - case ConfigurationOption.ConfigurationTypes.TYPE_BYTE: - byte byteResult; - if (Byte.TryParse(console_result, out byteResult)) - { - convertSuccess = true; - return_result = byteResult; - } - errorMessage = "a byte (Byte)"; - break; - case ConfigurationOption.ConfigurationTypes.TYPE_CHARACTER: - char charResult; - if (Char.TryParse(console_result, out charResult)) - { - convertSuccess = true; - return_result = charResult; - } - errorMessage = "a character (Char)"; - break; - case ConfigurationOption.ConfigurationTypes.TYPE_INT16: - short shortResult; - if (Int16.TryParse(console_result, out shortResult)) - { - convertSuccess = true; - return_result = shortResult; - } - errorMessage = "a signed 32 bit integer (short)"; - break; - case ConfigurationOption.ConfigurationTypes.TYPE_INT32: - int intResult; - if (Int32.TryParse(console_result, out intResult)) - { - convertSuccess = true; - return_result = intResult; - } - errorMessage = "a signed 32 bit integer (int)"; - break; - case ConfigurationOption.ConfigurationTypes.TYPE_INT64: - long longResult; - if (Int64.TryParse(console_result, out longResult)) - { - convertSuccess = true; - return_result = longResult; - } - errorMessage = "a signed 32 bit integer (long)"; - break; - case ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS: - IPAddress ipAddressResult; - if (IPAddress.TryParse(console_result, out ipAddressResult)) - { - convertSuccess = true; - return_result = ipAddressResult; - } - errorMessage = "an IP Address (IPAddress)"; - break; - case ConfigurationOption.ConfigurationTypes.TYPE_LLUUID: - LLUUID uuidResult; - if (LLUUID.TryParse(console_result, out uuidResult)) - { - convertSuccess = true; - return_result = uuidResult; - } - errorMessage = "a UUID (LLUUID)"; - break; - case ConfigurationOption.ConfigurationTypes.TYPE_LLVECTOR3: - LLVector3 vectorResult; - if (LLVector3.TryParse(console_result, out vectorResult)) - { - convertSuccess = true; - return_result = vectorResult; - } - errorMessage = "a vector (LLVector3)"; - break; - case ConfigurationOption.ConfigurationTypes.TYPE_UINT16: - ushort ushortResult; - if (UInt16.TryParse(console_result, out ushortResult)) - { - convertSuccess = true; - return_result = ushortResult; - } - errorMessage = "an unsigned 16 bit integer (ushort)"; - break; - case ConfigurationOption.ConfigurationTypes.TYPE_UINT32: - uint uintResult; - if (UInt32.TryParse(console_result, out uintResult)) - { - convertSuccess = true; - return_result = uintResult; - } - errorMessage = "an unsigned 32 bit integer (uint)"; - break; - case ConfigurationOption.ConfigurationTypes.TYPE_UINT64: - ulong ulongResult; - if (UInt64.TryParse(console_result, out ulongResult)) - { - convertSuccess = true; - return_result = ulongResult; - } - errorMessage = "an unsigned 64 bit integer (ulong)"; - break; - case ConfigurationOption.ConfigurationTypes.TYPE_FLOAT: - float floatResult; - if ( - float.TryParse(console_result, NumberStyles.AllowDecimalPoint, Culture.NumberFormatInfo, - out floatResult)) - { - convertSuccess = true; - return_result = floatResult; - } - errorMessage = "a single-precision floating point number (float)"; - break; - case ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE: - double doubleResult; - if ( - Double.TryParse(console_result, NumberStyles.AllowDecimalPoint, Culture.NumberFormatInfo, - out doubleResult)) - { - convertSuccess = true; - return_result = doubleResult; - } - errorMessage = "an double-precision floating point number (double)"; - break; - } - - if (convertSuccess) - { - if (useFile) - { - configurationPlugin.SetAttribute(configOption.configurationKey, console_result); - } - - if (!resultFunction(configOption.configurationKey, return_result)) - { - MainLog.Instance.Notice( - "The handler for the last configuration option denied that input, please try again."); - convertSuccess = false; - ignoreNextFromConfig = true; - } - } - else - { - if (configOption.configurationUseDefaultNoPrompt) - { - MainLog.Instance.Error("CONFIG", - string.Format( - "[{3}]:[{1}] is not valid default for parameter [{0}].\nThe configuration result must be parsable to {2}.\n", - configOption.configurationKey, console_result, errorMessage, - configurationFilename)); - convertSuccess = true; - } - else - { - MainLog.Instance.Warn("CONFIG", - string.Format( - "[{3}]:[{1}] is not a valid value [{0}].\nThe configuration result must be parsable to {2}.\n", - configOption.configurationKey, console_result, errorMessage, - configurationFilename)); - ignoreNextFromConfig = true; - } - } - } - } - - if (useFile) - { - configurationPlugin.Commit(); - configurationPlugin.Close(); - } - } - - private IGenericConfig LoadConfigDll(string dllName) - { - Assembly pluginAssembly = Assembly.LoadFrom(dllName); - IGenericConfig plug = null; - - foreach (Type pluginType in pluginAssembly.GetTypes()) - { - if (pluginType.IsPublic) - { - if (!pluginType.IsAbstract) - { - Type typeInterface = pluginType.GetInterface("IGenericConfig", true); - - if (typeInterface != null) - { - plug = - (IGenericConfig) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); - } - } - } - } - - pluginAssembly = null; - return plug; - } - - public void forceSetConfigurationOption(string configuration_key, string configuration_value) - { - configurationPlugin.LoadData(); - configurationPlugin.SetAttribute(configuration_key, configuration_value); - configurationPlugin.Commit(); - configurationPlugin.Close(); - } - } -} \ No newline at end of file +/* +* 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.Generic; +using System.Globalization; +using System.Net; +using System.Reflection; +using System.Xml; +using libsecondlife; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework +{ + public class ConfigurationMember + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + public delegate bool ConfigurationOptionResult(string configuration_key, object configuration_result); + + public delegate void ConfigurationOptionsLoad(); + + private List configurationOptions = new List(); + private string configurationFilename = String.Empty; + private string configurationDescription = String.Empty; + private XmlNode configurationFromXMLNode = null; + private ConfigurationOptionsLoad loadFunction; + private ConfigurationOptionResult resultFunction; + + private IGenericConfig configurationPlugin = null; + private bool useConsoleToPromptOnError = true; + /// + /// This is the default configuration DLL loaded + /// + private string configurationPluginFilename = "OpenSim.Framework.Configuration.XML.dll"; + + public ConfigurationMember(string configuration_filename, string configuration_description, + ConfigurationOptionsLoad load_function, ConfigurationOptionResult result_function, bool use_console_to_prompt_on_error) + { + configurationFilename = configuration_filename; + configurationDescription = configuration_description; + loadFunction = load_function; + resultFunction = result_function; + useConsoleToPromptOnError = use_console_to_prompt_on_error; + } + + public ConfigurationMember(XmlNode configuration_xml, string configuration_description, + ConfigurationOptionsLoad load_function, ConfigurationOptionResult result_function, bool use_console_to_prompt_on_error) + { + configurationFilename = String.Empty; + configurationFromXMLNode = configuration_xml; + configurationDescription = configuration_description; + loadFunction = load_function; + resultFunction = result_function; + useConsoleToPromptOnError = use_console_to_prompt_on_error; + } + + public void setConfigurationFilename(string filename) + { + configurationFilename = filename; + } + + public void setConfigurationDescription(string desc) + { + configurationDescription = desc; + } + + public void setConfigurationResultFunction(ConfigurationOptionResult result) + { + resultFunction = result; + } + + public void forceConfigurationPluginLibrary(string dll_filename) + { + configurationPluginFilename = dll_filename; + } + + private void checkAndAddConfigOption(ConfigurationOption option) + { + if ((option.configurationKey != String.Empty && option.configurationQuestion != String.Empty) || + (option.configurationKey != String.Empty && option.configurationUseDefaultNoPrompt)) + { + if (!configurationOptions.Contains(option)) + { + configurationOptions.Add(option); + } + } + else + { + m_log.Info( + "Required fields for adding a configuration option is invalid. Will not add this option (" + + option.configurationKey + ")"); + } + } + + public void addConfigurationOption(string configuration_key, + ConfigurationOption.ConfigurationTypes configuration_type, + string configuration_question, string configuration_default, + bool use_default_no_prompt) + { + ConfigurationOption configOption = new ConfigurationOption(); + configOption.configurationKey = configuration_key; + configOption.configurationQuestion = configuration_question; + configOption.configurationDefault = configuration_default; + configOption.configurationType = configuration_type; + configOption.configurationUseDefaultNoPrompt = use_default_no_prompt; + configOption.shouldIBeAsked = null; //Assumes true, I can ask whenever + checkAndAddConfigOption(configOption); + } + + public void addConfigurationOption(string configuration_key, + ConfigurationOption.ConfigurationTypes configuration_type, + string configuration_question, string configuration_default, + bool use_default_no_prompt, + ConfigurationOption.ConfigurationOptionShouldBeAsked shouldIBeAskedDelegate) + { + ConfigurationOption configOption = new ConfigurationOption(); + configOption.configurationKey = configuration_key; + configOption.configurationQuestion = configuration_question; + configOption.configurationDefault = configuration_default; + configOption.configurationType = configuration_type; + configOption.configurationUseDefaultNoPrompt = use_default_no_prompt; + configOption.shouldIBeAsked = shouldIBeAskedDelegate; + checkAndAddConfigOption(configOption); + } + + // TEMP - REMOVE + private int cE = 0; + public void performConfigurationRetrieve() + { + if (cE > 1) + m_log.Error("READING CONFIGURATION COUT: " + cE.ToString()); + + + configurationPlugin = LoadConfigDll(configurationPluginFilename); + configurationOptions.Clear(); + if (loadFunction == null) + { + m_log.Error("Load Function for '" + configurationDescription + + "' is null. Refusing to run configuration."); + return; + } + + if (resultFunction == null) + { + m_log.Error("Result Function for '" + configurationDescription + + "' is null. Refusing to run configuration."); + return; + } + + m_log.Info("[CONFIG]: Calling Configuration Load Function..."); + loadFunction(); + + if (configurationOptions.Count <= 0) + { + m_log.Error("[CONFIG]: No configuration options were specified for '" + configurationOptions + + "'. Refusing to continue configuration."); + return; + } + + bool useFile = true; + if (configurationPlugin == null) + { + m_log.Error("[CONFIG]: Configuration Plugin NOT LOADED!"); + return; + } + + if (configurationFilename.Trim() != String.Empty) + { + configurationPlugin.SetFileName(configurationFilename); + try + { + configurationPlugin.LoadData(); + useFile = true; + } + catch (XmlException e) + { + m_log.Error("Error loading " + configurationFilename + ": " + e.ToString()); + useFile = false; + } + } + else + { + if (configurationFromXMLNode != null) + { + m_log.Info("Loading from XML Node, will not save to the file"); + configurationPlugin.LoadDataFromString(configurationFromXMLNode.OuterXml); + } + + m_log.Info("XML Configuration Filename is not valid; will not save to the file."); + useFile = false; + } + + foreach (ConfigurationOption configOption in configurationOptions) + { + bool convertSuccess = false; + object return_result = null; + string errorMessage = String.Empty; + bool ignoreNextFromConfig = false; + while (convertSuccess == false) + { + string console_result = String.Empty; + string attribute = null; + if (useFile || configurationFromXMLNode != null) + { + if (!ignoreNextFromConfig) + { + attribute = configurationPlugin.GetAttribute(configOption.configurationKey); + } + else + { + ignoreNextFromConfig = false; + } + } + + if (attribute == null) + { + if (configOption.configurationUseDefaultNoPrompt || useConsoleToPromptOnError == false) + { + console_result = configOption.configurationDefault; + } + else + { + if ((configOption.shouldIBeAsked != null && + configOption.shouldIBeAsked(configOption.configurationKey)) || + configOption.shouldIBeAsked == null) + { + if (configurationDescription.Trim() != String.Empty) + { + console_result = + MainConsole.Instance.CmdPrompt( + configurationDescription + ": " + configOption.configurationQuestion, + configOption.configurationDefault); + } + else + { + console_result = + MainConsole.Instance.CmdPrompt(configOption.configurationQuestion, + configOption.configurationDefault); + } + } + else + { + //Dont Ask! Just use default + console_result = configOption.configurationDefault; + } + } + } + else + { + console_result = attribute; + } + + switch (configOption.configurationType) + { + case ConfigurationOption.ConfigurationTypes.TYPE_STRING: + return_result = console_result; + convertSuccess = true; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY: + if (console_result.Length > 0) + { + return_result = console_result; + convertSuccess = true; + } + errorMessage = "a string that is not empty"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN: + bool boolResult; + if (Boolean.TryParse(console_result, out boolResult)) + { + convertSuccess = true; + return_result = boolResult; + } + errorMessage = "'true' or 'false' (Boolean)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_BYTE: + byte byteResult; + if (Byte.TryParse(console_result, out byteResult)) + { + convertSuccess = true; + return_result = byteResult; + } + errorMessage = "a byte (Byte)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_CHARACTER: + char charResult; + if (Char.TryParse(console_result, out charResult)) + { + convertSuccess = true; + return_result = charResult; + } + errorMessage = "a character (Char)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_INT16: + short shortResult; + if (Int16.TryParse(console_result, out shortResult)) + { + convertSuccess = true; + return_result = shortResult; + } + errorMessage = "a signed 32 bit integer (short)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_INT32: + int intResult; + if (Int32.TryParse(console_result, out intResult)) + { + convertSuccess = true; + return_result = intResult; + } + errorMessage = "a signed 32 bit integer (int)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_INT64: + long longResult; + if (Int64.TryParse(console_result, out longResult)) + { + convertSuccess = true; + return_result = longResult; + } + errorMessage = "a signed 32 bit integer (long)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS: + IPAddress ipAddressResult; + if (IPAddress.TryParse(console_result, out ipAddressResult)) + { + convertSuccess = true; + return_result = ipAddressResult; + } + errorMessage = "an IP Address (IPAddress)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_LLUUID: + LLUUID uuidResult; + if (LLUUID.TryParse(console_result, out uuidResult)) + { + convertSuccess = true; + return_result = uuidResult; + } + errorMessage = "a UUID (LLUUID)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_LLVECTOR3: + LLVector3 vectorResult; + if (LLVector3.TryParse(console_result, out vectorResult)) + { + convertSuccess = true; + return_result = vectorResult; + } + errorMessage = "a vector (LLVector3)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_UINT16: + ushort ushortResult; + if (UInt16.TryParse(console_result, out ushortResult)) + { + convertSuccess = true; + return_result = ushortResult; + } + errorMessage = "an unsigned 16 bit integer (ushort)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_UINT32: + uint uintResult; + if (UInt32.TryParse(console_result, out uintResult)) + { + convertSuccess = true; + return_result = uintResult; + } + errorMessage = "an unsigned 32 bit integer (uint)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_UINT64: + ulong ulongResult; + if (UInt64.TryParse(console_result, out ulongResult)) + { + convertSuccess = true; + return_result = ulongResult; + } + errorMessage = "an unsigned 64 bit integer (ulong)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_FLOAT: + float floatResult; + if ( + float.TryParse(console_result, NumberStyles.AllowDecimalPoint, Culture.NumberFormatInfo, + out floatResult)) + { + convertSuccess = true; + return_result = floatResult; + } + errorMessage = "a single-precision floating point number (float)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE: + double doubleResult; + if ( + Double.TryParse(console_result, NumberStyles.AllowDecimalPoint, Culture.NumberFormatInfo, + out doubleResult)) + { + convertSuccess = true; + return_result = doubleResult; + } + errorMessage = "an double-precision floating point number (double)"; + break; + } + + if (convertSuccess) + { + if (useFile) + { + configurationPlugin.SetAttribute(configOption.configurationKey, console_result); + } + + if (!resultFunction(configOption.configurationKey, return_result)) + { + m_log.Info( + "The handler for the last configuration option denied that input, please try again."); + convertSuccess = false; + ignoreNextFromConfig = true; + } + } + else + { + if (configOption.configurationUseDefaultNoPrompt) + { + m_log.Error(string.Format( + "[CONFIG]: [{3}]:[{1}] is not valid default for parameter [{0}].\nThe configuration result must be parsable to {2}.\n", + configOption.configurationKey, console_result, errorMessage, + configurationFilename)); + convertSuccess = true; + } + else + { + m_log.Warn(string.Format( + "[CONFIG]: [{3}]:[{1}] is not a valid value [{0}].\nThe configuration result must be parsable to {2}.\n", + configOption.configurationKey, console_result, errorMessage, + configurationFilename)); + ignoreNextFromConfig = true; + } + } + } + } + + if (useFile) + { + configurationPlugin.Commit(); + configurationPlugin.Close(); + } + } + + private IGenericConfig LoadConfigDll(string dllName) + { + Assembly pluginAssembly = Assembly.LoadFrom(dllName); + IGenericConfig plug = null; + + foreach (Type pluginType in pluginAssembly.GetTypes()) + { + if (pluginType.IsPublic) + { + if (!pluginType.IsAbstract) + { + Type typeInterface = pluginType.GetInterface("IGenericConfig", true); + + if (typeInterface != null) + { + plug = + (IGenericConfig) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); + } + } + } + } + + pluginAssembly = null; + return plug; + } + + public void forceSetConfigurationOption(string configuration_key, string configuration_value) + { + configurationPlugin.LoadData(); + configurationPlugin.SetAttribute(configuration_key, configuration_value); + configurationPlugin.Commit(); + configurationPlugin.Close(); + } + } +} diff --git a/OpenSim/Framework/ConfigurationOption.cs b/OpenSim/Framework/ConfigurationOption.cs index e3a26e0a58..185b25ab79 100644 --- a/OpenSim/Framework/ConfigurationOption.cs +++ b/OpenSim/Framework/ConfigurationOption.cs @@ -1,63 +1,65 @@ -/* -* 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. -* -*/ - -namespace OpenSim.Framework -{ - public class ConfigurationOption - { - public delegate bool ConfigurationOptionShouldBeAsked(string configuration_key); - - public enum ConfigurationTypes - { - TYPE_STRING, - TYPE_STRING_NOT_EMPTY, - TYPE_UINT16, - TYPE_UINT32, - TYPE_UINT64, - TYPE_INT16, - TYPE_INT32, - TYPE_INT64, - TYPE_IP_ADDRESS, - TYPE_CHARACTER, - TYPE_BOOLEAN, - TYPE_BYTE, - TYPE_LLUUID, - TYPE_LLVECTOR3, - TYPE_FLOAT, - TYPE_DOUBLE - } ; - - public string configurationKey = ""; - public string configurationQuestion = ""; - public string configurationDefault = ""; - - public ConfigurationTypes configurationType = ConfigurationTypes.TYPE_STRING; - public bool configurationUseDefaultNoPrompt = false; - public ConfigurationOptionShouldBeAsked shouldIBeAsked; //Should I be asked now? Based on previous answers - } -} \ No newline at end of file +/* +* 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; + +namespace OpenSim.Framework +{ + public class ConfigurationOption + { + public delegate bool ConfigurationOptionShouldBeAsked(string configuration_key); + + public enum ConfigurationTypes + { + TYPE_STRING, + TYPE_STRING_NOT_EMPTY, + TYPE_UINT16, + TYPE_UINT32, + TYPE_UINT64, + TYPE_INT16, + TYPE_INT32, + TYPE_INT64, + TYPE_IP_ADDRESS, + TYPE_CHARACTER, + TYPE_BOOLEAN, + TYPE_BYTE, + TYPE_LLUUID, + TYPE_LLVECTOR3, + TYPE_FLOAT, + TYPE_DOUBLE + } ; + + public string configurationKey = String.Empty; + public string configurationQuestion = String.Empty; + public string configurationDefault = String.Empty; + + public ConfigurationTypes configurationType = ConfigurationTypes.TYPE_STRING; + public bool configurationUseDefaultNoPrompt = false; + public ConfigurationOptionShouldBeAsked shouldIBeAsked; //Should I be asked now? Based on previous answers + } +} diff --git a/OpenSim/Framework/Console/AssemblyInfo.cs b/OpenSim/Framework/Console/AssemblyInfo.cs index e6c68afc67..07a4a5aa38 100644 --- a/OpenSim/Framework/Console/AssemblyInfo.cs +++ b/OpenSim/Framework/Console/AssemblyInfo.cs @@ -1,58 +1,58 @@ -/* -* 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.Reflection; -using System.Runtime.InteropServices; - -// Information about this assembly is defined by the following -// attributes. -// -// change them to the information which is associated with the assembly -// you compile. - -[assembly : AssemblyTitle("ServerConsole")] -[assembly : AssemblyDescription("")] -[assembly : AssemblyConfiguration("")] -[assembly : AssemblyCompany("")] -[assembly : AssemblyProduct("ServerConsole")] -[assembly : AssemblyCopyright("")] -[assembly : AssemblyTrademark("")] -[assembly : AssemblyCulture("")] - -// This sets the default COM visibility of types in the assembly to invisible. -// If you need to expose a type to COM, use [ComVisible(true)] on that type. - -[assembly : ComVisible(false)] - -// The assembly version has following format : -// -// Major.Minor.Build.Revision -// -// You can specify all values by your own or you can build default build and revision -// numbers with the '*' character (the default): - -[assembly : AssemblyVersion("1.0.*")] \ No newline at end of file +/* +* 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.Reflection; +using System.Runtime.InteropServices; + +// Information about this assembly is defined by the following +// attributes. +// +// change them to the information which is associated with the assembly +// you compile. + +[assembly : AssemblyTitle("ServerConsole")] +[assembly : AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly : AssemblyProduct("ServerConsole")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. + +[assembly : ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all values by your own or you can build default build and revision +// numbers with the '*' character (the default): + +[assembly : AssemblyVersion("1.0.*")] diff --git a/OpenSim/Framework/Console/LogBase.cs b/OpenSim/Framework/Console/ConsoleBase.cs similarity index 63% rename from OpenSim/Framework/Console/LogBase.cs rename to OpenSim/Framework/Console/ConsoleBase.cs index 258f43423b..2a996c5f96 100644 --- a/OpenSim/Framework/Console/LogBase.cs +++ b/OpenSim/Framework/Console/ConsoleBase.cs @@ -1,482 +1,424 @@ -/* -* 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.Generic; -using System.Diagnostics; -using System.IO; -using System.Net; - -namespace OpenSim.Framework.Console -{ - public enum LogPriority : int - { - CRITICAL, - HIGH, - MEDIUM, - NORMAL, - LOW, - VERBOSE, - EXTRAVERBOSE - } - - public class LogBase - { - private object m_syncRoot = new object(); - - private StreamWriter Log; - public conscmd_callback cmdparser; - public string componentname; - private bool m_verbose; - - public LogBase(string LogFile, string componentname, conscmd_callback cmdparser, bool verbose) - { - this.componentname = componentname; - this.cmdparser = cmdparser; - m_verbose = verbose; - System.Console.WriteLine("Creating new local console"); - - if (String.IsNullOrEmpty(LogFile)) - { - LogFile = componentname + ".log"; - } - - System.Console.WriteLine("Logs will be saved to current directory in " + LogFile); - - Log = File.AppendText(LogFile); - Log.WriteLine("========================================================================"); - Log.WriteLine(componentname + " Started at " + DateTime.Now.ToString()); - } - - public void Close() - { - Log.WriteLine("Shutdown at " + DateTime.Now.ToString()); - Log.Close(); - } - - /// - /// derive an ansi color from a string, ignoring the darker colors. - /// This is used to help automatically bin component tags with colors - /// in various print functions. - /// - /// arbitrary string for input - /// an ansii color - private ConsoleColor DeriveColor(string input) - { - int colIdx = (input.ToUpper().GetHashCode()%6) + 9; - return (ConsoleColor) colIdx; - } - - /// - /// Sends a warning to the current log output - /// - /// The message to send - /// WriteLine-style message arguments - public void Warn(string format, params object[] args) - { - WriteNewLine(ConsoleColor.Yellow, format, args); - return; - } - - /// - /// Sends a warning to the current log output - /// - /// The module that sent this message - /// The message to send - /// WriteLine-style message arguments - public void Warn(string sender, string format, params object[] args) - { - WritePrefixLine(DeriveColor(sender), sender); - WriteNewLine(ConsoleColor.Yellow, format, args); - return; - } - - /// - /// Sends a notice to the current log output - /// - /// The message to send - /// WriteLine-style message arguments - public void Notice(string format, params object[] args) - { - WriteNewLine(ConsoleColor.White, format, args); - return; - } - - /// - /// Sends a notice to the current log output - /// - /// The module that sent this message - /// The message to send - /// WriteLine-style message arguments - public void Notice(string sender, string format, params object[] args) - { - WritePrefixLine(DeriveColor(sender), sender); - WriteNewLine(ConsoleColor.White, format, args); - return; - } - - /// - /// Sends an error to the current log output - /// - /// The message to send - /// WriteLine-style message arguments - public void Error(string format, params object[] args) - { - WriteNewLine(ConsoleColor.Red, format, args); - return; - } - - /// - /// Sends an error to the current log output - /// - /// The module that sent this message - /// The message to send - /// WriteLine-style message arguments - public void Error(string sender, string format, params object[] args) - { - WritePrefixLine(DeriveColor(sender), sender); - Error(format, args); - return; - } - - /// - /// Sends an informational message to the current log output - /// - /// The module that sent this message - /// The message to send - /// WriteLine-style message arguments - public void Verbose(string sender, string format, params object[] args) - { - if (m_verbose) - { - WritePrefixLine(DeriveColor(sender), sender); - WriteNewLine(ConsoleColor.Gray, format, args); - return; - } - } - - /// - /// Sends a status message to the current log output - /// - /// The message to send - /// WriteLine-style message arguments - public void Status(string format, params object[] args) - { - WriteNewLine(ConsoleColor.Blue, format, args); - return; - } - - /// - /// Sends a status message to the current log output - /// - /// The module that sent this message - /// The message to send - /// WriteLine-style message arguments - public void Status(string sender, string format, params object[] args) - { - WritePrefixLine(DeriveColor(sender), sender); - WriteNewLine(ConsoleColor.Blue, format, args); - return; - } - - [Conditional("DEBUG")] - public void Debug(string format, params object[] args) - { - WriteNewLine(ConsoleColor.Gray, format, args); - return; - } - - [Conditional("DEBUG")] - public void Debug(string sender, string format, params object[] args) - { - WritePrefixLine(DeriveColor(sender), sender); - WriteNewLine(ConsoleColor.Gray, format, args); - return; - } - - private void WriteNewLine(ConsoleColor color, string format, params object[] args) - { - lock (m_syncRoot) - { - string now = DateTime.Now.ToString("[MM-dd hh:mm:ss] "); - Log.Write(now); - try - { - Log.WriteLine(format, args); - Log.Flush(); - } - - catch (FormatException) - { - System.Console.WriteLine(args); - } - System.Console.Write(now); - try - { - if (color != ConsoleColor.White) - System.Console.ForegroundColor = color; - - System.Console.WriteLine(format, args); - System.Console.ResetColor(); - } - catch (ArgumentNullException) - { - // Some older systems dont support coloured text. - System.Console.WriteLine(format, args); - } - catch (FormatException) - { - // Some older systems dont support coloured text. - System.Console.WriteLine(args); - } - - return; - } - } - - private void WritePrefixLine(ConsoleColor color, string sender) - { - lock (m_syncRoot) - { - sender = sender.ToUpper(); - Log.WriteLine("[" + sender + "] "); - Log.Flush(); - - System.Console.Write("["); - - try - { - System.Console.ForegroundColor = color; - System.Console.Write(sender); - System.Console.ResetColor(); - } - catch (ArgumentNullException) - { - // Some older systems dont support coloured text. - System.Console.WriteLine(sender); - } - - System.Console.Write("] \t"); - - return; - } - } - - - public string ReadLine() - { - try - { - string TempStr = System.Console.ReadLine(); - Log.WriteLine(TempStr); - return TempStr; - } - catch (Exception e) - { - MainLog.Instance.Error("Console", "System.Console.ReadLine exception " + e.ToString()); - return ""; - } - } - - public int Read() - { - int TempInt = System.Console.Read(); - Log.Write((char) TempInt); - return TempInt; - } - - public IPAddress CmdPromptIPAddress(string prompt, string defaultvalue) - { - IPAddress address; - string addressStr; - - while (true) - { - addressStr = MainLog.Instance.CmdPrompt(prompt, defaultvalue); - if (IPAddress.TryParse(addressStr, out address)) - { - break; - } - else - { - MainLog.Instance.Error("Illegal address. Please re-enter."); - } - } - - return address; - } - - public uint CmdPromptIPPort(string prompt, string defaultvalue) - { - uint port; - string portStr; - - while (true) - { - portStr = MainLog.Instance.CmdPrompt(prompt, defaultvalue); - if (uint.TryParse(portStr, out port)) - { - if (port >= IPEndPoint.MinPort && port <= IPEndPoint.MaxPort) - { - break; - } - } - - MainLog.Instance.Error("Illegal address. Please re-enter."); - } - - return port; - } - - // Displays a prompt and waits for the user to enter a string, then returns that string - // Done with no echo and suitable for passwords - public string PasswdPrompt(string prompt) - { - // FIXME: Needs to be better abstracted - Log.WriteLine(prompt); - Notice(prompt); - ConsoleColor oldfg = System.Console.ForegroundColor; - System.Console.ForegroundColor = System.Console.BackgroundColor; - string temp = System.Console.ReadLine(); - System.Console.ForegroundColor = oldfg; - return temp; - } - - // Displays a command prompt and waits for the user to enter a string, then returns that string - public string CmdPrompt(string prompt) - { - Notice(String.Format("{0}: ", prompt)); - return ReadLine(); - } - - // Displays a command prompt and returns a default value if the user simply presses enter - public string CmdPrompt(string prompt, string defaultresponse) - { - string temp = CmdPrompt(String.Format("{0} [{1}]", prompt, defaultresponse)); - if (temp == "") - { - return defaultresponse; - } - else - { - return temp; - } - } - - // Displays a command prompt and returns a default value, user may only enter 1 of 2 options - public string CmdPrompt(string prompt, string defaultresponse, string OptionA, string OptionB) - { - bool itisdone = false; - string temp = CmdPrompt(prompt, defaultresponse); - while (itisdone == false) - { - if ((temp == OptionA) || (temp == OptionB)) - { - itisdone = true; - } - else - { - Notice("Valid options are " + OptionA + " or " + OptionB); - temp = CmdPrompt(prompt, defaultresponse); - } - } - return temp; - } - - // Runs a command with a number of parameters - public Object RunCmd(string Cmd, string[] cmdparams) - { - cmdparser.RunCmd(Cmd, cmdparams); - return null; - } - - // Shows data about something - public void ShowCommands(string ShowWhat) - { - cmdparser.Show(ShowWhat); - } - - public void MainLogPrompt() - { - string tempstr = CmdPrompt(componentname + "# "); - MainLogRunCommand(tempstr); - } - - public void MainLogRunCommand(string command) - { - string[] tempstrarray; - tempstrarray = command.Split(' '); - string cmd = tempstrarray[0]; - Array.Reverse(tempstrarray); - Array.Resize(ref tempstrarray, tempstrarray.Length - 1); - Array.Reverse(tempstrarray); - string[] cmdparams = (string[]) tempstrarray; - try - { - RunCmd(cmd, cmdparams); - } - catch (Exception e) - { - MainLog.Instance.Error("Console", "Command failed with exception " + e.ToString()); - } - } - - public string LineInfo - { - get - { - string result = String.Empty; - - string stacktrace = Environment.StackTrace; - List lines = new List(stacktrace.Split(new string[] {"at "}, StringSplitOptions.None)); - - if (lines.Count > 4) - { - lines.RemoveRange(0, 4); - - string tmpLine = lines[0]; - - int inIndex = tmpLine.IndexOf(" in "); - - if (inIndex > -1) - { - result = tmpLine.Substring(0, inIndex); - - int lineIndex = tmpLine.IndexOf(":line "); - - if (lineIndex > -1) - { - lineIndex += 6; - result += ", line " + tmpLine.Substring(lineIndex, (tmpLine.Length - lineIndex) - 5); - } - } - } - return result; - } - } - } -} \ No newline at end of file +/* +* 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.Generic; +using System.Diagnostics; +using System.IO; +using System.Net; + +namespace OpenSim.Framework.Console +{ + public class ConsoleBase + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private readonly object m_syncRoot = new object(); + + public conscmd_callback m_cmdParser; + public string m_componentName; + + public ConsoleBase(string componentname, conscmd_callback cmdparser) + { + m_componentName = componentname; + m_cmdParser = cmdparser; + + System.Console.WriteLine("Creating new local console"); + + m_log.Info("[" + m_componentName + "]: Started at " + DateTime.Now.ToString()); + } + + public void Close() + { + m_log.Info("[" + m_componentName + "]: Shutdown at " + DateTime.Now.ToString()); + } + + /// + /// derive an ansi color from a string, ignoring the darker colors. + /// This is used to help automatically bin component tags with colors + /// in various print functions. + /// + /// arbitrary string for input + /// an ansii color + private ConsoleColor DeriveColor(string input) + { + int colIdx = (input.ToUpper().GetHashCode() % 6) + 9; + return (ConsoleColor) colIdx; + } + + /// + /// Sends a warning to the current console output + /// + /// The message to send + /// WriteLine-style message arguments + public void Warn(string format, params object[] args) + { + WriteNewLine(ConsoleColor.Yellow, format, args); + } + + /// + /// Sends a warning to the current console output + /// + /// The module that sent this message + /// The message to send + /// WriteLine-style message arguments + public void Warn(string sender, string format, params object[] args) + { + WritePrefixLine(DeriveColor(sender), sender); + WriteNewLine(ConsoleColor.Yellow, format, args); + } + + /// + /// Sends a notice to the current console output + /// + /// The message to send + /// WriteLine-style message arguments + public void Notice(string format, params object[] args) + { + WriteNewLine(ConsoleColor.White, format, args); + } + + /// + /// Sends a notice to the current console output + /// + /// The module that sent this message + /// The message to send + /// WriteLine-style message arguments + public void Notice(string sender, string format, params object[] args) + { + WritePrefixLine(DeriveColor(sender), sender); + WriteNewLine(ConsoleColor.White, format, args); + } + + /// + /// Sends an error to the current console output + /// + /// The message to send + /// WriteLine-style message arguments + public void Error(string format, params object[] args) + { + WriteNewLine(ConsoleColor.Red, format, args); + } + + /// + /// Sends an error to the current console output + /// + /// The module that sent this message + /// The message to send + /// WriteLine-style message arguments + public void Error(string sender, string format, params object[] args) + { + WritePrefixLine(DeriveColor(sender), sender); + Error(format, args); + } + + /// + /// Sends a status message to the current console output + /// + /// The message to send + /// WriteLine-style message arguments + public void Status(string format, params object[] args) + { + WriteNewLine(ConsoleColor.Blue, format, args); + } + + /// + /// Sends a status message to the current console output + /// + /// The module that sent this message + /// The message to send + /// WriteLine-style message arguments + public void Status(string sender, string format, params object[] args) + { + WritePrefixLine(DeriveColor(sender), sender); + WriteNewLine(ConsoleColor.Blue, format, args); + } + + [Conditional("DEBUG")] + public void Debug(string format, params object[] args) + { + WriteNewLine(ConsoleColor.Gray, format, args); + } + + [Conditional("DEBUG")] + public void Debug(string sender, string format, params object[] args) + { + WritePrefixLine(DeriveColor(sender), sender); + WriteNewLine(ConsoleColor.Gray, format, args); + } + + private void WriteNewLine(ConsoleColor color, string format, params object[] args) + { + try + { + lock (m_syncRoot) + { + try + { + if (color != ConsoleColor.White) + System.Console.ForegroundColor = color; + + System.Console.WriteLine(format, args); + System.Console.ResetColor(); + } + catch (ArgumentNullException) + { + // Some older systems dont support coloured text. + System.Console.WriteLine(format, args); + } + catch (FormatException) + { + System.Console.WriteLine(args); + } + } + } + catch (ObjectDisposedException) + { + } + } + + private void WritePrefixLine(ConsoleColor color, string sender) + { + try + { + lock (m_syncRoot) + { + sender = sender.ToUpper(); + + System.Console.WriteLine("[" + sender + "] "); + + System.Console.Write("["); + + try + { + System.Console.ForegroundColor = color; + System.Console.Write(sender); + System.Console.ResetColor(); + } + catch (ArgumentNullException) + { + // Some older systems dont support coloured text. + System.Console.WriteLine(sender); + } + + System.Console.Write("] \t"); + } + } + catch (ObjectDisposedException) + { + } + } + + public string ReadLine() + { + try + { + return System.Console.ReadLine(); + } + catch (Exception e) + { + m_log.Error("[Console]: System.Console.ReadLine exception " + e.ToString()); + return String.Empty; + } + } + + public int Read() + { + return System.Console.Read(); + } + + public IPAddress CmdPromptIPAddress(string prompt, string defaultvalue) + { + IPAddress address; + string addressStr; + + while (true) + { + addressStr = CmdPrompt(prompt, defaultvalue); + if (IPAddress.TryParse(addressStr, out address)) + { + break; + } + else + { + m_log.Error("Illegal address. Please re-enter."); + } + } + + return address; + } + + public uint CmdPromptIPPort(string prompt, string defaultvalue) + { + uint port; + string portStr; + + while (true) + { + portStr = CmdPrompt(prompt, defaultvalue); + if (uint.TryParse(portStr, out port)) + { + if (port >= IPEndPoint.MinPort && port <= IPEndPoint.MaxPort) + { + break; + } + } + + m_log.Error("Illegal address. Please re-enter."); + } + + return port; + } + + // Displays a prompt and waits for the user to enter a string, then returns that string + // (Done with no echo and suitable for passwords - currently disabled) + public string PasswdPrompt(string prompt) + { + // FIXME: Needs to be better abstracted + System.Console.WriteLine(String.Format("{0}: ", prompt)); + //ConsoleColor oldfg = System.Console.ForegroundColor; + //System.Console.ForegroundColor = System.Console.BackgroundColor; + string temp = System.Console.ReadLine(); + //System.Console.ForegroundColor = oldfg; + return temp; + } + + // Displays a command prompt and waits for the user to enter a string, then returns that string + public string CmdPrompt(string prompt) + { + System.Console.WriteLine(String.Format("{0}: ", prompt)); + return ReadLine(); + } + + // Displays a command prompt and returns a default value if the user simply presses enter + public string CmdPrompt(string prompt, string defaultresponse) + { + string temp = CmdPrompt(String.Format("{0} [{1}]", prompt, defaultresponse)); + if (temp == String.Empty) + { + return defaultresponse; + } + else + { + return temp; + } + } + + // Displays a command prompt and returns a default value, user may only enter 1 of 2 options + public string CmdPrompt(string prompt, string defaultresponse, string OptionA, string OptionB) + { + bool itisdone = false; + string temp = CmdPrompt(prompt, defaultresponse); + while (itisdone == false) + { + if ((temp == OptionA) || (temp == OptionB)) + { + itisdone = true; + } + else + { + System.Console.WriteLine("Valid options are " + OptionA + " or " + OptionB); + temp = CmdPrompt(prompt, defaultresponse); + } + } + return temp; + } + + // Runs a command with a number of parameters + public Object RunCmd(string Cmd, string[] cmdparams) + { + m_cmdParser.RunCmd(Cmd, cmdparams); + return null; + } + + // Shows data about something + public void ShowCommands(string ShowWhat) + { + m_cmdParser.Show(ShowWhat); + } + + public void Prompt() + { + string tempstr = CmdPrompt(m_componentName + "# "); + RunCommand(tempstr); + } + + public void RunCommand(string command) + { + string[] tempstrarray; + tempstrarray = command.Split(' '); + string cmd = tempstrarray[0]; + Array.Reverse(tempstrarray); + Array.Resize(ref tempstrarray, tempstrarray.Length - 1); + Array.Reverse(tempstrarray); + string[] cmdparams = (string[]) tempstrarray; + + try + { + RunCmd(cmd, cmdparams); + } + catch (Exception e) + { + m_log.ErrorFormat("[Console]: Command [{0}] failed with exception {1}", command, e.ToString()); + } + } + + public string LineInfo + { + get + { + string result = String.Empty; + + string stacktrace = Environment.StackTrace; + List lines = new List(stacktrace.Split(new string[] {"at "}, StringSplitOptions.None)); + + if (lines.Count > 4) + { + lines.RemoveRange(0, 4); + + string tmpLine = lines[0]; + + int inIndex = tmpLine.IndexOf(" in "); + + if (inIndex > -1) + { + result = tmpLine.Substring(0, inIndex); + + int lineIndex = tmpLine.IndexOf(":line "); + + if (lineIndex > -1) + { + lineIndex += 6; + result += ", line " + tmpLine.Substring(lineIndex, (tmpLine.Length - lineIndex) - 5); + } + } + } + return result; + } + } + } +} diff --git a/OpenSim/Framework/Console/MainLog.cs b/OpenSim/Framework/Console/MainConsole.cs similarity index 92% rename from OpenSim/Framework/Console/MainLog.cs rename to OpenSim/Framework/Console/MainConsole.cs index fb1ac4fb54..fb88d04c00 100644 --- a/OpenSim/Framework/Console/MainLog.cs +++ b/OpenSim/Framework/Console/MainConsole.cs @@ -1,40 +1,41 @@ -/* -* 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. -* -*/ -namespace OpenSim.Framework.Console -{ - public class MainLog - { - private static LogBase instance; - - public static LogBase Instance - { - get { return instance; } - set { instance = value; } - } - } +/* +* 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. +* +*/ + +namespace OpenSim.Framework.Console +{ + public class MainConsole + { + private static ConsoleBase instance; + + public static ConsoleBase Instance + { + get { return instance; } + set { instance = value; } + } + } } \ No newline at end of file diff --git a/OpenSim/Framework/Console/OpenSimAppender.cs b/OpenSim/Framework/Console/OpenSimAppender.cs new file mode 100644 index 0000000000..e451d98aee --- /dev/null +++ b/OpenSim/Framework/Console/OpenSimAppender.cs @@ -0,0 +1,115 @@ +/* +* 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.Text; +using System.Text.RegularExpressions; +using System.Globalization; + +using log4net.Core; +using log4net.Layout; +using log4net.Appender; +using log4net.Util; + +namespace OpenSim.Framework.Console +{ + public class OpenSimAppender : AnsiColorTerminalAppender + { + override protected void Append(LoggingEvent le) + { + try { + string loggingMessage = RenderLoggingEvent(le); + string regex = @"^(?.*?)\[(?[^\]]+)\]:?(?.*)"; + + Regex RE = new Regex(regex, RegexOptions.Multiline); + MatchCollection matches = RE.Matches(loggingMessage); + // Get some direct matches $1 $4 is a + if (matches.Count == 1) + { + System.Console.Write(matches[0].Groups["Front"].Value); + System.Console.Write("["); + + WriteColorText(DeriveColor(matches[0].Groups["Category"].Value), matches[0].Groups["Category"].Value); + System.Console.Write("]:"); + + if (le.Level == Level.Error) + { + WriteColorText(ConsoleColor.Red, matches[0].Groups["End"].Value); + } + else if (le.Level == Level.Warn) + { + WriteColorText(ConsoleColor.Yellow, matches[0].Groups["End"].Value); + } + else + { + System.Console.Write(matches[0].Groups["End"].Value); + } + System.Console.WriteLine(); + } + else + { + System.Console.Write(loggingMessage); + } + } + catch (Exception e) + { + System.Console.WriteLine("Couldn't write out log message", e.ToString()); + } + } + + private void WriteColorText(ConsoleColor color, string sender) + { + try + { + lock (this) + { + try + { + System.Console.ForegroundColor = color; + System.Console.Write(sender); + System.Console.ResetColor(); + } + catch (ArgumentNullException) + { + // Some older systems dont support coloured text. + System.Console.WriteLine(sender); + } + } + } + catch (ObjectDisposedException) + { + } + } + + private ConsoleColor DeriveColor(string input) + { + int colIdx = (input.ToUpper().GetHashCode() % 6) + 9; + return (ConsoleColor) colIdx; + } + } +} diff --git a/OpenSim/Framework/Constants.cs b/OpenSim/Framework/Constants.cs new file mode 100644 index 0000000000..9eca152e3d --- /dev/null +++ b/OpenSim/Framework/Constants.cs @@ -0,0 +1,39 @@ +/* +* 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.Generic; +using System.Text; + +namespace OpenSim.Framework +{ + public class Constants + { + public const uint RegionSize = 256; + } +} diff --git a/OpenSim/Framework/Culture.cs b/OpenSim/Framework/Culture.cs index 45f90aff6f..27f2599a8f 100644 --- a/OpenSim/Framework/Culture.cs +++ b/OpenSim/Framework/Culture.cs @@ -1,54 +1,54 @@ -/* -* 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.Globalization; -using System.Threading; - -namespace OpenSim.Framework -{ - public class Culture - { - private static readonly CultureInfo m_cultureInfo = new CultureInfo("en-US", true); - - public static NumberFormatInfo NumberFormatInfo - { - get { return m_cultureInfo.NumberFormat; } - } - - public static IFormatProvider FormatProvider - { - get { return m_cultureInfo; } - } - - public static void SetCurrentCulture() - { - Thread.CurrentThread.CurrentCulture = m_cultureInfo; - } - } -} \ No newline at end of file +/* +* 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.Globalization; +using System.Threading; + +namespace OpenSim.Framework +{ + public class Culture + { + private static readonly CultureInfo m_cultureInfo = new CultureInfo("en-US", true); + + public static NumberFormatInfo NumberFormatInfo + { + get { return m_cultureInfo.NumberFormat; } + } + + public static IFormatProvider FormatProvider + { + get { return m_cultureInfo; } + } + + public static void SetCurrentCulture() + { + Thread.CurrentThread.CurrentCulture = m_cultureInfo; + } + } +} diff --git a/OpenSim/Framework/Data.DB4o/DB4oUserData.cs b/OpenSim/Framework/Data.DB4o/DB4oUserData.cs index b5d8baafe9..602fd14b0c 100644 --- a/OpenSim/Framework/Data.DB4o/DB4oUserData.cs +++ b/OpenSim/Framework/Data.DB4o/DB4oUserData.cs @@ -1,277 +1,282 @@ -/* -* 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.Generic; -using System.IO; -using libsecondlife; - -namespace OpenSim.Framework.Data.DB4o -{ - /// - /// A User storage interface for the DB4o database system - /// - public class DB4oUserData : IUserData - { - /// - /// The database manager - /// - private DB4oUserManager manager; - - /// - /// Artificial constructor called upon plugin load - /// - public void Initialise() - { - manager = new DB4oUserManager(Path.Combine(Util.dataDir(), "userprofiles.yap")); - } - - /// - /// Loads a specified user profile from a UUID - /// - /// The users UUID - /// A user profile - public UserProfileData GetUserByUUID(LLUUID uuid) - { - if (manager.userProfiles.ContainsKey(uuid)) - return manager.userProfiles[uuid]; - return null; - } - - /// - /// Loads a specified user profile from a account - /// - /// The users account - /// A user profile - public UserProfileData GetUserByAccount(string account) - { - if (manager.userProfiles.ContainsKey(account)) - return manager.userProfiles[account]; - return null; - } - - /// - /// Returns a user by searching for its name - /// - /// The users account name - /// A matching users profile - public UserProfileData GetUserByName(string name) - { - return GetUserByName(name.Split(' ')[0], name.Split(' ')[1]); - } - - /// - /// Returns a user by searching for its name - /// - /// The first part of the users account name - /// The second part of the users account name - /// A matching users profile - public UserProfileData GetUserByName(string fname, string lname) - { - foreach (UserProfileData profile in manager.userProfiles.Values) - { - if (profile.username == fname && profile.surname == lname) - return profile; - } - return null; - } - - /// - /// Returns a user by UUID direct - /// - /// The users account ID - /// A matching users profile - public UserAgentData GetAgentByUUID(LLUUID uuid) - { - try - { - return GetUserByUUID(uuid).currentAgent; - } - catch (Exception) - { - return null; - } - } - - /// - /// Returns a session by account name - /// - /// The account name - /// The users session agent - public UserAgentData GetAgentByName(string name) - { - return GetAgentByName(name.Split(' ')[0], name.Split(' ')[1]); - } - - /// - /// Returns a session by account name - /// - /// The first part of the users account name - /// The second part of the users account name - /// A user agent - public UserAgentData GetAgentByName(string fname, string lname) - { - try - { - return GetUserByName(fname, lname).currentAgent; - } - catch (Exception) - { - return null; - } - } - - #region User Friends List Data - - public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms) - { - //MainLog.Instance.Verbose("FRIEND", "Stub AddNewUserFriend called"); - } - - public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend) - { - //MainLog.Instance.Verbose("FRIEND", "Stub RemoveUserFriend called"); - } - public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms) - { - //MainLog.Instance.Verbose("FRIEND", "Stub UpdateUserFriendPerms called"); - } - - - public List GetUserFriendList(LLUUID friendlistowner) - { - //MainLog.Instance.Verbose("FRIEND", "Stub GetUserFriendList called"); - return new List(); - } - - #endregion - - public void UpdateUserCurrentRegion(LLUUID avatarid, LLUUID regionuuid) - { - //MainLog.Instance.Verbose("USER", "Stub UpdateUserCUrrentRegion called"); - } - - public void LogOffUser(LLUUID avatarid) - { - //MainLog.Instance.Verbose("USER", "Stub LogOffUser called"); - } - - public List GeneratePickerResults(LLUUID queryID, string query) - { - //Do nothing yet - List returnlist = new List(); - return returnlist; - } - - /// - /// Creates a new user profile - /// - /// The profile to add to the database - public void AddNewUserProfile(UserProfileData user) - { - try - { - manager.UpdateRecord(user); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - } - } - - /// - /// Creates a new user profile - /// - /// The profile to add to the database - /// True on success, false on error - public bool UpdateUserProfile(UserProfileData user) - { - try - { - return manager.UpdateRecord(user); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - return false; - } - } - - - /// - /// Creates a new user agent - /// - /// The agent to add to the database - public void AddNewUserAgent(UserAgentData agent) - { - // Do nothing. yet. - } - - /// - /// Transfers money between two user accounts - /// - /// Starting account - /// End account - /// The amount to move - /// Success? - public bool MoneyTransferRequest(LLUUID from, LLUUID to, uint amount) - { - return true; - } - - /// - /// Transfers inventory between two accounts - /// - /// Move to inventory server - /// Senders account - /// Receivers account - /// Inventory item - /// Success? - public bool InventoryTransferRequest(LLUUID from, LLUUID to, LLUUID item) - { - return true; - } - - /// - /// Returns the name of the storage provider - /// - /// Storage provider name - public string getName() - { - return "DB4o Userdata"; - } - - /// - /// Returns the version of the storage provider - /// - /// Storage provider version - public string GetVersion() - { - return "0.1"; - } - } -} \ No newline at end of file +/* +* 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.Generic; +using System.IO; +using libsecondlife; + +namespace OpenSim.Framework.Data.DB4o +{ + /// + /// A User storage interface for the DB4o database system + /// + public class DB4oUserData : IUserData + { + //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// The database manager + /// + private DB4oUserManager manager; + + /// + /// Artificial constructor called upon plugin load + /// + public void Initialise() + { + manager = new DB4oUserManager(Path.Combine(Util.dataDir(), "userprofiles.yap")); + } + + /// + /// Loads a specified user profile from a UUID + /// + /// The users UUID + /// A user profile + public UserProfileData GetUserByUUID(LLUUID uuid) + { + if (manager.userProfiles.ContainsKey(uuid)) + return manager.userProfiles[uuid]; + return null; + } + + /// + /// Loads a specified user profile from a account + /// + /// The users account + /// A user profile + public UserProfileData GetUserByAccount(string account) + { + if (manager.userProfiles.ContainsKey(account)) + return manager.userProfiles[account]; + return null; + } + + /// + /// Returns a user by searching for its name + /// + /// The users account name + /// A matching users profile + public UserProfileData GetUserByName(string name) + { + return GetUserByName(name.Split(' ')[0], name.Split(' ')[1]); + } + + /// + /// Returns a user by searching for its name + /// + /// The first part of the users account name + /// The second part of the users account name + /// A matching users profile + public UserProfileData GetUserByName(string fname, string lname) + { + foreach (UserProfileData profile in manager.userProfiles.Values) + { + if (profile.username == fname && profile.surname == lname) + return profile; + } + return null; + } + + /// + /// Returns a user by UUID direct + /// + /// The users account ID + /// A matching users profile + public UserAgentData GetAgentByUUID(LLUUID uuid) + { + try + { + return GetUserByUUID(uuid).currentAgent; + } + catch (Exception) + { + return null; + } + } + + /// + /// Returns a session by account name + /// + /// The account name + /// The users session agent + public UserAgentData GetAgentByName(string name) + { + return GetAgentByName(name.Split(' ')[0], name.Split(' ')[1]); + } + + /// + /// Returns a session by account name + /// + /// The first part of the users account name + /// The second part of the users account name + /// A user agent + public UserAgentData GetAgentByName(string fname, string lname) + { + try + { + return GetUserByName(fname, lname).currentAgent; + } + catch (Exception) + { + return null; + } + } + public void StoreWebLoginKey(LLUUID AgentID, LLUUID WebLoginKey) + { + UserProfileData user = GetUserByUUID(AgentID); + user.webLoginKey = WebLoginKey; + UpdateUserProfile(user); + + } + #region User Friends List Data + + public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms) + { + //m_log.Info("[FRIEND]: Stub AddNewUserFriend called"); + } + + public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend) + { + //m_log.Info("[FRIEND]: Stub RemoveUserFriend called"); + } + public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms) + { + //m_log.Info("[FRIEND]: Stub UpdateUserFriendPerms called"); + } + + + public List GetUserFriendList(LLUUID friendlistowner) + { + //m_log.Info("[FRIEND]: Stub GetUserFriendList called"); + return new List(); + } + + #endregion + + public void UpdateUserCurrentRegion(LLUUID avatarid, LLUUID regionuuid) + { + //m_log.Info("[USER]: Stub UpdateUserCUrrentRegion called"); + } + + + + public List GeneratePickerResults(LLUUID queryID, string query) + { + //Do nothing yet + List returnlist = new List(); + return returnlist; + } + + /// + /// Creates a new user profile + /// + /// The profile to add to the database + public void AddNewUserProfile(UserProfileData user) + { + try + { + manager.UpdateRecord(user); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + } + + /// + /// Creates a new user profile + /// + /// The profile to add to the database + /// True on success, false on error + public bool UpdateUserProfile(UserProfileData user) + { + try + { + return manager.UpdateRecord(user); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + return false; + } + } + + + /// + /// Creates a new user agent + /// + /// The agent to add to the database + public void AddNewUserAgent(UserAgentData agent) + { + // Do nothing. yet. + } + + /// + /// Transfers money between two user accounts + /// + /// Starting account + /// End account + /// The amount to move + /// Success? + public bool MoneyTransferRequest(LLUUID from, LLUUID to, uint amount) + { + return true; + } + + /// + /// Transfers inventory between two accounts + /// + /// Move to inventory server + /// Senders account + /// Receivers account + /// Inventory item + /// Success? + public bool InventoryTransferRequest(LLUUID from, LLUUID to, LLUUID item) + { + return true; + } + + /// + /// Returns the name of the storage provider + /// + /// Storage provider name + public string getName() + { + return "DB4o Userdata"; + } + + /// + /// Returns the version of the storage provider + /// + /// Storage provider version + public string GetVersion() + { + return "0.1"; + } + } +} diff --git a/OpenSim/Framework/Data.DB4o/Properties/AssemblyInfo.cs b/OpenSim/Framework/Data.DB4o/Properties/AssemblyInfo.cs index ddf8a3414a..a0d210f404 100644 --- a/OpenSim/Framework/Data.DB4o/Properties/AssemblyInfo.cs +++ b/OpenSim/Framework/Data.DB4o/Properties/AssemblyInfo.cs @@ -1,38 +1,66 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. - -[assembly : AssemblyTitle("OpenSim.Framework.Data.DB4o")] -[assembly : AssemblyDescription("")] -[assembly : AssemblyConfiguration("")] -[assembly : AssemblyCompany("")] -[assembly : AssemblyProduct("OpenSim.Framework.Data.DB4o")] -[assembly : AssemblyCopyright("Copyright © 2007")] -[assembly : AssemblyTrademark("")] -[assembly : AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. - -[assembly : ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM - -[assembly : Guid("57991e15-79da-41b7-aa06-2e6b49165a63")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: - -[assembly : AssemblyVersion("1.0.0.0")] -[assembly : AssemblyFileVersion("1.0.0.0")] \ No newline at end of file +/* +* 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.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. + +[assembly : AssemblyTitle("OpenSim.Framework.Data.DB4o")] +[assembly : AssemblyDescription("")] +[assembly : AssemblyConfiguration("")] +[assembly : AssemblyCompany("")] +[assembly : AssemblyProduct("OpenSim.Framework.Data.DB4o")] +[assembly : AssemblyCopyright("Copyright © OpenSimulator.org Developers 2007-2008")] +[assembly : AssemblyTrademark("")] +[assembly : AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. + +[assembly : ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM + +[assembly : Guid("57991e15-79da-41b7-aa06-2e6b49165a63")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly : AssemblyVersion("1.0.0.0")] +[assembly : AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/Data.MSSQL/MSSQLAssetData.cs b/OpenSim/Framework/Data.MSSQL/MSSQLAssetData.cs index 9c3dbf9520..524c17616c 100644 --- a/OpenSim/Framework/Data.MSSQL/MSSQLAssetData.cs +++ b/OpenSim/Framework/Data.MSSQL/MSSQLAssetData.cs @@ -1,240 +1,242 @@ -/* -* 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.Generic; -using System.Data; -using System.Data.SqlClient; -using libsecondlife; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.Data.MSSQL -{ - internal class MSSQLAssetData : IAssetProvider - { - private MSSQLManager database; - - #region IAssetProvider Members - - private void UpgradeAssetsTable(string tableName) - { - // null as the version, indicates that the table didn't exist - if (tableName == null) - { - MainLog.Instance.Notice("ASSETS", "Creating new database tables"); - database.ExecuteResourceSql("CreateAssetsTable.sql"); - return; - } - } - - /// - /// Ensure that the assets related tables exists and are at the latest version - /// - private void TestTables() - { - Dictionary tableList = new Dictionary(); - - tableList["assets"] = null; - database.GetTableVersion(tableList); - - UpgradeAssetsTable(tableList["assets"]); - } - - public AssetBase FetchAsset(LLUUID assetID) - { - AssetBase asset = null; - - Dictionary param = new Dictionary(); - param["id"] = assetID.ToString(); - - IDbCommand result = database.Query("SELECT * FROM assets WHERE id = @id", param); - IDataReader reader = result.ExecuteReader(); - - asset = database.getAssetRow(reader); - reader.Close(); - result.Dispose(); - - return asset; - } - - public void CreateAsset(AssetBase asset) - { - if (ExistsAsset((LLUUID) asset.FullID)) - { - return; - } - - - SqlCommand cmd = - new SqlCommand( - "INSERT INTO assets ([id], [name], [mediaUrl], [description], [assetType], [invType], [local], [temporary], [data])" + - " VALUES " + - "(@id, @name, @mediaUrl, @description, @assetType, @invType, @local, @temporary, @data)", - database.getConnection()); - - using (cmd) - { - //SqlParameter p = cmd.Parameters.Add("id", SqlDbType.NVarChar); - //p.Value = asset.FullID.ToString(); - cmd.Parameters.AddWithValue("id", asset.FullID.ToString()); - cmd.Parameters.AddWithValue("name", asset.Name); - cmd.Parameters.AddWithValue("mediaUrl", asset.MediaURL); - cmd.Parameters.AddWithValue("description", asset.Description); - SqlParameter e = cmd.Parameters.Add("assetType", SqlDbType.TinyInt); - e.Value = asset.Type; - SqlParameter f = cmd.Parameters.Add("invType", SqlDbType.TinyInt); - f.Value = asset.InvType; - SqlParameter g = cmd.Parameters.Add("local", SqlDbType.TinyInt); - g.Value = asset.Local; - SqlParameter h = cmd.Parameters.Add("temporary", SqlDbType.TinyInt); - h.Value = asset.Temporary; - SqlParameter i = cmd.Parameters.Add("data", SqlDbType.Image); - i.Value = asset.Data; - try - { - cmd.ExecuteNonQuery(); - } - catch (Exception) - { - throw; - } - - cmd.Dispose(); - } - } - - - public void UpdateAsset(AssetBase asset) - { - SqlCommand command = new SqlCommand("UPDATE assets set id = @id, " + - "name = @name, " + - "mediaUrl = @mediaUrl, "+ - "description = @description," + - "assetType = @assetType," + - "invType = @invType," + - "local = @local," + - "temporary = @temporary," + - "data = @data where " + - "id = @keyId;", database.getConnection()); - SqlParameter param1 = new SqlParameter("@id", asset.FullID.ToString()); - SqlParameter param2 = new SqlParameter("@name", asset.Name); - SqlParameter param3 = new SqlParameter("@mediaUrl", asset.MediaURL); - SqlParameter param4 = new SqlParameter("@description", asset.Description); - SqlParameter param5 = new SqlParameter("@assetType", Convert.ToBoolean(asset.Type)); - SqlParameter param6 = new SqlParameter("@invType", Convert.ToBoolean(asset.InvType)); - SqlParameter param7 = new SqlParameter("@local", asset.Local); - SqlParameter param8 = new SqlParameter("@temporary", asset.Temporary); - SqlParameter param9 = new SqlParameter("@data", asset.Data); - SqlParameter param10 = new SqlParameter("@keyId", asset.FullID.ToString()); - command.Parameters.Add(param1); - command.Parameters.Add(param2); - command.Parameters.Add(param3); - command.Parameters.Add(param4); - command.Parameters.Add(param5); - command.Parameters.Add(param6); - command.Parameters.Add(param7); - command.Parameters.Add(param8); - command.Parameters.Add(param9); - command.Parameters.Add(param10); - - try - { - command.ExecuteNonQuery(); - } - catch (Exception e) - { - MainLog.Instance.Error(e.ToString()); - } - } - - public bool ExistsAsset(LLUUID uuid) - { - if (FetchAsset(uuid) != null) - { - return true; - } - return false; - } - - // rex, new function, fixme not implemented - public List GetAssetList(int vAssetType) - { - List retvals = new List(); - return retvals; - } - - - /// - /// All writes are immediately commited to the database, so this is a no-op - /// - public void CommitAssets() - { - } - - // rex new function for "replace assets" functionality - // TODO: actual implementation by someone, should return LLUUID of an asset - // with matching type & name, or zero if not in DB - public LLUUID ExistsAsset(sbyte type, string name) - { - return LLUUID.Zero; - } - - #endregion - - #region IPlugin Members - - public void Initialise() - { - IniFile GridDataMySqlFile = new IniFile("mssql_connection.ini"); - string settingDataSource = GridDataMySqlFile.ParseFileReadValue("data_source"); - string settingInitialCatalog = GridDataMySqlFile.ParseFileReadValue("initial_catalog"); - string settingPersistSecurityInfo = GridDataMySqlFile.ParseFileReadValue("persist_security_info"); - string settingUserId = GridDataMySqlFile.ParseFileReadValue("user_id"); - string settingPassword = GridDataMySqlFile.ParseFileReadValue("password"); - - database = - new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, - settingPassword); - - TestTables(); - } - - public string Version - { -// get { return database.getVersion(); } - get { return database.getVersion(); } - } - - public string Name - { - get { return "MSSQL Asset storage engine"; } - } - - #endregion - } -} \ No newline at end of file +/* +* 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.Generic; +using System.Data; +using System.Data.SqlClient; +using libsecondlife; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Data.MSSQL +{ + internal class MSSQLAssetData : IAssetProvider + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private MSSQLManager database; + + #region IAssetProvider Members + + private void UpgradeAssetsTable(string tableName) + { + // null as the version, indicates that the table didn't exist + if (tableName == null) + { + m_log.Info("[ASSETS]: Creating new database tables"); + database.ExecuteResourceSql("CreateAssetsTable.sql"); + return; + } + } + + /// + /// Ensure that the assets related tables exists and are at the latest version + /// + private void TestTables() + { + Dictionary tableList = new Dictionary(); + + tableList["assets"] = null; + database.GetTableVersion(tableList); + + UpgradeAssetsTable(tableList["assets"]); + } + + public AssetBase FetchAsset(LLUUID assetID) + { + AssetBase asset = null; + + Dictionary param = new Dictionary(); + param["id"] = assetID.ToString(); + + IDbCommand result = database.Query("SELECT * FROM assets WHERE id = @id", param); + IDataReader reader = result.ExecuteReader(); + + asset = database.getAssetRow(reader); + reader.Close(); + result.Dispose(); + + return asset; + } + + public void CreateAsset(AssetBase asset) + { + if (ExistsAsset((LLUUID) asset.FullID)) + { + return; + } + + + SqlCommand cmd = + new SqlCommand( + "INSERT INTO assets ([id], [name], [mediaUrl], [description], [assetType], [invType], [local], [temporary], [data])" + + " VALUES " + + "(@id, @name, @mediaUrl, @description, @assetType, @invType, @local, @temporary, @data)", + database.getConnection()); + + using (cmd) + { + //SqlParameter p = cmd.Parameters.Add("id", SqlDbType.NVarChar); + //p.Value = asset.FullID.ToString(); + cmd.Parameters.AddWithValue("id", asset.FullID.ToString()); + cmd.Parameters.AddWithValue("name", asset.Name); + cmd.Parameters.AddWithValue("mediaUrl", asset.MediaURL); + cmd.Parameters.AddWithValue("description", asset.Description); + SqlParameter e = cmd.Parameters.Add("assetType", SqlDbType.TinyInt); + e.Value = asset.Type; + SqlParameter f = cmd.Parameters.Add("invType", SqlDbType.TinyInt); + f.Value = asset.InvType; + SqlParameter g = cmd.Parameters.Add("local", SqlDbType.TinyInt); + g.Value = asset.Local; + SqlParameter h = cmd.Parameters.Add("temporary", SqlDbType.TinyInt); + h.Value = asset.Temporary; + SqlParameter i = cmd.Parameters.Add("data", SqlDbType.Image); + i.Value = asset.Data; + try + { + cmd.ExecuteNonQuery(); + } + catch (Exception) + { + throw; + } + + cmd.Dispose(); + } + } + + + public void UpdateAsset(AssetBase asset) + { + SqlCommand command = new SqlCommand("UPDATE assets set id = @id, " + + "name = @name, " + + "mediaUrl = @mediaUrl, "+ + "description = @description," + + "assetType = @assetType," + + "invType = @invType," + + "local = @local," + + "temporary = @temporary," + + "data = @data where " + + "id = @keyId;", database.getConnection()); + SqlParameter param1 = new SqlParameter("@id", asset.FullID.ToString()); + SqlParameter param2 = new SqlParameter("@name", asset.Name); + SqlParameter param3 = new SqlParameter("@mediaUrl", asset.MediaURL); + SqlParameter param4 = new SqlParameter("@description", asset.Description); + SqlParameter param5 = new SqlParameter("@assetType", Convert.ToBoolean(asset.Type)); + SqlParameter param6 = new SqlParameter("@invType", Convert.ToBoolean(asset.InvType)); + SqlParameter param7 = new SqlParameter("@local", asset.Local); + SqlParameter param8 = new SqlParameter("@temporary", asset.Temporary); + SqlParameter param9 = new SqlParameter("@data", asset.Data); + SqlParameter param10 = new SqlParameter("@keyId", asset.FullID.ToString()); + command.Parameters.Add(param1); + command.Parameters.Add(param2); + command.Parameters.Add(param3); + command.Parameters.Add(param4); + command.Parameters.Add(param5); + command.Parameters.Add(param6); + command.Parameters.Add(param7); + command.Parameters.Add(param8); + command.Parameters.Add(param9); + command.Parameters.Add(param10); + + try + { + command.ExecuteNonQuery(); + } + catch (Exception e) + { + m_log.Error(e.ToString()); + } + } + + public bool ExistsAsset(LLUUID uuid) + { + if (FetchAsset(uuid) != null) + { + return true; + } + return false; + } + + // rex, new function, fixme not implemented + public List GetAssetList(int vAssetType) + { + List retvals = new List(); + return retvals; + } + + + /// + /// All writes are immediately commited to the database, so this is a no-op + /// + public void CommitAssets() + { + } + + // rex new function for "replace assets" functionality + // TODO: actual implementation by someone, should return LLUUID of an asset + // with matching type & name, or zero if not in DB + public LLUUID ExistsAsset(sbyte type, string name) + { + return LLUUID.Zero; + } + + #endregion + + #region IPlugin Members + + public void Initialise() + { + IniFile GridDataMySqlFile = new IniFile("mssql_connection.ini"); + string settingDataSource = GridDataMySqlFile.ParseFileReadValue("data_source"); + string settingInitialCatalog = GridDataMySqlFile.ParseFileReadValue("initial_catalog"); + string settingPersistSecurityInfo = GridDataMySqlFile.ParseFileReadValue("persist_security_info"); + string settingUserId = GridDataMySqlFile.ParseFileReadValue("user_id"); + string settingPassword = GridDataMySqlFile.ParseFileReadValue("password"); + + database = + new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, + settingPassword); + + TestTables(); + } + + public string Version + { +// get { return database.getVersion(); } + get { return database.getVersion(); } + } + + public string Name + { + get { return "MSSQL Asset storage engine"; } + } + + #endregion + } +} diff --git a/OpenSim/Framework/Data.MSSQL/MSSQLGridData.cs b/OpenSim/Framework/Data.MSSQL/MSSQLGridData.cs index db9c371c89..c7c338e751 100644 --- a/OpenSim/Framework/Data.MSSQL/MSSQLGridData.cs +++ b/OpenSim/Framework/Data.MSSQL/MSSQLGridData.cs @@ -1,309 +1,327 @@ -/* -* 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.Generic; -using System.Data; -using System.Security.Cryptography; -using System.Text; -using libsecondlife; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.Data.MSSQL -{ - /// - /// A grid data interface for Microsoft SQL Server - /// - public class SqlGridData : IGridData - { - /// - /// Database manager - /// - private MSSQLManager database; - - /// - /// Initialises the Grid Interface - /// - public void Initialise() - { - IniFile GridDataMySqlFile = new IniFile("mssql_connection.ini"); - string settingDataSource = GridDataMySqlFile.ParseFileReadValue("data_source"); - string settingInitialCatalog = GridDataMySqlFile.ParseFileReadValue("initial_catalog"); - string settingPersistSecurityInfo = GridDataMySqlFile.ParseFileReadValue("persist_security_info"); - string settingUserId = GridDataMySqlFile.ParseFileReadValue("user_id"); - string settingPassword = GridDataMySqlFile.ParseFileReadValue("password"); - - database = - new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, - settingPassword); - } - - /// - /// Shuts down the grid interface - /// - public void Close() - { - database.Close(); - } - - /// - /// Returns the storage system name - /// - /// A string containing the storage system name - public string getName() - { - return "Sql OpenGridData"; - } - - /// - /// Returns the storage system version - /// - /// A string containing the storage system version - public string getVersion() - { - return "0.1"; - } - - /// - /// Returns a list of regions within the specified ranges - /// - /// minimum X coordinate - /// minimum Y coordinate - /// maximum X coordinate - /// maximum Y coordinate - /// An array of region profiles - public RegionProfileData[] GetProfilesInRange(uint a, uint b, uint c, uint d) - { - return null; - } - - /// - /// Returns a sim profile from it's location - /// - /// Region location handle - /// Sim profile - public RegionProfileData GetProfileByHandle(ulong handle) - { - IDataReader reader = null; - try - { - Dictionary param = new Dictionary(); - param["handle"] = handle.ToString(); - IDbCommand result = database.Query("SELECT * FROM regions WHERE regionHandle = @handle", param); - reader = result.ExecuteReader(); - - RegionProfileData row = database.getRegionRow(reader); - reader.Close(); - result.Dispose(); - - return row; - } - catch (Exception) - { - if (reader != null) - { - reader.Close(); - } - } - return null; - } - - /// - /// // Returns a list of avatar and UUIDs that match the query - /// - public List GeneratePickerResults(LLUUID queryID, string query) - { - List returnlist = new List(); - string[] querysplit; - querysplit = query.Split(' '); - if (querysplit.Length == 2) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["first"] = querysplit[0]; - param["second"] = querysplit[1]; - - IDbCommand result = - database.Query( - "SELECT UUID,username,surname FROM users WHERE username = @first AND lastname = @second", - param); - IDataReader reader = result.ExecuteReader(); - - - while (reader.Read()) - { - AvatarPickerAvatar user = new AvatarPickerAvatar(); - user.AvatarID = new LLUUID((string) reader["UUID"]); - user.firstName = (string) reader["username"]; - user.lastName = (string) reader["surname"]; - returnlist.Add(user); - } - reader.Close(); - result.Dispose(); - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return returnlist; - } - } - else if (querysplit.Length == 1) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["first"] = querysplit[0]; - param["second"] = querysplit[1]; - - IDbCommand result = - database.Query( - "SELECT UUID,username,surname FROM users WHERE username = @first OR lastname = @second", - param); - IDataReader reader = result.ExecuteReader(); - - - while (reader.Read()) - { - AvatarPickerAvatar user = new AvatarPickerAvatar(); - user.AvatarID = new LLUUID((string) reader["UUID"]); - user.firstName = (string) reader["username"]; - user.lastName = (string) reader["surname"]; - returnlist.Add(user); - } - reader.Close(); - result.Dispose(); - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return returnlist; - } - } - return returnlist; - } - - /// - /// Returns a sim profile from it's UUID - /// - /// The region UUID - /// The sim profile - public RegionProfileData GetProfileByLLUUID(LLUUID uuid) - { - Dictionary param = new Dictionary(); - param["uuid"] = uuid.ToString(); - IDbCommand result = database.Query("SELECT * FROM regions WHERE uuid = @uuid", param); - IDataReader reader = result.ExecuteReader(); - - RegionProfileData row = database.getRegionRow(reader); - reader.Close(); - result.Dispose(); - - return row; - } - - /// - /// Adds a new specified region to the database - /// - /// The profile to add - /// A dataresponse enum indicating success - public DataResponse AddProfile(RegionProfileData profile) - { - try - { - if (GetProfileByLLUUID(profile.UUID) != null) - { - return DataResponse.RESPONSE_OK; - } - } - catch (Exception) - { - System.Console.WriteLine("No regions found. Create new one."); - } - - if (database.insertRegionRow(profile)) - { - return DataResponse.RESPONSE_OK; - } - else - { - return DataResponse.RESPONSE_ERROR; - } - } - - /// - /// DEPRECIATED. Attempts to authenticate a region by comparing a shared secret. - /// - /// The UUID of the challenger - /// The attempted regionHandle of the challenger - /// The secret - /// Whether the secret and regionhandle match the database entry for UUID - public bool AuthenticateSim(LLUUID uuid, ulong handle, string authkey) - { - bool throwHissyFit = false; // Should be true by 1.0 - - if (throwHissyFit) - throw new Exception("CRYPTOWEAK AUTHENTICATE: Refusing to authenticate due to replay potential."); - - RegionProfileData data = GetProfileByLLUUID(uuid); - - return (handle == data.regionHandle && authkey == data.regionSecret); - } - - /// - /// NOT YET FUNCTIONAL. Provides a cryptographic authentication of a region - /// - /// This requires a security audit. - /// - /// - /// - /// - /// - public bool AuthenticateSim(LLUUID uuid, ulong handle, string authhash, string challenge) - { - SHA512Managed HashProvider = new SHA512Managed(); - ASCIIEncoding TextProvider = new ASCIIEncoding(); - - byte[] stream = TextProvider.GetBytes(uuid.ToString() + ":" + handle.ToString() + ":" + challenge); - byte[] hash = HashProvider.ComputeHash(stream); - return false; - } - - public ReservationData GetReservationAtPoint(uint x, uint y) - { - return null; - } - } -} \ No newline at end of file +/* +* 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.Generic; +using System.Data; +using System.Security.Cryptography; +using System.Text; +using libsecondlife; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Data.MSSQL +{ + /// + /// A grid data interface for Microsoft SQL Server + /// + public class MSSQLGridData : IGridData + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// Database manager + /// + private MSSQLManager database; + + private string m_regionsTableName; + + /// + /// Initialises the Grid Interface + /// + public void Initialise() + { + IniFile iniFile = new IniFile("mssql_connection.ini"); + + string settingDataSource = iniFile.ParseFileReadValue("data_source"); + string settingInitialCatalog = iniFile.ParseFileReadValue("initial_catalog"); + string settingPersistSecurityInfo = iniFile.ParseFileReadValue("persist_security_info"); + string settingUserId = iniFile.ParseFileReadValue("user_id"); + string settingPassword = iniFile.ParseFileReadValue("password"); + + m_regionsTableName = iniFile.ParseFileReadValue("regionstablename"); + if (m_regionsTableName == null) + { + m_regionsTableName = "regions"; + } + + database = + new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, + settingPassword); + + TestTables(); + } + + private void TestTables() + { + IDbCommand cmd = database.Query("SELECT TOP 1 * FROM "+m_regionsTableName, new Dictionary()); + + try + { + cmd.ExecuteNonQuery(); + cmd.Dispose(); + } + catch (Exception) + { + m_log.Info("[DATASTORE]: MSSQL Database doesn't exist... creating"); + database.ExecuteResourceSql("Mssql-regions.sql"); + } + } + + /// + /// Shuts down the grid interface + /// + public void Close() + { + database.Close(); + } + + /// + /// Returns the storage system name + /// + /// A string containing the storage system name + public string getName() + { + return "Sql OpenGridData"; + } + + /// + /// Returns the storage system version + /// + /// A string containing the storage system version + public string getVersion() + { + return "0.1"; + } + + /// + /// Returns a list of regions within the specified ranges + /// + /// minimum X coordinate + /// minimum Y coordinate + /// maximum X coordinate + /// maximum Y coordinate + /// An array of region profiles + public RegionProfileData[] GetProfilesInRange(uint a, uint b, uint c, uint d) + { + return null; + } + + /// + /// Returns a sim profile from it's location + /// + /// Region location handle + /// Sim profile + public RegionProfileData GetProfileByHandle(ulong handle) + { + IDataReader reader = null; + try + { + Dictionary param = new Dictionary(); + param["handle"] = handle.ToString(); + IDbCommand result = database.Query("SELECT * FROM " + m_regionsTableName + " WHERE regionHandle = @handle", param); + reader = result.ExecuteReader(); + + RegionProfileData row = database.getRegionRow(reader); + reader.Close(); + result.Dispose(); + + return row; + } + catch (Exception) + { + if (reader != null) + { + reader.Close(); + } + } + return null; + } + + + /// + /// Returns a sim profile from it's UUID + /// + /// The region UUID + /// The sim profile + public RegionProfileData GetProfileByLLUUID(LLUUID uuid) + { + Dictionary param = new Dictionary(); + param["uuid"] = uuid.ToString(); + IDbCommand result = database.Query("SELECT * FROM " + m_regionsTableName + " WHERE uuid = @uuid", param); + IDataReader reader = result.ExecuteReader(); + + RegionProfileData row = database.getRegionRow(reader); + reader.Close(); + result.Dispose(); + + return row; + } + + /// + /// Adds a new specified region to the database + /// + /// The profile to add + /// A dataresponse enum indicating success + public DataResponse AddProfile(RegionProfileData profile) + { + try + { + if (GetProfileByLLUUID(profile.UUID) != null) + { + return DataResponse.RESPONSE_OK; + } + } + catch (Exception) + { + System.Console.WriteLine("No regions found. Create new one."); + } + + if ( insertRegionRow(profile)) + { + return DataResponse.RESPONSE_OK; + } + else + { + return DataResponse.RESPONSE_ERROR; + } + } + + + /// + /// Creates a new region in the database + /// + /// The region profile to insert + /// Successful? + public bool insertRegionRow(RegionProfileData profile) + { + //Insert new region + string sql = + "INSERT INTO " + m_regionsTableName + " ([regionHandle], [regionName], [uuid], [regionRecvKey], [regionSecret], [regionSendKey], [regionDataURI], "; + sql += + "[serverIP], [serverPort], [serverURI], [locX], [locY], [locZ], [eastOverrideHandle], [westOverrideHandle], [southOverrideHandle], [northOverrideHandle], [regionAssetURI], [regionAssetRecvKey], "; + sql += + "[regionAssetSendKey], [regionUserURI], [regionUserRecvKey], [regionUserSendKey], [regionMapTexture], [serverHttpPort], [serverRemotingPort]) VALUES "; + + sql += "(@regionHandle, @regionName, @uuid, @regionRecvKey, @regionSecret, @regionSendKey, @regionDataURI, "; + sql += + "@serverIP, @serverPort, @serverURI, @locX, @locY, @locZ, @eastOverrideHandle, @westOverrideHandle, @southOverrideHandle, @northOverrideHandle, @regionAssetURI, @regionAssetRecvKey, "; + sql += + "@regionAssetSendKey, @regionUserURI, @regionUserRecvKey, @regionUserSendKey, @regionMapTexture, @serverHttpPort, @serverRemotingPort);"; + + Dictionary parameters = new Dictionary(); + + parameters["regionHandle"] = profile.regionHandle.ToString(); + parameters["regionName"] = profile.regionName; + parameters["uuid"] = profile.UUID.ToString(); + parameters["regionRecvKey"] = profile.regionRecvKey; + parameters["regionSecret"] = profile.regionSecret; + parameters["regionSendKey"] = profile.regionSendKey; + parameters["regionDataURI"] = profile.regionDataURI; + parameters["serverIP"] = profile.serverIP; + parameters["serverPort"] = profile.serverPort.ToString(); + parameters["serverURI"] = profile.serverURI; + parameters["locX"] = profile.regionLocX.ToString(); + parameters["locY"] = profile.regionLocY.ToString(); + parameters["locZ"] = profile.regionLocZ.ToString(); + parameters["eastOverrideHandle"] = profile.regionEastOverrideHandle.ToString(); + parameters["westOverrideHandle"] = profile.regionWestOverrideHandle.ToString(); + parameters["northOverrideHandle"] = profile.regionNorthOverrideHandle.ToString(); + parameters["southOverrideHandle"] = profile.regionSouthOverrideHandle.ToString(); + parameters["regionAssetURI"] = profile.regionAssetURI; + parameters["regionAssetRecvKey"] = profile.regionAssetRecvKey; + parameters["regionAssetSendKey"] = profile.regionAssetSendKey; + parameters["regionUserURI"] = profile.regionUserURI; + parameters["regionUserRecvKey"] = profile.regionUserRecvKey; + parameters["regionUserSendKey"] = profile.regionUserSendKey; + parameters["regionMapTexture"] = profile.regionMapTextureID.ToString(); + parameters["serverHttpPort"] = profile.httpPort.ToString(); + parameters["serverRemotingPort"] = profile.remotingPort.ToString(); + + + bool returnval = false; + + try + { + IDbCommand result = database.Query(sql, parameters); + + if (result.ExecuteNonQuery() == 1) + returnval = true; + + result.Dispose(); + } + catch (Exception e) + { + m_log.Error("MSSQLManager : " + e.ToString()); + } + + return returnval; + } + + /// + /// DEPRECIATED. Attempts to authenticate a region by comparing a shared secret. + /// + /// The UUID of the challenger + /// The attempted regionHandle of the challenger + /// The secret + /// Whether the secret and regionhandle match the database entry for UUID + public bool AuthenticateSim(LLUUID uuid, ulong handle, string authkey) + { + bool throwHissyFit = false; // Should be true by 1.0 + + if (throwHissyFit) + throw new Exception("CRYPTOWEAK AUTHENTICATE: Refusing to authenticate due to replay potential."); + + RegionProfileData data = GetProfileByLLUUID(uuid); + + return (handle == data.regionHandle && authkey == data.regionSecret); + } + + /// + /// NOT YET FUNCTIONAL. Provides a cryptographic authentication of a region + /// + /// This requires a security audit. + /// + /// + /// + /// + /// + public bool AuthenticateSim(LLUUID uuid, ulong handle, string authhash, string challenge) + { + SHA512Managed HashProvider = new SHA512Managed(); + ASCIIEncoding TextProvider = new ASCIIEncoding(); + + byte[] stream = TextProvider.GetBytes(uuid.ToString() + ":" + handle.ToString() + ":" + challenge); + byte[] hash = HashProvider.ComputeHash(stream); + return false; + } + + public ReservationData GetReservationAtPoint(uint x, uint y) + { + return null; + } + } +} diff --git a/OpenSim/Framework/Data.MSSQL/MSSQLInventoryData.cs b/OpenSim/Framework/Data.MSSQL/MSSQLInventoryData.cs index e4c82d6820..42023b070f 100644 --- a/OpenSim/Framework/Data.MSSQL/MSSQLInventoryData.cs +++ b/OpenSim/Framework/Data.MSSQL/MSSQLInventoryData.cs @@ -1,726 +1,728 @@ -/* -* 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.Generic; -using System.Data; -using System.Data.SqlClient; -using libsecondlife; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.Data.MSSQL -{ - /// - /// A MySQL interface for the inventory server - /// - public class MSSQLInventoryData : IInventoryData - { - /// - /// The database manager - /// - private MSSQLManager database; - - /// - /// Loads and initialises this database plugin - /// - public void Initialise() - { - IniFile GridDataMySqlFile = new IniFile("mssql_connection.ini"); - string settingDataSource = GridDataMySqlFile.ParseFileReadValue("data_source"); - string settingInitialCatalog = GridDataMySqlFile.ParseFileReadValue("initial_catalog"); - string settingPersistSecurityInfo = GridDataMySqlFile.ParseFileReadValue("persist_security_info"); - string settingUserId = GridDataMySqlFile.ParseFileReadValue("user_id"); - string settingPassword = GridDataMySqlFile.ParseFileReadValue("password"); - - database = - new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, - settingPassword); - TestTables(); - } - - #region Test and initialization code - - private void UpgradeFoldersTable(string tableName) - { - // null as the version, indicates that the table didn't exist - if (tableName == null) - { - database.ExecuteResourceSql("CreateFoldersTable.sql"); - //database.ExecuteResourceSql("UpgradeFoldersTableToVersion2.sql"); - return; - } - } - - private void UpgradeItemsTable(string tableName) - { - // null as the version, indicates that the table didn't exist - if (tableName == null) - { - database.ExecuteResourceSql("CreateItemsTable.sql"); - //database.ExecuteResourceSql("UpgradeItemsTableToVersion2.sql"); - return; - } - } - - private void TestTables() - { - Dictionary tableList = new Dictionary(); - - tableList["inventoryfolders"] = null; - tableList["inventoryitems"] = null; - - database.GetTableVersion(tableList); - - UpgradeFoldersTable(tableList["inventoryfolders"]); - UpgradeItemsTable(tableList["inventoryitems"]); - } - - #endregion - - /// - /// The name of this DB provider - /// - /// Name of DB provider - public string getName() - { - return "MSSQL Inventory Data Interface"; - } - - /// - /// Closes this DB provider - /// - public void Close() - { - // Do nothing. - } - - /// - /// Returns the version of this DB provider - /// - /// A string containing the DB provider - public string getVersion() - { - return database.getVersion(); - } - - /// - /// Returns a list of items in a specified folder - /// - /// The folder to search - /// A list containing inventory items - public List getInventoryInFolder(LLUUID folderID) - { - try - { - lock (database) - { - List items = new List(); - - Dictionary param = new Dictionary(); - param["parentFolderID"] = folderID.ToString(); - - IDbCommand result = - database.Query("SELECT * FROM inventoryitems WHERE parentFolderID = @parentFolderID", param); - IDataReader reader = result.ExecuteReader(); - - while (reader.Read()) - items.Add(readInventoryItem(reader)); - - reader.Close(); - result.Dispose(); - - return items; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - - /// - /// Returns a list of the root folders within a users inventory - /// - /// The user whos inventory is to be searched - /// A list of folder objects - public List getUserRootFolders(LLUUID user) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["uuid"] = user.ToString(); - param["zero"] = LLUUID.Zero.ToString(); - - IDbCommand result = - database.Query( - "SELECT * FROM inventoryfolders WHERE parentFolderID = @zero AND agentID = @uuid", param); - IDataReader reader = result.ExecuteReader(); - - List items = new List(); - while (reader.Read()) - items.Add(readInventoryFolder(reader)); - - - reader.Close(); - result.Dispose(); - - return items; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - - // see InventoryItemBase.getUserRootFolder - public InventoryFolderBase getUserRootFolder(LLUUID user) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["uuid"] = user.ToString(); - param["zero"] = LLUUID.Zero.ToString(); - - IDbCommand result = - database.Query( - "SELECT * FROM inventoryfolders WHERE parentFolderID = @zero AND agentID = @uuid", param); - IDataReader reader = result.ExecuteReader(); - - List items = new List(); - while (reader.Read()) - items.Add(readInventoryFolder(reader)); - - InventoryFolderBase rootFolder = null; - - // There should only ever be one root folder for a user. However, if there's more - // than one we'll simply use the first one rather than failing. It would be even - // nicer to print some message to this effect, but this feels like it's too low a - // to put such a message out, and it's too minor right now to spare the time to - // suitably refactor. - if (items.Count > 0) - { - rootFolder = items[0]; - } - - reader.Close(); - result.Dispose(); - - return rootFolder; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - - /// - /// Returns a list of folders in a users inventory contained within the specified folder - /// - /// The folder to search - /// A list of inventory folders - public List getInventoryFolders(LLUUID parentID) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["parentFolderID"] = parentID.ToString(); - - - IDbCommand result = - database.Query("SELECT * FROM inventoryfolders WHERE parentFolderID = @parentFolderID", param); - IDataReader reader = result.ExecuteReader(); - - List items = new List(); - - while (reader.Read()) - items.Add(readInventoryFolder(reader)); - - reader.Close(); - result.Dispose(); - - return items; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - - /// - /// Reads a one item from an SQL result - /// - /// The SQL Result - /// the item read - private InventoryItemBase readInventoryItem(IDataReader reader) - { - try - { - InventoryItemBase item = new InventoryItemBase(); - - item.inventoryID = new LLUUID((string) reader["inventoryID"]); - item.assetID = new LLUUID((string) reader["assetID"]); - item.assetType = (int) reader["assetType"]; - item.parentFolderID = new LLUUID((string) reader["parentFolderID"]); - item.avatarID = new LLUUID((string) reader["avatarID"]); - item.inventoryName = (string) reader["inventoryName"]; - item.inventoryDescription = (string) reader["inventoryDescription"]; - item.inventoryNextPermissions = Convert.ToUInt32(reader["inventoryNextPermissions"]); - item.inventoryCurrentPermissions = Convert.ToUInt32(reader["inventoryCurrentPermissions"]); - item.invType = (int) reader["invType"]; - item.creatorsID = new LLUUID((string) reader["creatorID"]); - item.inventoryBasePermissions = Convert.ToUInt32(reader["inventoryBasePermissions"]); - item.inventoryEveryOnePermissions = Convert.ToUInt32(reader["inventoryEveryOnePermissions"]); - return item; - } - catch (SqlException e) - { - MainLog.Instance.Error(e.ToString()); - } - - return null; - } - - /// - /// Returns a specified inventory item - /// - /// The item to return - /// An inventory item - public InventoryItemBase getInventoryItem(LLUUID itemID) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["inventoryID"] = itemID.ToString(); - - IDbCommand result = - database.Query("SELECT * FROM inventoryitems WHERE inventoryID = @inventoryID", param); - IDataReader reader = result.ExecuteReader(); - - InventoryItemBase item = null; - if (reader.Read()) - item = readInventoryItem(reader); - - reader.Close(); - result.Dispose(); - - return item; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - } - return null; - } - - /// - /// Reads a list of inventory folders returned by a query. - /// - /// A MySQL Data Reader - /// A List containing inventory folders - protected InventoryFolderBase readInventoryFolder(IDataReader reader) - { - try - { - InventoryFolderBase folder = new InventoryFolderBase(); - folder.agentID = new LLUUID((string) reader["agentID"]); - folder.parentID = new LLUUID((string) reader["parentFolderID"]); - folder.folderID = new LLUUID((string) reader["folderID"]); - folder.name = (string) reader["folderName"]; - folder.type = (short) reader["type"]; - folder.version = (ushort) ((int) reader["version"]); - return folder; - } - catch (Exception e) - { - MainLog.Instance.Error(e.ToString()); - } - - return null; - } - - - /// - /// Returns a specified inventory folder - /// - /// The folder to return - /// A folder class - public InventoryFolderBase getInventoryFolder(LLUUID folderID) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["uuid"] = folderID.ToString(); - - IDbCommand result = database.Query("SELECT * FROM inventoryfolders WHERE folderID = @uuid", param); - IDataReader reader = result.ExecuteReader(); - - reader.Read(); - InventoryFolderBase folder = readInventoryFolder(reader); - reader.Close(); - result.Dispose(); - - return folder; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - - /// - /// Adds a specified item to the database - /// - /// The inventory item - public void addInventoryItem(InventoryItemBase item) - { - string sql = "INSERT INTO inventoryitems"; - sql += - "([inventoryID], [assetID], [assetType], [parentFolderID], [avatarID], [inventoryName], [inventoryDescription], [inventoryNextPermissions], [inventoryCurrentPermissions], [invType], [creatorID], [inventoryBasePermissions], [inventoryEveryOnePermissions]) VALUES "; - sql += - "(@inventoryID, @assetID, @assetType, @parentFolderID, @avatarID, @inventoryName, @inventoryDescription, @inventoryNextPermissions, @inventoryCurrentPermissions, @invType, @creatorID, @inventoryBasePermissions, @inventoryEveryOnePermissions);"; - - try - { - Dictionary param = new Dictionary(); - param["inventoryID"] = item.inventoryID.ToString(); - param["assetID"] = item.assetID.ToString(); - param["assetType"] = item.assetType.ToString(); - param["parentFolderID"] = item.parentFolderID.ToString(); - param["avatarID"] = item.avatarID.ToString(); - param["inventoryName"] = item.inventoryName; - param["inventoryDescription"] = item.inventoryDescription; - param["inventoryNextPermissions"] = item.inventoryNextPermissions.ToString(); - param["inventoryCurrentPermissions"] = item.inventoryCurrentPermissions.ToString(); - param["invType"] = Convert.ToString(item.invType); - param["creatorID"] = item.creatorsID.ToString(); - param["inventoryBasePermissions"] = Convert.ToString(item.inventoryBasePermissions); - param["inventoryEveryOnePermissions"] = Convert.ToString(item.inventoryEveryOnePermissions); - - IDbCommand result = database.Query(sql, param); - result.ExecuteNonQuery(); - result.Dispose(); - } - catch (SqlException e) - { - MainLog.Instance.Error(e.ToString()); - } - } - - /// - /// Updates the specified inventory item - /// - /// Inventory item to update - public void updateInventoryItem(InventoryItemBase item) - { - SqlCommand command = new SqlCommand("UPDATE inventoryitems set inventoryID = @inventoryID, " + - "assetID = @assetID, " + - "assetType = @assetType" + - "parentFolderID = @parentFolderID" + - "avatarID = @avatarID" + - "inventoryName = @inventoryName" + - "inventoryDescription = @inventoryDescription" + - "inventoryNextPermissions = @inventoryNextPermissions" + - "inventoryCurrentPermissions = @inventoryCurrentPermissions" + - "invType = @invType" + - "creatorID = @creatorID" + - "inventoryBasePermissions = @inventoryBasePermissions" + - "inventoryEveryOnePermissions = @inventoryEveryOnePermissions) where " + - "inventoryID = @keyInventoryID;", database.getConnection()); - SqlParameter param1 = new SqlParameter("@inventoryID", item.inventoryID.ToString()); - SqlParameter param2 = new SqlParameter("@assetID", item.assetID); - SqlParameter param3 = new SqlParameter("@assetType", item.assetType); - SqlParameter param4 = new SqlParameter("@parentFolderID", item.parentFolderID); - SqlParameter param5 = new SqlParameter("@avatarID", item.avatarID); - SqlParameter param6 = new SqlParameter("@inventoryName", item.inventoryName); - SqlParameter param7 = new SqlParameter("@inventoryDescription", item.inventoryDescription); - SqlParameter param8 = new SqlParameter("@inventoryNextPermissions", item.inventoryNextPermissions); - SqlParameter param9 = new SqlParameter("@inventoryCurrentPermissions", item.inventoryCurrentPermissions); - SqlParameter param10 = new SqlParameter("@invType", item.invType); - SqlParameter param11 = new SqlParameter("@creatorID", item.creatorsID); - SqlParameter param12 = new SqlParameter("@inventoryBasePermissions", item.inventoryBasePermissions); - SqlParameter param13 = new SqlParameter("@inventoryEveryOnePermissions", item.inventoryEveryOnePermissions); - SqlParameter param14 = new SqlParameter("@keyInventoryID", item.inventoryID.ToString()); - command.Parameters.Add(param1); - command.Parameters.Add(param2); - command.Parameters.Add(param3); - command.Parameters.Add(param4); - command.Parameters.Add(param5); - command.Parameters.Add(param6); - command.Parameters.Add(param7); - command.Parameters.Add(param8); - command.Parameters.Add(param9); - command.Parameters.Add(param10); - command.Parameters.Add(param11); - command.Parameters.Add(param12); - command.Parameters.Add(param13); - command.Parameters.Add(param14); - - try - { - command.ExecuteNonQuery(); - } - catch (Exception e) - { - MainLog.Instance.Error(e.ToString()); - } - } - - /// - /// - /// - /// - public void deleteInventoryItem(LLUUID itemID) - { - try - { - Dictionary param = new Dictionary(); - param["uuid"] = itemID.ToString(); - - IDbCommand cmd = database.Query("DELETE FROM inventoryitems WHERE inventoryID=@uuid", param); - cmd.ExecuteNonQuery(); - cmd.Dispose(); - } - catch (SqlException e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - } - } - - /// - /// Creates a new inventory folder - /// - /// Folder to create - public void addInventoryFolder(InventoryFolderBase folder) - { - string sql = - "INSERT INTO inventoryfolders ([folderID], [agentID], [parentFolderID], [folderName], [type], [version]) VALUES "; - sql += "(@folderID, @agentID, @parentFolderID, @folderName, @type, @version);"; - - - Dictionary param = new Dictionary(); - param["folderID"] = folder.folderID.ToString(); - param["agentID"] = folder.agentID.ToString(); - param["parentFolderID"] = folder.parentID.ToString(); - param["folderName"] = folder.name; - param["type"] = Convert.ToString(folder.type); - param["version"] = Convert.ToString(folder.version); - - try - { - IDbCommand result = database.Query(sql, param); - result.ExecuteNonQuery(); - result.Dispose(); - } - catch (Exception e) - { - MainLog.Instance.Error(e.ToString()); - } - } - - /// - /// Updates an inventory folder - /// - /// Folder to update - public void updateInventoryFolder(InventoryFolderBase folder) - { - SqlCommand command = new SqlCommand("UPDATE inventoryfolders set folderID = @folderID, " + - "agentID = @agentID, " + - "parentFolderID = @parentFolderID," + - "folderName = @folderName," + - "type = @type," + - "version = @version where " + - "folderID = @keyFolderID;", database.getConnection()); - SqlParameter param1 = new SqlParameter("@folderID", folder.folderID.ToString()); - SqlParameter param2 = new SqlParameter("@agentID", folder.agentID.ToString()); - SqlParameter param3 = new SqlParameter("@parentFolderID", folder.parentID.ToString()); - SqlParameter param4 = new SqlParameter("@folderName", folder.name); - SqlParameter param5 = new SqlParameter("@type", folder.type); - SqlParameter param6 = new SqlParameter("@version", folder.version); - SqlParameter param7 = new SqlParameter("@keyFolderID", folder.folderID.ToString()); - command.Parameters.Add(param1); - command.Parameters.Add(param2); - command.Parameters.Add(param3); - command.Parameters.Add(param4); - command.Parameters.Add(param5); - command.Parameters.Add(param6); - command.Parameters.Add(param7); - - try - { - command.ExecuteNonQuery(); - } - catch (Exception e) - { - MainLog.Instance.Error(e.ToString()); - } - } - - /// - /// Updates an inventory folder - /// - /// Folder to update - public void moveInventoryFolder(InventoryFolderBase folder) - { - SqlCommand command = new SqlCommand("UPDATE inventoryfolders set folderID = @folderID, " + - "parentFolderID = @parentFolderID," + - "folderID = @keyFolderID;", database.getConnection()); - SqlParameter param1 = new SqlParameter("@folderID", folder.folderID.ToString()); - SqlParameter param2 = new SqlParameter("@parentFolderID", folder.parentID.ToString()); - SqlParameter param3 = new SqlParameter("@keyFolderID", folder.folderID.ToString()); - command.Parameters.Add(param1); - command.Parameters.Add(param2); - command.Parameters.Add(param3); - - try - { - command.ExecuteNonQuery(); - } - catch (Exception e) - { - MainLog.Instance.Error(e.ToString()); - } - } - - /// - /// Append a list of all the child folders of a parent folder - /// - /// list where folders will be appended - /// ID of parent - protected void getInventoryFolders(ref List folders, LLUUID parentID) - { - List subfolderList = getInventoryFolders(parentID); - - foreach (InventoryFolderBase f in subfolderList) - folders.Add(f); - } - - /// - /// Returns all child folders in the hierarchy from the parent folder and down - /// - /// The folder to get subfolders for - /// A list of inventory folders - protected List getFolderHierarchy(LLUUID parentID) - { - List folders = new List(); - getInventoryFolders(ref folders, parentID); - - for (int i = 0; i < folders.Count; i++) - getInventoryFolders(ref folders, folders[i].folderID); - - return folders; - } - - protected void deleteOneFolder(LLUUID folderID) - { - try - { - Dictionary param = new Dictionary(); - param["folderID"] = folderID.ToString(); - - IDbCommand cmd = database.Query("DELETE FROM inventoryfolders WHERE folderID=@folderID", param); - cmd.ExecuteNonQuery(); - cmd.Dispose(); - } - catch (SqlException e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - } - } - - protected void deleteItemsInFolder(LLUUID folderID) - { - try - { - Dictionary param = new Dictionary(); - param["parentFolderID"] = folderID.ToString(); - - - IDbCommand cmd = - database.Query("DELETE FROM inventoryitems WHERE parentFolderID=@parentFolderID", param); - cmd.ExecuteNonQuery(); - cmd.Dispose(); - } - catch (SqlException e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - } - } - - - /// - /// Delete an inventory folder - /// - /// Id of folder to delete - public void deleteInventoryFolder(LLUUID folderID) - { - lock (database) - { - List subFolders = getFolderHierarchy(folderID); - - //Delete all sub-folders - foreach (InventoryFolderBase f in subFolders) - { - deleteOneFolder(f.folderID); - deleteItemsInFolder(f.folderID); - } - - //Delete the actual row - deleteOneFolder(folderID); - deleteItemsInFolder(folderID); - } - } - } -} \ No newline at end of file +/* +* 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.Generic; +using System.Data; +using System.Data.SqlClient; +using libsecondlife; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Data.MSSQL +{ + /// + /// A MySQL interface for the inventory server + /// + public class MSSQLInventoryData : IInventoryData + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// The database manager + /// + private MSSQLManager database; + + /// + /// Loads and initialises this database plugin + /// + public void Initialise() + { + IniFile GridDataMySqlFile = new IniFile("mssql_connection.ini"); + string settingDataSource = GridDataMySqlFile.ParseFileReadValue("data_source"); + string settingInitialCatalog = GridDataMySqlFile.ParseFileReadValue("initial_catalog"); + string settingPersistSecurityInfo = GridDataMySqlFile.ParseFileReadValue("persist_security_info"); + string settingUserId = GridDataMySqlFile.ParseFileReadValue("user_id"); + string settingPassword = GridDataMySqlFile.ParseFileReadValue("password"); + + database = + new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, + settingPassword); + TestTables(); + } + + #region Test and initialization code + + private void UpgradeFoldersTable(string tableName) + { + // null as the version, indicates that the table didn't exist + if (tableName == null) + { + database.ExecuteResourceSql("CreateFoldersTable.sql"); + //database.ExecuteResourceSql("UpgradeFoldersTableToVersion2.sql"); + return; + } + } + + private void UpgradeItemsTable(string tableName) + { + // null as the version, indicates that the table didn't exist + if (tableName == null) + { + database.ExecuteResourceSql("CreateItemsTable.sql"); + //database.ExecuteResourceSql("UpgradeItemsTableToVersion2.sql"); + return; + } + } + + private void TestTables() + { + Dictionary tableList = new Dictionary(); + + tableList["inventoryfolders"] = null; + tableList["inventoryitems"] = null; + + database.GetTableVersion(tableList); + + UpgradeFoldersTable(tableList["inventoryfolders"]); + UpgradeItemsTable(tableList["inventoryitems"]); + } + + #endregion + + /// + /// The name of this DB provider + /// + /// Name of DB provider + public string getName() + { + return "MSSQL Inventory Data Interface"; + } + + /// + /// Closes this DB provider + /// + public void Close() + { + // Do nothing. + } + + /// + /// Returns the version of this DB provider + /// + /// A string containing the DB provider + public string getVersion() + { + return database.getVersion(); + } + + /// + /// Returns a list of items in a specified folder + /// + /// The folder to search + /// A list containing inventory items + public List getInventoryInFolder(LLUUID folderID) + { + try + { + lock (database) + { + List items = new List(); + + Dictionary param = new Dictionary(); + param["parentFolderID"] = folderID.ToString(); + + IDbCommand result = + database.Query("SELECT * FROM inventoryitems WHERE parentFolderID = @parentFolderID", param); + IDataReader reader = result.ExecuteReader(); + + while (reader.Read()) + items.Add(readInventoryItem(reader)); + + reader.Close(); + result.Dispose(); + + return items; + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return null; + } + } + + /// + /// Returns a list of the root folders within a users inventory + /// + /// The user whos inventory is to be searched + /// A list of folder objects + public List getUserRootFolders(LLUUID user) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["uuid"] = user.ToString(); + param["zero"] = LLUUID.Zero.ToString(); + + IDbCommand result = + database.Query( + "SELECT * FROM inventoryfolders WHERE parentFolderID = @zero AND agentID = @uuid", param); + IDataReader reader = result.ExecuteReader(); + + List items = new List(); + while (reader.Read()) + items.Add(readInventoryFolder(reader)); + + + reader.Close(); + result.Dispose(); + + return items; + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return null; + } + } + + // see InventoryItemBase.getUserRootFolder + public InventoryFolderBase getUserRootFolder(LLUUID user) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["uuid"] = user.ToString(); + param["zero"] = LLUUID.Zero.ToString(); + + IDbCommand result = + database.Query( + "SELECT * FROM inventoryfolders WHERE parentFolderID = @zero AND agentID = @uuid", param); + IDataReader reader = result.ExecuteReader(); + + List items = new List(); + while (reader.Read()) + items.Add(readInventoryFolder(reader)); + + InventoryFolderBase rootFolder = null; + + // There should only ever be one root folder for a user. However, if there's more + // than one we'll simply use the first one rather than failing. It would be even + // nicer to print some message to this effect, but this feels like it's too low a + // to put such a message out, and it's too minor right now to spare the time to + // suitably refactor. + if (items.Count > 0) + { + rootFolder = items[0]; + } + + reader.Close(); + result.Dispose(); + + return rootFolder; + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return null; + } + } + + /// + /// Returns a list of folders in a users inventory contained within the specified folder + /// + /// The folder to search + /// A list of inventory folders + public List getInventoryFolders(LLUUID parentID) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["parentFolderID"] = parentID.ToString(); + + + IDbCommand result = + database.Query("SELECT * FROM inventoryfolders WHERE parentFolderID = @parentFolderID", param); + IDataReader reader = result.ExecuteReader(); + + List items = new List(); + + while (reader.Read()) + items.Add(readInventoryFolder(reader)); + + reader.Close(); + result.Dispose(); + + return items; + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return null; + } + } + + /// + /// Reads a one item from an SQL result + /// + /// The SQL Result + /// the item read + private InventoryItemBase readInventoryItem(IDataReader reader) + { + try + { + InventoryItemBase item = new InventoryItemBase(); + + item.inventoryID = new LLUUID((string) reader["inventoryID"]); + item.assetID = new LLUUID((string) reader["assetID"]); + item.assetType = (int) reader["assetType"]; + item.parentFolderID = new LLUUID((string) reader["parentFolderID"]); + item.avatarID = new LLUUID((string) reader["avatarID"]); + item.inventoryName = (string) reader["inventoryName"]; + item.inventoryDescription = (string) reader["inventoryDescription"]; + item.inventoryNextPermissions = Convert.ToUInt32(reader["inventoryNextPermissions"]); + item.inventoryCurrentPermissions = Convert.ToUInt32(reader["inventoryCurrentPermissions"]); + item.invType = (int) reader["invType"]; + item.creatorsID = new LLUUID((string) reader["creatorID"]); + item.inventoryBasePermissions = Convert.ToUInt32(reader["inventoryBasePermissions"]); + item.inventoryEveryOnePermissions = Convert.ToUInt32(reader["inventoryEveryOnePermissions"]); + return item; + } + catch (SqlException e) + { + m_log.Error(e.ToString()); + } + + return null; + } + + /// + /// Returns a specified inventory item + /// + /// The item to return + /// An inventory item + public InventoryItemBase getInventoryItem(LLUUID itemID) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["inventoryID"] = itemID.ToString(); + + IDbCommand result = + database.Query("SELECT * FROM inventoryitems WHERE inventoryID = @inventoryID", param); + IDataReader reader = result.ExecuteReader(); + + InventoryItemBase item = null; + if (reader.Read()) + item = readInventoryItem(reader); + + reader.Close(); + result.Dispose(); + + return item; + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + } + return null; + } + + /// + /// Reads a list of inventory folders returned by a query. + /// + /// A MySQL Data Reader + /// A List containing inventory folders + protected InventoryFolderBase readInventoryFolder(IDataReader reader) + { + try + { + InventoryFolderBase folder = new InventoryFolderBase(); + folder.agentID = new LLUUID((string) reader["agentID"]); + folder.parentID = new LLUUID((string) reader["parentFolderID"]); + folder.folderID = new LLUUID((string) reader["folderID"]); + folder.name = (string) reader["folderName"]; + folder.type = (short) reader["type"]; + folder.version = (ushort) ((int) reader["version"]); + return folder; + } + catch (Exception e) + { + m_log.Error(e.ToString()); + } + + return null; + } + + + /// + /// Returns a specified inventory folder + /// + /// The folder to return + /// A folder class + public InventoryFolderBase getInventoryFolder(LLUUID folderID) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["uuid"] = folderID.ToString(); + + IDbCommand result = database.Query("SELECT * FROM inventoryfolders WHERE folderID = @uuid", param); + IDataReader reader = result.ExecuteReader(); + + reader.Read(); + InventoryFolderBase folder = readInventoryFolder(reader); + reader.Close(); + result.Dispose(); + + return folder; + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return null; + } + } + + /// + /// Adds a specified item to the database + /// + /// The inventory item + public void addInventoryItem(InventoryItemBase item) + { + string sql = "INSERT INTO inventoryitems"; + sql += + "([inventoryID], [assetID], [assetType], [parentFolderID], [avatarID], [inventoryName], [inventoryDescription], [inventoryNextPermissions], [inventoryCurrentPermissions], [invType], [creatorID], [inventoryBasePermissions], [inventoryEveryOnePermissions]) VALUES "; + sql += + "(@inventoryID, @assetID, @assetType, @parentFolderID, @avatarID, @inventoryName, @inventoryDescription, @inventoryNextPermissions, @inventoryCurrentPermissions, @invType, @creatorID, @inventoryBasePermissions, @inventoryEveryOnePermissions);"; + + try + { + Dictionary param = new Dictionary(); + param["inventoryID"] = item.inventoryID.ToString(); + param["assetID"] = item.assetID.ToString(); + param["assetType"] = item.assetType.ToString(); + param["parentFolderID"] = item.parentFolderID.ToString(); + param["avatarID"] = item.avatarID.ToString(); + param["inventoryName"] = item.inventoryName; + param["inventoryDescription"] = item.inventoryDescription; + param["inventoryNextPermissions"] = item.inventoryNextPermissions.ToString(); + param["inventoryCurrentPermissions"] = item.inventoryCurrentPermissions.ToString(); + param["invType"] = Convert.ToString(item.invType); + param["creatorID"] = item.creatorsID.ToString(); + param["inventoryBasePermissions"] = Convert.ToString(item.inventoryBasePermissions); + param["inventoryEveryOnePermissions"] = Convert.ToString(item.inventoryEveryOnePermissions); + + IDbCommand result = database.Query(sql, param); + result.ExecuteNonQuery(); + result.Dispose(); + } + catch (SqlException e) + { + m_log.Error(e.ToString()); + } + } + + /// + /// Updates the specified inventory item + /// + /// Inventory item to update + public void updateInventoryItem(InventoryItemBase item) + { + SqlCommand command = new SqlCommand("UPDATE inventoryitems set inventoryID = @inventoryID, " + + "assetID = @assetID, " + + "assetType = @assetType" + + "parentFolderID = @parentFolderID" + + "avatarID = @avatarID" + + "inventoryName = @inventoryName" + + "inventoryDescription = @inventoryDescription" + + "inventoryNextPermissions = @inventoryNextPermissions" + + "inventoryCurrentPermissions = @inventoryCurrentPermissions" + + "invType = @invType" + + "creatorID = @creatorID" + + "inventoryBasePermissions = @inventoryBasePermissions" + + "inventoryEveryOnePermissions = @inventoryEveryOnePermissions) where " + + "inventoryID = @keyInventoryID;", database.getConnection()); + SqlParameter param1 = new SqlParameter("@inventoryID", item.inventoryID.ToString()); + SqlParameter param2 = new SqlParameter("@assetID", item.assetID); + SqlParameter param3 = new SqlParameter("@assetType", item.assetType); + SqlParameter param4 = new SqlParameter("@parentFolderID", item.parentFolderID); + SqlParameter param5 = new SqlParameter("@avatarID", item.avatarID); + SqlParameter param6 = new SqlParameter("@inventoryName", item.inventoryName); + SqlParameter param7 = new SqlParameter("@inventoryDescription", item.inventoryDescription); + SqlParameter param8 = new SqlParameter("@inventoryNextPermissions", item.inventoryNextPermissions); + SqlParameter param9 = new SqlParameter("@inventoryCurrentPermissions", item.inventoryCurrentPermissions); + SqlParameter param10 = new SqlParameter("@invType", item.invType); + SqlParameter param11 = new SqlParameter("@creatorID", item.creatorsID); + SqlParameter param12 = new SqlParameter("@inventoryBasePermissions", item.inventoryBasePermissions); + SqlParameter param13 = new SqlParameter("@inventoryEveryOnePermissions", item.inventoryEveryOnePermissions); + SqlParameter param14 = new SqlParameter("@keyInventoryID", item.inventoryID.ToString()); + command.Parameters.Add(param1); + command.Parameters.Add(param2); + command.Parameters.Add(param3); + command.Parameters.Add(param4); + command.Parameters.Add(param5); + command.Parameters.Add(param6); + command.Parameters.Add(param7); + command.Parameters.Add(param8); + command.Parameters.Add(param9); + command.Parameters.Add(param10); + command.Parameters.Add(param11); + command.Parameters.Add(param12); + command.Parameters.Add(param13); + command.Parameters.Add(param14); + + try + { + command.ExecuteNonQuery(); + } + catch (Exception e) + { + m_log.Error(e.ToString()); + } + } + + /// + /// + /// + /// + public void deleteInventoryItem(LLUUID itemID) + { + try + { + Dictionary param = new Dictionary(); + param["uuid"] = itemID.ToString(); + + IDbCommand cmd = database.Query("DELETE FROM inventoryitems WHERE inventoryID=@uuid", param); + cmd.ExecuteNonQuery(); + cmd.Dispose(); + } + catch (SqlException e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + } + } + + /// + /// Creates a new inventory folder + /// + /// Folder to create + public void addInventoryFolder(InventoryFolderBase folder) + { + string sql = + "INSERT INTO inventoryfolders ([folderID], [agentID], [parentFolderID], [folderName], [type], [version]) VALUES "; + sql += "(@folderID, @agentID, @parentFolderID, @folderName, @type, @version);"; + + + Dictionary param = new Dictionary(); + param["folderID"] = folder.folderID.ToString(); + param["agentID"] = folder.agentID.ToString(); + param["parentFolderID"] = folder.parentID.ToString(); + param["folderName"] = folder.name; + param["type"] = Convert.ToString(folder.type); + param["version"] = Convert.ToString(folder.version); + + try + { + IDbCommand result = database.Query(sql, param); + result.ExecuteNonQuery(); + result.Dispose(); + } + catch (Exception e) + { + m_log.Error(e.ToString()); + } + } + + /// + /// Updates an inventory folder + /// + /// Folder to update + public void updateInventoryFolder(InventoryFolderBase folder) + { + SqlCommand command = new SqlCommand("UPDATE inventoryfolders set folderID = @folderID, " + + "agentID = @agentID, " + + "parentFolderID = @parentFolderID," + + "folderName = @folderName," + + "type = @type," + + "version = @version where " + + "folderID = @keyFolderID;", database.getConnection()); + SqlParameter param1 = new SqlParameter("@folderID", folder.folderID.ToString()); + SqlParameter param2 = new SqlParameter("@agentID", folder.agentID.ToString()); + SqlParameter param3 = new SqlParameter("@parentFolderID", folder.parentID.ToString()); + SqlParameter param4 = new SqlParameter("@folderName", folder.name); + SqlParameter param5 = new SqlParameter("@type", folder.type); + SqlParameter param6 = new SqlParameter("@version", folder.version); + SqlParameter param7 = new SqlParameter("@keyFolderID", folder.folderID.ToString()); + command.Parameters.Add(param1); + command.Parameters.Add(param2); + command.Parameters.Add(param3); + command.Parameters.Add(param4); + command.Parameters.Add(param5); + command.Parameters.Add(param6); + command.Parameters.Add(param7); + + try + { + command.ExecuteNonQuery(); + } + catch (Exception e) + { + m_log.Error(e.ToString()); + } + } + + /// + /// Updates an inventory folder + /// + /// Folder to update + public void moveInventoryFolder(InventoryFolderBase folder) + { + SqlCommand command = new SqlCommand("UPDATE inventoryfolders set folderID = @folderID, " + + "parentFolderID = @parentFolderID," + + "folderID = @keyFolderID;", database.getConnection()); + SqlParameter param1 = new SqlParameter("@folderID", folder.folderID.ToString()); + SqlParameter param2 = new SqlParameter("@parentFolderID", folder.parentID.ToString()); + SqlParameter param3 = new SqlParameter("@keyFolderID", folder.folderID.ToString()); + command.Parameters.Add(param1); + command.Parameters.Add(param2); + command.Parameters.Add(param3); + + try + { + command.ExecuteNonQuery(); + } + catch (Exception e) + { + m_log.Error(e.ToString()); + } + } + + /// + /// Append a list of all the child folders of a parent folder + /// + /// list where folders will be appended + /// ID of parent + protected void getInventoryFolders(ref List folders, LLUUID parentID) + { + List subfolderList = getInventoryFolders(parentID); + + foreach (InventoryFolderBase f in subfolderList) + folders.Add(f); + } + + /// + /// Returns all child folders in the hierarchy from the parent folder and down + /// + /// The folder to get subfolders for + /// A list of inventory folders + protected List getFolderHierarchy(LLUUID parentID) + { + List folders = new List(); + getInventoryFolders(ref folders, parentID); + + for (int i = 0; i < folders.Count; i++) + getInventoryFolders(ref folders, folders[i].folderID); + + return folders; + } + + protected void deleteOneFolder(LLUUID folderID) + { + try + { + Dictionary param = new Dictionary(); + param["folderID"] = folderID.ToString(); + + IDbCommand cmd = database.Query("DELETE FROM inventoryfolders WHERE folderID=@folderID", param); + cmd.ExecuteNonQuery(); + cmd.Dispose(); + } + catch (SqlException e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + } + } + + protected void deleteItemsInFolder(LLUUID folderID) + { + try + { + Dictionary param = new Dictionary(); + param["parentFolderID"] = folderID.ToString(); + + + IDbCommand cmd = + database.Query("DELETE FROM inventoryitems WHERE parentFolderID=@parentFolderID", param); + cmd.ExecuteNonQuery(); + cmd.Dispose(); + } + catch (SqlException e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + } + } + + + /// + /// Delete an inventory folder + /// + /// Id of folder to delete + public void deleteInventoryFolder(LLUUID folderID) + { + lock (database) + { + List subFolders = getFolderHierarchy(folderID); + + //Delete all sub-folders + foreach (InventoryFolderBase f in subFolders) + { + deleteOneFolder(f.folderID); + deleteItemsInFolder(f.folderID); + } + + //Delete the actual row + deleteOneFolder(folderID); + deleteItemsInFolder(folderID); + } + } + } +} diff --git a/OpenSim/Framework/Data.MSSQL/MSSQLLogData.cs b/OpenSim/Framework/Data.MSSQL/MSSQLLogData.cs index 4fdaa8aef2..dcd60403cc 100644 --- a/OpenSim/Framework/Data.MSSQL/MSSQLLogData.cs +++ b/OpenSim/Framework/Data.MSSQL/MSSQLLogData.cs @@ -1,105 +1,120 @@ -/* -* 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. -* -*/ -namespace OpenSim.Framework.Data.MSSQL -{ - /// - /// An interface to the log database for MySQL - /// - internal class MSSQLLogData : ILogData - { - /// - /// The database manager - /// - public MSSQLManager database; - - /// - /// Artificial constructor called when the plugin is loaded - /// - public void Initialise() - { - IniFile GridDataMySqlFile = new IniFile("mssql_connection.ini"); - string settingDataSource = GridDataMySqlFile.ParseFileReadValue("data_source"); - string settingInitialCatalog = GridDataMySqlFile.ParseFileReadValue("initial_catalog"); - string settingPersistSecurityInfo = GridDataMySqlFile.ParseFileReadValue("persist_security_info"); - string settingUserId = GridDataMySqlFile.ParseFileReadValue("user_id"); - string settingPassword = GridDataMySqlFile.ParseFileReadValue("password"); - - database = - new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, - settingPassword); - } - - /// - /// Saves a log item to the database - /// - /// The daemon triggering the event - /// The target of the action (region / agent UUID, etc) - /// The method call where the problem occured - /// The arguments passed to the method - /// How critical is this? - /// The message to log - public void saveLog(string serverDaemon, string target, string methodCall, string arguments, int priority, - string logMessage) - { - try - { - database.insertLogRow(serverDaemon, target, methodCall, arguments, priority, logMessage); - } - catch - { - database.Reconnect(); - } - } - - /// - /// Returns the name of this DB provider - /// - /// A string containing the DB provider name - public string getName() - { - return "MSSQL Logdata Interface"; - } - - /// - /// Closes the database provider - /// - public void Close() - { - // Do nothing. - } - - /// - /// Returns the version of this DB provider - /// - /// A string containing the provider version - public string getVersion() - { - return "0.1"; - } - } -} \ No newline at end of file +/* +* 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.Collections.Generic; +using System.Data; + +namespace OpenSim.Framework.Data.MSSQL +{ + /// + /// An interface to the log database for MySQL + /// + internal class MSSQLLogData : ILogData + { + /// + /// The database manager + /// + public MSSQLManager database; + + /// + /// Artificial constructor called when the plugin is loaded + /// + public void Initialise() + { + IniFile GridDataMySqlFile = new IniFile("mssql_connection.ini"); + string settingDataSource = GridDataMySqlFile.ParseFileReadValue("data_source"); + string settingInitialCatalog = GridDataMySqlFile.ParseFileReadValue("initial_catalog"); + string settingPersistSecurityInfo = GridDataMySqlFile.ParseFileReadValue("persist_security_info"); + string settingUserId = GridDataMySqlFile.ParseFileReadValue("user_id"); + string settingPassword = GridDataMySqlFile.ParseFileReadValue("password"); + + database = + new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, + settingPassword); + + IDbCommand cmd = database.Query("select top 1 * from logs", new Dictionary()); + try + { + cmd.ExecuteNonQuery(); + cmd.Dispose(); + } + catch + { + database.ExecuteResourceSql("Mssql-logs.sql"); + } + + } + + /// + /// Saves a log item to the database + /// + /// The daemon triggering the event + /// The target of the action (region / agent UUID, etc) + /// The method call where the problem occured + /// The arguments passed to the method + /// How critical is this? + /// The message to log + public void saveLog(string serverDaemon, string target, string methodCall, string arguments, int priority, + string logMessage) + { + try + { + database.insertLogRow(serverDaemon, target, methodCall, arguments, priority, logMessage); + } + catch + { + database.Reconnect(); + } + } + + /// + /// Returns the name of this DB provider + /// + /// A string containing the DB provider name + public string getName() + { + return "MSSQL Logdata Interface"; + } + + /// + /// Closes the database provider + /// + public void Close() + { + // Do nothing. + } + + /// + /// Returns the version of this DB provider + /// + /// A string containing the provider version + public string getVersion() + { + return "0.1"; + } + } +} diff --git a/OpenSim/Framework/Data.MSSQL/MSSQLManager.cs b/OpenSim/Framework/Data.MSSQL/MSSQLManager.cs index 7a92dc80b8..ed42fa83d4 100644 --- a/OpenSim/Framework/Data.MSSQL/MSSQLManager.cs +++ b/OpenSim/Framework/Data.MSSQL/MSSQLManager.cs @@ -1,769 +1,566 @@ -/* -* 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.Generic; -using System.Data; -using System.Data.SqlClient; -using System.IO; -using System.Reflection; -using libsecondlife; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.Data.MSSQL -{ - /// - /// A management class for the MS SQL Storage Engine - /// - internal class MSSQLManager - { - /// - /// The database connection object - /// - private IDbConnection dbcon; - - /// - /// Connection string for ADO.net - /// - private string connectionString; - - /// - /// Initialises and creates a new Sql connection and maintains it. - /// - /// The Sql server being connected to - /// The name of the Sql database being used - /// The username logging into the database - /// The password for the user logging in - /// Whether to use connection pooling or not, can be one of the following: 'yes', 'true', 'no' or 'false', if unsure use 'false'. - public MSSQLManager(string dataSource, string initialCatalog, string persistSecurityInfo, string userId, - string password) - { - try - { - connectionString = "Data Source=" + dataSource + ";Initial Catalog=" + initialCatalog + - ";Persist Security Info=" + persistSecurityInfo + ";User ID=" + userId + ";Password=" + - password + ";"; - dbcon = new SqlConnection(connectionString); - TestTables(dbcon); - //System.Threading.Thread.Sleep(3000); - dbcon.Open(); - } - catch (Exception e) - { - throw new Exception("Error initialising Sql Database: " + e.ToString()); - } - } - - private bool TestTables(IDbConnection conn) - { - IDbCommand cmd = Query("SELECT * FROM regions", new Dictionary()); - //SqlCommand cmd = (SqlCommand)dbcon.CreateCommand(); - //cmd.CommandText = "SELECT * FROM regions"; - try - { - conn.Open(); - cmd.ExecuteNonQuery(); - cmd.Dispose(); - conn.Close(); - } - catch (Exception) - { - MainLog.Instance.Verbose("DATASTORE", "MSSQL Database doesn't exist... creating"); - InitDB(conn); - } - cmd = Query("select top 1 webLoginKey from users", new Dictionary()); - try - { - conn.Open(); - cmd.ExecuteNonQuery(); - cmd.Dispose(); - conn.Close(); - } - catch (Exception) - { - conn.Close(); - conn.Open(); - cmd = Query("alter table users add [webLoginKey] varchar(36) default NULL", new Dictionary()); - cmd.ExecuteNonQuery(); - cmd.Dispose(); - conn.Close(); - } - return true; - } - - private void InitDB(IDbConnection conn) - { - string createRegions = defineTable(createRegionsTable()); - Dictionary param = new Dictionary(); - IDbCommand pcmd = Query(createRegions, param); - if (conn.State == ConnectionState.Closed) - { - conn.Open(); - } - pcmd.ExecuteNonQuery(); - pcmd.Dispose(); - - ExecuteResourceSql("Mssql-users.sql"); - ExecuteResourceSql("Mssql-agents.sql"); - ExecuteResourceSql("Mssql-logs.sql"); - - conn.Close(); - } - - private DataTable createRegionsTable() - { - DataTable regions = new DataTable("regions"); - - createCol(regions, "regionHandle", typeof (ulong)); - createCol(regions, "regionName", typeof (String)); - createCol(regions, "uuid", typeof (String)); - - createCol(regions, "regionRecvKey", typeof (String)); - createCol(regions, "regionSecret", typeof (String)); - createCol(regions, "regionSendKey", typeof (String)); - - createCol(regions, "regionDataURI", typeof (String)); - createCol(regions, "serverIP", typeof (String)); - createCol(regions, "serverPort", typeof (String)); - createCol(regions, "serverURI", typeof (String)); - - - createCol(regions, "locX", typeof (uint)); - createCol(regions, "locY", typeof (uint)); - createCol(regions, "locZ", typeof (uint)); - - createCol(regions, "eastOverrideHandle", typeof (ulong)); - createCol(regions, "westOverrideHandle", typeof (ulong)); - createCol(regions, "southOverrideHandle", typeof (ulong)); - createCol(regions, "northOverrideHandle", typeof (ulong)); - - createCol(regions, "regionAssetURI", typeof (String)); - createCol(regions, "regionAssetRecvKey", typeof (String)); - createCol(regions, "regionAssetSendKey", typeof (String)); - - createCol(regions, "regionUserURI", typeof (String)); - createCol(regions, "regionUserRecvKey", typeof (String)); - createCol(regions, "regionUserSendKey", typeof (String)); - - createCol(regions, "regionMapTexture", typeof (String)); - createCol(regions, "serverHttpPort", typeof (String)); - createCol(regions, "serverRemotingPort", typeof (uint)); - - // Add in contraints - regions.PrimaryKey = new DataColumn[] {regions.Columns["UUID"]}; - return regions; - } - - protected static void createCol(DataTable dt, string name, Type type) - { - DataColumn col = new DataColumn(name, type); - dt.Columns.Add(col); - } - - protected static string defineTable(DataTable dt) - { - string sql = "create table " + dt.TableName + "("; - string subsql = ""; - foreach (DataColumn col in dt.Columns) - { - if (subsql.Length > 0) - { - // a map function would rock so much here - subsql += ",\n"; - } - - subsql += col.ColumnName + " " + SqlType(col.DataType); - if (col == dt.PrimaryKey[0]) - { - subsql += " primary key"; - } - } - sql += subsql; - sql += ")"; - return sql; - } - - - // this is something we'll need to implement for each db - // slightly differently. - private static string SqlType(Type type) - { - if (type == typeof (String)) - { - return "varchar(255)"; - } - else if (type == typeof (Int32)) - { - return "integer"; - } - else if (type == typeof (Double)) - { - return "float"; - } - else if (type == typeof (Byte[])) - { - return "image"; - } - else - { - return "varchar(255)"; - } - } - - /// - /// Shuts down the database connection - /// - public void Close() - { - dbcon.Close(); - dbcon = null; - } - - /// - /// Reconnects to the database - /// - public void Reconnect() - { - lock (dbcon) - { - try - { - //string connectionString = "Data Source=WRK-OU-738\\SQLEXPRESS;Initial Catalog=rex;Persist Security Info=True;User ID=sa;Password=rex"; - // Close the DB connection - dbcon.Close(); - // Try reopen it - dbcon = new SqlConnection(connectionString); - dbcon.Open(); - } - catch (Exception e) - { - MainLog.Instance.Error("Unable to reconnect to database " + e.ToString()); - } - } - } - - /// - /// Runs a query with protection against SQL Injection by using parameterised input. - /// - /// The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y - /// The parameters - index so that @y is indexed as 'y' - /// A Sql DB Command - public IDbCommand Query(string sql, Dictionary parameters) - { - SqlCommand dbcommand = (SqlCommand) dbcon.CreateCommand(); - dbcommand.CommandText = sql; - foreach (KeyValuePair param in parameters) - { - dbcommand.Parameters.AddWithValue(param.Key, param.Value); - } - - return (IDbCommand) dbcommand; - } - - /// - /// Runs a database reader object and returns a region row - /// - /// An active database reader - /// A region row - public RegionProfileData getRegionRow(IDataReader reader) - { - RegionProfileData regionprofile = new RegionProfileData(); - - if (reader.Read()) - { - // Region Main - regionprofile.regionHandle = Convert.ToUInt64(reader["regionHandle"]); - regionprofile.regionName = (string) reader["regionName"]; - regionprofile.UUID = new LLUUID((string) reader["uuid"]); - - // Secrets - regionprofile.regionRecvKey = (string) reader["regionRecvKey"]; - regionprofile.regionSecret = (string) reader["regionSecret"]; - regionprofile.regionSendKey = (string) reader["regionSendKey"]; - - // Region Server - regionprofile.regionDataURI = (string) reader["regionDataURI"]; - regionprofile.regionOnline = false; // Needs to be pinged before this can be set. - regionprofile.serverIP = (string) reader["serverIP"]; - regionprofile.serverPort = Convert.ToUInt32(reader["serverPort"]); - regionprofile.serverURI = (string) reader["serverURI"]; - regionprofile.httpPort = Convert.ToUInt32(reader["serverHttpPort"]); - regionprofile.remotingPort = Convert.ToUInt32(reader["serverRemotingPort"]); - - - // Location - regionprofile.regionLocX = Convert.ToUInt32(reader["locX"]); - regionprofile.regionLocY = Convert.ToUInt32(reader["locY"]); - regionprofile.regionLocZ = Convert.ToUInt32(reader["locZ"]); - - // Neighbours - 0 = No Override - regionprofile.regionEastOverrideHandle = Convert.ToUInt64(reader["eastOverrideHandle"]); - regionprofile.regionWestOverrideHandle = Convert.ToUInt64(reader["westOverrideHandle"]); - regionprofile.regionSouthOverrideHandle = Convert.ToUInt64(reader["southOverrideHandle"]); - regionprofile.regionNorthOverrideHandle = Convert.ToUInt64(reader["northOverrideHandle"]); - - // Assets - regionprofile.regionAssetURI = (string) reader["regionAssetURI"]; - regionprofile.regionAssetRecvKey = (string) reader["regionAssetRecvKey"]; - regionprofile.regionAssetSendKey = (string) reader["regionAssetSendKey"]; - - // Userserver - regionprofile.regionUserURI = (string) reader["regionUserURI"]; - regionprofile.regionUserRecvKey = (string) reader["regionUserRecvKey"]; - regionprofile.regionUserSendKey = (string) reader["regionUserSendKey"]; - - // World Map Addition - string tempRegionMap = reader["regionMapTexture"].ToString(); - if (tempRegionMap != "") - { - regionprofile.regionMapTextureID = new LLUUID(tempRegionMap); - } - else - { - regionprofile.regionMapTextureID = new LLUUID(); - } - } - else - { - reader.Close(); - throw new Exception("No rows to return"); - } - return regionprofile; - } - - /// - /// Reads a user profile from an active data reader - /// - /// An active database reader - /// A user profile - public UserProfileData readUserRow(IDataReader reader) - { - UserProfileData retval = new UserProfileData(); - - if (reader.Read()) - { - retval.UUID = new LLUUID((string) reader["UUID"]); - retval.username = (string) reader["username"]; - retval.surname = (string) reader["lastname"]; - - retval.passwordHash = (string) reader["passwordHash"]; - retval.passwordSalt = (string) reader["passwordSalt"]; - - retval.homeRegion = Convert.ToUInt64(reader["homeRegion"].ToString()); - retval.homeLocation = new LLVector3( - Convert.ToSingle(reader["homeLocationX"].ToString()), - Convert.ToSingle(reader["homeLocationY"].ToString()), - Convert.ToSingle(reader["homeLocationZ"].ToString())); - retval.homeLookAt = new LLVector3( - Convert.ToSingle(reader["homeLookAtX"].ToString()), - Convert.ToSingle(reader["homeLookAtY"].ToString()), - Convert.ToSingle(reader["homeLookAtZ"].ToString())); - - retval.created = Convert.ToInt32(reader["created"].ToString()); - retval.lastLogin = Convert.ToInt32(reader["lastLogin"].ToString()); - - retval.userInventoryURI = (string) reader["userInventoryURI"]; - retval.userAssetURI = (string) reader["userAssetURI"]; - - retval.profileCanDoMask = Convert.ToUInt32(reader["profileCanDoMask"].ToString()); - retval.profileWantDoMask = Convert.ToUInt32(reader["profileWantDoMask"].ToString()); - - retval.profileAboutText = (string) reader["profileAboutText"]; - retval.profileFirstText = (string) reader["profileFirstText"]; - - retval.profileImage = new LLUUID((string) reader["profileImage"]); - retval.profileFirstImage = new LLUUID((string) reader["profileFirstImage"]); - retval.webLoginKey = new LLUUID((string)reader["webLoginKey"]); - } - else - { - return null; - } - return retval; - } - - /// - /// Reads an agent row from a database reader - /// - /// An active database reader - /// A user session agent - public UserAgentData readAgentRow(IDataReader reader) - { - UserAgentData retval = new UserAgentData(); - - if (reader.Read()) - { - // Agent IDs - retval.UUID = new LLUUID((string) reader["UUID"]); - retval.sessionID = new LLUUID((string) reader["sessionID"]); - retval.secureSessionID = new LLUUID((string) reader["secureSessionID"]); - - // Agent Who? - retval.agentIP = (string) reader["agentIP"]; - retval.agentPort = Convert.ToUInt32(reader["agentPort"].ToString()); - retval.agentOnline = Convert.ToBoolean(reader["agentOnline"].ToString()); - - // Login/Logout times (UNIX Epoch) - retval.loginTime = Convert.ToInt32(reader["loginTime"].ToString()); - retval.logoutTime = Convert.ToInt32(reader["logoutTime"].ToString()); - - // Current position - retval.currentRegion = (string) reader["currentRegion"]; - retval.currentHandle = Convert.ToUInt64(reader["currentHandle"].ToString()); - LLVector3.TryParse((string) reader["currentPos"], out retval.currentPos); - } - else - { - return null; - } - return retval; - } - - public AssetBase getAssetRow(IDataReader reader) - { - AssetBase asset = new AssetBase(); - if (reader.Read()) - { - // Region Main - - asset = new AssetBase(); - asset.Data = (byte[]) reader["data"]; - asset.Description = (string) reader["description"]; - asset.MediaURL = (string)reader["mediaUrl"]; - asset.FullID = new LLUUID((string) reader["id"]); - asset.InvType = Convert.ToSByte(reader["invType"]); - asset.Local = Convert.ToBoolean(reader["local"]); // ((sbyte)reader["local"]) != 0 ? true : false; - asset.Name = (string) reader["name"]; - asset.Type = Convert.ToSByte(reader["assetType"]); - } - else - { - return null; // throw new Exception("No rows to return"); - } - return asset; - } - - /// - /// Creates a new region in the database - /// - /// The region profile to insert - /// Successful? - public bool insertRegionRow(RegionProfileData profile) - { - //Insert new region - string sql = - "INSERT INTO regions ([regionHandle], [regionName], [uuid], [regionRecvKey], [regionSecret], [regionSendKey], [regionDataURI], "; - sql += - "[serverIP], [serverPort], [serverURI], [locX], [locY], [locZ], [eastOverrideHandle], [westOverrideHandle], [southOverrideHandle], [northOverrideHandle], [regionAssetURI], [regionAssetRecvKey], "; - sql += - "[regionAssetSendKey], [regionUserURI], [regionUserRecvKey], [regionUserSendKey], [regionMapTexture], [serverHttpPort], [serverRemotingPort]) VALUES "; - - sql += "(@regionHandle, @regionName, @uuid, @regionRecvKey, @regionSecret, @regionSendKey, @regionDataURI, "; - sql += - "@serverIP, @serverPort, @serverURI, @locX, @locY, @locZ, @eastOverrideHandle, @westOverrideHandle, @southOverrideHandle, @northOverrideHandle, @regionAssetURI, @regionAssetRecvKey, "; - sql += - "@regionAssetSendKey, @regionUserURI, @regionUserRecvKey, @regionUserSendKey, @regionMapTexture, @serverHttpPort, @serverRemotingPort);"; - - Dictionary parameters = new Dictionary(); - - parameters["regionHandle"] = profile.regionHandle.ToString(); - parameters["regionName"] = profile.regionName; - parameters["uuid"] = profile.UUID.ToString(); - parameters["regionRecvKey"] = profile.regionRecvKey; - parameters["regionSecret"] = profile.regionSecret; - parameters["regionSendKey"] = profile.regionSendKey; - parameters["regionDataURI"] = profile.regionDataURI; - parameters["serverIP"] = profile.serverIP; - parameters["serverPort"] = profile.serverPort.ToString(); - parameters["serverURI"] = profile.serverURI; - parameters["locX"] = profile.regionLocX.ToString(); - parameters["locY"] = profile.regionLocY.ToString(); - parameters["locZ"] = profile.regionLocZ.ToString(); - parameters["eastOverrideHandle"] = profile.regionEastOverrideHandle.ToString(); - parameters["westOverrideHandle"] = profile.regionWestOverrideHandle.ToString(); - parameters["northOverrideHandle"] = profile.regionNorthOverrideHandle.ToString(); - parameters["southOverrideHandle"] = profile.regionSouthOverrideHandle.ToString(); - parameters["regionAssetURI"] = profile.regionAssetURI; - parameters["regionAssetRecvKey"] = profile.regionAssetRecvKey; - parameters["regionAssetSendKey"] = profile.regionAssetSendKey; - parameters["regionUserURI"] = profile.regionUserURI; - parameters["regionUserRecvKey"] = profile.regionUserRecvKey; - parameters["regionUserSendKey"] = profile.regionUserSendKey; - parameters["regionMapTexture"] = profile.regionMapTextureID.ToString(); - parameters["serverHttpPort"] = profile.httpPort.ToString(); - parameters["serverRemotingPort"] = profile.remotingPort.ToString(); - - - bool returnval = false; - - try - { - IDbCommand result = Query(sql, parameters); - - if (result.ExecuteNonQuery() == 1) - returnval = true; - - result.Dispose(); - } - catch (Exception e) - { - MainLog.Instance.Error("MSSQLManager : " + e.ToString()); - } - - return returnval; - } - - - /// - /// Inserts a new row into the log database - /// - /// The daemon which triggered this event - /// Who were we operating on when this occured (region UUID, user UUID, etc) - /// The method call where the problem occured - /// The arguments passed to the method - /// How critical is this? - /// Extra message info - /// Saved successfully? - public bool insertLogRow(string serverDaemon, string target, string methodCall, string arguments, int priority, - string logMessage) - { - string sql = "INSERT INTO logs ([target], [server], [method], [arguments], [priority], [message]) VALUES "; - sql += "(@target, @server, @method, @arguments, @priority, @message);"; - - Dictionary parameters = new Dictionary(); - parameters["server"] = serverDaemon; - parameters["target"] = target; - parameters["method"] = methodCall; - parameters["arguments"] = arguments; - parameters["priority"] = priority.ToString(); - parameters["message"] = logMessage; - - bool returnval = false; - - try - { - IDbCommand result = Query(sql, parameters); - - if (result.ExecuteNonQuery() == 1) - returnval = true; - - result.Dispose(); - } - catch (Exception e) - { - MainLog.Instance.Error(e.ToString()); - return false; - } - - return returnval; - } - - - /// - /// Creates a new user and inserts it into the database - /// - /// User ID - /// First part of the login - /// Second part of the login - /// A salted hash of the users password - /// The salt used for the password hash - /// A regionHandle of the users home region - /// Home region position vector - /// Home region position vector - /// Home region position vector - /// Home region 'look at' vector - /// Home region 'look at' vector - /// Home region 'look at' vector - /// Account created (unix timestamp) - /// Last login (unix timestamp) - /// Users inventory URI - /// Users asset URI - /// I can do mask - /// I want to do mask - /// Profile text - /// Firstlife text - /// UUID for profile image - /// UUID for firstlife image - /// Success? - public bool insertUserRow(LLUUID uuid, string username, string lastname, string passwordHash, - string passwordSalt, UInt64 homeRegion, float homeLocX, float homeLocY, float homeLocZ, - float homeLookAtX, float homeLookAtY, float homeLookAtZ, int created, int lastlogin, - string inventoryURI, string assetURI, uint canDoMask, uint wantDoMask, - string aboutText, string firstText, - LLUUID profileImage, LLUUID firstImage, LLUUID webLoginKey) - { - string sql = "INSERT INTO users "; - sql += "([UUID], [username], [lastname], [passwordHash], [passwordSalt], [homeRegion], "; - sql += - "[homeLocationX], [homeLocationY], [homeLocationZ], [homeLookAtX], [homeLookAtY], [homeLookAtZ], [created], "; - sql += - "[lastLogin], [userInventoryURI], [userAssetURI], [profileCanDoMask], [profileWantDoMask], [profileAboutText], "; - sql += "[profileFirstText], [profileImage], [profileFirstImage], [webLoginKey]) VALUES "; - - sql += "(@UUID, @username, @lastname, @passwordHash, @passwordSalt, @homeRegion, "; - sql += - "@homeLocationX, @homeLocationY, @homeLocationZ, @homeLookAtX, @homeLookAtY, @homeLookAtZ, @created, "; - sql += - "@lastLogin, @userInventoryURI, @userAssetURI, @profileCanDoMask, @profileWantDoMask, @profileAboutText, "; - sql += "@profileFirstText, @profileImage, @profileFirstImage, @webLoginKey);"; - - Dictionary parameters = new Dictionary(); - parameters["UUID"] = uuid.ToString(); - parameters["username"] = username.ToString(); - parameters["lastname"] = lastname.ToString(); - parameters["passwordHash"] = passwordHash.ToString(); - parameters["passwordSalt"] = passwordSalt.ToString(); - parameters["homeRegion"] = homeRegion.ToString(); - parameters["homeLocationX"] = homeLocX.ToString(); - parameters["homeLocationY"] = homeLocY.ToString(); - parameters["homeLocationZ"] = homeLocZ.ToString(); - parameters["homeLookAtX"] = homeLookAtX.ToString(); - parameters["homeLookAtY"] = homeLookAtY.ToString(); - parameters["homeLookAtZ"] = homeLookAtZ.ToString(); - parameters["created"] = created.ToString(); - parameters["lastLogin"] = lastlogin.ToString(); - parameters["userInventoryURI"] = ""; - parameters["userAssetURI"] = ""; - parameters["profileCanDoMask"] = "0"; - parameters["profileWantDoMask"] = "0"; - parameters["profileAboutText"] = ""; - parameters["profileFirstText"] = ""; - parameters["profileImage"] = LLUUID.Zero.ToString(); - parameters["profileFirstImage"] = LLUUID.Zero.ToString(); - parameters["webLoginKey"] = LLUUID.Random().ToString(); - - bool returnval = false; - - try - { - IDbCommand result = Query(sql, parameters); - - if (result.ExecuteNonQuery() == 1) - returnval = true; - - result.Dispose(); - } - catch (Exception e) - { - MainLog.Instance.Error(e.ToString()); - return false; - } - - return returnval; - } - - /// - /// Execute a SQL statement stored in a resource, as a string - /// - /// - public void ExecuteResourceSql(string name) - { - try - { - SqlCommand cmd = new SqlCommand(getResourceString(name), (SqlConnection) dbcon); - cmd.ExecuteNonQuery(); - cmd.Dispose(); - } - catch (Exception e) - { - MainLog.Instance.Error("Unable to execute query " + e.ToString()); - } - } - - public SqlConnection getConnection() - { - return (SqlConnection) dbcon; - } - - /// - /// Given a list of tables, return the version of the tables, as seen in the database - /// - /// - public void GetTableVersion(Dictionary tableList) - { - lock (dbcon) - { - Dictionary param = new Dictionary(); - param["dbname"] = dbcon.Database; - IDbCommand tablesCmd = - Query("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_CATALOG=@dbname", param); - using (IDataReader tables = tablesCmd.ExecuteReader()) - { - while (tables.Read()) - { - try - { - string tableName = (string) tables["TABLE_NAME"]; - if (tableList.ContainsKey(tableName)) - tableList[tableName] = tableName; - } - catch (Exception e) - { - MainLog.Instance.Error(e.ToString()); - } - } - tables.Close(); - } - } - } - - private string getResourceString(string name) - { - Assembly assem = GetType().Assembly; - string[] names = assem.GetManifestResourceNames(); - - foreach (string s in names) - if (s.EndsWith(name)) - using (Stream resource = assem.GetManifestResourceStream(s)) - { - using (StreamReader resourceReader = new StreamReader(resource)) - { - string resourceString = resourceReader.ReadToEnd(); - return resourceString; - } - } - throw new Exception(string.Format("Resource '{0}' was not found", name)); - } - - /// - /// Returns the version of this DB provider - /// - /// A string containing the DB provider - public string getVersion() - { - Module module = GetType().Module; - string dllName = module.Assembly.ManifestModule.Name; - Version dllVersion = module.Assembly.GetName().Version; - - - return - string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build, - dllVersion.Revision); - } - } -} \ No newline at end of file +/* +* 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.Generic; +using System.Data; +using System.Data.SqlClient; +using System.IO; +using System.Reflection; +using libsecondlife; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Data.MSSQL +{ + /// + /// A management class for the MS SQL Storage Engine + /// + public class MSSQLManager + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// The database connection object + /// + private IDbConnection dbcon; + + /// + /// Connection string for ADO.net + /// + private readonly string connectionString; + + public MSSQLManager(string dataSource, string initialCatalog, string persistSecurityInfo, string userId, + string password) + { + connectionString = "Data Source=" + dataSource + ";Initial Catalog=" + initialCatalog + + ";Persist Security Info=" + persistSecurityInfo + ";User ID=" + userId + ";Password=" + + password + ";"; + dbcon = new SqlConnection(connectionString); + TestTables(dbcon); + //System.Threading.Thread.Sleep(3000); + dbcon.Open(); + } + catch (Exception e) + { + throw new Exception("Error initialising Sql Database: " + e.ToString()); + } + } + + private bool TestTables(IDbConnection conn) + { + IDbCommand cmd = Query("SELECT * FROM regions", new Dictionary()); + //SqlCommand cmd = (SqlCommand)dbcon.CreateCommand(); + //cmd.CommandText = "SELECT * FROM regions"; + try + { + conn.Open(); + cmd.ExecuteNonQuery(); + cmd.Dispose(); + conn.Close(); + } + catch (Exception) + { + MainLog.Instance.Verbose("DATASTORE", "MSSQL Database doesn't exist... creating"); + InitDB(conn); + } + cmd = Query("select top 1 webLoginKey from users", new Dictionary()); + try + { + conn.Open(); + cmd.ExecuteNonQuery(); + cmd.Dispose(); + conn.Close(); + } + catch (Exception) + { + conn.Close(); + conn.Open(); + cmd = Query("alter table users add [webLoginKey] varchar(36) default NULL", new Dictionary()); + cmd.ExecuteNonQuery(); + cmd.Dispose(); + conn.Close(); + } + return true; + } + + // createCol(regions, "regionHandle", typeof (ulong)); + // createCol(regions, "regionName", typeof (String)); + // createCol(regions, "uuid", typeof (String)); + + // createCol(regions, "regionRecvKey", typeof (String)); + // createCol(regions, "regionSecret", typeof (String)); + // createCol(regions, "regionSendKey", typeof (String)); + + // createCol(regions, "regionDataURI", typeof (String)); + // createCol(regions, "serverIP", typeof (String)); + // createCol(regions, "serverPort", typeof (String)); + // createCol(regions, "serverURI", typeof (String)); + + + // createCol(regions, "locX", typeof (uint)); + // createCol(regions, "locY", typeof (uint)); + // createCol(regions, "locZ", typeof (uint)); + + // createCol(regions, "eastOverrideHandle", typeof (ulong)); + // createCol(regions, "westOverrideHandle", typeof (ulong)); + // createCol(regions, "southOverrideHandle", typeof (ulong)); + // createCol(regions, "northOverrideHandle", typeof (ulong)); + + // createCol(regions, "regionAssetURI", typeof (String)); + // createCol(regions, "regionAssetRecvKey", typeof (String)); + // createCol(regions, "regionAssetSendKey", typeof (String)); + + // createCol(regions, "regionUserURI", typeof (String)); + // createCol(regions, "regionUserRecvKey", typeof (String)); + // createCol(regions, "regionUserSendKey", typeof (String)); + + // createCol(regions, "regionMapTexture", typeof (String)); + // createCol(regions, "serverHttpPort", typeof (String)); + // createCol(regions, "serverRemotingPort", typeof (uint)); + + // // Add in contraints + // regions.PrimaryKey = new DataColumn[] {regions.Columns["UUID"]}; + // return regions; + //} + + protected static void createCol(DataTable dt, string name, Type type) + { + DataColumn col = new DataColumn(name, type); + dt.Columns.Add(col); + } + + protected static string defineTable(DataTable dt) + { + string sql = "create table " + dt.TableName + "("; + string subsql = String.Empty; + foreach (DataColumn col in dt.Columns) + { + if (subsql.Length > 0) + { + // a map function would rock so much here + subsql += ",\n"; + } + + subsql += col.ColumnName + " " + SqlType(col.DataType); + if (col == dt.PrimaryKey[0]) + { + subsql += " primary key"; + } + } + sql += subsql; + sql += ")"; + return sql; + } + + + // this is something we'll need to implement for each db + // slightly differently. + private static string SqlType(Type type) + { + if (type == typeof(String)) + { + return "varchar(255)"; + } + else if (type == typeof(Int32)) + { + return "integer"; + } + else if (type == typeof(Double)) + { + return "float"; + } + else if (type == typeof(Byte[])) + { + return "image"; + } + else + { + return "varchar(255)"; + } + } + + /// + /// Shuts down the database connection + /// + public void Close() + { + dbcon.Close(); + dbcon = null; + } + + /// + /// Reconnects to the database + /// + public void Reconnect() + { + lock (dbcon) + { + try + { + // Close the DB connection + dbcon.Close(); + // Try reopen it + dbcon = new SqlConnection(connectionString); + dbcon.Open(); + } + catch (Exception e) + { + m_log.Error("Unable to reconnect to database " + e.ToString()); + } + } + } + + /// + /// Runs a query with protection against SQL Injection by using parameterised input. + /// + /// The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y + /// The parameters - index so that @y is indexed as 'y' + /// A Sql DB Command + public IDbCommand Query(string sql, Dictionary parameters) + { + SqlCommand dbcommand = (SqlCommand)dbcon.CreateCommand(); + dbcommand.CommandText = sql; + foreach (KeyValuePair param in parameters) + { + dbcommand.Parameters.AddWithValue(param.Key, param.Value); + } + + return (IDbCommand)dbcommand; + } + + /// + /// Runs a database reader object and returns a region row + /// + /// An active database reader + /// A region row + public RegionProfileData getRegionRow(IDataReader reader) + { + RegionProfileData regionprofile = new RegionProfileData(); + + if (reader.Read()) + { + // Region Main + regionprofile.regionHandle = Convert.ToUInt64(reader["regionHandle"]); + regionprofile.regionName = (string)reader["regionName"]; + regionprofile.UUID = new LLUUID((string)reader["uuid"]); + + // Secrets + regionprofile.regionRecvKey = (string)reader["regionRecvKey"]; + regionprofile.regionSecret = (string)reader["regionSecret"]; + regionprofile.regionSendKey = (string)reader["regionSendKey"]; + + // Region Server + regionprofile.regionDataURI = (string)reader["regionDataURI"]; + regionprofile.regionOnline = false; // Needs to be pinged before this can be set. + regionprofile.serverIP = (string)reader["serverIP"]; + regionprofile.serverPort = Convert.ToUInt32(reader["serverPort"]); + regionprofile.serverURI = (string)reader["serverURI"]; + regionprofile.httpPort = Convert.ToUInt32(reader["serverHttpPort"]); + regionprofile.remotingPort = Convert.ToUInt32(reader["serverRemotingPort"]); + + + // Location + regionprofile.regionLocX = Convert.ToUInt32(reader["locX"]); + regionprofile.regionLocY = Convert.ToUInt32(reader["locY"]); + regionprofile.regionLocZ = Convert.ToUInt32(reader["locZ"]); + + // Neighbours - 0 = No Override + regionprofile.regionEastOverrideHandle = Convert.ToUInt64(reader["eastOverrideHandle"]); + regionprofile.regionWestOverrideHandle = Convert.ToUInt64(reader["westOverrideHandle"]); + regionprofile.regionSouthOverrideHandle = Convert.ToUInt64(reader["southOverrideHandle"]); + regionprofile.regionNorthOverrideHandle = Convert.ToUInt64(reader["northOverrideHandle"]); + + // Assets + regionprofile.regionAssetURI = (string)reader["regionAssetURI"]; + regionprofile.regionAssetRecvKey = (string)reader["regionAssetRecvKey"]; + regionprofile.regionAssetSendKey = (string)reader["regionAssetSendKey"]; + + // Userserver + regionprofile.regionUserURI = (string)reader["regionUserURI"]; + regionprofile.regionUserRecvKey = (string)reader["regionUserRecvKey"]; + regionprofile.regionUserSendKey = (string)reader["regionUserSendKey"]; + + // World Map Addition + string tempRegionMap = reader["regionMapTexture"].ToString(); + if (tempRegionMap != String.Empty) + { + regionprofile.regionMapTextureID = new LLUUID(tempRegionMap); + } + else + { + regionprofile.regionMapTextureID = new LLUUID(); + } + } + else + { + reader.Close(); + throw new Exception("No rows to return"); + } + return regionprofile; + } + + /// + /// Reads a user profile from an active data reader + /// + /// An active database reader + /// A user profile + public UserProfileData readUserRow(IDataReader reader) + { + UserProfileData retval = new UserProfileData(); + + if (reader.Read()) + { + retval.UUID = new LLUUID((string)reader["UUID"]); + retval.username = (string)reader["username"]; + retval.surname = (string)reader["lastname"]; + + retval.passwordHash = (string)reader["passwordHash"]; + retval.passwordSalt = (string)reader["passwordSalt"]; + + retval.homeRegion = Convert.ToUInt64(reader["homeRegion"].ToString()); + retval.homeLocation = new LLVector3( + Convert.ToSingle(reader["homeLocationX"].ToString()), + Convert.ToSingle(reader["homeLocationY"].ToString()), + Convert.ToSingle(reader["homeLocationZ"].ToString())); + retval.homeLookAt = new LLVector3( + Convert.ToSingle(reader["homeLookAtX"].ToString()), + Convert.ToSingle(reader["homeLookAtY"].ToString()), + Convert.ToSingle(reader["homeLookAtZ"].ToString())); + + retval.created = Convert.ToInt32(reader["created"].ToString()); + retval.lastLogin = Convert.ToInt32(reader["lastLogin"].ToString()); + + retval.userInventoryURI = (string)reader["userInventoryURI"]; + retval.userAssetURI = (string)reader["userAssetURI"]; + + retval.profileCanDoMask = Convert.ToUInt32(reader["profileCanDoMask"].ToString()); + retval.profileWantDoMask = Convert.ToUInt32(reader["profileWantDoMask"].ToString()); + + retval.profileAboutText = (string)reader["profileAboutText"]; + retval.profileFirstText = (string)reader["profileFirstText"]; + + retval.profileImage = new LLUUID((string)reader["profileImage"]); + retval.profileFirstImage = new LLUUID((string)reader["profileFirstImage"]); + retval.webLoginKey = new LLUUID((string)reader["webLoginKey"]); + } + else + { + return null; + } + return retval; + } + + /// + /// Reads an agent row from a database reader + /// + /// An active database reader + /// A user session agent + public UserAgentData readAgentRow(IDataReader reader) + { + UserAgentData retval = new UserAgentData(); + + if (reader.Read()) + { + // Agent IDs + retval.UUID = new LLUUID((string)reader["UUID"]); + retval.sessionID = new LLUUID((string)reader["sessionID"]); + retval.secureSessionID = new LLUUID((string)reader["secureSessionID"]); + + // Agent Who? + retval.agentIP = (string)reader["agentIP"]; + retval.agentPort = Convert.ToUInt32(reader["agentPort"].ToString()); + retval.agentOnline = Convert.ToBoolean(reader["agentOnline"].ToString()); + + // Login/Logout times (UNIX Epoch) + retval.loginTime = Convert.ToInt32(reader["loginTime"].ToString()); + retval.logoutTime = Convert.ToInt32(reader["logoutTime"].ToString()); + + // Current position + retval.currentRegion = (string)reader["currentRegion"]; + retval.currentHandle = Convert.ToUInt64(reader["currentHandle"].ToString()); + LLVector3.TryParse((string)reader["currentPos"], out retval.currentPos); + } + else + { + return null; + } + return retval; + } + + public AssetBase getAssetRow(IDataReader reader) + { + AssetBase asset = new AssetBase(); + if (reader.Read()) + { + // Region Main + + asset = new AssetBase(); + asset.Data = (byte[]) reader["data"]; + asset.Description = (string) reader["description"]; + asset.MediaURL = (string)reader["mediaUrl"]; + asset.FullID = new LLUUID((string) reader["id"]); + asset.InvType = Convert.ToSByte(reader["invType"]); + asset.Local = Convert.ToBoolean(reader["local"]); // ((sbyte)reader["local"]) != 0 ? true : false; + asset.Name = (string)reader["name"]; + asset.Type = Convert.ToSByte(reader["assetType"]); + } + else + { + return null; // throw new Exception("No rows to return"); + } + return asset; + } + + + /// + /// Inserts a new row into the log database + /// + /// The daemon which triggered this event + /// Who were we operating on when this occured (region UUID, user UUID, etc) + /// The method call where the problem occured + /// The arguments passed to the method + /// How critical is this? + /// Extra message info + /// Saved successfully? + public bool insertLogRow(string serverDaemon, string target, string methodCall, string arguments, int priority, + string logMessage) + { + string sql = "INSERT INTO logs ([target], [server], [method], [arguments], [priority], [message]) VALUES "; + sql += "(@target, @server, @method, @arguments, @priority, @message);"; + + Dictionary parameters = new Dictionary(); + parameters["server"] = serverDaemon; + parameters["target"] = target; + parameters["method"] = methodCall; + parameters["arguments"] = arguments; + parameters["priority"] = priority.ToString(); + parameters["message"] = logMessage; + + bool returnval = false; + + try + { + IDbCommand result = Query(sql, parameters); + + if (result.ExecuteNonQuery() == 1) + returnval = true; + + result.Dispose(); + } + catch (Exception e) + { + m_log.Error(e.ToString()); + return false; + } + + return returnval; + } + + /// + /// Execute a SQL statement stored in a resource, as a string + /// + /// + public void ExecuteResourceSql(string name) + { + SqlCommand cmd = new SqlCommand(getResourceString(name), (SqlConnection)dbcon); + cmd.ExecuteNonQuery(); + cmd.Dispose(); + } + + public SqlConnection getConnection() + { + return (SqlConnection)dbcon; + } + + /// + /// Given a list of tables, return the version of the tables, as seen in the database + /// + /// + public void GetTableVersion(Dictionary tableList) + { + lock (dbcon) + { + Dictionary param = new Dictionary(); + param["dbname"] = dbcon.Database; + IDbCommand tablesCmd = + Query("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_CATALOG=@dbname", param); + using (IDataReader tables = tablesCmd.ExecuteReader()) + { + while (tables.Read()) + { + try + { + string tableName = (string)tables["TABLE_NAME"]; + if (tableList.ContainsKey(tableName)) + tableList[tableName] = tableName; + } + catch (Exception e) + { + m_log.Error(e.ToString()); + } + } + tables.Close(); + } + } + } + + private string getResourceString(string name) + { + Assembly assem = GetType().Assembly; + string[] names = assem.GetManifestResourceNames(); + + foreach (string s in names) + if (s.EndsWith(name)) + using (Stream resource = assem.GetManifestResourceStream(s)) + { + using (StreamReader resourceReader = new StreamReader(resource)) + { + string resourceString = resourceReader.ReadToEnd(); + return resourceString; + } + } + throw new Exception(string.Format("Resource '{0}' was not found", name)); + } + + /// + /// Returns the version of this DB provider + /// + /// A string containing the DB provider + public string getVersion() + { + Module module = GetType().Module; + string dllName = module.Assembly.ManifestModule.Name; + Version dllVersion = module.Assembly.GetName().Version; + + + return + string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build, + dllVersion.Revision); + } + } +} diff --git a/OpenSim/Framework/Data.MSSQL/MSSQLUserData.cs b/OpenSim/Framework/Data.MSSQL/MSSQLUserData.cs index 17fa0ef918..4b6a4a37c6 100644 --- a/OpenSim/Framework/Data.MSSQL/MSSQLUserData.cs +++ b/OpenSim/Framework/Data.MSSQL/MSSQLUserData.cs @@ -1,521 +1,813 @@ -/* -* 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.Generic; -using System.Data; -using System.Data.SqlClient; -using libsecondlife; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.Data.MSSQL -{ - /// - /// A database interface class to a user profile storage system - /// - internal class MSSQLUserData : IUserData - { - /// - /// Database manager for MySQL - /// - public MSSQLManager database; - - /// - /// Loads and initialises the MySQL storage plugin - /// - public void Initialise() - { - // Load from an INI file connection details - // TODO: move this to XML? - IniFile GridDataMySqlFile = new IniFile("mssql_connection.ini"); - string settingDataSource = GridDataMySqlFile.ParseFileReadValue("data_source"); - string settingInitialCatalog = GridDataMySqlFile.ParseFileReadValue("initial_catalog"); - string settingPersistSecurityInfo = GridDataMySqlFile.ParseFileReadValue("persist_security_info"); - string settingUserId = GridDataMySqlFile.ParseFileReadValue("user_id"); - string settingPassword = GridDataMySqlFile.ParseFileReadValue("password"); - - database = - new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, - settingPassword); - } - - /// - /// Searches the database for a specified user profile by name components - /// - /// The first part of the account name - /// The second part of the account name - /// A user profile - public UserProfileData GetUserByName(string user, string last) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["first"] = user; - param["second"] = last; - - IDbCommand result = - database.Query("SELECT * FROM users WHERE username = @first AND lastname = @second", param); - IDataReader reader = result.ExecuteReader(); - - UserProfileData row = database.readUserRow(reader); - - reader.Close(); - result.Dispose(); - - return row; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - - #region User Friends List Data - - public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms) - { - MainLog.Instance.Verbose("FRIEND", "Stub AddNewUserFriend called"); - } - - public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend) - { - MainLog.Instance.Verbose("FRIEND", "Stub RemoveUserFriend called"); - } - public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms) - { - MainLog.Instance.Verbose("FRIEND", "Stub UpdateUserFriendPerms called"); - } - - - public List GetUserFriendList(LLUUID friendlistowner) - { - MainLog.Instance.Verbose("FRIEND", "Stub GetUserFriendList called"); - return new List(); - } - - #endregion - - public void UpdateUserCurrentRegion(LLUUID avatarid, LLUUID regionuuid) - { - MainLog.Instance.Verbose("USER", "Stub UpdateUserCUrrentRegion called"); - } - - public void LogOffUser(LLUUID avatarid) - { - MainLog.Instance.Verbose("USER", "Stub LogOffUser called"); - } - - public List GeneratePickerResults(LLUUID queryID, string query) - { - List returnlist = new List(); - string[] querysplit; - querysplit = query.Split(' '); - if (querysplit.Length == 2) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["first"] = querysplit[0]; - param["second"] = querysplit[1]; - - IDbCommand result = - database.Query( - "SELECT UUID,username,surname FROM users WHERE username = @first AND lastname = @second", - param); - IDataReader reader = result.ExecuteReader(); - - - while (reader.Read()) - { - Framework.AvatarPickerAvatar user = new Framework.AvatarPickerAvatar(); - user.AvatarID = new LLUUID((string) reader["UUID"]); - user.firstName = (string) reader["username"]; - user.lastName = (string) reader["surname"]; - returnlist.Add(user); - } - reader.Close(); - result.Dispose(); - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return returnlist; - } - } - else if (querysplit.Length == 1) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["first"] = querysplit[0]; - param["second"] = querysplit[1]; - - IDbCommand result = - database.Query( - "SELECT UUID,username,surname FROM users WHERE username = @first OR lastname = @second", - param); - IDataReader reader = result.ExecuteReader(); - - - while (reader.Read()) - { - Framework.AvatarPickerAvatar user = new Framework.AvatarPickerAvatar(); - user.AvatarID = new LLUUID((string) reader["UUID"]); - user.firstName = (string) reader["username"]; - user.lastName = (string) reader["surname"]; - returnlist.Add(user); - } - reader.Close(); - result.Dispose(); - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return returnlist; - } - } - return returnlist; - } - - // See IUserData - public UserProfileData GetUserByUUID(LLUUID uuid) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["uuid"] = uuid.ToString(); - - IDbCommand result = database.Query("SELECT * FROM users WHERE UUID = @uuid", param); - IDataReader reader = result.ExecuteReader(); - - UserProfileData row = database.readUserRow(reader); - - reader.Close(); - result.Dispose(); - - return row; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - - /// - /// Searches the database for a specified user profile by account - /// - /// The account - /// The users profile - public UserProfileData GetUserByAccount(string account) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["account"] = account; - - IDbCommand result = database.Query("SELECT * FROM users WHERE account = @account", param); - IDataReader reader = result.ExecuteReader(); - - UserProfileData row = database.readUserRow(reader); - - reader.Close(); - result.Dispose(); - - if (row != null) - { - UserAgentData agentData = GetAgentByUUID(row.UUID); - if (agentData != null) - { - row.currentAgent = agentData; - } - } - - return row; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - - /// - /// Returns a user session searching by name - /// - /// The account name - /// The users session - public UserAgentData GetAgentByName(string name) - { - return GetAgentByName(name.Split(' ')[0], name.Split(' ')[1]); - } - - /// - /// Returns a user session by account name - /// - /// First part of the users account name - /// Second part of the users account name - /// The users session - public UserAgentData GetAgentByName(string user, string last) - { - UserProfileData profile = GetUserByName(user, last); - return GetAgentByUUID(profile.UUID); - } - - /// - /// Returns an agent session by account UUID - /// - /// The accounts UUID - /// The users session - public UserAgentData GetAgentByUUID(LLUUID uuid) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["uuid"] = uuid.ToString(); - - IDbCommand result = database.Query("SELECT * FROM agents WHERE UUID = @uuid", param); - IDataReader reader = result.ExecuteReader(); - - UserAgentData row = database.readAgentRow(reader); - - reader.Close(); - result.Dispose(); - - return row; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - - /// - /// Creates a new users profile - /// - /// The user profile to create - public void AddNewUserProfile(UserProfileData user) - { - try - { - lock (database) - { - database.insertUserRow(user.UUID, user.username, user.surname, user.passwordHash, user.passwordSalt, - user.homeRegion, user.homeLocation.X, user.homeLocation.Y, - user.homeLocation.Z, - user.homeLookAt.X, user.homeLookAt.Y, user.homeLookAt.Z, user.created, - user.lastLogin, user.userInventoryURI, user.userAssetURI, - user.profileCanDoMask, user.profileWantDoMask, - user.profileAboutText, user.profileFirstText, user.profileImage, - user.profileFirstImage,user.webLoginKey); - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - } - } - - /// - /// Creates a new agent - /// - /// The agent to create - public void AddNewUserAgent(UserAgentData agent) - { - // Do nothing. - } - - - public bool UpdateUserProfile(UserProfileData user) - { - SqlCommand command = new SqlCommand("UPDATE users set UUID = @uuid, " + - "username = @username, " + - "lastname = @lastname," + - "passwordHash = @passwordHash," + - "passwordSalt = @passwordSalt," + - "homeRegion = @homeRegion," + - "homeLocationX = @homeLocationX," + - "homeLocationY = @homeLocationY," + - "homeLocationZ = @homeLocationZ," + - "homeLookAtX = @homeLookAtX," + - "homeLookAtY = @homeLookAtY," + - "homeLookAtZ = @homeLookAtZ," + - "created = @created," + - "lastLogin = @lastLogin," + - "userInventoryURI = @userInventoryURI," + - "userAssetURI = @userAssetURI," + - "profileCanDoMask = @profileCanDoMask," + - "profileWantDoMask = @profileWantDoMask," + - "profileAboutText = @profileAboutText," + - "profileFirstText = @profileFirstText," + - "profileImage = @profileImage," + - "profileFirstImage = @profileFirstImage where " + - "UUID = @keyUUUID;", database.getConnection()); - SqlParameter param1 = new SqlParameter("@uuid", user.UUID.ToString()); - SqlParameter param2 = new SqlParameter("@username", user.username); - SqlParameter param3 = new SqlParameter("@lastname", user.surname); - SqlParameter param4 = new SqlParameter("@passwordHash", user.passwordHash); - SqlParameter param5 = new SqlParameter("@passwordSalt", user.passwordSalt); - SqlParameter param6 = new SqlParameter("@homeRegion", Convert.ToInt64(user.homeRegion)); - SqlParameter param7 = new SqlParameter("@homeLocationX", user.homeLocation.X); - SqlParameter param8 = new SqlParameter("@homeLocationY", user.homeLocation.Y); - SqlParameter param9 = new SqlParameter("@homeLocationZ", user.homeLocation.Y); - SqlParameter param10 = new SqlParameter("@homeLookAtX", user.homeLookAt.X); - SqlParameter param11 = new SqlParameter("@homeLookAtY", user.homeLookAt.Y); - SqlParameter param12 = new SqlParameter("@homeLookAtZ", user.homeLookAt.Z); - SqlParameter param13 = new SqlParameter("@created", Convert.ToInt32(user.created)); - SqlParameter param14 = new SqlParameter("@lastLogin", Convert.ToInt32(user.lastLogin)); - SqlParameter param15 = new SqlParameter("@userInventoryURI", user.userInventoryURI); - SqlParameter param16 = new SqlParameter("@userAssetURI", user.userAssetURI); - SqlParameter param17 = new SqlParameter("@profileCanDoMask", Convert.ToInt32(user.profileCanDoMask)); - SqlParameter param18 = new SqlParameter("@profileWantDoMask", Convert.ToInt32(user.profileWantDoMask)); - SqlParameter param19 = new SqlParameter("@profileAboutText", user.profileAboutText); - SqlParameter param20 = new SqlParameter("@profileFirstText", user.profileFirstText); - SqlParameter param21 = new SqlParameter("@profileImage", LLUUID.Zero.ToString()); - SqlParameter param22 = new SqlParameter("@profileFirstImage", LLUUID.Zero.ToString()); - SqlParameter param23 = new SqlParameter("@keyUUUID", user.UUID.ToString()); - command.Parameters.Add(param1); - command.Parameters.Add(param2); - command.Parameters.Add(param3); - command.Parameters.Add(param4); - command.Parameters.Add(param5); - command.Parameters.Add(param6); - command.Parameters.Add(param7); - command.Parameters.Add(param8); - command.Parameters.Add(param9); - command.Parameters.Add(param10); - command.Parameters.Add(param11); - command.Parameters.Add(param12); - command.Parameters.Add(param13); - command.Parameters.Add(param14); - command.Parameters.Add(param15); - command.Parameters.Add(param16); - command.Parameters.Add(param17); - command.Parameters.Add(param18); - command.Parameters.Add(param19); - command.Parameters.Add(param20); - command.Parameters.Add(param21); - command.Parameters.Add(param22); - command.Parameters.Add(param23); - try - { - int affected = command.ExecuteNonQuery(); - if (affected != 0) - { - return true; - } - else - { - return false; - } - } - catch (Exception e) - { - MainLog.Instance.Error(e.ToString()); - } - return false; - } - - /// - /// Performs a money transfer request between two accounts - /// - /// The senders account ID - /// The receivers account ID - /// The amount to transfer - /// Success? - public bool MoneyTransferRequest(LLUUID from, LLUUID to, uint amount) - { - return false; - } - - /// - /// Performs an inventory transfer request between two accounts - /// - /// TODO: Move to inventory server - /// The senders account ID - /// The receivers account ID - /// The item to transfer - /// Success? - public bool InventoryTransferRequest(LLUUID from, LLUUID to, LLUUID item) - { - return false; - } - - /// - /// Database provider name - /// - /// Provider name - public string getName() - { - return "MSSQL Userdata Interface"; - } - - /// - /// Database provider version - /// - /// provider version - public string GetVersion() - { - return database.getVersion(); - } - - /// - /// Not implemented - /// - /// - public void runQuery(string query) - { - } - } -} \ No newline at end of file +/* +* 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.Generic; +using System.Data; +using System.Data.SqlClient; +using libsecondlife; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Data.MSSQL +{ + /// + /// A database interface class to a user profile storage system + /// + public class MSSQLUserData : IUserData + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// Database manager for MySQL + /// + public MSSQLManager database; + + private string m_agentsTableName; + private string m_usersTableName; + private string m_userFriendsTableName; + + /// + /// Loads and initialises the MySQL storage plugin + /// + public void Initialise() + { + // Load from an INI file connection details + // TODO: move this to XML? + IniFile iniFile = new IniFile("mssql_connection.ini"); + string settingDataSource = iniFile.ParseFileReadValue("data_source"); + string settingInitialCatalog = iniFile.ParseFileReadValue("initial_catalog"); + string settingPersistSecurityInfo = iniFile.ParseFileReadValue("persist_security_info"); + string settingUserId = iniFile.ParseFileReadValue("user_id"); + string settingPassword = iniFile.ParseFileReadValue("password"); + + m_usersTableName = iniFile.ParseFileReadValue("userstablename"); + if (m_usersTableName == null) + { + m_usersTableName = "users"; + } + + m_userFriendsTableName = iniFile.ParseFileReadValue("userfriendstablename"); + if (m_userFriendsTableName == null) + { + m_userFriendsTableName = "userfriends"; + } + + m_agentsTableName = iniFile.ParseFileReadValue("agentstablename"); + if (m_agentsTableName == null) + { + m_agentsTableName = "agents"; + } + + database = + new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId, + settingPassword); + + TestTables(); + } + + private bool TestTables() + { + IDbCommand cmd; + + cmd = database.Query("select top 1 * from " + m_usersTableName, new Dictionary()); + try + { + cmd.ExecuteNonQuery(); + } + catch + { + database.ExecuteResourceSql("Mssql-users.sql"); + } + + cmd = database.Query("select top 1 * from " + m_agentsTableName, new Dictionary()); + try + { + cmd.ExecuteNonQuery(); + } + catch + { + database.ExecuteResourceSql("Mssql-agents.sql"); + } + + cmd = database.Query("select top 1 * from " + m_userFriendsTableName, new Dictionary()); + try + { + cmd.ExecuteNonQuery(); + } + catch + { + database.ExecuteResourceSql("CreateUserFriendsTable.sql"); + } + + return true; + } + /// + /// Searches the database for a specified user profile by name components + /// + /// The first part of the account name + /// The second part of the account name + /// A user profile + public UserProfileData GetUserByName(string user, string last) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["first"] = user; + param["second"] = last; + + IDbCommand result = + database.Query("SELECT * FROM " + m_usersTableName + " WHERE username = @first AND lastname = @second", param); + IDataReader reader = result.ExecuteReader(); + + UserProfileData row = database.readUserRow(reader); + + reader.Close(); + result.Dispose(); + + return row; + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return null; + } + } + + #region User Friends List Data + + public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms) + { + int dtvalue = Util.UnixTimeSinceEpoch(); + + Dictionary param = new Dictionary(); + param["@ownerID"] = friendlistowner.UUID.ToString(); + param["@friendID"] = friend.UUID.ToString(); + param["@friendPerms"] = perms.ToString(); + param["@datetimestamp"] = dtvalue.ToString(); + + try + { + lock (database) + { + IDbCommand adder = + database.Query( + "INSERT INTO " + m_userFriendsTableName + " " + + "(ownerID,friendID,friendPerms,datetimestamp) " + + "VALUES " + + "(@ownerID,@friendID,@friendPerms,@datetimestamp)", + param); + + adder.ExecuteNonQuery(); + + adder = + database.Query( + "INSERT INTO " + m_userFriendsTableName + " " + + "(ownerID,friendID,friendPerms,datetimestamp) " + + "VALUES " + + "(@friendID,@ownerID,@friendPerms,@datetimestamp)", + param); + adder.ExecuteNonQuery(); + + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return; + } + } + + public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend) + { + Dictionary param = new Dictionary(); + param["@ownerID"] = friendlistowner.UUID.ToString(); + param["@friendID"] = friend.UUID.ToString(); + + + try + { + lock (database) + { + IDbCommand updater = + database.Query( + "delete from " + m_userFriendsTableName + " where ownerID = @ownerID and friendID = @friendID", + param); + updater.ExecuteNonQuery(); + + updater = + database.Query( + "delete from " + m_userFriendsTableName + " where ownerID = @friendID and friendID = @ownerID", + param); + updater.ExecuteNonQuery(); + + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return; + } + } + + public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms) + { + Dictionary param = new Dictionary(); + param["@ownerID"] = friendlistowner.UUID.ToString(); + param["@friendID"] = friend.UUID.ToString(); + param["@friendPerms"] = perms.ToString(); + + + try + { + lock (database) + { + IDbCommand updater = + database.Query( + "update " + m_userFriendsTableName + + " SET friendPerms = @friendPerms " + + "where ownerID = @ownerID and friendID = @friendID", + param); + + updater.ExecuteNonQuery(); + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return; + } + } + + + public List GetUserFriendList(LLUUID friendlistowner) + { + List Lfli = new List(); + + Dictionary param = new Dictionary(); + param["@ownerID"] = friendlistowner.UUID.ToString(); + + try + { + lock (database) + { + //Left Join userfriends to itself + IDbCommand result = + database.Query( + "select a.ownerID,a.friendID,a.friendPerms,b.friendPerms as ownerperms from " + m_userFriendsTableName + " as a, " + m_userFriendsTableName + " as b" + + " where a.ownerID = @ownerID and b.ownerID = a.friendID and b.friendID = a.ownerID", + param); + IDataReader reader = result.ExecuteReader(); + + + while (reader.Read()) + { + FriendListItem fli = new FriendListItem(); + fli.FriendListOwner = new LLUUID((string)reader["ownerID"]); + fli.Friend = new LLUUID((string)reader["friendID"]); + fli.FriendPerms = (uint)Convert.ToInt32(reader["friendPerms"]); + + // This is not a real column in the database table, it's a joined column from the opposite record + fli.FriendListOwnerPerms = (uint)Convert.ToInt32(reader["ownerperms"]); + + Lfli.Add(fli); + } + reader.Close(); + result.Dispose(); + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return Lfli; + } + + return Lfli; + } + + #endregion + + public void UpdateUserCurrentRegion(LLUUID avatarid, LLUUID regionuuid) + { + m_log.Info("[USER]: Stub UpdateUserCUrrentRegion called"); + } + + + + public List GeneratePickerResults(LLUUID queryID, string query) + { + List returnlist = new List(); + string[] querysplit; + querysplit = query.Split(' '); + if (querysplit.Length == 2) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["first"] = querysplit[0]; + param["second"] = querysplit[1]; + + IDbCommand result = + database.Query( + "SELECT UUID,username,lastname FROM " + m_usersTableName + " WHERE username = @first AND lastname = @second", + param); + IDataReader reader = result.ExecuteReader(); + + + while (reader.Read()) + { + Framework.AvatarPickerAvatar user = new Framework.AvatarPickerAvatar(); + user.AvatarID = new LLUUID((string)reader["UUID"]); + user.firstName = (string)reader["username"]; + user.lastName = (string)reader["lastname"]; + returnlist.Add(user); + } + reader.Close(); + result.Dispose(); + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return returnlist; + } + } + else if (querysplit.Length == 1) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["first"] = querysplit[0]; + + IDbCommand result = + database.Query( + "SELECT UUID,username,lastname FROM " + m_usersTableName + " WHERE username = @first OR lastname = @first", + param); + IDataReader reader = result.ExecuteReader(); + + + while (reader.Read()) + { + Framework.AvatarPickerAvatar user = new Framework.AvatarPickerAvatar(); + user.AvatarID = new LLUUID((string)reader["UUID"]); + user.firstName = (string)reader["username"]; + user.lastName = (string)reader["lastname"]; + returnlist.Add(user); + } + reader.Close(); + result.Dispose(); + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return returnlist; + } + } + return returnlist; + } + + // See IUserData + public UserProfileData GetUserByUUID(LLUUID uuid) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["uuid"] = uuid.ToString(); + + IDbCommand result = database.Query("SELECT * FROM " + m_usersTableName + " WHERE UUID = @uuid", param); + IDataReader reader = result.ExecuteReader(); + + UserProfileData row = database.readUserRow(reader); + + reader.Close(); + result.Dispose(); + + return row; + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return null; + } + } + + /// + /// Searches the database for a specified user profile by account + /// + /// The account + /// The users profile + public UserProfileData GetUserByAccount(string account) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["account"] = account; + + IDbCommand result = database.Query("SELECT * FROM users WHERE account = @account", param); + IDataReader reader = result.ExecuteReader(); + + UserProfileData row = database.readUserRow(reader); + + reader.Close(); + result.Dispose(); + + if (row != null) + { + UserAgentData agentData = GetAgentByUUID(row.UUID); + if (agentData != null) + { + row.currentAgent = agentData; + } + } + + return row; + } + } + catch (Exception e) + { + database.Reconnect(); + MainLog.Instance.Error(e.ToString()); + return null; + } + } + + /// + /// Returns a user session searching by name + /// + /// The account name + /// The users session + public UserAgentData GetAgentByName(string name) + { + return GetAgentByName(name.Split(' ')[0], name.Split(' ')[1]); + } + + /// + /// Returns a user session by account name + /// + /// First part of the users account name + /// Second part of the users account name + /// The users session + public UserAgentData GetAgentByName(string user, string last) + { + UserProfileData profile = GetUserByName(user, last); + return GetAgentByUUID(profile.UUID); + } + + /// + /// Returns an agent session by account UUID + /// + /// The accounts UUID + /// The users session + public UserAgentData GetAgentByUUID(LLUUID uuid) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["uuid"] = uuid.ToString(); + + IDbCommand result = database.Query("SELECT * FROM " + m_agentsTableName + " WHERE UUID = @uuid", param); + IDataReader reader = result.ExecuteReader(); + + UserAgentData row = database.readAgentRow(reader); + + reader.Close(); + result.Dispose(); + + return row; + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return null; + } + } + public void StoreWebLoginKey(LLUUID AgentID, LLUUID WebLoginKey) + { + UserProfileData user = GetUserByUUID(AgentID); + user.webLoginKey = WebLoginKey; + UpdateUserProfile(user); + + } + /// + /// Creates a new users profile + /// + /// The user profile to create + public void AddNewUserProfile(UserProfileData user) + { + try + { + lock (database) + { + InsertUserRow(user.UUID, user.username, user.surname, user.passwordHash, user.passwordSalt, + user.homeRegion, user.homeLocation.X, user.homeLocation.Y, + user.homeLocation.Z, + user.homeLookAt.X, user.homeLookAt.Y, user.homeLookAt.Z, user.created, + user.lastLogin, user.userInventoryURI, user.userAssetURI, + user.profileCanDoMask, user.profileWantDoMask, + user.profileAboutText, user.profileFirstText, user.profileImage, + user.profileFirstImage, user.webLoginKey); + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + } + } + + /// + /// Creates a new user and inserts it into the database + /// + /// User ID + /// First part of the login + /// Second part of the login + /// A salted hash of the users password + /// The salt used for the password hash + /// A regionHandle of the users home region + /// Home region position vector + /// Home region position vector + /// Home region position vector + /// Home region 'look at' vector + /// Home region 'look at' vector + /// Home region 'look at' vector + /// Account created (unix timestamp) + /// Last login (unix timestamp) + /// Users inventory URI + /// Users asset URI + /// I can do mask + /// I want to do mask + /// Profile text + /// Firstlife text + /// UUID for profile image + /// UUID for firstlife image + /// Success? + private bool InsertUserRow(LLUUID uuid, string username, string lastname, string passwordHash, + string passwordSalt, UInt64 homeRegion, float homeLocX, float homeLocY, float homeLocZ, + float homeLookAtX, float homeLookAtY, float homeLookAtZ, int created, int lastlogin, + string inventoryURI, string assetURI, uint canDoMask, uint wantDoMask, + string aboutText, string firstText, + LLUUID profileImage, LLUUID firstImage, LLUUID webLoginKey) + { + string sql = "INSERT INTO "+m_usersTableName; + sql += " ([UUID], [username], [lastname], [passwordHash], [passwordSalt], [homeRegion], "; + sql += + "[homeLocationX], [homeLocationY], [homeLocationZ], [homeLookAtX], [homeLookAtY], [homeLookAtZ], [created], "; + sql += + "[lastLogin], [userInventoryURI], [userAssetURI], [profileCanDoMask], [profileWantDoMask], [profileAboutText], "; + sql += "[profileFirstText], [profileImage], [profileFirstImage], [webLoginKey]) VALUES "; + + sql += "(@UUID, @username, @lastname, @passwordHash, @passwordSalt, @homeRegion, "; + sql += + "@homeLocationX, @homeLocationY, @homeLocationZ, @homeLookAtX, @homeLookAtY, @homeLookAtZ, @created, "; + sql += + "@lastLogin, @userInventoryURI, @userAssetURI, @profileCanDoMask, @profileWantDoMask, @profileAboutText, "; + sql += "@profileFirstText, @profileImage, @profileFirstImage, @webLoginKey);"; + + Dictionary parameters = new Dictionary(); + parameters["UUID"] = uuid.ToString(); + parameters["username"] = username.ToString(); + parameters["lastname"] = lastname.ToString(); + parameters["passwordHash"] = passwordHash.ToString(); + parameters["passwordSalt"] = passwordSalt.ToString(); + parameters["homeRegion"] = homeRegion.ToString(); + parameters["homeLocationX"] = homeLocX.ToString(); + parameters["homeLocationY"] = homeLocY.ToString(); + parameters["homeLocationZ"] = homeLocZ.ToString(); + parameters["homeLookAtX"] = homeLookAtX.ToString(); + parameters["homeLookAtY"] = homeLookAtY.ToString(); + parameters["homeLookAtZ"] = homeLookAtZ.ToString(); + parameters["created"] = created.ToString(); + parameters["lastLogin"] = lastlogin.ToString(); + parameters["userInventoryURI"] = String.Empty; + parameters["userAssetURI"] = String.Empty; + parameters["profileCanDoMask"] = "0"; + parameters["profileWantDoMask"] = "0"; + parameters["profileAboutText"] = String.Empty; + parameters["profileFirstText"] = String.Empty; + parameters["profileImage"] = LLUUID.Zero.ToString(); + parameters["profileFirstImage"] = LLUUID.Zero.ToString(); + parameters["webLoginKey"] = LLUUID.Random().ToString(); + + bool returnval = false; + + try + { + IDbCommand result = database.Query(sql, parameters); + + if (result.ExecuteNonQuery() == 1) + returnval = true; + + result.Dispose(); + } + catch (Exception e) + { + m_log.Error(e.ToString()); + return false; + } + + return returnval; + } + + /// + /// Creates a new agent + /// + /// The agent to create + public void AddNewUserAgent(UserAgentData agent) + { + // Do nothing. + } + + + public bool UpdateUserProfile(UserProfileData user) + { + SqlCommand command = new SqlCommand("UPDATE " + m_usersTableName + " set UUID = @uuid, " + + "username = @username, " + + "lastname = @lastname," + + "passwordHash = @passwordHash," + + "passwordSalt = @passwordSalt," + + "homeRegion = @homeRegion," + + "homeLocationX = @homeLocationX," + + "homeLocationY = @homeLocationY," + + "homeLocationZ = @homeLocationZ," + + "homeLookAtX = @homeLookAtX," + + "homeLookAtY = @homeLookAtY," + + "homeLookAtZ = @homeLookAtZ," + + "created = @created," + + "lastLogin = @lastLogin," + + "userInventoryURI = @userInventoryURI," + + "userAssetURI = @userAssetURI," + + "profileCanDoMask = @profileCanDoMask," + + "profileWantDoMask = @profileWantDoMask," + + "profileAboutText = @profileAboutText," + + "profileFirstText = @profileFirstText," + + "profileImage = @profileImage," + + "profileFirstImage = @profileFirstImage, " + + "webLoginKey = @webLoginKey where " + + "UUID = @keyUUUID;", database.getConnection()); + SqlParameter param1 = new SqlParameter("@uuid", user.UUID.ToString()); + SqlParameter param2 = new SqlParameter("@username", user.username); + SqlParameter param3 = new SqlParameter("@lastname", user.surname); + SqlParameter param4 = new SqlParameter("@passwordHash", user.passwordHash); + SqlParameter param5 = new SqlParameter("@passwordSalt", user.passwordSalt); + SqlParameter param6 = new SqlParameter("@homeRegion", Convert.ToInt64(user.homeRegion)); + SqlParameter param7 = new SqlParameter("@homeLocationX", user.homeLocation.X); + SqlParameter param8 = new SqlParameter("@homeLocationY", user.homeLocation.Y); + SqlParameter param9 = new SqlParameter("@homeLocationZ", user.homeLocation.Y); + SqlParameter param10 = new SqlParameter("@homeLookAtX", user.homeLookAt.X); + SqlParameter param11 = new SqlParameter("@homeLookAtY", user.homeLookAt.Y); + SqlParameter param12 = new SqlParameter("@homeLookAtZ", user.homeLookAt.Z); + SqlParameter param13 = new SqlParameter("@created", Convert.ToInt32(user.created)); + SqlParameter param14 = new SqlParameter("@lastLogin", Convert.ToInt32(user.lastLogin)); + SqlParameter param15 = new SqlParameter("@userInventoryURI", user.userInventoryURI); + SqlParameter param16 = new SqlParameter("@userAssetURI", user.userAssetURI); + SqlParameter param17 = new SqlParameter("@profileCanDoMask", Convert.ToInt32(user.profileCanDoMask)); + SqlParameter param18 = new SqlParameter("@profileWantDoMask", Convert.ToInt32(user.profileWantDoMask)); + SqlParameter param19 = new SqlParameter("@profileAboutText", user.profileAboutText); + SqlParameter param20 = new SqlParameter("@profileFirstText", user.profileFirstText); + SqlParameter param21 = new SqlParameter("@profileImage", LLUUID.Zero.ToString()); + SqlParameter param22 = new SqlParameter("@profileFirstImage", LLUUID.Zero.ToString()); + SqlParameter param23 = new SqlParameter("@keyUUUID", user.UUID.ToString()); + SqlParameter param24 = new SqlParameter("@webLoginKey", user.webLoginKey.UUID.ToString()); + command.Parameters.Add(param1); + command.Parameters.Add(param2); + command.Parameters.Add(param3); + command.Parameters.Add(param4); + command.Parameters.Add(param5); + command.Parameters.Add(param6); + command.Parameters.Add(param7); + command.Parameters.Add(param8); + command.Parameters.Add(param9); + command.Parameters.Add(param10); + command.Parameters.Add(param11); + command.Parameters.Add(param12); + command.Parameters.Add(param13); + command.Parameters.Add(param14); + command.Parameters.Add(param15); + command.Parameters.Add(param16); + command.Parameters.Add(param17); + command.Parameters.Add(param18); + command.Parameters.Add(param19); + command.Parameters.Add(param20); + command.Parameters.Add(param21); + command.Parameters.Add(param22); + command.Parameters.Add(param23); + command.Parameters.Add(param24); + try + { + int affected = command.ExecuteNonQuery(); + if (affected != 0) + { + return true; + } + else + { + return false; + } + } + catch (Exception e) + { + m_log.Error(e.ToString()); + } + return false; + } + + /// + /// Performs a money transfer request between two accounts + /// + /// The senders account ID + /// The receivers account ID + /// The amount to transfer + /// Success? + public bool MoneyTransferRequest(LLUUID from, LLUUID to, uint amount) + { + return false; + } + + /// + /// Performs an inventory transfer request between two accounts + /// + /// TODO: Move to inventory server + /// The senders account ID + /// The receivers account ID + /// The item to transfer + /// Success? + public bool InventoryTransferRequest(LLUUID from, LLUUID to, LLUUID item) + { + return false; + } + + /// + /// Database provider name + /// + /// Provider name + public string getName() + { + return "MSSQL Userdata Interface"; + } + + /// + /// Database provider version + /// + /// provider version + public string GetVersion() + { + return database.getVersion(); + } + + /// + /// Not implemented + /// + /// + public void runQuery(string query) + { + } + } +} diff --git a/OpenSim/Framework/Data.MSSQL/Properties/AssemblyInfo.cs b/OpenSim/Framework/Data.MSSQL/Properties/AssemblyInfo.cs index 0e97b3c6b4..287b9e43c3 100644 --- a/OpenSim/Framework/Data.MSSQL/Properties/AssemblyInfo.cs +++ b/OpenSim/Framework/Data.MSSQL/Properties/AssemblyInfo.cs @@ -1,38 +1,66 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. - -[assembly : AssemblyTitle("OpenSim.Framework.Data.MSSQL")] -[assembly : AssemblyDescription("")] -[assembly : AssemblyConfiguration("")] -[assembly : AssemblyCompany("")] -[assembly : AssemblyProduct("OpenSim.Framework.Data.MSSQL")] -[assembly : AssemblyCopyright("Copyright © 2007")] -[assembly : AssemblyTrademark("")] -[assembly : AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. - -[assembly : ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM - -[assembly : Guid("0e1c1ca4-2cf2-4315-b0e7-432c02feea8a")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: - -[assembly : AssemblyVersion("1.0.0.0")] -[assembly : AssemblyFileVersion("1.0.0.0")] \ No newline at end of file +/* +* 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.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. + +[assembly : AssemblyTitle("OpenSim.Framework.Data.MSSQL")] +[assembly : AssemblyDescription("")] +[assembly : AssemblyConfiguration("")] +[assembly : AssemblyCompany("")] +[assembly : AssemblyProduct("OpenSim.Framework.Data.MSSQL")] +[assembly : AssemblyCopyright("Copyright © OpenSimulator.org Developers 2007-2008")] +[assembly : AssemblyTrademark("")] +[assembly : AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. + +[assembly : ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM + +[assembly : Guid("0e1c1ca4-2cf2-4315-b0e7-432c02feea8a")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly : AssemblyVersion("1.0.0.0")] +[assembly : AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/Data.MSSQL/Resources/CreateUserFriendsTable.sql b/OpenSim/Framework/Data.MSSQL/Resources/CreateUserFriendsTable.sql new file mode 100644 index 0000000000..6f5885ef2c --- /dev/null +++ b/OpenSim/Framework/Data.MSSQL/Resources/CreateUserFriendsTable.sql @@ -0,0 +1,14 @@ +SET ANSI_NULLS ON + +SET QUOTED_IDENTIFIER ON + +SET ANSI_PADDING ON + +CREATE TABLE [dbo].[userfriends]( +[ownerID] [varchar](50) COLLATE Latin1_General_CI_AS NOT NULL, +[friendID] [varchar](50) COLLATE Latin1_General_CI_AS NOT NULL, +[friendPerms] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, +[datetimestamp] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL +) ON [PRIMARY] + +SET ANSI_PADDING OFF diff --git a/OpenSim/Framework/Data.MSSQL/Resources/Mssql-regions.sql b/OpenSim/Framework/Data.MSSQL/Resources/Mssql-regions.sql new file mode 100644 index 0000000000..c5d8329cf4 --- /dev/null +++ b/OpenSim/Framework/Data.MSSQL/Resources/Mssql-regions.sql @@ -0,0 +1,40 @@ +SET ANSI_NULLS ON + +SET QUOTED_IDENTIFIER ON + +SET ANSI_PADDING ON + +CREATE TABLE [dbo].[regions]( + [regionHandle] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionName] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [uuid] [varchar](255) COLLATE Latin1_General_CI_AS NOT NULL, + [regionRecvKey] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionSecret] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionSendKey] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionDataURI] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [serverIP] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [serverPort] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [serverURI] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [locX] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [locY] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [locZ] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [eastOverrideHandle] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [westOverrideHandle] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [southOverrideHandle] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [northOverrideHandle] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionAssetURI] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionAssetRecvKey] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionAssetSendKey] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionUserURI] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionUserRecvKey] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionUserSendKey] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [regionMapTexture] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [serverHttpPort] [varchar](255) COLLATE Latin1_General_CI_AS NULL, + [serverRemotingPort] [varchar](255) COLLATE Latin1_General_CI_AS NULL, +PRIMARY KEY CLUSTERED +( + [uuid] ASC +)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] +) ON [PRIMARY] + +SET ANSI_PADDING OFF diff --git a/OpenSim/Framework/Data.MySQL/MySQLAssetData.cs b/OpenSim/Framework/Data.MySQL/MySQLAssetData.cs index 45515f4d8f..490fc163aa 100644 --- a/OpenSim/Framework/Data.MySQL/MySQLAssetData.cs +++ b/OpenSim/Framework/Data.MySQL/MySQLAssetData.cs @@ -1,194 +1,214 @@ -/* -* 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.Generic; -using System.Data; -using libsecondlife; -using MySql.Data.MySqlClient; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.Data.MySQL -{ - internal class MySQLAssetData : IAssetProvider - { - private MySQLManager _dbConnection; - - #region IAssetProvider Members - - private void UpgradeAssetsTable(string oldVersion) - { - // null as the version, indicates that the table didn't exist - if (oldVersion == null) - { - MainLog.Instance.Notice("ASSETS", "Creating new database tables"); - _dbConnection.ExecuteResourceSql("CreateAssetsTable.sql"); - return; - } - } - - /// - /// Ensure that the assets related tables exists and are at the latest version - /// - private void TestTables() - { - Dictionary tableList = new Dictionary(); - - tableList["assets"] = null; - _dbConnection.GetTableVersion(tableList); - - UpgradeAssetsTable(tableList["assets"]); - } - - public AssetBase FetchAsset(LLUUID assetID) - { - AssetBase asset = null; - lock (_dbConnection) - { - MySqlCommand cmd = - new MySqlCommand( - "SELECT name, description, assetType, invType, local, temporary, data FROM assets WHERE id=?id", - _dbConnection.Connection); - MySqlParameter p = cmd.Parameters.Add("?id", MySqlDbType.Binary, 16); - p.Value = assetID.GetBytes(); - try - { - using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) - { - if (dbReader.Read()) - { - asset = new AssetBase(); - asset.Data = (byte[]) dbReader["data"]; - asset.Description = (string) dbReader["description"]; - asset.FullID = assetID; - asset.InvType = (sbyte) dbReader["invType"]; - asset.Local = ((sbyte) dbReader["local"]) != 0 ? true : false; - asset.Name = (string) dbReader["name"]; - asset.Type = (sbyte) dbReader["assetType"]; - } - dbReader.Close(); - cmd.Dispose(); - } - } - catch (Exception) - { - MainLog.Instance.Warn("ASSETS", "MySql failure fetching asset"); - } - } - return asset; - } - - public void CreateAsset(AssetBase asset) - { - MySqlCommand cmd = - new MySqlCommand( - "REPLACE INTO assets(id, name, description, assetType, invType, local, temporary, data)" + - "VALUES(?id, ?name, ?description, ?assetType, ?invType, ?local, ?temporary, ?data)", - _dbConnection.Connection); - - // need to ensure we dispose - using (cmd) - { - MySqlParameter p = cmd.Parameters.Add("?id", MySqlDbType.Binary, 16); - p.Value = asset.FullID.GetBytes(); - cmd.Parameters.AddWithValue("?name", asset.Name); - cmd.Parameters.AddWithValue("?description", asset.Description); - cmd.Parameters.AddWithValue("?assetType", asset.Type); - cmd.Parameters.AddWithValue("?invType", asset.InvType); - cmd.Parameters.AddWithValue("?local", asset.Local); - cmd.Parameters.AddWithValue("?temporary", asset.Temporary); - cmd.Parameters.AddWithValue("?data", asset.Data); - cmd.ExecuteNonQuery(); - cmd.Dispose(); - } - } - - public void UpdateAsset(AssetBase asset) - { - CreateAsset(asset); - } - - public bool ExistsAsset(LLUUID uuid) - { - throw new Exception("The method or operation is not implemented."); - } - - // rex, new function, fixme not implemented - public List GetAssetList(int vAssetType) - { - List retvals = new List(); - return retvals; - } - - /// - /// All writes are immediately commited to the database, so this is a no-op - /// - public void CommitAssets() - { - } - - // rex new function for "replace assets" functionality - // TODO: actual implementation by someone, should return LLUUID of an asset - // with matching type & name, or zero if not in DB - public LLUUID ExistsAsset(sbyte type, string name) - { - return LLUUID.Zero; - } - - #endregion - - #region IPlugin Members - - public void Initialise() - { - IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini"); - string hostname = GridDataMySqlFile.ParseFileReadValue("hostname"); - string database = GridDataMySqlFile.ParseFileReadValue("database"); - string username = GridDataMySqlFile.ParseFileReadValue("username"); - string password = GridDataMySqlFile.ParseFileReadValue("password"); - string pooling = GridDataMySqlFile.ParseFileReadValue("pooling"); - string port = GridDataMySqlFile.ParseFileReadValue("port"); - - _dbConnection = new MySQLManager(hostname, database, username, password, pooling, port); - - TestTables(); - } - - public string Version - { - get { return _dbConnection.getVersion(); } - } - - public string Name - { - get { return "MySQL Asset storage engine"; } - } - - #endregion - } -} \ No newline at end of file +/* +* 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.Generic; +using System.Data; +using libsecondlife; +using MySql.Data.MySqlClient; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Data.MySQL +{ + internal class MySQLAssetData : IAssetProvider + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private MySQLManager _dbConnection; + + #region IAssetProvider Members + + private void UpgradeAssetsTable(string oldVersion) + { + // null as the version, indicates that the table didn't exist + if (oldVersion == null) + { + m_log.Info("[ASSETS]: Creating new database tables"); + _dbConnection.ExecuteResourceSql("CreateAssetsTable.sql"); + return; + } + } + + /// + /// Ensure that the assets related tables exists and are at the latest version + /// + private void TestTables() + { + Dictionary tableList = new Dictionary(); + + tableList["assets"] = null; + _dbConnection.GetTableVersion(tableList); + + UpgradeAssetsTable(tableList["assets"]); + } + + public AssetBase FetchAsset(LLUUID assetID) + { + AssetBase asset = null; + lock (_dbConnection) + { + MySqlCommand cmd = + new MySqlCommand( + "SELECT name, description, assetType, invType, local, temporary, data FROM assets WHERE id=?id", + _dbConnection.Connection); + MySqlParameter p = cmd.Parameters.Add("?id", MySqlDbType.Binary, 16); + p.Value = assetID.GetBytes(); + + try + { + using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) + { + if (dbReader.Read()) + { + asset = new AssetBase(); + asset.Data = (byte[]) dbReader["data"]; + asset.Description = (string) dbReader["description"]; + asset.FullID = assetID; + asset.InvType = (sbyte) dbReader["invType"]; + asset.Local = ((sbyte) dbReader["local"]) != 0 ? true : false; + asset.Name = (string) dbReader["name"]; + asset.Type = (sbyte) dbReader["assetType"]; + } + dbReader.Close(); + cmd.Dispose(); + } + } + catch (Exception e) + { + m_log.ErrorFormat( + "[ASSETS]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString() + + Environment.NewLine + "Attempting reconnection", assetID); + _dbConnection.Reconnect(); + } + } + return asset; + } + + public void CreateAsset(AssetBase asset) + { + lock (_dbConnection) + { + MySqlCommand cmd = + new MySqlCommand( + "REPLACE INTO assets(id, name, description, assetType, invType, local, temporary, data)" + + "VALUES(?id, ?name, ?description, ?assetType, ?invType, ?local, ?temporary, ?data)", + _dbConnection.Connection); + + // need to ensure we dispose + try + { + using (cmd) + { + MySqlParameter p = cmd.Parameters.Add("?id", MySqlDbType.Binary, 16); + p.Value = asset.FullID.GetBytes(); + cmd.Parameters.AddWithValue("?name", asset.Name); + cmd.Parameters.AddWithValue("?description", asset.Description); + cmd.Parameters.AddWithValue("?assetType", asset.Type); + cmd.Parameters.AddWithValue("?invType", asset.InvType); + cmd.Parameters.AddWithValue("?local", asset.Local); + cmd.Parameters.AddWithValue("?temporary", asset.Temporary); + cmd.Parameters.AddWithValue("?data", asset.Data); + cmd.ExecuteNonQuery(); + cmd.Dispose(); + } + } + catch (Exception e) + { + m_log.ErrorFormat( + "[ASSETS]: " + + "MySql failure creating asset {0} with name {1}" + Environment.NewLine + e.ToString() + + Environment.NewLine + "Attempting reconnection", asset.FullID, asset.Name); + _dbConnection.Reconnect(); + } + } + } + + public void UpdateAsset(AssetBase asset) + { + CreateAsset(asset); + } + + public bool ExistsAsset(LLUUID uuid) + { + throw new Exception("The method or operation is not implemented."); + } + + // rex, new function, fixme not implemented + public List GetAssetList(int vAssetType) + { + List retvals = new List(); + return retvals; + } + + /// + /// All writes are immediately commited to the database, so this is a no-op + /// + public void CommitAssets() + { + } + + // rex new function for "replace assets" functionality + // TODO: actual implementation by someone, should return LLUUID of an asset + // with matching type & name, or zero if not in DB + public LLUUID ExistsAsset(sbyte type, string name) + { + return LLUUID.Zero; + } + + #endregion + + #region IPlugin Members + + public void Initialise() + { + IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini"); + string hostname = GridDataMySqlFile.ParseFileReadValue("hostname"); + string database = GridDataMySqlFile.ParseFileReadValue("database"); + string username = GridDataMySqlFile.ParseFileReadValue("username"); + string password = GridDataMySqlFile.ParseFileReadValue("password"); + string pooling = GridDataMySqlFile.ParseFileReadValue("pooling"); + string port = GridDataMySqlFile.ParseFileReadValue("port"); + + _dbConnection = new MySQLManager(hostname, database, username, password, pooling, port); + + TestTables(); + } + + public string Version + { + get { return _dbConnection.getVersion(); } + } + + public string Name + { + get { return "MySQL Asset storage engine"; } + } + + #endregion + } +} diff --git a/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs b/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs index eacf910dc5..e0dce8e28b 100644 --- a/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs +++ b/OpenSim/Framework/Data.MySQL/MySQLDataStore.cs @@ -1,1412 +1,1692 @@ -/* -* 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.Generic; -using System.Data; -using System.Diagnostics; -using System.IO; -using libsecondlife; -using MySql.Data.MySqlClient; -using OpenSim.Framework.Console; -using OpenSim.Region.Environment.Interfaces; -using OpenSim.Region.Environment.LandManagement; -using OpenSim.Region.Environment.Scenes; - -namespace OpenSim.Framework.Data.MySQL -{ - public class MySQLDataStore : IRegionDataStore - { - private const string m_primSelect = "select * from prims"; - private const string m_shapeSelect = "select * from primshapes"; - private const string m_terrainSelect = "select * from terrain limit 1"; - private const string m_landSelect = "select * from land"; - private const string m_landAccessListSelect = "select * from landaccesslist"; - - private DataSet m_dataSet; - private MySqlDataAdapter m_primDataAdapter; - private MySqlDataAdapter m_shapeDataAdapter; - private MySqlConnection m_connection; - private MySqlDataAdapter m_terrainDataAdapter; - private MySqlDataAdapter m_landDataAdapter; - private MySqlDataAdapter m_landAccessListDataAdapter; - private DataTable m_primTable; - private DataTable m_shapeTable; - private DataTable m_terrainTable; - private DataTable m_landTable; - private DataTable m_landAccessListTable; - - /*********************************************************************** - * - * Public Interface Functions - * - **********************************************************************/ - - // see IRegionDataStore - public void Initialise(string connectionstring, bool persistPrimInventories) - { - m_dataSet = new DataSet(); - - MainLog.Instance.Verbose("DATASTORE", "MySql - connecting: " + connectionstring); - m_connection = new MySqlConnection(connectionstring); - - MySqlCommand primSelectCmd = new MySqlCommand(m_primSelect, m_connection); - m_primDataAdapter = new MySqlDataAdapter(primSelectCmd); - - MySqlCommand shapeSelectCmd = new MySqlCommand(m_shapeSelect, m_connection); - m_shapeDataAdapter = new MySqlDataAdapter(shapeSelectCmd); - - MySqlCommand terrainSelectCmd = new MySqlCommand(m_terrainSelect, m_connection); - m_terrainDataAdapter = new MySqlDataAdapter(terrainSelectCmd); - - MySqlCommand landSelectCmd = new MySqlCommand(m_landSelect, m_connection); - m_landDataAdapter = new MySqlDataAdapter(landSelectCmd); - - MySqlCommand landAccessListSelectCmd = new MySqlCommand(m_landAccessListSelect, m_connection); - m_landAccessListDataAdapter = new MySqlDataAdapter(landAccessListSelectCmd); - - TestTables(m_connection); - - lock (m_dataSet) - { - m_primTable = createPrimTable(); - m_dataSet.Tables.Add(m_primTable); - SetupPrimCommands(m_primDataAdapter, m_connection); - m_primDataAdapter.Fill(m_primTable); - - m_shapeTable = createShapeTable(); - m_dataSet.Tables.Add(m_shapeTable); - SetupShapeCommands(m_shapeDataAdapter, m_connection); - m_shapeDataAdapter.Fill(m_shapeTable); - - m_terrainTable = createTerrainTable(); - m_dataSet.Tables.Add(m_terrainTable); - SetupTerrainCommands(m_terrainDataAdapter, m_connection); - m_terrainDataAdapter.Fill(m_terrainTable); - - m_landTable = createLandTable(); - m_dataSet.Tables.Add(m_landTable); - setupLandCommands(m_landDataAdapter, m_connection); - m_landDataAdapter.Fill(m_landTable); - - m_landAccessListTable = createLandAccessListTable(); - m_dataSet.Tables.Add(m_landAccessListTable); - setupLandAccessCommands(m_landAccessListDataAdapter, m_connection); - m_landAccessListDataAdapter.Fill(m_landAccessListTable); - } - } - - public void StoreObject(SceneObjectGroup obj, LLUUID regionUUID) - { - lock (m_dataSet) - { - foreach (SceneObjectPart prim in obj.Children.Values) - { - if ((prim.ObjectFlags & (uint) LLObject.ObjectFlags.Physics) == 0) - { - MainLog.Instance.Verbose("DATASTORE", "Adding obj: " + obj.UUID + " to region: " + regionUUID); - addPrim(prim, obj.UUID, regionUUID); - } - else - { - // MainLog.Instance.Verbose("DATASTORE", "Ignoring Physical obj: " + obj.UUID + " in region: " + regionUUID); - } - } - } - - Commit(); - } - - public void RemoveObject(LLUUID obj, LLUUID regionUUID) - { - DataTable prims = m_primTable; - DataTable shapes = m_shapeTable; - - string selectExp = "SceneGroupID = '" + Util.ToRawUuidString(obj) + "'"; - lock (m_dataSet) - { - DataRow[] primRows = prims.Select(selectExp); - foreach (DataRow row in primRows) - { - LLUUID uuid = new LLUUID((string) row["UUID"]); - DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(uuid)); - if (shapeRow != null) - { - shapeRow.Delete(); - } - row.Delete(); - } - } - - Commit(); - } - - public List LoadObjects(LLUUID regionUUID) - { - Dictionary createdObjects = new Dictionary(); - - List retvals = new List(); - - DataTable prims = m_primTable; - DataTable shapes = m_shapeTable; - - string byRegion = "RegionUUID = '" + Util.ToRawUuidString(regionUUID) + "'"; - string orderByParent = "ParentID ASC"; - - lock (m_dataSet) - { - DataRow[] primsForRegion = prims.Select(byRegion, orderByParent); - MainLog.Instance.Verbose("DATASTORE", - "Loaded " + primsForRegion.Length + " prims for region: " + regionUUID); - - foreach (DataRow primRow in primsForRegion) - { - try - { - string uuid = (string) primRow["UUID"]; - string objID = (string) primRow["SceneGroupID"]; - if (uuid == objID) //is new SceneObjectGroup ? - { - SceneObjectGroup group = new SceneObjectGroup(); - SceneObjectPart prim = buildPrim(primRow); - DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(prim.UUID)); - if (shapeRow != null) - { - prim.Shape = buildShape(shapeRow); - } - else - { - MainLog.Instance.Notice( - "No shape found for prim in storage, so setting default box shape"); - prim.Shape = PrimitiveBaseShape.Default; - } - group.AddPart(prim); - group.RootPart = prim; - - createdObjects.Add(group.UUID, group); - retvals.Add(group); - } - else - { - SceneObjectPart prim = buildPrim(primRow); - DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(prim.UUID)); - if (shapeRow != null) - { - prim.Shape = buildShape(shapeRow); - } - else - { - MainLog.Instance.Notice( - "No shape found for prim in storage, so setting default box shape"); - prim.Shape = PrimitiveBaseShape.Default; - } - createdObjects[new LLUUID(objID)].AddPart(prim); - } - } - catch (Exception e) - { - MainLog.Instance.Error("DATASTORE", "Failed create prim object, exception and data follows"); - MainLog.Instance.Verbose("DATASTORE", e.ToString()); - foreach (DataColumn col in prims.Columns) - { - MainLog.Instance.Verbose("DATASTORE", "Col: " + col.ColumnName + " => " + primRow[col]); - } - } - } - } - return retvals; - } - - - public void StoreTerrain(double[,] ter, LLUUID regionID) - { - int revision = Util.UnixTimeSinceEpoch(); - MainLog.Instance.Verbose("DATASTORE", "Storing terrain revision r" + revision.ToString()); - - DataTable terrain = m_dataSet.Tables["terrain"]; - lock (m_dataSet) - { - MySqlCommand cmd = new MySqlCommand("insert into terrain(RegionUUID, Revision, Heightfield)" + - " values(?RegionUUID, ?Revision, ?Heightfield)", m_connection); - using (cmd) - { - cmd.Parameters.Add(new MySqlParameter("?RegionUUID", Util.ToRawUuidString(regionID))); - cmd.Parameters.Add(new MySqlParameter("?Revision", revision)); - cmd.Parameters.Add(new MySqlParameter("?Heightfield", serializeTerrain(ter))); - cmd.ExecuteNonQuery(); - } - } - } - - public double[,] LoadTerrain(LLUUID regionID) - { - double[,] terret = new double[256,256]; - terret.Initialize(); - - MySqlCommand cmd = new MySqlCommand( - @"select RegionUUID, Revision, Heightfield from terrain - where RegionUUID=?RegionUUID order by Revision desc limit 1" - , m_connection); - - MySqlParameter param = new MySqlParameter(); - cmd.Parameters.Add(new MySqlParameter("?RegionUUID", Util.ToRawUuidString(regionID))); - - if (m_connection.State != ConnectionState.Open) - { - m_connection.Open(); - } - - using (MySqlDataReader row = cmd.ExecuteReader()) - { - int rev = 0; - if (row.Read()) - { - byte[] heightmap = (byte[]) row["Heightfield"]; - for (int x = 0; x < 256; x++) - { - for (int y = 0; y < 256; y++) - { - terret[x, y] = BitConverter.ToDouble(heightmap, ((x*256) + y)*8); - } - } - rev = (int) row["Revision"]; - } - else - { - MainLog.Instance.Verbose("DATASTORE", "No terrain found for region"); - return null; - } - - MainLog.Instance.Verbose("DATASTORE", "Loaded terrain revision r" + rev.ToString()); - } - - return terret; - } - - public void RemoveLandObject(LLUUID globalID) - { - lock (m_dataSet) - { - using (MySqlCommand cmd = new MySqlCommand("delete from land where UUID=?UUID", m_connection)) - { - cmd.Parameters.Add(new MySqlParameter("?UUID", Util.ToRawUuidString(globalID))); - cmd.ExecuteNonQuery(); - } - - using ( - MySqlCommand cmd = new MySqlCommand("delete from landaccesslist where LandUUID=?UUID", m_connection) - ) - { - cmd.Parameters.Add(new MySqlParameter("?UUID", Util.ToRawUuidString(globalID))); - cmd.ExecuteNonQuery(); - } - } - } - - public void StoreLandObject(Land parcel, LLUUID regionUUID) - { - lock (m_dataSet) - { - DataTable land = m_landTable; - DataTable landaccesslist = m_landAccessListTable; - - DataRow landRow = land.Rows.Find(Util.ToRawUuidString(parcel.landData.globalID)); - if (landRow == null) - { - landRow = land.NewRow(); - fillLandRow(landRow, parcel.landData, regionUUID); - land.Rows.Add(landRow); - } - else - { - fillLandRow(landRow, parcel.landData, regionUUID); - } - - using ( - MySqlCommand cmd = - new MySqlCommand("delete from landaccesslist where LandUUID=?LandUUID", m_connection)) - { - cmd.Parameters.Add(new MySqlParameter("?LandUUID", Util.ToRawUuidString(parcel.landData.globalID))); - cmd.ExecuteNonQuery(); - } - - foreach (ParcelManager.ParcelAccessEntry entry in parcel.landData.parcelAccessList) - { - DataRow newAccessRow = landaccesslist.NewRow(); - fillLandAccessRow(newAccessRow, entry, parcel.landData.globalID); - landaccesslist.Rows.Add(newAccessRow); - } - } - - Commit(); - } - - public List LoadLandObjects(LLUUID regionUUID) - { - List landDataForRegion = new List(); - lock (m_dataSet) - { - DataTable land = m_landTable; - DataTable landaccesslist = m_landAccessListTable; - string searchExp = "RegionUUID = '" + Util.ToRawUuidString(regionUUID) + "'"; - DataRow[] rawDataForRegion = land.Select(searchExp); - foreach (DataRow rawDataLand in rawDataForRegion) - { - LandData newLand = buildLandData(rawDataLand); - string accessListSearchExp = "LandUUID = '" + Util.ToRawUuidString(newLand.globalID) + "'"; - DataRow[] rawDataForLandAccessList = landaccesslist.Select(accessListSearchExp); - foreach (DataRow rawDataLandAccess in rawDataForLandAccessList) - { - newLand.parcelAccessList.Add(buildLandAccessData(rawDataLandAccess)); - } - - landDataForRegion.Add(newLand); - } - } - return landDataForRegion; - } - - private void DisplayDataSet(DataSet ds, string title) - { - Debug.WriteLine(title); - //--- Loop through the DataTables - foreach (DataTable table in ds.Tables) - { - Debug.WriteLine("*** DataTable: " + table.TableName + "***"); - //--- Loop through each DataTable's DataRows - foreach (DataRow row in table.Rows) - { - //--- Display the original values, if there are any. - if (row.HasVersion(DataRowVersion.Original)) - { - Debug.Write("Original Row Values ===> "); - foreach (DataColumn column in table.Columns) - Debug.Write(column.ColumnName + " = " + - row[column, DataRowVersion.Original] + ", "); - Debug.WriteLine(""); - } - //--- Display the current values, if there are any. - if (row.HasVersion(DataRowVersion.Current)) - { - Debug.Write("Current Row Values ====> "); - foreach (DataColumn column in table.Columns) - Debug.Write(column.ColumnName + " = " + - row[column, DataRowVersion.Current] + ", "); - Debug.WriteLine(""); - } - Debug.WriteLine(""); - } - } - } - - public void Commit() - { - if (m_connection.State != ConnectionState.Open) - { - m_connection.Open(); - } - - lock (m_dataSet) - { - // DisplayDataSet(m_dataSet, "Region DataSet"); - - m_primDataAdapter.Update(m_primTable); - m_shapeDataAdapter.Update(m_shapeTable); - m_terrainDataAdapter.Update(m_terrainTable); - m_landDataAdapter.Update(m_landTable); - m_landAccessListDataAdapter.Update(m_landAccessListTable); - - m_dataSet.AcceptChanges(); - } - } - - public void Shutdown() - { - Commit(); - } - - /*********************************************************************** - * - * Database Definition Functions - * - * This should be db agnostic as we define them in ADO.NET terms - * - **********************************************************************/ - - private DataColumn createCol(DataTable dt, string name, Type type) - { - DataColumn col = new DataColumn(name, type); - dt.Columns.Add(col); - return col; - } - - private DataTable createTerrainTable() - { - DataTable terrain = new DataTable("terrain"); - - createCol(terrain, "RegionUUID", typeof (String)); - createCol(terrain, "Revision", typeof (Int32)); - DataColumn heightField = createCol(terrain, "Heightfield", typeof (Byte[])); - return terrain; - } - - private DataTable createPrimTable() - { - DataTable prims = new DataTable("prims"); - - createCol(prims, "UUID", typeof (String)); - createCol(prims, "RegionUUID", typeof (String)); - createCol(prims, "ParentID", typeof (Int32)); - createCol(prims, "CreationDate", typeof (Int32)); - createCol(prims, "Name", typeof (String)); - createCol(prims, "SceneGroupID", typeof (String)); - // various text fields - createCol(prims, "Text", typeof (String)); - createCol(prims, "Description", typeof (String)); - createCol(prims, "SitName", typeof (String)); - createCol(prims, "TouchName", typeof (String)); - // permissions - createCol(prims, "ObjectFlags", typeof (Int32)); - createCol(prims, "CreatorID", typeof (String)); - createCol(prims, "OwnerID", typeof (String)); - createCol(prims, "GroupID", typeof (String)); - createCol(prims, "LastOwnerID", typeof (String)); - createCol(prims, "OwnerMask", typeof (Int32)); - createCol(prims, "NextOwnerMask", typeof (Int32)); - createCol(prims, "GroupMask", typeof (Int32)); - createCol(prims, "EveryoneMask", typeof (Int32)); - createCol(prims, "BaseMask", typeof (Int32)); - // vectors - createCol(prims, "PositionX", typeof (Double)); - createCol(prims, "PositionY", typeof (Double)); - createCol(prims, "PositionZ", typeof (Double)); - createCol(prims, "GroupPositionX", typeof (Double)); - createCol(prims, "GroupPositionY", typeof (Double)); - createCol(prims, "GroupPositionZ", typeof (Double)); - createCol(prims, "VelocityX", typeof (Double)); - createCol(prims, "VelocityY", typeof (Double)); - createCol(prims, "VelocityZ", typeof (Double)); - createCol(prims, "AngularVelocityX", typeof (Double)); - createCol(prims, "AngularVelocityY", typeof (Double)); - createCol(prims, "AngularVelocityZ", typeof (Double)); - createCol(prims, "AccelerationX", typeof (Double)); - createCol(prims, "AccelerationY", typeof (Double)); - createCol(prims, "AccelerationZ", typeof (Double)); - // quaternions - createCol(prims, "RotationX", typeof (Double)); - createCol(prims, "RotationY", typeof (Double)); - createCol(prims, "RotationZ", typeof (Double)); - createCol(prims, "RotationW", typeof (Double)); - // sit target - createCol(prims, "SitTargetOffsetX", typeof (Double)); - createCol(prims, "SitTargetOffsetY", typeof (Double)); - createCol(prims, "SitTargetOffsetZ", typeof (Double)); - - createCol(prims, "SitTargetOrientW", typeof (Double)); - createCol(prims, "SitTargetOrientX", typeof (Double)); - createCol(prims, "SitTargetOrientY", typeof (Double)); - createCol(prims, "SitTargetOrientZ", typeof (Double)); - - - // Add in contraints - prims.PrimaryKey = new DataColumn[] {prims.Columns["UUID"]}; - - return prims; - } - - private DataTable createLandTable() - { - DataTable land = new DataTable("land"); - createCol(land, "UUID", typeof (String)); - createCol(land, "RegionUUID", typeof (String)); - createCol(land, "LocalLandID", typeof (Int32)); - - // Bitmap is a byte[512] - createCol(land, "Bitmap", typeof (Byte[])); - - createCol(land, "Name", typeof (String)); - createCol(land, "Description", typeof (String)); - createCol(land, "OwnerUUID", typeof (String)); - createCol(land, "IsGroupOwned", typeof (Int32)); - createCol(land, "Area", typeof (Int32)); - createCol(land, "AuctionID", typeof (Int32)); //Unemplemented - createCol(land, "Category", typeof (Int32)); //Enum libsecondlife.Parcel.ParcelCategory - createCol(land, "ClaimDate", typeof (Int32)); - createCol(land, "ClaimPrice", typeof (Int32)); - createCol(land, "GroupUUID", typeof (String)); - createCol(land, "SalePrice", typeof (Int32)); - createCol(land, "LandStatus", typeof (Int32)); //Enum. libsecondlife.Parcel.ParcelStatus - createCol(land, "LandFlags", typeof (Int32)); - createCol(land, "LandingType", typeof (Int32)); - createCol(land, "MediaAutoScale", typeof (Int32)); - createCol(land, "MediaTextureUUID", typeof (String)); - createCol(land, "MediaURL", typeof (String)); - createCol(land, "MusicURL", typeof (String)); - createCol(land, "PassHours", typeof (Double)); - createCol(land, "PassPrice", typeof (Int32)); - createCol(land, "SnapshotUUID", typeof (String)); - createCol(land, "UserLocationX", typeof (Double)); - createCol(land, "UserLocationY", typeof (Double)); - createCol(land, "UserLocationZ", typeof (Double)); - createCol(land, "UserLookAtX", typeof (Double)); - createCol(land, "UserLookAtY", typeof (Double)); - createCol(land, "UserLookAtZ", typeof (Double)); - - land.PrimaryKey = new DataColumn[] {land.Columns["UUID"]}; - - return land; - } - - private DataTable createLandAccessListTable() - { - DataTable landaccess = new DataTable("landaccesslist"); - createCol(landaccess, "LandUUID", typeof (String)); - createCol(landaccess, "AccessUUID", typeof (String)); - createCol(landaccess, "Flags", typeof (Int32)); - - return landaccess; - } - - private DataTable createShapeTable() - { - DataTable shapes = new DataTable("primshapes"); - createCol(shapes, "UUID", typeof (String)); - // shape is an enum - createCol(shapes, "Shape", typeof (Int32)); - // vectors - createCol(shapes, "ScaleX", typeof (Double)); - createCol(shapes, "ScaleY", typeof (Double)); - createCol(shapes, "ScaleZ", typeof (Double)); - // paths - createCol(shapes, "PCode", typeof (Int32)); - createCol(shapes, "PathBegin", typeof (Int32)); - createCol(shapes, "PathEnd", typeof (Int32)); - createCol(shapes, "PathScaleX", typeof (Int32)); - createCol(shapes, "PathScaleY", typeof (Int32)); - createCol(shapes, "PathShearX", typeof (Int32)); - createCol(shapes, "PathShearY", typeof (Int32)); - createCol(shapes, "PathSkew", typeof (Int32)); - createCol(shapes, "PathCurve", typeof (Int32)); - createCol(shapes, "PathRadiusOffset", typeof (Int32)); - createCol(shapes, "PathRevolutions", typeof (Int32)); - createCol(shapes, "PathTaperX", typeof (Int32)); - createCol(shapes, "PathTaperY", typeof (Int32)); - createCol(shapes, "PathTwist", typeof (Int32)); - createCol(shapes, "PathTwistBegin", typeof (Int32)); - // profile - createCol(shapes, "ProfileBegin", typeof (Int32)); - createCol(shapes, "ProfileEnd", typeof (Int32)); - createCol(shapes, "ProfileCurve", typeof (Int32)); - createCol(shapes, "ProfileHollow", typeof (Int32)); - createCol(shapes, "Texture", typeof (Byte[])); - createCol(shapes, "ExtraParams", typeof (Byte[])); - - shapes.PrimaryKey = new DataColumn[] {shapes.Columns["UUID"]}; - - return shapes; - } - - /*********************************************************************** - * - * Convert between ADO.NET <=> OpenSim Objects - * - * These should be database independant - * - **********************************************************************/ - - private SceneObjectPart buildPrim(DataRow row) - { - SceneObjectPart prim = new SceneObjectPart(); - prim.UUID = new LLUUID((String) row["UUID"]); - // explicit conversion of integers is required, which sort - // of sucks. No idea if there is a shortcut here or not. - prim.ParentID = Convert.ToUInt32(row["ParentID"]); - prim.CreationDate = Convert.ToInt32(row["CreationDate"]); - prim.Name = (String) row["Name"]; - // various text fields - prim.Text = (String) row["Text"]; - prim.Description = (String) row["Description"]; - prim.SitName = (String) row["SitName"]; - prim.TouchName = (String) row["TouchName"]; - // permissions - prim.ObjectFlags = Convert.ToUInt32(row["ObjectFlags"]); - prim.CreatorID = new LLUUID((String) row["CreatorID"]); - prim.OwnerID = new LLUUID((String) row["OwnerID"]); - prim.GroupID = new LLUUID((String) row["GroupID"]); - prim.LastOwnerID = new LLUUID((String) row["LastOwnerID"]); - prim.OwnerMask = Convert.ToUInt32(row["OwnerMask"]); - prim.NextOwnerMask = Convert.ToUInt32(row["NextOwnerMask"]); - prim.GroupMask = Convert.ToUInt32(row["GroupMask"]); - prim.EveryoneMask = Convert.ToUInt32(row["EveryoneMask"]); - prim.BaseMask = Convert.ToUInt32(row["BaseMask"]); - // vectors - prim.OffsetPosition = new LLVector3( - Convert.ToSingle(row["PositionX"]), - Convert.ToSingle(row["PositionY"]), - Convert.ToSingle(row["PositionZ"]) - ); - prim.GroupPosition = new LLVector3( - Convert.ToSingle(row["GroupPositionX"]), - Convert.ToSingle(row["GroupPositionY"]), - Convert.ToSingle(row["GroupPositionZ"]) - ); - prim.Velocity = new LLVector3( - Convert.ToSingle(row["VelocityX"]), - Convert.ToSingle(row["VelocityY"]), - Convert.ToSingle(row["VelocityZ"]) - ); - prim.AngularVelocity = new LLVector3( - Convert.ToSingle(row["AngularVelocityX"]), - Convert.ToSingle(row["AngularVelocityY"]), - Convert.ToSingle(row["AngularVelocityZ"]) - ); - prim.Acceleration = new LLVector3( - Convert.ToSingle(row["AccelerationX"]), - Convert.ToSingle(row["AccelerationY"]), - Convert.ToSingle(row["AccelerationZ"]) - ); - // quaternions - prim.RotationOffset = new LLQuaternion( - Convert.ToSingle(row["RotationX"]), - Convert.ToSingle(row["RotationY"]), - Convert.ToSingle(row["RotationZ"]), - Convert.ToSingle(row["RotationW"]) - ); - try - { - prim.SetSitTargetLL(new LLVector3( - Convert.ToSingle(row["SitTargetOffsetX"]), - Convert.ToSingle(row["SitTargetOffsetY"]), - Convert.ToSingle(row["SitTargetOffsetZ"])), new LLQuaternion( - Convert.ToSingle( - row["SitTargetOrientX"]), - Convert.ToSingle( - row["SitTargetOrientY"]), - Convert.ToSingle( - row["SitTargetOrientZ"]), - Convert.ToSingle( - row["SitTargetOrientW"]))); - } - catch (InvalidCastException) - { - // Database table was created before we got here and needs to be created! :P - - using ( - MySqlCommand cmd = - new MySqlCommand( - "ALTER TABLE `prims` ADD COLUMN `SitTargetOffsetX` float NOT NULL default 0, ADD COLUMN `SitTargetOffsetY` float NOT NULL default 0, ADD COLUMN `SitTargetOffsetZ` float NOT NULL default 0, ADD COLUMN `SitTargetOrientW` float NOT NULL default 0, ADD COLUMN `SitTargetOrientX` float NOT NULL default 0, ADD COLUMN `SitTargetOrientY` float NOT NULL default 0, ADD COLUMN `SitTargetOrientZ` float NOT NULL default 0;", - m_connection)) - { - cmd.ExecuteNonQuery(); - } - } - return prim; - } - - private LandData buildLandData(DataRow row) - { - LandData newData = new LandData(); - - newData.globalID = new LLUUID((String) row["UUID"]); - newData.localID = Convert.ToInt32(row["LocalLandID"]); - - // Bitmap is a byte[512] - newData.landBitmapByteArray = (Byte[]) row["Bitmap"]; - - newData.landName = (String) row["Name"]; - newData.landDesc = (String) row["Description"]; - newData.ownerID = (String) row["OwnerUUID"]; - newData.isGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]); - newData.area = Convert.ToInt32(row["Area"]); - newData.auctionID = Convert.ToUInt32(row["AuctionID"]); //Unemplemented - newData.category = (Parcel.ParcelCategory) Convert.ToInt32(row["Category"]); - //Enum libsecondlife.Parcel.ParcelCategory - newData.claimDate = Convert.ToInt32(row["ClaimDate"]); - newData.claimPrice = Convert.ToInt32(row["ClaimPrice"]); - newData.groupID = new LLUUID((String) row["GroupUUID"]); - newData.salePrice = Convert.ToInt32(row["SalePrice"]); - newData.landStatus = (Parcel.ParcelStatus) Convert.ToInt32(row["LandStatus"]); - //Enum. libsecondlife.Parcel.ParcelStatus - newData.landFlags = Convert.ToUInt32(row["LandFlags"]); - newData.landingType = Convert.ToByte(row["LandingType"]); - newData.mediaAutoScale = Convert.ToByte(row["MediaAutoScale"]); - newData.mediaID = new LLUUID((String) row["MediaTextureUUID"]); - newData.mediaURL = (String) row["MediaURL"]; - newData.musicURL = (String) row["MusicURL"]; - newData.passHours = Convert.ToSingle(row["PassHours"]); - newData.passPrice = Convert.ToInt32(row["PassPrice"]); - newData.snapshotID = (String) row["SnapshotUUID"]; - - newData.userLocation = - new LLVector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]), - Convert.ToSingle(row["UserLocationZ"])); - newData.userLookAt = - new LLVector3(Convert.ToSingle(row["UserLookAtX"]), Convert.ToSingle(row["UserLookAtY"]), - Convert.ToSingle(row["UserLookAtZ"])); - newData.parcelAccessList = new List(); - - return newData; - } - - private ParcelManager.ParcelAccessEntry buildLandAccessData(DataRow row) - { - ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); - entry.AgentID = new LLUUID((string) row["AccessUUID"]); - entry.Flags = (ParcelManager.AccessList) Convert.ToInt32(row["Flags"]); - entry.Time = new DateTime(); - return entry; - } - - private Array serializeTerrain(double[,] val) - { - MemoryStream str = new MemoryStream(65536*sizeof (double)); - BinaryWriter bw = new BinaryWriter(str); - - // TODO: COMPATIBILITY - Add byte-order conversions - for (int x = 0; x < 256; x++) - for (int y = 0; y < 256; y++) - bw.Write(val[x, y]); - - return str.ToArray(); - } - - private void fillPrimRow(DataRow row, SceneObjectPart prim, LLUUID sceneGroupID, LLUUID regionUUID) - { - row["UUID"] = Util.ToRawUuidString(prim.UUID); - row["RegionUUID"] = Util.ToRawUuidString(regionUUID); - row["ParentID"] = prim.ParentID; - row["CreationDate"] = prim.CreationDate; - row["Name"] = prim.Name; - row["SceneGroupID"] = Util.ToRawUuidString(sceneGroupID); - // the UUID of the root part for this SceneObjectGroup - // various text fields - row["Text"] = prim.Text; - row["Description"] = prim.Description; - row["SitName"] = prim.SitName; - row["TouchName"] = prim.TouchName; - // permissions - row["ObjectFlags"] = prim.ObjectFlags; - row["CreatorID"] = Util.ToRawUuidString(prim.CreatorID); - row["OwnerID"] = Util.ToRawUuidString(prim.OwnerID); - row["GroupID"] = Util.ToRawUuidString(prim.GroupID); - row["LastOwnerID"] = Util.ToRawUuidString(prim.LastOwnerID); - row["OwnerMask"] = prim.OwnerMask; - row["NextOwnerMask"] = prim.NextOwnerMask; - row["GroupMask"] = prim.GroupMask; - row["EveryoneMask"] = prim.EveryoneMask; - row["BaseMask"] = prim.BaseMask; - // vectors - row["PositionX"] = prim.OffsetPosition.X; - row["PositionY"] = prim.OffsetPosition.Y; - row["PositionZ"] = prim.OffsetPosition.Z; - row["GroupPositionX"] = prim.GroupPosition.X; - row["GroupPositionY"] = prim.GroupPosition.Y; - row["GroupPositionZ"] = prim.GroupPosition.Z; - row["VelocityX"] = prim.Velocity.X; - row["VelocityY"] = prim.Velocity.Y; - row["VelocityZ"] = prim.Velocity.Z; - row["AngularVelocityX"] = prim.AngularVelocity.X; - row["AngularVelocityY"] = prim.AngularVelocity.Y; - row["AngularVelocityZ"] = prim.AngularVelocity.Z; - row["AccelerationX"] = prim.Acceleration.X; - row["AccelerationY"] = prim.Acceleration.Y; - row["AccelerationZ"] = prim.Acceleration.Z; - // quaternions - row["RotationX"] = prim.RotationOffset.X; - row["RotationY"] = prim.RotationOffset.Y; - row["RotationZ"] = prim.RotationOffset.Z; - row["RotationW"] = prim.RotationOffset.W; - - try - { - // Sit target - LLVector3 sitTargetPos = prim.GetSitTargetPositionLL(); - row["SitTargetOffsetX"] = sitTargetPos.X; - row["SitTargetOffsetY"] = sitTargetPos.Y; - row["SitTargetOffsetZ"] = sitTargetPos.Z; - - LLQuaternion sitTargetOrient = prim.GetSitTargetOrientationLL(); - row["SitTargetOrientW"] = sitTargetOrient.W; - row["SitTargetOrientX"] = sitTargetOrient.X; - row["SitTargetOrientY"] = sitTargetOrient.Y; - row["SitTargetOrientZ"] = sitTargetOrient.Z; - } - catch (MySqlException) - { - // Database table was created before we got here and needs to be created! :P - - using ( - MySqlCommand cmd = - new MySqlCommand( - "ALTER TABLE `prims` ADD COLUMN `SitTargetOffsetX` float NOT NULL default 0, ADD COLUMN `SitTargetOffsetY` float NOT NULL default 0, ADD COLUMN `SitTargetOffsetZ` float NOT NULL default 0, ADD COLUMN `SitTargetOrientW` float NOT NULL default 0, ADD COLUMN `SitTargetOrientX` float NOT NULL default 0, ADD COLUMN `SitTargetOrientY` float NOT NULL default 0, ADD COLUMN `SitTargetOrientZ` float NOT NULL default 0;", - m_connection)) - { - cmd.ExecuteNonQuery(); - } - } - } - - private void fillLandRow(DataRow row, LandData land, LLUUID regionUUID) - { - row["UUID"] = Util.ToRawUuidString(land.globalID); - row["RegionUUID"] = Util.ToRawUuidString(regionUUID); - row["LocalLandID"] = land.localID; - - // Bitmap is a byte[512] - row["Bitmap"] = land.landBitmapByteArray; - - row["Name"] = land.landName; - row["Description"] = land.landDesc; - row["OwnerUUID"] = Util.ToRawUuidString(land.ownerID); - row["IsGroupOwned"] = land.isGroupOwned; - row["Area"] = land.area; - row["AuctionID"] = land.auctionID; //Unemplemented - row["Category"] = land.category; //Enum libsecondlife.Parcel.ParcelCategory - row["ClaimDate"] = land.claimDate; - row["ClaimPrice"] = land.claimPrice; - row["GroupUUID"] = Util.ToRawUuidString(land.groupID); - row["SalePrice"] = land.salePrice; - row["LandStatus"] = land.landStatus; //Enum. libsecondlife.Parcel.ParcelStatus - row["LandFlags"] = land.landFlags; - row["LandingType"] = land.landingType; - row["MediaAutoScale"] = land.mediaAutoScale; - row["MediaTextureUUID"] = Util.ToRawUuidString(land.mediaID); - row["MediaURL"] = land.mediaURL; - row["MusicURL"] = land.musicURL; - row["PassHours"] = land.passHours; - row["PassPrice"] = land.passPrice; - row["SnapshotUUID"] = Util.ToRawUuidString(land.snapshotID); - row["UserLocationX"] = land.userLocation.X; - row["UserLocationY"] = land.userLocation.Y; - row["UserLocationZ"] = land.userLocation.Z; - row["UserLookAtX"] = land.userLookAt.X; - row["UserLookAtY"] = land.userLookAt.Y; - row["UserLookAtZ"] = land.userLookAt.Z; - } - - private void fillLandAccessRow(DataRow row, ParcelManager.ParcelAccessEntry entry, LLUUID parcelID) - { - row["LandUUID"] = Util.ToRawUuidString(parcelID); - row["AccessUUID"] = Util.ToRawUuidString(entry.AgentID); - row["Flags"] = entry.Flags; - } - - private PrimitiveBaseShape buildShape(DataRow row) - { - PrimitiveBaseShape s = new PrimitiveBaseShape(); - s.Scale = new LLVector3( - Convert.ToSingle(row["ScaleX"]), - Convert.ToSingle(row["ScaleY"]), - Convert.ToSingle(row["ScaleZ"]) - ); - // paths - s.PCode = Convert.ToByte(row["PCode"]); - s.PathBegin = Convert.ToUInt16(row["PathBegin"]); - s.PathEnd = Convert.ToUInt16(row["PathEnd"]); - s.PathScaleX = Convert.ToByte(row["PathScaleX"]); - s.PathScaleY = Convert.ToByte(row["PathScaleY"]); - s.PathShearX = Convert.ToByte(row["PathShearX"]); - s.PathShearY = Convert.ToByte(row["PathShearY"]); - s.PathSkew = Convert.ToSByte(row["PathSkew"]); - s.PathCurve = Convert.ToByte(row["PathCurve"]); - s.PathRadiusOffset = Convert.ToSByte(row["PathRadiusOffset"]); - s.PathRevolutions = Convert.ToByte(row["PathRevolutions"]); - s.PathTaperX = Convert.ToSByte(row["PathTaperX"]); - s.PathTaperY = Convert.ToSByte(row["PathTaperY"]); - s.PathTwist = Convert.ToSByte(row["PathTwist"]); - s.PathTwistBegin = Convert.ToSByte(row["PathTwistBegin"]); - // profile - s.ProfileBegin = Convert.ToUInt16(row["ProfileBegin"]); - s.ProfileEnd = Convert.ToUInt16(row["ProfileEnd"]); - s.ProfileCurve = Convert.ToByte(row["ProfileCurve"]); - s.ProfileHollow = Convert.ToUInt16(row["ProfileHollow"]); - - byte[] textureEntry = (byte[]) row["Texture"]; - s.TextureEntry = textureEntry; - - s.ExtraParams = (byte[]) row["ExtraParams"]; - - return s; - } - - private void fillShapeRow(DataRow row, SceneObjectPart prim) - { - PrimitiveBaseShape s = prim.Shape; - row["UUID"] = Util.ToRawUuidString(prim.UUID); - // shape is an enum - row["Shape"] = 0; - // vectors - row["ScaleX"] = s.Scale.X; - row["ScaleY"] = s.Scale.Y; - row["ScaleZ"] = s.Scale.Z; - // paths - row["PCode"] = s.PCode; - row["PathBegin"] = s.PathBegin; - row["PathEnd"] = s.PathEnd; - row["PathScaleX"] = s.PathScaleX; - row["PathScaleY"] = s.PathScaleY; - row["PathShearX"] = s.PathShearX; - row["PathShearY"] = s.PathShearY; - row["PathSkew"] = s.PathSkew; - row["PathCurve"] = s.PathCurve; - row["PathRadiusOffset"] = s.PathRadiusOffset; - row["PathRevolutions"] = s.PathRevolutions; - row["PathTaperX"] = s.PathTaperX; - row["PathTaperY"] = s.PathTaperY; - row["PathTwist"] = s.PathTwist; - row["PathTwistBegin"] = s.PathTwistBegin; - // profile - row["ProfileBegin"] = s.ProfileBegin; - row["ProfileEnd"] = s.ProfileEnd; - row["ProfileCurve"] = s.ProfileCurve; - row["ProfileHollow"] = s.ProfileHollow; - row["Texture"] = s.TextureEntry; - row["ExtraParams"] = s.ExtraParams; - } - - private void addPrim(SceneObjectPart prim, LLUUID sceneGroupID, LLUUID regionUUID) - { - DataTable prims = m_dataSet.Tables["prims"]; - DataTable shapes = m_dataSet.Tables["primshapes"]; - - DataRow primRow = prims.Rows.Find(Util.ToRawUuidString(prim.UUID)); - if (primRow == null) - { - primRow = prims.NewRow(); - fillPrimRow(primRow, prim, sceneGroupID, regionUUID); - prims.Rows.Add(primRow); - } - else - { - fillPrimRow(primRow, prim, sceneGroupID, regionUUID); - } - - DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(prim.UUID)); - if (shapeRow == null) - { - shapeRow = shapes.NewRow(); - fillShapeRow(shapeRow, prim); - shapes.Rows.Add(shapeRow); - } - else - { - fillShapeRow(shapeRow, prim); - } - } - - /*********************************************************************** - * - * SQL Statement Creation Functions - * - * These functions create SQL statements for update, insert, and create. - * They can probably be factored later to have a db independant - * portion and a db specific portion - * - **********************************************************************/ - - private MySqlCommand createInsertCommand(string table, DataTable dt) - { - /** - * This is subtle enough to deserve some commentary. - * Instead of doing *lots* and *lots of hardcoded strings - * for database definitions we'll use the fact that - * realistically all insert statements look like "insert - * into A(b, c) values(:b, :c) on the parameterized query - * front. If we just have a list of b, c, etc... we can - * generate these strings instead of typing them out. - */ - string[] cols = new string[dt.Columns.Count]; - for (int i = 0; i < dt.Columns.Count; i++) - { - DataColumn col = dt.Columns[i]; - cols[i] = col.ColumnName; - } - - string sql = "insert into " + table + "("; - sql += String.Join(", ", cols); - // important, the first ':' needs to be here, the rest get added in the join - sql += ") values (?"; - sql += String.Join(", ?", cols); - sql += ")"; - MySqlCommand cmd = new MySqlCommand(sql); - - // this provides the binding for all our parameters, so - // much less code than it used to be - foreach (DataColumn col in dt.Columns) - { - cmd.Parameters.Add(createMySqlParameter(col.ColumnName, col.DataType)); - } - return cmd; - } - - private MySqlCommand createUpdateCommand(string table, string pk, DataTable dt) - { - string sql = "update " + table + " set "; - string subsql = ""; - foreach (DataColumn col in dt.Columns) - { - if (subsql.Length > 0) - { - // a map function would rock so much here - subsql += ", "; - } - subsql += col.ColumnName + "=?" + col.ColumnName; - } - sql += subsql; - sql += " where " + pk; - MySqlCommand cmd = new MySqlCommand(sql); - - // this provides the binding for all our parameters, so - // much less code than it used to be - - foreach (DataColumn col in dt.Columns) - { - cmd.Parameters.Add(createMySqlParameter(col.ColumnName, col.DataType)); - } - return cmd; - } - - - private string defineTable(DataTable dt) - { - string sql = "create table " + dt.TableName + "("; - string subsql = ""; - foreach (DataColumn col in dt.Columns) - { - if (subsql.Length > 0) - { - // a map function would rock so much here - subsql += ",\n"; - } - subsql += col.ColumnName + " " + MySqlType(col.DataType); - if (dt.PrimaryKey.Length > 0 && col == dt.PrimaryKey[0]) - { - subsql += " primary key"; - } - } - sql += subsql; - sql += ")"; - return sql; - } - - /*********************************************************************** - * - * Database Binding functions - * - * These will be db specific due to typing, and minor differences - * in databases. - * - **********************************************************************/ - - /// - /// This is a convenience function that collapses 5 repetitive - /// lines for defining MySqlParameters to 2 parameters: - /// column name and database type. - /// - /// It assumes certain conventions like ?param as the param - /// name to replace in parametrized queries, and that source - /// version is always current version, both of which are fine - /// for us. - /// - ///a built MySql parameter - private MySqlParameter createMySqlParameter(string name, Type type) - { - MySqlParameter param = new MySqlParameter(); - param.ParameterName = "?" + name; - param.DbType = dbtypeFromType(type); - param.SourceColumn = name; - param.SourceVersion = DataRowVersion.Current; - return param; - } - - private MySqlParameter createParamWithValue(string name, Type type, Object o) - { - MySqlParameter param = createMySqlParameter(name, type); - param.Value = o; - return param; - } - - private void SetupPrimCommands(MySqlDataAdapter da, MySqlConnection conn) - { - MySqlCommand insertCommand = createInsertCommand("prims", m_primTable); - insertCommand.Connection = conn; - da.InsertCommand = insertCommand; - - MySqlCommand updateCommand = createUpdateCommand("prims", "UUID=?UUID", m_primTable); - updateCommand.Connection = conn; - da.UpdateCommand = updateCommand; - - MySqlCommand delete = new MySqlCommand("delete from prims where UUID=?UUID"); - delete.Parameters.Add(createMySqlParameter("UUID", typeof (String))); - delete.Connection = conn; - da.DeleteCommand = delete; - } - - private void SetupTerrainCommands(MySqlDataAdapter da, MySqlConnection conn) - { - da.InsertCommand = createInsertCommand("terrain", m_dataSet.Tables["terrain"]); - da.InsertCommand.Connection = conn; - } - - private void setupLandCommands(MySqlDataAdapter da, MySqlConnection conn) - { - da.InsertCommand = createInsertCommand("land", m_dataSet.Tables["land"]); - da.InsertCommand.Connection = conn; - - da.UpdateCommand = createUpdateCommand("land", "UUID=?UUID", m_dataSet.Tables["land"]); - da.UpdateCommand.Connection = conn; - } - - private void setupLandAccessCommands(MySqlDataAdapter da, MySqlConnection conn) - { - da.InsertCommand = createInsertCommand("landaccesslist", m_dataSet.Tables["landaccesslist"]); - da.InsertCommand.Connection = conn; - } - - private void SetupShapeCommands(MySqlDataAdapter da, MySqlConnection conn) - { - da.InsertCommand = createInsertCommand("primshapes", m_dataSet.Tables["primshapes"]); - da.InsertCommand.Connection = conn; - - da.UpdateCommand = createUpdateCommand("primshapes", "UUID=?UUID", m_dataSet.Tables["primshapes"]); - da.UpdateCommand.Connection = conn; - - MySqlCommand delete = new MySqlCommand("delete from primshapes where UUID = ?UUID"); - delete.Parameters.Add(createMySqlParameter("UUID", typeof (String))); - delete.Connection = conn; - da.DeleteCommand = delete; - } - - private void InitDB(MySqlConnection conn) - { - string createPrims = defineTable(createPrimTable()); - string createShapes = defineTable(createShapeTable()); - string createTerrain = defineTable(createTerrainTable()); - string createLand = defineTable(createLandTable()); - string createLandAccessList = defineTable(createLandAccessListTable()); - - MySqlCommand pcmd = new MySqlCommand(createPrims, conn); - MySqlCommand scmd = new MySqlCommand(createShapes, conn); - MySqlCommand tcmd = new MySqlCommand(createTerrain, conn); - MySqlCommand lcmd = new MySqlCommand(createLand, conn); - MySqlCommand lalcmd = new MySqlCommand(createLandAccessList, conn); - - if (conn.State != ConnectionState.Open) - { - conn.Open(); - } - - try - { - pcmd.ExecuteNonQuery(); - } - catch (MySqlException) - { - MainLog.Instance.Warn("MySql", "Primitives Table Already Exists"); - } - - try - { - scmd.ExecuteNonQuery(); - } - catch (MySqlException) - { - MainLog.Instance.Warn("MySql", "Shapes Table Already Exists"); - } - - try - { - tcmd.ExecuteNonQuery(); - } - catch (MySqlException) - { - MainLog.Instance.Warn("MySql", "Terrain Table Already Exists"); - } - - try - { - lcmd.ExecuteNonQuery(); - } - catch (MySqlException) - { - MainLog.Instance.Warn("MySql", "Land Table Already Exists"); - } - - try - { - lalcmd.ExecuteNonQuery(); - } - catch (MySqlException) - { - MainLog.Instance.Warn("MySql", "LandAccessList Table Already Exists"); - } - conn.Close(); - } - - private bool TestTables(MySqlConnection conn) - { - MySqlCommand primSelectCmd = new MySqlCommand(m_primSelect, conn); - MySqlDataAdapter pDa = new MySqlDataAdapter(primSelectCmd); - MySqlCommand shapeSelectCmd = new MySqlCommand(m_shapeSelect, conn); - MySqlDataAdapter sDa = new MySqlDataAdapter(shapeSelectCmd); - MySqlCommand terrainSelectCmd = new MySqlCommand(m_terrainSelect, conn); - MySqlDataAdapter tDa = new MySqlDataAdapter(terrainSelectCmd); - MySqlCommand landSelectCmd = new MySqlCommand(m_landSelect, conn); - MySqlDataAdapter lDa = new MySqlDataAdapter(landSelectCmd); - MySqlCommand landAccessListSelectCmd = new MySqlCommand(m_landAccessListSelect, conn); - MySqlDataAdapter lalDa = new MySqlDataAdapter(landAccessListSelectCmd); - - DataSet tmpDS = new DataSet(); - try - { - pDa.Fill(tmpDS, "prims"); - sDa.Fill(tmpDS, "primshapes"); - tDa.Fill(tmpDS, "terrain"); - lDa.Fill(tmpDS, "land"); - lalDa.Fill(tmpDS, "landaccesslist"); - } - catch (MySqlException) - { - MainLog.Instance.Verbose("DATASTORE", "MySql Database doesn't exist... creating"); - InitDB(conn); - } - - pDa.Fill(tmpDS, "prims"); - sDa.Fill(tmpDS, "primshapes"); - tDa.Fill(tmpDS, "terrain"); - lDa.Fill(tmpDS, "land"); - lalDa.Fill(tmpDS, "landaccesslist"); - - foreach (DataColumn col in createPrimTable().Columns) - { - if (!tmpDS.Tables["prims"].Columns.Contains(col.ColumnName)) - { - MainLog.Instance.Verbose("DATASTORE", "Missing required column:" + col.ColumnName); - return false; - } - } - foreach (DataColumn col in createShapeTable().Columns) - { - if (!tmpDS.Tables["primshapes"].Columns.Contains(col.ColumnName)) - { - MainLog.Instance.Verbose("DATASTORE", "Missing required column:" + col.ColumnName); - return false; - } - } - foreach (DataColumn col in createTerrainTable().Columns) - { - if (!tmpDS.Tables["terrain"].Columns.Contains(col.ColumnName)) - { - MainLog.Instance.Verbose("DATASTORE", "Missing require column:" + col.ColumnName); - return false; - } - } - foreach (DataColumn col in createLandTable().Columns) - { - if (!tmpDS.Tables["land"].Columns.Contains(col.ColumnName)) - { - MainLog.Instance.Verbose("DATASTORE", "Missing require column:" + col.ColumnName); - return false; - } - } - foreach (DataColumn col in createLandAccessListTable().Columns) - { - if (!tmpDS.Tables["landaccesslist"].Columns.Contains(col.ColumnName)) - { - MainLog.Instance.Verbose("DATASTORE", "Missing require column:" + col.ColumnName); - return false; - } - } - return true; - } - - /*********************************************************************** - * - * Type conversion functions - * - **********************************************************************/ - - private DbType dbtypeFromType(Type type) - { - if (type == typeof (String)) - { - return DbType.String; - } - else if (type == typeof (Int32)) - { - return DbType.Int32; - } - else if (type == typeof (Double)) - { - return DbType.Double; - } - else if (type == typeof (Byte)) - { - return DbType.Byte; - } - else if (type == typeof (Double)) - { - return DbType.Double; - } - else if (type == typeof (Byte[])) - { - return DbType.Binary; - } - else - { - return DbType.String; - } - } - - // this is something we'll need to implement for each db - // slightly differently. - private string MySqlType(Type type) - { - if (type == typeof (String)) - { - return "varchar(255)"; - } - else if (type == typeof (Int32)) - { - return "integer"; - } - else if (type == typeof (Double)) - { - return "float"; - } - else if (type == typeof (Byte[])) - { - return "longblob"; - } - else - { - return "string"; - } - } - } -} \ No newline at end of file +/* +* 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.Generic; +using System.Data; +using System.Diagnostics; +using System.IO; +using libsecondlife; +using MySql.Data.MySqlClient; +using OpenSim.Framework.Console; +using OpenSim.Region.Environment.Interfaces; +using OpenSim.Region.Environment.LandManagement; +using OpenSim.Region.Environment.Scenes; + +namespace OpenSim.Framework.Data.MySQL +{ + public class MySQLDataStore : IRegionDataStore + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private const string m_primSelect = "select * from prims"; + private const string m_shapeSelect = "select * from primshapes"; + private const string m_itemsSelect = "select * from primitems"; + private const string m_terrainSelect = "select * from terrain limit 1"; + private const string m_landSelect = "select * from land"; + private const string m_landAccessListSelect = "select * from landaccesslist"; + + private DataSet m_dataSet; + private MySqlDataAdapter m_primDataAdapter; + private MySqlDataAdapter m_shapeDataAdapter; + private MySqlDataAdapter m_itemsDataAdapter; + private MySqlConnection m_connection; + private MySqlDataAdapter m_terrainDataAdapter; + private MySqlDataAdapter m_landDataAdapter; + private MySqlDataAdapter m_landAccessListDataAdapter; + + private DataTable m_primTable; + private DataTable m_shapeTable; + private DataTable m_itemsTable; + private DataTable m_terrainTable; + private DataTable m_landTable; + private DataTable m_landAccessListTable; + + // Temporary attribute while this is experimental + private bool persistPrimInventories; + + /*********************************************************************** + * + * Public Interface Functions + * + **********************************************************************/ + + // see IRegionDataStore + public void Initialise(string connectionstring, bool persistPrimInventories) + { + m_dataSet = new DataSet(); + this.persistPrimInventories = persistPrimInventories; + + m_log.Info("[DATASTORE]: MySql - connecting: " + connectionstring); + m_connection = new MySqlConnection(connectionstring); + + MySqlCommand primSelectCmd = new MySqlCommand(m_primSelect, m_connection); + m_primDataAdapter = new MySqlDataAdapter(primSelectCmd); + + MySqlCommand shapeSelectCmd = new MySqlCommand(m_shapeSelect, m_connection); + m_shapeDataAdapter = new MySqlDataAdapter(shapeSelectCmd); + + MySqlCommand itemsSelectCmd = new MySqlCommand(m_itemsSelect, m_connection); + m_itemsDataAdapter = new MySqlDataAdapter(itemsSelectCmd); + + MySqlCommand terrainSelectCmd = new MySqlCommand(m_terrainSelect, m_connection); + m_terrainDataAdapter = new MySqlDataAdapter(terrainSelectCmd); + + MySqlCommand landSelectCmd = new MySqlCommand(m_landSelect, m_connection); + m_landDataAdapter = new MySqlDataAdapter(landSelectCmd); + + MySqlCommand landAccessListSelectCmd = new MySqlCommand(m_landAccessListSelect, m_connection); + m_landAccessListDataAdapter = new MySqlDataAdapter(landAccessListSelectCmd); + + TestTables(m_connection); + + lock (m_dataSet) + { + m_primTable = createPrimTable(); + m_dataSet.Tables.Add(m_primTable); + SetupPrimCommands(m_primDataAdapter, m_connection); + m_primDataAdapter.Fill(m_primTable); + + m_shapeTable = createShapeTable(); + m_dataSet.Tables.Add(m_shapeTable); + SetupShapeCommands(m_shapeDataAdapter, m_connection); + m_shapeDataAdapter.Fill(m_shapeTable); + + if (persistPrimInventories) + { + m_itemsTable = createItemsTable(); + m_dataSet.Tables.Add(m_itemsTable); + SetupItemsCommands(m_itemsDataAdapter, m_connection); + m_itemsDataAdapter.Fill(m_itemsTable); + } + + m_terrainTable = createTerrainTable(); + m_dataSet.Tables.Add(m_terrainTable); + SetupTerrainCommands(m_terrainDataAdapter, m_connection); + m_terrainDataAdapter.Fill(m_terrainTable); + + m_landTable = createLandTable(); + m_dataSet.Tables.Add(m_landTable); + setupLandCommands(m_landDataAdapter, m_connection); + m_landDataAdapter.Fill(m_landTable); + + m_landAccessListTable = createLandAccessListTable(); + m_dataSet.Tables.Add(m_landAccessListTable); + setupLandAccessCommands(m_landAccessListDataAdapter, m_connection); + m_landAccessListDataAdapter.Fill(m_landAccessListTable); + } + } + + public void StoreObject(SceneObjectGroup obj, LLUUID regionUUID) + { + lock (m_dataSet) + { + foreach (SceneObjectPart prim in obj.Children.Values) + { + if ((prim.ObjectFlags & (uint) LLObject.ObjectFlags.Physics) == 0) + { + m_log.Info("[DATASTORE]: Adding obj: " + obj.UUID + " to region: " + regionUUID); + addPrim(prim, obj.UUID, regionUUID); + } + else + { + // m_log.Info("[DATASTORE]: Ignoring Physical obj: " + obj.UUID + " in region: " + regionUUID); + } + } + } + + Commit(); + } + + public void RemoveObject(LLUUID obj, LLUUID regionUUID) + { + m_log.InfoFormat("[DATASTORE]: Removing obj: {0} from region: {1}", obj.UUID, regionUUID); + + DataTable prims = m_primTable; + DataTable shapes = m_shapeTable; + + string selectExp = "SceneGroupID = '" + Util.ToRawUuidString(obj) + "'"; + lock (m_dataSet) + { + DataRow[] primRows = prims.Select(selectExp); + foreach (DataRow row in primRows) + { + // Remove shapes row + LLUUID uuid = new LLUUID((string) row["UUID"]); + DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(uuid)); + if (shapeRow != null) + { + shapeRow.Delete(); + } + + if (persistPrimInventories) + { + RemoveItems(uuid); + } + + // Remove prim row + row.Delete(); + } + } + + Commit(); + } + + /// + /// Remove all persisted items of the given prim. + /// The caller must acquire the necessrary synchronization locks and commit or rollback changes. + /// + private void RemoveItems(LLUUID uuid) + { + String sql = String.Format("primID = '{0}'", uuid); + DataRow[] itemRows = m_itemsTable.Select(sql); + + foreach (DataRow itemRow in itemRows) + { + itemRow.Delete(); + } + } + + /// + /// Load persisted objects from region storage. + /// + public List LoadObjects(LLUUID regionUUID) + { + Dictionary createdObjects = new Dictionary(); + + List retvals = new List(); + + DataTable prims = m_primTable; + DataTable shapes = m_shapeTable; + + string byRegion = "RegionUUID = '" + Util.ToRawUuidString(regionUUID) + "'"; + string orderByParent = "ParentID ASC"; + + lock (m_dataSet) + { + DataRow[] primsForRegion = prims.Select(byRegion, orderByParent); + m_log.Info("[DATASTORE]: " + + "Loaded " + primsForRegion.Length + " prims for region: " + regionUUID); + + foreach (DataRow primRow in primsForRegion) + { + try + { + string uuid = (string) primRow["UUID"]; + string objID = (string) primRow["SceneGroupID"]; + + SceneObjectPart prim = buildPrim(primRow); + + if (uuid == objID) //is new SceneObjectGroup ? + { + SceneObjectGroup group = new SceneObjectGroup(); + + DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(prim.UUID)); + if (shapeRow != null) + { + prim.Shape = buildShape(shapeRow); + } + else + { + m_log.Info( + "No shape found for prim in storage, so setting default box shape"); + prim.Shape = PrimitiveBaseShape.Default; + } + group.AddPart(prim); + group.RootPart = prim; + + createdObjects.Add(group.UUID, group); + retvals.Add(group); + } + else + { + DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(prim.UUID)); + if (shapeRow != null) + { + prim.Shape = buildShape(shapeRow); + } + else + { + m_log.Info( + "No shape found for prim in storage, so setting default box shape"); + prim.Shape = PrimitiveBaseShape.Default; + } + createdObjects[new LLUUID(objID)].AddPart(prim); + } + + if (persistPrimInventories) + { + LoadItems(prim); + } + } + catch (Exception e) + { + m_log.Error("[DATASTORE]: Failed create prim object, exception and data follows"); + m_log.Info("[DATASTORE]: " + e.ToString()); + foreach (DataColumn col in prims.Columns) + { + m_log.Info("[DATASTORE]: Col: " + col.ColumnName + " => " + primRow[col]); + } + } + } + } + return retvals; + } + + /// + /// Load in a prim's persisted inventory. + /// + /// + private void LoadItems(SceneObjectPart prim) + { + //m_log.InfoFormat("[DATASTORE]: Loading inventory for {0}, {1}", prim.Name, prim.UUID); + + DataTable dbItems = m_itemsTable; + + String sql = String.Format("primID = '{0}'", prim.UUID.ToString()); + DataRow[] dbItemRows = dbItems.Select(sql); + + IList inventory = new List(); + + foreach (DataRow row in dbItemRows) + { + TaskInventoryItem item = buildItem(row); + inventory.Add(item); + + //m_log.DebugFormat("[DATASTORE]: Restored item {0}, {1}", item.Name, item.ItemID); + } + + prim.RestoreInventoryItems(inventory); + + // XXX A nasty little hack to recover the folder id for the prim (which is currently stored in + // every item). This data should really be stored in the prim table itself. + if (dbItemRows.Length > 0) + { + prim.FolderID = inventory[0].ParentID; + } + } + + public void StoreTerrain(double[,] ter, LLUUID regionID) + { + int revision = Util.UnixTimeSinceEpoch(); + m_log.Info("[DATASTORE]: Storing terrain revision r" + revision.ToString()); + + DataTable terrain = m_dataSet.Tables["terrain"]; + lock (m_dataSet) + { + MySqlCommand cmd = new MySqlCommand("insert into terrain(RegionUUID, Revision, Heightfield)" + + " values(?RegionUUID, ?Revision, ?Heightfield)", m_connection); + using (cmd) + { + cmd.Parameters.Add(new MySqlParameter("?RegionUUID", Util.ToRawUuidString(regionID))); + cmd.Parameters.Add(new MySqlParameter("?Revision", revision)); + cmd.Parameters.Add(new MySqlParameter("?Heightfield", serializeTerrain(ter))); + cmd.ExecuteNonQuery(); + } + } + } + + public double[,] LoadTerrain(LLUUID regionID) + { + double[,] terret = new double[256,256]; + terret.Initialize(); + + MySqlCommand cmd = new MySqlCommand( + @"select RegionUUID, Revision, Heightfield from terrain + where RegionUUID=?RegionUUID order by Revision desc limit 1" + , m_connection); + + MySqlParameter param = new MySqlParameter(); + cmd.Parameters.Add(new MySqlParameter("?RegionUUID", Util.ToRawUuidString(regionID))); + + if (m_connection.State != ConnectionState.Open) + { + m_connection.Open(); + } + + using (MySqlDataReader row = cmd.ExecuteReader()) + { + int rev = 0; + if (row.Read()) + { + MemoryStream str = new MemoryStream((byte[]) row["Heightfield"]); + BinaryReader br = new BinaryReader(str); + for (int x = 0; x < 256; x++) + { + for (int y = 0; y < 256; y++) + { + terret[x, y] = br.ReadDouble(); + } + } + rev = (int) row["Revision"]; + } + else + { + m_log.Info("[DATASTORE]: No terrain found for region"); + return null; + } + + m_log.Info("[DATASTORE]: Loaded terrain revision r" + rev.ToString()); + } + + return terret; + } + + public void RemoveLandObject(LLUUID globalID) + { + lock (m_dataSet) + { + using (MySqlCommand cmd = new MySqlCommand("delete from land where UUID=?UUID", m_connection)) + { + cmd.Parameters.Add(new MySqlParameter("?UUID", Util.ToRawUuidString(globalID))); + cmd.ExecuteNonQuery(); + } + + using ( + MySqlCommand cmd = new MySqlCommand("delete from landaccesslist where LandUUID=?UUID", m_connection) + ) + { + cmd.Parameters.Add(new MySqlParameter("?UUID", Util.ToRawUuidString(globalID))); + cmd.ExecuteNonQuery(); + } + } + } + + static Random rnd = new Random(); + public void StoreLandObject(Land parcel, LLUUID regionUUID) + { + // Does the new locking fix it? + m_log.Info("[DATASTORE]: Tedds temp fix: Waiting 3 seconds to avoid others writing to table while we hold a dataset of it. (Someone please fix! :))"); + System.Threading.Thread.Sleep(2500 + rnd.Next(0, 1000)); + + lock (m_dataSet) + { + DataTable land = m_landTable; + DataTable landaccesslist = m_landAccessListTable; + + DataRow landRow = land.Rows.Find(Util.ToRawUuidString(parcel.landData.globalID)); + if (landRow == null) + { + landRow = land.NewRow(); + fillLandRow(landRow, parcel.landData, regionUUID); + land.Rows.Add(landRow); + } + else + { + fillLandRow(landRow, parcel.landData, regionUUID); + } + + using ( + MySqlCommand cmd = + new MySqlCommand("delete from landaccesslist where LandUUID=?LandUUID", m_connection)) + { + cmd.Parameters.Add(new MySqlParameter("?LandUUID", Util.ToRawUuidString(parcel.landData.globalID))); + cmd.ExecuteNonQuery(); + } + + foreach (ParcelManager.ParcelAccessEntry entry in parcel.landData.parcelAccessList) + { + DataRow newAccessRow = landaccesslist.NewRow(); + fillLandAccessRow(newAccessRow, entry, parcel.landData.globalID); + landaccesslist.Rows.Add(newAccessRow); + } + + } + Commit(); + } + + public List LoadLandObjects(LLUUID regionUUID) + { + List landDataForRegion = new List(); + lock (m_dataSet) + { + DataTable land = m_landTable; + DataTable landaccesslist = m_landAccessListTable; + string searchExp = "RegionUUID = '" + Util.ToRawUuidString(regionUUID) + "'"; + DataRow[] rawDataForRegion = land.Select(searchExp); + foreach (DataRow rawDataLand in rawDataForRegion) + { + LandData newLand = buildLandData(rawDataLand); + string accessListSearchExp = "LandUUID = '" + Util.ToRawUuidString(newLand.globalID) + "'"; + DataRow[] rawDataForLandAccessList = landaccesslist.Select(accessListSearchExp); + foreach (DataRow rawDataLandAccess in rawDataForLandAccessList) + { + newLand.parcelAccessList.Add(buildLandAccessData(rawDataLandAccess)); + } + + landDataForRegion.Add(newLand); + } + } + return landDataForRegion; + } + + private void DisplayDataSet(DataSet ds, string title) + { + Debug.WriteLine(title); + //--- Loop through the DataTables + foreach (DataTable table in ds.Tables) + { + Debug.WriteLine("*** DataTable: " + table.TableName + "***"); + //--- Loop through each DataTable's DataRows + foreach (DataRow row in table.Rows) + { + //--- Display the original values, if there are any. + if (row.HasVersion(DataRowVersion.Original)) + { + Debug.Write("Original Row Values ===> "); + foreach (DataColumn column in table.Columns) + Debug.Write(column.ColumnName + " = " + + row[column, DataRowVersion.Original] + ", "); + Debug.WriteLine(String.Empty); + } + //--- Display the current values, if there are any. + if (row.HasVersion(DataRowVersion.Current)) + { + Debug.Write("Current Row Values ====> "); + foreach (DataColumn column in table.Columns) + Debug.Write(column.ColumnName + " = " + + row[column, DataRowVersion.Current] + ", "); + Debug.WriteLine(String.Empty); + } + Debug.WriteLine(String.Empty); + } + } + } + + public void Commit() + { + if (m_connection.State != ConnectionState.Open) + { + m_connection.Open(); + } + + lock (m_dataSet) + { + // DisplayDataSet(m_dataSet, "Region DataSet"); + + m_primDataAdapter.Update(m_primTable); + m_shapeDataAdapter.Update(m_shapeTable); + + if (persistPrimInventories) + { + m_itemsDataAdapter.Update(m_itemsTable); + } + + m_terrainDataAdapter.Update(m_terrainTable); + m_landDataAdapter.Update(m_landTable); + m_landAccessListDataAdapter.Update(m_landAccessListTable); + + m_dataSet.AcceptChanges(); + } + } + + + public void Shutdown() + { + Commit(); + } + + /*********************************************************************** + * + * Database Definition Functions + * + * This should be db agnostic as we define them in ADO.NET terms + * + **********************************************************************/ + + private DataColumn createCol(DataTable dt, string name, Type type) + { + DataColumn col = new DataColumn(name, type); + dt.Columns.Add(col); + return col; + } + + private DataTable createTerrainTable() + { + DataTable terrain = new DataTable("terrain"); + + createCol(terrain, "RegionUUID", typeof (String)); + createCol(terrain, "Revision", typeof (Int32)); + DataColumn heightField = createCol(terrain, "Heightfield", typeof (Byte[])); + return terrain; + } + + private DataTable createPrimTable() + { + DataTable prims = new DataTable("prims"); + + createCol(prims, "UUID", typeof (String)); + createCol(prims, "RegionUUID", typeof (String)); + createCol(prims, "ParentID", typeof (Int32)); + createCol(prims, "CreationDate", typeof (Int32)); + createCol(prims, "Name", typeof (String)); + createCol(prims, "SceneGroupID", typeof (String)); + // various text fields + createCol(prims, "Text", typeof (String)); + createCol(prims, "Description", typeof (String)); + createCol(prims, "SitName", typeof (String)); + createCol(prims, "TouchName", typeof (String)); + // permissions + createCol(prims, "ObjectFlags", typeof (Int32)); + createCol(prims, "CreatorID", typeof (String)); + createCol(prims, "OwnerID", typeof (String)); + createCol(prims, "GroupID", typeof (String)); + createCol(prims, "LastOwnerID", typeof (String)); + createCol(prims, "OwnerMask", typeof (Int32)); + createCol(prims, "NextOwnerMask", typeof (Int32)); + createCol(prims, "GroupMask", typeof (Int32)); + createCol(prims, "EveryoneMask", typeof (Int32)); + createCol(prims, "BaseMask", typeof (Int32)); + // vectors + createCol(prims, "PositionX", typeof (Double)); + createCol(prims, "PositionY", typeof (Double)); + createCol(prims, "PositionZ", typeof (Double)); + createCol(prims, "GroupPositionX", typeof (Double)); + createCol(prims, "GroupPositionY", typeof (Double)); + createCol(prims, "GroupPositionZ", typeof (Double)); + createCol(prims, "VelocityX", typeof (Double)); + createCol(prims, "VelocityY", typeof (Double)); + createCol(prims, "VelocityZ", typeof (Double)); + createCol(prims, "AngularVelocityX", typeof (Double)); + createCol(prims, "AngularVelocityY", typeof (Double)); + createCol(prims, "AngularVelocityZ", typeof (Double)); + createCol(prims, "AccelerationX", typeof (Double)); + createCol(prims, "AccelerationY", typeof (Double)); + createCol(prims, "AccelerationZ", typeof (Double)); + // quaternions + createCol(prims, "RotationX", typeof (Double)); + createCol(prims, "RotationY", typeof (Double)); + createCol(prims, "RotationZ", typeof (Double)); + createCol(prims, "RotationW", typeof (Double)); + // sit target + createCol(prims, "SitTargetOffsetX", typeof (Double)); + createCol(prims, "SitTargetOffsetY", typeof (Double)); + createCol(prims, "SitTargetOffsetZ", typeof (Double)); + + createCol(prims, "SitTargetOrientW", typeof (Double)); + createCol(prims, "SitTargetOrientX", typeof (Double)); + createCol(prims, "SitTargetOrientY", typeof (Double)); + createCol(prims, "SitTargetOrientZ", typeof (Double)); + + + // Add in contraints + prims.PrimaryKey = new DataColumn[] {prims.Columns["UUID"]}; + + return prims; + } + + private DataTable createLandTable() + { + DataTable land = new DataTable("land"); + createCol(land, "UUID", typeof (String)); + createCol(land, "RegionUUID", typeof (String)); + createCol(land, "LocalLandID", typeof (Int32)); + + // Bitmap is a byte[512] + createCol(land, "Bitmap", typeof (Byte[])); + + createCol(land, "Name", typeof (String)); + createCol(land, "Description", typeof (String)); + createCol(land, "OwnerUUID", typeof (String)); + createCol(land, "IsGroupOwned", typeof (Int32)); + createCol(land, "Area", typeof (Int32)); + createCol(land, "AuctionID", typeof (Int32)); //Unemplemented + createCol(land, "Category", typeof (Int32)); //Enum libsecondlife.Parcel.ParcelCategory + createCol(land, "ClaimDate", typeof (Int32)); + createCol(land, "ClaimPrice", typeof (Int32)); + createCol(land, "GroupUUID", typeof (String)); + createCol(land, "SalePrice", typeof (Int32)); + createCol(land, "LandStatus", typeof (Int32)); //Enum. libsecondlife.Parcel.ParcelStatus + createCol(land, "LandFlags", typeof (Int32)); + createCol(land, "LandingType", typeof (Int32)); + createCol(land, "MediaAutoScale", typeof (Int32)); + createCol(land, "MediaTextureUUID", typeof (String)); + createCol(land, "MediaURL", typeof (String)); + createCol(land, "MusicURL", typeof (String)); + createCol(land, "PassHours", typeof (Double)); + createCol(land, "PassPrice", typeof (Int32)); + createCol(land, "SnapshotUUID", typeof (String)); + createCol(land, "UserLocationX", typeof (Double)); + createCol(land, "UserLocationY", typeof (Double)); + createCol(land, "UserLocationZ", typeof (Double)); + createCol(land, "UserLookAtX", typeof (Double)); + createCol(land, "UserLookAtY", typeof (Double)); + createCol(land, "UserLookAtZ", typeof (Double)); + + land.PrimaryKey = new DataColumn[] {land.Columns["UUID"]}; + + return land; + } + + private DataTable createLandAccessListTable() + { + DataTable landaccess = new DataTable("landaccesslist"); + createCol(landaccess, "LandUUID", typeof (String)); + createCol(landaccess, "AccessUUID", typeof (String)); + createCol(landaccess, "Flags", typeof (Int32)); + + return landaccess; + } + + private DataTable createShapeTable() + { + DataTable shapes = new DataTable("primshapes"); + createCol(shapes, "UUID", typeof (String)); + // shape is an enum + createCol(shapes, "Shape", typeof (Int32)); + // vectors + createCol(shapes, "ScaleX", typeof (Double)); + createCol(shapes, "ScaleY", typeof (Double)); + createCol(shapes, "ScaleZ", typeof (Double)); + // paths + createCol(shapes, "PCode", typeof (Int32)); + createCol(shapes, "PathBegin", typeof (Int32)); + createCol(shapes, "PathEnd", typeof (Int32)); + createCol(shapes, "PathScaleX", typeof (Int32)); + createCol(shapes, "PathScaleY", typeof (Int32)); + createCol(shapes, "PathShearX", typeof (Int32)); + createCol(shapes, "PathShearY", typeof (Int32)); + createCol(shapes, "PathSkew", typeof (Int32)); + createCol(shapes, "PathCurve", typeof (Int32)); + createCol(shapes, "PathRadiusOffset", typeof (Int32)); + createCol(shapes, "PathRevolutions", typeof (Int32)); + createCol(shapes, "PathTaperX", typeof (Int32)); + createCol(shapes, "PathTaperY", typeof (Int32)); + createCol(shapes, "PathTwist", typeof (Int32)); + createCol(shapes, "PathTwistBegin", typeof (Int32)); + // profile + createCol(shapes, "ProfileBegin", typeof (Int32)); + createCol(shapes, "ProfileEnd", typeof (Int32)); + createCol(shapes, "ProfileCurve", typeof (Int32)); + createCol(shapes, "ProfileHollow", typeof (Int32)); + createCol(shapes, "Texture", typeof (Byte[])); + createCol(shapes, "ExtraParams", typeof (Byte[])); + + shapes.PrimaryKey = new DataColumn[] {shapes.Columns["UUID"]}; + + return shapes; + } + + private DataTable createItemsTable() + { + DataTable items = new DataTable("primitems"); + + createCol(items, "itemID", typeof (String)); + createCol(items, "primID", typeof (String)); + createCol(items, "assetID", typeof (String)); + createCol(items, "parentFolderID", typeof (String)); + + createCol(items, "invType", typeof (Int32)); + createCol(items, "assetType", typeof (Int32)); + + createCol(items, "name", typeof (String)); + createCol(items, "description", typeof (String)); + + createCol(items, "creationDate", typeof (Int64)); + createCol(items, "creatorID", typeof (String)); + createCol(items, "ownerID", typeof (String)); + createCol(items, "lastOwnerID", typeof (String)); + createCol(items, "groupID", typeof (String)); + + createCol(items, "nextPermissions", typeof (Int32)); + createCol(items, "currentPermissions", typeof (Int32)); + createCol(items, "basePermissions", typeof (Int32)); + createCol(items, "everyonePermissions", typeof (Int32)); + createCol(items, "groupPermissions", typeof (Int32)); + + items.PrimaryKey = new DataColumn[] {items.Columns["itemID"]}; + + return items; + } + + /*********************************************************************** + * + * Convert between ADO.NET <=> OpenSim Objects + * + * These should be database independant + * + **********************************************************************/ + + private SceneObjectPart buildPrim(DataRow row) + { + SceneObjectPart prim = new SceneObjectPart(); + prim.UUID = new LLUUID((String) row["UUID"]); + // explicit conversion of integers is required, which sort + // of sucks. No idea if there is a shortcut here or not. + prim.ParentID = Convert.ToUInt32(row["ParentID"]); + prim.CreationDate = Convert.ToInt32(row["CreationDate"]); + prim.Name = (String) row["Name"]; + // various text fields + prim.Text = (String) row["Text"]; + prim.Description = (String) row["Description"]; + prim.SitName = (String) row["SitName"]; + prim.TouchName = (String) row["TouchName"]; + // permissions + prim.ObjectFlags = Convert.ToUInt32(row["ObjectFlags"]); + prim.CreatorID = new LLUUID((String) row["CreatorID"]); + prim.OwnerID = new LLUUID((String) row["OwnerID"]); + prim.GroupID = new LLUUID((String) row["GroupID"]); + prim.LastOwnerID = new LLUUID((String) row["LastOwnerID"]); + prim.OwnerMask = Convert.ToUInt32(row["OwnerMask"]); + prim.NextOwnerMask = Convert.ToUInt32(row["NextOwnerMask"]); + prim.GroupMask = Convert.ToUInt32(row["GroupMask"]); + prim.EveryoneMask = Convert.ToUInt32(row["EveryoneMask"]); + prim.BaseMask = Convert.ToUInt32(row["BaseMask"]); + // vectors + prim.OffsetPosition = new LLVector3( + Convert.ToSingle(row["PositionX"]), + Convert.ToSingle(row["PositionY"]), + Convert.ToSingle(row["PositionZ"]) + ); + prim.GroupPosition = new LLVector3( + Convert.ToSingle(row["GroupPositionX"]), + Convert.ToSingle(row["GroupPositionY"]), + Convert.ToSingle(row["GroupPositionZ"]) + ); + prim.Velocity = new LLVector3( + Convert.ToSingle(row["VelocityX"]), + Convert.ToSingle(row["VelocityY"]), + Convert.ToSingle(row["VelocityZ"]) + ); + prim.AngularVelocity = new LLVector3( + Convert.ToSingle(row["AngularVelocityX"]), + Convert.ToSingle(row["AngularVelocityY"]), + Convert.ToSingle(row["AngularVelocityZ"]) + ); + prim.Acceleration = new LLVector3( + Convert.ToSingle(row["AccelerationX"]), + Convert.ToSingle(row["AccelerationY"]), + Convert.ToSingle(row["AccelerationZ"]) + ); + // quaternions + prim.RotationOffset = new LLQuaternion( + Convert.ToSingle(row["RotationX"]), + Convert.ToSingle(row["RotationY"]), + Convert.ToSingle(row["RotationZ"]), + Convert.ToSingle(row["RotationW"]) + ); + try + { + prim.SetSitTargetLL(new LLVector3( + Convert.ToSingle(row["SitTargetOffsetX"]), + Convert.ToSingle(row["SitTargetOffsetY"]), + Convert.ToSingle(row["SitTargetOffsetZ"])), new LLQuaternion( + Convert.ToSingle( + row["SitTargetOrientX"]), + Convert.ToSingle( + row["SitTargetOrientY"]), + Convert.ToSingle( + row["SitTargetOrientZ"]), + Convert.ToSingle( + row["SitTargetOrientW"]))); + } + catch (InvalidCastException) + { + // Database table was created before we got here and needs to be created! :P + + using ( + MySqlCommand cmd = + new MySqlCommand( + "ALTER TABLE `prims` ADD COLUMN `SitTargetOffsetX` float NOT NULL default 0, ADD COLUMN `SitTargetOffsetY` float NOT NULL default 0, ADD COLUMN `SitTargetOffsetZ` float NOT NULL default 0, ADD COLUMN `SitTargetOrientW` float NOT NULL default 0, ADD COLUMN `SitTargetOrientX` float NOT NULL default 0, ADD COLUMN `SitTargetOrientY` float NOT NULL default 0, ADD COLUMN `SitTargetOrientZ` float NOT NULL default 0;", + m_connection)) + { + cmd.ExecuteNonQuery(); + } + } + return prim; + } + + + /// + /// Build a prim inventory item from the persisted data. + /// + /// + /// + private TaskInventoryItem buildItem(DataRow row) + { + TaskInventoryItem taskItem = new TaskInventoryItem(); + + taskItem.ItemID = new LLUUID((String)row["itemID"]); + taskItem.ParentPartID = new LLUUID((String)row["primID"]); + taskItem.AssetID = new LLUUID((String)row["assetID"]); + taskItem.ParentID = new LLUUID((String)row["parentFolderID"]); + + taskItem.InvType = Convert.ToInt32(row["invType"]); + taskItem.Type = Convert.ToInt32(row["assetType"]); + + taskItem.Name = (String)row["name"]; + taskItem.Description = (String)row["description"]; + taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]); + taskItem.CreatorID = new LLUUID((String)row["creatorID"]); + taskItem.OwnerID = new LLUUID((String)row["ownerID"]); + taskItem.LastOwnerID = new LLUUID((String)row["lastOwnerID"]); + taskItem.GroupID = new LLUUID((String)row["groupID"]); + + taskItem.NextOwnerMask = Convert.ToUInt32(row["nextPermissions"]); + taskItem.OwnerMask = Convert.ToUInt32(row["currentPermissions"]); + taskItem.BaseMask = Convert.ToUInt32(row["basePermissions"]); + taskItem.EveryoneMask = Convert.ToUInt32(row["everyonePermissions"]); + taskItem.GroupMask = Convert.ToUInt32(row["groupPermissions"]); + + return taskItem; + } + + private LandData buildLandData(DataRow row) + { + LandData newData = new LandData(); + + newData.globalID = new LLUUID((String) row["UUID"]); + newData.localID = Convert.ToInt32(row["LocalLandID"]); + + // Bitmap is a byte[512] + newData.landBitmapByteArray = (Byte[]) row["Bitmap"]; + + newData.landName = (String) row["Name"]; + newData.landDesc = (String) row["Description"]; + newData.ownerID = (String) row["OwnerUUID"]; + newData.isGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]); + newData.area = Convert.ToInt32(row["Area"]); + newData.auctionID = Convert.ToUInt32(row["AuctionID"]); //Unemplemented + newData.category = (Parcel.ParcelCategory) Convert.ToInt32(row["Category"]); + //Enum libsecondlife.Parcel.ParcelCategory + newData.claimDate = Convert.ToInt32(row["ClaimDate"]); + newData.claimPrice = Convert.ToInt32(row["ClaimPrice"]); + newData.groupID = new LLUUID((String) row["GroupUUID"]); + newData.salePrice = Convert.ToInt32(row["SalePrice"]); + newData.landStatus = (Parcel.ParcelStatus) Convert.ToInt32(row["LandStatus"]); + //Enum. libsecondlife.Parcel.ParcelStatus + newData.landFlags = Convert.ToUInt32(row["LandFlags"]); + newData.landingType = Convert.ToByte(row["LandingType"]); + newData.mediaAutoScale = Convert.ToByte(row["MediaAutoScale"]); + newData.mediaID = new LLUUID((String) row["MediaTextureUUID"]); + newData.mediaURL = (String) row["MediaURL"]; + newData.musicURL = (String) row["MusicURL"]; + newData.passHours = Convert.ToSingle(row["PassHours"]); + newData.passPrice = Convert.ToInt32(row["PassPrice"]); + newData.snapshotID = (String) row["SnapshotUUID"]; + + newData.userLocation = + new LLVector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]), + Convert.ToSingle(row["UserLocationZ"])); + newData.userLookAt = + new LLVector3(Convert.ToSingle(row["UserLookAtX"]), Convert.ToSingle(row["UserLookAtY"]), + Convert.ToSingle(row["UserLookAtZ"])); + newData.parcelAccessList = new List(); + + return newData; + } + + private ParcelManager.ParcelAccessEntry buildLandAccessData(DataRow row) + { + ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); + entry.AgentID = new LLUUID((string) row["AccessUUID"]); + entry.Flags = (ParcelManager.AccessList) Convert.ToInt32(row["Flags"]); + entry.Time = new DateTime(); + return entry; + } + + private Array serializeTerrain(double[,] val) + { + MemoryStream str = new MemoryStream(65536*sizeof (double)); + BinaryWriter bw = new BinaryWriter(str); + + // TODO: COMPATIBILITY - Add byte-order conversions + for (int x = 0; x < 256; x++) + for (int y = 0; y < 256; y++) + bw.Write(val[x, y]); + + return str.ToArray(); + } + + private void fillPrimRow(DataRow row, SceneObjectPart prim, LLUUID sceneGroupID, LLUUID regionUUID) + { + row["UUID"] = Util.ToRawUuidString(prim.UUID); + row["RegionUUID"] = Util.ToRawUuidString(regionUUID); + row["ParentID"] = prim.ParentID; + row["CreationDate"] = prim.CreationDate; + row["Name"] = prim.Name; + row["SceneGroupID"] = Util.ToRawUuidString(sceneGroupID); + // the UUID of the root part for this SceneObjectGroup + // various text fields + row["Text"] = prim.Text; + row["Description"] = prim.Description; + row["SitName"] = prim.SitName; + row["TouchName"] = prim.TouchName; + // permissions + row["ObjectFlags"] = prim.ObjectFlags; + row["CreatorID"] = Util.ToRawUuidString(prim.CreatorID); + row["OwnerID"] = Util.ToRawUuidString(prim.OwnerID); + row["GroupID"] = Util.ToRawUuidString(prim.GroupID); + row["LastOwnerID"] = Util.ToRawUuidString(prim.LastOwnerID); + row["OwnerMask"] = prim.OwnerMask; + row["NextOwnerMask"] = prim.NextOwnerMask; + row["GroupMask"] = prim.GroupMask; + row["EveryoneMask"] = prim.EveryoneMask; + row["BaseMask"] = prim.BaseMask; + // vectors + row["PositionX"] = prim.OffsetPosition.X; + row["PositionY"] = prim.OffsetPosition.Y; + row["PositionZ"] = prim.OffsetPosition.Z; + row["GroupPositionX"] = prim.GroupPosition.X; + row["GroupPositionY"] = prim.GroupPosition.Y; + row["GroupPositionZ"] = prim.GroupPosition.Z; + row["VelocityX"] = prim.Velocity.X; + row["VelocityY"] = prim.Velocity.Y; + row["VelocityZ"] = prim.Velocity.Z; + row["AngularVelocityX"] = prim.AngularVelocity.X; + row["AngularVelocityY"] = prim.AngularVelocity.Y; + row["AngularVelocityZ"] = prim.AngularVelocity.Z; + row["AccelerationX"] = prim.Acceleration.X; + row["AccelerationY"] = prim.Acceleration.Y; + row["AccelerationZ"] = prim.Acceleration.Z; + // quaternions + row["RotationX"] = prim.RotationOffset.X; + row["RotationY"] = prim.RotationOffset.Y; + row["RotationZ"] = prim.RotationOffset.Z; + row["RotationW"] = prim.RotationOffset.W; + + try + { + // Sit target + LLVector3 sitTargetPos = prim.GetSitTargetPositionLL(); + row["SitTargetOffsetX"] = sitTargetPos.X; + row["SitTargetOffsetY"] = sitTargetPos.Y; + row["SitTargetOffsetZ"] = sitTargetPos.Z; + + LLQuaternion sitTargetOrient = prim.GetSitTargetOrientationLL(); + row["SitTargetOrientW"] = sitTargetOrient.W; + row["SitTargetOrientX"] = sitTargetOrient.X; + row["SitTargetOrientY"] = sitTargetOrient.Y; + row["SitTargetOrientZ"] = sitTargetOrient.Z; + } + catch (MySqlException) + { + // Database table was created before we got here and needs to be created! :P + + using ( + MySqlCommand cmd = + new MySqlCommand( + "ALTER TABLE `prims` ADD COLUMN `SitTargetOffsetX` float NOT NULL default 0, ADD COLUMN `SitTargetOffsetY` float NOT NULL default 0, ADD COLUMN `SitTargetOffsetZ` float NOT NULL default 0, ADD COLUMN `SitTargetOrientW` float NOT NULL default 0, ADD COLUMN `SitTargetOrientX` float NOT NULL default 0, ADD COLUMN `SitTargetOrientY` float NOT NULL default 0, ADD COLUMN `SitTargetOrientZ` float NOT NULL default 0;", + m_connection)) + { + cmd.ExecuteNonQuery(); + } + } + } + + private void fillItemRow(DataRow row, TaskInventoryItem taskItem) + { + row["itemID"] = taskItem.ItemID; + row["primID"] = taskItem.ParentPartID; + row["assetID"] = taskItem.AssetID; + row["parentFolderID"] = taskItem.ParentID; + + row["invType"] = taskItem.InvType; + row["assetType"] = taskItem.Type; + + row["name"] = taskItem.Name; + row["description"] = taskItem.Description; + row["creationDate"] = taskItem.CreationDate; + row["creatorID"] = taskItem.CreatorID; + row["ownerID"] = taskItem.OwnerID; + row["lastOwnerID"] = taskItem.LastOwnerID; + row["groupID"] = taskItem.GroupID; + row["nextPermissions"] = taskItem.NextOwnerMask; + row["currentPermissions"] = taskItem.OwnerMask; + row["basePermissions"] = taskItem.BaseMask; + row["everyonePermissions"] = taskItem.EveryoneMask; + row["groupPermissions"] = taskItem.GroupMask; + } + + private void fillLandRow(DataRow row, LandData land, LLUUID regionUUID) + { + row["UUID"] = Util.ToRawUuidString(land.globalID); + row["RegionUUID"] = Util.ToRawUuidString(regionUUID); + row["LocalLandID"] = land.localID; + + // Bitmap is a byte[512] + row["Bitmap"] = land.landBitmapByteArray; + + row["Name"] = land.landName; + row["Description"] = land.landDesc; + row["OwnerUUID"] = Util.ToRawUuidString(land.ownerID); + row["IsGroupOwned"] = land.isGroupOwned; + row["Area"] = land.area; + row["AuctionID"] = land.auctionID; //Unemplemented + row["Category"] = land.category; //Enum libsecondlife.Parcel.ParcelCategory + row["ClaimDate"] = land.claimDate; + row["ClaimPrice"] = land.claimPrice; + row["GroupUUID"] = Util.ToRawUuidString(land.groupID); + row["SalePrice"] = land.salePrice; + row["LandStatus"] = land.landStatus; //Enum. libsecondlife.Parcel.ParcelStatus + row["LandFlags"] = land.landFlags; + row["LandingType"] = land.landingType; + row["MediaAutoScale"] = land.mediaAutoScale; + row["MediaTextureUUID"] = Util.ToRawUuidString(land.mediaID); + row["MediaURL"] = land.mediaURL; + row["MusicURL"] = land.musicURL; + row["PassHours"] = land.passHours; + row["PassPrice"] = land.passPrice; + row["SnapshotUUID"] = Util.ToRawUuidString(land.snapshotID); + row["UserLocationX"] = land.userLocation.X; + row["UserLocationY"] = land.userLocation.Y; + row["UserLocationZ"] = land.userLocation.Z; + row["UserLookAtX"] = land.userLookAt.X; + row["UserLookAtY"] = land.userLookAt.Y; + row["UserLookAtZ"] = land.userLookAt.Z; + } + + private void fillLandAccessRow(DataRow row, ParcelManager.ParcelAccessEntry entry, LLUUID parcelID) + { + row["LandUUID"] = Util.ToRawUuidString(parcelID); + row["AccessUUID"] = Util.ToRawUuidString(entry.AgentID); + row["Flags"] = entry.Flags; + } + + private PrimitiveBaseShape buildShape(DataRow row) + { + PrimitiveBaseShape s = new PrimitiveBaseShape(); + s.Scale = new LLVector3( + Convert.ToSingle(row["ScaleX"]), + Convert.ToSingle(row["ScaleY"]), + Convert.ToSingle(row["ScaleZ"]) + ); + // paths + s.PCode = Convert.ToByte(row["PCode"]); + s.PathBegin = Convert.ToUInt16(row["PathBegin"]); + s.PathEnd = Convert.ToUInt16(row["PathEnd"]); + s.PathScaleX = Convert.ToByte(row["PathScaleX"]); + s.PathScaleY = Convert.ToByte(row["PathScaleY"]); + s.PathShearX = Convert.ToByte(row["PathShearX"]); + s.PathShearY = Convert.ToByte(row["PathShearY"]); + s.PathSkew = Convert.ToSByte(row["PathSkew"]); + s.PathCurve = Convert.ToByte(row["PathCurve"]); + s.PathRadiusOffset = Convert.ToSByte(row["PathRadiusOffset"]); + s.PathRevolutions = Convert.ToByte(row["PathRevolutions"]); + s.PathTaperX = Convert.ToSByte(row["PathTaperX"]); + s.PathTaperY = Convert.ToSByte(row["PathTaperY"]); + s.PathTwist = Convert.ToSByte(row["PathTwist"]); + s.PathTwistBegin = Convert.ToSByte(row["PathTwistBegin"]); + // profile + s.ProfileBegin = Convert.ToUInt16(row["ProfileBegin"]); + s.ProfileEnd = Convert.ToUInt16(row["ProfileEnd"]); + s.ProfileCurve = Convert.ToByte(row["ProfileCurve"]); + s.ProfileHollow = Convert.ToUInt16(row["ProfileHollow"]); + + byte[] textureEntry = (byte[]) row["Texture"]; + s.TextureEntry = textureEntry; + + s.ExtraParams = (byte[]) row["ExtraParams"]; + + return s; + } + + private void fillShapeRow(DataRow row, SceneObjectPart prim) + { + PrimitiveBaseShape s = prim.Shape; + row["UUID"] = Util.ToRawUuidString(prim.UUID); + // shape is an enum + row["Shape"] = 0; + // vectors + row["ScaleX"] = s.Scale.X; + row["ScaleY"] = s.Scale.Y; + row["ScaleZ"] = s.Scale.Z; + // paths + row["PCode"] = s.PCode; + row["PathBegin"] = s.PathBegin; + row["PathEnd"] = s.PathEnd; + row["PathScaleX"] = s.PathScaleX; + row["PathScaleY"] = s.PathScaleY; + row["PathShearX"] = s.PathShearX; + row["PathShearY"] = s.PathShearY; + row["PathSkew"] = s.PathSkew; + row["PathCurve"] = s.PathCurve; + row["PathRadiusOffset"] = s.PathRadiusOffset; + row["PathRevolutions"] = s.PathRevolutions; + row["PathTaperX"] = s.PathTaperX; + row["PathTaperY"] = s.PathTaperY; + row["PathTwist"] = s.PathTwist; + row["PathTwistBegin"] = s.PathTwistBegin; + // profile + row["ProfileBegin"] = s.ProfileBegin; + row["ProfileEnd"] = s.ProfileEnd; + row["ProfileCurve"] = s.ProfileCurve; + row["ProfileHollow"] = s.ProfileHollow; + row["Texture"] = s.TextureEntry; + row["ExtraParams"] = s.ExtraParams; + } + + private void addPrim(SceneObjectPart prim, LLUUID sceneGroupID, LLUUID regionUUID) + { + DataTable prims = m_dataSet.Tables["prims"]; + DataTable shapes = m_dataSet.Tables["primshapes"]; + + DataRow primRow = prims.Rows.Find(Util.ToRawUuidString(prim.UUID)); + if (primRow == null) + { + primRow = prims.NewRow(); + fillPrimRow(primRow, prim, sceneGroupID, regionUUID); + prims.Rows.Add(primRow); + } + else + { + fillPrimRow(primRow, prim, sceneGroupID, regionUUID); + } + + DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(prim.UUID)); + if (shapeRow == null) + { + shapeRow = shapes.NewRow(); + fillShapeRow(shapeRow, prim); + shapes.Rows.Add(shapeRow); + } + else + { + fillShapeRow(shapeRow, prim); + } + } + + // see IRegionDatastore + public void StorePrimInventory(LLUUID primID, ICollection items) + { + if (!persistPrimInventories) + return; + + m_log.InfoFormat("[DATASTORE]: Persisting Prim Inventory with prim ID {0}", primID); + + // For now, we're just going to crudely remove all the previous inventory items + // no matter whether they have changed or not, and replace them with the current set. + lock (m_dataSet) + { + RemoveItems(primID); + + // repalce with current inventory details + foreach (TaskInventoryItem newItem in items) + { +// m_log.InfoFormat( +// "[DATASTORE]: " + +// "Adding item {0}, {1} to prim ID {2}", +// newItem.Name, newItem.ItemID, newItem.ParentPartID); + + DataRow newItemRow = m_itemsTable.NewRow(); + fillItemRow(newItemRow, newItem); + m_itemsTable.Rows.Add(newItemRow); + } + } + + Commit(); + } + + /*********************************************************************** + * + * SQL Statement Creation Functions + * + * These functions create SQL statements for update, insert, and create. + * They can probably be factored later to have a db independant + * portion and a db specific portion + * + **********************************************************************/ + + private MySqlCommand createInsertCommand(string table, DataTable dt) + { + /** + * This is subtle enough to deserve some commentary. + * Instead of doing *lots* and *lots of hardcoded strings + * for database definitions we'll use the fact that + * realistically all insert statements look like "insert + * into A(b, c) values(:b, :c) on the parameterized query + * front. If we just have a list of b, c, etc... we can + * generate these strings instead of typing them out. + */ + string[] cols = new string[dt.Columns.Count]; + for (int i = 0; i < dt.Columns.Count; i++) + { + DataColumn col = dt.Columns[i]; + cols[i] = col.ColumnName; + } + + string sql = "insert into " + table + "("; + sql += String.Join(", ", cols); + // important, the first ':' needs to be here, the rest get added in the join + sql += ") values (?"; + sql += String.Join(", ?", cols); + sql += ")"; + MySqlCommand cmd = new MySqlCommand(sql); + + // this provides the binding for all our parameters, so + // much less code than it used to be + foreach (DataColumn col in dt.Columns) + { + cmd.Parameters.Add(createMySqlParameter(col.ColumnName, col.DataType)); + } + return cmd; + } + + private MySqlCommand createUpdateCommand(string table, string pk, DataTable dt) + { + string sql = "update " + table + " set "; + string subsql = String.Empty; + foreach (DataColumn col in dt.Columns) + { + if (subsql.Length > 0) + { + // a map function would rock so much here + subsql += ", "; + } + subsql += col.ColumnName + "=?" + col.ColumnName; + } + sql += subsql; + sql += " where " + pk; + MySqlCommand cmd = new MySqlCommand(sql); + + // this provides the binding for all our parameters, so + // much less code than it used to be + + foreach (DataColumn col in dt.Columns) + { + cmd.Parameters.Add(createMySqlParameter(col.ColumnName, col.DataType)); + } + return cmd; + } + + private string defineTable(DataTable dt) + { + string sql = "create table " + dt.TableName + "("; + string subsql = String.Empty; + foreach (DataColumn col in dt.Columns) + { + if (subsql.Length > 0) + { + // a map function would rock so much here + subsql += ",\n"; + } + subsql += col.ColumnName + " " + MySqlType(col.DataType); + if (dt.PrimaryKey.Length > 0 && col == dt.PrimaryKey[0]) + { + subsql += " primary key"; + } + } + sql += subsql; + sql += ")"; + + //m_log.InfoFormat("[DATASTORE]: defineTable() sql {0}", sql); + + return sql; + } + + /*********************************************************************** + * + * Database Binding functions + * + * These will be db specific due to typing, and minor differences + * in databases. + * + **********************************************************************/ + + /// + /// This is a convenience function that collapses 5 repetitive + /// lines for defining MySqlParameters to 2 parameters: + /// column name and database type. + /// + /// It assumes certain conventions like ?param as the param + /// name to replace in parametrized queries, and that source + /// version is always current version, both of which are fine + /// for us. + /// + ///a built MySql parameter + private MySqlParameter createMySqlParameter(string name, Type type) + { + MySqlParameter param = new MySqlParameter(); + param.ParameterName = "?" + name; + param.DbType = dbtypeFromType(type); + param.SourceColumn = name; + param.SourceVersion = DataRowVersion.Current; + return param; + } + + private MySqlParameter createParamWithValue(string name, Type type, Object o) + { + MySqlParameter param = createMySqlParameter(name, type); + param.Value = o; + return param; + } + + private void SetupPrimCommands(MySqlDataAdapter da, MySqlConnection conn) + { + MySqlCommand insertCommand = createInsertCommand("prims", m_primTable); + insertCommand.Connection = conn; + da.InsertCommand = insertCommand; + + MySqlCommand updateCommand = createUpdateCommand("prims", "UUID=?UUID", m_primTable); + updateCommand.Connection = conn; + da.UpdateCommand = updateCommand; + + MySqlCommand delete = new MySqlCommand("delete from prims where UUID=?UUID"); + delete.Parameters.Add(createMySqlParameter("UUID", typeof (String))); + delete.Connection = conn; + da.DeleteCommand = delete; + } + + private void SetupItemsCommands(MySqlDataAdapter da, MySqlConnection conn) + { + da.InsertCommand = createInsertCommand("primitems", m_itemsTable); + da.InsertCommand.Connection = conn; + + da.UpdateCommand = createUpdateCommand("primitems", "itemID = ?itemID", m_itemsTable); + da.UpdateCommand.Connection = conn; + + MySqlCommand delete = new MySqlCommand("delete from primitems where itemID = ?itemID"); + delete.Parameters.Add(createMySqlParameter("itemID", typeof (String))); + delete.Connection = conn; + da.DeleteCommand = delete; + } + + private void SetupTerrainCommands(MySqlDataAdapter da, MySqlConnection conn) + { + da.InsertCommand = createInsertCommand("terrain", m_dataSet.Tables["terrain"]); + da.InsertCommand.Connection = conn; + } + + private void setupLandCommands(MySqlDataAdapter da, MySqlConnection conn) + { + da.InsertCommand = createInsertCommand("land", m_dataSet.Tables["land"]); + da.InsertCommand.Connection = conn; + + da.UpdateCommand = createUpdateCommand("land", "UUID=?UUID", m_dataSet.Tables["land"]); + da.UpdateCommand.Connection = conn; + } + + private void setupLandAccessCommands(MySqlDataAdapter da, MySqlConnection conn) + { + da.InsertCommand = createInsertCommand("landaccesslist", m_dataSet.Tables["landaccesslist"]); + da.InsertCommand.Connection = conn; + } + + private void SetupShapeCommands(MySqlDataAdapter da, MySqlConnection conn) + { + da.InsertCommand = createInsertCommand("primshapes", m_dataSet.Tables["primshapes"]); + da.InsertCommand.Connection = conn; + + da.UpdateCommand = createUpdateCommand("primshapes", "UUID=?UUID", m_dataSet.Tables["primshapes"]); + da.UpdateCommand.Connection = conn; + + MySqlCommand delete = new MySqlCommand("delete from primshapes where UUID = ?UUID"); + delete.Parameters.Add(createMySqlParameter("UUID", typeof (String))); + delete.Connection = conn; + da.DeleteCommand = delete; + } + + private void InitDB(MySqlConnection conn) + { + string createPrims = defineTable(createPrimTable()); + string createShapes = defineTable(createShapeTable()); + string createItems = defineTable(createItemsTable()); + string createTerrain = defineTable(createTerrainTable()); + string createLand = defineTable(createLandTable()); + string createLandAccessList = defineTable(createLandAccessListTable()); + + MySqlCommand pcmd = new MySqlCommand(createPrims, conn); + MySqlCommand scmd = new MySqlCommand(createShapes, conn); + MySqlCommand icmd = new MySqlCommand(createItems, conn); + MySqlCommand tcmd = new MySqlCommand(createTerrain, conn); + MySqlCommand lcmd = new MySqlCommand(createLand, conn); + MySqlCommand lalcmd = new MySqlCommand(createLandAccessList, conn); + + if (conn.State != ConnectionState.Open) + { + try + { + conn.Open(); + } + catch (Exception ex) + { + m_log.Error("[MySql]: Error connecting to MySQL server: " + ex.Message); + m_log.Error("[MySql]: Application is terminating!"); + System.Threading.Thread.CurrentThread.Abort(); + } + } + + try + { + pcmd.ExecuteNonQuery(); + } + catch (MySqlException e) + { + m_log.WarnFormat("[MySql]: Primitives Table Already Exists: {0}", e); + } + + try + { + scmd.ExecuteNonQuery(); + } + catch (MySqlException e) + { + m_log.WarnFormat("[MySql]: Shapes Table Already Exists: {0}", e); + } + + try + { + icmd.ExecuteNonQuery(); + } + catch (MySqlException e) + { + m_log.WarnFormat("[MySql]: Items Table Already Exists: {0}", e); + } + + try + { + tcmd.ExecuteNonQuery(); + } + catch (MySqlException e) + { + m_log.WarnFormat("[MySql]: Terrain Table Already Exists: {0}", e); + } + + try + { + lcmd.ExecuteNonQuery(); + } + catch (MySqlException e) + { + m_log.WarnFormat("[MySql]: Land Table Already Exists: {0}", e); + } + + try + { + lalcmd.ExecuteNonQuery(); + } + catch (MySqlException e) + { + m_log.WarnFormat("[MySql]: LandAccessList Table Already Exists: {0}", e); + } + conn.Close(); + } + + private bool TestTables(MySqlConnection conn) + { + MySqlCommand primSelectCmd = new MySqlCommand(m_primSelect, conn); + MySqlDataAdapter pDa = new MySqlDataAdapter(primSelectCmd); + MySqlCommand shapeSelectCmd = new MySqlCommand(m_shapeSelect, conn); + MySqlDataAdapter sDa = new MySqlDataAdapter(shapeSelectCmd); + MySqlCommand itemsSelectCmd = new MySqlCommand(m_itemsSelect, conn); + MySqlDataAdapter iDa = new MySqlDataAdapter(itemsSelectCmd); + MySqlCommand terrainSelectCmd = new MySqlCommand(m_terrainSelect, conn); + MySqlDataAdapter tDa = new MySqlDataAdapter(terrainSelectCmd); + MySqlCommand landSelectCmd = new MySqlCommand(m_landSelect, conn); + MySqlDataAdapter lDa = new MySqlDataAdapter(landSelectCmd); + MySqlCommand landAccessListSelectCmd = new MySqlCommand(m_landAccessListSelect, conn); + MySqlDataAdapter lalDa = new MySqlDataAdapter(landAccessListSelectCmd); + + DataSet tmpDS = new DataSet(); + try + { + pDa.Fill(tmpDS, "prims"); + sDa.Fill(tmpDS, "primshapes"); + + if (persistPrimInventories) + iDa.Fill(tmpDS, "primitems"); + + tDa.Fill(tmpDS, "terrain"); + lDa.Fill(tmpDS, "land"); + lalDa.Fill(tmpDS, "landaccesslist"); + } + catch (MySqlException) + { + m_log.Info("[DATASTORE]: MySql Database doesn't exist... creating"); + InitDB(conn); + } + + pDa.Fill(tmpDS, "prims"); + sDa.Fill(tmpDS, "primshapes"); + + if (persistPrimInventories) + iDa.Fill(tmpDS, "primitems"); + + tDa.Fill(tmpDS, "terrain"); + lDa.Fill(tmpDS, "land"); + lalDa.Fill(tmpDS, "landaccesslist"); + + foreach (DataColumn col in createPrimTable().Columns) + { + if (!tmpDS.Tables["prims"].Columns.Contains(col.ColumnName)) + { + m_log.Info("[DATASTORE]: Missing required column:" + col.ColumnName); + return false; + } + } + + foreach (DataColumn col in createShapeTable().Columns) + { + if (!tmpDS.Tables["primshapes"].Columns.Contains(col.ColumnName)) + { + m_log.Info("[DATASTORE]: Missing required column:" + col.ColumnName); + return false; + } + } + + // XXX primitems should probably go here eventually + + foreach (DataColumn col in createTerrainTable().Columns) + { + if (!tmpDS.Tables["terrain"].Columns.Contains(col.ColumnName)) + { + m_log.Info("[DATASTORE]: Missing require column:" + col.ColumnName); + return false; + } + } + + foreach (DataColumn col in createLandTable().Columns) + { + if (!tmpDS.Tables["land"].Columns.Contains(col.ColumnName)) + { + m_log.Info("[DATASTORE]: Missing require column:" + col.ColumnName); + return false; + } + } + + foreach (DataColumn col in createLandAccessListTable().Columns) + { + if (!tmpDS.Tables["landaccesslist"].Columns.Contains(col.ColumnName)) + { + m_log.Info("[DATASTORE]: Missing require column:" + col.ColumnName); + return false; + } + } + + return true; + } + + /*********************************************************************** + * + * Type conversion functions + * + **********************************************************************/ + + private DbType dbtypeFromType(Type type) + { + if (type == typeof (String)) + { + return DbType.String; + } + else if (type == typeof (Int32)) + { + return DbType.Int32; + } + else if (type == typeof (Double)) + { + return DbType.Double; + } + else if (type == typeof (Byte)) + { + return DbType.Byte; + } + else if (type == typeof (Double)) + { + return DbType.Double; + } + else if (type == typeof (Byte[])) + { + return DbType.Binary; + } + else + { + return DbType.String; + } + } + + // this is something we'll need to implement for each db + // slightly differently. + private string MySqlType(Type type) + { + if (type == typeof (String)) + { + return "varchar(255)"; + } + else if (type == typeof (Int32)) + { + return "integer"; + } + else if (type == typeof (Int64)) + { + return "bigint"; + } + else if (type == typeof (Double)) + { + return "float"; + } + else if (type == typeof (Byte[])) + { + return "longblob"; + } + else + { + return "string"; + } + } + } +} diff --git a/OpenSim/Framework/Data.MySQL/MySQLDatabaseMapper.cs b/OpenSim/Framework/Data.MySQL/MySQLDatabaseMapper.cs new file mode 100644 index 0000000000..04b4b4d391 --- /dev/null +++ b/OpenSim/Framework/Data.MySQL/MySQLDatabaseMapper.cs @@ -0,0 +1,54 @@ +/* +* 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.Data.Common; +using MySql.Data.MySqlClient; + //using TribalMedia.Framework.Data; + +namespace OpenSim.Framework.Data.MySQL +{ + /* + public class MySQLDatabaseMapper : OpenSimDatabaseConnector + { + public MySQLDatabaseMapper(string connectionString) + : base(connectionString) + { + } + + public override DbConnection GetNewConnection() + { + MySqlConnection connection = new MySqlConnection(m_connectionString); + return connection; + } + + public override string CreateParamName(string fieldName) + { + return "?" + fieldName; + } + }*/ +} diff --git a/OpenSim/Framework/Data.MySQL/MySQLGridData.cs b/OpenSim/Framework/Data.MySQL/MySQLGridData.cs index bf8ed3914f..1703d62f12 100644 --- a/OpenSim/Framework/Data.MySQL/MySQLGridData.cs +++ b/OpenSim/Framework/Data.MySQL/MySQLGridData.cs @@ -1,413 +1,331 @@ -/* -* 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.Generic; -using System.Data; -using System.Security.Cryptography; -using System.Text; -using System.Text.RegularExpressions; -using libsecondlife; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.Data.MySQL -{ - /// - /// A MySQL Interface for the Grid Server - /// - public class MySQLGridData : IGridData - { - /// - /// MySQL Database Manager - /// - private MySQLManager database; - - /// - /// Initialises the Grid Interface - /// - public void Initialise() - { - IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini"); - string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname"); - string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database"); - string settingUsername = GridDataMySqlFile.ParseFileReadValue("username"); - string settingPassword = GridDataMySqlFile.ParseFileReadValue("password"); - string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling"); - string settingPort = GridDataMySqlFile.ParseFileReadValue("port"); - - database = - new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, settingPooling, - settingPort); - - TestTables(); - } - - #region Test and initialization code - - /// - /// Ensure that the user related tables exists and are at the latest version - /// - private void TestTables() - { - Dictionary tableList = new Dictionary(); - - tableList["regions"] = null; - database.GetTableVersion(tableList); - - UpgradeRegionsTable(tableList["regions"]); - } - - /// - /// Create or upgrade the table if necessary - /// - /// A null indicates that the table does not - /// currently exist - private void UpgradeRegionsTable(string oldVersion) - { - // null as the version, indicates that the table didn't exist - if (oldVersion == null) - { - database.ExecuteResourceSql("CreateRegionsTable.sql"); - return; - } - } - - #endregion - - /// - /// Shuts down the grid interface - /// - public void Close() - { - database.Close(); - } - - /// - /// Returns the plugin name - /// - /// Plugin name - public string getName() - { - return "MySql OpenGridData"; - } - - /// - /// Returns the plugin version - /// - /// Plugin version - public string getVersion() - { - return "0.1"; - } - - /// - /// Returns all the specified region profiles within coordates -- coordinates are inclusive - /// - /// Minimum X coordinate - /// Minimum Y coordinate - /// Maximum X coordinate - /// Maximum Y coordinate - /// - public RegionProfileData[] GetProfilesInRange(uint xmin, uint ymin, uint xmax, uint ymax) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["?xmin"] = xmin.ToString(); - param["?ymin"] = ymin.ToString(); - param["?xmax"] = xmax.ToString(); - param["?ymax"] = ymax.ToString(); - - IDbCommand result = - database.Query( - "SELECT * FROM regions WHERE locX >= ?xmin AND locX <= ?xmax AND locY >= ?ymin AND locY <= ?ymax", - param); - IDataReader reader = result.ExecuteReader(); - - RegionProfileData row; - - List rows = new List(); - - while ((row = database.readSimRow(reader)) != null) - { - rows.Add(row); - } - reader.Close(); - result.Dispose(); - - return rows.ToArray(); - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - - /// - /// Returns a sim profile from it's location - /// - /// Region location handle - /// Sim profile - public RegionProfileData GetProfileByHandle(ulong handle) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["?handle"] = handle.ToString(); - - IDbCommand result = database.Query("SELECT * FROM regions WHERE regionHandle = ?handle", param); - IDataReader reader = result.ExecuteReader(); - - RegionProfileData row = database.readSimRow(reader); - reader.Close(); - result.Dispose(); - - return row; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - - /// - /// // Returns a list of avatar and UUIDs that match the query - /// - public List GeneratePickerResults(LLUUID queryID, string query) - { - List returnlist = new List(); - - Regex objAlphaNumericPattern = new Regex("[^a-zA-Z0-9]"); - - string[] querysplit; - querysplit = query.Split(' '); - if (querysplit.Length == 2) - { - Dictionary param = new Dictionary(); - param["?first"] = objAlphaNumericPattern.Replace(querysplit[0], "") + "%"; - param["?second"] = objAlphaNumericPattern.Replace(querysplit[1], "") + "%"; - try - { - lock (database) - { - IDbCommand result = - database.Query( - "SELECT UUID,username,surname FROM users WHERE username like ?first AND lastname like ?second LIMIT 100", - param); - IDataReader reader = result.ExecuteReader(); - - - while (reader.Read()) - { - AvatarPickerAvatar user = new AvatarPickerAvatar(); - user.AvatarID = new LLUUID((string) reader["UUID"]); - user.firstName = (string) reader["username"]; - user.lastName = (string) reader["surname"]; - returnlist.Add(user); - } - reader.Close(); - result.Dispose(); - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return returnlist; - } - } - else if (querysplit.Length == 1) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["?first"] = objAlphaNumericPattern.Replace(querysplit[0], "") + "%"; - - IDbCommand result = - database.Query( - "SELECT UUID,username,surname FROM users WHERE username like ?first OR lastname like ?second", - param); - IDataReader reader = result.ExecuteReader(); - - - while (reader.Read()) - { - AvatarPickerAvatar user = new AvatarPickerAvatar(); - user.AvatarID = new LLUUID((string) reader["UUID"]); - user.firstName = (string) reader["username"]; - user.lastName = (string) reader["surname"]; - returnlist.Add(user); - } - reader.Close(); - result.Dispose(); - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return returnlist; - } - } - return returnlist; - } - - /// - /// Returns a sim profile from it's UUID - /// - /// The region UUID - /// The sim profile - public RegionProfileData GetProfileByLLUUID(LLUUID uuid) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["?uuid"] = uuid.ToString(); - - IDbCommand result = database.Query("SELECT * FROM regions WHERE uuid = ?uuid", param); - IDataReader reader = result.ExecuteReader(); - - RegionProfileData row = database.readSimRow(reader); - reader.Close(); - result.Dispose(); - - return row; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - - /// - /// Adds a new profile to the database - /// - /// The profile to add - /// Successful? - public DataResponse AddProfile(RegionProfileData profile) - { - lock (database) - { - if (database.insertRegion(profile)) - { - return DataResponse.RESPONSE_OK; - } - else - { - return DataResponse.RESPONSE_ERROR; - } - } - } - - /// - /// DEPRECIATED. Attempts to authenticate a region by comparing a shared secret. - /// - /// The UUID of the challenger - /// The attempted regionHandle of the challenger - /// The secret - /// Whether the secret and regionhandle match the database entry for UUID - public bool AuthenticateSim(LLUUID uuid, ulong handle, string authkey) - { - bool throwHissyFit = false; // Should be true by 1.0 - - if (throwHissyFit) - throw new Exception("CRYPTOWEAK AUTHENTICATE: Refusing to authenticate due to replay potential."); - - RegionProfileData data = GetProfileByLLUUID(uuid); - - return (handle == data.regionHandle && authkey == data.regionSecret); - } - - /// - /// NOT YET FUNCTIONAL. Provides a cryptographic authentication of a region - /// - /// This requires a security audit. - /// - /// - /// - /// - /// - public bool AuthenticateSim(LLUUID uuid, ulong handle, string authhash, string challenge) - { - SHA512Managed HashProvider = new SHA512Managed(); - ASCIIEncoding TextProvider = new ASCIIEncoding(); - - byte[] stream = TextProvider.GetBytes(uuid.ToString() + ":" + handle.ToString() + ":" + challenge); - byte[] hash = HashProvider.ComputeHash(stream); - - return false; - } - - public ReservationData GetReservationAtPoint(uint x, uint y) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["?x"] = x.ToString(); - param["?y"] = y.ToString(); - IDbCommand result = - database.Query( - "SELECT * FROM reservations WHERE resXMin <= ?x AND resXMax >= ?x AND resYMin <= ?y AND resYMax >= ?y", - param); - IDataReader reader = result.ExecuteReader(); - - ReservationData row = database.readReservationRow(reader); - reader.Close(); - result.Dispose(); - - return row; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - } -} \ No newline at end of file +/* +* 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.Generic; +using System.Data; +using System.Security.Cryptography; +using System.Text; +using System.Text.RegularExpressions; +using libsecondlife; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Data.MySQL +{ + /// + /// A MySQL Interface for the Grid Server + /// + public class MySQLGridData : IGridData + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// MySQL Database Manager + /// + private MySQLManager database; + + /// + /// Initialises the Grid Interface + /// + public void Initialise() + { + IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini"); + string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname"); + string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database"); + string settingUsername = GridDataMySqlFile.ParseFileReadValue("username"); + string settingPassword = GridDataMySqlFile.ParseFileReadValue("password"); + string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling"); + string settingPort = GridDataMySqlFile.ParseFileReadValue("port"); + + database = + new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, settingPooling, + settingPort); + + TestTables(); + } + + #region Test and initialization code + + /// + /// Ensure that the user related tables exists and are at the latest version + /// + private void TestTables() + { + Dictionary tableList = new Dictionary(); + + tableList["regions"] = null; + database.GetTableVersion(tableList); + + UpgradeRegionsTable(tableList["regions"]); + } + + /// + /// Create or upgrade the table if necessary + /// + /// A null indicates that the table does not + /// currently exist + private void UpgradeRegionsTable(string oldVersion) + { + // null as the version, indicates that the table didn't exist + if (oldVersion == null) + { + database.ExecuteResourceSql("CreateRegionsTable.sql"); + return; + } + } + + #endregion + + /// + /// Shuts down the grid interface + /// + public void Close() + { + database.Close(); + } + + /// + /// Returns the plugin name + /// + /// Plugin name + public string getName() + { + return "MySql OpenGridData"; + } + + /// + /// Returns the plugin version + /// + /// Plugin version + public string getVersion() + { + return "0.1"; + } + + /// + /// Returns all the specified region profiles within coordates -- coordinates are inclusive + /// + /// Minimum X coordinate + /// Minimum Y coordinate + /// Maximum X coordinate + /// Maximum Y coordinate + /// + public RegionProfileData[] GetProfilesInRange(uint xmin, uint ymin, uint xmax, uint ymax) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?xmin"] = xmin.ToString(); + param["?ymin"] = ymin.ToString(); + param["?xmax"] = xmax.ToString(); + param["?ymax"] = ymax.ToString(); + + IDbCommand result = + database.Query( + "SELECT * FROM regions WHERE locX >= ?xmin AND locX <= ?xmax AND locY >= ?ymin AND locY <= ?ymax", + param); + IDataReader reader = result.ExecuteReader(); + + RegionProfileData row; + + List rows = new List(); + + while ((row = database.readSimRow(reader)) != null) + { + rows.Add(row); + } + reader.Close(); + result.Dispose(); + + return rows.ToArray(); + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return null; + } + } + + /// + /// Returns a sim profile from it's location + /// + /// Region location handle + /// Sim profile + public RegionProfileData GetProfileByHandle(ulong handle) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?handle"] = handle.ToString(); + + IDbCommand result = database.Query("SELECT * FROM regions WHERE regionHandle = ?handle", param); + IDataReader reader = result.ExecuteReader(); + + RegionProfileData row = database.readSimRow(reader); + reader.Close(); + result.Dispose(); + + return row; + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return null; + } + } + + /// + /// Returns a sim profile from it's UUID + /// + /// The region UUID + /// The sim profile + public RegionProfileData GetProfileByLLUUID(LLUUID uuid) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?uuid"] = uuid.ToString(); + + IDbCommand result = database.Query("SELECT * FROM regions WHERE uuid = ?uuid", param); + IDataReader reader = result.ExecuteReader(); + + RegionProfileData row = database.readSimRow(reader); + reader.Close(); + result.Dispose(); + + return row; + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return null; + } + } + + /// + /// Adds a new profile to the database + /// + /// The profile to add + /// Successful? + public DataResponse AddProfile(RegionProfileData profile) + { + lock (database) + { + if (database.insertRegion(profile)) + { + return DataResponse.RESPONSE_OK; + } + else + { + return DataResponse.RESPONSE_ERROR; + } + } + } + + /// + /// DEPRECIATED. Attempts to authenticate a region by comparing a shared secret. + /// + /// The UUID of the challenger + /// The attempted regionHandle of the challenger + /// The secret + /// Whether the secret and regionhandle match the database entry for UUID + public bool AuthenticateSim(LLUUID uuid, ulong handle, string authkey) + { + bool throwHissyFit = false; // Should be true by 1.0 + + if (throwHissyFit) + throw new Exception("CRYPTOWEAK AUTHENTICATE: Refusing to authenticate due to replay potential."); + + RegionProfileData data = GetProfileByLLUUID(uuid); + + return (handle == data.regionHandle && authkey == data.regionSecret); + } + + /// + /// NOT YET FUNCTIONAL. Provides a cryptographic authentication of a region + /// + /// This requires a security audit. + /// + /// + /// + /// + /// + public bool AuthenticateSim(LLUUID uuid, ulong handle, string authhash, string challenge) + { + SHA512Managed HashProvider = new SHA512Managed(); + ASCIIEncoding TextProvider = new ASCIIEncoding(); + + byte[] stream = TextProvider.GetBytes(uuid.ToString() + ":" + handle.ToString() + ":" + challenge); + byte[] hash = HashProvider.ComputeHash(stream); + + return false; + } + + public ReservationData GetReservationAtPoint(uint x, uint y) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?x"] = x.ToString(); + param["?y"] = y.ToString(); + IDbCommand result = + database.Query( + "SELECT * FROM reservations WHERE resXMin <= ?x AND resXMax >= ?x AND resYMin <= ?y AND resYMax >= ?y", + param); + IDataReader reader = result.ExecuteReader(); + + ReservationData row = database.readReservationRow(reader); + reader.Close(); + result.Dispose(); + + return row; + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return null; + } + } + } +} diff --git a/OpenSim/Framework/Data.MySQL/MySQLInventoryData.cs b/OpenSim/Framework/Data.MySQL/MySQLInventoryData.cs index ac8c81c479..07155e7fbf 100644 --- a/OpenSim/Framework/Data.MySQL/MySQLInventoryData.cs +++ b/OpenSim/Framework/Data.MySQL/MySQLInventoryData.cs @@ -1,640 +1,653 @@ -/* -* 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.Generic; -using libsecondlife; -using MySql.Data.MySqlClient; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.Data.MySQL -{ - /// - /// A MySQL interface for the inventory server - /// - public class MySQLInventoryData : IInventoryData - { - /// - /// The database manager - /// - private MySQLManager database; - - /// - /// Loads and initialises this database plugin - /// - public void Initialise() - { - IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini"); - string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname"); - string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database"); - string settingUsername = GridDataMySqlFile.ParseFileReadValue("username"); - string settingPassword = GridDataMySqlFile.ParseFileReadValue("password"); - string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling"); - string settingPort = GridDataMySqlFile.ParseFileReadValue("port"); - - database = - new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, settingPooling, - settingPort); - TestTables(database.Connection); - } - - #region Test and initialization code - - private void UpgradeFoldersTable(string oldVersion) - { - // null as the version, indicates that the table didn't exist - if (oldVersion == null) - { - database.ExecuteResourceSql("CreateFoldersTable.sql"); - return; - } - - // if the table is already at the current version, then we can exit immediately -// if (oldVersion == "Rev. 2") -// return; - -// database.ExecuteResourceSql("UpgradeFoldersTableToVersion2.sql"); - } - - private void UpgradeItemsTable(string oldVersion) - { - // null as the version, indicates that the table didn't exist - if (oldVersion == null) - { - database.ExecuteResourceSql("CreateItemsTable.sql"); - return; - } - - // if the table is already at the current version, then we can exit immediately -// if (oldVersion == "Rev. 2") -// return; - -// database.ExecuteResourceSql("UpgradeItemsTableToVersion2.sql"); - } - - private void TestTables(MySqlConnection conn) - { - Dictionary tableList = new Dictionary(); - - tableList["inventoryfolders"] = null; - tableList["inventoryitems"] = null; - - database.GetTableVersion(tableList); - MainLog.Instance.Verbose("MYSQL", "Inventory Folder Version: " + tableList["inventoryfolders"]); - MainLog.Instance.Verbose("MYSQL", "Inventory Items Version: " + tableList["inventoryitems"]); - - UpgradeFoldersTable(tableList["inventoryfolders"]); - UpgradeItemsTable(tableList["inventoryitems"]); - } - - #endregion - - /// - /// The name of this DB provider - /// - /// Name of DB provider - public string getName() - { - return "MySQL Inventory Data Interface"; - } - - /// - /// Closes this DB provider - /// - public void Close() - { - // Do nothing. - } - - /// - /// Returns the version of this DB provider - /// - /// A string containing the DB provider - public string getVersion() - { - return database.getVersion(); - } - - /// - /// Returns a list of items in a specified folder - /// - /// The folder to search - /// A list containing inventory items - public List getInventoryInFolder(LLUUID folderID) - { - try - { - lock (database) - { - List items = new List(); - - MySqlCommand result = - new MySqlCommand("SELECT * FROM inventoryitems WHERE parentFolderID = ?uuid", - database.Connection); - result.Parameters.AddWithValue("?uuid", folderID.ToString()); - MySqlDataReader reader = result.ExecuteReader(); - - while (reader.Read()) - items.Add(readInventoryItem(reader)); - - reader.Close(); - result.Dispose(); - - return items; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - - /// - /// Returns a list of the root folders within a users inventory - /// - /// The user whos inventory is to be searched - /// A list of folder objects - public List getUserRootFolders(LLUUID user) - { - try - { - lock (database) - { - MySqlCommand result = - new MySqlCommand( - "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", - database.Connection); - result.Parameters.AddWithValue("?uuid", user.ToString()); - result.Parameters.AddWithValue("?zero", LLUUID.Zero.ToString()); - MySqlDataReader reader = result.ExecuteReader(); - - List items = new List(); - while (reader.Read()) - items.Add(readInventoryFolder(reader)); - - - reader.Close(); - result.Dispose(); - - return items; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - - // see InventoryItemBase.getUserRootFolder - public InventoryFolderBase getUserRootFolder(LLUUID user) - { - try - { - lock (database) - { - MySqlCommand result = - new MySqlCommand( - "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", - database.Connection); - result.Parameters.AddWithValue("?uuid", user.ToString()); - result.Parameters.AddWithValue("?zero", LLUUID.Zero.ToString()); - - MySqlDataReader reader = result.ExecuteReader(); - - List items = new List(); - while (reader.Read()) - items.Add(readInventoryFolder(reader)); - - InventoryFolderBase rootFolder = null; - - // There should only ever be one root folder for a user. However, if there's more - // than one we'll simply use the first one rather than failing. It would be even - // nicer to print some message to this effect, but this feels like it's too low a - // to put such a message out, and it's too minor right now to spare the time to - // suitably refactor. - if (items.Count > 0) - { - rootFolder = items[0]; - } - - reader.Close(); - result.Dispose(); - - return rootFolder; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - - /// - /// Return a list of folders in a users inventory contained within the specified folder. - /// This method is only used in tests - in normal operation the user always have one, - /// and only one, root folder. - /// - /// The folder to search - /// A list of inventory folders - public List getInventoryFolders(LLUUID parentID) - { - try - { - lock (database) - { - MySqlCommand result = - new MySqlCommand("SELECT * FROM inventoryfolders WHERE parentFolderID = ?uuid", - database.Connection); - result.Parameters.AddWithValue("?uuid", parentID.ToString()); - MySqlDataReader reader = result.ExecuteReader(); - - List items = new List(); - - while (reader.Read()) - items.Add(readInventoryFolder(reader)); - - reader.Close(); - result.Dispose(); - - return items; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - - /// - /// Reads a one item from an SQL result - /// - /// The SQL Result - /// the item read - private InventoryItemBase readInventoryItem(MySqlDataReader reader) - { - try - { - InventoryItemBase item = new InventoryItemBase(); - - item.inventoryID = new LLUUID((string) reader["inventoryID"]); - item.assetID = new LLUUID((string) reader["assetID"]); - item.assetType = (int) reader["assetType"]; - item.parentFolderID = new LLUUID((string) reader["parentFolderID"]); - item.avatarID = new LLUUID((string) reader["avatarID"]); - item.inventoryName = (string) reader["inventoryName"]; - item.inventoryDescription = (string) reader["inventoryDescription"]; - item.inventoryNextPermissions = (uint) reader["inventoryNextPermissions"]; - item.inventoryCurrentPermissions = (uint) reader["inventoryCurrentPermissions"]; - item.invType = (int) reader["invType"]; - item.creatorsID = new LLUUID((string) reader["creatorID"]); - item.inventoryBasePermissions = (uint) reader["inventoryBasePermissions"]; - item.inventoryEveryOnePermissions = (uint) reader["inventoryEveryOnePermissions"]; - return item; - } - catch (MySqlException e) - { - MainLog.Instance.Error(e.ToString()); - } - - return null; - } - - /// - /// Returns a specified inventory item - /// - /// The item to return - /// An inventory item - public InventoryItemBase getInventoryItem(LLUUID itemID) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - - MySqlCommand result = - new MySqlCommand("SELECT * FROM inventoryitems WHERE inventoryID = ?uuid", database.Connection); - result.Parameters.AddWithValue("?uuid", itemID.ToString()); - MySqlDataReader reader = result.ExecuteReader(); - - InventoryItemBase item = null; - if (reader.Read()) - item = readInventoryItem(reader); - - reader.Close(); - result.Dispose(); - - return item; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - } - return null; - } - - /// - /// Reads a list of inventory folders returned by a query. - /// - /// A MySQL Data Reader - /// A List containing inventory folders - protected InventoryFolderBase readInventoryFolder(MySqlDataReader reader) - { - try - { - InventoryFolderBase folder = new InventoryFolderBase(); - folder.agentID = new LLUUID((string) reader["agentID"]); - folder.parentID = new LLUUID((string) reader["parentFolderID"]); - folder.folderID = new LLUUID((string) reader["folderID"]); - folder.name = (string) reader["folderName"]; - folder.type = (short) reader["type"]; - folder.version = (ushort) ((int) reader["version"]); - return folder; - } - catch (Exception e) - { - MainLog.Instance.Error(e.ToString()); - } - - return null; - } - - - /// - /// Returns a specified inventory folder - /// - /// The folder to return - /// A folder class - public InventoryFolderBase getInventoryFolder(LLUUID folderID) - { - try - { - lock (database) - { - MySqlCommand result = - new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", database.Connection); - result.Parameters.AddWithValue("?uuid", folderID.ToString()); - MySqlDataReader reader = result.ExecuteReader(); - - reader.Read(); - InventoryFolderBase folder = readInventoryFolder(reader); - reader.Close(); - result.Dispose(); - - return folder; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - - /// - /// Adds a specified item to the database - /// - /// The inventory item - public void addInventoryItem(InventoryItemBase item) - { - string sql = - "REPLACE INTO inventoryitems (inventoryID, assetID, assetType, parentFolderID, avatarID, inventoryName, inventoryDescription, inventoryNextPermissions, inventoryCurrentPermissions, invType, creatorID, inventoryBasePermissions, inventoryEveryOnePermissions) VALUES "; - sql += - "(?inventoryID, ?assetID, ?assetType, ?parentFolderID, ?avatarID, ?inventoryName, ?inventoryDescription, ?inventoryNextPermissions, ?inventoryCurrentPermissions, ?invType, ?creatorID, ?inventoryBasePermissions, ?inventoryEveryOnePermissions)"; - - try - { - MySqlCommand result = new MySqlCommand(sql, database.Connection); - result.Parameters.AddWithValue("?inventoryID", item.inventoryID.ToString()); - result.Parameters.AddWithValue("?assetID", item.assetID.ToString()); - result.Parameters.AddWithValue("?assetType", item.assetType.ToString()); - result.Parameters.AddWithValue("?parentFolderID", item.parentFolderID.ToString()); - result.Parameters.AddWithValue("?avatarID", item.avatarID.ToString()); - result.Parameters.AddWithValue("?inventoryName", item.inventoryName); - result.Parameters.AddWithValue("?inventoryDescription", item.inventoryDescription); - result.Parameters.AddWithValue("?inventoryNextPermissions", item.inventoryNextPermissions.ToString()); - result.Parameters.AddWithValue("?inventoryCurrentPermissions", - item.inventoryCurrentPermissions.ToString()); - result.Parameters.AddWithValue("?invType", item.invType); - result.Parameters.AddWithValue("?creatorID", item.creatorsID.ToString()); - result.Parameters.AddWithValue("?inventoryBasePermissions", item.inventoryBasePermissions); - result.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.inventoryEveryOnePermissions); - result.ExecuteNonQuery(); - result.Dispose(); - } - catch (MySqlException e) - { - MainLog.Instance.Error(e.ToString()); - } - } - - /// - /// Updates the specified inventory item - /// - /// Inventory item to update - public void updateInventoryItem(InventoryItemBase item) - { - addInventoryItem(item); - } - - /// - /// - /// - /// - public void deleteInventoryItem(LLUUID itemID) - { - try - { - MySqlCommand cmd = - new MySqlCommand("DELETE FROM inventoryitems WHERE inventoryID=?uuid", database.Connection); - cmd.Parameters.AddWithValue("?uuid", itemID.ToString()); - cmd.ExecuteNonQuery(); - } - catch (MySqlException e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - } - } - - /// - /// Creates a new inventory folder - /// - /// Folder to create - public void addInventoryFolder(InventoryFolderBase folder) - { - string sql = - "REPLACE INTO inventoryfolders (folderID, agentID, parentFolderID, folderName, type, version) VALUES "; - sql += "(?folderID, ?agentID, ?parentFolderID, ?folderName, ?type, ?version)"; - - MySqlCommand cmd = new MySqlCommand(sql, database.Connection); - cmd.Parameters.AddWithValue("?folderID", folder.folderID.ToString()); - cmd.Parameters.AddWithValue("?agentID", folder.agentID.ToString()); - cmd.Parameters.AddWithValue("?parentFolderID", folder.parentID.ToString()); - cmd.Parameters.AddWithValue("?folderName", folder.name); - cmd.Parameters.AddWithValue("?type", (short) folder.type); - cmd.Parameters.AddWithValue("?version", folder.version); - - try - { - cmd.ExecuteNonQuery(); - } - catch (Exception e) - { - MainLog.Instance.Error(e.ToString()); - } - } - - /// - /// Updates an inventory folder - /// - /// Folder to update - public void updateInventoryFolder(InventoryFolderBase folder) - { - addInventoryFolder(folder); - } - - /// Creates a new inventory folder - /// - /// Folder to create - public void moveInventoryFolder(InventoryFolderBase folder) - { - string sql = - "UPDATE inventoryfolders SET parentFolderID=?parentFolderID WHERE folderID=?folderID"; - - MySqlCommand cmd = new MySqlCommand(sql, database.Connection); - cmd.Parameters.AddWithValue("?folderID", folder.folderID.ToString()); - cmd.Parameters.AddWithValue("?parentFolderID", folder.parentID.ToString()); - - - try - { - cmd.ExecuteNonQuery(); - } - catch (Exception e) - { - MainLog.Instance.Error(e.ToString()); - } - } - - /// - /// Append a list of all the child folders of a parent folder - /// - /// list where folders will be appended - /// ID of parent - protected void getInventoryFolders(ref List folders, LLUUID parentID) - { - List subfolderList = getInventoryFolders(parentID); - - foreach (InventoryFolderBase f in subfolderList) - folders.Add(f); - } - - /// - /// Returns all child folders in the hierarchy from the parent folder and down - /// - /// The folder to get subfolders for - /// A list of inventory folders - protected List getFolderHierarchy(LLUUID parentID) - { - List folders = new List(); - getInventoryFolders(ref folders, parentID); - - for (int i = 0; i < folders.Count; i++) - getInventoryFolders(ref folders, folders[i].folderID); - - return folders; - } - - protected void deleteOneFolder(LLUUID folderID) - { - try - { - MySqlCommand cmd = - new MySqlCommand("DELETE FROM inventoryfolders WHERE folderID=?uuid", database.Connection); - cmd.Parameters.AddWithValue("?uuid", folderID.ToString()); - cmd.ExecuteNonQuery(); - } - catch (MySqlException e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - } - } - - protected void deleteItemsInFolder(LLUUID folderID) - { - try - { - MySqlCommand cmd = - new MySqlCommand("DELETE FROM inventoryitems WHERE parentFolderID=?uuid", database.Connection); - cmd.Parameters.AddWithValue("?uuid", folderID.ToString()); - cmd.ExecuteNonQuery(); - } - catch (MySqlException e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - } - } - - - /// - /// Delete an inventory folder - /// - /// Id of folder to delete - public void deleteInventoryFolder(LLUUID folderID) - { - lock (database) - { - List subFolders = getFolderHierarchy(folderID); - - //Delete all sub-folders - foreach (InventoryFolderBase f in subFolders) - { - deleteOneFolder(f.folderID); - deleteItemsInFolder(f.folderID); - } - - //Delete the actual row - deleteOneFolder(folderID); - deleteItemsInFolder(folderID); - } - } - } -} \ No newline at end of file +/* +* 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.Generic; +using libsecondlife; +using MySql.Data.MySqlClient; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Data.MySQL +{ + /// + /// A MySQL interface for the inventory server + /// + public class MySQLInventoryData : IInventoryData + { + private static readonly log4net.ILog m_log + = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// The database manager + /// + private MySQLManager database; + + /// + /// Loads and initialises this database plugin + /// + public void Initialise() + { + IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini"); + string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname"); + string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database"); + string settingUsername = GridDataMySqlFile.ParseFileReadValue("username"); + string settingPassword = GridDataMySqlFile.ParseFileReadValue("password"); + string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling"); + string settingPort = GridDataMySqlFile.ParseFileReadValue("port"); + + database = + new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, settingPooling, + settingPort); + TestTables(database.Connection); + } + + #region Test and initialization code + + private void UpgradeFoldersTable(string oldVersion) + { + // null as the version, indicates that the table didn't exist + if (oldVersion == null) + { + database.ExecuteResourceSql("CreateFoldersTable.sql"); + return; + } + + // if the table is already at the current version, then we can exit immediately +// if (oldVersion == "Rev. 2") +// return; + +// database.ExecuteResourceSql("UpgradeFoldersTableToVersion2.sql"); + } + + private void UpgradeItemsTable(string oldVersion) + { + // null as the version, indicates that the table didn't exist + if (oldVersion == null) + { + database.ExecuteResourceSql("CreateItemsTable.sql"); + return; + } + + // if the table is already at the current version, then we can exit immediately +// if (oldVersion == "Rev. 2") +// return; + +// database.ExecuteResourceSql("UpgradeItemsTableToVersion2.sql"); + } + + private void TestTables(MySqlConnection conn) + { + Dictionary tableList = new Dictionary(); + + tableList["inventoryfolders"] = null; + tableList["inventoryitems"] = null; + + database.GetTableVersion(tableList); + m_log.Info("[MYSQL]: Inventory Folder Version: " + tableList["inventoryfolders"]); + m_log.Info("[MYSQL]: Inventory Items Version: " + tableList["inventoryitems"]); + + UpgradeFoldersTable(tableList["inventoryfolders"]); + UpgradeItemsTable(tableList["inventoryitems"]); + } + + #endregion + + /// + /// The name of this DB provider + /// + /// Name of DB provider + public string getName() + { + return "MySQL Inventory Data Interface"; + } + + /// + /// Closes this DB provider + /// + public void Close() + { + // Do nothing. + } + + /// + /// Returns the version of this DB provider + /// + /// A string containing the DB provider + public string getVersion() + { + return database.getVersion(); + } + + /// + /// Returns a list of items in a specified folder + /// + /// The folder to search + /// A list containing inventory items + public List getInventoryInFolder(LLUUID folderID) + { + try + { + lock (database) + { + List items = new List(); + + MySqlCommand result = + new MySqlCommand("SELECT * FROM inventoryitems WHERE parentFolderID = ?uuid", + database.Connection); + result.Parameters.AddWithValue("?uuid", folderID.ToString()); + MySqlDataReader reader = result.ExecuteReader(); + + while (reader.Read()) + items.Add(readInventoryItem(reader)); + + reader.Close(); + result.Dispose(); + + return items; + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return null; + } + } + + /// + /// Returns a list of the root folders within a users inventory + /// + /// The user whos inventory is to be searched + /// A list of folder objects + public List getUserRootFolders(LLUUID user) + { + try + { + lock (database) + { + MySqlCommand result = + new MySqlCommand( + "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", + database.Connection); + result.Parameters.AddWithValue("?uuid", user.ToString()); + result.Parameters.AddWithValue("?zero", LLUUID.Zero.ToString()); + MySqlDataReader reader = result.ExecuteReader(); + + List items = new List(); + while (reader.Read()) + items.Add(readInventoryFolder(reader)); + + + reader.Close(); + result.Dispose(); + + return items; + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return null; + } + } + + // see InventoryItemBase.getUserRootFolder + public InventoryFolderBase getUserRootFolder(LLUUID user) + { + try + { + lock (database) + { + MySqlCommand result = + new MySqlCommand( + "SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", + database.Connection); + result.Parameters.AddWithValue("?uuid", user.ToString()); + result.Parameters.AddWithValue("?zero", LLUUID.Zero.ToString()); + + MySqlDataReader reader = result.ExecuteReader(); + + List items = new List(); + while (reader.Read()) + items.Add(readInventoryFolder(reader)); + + InventoryFolderBase rootFolder = null; + + // There should only ever be one root folder for a user. However, if there's more + // than one we'll simply use the first one rather than failing. It would be even + // nicer to print some message to this effect, but this feels like it's too low a + // to put such a message out, and it's too minor right now to spare the time to + // suitably refactor. + if (items.Count > 0) + { + rootFolder = items[0]; + } + + reader.Close(); + result.Dispose(); + + return rootFolder; + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return null; + } + } + + /// + /// Return a list of folders in a users inventory contained within the specified folder. + /// This method is only used in tests - in normal operation the user always have one, + /// and only one, root folder. + /// + /// The folder to search + /// A list of inventory folders + public List getInventoryFolders(LLUUID parentID) + { + try + { + lock (database) + { + MySqlCommand result = + new MySqlCommand("SELECT * FROM inventoryfolders WHERE parentFolderID = ?uuid", + database.Connection); + result.Parameters.AddWithValue("?uuid", parentID.ToString()); + MySqlDataReader reader = result.ExecuteReader(); + + List items = new List(); + + while (reader.Read()) + items.Add(readInventoryFolder(reader)); + + reader.Close(); + result.Dispose(); + + return items; + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return null; + } + } + + /// + /// Reads a one item from an SQL result + /// + /// The SQL Result + /// the item read + private InventoryItemBase readInventoryItem(MySqlDataReader reader) + { + try + { + InventoryItemBase item = new InventoryItemBase(); + + item.inventoryID = new LLUUID((string) reader["inventoryID"]); + item.assetID = new LLUUID((string) reader["assetID"]); + item.assetType = (int) reader["assetType"]; + item.parentFolderID = new LLUUID((string) reader["parentFolderID"]); + item.avatarID = new LLUUID((string) reader["avatarID"]); + item.inventoryName = (string) reader["inventoryName"]; + item.inventoryDescription = (string) reader["inventoryDescription"]; + item.inventoryNextPermissions = (uint) reader["inventoryNextPermissions"]; + item.inventoryCurrentPermissions = (uint) reader["inventoryCurrentPermissions"]; + item.invType = (int) reader["invType"]; + item.creatorsID = new LLUUID((string) reader["creatorID"]); + item.inventoryBasePermissions = (uint) reader["inventoryBasePermissions"]; + item.inventoryEveryOnePermissions = (uint) reader["inventoryEveryOnePermissions"]; + return item; + } + catch (MySqlException e) + { + m_log.Error(e.ToString()); + } + + return null; + } + + /// + /// Returns a specified inventory item + /// + /// The item to return + /// An inventory item + public InventoryItemBase getInventoryItem(LLUUID itemID) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + + MySqlCommand result = + new MySqlCommand("SELECT * FROM inventoryitems WHERE inventoryID = ?uuid", database.Connection); + result.Parameters.AddWithValue("?uuid", itemID.ToString()); + MySqlDataReader reader = result.ExecuteReader(); + + InventoryItemBase item = null; + if (reader.Read()) + item = readInventoryItem(reader); + + reader.Close(); + result.Dispose(); + + return item; + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + } + return null; + } + + /// + /// Reads a list of inventory folders returned by a query. + /// + /// A MySQL Data Reader + /// A List containing inventory folders + protected InventoryFolderBase readInventoryFolder(MySqlDataReader reader) + { + try + { + InventoryFolderBase folder = new InventoryFolderBase(); + folder.agentID = new LLUUID((string) reader["agentID"]); + folder.parentID = new LLUUID((string) reader["parentFolderID"]); + folder.folderID = new LLUUID((string) reader["folderID"]); + folder.name = (string) reader["folderName"]; + folder.type = (short) reader["type"]; + folder.version = (ushort) ((int) reader["version"]); + return folder; + } + catch (Exception e) + { + m_log.Error(e.ToString()); + } + + return null; + } + + + /// + /// Returns a specified inventory folder + /// + /// The folder to return + /// A folder class + public InventoryFolderBase getInventoryFolder(LLUUID folderID) + { + try + { + lock (database) + { + MySqlCommand result = + new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", database.Connection); + result.Parameters.AddWithValue("?uuid", folderID.ToString()); + MySqlDataReader reader = result.ExecuteReader(); + + reader.Read(); + InventoryFolderBase folder = readInventoryFolder(reader); + reader.Close(); + result.Dispose(); + + return folder; + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return null; + } + } + + /// + /// Adds a specified item to the database + /// + /// The inventory item + public void addInventoryItem(InventoryItemBase item) + { + string sql = + "REPLACE INTO inventoryitems (inventoryID, assetID, assetType, parentFolderID, avatarID, inventoryName, inventoryDescription, inventoryNextPermissions, inventoryCurrentPermissions, invType, creatorID, inventoryBasePermissions, inventoryEveryOnePermissions) VALUES "; + sql += + "(?inventoryID, ?assetID, ?assetType, ?parentFolderID, ?avatarID, ?inventoryName, ?inventoryDescription, ?inventoryNextPermissions, ?inventoryCurrentPermissions, ?invType, ?creatorID, ?inventoryBasePermissions, ?inventoryEveryOnePermissions)"; + + try + { + MySqlCommand result = new MySqlCommand(sql, database.Connection); + result.Parameters.AddWithValue("?inventoryID", item.inventoryID.ToString()); + result.Parameters.AddWithValue("?assetID", item.assetID.ToString()); + result.Parameters.AddWithValue("?assetType", item.assetType.ToString()); + result.Parameters.AddWithValue("?parentFolderID", item.parentFolderID.ToString()); + result.Parameters.AddWithValue("?avatarID", item.avatarID.ToString()); + result.Parameters.AddWithValue("?inventoryName", item.inventoryName); + result.Parameters.AddWithValue("?inventoryDescription", item.inventoryDescription); + result.Parameters.AddWithValue("?inventoryNextPermissions", item.inventoryNextPermissions.ToString()); + result.Parameters.AddWithValue("?inventoryCurrentPermissions", + item.inventoryCurrentPermissions.ToString()); + result.Parameters.AddWithValue("?invType", item.invType); + result.Parameters.AddWithValue("?creatorID", item.creatorsID.ToString()); + result.Parameters.AddWithValue("?inventoryBasePermissions", item.inventoryBasePermissions); + result.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.inventoryEveryOnePermissions); + result.ExecuteNonQuery(); + result.Dispose(); + } + catch (MySqlException e) + { + m_log.Error(e.ToString()); + } + } + + /// + /// Updates the specified inventory item + /// + /// Inventory item to update + public void updateInventoryItem(InventoryItemBase item) + { + addInventoryItem(item); + } + + /// + /// + /// + /// + public void deleteInventoryItem(LLUUID itemID) + { + try + { + MySqlCommand cmd = + new MySqlCommand("DELETE FROM inventoryitems WHERE inventoryID=?uuid", database.Connection); + cmd.Parameters.AddWithValue("?uuid", itemID.ToString()); + cmd.ExecuteNonQuery(); + } + catch (MySqlException e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + } + } + + /// + /// Creates a new inventory folder + /// + /// Folder to create + public void addInventoryFolder(InventoryFolderBase folder) + { + string sql = + "REPLACE INTO inventoryfolders (folderID, agentID, parentFolderID, folderName, type, version) VALUES "; + sql += "(?folderID, ?agentID, ?parentFolderID, ?folderName, ?type, ?version)"; + + MySqlCommand cmd = new MySqlCommand(sql, database.Connection); + cmd.Parameters.AddWithValue("?folderID", folder.folderID.ToString()); + cmd.Parameters.AddWithValue("?agentID", folder.agentID.ToString()); + cmd.Parameters.AddWithValue("?parentFolderID", folder.parentID.ToString()); + cmd.Parameters.AddWithValue("?folderName", folder.name); + cmd.Parameters.AddWithValue("?type", (short) folder.type); + cmd.Parameters.AddWithValue("?version", folder.version); + + try + { + lock (database) + { + cmd.ExecuteNonQuery(); + } + } + catch (Exception e) + { + m_log.Error(e.ToString()); + } + } + + /// + /// Updates an inventory folder + /// + /// Folder to update + public void updateInventoryFolder(InventoryFolderBase folder) + { + addInventoryFolder(folder); + } + + /// Creates a new inventory folder + /// + /// Folder to create + public void moveInventoryFolder(InventoryFolderBase folder) + { + string sql = + "UPDATE inventoryfolders SET parentFolderID=?parentFolderID WHERE folderID=?folderID"; + + MySqlCommand cmd = new MySqlCommand(sql, database.Connection); + cmd.Parameters.AddWithValue("?folderID", folder.folderID.ToString()); + cmd.Parameters.AddWithValue("?parentFolderID", folder.parentID.ToString()); + + try + { + lock (database) + { + cmd.ExecuteNonQuery(); + } + } + catch (Exception e) + { + m_log.Error(e.ToString()); + } + } + + /// + /// Append a list of all the child folders of a parent folder + /// + /// list where folders will be appended + /// ID of parent + protected void getInventoryFolders(ref List folders, LLUUID parentID) + { + List subfolderList = getInventoryFolders(parentID); + + foreach (InventoryFolderBase f in subfolderList) + folders.Add(f); + } + + /// + /// Returns all child folders in the hierarchy from the parent folder and down + /// + /// The folder to get subfolders for + /// A list of inventory folders + protected List getFolderHierarchy(LLUUID parentID) + { + List folders = new List(); + getInventoryFolders(ref folders, parentID); + + for (int i = 0; i < folders.Count; i++) + getInventoryFolders(ref folders, folders[i].folderID); + + return folders; + } + + protected void deleteOneFolder(LLUUID folderID) + { + try + { + MySqlCommand cmd = + new MySqlCommand("DELETE FROM inventoryfolders WHERE folderID=?uuid", database.Connection); + cmd.Parameters.AddWithValue("?uuid", folderID.ToString()); + + lock (database) + { + cmd.ExecuteNonQuery(); + } + } + catch (MySqlException e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + } + } + + protected void deleteItemsInFolder(LLUUID folderID) + { + try + { + MySqlCommand cmd = + new MySqlCommand("DELETE FROM inventoryitems WHERE parentFolderID=?uuid", database.Connection); + cmd.Parameters.AddWithValue("?uuid", folderID.ToString()); + + lock (database) + { + cmd.ExecuteNonQuery(); + } + } + catch (MySqlException e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + } + } + + + /// + /// Delete an inventory folder + /// + /// Id of folder to delete + public void deleteInventoryFolder(LLUUID folderID) + { + List subFolders = getFolderHierarchy(folderID); + + //Delete all sub-folders + foreach (InventoryFolderBase f in subFolders) + { + deleteOneFolder(f.folderID); + deleteItemsInFolder(f.folderID); + } + + //Delete the actual row + deleteOneFolder(folderID); + deleteItemsInFolder(folderID); + } + } +} diff --git a/OpenSim/Framework/Data.MySQL/MySQLManager.cs b/OpenSim/Framework/Data.MySQL/MySQLManager.cs index b290fa23a7..6350c6a8c0 100644 --- a/OpenSim/Framework/Data.MySQL/MySQLManager.cs +++ b/OpenSim/Framework/Data.MySQL/MySQLManager.cs @@ -1,690 +1,739 @@ -/* -* 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.Generic; -using System.Data; -using System.IO; -using System.Reflection; -using libsecondlife; -using MySql.Data.MySqlClient; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.Data.MySQL -{ - /// - /// A MySQL Database manager - /// - internal class MySQLManager - { - /// - /// The database connection object - /// - private MySqlConnection dbcon; - - /// - /// Connection string for ADO.net - /// - private string connectionString; - - /// - /// Initialises and creates a new MySQL connection and maintains it. - /// - /// The MySQL server being connected to - /// The name of the MySQL database being used - /// The username logging into the database - /// The password for the user logging in - /// Whether to use connection pooling or not, can be one of the following: 'yes', 'true', 'no' or 'false', if unsure use 'false'. - public MySQLManager(string hostname, string database, string username, string password, string cpooling, - string port) - { - try - { - connectionString = "Server=" + hostname + ";Port=" + port + ";Database=" + database + ";User ID=" + - username + ";Password=" + password + ";Pooling=" + cpooling + ";"; - dbcon = new MySqlConnection(connectionString); - - dbcon.Open(); - - MainLog.Instance.Verbose("MYSQL", "Connection established"); - } - catch (Exception e) - { - throw new Exception("Error initialising MySql Database: " + e.ToString()); - } - } - - /// - /// Get the connection being used - /// - public MySqlConnection Connection - { - get { return dbcon; } - } - - /// - /// Shuts down the database connection - /// - public void Close() - { - dbcon.Close(); - dbcon = null; - } - - /// - /// Reconnects to the database - /// - public void Reconnect() - { - lock (dbcon) - { - try - { - // Close the DB connection - dbcon.Close(); - // Try reopen it - dbcon = new MySqlConnection(connectionString); - dbcon.Open(); - } - catch (Exception e) - { - MainLog.Instance.Error("Unable to reconnect to database " + e.ToString()); - } - } - } - - /// - /// Returns the version of this DB provider - /// - /// A string containing the DB provider - public string getVersion() - { - Module module = GetType().Module; - string dllName = module.Assembly.ManifestModule.Name; - Version dllVersion = module.Assembly.GetName().Version; - - - return - string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build, - dllVersion.Revision); - } - - - /// - /// Extract a named string resource from the embedded resources - /// - /// name of embedded resource - /// string contained within the embedded resource - private string getResourceString(string name) - { - Assembly assem = GetType().Assembly; - string[] names = assem.GetManifestResourceNames(); - - foreach (string s in names) - if (s.EndsWith(name)) - using (Stream resource = assem.GetManifestResourceStream(s)) - { - using (StreamReader resourceReader = new StreamReader(resource)) - { - string resourceString = resourceReader.ReadToEnd(); - return resourceString; - } - } - throw new Exception(string.Format("Resource '{0}' was not found", name)); - } - - /// - /// Execute a SQL statement stored in a resource, as a string - /// - /// - public void ExecuteResourceSql(string name) - { - MySqlCommand cmd = new MySqlCommand(getResourceString(name), dbcon); - cmd.ExecuteNonQuery(); - } - - /// - /// Given a list of tables, return the version of the tables, as seen in the database - /// - /// - public void GetTableVersion(Dictionary tableList) - { - lock (dbcon) - { - MySqlCommand tablesCmd = - new MySqlCommand( - "SELECT TABLE_NAME, TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=?dbname", - dbcon); - tablesCmd.Parameters.AddWithValue("?dbname", dbcon.Database); - using (MySqlDataReader tables = tablesCmd.ExecuteReader()) - { - while (tables.Read()) - { - try - { - string tableName = (string) tables["TABLE_NAME"]; - string comment = (string) tables["TABLE_COMMENT"]; - if (tableList.ContainsKey(tableName)) - tableList[tableName] = comment; - } - catch (Exception e) - { - MainLog.Instance.Error(e.ToString()); - } - } - tables.Close(); - } - } - } - - - // at some time this code should be cleaned up - - /// - /// Runs a query with protection against SQL Injection by using parameterised input. - /// - /// The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y - /// The parameters - index so that @y is indexed as 'y' - /// A MySQL DB Command - public IDbCommand Query(string sql, Dictionary parameters) - { - try - { - MySqlCommand dbcommand = (MySqlCommand) dbcon.CreateCommand(); - dbcommand.CommandText = sql; - foreach (KeyValuePair param in parameters) - { - dbcommand.Parameters.AddWithValue(param.Key, param.Value); - } - - return (IDbCommand) dbcommand; - } - catch - { - lock (dbcon) - { - // Close the DB connection - try - { - dbcon.Close(); - } - catch - { - } - - // Try reopen it - try - { - dbcon = new MySqlConnection(connectionString); - dbcon.Open(); - } - catch (Exception e) - { - MainLog.Instance.Error("Unable to reconnect to database " + e.ToString()); - } - - // Run the query again - try - { - MySqlCommand dbcommand = (MySqlCommand) dbcon.CreateCommand(); - dbcommand.CommandText = sql; - foreach (KeyValuePair param in parameters) - { - dbcommand.Parameters.AddWithValue(param.Key, param.Value); - } - - return (IDbCommand) dbcommand; - } - catch (Exception e) - { - // Return null if it fails. - MainLog.Instance.Error("Failed during Query generation: " + e.ToString()); - return null; - } - } - } - } - - /// - /// Reads a region row from a database reader - /// - /// An active database reader - /// A region profile - public RegionProfileData readSimRow(IDataReader reader) - { - RegionProfileData retval = new RegionProfileData(); - - if (reader.Read()) - { - // Region Main - retval.regionHandle = Convert.ToUInt64(reader["regionHandle"].ToString()); - retval.regionName = (string) reader["regionName"]; - retval.UUID = new LLUUID((string) reader["uuid"]); - - // Secrets - retval.regionRecvKey = (string) reader["regionRecvKey"]; - retval.regionSecret = (string) reader["regionSecret"]; - retval.regionSendKey = (string) reader["regionSendKey"]; - - // Region Server - retval.regionDataURI = (string) reader["regionDataURI"]; - retval.regionOnline = false; // Needs to be pinged before this can be set. - retval.serverIP = (string) reader["serverIP"]; - retval.serverPort = uint.Parse(reader["serverPort"].ToString()); - //retval.serverPort = (uint) reader["serverPort"]; // this caused exceptions - retval.serverURI = (string) reader["serverURI"]; - retval.httpPort = Convert.ToUInt32(reader["serverHttpPort"].ToString()); - retval.remotingPort = Convert.ToUInt32(reader["serverRemotingPort"].ToString()); - - // Location - retval.regionLocX = Convert.ToUInt32(reader["locX"].ToString()); - retval.regionLocY = Convert.ToUInt32(reader["locY"].ToString()); - retval.regionLocZ = Convert.ToUInt32(reader["locZ"].ToString()); - - // Neighbours - 0 = No Override - retval.regionEastOverrideHandle = Convert.ToUInt64(reader["eastOverrideHandle"].ToString()); - retval.regionWestOverrideHandle = Convert.ToUInt64(reader["westOverrideHandle"].ToString()); - retval.regionSouthOverrideHandle = Convert.ToUInt64(reader["southOverrideHandle"].ToString()); - retval.regionNorthOverrideHandle = Convert.ToUInt64(reader["northOverrideHandle"].ToString()); - - // Assets - retval.regionAssetURI = (string) reader["regionAssetURI"]; - retval.regionAssetRecvKey = (string) reader["regionAssetRecvKey"]; - retval.regionAssetSendKey = (string) reader["regionAssetSendKey"]; - - // Userserver - retval.regionUserURI = (string) reader["regionUserURI"]; - retval.regionUserRecvKey = (string) reader["regionUserRecvKey"]; - retval.regionUserSendKey = (string) reader["regionUserSendKey"]; - - // World Map Addition - string tempRegionMap = reader["regionMapTexture"].ToString(); - if (tempRegionMap != "") - { - retval.regionMapTextureID = new LLUUID(tempRegionMap); - } - else - { - retval.regionMapTextureID = LLUUID.Zero; - } - } - else - { - return null; - } - return retval; - } - - /// - /// Reads a reservation row from a database reader - /// - /// An active database reader - /// A reservation data object - public ReservationData readReservationRow(IDataReader reader) - { - ReservationData retval = new ReservationData(); - if (reader.Read()) - { - retval.gridRecvKey = (string) reader["gridRecvKey"]; - retval.gridSendKey = (string) reader["gridSendKey"]; - retval.reservationCompany = (string) reader["resCompany"]; - retval.reservationMaxX = Convert.ToInt32(reader["resXMax"].ToString()); - retval.reservationMaxY = Convert.ToInt32(reader["resYMax"].ToString()); - retval.reservationMinX = Convert.ToInt32(reader["resXMin"].ToString()); - retval.reservationMinY = Convert.ToInt32(reader["resYMin"].ToString()); - retval.reservationName = (string) reader["resName"]; - retval.status = Convert.ToInt32(reader["status"].ToString()) == 1; - retval.userUUID = new LLUUID((string) reader["userUUID"]); - } - else - { - return null; - } - return retval; - } - - /// - /// Reads an agent row from a database reader - /// - /// An active database reader - /// A user session agent - public UserAgentData readAgentRow(IDataReader reader) - { - UserAgentData retval = new UserAgentData(); - - if (reader.Read()) - { - // Agent IDs - retval.UUID = new LLUUID((string) reader["UUID"]); - retval.sessionID = new LLUUID((string) reader["sessionID"]); - retval.secureSessionID = new LLUUID((string) reader["secureSessionID"]); - - // Agent Who? - retval.agentIP = (string) reader["agentIP"]; - retval.agentPort = Convert.ToUInt32(reader["agentPort"].ToString()); - retval.agentOnline = Convert.ToBoolean(reader["agentOnline"].ToString()); - - // Login/Logout times (UNIX Epoch) - retval.loginTime = Convert.ToInt32(reader["loginTime"].ToString()); - retval.logoutTime = Convert.ToInt32(reader["logoutTime"].ToString()); - - // Current position - retval.currentRegion = (string) reader["currentRegion"]; - retval.currentHandle = Convert.ToUInt64(reader["currentHandle"].ToString()); - LLVector3.TryParse((string) reader["currentPos"], out retval.currentPos); - } - else - { - return null; - } - return retval; - } - - /// - /// Reads a user profile from an active data reader - /// - /// An active database reader - /// A user profile - public UserProfileData readUserRow(IDataReader reader) - { - UserProfileData retval = new UserProfileData(); - - if (reader.Read()) - { - retval.UUID = new LLUUID((string) reader["UUID"]); - retval.username = (string) reader["username"]; - retval.surname = (string) reader["lastname"]; - - retval.passwordHash = (string) reader["passwordHash"]; - retval.passwordSalt = (string) reader["passwordSalt"]; - - retval.homeRegion = Convert.ToUInt64(reader["homeRegion"].ToString()); - retval.homeLocation = new LLVector3( - Convert.ToSingle(reader["homeLocationX"].ToString()), - Convert.ToSingle(reader["homeLocationY"].ToString()), - Convert.ToSingle(reader["homeLocationZ"].ToString())); - retval.homeLookAt = new LLVector3( - Convert.ToSingle(reader["homeLookAtX"].ToString()), - Convert.ToSingle(reader["homeLookAtY"].ToString()), - Convert.ToSingle(reader["homeLookAtZ"].ToString())); - - retval.created = Convert.ToInt32(reader["created"].ToString()); - retval.lastLogin = Convert.ToInt32(reader["lastLogin"].ToString()); - - retval.userInventoryURI = (string) reader["userInventoryURI"]; - retval.userAssetURI = (string) reader["userAssetURI"]; - - retval.profileCanDoMask = Convert.ToUInt32(reader["profileCanDoMask"].ToString()); - retval.profileWantDoMask = Convert.ToUInt32(reader["profileWantDoMask"].ToString()); - - retval.profileAboutText = (string) reader["profileAboutText"]; - retval.profileFirstText = (string) reader["profileFirstText"]; - - retval.profileImage = new LLUUID((string) reader["profileImage"]); - retval.profileFirstImage = new LLUUID((string) reader["profileFirstImage"]); - retval.webLoginKey = new LLUUID((string)reader["webLoginKey"]); - } - else - { - return null; - } - return retval; - } - - - /// - /// Inserts a new row into the log database - /// - /// The daemon which triggered this event - /// Who were we operating on when this occured (region UUID, user UUID, etc) - /// The method call where the problem occured - /// The arguments passed to the method - /// How critical is this? - /// Extra message info - /// Saved successfully? - public bool insertLogRow(string serverDaemon, string target, string methodCall, string arguments, int priority, - string logMessage) - { - string sql = "INSERT INTO logs (`target`, `server`, `method`, `arguments`, `priority`, `message`) VALUES "; - sql += "(?target, ?server, ?method, ?arguments, ?priority, ?message)"; - - Dictionary parameters = new Dictionary(); - parameters["?server"] = serverDaemon; - parameters["?target"] = target; - parameters["?method"] = methodCall; - parameters["?arguments"] = arguments; - parameters["?priority"] = priority.ToString(); - parameters["?message"] = logMessage; - - bool returnval = false; - - try - { - IDbCommand result = Query(sql, parameters); - - if (result.ExecuteNonQuery() == 1) - returnval = true; - - result.Dispose(); - } - catch (Exception e) - { - MainLog.Instance.Error(e.ToString()); - return false; - } - - return returnval; - } - - - /// - /// Creates a new user and inserts it into the database - /// - /// User ID - /// First part of the login - /// Second part of the login - /// A salted hash of the users password - /// The salt used for the password hash - /// A regionHandle of the users home region - /// Home region position vector - /// Home region position vector - /// Home region position vector - /// Home region 'look at' vector - /// Home region 'look at' vector - /// Home region 'look at' vector - /// Account created (unix timestamp) - /// Last login (unix timestamp) - /// Users inventory URI - /// Users asset URI - /// I can do mask - /// I want to do mask - /// Profile text - /// Firstlife text - /// UUID for profile image - /// UUID for firstlife image - /// Success? - public bool insertUserRow(LLUUID uuid, string username, string lastname, string passwordHash, - string passwordSalt, UInt64 homeRegion, float homeLocX, float homeLocY, float homeLocZ, - float homeLookAtX, float homeLookAtY, float homeLookAtZ, int created, int lastlogin, - string inventoryURI, string assetURI, uint canDoMask, uint wantDoMask, - string aboutText, string firstText, - LLUUID profileImage, LLUUID firstImage, LLUUID webLoginKey) - { - string sql = - "INSERT INTO users (`UUID`, `username`, `lastname`, `passwordHash`, `passwordSalt`, `homeRegion`, "; - sql += - "`homeLocationX`, `homeLocationY`, `homeLocationZ`, `homeLookAtX`, `homeLookAtY`, `homeLookAtZ`, `created`, "; - sql += - "`lastLogin`, `userInventoryURI`, `userAssetURI`, `profileCanDoMask`, `profileWantDoMask`, `profileAboutText`, "; - sql += "`profileFirstText`, `profileImage`, `profileFirstImage`, `webLoginKey`) VALUES "; - - sql += "(?UUID, ?username, ?lastname, ?passwordHash, ?passwordSalt, ?homeRegion, "; - sql += - "?homeLocationX, ?homeLocationY, ?homeLocationZ, ?homeLookAtX, ?homeLookAtY, ?homeLookAtZ, ?created, "; - sql += - "?lastLogin, ?userInventoryURI, ?userAssetURI, ?profileCanDoMask, ?profileWantDoMask, ?profileAboutText, "; - sql += "?profileFirstText, ?profileImage, ?profileFirstImage, ?webLoginKey)"; - - Dictionary parameters = new Dictionary(); - parameters["?UUID"] = uuid.ToString(); - parameters["?username"] = username.ToString(); - parameters["?lastname"] = lastname.ToString(); - parameters["?passwordHash"] = passwordHash.ToString(); - parameters["?passwordSalt"] = passwordSalt.ToString(); - parameters["?homeRegion"] = homeRegion.ToString(); - parameters["?homeLocationX"] = homeLocX.ToString(); - parameters["?homeLocationY"] = homeLocY.ToString(); - parameters["?homeLocationZ"] = homeLocZ.ToString(); - parameters["?homeLookAtX"] = homeLookAtX.ToString(); - parameters["?homeLookAtY"] = homeLookAtY.ToString(); - parameters["?homeLookAtZ"] = homeLookAtZ.ToString(); - parameters["?created"] = created.ToString(); - parameters["?lastLogin"] = lastlogin.ToString(); - parameters["?userInventoryURI"] = ""; - parameters["?userAssetURI"] = ""; - parameters["?profileCanDoMask"] = "0"; - parameters["?profileWantDoMask"] = "0"; - parameters["?profileAboutText"] = ""; - parameters["?profileFirstText"] = ""; - parameters["?profileImage"] = LLUUID.Zero.ToString(); - parameters["?profileFirstImage"] = LLUUID.Zero.ToString(); - parameters["?webLoginKey"] = LLUUID.Random().ToString(); - - bool returnval = false; - - try - { - IDbCommand result = Query(sql, parameters); - - if (result.ExecuteNonQuery() == 1) - returnval = true; - - result.Dispose(); - } - catch (Exception e) - { - MainLog.Instance.Error(e.ToString()); - return false; - } - - return returnval; - } - - - /// - /// Inserts a new region into the database - /// - /// The region to insert - /// Success? - public bool insertRegion(RegionProfileData regiondata) - { - bool GRID_ONLY_UPDATE_NECESSARY_DATA = false; - - string sql = ""; - if (GRID_ONLY_UPDATE_NECESSARY_DATA) - { - sql += "INSERT INTO "; - } - else - { - sql += "REPLACE INTO "; - } - - sql += "regions (regionHandle, regionName, uuid, regionRecvKey, regionSecret, regionSendKey, regionDataURI, "; - sql += - "serverIP, serverPort, serverURI, locX, locY, locZ, eastOverrideHandle, westOverrideHandle, southOverrideHandle, northOverrideHandle, regionAssetURI, regionAssetRecvKey, "; - sql += - "regionAssetSendKey, regionUserURI, regionUserRecvKey, regionUserSendKey, regionMapTexture, serverHttpPort, serverRemotingPort) VALUES "; - - sql += "(?regionHandle, ?regionName, ?uuid, ?regionRecvKey, ?regionSecret, ?regionSendKey, ?regionDataURI, "; - sql += - "?serverIP, ?serverPort, ?serverURI, ?locX, ?locY, ?locZ, ?eastOverrideHandle, ?westOverrideHandle, ?southOverrideHandle, ?northOverrideHandle, ?regionAssetURI, ?regionAssetRecvKey, "; - sql += - "?regionAssetSendKey, ?regionUserURI, ?regionUserRecvKey, ?regionUserSendKey, ?regionMapTexture, ?serverHttpPort, ?serverRemotingPort)"; - - if (GRID_ONLY_UPDATE_NECESSARY_DATA) - { - sql += "ON DUPLICATE KEY UPDATE serverIP = ?serverIP, serverPort = ?serverPort, serverURI = ?serverURI;"; - } - else - { - sql += ";"; - } - - Dictionary parameters = new Dictionary(); - - parameters["?regionHandle"] = regiondata.regionHandle.ToString(); - parameters["?regionName"] = regiondata.regionName.ToString(); - parameters["?uuid"] = regiondata.UUID.ToString(); - parameters["?regionRecvKey"] = regiondata.regionRecvKey.ToString(); - parameters["?regionSecret"] = regiondata.regionSecret.ToString(); - parameters["?regionSendKey"] = regiondata.regionSendKey.ToString(); - parameters["?regionDataURI"] = regiondata.regionDataURI.ToString(); - parameters["?serverIP"] = regiondata.serverIP.ToString(); - parameters["?serverPort"] = regiondata.serverPort.ToString(); - parameters["?serverURI"] = regiondata.serverURI.ToString(); - parameters["?locX"] = regiondata.regionLocX.ToString(); - parameters["?locY"] = regiondata.regionLocY.ToString(); - parameters["?locZ"] = regiondata.regionLocZ.ToString(); - parameters["?eastOverrideHandle"] = regiondata.regionEastOverrideHandle.ToString(); - parameters["?westOverrideHandle"] = regiondata.regionWestOverrideHandle.ToString(); - parameters["?northOverrideHandle"] = regiondata.regionNorthOverrideHandle.ToString(); - parameters["?southOverrideHandle"] = regiondata.regionSouthOverrideHandle.ToString(); - parameters["?regionAssetURI"] = regiondata.regionAssetURI.ToString(); - parameters["?regionAssetRecvKey"] = regiondata.regionAssetRecvKey.ToString(); - parameters["?regionAssetSendKey"] = regiondata.regionAssetSendKey.ToString(); - parameters["?regionUserURI"] = regiondata.regionUserURI.ToString(); - parameters["?regionUserRecvKey"] = regiondata.regionUserRecvKey.ToString(); - parameters["?regionUserSendKey"] = regiondata.regionUserSendKey.ToString(); - parameters["?regionMapTexture"] = regiondata.regionMapTextureID.ToString(); - parameters["?serverHttpPort"] = regiondata.httpPort.ToString(); - parameters["?serverRemotingPort"] = regiondata.remotingPort.ToString(); - bool returnval = false; - - try - { - IDbCommand result = Query(sql, parameters); - - //Console.WriteLine(result.CommandText); - int x; - if ((x = result.ExecuteNonQuery()) > 0) - { - returnval = true; - } - result.Dispose(); - } - catch (Exception e) - { - MainLog.Instance.Error(e.ToString()); - return false; - } - - return returnval; - } - } -} \ No newline at end of file +/* +* 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.Generic; +using System.Data; +using System.Data.SqlClient; +using System.IO; +using System.Reflection; +using libsecondlife; +using MySql.Data.MySqlClient; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Data.MySQL +{ + /// + /// A MySQL Database manager + /// + internal class MySQLManager + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// The database connection object + /// + private MySqlConnection dbcon; + + /// + /// Connection string for ADO.net + /// + private string connectionString; + + /// + /// Initialises and creates a new MySQL connection and maintains it. + /// + /// The MySQL server being connected to + /// The name of the MySQL database being used + /// The username logging into the database + /// The password for the user logging in + /// Whether to use connection pooling or not, can be one of the following: 'yes', 'true', 'no' or 'false', if unsure use 'false'. + public MySQLManager(string hostname, string database, string username, string password, string cpooling, + string port) + { + try + { + connectionString = "Server=" + hostname + ";Port=" + port + ";Database=" + database + ";User ID=" + + username + ";Password=" + password + ";Pooling=" + cpooling + ";"; + dbcon = new MySqlConnection(connectionString); + + try + { + dbcon.Open(); + } + catch(Exception e) + { + throw new Exception( "Connection error while using connection string ["+connectionString+"]", e ); + } + + m_log.Info("[MYSQL]: Connection established"); + } + catch (Exception e) + { + throw new Exception("Error initialising MySql Database: " + e.ToString()); + } + } + + /// + /// Get the connection being used + /// + public MySqlConnection Connection + { + get { return dbcon; } + } + + /// + /// Shuts down the database connection + /// + public void Close() + { + dbcon.Close(); + dbcon = null; + } + + /// + /// Reconnects to the database + /// + public void Reconnect() + { + lock (dbcon) + { + try + { + // Close the DB connection + dbcon.Close(); + // Try reopen it + dbcon = new MySqlConnection(connectionString); + dbcon.Open(); + } + catch (Exception e) + { + m_log.Error("Unable to reconnect to database " + e.ToString()); + } + } + } + + /// + /// Returns the version of this DB provider + /// + /// A string containing the DB provider + public string getVersion() + { + Module module = GetType().Module; + string dllName = module.Assembly.ManifestModule.Name; + Version dllVersion = module.Assembly.GetName().Version; + + + return + string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build, + dllVersion.Revision); + } + + + /// + /// Extract a named string resource from the embedded resources + /// + /// name of embedded resource + /// string contained within the embedded resource + private string getResourceString(string name) + { + Assembly assem = GetType().Assembly; + string[] names = assem.GetManifestResourceNames(); + + foreach (string s in names) + if (s.EndsWith(name)) + using (Stream resource = assem.GetManifestResourceStream(s)) + { + using (StreamReader resourceReader = new StreamReader(resource)) + { + string resourceString = resourceReader.ReadToEnd(); + return resourceString; + } + } + throw new Exception(string.Format("Resource '{0}' was not found", name)); + } + + /// + /// Execute a SQL statement stored in a resource, as a string + /// + /// + public void ExecuteResourceSql(string name) + { + MySqlCommand cmd = new MySqlCommand(getResourceString(name), dbcon); + cmd.ExecuteNonQuery(); + } + + /// + /// Given a list of tables, return the version of the tables, as seen in the database + /// + /// + public void GetTableVersion(Dictionary tableList) + { + lock (dbcon) + { + MySqlCommand tablesCmd = + new MySqlCommand( + "SELECT TABLE_NAME, TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=?dbname", + dbcon); + tablesCmd.Parameters.AddWithValue("?dbname", dbcon.Database); + using (MySqlDataReader tables = tablesCmd.ExecuteReader()) + { + while (tables.Read()) + { + try + { + string tableName = (string) tables["TABLE_NAME"]; + string comment = (string) tables["TABLE_COMMENT"]; + if (tableList.ContainsKey(tableName)) + { + tableList[tableName] = comment; + } + } + catch (Exception e) + { + m_log.Error(e.ToString()); + } + } + tables.Close(); + } + } + } + + + // at some time this code should be cleaned up + + /// + /// Runs a query with protection against SQL Injection by using parameterised input. + /// + /// The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y + /// The parameters - index so that @y is indexed as 'y' + /// A MySQL DB Command + public IDbCommand Query(string sql, Dictionary parameters) + { + try + { + MySqlCommand dbcommand = (MySqlCommand) dbcon.CreateCommand(); + dbcommand.CommandText = sql; + foreach (KeyValuePair param in parameters) + { + dbcommand.Parameters.AddWithValue(param.Key, param.Value); + } + + return (IDbCommand) dbcommand; + } + catch + { + lock (dbcon) + { + // Close the DB connection + try + { + dbcon.Close(); + } + catch + { + } + + // Try reopen it + try + { + dbcon = new MySqlConnection(connectionString); + dbcon.Open(); + } + catch (Exception e) + { + m_log.Error("Unable to reconnect to database " + e.ToString()); + } + + // Run the query again + try + { + MySqlCommand dbcommand = (MySqlCommand) dbcon.CreateCommand(); + dbcommand.CommandText = sql; + foreach (KeyValuePair param in parameters) + { + dbcommand.Parameters.AddWithValue(param.Key, param.Value); + } + + return (IDbCommand) dbcommand; + } + catch (Exception e) + { + // Return null if it fails. + m_log.Error("Failed during Query generation: " + e.ToString()); + return null; + } + } + } + } + + /// + /// Reads a region row from a database reader + /// + /// An active database reader + /// A region profile + public RegionProfileData readSimRow(IDataReader reader) + { + RegionProfileData retval = new RegionProfileData(); + + if (reader.Read()) + { + // Region Main + retval.regionHandle = Convert.ToUInt64(reader["regionHandle"].ToString()); + retval.regionName = (string) reader["regionName"]; + retval.UUID = new LLUUID((string) reader["uuid"]); + + // Secrets + retval.regionRecvKey = (string) reader["regionRecvKey"]; + retval.regionSecret = (string) reader["regionSecret"]; + retval.regionSendKey = (string) reader["regionSendKey"]; + + // Region Server + retval.regionDataURI = (string) reader["regionDataURI"]; + retval.regionOnline = false; // Needs to be pinged before this can be set. + retval.serverIP = (string) reader["serverIP"]; + retval.serverPort = uint.Parse(reader["serverPort"].ToString()); + //retval.serverPort = (uint) reader["serverPort"]; // this caused exceptions + retval.serverURI = (string) reader["serverURI"]; + retval.httpPort = Convert.ToUInt32(reader["serverHttpPort"].ToString()); + retval.remotingPort = Convert.ToUInt32(reader["serverRemotingPort"].ToString()); + + // Location + retval.regionLocX = Convert.ToUInt32(reader["locX"].ToString()); + retval.regionLocY = Convert.ToUInt32(reader["locY"].ToString()); + retval.regionLocZ = Convert.ToUInt32(reader["locZ"].ToString()); + + // Neighbours - 0 = No Override + retval.regionEastOverrideHandle = Convert.ToUInt64(reader["eastOverrideHandle"].ToString()); + retval.regionWestOverrideHandle = Convert.ToUInt64(reader["westOverrideHandle"].ToString()); + retval.regionSouthOverrideHandle = Convert.ToUInt64(reader["southOverrideHandle"].ToString()); + retval.regionNorthOverrideHandle = Convert.ToUInt64(reader["northOverrideHandle"].ToString()); + + // Assets + retval.regionAssetURI = (string) reader["regionAssetURI"]; + retval.regionAssetRecvKey = (string) reader["regionAssetRecvKey"]; + retval.regionAssetSendKey = (string) reader["regionAssetSendKey"]; + + // Userserver + retval.regionUserURI = (string) reader["regionUserURI"]; + retval.regionUserRecvKey = (string) reader["regionUserRecvKey"]; + retval.regionUserSendKey = (string) reader["regionUserSendKey"]; + + // World Map Addition + string tempRegionMap = reader["regionMapTexture"].ToString(); + if (tempRegionMap != String.Empty) + { + retval.regionMapTextureID = new LLUUID(tempRegionMap); + } + else + { + retval.regionMapTextureID = LLUUID.Zero; + } + + // part of an initial brutish effort to provide accurate information (as per the xml region spec) + // wrt the ownership of a given region + // the (very bad) assumption is that this value is being read and handled inconsistently or + // not at all. Current strategy is to put the code in place to support the validity of this information + // and to roll forward debugging any issues from that point + // + // this particular section of the mod attempts to supply a value from the region table to the caller of 'readSimRow()' + // for the UUID of the region's owner (master avatar) + try + { + retval.owner_uuid = new LLUUID((string)reader["owner_uuid"]); + } + catch + { + retval.owner_uuid = LLUUID.Zero; + } + } + else + { + return null; + } + return retval; + } + + /// + /// Reads a reservation row from a database reader + /// + /// An active database reader + /// A reservation data object + public ReservationData readReservationRow(IDataReader reader) + { + ReservationData retval = new ReservationData(); + if (reader.Read()) + { + retval.gridRecvKey = (string) reader["gridRecvKey"]; + retval.gridSendKey = (string) reader["gridSendKey"]; + retval.reservationCompany = (string) reader["resCompany"]; + retval.reservationMaxX = Convert.ToInt32(reader["resXMax"].ToString()); + retval.reservationMaxY = Convert.ToInt32(reader["resYMax"].ToString()); + retval.reservationMinX = Convert.ToInt32(reader["resXMin"].ToString()); + retval.reservationMinY = Convert.ToInt32(reader["resYMin"].ToString()); + retval.reservationName = (string) reader["resName"]; + retval.status = Convert.ToInt32(reader["status"].ToString()) == 1; + retval.userUUID = new LLUUID((string) reader["userUUID"]); + } + else + { + return null; + } + return retval; + } + + /// + /// Reads an agent row from a database reader + /// + /// An active database reader + /// A user session agent + public UserAgentData readAgentRow(IDataReader reader) + { + UserAgentData retval = new UserAgentData(); + + if (reader.Read()) + { + // Agent IDs + retval.UUID = new LLUUID((string) reader["UUID"]); + retval.sessionID = new LLUUID((string) reader["sessionID"]); + retval.secureSessionID = new LLUUID((string) reader["secureSessionID"]); + + // Agent Who? + retval.agentIP = (string) reader["agentIP"]; + retval.agentPort = Convert.ToUInt32(reader["agentPort"].ToString()); + retval.agentOnline = Convert.ToBoolean(reader["agentOnline"].ToString()); + + // Login/Logout times (UNIX Epoch) + retval.loginTime = Convert.ToInt32(reader["loginTime"].ToString()); + retval.logoutTime = Convert.ToInt32(reader["logoutTime"].ToString()); + + // Current position + retval.currentRegion = (string) reader["currentRegion"]; + retval.currentHandle = Convert.ToUInt64(reader["currentHandle"].ToString()); + LLVector3.TryParse((string) reader["currentPos"], out retval.currentPos); + } + else + { + return null; + } + return retval; + } + + /// + /// Reads a user profile from an active data reader + /// + /// An active database reader + /// A user profile + public UserProfileData readUserRow(IDataReader reader) + { + UserProfileData retval = new UserProfileData(); + + if (reader.Read()) + { + retval.UUID = new LLUUID((string) reader["UUID"]); + retval.username = (string) reader["username"]; + retval.surname = (string) reader["lastname"]; + + retval.passwordHash = (string) reader["passwordHash"]; + retval.passwordSalt = (string) reader["passwordSalt"]; + + retval.homeRegion = Convert.ToUInt64(reader["homeRegion"].ToString()); + retval.homeLocation = new LLVector3( + Convert.ToSingle(reader["homeLocationX"].ToString()), + Convert.ToSingle(reader["homeLocationY"].ToString()), + Convert.ToSingle(reader["homeLocationZ"].ToString())); + retval.homeLookAt = new LLVector3( + Convert.ToSingle(reader["homeLookAtX"].ToString()), + Convert.ToSingle(reader["homeLookAtY"].ToString()), + Convert.ToSingle(reader["homeLookAtZ"].ToString())); + + retval.created = Convert.ToInt32(reader["created"].ToString()); + retval.lastLogin = Convert.ToInt32(reader["lastLogin"].ToString()); + + retval.userInventoryURI = (string) reader["userInventoryURI"]; + retval.userAssetURI = (string) reader["userAssetURI"]; + + retval.profileCanDoMask = Convert.ToUInt32(reader["profileCanDoMask"].ToString()); + retval.profileWantDoMask = Convert.ToUInt32(reader["profileWantDoMask"].ToString()); + + retval.profileAboutText = (string) reader["profileAboutText"]; + retval.profileFirstText = (string) reader["profileFirstText"]; + + retval.profileImage = new LLUUID((string) reader["profileImage"]); + retval.profileFirstImage = new LLUUID((string) reader["profileFirstImage"]); + + if( reader.IsDBNull( reader.GetOrdinal( "webLoginKey" ) ) ) + { + retval.webLoginKey = LLUUID.Zero; + } + else + { + retval.webLoginKey = new LLUUID((string)reader["webLoginKey"]); + } + } + else + { + return null; + } + return retval; + } + + + /// + /// Inserts a new row into the log database + /// + /// The daemon which triggered this event + /// Who were we operating on when this occured (region UUID, user UUID, etc) + /// The method call where the problem occured + /// The arguments passed to the method + /// How critical is this? + /// Extra message info + /// Saved successfully? + public bool insertLogRow(string serverDaemon, string target, string methodCall, string arguments, int priority, + string logMessage) + { + string sql = "INSERT INTO logs (`target`, `server`, `method`, `arguments`, `priority`, `message`) VALUES "; + sql += "(?target, ?server, ?method, ?arguments, ?priority, ?message)"; + + Dictionary parameters = new Dictionary(); + parameters["?server"] = serverDaemon; + parameters["?target"] = target; + parameters["?method"] = methodCall; + parameters["?arguments"] = arguments; + parameters["?priority"] = priority.ToString(); + parameters["?message"] = logMessage; + + bool returnval = false; + + try + { + IDbCommand result = Query(sql, parameters); + + if (result.ExecuteNonQuery() == 1) + returnval = true; + + result.Dispose(); + } + catch (Exception e) + { + m_log.Error(e.ToString()); + return false; + } + + return returnval; + } + + + /// + /// Creates a new user and inserts it into the database + /// + /// User ID + /// First part of the login + /// Second part of the login + /// A salted hash of the users password + /// The salt used for the password hash + /// A regionHandle of the users home region + /// Home region position vector + /// Home region position vector + /// Home region position vector + /// Home region 'look at' vector + /// Home region 'look at' vector + /// Home region 'look at' vector + /// Account created (unix timestamp) + /// Last login (unix timestamp) + /// Users inventory URI + /// Users asset URI + /// I can do mask + /// I want to do mask + /// Profile text + /// Firstlife text + /// UUID for profile image + /// UUID for firstlife image + /// Success? + public bool insertUserRow(LLUUID uuid, string username, string lastname, string passwordHash, + string passwordSalt, UInt64 homeRegion, float homeLocX, float homeLocY, float homeLocZ, + float homeLookAtX, float homeLookAtY, float homeLookAtZ, int created, int lastlogin, + string inventoryURI, string assetURI, uint canDoMask, uint wantDoMask, + string aboutText, string firstText, + LLUUID profileImage, LLUUID firstImage, LLUUID webLoginKey) + { + string sql = + "INSERT INTO users (`UUID`, `username`, `lastname`, `passwordHash`, `passwordSalt`, `homeRegion`, "; + sql += + "`homeLocationX`, `homeLocationY`, `homeLocationZ`, `homeLookAtX`, `homeLookAtY`, `homeLookAtZ`, `created`, "; + sql += + "`lastLogin`, `userInventoryURI`, `userAssetURI`, `profileCanDoMask`, `profileWantDoMask`, `profileAboutText`, "; + sql += "`profileFirstText`, `profileImage`, `profileFirstImage`, `webLoginKey`) VALUES "; + + sql += "(?UUID, ?username, ?lastname, ?passwordHash, ?passwordSalt, ?homeRegion, "; + sql += + "?homeLocationX, ?homeLocationY, ?homeLocationZ, ?homeLookAtX, ?homeLookAtY, ?homeLookAtZ, ?created, "; + sql += + "?lastLogin, ?userInventoryURI, ?userAssetURI, ?profileCanDoMask, ?profileWantDoMask, ?profileAboutText, "; + sql += "?profileFirstText, ?profileImage, ?profileFirstImage, ?webLoginKey)"; + + Dictionary parameters = new Dictionary(); + parameters["?UUID"] = uuid.ToString(); + parameters["?username"] = username.ToString(); + parameters["?lastname"] = lastname.ToString(); + parameters["?passwordHash"] = passwordHash.ToString(); + parameters["?passwordSalt"] = passwordSalt.ToString(); + parameters["?homeRegion"] = homeRegion.ToString(); + parameters["?homeLocationX"] = homeLocX.ToString(); + parameters["?homeLocationY"] = homeLocY.ToString(); + parameters["?homeLocationZ"] = homeLocZ.ToString(); + parameters["?homeLookAtX"] = homeLookAtX.ToString(); + parameters["?homeLookAtY"] = homeLookAtY.ToString(); + parameters["?homeLookAtZ"] = homeLookAtZ.ToString(); + parameters["?created"] = created.ToString(); + parameters["?lastLogin"] = lastlogin.ToString(); + parameters["?userInventoryURI"] = String.Empty; + parameters["?userAssetURI"] = String.Empty; + parameters["?profileCanDoMask"] = "0"; + parameters["?profileWantDoMask"] = "0"; + parameters["?profileAboutText"] = String.Empty; + parameters["?profileFirstText"] = String.Empty; + parameters["?profileImage"] = LLUUID.Zero.ToString(); + parameters["?profileFirstImage"] = LLUUID.Zero.ToString(); + parameters["?webLoginKey"] = LLUUID.Random().ToString(); + + bool returnval = false; + + try + { + IDbCommand result = Query(sql, parameters); + + if (result.ExecuteNonQuery() == 1) + returnval = true; + + result.Dispose(); + } + catch (Exception e) + { + m_log.Error(e.ToString()); + return false; + } + + return returnval; + } + + + /// + /// Inserts a new region into the database + /// + /// The region to insert + /// Success? + public bool insertRegion(RegionProfileData regiondata) + { + bool GRID_ONLY_UPDATE_NECESSARY_DATA = false; + + string sql = String.Empty; + if (GRID_ONLY_UPDATE_NECESSARY_DATA) + { + sql += "INSERT INTO "; + } + else + { + sql += "REPLACE INTO "; + } + + sql += "regions (regionHandle, regionName, uuid, regionRecvKey, regionSecret, regionSendKey, regionDataURI, "; + sql += + "serverIP, serverPort, serverURI, locX, locY, locZ, eastOverrideHandle, westOverrideHandle, southOverrideHandle, northOverrideHandle, regionAssetURI, regionAssetRecvKey, "; + + // part of an initial brutish effort to provide accurate information (as per the xml region spec) + // wrt the ownership of a given region + // the (very bad) assumption is that this value is being read and handled inconsistently or + // not at all. Current strategy is to put the code in place to support the validity of this information + // and to roll forward debugging any issues from that point + // + // this particular section of the mod attempts to implement the commit of a supplied value + // server for the UUID of the region's owner (master avatar). It consists of the addition of the column and value to the relevant sql, + // as well as the related parameterization + sql += + "regionAssetSendKey, regionUserURI, regionUserRecvKey, regionUserSendKey, regionMapTexture, serverHttpPort, serverRemotingPort, owner_uuid) VALUES "; + + sql += "(?regionHandle, ?regionName, ?uuid, ?regionRecvKey, ?regionSecret, ?regionSendKey, ?regionDataURI, "; + sql += + "?serverIP, ?serverPort, ?serverURI, ?locX, ?locY, ?locZ, ?eastOverrideHandle, ?westOverrideHandle, ?southOverrideHandle, ?northOverrideHandle, ?regionAssetURI, ?regionAssetRecvKey, "; + sql += + "?regionAssetSendKey, ?regionUserURI, ?regionUserRecvKey, ?regionUserSendKey, ?regionMapTexture, ?serverHttpPort, ?serverRemotingPort, ?owner_uuid)"; + + if (GRID_ONLY_UPDATE_NECESSARY_DATA) + { + sql += "ON DUPLICATE KEY UPDATE serverIP = ?serverIP, serverPort = ?serverPort, serverURI = ?serverURI, owner_uuid - ?owner_uuid;"; + } + else + { + sql += ";"; + } + + Dictionary parameters = new Dictionary(); + + parameters["?regionHandle"] = regiondata.regionHandle.ToString(); + parameters["?regionName"] = regiondata.regionName.ToString(); + parameters["?uuid"] = regiondata.UUID.ToString(); + parameters["?regionRecvKey"] = regiondata.regionRecvKey.ToString(); + parameters["?regionSecret"] = regiondata.regionSecret.ToString(); + parameters["?regionSendKey"] = regiondata.regionSendKey.ToString(); + parameters["?regionDataURI"] = regiondata.regionDataURI.ToString(); + parameters["?serverIP"] = regiondata.serverIP.ToString(); + parameters["?serverPort"] = regiondata.serverPort.ToString(); + parameters["?serverURI"] = regiondata.serverURI.ToString(); + parameters["?locX"] = regiondata.regionLocX.ToString(); + parameters["?locY"] = regiondata.regionLocY.ToString(); + parameters["?locZ"] = regiondata.regionLocZ.ToString(); + parameters["?eastOverrideHandle"] = regiondata.regionEastOverrideHandle.ToString(); + parameters["?westOverrideHandle"] = regiondata.regionWestOverrideHandle.ToString(); + parameters["?northOverrideHandle"] = regiondata.regionNorthOverrideHandle.ToString(); + parameters["?southOverrideHandle"] = regiondata.regionSouthOverrideHandle.ToString(); + parameters["?regionAssetURI"] = regiondata.regionAssetURI.ToString(); + parameters["?regionAssetRecvKey"] = regiondata.regionAssetRecvKey.ToString(); + parameters["?regionAssetSendKey"] = regiondata.regionAssetSendKey.ToString(); + parameters["?regionUserURI"] = regiondata.regionUserURI.ToString(); + parameters["?regionUserRecvKey"] = regiondata.regionUserRecvKey.ToString(); + parameters["?regionUserSendKey"] = regiondata.regionUserSendKey.ToString(); + parameters["?regionMapTexture"] = regiondata.regionMapTextureID.ToString(); + parameters["?serverHttpPort"] = regiondata.httpPort.ToString(); + parameters["?serverRemotingPort"] = regiondata.remotingPort.ToString(); + parameters["?owner_uuid"] = regiondata.owner_uuid.ToString(); + + bool returnval = false; + + try + { + IDbCommand result = Query(sql, parameters); + + //Console.WriteLine(result.CommandText); + int x; + if ((x = result.ExecuteNonQuery()) > 0) + { + returnval = true; + } + result.Dispose(); + } + catch (Exception e) + { + m_log.Error(e.ToString()); + return false; + } + + return returnval; + } + } +} diff --git a/OpenSim/Framework/Data.MySQL/MySQLUserData.cs b/OpenSim/Framework/Data.MySQL/MySQLUserData.cs index 4fb0e782ab..04ef19e457 100644 --- a/OpenSim/Framework/Data.MySQL/MySQLUserData.cs +++ b/OpenSim/Framework/Data.MySQL/MySQLUserData.cs @@ -1,626 +1,677 @@ -/* -* 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.Generic; -using System.Data; -using System.Text.RegularExpressions; -using libsecondlife; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.Data.MySQL -{ - /// - /// A database interface class to a user profile storage system - /// - internal class MySQLUserData : IUserData - { - /// - /// Database manager for MySQL - /// - public MySQLManager database; - - /// - /// Loads and initialises the MySQL storage plugin - /// - public void Initialise() - { - // Load from an INI file connection details - // TODO: move this to XML? - IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini"); - string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname"); - string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database"); - string settingUsername = GridDataMySqlFile.ParseFileReadValue("username"); - string settingPassword = GridDataMySqlFile.ParseFileReadValue("password"); - string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling"); - string settingPort = GridDataMySqlFile.ParseFileReadValue("port"); - - database = - new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, settingPooling, - settingPort); - - TestTables(); - } - - #region Test and initialization code - - /// - /// Ensure that the user related tables exists and are at the latest version - /// - private void TestTables() - { - Dictionary tableList = new Dictionary(); - - tableList["agents"] = null; - tableList["users"] = null; - tableList["userfriends"] = null; - database.GetTableVersion(tableList); - - UpgradeAgentsTable(tableList["agents"]); - UpgradeUsersTable(tableList["users"]); - UpgradeFriendsTable(tableList["userfriends"]); - - } - - /// - /// Create or upgrade the table if necessary - /// - /// A null indicates that the table does not - /// currently exist - private void UpgradeAgentsTable(string oldVersion) - { - // null as the version, indicates that the table didn't exist - if (oldVersion == null) - { - database.ExecuteResourceSql("CreateAgentsTable.sql"); - return; - } - } - - /// - /// Create or upgrade the table if necessary - /// - /// A null indicates that the table does not - /// currently exist - private void UpgradeUsersTable(string oldVersion) - { - // null as the version, indicates that the table didn't exist - if (oldVersion == null) - { - database.ExecuteResourceSql("CreateUsersTable.sql"); - return; - } - else if (oldVersion.Contains("Rev. 1")) - { - database.ExecuteResourceSql("UpgradeUsersTableToVersion2.sql"); - return; - } - //MainLog.Instance.Verbose("DB","DBVers:" + oldVersion); - } - - /// - /// Create or upgrade the table if necessary - /// - /// A null indicates that the table does not - /// currently exist - private void UpgradeFriendsTable(string oldVersion) - { - // null as the version, indicates that the table didn't exist - if (oldVersion == null) - { - database.ExecuteResourceSql("CreateUserFriendsTable.sql"); - return; - } - } - - #endregion - - // see IUserData - public UserProfileData GetUserByName(string user, string last) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["?first"] = user; - param["?second"] = last; - - IDbCommand result = - database.Query("SELECT * FROM users WHERE username = ?first AND lastname = ?second", param); - IDataReader reader = result.ExecuteReader(); - - UserProfileData row = database.readUserRow(reader); - - reader.Close(); - result.Dispose(); - return row; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - - #region User Friends List Data - - public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms) - { - int dtvalue = Util.UnixTimeSinceEpoch(); - - Dictionary param = new Dictionary(); - param["?ownerID"] = friendlistowner.UUID.ToString(); - param["?friendID"] = friend.UUID.ToString(); - param["?friendPerms"] = perms.ToString(); - param["?datetimestamp"] = dtvalue.ToString(); - - try - { - lock (database) - { - IDbCommand adder = - database.Query( - "INSERT INTO `userfriends` " + - "(`ownerID`,`friendID`,`friendPerms`,`datetimestamp`) " + - "VALUES " + - "(?ownerID,?friendID,?friendPerms,?datetimestamp)", - param); - adder.ExecuteNonQuery(); - - adder = - database.Query( - "INSERT INTO `userfriends` " + - "(`ownerID`,`friendID`,`friendPerms`,`datetimestamp`) " + - "VALUES " + - "(?friendID,?ownerID,?friendPerms,?datetimestamp)", - param); - adder.ExecuteNonQuery(); - - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return; - } - } - - public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend) - { - Dictionary param = new Dictionary(); - param["?ownerID"] = friendlistowner.UUID.ToString(); - param["?friendID"] = friend.UUID.ToString(); - - - try - { - lock (database) - { - IDbCommand updater = - database.Query( - "delete from userfriends " + - "where ownerID = ?ownerID and friendID = ?friendID", - param); - updater.ExecuteNonQuery(); - - updater = - database.Query( - "delete from userfriends " + - "where ownerID = ?friendID and friendID = ?ownerID", - param); - updater.ExecuteNonQuery(); - - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return; - } - } - public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms) - { - Dictionary param = new Dictionary(); - param["?ownerID"] = friendlistowner.UUID.ToString(); - param["?friendID"] = friend.UUID.ToString(); - param["?friendPerms"] = perms.ToString(); - - - try - { - lock (database) - { - IDbCommand updater = - database.Query( - "update userfriends " + - "SET friendPerms = ?friendPerms " + - "where ownerID = ?ownerID and friendID = ?friendID", - param); - updater.ExecuteNonQuery(); - - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return; - } - } - - - public List GetUserFriendList(LLUUID friendlistowner) - { - List Lfli = new List(); - - Dictionary param = new Dictionary(); - param["?ownerID"] = friendlistowner.UUID.ToString(); - - try - { - lock (database) - { - //Left Join userfriends to itself - IDbCommand result = - database.Query( - "select a.ownerID,a.friendID,a.friendPerms,b.friendPerms as ownerperms from userfriends as a, userfriends as b" + - " where a.ownerID = ?ownerID and b.ownerID = a.friendID and b.friendID = a.ownerID", - param); - IDataReader reader = result.ExecuteReader(); - - - while (reader.Read()) - { - FriendListItem fli = new FriendListItem(); - fli.FriendListOwner = new LLUUID((string)reader["ownerID"]); - fli.Friend = new LLUUID((string)reader["friendID"]); - fli.FriendPerms = (uint)Convert.ToInt32(reader["friendPerms"]); - - // This is not a real column in the database table, it's a joined column from the opposite record - fli.FriendListOwnerPerms = (uint)Convert.ToInt32(reader["ownerperms"]); - - Lfli.Add(fli); - } - reader.Close(); - result.Dispose(); - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return Lfli; - } - - return Lfli; - } - - #endregion - - public void UpdateUserCurrentRegion(LLUUID avatarid, LLUUID regionuuid) - { - MainLog.Instance.Verbose("USER", "Stub UpdateUserCUrrentRegion called"); - } - - public void LogOffUser(LLUUID avatarid) - { - MainLog.Instance.Verbose("USER", "Stub LogOffUser called"); - } - - public List GeneratePickerResults(LLUUID queryID, string query) - { - List returnlist = new List(); - - Regex objAlphaNumericPattern = new Regex("[^a-zA-Z0-9]"); - - string[] querysplit; - querysplit = query.Split(' '); - if (querysplit.Length == 2) - { - Dictionary param = new Dictionary(); - param["?first"] = objAlphaNumericPattern.Replace(querysplit[0], "") + "%"; - param["?second"] = objAlphaNumericPattern.Replace(querysplit[1], "") + "%"; - try - { - lock (database) - { - IDbCommand result = - database.Query( - "SELECT UUID,username,lastname FROM users WHERE username like ?first AND lastname like ?second LIMIT 100", - param); - IDataReader reader = result.ExecuteReader(); - - - while (reader.Read()) - { - Framework.AvatarPickerAvatar user = new Framework.AvatarPickerAvatar(); - user.AvatarID = new LLUUID((string) reader["UUID"]); - user.firstName = (string) reader["username"]; - user.lastName = (string) reader["lastname"]; - returnlist.Add(user); - } - reader.Close(); - result.Dispose(); - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return returnlist; - } - } - else if (querysplit.Length == 1) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["?first"] = objAlphaNumericPattern.Replace(querysplit[0], "") + "%"; - - IDbCommand result = - database.Query( - "SELECT UUID,username,lastname FROM users WHERE username like ?first OR lastname like ?first LIMIT 100", - param); - IDataReader reader = result.ExecuteReader(); - - - while (reader.Read()) - { - Framework.AvatarPickerAvatar user = new Framework.AvatarPickerAvatar(); - user.AvatarID = new LLUUID((string) reader["UUID"]); - user.firstName = (string) reader["username"]; - user.lastName = (string) reader["lastname"]; - returnlist.Add(user); - } - reader.Close(); - result.Dispose(); - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return returnlist; - } - } - return returnlist; - } - - // see IUserData - public UserProfileData GetUserByUUID(LLUUID uuid) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["?uuid"] = uuid.ToString(); - - IDbCommand result = database.Query("SELECT * FROM users WHERE UUID = ?uuid", param); - IDataReader reader = result.ExecuteReader(); - - UserProfileData row = database.readUserRow(reader); - - reader.Close(); - result.Dispose(); - - return row; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - - /// - /// Searches the database for a specified user profile by account - /// - /// The account - /// The users profile - public UserProfileData GetUserByAccount(string account) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["?account"] = account; - - IDbCommand result = database.Query("SELECT * FROM users WHERE account = ?account", param); - IDataReader reader = result.ExecuteReader(); - - UserProfileData row = database.readUserRow(reader); - - reader.Close(); - result.Dispose(); - - return row; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - - /// - /// Returns a user session searching by name - /// - /// The account name - /// The users session - public UserAgentData GetAgentByName(string name) - { - return GetAgentByName(name.Split(' ')[0], name.Split(' ')[1]); - } - - /// - /// Returns a user session by account name - /// - /// First part of the users account name - /// Second part of the users account name - /// The users session - public UserAgentData GetAgentByName(string user, string last) - { - UserProfileData profile = GetUserByName(user, last); - return GetAgentByUUID(profile.UUID); - } - - /// - /// Returns an agent session by account UUID - /// - /// The accounts UUID - /// The users session - public UserAgentData GetAgentByUUID(LLUUID uuid) - { - try - { - lock (database) - { - Dictionary param = new Dictionary(); - param["?uuid"] = uuid.ToString(); - - IDbCommand result = database.Query("SELECT * FROM agents WHERE UUID = ?uuid", param); - IDataReader reader = result.ExecuteReader(); - - UserAgentData row = database.readAgentRow(reader); - - reader.Close(); - result.Dispose(); - - return row; - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - return null; - } - } - - /// - /// Creates a new users profile - /// - /// The user profile to create - public void AddNewUserProfile(UserProfileData user) - { - try - { - lock (database) - { - database.insertUserRow(user.UUID, user.username, user.surname, user.passwordHash, user.passwordSalt, - user.homeRegion, user.homeLocation.X, user.homeLocation.Y, - user.homeLocation.Z, - user.homeLookAt.X, user.homeLookAt.Y, user.homeLookAt.Z, user.created, - user.lastLogin, user.userInventoryURI, user.userAssetURI, - user.profileCanDoMask, user.profileWantDoMask, - user.profileAboutText, user.profileFirstText, user.profileImage, - user.profileFirstImage, user.webLoginKey); - } - } - catch (Exception e) - { - database.Reconnect(); - MainLog.Instance.Error(e.ToString()); - } - } - - /// - /// Creates a new agent - /// - /// The agent to create - public void AddNewUserAgent(UserAgentData agent) - { - // Do nothing. - } - - /// - /// Updates a user profile stored in the DB - /// - /// The profile data to use to update the DB - public bool UpdateUserProfile(UserProfileData user) - { - // TODO: implement - return true; - } - - /// - /// Performs a money transfer request between two accounts - /// - /// The senders account ID - /// The receivers account ID - /// The amount to transfer - /// Success? - public bool MoneyTransferRequest(LLUUID from, LLUUID to, uint amount) - { - return false; - } - - /// - /// Performs an inventory transfer request between two accounts - /// - /// TODO: Move to inventory server - /// The senders account ID - /// The receivers account ID - /// The item to transfer - /// Success? - public bool InventoryTransferRequest(LLUUID from, LLUUID to, LLUUID item) - { - return false; - } - - /// - /// Database provider name - /// - /// Provider name - public string getName() - { - return "MySQL Userdata Interface"; - } - - /// - /// Database provider version - /// - /// provider version - public string GetVersion() - { - return "0.1"; - } - } -} \ No newline at end of file +/* +* 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.Generic; +using System.Data; +using System.Text.RegularExpressions; +using libsecondlife; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Data.MySQL +{ + /// + /// A database interface class to a user profile storage system + /// + internal class MySQLUserData : IUserData + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// Database manager for MySQL + /// + public MySQLManager database; + + private string m_agentsTableName; + private string m_usersTableName; + private string m_userFriendsTableName; + + /// + /// Loads and initialises the MySQL storage plugin + /// + public void Initialise() + { + // Load from an INI file connection details + // TODO: move this to XML? Yes, PLEASE! + + IniFile iniFile = new IniFile("mysql_connection.ini"); + string settingHostname = iniFile.ParseFileReadValue("hostname"); + string settingDatabase = iniFile.ParseFileReadValue("database"); + string settingUsername = iniFile.ParseFileReadValue("username"); + string settingPassword = iniFile.ParseFileReadValue("password"); + string settingPooling = iniFile.ParseFileReadValue("pooling"); + string settingPort = iniFile.ParseFileReadValue("port"); + + m_usersTableName = iniFile.ParseFileReadValue("userstablename"); + if( m_usersTableName == null ) + { + m_usersTableName = "users"; + } + + m_userFriendsTableName = iniFile.ParseFileReadValue("userfriendstablename"); + if (m_userFriendsTableName == null) + { + m_userFriendsTableName = "userfriends"; + } + + m_agentsTableName = iniFile.ParseFileReadValue("agentstablename"); + if (m_agentsTableName == null) + { + m_agentsTableName = "agents"; + } + + database = + new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, settingPooling, + settingPort); + + TestTables(); + } + + #region Test and initialization code + + /// + /// Ensure that the user related tables exists and are at the latest version + /// + private void TestTables() + { + Dictionary tableList = new Dictionary(); + + tableList[m_agentsTableName] = null; + tableList[m_usersTableName] = null; + tableList[m_userFriendsTableName] = null; + database.GetTableVersion(tableList); + + UpgradeAgentsTable(tableList[m_agentsTableName]); + UpgradeUsersTable(tableList[m_usersTableName]); + UpgradeFriendsTable(tableList[m_userFriendsTableName]); + + } + + /// + /// Create or upgrade the table if necessary + /// + /// A null indicates that the table does not + /// currently exist + private void UpgradeAgentsTable(string oldVersion) + { + // null as the version, indicates that the table didn't exist + if (oldVersion == null) + { + database.ExecuteResourceSql("CreateAgentsTable.sql"); + return; + } + } + + /// + /// Create or upgrade the table if necessary + /// + /// A null indicates that the table does not + /// currently exist + private void UpgradeUsersTable(string oldVersion) + { + // null as the version, indicates that the table didn't exist + if (oldVersion == null) + { + database.ExecuteResourceSql("CreateUsersTable.sql"); + return; + } + else if (oldVersion.Contains("Rev. 1")) + { + database.ExecuteResourceSql("UpgradeUsersTableToVersion2.sql"); + return; + } + //m_log.Info("[DB]: DBVers:" + oldVersion); + } + + /// + /// Create or upgrade the table if necessary + /// + /// A null indicates that the table does not + /// currently exist + private void UpgradeFriendsTable(string oldVersion) + { + // null as the version, indicates that the table didn't exist + if (oldVersion == null) + { + database.ExecuteResourceSql("CreateUserFriendsTable.sql"); + return; + } + } + + #endregion + + // see IUserData + public UserProfileData GetUserByName(string user, string last) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?first"] = user; + param["?second"] = last; + + IDbCommand result = + database.Query("SELECT * FROM " + m_usersTableName + " WHERE username = ?first AND lastname = ?second", param); + IDataReader reader = result.ExecuteReader(); + + UserProfileData row = database.readUserRow(reader); + + reader.Close(); + result.Dispose(); + return row; + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return null; + } + } + + #region User Friends List Data + + public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms) + { + int dtvalue = Util.UnixTimeSinceEpoch(); + + Dictionary param = new Dictionary(); + param["?ownerID"] = friendlistowner.UUID.ToString(); + param["?friendID"] = friend.UUID.ToString(); + param["?friendPerms"] = perms.ToString(); + param["?datetimestamp"] = dtvalue.ToString(); + + try + { + lock (database) + { + IDbCommand adder = + database.Query( + "INSERT INTO `" + m_userFriendsTableName + "` " + + "(`ownerID`,`friendID`,`friendPerms`,`datetimestamp`) " + + "VALUES " + + "(?ownerID,?friendID,?friendPerms,?datetimestamp)", + param); + adder.ExecuteNonQuery(); + + adder = + database.Query( + "INSERT INTO `" + m_userFriendsTableName + "` " + + "(`ownerID`,`friendID`,`friendPerms`,`datetimestamp`) " + + "VALUES " + + "(?friendID,?ownerID,?friendPerms,?datetimestamp)", + param); + adder.ExecuteNonQuery(); + + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return; + } + } + + public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend) + { + Dictionary param = new Dictionary(); + param["?ownerID"] = friendlistowner.UUID.ToString(); + param["?friendID"] = friend.UUID.ToString(); + + + try + { + lock (database) + { + IDbCommand updater = + database.Query( + "delete from " + m_userFriendsTableName + " where ownerID = ?ownerID and friendID = ?friendID", + param); + updater.ExecuteNonQuery(); + + updater = + database.Query( + "delete from " + m_userFriendsTableName + " where ownerID = ?friendID and friendID = ?ownerID", + param); + updater.ExecuteNonQuery(); + + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return; + } + } + public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms) + { + Dictionary param = new Dictionary(); + param["?ownerID"] = friendlistowner.UUID.ToString(); + param["?friendID"] = friend.UUID.ToString(); + param["?friendPerms"] = perms.ToString(); + + + try + { + lock (database) + { + IDbCommand updater = + database.Query( + "update " + m_userFriendsTableName + + " SET friendPerms = ?friendPerms " + + "where ownerID = ?ownerID and friendID = ?friendID", + param); + updater.ExecuteNonQuery(); + + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return; + } + } + + + public List GetUserFriendList(LLUUID friendlistowner) + { + List Lfli = new List(); + + Dictionary param = new Dictionary(); + param["?ownerID"] = friendlistowner.UUID.ToString(); + + try + { + lock (database) + { + //Left Join userfriends to itself + IDbCommand result = + database.Query( + "select a.ownerID,a.friendID,a.friendPerms,b.friendPerms as ownerperms from " + m_userFriendsTableName + " as a, " + m_userFriendsTableName + " as b" + + " where a.ownerID = ?ownerID and b.ownerID = a.friendID and b.friendID = a.ownerID", + param); + IDataReader reader = result.ExecuteReader(); + + + while (reader.Read()) + { + FriendListItem fli = new FriendListItem(); + fli.FriendListOwner = new LLUUID((string)reader["ownerID"]); + fli.Friend = new LLUUID((string)reader["friendID"]); + fli.FriendPerms = (uint)Convert.ToInt32(reader["friendPerms"]); + + // This is not a real column in the database table, it's a joined column from the opposite record + fli.FriendListOwnerPerms = (uint)Convert.ToInt32(reader["ownerperms"]); + + Lfli.Add(fli); + } + reader.Close(); + result.Dispose(); + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return Lfli; + } + + return Lfli; + } + + #endregion + + public void UpdateUserCurrentRegion(LLUUID avatarid, LLUUID regionuuid) + { + m_log.Info("[USER]: Stub UpdateUserCUrrentRegion called"); + } + + + public List GeneratePickerResults(LLUUID queryID, string query) + { + List returnlist = new List(); + + Regex objAlphaNumericPattern = new Regex("[^a-zA-Z0-9]"); + + string[] querysplit; + querysplit = query.Split(' '); + if (querysplit.Length == 2) + { + Dictionary param = new Dictionary(); + param["?first"] = objAlphaNumericPattern.Replace(querysplit[0], String.Empty) + "%"; + param["?second"] = objAlphaNumericPattern.Replace(querysplit[1], String.Empty) + "%"; + try + { + lock (database) + { + IDbCommand result = + database.Query( + "SELECT UUID,username,lastname FROM " + m_usersTableName + " WHERE username like ?first AND lastname like ?second LIMIT 100", + param); + IDataReader reader = result.ExecuteReader(); + + + while (reader.Read()) + { + Framework.AvatarPickerAvatar user = new Framework.AvatarPickerAvatar(); + user.AvatarID = new LLUUID((string) reader["UUID"]); + user.firstName = (string) reader["username"]; + user.lastName = (string) reader["lastname"]; + returnlist.Add(user); + } + reader.Close(); + result.Dispose(); + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return returnlist; + } + } + else if (querysplit.Length == 1) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?first"] = objAlphaNumericPattern.Replace(querysplit[0], String.Empty) + "%"; + + IDbCommand result = + database.Query( + "SELECT UUID,username,lastname FROM " + m_usersTableName + " WHERE username like ?first OR lastname like ?first LIMIT 100", + param); + IDataReader reader = result.ExecuteReader(); + + + while (reader.Read()) + { + Framework.AvatarPickerAvatar user = new Framework.AvatarPickerAvatar(); + user.AvatarID = new LLUUID((string) reader["UUID"]); + user.firstName = (string) reader["username"]; + user.lastName = (string) reader["lastname"]; + returnlist.Add(user); + } + reader.Close(); + result.Dispose(); + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return returnlist; + } + } + return returnlist; + } + + // see IUserData + public UserProfileData GetUserByUUID(LLUUID uuid) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?uuid"] = uuid.ToString(); + + IDbCommand result = database.Query("SELECT * FROM " + m_usersTableName + " WHERE UUID = ?uuid", param); + IDataReader reader = result.ExecuteReader(); + + UserProfileData row = database.readUserRow(reader); + + reader.Close(); + result.Dispose(); + + return row; + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return null; + } + } + + /// + /// Searches the database for a specified user profile by account + /// + /// The account + /// The users profile + public UserProfileData GetUserByAccount(string account) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?account"] = account; + + IDbCommand result = database.Query("SELECT * FROM users WHERE account = ?account", param); + IDataReader reader = result.ExecuteReader(); + + UserProfileData row = database.readUserRow(reader); + + reader.Close(); + result.Dispose(); + + return row; + } + } + catch (Exception e) + { + database.Reconnect(); + MainLog.Instance.Error(e.ToString()); + return null; + } + } + + /// + /// Returns a user session searching by name + /// + /// The account name + /// The users session + public UserAgentData GetAgentByName(string name) + { + return GetAgentByName(name.Split(' ')[0], name.Split(' ')[1]); + } + + /// + /// Returns a user session by account name + /// + /// First part of the users account name + /// Second part of the users account name + /// The users session + public UserAgentData GetAgentByName(string user, string last) + { + UserProfileData profile = GetUserByName(user, last); + return GetAgentByUUID(profile.UUID); + } + + public void StoreWebLoginKey(LLUUID AgentID, LLUUID WebLoginKey) + { + + Dictionary param = new Dictionary(); + param["?UUID"] = AgentID.UUID.ToString(); + param["?webLoginKey"] = WebLoginKey.UUID.ToString(); + + try + { + lock (database) + { + IDbCommand updater = + database.Query( + "update " + m_usersTableName + " SET webLoginKey = ?webLoginKey " + + "where UUID = ?UUID", + param); + updater.ExecuteNonQuery(); + + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return; + } + + + + + } + + /// + /// Returns an agent session by account UUID + /// + /// The accounts UUID + /// The users session + public UserAgentData GetAgentByUUID(LLUUID uuid) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?uuid"] = uuid.ToString(); + + IDbCommand result = database.Query("SELECT * FROM " + m_agentsTableName + " WHERE UUID = ?uuid", param); + IDataReader reader = result.ExecuteReader(); + + UserAgentData row = database.readAgentRow(reader); + + reader.Close(); + result.Dispose(); + + return row; + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + return null; + } + } + + /// + /// Creates a new users profile + /// + /// The user profile to create + public void AddNewUserProfile(UserProfileData user) + { + try + { + lock (database) + { + database.insertUserRow(user.UUID, user.username, user.surname, user.passwordHash, user.passwordSalt, + user.homeRegion, user.homeLocation.X, user.homeLocation.Y, + user.homeLocation.Z, + user.homeLookAt.X, user.homeLookAt.Y, user.homeLookAt.Z, user.created, + user.lastLogin, user.userInventoryURI, user.userAssetURI, + user.profileCanDoMask, user.profileWantDoMask, + user.profileAboutText, user.profileFirstText, user.profileImage, + user.profileFirstImage, user.webLoginKey); + } + } + catch (Exception e) + { + database.Reconnect(); + m_log.Error(e.ToString()); + } + } + + /// + /// Creates a new agent + /// + /// The agent to create + public void AddNewUserAgent(UserAgentData agent) + { + // Do nothing. + } + + /// + /// Updates a user profile stored in the DB + /// + /// The profile data to use to update the DB + public bool UpdateUserProfile(UserProfileData user) + { + // TODO: implement + return true; + } + + /// + /// Performs a money transfer request between two accounts + /// + /// The senders account ID + /// The receivers account ID + /// The amount to transfer + /// Success? + public bool MoneyTransferRequest(LLUUID from, LLUUID to, uint amount) + { + return false; + } + + /// + /// Performs an inventory transfer request between two accounts + /// + /// TODO: Move to inventory server + /// The senders account ID + /// The receivers account ID + /// The item to transfer + /// Success? + public bool InventoryTransferRequest(LLUUID from, LLUUID to, LLUUID item) + { + return false; + } + + /// + /// Database provider name + /// + /// Provider name + public string getName() + { + return "MySQL Userdata Interface"; + } + + /// + /// Database provider version + /// + /// provider version + public string GetVersion() + { + return "0.1"; + } + } +} diff --git a/OpenSim/Framework/Data.MySQL/Properties/AssemblyInfo.cs b/OpenSim/Framework/Data.MySQL/Properties/AssemblyInfo.cs index cb7f8c5610..041b1eff1d 100644 --- a/OpenSim/Framework/Data.MySQL/Properties/AssemblyInfo.cs +++ b/OpenSim/Framework/Data.MySQL/Properties/AssemblyInfo.cs @@ -1,38 +1,66 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. - -[assembly : AssemblyTitle("OpenSim.Framework.Data.MySQL")] -[assembly : AssemblyDescription("")] -[assembly : AssemblyConfiguration("")] -[assembly : AssemblyCompany("")] -[assembly : AssemblyProduct("OpenSim.Framework.Data.MySQL")] -[assembly : AssemblyCopyright("Copyright © 2007")] -[assembly : AssemblyTrademark("")] -[assembly : AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. - -[assembly : ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM - -[assembly : Guid("e49826b2-dcef-41be-a5bd-596733fa3304")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: - -[assembly : AssemblyVersion("1.0.0.0")] -[assembly : AssemblyFileVersion("1.0.0.0")] \ No newline at end of file +/* +* 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.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. + +[assembly : AssemblyTitle("OpenSim.Framework.Data.MySQL")] +[assembly : AssemblyDescription("")] +[assembly : AssemblyConfiguration("")] +[assembly : AssemblyCompany("")] +[assembly : AssemblyProduct("OpenSim.Framework.Data.MySQL")] +[assembly : AssemblyCopyright("Copyright © OpenSimulator.org Developers 2007-2008")] +[assembly : AssemblyTrademark("")] +[assembly : AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. + +[assembly : ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM + +[assembly : Guid("e49826b2-dcef-41be-a5bd-596733fa3304")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly : AssemblyVersion("1.0.0.0")] +[assembly : AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/Data.MySQL/Resources/AvatarAppearance.sql b/OpenSim/Framework/Data.MySQL/Resources/AvatarAppearance.sql new file mode 100644 index 0000000000..b638ee2d7d --- /dev/null +++ b/OpenSim/Framework/Data.MySQL/Resources/AvatarAppearance.sql @@ -0,0 +1,42 @@ +-- +-- Create schema avatar_appearance +-- + +CREATE DATABASE IF NOT EXISTS avatar_appearance; +USE avatar_appearance; + +DROP TABLE IF EXISTS `avatarappearance`; +CREATE TABLE `avatarappearance` ( + `UUID` char(36) NOT NULL, + `Serial` int(10) unsigned NOT NULL, + `WearableItem0` char(36) NOT NULL, + `WearableAsset0` char(36) NOT NULL, + `WearableItem1` char(36) NOT NULL, + `WearableAsset1` char(36) NOT NULL, + `WearableItem2` char(36) NOT NULL, + `WearableAsset2` char(36) NOT NULL, + `WearableItem3` char(36) NOT NULL, + `WearableAsset3` char(36) NOT NULL, + `WearableItem4` char(36) NOT NULL, + `WearableAsset4` char(36) NOT NULL, + `WearableItem5` char(36) NOT NULL, + `WearableAsset5` char(36) NOT NULL, + `WearableItem6` char(36) NOT NULL, + `WearableAsset6` char(36) NOT NULL, + `WearableItem7` char(36) NOT NULL, + `WearableAsset7` char(36) NOT NULL, + `WearableItem8` char(36) NOT NULL, + `WearableAsset8` char(36) NOT NULL, + `WearableItem9` char(36) NOT NULL, + `WearableAsset9` char(36) NOT NULL, + `WearableItem10` char(36) NOT NULL, + `WearableAsset10` char(36) NOT NULL, + `WearableItem11` char(36) NOT NULL, + `WearableAsset11` char(36) NOT NULL, + `WearableItem12` char(36) NOT NULL, + `WearableAsset12` char(36) NOT NULL, + + + PRIMARY KEY (`UUID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + diff --git a/OpenSim/Framework/Data.MySQL/Resources/CreateUserFriendsTable.sql b/OpenSim/Framework/Data.MySQL/Resources/CreateUserFriendsTable.sql index d6647d50b8..d82f96e95e 100644 --- a/OpenSim/Framework/Data.MySQL/Resources/CreateUserFriendsTable.sql +++ b/OpenSim/Framework/Data.MySQL/Resources/CreateUserFriendsTable.sql @@ -1,11 +1,11 @@ -SET FOREIGN_KEY_CHECKS=0; --- ---------------------------- --- Table structure for users --- ---------------------------- -CREATE TABLE `userfriends` ( - `ownerID` VARCHAR(37) NOT NULL, - `friendID` VARCHAR(47) NOT NULL, - `friendPerms` INT NOT NULL, - `datetimestamp` INT NOT NULL, - UNIQUE KEY (`ownerID`, `friendID`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Rev.1'; \ No newline at end of file +SET FOREIGN_KEY_CHECKS=0; +-- ---------------------------- +-- Table structure for users +-- ---------------------------- +CREATE TABLE `userfriends` ( + `ownerID` VARCHAR(37) NOT NULL, + `friendID` VARCHAR(37) NOT NULL, + `friendPerms` INT NOT NULL, + `datetimestamp` INT NOT NULL, + UNIQUE KEY (`ownerID`, `friendID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Rev.1'; diff --git a/OpenSim/Framework/Data.SQLite/Properties/AssemblyInfo.cs b/OpenSim/Framework/Data.SQLite/Properties/AssemblyInfo.cs index 1f8680bb7f..a94582924b 100644 --- a/OpenSim/Framework/Data.SQLite/Properties/AssemblyInfo.cs +++ b/OpenSim/Framework/Data.SQLite/Properties/AssemblyInfo.cs @@ -1,38 +1,66 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. - -[assembly : AssemblyTitle("OpenSim.Framework.Data.SQLite")] -[assembly : AssemblyDescription("")] -[assembly : AssemblyConfiguration("")] -[assembly : AssemblyCompany("")] -[assembly : AssemblyProduct("OpenSim.Framework.Data.SQLite")] -[assembly : AssemblyCopyright("Copyright © 2007")] -[assembly : AssemblyTrademark("")] -[assembly : AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. - -[assembly : ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM - -[assembly : Guid("6113d5ce-4547-49f4-9236-0dcc503457b1")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: - -[assembly : AssemblyVersion("0.4.0.0")] -[assembly : AssemblyFileVersion("1.0.0.0")] \ No newline at end of file +/* +* 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.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. + +[assembly : AssemblyTitle("OpenSim.Framework.Data.SQLite")] +[assembly : AssemblyDescription("")] +[assembly : AssemblyConfiguration("")] +[assembly : AssemblyCompany("")] +[assembly : AssemblyProduct("OpenSim.Framework.Data.SQLite")] +[assembly : AssemblyCopyright("Copyright © OpenSimulator.org Developers 2007-2008")] +[assembly : AssemblyTrademark("")] +[assembly : AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. + +[assembly : ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM + +[assembly : Guid("6113d5ce-4547-49f4-9236-0dcc503457b1")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly : AssemblyVersion("1.0.0.0")] +[assembly : AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/Data.SQLite/Resources/001_AssetStore.sql b/OpenSim/Framework/Data.SQLite/Resources/001_AssetStore.sql new file mode 100644 index 0000000000..1dc05d8cd7 --- /dev/null +++ b/OpenSim/Framework/Data.SQLite/Resources/001_AssetStore.sql @@ -0,0 +1,13 @@ +BEGIN TRANSACTION; + +CREATE TABLE assets( + UUID varchar(255) primary key, + Name varchar(255), + Description varchar(255), + Type integer, + InvType integer, + Local integer, + Temporary integer, + Data blob); + +COMMIT; diff --git a/OpenSim/Framework/Data.SQLite/Resources/001_InventoryStore.sql b/OpenSim/Framework/Data.SQLite/Resources/001_InventoryStore.sql new file mode 100644 index 0000000000..e4951b060c --- /dev/null +++ b/OpenSim/Framework/Data.SQLite/Resources/001_InventoryStore.sql @@ -0,0 +1,26 @@ +BEGIN TRANSACTION; + +CREATE TABLE inventoryitems( + UUID varchar(255) primary key, + assetID varchar(255), + assetType integer, + invType integer, + parentFolderID varchar(255), + avatarID varchar(255), + creatorsID varchar(255), + inventoryName varchar(255), + inventoryDescription varchar(255), + inventoryNextPermissions integer, + inventoryCurrentPermissions integer, + inventoryBasePermissions integer, + inventoryEveryOnePermissions integer); + +CREATE TABLE inventoryfolders( + UUID varchar(255) primary key, + name varchar(255), + agentID varchar(255), + parentID varchar(255), + type integer, + version integer); + +COMMIT; diff --git a/OpenSim/Framework/Data.SQLite/Resources/001_RegionStore.sql b/OpenSim/Framework/Data.SQLite/Resources/001_RegionStore.sql new file mode 100644 index 0000000000..45a36facc6 --- /dev/null +++ b/OpenSim/Framework/Data.SQLite/Resources/001_RegionStore.sql @@ -0,0 +1,121 @@ +BEGIN TRANSACTION; + +CREATE TABLE prims( + UUID varchar(255) primary key, + RegionUUID varchar(255), + ParentID integer, + CreationDate integer, + Name varchar(255), + SceneGroupID varchar(255), + Text varchar(255), + Description varchar(255), + SitName varchar(255), + TouchName varchar(255), + CreatorID varchar(255), + OwnerID varchar(255), + GroupID varchar(255), + LastOwnerID varchar(255), + OwnerMask integer, + NextOwnerMask integer, + GroupMask integer, + EveryoneMask integer, + BaseMask integer, + PositionX float, + PositionY float, + PositionZ float, + GroupPositionX float, + GroupPositionY float, + GroupPositionZ float, + VelocityX float, + VelocityY float, + VelocityZ float, + AngularVelocityX float, + AngularVelocityY float, + AngularVelocityZ float, + AccelerationX float, + AccelerationY float, + AccelerationZ float, + RotationX float, + RotationY float, + RotationZ float, + RotationW float, + ObjectFlags integer, + SitTargetOffsetX float NOT NULL default 0, + SitTargetOffsetY float NOT NULL default 0, + SitTargetOffsetZ float NOT NULL default 0, + SitTargetOrientW float NOT NULL default 0, + SitTargetOrientX float NOT NULL default 0, + SitTargetOrientY float NOT NULL default 0, + SitTargetOrientZ float NOT NULL default 0); + +CREATE TABLE primshapes(UUID varchar(255) primary key, + Shape integer, + ScaleX float, + ScaleY float, + ScaleZ float, + PCode integer, + PathBegin integer, + PathEnd integer, + PathScaleX integer, + PathScaleY integer, + PathShearX integer, + PathShearY integer, + PathSkew integer, + PathCurve integer, + PathRadiusOffset integer, + PathRevolutions integer, + PathTaperX integer, + PathTaperY integer, + PathTwist integer, + PathTwistBegin integer, + ProfileBegin integer, + ProfileEnd integer, + ProfileCurve integer, + ProfileHollow integer, + Texture blob, + ExtraParams blob); + +CREATE TABLE terrain( + RegionUUID varchar(255), + Revision integer, + Heightfield blob); + +CREATE TABLE land( + UUID varchar(255) primary key, + RegionUUID varchar(255), + LocalLandID string, + Bitmap blob, + Name varchar(255), + Desc varchar(255), + OwnerUUID varchar(36), + IsGroupOwned string, + Area integer, + AuctionID integer, + Category integer, + ClaimDate integer, + ClaimPrice integer, + GroupUUID varchar(255), + SalePrice integer, + LandStatus integer, + LandFlags string, + LandingType string, + MediaAutoScale string, + MediaTextureUUID varchar(255), + MediaURL varchar(255), + MusicURL varchar(255), + PassHours float, + PassPrice string, + SnapshotUUID varchar(255), + UserLocationX float, + UserLocationY float, + UserLocationZ float, + UserLookAtX float, + UserLookAtY float, + UserLookAtZ float); + +CREATE TABLE landaccesslist( + LandUUID varchar(255), + AccessUUID varchar(255), + Flags string); + +COMMIT; diff --git a/OpenSim/Framework/Data.SQLite/Resources/001_UserStore.sql b/OpenSim/Framework/Data.SQLite/Resources/001_UserStore.sql new file mode 100644 index 0000000000..070e340155 --- /dev/null +++ b/OpenSim/Framework/Data.SQLite/Resources/001_UserStore.sql @@ -0,0 +1,37 @@ +BEGIN TRANSACTION; + +CREATE TABLE users( + UUID varchar(255) primary key, + username varchar(255), + surname varchar(255), + passwordHash varchar(255), + passwordSalt varchar(255), + homeRegionX integer, + homeRegionY integer, + homeLocationX float, + homeLocationY float, + homeLocationZ float, + homeLookAtX float, + homeLookAtY float, + homeLookAtZ float, + created integer, + lastLogin integer, + rootInventoryFolderID varchar(255), + userInventoryURI varchar(255), + userAssetURI varchar(255), + profileCanDoMask integer, + profileWantDoMask integer, + profileAboutText varchar(255), + profileFirstText varchar(255), + profileImage varchar(255), + profileFirstImage varchar(255), + webLoginKey text default '00000000-0000-0000-0000-000000000000'); + +CREATE TABLE userfriends( + ownerID varchar(255), + friendID varchar(255), + friendPerms integer, + ownerPerms integer, + datetimestamp integer); + +COMMIT; diff --git a/OpenSim/Framework/Data.SQLite/SQLiteAssetData.cs b/OpenSim/Framework/Data.SQLite/SQLiteAssetData.cs index 411e64093c..ee62db6aea 100644 --- a/OpenSim/Framework/Data.SQLite/SQLiteAssetData.cs +++ b/OpenSim/Framework/Data.SQLite/SQLiteAssetData.cs @@ -1,379 +1,391 @@ -/* -* 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.Data; -using System.Reflection; -using libsecondlife; -using Mono.Data.SqliteClient; -using OpenSim.Framework.Console; -using System.Collections.Generic; // rex added - -namespace OpenSim.Framework.Data.SQLite -{ - /// - /// A User storage interface for the DB4o database system - /// - public class SQLiteAssetData : SQLiteBase, IAssetProvider - { - /// - /// The database manager - /// - /// - /// Artificial constructor called upon plugin load - /// - private const string assetSelect = "select * from assets"; - - private DataSet ds; - private SqliteDataAdapter da; - - public void Initialise(string dbfile, string dbname) - { - SqliteConnection conn = new SqliteConnection("URI=file:" + dbfile + ",version=3"); - TestTables(conn); - - ds = new DataSet(); - da = new SqliteDataAdapter(new SqliteCommand(assetSelect, conn)); - - lock (ds) - { - ds.Tables.Add(createAssetsTable()); - - setupAssetCommands(da, conn); - try - { - da.Fill(ds.Tables["assets"]); - } - catch (Exception e) - { - MainLog.Instance.Verbose("SQLITE", e.ToString()); - } - } - - return; - } - - public AssetBase FetchAsset(LLUUID uuid) - { - AssetBase asset = new AssetBase(); - DataRow row = ds.Tables["assets"].Rows.Find(Util.ToRawUuidString(uuid)); - if (row != null) - { - return buildAsset(row); - } - else - { - return null; - } - } - - public void CreateAsset(AssetBase asset) - { - // no difference for now - UpdateAsset(asset); - } - - public void UpdateAsset(AssetBase asset) - { - LogAssetLoad(asset); - - DataTable assets = ds.Tables["assets"]; - lock (ds) - { - DataRow row = assets.Rows.Find(Util.ToRawUuidString(asset.FullID)); - if (row == null) - { - row = assets.NewRow(); - fillAssetRow(row, asset); - assets.Rows.Add(row); - } - else - { - fillAssetRow(row, asset); - } - } - } - - // rex new function for "replace assets" functionality - public LLUUID ExistsAsset(sbyte type, string name) - { - LLUUID retVal = LLUUID.Zero; - - lock (ds) - { - string selectExp = "Type = '" + type.ToString() + "' AND Name = '" + name + "'"; - DataRow[] match = ds.Tables["assets"].Select(selectExp); - if (match.Length > 0) - { - retVal = new LLUUID((String)match[0]["UUID"]); - } - } - - return retVal; - } - - private void LogAssetLoad(AssetBase asset) - { - string temporary = asset.Temporary ? "Temporary" : "Stored"; - string local = asset.Local ? "Local" : "Remote"; - - MainLog.Instance.Verbose("SQLITE", - string.Format("Loaded {6} {5} Asset: [{0}][{3}/{4}] \"{1}\":{2} ({7} bytes)", - asset.FullID, asset.Name, asset.Description, asset.Type, - asset.InvType, temporary, local, asset.Data.Length)); - } - - public bool ExistsAsset(LLUUID uuid) - { - DataRow row = ds.Tables["assets"].Rows.Find(Util.ToRawUuidString(uuid)); - return (row != null); - } - - // rex, new function - public List GetAssetList(int vAssetType) - { - List retvals = new List(); - lock (ds) - { - string selectExp = "InvType = '" + vAssetType.ToString() + "'"; - DataRow[] allAssets = ds.Tables["assets"].Select(selectExp); - foreach (DataRow row in allAssets) - { - // Do not use buildAsset(row) because we don't want to return the asset.data - Tuco - AssetBase asset = new AssetBase(); - asset.FullID = new LLUUID((String)row["UUID"]); - asset.Name = (String)row["Name"]; - asset.Description = (String)row["Description"]; - asset.Type = Convert.ToSByte(row["Type"]); - asset.InvType = Convert.ToSByte(row["InvType"]); - asset.Local = Convert.ToBoolean(row["Local"]); - asset.Temporary = Convert.ToBoolean(row["Temporary"]); - retvals.Add(asset); - } - } - return retvals; - } - - - public void DeleteAsset(LLUUID uuid) - { - lock (ds) - { - DataRow row = ds.Tables["assets"].Rows.Find(Util.ToRawUuidString(uuid)); - if (row != null) - { - row.Delete(); - } - } - } - - public void CommitAssets() // force a sync to the database - { - MainLog.Instance.Verbose("SQLITE", "Attempting commit"); - lock (ds) - { - da.Update(ds, "assets"); - ds.AcceptChanges(); - } - } - - /*********************************************************************** - * - * Database Definition Functions - * - * This should be db agnostic as we define them in ADO.NET terms - * - **********************************************************************/ - - private DataTable createAssetsTable() - { - DataTable assets = new DataTable("assets"); - - createCol(assets, "UUID", typeof (String)); - createCol(assets, "Name", typeof (String)); - createCol(assets, "Description", typeof (String)); - createCol(assets, "MediaURL", typeof(String));//rex mediaurl - createCol(assets, "Type", typeof (Int32)); - createCol(assets, "InvType", typeof (Int32)); - createCol(assets, "Local", typeof (Boolean)); - createCol(assets, "Temporary", typeof (Boolean)); - createCol(assets, "Data", typeof (Byte[])); - // Add in contraints - assets.PrimaryKey = new DataColumn[] {assets.Columns["UUID"]}; - return assets; - } - - /*********************************************************************** - * - * Convert between ADO.NET <=> OpenSim Objects - * - * These should be database independant - * - **********************************************************************/ - - private AssetBase buildAsset(DataRow row) - { - // TODO: this doesn't work yet because something more - // interesting has to be done to actually get these values - // back out. Not enough time to figure it out yet. - AssetBase asset = new AssetBase(); - - asset.FullID = new LLUUID((String) row["UUID"]); - asset.Name = (String) row["Name"]; - asset.Description = (String) row["Description"]; - try - { - asset.MediaURL = (String) row["MediaURL"];//rex mediaurl - } - catch (Exception) - { - asset.MediaURL = ""; // fixme, the row returns null which can't be cast to string, happens with old dbs right now. - Tuco - } - asset.Type = Convert.ToSByte(row["Type"]); - asset.InvType = Convert.ToSByte(row["InvType"]); - asset.Local = Convert.ToBoolean(row["Local"]); - asset.Temporary = Convert.ToBoolean(row["Temporary"]); - asset.Data = (byte[]) row["Data"]; - return asset; - } - - - private void fillAssetRow(DataRow row, AssetBase asset) - { - row["UUID"] = Util.ToRawUuidString(asset.FullID); - row["Name"] = asset.Name; - if (asset.Description != null) - { - row["Description"] = asset.Description; - } - else - { - row["Description"] = " "; - } - - if (asset.MediaURL != null) //rex mediaurl - { - row["MediaURL"] = asset.MediaURL; - } - else - { - row["MediaURL"] = " "; - } - row["Type"] = asset.Type; - row["InvType"] = asset.InvType; - row["Local"] = asset.Local; - row["Temporary"] = asset.Temporary; - row["Data"] = asset.Data; - - // ADO.NET doesn't handle NULL very well - foreach (DataColumn col in ds.Tables["assets"].Columns) - { - if (row[col] == null) - { - row[col] = ""; - } - } - } - - /*********************************************************************** - * - * Database Binding functions - * - * These will be db specific due to typing, and minor differences - * in databases. - * - **********************************************************************/ - - private void setupAssetCommands(SqliteDataAdapter da, SqliteConnection conn) - { - da.InsertCommand = createInsertCommand("assets", ds.Tables["assets"]); - da.InsertCommand.Connection = conn; - - da.UpdateCommand = createUpdateCommand("assets", "UUID=:UUID", ds.Tables["assets"]); - da.UpdateCommand.Connection = conn; - - SqliteCommand delete = new SqliteCommand("delete from assets where UUID = :UUID"); - delete.Parameters.Add(createSqliteParameter("UUID", typeof (String))); - delete.Connection = conn; - da.DeleteCommand = delete; - } - - private void InitDB(SqliteConnection conn) - { - string createAssets = defineTable(createAssetsTable()); - SqliteCommand pcmd = new SqliteCommand(createAssets, conn); - conn.Open(); - pcmd.ExecuteNonQuery(); - conn.Close(); - } - - private bool TestTables(SqliteConnection conn) - { - SqliteCommand cmd = new SqliteCommand(assetSelect, conn); - SqliteDataAdapter pDa = new SqliteDataAdapter(cmd); - DataSet tmpDS = new DataSet(); - try - { - pDa.Fill(tmpDS, "assets"); - } - catch (SqliteSyntaxException) - { - MainLog.Instance.Verbose("SQLITE", "SQLite Database doesn't exist... creating"); - InitDB(conn); - } - return true; - } - - #region IPlugin interface - - public string Version - { - get - { - Module module = GetType().Module; - string dllName = module.Assembly.ManifestModule.Name; - Version dllVersion = module.Assembly.GetName().Version; - - return - string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build, - dllVersion.Revision); - } - } - - public void Initialise() - { - Initialise("AssetStorage.db", ""); - } - - public string Name - { - get { return "SQLite Asset storage engine"; } - } - - #endregion - } -} \ No newline at end of file +/* +* 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.Data; +using System.Reflection; +using libsecondlife; +using Mono.Data.SqliteClient; +using OpenSim.Framework.Console; +using System.Collections.Generic; // rex added + +namespace OpenSim.Framework.Data.SQLite +{ + /// + /// A User storage interface for the DB4o database system + /// + public class SQLiteAssetData : SQLiteBase, IAssetProvider + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// The database manager + /// + /// + /// Artificial constructor called upon plugin load + /// + private const string SelectAssetSQL = "select * from assets where UUID=:UUID"; + private const string DeleteAssetSQL = "delete from assets where UUID=:UUID"; + private const string InsertAssetSQL = "insert into assets(UUID, Name, Description, Type, InvType, Local, Temporary, Data) values(:UUID, :Name, :Description, :Type, :InvType, :Local, :Temporary, :Data)"; + private const string UpdateAssetSQL = "update assets set Name=:Name, Description=:Description, Type=:Type, InvType=:InvType, Local=:Local, Temporary=:Temporary, Data=:Data where UUID=:UUID"; + private const string assetSelect = "select * from assets"; + + private SqliteConnection m_conn; + + public void Initialise(string dbfile, string dbname) + { + m_conn = new SqliteConnection("URI=file:" + dbfile + ",version=3"); + m_conn.Open(); + TestTables(m_conn); + return; + } + + public AssetBase FetchAsset(LLUUID uuid) + { + + using (SqliteCommand cmd = new SqliteCommand(SelectAssetSQL, m_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":UUID", Util.ToRawUuidString(uuid))); + using (IDataReader reader = cmd.ExecuteReader()) + { + if (reader.Read()) + { + AssetBase asset = buildAsset(reader); + reader.Close(); + return asset; + } + else + { + reader.Close(); + return null; + } + } + } + } + + public void CreateAsset(AssetBase asset) + { + m_log.Info("[SQLITE]: Creating Asset " + Util.ToRawUuidString(asset.FullID)); + if (ExistsAsset(asset.FullID)) + { + m_log.Info("[SQLITE]: Asset exists, updating instead. You should fix the caller for this!"); + UpdateAsset(asset); + } + else + { + using (SqliteCommand cmd = new SqliteCommand(InsertAssetSQL, m_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":UUID", Util.ToRawUuidString(asset.FullID))); + cmd.Parameters.Add(new SqliteParameter(":Name", asset.Name)); + cmd.Parameters.Add(new SqliteParameter(":Description", asset.Description)); + cmd.Parameters.Add(new SqliteParameter(":Type", asset.Type)); + cmd.Parameters.Add(new SqliteParameter(":InvType", asset.InvType)); + cmd.Parameters.Add(new SqliteParameter(":Local", asset.Local)); + cmd.Parameters.Add(new SqliteParameter(":Temporary", asset.Temporary)); + cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data)); + + cmd.ExecuteNonQuery(); + } + } + } + + public void UpdateAsset(AssetBase asset) + { + LogAssetLoad(asset); + + using (SqliteCommand cmd = new SqliteCommand(UpdateAssetSQL, m_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":UUID", Util.ToRawUuidString(asset.FullID))); + cmd.Parameters.Add(new SqliteParameter(":Name", asset.Name)); + cmd.Parameters.Add(new SqliteParameter(":Description", asset.Description)); + cmd.Parameters.Add(new SqliteParameter(":Type", asset.Type)); + cmd.Parameters.Add(new SqliteParameter(":InvType", asset.InvType)); + cmd.Parameters.Add(new SqliteParameter(":Local", asset.Local)); + cmd.Parameters.Add(new SqliteParameter(":Temporary", asset.Temporary)); + cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data)); + + cmd.ExecuteNonQuery(); + } + + } + + // rex new function for "replace assets" functionality + public LLUUID ExistsAsset(sbyte type, string name) + { + LLUUID retVal = LLUUID.Zero; + + lock (ds) + { + string selectExp = "Type = '" + type.ToString() + "' AND Name = '" + name + "'"; + DataRow[] match = ds.Tables["assets"].Select(selectExp); + if (match.Length > 0) + { + retVal = new LLUUID((String)match[0]["UUID"]); + } + } + + return retVal; + } + + private void LogAssetLoad(AssetBase asset) + { + string temporary = asset.Temporary ? "Temporary" : "Stored"; + string local = asset.Local ? "Local" : "Remote"; + + m_log.Info("[SQLITE]: " + + string.Format("Loaded {6} {5} Asset: [{0}][{3}/{4}] \"{1}\":{2} ({7} bytes)", + asset.FullID, asset.Name, asset.Description, asset.Type, + asset.InvType, temporary, local, asset.Data.Length)); + } + + public bool ExistsAsset(LLUUID uuid) + { + using (SqliteCommand cmd = new SqliteCommand(SelectAssetSQL, m_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":UUID", Util.ToRawUuidString(uuid))); + using (IDataReader reader = cmd.ExecuteReader()) + { + if(reader.Read()) + { + reader.Close(); + return true; + } + else + { + reader.Close(); + return false; + } + } + } + } + + // rex, new function + public List GetAssetList(int vAssetType) + { + List retvals = new List(); + lock (ds) + { + string selectExp = "InvType = '" + vAssetType.ToString() + "'"; + DataRow[] allAssets = ds.Tables["assets"].Select(selectExp); + foreach (DataRow row in allAssets) + { + // Do not use buildAsset(row) because we don't want to return the asset.data - Tuco + AssetBase asset = new AssetBase(); + asset.FullID = new LLUUID((String)row["UUID"]); + asset.Name = (String)row["Name"]; + asset.Description = (String)row["Description"]; + asset.Type = Convert.ToSByte(row["Type"]); + asset.InvType = Convert.ToSByte(row["InvType"]); + asset.Local = Convert.ToBoolean(row["Local"]); + asset.Temporary = Convert.ToBoolean(row["Temporary"]); + retvals.Add(asset); + } + } + return retvals; + } + + + public void DeleteAsset(LLUUID uuid) + { + using (SqliteCommand cmd = new SqliteCommand(DeleteAssetSQL, m_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":UUID", Util.ToRawUuidString(uuid))); + + cmd.ExecuteNonQuery(); + } + } + + public void CommitAssets() // force a sync to the database + { + m_log.Info("[SQLITE]: Attempting commit"); + // lock (ds) + // { + // da.Update(ds, "assets"); + // ds.AcceptChanges(); + // } + } + + /*********************************************************************** + * + * Database Definition Functions + * + * This should be db agnostic as we define them in ADO.NET terms + * + **********************************************************************/ + + private DataTable createAssetsTable() + { + DataTable assets = new DataTable("assets"); + + createCol(assets, "UUID", typeof (String)); + createCol(assets, "Name", typeof (String)); + createCol(assets, "Description", typeof (String)); + createCol(assets, "MediaURL", typeof(String));//rex mediaurl + createCol(assets, "Type", typeof (Int32)); + createCol(assets, "InvType", typeof (Int32)); + createCol(assets, "Local", typeof (Boolean)); + createCol(assets, "Temporary", typeof (Boolean)); + createCol(assets, "Data", typeof (Byte[])); + // Add in contraints + assets.PrimaryKey = new DataColumn[] {assets.Columns["UUID"]}; + return assets; + } + + /*********************************************************************** + * + * Convert between ADO.NET <=> OpenSim Objects + * + * These should be database independant + * + **********************************************************************/ + + private AssetBase buildAsset(IDataReader row) + { + // TODO: this doesn't work yet because something more + // interesting has to be done to actually get these values + // back out. Not enough time to figure it out yet. + AssetBase asset = new AssetBase(); + + asset.FullID = new LLUUID((String) row["UUID"]); + asset.Name = (String) row["Name"]; + asset.Description = (String) row["Description"]; + try + { + asset.MediaURL = (String) row["MediaURL"];//rex mediaurl + } + catch (Exception) + { + asset.MediaURL = ""; // fixme, the row returns null which can't be cast to string, happens with old dbs right now. - Tuco + } + asset.Type = Convert.ToSByte(row["Type"]); + asset.InvType = Convert.ToSByte(row["InvType"]); + asset.Local = Convert.ToBoolean(row["Local"]); + asset.Temporary = Convert.ToBoolean(row["Temporary"]); + asset.Data = (byte[]) row["Data"]; + return asset; + } + + + private void fillAssetRow(DataRow row, AssetBase asset) + { + row["UUID"] = Util.ToRawUuidString(asset.FullID); + row["Name"] = asset.Name; + if (asset.Description != null) + { + row["Description"] = asset.Description; + } + else + { + row["Description"] = " "; + } + + if (asset.MediaURL != null) //rex mediaurl + { + row["MediaURL"] = asset.MediaURL; + } + else + { + row["MediaURL"] = " "; + } + row["Type"] = asset.Type; + row["InvType"] = asset.InvType; + row["Local"] = asset.Local; + row["Temporary"] = asset.Temporary; + row["Data"] = asset.Data; + + // ADO.NET doesn't handle NULL very well + foreach (DataColumn col in ds.Tables["assets"].Columns) + { + if (row[col] == null) + { + row[col] = ""; + } + } + } + + /*********************************************************************** + * + * Database Binding functions + * + * These will be db specific due to typing, and minor differences + * in databases. + * + **********************************************************************/ + + private void InitDB(SqliteConnection conn) + { + string createAssets = defineTable(createAssetsTable()); + SqliteCommand pcmd = new SqliteCommand(createAssets, conn); + pcmd.ExecuteNonQuery(); + } + + private bool TestTables(SqliteConnection conn) + { + SqliteCommand cmd = new SqliteCommand(assetSelect, conn); + SqliteDataAdapter pDa = new SqliteDataAdapter(cmd); + DataSet tmpDS = new DataSet(); + try + { + pDa.Fill(tmpDS, "assets"); + } + catch (SqliteSyntaxException) + { + m_log.Info("[SQLITE]: SQLite Database doesn't exist... creating"); + InitDB(conn); + } + return true; + } + + #region IPlugin interface + + public string Version + { + get + { + Module module = GetType().Module; + string dllName = module.Assembly.ManifestModule.Name; + Version dllVersion = module.Assembly.GetName().Version; + + return + string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build, + dllVersion.Revision); + } + } + + public void Initialise() + { + Initialise("AssetStorage.db", ""); + } + + public string Name + { + get { return "SQLite Asset storage engine"; } + } + + #endregion + } +} diff --git a/OpenSim/Framework/Data.SQLite/SQLiteBase.cs b/OpenSim/Framework/Data.SQLite/SQLiteBase.cs index 8fc2b28562..d6ce5a05b8 100644 --- a/OpenSim/Framework/Data.SQLite/SQLiteBase.cs +++ b/OpenSim/Framework/Data.SQLite/SQLiteBase.cs @@ -1,269 +1,269 @@ -/* -* 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.Data; -using Mono.Data.SqliteClient; - -namespace OpenSim.Framework.Data.SQLite -{ - /// - /// A base class for methods needed by all SQLite database classes - /// - public class SQLiteBase - { - /*********************************************************************** - * - * Database Definition Functions - * - * This should be db agnostic as we define them in ADO.NET terms - * - **********************************************************************/ - - protected static void createCol(DataTable dt, string name, Type type) - { - DataColumn col = new DataColumn(name, type); - dt.Columns.Add(col); - } - - /*********************************************************************** - * - * SQL Statement Creation Functions - * - * These functions create SQL statements for update, insert, and create. - * They can probably be factored later to have a db independant - * portion and a db specific portion - * - **********************************************************************/ - - protected static SqliteCommand createInsertCommand(string table, DataTable dt) - { - /** - * This is subtle enough to deserve some commentary. - * Instead of doing *lots* and *lots of hardcoded strings - * for database definitions we'll use the fact that - * realistically all insert statements look like "insert - * into A(b, c) values(:b, :c) on the parameterized query - * front. If we just have a list of b, c, etc... we can - * generate these strings instead of typing them out. - */ - string[] cols = new string[dt.Columns.Count]; - for (int i = 0; i < dt.Columns.Count; i++) - { - DataColumn col = dt.Columns[i]; - cols[i] = col.ColumnName; - } - - string sql = "insert into " + table + "("; - sql += String.Join(", ", cols); - // important, the first ':' needs to be here, the rest get added in the join - sql += ") values (:"; - sql += String.Join(", :", cols); - sql += ")"; - SqliteCommand cmd = new SqliteCommand(sql); - - // this provides the binding for all our parameters, so - // much less code than it used to be - foreach (DataColumn col in dt.Columns) - { - cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType)); - } - return cmd; - } - - protected static SqliteCommand createUpdateCommand(string table, string pk, DataTable dt) - { - string sql = "update " + table + " set "; - string subsql = ""; - foreach (DataColumn col in dt.Columns) - { - if (subsql.Length > 0) - { - // a map function would rock so much here - subsql += ", "; - } - subsql += col.ColumnName + "= :" + col.ColumnName; - } - sql += subsql; - sql += " where " + pk; - SqliteCommand cmd = new SqliteCommand(sql); - - // this provides the binding for all our parameters, so - // much less code than it used to be - - foreach (DataColumn col in dt.Columns) - { - cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType)); - } - return cmd; - } - - - protected static string defineTable(DataTable dt) - { - string sql = "create table " + dt.TableName + "("; - string subsql = ""; - foreach (DataColumn col in dt.Columns) - { - if (subsql.Length > 0) - { - // a map function would rock so much here - subsql += ",\n"; - } - subsql += col.ColumnName + " " + sqliteType(col.DataType); - if (dt.PrimaryKey.Length > 0) - { - if (col == dt.PrimaryKey[0]) - { - subsql += " primary key"; - } - } - } - sql += subsql; - sql += ")"; - return sql; - } - - /*********************************************************************** - * - * Database Binding functions - * - * These will be db specific due to typing, and minor differences - * in databases. - * - **********************************************************************/ - - /// - /// This is a convenience function that collapses 5 repetitive - /// lines for defining SqliteParameters to 2 parameters: - /// column name and database type. - /// - /// It assumes certain conventions like :param as the param - /// name to replace in parametrized queries, and that source - /// version is always current version, both of which are fine - /// for us. - /// - ///a built sqlite parameter - protected static SqliteParameter createSqliteParameter(string name, Type type) - { - SqliteParameter param = new SqliteParameter(); - param.ParameterName = ":" + name; - param.DbType = dbtypeFromType(type); - param.SourceColumn = name; - param.SourceVersion = DataRowVersion.Current; - return param; - } - - /*********************************************************************** - * - * Type conversion functions - * - **********************************************************************/ - - protected static DbType dbtypeFromType(Type type) - { - if (type == typeof (String)) - { - return DbType.String; - } - else if (type == typeof (Int32)) - { - return DbType.Int32; - } - else if (type == typeof (UInt32)) - { - return DbType.UInt32; - } - else if (type == typeof (Int64)) - { - return DbType.Int64; - } - else if (type == typeof (UInt64)) - { - return DbType.UInt64; - } - else if (type == typeof (Double)) - { - return DbType.Double; - } - else if (type == typeof (Boolean)) - { - return DbType.Boolean; - } - else if (type == typeof (Byte[])) - { - return DbType.Binary; - } - else - { - return DbType.String; - } - } - - // this is something we'll need to implement for each db - // slightly differently. - protected static string sqliteType(Type type) - { - if (type == typeof (String)) - { - return "varchar(255)"; - } - else if (type == typeof (Int32)) - { - return "integer"; - } - else if (type == typeof (UInt32)) - { - return "integer"; - } - else if (type == typeof (Int64)) - { - return "varchar(255)"; - } - else if (type == typeof (UInt64)) - { - return "varchar(255)"; - } - else if (type == typeof (Double)) - { - return "float"; - } - else if (type == typeof (Boolean)) - { - return "integer"; - } - else if (type == typeof (Byte[])) - { - return "blob"; - } - else - { - return "string"; - } - } - } -} \ No newline at end of file +/* +* 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.Data; +using Mono.Data.SqliteClient; + +namespace OpenSim.Framework.Data.SQLite +{ + /// + /// A base class for methods needed by all SQLite database classes + /// + public class SQLiteBase + { + /*********************************************************************** + * + * Database Definition Functions + * + * This should be db agnostic as we define them in ADO.NET terms + * + **********************************************************************/ + + protected static void createCol(DataTable dt, string name, Type type) + { + DataColumn col = new DataColumn(name, type); + dt.Columns.Add(col); + } + + /*********************************************************************** + * + * SQL Statement Creation Functions + * + * These functions create SQL statements for update, insert, and create. + * They can probably be factored later to have a db independant + * portion and a db specific portion + * + **********************************************************************/ + + protected static SqliteCommand createInsertCommand(string table, DataTable dt) + { + /** + * This is subtle enough to deserve some commentary. + * Instead of doing *lots* and *lots of hardcoded strings + * for database definitions we'll use the fact that + * realistically all insert statements look like "insert + * into A(b, c) values(:b, :c) on the parameterized query + * front. If we just have a list of b, c, etc... we can + * generate these strings instead of typing them out. + */ + string[] cols = new string[dt.Columns.Count]; + for (int i = 0; i < dt.Columns.Count; i++) + { + DataColumn col = dt.Columns[i]; + cols[i] = col.ColumnName; + } + + string sql = "insert into " + table + "("; + sql += String.Join(", ", cols); + // important, the first ':' needs to be here, the rest get added in the join + sql += ") values (:"; + sql += String.Join(", :", cols); + sql += ")"; + SqliteCommand cmd = new SqliteCommand(sql); + + // this provides the binding for all our parameters, so + // much less code than it used to be + foreach (DataColumn col in dt.Columns) + { + cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType)); + } + return cmd; + } + + protected static SqliteCommand createUpdateCommand(string table, string pk, DataTable dt) + { + string sql = "update " + table + " set "; + string subsql = String.Empty; + foreach (DataColumn col in dt.Columns) + { + if (subsql.Length > 0) + { + // a map function would rock so much here + subsql += ", "; + } + subsql += col.ColumnName + "= :" + col.ColumnName; + } + sql += subsql; + sql += " where " + pk; + SqliteCommand cmd = new SqliteCommand(sql); + + // this provides the binding for all our parameters, so + // much less code than it used to be + + foreach (DataColumn col in dt.Columns) + { + cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType)); + } + return cmd; + } + + + protected static string defineTable(DataTable dt) + { + string sql = "create table " + dt.TableName + "("; + string subsql = String.Empty; + foreach (DataColumn col in dt.Columns) + { + if (subsql.Length > 0) + { + // a map function would rock so much here + subsql += ",\n"; + } + subsql += col.ColumnName + " " + sqliteType(col.DataType); + if (dt.PrimaryKey.Length > 0) + { + if (col == dt.PrimaryKey[0]) + { + subsql += " primary key"; + } + } + } + sql += subsql; + sql += ")"; + return sql; + } + + /*********************************************************************** + * + * Database Binding functions + * + * These will be db specific due to typing, and minor differences + * in databases. + * + **********************************************************************/ + + /// + /// This is a convenience function that collapses 5 repetitive + /// lines for defining SqliteParameters to 2 parameters: + /// column name and database type. + /// + /// It assumes certain conventions like :param as the param + /// name to replace in parametrized queries, and that source + /// version is always current version, both of which are fine + /// for us. + /// + ///a built sqlite parameter + protected static SqliteParameter createSqliteParameter(string name, Type type) + { + SqliteParameter param = new SqliteParameter(); + param.ParameterName = ":" + name; + param.DbType = dbtypeFromType(type); + param.SourceColumn = name; + param.SourceVersion = DataRowVersion.Current; + return param; + } + + /*********************************************************************** + * + * Type conversion functions + * + **********************************************************************/ + + protected static DbType dbtypeFromType(Type type) + { + if (type == typeof (String)) + { + return DbType.String; + } + else if (type == typeof (Int32)) + { + return DbType.Int32; + } + else if (type == typeof (UInt32)) + { + return DbType.UInt32; + } + else if (type == typeof (Int64)) + { + return DbType.Int64; + } + else if (type == typeof (UInt64)) + { + return DbType.UInt64; + } + else if (type == typeof (Double)) + { + return DbType.Double; + } + else if (type == typeof (Boolean)) + { + return DbType.Boolean; + } + else if (type == typeof (Byte[])) + { + return DbType.Binary; + } + else + { + return DbType.String; + } + } + + // this is something we'll need to implement for each db + // slightly differently. + protected static string sqliteType(Type type) + { + if (type == typeof (String)) + { + return "varchar(255)"; + } + else if (type == typeof (Int32)) + { + return "integer"; + } + else if (type == typeof (UInt32)) + { + return "integer"; + } + else if (type == typeof (Int64)) + { + return "varchar(255)"; + } + else if (type == typeof (UInt64)) + { + return "varchar(255)"; + } + else if (type == typeof (Double)) + { + return "float"; + } + else if (type == typeof (Boolean)) + { + return "integer"; + } + else if (type == typeof (Byte[])) + { + return "blob"; + } + else + { + return "string"; + } + } + } +} diff --git a/OpenSim/Framework/Data.SQLite/SQLiteInventoryStore.cs b/OpenSim/Framework/Data.SQLite/SQLiteInventoryStore.cs index 4c3881a344..566880b2f7 100644 --- a/OpenSim/Framework/Data.SQLite/SQLiteInventoryStore.cs +++ b/OpenSim/Framework/Data.SQLite/SQLiteInventoryStore.cs @@ -1,632 +1,676 @@ -/* -* 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.Generic; -using System.Data; -using System.Reflection; -using libsecondlife; -using Mono.Data.SqliteClient; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.Data.SQLite -{ - public class SQLiteInventoryStore : SQLiteBase, IInventoryData - { - private const string invItemsSelect = "select * from inventoryitems"; - private const string invFoldersSelect = "select * from inventoryfolders"; - - private DataSet ds; - private SqliteDataAdapter invItemsDa; - private SqliteDataAdapter invFoldersDa; - - /// - /// Initialises the interface - /// - public void Initialise() - { - Initialise("inventoryStore.db", "inventoryDatabase"); - } - - public void Initialise(string dbfile, string dbname) - { - string connectionString = "URI=file:" + dbfile + ",version=3"; - - MainLog.Instance.Verbose("Inventory", "Sqlite - connecting: " + dbfile); - SqliteConnection conn = new SqliteConnection(connectionString); - - TestTables(conn); - - SqliteCommand itemsSelectCmd = new SqliteCommand(invItemsSelect, conn); - invItemsDa = new SqliteDataAdapter(itemsSelectCmd); - // SqliteCommandBuilder primCb = new SqliteCommandBuilder(primDa); - - SqliteCommand foldersSelectCmd = new SqliteCommand(invFoldersSelect, conn); - invFoldersDa = new SqliteDataAdapter(foldersSelectCmd); - - ds = new DataSet(); - - ds.Tables.Add(createInventoryFoldersTable()); - invFoldersDa.Fill(ds.Tables["inventoryfolders"]); - setupFoldersCommands(invFoldersDa, conn); - MainLog.Instance.Verbose("DATASTORE", "Populated Intentory Folders Definitions"); - - ds.Tables.Add(createInventoryItemsTable()); - invItemsDa.Fill(ds.Tables["inventoryitems"]); - setupItemsCommands(invItemsDa, conn); - MainLog.Instance.Verbose("DATASTORE", "Populated Intentory Items Definitions"); - - ds.AcceptChanges(); - } - - public InventoryItemBase buildItem(DataRow row) - { - InventoryItemBase item = new InventoryItemBase(); - item.inventoryID = new LLUUID((string) row["UUID"]); - item.assetID = new LLUUID((string) row["assetID"]); - item.assetType = Convert.ToInt32(row["assetType"]); - item.invType = Convert.ToInt32(row["invType"]); - item.parentFolderID = new LLUUID((string) row["parentFolderID"]); - item.avatarID = new LLUUID((string) row["avatarID"]); - item.creatorsID = new LLUUID((string) row["creatorsID"]); - item.inventoryName = (string) row["inventoryName"]; - item.inventoryDescription = (string) row["inventoryDescription"]; - - item.inventoryNextPermissions = Convert.ToUInt32(row["inventoryNextPermissions"]); - item.inventoryCurrentPermissions = Convert.ToUInt32(row["inventoryCurrentPermissions"]); - item.inventoryBasePermissions = Convert.ToUInt32(row["inventoryBasePermissions"]); - item.inventoryEveryOnePermissions = Convert.ToUInt32(row["inventoryEveryOnePermissions"]); - return item; - } - - private void fillItemRow(DataRow row, InventoryItemBase item) - { - row["UUID"] = Util.ToRawUuidString(item.inventoryID); - row["assetID"] = Util.ToRawUuidString(item.assetID); - row["assetType"] = item.assetType; - row["invType"] = item.invType; - row["parentFolderID"] = Util.ToRawUuidString(item.parentFolderID); - row["avatarID"] = Util.ToRawUuidString(item.avatarID); - row["creatorsID"] = Util.ToRawUuidString(item.creatorsID); - row["inventoryName"] = item.inventoryName; - row["inventoryDescription"] = item.inventoryDescription; - - row["inventoryNextPermissions"] = item.inventoryNextPermissions; - row["inventoryCurrentPermissions"] = item.inventoryCurrentPermissions; - row["inventoryBasePermissions"] = item.inventoryBasePermissions; - row["inventoryEveryOnePermissions"] = item.inventoryEveryOnePermissions; - } - - private void addFolder(InventoryFolderBase folder) - { - DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; - - DataRow inventoryRow = inventoryFolderTable.Rows.Find(Util.ToRawUuidString(folder.folderID)); - if (inventoryRow == null) - { - inventoryRow = inventoryFolderTable.NewRow(); - fillFolderRow(inventoryRow, folder); - inventoryFolderTable.Rows.Add(inventoryRow); - } - else - { - fillFolderRow(inventoryRow, folder); - } - - invFoldersDa.Update(ds, "inventoryfolders"); - } - - private void moveFolder(InventoryFolderBase folder) - { - DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; - - DataRow inventoryRow = inventoryFolderTable.Rows.Find(Util.ToRawUuidString(folder.folderID)); - if (inventoryRow == null) - { - inventoryRow = inventoryFolderTable.NewRow(); - fillFolderRow(inventoryRow, folder); - inventoryFolderTable.Rows.Add(inventoryRow); - } - else - { - moveFolderRow(inventoryRow, folder); - } - - invFoldersDa.Update(ds, "inventoryfolders"); - } - - private void addItem(InventoryItemBase item) - { - DataTable inventoryItemTable = ds.Tables["inventoryitems"]; - - DataRow inventoryRow = inventoryItemTable.Rows.Find(Util.ToRawUuidString(item.inventoryID)); - if (inventoryRow == null) - { - inventoryRow = inventoryItemTable.NewRow(); - fillItemRow(inventoryRow, item); - inventoryItemTable.Rows.Add(inventoryRow); - } - else - { - fillItemRow(inventoryRow, item); - } - invItemsDa.Update(ds, "inventoryitems"); - } - - public void Shutdown() - { - // TODO: DataSet commit - } - - /// - /// Closes the interface - /// - public void Close() - { - } - - /// - /// The plugin being loaded - /// - /// A string containing the plugin name - public string getName() - { - return "SQLite Inventory Data Interface"; - } - - /// - /// The plugins version - /// - /// A string containing the plugin version - public string getVersion() - { - Module module = GetType().Module; - string dllName = module.Assembly.ManifestModule.Name; - Version dllVersion = module.Assembly.GetName().Version; - - - return - string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build, - dllVersion.Revision); - } - - /// - /// Returns a list of inventory items contained within the specified folder - /// - /// The UUID of the target folder - /// A List of InventoryItemBase items - public List getInventoryInFolder(LLUUID folderID) - { - List retval = new List(); - DataTable inventoryItemTable = ds.Tables["inventoryitems"]; - string selectExp = "parentFolderID = '" + Util.ToRawUuidString(folderID) + "'"; - DataRow[] rows = inventoryItemTable.Select(selectExp); - foreach (DataRow row in rows) - { - retval.Add(buildItem(row)); - } - - return retval; - } - - /// - /// Returns a list of the root folders within a users inventory - /// - /// The user whos inventory is to be searched - /// A list of folder objects - public List getUserRootFolders(LLUUID user) - { - return new List(); - } - - // see InventoryItemBase.getUserRootFolder - public InventoryFolderBase getUserRootFolder(LLUUID user) - { - List folders = new List(); - DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; - string selectExp = "agentID = '" + Util.ToRawUuidString(user) + "' AND parentID = '" + - Util.ToRawUuidString(LLUUID.Zero) + "'"; - DataRow[] rows = inventoryFolderTable.Select(selectExp); - foreach (DataRow row in rows) - { - folders.Add(buildFolder(row)); - } - - // There should only ever be one root folder for a user. However, if there's more - // than one we'll simply use the first one rather than failing. It would be even - // nicer to print some message to this effect, but this feels like it's too low a - // to put such a message out, and it's too minor right now to spare the time to - // suitably refactor. - if (folders.Count > 0) - { - return folders[0]; - } - - return null; - } - - /// - /// Append a list of all the child folders of a parent folder - /// - /// list where folders will be appended - /// ID of parent - protected void getInventoryFolders(ref List folders, LLUUID parentID) - { - DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; - string selectExp = "parentID = '" + Util.ToRawUuidString(parentID) + "'"; - DataRow[] rows = inventoryFolderTable.Select(selectExp); - foreach (DataRow row in rows) - { - folders.Add(buildFolder(row)); - } - } - - /// - /// Returns a list of inventory folders contained in the folder 'parentID' - /// - /// The folder to get subfolders for - /// A list of inventory folders - public List getInventoryFolders(LLUUID parentID) - { - List folders = new List(); - getInventoryFolders(ref folders, Util.ToRawUuidString(parentID)); - return folders; - } - - /// - /// Returns all child folders in the hierarchy from the parent folder and down - /// - /// The folder to get subfolders for - /// A list of inventory folders - protected List getFolderHierarchy(LLUUID parentID) - { - List folders = new List(); - getInventoryFolders(ref folders, Util.ToRawUuidString(parentID)); - - for (int i = 0; i < folders.Count; i++) - getInventoryFolders(ref folders, Util.ToRawUuidString(folders[i].folderID)); - - return folders; - } - - /// - /// Returns an inventory item by its UUID - /// - /// The UUID of the item to be returned - /// A class containing item information - public InventoryItemBase getInventoryItem(LLUUID item) - { - DataRow row = ds.Tables["inventoryitems"].Rows.Find(Util.ToRawUuidString(item)); - if (row != null) - { - return buildItem(row); - } - else - { - return null; - } - } - - /// - /// Returns a specified inventory folder by its UUID - /// - /// The UUID of the folder to be returned - /// A class containing folder information - public InventoryFolderBase getInventoryFolder(LLUUID folder) - { - // TODO: Deep voodoo here. If you enable this code then - // multi region breaks. No idea why, but I figured it was - // better to leave multi region at this point. It does mean - // that you don't get to see system textures why creating - // clothes and the like. :( - - DataRow row = ds.Tables["inventoryfolders"].Rows.Find(Util.ToRawUuidString(folder)); - if (row != null) - { - return buildFolder(row); - } - else - { - return null; - } - } - - /// - /// Creates a new inventory item based on item - /// - /// The item to be created - public void addInventoryItem(InventoryItemBase item) - { - addItem(item); - } - - /// - /// Updates an inventory item with item (updates based on ID) - /// - /// The updated item - public void updateInventoryItem(InventoryItemBase item) - { - addItem(item); - } - - /// - /// - /// - /// - public void deleteInventoryItem(LLUUID itemID) - { - DataTable inventoryItemTable = ds.Tables["inventoryitems"]; - - DataRow inventoryRow = inventoryItemTable.Rows.Find(Util.ToRawUuidString(itemID)); - if (inventoryRow != null) - { - inventoryRow.Delete(); - } - - invItemsDa.Update(ds, "inventoryitems"); - } - - - /// - /// Delete all items in the specified folder - /// - /// id of the folder, whose item content should be deleted - //!TODO, this is horribly inefficient, but I don't want to ruin the overall structure of this implementation - private void deleteItemsInFolder(LLUUID folderId) - { - List items = getInventoryInFolder(Util.ToRawUuidString(folderId)); - - foreach (InventoryItemBase i in items) - deleteInventoryItem(Util.ToRawUuidString(i.inventoryID)); - } - - /// - /// Adds a new folder specified by folder - /// - /// The inventory folder - public void addInventoryFolder(InventoryFolderBase folder) - { - addFolder(folder); - } - - /// - /// Updates a folder based on its ID with folder - /// - /// The inventory folder - public void updateInventoryFolder(InventoryFolderBase folder) - { - addFolder(folder); - } - - /// - /// Moves a folder based on its ID with folder - /// - /// The inventory folder - public void moveInventoryFolder(InventoryFolderBase folder) - { - moveFolder(folder); - } - - /// - /// Delete a folder - /// - /// - /// This will clean-up any child folders and child items as well - /// - /// - public void deleteInventoryFolder(LLUUID folderID) - { - List subFolders = getFolderHierarchy(Util.ToRawUuidString(folderID)); - - DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; - DataRow inventoryRow; - - //Delete all sub-folders - foreach (InventoryFolderBase f in subFolders) - { - inventoryRow = inventoryFolderTable.Rows.Find(Util.ToRawUuidString(f.folderID)); - if (inventoryRow != null) - { - deleteItemsInFolder(Util.ToRawUuidString(f.folderID)); - inventoryRow.Delete(); - } - } - - //Delete the actual row - inventoryRow = inventoryFolderTable.Rows.Find(Util.ToRawUuidString(folderID)); - if (inventoryRow != null) - { - deleteItemsInFolder(Util.ToRawUuidString(folderID)); - inventoryRow.Delete(); - } - - invFoldersDa.Update(ds, "inventoryfolders"); - } - - /*********************************************************************** - * - * Data Table definitions - * - **********************************************************************/ - - private static DataTable createInventoryItemsTable() - { - DataTable inv = new DataTable("inventoryitems"); - - createCol(inv, "UUID", typeof (String)); //inventoryID - createCol(inv, "assetID", typeof (String)); - createCol(inv, "assetType", typeof (Int32)); - createCol(inv, "invType", typeof (Int32)); - createCol(inv, "parentFolderID", typeof (String)); - createCol(inv, "avatarID", typeof (String)); - createCol(inv, "creatorsID", typeof (String)); - - createCol(inv, "inventoryName", typeof (String)); - createCol(inv, "inventoryDescription", typeof (String)); - // permissions - createCol(inv, "inventoryNextPermissions", typeof (Int32)); - createCol(inv, "inventoryCurrentPermissions", typeof (Int32)); - createCol(inv, "inventoryBasePermissions", typeof (Int32)); - createCol(inv, "inventoryEveryOnePermissions", typeof (Int32)); - - inv.PrimaryKey = new DataColumn[] {inv.Columns["UUID"]}; - return inv; - } - - private DataTable createInventoryFoldersTable() - { - DataTable fol = new DataTable("inventoryfolders"); - - createCol(fol, "UUID", typeof (String)); //folderID - createCol(fol, "name", typeof (String)); - createCol(fol, "agentID", typeof (String)); - createCol(fol, "parentID", typeof (String)); - createCol(fol, "type", typeof (Int32)); - createCol(fol, "version", typeof (Int32)); - - fol.PrimaryKey = new DataColumn[] {fol.Columns["UUID"]}; - return fol; - } - - private void setupItemsCommands(SqliteDataAdapter da, SqliteConnection conn) - { - da.InsertCommand = createInsertCommand("inventoryitems", ds.Tables["inventoryitems"]); - da.InsertCommand.Connection = conn; - - da.UpdateCommand = createUpdateCommand("inventoryitems", "UUID=:UUID", ds.Tables["inventoryitems"]); - da.UpdateCommand.Connection = conn; - - SqliteCommand delete = new SqliteCommand("delete from inventoryitems where UUID = :UUID"); - delete.Parameters.Add(createSqliteParameter("UUID", typeof (String))); - delete.Connection = conn; - da.DeleteCommand = delete; - } - - private void setupFoldersCommands(SqliteDataAdapter da, SqliteConnection conn) - { - da.InsertCommand = createInsertCommand("inventoryfolders", ds.Tables["inventoryfolders"]); - da.InsertCommand.Connection = conn; - - da.UpdateCommand = createUpdateCommand("inventoryfolders", "UUID=:UUID", ds.Tables["inventoryfolders"]); - da.UpdateCommand.Connection = conn; - - SqliteCommand delete = new SqliteCommand("delete from inventoryfolders where UUID = :UUID"); - delete.Parameters.Add(createSqliteParameter("UUID", typeof (String))); - delete.Connection = conn; - da.DeleteCommand = delete; - } - - private InventoryFolderBase buildFolder(DataRow row) - { - InventoryFolderBase folder = new InventoryFolderBase(); - folder.folderID = new LLUUID((string) row["UUID"]); - folder.name = (string) row["name"]; - folder.agentID = new LLUUID((string) row["agentID"]); - folder.parentID = new LLUUID((string) row["parentID"]); - folder.type = Convert.ToInt16(row["type"]); - folder.version = Convert.ToUInt16(row["version"]); - return folder; - } - - private void fillFolderRow(DataRow row, InventoryFolderBase folder) - { - row["UUID"] = Util.ToRawUuidString(folder.folderID); - row["name"] = folder.name; - row["agentID"] = Util.ToRawUuidString(folder.agentID); - row["parentID"] = Util.ToRawUuidString(folder.parentID); - row["type"] = folder.type; - row["version"] = folder.version; - } - - private void moveFolderRow(DataRow row, InventoryFolderBase folder) - { - row["UUID"] = Util.ToRawUuidString(folder.folderID); - row["parentID"] = Util.ToRawUuidString(folder.parentID); - } - - /*********************************************************************** - * - * Test and Initialization code - * - **********************************************************************/ - - private void InitDB(SqliteConnection conn) - { - string createInventoryItems = defineTable(createInventoryItemsTable()); - string createInventoryFolders = defineTable(createInventoryFoldersTable()); - - SqliteCommand pcmd = new SqliteCommand(createInventoryItems, conn); - SqliteCommand scmd = new SqliteCommand(createInventoryFolders, conn); - conn.Open(); - pcmd.ExecuteNonQuery(); - scmd.ExecuteNonQuery(); - conn.Close(); - } - - private bool TestTables(SqliteConnection conn) - { - SqliteCommand invItemsSelectCmd = new SqliteCommand(invItemsSelect, conn); - SqliteDataAdapter pDa = new SqliteDataAdapter(invItemsSelectCmd); - SqliteCommand invFoldersSelectCmd = new SqliteCommand(invFoldersSelect, conn); - SqliteDataAdapter sDa = new SqliteDataAdapter(invFoldersSelectCmd); - - DataSet tmpDS = new DataSet(); - try - { - pDa.Fill(tmpDS, "inventoryitems"); - sDa.Fill(tmpDS, "inventoryfolders"); - } - catch (SqliteSyntaxException) - { - MainLog.Instance.Verbose("DATASTORE", "SQLite Database doesn't exist... creating"); - InitDB(conn); - } - - pDa.Fill(tmpDS, "inventoryitems"); - sDa.Fill(tmpDS, "inventoryfolders"); - - foreach (DataColumn col in createInventoryItemsTable().Columns) - { - if (! tmpDS.Tables["inventoryitems"].Columns.Contains(col.ColumnName)) - { - MainLog.Instance.Verbose("DATASTORE", "Missing required column:" + col.ColumnName); - return false; - } - } - foreach (DataColumn col in createInventoryFoldersTable().Columns) - { - if (! tmpDS.Tables["inventoryfolders"].Columns.Contains(col.ColumnName)) - { - MainLog.Instance.Verbose("DATASTORE", "Missing required column:" + col.ColumnName); - return false; - } - } - return true; - } - } -} \ No newline at end of file +/* +* 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.Generic; +using System.Data; +using System.Reflection; +using libsecondlife; +using Mono.Data.SqliteClient; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Data.SQLite +{ + public class SQLiteInventoryStore : SQLiteBase, IInventoryData + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private const string invItemsSelect = "select * from inventoryitems"; + private const string invFoldersSelect = "select * from inventoryfolders"; + + private DataSet ds; + private SqliteDataAdapter invItemsDa; + private SqliteDataAdapter invFoldersDa; + + /// + /// used to manage concurrent access tothe sqlite database files. Only one thread may open, read, write at a time. + /// + private object InventoryLock = new object(); + + /// + /// Initialises the interface + /// + public void Initialise() + { + Initialise("inventoryStore.db", "inventoryDatabase"); + } + + public void Initialise(string dbfile, string dbname) + { + string connectionString = "URI=file:" + dbfile + ",version=3"; + + m_log.Info("[Inventory]: Sqlite - connecting: " + dbfile); + SqliteConnection conn = new SqliteConnection(connectionString); + + TestTables(conn); + + SqliteCommand itemsSelectCmd = new SqliteCommand(invItemsSelect, conn); + invItemsDa = new SqliteDataAdapter(itemsSelectCmd); + // SqliteCommandBuilder primCb = new SqliteCommandBuilder(primDa); + + SqliteCommand foldersSelectCmd = new SqliteCommand(invFoldersSelect, conn); + invFoldersDa = new SqliteDataAdapter(foldersSelectCmd); + + ds = new DataSet(); + + ds.Tables.Add(createInventoryFoldersTable()); + invFoldersDa.Fill(ds.Tables["inventoryfolders"]); + setupFoldersCommands(invFoldersDa, conn); + m_log.Info("[DATASTORE]: Populated Intentory Folders Definitions"); + + ds.Tables.Add(createInventoryItemsTable()); + invItemsDa.Fill(ds.Tables["inventoryitems"]); + setupItemsCommands(invItemsDa, conn); + m_log.Info("[DATASTORE]: Populated Intentory Items Definitions"); + + ds.AcceptChanges(); + } + + public InventoryItemBase buildItem(DataRow row) + { + InventoryItemBase item = new InventoryItemBase(); + item.inventoryID = new LLUUID((string) row["UUID"]); + item.assetID = new LLUUID((string) row["assetID"]); + item.assetType = Convert.ToInt32(row["assetType"]); + item.invType = Convert.ToInt32(row["invType"]); + item.parentFolderID = new LLUUID((string) row["parentFolderID"]); + item.avatarID = new LLUUID((string) row["avatarID"]); + item.creatorsID = new LLUUID((string) row["creatorsID"]); + item.inventoryName = (string) row["inventoryName"]; + item.inventoryDescription = (string) row["inventoryDescription"]; + + item.inventoryNextPermissions = Convert.ToUInt32(row["inventoryNextPermissions"]); + item.inventoryCurrentPermissions = Convert.ToUInt32(row["inventoryCurrentPermissions"]); + item.inventoryBasePermissions = Convert.ToUInt32(row["inventoryBasePermissions"]); + item.inventoryEveryOnePermissions = Convert.ToUInt32(row["inventoryEveryOnePermissions"]); + return item; + } + + private void fillItemRow(DataRow row, InventoryItemBase item) + { + row["UUID"] = Util.ToRawUuidString(item.inventoryID); + row["assetID"] = Util.ToRawUuidString(item.assetID); + row["assetType"] = item.assetType; + row["invType"] = item.invType; + row["parentFolderID"] = Util.ToRawUuidString(item.parentFolderID); + row["avatarID"] = Util.ToRawUuidString(item.avatarID); + row["creatorsID"] = Util.ToRawUuidString(item.creatorsID); + row["inventoryName"] = item.inventoryName; + row["inventoryDescription"] = item.inventoryDescription; + + row["inventoryNextPermissions"] = item.inventoryNextPermissions; + row["inventoryCurrentPermissions"] = item.inventoryCurrentPermissions; + row["inventoryBasePermissions"] = item.inventoryBasePermissions; + row["inventoryEveryOnePermissions"] = item.inventoryEveryOnePermissions; + } + + private void addFolder(InventoryFolderBase folder) + { + lock (InventoryLock) + { + DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; + + DataRow inventoryRow = inventoryFolderTable.Rows.Find(Util.ToRawUuidString(folder.folderID)); + if (inventoryRow == null) + { + inventoryRow = inventoryFolderTable.NewRow(); + fillFolderRow(inventoryRow, folder); + inventoryFolderTable.Rows.Add(inventoryRow); + } + else + { + fillFolderRow(inventoryRow, folder); + } + + invFoldersDa.Update(ds, "inventoryfolders"); + } + } + + private void moveFolder(InventoryFolderBase folder) + { + lock (InventoryLock) + { + DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; + + DataRow inventoryRow = inventoryFolderTable.Rows.Find(Util.ToRawUuidString(folder.folderID)); + if (inventoryRow == null) + { + inventoryRow = inventoryFolderTable.NewRow(); + fillFolderRow(inventoryRow, folder); + inventoryFolderTable.Rows.Add(inventoryRow); + } + else + { + moveFolderRow(inventoryRow, folder); + } + + invFoldersDa.Update(ds, "inventoryfolders"); + } + } + + private void addItem(InventoryItemBase item) + { + lock (InventoryLock) + { + DataTable inventoryItemTable = ds.Tables["inventoryitems"]; + + DataRow inventoryRow = inventoryItemTable.Rows.Find(Util.ToRawUuidString(item.inventoryID)); + if (inventoryRow == null) + { + inventoryRow = inventoryItemTable.NewRow(); + fillItemRow(inventoryRow, item); + inventoryItemTable.Rows.Add(inventoryRow); + } + else + { + fillItemRow(inventoryRow, item); + } + invItemsDa.Update(ds, "inventoryitems"); + } + } + + public void Shutdown() + { + // TODO: DataSet commit + } + + /// + /// Closes the interface + /// + public void Close() + { + } + + /// + /// The plugin being loaded + /// + /// A string containing the plugin name + public string getName() + { + return "SQLite Inventory Data Interface"; + } + + /// + /// The plugins version + /// + /// A string containing the plugin version + public string getVersion() + { + Module module = GetType().Module; + string dllName = module.Assembly.ManifestModule.Name; + Version dllVersion = module.Assembly.GetName().Version; + + + return + string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build, + dllVersion.Revision); + } + + /// + /// Returns a list of inventory items contained within the specified folder + /// + /// The UUID of the target folder + /// A List of InventoryItemBase items + public List getInventoryInFolder(LLUUID folderID) + { + lock (InventoryLock) + { + List retval = new List(); + DataTable inventoryItemTable = ds.Tables["inventoryitems"]; + string selectExp = "parentFolderID = '" + Util.ToRawUuidString(folderID) + "'"; + DataRow[] rows = inventoryItemTable.Select(selectExp); + foreach (DataRow row in rows) + { + retval.Add(buildItem(row)); + } + + return retval; + } + } + + /// + /// Returns a list of the root folders within a users inventory + /// + /// The user whos inventory is to be searched + /// A list of folder objects + public List getUserRootFolders(LLUUID user) + { + return new List(); + } + + // see InventoryItemBase.getUserRootFolder + public InventoryFolderBase getUserRootFolder(LLUUID user) + { + lock (InventoryLock) + { + List folders = new List(); + DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; + string selectExp = "agentID = '" + Util.ToRawUuidString(user) + "' AND parentID = '" + + Util.ToRawUuidString(LLUUID.Zero) + "'"; + DataRow[] rows = inventoryFolderTable.Select(selectExp); + foreach (DataRow row in rows) + { + folders.Add(buildFolder(row)); + } + + // There should only ever be one root folder for a user. However, if there's more + // than one we'll simply use the first one rather than failing. It would be even + // nicer to print some message to this effect, but this feels like it's too low a + // to put such a message out, and it's too minor right now to spare the time to + // suitably refactor. + if (folders.Count > 0) + { + return folders[0]; + } + + return null; + } + } + + /// + /// Append a list of all the child folders of a parent folder + /// + /// list where folders will be appended + /// ID of parent + protected void getInventoryFolders(ref List folders, LLUUID parentID) + { + lock (InventoryLock) + { + DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; + string selectExp = "parentID = '" + Util.ToRawUuidString(parentID) + "'"; + DataRow[] rows = inventoryFolderTable.Select(selectExp); + foreach (DataRow row in rows) + { + folders.Add(buildFolder(row)); + } + } + } + + /// + /// Returns a list of inventory folders contained in the folder 'parentID' + /// + /// The folder to get subfolders for + /// A list of inventory folders + public List getInventoryFolders(LLUUID parentID) + { + List folders = new List(); + getInventoryFolders(ref folders, Util.ToRawUuidString(parentID)); + return folders; + } + + /// + /// Returns all child folders in the hierarchy from the parent folder and down + /// + /// The folder to get subfolders for + /// A list of inventory folders + protected List getFolderHierarchy(LLUUID parentID) + { + List folders = new List(); + getInventoryFolders(ref folders, Util.ToRawUuidString(parentID)); + + for (int i = 0; i < folders.Count; i++) + getInventoryFolders(ref folders, Util.ToRawUuidString(folders[i].folderID)); + + return folders; + } + + /// + /// Returns an inventory item by its UUID + /// + /// The UUID of the item to be returned + /// A class containing item information + public InventoryItemBase getInventoryItem(LLUUID item) + { + lock (InventoryLock) + { + DataRow row = ds.Tables["inventoryitems"].Rows.Find(Util.ToRawUuidString(item)); + if (row != null) + { + return buildItem(row); + } + else + { + return null; + } + } + } + + /// + /// Returns a specified inventory folder by its UUID + /// + /// The UUID of the folder to be returned + /// A class containing folder information + public InventoryFolderBase getInventoryFolder(LLUUID folder) + { + // TODO: Deep voodoo here. If you enable this code then + // multi region breaks. No idea why, but I figured it was + // better to leave multi region at this point. It does mean + // that you don't get to see system textures why creating + // clothes and the like. :( + lock (InventoryLock) + { + DataRow row = ds.Tables["inventoryfolders"].Rows.Find(Util.ToRawUuidString(folder)); + if (row != null) + { + return buildFolder(row); + } + else + { + return null; + } + } + } + + /// + /// Creates a new inventory item based on item + /// + /// The item to be created + public void addInventoryItem(InventoryItemBase item) + { + addItem(item); + } + + /// + /// Updates an inventory item with item (updates based on ID) + /// + /// The updated item + public void updateInventoryItem(InventoryItemBase item) + { + addItem(item); + } + + /// + /// + /// + /// + public void deleteInventoryItem(LLUUID itemID) + { + lock (InventoryLock) + { + DataTable inventoryItemTable = ds.Tables["inventoryitems"]; + + DataRow inventoryRow = inventoryItemTable.Rows.Find(Util.ToRawUuidString(itemID)); + if (inventoryRow != null) + { + inventoryRow.Delete(); + } + + invItemsDa.Update(ds, "inventoryitems"); + } + } + + /// + /// Delete all items in the specified folder + /// + /// id of the folder, whose item content should be deleted + //!TODO, this is horribly inefficient, but I don't want to ruin the overall structure of this implementation + private void deleteItemsInFolder(LLUUID folderId) + { + List items = getInventoryInFolder(Util.ToRawUuidString(folderId)); + + foreach (InventoryItemBase i in items) + deleteInventoryItem(Util.ToRawUuidString(i.inventoryID)); + } + + /// + /// Adds a new folder specified by folder + /// + /// The inventory folder + public void addInventoryFolder(InventoryFolderBase folder) + { + addFolder(folder); + } + + /// + /// Updates a folder based on its ID with folder + /// + /// The inventory folder + public void updateInventoryFolder(InventoryFolderBase folder) + { + addFolder(folder); + } + + /// + /// Moves a folder based on its ID with folder + /// + /// The inventory folder + public void moveInventoryFolder(InventoryFolderBase folder) + { + moveFolder(folder); + } + + /// + /// Delete a folder + /// + /// + /// This will clean-up any child folders and child items as well + /// + /// + public void deleteInventoryFolder(LLUUID folderID) + { + lock (InventoryLock) + { + List subFolders = getFolderHierarchy(Util.ToRawUuidString(folderID)); + + DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; + DataRow inventoryRow; + + //Delete all sub-folders + foreach (InventoryFolderBase f in subFolders) + { + inventoryRow = inventoryFolderTable.Rows.Find(Util.ToRawUuidString(f.folderID)); + if (inventoryRow != null) + { + deleteItemsInFolder(Util.ToRawUuidString(f.folderID)); + inventoryRow.Delete(); + } + } + + //Delete the actual row + inventoryRow = inventoryFolderTable.Rows.Find(Util.ToRawUuidString(folderID)); + if (inventoryRow != null) + { + deleteItemsInFolder(Util.ToRawUuidString(folderID)); + inventoryRow.Delete(); + } + + invFoldersDa.Update(ds, "inventoryfolders"); + } + } + + /*********************************************************************** + * + * Data Table definitions + * + **********************************************************************/ + + private static DataTable createInventoryItemsTable() + { + DataTable inv = new DataTable("inventoryitems"); + + createCol(inv, "UUID", typeof (String)); //inventoryID + createCol(inv, "assetID", typeof (String)); + createCol(inv, "assetType", typeof (Int32)); + createCol(inv, "invType", typeof (Int32)); + createCol(inv, "parentFolderID", typeof (String)); + createCol(inv, "avatarID", typeof (String)); + createCol(inv, "creatorsID", typeof (String)); + + createCol(inv, "inventoryName", typeof (String)); + createCol(inv, "inventoryDescription", typeof (String)); + // permissions + createCol(inv, "inventoryNextPermissions", typeof (Int32)); + createCol(inv, "inventoryCurrentPermissions", typeof (Int32)); + createCol(inv, "inventoryBasePermissions", typeof (Int32)); + createCol(inv, "inventoryEveryOnePermissions", typeof (Int32)); + + inv.PrimaryKey = new DataColumn[] {inv.Columns["UUID"]}; + return inv; + } + + private DataTable createInventoryFoldersTable() + { + DataTable fol = new DataTable("inventoryfolders"); + + createCol(fol, "UUID", typeof (String)); //folderID + createCol(fol, "name", typeof (String)); + createCol(fol, "agentID", typeof (String)); + createCol(fol, "parentID", typeof (String)); + createCol(fol, "type", typeof (Int32)); + createCol(fol, "version", typeof (Int32)); + + fol.PrimaryKey = new DataColumn[] {fol.Columns["UUID"]}; + return fol; + } + + private void setupItemsCommands(SqliteDataAdapter da, SqliteConnection conn) + { + lock (InventoryLock) + { + da.InsertCommand = createInsertCommand("inventoryitems", ds.Tables["inventoryitems"]); + da.InsertCommand.Connection = conn; + + da.UpdateCommand = createUpdateCommand("inventoryitems", "UUID=:UUID", ds.Tables["inventoryitems"]); + da.UpdateCommand.Connection = conn; + + SqliteCommand delete = new SqliteCommand("delete from inventoryitems where UUID = :UUID"); + delete.Parameters.Add(createSqliteParameter("UUID", typeof(String))); + delete.Connection = conn; + da.DeleteCommand = delete; + } + } + + private void setupFoldersCommands(SqliteDataAdapter da, SqliteConnection conn) + { + lock (InventoryLock) + { + da.InsertCommand = createInsertCommand("inventoryfolders", ds.Tables["inventoryfolders"]); + da.InsertCommand.Connection = conn; + + da.UpdateCommand = createUpdateCommand("inventoryfolders", "UUID=:UUID", ds.Tables["inventoryfolders"]); + da.UpdateCommand.Connection = conn; + + SqliteCommand delete = new SqliteCommand("delete from inventoryfolders where UUID = :UUID"); + delete.Parameters.Add(createSqliteParameter("UUID", typeof(String))); + delete.Connection = conn; + da.DeleteCommand = delete; + } + } + + private InventoryFolderBase buildFolder(DataRow row) + { + InventoryFolderBase folder = new InventoryFolderBase(); + folder.folderID = new LLUUID((string) row["UUID"]); + folder.name = (string) row["name"]; + folder.agentID = new LLUUID((string) row["agentID"]); + folder.parentID = new LLUUID((string) row["parentID"]); + folder.type = Convert.ToInt16(row["type"]); + folder.version = Convert.ToUInt16(row["version"]); + return folder; + } + + private void fillFolderRow(DataRow row, InventoryFolderBase folder) + { + row["UUID"] = Util.ToRawUuidString(folder.folderID); + row["name"] = folder.name; + row["agentID"] = Util.ToRawUuidString(folder.agentID); + row["parentID"] = Util.ToRawUuidString(folder.parentID); + row["type"] = folder.type; + row["version"] = folder.version; + } + + private void moveFolderRow(DataRow row, InventoryFolderBase folder) + { + row["UUID"] = Util.ToRawUuidString(folder.folderID); + row["parentID"] = Util.ToRawUuidString(folder.parentID); + } + + /*********************************************************************** + * + * Test and Initialization code + * + **********************************************************************/ + + private void InitDB(SqliteConnection conn) + { + lock (InventoryLock) + { + string createInventoryItems = defineTable(createInventoryItemsTable()); + string createInventoryFolders = defineTable(createInventoryFoldersTable()); + + SqliteCommand pcmd = new SqliteCommand(createInventoryItems, conn); + SqliteCommand scmd = new SqliteCommand(createInventoryFolders, conn); + conn.Open(); + pcmd.ExecuteNonQuery(); + scmd.ExecuteNonQuery(); + conn.Close(); + } + } + + private bool TestTables(SqliteConnection conn) + { + SqliteCommand invItemsSelectCmd = new SqliteCommand(invItemsSelect, conn); + SqliteDataAdapter pDa = new SqliteDataAdapter(invItemsSelectCmd); + SqliteCommand invFoldersSelectCmd = new SqliteCommand(invFoldersSelect, conn); + SqliteDataAdapter sDa = new SqliteDataAdapter(invFoldersSelectCmd); + + DataSet tmpDS = new DataSet(); + try + { + pDa.Fill(tmpDS, "inventoryitems"); + sDa.Fill(tmpDS, "inventoryfolders"); + } + catch (SqliteSyntaxException) + { + m_log.Info("[DATASTORE]: SQLite Database doesn't exist... creating"); + InitDB(conn); + } + + pDa.Fill(tmpDS, "inventoryitems"); + sDa.Fill(tmpDS, "inventoryfolders"); + + foreach (DataColumn col in createInventoryItemsTable().Columns) + { + if (! tmpDS.Tables["inventoryitems"].Columns.Contains(col.ColumnName)) + { + m_log.Info("[DATASTORE]: Missing required column:" + col.ColumnName); + return false; + } + } + foreach (DataColumn col in createInventoryFoldersTable().Columns) + { + if (! tmpDS.Tables["inventoryfolders"].Columns.Contains(col.ColumnName)) + { + m_log.Info("[DATASTORE]: Missing required column:" + col.ColumnName); + return false; + } + } + return true; + } + } +} diff --git a/OpenSim/Framework/Data.SQLite/SQLiteManager.cs b/OpenSim/Framework/Data.SQLite/SQLiteManager.cs index b2c9a25e73..b3b84b742e 100644 --- a/OpenSim/Framework/Data.SQLite/SQLiteManager.cs +++ b/OpenSim/Framework/Data.SQLite/SQLiteManager.cs @@ -1,278 +1,280 @@ -/* -* 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.Generic; -using System.Data; -using System.Data.SQLite; -using libsecondlife; -using Mono.Data.SqliteClient; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.Data.SQLite -{ - internal class SQLiteManager : SQLiteBase - { - private IDbConnection dbcon; - - /// - /// Initialises and creates a new SQLite connection and maintains it. - /// - /// The SQLite server being connected to - /// The name of the SQLite database being used - /// The username logging into the database - /// The password for the user logging in - /// Whether to use connection pooling or not, can be one of the following: 'yes', 'true', 'no' or 'false', if unsure use 'false'. - public SQLiteManager(string hostname, string database, string username, string password, string cpooling) - { - try - { - string connectionString = "URI=file:GridServerSqlite.db;"; - dbcon = new SQLiteConnection(connectionString); - - dbcon.Open(); - } - catch (Exception e) - { - throw new Exception("Error initialising SQLite Database: " + e.ToString()); - } - } - - /// - /// Shuts down the database connection - /// - public void Close() - { - dbcon.Close(); - dbcon = null; - } - - /// - /// Runs a query with protection against SQL Injection by using parameterised input. - /// - /// The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y - /// The parameters - index so that @y is indexed as 'y' - /// A SQLite DB Command - public IDbCommand Query(string sql, Dictionary parameters) - { - SQLiteCommand dbcommand = (SQLiteCommand) dbcon.CreateCommand(); - dbcommand.CommandText = sql; - foreach (KeyValuePair param in parameters) - { - SQLiteParameter paramx = new SQLiteParameter(param.Key, param.Value); - dbcommand.Parameters.Add(paramx); - } - - return (IDbCommand) dbcommand; - } - - private bool TestTables(SQLiteConnection conn) - { - SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM regions", conn); - SQLiteDataAdapter pDa = new SQLiteDataAdapter(cmd); - DataSet tmpDS = new DataSet(); - try - { - pDa.Fill(tmpDS, "regions"); - } - catch (SqliteSyntaxException) - { - MainLog.Instance.Verbose("DATASTORE", "SQLite Database doesn't exist... creating"); - InitDB(conn); - } - return true; - } - - private DataTable createRegionsTable() - { - DataTable regions = new DataTable("regions"); - - createCol(regions, "regionHandle", typeof (ulong)); - createCol(regions, "regionName", typeof (String)); - createCol(regions, "uuid", typeof (String)); - - createCol(regions, "regionRecvKey", typeof (String)); - createCol(regions, "regionSecret", typeof (String)); - createCol(regions, "regionSendKey", typeof (String)); - - createCol(regions, "regionDataURI", typeof (String)); - createCol(regions, "serverIP", typeof (String)); - createCol(regions, "serverPort", typeof (String)); - createCol(regions, "serverURI", typeof (String)); - - - createCol(regions, "locX", typeof (uint)); - createCol(regions, "locY", typeof (uint)); - createCol(regions, "locZ", typeof (uint)); - - createCol(regions, "eastOverrideHandle", typeof (ulong)); - createCol(regions, "westOverrideHandle", typeof (ulong)); - createCol(regions, "southOverrideHandle", typeof (ulong)); - createCol(regions, "northOverrideHandle", typeof (ulong)); - - createCol(regions, "regionAssetURI", typeof (String)); - createCol(regions, "regionAssetRecvKey", typeof (String)); - createCol(regions, "regionAssetSendKey", typeof (String)); - - createCol(regions, "regionUserURI", typeof (String)); - createCol(regions, "regionUserRecvKey", typeof (String)); - createCol(regions, "regionUserSendKey", typeof (String)); - - // Add in contraints - regions.PrimaryKey = new DataColumn[] {regions.Columns["UUID"]}; - return regions; - } - - private void InitDB(SQLiteConnection conn) - { - string createUsers = defineTable(createRegionsTable()); - SQLiteCommand pcmd = new SQLiteCommand(createUsers, conn); - conn.Open(); - pcmd.ExecuteNonQuery(); - conn.Close(); - } - - - /// - /// Reads a region row from a database reader - /// - /// An active database reader - /// A region profile - public RegionProfileData getRow(IDataReader reader) - { - RegionProfileData retval = new RegionProfileData(); - - if (reader.Read()) - { - // Region Main - retval.regionHandle = (ulong) reader["regionHandle"]; - retval.regionName = (string) reader["regionName"]; - retval.UUID = new LLUUID((string) reader["uuid"]); - - // Secrets - retval.regionRecvKey = (string) reader["regionRecvKey"]; - retval.regionSecret = (string) reader["regionSecret"]; - retval.regionSendKey = (string) reader["regionSendKey"]; - - // Region Server - retval.regionDataURI = (string) reader["regionDataURI"]; - retval.regionOnline = false; // Needs to be pinged before this can be set. - retval.serverIP = (string) reader["serverIP"]; - retval.serverPort = (uint) reader["serverPort"]; - retval.serverURI = (string) reader["serverURI"]; - - // Location - retval.regionLocX = (uint) ((int) reader["locX"]); - retval.regionLocY = (uint) ((int) reader["locY"]); - retval.regionLocZ = (uint) ((int) reader["locZ"]); - - // Neighbours - 0 = No Override - retval.regionEastOverrideHandle = (ulong) reader["eastOverrideHandle"]; - retval.regionWestOverrideHandle = (ulong) reader["westOverrideHandle"]; - retval.regionSouthOverrideHandle = (ulong) reader["southOverrideHandle"]; - retval.regionNorthOverrideHandle = (ulong) reader["northOverrideHandle"]; - - // Assets - retval.regionAssetURI = (string) reader["regionAssetURI"]; - retval.regionAssetRecvKey = (string) reader["regionAssetRecvKey"]; - retval.regionAssetSendKey = (string) reader["regionAssetSendKey"]; - - // Userserver - retval.regionUserURI = (string) reader["regionUserURI"]; - retval.regionUserRecvKey = (string) reader["regionUserRecvKey"]; - retval.regionUserSendKey = (string) reader["regionUserSendKey"]; - } - else - { - throw new Exception("No rows to return"); - } - return retval; - } - - /// - /// Inserts a new region into the database - /// - /// The region to insert - /// Success? - public bool insertRow(RegionProfileData profile) - { - string sql = - "REPLACE INTO regions VALUES (regionHandle, regionName, uuid, regionRecvKey, regionSecret, regionSendKey, regionDataURI, "; - sql += - "serverIP, serverPort, serverURI, locX, locY, locZ, eastOverrideHandle, westOverrideHandle, southOverrideHandle, northOverrideHandle, regionAssetURI, regionAssetRecvKey, "; - sql += "regionAssetSendKey, regionUserURI, regionUserRecvKey, regionUserSendKey) VALUES "; - - sql += "(@regionHandle, @regionName, @uuid, @regionRecvKey, @regionSecret, @regionSendKey, @regionDataURI, "; - sql += - "@serverIP, @serverPort, @serverURI, @locX, @locY, @locZ, @eastOverrideHandle, @westOverrideHandle, @southOverrideHandle, @northOverrideHandle, @regionAssetURI, @regionAssetRecvKey, "; - sql += "@regionAssetSendKey, @regionUserURI, @regionUserRecvKey, @regionUserSendKey);"; - - Dictionary parameters = new Dictionary(); - - parameters["regionHandle"] = profile.regionHandle.ToString(); - parameters["regionName"] = profile.regionName; - parameters["uuid"] = profile.UUID.ToString(); - parameters["regionRecvKey"] = profile.regionRecvKey; - parameters["regionSendKey"] = profile.regionSendKey; - parameters["regionDataURI"] = profile.regionDataURI; - parameters["serverIP"] = profile.serverIP; - parameters["serverPort"] = profile.serverPort.ToString(); - parameters["serverURI"] = profile.serverURI; - parameters["locX"] = profile.regionLocX.ToString(); - parameters["locY"] = profile.regionLocY.ToString(); - parameters["locZ"] = profile.regionLocZ.ToString(); - parameters["eastOverrideHandle"] = profile.regionEastOverrideHandle.ToString(); - parameters["westOverrideHandle"] = profile.regionWestOverrideHandle.ToString(); - parameters["northOverrideHandle"] = profile.regionNorthOverrideHandle.ToString(); - parameters["southOverrideHandle"] = profile.regionSouthOverrideHandle.ToString(); - parameters["regionAssetURI"] = profile.regionAssetURI; - parameters["regionAssetRecvKey"] = profile.regionAssetRecvKey; - parameters["regionAssetSendKey"] = profile.regionAssetSendKey; - parameters["regionUserURI"] = profile.regionUserURI; - parameters["regionUserRecvKey"] = profile.regionUserRecvKey; - parameters["regionUserSendKey"] = profile.regionUserSendKey; - - bool returnval = false; - - try - { - IDbCommand result = Query(sql, parameters); - - if (result.ExecuteNonQuery() == 1) - returnval = true; - - result.Dispose(); - } - catch (Exception) - { - return false; - } - - return returnval; - } - } -} \ No newline at end of file +/* +* 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.Generic; +using System.Data; +using System.Data.SQLite; +using libsecondlife; +using Mono.Data.SqliteClient; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Data.SQLite +{ + internal class SQLiteManager : SQLiteBase + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private IDbConnection dbcon; + + /// + /// Initialises and creates a new SQLite connection and maintains it. + /// + /// The SQLite server being connected to + /// The name of the SQLite database being used + /// The username logging into the database + /// The password for the user logging in + /// Whether to use connection pooling or not, can be one of the following: 'yes', 'true', 'no' or 'false', if unsure use 'false'. + public SQLiteManager(string hostname, string database, string username, string password, string cpooling) + { + try + { + string connectionString = "URI=file:GridServerSqlite.db;"; + dbcon = new SQLiteConnection(connectionString); + + dbcon.Open(); + } + catch (Exception e) + { + throw new Exception("Error initialising SQLite Database: " + e.ToString()); + } + } + + /// + /// Shuts down the database connection + /// + public void Close() + { + dbcon.Close(); + dbcon = null; + } + + /// + /// Runs a query with protection against SQL Injection by using parameterised input. + /// + /// The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y + /// The parameters - index so that @y is indexed as 'y' + /// A SQLite DB Command + public IDbCommand Query(string sql, Dictionary parameters) + { + SQLiteCommand dbcommand = (SQLiteCommand) dbcon.CreateCommand(); + dbcommand.CommandText = sql; + foreach (KeyValuePair param in parameters) + { + SQLiteParameter paramx = new SQLiteParameter(param.Key, param.Value); + dbcommand.Parameters.Add(paramx); + } + + return (IDbCommand) dbcommand; + } + + private bool TestTables(SQLiteConnection conn) + { + SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM regions", conn); + SQLiteDataAdapter pDa = new SQLiteDataAdapter(cmd); + DataSet tmpDS = new DataSet(); + try + { + pDa.Fill(tmpDS, "regions"); + } + catch (SqliteSyntaxException) + { + m_log.Info("[DATASTORE]: SQLite Database doesn't exist... creating"); + InitDB(conn); + } + return true; + } + + private DataTable createRegionsTable() + { + DataTable regions = new DataTable("regions"); + + createCol(regions, "regionHandle", typeof (ulong)); + createCol(regions, "regionName", typeof (String)); + createCol(regions, "uuid", typeof (String)); + + createCol(regions, "regionRecvKey", typeof (String)); + createCol(regions, "regionSecret", typeof (String)); + createCol(regions, "regionSendKey", typeof (String)); + + createCol(regions, "regionDataURI", typeof (String)); + createCol(regions, "serverIP", typeof (String)); + createCol(regions, "serverPort", typeof (String)); + createCol(regions, "serverURI", typeof (String)); + + + createCol(regions, "locX", typeof (uint)); + createCol(regions, "locY", typeof (uint)); + createCol(regions, "locZ", typeof (uint)); + + createCol(regions, "eastOverrideHandle", typeof (ulong)); + createCol(regions, "westOverrideHandle", typeof (ulong)); + createCol(regions, "southOverrideHandle", typeof (ulong)); + createCol(regions, "northOverrideHandle", typeof (ulong)); + + createCol(regions, "regionAssetURI", typeof (String)); + createCol(regions, "regionAssetRecvKey", typeof (String)); + createCol(regions, "regionAssetSendKey", typeof (String)); + + createCol(regions, "regionUserURI", typeof (String)); + createCol(regions, "regionUserRecvKey", typeof (String)); + createCol(regions, "regionUserSendKey", typeof (String)); + + // Add in contraints + regions.PrimaryKey = new DataColumn[] {regions.Columns["UUID"]}; + return regions; + } + + private void InitDB(SQLiteConnection conn) + { + string createUsers = defineTable(createRegionsTable()); + SQLiteCommand pcmd = new SQLiteCommand(createUsers, conn); + conn.Open(); + pcmd.ExecuteNonQuery(); + conn.Close(); + } + + + /// + /// Reads a region row from a database reader + /// + /// An active database reader + /// A region profile + public RegionProfileData getRow(IDataReader reader) + { + RegionProfileData retval = new RegionProfileData(); + + if (reader.Read()) + { + // Region Main + retval.regionHandle = (ulong) reader["regionHandle"]; + retval.regionName = (string) reader["regionName"]; + retval.UUID = new LLUUID((string) reader["uuid"]); + + // Secrets + retval.regionRecvKey = (string) reader["regionRecvKey"]; + retval.regionSecret = (string) reader["regionSecret"]; + retval.regionSendKey = (string) reader["regionSendKey"]; + + // Region Server + retval.regionDataURI = (string) reader["regionDataURI"]; + retval.regionOnline = false; // Needs to be pinged before this can be set. + retval.serverIP = (string) reader["serverIP"]; + retval.serverPort = (uint) reader["serverPort"]; + retval.serverURI = (string) reader["serverURI"]; + + // Location + retval.regionLocX = (uint) ((int) reader["locX"]); + retval.regionLocY = (uint) ((int) reader["locY"]); + retval.regionLocZ = (uint) ((int) reader["locZ"]); + + // Neighbours - 0 = No Override + retval.regionEastOverrideHandle = (ulong) reader["eastOverrideHandle"]; + retval.regionWestOverrideHandle = (ulong) reader["westOverrideHandle"]; + retval.regionSouthOverrideHandle = (ulong) reader["southOverrideHandle"]; + retval.regionNorthOverrideHandle = (ulong) reader["northOverrideHandle"]; + + // Assets + retval.regionAssetURI = (string) reader["regionAssetURI"]; + retval.regionAssetRecvKey = (string) reader["regionAssetRecvKey"]; + retval.regionAssetSendKey = (string) reader["regionAssetSendKey"]; + + // Userserver + retval.regionUserURI = (string) reader["regionUserURI"]; + retval.regionUserRecvKey = (string) reader["regionUserRecvKey"]; + retval.regionUserSendKey = (string) reader["regionUserSendKey"]; + } + else + { + throw new Exception("No rows to return"); + } + return retval; + } + + /// + /// Inserts a new region into the database + /// + /// The region to insert + /// Success? + public bool insertRow(RegionProfileData profile) + { + string sql = + "REPLACE INTO regions VALUES (regionHandle, regionName, uuid, regionRecvKey, regionSecret, regionSendKey, regionDataURI, "; + sql += + "serverIP, serverPort, serverURI, locX, locY, locZ, eastOverrideHandle, westOverrideHandle, southOverrideHandle, northOverrideHandle, regionAssetURI, regionAssetRecvKey, "; + sql += "regionAssetSendKey, regionUserURI, regionUserRecvKey, regionUserSendKey) VALUES "; + + sql += "(@regionHandle, @regionName, @uuid, @regionRecvKey, @regionSecret, @regionSendKey, @regionDataURI, "; + sql += + "@serverIP, @serverPort, @serverURI, @locX, @locY, @locZ, @eastOverrideHandle, @westOverrideHandle, @southOverrideHandle, @northOverrideHandle, @regionAssetURI, @regionAssetRecvKey, "; + sql += "@regionAssetSendKey, @regionUserURI, @regionUserRecvKey, @regionUserSendKey);"; + + Dictionary parameters = new Dictionary(); + + parameters["regionHandle"] = profile.regionHandle.ToString(); + parameters["regionName"] = profile.regionName; + parameters["uuid"] = profile.UUID.ToString(); + parameters["regionRecvKey"] = profile.regionRecvKey; + parameters["regionSendKey"] = profile.regionSendKey; + parameters["regionDataURI"] = profile.regionDataURI; + parameters["serverIP"] = profile.serverIP; + parameters["serverPort"] = profile.serverPort.ToString(); + parameters["serverURI"] = profile.serverURI; + parameters["locX"] = profile.regionLocX.ToString(); + parameters["locY"] = profile.regionLocY.ToString(); + parameters["locZ"] = profile.regionLocZ.ToString(); + parameters["eastOverrideHandle"] = profile.regionEastOverrideHandle.ToString(); + parameters["westOverrideHandle"] = profile.regionWestOverrideHandle.ToString(); + parameters["northOverrideHandle"] = profile.regionNorthOverrideHandle.ToString(); + parameters["southOverrideHandle"] = profile.regionSouthOverrideHandle.ToString(); + parameters["regionAssetURI"] = profile.regionAssetURI; + parameters["regionAssetRecvKey"] = profile.regionAssetRecvKey; + parameters["regionAssetSendKey"] = profile.regionAssetSendKey; + parameters["regionUserURI"] = profile.regionUserURI; + parameters["regionUserRecvKey"] = profile.regionUserRecvKey; + parameters["regionUserSendKey"] = profile.regionUserSendKey; + + bool returnval = false; + + try + { + IDbCommand result = Query(sql, parameters); + + if (result.ExecuteNonQuery() == 1) + returnval = true; + + result.Dispose(); + } + catch (Exception) + { + return false; + } + + return returnval; + } + } +} diff --git a/OpenSim/Framework/Data.SQLite/SQLiteRegionData.cs b/OpenSim/Framework/Data.SQLite/SQLiteRegionData.cs new file mode 100644 index 0000000000..760a3bacfb --- /dev/null +++ b/OpenSim/Framework/Data.SQLite/SQLiteRegionData.cs @@ -0,0 +1,1733 @@ +/* +* 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.Generic; +using System.Data; +using System.IO; +using libsecondlife; +using Mono.Data.SqliteClient; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Region.Environment.Interfaces; +using OpenSim.Region.Environment.LandManagement; +using OpenSim.Region.Environment.Scenes; + +namespace OpenSim.Framework.Data.SQLite +{ + public class SQLiteRegionData : IRegionDataStore + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private const string primSelect = "select * from prims"; + private const string shapeSelect = "select * from primshapes"; + private const string itemsSelect = "select * from primitems"; + private const string terrainSelect = "select * from terrain limit 1"; + private const string landSelect = "select * from land"; + private const string landAccessListSelect = "select * from landaccesslist"; + + private DataSet ds; + private SqliteDataAdapter primDa; + private SqliteDataAdapter shapeDa; + private SqliteDataAdapter itemsDa; + private SqliteDataAdapter terrainDa; + private SqliteDataAdapter landDa; + private SqliteDataAdapter landAccessListDa; + + private SqliteConnection m_conn; + + private String m_connectionString; + + // Temporary attribute while this is experimental + private bool persistPrimInventories; + + /*********************************************************************** + * + * Public Interface Functions + * + **********************************************************************/ + + // see IRegionDataStore + public void Initialise(string connectionString, bool persistPrimInventories) + { + m_connectionString = connectionString; + this.persistPrimInventories = persistPrimInventories; + + ds = new DataSet(); + + m_log.Info("[DATASTORE]: Sqlite - connecting: " + connectionString); + m_conn = new SqliteConnection(m_connectionString); + m_conn.Open(); + + SqliteCommand primSelectCmd = new SqliteCommand(primSelect, m_conn); + primDa = new SqliteDataAdapter(primSelectCmd); + // SqliteCommandBuilder primCb = new SqliteCommandBuilder(primDa); + + SqliteCommand shapeSelectCmd = new SqliteCommand(shapeSelect, m_conn); + shapeDa = new SqliteDataAdapter(shapeSelectCmd); + // SqliteCommandBuilder shapeCb = new SqliteCommandBuilder(shapeDa); + + SqliteCommand itemsSelectCmd = new SqliteCommand(itemsSelect, m_conn); + itemsDa = new SqliteDataAdapter(itemsSelectCmd); + + SqliteCommand terrainSelectCmd = new SqliteCommand(terrainSelect, m_conn); + terrainDa = new SqliteDataAdapter(terrainSelectCmd); + + SqliteCommand landSelectCmd = new SqliteCommand(landSelect, m_conn); + landDa = new SqliteDataAdapter(landSelectCmd); + + SqliteCommand landAccessListSelectCmd = new SqliteCommand(landAccessListSelect, m_conn); + landAccessListDa = new SqliteDataAdapter(landAccessListSelectCmd); + + // We fill the data set, now we've got copies in memory for the information + // TODO: see if the linkage actually holds. + // primDa.FillSchema(ds, SchemaType.Source, "PrimSchema"); + TestTables(m_conn); + + lock (ds) + { + ds.Tables.Add(createPrimTable()); + setupPrimCommands(primDa, m_conn); + primDa.Fill(ds.Tables["prims"]); + + ds.Tables.Add(createShapeTable()); + setupShapeCommands(shapeDa, m_conn); + + if (persistPrimInventories) + { + ds.Tables.Add(createItemsTable()); + setupItemsCommands(itemsDa, m_conn); + itemsDa.Fill(ds.Tables["primitems"]); + } + + ds.Tables.Add(createTerrainTable()); + setupTerrainCommands(terrainDa, m_conn); + + ds.Tables.Add(createLandTable()); + setupLandCommands(landDa, m_conn); + + ds.Tables.Add(createLandAccessListTable()); + setupLandAccessCommands(landAccessListDa, m_conn); + + // WORKAROUND: This is a work around for sqlite on + // windows, which gets really unhappy with blob columns + // that have no sample data in them. At some point we + // need to actually find a proper way to handle this. + try + { + shapeDa.Fill(ds.Tables["primshapes"]); + } + catch (Exception) + { + m_log.Info("[DATASTORE]: Caught fill error on primshapes table"); + } + + try + { + terrainDa.Fill(ds.Tables["terrain"]); + } + catch (Exception) + { + m_log.Info("[DATASTORE]: Caught fill error on terrain table"); + } + + try + { + landDa.Fill(ds.Tables["land"]); + } + catch (Exception) + { + m_log.Info("[DATASTORE]: Caught fill error on land table"); + } + + try + { + landAccessListDa.Fill(ds.Tables["landaccesslist"]); + } + catch (Exception) + { + m_log.Info("[DATASTORE]: Caught fill error on landaccesslist table"); + } + return; + } + } + + public void StoreObject(SceneObjectGroup obj, LLUUID regionUUID) + { + lock (ds) + { + foreach (SceneObjectPart prim in obj.Children.Values) + { + if ((prim.ObjectFlags & (uint) LLObject.ObjectFlags.Physics) == 0) + { + m_log.Info("[DATASTORE]: Adding obj: " + obj.UUID + " to region: " + regionUUID); + addPrim(prim, Util.ToRawUuidString(obj.UUID), Util.ToRawUuidString(regionUUID)); + } + else if (prim.Stopped) + { + //m_log.Info("[DATASTORE]: " + + //"Adding stopped obj: " + obj.UUID + " to region: " + regionUUID); + //addPrim(prim, Util.ToRawUuidString(obj.UUID), Util.ToRawUuidString(regionUUID)); + } + else + { + // m_log.Info("[DATASTORE]: Ignoring Physical obj: " + obj.UUID + " in region: " + regionUUID); + } + } + } + + Commit(); + // m_log.Info("[Dump of prims]: " + ds.GetXml()); + } + + public void RemoveObject(LLUUID obj, LLUUID regionUUID) + { + m_log.InfoFormat("[DATASTORE]: Removing obj: {0} from region: {1}", obj.UUID, regionUUID); + + DataTable prims = ds.Tables["prims"]; + DataTable shapes = ds.Tables["primshapes"]; + + string selectExp = "SceneGroupID = '" + Util.ToRawUuidString(obj) + "'"; + lock (ds) + { + DataRow[] primRows = prims.Select(selectExp); + foreach (DataRow row in primRows) + { + // Remove shape rows + LLUUID uuid = new LLUUID((string) row["UUID"]); + DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(uuid)); + if (shapeRow != null) + { + shapeRow.Delete(); + } + + if (persistPrimInventories) + { + RemoveItems(uuid); + } + + // Remove prim row + row.Delete(); + } + } + + Commit(); + } + + /// + /// Remove all persisted items of the given prim. + /// The caller must acquire the necessrary synchronization locks and commit or rollback changes. + /// + private void RemoveItems(LLUUID uuid) + { + DataTable items = ds.Tables["primitems"]; + + String sql = String.Format("primID = '{0}'", uuid); + DataRow[] itemRows = items.Select(sql); + + foreach (DataRow itemRow in itemRows) + { + itemRow.Delete(); + } + } + + /// + /// Load persisted objects from region storage. + /// + /// + /// List of loaded groups + public List LoadObjects(LLUUID regionUUID) + { + Dictionary createdObjects = new Dictionary(); + + List retvals = new List(); + + DataTable prims = ds.Tables["prims"]; + DataTable shapes = ds.Tables["primshapes"]; + + string byRegion = "RegionUUID = '" + Util.ToRawUuidString(regionUUID) + "'"; + string orderByParent = "ParentID ASC"; + + lock (ds) + { + DataRow[] primsForRegion = prims.Select(byRegion, orderByParent); + m_log.Info("[DATASTORE]: " + + "Loaded " + primsForRegion.Length + " prims for region: " + regionUUID); + + foreach (DataRow primRow in primsForRegion) + { + try + { + SceneObjectPart prim = null; + + string uuid = (string) primRow["UUID"]; + string objID = (string) primRow["SceneGroupID"]; + if (uuid == objID) //is new SceneObjectGroup ? + { + SceneObjectGroup group = new SceneObjectGroup(); + prim = buildPrim(primRow); + DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(prim.UUID)); + if (shapeRow != null) + { + prim.Shape = buildShape(shapeRow); + } + else + { + m_log.Info( + "No shape found for prim in storage, so setting default box shape"); + prim.Shape = PrimitiveBaseShape.Default; + } + group.AddPart(prim); + group.RootPart = prim; + + createdObjects.Add(Util.ToRawUuidString(group.UUID), group); + retvals.Add(group); + } + else + { + prim = buildPrim(primRow); + DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(prim.UUID)); + if (shapeRow != null) + { + prim.Shape = buildShape(shapeRow); + } + else + { + m_log.Info( + "No shape found for prim in storage, so setting default box shape"); + prim.Shape = PrimitiveBaseShape.Default; + } + createdObjects[new LLUUID(objID)].AddPart(prim); + } + + if (persistPrimInventories) + { + LoadItems(prim); + } + } + catch (Exception e) + { + m_log.Error("[DATASTORE]: Failed create prim object, exception and data follows"); + m_log.Info("[DATASTORE]: " + e.ToString()); + foreach (DataColumn col in prims.Columns) + { + m_log.Info("[DATASTORE]: Col: " + col.ColumnName + " => " + primRow[col]); + } + } + } + } + return retvals; + } + + /// + /// Load in a prim's persisted inventory. + /// + /// + private void LoadItems(SceneObjectPart prim) + { + //m_log.DebugFormat("[DATASTORE]: Loading inventory for {0}, {1}", prim.Name, prim.UUID); + + DataTable dbItems = ds.Tables["primitems"]; + + String sql = String.Format("primID = '{0}'", prim.UUID.ToString()); + DataRow[] dbItemRows = dbItems.Select(sql); + + IList inventory = new List(); + + foreach (DataRow row in dbItemRows) + { + TaskInventoryItem item = buildItem(row); + inventory.Add(item); + + //m_log.DebugFormat("[DATASTORE]: Restored item {0}, {1}", item.Name, item.ItemID); + } + + prim.RestoreInventoryItems(inventory); + + // XXX A nasty little hack to recover the folder id for the prim (which is currently stored in + // every item). This data should really be stored in the prim table itself. + if (dbItemRows.Length > 0) + { + prim.FolderID = inventory[0].ParentID; + } + } + + public void StoreTerrain(double[,] ter, LLUUID regionID) + { + lock (ds) + { + int revision = Util.UnixTimeSinceEpoch(); + + // the following is an work around for .NET. The perf + // issues associated with it aren't as bad as you think. + m_log.Info("[DATASTORE]: Storing terrain revision r" + revision.ToString()); + String sql = "insert into terrain(RegionUUID, Revision, Heightfield)" + + " values(:RegionUUID, :Revision, :Heightfield)"; + + using (SqliteCommand cmd = new SqliteCommand(sql, m_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":RegionUUID", Util.ToRawUuidString(regionID))); + cmd.Parameters.Add(new SqliteParameter(":Revision", revision)); + cmd.Parameters.Add(new SqliteParameter(":Heightfield", serializeTerrain(ter))); + cmd.ExecuteNonQuery(); + } + + // This is added to get rid of the infinitely growing + // terrain databases which negatively impact on SQLite + // over time. Before reenabling this feature there + // needs to be a limitter put on the number of + // revisions in the database, as this old + // implementation is a DOS attack waiting to happen. + + using ( + SqliteCommand cmd = + new SqliteCommand("delete from terrain where RegionUUID=:RegionUUID and Revision < :Revision", + m_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":RegionUUID", Util.ToRawUuidString(regionID))); + cmd.Parameters.Add(new SqliteParameter(":Revision", revision)); + cmd.ExecuteNonQuery(); + } + } + } + + public double[,] LoadTerrain(LLUUID regionID) + { + lock (ds) + { + double[,] terret = new double[256,256]; + terret.Initialize(); + + String sql = "select RegionUUID, Revision, Heightfield from terrain" + + " where RegionUUID=:RegionUUID order by Revision desc"; + + using (SqliteCommand cmd = new SqliteCommand(sql, m_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":RegionUUID", Util.ToRawUuidString(regionID))); + + using (IDataReader row = cmd.ExecuteReader()) + { + int rev = 0; + if (row.Read()) + { + // TODO: put this into a function + MemoryStream str = new MemoryStream((byte[]) row["Heightfield"]); + BinaryReader br = new BinaryReader(str); + for (int x = 0; x < 256; x++) + { + for (int y = 0; y < 256; y++) + { + terret[x, y] = br.ReadDouble(); + } + } + rev = (int) row["Revision"]; + } + else + { + m_log.Info("[DATASTORE]: No terrain found for region"); + return null; + } + + m_log.Info("[DATASTORE]: Loaded terrain revision r" + rev.ToString()); + } + } + return terret; + } + } + + public void RemoveLandObject(LLUUID globalID) + { + lock (ds) + { + using (SqliteCommand cmd = new SqliteCommand("delete from land where UUID=:UUID", m_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":UUID", Util.ToRawUuidString(globalID))); + cmd.ExecuteNonQuery(); + } + + using (SqliteCommand cmd = new SqliteCommand("delete from landaccesslist where LandUUID=:UUID", m_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":UUID", Util.ToRawUuidString(globalID))); + cmd.ExecuteNonQuery(); + } + } + } + + public void StoreLandObject(Land parcel, LLUUID regionUUID) + { + lock (ds) + { + DataTable land = ds.Tables["land"]; + DataTable landaccesslist = ds.Tables["landaccesslist"]; + + DataRow landRow = land.Rows.Find(Util.ToRawUuidString(parcel.landData.globalID)); + if (landRow == null) + { + landRow = land.NewRow(); + fillLandRow(landRow, parcel.landData, regionUUID); + land.Rows.Add(landRow); + } + else + { + fillLandRow(landRow, parcel.landData, regionUUID); + } + + using ( + SqliteCommand cmd = new SqliteCommand("delete from landaccesslist where LandUUID=:LandUUID", m_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":LandUUID", Util.ToRawUuidString(parcel.landData.globalID))); + cmd.ExecuteNonQuery(); + } + + foreach (ParcelManager.ParcelAccessEntry entry in parcel.landData.parcelAccessList) + { + DataRow newAccessRow = landaccesslist.NewRow(); + fillLandAccessRow(newAccessRow, entry, parcel.landData.globalID); + landaccesslist.Rows.Add(newAccessRow); + } + } + + Commit(); + } + + public List LoadLandObjects(LLUUID regionUUID) + { + List landDataForRegion = new List(); + lock (ds) + { + DataTable land = ds.Tables["land"]; + DataTable landaccesslist = ds.Tables["landaccesslist"]; + string searchExp = "RegionUUID = '" + Util.ToRawUuidString(regionUUID) + "'"; + DataRow[] rawDataForRegion = land.Select(searchExp); + foreach (DataRow rawDataLand in rawDataForRegion) + { + LandData newLand = buildLandData(rawDataLand); + string accessListSearchExp = "LandUUID = '" + Util.ToRawUuidString(newLand.globalID) + "'"; + DataRow[] rawDataForLandAccessList = landaccesslist.Select(accessListSearchExp); + foreach (DataRow rawDataLandAccess in rawDataForLandAccessList) + { + newLand.parcelAccessList.Add(buildLandAccessData(rawDataLandAccess)); + } + + landDataForRegion.Add(newLand); + } + } + return landDataForRegion; + } + + public void Commit() + { + lock (ds) + { + primDa.Update(ds, "prims"); + shapeDa.Update(ds, "primshapes"); + + if (persistPrimInventories) + { + itemsDa.Update(ds, "primitems"); + } + + terrainDa.Update(ds, "terrain"); + landDa.Update(ds, "land"); + landAccessListDa.Update(ds, "landaccesslist"); + ds.AcceptChanges(); + } + } + + public void Shutdown() + { + Commit(); + } + + /*********************************************************************** + * + * Database Definition Functions + * + * This should be db agnostic as we define them in ADO.NET terms + * + **********************************************************************/ + + private void createCol(DataTable dt, string name, Type type) + { + DataColumn col = new DataColumn(name, type); + dt.Columns.Add(col); + } + + private DataTable createTerrainTable() + { + DataTable terrain = new DataTable("terrain"); + + createCol(terrain, "RegionUUID", typeof (String)); + createCol(terrain, "Revision", typeof (Int32)); + createCol(terrain, "Heightfield", typeof (Byte[])); + + return terrain; + } + + private DataTable createPrimTable() + { + DataTable prims = new DataTable("prims"); + + createCol(prims, "UUID", typeof (String)); + createCol(prims, "RegionUUID", typeof (String)); + createCol(prims, "ParentID", typeof (Int32)); + createCol(prims, "CreationDate", typeof (Int32)); + createCol(prims, "Name", typeof (String)); + createCol(prims, "SceneGroupID", typeof (String)); + // various text fields + createCol(prims, "Text", typeof (String)); + createCol(prims, "Description", typeof (String)); + createCol(prims, "SitName", typeof (String)); + createCol(prims, "TouchName", typeof (String)); + // permissions + createCol(prims, "ObjectFlags", typeof (Int32)); + createCol(prims, "CreatorID", typeof (String)); + createCol(prims, "OwnerID", typeof (String)); + createCol(prims, "GroupID", typeof (String)); + createCol(prims, "LastOwnerID", typeof (String)); + createCol(prims, "OwnerMask", typeof (Int32)); + createCol(prims, "NextOwnerMask", typeof (Int32)); + createCol(prims, "GroupMask", typeof (Int32)); + createCol(prims, "EveryoneMask", typeof (Int32)); + createCol(prims, "BaseMask", typeof (Int32)); + // vectors + createCol(prims, "PositionX", typeof (Double)); + createCol(prims, "PositionY", typeof (Double)); + createCol(prims, "PositionZ", typeof (Double)); + createCol(prims, "GroupPositionX", typeof (Double)); + createCol(prims, "GroupPositionY", typeof (Double)); + createCol(prims, "GroupPositionZ", typeof (Double)); + createCol(prims, "VelocityX", typeof (Double)); + createCol(prims, "VelocityY", typeof (Double)); + createCol(prims, "VelocityZ", typeof (Double)); + createCol(prims, "AngularVelocityX", typeof (Double)); + createCol(prims, "AngularVelocityY", typeof (Double)); + createCol(prims, "AngularVelocityZ", typeof (Double)); + createCol(prims, "AccelerationX", typeof (Double)); + createCol(prims, "AccelerationY", typeof (Double)); + createCol(prims, "AccelerationZ", typeof (Double)); + // quaternions + createCol(prims, "RotationX", typeof (Double)); + createCol(prims, "RotationY", typeof (Double)); + createCol(prims, "RotationZ", typeof (Double)); + createCol(prims, "RotationW", typeof (Double)); + + // sit target + createCol(prims, "SitTargetOffsetX", typeof (Double)); + createCol(prims, "SitTargetOffsetY", typeof (Double)); + createCol(prims, "SitTargetOffsetZ", typeof (Double)); + + createCol(prims, "SitTargetOrientW", typeof (Double)); + createCol(prims, "SitTargetOrientX", typeof (Double)); + createCol(prims, "SitTargetOrientY", typeof (Double)); + createCol(prims, "SitTargetOrientZ", typeof (Double)); + + // Add in contraints + prims.PrimaryKey = new DataColumn[] {prims.Columns["UUID"]}; + + return prims; + } + + private DataTable createShapeTable() + { + DataTable shapes = new DataTable("primshapes"); + createCol(shapes, "UUID", typeof (String)); + // shape is an enum + createCol(shapes, "Shape", typeof (Int32)); + // vectors + createCol(shapes, "ScaleX", typeof (Double)); + createCol(shapes, "ScaleY", typeof (Double)); + createCol(shapes, "ScaleZ", typeof (Double)); + // paths + createCol(shapes, "PCode", typeof (Int32)); + createCol(shapes, "PathBegin", typeof (Int32)); + createCol(shapes, "PathEnd", typeof (Int32)); + createCol(shapes, "PathScaleX", typeof (Int32)); + createCol(shapes, "PathScaleY", typeof (Int32)); + createCol(shapes, "PathShearX", typeof (Int32)); + createCol(shapes, "PathShearY", typeof (Int32)); + createCol(shapes, "PathSkew", typeof (Int32)); + createCol(shapes, "PathCurve", typeof (Int32)); + createCol(shapes, "PathRadiusOffset", typeof (Int32)); + createCol(shapes, "PathRevolutions", typeof (Int32)); + createCol(shapes, "PathTaperX", typeof (Int32)); + createCol(shapes, "PathTaperY", typeof (Int32)); + createCol(shapes, "PathTwist", typeof (Int32)); + createCol(shapes, "PathTwistBegin", typeof (Int32)); + // profile + createCol(shapes, "ProfileBegin", typeof (Int32)); + createCol(shapes, "ProfileEnd", typeof (Int32)); + createCol(shapes, "ProfileCurve", typeof (Int32)); + createCol(shapes, "ProfileHollow", typeof (Int32)); + // text TODO: this isn't right, but I'm not sure the right + // way to specify this as a blob atm + createCol(shapes, "Texture", typeof (Byte[])); + createCol(shapes, "ExtraParams", typeof (Byte[])); + + shapes.PrimaryKey = new DataColumn[] {shapes.Columns["UUID"]}; + + return shapes; + } + + private DataTable createItemsTable() + { + DataTable items = new DataTable("primitems"); + + createCol(items, "itemID", typeof (String)); + createCol(items, "primID", typeof (String)); + createCol(items, "assetID", typeof (String)); + createCol(items, "parentFolderID", typeof (String)); + + createCol(items, "invType", typeof (Int32)); + createCol(items, "assetType", typeof (Int32)); + + createCol(items, "name", typeof (String)); + createCol(items, "description", typeof (String)); + + createCol(items, "creationDate", typeof (Int64)); + createCol(items, "creatorID", typeof (String)); + createCol(items, "ownerID", typeof (String)); + createCol(items, "lastOwnerID", typeof (String)); + createCol(items, "groupID", typeof (String)); + + createCol(items, "nextPermissions", typeof (UInt32)); + createCol(items, "currentPermissions", typeof (UInt32)); + createCol(items, "basePermissions", typeof (UInt32)); + createCol(items, "everyonePermissions", typeof (UInt32)); + createCol(items, "groupPermissions", typeof (UInt32)); + + items.PrimaryKey = new DataColumn[] {items.Columns["itemID"]}; + + return items; + } + + private DataTable createLandTable() + { + DataTable land = new DataTable("land"); + createCol(land, "UUID", typeof (String)); + createCol(land, "RegionUUID", typeof (String)); + createCol(land, "LocalLandID", typeof (UInt32)); + + // Bitmap is a byte[512] + createCol(land, "Bitmap", typeof (Byte[])); + + createCol(land, "Name", typeof (String)); + createCol(land, "Desc", typeof (String)); + createCol(land, "OwnerUUID", typeof (String)); + createCol(land, "IsGroupOwned", typeof (Boolean)); + createCol(land, "Area", typeof (Int32)); + createCol(land, "AuctionID", typeof (Int32)); //Unemplemented + createCol(land, "Category", typeof (Int32)); //Enum libsecondlife.Parcel.ParcelCategory + createCol(land, "ClaimDate", typeof (Int32)); + createCol(land, "ClaimPrice", typeof (Int32)); + createCol(land, "GroupUUID", typeof (string)); + createCol(land, "SalePrice", typeof (Int32)); + createCol(land, "LandStatus", typeof (Int32)); //Enum. libsecondlife.Parcel.ParcelStatus + createCol(land, "LandFlags", typeof (UInt32)); + createCol(land, "LandingType", typeof (Byte)); + createCol(land, "MediaAutoScale", typeof (Byte)); + createCol(land, "MediaTextureUUID", typeof (String)); + createCol(land, "MediaURL", typeof (String)); + createCol(land, "MusicURL", typeof (String)); + createCol(land, "PassHours", typeof (Double)); + createCol(land, "PassPrice", typeof (UInt32)); + createCol(land, "SnapshotUUID", typeof (String)); + createCol(land, "UserLocationX", typeof (Double)); + createCol(land, "UserLocationY", typeof (Double)); + createCol(land, "UserLocationZ", typeof (Double)); + createCol(land, "UserLookAtX", typeof (Double)); + createCol(land, "UserLookAtY", typeof (Double)); + createCol(land, "UserLookAtZ", typeof (Double)); + + land.PrimaryKey = new DataColumn[] {land.Columns["UUID"]}; + + return land; + } + + private DataTable createLandAccessListTable() + { + DataTable landaccess = new DataTable("landaccesslist"); + createCol(landaccess, "LandUUID", typeof (String)); + createCol(landaccess, "AccessUUID", typeof (String)); + createCol(landaccess, "Flags", typeof (UInt32)); + + return landaccess; + } + + /*********************************************************************** + * + * Convert between ADO.NET <=> OpenSim Objects + * + * These should be database independant + * + **********************************************************************/ + + private SceneObjectPart buildPrim(DataRow row) + { + // TODO: this doesn't work yet because something more + // interesting has to be done to actually get these values + // back out. Not enough time to figure it out yet. + SceneObjectPart prim = new SceneObjectPart(); + prim.UUID = new LLUUID((String) row["UUID"]); + // explicit conversion of integers is required, which sort + // of sucks. No idea if there is a shortcut here or not. + prim.ParentID = Convert.ToUInt32(row["ParentID"]); + prim.CreationDate = Convert.ToInt32(row["CreationDate"]); + prim.Name = (String) row["Name"]; + // various text fields + prim.Text = (String) row["Text"]; + prim.Description = (String) row["Description"]; + prim.SitName = (String) row["SitName"]; + prim.TouchName = (String) row["TouchName"]; + // permissions + prim.ObjectFlags = Convert.ToUInt32(row["ObjectFlags"]); + prim.CreatorID = new LLUUID((String) row["CreatorID"]); + prim.OwnerID = new LLUUID((String) row["OwnerID"]); + prim.GroupID = new LLUUID((String) row["GroupID"]); + prim.LastOwnerID = new LLUUID((String) row["LastOwnerID"]); + prim.OwnerMask = Convert.ToUInt32(row["OwnerMask"]); + prim.NextOwnerMask = Convert.ToUInt32(row["NextOwnerMask"]); + prim.GroupMask = Convert.ToUInt32(row["GroupMask"]); + prim.EveryoneMask = Convert.ToUInt32(row["EveryoneMask"]); + prim.BaseMask = Convert.ToUInt32(row["BaseMask"]); + // vectors + prim.OffsetPosition = new LLVector3( + Convert.ToSingle(row["PositionX"]), + Convert.ToSingle(row["PositionY"]), + Convert.ToSingle(row["PositionZ"]) + ); + prim.GroupPosition = new LLVector3( + Convert.ToSingle(row["GroupPositionX"]), + Convert.ToSingle(row["GroupPositionY"]), + Convert.ToSingle(row["GroupPositionZ"]) + ); + prim.Velocity = new LLVector3( + Convert.ToSingle(row["VelocityX"]), + Convert.ToSingle(row["VelocityY"]), + Convert.ToSingle(row["VelocityZ"]) + ); + prim.AngularVelocity = new LLVector3( + Convert.ToSingle(row["AngularVelocityX"]), + Convert.ToSingle(row["AngularVelocityY"]), + Convert.ToSingle(row["AngularVelocityZ"]) + ); + prim.Acceleration = new LLVector3( + Convert.ToSingle(row["AccelerationX"]), + Convert.ToSingle(row["AccelerationY"]), + Convert.ToSingle(row["AccelerationZ"]) + ); + // quaternions + prim.RotationOffset = new LLQuaternion( + Convert.ToSingle(row["RotationX"]), + Convert.ToSingle(row["RotationY"]), + Convert.ToSingle(row["RotationZ"]), + Convert.ToSingle(row["RotationW"]) + ); + + try + { + prim.SetSitTargetLL(new LLVector3( + Convert.ToSingle(row["SitTargetOffsetX"]), + Convert.ToSingle(row["SitTargetOffsetY"]), + Convert.ToSingle(row["SitTargetOffsetZ"])), new LLQuaternion( + Convert.ToSingle( + row["SitTargetOrientX"]), + Convert.ToSingle( + row["SitTargetOrientY"]), + Convert.ToSingle( + row["SitTargetOrientZ"]), + Convert.ToSingle( + row["SitTargetOrientW"]))); + } + catch (InvalidCastException) + { + // Database table was created before we got here and now has null values :P + m_conn.Open(); + SqliteCommand cmd = + new SqliteCommand("ALTER TABLE prims ADD COLUMN SitTargetOffsetX float NOT NULL default 0;", m_conn); + cmd.ExecuteNonQuery(); + cmd = + new SqliteCommand("ALTER TABLE prims ADD COLUMN SitTargetOffsetY float NOT NULL default 0;", m_conn); + cmd.ExecuteNonQuery(); + cmd = + new SqliteCommand("ALTER TABLE prims ADD COLUMN SitTargetOffsetZ float NOT NULL default 0;", m_conn); + cmd.ExecuteNonQuery(); + cmd = + new SqliteCommand("ALTER TABLE prims ADD COLUMN SitTargetOrientW float NOT NULL default 0;", m_conn); + cmd.ExecuteNonQuery(); + cmd = + new SqliteCommand("ALTER TABLE prims ADD COLUMN SitTargetOrientX float NOT NULL default 0;", m_conn); + cmd.ExecuteNonQuery(); + cmd = + new SqliteCommand("ALTER TABLE prims ADD COLUMN SitTargetOrientY float NOT NULL default 0;", m_conn); + cmd.ExecuteNonQuery(); + cmd = + new SqliteCommand("ALTER TABLE prims ADD COLUMN SitTargetOrientZ float NOT NULL default 0;", m_conn); + cmd.ExecuteNonQuery(); + } + + return prim; + } + + /// + /// Build a prim inventory item from the persisted data. + /// + /// + /// + private TaskInventoryItem buildItem(DataRow row) + { + TaskInventoryItem taskItem = new TaskInventoryItem(); + + taskItem.ItemID = new LLUUID((String)row["itemID"]); + taskItem.ParentPartID = new LLUUID((String)row["primID"]); + taskItem.AssetID = new LLUUID((String)row["assetID"]); + taskItem.ParentID = new LLUUID((String)row["parentFolderID"]); + + taskItem.InvType = Convert.ToInt32(row["invType"]); + taskItem.Type = Convert.ToInt32(row["assetType"]); + + taskItem.Name = (String)row["name"]; + taskItem.Description = (String)row["description"]; + taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]); + taskItem.CreatorID = new LLUUID((String)row["creatorID"]); + taskItem.OwnerID = new LLUUID((String)row["ownerID"]); + taskItem.LastOwnerID = new LLUUID((String)row["lastOwnerID"]); + taskItem.GroupID = new LLUUID((String)row["groupID"]); + + taskItem.NextOwnerMask = Convert.ToUInt32(row["nextPermissions"]); + taskItem.OwnerMask = Convert.ToUInt32(row["currentPermissions"]); + taskItem.BaseMask = Convert.ToUInt32(row["basePermissions"]); + taskItem.EveryoneMask = Convert.ToUInt32(row["everyonePermissions"]); + taskItem.GroupMask = Convert.ToUInt32(row["groupPermissions"]); + + return taskItem; + } + + private LandData buildLandData(DataRow row) + { + LandData newData = new LandData(); + + newData.globalID = new LLUUID((String) row["UUID"]); + newData.localID = Convert.ToInt32(row["LocalLandID"]); + + // Bitmap is a byte[512] + newData.landBitmapByteArray = (Byte[]) row["Bitmap"]; + + newData.landName = (String) row["Name"]; + newData.landDesc = (String) row["Desc"]; + newData.ownerID = (String) row["OwnerUUID"]; + newData.isGroupOwned = (Boolean) row["IsGroupOwned"]; + newData.area = Convert.ToInt32(row["Area"]); + newData.auctionID = Convert.ToUInt32(row["AuctionID"]); //Unemplemented + newData.category = (Parcel.ParcelCategory) Convert.ToInt32(row["Category"]); + //Enum libsecondlife.Parcel.ParcelCategory + newData.claimDate = Convert.ToInt32(row["ClaimDate"]); + newData.claimPrice = Convert.ToInt32(row["ClaimPrice"]); + newData.groupID = new LLUUID((String) row["GroupUUID"]); + newData.salePrice = Convert.ToInt32(row["SalePrice"]); + newData.landStatus = (Parcel.ParcelStatus) Convert.ToInt32(row["LandStatus"]); + //Enum. libsecondlife.Parcel.ParcelStatus + newData.landFlags = Convert.ToUInt32(row["LandFlags"]); + newData.landingType = (Byte) row["LandingType"]; + newData.mediaAutoScale = (Byte) row["MediaAutoScale"]; + newData.mediaID = new LLUUID((String) row["MediaTextureUUID"]); + newData.mediaURL = (String) row["MediaURL"]; + newData.musicURL = (String) row["MusicURL"]; + newData.passHours = Convert.ToSingle(row["PassHours"]); + newData.passPrice = Convert.ToInt32(row["PassPrice"]); + newData.snapshotID = (String) row["SnapshotUUID"]; + + newData.userLocation = + new LLVector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]), + Convert.ToSingle(row["UserLocationZ"])); + newData.userLookAt = + new LLVector3(Convert.ToSingle(row["UserLookAtX"]), Convert.ToSingle(row["UserLookAtY"]), + Convert.ToSingle(row["UserLookAtZ"])); + newData.parcelAccessList = new List(); + + return newData; + } + + private ParcelManager.ParcelAccessEntry buildLandAccessData(DataRow row) + { + ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); + entry.AgentID = new LLUUID((string) row["AccessUUID"]); + entry.Flags = (ParcelManager.AccessList) row["Flags"]; + entry.Time = new DateTime(); + return entry; + } + + private Array serializeTerrain(double[,] val) + { + MemoryStream str = new MemoryStream(65536*sizeof (double)); + BinaryWriter bw = new BinaryWriter(str); + + // TODO: COMPATIBILITY - Add byte-order conversions + for (int x = 0; x < 256; x++) + for (int y = 0; y < 256; y++) + bw.Write(val[x, y]); + + return str.ToArray(); + } + +// private void fillTerrainRow(DataRow row, LLUUID regionUUID, int rev, double[,] val) +// { +// row["RegionUUID"] = regionUUID; +// row["Revision"] = rev; + +// MemoryStream str = new MemoryStream(65536*sizeof (double)); +// BinaryWriter bw = new BinaryWriter(str); + +// // TODO: COMPATIBILITY - Add byte-order conversions +// for (int x = 0; x < 256; x++) +// for (int y = 0; y < 256; y++) +// bw.Write(val[x, y]); + +// row["Heightfield"] = str.ToArray(); +// } + + private void fillPrimRow(DataRow row, SceneObjectPart prim, LLUUID sceneGroupID, LLUUID regionUUID) + { + row["UUID"] = Util.ToRawUuidString(prim.UUID); + row["RegionUUID"] = Util.ToRawUuidString(regionUUID); + row["ParentID"] = prim.ParentID; + row["CreationDate"] = prim.CreationDate; + row["Name"] = prim.Name; + row["SceneGroupID"] = Util.ToRawUuidString(sceneGroupID); + // the UUID of the root part for this SceneObjectGroup + // various text fields + row["Text"] = prim.Text; + row["Description"] = prim.Description; + row["SitName"] = prim.SitName; + row["TouchName"] = prim.TouchName; + // permissions + row["ObjectFlags"] = prim.ObjectFlags; + row["CreatorID"] = Util.ToRawUuidString(prim.CreatorID); + row["OwnerID"] = Util.ToRawUuidString(prim.OwnerID); + row["GroupID"] = Util.ToRawUuidString(prim.GroupID); + row["LastOwnerID"] = Util.ToRawUuidString(prim.LastOwnerID); + row["OwnerMask"] = prim.OwnerMask; + row["NextOwnerMask"] = prim.NextOwnerMask; + row["GroupMask"] = prim.GroupMask; + row["EveryoneMask"] = prim.EveryoneMask; + row["BaseMask"] = prim.BaseMask; + // vectors + row["PositionX"] = prim.OffsetPosition.X; + row["PositionY"] = prim.OffsetPosition.Y; + row["PositionZ"] = prim.OffsetPosition.Z; + row["GroupPositionX"] = prim.GroupPosition.X; + row["GroupPositionY"] = prim.GroupPosition.Y; + row["GroupPositionZ"] = prim.GroupPosition.Z; + row["VelocityX"] = prim.Velocity.X; + row["VelocityY"] = prim.Velocity.Y; + row["VelocityZ"] = prim.Velocity.Z; + row["AngularVelocityX"] = prim.AngularVelocity.X; + row["AngularVelocityY"] = prim.AngularVelocity.Y; + row["AngularVelocityZ"] = prim.AngularVelocity.Z; + row["AccelerationX"] = prim.Acceleration.X; + row["AccelerationY"] = prim.Acceleration.Y; + row["AccelerationZ"] = prim.Acceleration.Z; + // quaternions + row["RotationX"] = prim.RotationOffset.X; + row["RotationY"] = prim.RotationOffset.Y; + row["RotationZ"] = prim.RotationOffset.Z; + row["RotationW"] = prim.RotationOffset.W; + + // Sit target + LLVector3 sitTargetPos = prim.GetSitTargetPositionLL(); + row["SitTargetOffsetX"] = sitTargetPos.X; + row["SitTargetOffsetY"] = sitTargetPos.Y; + row["SitTargetOffsetZ"] = sitTargetPos.Z; + + LLQuaternion sitTargetOrient = prim.GetSitTargetOrientationLL(); + row["SitTargetOrientW"] = sitTargetOrient.W; + row["SitTargetOrientX"] = sitTargetOrient.X; + row["SitTargetOrientY"] = sitTargetOrient.Y; + row["SitTargetOrientZ"] = sitTargetOrient.Z; + } + + private void fillItemRow(DataRow row, TaskInventoryItem taskItem) + { + row["itemID"] = taskItem.ItemID; + row["primID"] = taskItem.ParentPartID; + row["assetID"] = taskItem.AssetID; + row["parentFolderID"] = taskItem.ParentID; + + row["invType"] = taskItem.InvType; + row["assetType"] = taskItem.Type; + + row["name"] = taskItem.Name; + row["description"] = taskItem.Description; + row["creationDate"] = taskItem.CreationDate; + row["creatorID"] = taskItem.CreatorID; + row["ownerID"] = taskItem.OwnerID; + row["lastOwnerID"] = taskItem.LastOwnerID; + row["groupID"] = taskItem.GroupID; + row["nextPermissions"] = taskItem.NextOwnerMask; + row["currentPermissions"] = taskItem.OwnerMask; + row["basePermissions"] = taskItem.BaseMask; + row["everyonePermissions"] = taskItem.EveryoneMask; + row["groupPermissions"] = taskItem.GroupMask; + } + + private void fillLandRow(DataRow row, LandData land, LLUUID regionUUID) + { + row["UUID"] = Util.ToRawUuidString(land.globalID); + row["RegionUUID"] = Util.ToRawUuidString(regionUUID); + row["LocalLandID"] = land.localID; + + // Bitmap is a byte[512] + row["Bitmap"] = land.landBitmapByteArray; + + row["Name"] = land.landName; + row["Desc"] = land.landDesc; + row["OwnerUUID"] = Util.ToRawUuidString(land.ownerID); + row["IsGroupOwned"] = land.isGroupOwned; + row["Area"] = land.area; + row["AuctionID"] = land.auctionID; //Unemplemented + row["Category"] = land.category; //Enum libsecondlife.Parcel.ParcelCategory + row["ClaimDate"] = land.claimDate; + row["ClaimPrice"] = land.claimPrice; + row["GroupUUID"] = Util.ToRawUuidString(land.groupID); + row["SalePrice"] = land.salePrice; + row["LandStatus"] = land.landStatus; //Enum. libsecondlife.Parcel.ParcelStatus + row["LandFlags"] = land.landFlags; + row["LandingType"] = land.landingType; + row["MediaAutoScale"] = land.mediaAutoScale; + row["MediaTextureUUID"] = Util.ToRawUuidString(land.mediaID); + row["MediaURL"] = land.mediaURL; + row["MusicURL"] = land.musicURL; + row["PassHours"] = land.passHours; + row["PassPrice"] = land.passPrice; + row["SnapshotUUID"] = Util.ToRawUuidString(land.snapshotID); + row["UserLocationX"] = land.userLocation.X; + row["UserLocationY"] = land.userLocation.Y; + row["UserLocationZ"] = land.userLocation.Z; + row["UserLookAtX"] = land.userLookAt.X; + row["UserLookAtY"] = land.userLookAt.Y; + row["UserLookAtZ"] = land.userLookAt.Z; + } + + private void fillLandAccessRow(DataRow row, ParcelManager.ParcelAccessEntry entry, LLUUID parcelID) + { + row["LandUUID"] = Util.ToRawUuidString(parcelID); + row["AccessUUID"] = Util.ToRawUuidString(entry.AgentID); + row["Flags"] = entry.Flags; + } + + private PrimitiveBaseShape buildShape(DataRow row) + { + PrimitiveBaseShape s = new PrimitiveBaseShape(); + s.Scale = new LLVector3( + Convert.ToSingle(row["ScaleX"]), + Convert.ToSingle(row["ScaleY"]), + Convert.ToSingle(row["ScaleZ"]) + ); + // paths + s.PCode = Convert.ToByte(row["PCode"]); + s.PathBegin = Convert.ToUInt16(row["PathBegin"]); + s.PathEnd = Convert.ToUInt16(row["PathEnd"]); + s.PathScaleX = Convert.ToByte(row["PathScaleX"]); + s.PathScaleY = Convert.ToByte(row["PathScaleY"]); + s.PathShearX = Convert.ToByte(row["PathShearX"]); + s.PathShearY = Convert.ToByte(row["PathShearY"]); + s.PathSkew = Convert.ToSByte(row["PathSkew"]); + s.PathCurve = Convert.ToByte(row["PathCurve"]); + s.PathRadiusOffset = Convert.ToSByte(row["PathRadiusOffset"]); + s.PathRevolutions = Convert.ToByte(row["PathRevolutions"]); + s.PathTaperX = Convert.ToSByte(row["PathTaperX"]); + s.PathTaperY = Convert.ToSByte(row["PathTaperY"]); + s.PathTwist = Convert.ToSByte(row["PathTwist"]); + s.PathTwistBegin = Convert.ToSByte(row["PathTwistBegin"]); + // profile + s.ProfileBegin = Convert.ToUInt16(row["ProfileBegin"]); + s.ProfileEnd = Convert.ToUInt16(row["ProfileEnd"]); + s.ProfileCurve = Convert.ToByte(row["ProfileCurve"]); + s.ProfileHollow = Convert.ToUInt16(row["ProfileHollow"]); + // text TODO: this isn't right] = but I'm not sure the right + // way to specify this as a blob atm + + byte[] textureEntry = (byte[]) row["Texture"]; + s.TextureEntry = textureEntry; + + s.ExtraParams = (byte[]) row["ExtraParams"]; + // System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); + // string texture = encoding.GetString((Byte[])row["Texture"]); + // if (!texture.StartsWith("<")) + // { + // //here so that we can still work with old format database files (ie from before I added xml serialization) + // LLObject.TextureEntry textureEntry = null; + // textureEntry = new LLObject.TextureEntry(new LLUUID(texture)); + // s.TextureEntry = textureEntry.ToBytes(); + // } + // else + // { + // TextureBlock textureEntry = TextureBlock.FromXmlString(texture); + // s.TextureEntry = textureEntry.TextureData; + // s.ExtraParams = textureEntry.ExtraParams; + // } + + return s; + } + + private void fillShapeRow(DataRow row, SceneObjectPart prim) + { + PrimitiveBaseShape s = prim.Shape; + row["UUID"] = Util.ToRawUuidString(prim.UUID); + // shape is an enum + row["Shape"] = 0; + // vectors + row["ScaleX"] = s.Scale.X; + row["ScaleY"] = s.Scale.Y; + row["ScaleZ"] = s.Scale.Z; + // paths + row["PCode"] = s.PCode; + row["PathBegin"] = s.PathBegin; + row["PathEnd"] = s.PathEnd; + row["PathScaleX"] = s.PathScaleX; + row["PathScaleY"] = s.PathScaleY; + row["PathShearX"] = s.PathShearX; + row["PathShearY"] = s.PathShearY; + row["PathSkew"] = s.PathSkew; + row["PathCurve"] = s.PathCurve; + row["PathRadiusOffset"] = s.PathRadiusOffset; + row["PathRevolutions"] = s.PathRevolutions; + row["PathTaperX"] = s.PathTaperX; + row["PathTaperY"] = s.PathTaperY; + row["PathTwist"] = s.PathTwist; + row["PathTwistBegin"] = s.PathTwistBegin; + // profile + row["ProfileBegin"] = s.ProfileBegin; + row["ProfileEnd"] = s.ProfileEnd; + row["ProfileCurve"] = s.ProfileCurve; + row["ProfileHollow"] = s.ProfileHollow; + + row["Texture"] = s.TextureEntry; + row["ExtraParams"] = s.ExtraParams; + } + + private void addPrim(SceneObjectPart prim, LLUUID sceneGroupID, LLUUID regionUUID) + { + DataTable prims = ds.Tables["prims"]; + DataTable shapes = ds.Tables["primshapes"]; + + DataRow primRow = prims.Rows.Find(Util.ToRawUuidString(prim.UUID)); + if (primRow == null) + { + primRow = prims.NewRow(); + fillPrimRow(primRow, prim, sceneGroupID, regionUUID); + prims.Rows.Add(primRow); + } + else + { + fillPrimRow(primRow, prim, sceneGroupID, regionUUID); + } + + DataRow shapeRow = shapes.Rows.Find(Util.ToRawUuidString(prim.UUID)); + if (shapeRow == null) + { + shapeRow = shapes.NewRow(); + fillShapeRow(shapeRow, prim); + shapes.Rows.Add(shapeRow); + } + else + { + fillShapeRow(shapeRow, prim); + } + } + + // see IRegionDatastore + public void StorePrimInventory(LLUUID primID, ICollection items) + { + if (!persistPrimInventories) + return; + + m_log.InfoFormat("[DATASTORE]: Entered StorePrimInventory with prim ID {0}", primID); + + DataTable dbItems = ds.Tables["primitems"]; + + // For now, we're just going to crudely remove all the previous inventory items + // no matter whether they have changed or not, and replace them with the current set. + lock (ds) + { + RemoveItems(primID); + + // repalce with current inventory details + foreach (TaskInventoryItem newItem in items) + { +// m_log.InfoFormat( +// "[DATASTORE]: ", +// "Adding item {0}, {1} to prim ID {2}", +// newItem.Name, newItem.ItemID, newItem.ParentPartID); + + DataRow newItemRow = dbItems.NewRow(); + fillItemRow(newItemRow, newItem); + dbItems.Rows.Add(newItemRow); + } + } + + Commit(); + } + + /*********************************************************************** + * + * SQL Statement Creation Functions + * + * These functions create SQL statements for update, insert, and create. + * They can probably be factored later to have a db independant + * portion and a db specific portion + * + **********************************************************************/ + + private SqliteCommand createInsertCommand(string table, DataTable dt) + { + /** + * This is subtle enough to deserve some commentary. + * Instead of doing *lots* and *lots of hardcoded strings + * for database definitions we'll use the fact that + * realistically all insert statements look like "insert + * into A(b, c) values(:b, :c) on the parameterized query + * front. If we just have a list of b, c, etc... we can + * generate these strings instead of typing them out. + */ + string[] cols = new string[dt.Columns.Count]; + for (int i = 0; i < dt.Columns.Count; i++) + { + DataColumn col = dt.Columns[i]; + cols[i] = col.ColumnName; + } + + string sql = "insert into " + table + "("; + sql += String.Join(", ", cols); + // important, the first ':' needs to be here, the rest get added in the join + sql += ") values (:"; + sql += String.Join(", :", cols); + sql += ")"; + SqliteCommand cmd = new SqliteCommand(sql); + + // this provides the binding for all our parameters, so + // much less code than it used to be + foreach (DataColumn col in dt.Columns) + { + cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType)); + } + return cmd; + } + + private SqliteCommand createUpdateCommand(string table, string pk, DataTable dt) + { + string sql = "update " + table + " set "; + string subsql = String.Empty; + foreach (DataColumn col in dt.Columns) + { + if (subsql.Length > 0) + { + // a map function would rock so much here + subsql += ", "; + } + subsql += col.ColumnName + "= :" + col.ColumnName; + } + sql += subsql; + sql += " where " + pk; + SqliteCommand cmd = new SqliteCommand(sql); + + // this provides the binding for all our parameters, so + // much less code than it used to be + + foreach (DataColumn col in dt.Columns) + { + cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType)); + } + return cmd; + } + + + private string defineTable(DataTable dt) + { + string sql = "create table " + dt.TableName + "("; + string subsql = String.Empty; + foreach (DataColumn col in dt.Columns) + { + if (subsql.Length > 0) + { + // a map function would rock so much here + subsql += ",\n"; + } + subsql += col.ColumnName + " " + sqliteType(col.DataType); + if (dt.PrimaryKey.Length > 0 && col == dt.PrimaryKey[0]) + { + subsql += " primary key"; + } + } + sql += subsql; + sql += ")"; + return sql; + } + + /*********************************************************************** + * + * Database Binding functions + * + * These will be db specific due to typing, and minor differences + * in databases. + * + **********************************************************************/ + + /// + /// This is a convenience function that collapses 5 repetitive + /// lines for defining SqliteParameters to 2 parameters: + /// column name and database type. + /// + /// It assumes certain conventions like :param as the param + /// name to replace in parametrized queries, and that source + /// version is always current version, both of which are fine + /// for us. + /// + ///a built sqlite parameter + private SqliteParameter createSqliteParameter(string name, Type type) + { + SqliteParameter param = new SqliteParameter(); + param.ParameterName = ":" + name; + param.DbType = dbtypeFromType(type); + param.SourceColumn = name; + param.SourceVersion = DataRowVersion.Current; + return param; + } + + private void setupPrimCommands(SqliteDataAdapter da, SqliteConnection conn) + { + da.InsertCommand = createInsertCommand("prims", ds.Tables["prims"]); + da.InsertCommand.Connection = conn; + + da.UpdateCommand = createUpdateCommand("prims", "UUID=:UUID", ds.Tables["prims"]); + da.UpdateCommand.Connection = conn; + + SqliteCommand delete = new SqliteCommand("delete from prims where UUID = :UUID"); + delete.Parameters.Add(createSqliteParameter("UUID", typeof (String))); + delete.Connection = conn; + da.DeleteCommand = delete; + } + + private void setupItemsCommands(SqliteDataAdapter da, SqliteConnection conn) + { + da.InsertCommand = createInsertCommand("primitems", ds.Tables["primitems"]); + da.InsertCommand.Connection = conn; + + da.UpdateCommand = createUpdateCommand("primitems", "itemID = :itemID", ds.Tables["primitems"]); + da.UpdateCommand.Connection = conn; + + SqliteCommand delete = new SqliteCommand("delete from primitems where itemID = :itemID"); + delete.Parameters.Add(createSqliteParameter("itemID", typeof (String))); + delete.Connection = conn; + da.DeleteCommand = delete; + } + + private void setupTerrainCommands(SqliteDataAdapter da, SqliteConnection conn) + { + da.InsertCommand = createInsertCommand("terrain", ds.Tables["terrain"]); + da.InsertCommand.Connection = conn; + } + + private void setupLandCommands(SqliteDataAdapter da, SqliteConnection conn) + { + da.InsertCommand = createInsertCommand("land", ds.Tables["land"]); + da.InsertCommand.Connection = conn; + + da.UpdateCommand = createUpdateCommand("land", "UUID=:UUID", ds.Tables["land"]); + da.UpdateCommand.Connection = conn; + } + + private void setupLandAccessCommands(SqliteDataAdapter da, SqliteConnection conn) + { + da.InsertCommand = createInsertCommand("landaccesslist", ds.Tables["landaccesslist"]); + da.InsertCommand.Connection = conn; + } + + private void setupShapeCommands(SqliteDataAdapter da, SqliteConnection conn) + { + da.InsertCommand = createInsertCommand("primshapes", ds.Tables["primshapes"]); + da.InsertCommand.Connection = conn; + + da.UpdateCommand = createUpdateCommand("primshapes", "UUID=:UUID", ds.Tables["primshapes"]); + da.UpdateCommand.Connection = conn; + + SqliteCommand delete = new SqliteCommand("delete from primshapes where UUID = :UUID"); + delete.Parameters.Add(createSqliteParameter("UUID", typeof (String))); + delete.Connection = conn; + da.DeleteCommand = delete; + } + + /// + /// Create the necessary database tables. + /// + /// + private void InitDB(SqliteConnection conn) + { + string createPrims = defineTable(createPrimTable()); + string createShapes = defineTable(createShapeTable()); + string createItems = defineTable(createItemsTable()); + string createTerrain = defineTable(createTerrainTable()); + string createLand = defineTable(createLandTable()); + string createLandAccessList = defineTable(createLandAccessListTable()); + + SqliteCommand pcmd = new SqliteCommand(createPrims, conn); + SqliteCommand scmd = new SqliteCommand(createShapes, conn); + SqliteCommand icmd = new SqliteCommand(createItems, conn); + SqliteCommand tcmd = new SqliteCommand(createTerrain, conn); + SqliteCommand lcmd = new SqliteCommand(createLand, conn); + SqliteCommand lalcmd = new SqliteCommand(createLandAccessList, conn); + + conn.Open(); + + try + { + pcmd.ExecuteNonQuery(); + } + catch (SqliteSyntaxException) + { + m_log.Warn("[SQLITE]: Primitives Table Already Exists"); + } + + try + { + scmd.ExecuteNonQuery(); + } + catch (SqliteSyntaxException) + { + m_log.Warn("[SQLITE]: Shapes Table Already Exists"); + } + + if (persistPrimInventories) + { + try + { + icmd.ExecuteNonQuery(); + } + catch (SqliteSyntaxException) + { + m_log.Warn("[SQLITE]: Primitives Inventory Table Already Exists"); + } + } + + try + { + tcmd.ExecuteNonQuery(); + } + catch (SqliteSyntaxException) + { + m_log.Warn("[SQLITE]: Terrain Table Already Exists"); + } + + try + { + lcmd.ExecuteNonQuery(); + } + catch (SqliteSyntaxException) + { + m_log.Warn("[SQLITE]: Land Table Already Exists"); + } + + try + { + lalcmd.ExecuteNonQuery(); + } + catch (SqliteSyntaxException) + { + m_log.Warn("[SQLITE]: LandAccessList Table Already Exists"); + } + conn.Close(); + } + + private bool TestTables(SqliteConnection conn) + { + SqliteCommand primSelectCmd = new SqliteCommand(primSelect, conn); + SqliteDataAdapter pDa = new SqliteDataAdapter(primSelectCmd); + + SqliteCommand shapeSelectCmd = new SqliteCommand(shapeSelect, conn); + SqliteDataAdapter sDa = new SqliteDataAdapter(shapeSelectCmd); + + SqliteCommand itemsSelectCmd = new SqliteCommand(itemsSelect, conn); + SqliteDataAdapter iDa = new SqliteDataAdapter(itemsSelectCmd); + + SqliteCommand terrainSelectCmd = new SqliteCommand(terrainSelect, conn); + SqliteDataAdapter tDa = new SqliteDataAdapter(terrainSelectCmd); + + SqliteCommand landSelectCmd = new SqliteCommand(landSelect, conn); + SqliteDataAdapter lDa = new SqliteDataAdapter(landSelectCmd); + + SqliteCommand landAccessListSelectCmd = new SqliteCommand(landAccessListSelect, conn); + SqliteDataAdapter lalDa = new SqliteDataAdapter(landAccessListSelectCmd); + + DataSet tmpDS = new DataSet(); + try + { + pDa.Fill(tmpDS, "prims"); + sDa.Fill(tmpDS, "primshapes"); + + if (persistPrimInventories) + iDa.Fill(tmpDS, "primitems"); + + tDa.Fill(tmpDS, "terrain"); + lDa.Fill(tmpDS, "land"); + lalDa.Fill(tmpDS, "landaccesslist"); + } + catch (SqliteSyntaxException) + { + m_log.Info("[DATASTORE]: SQLite Database doesn't exist... creating"); + InitDB(conn); + } + + pDa.Fill(tmpDS, "prims"); + sDa.Fill(tmpDS, "primshapes"); + + if (persistPrimInventories) + iDa.Fill(tmpDS, "primitems"); + + tDa.Fill(tmpDS, "terrain"); + lDa.Fill(tmpDS, "land"); + lalDa.Fill(tmpDS, "landaccesslist"); + + foreach (DataColumn col in createPrimTable().Columns) + { + if (!tmpDS.Tables["prims"].Columns.Contains(col.ColumnName)) + { + m_log.Info("[DATASTORE]: Missing required column:" + col.ColumnName); + return false; + } + } + + foreach (DataColumn col in createShapeTable().Columns) + { + if (!tmpDS.Tables["primshapes"].Columns.Contains(col.ColumnName)) + { + m_log.Info("[DATASTORE]: Missing required column:" + col.ColumnName); + return false; + } + } + + // XXX primitems should probably go here eventually + + foreach (DataColumn col in createTerrainTable().Columns) + { + if (!tmpDS.Tables["terrain"].Columns.Contains(col.ColumnName)) + { + m_log.Info("[DATASTORE]: Missing require column:" + col.ColumnName); + return false; + } + } + + foreach (DataColumn col in createLandTable().Columns) + { + if (!tmpDS.Tables["land"].Columns.Contains(col.ColumnName)) + { + m_log.Info("[DATASTORE]: Missing require column:" + col.ColumnName); + return false; + } + } + + foreach (DataColumn col in createLandAccessListTable().Columns) + { + if (!tmpDS.Tables["landaccesslist"].Columns.Contains(col.ColumnName)) + { + m_log.Info("[DATASTORE]: Missing require column:" + col.ColumnName); + return false; + } + } + + return true; + } + + /*********************************************************************** + * + * Type conversion functions + * + **********************************************************************/ + + private DbType dbtypeFromType(Type type) + { + if (type == typeof (String)) + { + return DbType.String; + } + else if (type == typeof (Int32)) + { + return DbType.Int32; + } + else if (type == typeof (Double)) + { + return DbType.Double; + } + else if (type == typeof (Byte)) + { + return DbType.Byte; + } + else if (type == typeof (Double)) + { + return DbType.Double; + } + else if (type == typeof (Byte[])) + { + return DbType.Binary; + } + else + { + return DbType.String; + } + } + + // this is something we'll need to implement for each db + // slightly differently. + private string sqliteType(Type type) + { + if (type == typeof (String)) + { + return "varchar(255)"; + } + else if (type == typeof (Int32)) + { + return "integer"; + } + else if (type == typeof (Int64)) + { + return "integer"; + } + else if (type == typeof (Double)) + { + return "float"; + } + else if (type == typeof (Byte[])) + { + return "blob"; + } + else + { + return "string"; + } + } + } +} diff --git a/OpenSim/Framework/Data.SQLite/SQLiteUserData.cs b/OpenSim/Framework/Data.SQLite/SQLiteUserData.cs index 301e779e6b..111542f41b 100644 --- a/OpenSim/Framework/Data.SQLite/SQLiteUserData.cs +++ b/OpenSim/Framework/Data.SQLite/SQLiteUserData.cs @@ -1,879 +1,862 @@ -/* -* 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.Generic; -using System.Data; -using libsecondlife; -using Mono.Data.SqliteClient; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.Data.SQLite -{ - /// - /// A User storage interface for the SQLite database system - /// - public class SQLiteUserData : SQLiteBase, IUserData - { - /// - /// The database manager - /// - /// - /// Artificial constructor called upon plugin load - /// - private const string userSelect = "select * from users"; - private const string userFriendsSelect = "select a.ownerID as ownerID,a.friendID as friendID,a.friendPerms as friendPerms,b.friendPerms as ownerperms, b.ownerID as fownerID, b.friendID as ffriendID from userfriends as a, userfriends as b"; - - private DataSet ds; - private SqliteDataAdapter da; - private SqliteDataAdapter daf; - SqliteConnection g_conn; - - public void Initialise() - { - SqliteConnection conn = new SqliteConnection("URI=file:userprofiles.db,version=3"); - TestTables(conn); - - // This sucks, but It doesn't seem to work with the dataset Syncing :P - g_conn = conn; - - ds = new DataSet(); - da = new SqliteDataAdapter(new SqliteCommand(userSelect, conn)); - daf = new SqliteDataAdapter(new SqliteCommand(userFriendsSelect, conn)); - - lock (ds) - { - ds.Tables.Add(createUsersTable()); - ds.Tables.Add(createUserAgentsTable()); - ds.Tables.Add(createUserFriendsTable()); - - setupUserCommands(da, conn); - da.Fill(ds.Tables["users"]); - - setupUserFriendsCommands(daf, conn); - try - { - daf.Fill(ds.Tables["userfriends"]); - } - catch (SqliteSyntaxException) - { - MainLog.Instance.Verbose("SQLITE", "userfriends table not found, creating.... "); - InitDB(conn); - daf.Fill(ds.Tables["userfriends"]); - } - - } - - return; - } - - // see IUserData - public UserProfileData GetUserByUUID(LLUUID uuid) - { - lock (ds) - { - DataRow row = ds.Tables["users"].Rows.Find(Util.ToRawUuidString(uuid)); - if (row != null) - { - UserProfileData user = buildUserProfile(row); - row = ds.Tables["useragents"].Rows.Find(Util.ToRawUuidString(uuid)); - if (row != null) - { - user.currentAgent = buildUserAgent(row); - } - return user; - } - else - { - return null; - } - } - } - - /// - /// Loads a specified user profile from a account - /// - /// The users account - /// A user profile - public UserProfileData GetUserByAccount(string account) - { - lock (ds) - { - DataRow row = ds.Tables["users"].Rows.Find(account); - if (row != null) - { - UserProfileData user = buildUserProfile(row); - row = ds.Tables["useragents"].Rows.Find(user.UUID); - if (row != null) - { - user.currentAgent = buildUserAgent(row); - } - return user; - } - else - { - return null; - } - } - } - - // see IUserData - public UserProfileData GetUserByName(string fname, string lname) - { - string select = "surname = '" + lname + "' and username = '" + fname + "'"; - lock (ds) - { - DataRow[] rows = ds.Tables["users"].Select(select); - if (rows.Length > 0) - { - UserProfileData user = buildUserProfile(rows[0]); - DataRow row = ds.Tables["useragents"].Rows.Find(Util.ToRawUuidString(user.UUID)); - if (row != null) - { - user.currentAgent = buildUserAgent(row); - } - return user; - } - else - { - return null; - } - } - } - - #region User Friends List Data - - public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms) - { - //do stuff; - MainLog.Instance.Verbose("FRIEND", "Stub AddNewUserFriend called"); - DataTable friends = ds.Tables["userfriends"]; - DataTable ua = ds.Tables["userfriends"]; - lock (ds) - { - - - DataRow row = friends.NewRow(); - fillFriendRow(row, friendlistowner.UUID.ToString(),friend.UUID.ToString(),perms); - friends.Rows.Add(row); - - row = friends.NewRow(); - fillFriendRow(row, friend.UUID.ToString(), friendlistowner.UUID.ToString(), perms); - friends.Rows.Add(row); - - MainLog.Instance.Verbose("SQLITE", - "Adding Friend: " + ds.Tables["userfriends"].Rows.Count + " friends stored"); - // save changes off to disk - daf.Update(ds, "userfriends"); - } - } - - public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend) - { - DataTable ua = ds.Tables["userfriends"]; - string select = "`ownerID` ='" + friendlistowner.UUID.ToString() + "' and `friendID` ='" + friend.UUID.ToString() + "'"; - lock (ds) - { - DataRow[] rows = ds.Tables["userfriends"].Select(select); - - if ( rows != null) - { - if (rows.Length > 0) - { - for (int i = 0; i < rows.Length; i++) - { - DataRow row = rows[i]; - row.Delete(); - } - - } - } - } - select = "`ownerID` ='" + friend.UUID.ToString() + "' and `friendID` ='" + friendlistowner.UUID.ToString() + "'"; - lock (ds) - { - DataRow[] rows = ds.Tables["userfriends"].Select(select); - - if (rows != null) - { - if (rows.Length > 0) - { - for (int i = 0; i < rows.Length; i++) - { - DataRow row = rows[i]; - row.Delete(); - } - - } - } - } - SqliteCommand deletecommand = new SqliteCommand("delete from userfriends where `ownerID`='" + friendlistowner.UUID.ToString() + "' and `friendID` ='" + friend.UUID.ToString() + "'", g_conn); - g_conn.Open(); - deletecommand.ExecuteNonQuery(); - deletecommand = new SqliteCommand("delete from userfriends where `ownerID`='" + friend.UUID.ToString() + "' and `friendID` ='" + friendlistowner.UUID.ToString() + "'", g_conn); - deletecommand.ExecuteNonQuery(); - g_conn.Close(); - - MainLog.Instance.Verbose("FRIEND", "Stub RemoveUserFriend called"); - } - public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms) - { - DataTable ua = ds.Tables["userfriends"]; - string select = "a.ownerID ='" + friendlistowner.UUID.ToString() + "' and b.friendID ='" + friend.UUID.ToString() + "'"; - lock (ds) - { - DataRow[] rows = ds.Tables["userfriends"].Select(select); - - if ( rows != null) - { - if (rows.Length > 0) - { - for (int i = 0; i < rows.Length; i++) - { - FriendListItem user = new FriendListItem(); - DataRow row = rows[i]; - row["friendPerms"] = Convert.ToInt32(perms); - } - daf.Update(ds, "userfriends"); - } - } - } - MainLog.Instance.Verbose("FRIEND", "Stub UpdateUserFriendPerms called"); - } - - - public List GetUserFriendList(LLUUID friendlistowner) - { - List returnlist = new List(); - - string select = "ownerID = '" + friendlistowner.UUID.ToString() + "' and fownerID = friendID and ffriendID = ownerID"; - lock (ds) - { - DataRow[] rows = ds.Tables["userfriends"].Select(select); - - if (rows.Length > 0) - { - for (int i = 0; i < rows.Length; i++) - { - FriendListItem user = new FriendListItem(); - DataRow row = rows[i]; - user.FriendListOwner = new LLUUID((string)row[0]); - user.Friend = new LLUUID((string)row[1]); - user.FriendPerms = Convert.ToUInt32(row[2]); - user.FriendListOwnerPerms = Convert.ToUInt32(row[3]); - returnlist.Add(user); - } - } - } - return returnlist; - } - - - - - #endregion - - public void UpdateUserCurrentRegion(LLUUID avatarid, LLUUID regionuuid) - { - MainLog.Instance.Verbose("USER", "Stub UpdateUserCUrrentRegion called"); - } - - public void LogOffUser(LLUUID avatarid) - { - MainLog.Instance.Verbose("USER", "Stub LogOffUser called"); - } - - public List GeneratePickerResults(LLUUID queryID, string query) - { - List returnlist = new List(); - string[] querysplit; - querysplit = query.Split(' '); - if (querysplit.Length == 2) - { - string select = "username like '" + querysplit[0] + "%' and surname like '" + querysplit[1] + "%'"; - lock (ds) - { - DataRow[] rows = ds.Tables["users"].Select(select); - if (rows.Length > 0) - { - for (int i = 0; i < rows.Length; i++) - { - Framework.AvatarPickerAvatar user = new Framework.AvatarPickerAvatar(); - DataRow row = rows[i]; - user.AvatarID = new LLUUID((string) row["UUID"]); - user.firstName = (string) row["username"]; - user.lastName = (string) row["surname"]; - returnlist.Add(user); - } - } - } - } - else if (querysplit.Length == 1) - { - string select = "username like '" + querysplit[0] + "%' OR surname like '" + querysplit[0] + "%'"; - lock (ds) - { - DataRow[] rows = ds.Tables["users"].Select(select); - if (rows.Length > 0) - { - for (int i = 0; i < rows.Length; i++) - { - Framework.AvatarPickerAvatar user = new Framework.AvatarPickerAvatar(); - DataRow row = rows[i]; - user.AvatarID = new LLUUID((string) row[0]); - user.firstName = (string) row[1]; - user.lastName = (string) row[2]; - returnlist.Add(user); - } - } - } - } - return returnlist; - } - - /// - /// Returns a user by UUID direct - /// - /// The user's account ID - /// A matching user profile - public UserAgentData GetAgentByUUID(LLUUID uuid) - { - try - { - return GetUserByUUID(uuid).currentAgent; - } - catch (Exception) - { - return null; - } - } - - /// - /// Returns a session by account name - /// - /// The account name - /// The user's session agent - public UserAgentData GetAgentByName(string name) - { - return GetAgentByName(name.Split(' ')[0], name.Split(' ')[1]); - } - - /// - /// Returns a session by account name - /// - /// The first part of the user's account name - /// The second part of the user's account name - /// A user agent - public UserAgentData GetAgentByName(string fname, string lname) - { - try - { - return GetUserByName(fname, lname).currentAgent; - } - catch (Exception) - { - return null; - } - } - - /// - /// Creates a new user profile - /// - /// The profile to add to the database - public void AddNewUserProfile(UserProfileData user) - { - DataTable users = ds.Tables["users"]; - lock (ds) - { - DataRow row = users.Rows.Find(Util.ToRawUuidString(user.UUID)); - if (row == null) - { - row = users.NewRow(); - fillUserRow(row, user); - users.Rows.Add(row); - } - else - { - fillUserRow(row, user); - } - // This is why we're getting the 'logins never log-off'.. because It isn't clearing the - // useragents table once the useragent is null - // - // A database guy should look at this and figure out the best way to clear the useragents table. - if (user.currentAgent != null) - { - DataTable ua = ds.Tables["useragents"]; - row = ua.Rows.Find(Util.ToRawUuidString(user.UUID)); - if (row == null) - { - row = ua.NewRow(); - fillUserAgentRow(row, user.currentAgent); - ua.Rows.Add(row); - } - else - { - fillUserAgentRow(row, user.currentAgent); - } - } - else - { - // I just added this to help the standalone login situation. - //It still needs to be looked at by a Database guy - DataTable ua = ds.Tables["useragents"]; - row = ua.Rows.Find(Util.ToRawUuidString(user.UUID)); - - if (row == null) - { - // do nothing - } - else - { - row.Delete(); - ua.AcceptChanges(); - } - } - - MainLog.Instance.Verbose("SQLITE", - "Syncing user database: " + ds.Tables["users"].Rows.Count + " users stored"); - // save changes off to disk - da.Update(ds, "users"); - } - } - - /// - /// Creates a new user profile - /// - /// The profile to add to the database - /// True on success, false on error - public bool UpdateUserProfile(UserProfileData user) - { - try - { - AddNewUserProfile(user); - return true; - } - catch (Exception) - { - return false; - } - } - - /// - /// Creates a new user agent - /// - /// The agent to add to the database - public void AddNewUserAgent(UserAgentData agent) - { - // Do nothing. yet. - } - - /// - /// Transfers money between two user accounts - /// - /// Starting account - /// End account - /// The amount to move - /// Success? - public bool MoneyTransferRequest(LLUUID from, LLUUID to, uint amount) - { - return true; - } - - /// - /// Transfers inventory between two accounts - /// - /// Move to inventory server - /// Senders account - /// Receivers account - /// Inventory item - /// Success? - public bool InventoryTransferRequest(LLUUID from, LLUUID to, LLUUID item) - { - return true; - } - - /// - /// Returns the name of the storage provider - /// - /// Storage provider name - public string getName() - { - return "Sqlite Userdata"; - } - - /// - /// Returns the version of the storage provider - /// - /// Storage provider version - public string GetVersion() - { - return "0.1"; - } - - /*********************************************************************** - * - * DataTable creation - * - **********************************************************************/ - /*********************************************************************** - * - * Database Definition Functions - * - * This should be db agnostic as we define them in ADO.NET terms - * - **********************************************************************/ - - private DataTable createUsersTable() - { - DataTable users = new DataTable("users"); - - createCol(users, "UUID", typeof (String)); - createCol(users, "username", typeof (String)); - createCol(users, "surname", typeof (String)); - createCol(users, "passwordHash", typeof (String)); - createCol(users, "passwordSalt", typeof (String)); - - createCol(users, "homeRegionX", typeof (Int32)); - createCol(users, "homeRegionY", typeof (Int32)); - createCol(users, "homeLocationX", typeof (Double)); - createCol(users, "homeLocationY", typeof (Double)); - createCol(users, "homeLocationZ", typeof (Double)); - createCol(users, "homeLookAtX", typeof (Double)); - createCol(users, "homeLookAtY", typeof (Double)); - createCol(users, "homeLookAtZ", typeof (Double)); - createCol(users, "created", typeof (Int32)); - createCol(users, "lastLogin", typeof (Int32)); - createCol(users, "rootInventoryFolderID", typeof (String)); - createCol(users, "userInventoryURI", typeof (String)); - createCol(users, "userAssetURI", typeof (String)); - createCol(users, "profileCanDoMask", typeof (Int32)); - createCol(users, "profileWantDoMask", typeof (Int32)); - createCol(users, "profileAboutText", typeof (String)); - createCol(users, "profileFirstText", typeof (String)); - createCol(users, "profileImage", typeof (String)); - createCol(users, "profileFirstImage", typeof (String)); - createCol(users, "webLoginKey", typeof(String)); - // Add in contraints - users.PrimaryKey = new DataColumn[] {users.Columns["UUID"]}; - return users; - } - - private DataTable createUserAgentsTable() - { - DataTable ua = new DataTable("useragents"); - // this is the UUID of the user - createCol(ua, "UUID", typeof (String)); - createCol(ua, "agentIP", typeof (String)); - createCol(ua, "agentPort", typeof (Int32)); - createCol(ua, "agentOnline", typeof (Boolean)); - createCol(ua, "sessionID", typeof (String)); - createCol(ua, "secureSessionID", typeof (String)); - createCol(ua, "regionID", typeof (String)); - createCol(ua, "loginTime", typeof (Int32)); - createCol(ua, "logoutTime", typeof (Int32)); - createCol(ua, "currentRegion", typeof (String)); - createCol(ua, "currentHandle", typeof (String)); - // vectors - createCol(ua, "currentPosX", typeof (Double)); - createCol(ua, "currentPosY", typeof (Double)); - createCol(ua, "currentPosZ", typeof (Double)); - // constraints - ua.PrimaryKey = new DataColumn[] {ua.Columns["UUID"]}; - - return ua; - } - - private DataTable createUserFriendsTable() - { - DataTable ua = new DataTable("userfriends"); - // table contains user <----> user relationship with perms - createCol(ua, "ownerID", typeof(String)); - createCol(ua, "friendID", typeof(String)); - createCol(ua, "friendPerms", typeof(Int32)); - createCol(ua, "ownerPerms", typeof(Int32)); - createCol(ua, "datetimestamp", typeof(Int32)); - - return ua; - } - - /*********************************************************************** - * - * Convert between ADO.NET <=> OpenSim Objects - * - * These should be database independant - * - **********************************************************************/ - - private UserProfileData buildUserProfile(DataRow row) - { - // TODO: this doesn't work yet because something more - // interesting has to be done to actually get these values - // back out. Not enough time to figure it out yet. - UserProfileData user = new UserProfileData(); - user.UUID = new LLUUID((String) row["UUID"]); - user.username = (String) row["username"]; - user.surname = (String) row["surname"]; - user.passwordHash = (String) row["passwordHash"]; - user.passwordSalt = (String) row["passwordSalt"]; - - user.homeRegionX = Convert.ToUInt32(row["homeRegionX"]); - user.homeRegionY = Convert.ToUInt32(row["homeRegionY"]); - user.homeLocation = new LLVector3( - Convert.ToSingle(row["homeLocationX"]), - Convert.ToSingle(row["homeLocationY"]), - Convert.ToSingle(row["homeLocationZ"]) - ); - user.homeLookAt = new LLVector3( - Convert.ToSingle(row["homeLookAtX"]), - Convert.ToSingle(row["homeLookAtY"]), - Convert.ToSingle(row["homeLookAtZ"]) - ); - user.created = Convert.ToInt32(row["created"]); - user.lastLogin = Convert.ToInt32(row["lastLogin"]); - user.rootInventoryFolderID = new LLUUID((String) row["rootInventoryFolderID"]); - user.userInventoryURI = (String) row["userInventoryURI"]; - user.userAssetURI = (String) row["userAssetURI"]; - user.profileCanDoMask = Convert.ToUInt32(row["profileCanDoMask"]); - user.profileWantDoMask = Convert.ToUInt32(row["profileWantDoMask"]); - user.profileAboutText = (String) row["profileAboutText"]; - user.profileFirstText = (String) row["profileFirstText"]; - user.profileImage = new LLUUID((String) row["profileImage"]); - user.profileFirstImage = new LLUUID((String) row["profileFirstImage"]); - user.webLoginKey = new LLUUID((String) row["webLoginKey"]); - - return user; - } - - private void fillFriendRow(DataRow row, LLUUID ownerID, LLUUID friendID, uint perms) - { - row["ownerID"] = ownerID.UUID.ToString(); - row["friendID"] = friendID.UUID.ToString(); - row["friendPerms"] = perms; - foreach (DataColumn col in ds.Tables["userfriends"].Columns) - { - if (row[col] == null) - { - row[col] = ""; - } - } - } - - private void fillUserRow(DataRow row, UserProfileData user) - { - row["UUID"] = Util.ToRawUuidString(user.UUID); - row["username"] = user.username; - row["surname"] = user.surname; - row["passwordHash"] = user.passwordHash; - row["passwordSalt"] = user.passwordSalt; - - - row["homeRegionX"] = user.homeRegionX; - row["homeRegionY"] = user.homeRegionY; - row["homeLocationX"] = user.homeLocation.X; - row["homeLocationY"] = user.homeLocation.Y; - row["homeLocationZ"] = user.homeLocation.Z; - row["homeLookAtX"] = user.homeLookAt.X; - row["homeLookAtY"] = user.homeLookAt.Y; - row["homeLookAtZ"] = user.homeLookAt.Z; - - row["created"] = user.created; - row["lastLogin"] = user.lastLogin; - row["rootInventoryFolderID"] = user.rootInventoryFolderID; - row["userInventoryURI"] = user.userInventoryURI; - row["userAssetURI"] = user.userAssetURI; - row["profileCanDoMask"] = user.profileCanDoMask; - row["profileWantDoMask"] = user.profileWantDoMask; - row["profileAboutText"] = user.profileAboutText; - row["profileFirstText"] = user.profileFirstText; - row["profileImage"] = user.profileImage; - row["profileFirstImage"] = user.profileFirstImage; - row["webLoginKey"] = user.webLoginKey; - - // ADO.NET doesn't handle NULL very well - foreach (DataColumn col in ds.Tables["users"].Columns) - { - if (row[col] == null) - { - row[col] = ""; - } - } - } - - private UserAgentData buildUserAgent(DataRow row) - { - UserAgentData ua = new UserAgentData(); - - ua.UUID = new LLUUID((String) row["UUID"]); - ua.agentIP = (String) row["agentIP"]; - ua.agentPort = Convert.ToUInt32(row["agentPort"]); - ua.agentOnline = Convert.ToBoolean(row["agentOnline"]); - ua.sessionID = new LLUUID((String) row["sessionID"]); - ua.secureSessionID = new LLUUID((String) row["secureSessionID"]); - ua.regionID = new LLUUID((String) row["regionID"]); - ua.loginTime = Convert.ToInt32(row["loginTime"]); - ua.logoutTime = Convert.ToInt32(row["logoutTime"]); - ua.currentRegion = new LLUUID((String) row["currentRegion"]); - ua.currentHandle = Convert.ToUInt64(row["currentHandle"]); - ua.currentPos = new LLVector3( - Convert.ToSingle(row["currentPosX"]), - Convert.ToSingle(row["currentPosY"]), - Convert.ToSingle(row["currentPosZ"]) - ); - return ua; - } - - private void fillUserAgentRow(DataRow row, UserAgentData ua) - { - row["UUID"] = ua.UUID; - row["agentIP"] = ua.agentIP; - row["agentPort"] = ua.agentPort; - row["agentOnline"] = ua.agentOnline; - row["sessionID"] = ua.sessionID; - row["secureSessionID"] = ua.secureSessionID; - row["regionID"] = ua.regionID; - row["loginTime"] = ua.loginTime; - row["logoutTime"] = ua.logoutTime; - row["currentRegion"] = ua.currentRegion; - row["currentHandle"] = ua.currentHandle.ToString(); - // vectors - row["currentPosX"] = ua.currentPos.X; - row["currentPosY"] = ua.currentPos.Y; - row["currentPosZ"] = ua.currentPos.Z; - } - - /*********************************************************************** - * - * Database Binding functions - * - * These will be db specific due to typing, and minor differences - * in databases. - * - **********************************************************************/ - - private void setupUserCommands(SqliteDataAdapter da, SqliteConnection conn) - { - da.InsertCommand = createInsertCommand("users", ds.Tables["users"]); - da.InsertCommand.Connection = conn; - - da.UpdateCommand = createUpdateCommand("users", "UUID=:UUID", ds.Tables["users"]); - da.UpdateCommand.Connection = conn; - - SqliteCommand delete = new SqliteCommand("delete from users where UUID = :UUID"); - delete.Parameters.Add(createSqliteParameter("UUID", typeof (String))); - delete.Connection = conn; - da.DeleteCommand = delete; - } - - private void setupUserFriendsCommands(SqliteDataAdapter daf, SqliteConnection conn) - { - daf.InsertCommand = createInsertCommand("userfriends", ds.Tables["userfriends"]); - daf.InsertCommand.Connection = conn; - - daf.UpdateCommand = createUpdateCommand("userfriends", "ownerID=:ownerID and friendID=:friendID", ds.Tables["userfriends"]); - daf.UpdateCommand.Connection = conn; - - SqliteCommand delete = new SqliteCommand("delete from userfriends where ownerID=:ownerID and friendID=:friendID"); - delete.Parameters.Add(createSqliteParameter("ownerID", typeof(String))); - delete.Parameters.Add(createSqliteParameter("friendID", typeof(String))); - delete.Connection = conn; - daf.DeleteCommand = delete; - - } - - private void InitDB(SqliteConnection conn) - { - string createUsers = defineTable(createUsersTable()); - string createFriends = defineTable(createUserFriendsTable()); - - SqliteCommand pcmd = new SqliteCommand(createUsers, conn); - SqliteCommand fcmd = new SqliteCommand(createFriends, conn); - - conn.Open(); - - try - { - - pcmd.ExecuteNonQuery(); - } - catch (System.Exception) - { - MainLog.Instance.Verbose("USERS", "users table already exists"); - } - - try - { - fcmd.ExecuteNonQuery(); - } - catch (System.Exception) - { - MainLog.Instance.Verbose("USERS", "userfriends table already exists"); - } - - conn.Close(); - } - - private bool TestTables(SqliteConnection conn) - { - SqliteCommand cmd = new SqliteCommand(userSelect, conn); - SqliteCommand fcmd = new SqliteCommand(userFriendsSelect, conn); - SqliteDataAdapter pDa = new SqliteDataAdapter(cmd); - SqliteDataAdapter fDa = new SqliteDataAdapter(cmd); - - DataSet tmpDS = new DataSet(); - DataSet tmpDS2 = new DataSet(); - - try - { - pDa.Fill(tmpDS, "users"); - fDa.Fill(tmpDS2, "userfriends"); - } - catch (SqliteSyntaxException) - { - MainLog.Instance.Verbose("DATASTORE", "SQLite Database doesn't exist... creating"); - InitDB(conn); - } - conn.Open(); - try - { - cmd = new SqliteCommand("select webLoginKey from users limit 1;", conn); - cmd.ExecuteNonQuery(); - } - catch (SqliteSyntaxException) - { - cmd = new SqliteCommand("alter table users add column webLoginKey text default '00000000-0000-0000-0000-000000000000';", conn); - cmd.ExecuteNonQuery(); - pDa.Fill(tmpDS, "users"); - } - finally - { - conn.Close(); - } - - return true; - } - } -} \ No newline at end of file +/* +* 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.Generic; +using System.Data; +using libsecondlife; +using Mono.Data.SqliteClient; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Data.SQLite +{ + /// + /// A User storage interface for the SQLite database system + /// + public class SQLiteUserData : SQLiteBase, IUserData + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// The database manager + /// + /// + /// Artificial constructor called upon plugin load + /// + private const string SelectUserByUUID = "select * from users where UUID=:UUID"; + private const string SelectUserByName = "select * from users where username=:username and surname=:surname"; + private const string SelectFriendsByUUID = "select a.friendID, a.friendPerms, b.friendPerms from userfriends as a, userfriends as b where a.ownerID=:ownerID and b.ownerID=a.friendID and b.friendID=a.ownerID"; + + private const string userSelect = "select * from users"; + private const string userFriendsSelect = "select a.ownerID as ownerID,a.friendID as friendID,a.friendPerms as friendPerms,b.friendPerms as ownerperms, b.ownerID as fownerID, b.friendID as ffriendID from userfriends as a, userfriends as b"; + + private const string AvatarPickerAndSQL = "select * from users where username like :username and surname like :surname"; + private const string AvatarPickerOrSQL = "select * from users where username like :username or surname like :surname"; + + private DataSet ds; + private SqliteDataAdapter da; + private SqliteDataAdapter daf; + SqliteConnection g_conn; + + public void Initialise() + { + SqliteConnection conn = new SqliteConnection("URI=file:userprofiles.db,version=3"); + TestTables(conn); + + // This sucks, but It doesn't seem to work with the dataset Syncing :P + g_conn = conn; + g_conn.Open(); + + ds = new DataSet(); + da = new SqliteDataAdapter(new SqliteCommand(userSelect, conn)); + daf = new SqliteDataAdapter(new SqliteCommand(userFriendsSelect, conn)); + + lock (ds) + { + ds.Tables.Add(createUsersTable()); + ds.Tables.Add(createUserAgentsTable()); + ds.Tables.Add(createUserFriendsTable()); + + setupUserCommands(da, conn); + da.Fill(ds.Tables["users"]); + + setupUserFriendsCommands(daf, conn); + try + { + daf.Fill(ds.Tables["userfriends"]); + } + catch (SqliteSyntaxException) + { + m_log.Info("[SQLITE]: userfriends table not found, creating.... "); + InitDB(conn); + daf.Fill(ds.Tables["userfriends"]); + } + + } + + return; + } + + // see IUserData + public UserProfileData GetUserByUUID(LLUUID uuid) + { + lock (ds) + { + DataRow row = ds.Tables["users"].Rows.Find(Util.ToRawUuidString(uuid)); + if (row != null) + { + UserProfileData user = buildUserProfile(row); + row = ds.Tables["useragents"].Rows.Find(Util.ToRawUuidString(uuid)); + if (row != null) + { + user.currentAgent = buildUserAgent(row); + } + return user; + } + else + { + return null; + } + } + } + + /// + /// Loads a specified user profile from a account + /// + /// The users account + /// A user profile + public UserProfileData GetUserByAccount(string account) + { + lock (ds) + { + DataRow row = ds.Tables["users"].Rows.Find(account); + if (row != null) + { + UserProfileData user = buildUserProfile(row); + row = ds.Tables["useragents"].Rows.Find(user.UUID); + if (row != null) + { + user.currentAgent = buildUserAgent(row); + } + return user; + } + else + { + return null; + } + } + } + + // see IUserData + public UserProfileData GetUserByName(string fname, string lname) + { + string select = "surname = '" + lname + "' and username = '" + fname + "'"; + lock (ds) + { + DataRow[] rows = ds.Tables["users"].Select(select); + if (rows.Length > 0) + { + UserProfileData user = buildUserProfile(rows[0]); + DataRow row = ds.Tables["useragents"].Rows.Find(Util.ToRawUuidString(user.UUID)); + if (row != null) + { + user.currentAgent = buildUserAgent(row); + } + return user; + } + else + { + return null; + } + } + } + + #region User Friends List Data + + public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms) + { + string InsertFriends = "insert into userfriends(ownerID, friendID, friendPerms) values(:ownerID, :friendID, :perms)"; + + using (SqliteCommand cmd = new SqliteCommand(InsertFriends, g_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":ownerID", friendlistowner.UUID.ToString())); + cmd.Parameters.Add(new SqliteParameter(":friendID", friend.UUID.ToString())); + cmd.Parameters.Add(new SqliteParameter(":perms", perms)); + cmd.ExecuteNonQuery(); + } + using (SqliteCommand cmd = new SqliteCommand(InsertFriends, g_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":ownerID", friend.UUID.ToString())); + cmd.Parameters.Add(new SqliteParameter(":friendID", friendlistowner.UUID.ToString())); + cmd.Parameters.Add(new SqliteParameter(":perms", perms)); + cmd.ExecuteNonQuery(); + } + } + + public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend) + { + string DeletePerms = "delete from friendlist where (ownerID=:ownerID and friendID=:friendID) or (ownerID=:friendID and friendID=:ownerID)"; + using (SqliteCommand cmd = new SqliteCommand(DeletePerms, g_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":ownerID", friendlistowner.UUID.ToString())); + cmd.Parameters.Add(new SqliteParameter(":friendID", friend.UUID.ToString())); + cmd.ExecuteNonQuery(); + } + } + + public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms) + { + string UpdatePerms = "update friendlist set perms=:perms where ownerID=:ownerID and friendID=:friendID"; + using (SqliteCommand cmd = new SqliteCommand(UpdatePerms, g_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":perms", perms)); + cmd.Parameters.Add(new SqliteParameter(":ownerID", friendlistowner.UUID.ToString())); + cmd.Parameters.Add(new SqliteParameter(":friendID", friend.UUID.ToString())); + cmd.ExecuteNonQuery(); + } + } + + public List GetUserFriendList(LLUUID friendlistowner) + { + List returnlist = new List(); + + using (SqliteCommand cmd = new SqliteCommand(SelectFriendsByUUID, g_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":ownerID", friendlistowner.UUID.ToString())); + + try + { + using (IDataReader reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + FriendListItem user = new FriendListItem(); + user.FriendListOwner = friendlistowner; + user.Friend = new LLUUID((string)reader[0]); + user.FriendPerms = Convert.ToUInt32(reader[1]); + user.FriendListOwnerPerms = Convert.ToUInt32(reader[2]); + returnlist.Add(user); + } + reader.Close(); + } + } + catch (Exception ex) + { + m_log.Error("[USER]: Exception getting friends list for user: " + ex.ToString()); + } + } + + return returnlist; + } + + + + + #endregion + + public void UpdateUserCurrentRegion(LLUUID avatarid, LLUUID regionuuid) + { + m_log.Info("[USER]: Stub UpdateUserCUrrentRegion called"); + } + + + public List GeneratePickerResults(LLUUID queryID, string query) + { + List returnlist = new List(); + string[] querysplit; + querysplit = query.Split(' '); + if (querysplit.Length == 2) + { + using (SqliteCommand cmd = new SqliteCommand(AvatarPickerAndSQL, g_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":username", querysplit[0] + "%")); + cmd.Parameters.Add(new SqliteParameter(":surname", querysplit[1] + "%")); + + using (IDataReader reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + Framework.AvatarPickerAvatar user = new Framework.AvatarPickerAvatar(); + user.AvatarID = new LLUUID((string) reader["UUID"]); + user.firstName = (string) reader["username"]; + user.lastName = (string) reader["surname"]; + returnlist.Add(user); + } + reader.Close(); + } + } + } + else if (querysplit.Length == 1) + { + using (SqliteCommand cmd = new SqliteCommand(AvatarPickerOrSQL, g_conn)) + { + cmd.Parameters.Add(new SqliteParameter(":username", querysplit[0] + "%")); + cmd.Parameters.Add(new SqliteParameter(":surname", querysplit[0] + "%")); + + using (IDataReader reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + Framework.AvatarPickerAvatar user = new Framework.AvatarPickerAvatar(); + user.AvatarID = new LLUUID((string) reader["UUID"]); + user.firstName = (string) reader["username"]; + user.lastName = (string) reader["surname"]; + returnlist.Add(user); + } + reader.Close(); + } + } + } + return returnlist; + } + + /// + /// Returns a user by UUID direct + /// + /// The user's account ID + /// A matching user profile + public UserAgentData GetAgentByUUID(LLUUID uuid) + { + try + { + return GetUserByUUID(uuid).currentAgent; + } + catch (Exception) + { + return null; + } + } + + /// + /// Returns a session by account name + /// + /// The account name + /// The user's session agent + public UserAgentData GetAgentByName(string name) + { + return GetAgentByName(name.Split(' ')[0], name.Split(' ')[1]); + } + + /// + /// Returns a session by account name + /// + /// The first part of the user's account name + /// The second part of the user's account name + /// A user agent + public UserAgentData GetAgentByName(string fname, string lname) + { + try + { + return GetUserByName(fname, lname).currentAgent; + } + catch (Exception) + { + return null; + } + } + + + public void StoreWebLoginKey(LLUUID AgentID, LLUUID WebLoginKey) + { + DataTable users = ds.Tables["users"]; + lock (ds) + { + DataRow row = users.Rows.Find(Util.ToRawUuidString(AgentID)); + if (row == null) + { + m_log.Warn("[WEBLOGIN]: Unable to store new web login key for non-existant user"); + } + else + { + UserProfileData user = GetUserByUUID(AgentID); + user.webLoginKey = WebLoginKey; + fillUserRow(row, user); + da.Update(ds, "users"); + + } + } + + } + + /// + /// Creates a new user profile + /// + /// The profile to add to the database + public void AddNewUserProfile(UserProfileData user) + { + DataTable users = ds.Tables["users"]; + lock (ds) + { + DataRow row = users.Rows.Find(Util.ToRawUuidString(user.UUID)); + if (row == null) + { + row = users.NewRow(); + fillUserRow(row, user); + users.Rows.Add(row); + } + else + { + fillUserRow(row, user); + + } + // This is why we're getting the 'logins never log-off'.. because It isn't clearing the + // useragents table once the useragent is null + // + // A database guy should look at this and figure out the best way to clear the useragents table. + if (user.currentAgent != null) + { + DataTable ua = ds.Tables["useragents"]; + row = ua.Rows.Find(Util.ToRawUuidString(user.UUID)); + if (row == null) + { + row = ua.NewRow(); + fillUserAgentRow(row, user.currentAgent); + ua.Rows.Add(row); + } + else + { + fillUserAgentRow(row, user.currentAgent); + } + } + else + { + // I just added this to help the standalone login situation. + //It still needs to be looked at by a Database guy + DataTable ua = ds.Tables["useragents"]; + row = ua.Rows.Find(Util.ToRawUuidString(user.UUID)); + + if (row == null) + { + // do nothing + } + else + { + row.Delete(); + ua.AcceptChanges(); + } + } + + m_log.Info("[SQLITE]: " + + "Syncing user database: " + ds.Tables["users"].Rows.Count + " users stored"); + // save changes off to disk + da.Update(ds, "users"); + } + } + + /// + /// Creates a new user profile + /// + /// The profile to add to the database + /// True on success, false on error + public bool UpdateUserProfile(UserProfileData user) + { + try + { + AddNewUserProfile(user); + return true; + } + catch (Exception) + { + return false; + } + } + + /// + /// Creates a new user agent + /// + /// The agent to add to the database + public void AddNewUserAgent(UserAgentData agent) + { + // Do nothing. yet. + } + + /// + /// Transfers money between two user accounts + /// + /// Starting account + /// End account + /// The amount to move + /// Success? + public bool MoneyTransferRequest(LLUUID from, LLUUID to, uint amount) + { + return true; + } + + /// + /// Transfers inventory between two accounts + /// + /// Move to inventory server + /// Senders account + /// Receivers account + /// Inventory item + /// Success? + public bool InventoryTransferRequest(LLUUID from, LLUUID to, LLUUID item) + { + return true; + } + + /// + /// Returns the name of the storage provider + /// + /// Storage provider name + public string getName() + { + return "Sqlite Userdata"; + } + + /// + /// Returns the version of the storage provider + /// + /// Storage provider version + public string GetVersion() + { + return "0.1"; + } + + /*********************************************************************** + * + * DataTable creation + * + **********************************************************************/ + /*********************************************************************** + * + * Database Definition Functions + * + * This should be db agnostic as we define them in ADO.NET terms + * + **********************************************************************/ + + private DataTable createUsersTable() + { + DataTable users = new DataTable("users"); + + createCol(users, "UUID", typeof (String)); + createCol(users, "username", typeof (String)); + createCol(users, "surname", typeof (String)); + createCol(users, "passwordHash", typeof (String)); + createCol(users, "passwordSalt", typeof (String)); + + createCol(users, "homeRegionX", typeof (Int32)); + createCol(users, "homeRegionY", typeof (Int32)); + createCol(users, "homeLocationX", typeof (Double)); + createCol(users, "homeLocationY", typeof (Double)); + createCol(users, "homeLocationZ", typeof (Double)); + createCol(users, "homeLookAtX", typeof (Double)); + createCol(users, "homeLookAtY", typeof (Double)); + createCol(users, "homeLookAtZ", typeof (Double)); + createCol(users, "created", typeof (Int32)); + createCol(users, "lastLogin", typeof (Int32)); + createCol(users, "rootInventoryFolderID", typeof (String)); + createCol(users, "userInventoryURI", typeof (String)); + createCol(users, "userAssetURI", typeof (String)); + createCol(users, "profileCanDoMask", typeof (Int32)); + createCol(users, "profileWantDoMask", typeof (Int32)); + createCol(users, "profileAboutText", typeof (String)); + createCol(users, "profileFirstText", typeof (String)); + createCol(users, "profileImage", typeof (String)); + createCol(users, "profileFirstImage", typeof (String)); + createCol(users, "webLoginKey", typeof(String)); + // Add in contraints + users.PrimaryKey = new DataColumn[] {users.Columns["UUID"]}; + return users; + } + + private DataTable createUserAgentsTable() + { + DataTable ua = new DataTable("useragents"); + // this is the UUID of the user + createCol(ua, "UUID", typeof (String)); + createCol(ua, "agentIP", typeof (String)); + createCol(ua, "agentPort", typeof (Int32)); + createCol(ua, "agentOnline", typeof (Boolean)); + createCol(ua, "sessionID", typeof (String)); + createCol(ua, "secureSessionID", typeof (String)); + createCol(ua, "regionID", typeof (String)); + createCol(ua, "loginTime", typeof (Int32)); + createCol(ua, "logoutTime", typeof (Int32)); + createCol(ua, "currentRegion", typeof (String)); + createCol(ua, "currentHandle", typeof (String)); + // vectors + createCol(ua, "currentPosX", typeof (Double)); + createCol(ua, "currentPosY", typeof (Double)); + createCol(ua, "currentPosZ", typeof (Double)); + // constraints + ua.PrimaryKey = new DataColumn[] {ua.Columns["UUID"]}; + + return ua; + } + + private DataTable createUserFriendsTable() + { + DataTable ua = new DataTable("userfriends"); + // table contains user <----> user relationship with perms + createCol(ua, "ownerID", typeof(String)); + createCol(ua, "friendID", typeof(String)); + createCol(ua, "friendPerms", typeof(Int32)); + createCol(ua, "ownerPerms", typeof(Int32)); + createCol(ua, "datetimestamp", typeof(Int32)); + + return ua; + } + + /*********************************************************************** + * + * Convert between ADO.NET <=> OpenSim Objects + * + * These should be database independant + * + **********************************************************************/ + + private UserProfileData buildUserProfile(DataRow row) + { + // TODO: this doesn't work yet because something more + // interesting has to be done to actually get these values + // back out. Not enough time to figure it out yet. + UserProfileData user = new UserProfileData(); + user.UUID = new LLUUID((String) row["UUID"]); + user.username = (String) row["username"]; + user.surname = (String) row["surname"]; + user.passwordHash = (String) row["passwordHash"]; + user.passwordSalt = (String) row["passwordSalt"]; + + user.homeRegionX = Convert.ToUInt32(row["homeRegionX"]); + user.homeRegionY = Convert.ToUInt32(row["homeRegionY"]); + user.homeLocation = new LLVector3( + Convert.ToSingle(row["homeLocationX"]), + Convert.ToSingle(row["homeLocationY"]), + Convert.ToSingle(row["homeLocationZ"]) + ); + user.homeLookAt = new LLVector3( + Convert.ToSingle(row["homeLookAtX"]), + Convert.ToSingle(row["homeLookAtY"]), + Convert.ToSingle(row["homeLookAtZ"]) + ); + user.created = Convert.ToInt32(row["created"]); + user.lastLogin = Convert.ToInt32(row["lastLogin"]); + user.rootInventoryFolderID = new LLUUID((String) row["rootInventoryFolderID"]); + user.userInventoryURI = (String) row["userInventoryURI"]; + user.userAssetURI = (String) row["userAssetURI"]; + user.profileCanDoMask = Convert.ToUInt32(row["profileCanDoMask"]); + user.profileWantDoMask = Convert.ToUInt32(row["profileWantDoMask"]); + user.profileAboutText = (String) row["profileAboutText"]; + user.profileFirstText = (String) row["profileFirstText"]; + user.profileImage = new LLUUID((String) row["profileImage"]); + user.profileFirstImage = new LLUUID((String) row["profileFirstImage"]); + user.webLoginKey = new LLUUID((String) row["webLoginKey"]); + + return user; + } + + private void fillFriendRow(DataRow row, LLUUID ownerID, LLUUID friendID, uint perms) + { + row["ownerID"] = ownerID.UUID.ToString(); + row["friendID"] = friendID.UUID.ToString(); + row["friendPerms"] = perms; + foreach (DataColumn col in ds.Tables["userfriends"].Columns) + { + if (row[col] == null) + { + row[col] = String.Empty; + } + } + } + + private void fillUserRow(DataRow row, UserProfileData user) + { + row["UUID"] = Util.ToRawUuidString(user.UUID); + row["username"] = user.username; + row["surname"] = user.surname; + row["passwordHash"] = user.passwordHash; + row["passwordSalt"] = user.passwordSalt; + + + row["homeRegionX"] = user.homeRegionX; + row["homeRegionY"] = user.homeRegionY; + row["homeLocationX"] = user.homeLocation.X; + row["homeLocationY"] = user.homeLocation.Y; + row["homeLocationZ"] = user.homeLocation.Z; + row["homeLookAtX"] = user.homeLookAt.X; + row["homeLookAtY"] = user.homeLookAt.Y; + row["homeLookAtZ"] = user.homeLookAt.Z; + + row["created"] = user.created; + row["lastLogin"] = user.lastLogin; + row["rootInventoryFolderID"] = user.rootInventoryFolderID; + row["userInventoryURI"] = user.userInventoryURI; + row["userAssetURI"] = user.userAssetURI; + row["profileCanDoMask"] = user.profileCanDoMask; + row["profileWantDoMask"] = user.profileWantDoMask; + row["profileAboutText"] = user.profileAboutText; + row["profileFirstText"] = user.profileFirstText; + row["profileImage"] = user.profileImage; + row["profileFirstImage"] = user.profileFirstImage; + row["webLoginKey"] = user.webLoginKey; + + // ADO.NET doesn't handle NULL very well + foreach (DataColumn col in ds.Tables["users"].Columns) + { + if (row[col] == null) + { + row[col] = String.Empty; + } + } + } + + private UserAgentData buildUserAgent(DataRow row) + { + UserAgentData ua = new UserAgentData(); + + ua.UUID = new LLUUID((String) row["UUID"]); + ua.agentIP = (String) row["agentIP"]; + ua.agentPort = Convert.ToUInt32(row["agentPort"]); + ua.agentOnline = Convert.ToBoolean(row["agentOnline"]); + ua.sessionID = new LLUUID((String) row["sessionID"]); + ua.secureSessionID = new LLUUID((String) row["secureSessionID"]); + ua.regionID = new LLUUID((String) row["regionID"]); + ua.loginTime = Convert.ToInt32(row["loginTime"]); + ua.logoutTime = Convert.ToInt32(row["logoutTime"]); + ua.currentRegion = new LLUUID((String) row["currentRegion"]); + ua.currentHandle = Convert.ToUInt64(row["currentHandle"]); + ua.currentPos = new LLVector3( + Convert.ToSingle(row["currentPosX"]), + Convert.ToSingle(row["currentPosY"]), + Convert.ToSingle(row["currentPosZ"]) + ); + return ua; + } + + private void fillUserAgentRow(DataRow row, UserAgentData ua) + { + row["UUID"] = ua.UUID; + row["agentIP"] = ua.agentIP; + row["agentPort"] = ua.agentPort; + row["agentOnline"] = ua.agentOnline; + row["sessionID"] = ua.sessionID; + row["secureSessionID"] = ua.secureSessionID; + row["regionID"] = ua.regionID; + row["loginTime"] = ua.loginTime; + row["logoutTime"] = ua.logoutTime; + row["currentRegion"] = ua.currentRegion; + row["currentHandle"] = ua.currentHandle.ToString(); + // vectors + row["currentPosX"] = ua.currentPos.X; + row["currentPosY"] = ua.currentPos.Y; + row["currentPosZ"] = ua.currentPos.Z; + } + + /*********************************************************************** + * + * Database Binding functions + * + * These will be db specific due to typing, and minor differences + * in databases. + * + **********************************************************************/ + + private void setupUserCommands(SqliteDataAdapter da, SqliteConnection conn) + { + da.InsertCommand = createInsertCommand("users", ds.Tables["users"]); + da.InsertCommand.Connection = conn; + + da.UpdateCommand = createUpdateCommand("users", "UUID=:UUID", ds.Tables["users"]); + da.UpdateCommand.Connection = conn; + + SqliteCommand delete = new SqliteCommand("delete from users where UUID = :UUID"); + delete.Parameters.Add(createSqliteParameter("UUID", typeof (String))); + delete.Connection = conn; + da.DeleteCommand = delete; + } + + private void setupUserFriendsCommands(SqliteDataAdapter daf, SqliteConnection conn) + { + daf.InsertCommand = createInsertCommand("userfriends", ds.Tables["userfriends"]); + daf.InsertCommand.Connection = conn; + + daf.UpdateCommand = createUpdateCommand("userfriends", "ownerID=:ownerID and friendID=:friendID", ds.Tables["userfriends"]); + daf.UpdateCommand.Connection = conn; + + SqliteCommand delete = new SqliteCommand("delete from userfriends where ownerID=:ownerID and friendID=:friendID"); + delete.Parameters.Add(createSqliteParameter("ownerID", typeof(String))); + delete.Parameters.Add(createSqliteParameter("friendID", typeof(String))); + delete.Connection = conn; + daf.DeleteCommand = delete; + + } + + private void InitDB(SqliteConnection conn) + { + string createUsers = defineTable(createUsersTable()); + string createFriends = defineTable(createUserFriendsTable()); + + SqliteCommand pcmd = new SqliteCommand(createUsers, conn); + SqliteCommand fcmd = new SqliteCommand(createFriends, conn); + + conn.Open(); + + try + { + + pcmd.ExecuteNonQuery(); + } + catch (System.Exception) + { + m_log.Info("[USERS]: users table already exists"); + } + + try + { + fcmd.ExecuteNonQuery(); + } + catch (System.Exception) + { + m_log.Info("[USERS]: userfriends table already exists"); + } + + conn.Close(); + } + + private bool TestTables(SqliteConnection conn) + { + SqliteCommand cmd = new SqliteCommand(userSelect, conn); + SqliteCommand fcmd = new SqliteCommand(userFriendsSelect, conn); + SqliteDataAdapter pDa = new SqliteDataAdapter(cmd); + SqliteDataAdapter fDa = new SqliteDataAdapter(cmd); + + DataSet tmpDS = new DataSet(); + DataSet tmpDS2 = new DataSet(); + + try + { + pDa.Fill(tmpDS, "users"); + fDa.Fill(tmpDS2, "userfriends"); + } + catch (SqliteSyntaxException) + { + m_log.Info("[DATASTORE]: SQLite Database doesn't exist... creating"); + InitDB(conn); + } + conn.Open(); + try + { + cmd = new SqliteCommand("select webLoginKey from users limit 1;", conn); + cmd.ExecuteNonQuery(); + } + catch (SqliteSyntaxException) + { + cmd = new SqliteCommand("alter table users add column webLoginKey text default '00000000-0000-0000-0000-000000000000';", conn); + cmd.ExecuteNonQuery(); + pDa.Fill(tmpDS, "users"); + } + finally + { + conn.Close(); + } + + return true; + } + } +} diff --git a/OpenSim/Framework/Data/GridData.cs b/OpenSim/Framework/Data/GridData.cs index eededc5ef0..a7d758152b 100644 --- a/OpenSim/Framework/Data/GridData.cs +++ b/OpenSim/Framework/Data/GridData.cs @@ -1,125 +1,122 @@ -/* -* 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.Collections.Generic; -using libsecondlife; - -namespace OpenSim.Framework.Data -{ - public class AvatarPickerAvatar - { - public LLUUID AvatarID; - public string firstName; - public string lastName; - - public AvatarPickerAvatar() - { - } - } - - public enum DataResponse - { - RESPONSE_OK, - RESPONSE_AUTHREQUIRED, - RESPONSE_INVALIDCREDENTIALS, - RESPONSE_ERROR - } - - /// - /// A standard grid interface - /// - public interface IGridData - { - /// - /// Returns a sim profile from a regionHandle - /// - /// A 64bit Region Handle - /// A simprofile - RegionProfileData GetProfileByHandle(ulong regionHandle); - - /// - /// Returns a sim profile from a UUID - /// - /// A 128bit UUID - /// A sim profile - RegionProfileData GetProfileByLLUUID(LLUUID UUID); - - /// - /// Returns all profiles within the specified range - /// - /// Minimum sim coordinate (X) - /// Minimum sim coordinate (Y) - /// Maximum sim coordinate (X) - /// Maximum sim coordinate (Y) - /// An array containing all the sim profiles in the specified range - RegionProfileData[] GetProfilesInRange(uint Xmin, uint Ymin, uint Xmax, uint Ymax); - - - List GeneratePickerResults(LLUUID queryID, string query); - - /// - /// Authenticates a sim by use of its recv key. - /// WARNING: Insecure - /// - /// The UUID sent by the sim - /// The regionhandle sent by the sim - /// The receiving key sent by the sim - /// Whether the sim has been authenticated - bool AuthenticateSim(LLUUID UUID, ulong regionHandle, string simrecvkey); - - /// - /// Initialises the interface - /// - void Initialise(); - - /// - /// Closes the interface - /// - void Close(); - - /// - /// The plugin being loaded - /// - /// A string containing the plugin name - string getName(); - - /// - /// The plugins version - /// - /// A string containing the plugin version - string getVersion(); - - /// - /// Adds a new profile to the database - /// - /// The profile to add - /// RESPONSE_OK if successful, error if not. - DataResponse AddProfile(RegionProfileData profile); - - ReservationData GetReservationAtPoint(uint x, uint y); - } -} \ No newline at end of file +/* +* 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.Collections.Generic; +using libsecondlife; + +namespace OpenSim.Framework.Data +{ + public class AvatarPickerAvatar + { + public LLUUID AvatarID; + public string firstName; + public string lastName; + + public AvatarPickerAvatar() + { + } + } + + public enum DataResponse + { + RESPONSE_OK, + RESPONSE_AUTHREQUIRED, + RESPONSE_INVALIDCREDENTIALS, + RESPONSE_ERROR + } + + /// + /// A standard grid interface + /// + public interface IGridData + { + /// + /// Returns a sim profile from a regionHandle + /// + /// A 64bit Region Handle + /// A simprofile + RegionProfileData GetProfileByHandle(ulong regionHandle); + + /// + /// Returns a sim profile from a UUID + /// + /// A 128bit UUID + /// A sim profile + RegionProfileData GetProfileByLLUUID(LLUUID UUID); + + /// + /// Returns all profiles within the specified range + /// + /// Minimum sim coordinate (X) + /// Minimum sim coordinate (Y) + /// Maximum sim coordinate (X) + /// Maximum sim coordinate (Y) + /// An array containing all the sim profiles in the specified range + RegionProfileData[] GetProfilesInRange(uint Xmin, uint Ymin, uint Xmax, uint Ymax); + + /// + /// Authenticates a sim by use of its recv key. + /// WARNING: Insecure + /// + /// The UUID sent by the sim + /// The regionhandle sent by the sim + /// The receiving key sent by the sim + /// Whether the sim has been authenticated + bool AuthenticateSim(LLUUID UUID, ulong regionHandle, string simrecvkey); + + /// + /// Initialises the interface + /// + void Initialise(); + + /// + /// Closes the interface + /// + void Close(); + + /// + /// The plugin being loaded + /// + /// A string containing the plugin name + string getName(); + + /// + /// The plugins version + /// + /// A string containing the plugin version + string getVersion(); + + /// + /// Adds a new profile to the database + /// + /// The profile to add + /// RESPONSE_OK if successful, error if not. + DataResponse AddProfile(RegionProfileData profile); + + ReservationData GetReservationAtPoint(uint x, uint y); + } +} diff --git a/OpenSim/Framework/Data/OpenSimDataReader.cs b/OpenSim/Framework/Data/OpenSimDataReader.cs new file mode 100644 index 0000000000..716a74ecb9 --- /dev/null +++ b/OpenSim/Framework/Data/OpenSimDataReader.cs @@ -0,0 +1,68 @@ +/* +* 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.Generic; +using System.Data; +using System.Text; +using libsecondlife; + +using TribalMedia.Framework.Data; + +namespace OpenSim.Framework.Data +{ + public class OpenSimDataReader : BaseDataReader + { + public OpenSimDataReader(IDataReader source) : base(source) + { + } + + public LLVector3 GetVector(string s) + { + float x = GetFloat(s + "X"); + float y = GetFloat(s + "Y"); + float z = GetFloat(s + "Z"); + + LLVector3 vector = new LLVector3(x, y, z); + + return vector; + } + + public LLQuaternion GetQuaternion(string s) + { + float x = GetFloat(s + "X"); + float y = GetFloat(s + "Y"); + float z = GetFloat(s + "Z"); + float w = GetFloat(s + "W"); + + LLQuaternion quaternion = new LLQuaternion(x, y, z, w); + + return quaternion; + } + } +} diff --git a/OpenSim/Framework/Data/OpenSimDatabaseConnector.cs b/OpenSim/Framework/Data/OpenSimDatabaseConnector.cs new file mode 100644 index 0000000000..5f8a261900 --- /dev/null +++ b/OpenSim/Framework/Data/OpenSimDatabaseConnector.cs @@ -0,0 +1,78 @@ +/* +* 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.Data; +using System.Data.Common; +using libsecondlife; +using MySql.Data.MySqlClient; + +using TribalMedia.Framework.Data; + +namespace OpenSim.Framework.Data +{ + public abstract class OpenSimDatabaseConnector : BaseDatabaseConnector + { + public OpenSimDatabaseConnector(string connectionString) : base(connectionString) + { + } + + public override object ConvertToDbType(object value) + { + if (value is LLUUID) + { + return ((LLUUID) value).UUID.ToString(); + } + + return base.ConvertToDbType(value); + } + + public override BaseDataReader CreateReader(IDataReader reader) + { + return new OpenSimDataReader(reader); + } + } + + public class MySQLDatabaseMapper : OpenSimDatabaseConnector + { + public MySQLDatabaseMapper(string connectionString) + : base(connectionString) + { + } + + public override DbConnection GetNewConnection() + { + MySqlConnection connection = new MySqlConnection(m_connectionString); + return connection; + } + + public override string CreateParamName(string fieldName) + { + return "?" + fieldName; + } + } +} diff --git a/OpenSim/Framework/Data/OpenSimObjectFieldMapper.cs b/OpenSim/Framework/Data/OpenSimObjectFieldMapper.cs new file mode 100644 index 0000000000..67d9d43fb0 --- /dev/null +++ b/OpenSim/Framework/Data/OpenSimObjectFieldMapper.cs @@ -0,0 +1,103 @@ +/* +* 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.Generic; +using System.Data.Common; +using System.Text; +using libsecondlife; + +using TribalMedia.Framework.Data; + +namespace OpenSim.Framework.Data +{ + public class OpenSimObjectFieldMapper : ObjectField + { + public OpenSimObjectFieldMapper(BaseTableMapper tableMapper, string fieldName, + ObjectGetAccessor rowMapperGetAccessor, + ObjectSetAccessor rowMapperSetAccessor) + : base(tableMapper, fieldName, rowMapperGetAccessor, rowMapperSetAccessor) + { + } + + public override void ExpandField(TObj obj, DbCommand command, List fieldNames) + { + string fieldName = FieldName; + object value = GetParamValue(obj); + + if (ValueType == typeof(LLVector3)) + { + LLVector3 vector = (LLVector3)value; + + RawAddParam(command, fieldNames, fieldName + "X", vector.X); + RawAddParam(command, fieldNames, fieldName + "Y", vector.Y); + RawAddParam(command, fieldNames, fieldName + "Z", vector.Z); + } + else if (ValueType == typeof(LLQuaternion)) + { + LLQuaternion quaternion = (LLQuaternion)value; + + RawAddParam(command, fieldNames, fieldName + "X", quaternion.X); + RawAddParam(command, fieldNames, fieldName + "Y", quaternion.Y); + RawAddParam(command, fieldNames, fieldName + "Z", quaternion.Z); + RawAddParam(command, fieldNames, fieldName + "W", quaternion.W); + } + else + { + base.ExpandField(obj, command, fieldNames); + } + } + + protected override object GetValue(BaseDataReader reader) + { + object value; + + OpenSimDataReader osreader = (OpenSimDataReader) reader; + + if (ValueType == typeof(LLVector3)) + { + value = osreader.GetVector(FieldName); + } + else if (ValueType == typeof(LLQuaternion)) + { + value = osreader.GetQuaternion(FieldName); + } + else if (ValueType == typeof(LLUUID)) + { + Guid guid = reader.GetGuid(FieldName); + value = new LLUUID(guid); + } + else + { + value = base.GetValue(reader); + } + + return value; + } + } +} diff --git a/OpenSim/Framework/Data/OpenSimTableMapper.cs b/OpenSim/Framework/Data/OpenSimTableMapper.cs new file mode 100644 index 0000000000..e7b2ba67da --- /dev/null +++ b/OpenSim/Framework/Data/OpenSimTableMapper.cs @@ -0,0 +1,41 @@ +/* +* 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.Data; + +using TribalMedia.Framework.Data; + +namespace OpenSim.Framework.Data +{ + public abstract class OpenSimTableMapper : BaseTableMapper + { + public OpenSimTableMapper(BaseDatabaseConnector database, string tableName) : base(database, tableName) + { + } + } +} diff --git a/OpenSim/Framework/Data/PrimitiveBaseShapeTableMapper.cs b/OpenSim/Framework/Data/PrimitiveBaseShapeTableMapper.cs new file mode 100644 index 0000000000..9eb43320dd --- /dev/null +++ b/OpenSim/Framework/Data/PrimitiveBaseShapeTableMapper.cs @@ -0,0 +1,171 @@ +/* +* 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 OpenSim.Framework; +using TribalMedia.Framework.Data; +using libsecondlife; + +namespace OpenSim.Framework.Data +{ + public class PrimitiveBaseShapeRowMapper : BaseRowMapper + { + public Guid SceneObjectPartId; + + public PrimitiveBaseShapeRowMapper(BaseSchema schema, PrimitiveBaseShape obj) : base(schema, obj) + { + } + } + + public class PrimitiveBaseShapeTableMapper : OpenSimTableMapper + { + public PrimitiveBaseShapeTableMapper(BaseDatabaseConnector connection, string tableName) + : base(connection, tableName) + { + BaseSchema rowMapperSchema = new BaseSchema(this); + m_schema = rowMapperSchema; + + m_keyFieldMapper = rowMapperSchema.AddMapping("SceneObjectPartId", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.SceneObjectPartId; }, + delegate(PrimitiveBaseShapeRowMapper shape, Guid value) { shape.SceneObjectPartId = value; }); + + rowMapperSchema.AddMapping("PCode", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.Object.PCode; }, + delegate(PrimitiveBaseShapeRowMapper shape, byte value) { shape.Object.PCode = value; }); + + rowMapperSchema.AddMapping("PathBegin", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.Object.PathBegin; }, + delegate(PrimitiveBaseShapeRowMapper shape, ushort value) { shape.Object.PathBegin = value; }); + + rowMapperSchema.AddMapping("PathEnd", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.Object.PathEnd; }, + delegate(PrimitiveBaseShapeRowMapper shape, ushort value) { shape.Object.PathEnd = value; }); + + rowMapperSchema.AddMapping("PathScaleX", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.Object.PathScaleX; }, + delegate(PrimitiveBaseShapeRowMapper shape, byte value) { shape.Object.PathScaleX = value; }); + + rowMapperSchema.AddMapping("PathScaleY", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.Object.PathScaleY; }, + delegate(PrimitiveBaseShapeRowMapper shape, byte value) { shape.Object.PathScaleY = value; }); + + rowMapperSchema.AddMapping("PathShearX", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.Object.PathShearX; }, + delegate(PrimitiveBaseShapeRowMapper shape, byte value) { shape.Object.PathShearX = value; }); + + rowMapperSchema.AddMapping("PathShearY", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.Object.PathShearY; }, + delegate(PrimitiveBaseShapeRowMapper shape, byte value) { shape.Object.PathShearY = value; }); + + rowMapperSchema.AddMapping("ProfileBegin", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.Object.ProfileBegin; }, + delegate(PrimitiveBaseShapeRowMapper shape, ushort value) { shape.Object.ProfileBegin = value; }); + + rowMapperSchema.AddMapping("ProfileEnd", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.Object.ProfileEnd; }, + delegate(PrimitiveBaseShapeRowMapper shape, ushort value) { shape.Object.ProfileEnd = value; }); + + rowMapperSchema.AddMapping("Scale", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.Object.Scale; }, + delegate(PrimitiveBaseShapeRowMapper shape, LLVector3 value) { shape.Object.Scale = value; }); + + rowMapperSchema.AddMapping("PathTaperX", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.Object.PathTaperX; }, + delegate(PrimitiveBaseShapeRowMapper shape, sbyte value) { shape.Object.PathTaperX = value; }); + + rowMapperSchema.AddMapping("PathTaperY", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.Object.PathTaperY; }, + delegate(PrimitiveBaseShapeRowMapper shape, sbyte value) { shape.Object.PathTaperY = value; }); + + rowMapperSchema.AddMapping("PathTwist", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.Object.PathTwist; }, + delegate(PrimitiveBaseShapeRowMapper shape, sbyte value) { shape.Object.PathTwist = value; }); + + rowMapperSchema.AddMapping("PathRadiusOffset", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.Object.PathRadiusOffset; }, + delegate(PrimitiveBaseShapeRowMapper shape, sbyte value) { shape.Object.PathRadiusOffset = value; }); + + rowMapperSchema.AddMapping("PathRevolutions", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.Object.PathRevolutions; }, + delegate(PrimitiveBaseShapeRowMapper shape, byte value) { shape.Object.PathRevolutions = value; }); + + rowMapperSchema.AddMapping("PathTwistBegin", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.Object.PathTwistBegin; }, + delegate(PrimitiveBaseShapeRowMapper shape, sbyte value) { shape.Object.PathTwistBegin = value; }); + + rowMapperSchema.AddMapping("PathCurve", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.Object.PathCurve; }, + delegate(PrimitiveBaseShapeRowMapper shape, byte value) { shape.Object.PathCurve = value; }); + + rowMapperSchema.AddMapping("ProfileCurve", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.Object.ProfileCurve; }, + delegate(PrimitiveBaseShapeRowMapper shape, byte value) { shape.Object.ProfileCurve = value; }); + + rowMapperSchema.AddMapping("ProfileHollow", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.Object.ProfileHollow; }, + delegate(PrimitiveBaseShapeRowMapper shape, ushort value) { shape.Object.ProfileHollow = value; }); + + rowMapperSchema.AddMapping("TextureEntry", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.Object.TextureEntry; }, + delegate(PrimitiveBaseShapeRowMapper shape, byte[] value) { shape.Object.TextureEntry = value; }); + + rowMapperSchema.AddMapping("ExtraParams", + delegate(PrimitiveBaseShapeRowMapper shape) { return shape.Object.ExtraParams; }, + delegate(PrimitiveBaseShapeRowMapper shape, byte[] value) { shape.Object.ExtraParams = value; }); + } + + public override PrimitiveBaseShapeRowMapper FromReader(BaseDataReader reader) + { + PrimitiveBaseShape shape = new PrimitiveBaseShape(); + + PrimitiveBaseShapeRowMapper mapper = new PrimitiveBaseShapeRowMapper(m_schema, shape); + mapper.FillObject( reader ); + + return mapper; + } + + public bool Update(Guid sceneObjectPartId, PrimitiveBaseShape primitiveBaseShape) + { + PrimitiveBaseShapeRowMapper mapper = CreateRowMapper(sceneObjectPartId, primitiveBaseShape); + return Update(sceneObjectPartId, mapper); + } + + public bool Add(Guid sceneObjectPartId, PrimitiveBaseShape primitiveBaseShape) + { + PrimitiveBaseShapeRowMapper mapper = CreateRowMapper(sceneObjectPartId, primitiveBaseShape); + return Add(mapper); + } + + private PrimitiveBaseShapeRowMapper CreateRowMapper(Guid sceneObjectPartId, PrimitiveBaseShape primitiveBaseShape) + { + PrimitiveBaseShapeRowMapper mapper = new PrimitiveBaseShapeRowMapper( m_schema, primitiveBaseShape ); + mapper.SceneObjectPartId = sceneObjectPartId; + return mapper; + } + } +} diff --git a/OpenSim/Framework/Data/Properties/AssemblyInfo.cs b/OpenSim/Framework/Data/Properties/AssemblyInfo.cs index 447dfc1ae0..4ef500ccea 100644 --- a/OpenSim/Framework/Data/Properties/AssemblyInfo.cs +++ b/OpenSim/Framework/Data/Properties/AssemblyInfo.cs @@ -1,38 +1,66 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. - -[assembly : AssemblyTitle("OpenSim.Framework.Data")] -[assembly : AssemblyDescription("")] -[assembly : AssemblyConfiguration("")] -[assembly : AssemblyCompany("")] -[assembly : AssemblyProduct("OpenSim.Framework.Data")] -[assembly : AssemblyCopyright("Copyright © 2007")] -[assembly : AssemblyTrademark("")] -[assembly : AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. - -[assembly : ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM - -[assembly : Guid("3a711c34-b0c0-4264-b0fe-f366eabf9d7b")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: - -[assembly : AssemblyVersion("1.0.0.0")] -[assembly : AssemblyFileVersion("1.0.0.0")] \ No newline at end of file +/* +* 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.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. + +[assembly : AssemblyTitle("OpenSim.Framework.Data")] +[assembly : AssemblyDescription("")] +[assembly : AssemblyConfiguration("")] +[assembly : AssemblyCompany("")] +[assembly : AssemblyProduct("OpenSim.Framework.Data")] +[assembly : AssemblyCopyright("Copyright © OpenSimulator.org Developers 2007-2008")] +[assembly : AssemblyTrademark("")] +[assembly : AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. + +[assembly : ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM + +[assembly : Guid("3a711c34-b0c0-4264-b0fe-f366eabf9d7b")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly : AssemblyVersion("1.0.0.0")] +[assembly : AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/Data/RegionProfileData.cs b/OpenSim/Framework/Data/RegionProfileData.cs index e85024e98e..fb53ac7408 100644 --- a/OpenSim/Framework/Data/RegionProfileData.cs +++ b/OpenSim/Framework/Data/RegionProfileData.cs @@ -1,201 +1,221 @@ -/* -* 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 libsecondlife; -using Nwc.XmlRpc; - -namespace OpenSim.Framework.Data -{ - /// - /// A class which contains information known to the grid server about a region - /// - public class RegionProfileData - { - /// - /// The name of the region - /// - public string regionName = ""; - - /// - /// A 64-bit number combining map position into a (mostly) unique ID - /// - public ulong regionHandle; - - /// - /// OGS/OpenSim Specific ID for a region - /// - public LLUUID UUID; - - /// - /// Coordinates of the region - /// - public uint regionLocX; - - public uint regionLocY; - public uint regionLocZ; // Reserved (round-robin, layers, etc) - - /// - /// Authentication secrets - /// - /// Not very secure, needs improvement. - public string regionSendKey = ""; - - public string regionRecvKey = ""; - public string regionSecret = ""; - - /// - /// Whether the region is online - /// - public bool regionOnline; - - /// - /// Information about the server that the region is currently hosted on - /// - public string serverIP = ""; - - public uint serverPort; - public string serverURI = ""; - - public uint httpPort; - public uint remotingPort; - public string httpServerURI = ""; - - /// - /// Set of optional overrides. Can be used to create non-eulicidean spaces. - /// - public ulong regionNorthOverrideHandle; - - public ulong regionSouthOverrideHandle; - public ulong regionEastOverrideHandle; - public ulong regionWestOverrideHandle; - - /// - /// Optional: URI Location of the region database - /// - /// Used for floating sim pools where the region data is not nessecarily coupled to a specific server - public string regionDataURI = ""; - - /// - /// Region Asset Details - /// - public string regionAssetURI = ""; - - public string regionAssetSendKey = ""; - public string regionAssetRecvKey = ""; - - /// - /// Region Userserver Details - /// - public string regionUserURI = ""; - - public string regionUserSendKey = ""; - public string regionUserRecvKey = ""; - - /// - /// Region Map Texture Asset - /// - public LLUUID regionMapTextureID = new LLUUID("00000000-0000-0000-9999-000000000006"); - - /// - /// Get Sim profile data from grid server when in grid mode - /// - /// - /// - /// - /// - public RegionProfileData RequestSimProfileData(LLUUID region_uuid, string gridserver_url, - string gridserver_sendkey, string gridserver_recvkey) - { - Hashtable requestData = new Hashtable(); - requestData["region_uuid"] = region_uuid.UUID.ToString(); - requestData["authkey"] = gridserver_sendkey; - ArrayList SendParams = new ArrayList(); - SendParams.Add(requestData); - XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams); - XmlRpcResponse GridResp = GridReq.Send(gridserver_url, 3000); - - Hashtable responseData = (Hashtable) GridResp.Value; - - if (responseData.ContainsKey("error")) - { - return null; - } - - RegionProfileData simData = new RegionProfileData(); - simData.regionLocX = Convert.ToUInt32((string) responseData["region_locx"]); - simData.regionLocY = Convert.ToUInt32((string) responseData["region_locy"]); - simData.regionHandle = Helpers.UIntsToLong((simData.regionLocX*256), (simData.regionLocY*256)); - simData.serverIP = (string) responseData["sim_ip"]; - simData.serverPort = Convert.ToUInt32((string) responseData["sim_port"]); - simData.httpPort = Convert.ToUInt32((string) responseData["http_port"]); - simData.remotingPort = Convert.ToUInt32((string) responseData["remoting_port"]); - simData.serverURI = "http://" + simData.serverIP + ":" + simData.serverPort.ToString() + "/"; - simData.httpServerURI = "http://" + simData.serverIP + ":" + simData.httpPort.ToString() + "/"; - simData.UUID = new LLUUID((string) responseData["region_UUID"]); - simData.regionName = (string) responseData["region_name"]; - - return simData; - } - - public RegionProfileData RequestSimProfileData(ulong region_handle, string gridserver_url, - string gridserver_sendkey, string gridserver_recvkey) - { - Hashtable requestData = new Hashtable(); - requestData["region_handle"] = region_handle.ToString(); - requestData["authkey"] = gridserver_sendkey; - ArrayList SendParams = new ArrayList(); - SendParams.Add(requestData); - XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams); - XmlRpcResponse GridResp = GridReq.Send(gridserver_url, 3000); - - Hashtable responseData = (Hashtable) GridResp.Value; - - if (responseData.ContainsKey("error")) - { - return null; - } - - RegionProfileData simData = new RegionProfileData(); - simData.regionLocX = Convert.ToUInt32((string) responseData["region_locx"]); - simData.regionLocY = Convert.ToUInt32((string) responseData["region_locy"]); - simData.regionHandle = Helpers.UIntsToLong((simData.regionLocX*256), (simData.regionLocY*256)); - simData.serverIP = (string) responseData["sim_ip"]; - simData.serverPort = Convert.ToUInt32((string) responseData["sim_port"]); - simData.httpPort = Convert.ToUInt32((string) responseData["http_port"]); - simData.remotingPort = Convert.ToUInt32((string) responseData["remoting_port"]); - simData.httpServerURI = "http://" + simData.serverIP + ":" + simData.httpPort.ToString() + "/"; - simData.serverURI = "http://" + simData.serverIP + ":" + simData.serverPort.ToString() + "/"; - simData.UUID = new LLUUID((string) responseData["region_UUID"]); - simData.regionName = (string) responseData["region_name"]; - - return simData; - } - } -} \ No newline at end of file +/* +* 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 libsecondlife; +using Nwc.XmlRpc; + +namespace OpenSim.Framework.Data +{ + /// + /// A class which contains information known to the grid server about a region + /// + public class RegionProfileData + { + /// + /// The name of the region + /// + public string regionName = String.Empty; + + /// + /// A 64-bit number combining map position into a (mostly) unique ID + /// + public ulong regionHandle; + + /// + /// OGS/OpenSim Specific ID for a region + /// + public LLUUID UUID; + + /// + /// Coordinates of the region + /// + public uint regionLocX; + + public uint regionLocY; + public uint regionLocZ; // Reserved (round-robin, layers, etc) + + /// + /// Authentication secrets + /// + /// Not very secure, needs improvement. + public string regionSendKey = String.Empty; + + public string regionRecvKey = String.Empty; + public string regionSecret = String.Empty; + + /// + /// Whether the region is online + /// + public bool regionOnline; + + /// + /// Information about the server that the region is currently hosted on + /// + public string serverIP = String.Empty; + + public uint serverPort; + public string serverURI = String.Empty; + + public uint httpPort; + public uint remotingPort; + public string httpServerURI = String.Empty; + + /// + /// Set of optional overrides. Can be used to create non-eulicidean spaces. + /// + public ulong regionNorthOverrideHandle; + + public ulong regionSouthOverrideHandle; + public ulong regionEastOverrideHandle; + public ulong regionWestOverrideHandle; + + /// + /// Optional: URI Location of the region database + /// + /// Used for floating sim pools where the region data is not nessecarily coupled to a specific server + public string regionDataURI = String.Empty; + + /// + /// Region Asset Details + /// + public string regionAssetURI = String.Empty; + + public string regionAssetSendKey = String.Empty; + public string regionAssetRecvKey = String.Empty; + + /// + /// Region Userserver Details + /// + public string regionUserURI = String.Empty; + + public string regionUserSendKey = String.Empty; + public string regionUserRecvKey = String.Empty; + + /// + /// Region Map Texture Asset + /// + public LLUUID regionMapTextureID = new LLUUID("00000000-0000-0000-9999-000000000006"); + + // part of an initial brutish effort to provide accurate information (as per the xml region spec) + // wrt the ownership of a given region + // the (very bad) assumption is that this value is being read and handled inconsistently or + // not at all. Current strategy is to put the code in place to support the validity of this information + // and to roll forward debugging any issues from that point + // + /// + /// this particular mod to the file provides support within the spec for RegionProfileData for the + /// owner_uuid for the region + /// + public LLUUID owner_uuid; + + /// + /// Get Sim profile data from grid server when in grid mode + /// + /// + /// + /// + /// + public RegionProfileData RequestSimProfileData(LLUUID region_uuid, string gridserver_url, + string gridserver_sendkey, string gridserver_recvkey) + { + Hashtable requestData = new Hashtable(); + requestData["region_uuid"] = region_uuid.UUID.ToString(); + requestData["authkey"] = gridserver_sendkey; + ArrayList SendParams = new ArrayList(); + SendParams.Add(requestData); + XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams); + XmlRpcResponse GridResp = GridReq.Send(gridserver_url, 3000); + + Hashtable responseData = (Hashtable) GridResp.Value; + + if (responseData.ContainsKey("error")) + { + return null; + } + + RegionProfileData simData = new RegionProfileData(); + simData.regionLocX = Convert.ToUInt32((string) responseData["region_locx"]); + simData.regionLocY = Convert.ToUInt32((string) responseData["region_locy"]); + simData.regionHandle = Helpers.UIntsToLong((simData.regionLocX * Constants.RegionSize), (simData.regionLocY * Constants.RegionSize)); + simData.serverIP = (string) responseData["sim_ip"]; + simData.serverPort = Convert.ToUInt32((string) responseData["sim_port"]); + simData.httpPort = Convert.ToUInt32((string) responseData["http_port"]); + simData.remotingPort = Convert.ToUInt32((string) responseData["remoting_port"]); + simData.serverURI = "http://" + simData.serverIP + ":" + simData.serverPort.ToString() + "/"; + simData.httpServerURI = "http://" + simData.serverIP + ":" + simData.httpPort.ToString() + "/"; + simData.UUID = new LLUUID((string) responseData["region_UUID"]); + simData.regionName = (string) responseData["region_name"]; + + return simData; + } + + /// + /// Request sim profile information from a grid server + /// + /// + /// + /// + /// + /// The sim profile. Null if there was a request failure + public static RegionProfileData RequestSimProfileData(ulong region_handle, string gridserver_url, + string gridserver_sendkey, string gridserver_recvkey) + { + Hashtable requestData = new Hashtable(); + requestData["region_handle"] = region_handle.ToString(); + requestData["authkey"] = gridserver_sendkey; + ArrayList SendParams = new ArrayList(); + SendParams.Add(requestData); + XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams); + XmlRpcResponse GridResp = GridReq.Send(gridserver_url, 3000); + + Hashtable responseData = (Hashtable) GridResp.Value; + + if (responseData.ContainsKey("error")) + { + return null; + } + + RegionProfileData simData = new RegionProfileData(); + simData.regionLocX = Convert.ToUInt32((string) responseData["region_locx"]); + simData.regionLocY = Convert.ToUInt32((string) responseData["region_locy"]); + simData.regionHandle = Helpers.UIntsToLong((simData.regionLocX * Constants.RegionSize), (simData.regionLocY * Constants.RegionSize)); + simData.serverIP = (string) responseData["sim_ip"]; + simData.serverPort = Convert.ToUInt32((string) responseData["sim_port"]); + simData.httpPort = Convert.ToUInt32((string) responseData["http_port"]); + simData.remotingPort = Convert.ToUInt32((string) responseData["remoting_port"]); + simData.httpServerURI = "http://" + simData.serverIP + ":" + simData.httpPort.ToString() + "/"; + simData.serverURI = "http://" + simData.serverIP + ":" + simData.serverPort.ToString() + "/"; + simData.UUID = new LLUUID((string) responseData["region_UUID"]); + simData.regionName = (string) responseData["region_name"]; + + return simData; + } + } +} diff --git a/OpenSim/Framework/Data/ReservationData.cs b/OpenSim/Framework/Data/ReservationData.cs index dc1556ece4..3753358eaa 100644 --- a/OpenSim/Framework/Data/ReservationData.cs +++ b/OpenSim/Framework/Data/ReservationData.cs @@ -1,47 +1,47 @@ -/* -* 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 libsecondlife; - -namespace OpenSim.Framework.Data -{ - public class ReservationData - { - public LLUUID userUUID = LLUUID.Zero; - public int reservationMinX = 0; - public int reservationMinY = 0; - public int reservationMaxX = 65536; - public int reservationMaxY = 65536; - - public string reservationName = ""; - public string reservationCompany = ""; - public bool status = true; - - public string gridSendKey = ""; - public string gridRecvKey = ""; - } -} \ No newline at end of file +/* +* 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 libsecondlife; + +namespace OpenSim.Framework.Data +{ + public class ReservationData + { + public LLUUID userUUID = LLUUID.Zero; + public int reservationMinX = 0; + public int reservationMinY = 0; + public int reservationMaxX = 65536; + public int reservationMaxY = 65536; + + public string reservationName = System.String.Empty; + public string reservationCompany = System.String.Empty; + public bool status = true; + + public string gridSendKey = System.String.Empty; + public string gridRecvKey = System.String.Empty; + } +} diff --git a/OpenSim/Framework/EstateSettings.cs b/OpenSim/Framework/EstateSettings.cs index 2133766b4c..ca20257da8 100644 --- a/OpenSim/Framework/EstateSettings.cs +++ b/OpenSim/Framework/EstateSettings.cs @@ -1,1018 +1,1021 @@ -/* -* 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.IO; -using libsecondlife; - -namespace OpenSim.Framework -{ - public class EstateSettings - { - //Settings to this island - private float m_billableFactor; - - public float billableFactor - { - get { return m_billableFactor; } - set - { - m_billableFactor = value; - configMember.forceSetConfigurationOption("billable_factor", m_billableFactor.ToString()); - } - } - - - private uint m_estateID; - - public uint estateID - { - get { return m_estateID; } - set - { - m_estateID = value; - configMember.forceSetConfigurationOption("estate_id", m_estateID.ToString()); - } - } - - - private uint m_parentEstateID; - - public uint parentEstateID - { - get { return m_parentEstateID; } - set - { - m_parentEstateID = value; - configMember.forceSetConfigurationOption("parent_estate_id", m_parentEstateID.ToString()); - } - } - - private byte m_maxAgents; - - public byte maxAgents - { - get { return m_maxAgents; } - set - { - m_maxAgents = value; - configMember.forceSetConfigurationOption("max_agents", m_maxAgents.ToString()); - } - } - - private float m_objectBonusFactor; - - public float objectBonusFactor - { - get { return m_objectBonusFactor; } - set - { - m_objectBonusFactor = value; - configMember.forceSetConfigurationOption("object_bonus_factor", m_objectBonusFactor.ToString()); - } - } - - private int m_redirectGridX; - - public int redirectGridX - { - get { return m_redirectGridX; } - set - { - m_redirectGridX = value; - configMember.forceSetConfigurationOption("redirect_grid_x", m_redirectGridX.ToString()); - } - } - - private int m_redirectGridY; - - public int redirectGridY - { - get { return m_redirectGridY; } - set - { - m_redirectGridY = value; - configMember.forceSetConfigurationOption("redirect_grid_y", m_redirectGridY.ToString()); - } - } - - private Simulator.RegionFlags m_regionFlags; - - public Simulator.RegionFlags regionFlags - { - get { return m_regionFlags; } - set - { - m_regionFlags = value; - configMember.forceSetConfigurationOption("region_flags", ((uint)m_regionFlags).ToString()); - } - } - - - private Simulator.SimAccess m_simAccess; - - public Simulator.SimAccess simAccess - { - get { return m_simAccess; } - set - { - m_simAccess = value; - configMember.forceSetConfigurationOption("sim_access", ((byte)m_simAccess).ToString()); - } - } - - private float m_sunHour; - - public float sunHour - { - get { return m_sunHour; } - set - { - m_sunHour = value; - configMember.forceSetConfigurationOption("sun_hour", m_sunHour.ToString()); - } - } - - private float m_terrainRaiseLimit; - - public float terrainRaiseLimit - { - get { return m_terrainRaiseLimit; } - set - { - m_terrainRaiseLimit = value; - configMember.forceSetConfigurationOption("terrain_raise_limit", m_terrainRaiseLimit.ToString()); - } - } - - private float m_terrainLowerLimit; - - public float terrainLowerLimit - { - get { return m_terrainLowerLimit; } - set - { - m_terrainLowerLimit = value; - configMember.forceSetConfigurationOption("terrain_lower_limit", m_terrainLowerLimit.ToString()); - } - } - - private bool m_useFixedSun; - - public bool useFixedSun - { - get { return m_useFixedSun; } - set - { - m_useFixedSun = value; - configMember.forceSetConfigurationOption("use_fixed_sun", m_useFixedSun.ToString()); - } - } - - - private int m_pricePerMeter; - - public int pricePerMeter - { - get { return m_pricePerMeter; } - set - { - m_pricePerMeter = value; - configMember.forceSetConfigurationOption("price_per_meter", m_pricePerMeter.ToString()); - } - } - - - private ushort m_regionWaterHeight; - - public ushort regionWaterHeight - { - get { return m_regionWaterHeight; } - set - { - m_regionWaterHeight = value; - configMember.forceSetConfigurationOption("region_water_height", m_regionWaterHeight.ToString()); - } - } - - - private bool m_regionAllowTerraform; - - public bool regionAllowTerraform - { - get { return m_regionAllowTerraform; } - set - { - m_regionAllowTerraform = value; - configMember.forceSetConfigurationOption("region_allow_terraform", m_regionAllowTerraform.ToString()); - } - } - - - // Region Information - // Low resolution 'base' textures. No longer used. - private LLUUID m_terrainBase0; - - public LLUUID terrainBase0 - { - get { return m_terrainBase0; } - set - { - m_terrainBase0 = value; - configMember.forceSetConfigurationOption("terrain_base_0", m_terrainBase0.ToString()); - } - } - - private LLUUID m_terrainBase1; - - public LLUUID terrainBase1 - { - get { return m_terrainBase1; } - set - { - m_terrainBase1 = value; - configMember.forceSetConfigurationOption("terrain_base_1", m_terrainBase1.ToString()); - } - } - - private LLUUID m_terrainBase2; - - public LLUUID terrainBase2 - { - get { return m_terrainBase2; } - set - { - m_terrainBase2 = value; - configMember.forceSetConfigurationOption("terrain_base_2", m_terrainBase2.ToString()); - } - } - - private LLUUID m_terrainBase3; - - public LLUUID terrainBase3 - { - get { return m_terrainBase3; } - set - { - m_terrainBase3 = value; - configMember.forceSetConfigurationOption("terrain_base_3", m_terrainBase3.ToString()); - } - } - - - // Higher resolution terrain textures - private LLUUID m_terrainDetail0; - - public LLUUID terrainDetail0 - { - get { return m_terrainDetail0; } - set - { - m_terrainDetail0 = value; - configMember.forceSetConfigurationOption("terrain_detail_0", m_terrainDetail0.ToString()); - } - } - - private LLUUID m_terrainDetail1; - - public LLUUID terrainDetail1 - { - get { return m_terrainDetail1; } - set - { - m_terrainDetail1 = value; - configMember.forceSetConfigurationOption("terrain_detail_1", m_terrainDetail1.ToString()); - } - } - - private LLUUID m_terrainDetail2; - - public LLUUID terrainDetail2 - { - get { return m_terrainDetail2; } - set - { - m_terrainDetail2 = value; - configMember.forceSetConfigurationOption("terrain_detail_2", m_terrainDetail2.ToString()); - } - } - - private LLUUID m_terrainDetail3; - - public LLUUID terrainDetail3 - { - get { return m_terrainDetail3; } - set - { - m_terrainDetail3 = value; - configMember.forceSetConfigurationOption("terrain_detail_3", m_terrainDetail3.ToString()); - } - } - - // First quad - each point is bilinearly interpolated at each meter of terrain - private float m_terrainStartHeight0; - - public float terrainStartHeight0 - { - get { return m_terrainStartHeight0; } - set - { - m_terrainStartHeight0 = value; - configMember.forceSetConfigurationOption("terrain_start_height_0", m_terrainStartHeight0.ToString()); - } - } - - - private float m_terrainStartHeight1; - - public float terrainStartHeight1 - { - get { return m_terrainStartHeight1; } - set - { - m_terrainStartHeight1 = value; - configMember.forceSetConfigurationOption("terrain_start_height_1", m_terrainStartHeight1.ToString()); - } - } - - private float m_terrainStartHeight2; - - public float terrainStartHeight2 - { - get { return m_terrainStartHeight2; } - set - { - m_terrainStartHeight2 = value; - configMember.forceSetConfigurationOption("terrain_start_height_2", m_terrainStartHeight2.ToString()); - } - } - - private float m_terrainStartHeight3; - - public float terrainStartHeight3 - { - get { return m_terrainStartHeight3; } - set - { - m_terrainStartHeight3 = value; - configMember.forceSetConfigurationOption("terrain_start_height_3", m_terrainStartHeight3.ToString()); - } - } - - // Second quad - also bilinearly interpolated. - // Terrain texturing is done that: - // 0..3 (0 = base0, 3 = base3) = (terrain[x,y] - start[x,y]) / range[x,y] - private float m_terrainHeightRange0; - - public float terrainHeightRange0 - { - get { return m_terrainHeightRange0; } - set - { - m_terrainHeightRange0 = value; - configMember.forceSetConfigurationOption("terrain_height_range_0", m_terrainHeightRange0.ToString()); - } - } - - private float m_terrainHeightRange1; - - public float terrainHeightRange1 - { - get { return m_terrainHeightRange1; } - set - { - m_terrainHeightRange1 = value; - configMember.forceSetConfigurationOption("terrain_height_range_1", m_terrainHeightRange1.ToString()); - } - } - - private float m_terrainHeightRange2; - - public float terrainHeightRange2 - { - get { return m_terrainHeightRange2; } - set - { - m_terrainHeightRange2 = value; - configMember.forceSetConfigurationOption("terrain_height_range_2", m_terrainHeightRange2.ToString()); - } - } - - private float m_terrainHeightRange3; - - public float terrainHeightRange3 - { - get { return m_terrainHeightRange3; } - set - { - m_terrainHeightRange3 = value; - configMember.forceSetConfigurationOption("terrain_height_range_3", m_terrainHeightRange3.ToString()); - } - } - - // Terrain Default (Must be in F32 Format!) - private string m_terrainFile; - - public string terrainFile - { - get { return m_terrainFile; } - set - { - m_terrainFile = value; - configMember.forceSetConfigurationOption("terrain_file", m_terrainFile.ToString()); - } - } - - private double m_terrainMultiplier; - - public double terrainMultiplier - { - get { return m_terrainMultiplier; } - set - { - m_terrainMultiplier = value; - configMember.forceSetConfigurationOption("terrain_multiplier", m_terrainMultiplier.ToString()); - } - } - - private float m_waterHeight; - - public float waterHeight - { - get { return m_waterHeight; } - set - { - m_waterHeight = value; - configMember.forceSetConfigurationOption("water_height", m_waterHeight.ToString()); - } - } - - private LLUUID m_terrainImageID; - - public LLUUID terrainImageID - { - get { return m_terrainImageID; } - set - { - m_terrainImageID = value; - // I don't think there is a reason that this actually - // needs to be written back to the estate settings - // file. - - // configMember.forceSetConfigurationOption("terrain_image_id", m_terrainImageID.ToString()); - } - } - - private LLUUID m_estateManager0; - private LLUUID m_estateManager1; - private LLUUID m_estateManager2; - private LLUUID m_estateManager3; - private LLUUID m_estateManager4; - private LLUUID m_estateManager5; - private LLUUID m_estateManager6; - private LLUUID m_estateManager7; - private LLUUID m_estateManager8; - private LLUUID m_estateManager9; - - public LLUUID[] estateManagers - { - get { - // returns a condensed array of LLUUIDs - return GetEstateManagers(); - - } - set - { - // Sets a Condensed array of LLUUIDS - int i = 0; - for (i = 0; i < value.Length; i++) - { - switch (i) - { - case 0: - m_estateManager0 = value[i]; - break; - case 1: - m_estateManager1 = value[i]; - break; - case 2: - m_estateManager2 = value[i]; - break; - case 3: - m_estateManager3 = value[i]; - break; - case 4: - m_estateManager4 = value[i]; - break; - case 5: - m_estateManager5 = value[i]; - break; - case 6: - m_estateManager6 = value[i]; - break; - case 7: - m_estateManager7 = value[i]; - break; - case 8: - m_estateManager8 = value[i]; - break; - case 9: - m_estateManager9 = value[i]; - break; - } - - } - // Clear the rest of them.. as they're no longer valid - for (int j = i; j < 10; j++) - { - switch (i) - { - case 0: - m_estateManager0 = LLUUID.Zero; - break; - case 1: - m_estateManager1 = LLUUID.Zero; - break; - case 2: - m_estateManager2 = LLUUID.Zero; - break; - case 3: - m_estateManager3 = LLUUID.Zero; - break; - case 4: - m_estateManager4 = LLUUID.Zero; - break; - case 5: - m_estateManager5 = LLUUID.Zero; - break; - case 6: - m_estateManager6 = LLUUID.Zero; - break; - case 7: - m_estateManager7 = LLUUID.Zero; - break; - case 8: - m_estateManager8 = LLUUID.Zero; - break; - case 9: - m_estateManager9 = LLUUID.Zero; - break; - } - } - for (i = 0; i < 10; i++) - { - // Writes out the Estate managers to the XML file. - configMember.forceSetConfigurationOption("estate_manager_" + i, (GetEstateManagerAtPos(i)).ToString()); - - } - } - } - - - - #region EstateManager Get Methods to sort out skipped spots in the XML (suser error) - - private LLUUID GetEstateManagerAtPos(int pos) - { - // This is a helper for writing them out to the xml file - switch (pos) - { - case 0: - return m_estateManager0; - - case 1: - return m_estateManager1; - - case 2: - return m_estateManager2; - - case 3: - return m_estateManager3; - - case 4: - return m_estateManager4; - - case 5: - return m_estateManager5; - - case 6: - return m_estateManager6; - - case 7: - return m_estateManager7; - - case 8: - return m_estateManager8; - - case 9: - return m_estateManager9; - - default: - return LLUUID.Zero; - - } - } - private LLUUID[] GetEstateManagers() - { - int numEstateManagers = GetNumberOfEstateManagers(); - LLUUID[] rEstateManagers = new LLUUID[numEstateManagers]; - - int pos = 0; - - for (int i = 0; i < numEstateManagers; i++) - { - pos = GetNextEstateManager(pos); - - rEstateManagers[i] = GetEstateManagerAtPos(pos); pos++; - - } - return rEstateManagers; - } - - private int GetNextEstateManager(int startpos) - { - // This is a utility function that skips over estate managers set to LLUUID.Zero - int i = startpos; - for (i=startpos;i<10;i++) - { - if (GetEstateManagerAtPos(i) != LLUUID.Zero) return i; - } - return i; - - } - private int GetNumberOfEstateManagers() - { - // This function returns the number of estate managers set - // Regardless of whether there is a skipped spot - int numEstateManagers = 0; - if (m_estateManager0 != LLUUID.Zero) numEstateManagers++; - if (m_estateManager1 != LLUUID.Zero) numEstateManagers++; - if (m_estateManager2 != LLUUID.Zero) numEstateManagers++; - if (m_estateManager3 != LLUUID.Zero) numEstateManagers++; - if (m_estateManager4 != LLUUID.Zero) numEstateManagers++; - if (m_estateManager5 != LLUUID.Zero) numEstateManagers++; - if (m_estateManager6 != LLUUID.Zero) numEstateManagers++; - if (m_estateManager7 != LLUUID.Zero) numEstateManagers++; - if (m_estateManager8 != LLUUID.Zero) numEstateManagers++; - if (m_estateManager9 != LLUUID.Zero) numEstateManagers++; - - return numEstateManagers; - } - - public void AddEstateManager(LLUUID avatarID) - { - LLUUID[] testateManagers = GetEstateManagers(); - LLUUID[] nestateManagers = new LLUUID[testateManagers.Length + 1]; - - int i = 0; - for (i = 0; i < testateManagers.Length; i++) - { - nestateManagers[i] = testateManagers[i]; - } - - nestateManagers[i] = avatarID; - - //Saves it to the estate settings file - estateManagers = nestateManagers; - - } - public void RemoveEstateManager(LLUUID avatarID) - { - int notfoundparam = 11; // starting high so the condense routine (max ten) doesn't run if we don't find it. - LLUUID[] testateManagers = GetEstateManagers(); // temporary estate managers list - - - int i = 0; - int foundpos = notfoundparam; - - // search for estate manager. - for (i = 0; i < testateManagers.Length; i++) - { - if (testateManagers[i] == avatarID) - { - foundpos = i; - break; - } - } - if (foundpos < notfoundparam) - { - LLUUID[] restateManagers = new LLUUID[testateManagers.Length - 1]; - - // fill new estate managers array up to the found spot - for (int j = 0; j < foundpos; j++) - restateManagers[j] = testateManagers[j]; - - // skip over the estate manager we're removing and compress - for (int j = foundpos + 1; j < testateManagers.Length; j++) - restateManagers[j - 1] = testateManagers[j]; - - estateManagers = restateManagers; - } - else - { - OpenSim.Framework.Console.MainLog.Instance.Error("ESTATESETTINGS", "Unable to locate estate manager : " + avatarID.ToString() + " for removal"); - } - } - - #endregion - - private ConfigurationMember configMember; - - public EstateSettings() - { - // Temporary hack to prevent multiple loadings. - if (configMember == null) - { - configMember = - new ConfigurationMember(Path.Combine(Util.configDir(), "estate_settings.xml"), "ESTATE SETTINGS", - loadConfigurationOptions, handleIncomingConfiguration,true); - configMember.performConfigurationRetrieve(); - } - } - - public void loadConfigurationOptions() - { - configMember.addConfigurationOption("billable_factor", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", - "0.0", true); - configMember.addConfigurationOption("estate_id", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, "", "0", - true); - configMember.addConfigurationOption("parent_estate_id", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, - "", "0", true); - configMember.addConfigurationOption("max_agents", ConfigurationOption.ConfigurationTypes.TYPE_BYTE, "", "40", - true); - - configMember.addConfigurationOption("object_bonus_factor", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, - "", "1.0", true); - configMember.addConfigurationOption("redirect_grid_x", ConfigurationOption.ConfigurationTypes.TYPE_INT32, "", - "0", true); - configMember.addConfigurationOption("redirect_grid_y", ConfigurationOption.ConfigurationTypes.TYPE_INT32, "", - "0", true); - configMember.addConfigurationOption("region_flags", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, "", - "0", true); - configMember.addConfigurationOption("sim_access", ConfigurationOption.ConfigurationTypes.TYPE_BYTE, "", "21", - true); - configMember.addConfigurationOption("sun_hour", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "0", - true); - configMember.addConfigurationOption("terrain_raise_limit", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, - "", "0", true); - configMember.addConfigurationOption("terrain_lower_limit", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, - "", "0", true); - configMember.addConfigurationOption("use_fixed_sun", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN, "", - "false", true); - configMember.addConfigurationOption("price_per_meter", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, - "", "1", true); - configMember.addConfigurationOption("region_water_height", - ConfigurationOption.ConfigurationTypes.TYPE_UINT16, "", "20", true); - configMember.addConfigurationOption("region_allow_terraform", - ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN, "", "true", true); - - configMember.addConfigurationOption("terrain_base_0", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, "", - "b8d3965a-ad78-bf43-699b-bff8eca6c975", true); - configMember.addConfigurationOption("terrain_base_1", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, "", - "abb783e6-3e93-26c0-248a-247666855da3", true); - configMember.addConfigurationOption("terrain_base_2", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, "", - "179cdabd-398a-9b6b-1391-4dc333ba321f", true); - configMember.addConfigurationOption("terrain_base_3", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, "", - "beb169c7-11ea-fff2-efe5-0f24dc881df2", true); - - configMember.addConfigurationOption("terrain_detail_0", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, - "", "00000000-0000-0000-0000-000000000000", true); - configMember.addConfigurationOption("terrain_detail_1", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, - "", "00000000-0000-0000-0000-000000000000", true); - configMember.addConfigurationOption("terrain_detail_2", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, - "", "00000000-0000-0000-0000-000000000000", true); - configMember.addConfigurationOption("terrain_detail_3", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, - "", "00000000-0000-0000-0000-000000000000", true); - - configMember.addConfigurationOption("terrain_start_height_0", - ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "10.0", true); - configMember.addConfigurationOption("terrain_start_height_1", - ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "10.0", true); - configMember.addConfigurationOption("terrain_start_height_2", - ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "10.0", true); - configMember.addConfigurationOption("terrain_start_height_3", - ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "10.0", true); - - configMember.addConfigurationOption("terrain_height_range_0", - ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "60.0", true); - configMember.addConfigurationOption("terrain_height_range_1", - ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "60.0", true); - configMember.addConfigurationOption("terrain_height_range_2", - ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "60.0", true); - configMember.addConfigurationOption("terrain_height_range_3", - ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "60.0", true); - - configMember.addConfigurationOption("terrain_file", - ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "", - "default.r32", true); - configMember.addConfigurationOption("terrain_multiplier", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, - "", "60.0", true); - configMember.addConfigurationOption("water_height", ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE, "", - "20.0", true); - configMember.addConfigurationOption("terrain_image_id", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, - "", "00000000-0000-0000-0000-000000000000", true); - - configMember.addConfigurationOption("estate_manager_0", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, - "", "00000000-0000-0000-0000-000000000000", true); - configMember.addConfigurationOption("estate_manager_1", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, - "", "00000000-0000-0000-0000-000000000000", true); - configMember.addConfigurationOption("estate_manager_2", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, - "", "00000000-0000-0000-0000-000000000000", true); - configMember.addConfigurationOption("estate_manager_3", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, - "", "00000000-0000-0000-0000-000000000000", true); - configMember.addConfigurationOption("estate_manager_4", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, - "", "00000000-0000-0000-0000-000000000000", true); - configMember.addConfigurationOption("estate_manager_5", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, - "", "00000000-0000-0000-0000-000000000000", true); - configMember.addConfigurationOption("estate_manager_6", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, - "", "00000000-0000-0000-0000-000000000000", true); - configMember.addConfigurationOption("estate_manager_7", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, - "", "00000000-0000-0000-0000-000000000000", true); - configMember.addConfigurationOption("estate_manager_8", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, - "", "00000000-0000-0000-0000-000000000000", true); - configMember.addConfigurationOption("estate_manager_9", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, - "", "00000000-0000-0000-0000-000000000000", true); - - } - - public bool handleIncomingConfiguration(string configuration_key, object configuration_result) - { - switch (configuration_key) - { - case "billable_factor": - m_billableFactor = (float) configuration_result; - break; - case "estate_id": - m_estateID = (uint) configuration_result; - break; - case "parent_estate_id": - m_parentEstateID = (uint) configuration_result; - break; - case "max_agents": - m_maxAgents = (byte) configuration_result; - break; - - case "object_bonus_factor": - m_objectBonusFactor = (float) configuration_result; - break; - case "redirect_grid_x": - m_redirectGridX = (int) configuration_result; - break; - case "redirect_grid_y": - m_redirectGridY = (int) configuration_result; - break; - case "region_flags": - m_regionFlags = (Simulator.RegionFlags) ((uint) configuration_result); - break; - case "sim_access": - m_simAccess = (Simulator.SimAccess) ((byte) configuration_result); - break; - case "sun_hour": - m_sunHour = (float) configuration_result; - break; - case "terrain_raise_limit": - m_terrainRaiseLimit = (float) configuration_result; - break; - case "terrain_lower_limit": - m_terrainLowerLimit = (float) configuration_result; - break; - case "use_fixed_sun": - m_useFixedSun = (bool) configuration_result; - break; - case "price_per_meter": - m_pricePerMeter = Convert.ToInt32(configuration_result); - break; - case "region_water_height": - m_regionWaterHeight = (ushort) configuration_result; - break; - case "region_allow_terraform": - m_regionAllowTerraform = (bool) configuration_result; - break; - - case "terrain_base_0": - m_terrainBase0 = (LLUUID) configuration_result; - break; - case "terrain_base_1": - m_terrainBase1 = (LLUUID) configuration_result; - break; - case "terrain_base_2": - m_terrainBase2 = (LLUUID) configuration_result; - break; - case "terrain_base_3": - m_terrainBase3 = (LLUUID) configuration_result; - break; - - case "terrain_detail_0": - m_terrainDetail0 = (LLUUID) configuration_result; - break; - case "terrain_detail_1": - m_terrainDetail1 = (LLUUID) configuration_result; - break; - case "terrain_detail_2": - m_terrainDetail2 = (LLUUID) configuration_result; - break; - case "terrain_detail_3": - m_terrainDetail3 = (LLUUID) configuration_result; - break; - - case "terrain_start_height_0": - m_terrainStartHeight0 = (float) configuration_result; - break; - case "terrain_start_height_1": - m_terrainStartHeight1 = (float) configuration_result; - break; - case "terrain_start_height_2": - m_terrainStartHeight2 = (float) configuration_result; - break; - case "terrain_start_height_3": - m_terrainStartHeight3 = (float) configuration_result; - break; - - case "terrain_height_range_0": - m_terrainHeightRange0 = (float) configuration_result; - break; - case "terrain_height_range_1": - m_terrainHeightRange1 = (float) configuration_result; - break; - case "terrain_height_range_2": - m_terrainHeightRange2 = (float) configuration_result; - break; - case "terrain_height_range_3": - m_terrainHeightRange3 = (float) configuration_result; - break; - - case "terrain_file": - m_terrainFile = (string) configuration_result; - break; - case "terrain_multiplier": - m_terrainMultiplier = Convert.ToDouble(configuration_result); - break; - case "water_height": - double tmpVal = (double) configuration_result; - m_waterHeight = (float) tmpVal; - break; - case "terrain_image_id": - m_terrainImageID = (LLUUID) configuration_result; - break; - - case "estate_manager_0": - m_estateManager0 = (LLUUID)configuration_result; - break; - case "estate_manager_1": - m_estateManager1 = (LLUUID)configuration_result; - break; - case "estate_manager_2": - m_estateManager2 = (LLUUID)configuration_result; - break; - case "estate_manager_3": - m_estateManager3 = (LLUUID)configuration_result; - break; - case "estate_manager_4": - m_estateManager4 = (LLUUID)configuration_result; - break; - case "estate_manager_5": - m_estateManager5 = (LLUUID)configuration_result; - break; - case "estate_manager_6": - m_estateManager6 = (LLUUID)configuration_result; - break; - case "estate_manager_7": - m_estateManager7 = (LLUUID)configuration_result; - break; - case "estate_manager_8": - m_estateManager8 = (LLUUID)configuration_result; - break; - case "estate_manager_9": - m_estateManager9 = (LLUUID)configuration_result; - break; - - } - - return true; - } - } -} \ No newline at end of file +/* +* 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.IO; +using libsecondlife; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework +{ + public class EstateSettings + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + //Settings to this island + private float m_billableFactor; + + public float billableFactor + { + get { return m_billableFactor; } + set + { + m_billableFactor = value; + configMember.forceSetConfigurationOption("billable_factor", m_billableFactor.ToString()); + } + } + + + private uint m_estateID; + + public uint estateID + { + get { return m_estateID; } + set + { + m_estateID = value; + configMember.forceSetConfigurationOption("estate_id", m_estateID.ToString()); + } + } + + + private uint m_parentEstateID; + + public uint parentEstateID + { + get { return m_parentEstateID; } + set + { + m_parentEstateID = value; + configMember.forceSetConfigurationOption("parent_estate_id", m_parentEstateID.ToString()); + } + } + + private byte m_maxAgents; + + public byte maxAgents + { + get { return m_maxAgents; } + set + { + m_maxAgents = value; + configMember.forceSetConfigurationOption("max_agents", m_maxAgents.ToString()); + } + } + + private float m_objectBonusFactor; + + public float objectBonusFactor + { + get { return m_objectBonusFactor; } + set + { + m_objectBonusFactor = value; + configMember.forceSetConfigurationOption("object_bonus_factor", m_objectBonusFactor.ToString()); + } + } + + private int m_redirectGridX; + + public int redirectGridX + { + get { return m_redirectGridX; } + set + { + m_redirectGridX = value; + configMember.forceSetConfigurationOption("redirect_grid_x", m_redirectGridX.ToString()); + } + } + + private int m_redirectGridY; + + public int redirectGridY + { + get { return m_redirectGridY; } + set + { + m_redirectGridY = value; + configMember.forceSetConfigurationOption("redirect_grid_y", m_redirectGridY.ToString()); + } + } + + private Simulator.RegionFlags m_regionFlags; + + public Simulator.RegionFlags regionFlags + { + get { return m_regionFlags; } + set + { + m_regionFlags = value; + configMember.forceSetConfigurationOption("region_flags", ((uint)m_regionFlags).ToString()); + } + } + + + private Simulator.SimAccess m_simAccess; + + public Simulator.SimAccess simAccess + { + get { return m_simAccess; } + set + { + m_simAccess = value; + configMember.forceSetConfigurationOption("sim_access", ((byte)m_simAccess).ToString()); + } + } + + private float m_sunHour; + + public float sunHour + { + get { return m_sunHour; } + set + { + m_sunHour = value; + configMember.forceSetConfigurationOption("sun_hour", m_sunHour.ToString()); + } + } + + private float m_terrainRaiseLimit; + + public float terrainRaiseLimit + { + get { return m_terrainRaiseLimit; } + set + { + m_terrainRaiseLimit = value; + configMember.forceSetConfigurationOption("terrain_raise_limit", m_terrainRaiseLimit.ToString()); + } + } + + private float m_terrainLowerLimit; + + public float terrainLowerLimit + { + get { return m_terrainLowerLimit; } + set + { + m_terrainLowerLimit = value; + configMember.forceSetConfigurationOption("terrain_lower_limit", m_terrainLowerLimit.ToString()); + } + } + + private bool m_useFixedSun; + + public bool useFixedSun + { + get { return m_useFixedSun; } + set + { + m_useFixedSun = value; + configMember.forceSetConfigurationOption("use_fixed_sun", m_useFixedSun.ToString()); + } + } + + + private int m_pricePerMeter; + + public int pricePerMeter + { + get { return m_pricePerMeter; } + set + { + m_pricePerMeter = value; + configMember.forceSetConfigurationOption("price_per_meter", m_pricePerMeter.ToString()); + } + } + + + private ushort m_regionWaterHeight; + + public ushort regionWaterHeight + { + get { return m_regionWaterHeight; } + set + { + m_regionWaterHeight = value; + configMember.forceSetConfigurationOption("region_water_height", m_regionWaterHeight.ToString()); + } + } + + + private bool m_regionAllowTerraform; + + public bool regionAllowTerraform + { + get { return m_regionAllowTerraform; } + set + { + m_regionAllowTerraform = value; + configMember.forceSetConfigurationOption("region_allow_terraform", m_regionAllowTerraform.ToString()); + } + } + + + // Region Information + // Low resolution 'base' textures. No longer used. + private LLUUID m_terrainBase0; + + public LLUUID terrainBase0 + { + get { return m_terrainBase0; } + set + { + m_terrainBase0 = value; + configMember.forceSetConfigurationOption("terrain_base_0", m_terrainBase0.ToString()); + } + } + + private LLUUID m_terrainBase1; + + public LLUUID terrainBase1 + { + get { return m_terrainBase1; } + set + { + m_terrainBase1 = value; + configMember.forceSetConfigurationOption("terrain_base_1", m_terrainBase1.ToString()); + } + } + + private LLUUID m_terrainBase2; + + public LLUUID terrainBase2 + { + get { return m_terrainBase2; } + set + { + m_terrainBase2 = value; + configMember.forceSetConfigurationOption("terrain_base_2", m_terrainBase2.ToString()); + } + } + + private LLUUID m_terrainBase3; + + public LLUUID terrainBase3 + { + get { return m_terrainBase3; } + set + { + m_terrainBase3 = value; + configMember.forceSetConfigurationOption("terrain_base_3", m_terrainBase3.ToString()); + } + } + + + // Higher resolution terrain textures + private LLUUID m_terrainDetail0; + + public LLUUID terrainDetail0 + { + get { return m_terrainDetail0; } + set + { + m_terrainDetail0 = value; + configMember.forceSetConfigurationOption("terrain_detail_0", m_terrainDetail0.ToString()); + } + } + + private LLUUID m_terrainDetail1; + + public LLUUID terrainDetail1 + { + get { return m_terrainDetail1; } + set + { + m_terrainDetail1 = value; + configMember.forceSetConfigurationOption("terrain_detail_1", m_terrainDetail1.ToString()); + } + } + + private LLUUID m_terrainDetail2; + + public LLUUID terrainDetail2 + { + get { return m_terrainDetail2; } + set + { + m_terrainDetail2 = value; + configMember.forceSetConfigurationOption("terrain_detail_2", m_terrainDetail2.ToString()); + } + } + + private LLUUID m_terrainDetail3; + + public LLUUID terrainDetail3 + { + get { return m_terrainDetail3; } + set + { + m_terrainDetail3 = value; + configMember.forceSetConfigurationOption("terrain_detail_3", m_terrainDetail3.ToString()); + } + } + + // First quad - each point is bilinearly interpolated at each meter of terrain + private float m_terrainStartHeight0; + + public float terrainStartHeight0 + { + get { return m_terrainStartHeight0; } + set + { + m_terrainStartHeight0 = value; + configMember.forceSetConfigurationOption("terrain_start_height_0", m_terrainStartHeight0.ToString()); + } + } + + + private float m_terrainStartHeight1; + + public float terrainStartHeight1 + { + get { return m_terrainStartHeight1; } + set + { + m_terrainStartHeight1 = value; + configMember.forceSetConfigurationOption("terrain_start_height_1", m_terrainStartHeight1.ToString()); + } + } + + private float m_terrainStartHeight2; + + public float terrainStartHeight2 + { + get { return m_terrainStartHeight2; } + set + { + m_terrainStartHeight2 = value; + configMember.forceSetConfigurationOption("terrain_start_height_2", m_terrainStartHeight2.ToString()); + } + } + + private float m_terrainStartHeight3; + + public float terrainStartHeight3 + { + get { return m_terrainStartHeight3; } + set + { + m_terrainStartHeight3 = value; + configMember.forceSetConfigurationOption("terrain_start_height_3", m_terrainStartHeight3.ToString()); + } + } + + // Second quad - also bilinearly interpolated. + // Terrain texturing is done that: + // 0..3 (0 = base0, 3 = base3) = (terrain[x,y] - start[x,y]) / range[x,y] + private float m_terrainHeightRange0; + + public float terrainHeightRange0 + { + get { return m_terrainHeightRange0; } + set + { + m_terrainHeightRange0 = value; + configMember.forceSetConfigurationOption("terrain_height_range_0", m_terrainHeightRange0.ToString()); + } + } + + private float m_terrainHeightRange1; + + public float terrainHeightRange1 + { + get { return m_terrainHeightRange1; } + set + { + m_terrainHeightRange1 = value; + configMember.forceSetConfigurationOption("terrain_height_range_1", m_terrainHeightRange1.ToString()); + } + } + + private float m_terrainHeightRange2; + + public float terrainHeightRange2 + { + get { return m_terrainHeightRange2; } + set + { + m_terrainHeightRange2 = value; + configMember.forceSetConfigurationOption("terrain_height_range_2", m_terrainHeightRange2.ToString()); + } + } + + private float m_terrainHeightRange3; + + public float terrainHeightRange3 + { + get { return m_terrainHeightRange3; } + set + { + m_terrainHeightRange3 = value; + configMember.forceSetConfigurationOption("terrain_height_range_3", m_terrainHeightRange3.ToString()); + } + } + + // Terrain Default (Must be in F32 Format!) + private string m_terrainFile; + + public string terrainFile + { + get { return m_terrainFile; } + set + { + m_terrainFile = value; + configMember.forceSetConfigurationOption("terrain_file", m_terrainFile.ToString()); + } + } + + private double m_terrainMultiplier; + + public double terrainMultiplier + { + get { return m_terrainMultiplier; } + set + { + m_terrainMultiplier = value; + configMember.forceSetConfigurationOption("terrain_multiplier", m_terrainMultiplier.ToString()); + } + } + + private float m_waterHeight; + + public float waterHeight + { + get { return m_waterHeight; } + set + { + m_waterHeight = value; + configMember.forceSetConfigurationOption("water_height", m_waterHeight.ToString()); + } + } + + private LLUUID m_terrainImageID; + + public LLUUID terrainImageID + { + get { return m_terrainImageID; } + set + { + m_terrainImageID = value; + // I don't think there is a reason that this actually + // needs to be written back to the estate settings + // file. + + // configMember.forceSetConfigurationOption("terrain_image_id", m_terrainImageID.ToString()); + } + } + + private LLUUID m_estateManager0; + private LLUUID m_estateManager1; + private LLUUID m_estateManager2; + private LLUUID m_estateManager3; + private LLUUID m_estateManager4; + private LLUUID m_estateManager5; + private LLUUID m_estateManager6; + private LLUUID m_estateManager7; + private LLUUID m_estateManager8; + private LLUUID m_estateManager9; + + public LLUUID[] estateManagers + { + get { + // returns a condensed array of LLUUIDs + return GetEstateManagers(); + + } + set + { + // Sets a Condensed array of LLUUIDS + int i = 0; + for (i = 0; i < value.Length; i++) + { + switch (i) + { + case 0: + m_estateManager0 = value[i]; + break; + case 1: + m_estateManager1 = value[i]; + break; + case 2: + m_estateManager2 = value[i]; + break; + case 3: + m_estateManager3 = value[i]; + break; + case 4: + m_estateManager4 = value[i]; + break; + case 5: + m_estateManager5 = value[i]; + break; + case 6: + m_estateManager6 = value[i]; + break; + case 7: + m_estateManager7 = value[i]; + break; + case 8: + m_estateManager8 = value[i]; + break; + case 9: + m_estateManager9 = value[i]; + break; + } + + } + // Clear the rest of them.. as they're no longer valid + for (int j = i; j < 10; j++) + { + switch (i) + { + case 0: + m_estateManager0 = LLUUID.Zero; + break; + case 1: + m_estateManager1 = LLUUID.Zero; + break; + case 2: + m_estateManager2 = LLUUID.Zero; + break; + case 3: + m_estateManager3 = LLUUID.Zero; + break; + case 4: + m_estateManager4 = LLUUID.Zero; + break; + case 5: + m_estateManager5 = LLUUID.Zero; + break; + case 6: + m_estateManager6 = LLUUID.Zero; + break; + case 7: + m_estateManager7 = LLUUID.Zero; + break; + case 8: + m_estateManager8 = LLUUID.Zero; + break; + case 9: + m_estateManager9 = LLUUID.Zero; + break; + } + } + for (i = 0; i < 10; i++) + { + // Writes out the Estate managers to the XML file. + configMember.forceSetConfigurationOption("estate_manager_" + i, (GetEstateManagerAtPos(i)).ToString()); + + } + } + } + + + + #region EstateManager Get Methods to sort out skipped spots in the XML (suser error) + + private LLUUID GetEstateManagerAtPos(int pos) + { + // This is a helper for writing them out to the xml file + switch (pos) + { + case 0: + return m_estateManager0; + + case 1: + return m_estateManager1; + + case 2: + return m_estateManager2; + + case 3: + return m_estateManager3; + + case 4: + return m_estateManager4; + + case 5: + return m_estateManager5; + + case 6: + return m_estateManager6; + + case 7: + return m_estateManager7; + + case 8: + return m_estateManager8; + + case 9: + return m_estateManager9; + + default: + return LLUUID.Zero; + + } + } + private LLUUID[] GetEstateManagers() + { + int numEstateManagers = GetNumberOfEstateManagers(); + LLUUID[] rEstateManagers = new LLUUID[numEstateManagers]; + + int pos = 0; + + for (int i = 0; i < numEstateManagers; i++) + { + pos = GetNextEstateManager(pos); + + rEstateManagers[i] = GetEstateManagerAtPos(pos); pos++; + + } + return rEstateManagers; + } + + private int GetNextEstateManager(int startpos) + { + // This is a utility function that skips over estate managers set to LLUUID.Zero + int i = startpos; + for (i=startpos;i<10;i++) + { + if (GetEstateManagerAtPos(i) != LLUUID.Zero) return i; + } + return i; + + } + private int GetNumberOfEstateManagers() + { + // This function returns the number of estate managers set + // Regardless of whether there is a skipped spot + int numEstateManagers = 0; + if (m_estateManager0 != LLUUID.Zero) numEstateManagers++; + if (m_estateManager1 != LLUUID.Zero) numEstateManagers++; + if (m_estateManager2 != LLUUID.Zero) numEstateManagers++; + if (m_estateManager3 != LLUUID.Zero) numEstateManagers++; + if (m_estateManager4 != LLUUID.Zero) numEstateManagers++; + if (m_estateManager5 != LLUUID.Zero) numEstateManagers++; + if (m_estateManager6 != LLUUID.Zero) numEstateManagers++; + if (m_estateManager7 != LLUUID.Zero) numEstateManagers++; + if (m_estateManager8 != LLUUID.Zero) numEstateManagers++; + if (m_estateManager9 != LLUUID.Zero) numEstateManagers++; + + return numEstateManagers; + } + + public void AddEstateManager(LLUUID avatarID) + { + LLUUID[] testateManagers = GetEstateManagers(); + LLUUID[] nestateManagers = new LLUUID[testateManagers.Length + 1]; + + int i = 0; + for (i = 0; i < testateManagers.Length; i++) + { + nestateManagers[i] = testateManagers[i]; + } + + nestateManagers[i] = avatarID; + + //Saves it to the estate settings file + estateManagers = nestateManagers; + + } + public void RemoveEstateManager(LLUUID avatarID) + { + int notfoundparam = 11; // starting high so the condense routine (max ten) doesn't run if we don't find it. + LLUUID[] testateManagers = GetEstateManagers(); // temporary estate managers list + + + int i = 0; + int foundpos = notfoundparam; + + // search for estate manager. + for (i = 0; i < testateManagers.Length; i++) + { + if (testateManagers[i] == avatarID) + { + foundpos = i; + break; + } + } + if (foundpos < notfoundparam) + { + LLUUID[] restateManagers = new LLUUID[testateManagers.Length - 1]; + + // fill new estate managers array up to the found spot + for (int j = 0; j < foundpos; j++) + restateManagers[j] = testateManagers[j]; + + // skip over the estate manager we're removing and compress + for (int j = foundpos + 1; j < testateManagers.Length; j++) + restateManagers[j - 1] = testateManagers[j]; + + estateManagers = restateManagers; + } + else + { + m_log.Error("[ESTATESETTINGS]: Unable to locate estate manager : " + avatarID.ToString() + " for removal"); + } + } + + #endregion + + private ConfigurationMember configMember; + + public EstateSettings() + { + // Temporary hack to prevent multiple loadings. + if (configMember == null) + { + configMember = + new ConfigurationMember(Path.Combine(Util.configDir(), "estate_settings.xml"), "ESTATE SETTINGS", + loadConfigurationOptions, handleIncomingConfiguration, true); + configMember.performConfigurationRetrieve(); + } + } + + public void loadConfigurationOptions() + { + configMember.addConfigurationOption("billable_factor", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, String.Empty, + "0.0", true); + configMember.addConfigurationOption("estate_id", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, String.Empty, "0", + true); + configMember.addConfigurationOption("parent_estate_id", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + String.Empty, "0", true); + configMember.addConfigurationOption("max_agents", ConfigurationOption.ConfigurationTypes.TYPE_BYTE, String.Empty, "40", + true); + + configMember.addConfigurationOption("object_bonus_factor", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, + String.Empty, "1.0", true); + configMember.addConfigurationOption("redirect_grid_x", ConfigurationOption.ConfigurationTypes.TYPE_INT32, String.Empty, + "0", true); + configMember.addConfigurationOption("redirect_grid_y", ConfigurationOption.ConfigurationTypes.TYPE_INT32, String.Empty, + "0", true); + configMember.addConfigurationOption("region_flags", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, String.Empty, + "0", true); + configMember.addConfigurationOption("sim_access", ConfigurationOption.ConfigurationTypes.TYPE_BYTE, String.Empty, "21", + true); + configMember.addConfigurationOption("sun_hour", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, String.Empty, "0", + true); + configMember.addConfigurationOption("terrain_raise_limit", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, + String.Empty, "0", true); + configMember.addConfigurationOption("terrain_lower_limit", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, + String.Empty, "0", true); + configMember.addConfigurationOption("use_fixed_sun", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN, String.Empty, + "false", true); + configMember.addConfigurationOption("price_per_meter", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + String.Empty, "1", true); + configMember.addConfigurationOption("region_water_height", + ConfigurationOption.ConfigurationTypes.TYPE_UINT16, String.Empty, "20", true); + configMember.addConfigurationOption("region_allow_terraform", + ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN, String.Empty, "true", true); + + configMember.addConfigurationOption("terrain_base_0", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, String.Empty, + "b8d3965a-ad78-bf43-699b-bff8eca6c975", true); + configMember.addConfigurationOption("terrain_base_1", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, String.Empty, + "abb783e6-3e93-26c0-248a-247666855da3", true); + configMember.addConfigurationOption("terrain_base_2", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, String.Empty, + "179cdabd-398a-9b6b-1391-4dc333ba321f", true); + configMember.addConfigurationOption("terrain_base_3", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, String.Empty, + "beb169c7-11ea-fff2-efe5-0f24dc881df2", true); + + configMember.addConfigurationOption("terrain_detail_0", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, + String.Empty, "00000000-0000-0000-0000-000000000000", true); + configMember.addConfigurationOption("terrain_detail_1", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, + String.Empty, "00000000-0000-0000-0000-000000000000", true); + configMember.addConfigurationOption("terrain_detail_2", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, + String.Empty, "00000000-0000-0000-0000-000000000000", true); + configMember.addConfigurationOption("terrain_detail_3", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, + String.Empty, "00000000-0000-0000-0000-000000000000", true); + + configMember.addConfigurationOption("terrain_start_height_0", + ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, String.Empty, "10.0", true); + configMember.addConfigurationOption("terrain_start_height_1", + ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, String.Empty, "10.0", true); + configMember.addConfigurationOption("terrain_start_height_2", + ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, String.Empty, "10.0", true); + configMember.addConfigurationOption("terrain_start_height_3", + ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, String.Empty, "10.0", true); + + configMember.addConfigurationOption("terrain_height_range_0", + ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, String.Empty, "60.0", true); + configMember.addConfigurationOption("terrain_height_range_1", + ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, String.Empty, "60.0", true); + configMember.addConfigurationOption("terrain_height_range_2", + ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, String.Empty, "60.0", true); + configMember.addConfigurationOption("terrain_height_range_3", + ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, String.Empty, "60.0", true); + + configMember.addConfigurationOption("terrain_file", + ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, String.Empty, + "default.r32", true); + configMember.addConfigurationOption("terrain_multiplier", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, + String.Empty, "60.0", true); + configMember.addConfigurationOption("water_height", ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE, String.Empty, + "20.0", true); + configMember.addConfigurationOption("terrain_image_id", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, + String.Empty, "00000000-0000-0000-0000-000000000000", true); + + configMember.addConfigurationOption("estate_manager_0", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, + String.Empty, "00000000-0000-0000-0000-000000000000", true); + configMember.addConfigurationOption("estate_manager_1", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, + String.Empty, "00000000-0000-0000-0000-000000000000", true); + configMember.addConfigurationOption("estate_manager_2", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, + String.Empty, "00000000-0000-0000-0000-000000000000", true); + configMember.addConfigurationOption("estate_manager_3", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, + String.Empty, "00000000-0000-0000-0000-000000000000", true); + configMember.addConfigurationOption("estate_manager_4", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, + String.Empty, "00000000-0000-0000-0000-000000000000", true); + configMember.addConfigurationOption("estate_manager_5", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, + String.Empty, "00000000-0000-0000-0000-000000000000", true); + configMember.addConfigurationOption("estate_manager_6", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, + String.Empty, "00000000-0000-0000-0000-000000000000", true); + configMember.addConfigurationOption("estate_manager_7", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, + String.Empty, "00000000-0000-0000-0000-000000000000", true); + configMember.addConfigurationOption("estate_manager_8", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, + String.Empty, "00000000-0000-0000-0000-000000000000", true); + configMember.addConfigurationOption("estate_manager_9", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, + String.Empty, "00000000-0000-0000-0000-000000000000", true); + + } + + public bool handleIncomingConfiguration(string configuration_key, object configuration_result) + { + switch (configuration_key) + { + case "billable_factor": + m_billableFactor = (float) configuration_result; + break; + case "estate_id": + m_estateID = (uint) configuration_result; + break; + case "parent_estate_id": + m_parentEstateID = (uint) configuration_result; + break; + case "max_agents": + m_maxAgents = (byte) configuration_result; + break; + + case "object_bonus_factor": + m_objectBonusFactor = (float) configuration_result; + break; + case "redirect_grid_x": + m_redirectGridX = (int) configuration_result; + break; + case "redirect_grid_y": + m_redirectGridY = (int) configuration_result; + break; + case "region_flags": + m_regionFlags = (Simulator.RegionFlags) ((uint) configuration_result); + break; + case "sim_access": + m_simAccess = (Simulator.SimAccess) ((byte) configuration_result); + break; + case "sun_hour": + m_sunHour = (float) configuration_result; + break; + case "terrain_raise_limit": + m_terrainRaiseLimit = (float) configuration_result; + break; + case "terrain_lower_limit": + m_terrainLowerLimit = (float) configuration_result; + break; + case "use_fixed_sun": + m_useFixedSun = (bool) configuration_result; + break; + case "price_per_meter": + m_pricePerMeter = Convert.ToInt32(configuration_result); + break; + case "region_water_height": + m_regionWaterHeight = (ushort) configuration_result; + break; + case "region_allow_terraform": + m_regionAllowTerraform = (bool) configuration_result; + break; + + case "terrain_base_0": + m_terrainBase0 = (LLUUID) configuration_result; + break; + case "terrain_base_1": + m_terrainBase1 = (LLUUID) configuration_result; + break; + case "terrain_base_2": + m_terrainBase2 = (LLUUID) configuration_result; + break; + case "terrain_base_3": + m_terrainBase3 = (LLUUID) configuration_result; + break; + + case "terrain_detail_0": + m_terrainDetail0 = (LLUUID) configuration_result; + break; + case "terrain_detail_1": + m_terrainDetail1 = (LLUUID) configuration_result; + break; + case "terrain_detail_2": + m_terrainDetail2 = (LLUUID) configuration_result; + break; + case "terrain_detail_3": + m_terrainDetail3 = (LLUUID) configuration_result; + break; + + case "terrain_start_height_0": + m_terrainStartHeight0 = (float) configuration_result; + break; + case "terrain_start_height_1": + m_terrainStartHeight1 = (float) configuration_result; + break; + case "terrain_start_height_2": + m_terrainStartHeight2 = (float) configuration_result; + break; + case "terrain_start_height_3": + m_terrainStartHeight3 = (float) configuration_result; + break; + + case "terrain_height_range_0": + m_terrainHeightRange0 = (float) configuration_result; + break; + case "terrain_height_range_1": + m_terrainHeightRange1 = (float) configuration_result; + break; + case "terrain_height_range_2": + m_terrainHeightRange2 = (float) configuration_result; + break; + case "terrain_height_range_3": + m_terrainHeightRange3 = (float) configuration_result; + break; + + case "terrain_file": + m_terrainFile = (string) configuration_result; + break; + case "terrain_multiplier": + m_terrainMultiplier = Convert.ToDouble(configuration_result); + break; + case "water_height": + double tmpVal = (double) configuration_result; + m_waterHeight = (float) tmpVal; + break; + case "terrain_image_id": + m_terrainImageID = (LLUUID) configuration_result; + break; + + case "estate_manager_0": + m_estateManager0 = (LLUUID)configuration_result; + break; + case "estate_manager_1": + m_estateManager1 = (LLUUID)configuration_result; + break; + case "estate_manager_2": + m_estateManager2 = (LLUUID)configuration_result; + break; + case "estate_manager_3": + m_estateManager3 = (LLUUID)configuration_result; + break; + case "estate_manager_4": + m_estateManager4 = (LLUUID)configuration_result; + break; + case "estate_manager_5": + m_estateManager5 = (LLUUID)configuration_result; + break; + case "estate_manager_6": + m_estateManager6 = (LLUUID)configuration_result; + break; + case "estate_manager_7": + m_estateManager7 = (LLUUID)configuration_result; + break; + case "estate_manager_8": + m_estateManager8 = (LLUUID)configuration_result; + break; + case "estate_manager_9": + m_estateManager9 = (LLUUID)configuration_result; + break; + + } + + return true; + } + } +} diff --git a/OpenSim/Framework/GridConfig.cs b/OpenSim/Framework/GridConfig.cs index 745b86410e..1b5fa859c7 100644 --- a/OpenSim/Framework/GridConfig.cs +++ b/OpenSim/Framework/GridConfig.cs @@ -1,146 +1,149 @@ -/* -* 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. -* -*/ - -namespace OpenSim.Framework -{ - public class GridConfig - { - public string GridOwner = ""; - public string DefaultAssetServer = ""; - public string AssetSendKey = ""; - public string AssetRecvKey = ""; - - public string DefaultUserServer = ""; - public string UserSendKey = ""; - public string UserRecvKey = ""; - - public string SimSendKey = ""; - public string SimRecvKey = ""; - - public string DatabaseProvider = ""; - - - public static uint DefaultHttpPort = 8001; - public uint HttpPort = DefaultHttpPort; - - public string AllowForcefulBanlines = "TRUE"; - - private ConfigurationMember configMember; - - public GridConfig(string description, string filename) - { - configMember = - new ConfigurationMember(filename, description, loadConfigurationOptions, handleIncomingConfiguration, true); - configMember.performConfigurationRetrieve(); - } - - public void loadConfigurationOptions() - { - configMember.addConfigurationOption("grid_owner", - ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, - "OGS Grid Owner", "OGS development team", false); - configMember.addConfigurationOption("default_asset_server", - ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, - "Default Asset Server URI", - "http://127.0.0.1:" + AssetConfig.DefaultHttpPort.ToString() + "/", - false); - configMember.addConfigurationOption("asset_send_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "Key to send to asset server", "null", false); - configMember.addConfigurationOption("asset_recv_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "Key to expect from asset server", "null", false); - - configMember.addConfigurationOption("default_user_server", - ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, - "Default User Server URI", - "http://127.0.0.1:" + UserConfig.DefaultHttpPort.ToString() + "/", false); - configMember.addConfigurationOption("user_send_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "Key to send to user server", "null", false); - configMember.addConfigurationOption("user_recv_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "Key to expect from user server", "null", false); - - configMember.addConfigurationOption("sim_send_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "Key to send to a simulator", "null", false); - configMember.addConfigurationOption("sim_recv_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "Key to expect from a simulator", "null", false); - configMember.addConfigurationOption("database_provider", ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "DLL for database provider", "OpenSim.Framework.Data.MySQL.dll", false); - - configMember.addConfigurationOption("http_port", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, - "Http Listener port", DefaultHttpPort.ToString(), false); - - configMember.addConfigurationOption("allow_forceful_banlines", - ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "Allow Forceful Banlines", "TRUE", true); - } - - public bool handleIncomingConfiguration(string configuration_key, object configuration_result) - { - switch (configuration_key) - { - case "grid_owner": - GridOwner = (string) configuration_result; - break; - case "default_asset_server": - DefaultAssetServer = (string) configuration_result; - break; - case "asset_send_key": - AssetSendKey = (string) configuration_result; - break; - case "asset_recv_key": - AssetRecvKey = (string) configuration_result; - break; - case "default_user_server": - DefaultUserServer = (string) configuration_result; - break; - case "user_send_key": - UserSendKey = (string) configuration_result; - break; - case "user_recv_key": - UserRecvKey = (string) configuration_result; - break; - case "sim_send_key": - SimSendKey = (string) configuration_result; - break; - case "sim_recv_key": - SimRecvKey = (string) configuration_result; - break; - case "database_provider": - DatabaseProvider = (string) configuration_result; - break; - case "http_port": - HttpPort = (uint) configuration_result; - break; - case "allow_forceful_banlines": - AllowForcefulBanlines = (string) configuration_result; - break; - } - - return true; - } - } -} \ No newline at end of file +/* +* 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 OpenSim.Framework.Console; + +namespace OpenSim.Framework +{ + public class GridConfig + { + public string GridOwner = String.Empty; + public string DefaultAssetServer = String.Empty; + public string AssetSendKey = String.Empty; + public string AssetRecvKey = String.Empty; + + public string DefaultUserServer = String.Empty; + public string UserSendKey = String.Empty; + public string UserRecvKey = String.Empty; + + public string SimSendKey = String.Empty; + public string SimRecvKey = String.Empty; + + public string DatabaseProvider = String.Empty; + + + public static uint DefaultHttpPort = 8001; + public uint HttpPort = DefaultHttpPort; + + public string AllowForcefulBanlines = "TRUE"; + + private ConfigurationMember configMember; + + public GridConfig(string description, string filename) + { + configMember = + new ConfigurationMember(filename, description, loadConfigurationOptions, handleIncomingConfiguration, true); + configMember.performConfigurationRetrieve(); + } + + public void loadConfigurationOptions() + { + configMember.addConfigurationOption("grid_owner", + ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "OGS Grid Owner", "OGS development team", false); + configMember.addConfigurationOption("default_asset_server", + ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "Default Asset Server URI", + "http://127.0.0.1:" + AssetConfig.DefaultHttpPort.ToString() + "/", + false); + configMember.addConfigurationOption("asset_send_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "Key to send to asset server", "null", false); + configMember.addConfigurationOption("asset_recv_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "Key to expect from asset server", "null", false); + + configMember.addConfigurationOption("default_user_server", + ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "Default User Server URI", + "http://127.0.0.1:" + UserConfig.DefaultHttpPort.ToString() + "/", false); + configMember.addConfigurationOption("user_send_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "Key to send to user server", "null", false); + configMember.addConfigurationOption("user_recv_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "Key to expect from user server", "null", false); + + configMember.addConfigurationOption("sim_send_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "Key to send to a simulator", "null", false); + configMember.addConfigurationOption("sim_recv_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "Key to expect from a simulator", "null", false); + configMember.addConfigurationOption("database_provider", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "DLL for database provider", "OpenSim.Framework.Data.MySQL.dll", false); + + configMember.addConfigurationOption("http_port", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Http Listener port", DefaultHttpPort.ToString(), false); + + configMember.addConfigurationOption("allow_forceful_banlines", + ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "Allow Forceful Banlines", "TRUE", true); + } + + public bool handleIncomingConfiguration(string configuration_key, object configuration_result) + { + switch (configuration_key) + { + case "grid_owner": + GridOwner = (string) configuration_result; + break; + case "default_asset_server": + DefaultAssetServer = (string) configuration_result; + break; + case "asset_send_key": + AssetSendKey = (string) configuration_result; + break; + case "asset_recv_key": + AssetRecvKey = (string) configuration_result; + break; + case "default_user_server": + DefaultUserServer = (string) configuration_result; + break; + case "user_send_key": + UserSendKey = (string) configuration_result; + break; + case "user_recv_key": + UserRecvKey = (string) configuration_result; + break; + case "sim_send_key": + SimSendKey = (string) configuration_result; + break; + case "sim_recv_key": + SimRecvKey = (string) configuration_result; + break; + case "database_provider": + DatabaseProvider = (string) configuration_result; + break; + case "http_port": + HttpPort = (uint) configuration_result; + break; + case "allow_forceful_banlines": + AllowForcefulBanlines = (string) configuration_result; + break; + } + + return true; + } + } +} diff --git a/OpenSim/Framework/IAssetProvider.cs b/OpenSim/Framework/IAssetProvider.cs index 1cfa469d11..4db8fe49a1 100644 --- a/OpenSim/Framework/IAssetProvider.cs +++ b/OpenSim/Framework/IAssetProvider.cs @@ -1,44 +1,44 @@ -/* -* 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 libsecondlife; -using System.Collections.Generic; // rex added - -namespace OpenSim.Framework -{ - public interface IAssetProvider : IPlugin - { - AssetBase FetchAsset(LLUUID uuid); - void CreateAsset(AssetBase asset); - void UpdateAsset(AssetBase asset); - bool ExistsAsset(LLUUID uuid); - void CommitAssets(); // force a sync to the database - LLUUID ExistsAsset(sbyte type, string name); // rex new function for "replace asset" functionality - List GetAssetList(int vAssetType); // rex, added - } -} \ No newline at end of file +/* +* 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 libsecondlife; +using System.Collections.Generic; // rex added + +namespace OpenSim.Framework +{ + public interface IAssetProvider : IPlugin + { + AssetBase FetchAsset(LLUUID uuid); + void CreateAsset(AssetBase asset); + void UpdateAsset(AssetBase asset); + bool ExistsAsset(LLUUID uuid); + void CommitAssets(); // force a sync to the database + LLUUID ExistsAsset(sbyte type, string name); // rex new function for "replace asset" functionality + List GetAssetList(int vAssetType); // rex, added + } +} diff --git a/OpenSim/Framework/IAssetServer.cs b/OpenSim/Framework/IAssetServer.cs index b5f29c75ff..b673005d53 100644 --- a/OpenSim/Framework/IAssetServer.cs +++ b/OpenSim/Framework/IAssetServer.cs @@ -1,61 +1,71 @@ -/* -* 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.Generic; -using libsecondlife; - -namespace OpenSim.Framework -{ - /// - /// Description of IAssetServer. - /// - public interface IAssetServer - { - void SetReceiver(IAssetReceiver receiver); - void RequestAsset(LLUUID assetID, bool isTexture); - void UpdateAsset(AssetBase asset); - void StoreAndCommitAsset(AssetBase asset); - void Close(); - LLUUID ExistsAsset(sbyte type, string name); // rex new function for "replace asset" functionality - bool ExistsAsset(LLUUID assetID); // rex added - List GetAssetList(int vAssetType); // rex added - AssetBase FetchAsset(LLUUID assetID); // rex added - } - - // could change to delegate? - public interface IAssetReceiver - { - void AssetReceived(AssetBase asset, bool IsTexture); - void AssetNotFound(LLUUID assetID); - } - - public interface IAssetPlugin - { - IAssetServer GetAssetServer(); - } -} \ No newline at end of file +/* +* 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.Generic; +using libsecondlife; + +namespace OpenSim.Framework +{ + /// + /// Description of IAssetServer. + /// + public interface IAssetServer + { + void SetReceiver(IAssetReceiver receiver); + void RequestAsset(LLUUID assetID, bool isTexture); + void UpdateAsset(AssetBase asset); + void StoreAndCommitAsset(AssetBase asset); + void Close(); + LLUUID ExistsAsset(sbyte type, string name); // rex new function for "replace asset" functionality + bool ExistsAsset(LLUUID assetID); // rex added + List GetAssetList(int vAssetType); // rex added + AssetBase FetchAsset(LLUUID assetID); // rex added + } + + // could change to delegate? + public interface IAssetReceiver + { + /// + /// Call back made when a requested asset has been retrieved by an asset server + /// + /// + /// + void AssetReceived(AssetBase asset, bool IsTexture); + + /// + /// Call back made when an asset server could not retrieve a requested asset + /// + /// + void AssetNotFound(LLUUID assetID); + } + + public interface IAssetPlugin + { + IAssetServer GetAssetServer(); + } +} diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 7f79425831..27b6815497 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -1,661 +1,697 @@ -/* -* 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.Generic; -using System.Net; -using libsecondlife; -using libsecondlife.Packets; - -namespace OpenSim.Framework -{ - // Base Args Interface - public interface IEventArgs - { - IScene Scene { get; set; } - - IClientAPI Sender { get; set; } - } - - public delegate void ViewerEffectEventHandler(IClientAPI sender, ViewerEffectPacket.EffectBlock[] effectBlock); - - public delegate void ChatFromViewer(Object sender, ChatFromViewerArgs e); - - public enum ChatTypeEnum - { - Whisper = 0, - Say = 1, - Shout = 2, - // 3 is an obsolete version of Say - StartTyping = 4, - StopTyping = 5, - Broadcast = 0xFF - } - - public enum ThrottleOutPacketType : int - { - Resend = 0, - Land = 1, - Wind = 2, - Cloud = 3, - Task = 4, - Texture = 5, - Asset = 6, - Unknown = 7, - Back = 8 - } - - /// - /// ChatFromViewer Arguments - /// - public class ChatFromViewerArgs : EventArgs, IEventArgs - { - protected string m_message; - protected ChatTypeEnum m_type; - protected int m_channel; - protected LLVector3 m_position; - protected string m_from; - - protected IClientAPI m_sender; - protected IScene m_scene; - - /// - /// The message sent by the user - /// - public string Message - { - get { return m_message; } - set { m_message = value; } - } - - /// - /// The type of message, eg say, shout, broadcast. - /// - public ChatTypeEnum Type - { - get { return m_type; } - set { m_type = value; } - } - - /// - /// Which channel was this message sent on? Different channels may have different listeners. Public chat is on channel zero. - /// - public int Channel - { - get { return m_channel; } - set { m_channel = value; } - } - - /// - /// The position of the sender at the time of the message broadcast. - /// - public LLVector3 Position - { - get { return m_position; } - set { m_position = value; } - } - - /// - /// The name of the sender (needed for scripts) - /// - public string From - { - get { return m_from; } - set { m_from = value; } - } - - /// - /// The client responsible for sending the message, or null. - /// - public IClientAPI Sender - { - get { return m_sender; } - set { m_sender = value; } - } - - /// - /// - /// - public IScene Scene - { - get { return m_scene; } - set { m_scene = value; } - } - - public ChatFromViewerArgs() - { - m_position = new LLVector3(); - } - } - - public class TextureRequestArgs : EventArgs - { - protected LLUUID m_requestedAssetID; - private sbyte m_discardLevel; - private uint m_packetNumber; - private float m_priority; - - public float Priority - { - get { return m_priority; } - set { m_priority = value; } - } - - /// - /// - /// - public uint PacketNumber - { - get { return m_packetNumber; } - set { m_packetNumber = value; } - } - - /// - /// - /// - public sbyte DiscardLevel - { - get { return m_discardLevel; } - set { m_discardLevel = value; } - } - - /// - /// - /// - public LLUUID RequestedAssetID - { - get { return m_requestedAssetID; } - set { m_requestedAssetID = value; } - } - } - - public class AvatarWearingArgs : EventArgs - { - private List m_nowWearing = new List(); - - /// - /// - /// - public List NowWearing - { - get { return m_nowWearing; } - set { m_nowWearing = value; } - } - - public class Wearable - { - public LLUUID ItemID = new LLUUID("00000000-0000-0000-0000-000000000000"); - public byte Type = 0; - - public Wearable(LLUUID itemId, byte type) - { - ItemID = itemId; - Type = type; - } - } - } - - public delegate void TextureRequest(Object sender, TextureRequestArgs e); - - public delegate void AvatarNowWearing(Object sender, AvatarWearingArgs e); - - public delegate void ImprovedInstantMessage(IClientAPI remoteclient, - LLUUID fromAgentID, LLUUID fromAgentSession, LLUUID toAgentID, LLUUID imSessionID, uint timestamp, - string fromAgentName, string message, byte dialog, bool fromGroup, byte offline, uint ParentEstateID, - LLVector3 Position, LLUUID RegionID, byte[] binaryBucket); // This shouldn't be cut down... - // especially if we're ever going to implement groups, presence, estate message dialogs... - - public delegate void RezObject(IClientAPI remoteClient, LLUUID itemID, LLVector3 RayEnd, LLVector3 RayStart, - LLUUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, - uint EveryoneMask, uint GroupMask, uint NextOwnerMask, uint ItemFlags, - bool RezSelected, bool RemoveItem, LLUUID fromTaskID ); - - public delegate void ModifyTerrain( - float height, float seconds, byte size, byte action, float north, float west, float south, float east, - IClientAPI remoteClient); - - public delegate void SetAppearance(byte[] texture, AgentSetAppearancePacket.VisualParamBlock[] visualParam); - - public delegate void StartAnim(IClientAPI remoteClient, LLUUID animID, int seq); - - public delegate void StopAnim(IClientAPI remoteClient, LLUUID animID); - - public delegate void LinkObjects(uint parent, List children); - - public delegate void DelinkObjects(List primIds); - - public delegate void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY); - - public delegate void RequestMapName(IClientAPI remoteClient, string mapName); - - public delegate void TeleportLocationRequest( - IClientAPI remoteClient, ulong regionHandle, LLVector3 position, LLVector3 lookAt, uint flags); - - public delegate void DisconnectUser(); - - public delegate void RequestAvatarProperties(IClientAPI remoteClient, LLUUID avatarID); - - public delegate void SetAlwaysRun(IClientAPI remoteClient, bool SetAlwaysRun); - - public delegate void GenericCall2(); - - // really don't want to be passing packets in these events, so this is very temporary. - public delegate void GenericCall4(Packet packet, IClientAPI remoteClient); - - public delegate void GenericCall5(IClientAPI remoteClient, bool status); - - public delegate void GenericCall7(IClientAPI remoteClient, uint localID, string message); - - public delegate void UpdateShape(LLUUID agentID, uint localID, ObjectShapePacket.ObjectDataBlock shapeBlock); - - public delegate void ObjectExtraParams(LLUUID agentID, uint localID, ushort type, bool inUse, byte[] data); - - public delegate void ObjectSelect(uint localID, IClientAPI remoteClient); - - public delegate void RequestObjectPropertiesFamily( - IClientAPI remoteClient, LLUUID AgentID, uint RequestFlags, LLUUID TaskID); - - public delegate void ObjectDeselect(uint localID, IClientAPI remoteClient); - - public delegate void UpdatePrimFlags(uint localID, Packet packet, IClientAPI remoteClient); - - public delegate void UpdatePrimTexture(uint localID, byte[] texture, IClientAPI remoteClient); - - public delegate void UpdateVector(uint localID, LLVector3 pos, IClientAPI remoteClient); - - public delegate void UpdatePrimRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient); - - public delegate void UpdatePrimSingleRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient); - - public delegate void UpdatePrimGroupRotation(uint localID, LLVector3 pos, LLQuaternion rot, IClientAPI remoteClient); - - public delegate void ObjectDuplicate(uint localID, LLVector3 offset, uint dupeFlags, LLUUID AgentID, LLUUID GroupID); - - public delegate void StatusChange(bool status); - - public delegate void NewAvatar(IClientAPI remoteClient, LLUUID agentID, bool status); - - public delegate void UpdateAgent(IClientAPI remoteClient, AgentUpdatePacket agentData); - - public delegate void AgentRequestSit(IClientAPI remoteClient, LLUUID agentID, LLUUID targetID, LLVector3 offset); - - public delegate void AgentSit(IClientAPI remoteClient, LLUUID agentID); - - public delegate void AvatarPickerRequest(IClientAPI remoteClient, LLUUID agentdata, LLUUID queryID, string UserQuery - ); - - public delegate void MoveObject(LLUUID objectID, LLVector3 offset, LLVector3 grapPos, IClientAPI remoteClient); - - public delegate void ParcelAccessListRequest( - LLUUID agentID, LLUUID sessionID, uint flags, int sequenceID, int landLocalID, IClientAPI remote_client); - - public delegate void ParcelAccessListUpdateRequest( - LLUUID agentID, LLUUID sessionID, uint flags, int landLocalID, List entries, - IClientAPI remote_client); - - public delegate void ParcelPropertiesRequest( - int start_x, int start_y, int end_x, int end_y, int sequence_id, bool snap_selection, IClientAPI remote_client); - - public delegate void ParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client); - - public delegate void ParcelJoinRequest(int west, int south, int east, int north, IClientAPI remote_client); - - public delegate void ParcelPropertiesUpdateRequest(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client); - - public delegate void ParcelSelectObjects(int land_local_id, int request_type, IClientAPI remote_client); - - public delegate void ParcelObjectOwnerRequest(int local_id, IClientAPI remote_client); - - public delegate void EstateOwnerMessageRequest(EstateOwnerMessagePacket packet, IClientAPI remote_client); - - public delegate void RegionInfoRequest(IClientAPI remote_client, LLUUID sessionID); - - public delegate void EstateCovenantRequest(IClientAPI remote_client, LLUUID sessionID); - - public delegate void UUIDNameRequest(LLUUID id, IClientAPI remote_client); - - public delegate void AddNewPrim(LLUUID ownerID, LLVector3 RayEnd, LLQuaternion rot, PrimitiveBaseShape shape, byte bypassRaycast, LLVector3 RayStart, LLUUID RayTargetID, byte RayEndIsIntersection); - - public delegate void RequestGodlikePowers(LLUUID AgentID, LLUUID SessionID, LLUUID token, IClientAPI remote_client); - - public delegate void GodKickUser( - LLUUID GodAgentID, LLUUID GodSessionID, LLUUID AgentID, uint kickflags, byte[] reason); - - public delegate void CreateInventoryFolder( - IClientAPI remoteClient, LLUUID folderID, ushort folderType, string folderName, LLUUID parentID); - - public delegate void UpdateInventoryFolder( - IClientAPI remoteClient, LLUUID folderID, ushort type, string name, LLUUID parentID); - - public delegate void MoveInventoryFolder( - IClientAPI remoteClient, LLUUID folderID, LLUUID parentID); - - public delegate void CreateNewInventoryItem( - IClientAPI remoteClient, LLUUID transActionID, LLUUID folderID, uint callbackID, string description, string name, - sbyte invType, sbyte type, byte wearableType, uint nextOwnerMask); - - public delegate void FetchInventoryDescendents( - IClientAPI remoteClient, LLUUID folderID, LLUUID ownerID, bool fetchFolders, bool fetchItems, int sortOrder); - - public delegate void PurgeInventoryDescendents( - IClientAPI remoteClient, LLUUID folderID); - - public delegate void FetchInventory(IClientAPI remoteClient, LLUUID itemID, LLUUID ownerID); - - public delegate void RequestTaskInventory(IClientAPI remoteClient, uint localID); - - public delegate void UpdateInventoryItem( - IClientAPI remoteClient, LLUUID transactionID, LLUUID itemID, string name, string description, - uint nextOwnerMask); - - public delegate void CopyInventoryItem( - IClientAPI remoteClient, uint callbackID, LLUUID oldAgentID, LLUUID oldItemID, LLUUID newFolderID, - string newName); - - public delegate void MoveInventoryItem( - IClientAPI remoteClient, LLUUID folderID, LLUUID itemID, int length, string newName); - - public delegate void RemoveInventoryItem( - IClientAPI remoteClient, LLUUID itemID); // rex - - public delegate void RezScript(IClientAPI remoteClient, LLUUID itemID, uint localID); - - public delegate void UpdateTaskInventory(IClientAPI remoteClient, LLUUID itemID, LLUUID folderID, uint localID); - - public delegate void RemoveTaskInventory(IClientAPI remoteClient, LLUUID itemID, uint localID); - - public delegate void UDPAssetUploadRequest( - IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data, bool storeLocal, - bool tempFile); - - public delegate void XferReceive(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data); - - public delegate void RequestXfer(IClientAPI remoteClient, ulong xferID, string fileName); - - public delegate void ConfirmXfer(IClientAPI remoteClient, ulong xferID, uint packetID); - - public delegate void FriendActionDelegate(IClientAPI remoteClient,LLUUID agentID,LLUUID transactionID,List callingCardFolders); - - public delegate void FriendshipTermination(IClientAPI remoteClient,LLUUID agentID, LLUUID ExID); - - public delegate void ReceiveRexClientScriptCmd(IClientAPI remoteClient,LLUUID agentID,List vParams); // rex - - //Attachments - public delegate void RezSingleAttachmentFromInv(IClientAPI remoteClient, LLUUID itemID, LLUUID ownerID, - uint itemFlags, byte attachPoint); - public delegate void ObjectAttach(IClientAPI remoteClient, uint localID, LLQuaternion rotation, byte attachPoint); - public delegate void ObjectDetach(IClientAPI remoteClient, uint localID); - - - // REX - public delegate void UpdateAssetMediaURL(IClientAPI remoteClient, LLUUID itemID, string mediaUrl); - - // REX - public delegate void ObjectClickAction(IClientAPI remoteClient, uint objectLocalId, byte clickAction); - - public delegate void TriggerSound(IClientAPI remoteClient, LLUUID soundID, LLUUID ownerID, LLUUID objectID, LLUUID parentID, ulong handle, LLVector3 position, float gain); - - - public delegate void ObjectPermissions( - IClientAPI remoteClinet, LLUUID AgentID, LLUUID SessionID, - List permChanges); - - public interface IClientAPI - { - event ImprovedInstantMessage OnInstantMessage; - event ChatFromViewer OnChatFromViewer; - event TextureRequest OnRequestTexture; - event RezObject OnRezObject; - event ModifyTerrain OnModifyTerrain; - event SetAppearance OnSetAppearance; - event AvatarNowWearing OnAvatarNowWearing; - event StartAnim OnStartAnim; - event StopAnim OnStopAnim; - event LinkObjects OnLinkObjects; - event DelinkObjects OnDelinkObjects; - event RequestMapBlocks OnRequestMapBlocks; - event RequestMapName OnMapNameRequest; - event TeleportLocationRequest OnTeleportLocationRequest; - event DisconnectUser OnDisconnectUser; - event RequestAvatarProperties OnRequestAvatarProperties; - event SetAlwaysRun OnSetAlwaysRun; - event GenericCall4 OnDeRezObject; - event Action OnRegionHandShakeReply; - event GenericCall2 OnRequestWearables; - event GenericCall2 OnCompleteMovementToRegion; - event UpdateAgent OnAgentUpdate; - event AgentRequestSit OnAgentRequestSit; - event AgentSit OnAgentSit; - event AvatarPickerRequest OnAvatarPickerRequest; - event Action OnRequestAvatarsData; - event AddNewPrim OnAddPrim; - - event RequestGodlikePowers OnRequestGodlikePowers; - event GodKickUser OnGodKickUser; - - event ObjectDuplicate OnObjectDuplicate; - event UpdateVector OnGrabObject; - event ObjectSelect OnDeGrabObject; - event MoveObject OnGrabUpdate; - - event UpdateShape OnUpdatePrimShape; - event ObjectExtraParams OnUpdateExtraParams; - event ObjectSelect OnObjectSelect; - event ObjectDeselect OnObjectDeselect; - event GenericCall7 OnObjectDescription; - event GenericCall7 OnObjectName; - event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; - event UpdatePrimFlags OnUpdatePrimFlags; - event UpdatePrimTexture OnUpdatePrimTexture; - event UpdateVector OnUpdatePrimGroupPosition; - event UpdateVector OnUpdatePrimSinglePosition; - event UpdatePrimRotation OnUpdatePrimGroupRotation; - event UpdatePrimSingleRotation OnUpdatePrimSingleRotation; - event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation; - event UpdateVector OnUpdatePrimScale; - event StatusChange OnChildAgentStatus; - event GenericCall2 OnStopMovement; - event Action OnRemoveAvatar; - event ObjectPermissions OnObjectPermissions; - - event CreateNewInventoryItem OnCreateNewInventoryItem; - event CreateInventoryFolder OnCreateNewInventoryFolder; - event UpdateInventoryFolder OnUpdateInventoryFolder; - event MoveInventoryFolder OnMoveInventoryFolder; - event FetchInventoryDescendents OnFetchInventoryDescendents; - event PurgeInventoryDescendents OnPurgeInventoryDescendents; - event FetchInventory OnFetchInventory; - event RequestTaskInventory OnRequestTaskInventory; - event UpdateInventoryItem OnUpdateInventoryItem; - event CopyInventoryItem OnCopyInventoryItem; - event MoveInventoryItem OnMoveInventoryItem; - event RemoveInventoryItem OnRemoveInventoryItem; // rex - event UDPAssetUploadRequest OnAssetUploadRequest; - event XferReceive OnXferReceive; - event RequestXfer OnRequestXfer; - event ConfirmXfer OnConfirmXfer; - event RezScript OnRezScript; - event UpdateTaskInventory OnUpdateTaskInventory; - event RemoveTaskInventory OnRemoveTaskItem; - - event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; - event ObjectAttach OnObjectAttach; - event ObjectDetach OnObjectDetach; - - event UUIDNameRequest OnNameFromUUIDRequest; - - event ParcelAccessListRequest OnParcelAccessListRequest; - event ParcelAccessListUpdateRequest OnParcelAccessListUpdateRequest; - event ParcelPropertiesRequest OnParcelPropertiesRequest; - event ParcelDivideRequest OnParcelDivideRequest; - event ParcelJoinRequest OnParcelJoinRequest; - event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest; - event ParcelSelectObjects OnParcelSelectObjects; - event ParcelObjectOwnerRequest OnParcelObjectOwnerRequest; - event EstateOwnerMessageRequest OnEstateOwnerMessage; - event RegionInfoRequest OnRegionInfoRequest; - event EstateCovenantRequest OnEstateCovenantRequest; - - event FriendActionDelegate OnApproveFriendRequest; - event FriendActionDelegate OnDenyFriendRequest; - event FriendshipTermination OnTerminateFriendship; - - event ReceiveRexClientScriptCmd OnReceiveRexClientScriptCmd; // rex - event ObjectClickAction OnObjectClickAction; // rex - event UpdateAssetMediaURL OnUpdateAssetMediaURL; // rex - event TriggerSound OnTriggerSound; - - LLVector3 StartPos { get; set; } - - LLUUID AgentId { get; } - - LLUUID SessionId { get; } - - LLUUID SecureSessionId { get; } - - string FirstName { get; } - - string LastName { get; } - - /// - /// Returns the full name of the agent/avatar represented by this client - /// - /// - /// - string Name { get; } - - uint CircuitCode { get; } - - void OutPacket(Packet newPack, ThrottleOutPacketType packType); - void SendWearables(AvatarWearable[] wearables, int serial); - void SendAppearance(LLUUID agentID, byte[] visualParams, byte[] textureEntry); - void SendRexAppearance(LLUUID agentID, string avatarAddress); // rex - void SendRexScriptCommand(string vUnit,string vCommand, string vCmdParams); // rex - void SendStartPingCheck(byte seq); - void SendKillObject(ulong regionHandle, uint localID); - void SendAnimations(LLUUID[] animID, int[] seqs, LLUUID sourceAgentId); - void SendRegionHandshake(RegionInfo regionInfo); - void SendChatMessage(string message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID); - void SendChatMessage(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID); - - void SendInstantMessage(LLUUID fromAgent, LLUUID fromAgentSession, string message, LLUUID toAgent, - LLUUID imSessionID, string fromName, byte dialog, uint timeStamp); - - void SendLayerData(float[] map); - void SendLayerData(int px, int py, float[] map); - - void SendMediaURL(LLUUID assetId, string mediaURL); //rex - - void MoveAgentIntoRegion(RegionInfo regInfo, LLVector3 pos, LLVector3 look); - void InformClientOfNeighbour(ulong neighbourHandle, IPEndPoint neighbourExternalEndPoint); - AgentCircuitData RequestClientInfo(); - - void CrossRegion(ulong newRegionHandle, LLVector3 pos, LLVector3 lookAt, IPEndPoint newRegionExternalEndPoint, - string capsURL); - - void SendMapBlock(List mapBlocks); - void SendLocalTeleport(LLVector3 position, LLVector3 lookAt, uint flags); - - void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint, uint locationID, - uint flags, string capsURL); - - void SendTeleportFailed(); - void SendTeleportLocationStart(); - void SendMoneyBalance(LLUUID transaction, bool success, byte[] description, int balance); - - void SendAvatarData(ulong regionHandle, string firstName, string lastName, LLUUID avatarID, uint avatarLocalID, - LLVector3 Pos, byte[] textureEntry, uint parentID); - - void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, - LLVector3 velocity, LLQuaternion rotation); - - void SendCoarseLocationUpdate(List CoarseLocations); - - void AttachObject(uint localID, LLQuaternion rotation, byte attachPoint); - void SetChildAgentThrottle(byte[] throttle); - - void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, - LLVector3 pos, uint flags, LLUUID objectID, LLUUID ownerID, string text, byte[] color, - uint parentID, byte[] particleSystem, LLQuaternion rotation, byte clickAction); - - void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, - LLQuaternion rotation); - - void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, - LLQuaternion rotation, LLVector3 velocity, LLVector3 rotationalvelocity); - - void SendInventoryFolderDetails(LLUUID ownerID, LLUUID folderID, List items, - List folders, bool fetchFolders, - bool fetchItems); - - void SendInventoryItemDetails(LLUUID ownerID, InventoryItemBase item); - - /// - /// Tell the client that we have created the item it requested. - /// - /// - void SendInventoryItemCreateUpdate(InventoryItemBase Item); - - void SendRemoveInventoryItem(LLUUID itemID); - void SendTaskInventory(LLUUID taskID, short serial, byte[] fileName); - void SendXferPacket(ulong xferID, uint packet, byte[] data); - void SendAvatarPickerReply(AvatarPickerReplyPacket Pack); - - void SendPreLoadSound(LLUUID objectID, LLUUID ownerID, LLUUID soundID); - void SendPlayAttachedSound(LLUUID soundID, LLUUID objectID, LLUUID ownerID, float gain, byte flags); - void SendTriggeredSound(LLUUID soundID, LLUUID ownerID, LLUUID objectID, LLUUID parentID, ulong handle, LLVector3 position, float gain); - - void SendNameReply(LLUUID profileId, string firstname, string lastname); - void SendAlertMessage(string message); - - void SendAgentAlertMessage(string message, bool modal); - void SendLoadURL(string objectname, LLUUID objectID, LLUUID ownerID, bool groupOwned, string message, string url); - void SendDialog(string objectname, LLUUID objectID, LLUUID ownerID, string msg, LLUUID textureID, int ch, string[] buttonlabels); - bool AddMoney(int debit); - - void SendSunPos(LLVector3 sunPos, LLVector3 sunVel); - void SendViewerTime(int phase); - - void SendAvatarProperties(LLUUID avatarID, string aboutText, string bornOn, string charterMember, string flAbout, - uint flags, LLUUID flImageID, LLUUID imageID, string profileURL, LLUUID partnerID); - - void SendScriptTeleportRequest(string objectName, string simName, LLVector3 simPosition, LLVector3 lookAt); - - void SetDebug(int newDebug); - void InPacket(Packet NewPack); - void Close(bool ShutdownCircuit); - void Kick(string message); - void Stop(); - event ViewerEffectEventHandler OnViewerEffect; - event Action OnLogout; - event Action OnConnectionClosed; - - void SendBlueBoxMessage(LLUUID FromAvatarID, LLUUID fromSessionID, String FromAvatarName, String Message); - - void SendLogoutPacket(); - } -} +/* +* 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.Generic; +using System.Net; +using libsecondlife; +using libsecondlife.Packets; + +namespace OpenSim.Framework +{ + // Base Args Interface + public interface IEventArgs + { + IScene Scene { get; set; } + + IClientAPI Sender { get; set; } + } + + public delegate void ViewerEffectEventHandler(IClientAPI sender, ViewerEffectPacket.EffectBlock[] effectBlock); + + public delegate void ChatFromViewer(Object sender, ChatFromViewerArgs e); + + public enum ChatTypeEnum + { + Whisper = 0, + Say = 1, + Shout = 2, + // 3 is an obsolete version of Say + StartTyping = 4, + StopTyping = 5, + Broadcast = 0xFF + } + + public enum ThrottleOutPacketType : int + { + Resend = 0, + Land = 1, + Wind = 2, + Cloud = 3, + Task = 4, + Texture = 5, + Asset = 6, + Unknown = 7, // Also doubles as 'do not throttle' + Back = 8 + } + + /// + /// ChatFromViewer Arguments + /// + public class ChatFromViewerArgs : EventArgs, IEventArgs + { + protected string m_message; + protected ChatTypeEnum m_type; + protected int m_channel; + protected LLVector3 m_position; + protected string m_from; + + protected IClientAPI m_sender; + protected IScene m_scene; + + /// + /// The message sent by the user + /// + public string Message + { + get { return m_message; } + set { m_message = value; } + } + + /// + /// The type of message, eg say, shout, broadcast. + /// + public ChatTypeEnum Type + { + get { return m_type; } + set { m_type = value; } + } + + /// + /// Which channel was this message sent on? Different channels may have different listeners. Public chat is on channel zero. + /// + public int Channel + { + get { return m_channel; } + set { m_channel = value; } + } + + /// + /// The position of the sender at the time of the message broadcast. + /// + public LLVector3 Position + { + get { return m_position; } + set { m_position = value; } + } + + /// + /// The name of the sender (needed for scripts) + /// + public string From + { + get { return m_from; } + set { m_from = value; } + } + + /// + /// The client responsible for sending the message, or null. + /// + public IClientAPI Sender + { + get { return m_sender; } + set { m_sender = value; } + } + + /// + /// + /// + public IScene Scene + { + get { return m_scene; } + set { m_scene = value; } + } + + public ChatFromViewerArgs() + { + m_position = new LLVector3(); + } + } + + public class TextureRequestArgs : EventArgs + { + protected LLUUID m_requestedAssetID; + private sbyte m_discardLevel; + private uint m_packetNumber; + private float m_priority; + + public float Priority + { + get { return m_priority; } + set { m_priority = value; } + } + + /// + /// + /// + public uint PacketNumber + { + get { return m_packetNumber; } + set { m_packetNumber = value; } + } + + /// + /// + /// + public sbyte DiscardLevel + { + get { return m_discardLevel; } + set { m_discardLevel = value; } + } + + /// + /// + /// + public LLUUID RequestedAssetID + { + get { return m_requestedAssetID; } + set { m_requestedAssetID = value; } + } + } + + public class AvatarWearingArgs : EventArgs + { + private List m_nowWearing = new List(); + + /// + /// + /// + public List NowWearing + { + get { return m_nowWearing; } + set { m_nowWearing = value; } + } + + public class Wearable + { + public LLUUID ItemID = new LLUUID("00000000-0000-0000-0000-000000000000"); + public byte Type = 0; + + public Wearable(LLUUID itemId, byte type) + { + ItemID = itemId; + Type = type; + } + } + } + + public delegate void TextureRequest(Object sender, TextureRequestArgs e); + + public delegate void AvatarNowWearing(Object sender, AvatarWearingArgs e); + + public delegate void ImprovedInstantMessage(IClientAPI remoteclient, + LLUUID fromAgentID, LLUUID fromAgentSession, LLUUID toAgentID, LLUUID imSessionID, uint timestamp, + string fromAgentName, string message, byte dialog, bool fromGroup, byte offline, uint ParentEstateID, + LLVector3 Position, LLUUID RegionID, byte[] binaryBucket); // This shouldn't be cut down... + // especially if we're ever going to implement groups, presence, estate message dialogs... + + public delegate void RezObject(IClientAPI remoteClient, LLUUID itemID, LLVector3 RayEnd, LLVector3 RayStart, + LLUUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, + uint EveryoneMask, uint GroupMask, uint NextOwnerMask, uint ItemFlags, + bool RezSelected, bool RemoveItem, LLUUID fromTaskID ); + + public delegate void RezSingleAttachmentFromInv(IClientAPI remoteClient, LLUUID itemID, uint AttachmentPt, + uint ItemFlags, uint NextOwnerMask); + + public delegate void ObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, LLQuaternion rot); + + public delegate void ModifyTerrain( + float height, float seconds, byte size, byte action, float north, float west, float south, float east, + IClientAPI remoteClient); + + public delegate void SetAppearance(byte[] texture, AgentSetAppearancePacket.VisualParamBlock[] visualParam); + + public delegate void StartAnim(IClientAPI remoteClient, LLUUID animID, int seq); + + public delegate void StopAnim(IClientAPI remoteClient, LLUUID animID); + + public delegate void LinkObjects(uint parent, List children); + + public delegate void DelinkObjects(List primIds); + + public delegate void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY); + + public delegate void RequestMapName(IClientAPI remoteClient, string mapName); + + public delegate void TeleportLocationRequest( + IClientAPI remoteClient, ulong regionHandle, LLVector3 position, LLVector3 lookAt, uint flags); + + public delegate void DisconnectUser(); + + public delegate void RequestAvatarProperties(IClientAPI remoteClient, LLUUID avatarID); + + public delegate void SetAlwaysRun(IClientAPI remoteClient, bool SetAlwaysRun); + + public delegate void GenericCall2(); + + // really don't want to be passing packets in these events, so this is very temporary. + public delegate void GenericCall4(Packet packet, IClientAPI remoteClient); + + public delegate void GenericCall5(IClientAPI remoteClient, bool status); + + public delegate void GenericCall7(IClientAPI remoteClient, uint localID, string message); + + public delegate void UpdateShape(LLUUID agentID, uint localID, ObjectShapePacket.ObjectDataBlock shapeBlock); + + public delegate void ObjectExtraParams(LLUUID agentID, uint localID, ushort type, bool inUse, byte[] data); + + public delegate void ObjectSelect(uint localID, IClientAPI remoteClient); + + public delegate void RequestObjectPropertiesFamily( + IClientAPI remoteClient, LLUUID AgentID, uint RequestFlags, LLUUID TaskID); + + public delegate void ObjectDeselect(uint localID, IClientAPI remoteClient); + + public delegate void UpdatePrimFlags(uint localID, Packet packet, IClientAPI remoteClient); + + public delegate void UpdatePrimTexture(uint localID, byte[] texture, IClientAPI remoteClient); + + public delegate void UpdateVector(uint localID, LLVector3 pos, IClientAPI remoteClient); + + public delegate void UpdatePrimRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient); + + public delegate void UpdatePrimSingleRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient); + + public delegate void UpdatePrimGroupRotation(uint localID, LLVector3 pos, LLQuaternion rot, IClientAPI remoteClient); + + public delegate void ObjectDuplicate(uint localID, LLVector3 offset, uint dupeFlags, LLUUID AgentID, LLUUID GroupID); + + public delegate void StatusChange(bool status); + + public delegate void NewAvatar(IClientAPI remoteClient, LLUUID agentID, bool status); + + public delegate void UpdateAgent(IClientAPI remoteClient, AgentUpdatePacket agentData); + + public delegate void AgentRequestSit(IClientAPI remoteClient, LLUUID agentID, LLUUID targetID, LLVector3 offset); + + public delegate void AgentSit(IClientAPI remoteClient, LLUUID agentID); + + public delegate void AvatarPickerRequest(IClientAPI remoteClient, LLUUID agentdata, LLUUID queryID, string UserQuery + ); + + public delegate void MoveObject(LLUUID objectID, LLVector3 offset, LLVector3 grapPos, IClientAPI remoteClient); + + public delegate void ParcelAccessListRequest( + LLUUID agentID, LLUUID sessionID, uint flags, int sequenceID, int landLocalID, IClientAPI remote_client); + + public delegate void ParcelAccessListUpdateRequest( + LLUUID agentID, LLUUID sessionID, uint flags, int landLocalID, List entries, + IClientAPI remote_client); + + public delegate void ParcelPropertiesRequest( + int start_x, int start_y, int end_x, int end_y, int sequence_id, bool snap_selection, IClientAPI remote_client); + + public delegate void ParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client); + + public delegate void ParcelJoinRequest(int west, int south, int east, int north, IClientAPI remote_client); + + public delegate void ParcelPropertiesUpdateRequest(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client); + + public delegate void ParcelSelectObjects(int land_local_id, int request_type, IClientAPI remote_client); + + public delegate void ParcelObjectOwnerRequest(int local_id, IClientAPI remote_client); + + public delegate void EstateOwnerMessageRequest(EstateOwnerMessagePacket packet, IClientAPI remote_client); + + public delegate void RegionInfoRequest(IClientAPI remote_client, LLUUID sessionID); + + public delegate void EstateCovenantRequest(IClientAPI remote_client, LLUUID sessionID); + + public delegate void UUIDNameRequest(LLUUID id, IClientAPI remote_client); + + public delegate void AddNewPrim(LLUUID ownerID, LLVector3 RayEnd, LLQuaternion rot, PrimitiveBaseShape shape, byte bypassRaycast, LLVector3 RayStart, LLUUID RayTargetID, byte RayEndIsIntersection); + + public delegate void RequestGodlikePowers(LLUUID AgentID, LLUUID SessionID, LLUUID token, IClientAPI remote_client); + + public delegate void GodKickUser( + LLUUID GodAgentID, LLUUID GodSessionID, LLUUID AgentID, uint kickflags, byte[] reason); + + public delegate void CreateInventoryFolder( + IClientAPI remoteClient, LLUUID folderID, ushort folderType, string folderName, LLUUID parentID); + + public delegate void UpdateInventoryFolder( + IClientAPI remoteClient, LLUUID folderID, ushort type, string name, LLUUID parentID); + + public delegate void MoveInventoryFolder( + IClientAPI remoteClient, LLUUID folderID, LLUUID parentID); + + public delegate void CreateNewInventoryItem( + IClientAPI remoteClient, LLUUID transActionID, LLUUID folderID, uint callbackID, string description, string name, + sbyte invType, sbyte type, byte wearableType, uint nextOwnerMask); + + public delegate void FetchInventoryDescendents( + IClientAPI remoteClient, LLUUID folderID, LLUUID ownerID, bool fetchFolders, bool fetchItems, int sortOrder); + + public delegate void PurgeInventoryDescendents( + IClientAPI remoteClient, LLUUID folderID); + + public delegate void FetchInventory(IClientAPI remoteClient, LLUUID itemID, LLUUID ownerID); + + public delegate void RequestTaskInventory(IClientAPI remoteClient, uint localID); + + public delegate void UpdateInventoryItem( + IClientAPI remoteClient, LLUUID transactionID, LLUUID itemID, string name, string description, + uint nextOwnerMask); + + public delegate void CopyInventoryItem( + IClientAPI remoteClient, uint callbackID, LLUUID oldAgentID, LLUUID oldItemID, LLUUID newFolderID, + string newName); + + public delegate void MoveInventoryItem( + IClientAPI remoteClient, LLUUID folderID, LLUUID itemID, int length, string newName); + + public delegate void RemoveInventoryItem( + IClientAPI remoteClient, LLUUID itemID); + + public delegate void RemoveInventoryFolder( + IClientAPI remoteClient, LLUUID folderID); + + public delegate void RezScript(IClientAPI remoteClient, LLUUID itemID, uint localID); + + public delegate void UpdateTaskInventory(IClientAPI remoteClient, LLUUID itemID, LLUUID folderID, uint localID); + + public delegate void RemoveTaskInventory(IClientAPI remoteClient, LLUUID itemID, uint localID); + + public delegate void UDPAssetUploadRequest( + IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data, bool storeLocal, + bool tempFile); + + public delegate void XferReceive(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data); + + public delegate void RequestXfer(IClientAPI remoteClient, ulong xferID, string fileName); + + public delegate void ConfirmXfer(IClientAPI remoteClient, ulong xferID, uint packetID); + + public delegate void FriendActionDelegate(IClientAPI remoteClient,LLUUID agentID,LLUUID transactionID,List callingCardFolders); + + public delegate void FriendshipTermination(IClientAPI remoteClient,LLUUID agentID, LLUUID ExID); + + public delegate void ReceiveRexClientScriptCmd(IClientAPI remoteClient,LLUUID agentID,List vParams); // rex + public delegate void PacketStats(int inPackets, int outPackets, int unAckedBytes); + + public delegate void MoneyTransferRequest(LLUUID sourceID, LLUUID destID, int amount, int transactionType, string description); + + // We keep all this information for fraud purposes in the future. + public delegate void MoneyBalanceRequest(IClientAPI remoteClient, LLUUID agentID, LLUUID sessionID, LLUUID TransactionID); + + public delegate void ObjectPermissions(IClientAPI controller, LLUUID agentID, LLUUID sessionID, byte field, uint localId, uint mask, byte set); + //Attachments + public delegate void RezSingleAttachmentFromInv(IClientAPI remoteClient, LLUUID itemID, LLUUID ownerID, + uint itemFlags, byte attachPoint); + public delegate void ObjectAttach(IClientAPI remoteClient, uint localID, LLQuaternion rotation, byte attachPoint); + public delegate void ObjectDetach(IClientAPI remoteClient, uint localID); + + + // REX + public delegate void UpdateAssetMediaURL(IClientAPI remoteClient, LLUUID itemID, string mediaUrl); + + // REX + public delegate void ObjectClickAction(IClientAPI remoteClient, uint objectLocalId, byte clickAction); + + public delegate void TriggerSound(IClientAPI remoteClient, LLUUID soundID, LLUUID ownerID, LLUUID objectID, LLUUID parentID, ulong handle, LLVector3 position, float gain); + + + public delegate void ObjectPermissions( + IClientAPI remoteClinet, LLUUID AgentID, LLUUID SessionID, + List permChanges); + + public interface IClientAPI + { + event ImprovedInstantMessage OnInstantMessage; + event ChatFromViewer OnChatFromViewer; + event TextureRequest OnRequestTexture; + event RezObject OnRezObject; + event ModifyTerrain OnModifyTerrain; + event SetAppearance OnSetAppearance; + event AvatarNowWearing OnAvatarNowWearing; + event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; + event ObjectAttach OnObjectAttach; + event StartAnim OnStartAnim; + event StopAnim OnStopAnim; + event LinkObjects OnLinkObjects; + event DelinkObjects OnDelinkObjects; + event RequestMapBlocks OnRequestMapBlocks; + event RequestMapName OnMapNameRequest; + event TeleportLocationRequest OnTeleportLocationRequest; + event DisconnectUser OnDisconnectUser; + event RequestAvatarProperties OnRequestAvatarProperties; + event SetAlwaysRun OnSetAlwaysRun; + event GenericCall4 OnDeRezObject; + event Action OnRegionHandShakeReply; + event GenericCall2 OnRequestWearables; + event GenericCall2 OnCompleteMovementToRegion; + event UpdateAgent OnAgentUpdate; + event AgentRequestSit OnAgentRequestSit; + event AgentSit OnAgentSit; + event AvatarPickerRequest OnAvatarPickerRequest; + event Action OnRequestAvatarsData; + event AddNewPrim OnAddPrim; + + event FetchInventory OnAgentDataUpdateRequest; + event FetchInventory OnUserInfoRequest; + event TeleportLocationRequest OnSetStartLocationRequest; + + event RequestGodlikePowers OnRequestGodlikePowers; + event GodKickUser OnGodKickUser; + + event ObjectDuplicate OnObjectDuplicate; + event UpdateVector OnGrabObject; + event ObjectSelect OnDeGrabObject; + event MoveObject OnGrabUpdate; + + event UpdateShape OnUpdatePrimShape; + event ObjectExtraParams OnUpdateExtraParams; + event ObjectSelect OnObjectSelect; + event ObjectDeselect OnObjectDeselect; + event GenericCall7 OnObjectDescription; + event GenericCall7 OnObjectName; + event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; + event UpdatePrimFlags OnUpdatePrimFlags; + event UpdatePrimTexture OnUpdatePrimTexture; + event UpdateVector OnUpdatePrimGroupPosition; + event UpdateVector OnUpdatePrimSinglePosition; + event UpdatePrimRotation OnUpdatePrimGroupRotation; + event UpdatePrimSingleRotation OnUpdatePrimSingleRotation; + event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation; + event UpdateVector OnUpdatePrimScale; + event StatusChange OnChildAgentStatus; + event GenericCall2 OnStopMovement; + event Action OnRemoveAvatar; + event ObjectPermissions OnObjectPermissions; + + event CreateNewInventoryItem OnCreateNewInventoryItem; + event CreateInventoryFolder OnCreateNewInventoryFolder; + event UpdateInventoryFolder OnUpdateInventoryFolder; + event MoveInventoryFolder OnMoveInventoryFolder; + event FetchInventoryDescendents OnFetchInventoryDescendents; + event PurgeInventoryDescendents OnPurgeInventoryDescendents; + event FetchInventory OnFetchInventory; + event RequestTaskInventory OnRequestTaskInventory; + event UpdateInventoryItem OnUpdateInventoryItem; + event CopyInventoryItem OnCopyInventoryItem; + event MoveInventoryItem OnMoveInventoryItem; + event RemoveInventoryFolder OnRemoveInventoryFolder; + event RemoveInventoryItem OnRemoveInventoryItem; + event UDPAssetUploadRequest OnAssetUploadRequest; + event XferReceive OnXferReceive; + event RequestXfer OnRequestXfer; + event ConfirmXfer OnConfirmXfer; + event RezScript OnRezScript; + event UpdateTaskInventory OnUpdateTaskInventory; + event RemoveTaskInventory OnRemoveTaskItem; + + event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; + event ObjectAttach OnObjectAttach; + event ObjectDetach OnObjectDetach; + + event UUIDNameRequest OnNameFromUUIDRequest; + + event ParcelAccessListRequest OnParcelAccessListRequest; + event ParcelAccessListUpdateRequest OnParcelAccessListUpdateRequest; + event ParcelPropertiesRequest OnParcelPropertiesRequest; + event ParcelDivideRequest OnParcelDivideRequest; + event ParcelJoinRequest OnParcelJoinRequest; + event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest; + event ParcelSelectObjects OnParcelSelectObjects; + event ParcelObjectOwnerRequest OnParcelObjectOwnerRequest; + event EstateOwnerMessageRequest OnEstateOwnerMessage; + event RegionInfoRequest OnRegionInfoRequest; + event EstateCovenantRequest OnEstateCovenantRequest; + + event FriendActionDelegate OnApproveFriendRequest; + event FriendActionDelegate OnDenyFriendRequest; + event FriendshipTermination OnTerminateFriendship; + event PacketStats OnPacketStats; + + // Financial packets + event MoneyTransferRequest OnMoneyTransferRequest; + + event MoneyBalanceRequest OnMoneyBalanceRequest; + + event ReceiveRexClientScriptCmd OnReceiveRexClientScriptCmd; // rex + event ObjectClickAction OnObjectClickAction; // rex + event UpdateAssetMediaURL OnUpdateAssetMediaURL; // rex + event TriggerSound OnTriggerSound; + + LLVector3 StartPos { get; set; } + + LLUUID AgentId { get; } + + LLUUID SessionId { get; } + + LLUUID SecureSessionId { get; } + + string FirstName { get; } + + string LastName { get; } + + /// + /// Returns the full name of the agent/avatar represented by this client + /// + /// + /// + string Name { get; } + + uint CircuitCode { get; } + + void OutPacket(Packet newPack, ThrottleOutPacketType packType); + void SendWearables(AvatarWearable[] wearables, int serial); + void SendAppearance(LLUUID agentID, byte[] visualParams, byte[] textureEntry); + void SendRexAppearance(LLUUID agentID, string avatarAddress); // rex + void SendRexScriptCommand(string vUnit,string vCommand, string vCmdParams); // rex + void SendStartPingCheck(byte seq); + void SendKillObject(ulong regionHandle, uint localID); + void SendAnimations(LLUUID[] animID, int[] seqs, LLUUID sourceAgentId); + void SendRegionHandshake(RegionInfo regionInfo); + void SendChatMessage(string message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID); + void SendChatMessage(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID); + + void SendInstantMessage(LLUUID fromAgent, LLUUID fromAgentSession, string message, LLUUID toAgent, + LLUUID imSessionID, string fromName, byte dialog, uint timeStamp); + + void SendLayerData(float[] map); + void SendLayerData(int px, int py, float[] map); + + void SendMediaURL(LLUUID assetId, string mediaURL); //rex + + void MoveAgentIntoRegion(RegionInfo regInfo, LLVector3 pos, LLVector3 look); + void InformClientOfNeighbour(ulong neighbourHandle, IPEndPoint neighbourExternalEndPoint); + AgentCircuitData RequestClientInfo(); + + void CrossRegion(ulong newRegionHandle, LLVector3 pos, LLVector3 lookAt, IPEndPoint newRegionExternalEndPoint, + string capsURL); + + void SendMapBlock(List mapBlocks); + void SendLocalTeleport(LLVector3 position, LLVector3 lookAt, uint flags); + + void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint, uint locationID, + uint flags, string capsURL); + + void SendTeleportFailed(string reason); + void SendTeleportLocationStart(); + void SendMoneyBalance(LLUUID transaction, bool success, byte[] description, int balance); + + void SendAvatarData(ulong regionHandle, string firstName, string lastName, LLUUID avatarID, uint avatarLocalID, + LLVector3 Pos, byte[] textureEntry, uint parentID); + + void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, + LLVector3 velocity, LLQuaternion rotation); + + void SendCoarseLocationUpdate(List CoarseLocations); + + void AttachObject(uint localID, LLQuaternion rotation, byte attachPoint); + void SetChildAgentThrottle(byte[] throttle); + + void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, + LLVector3 pos, uint flags, LLUUID objectID, LLUUID ownerID, string text, byte[] color, + uint parentID, byte[] particleSystem, LLQuaternion rotation, byte clickAction, byte[] textureanimation); + + void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, + LLVector3 pos, uint flags, LLUUID objectID, LLUUID ownerID, string text, byte[] color, + uint parentID, byte[] particleSystem, LLQuaternion rotation, byte clickAction); + + void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, + LLQuaternion rotation); + + void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, + LLQuaternion rotation, LLVector3 velocity, LLVector3 rotationalvelocity); + + void SendInventoryFolderDetails(LLUUID ownerID, LLUUID folderID, List items, + List folders, bool fetchFolders, + bool fetchItems); + + void SendInventoryItemDetails(LLUUID ownerID, InventoryItemBase item); + + /// + /// Tell the client that we have created the item it requested. + /// + /// + void SendInventoryItemCreateUpdate(InventoryItemBase Item); + + void SendRemoveInventoryItem(LLUUID itemID); + void SendTaskInventory(LLUUID taskID, short serial, byte[] fileName); + void SendXferPacket(ulong xferID, uint packet, byte[] data); + void SendAvatarPickerReply(AvatarPickerReplyPacket Pack); + + void SendAgentDataUpdate(LLUUID agentid, LLUUID activegroupid, string firstname, string lastname, ulong grouppowers, string groupname, string grouptitle); + + void SendPreLoadSound(LLUUID objectID, LLUUID ownerID, LLUUID soundID); + void SendPlayAttachedSound(LLUUID soundID, LLUUID objectID, LLUUID ownerID, float gain, byte flags); + void SendTriggeredSound(LLUUID soundID, LLUUID ownerID, LLUUID objectID, LLUUID parentID, ulong handle, LLVector3 position, float gain); + + void SendNameReply(LLUUID profileId, string firstname, string lastname); + void SendAlertMessage(string message); + + void SendAgentAlertMessage(string message, bool modal); + void SendLoadURL(string objectname, LLUUID objectID, LLUUID ownerID, bool groupOwned, string message, string url); + void SendDialog(string objectname, LLUUID objectID, LLUUID ownerID, string msg, LLUUID textureID, int ch, string[] buttonlabels); + bool AddMoney(int debit); + + void SendSunPos(LLVector3 sunPos, LLVector3 sunVel); + void SendViewerTime(int phase); + + void SendAvatarProperties(LLUUID avatarID, string aboutText, string bornOn, string charterMember, string flAbout, + uint flags, LLUUID flImageID, LLUUID imageID, string profileURL, LLUUID partnerID); + + byte[] GetThrottlesPacked(float multiplier); + + void SendScriptTeleportRequest(string objectName, string simName, LLVector3 simPosition, LLVector3 lookAt); + + void SetDebug(int newDebug); + void InPacket(Packet NewPack); + void Close(bool ShutdownCircuit); + void Kick(string message); + void Stop(); + event ViewerEffectEventHandler OnViewerEffect; + event Action OnLogout; + event Action OnConnectionClosed; + + void SendBlueBoxMessage(LLUUID FromAvatarID, LLUUID fromSessionID, String FromAvatarName, String Message); + + void SendLogoutPacket(); + } +} diff --git a/OpenSim/Framework/IPlugin.cs b/OpenSim/Framework/IPlugin.cs index cc835daa99..9728d95325 100644 --- a/OpenSim/Framework/IPlugin.cs +++ b/OpenSim/Framework/IPlugin.cs @@ -1,53 +1,53 @@ -/* -* 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. -* -*/ - -namespace OpenSim.Framework -{ - /// - /// This interface, describes a generic plugin - /// - public interface IPlugin - { - /// - /// Returns the plugin version - /// - /// Plugin version in MAJOR.MINOR.REVISION.BUILD format - string Version { get; } - - /// - /// Returns the plugin name - /// - /// Plugin name, eg MySQL User Provider - string Name { get; } - - /// - /// Initialises the plugin (artificial constructor) - /// - void Initialise(); - } -} \ No newline at end of file +/* +* 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. +* +*/ + +namespace OpenSim.Framework +{ + /// + /// This interface, describes a generic plugin + /// + public interface IPlugin + { + /// + /// Returns the plugin version + /// + /// Plugin version in MAJOR.MINOR.REVISION.BUILD format + string Version { get; } + + /// + /// Returns the plugin name + /// + /// Plugin name, eg MySQL User Provider + string Name { get; } + + /// + /// Initialises the plugin (artificial constructor) + /// + void Initialise(); + } +} diff --git a/OpenSim/Framework/IRegionCommsListener.cs b/OpenSim/Framework/IRegionCommsListener.cs index ff81d21d27..7658caa171 100644 --- a/OpenSim/Framework/IRegionCommsListener.cs +++ b/OpenSim/Framework/IRegionCommsListener.cs @@ -1,68 +1,71 @@ -/* -* 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.Collections.Generic; -using libsecondlife; - -namespace OpenSim.Framework -{ - public delegate void ExpectUserDelegate(ulong regionHandle, AgentCircuitData agent); - - public delegate void ExpectPrimDelegate(ulong regionHandle, LLUUID primID, string objData); - - public delegate void UpdateNeighbours(List neighbours); - - public delegate void AgentCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying); - - public delegate void PrimCrossing(ulong regionHandle, LLUUID primID, LLVector3 position, bool isPhysical); - - public delegate void AcknowledgeAgentCross(ulong regionHandle, LLUUID agentID); - - public delegate void AcknowledgePrimCross(ulong regionHandle, LLUUID PrimID); - - public delegate void CloseAgentConnection(ulong regionHandle, LLUUID agentID); - - public delegate bool RegionUp(RegionInfo region); - - public delegate bool ChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData); - - - public interface IRegionCommsListener - { - event ExpectUserDelegate OnExpectUser; - event ExpectPrimDelegate OnExpectPrim; - event GenericCall2 OnExpectChildAgent; - event AgentCrossing OnAvatarCrossingIntoRegion; - event PrimCrossing OnPrimCrossingIntoRegion; - event AcknowledgeAgentCross OnAcknowledgeAgentCrossed; - event AcknowledgePrimCross OnAcknowledgePrimCrossed; - event UpdateNeighbours OnNeighboursUpdate; - event CloseAgentConnection OnCloseAgentConnection; - event RegionUp OnRegionUp; - event ChildAgentUpdate OnChildAgentUpdate; - } -} \ No newline at end of file +/* +* 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.Collections.Generic; +using libsecondlife; + +namespace OpenSim.Framework +{ + public delegate void ExpectUserDelegate(ulong regionHandle, AgentCircuitData agent); + + public delegate void ExpectPrimDelegate(ulong regionHandle, LLUUID primID, string objData); + + public delegate void UpdateNeighbours(List neighbours); + + public delegate void AgentCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying); + + public delegate void PrimCrossing(ulong regionHandle, LLUUID primID, LLVector3 position, bool isPhysical); + + public delegate void AcknowledgeAgentCross(ulong regionHandle, LLUUID agentID); + + public delegate void AcknowledgePrimCross(ulong regionHandle, LLUUID PrimID); + + public delegate bool CloseAgentConnection(ulong regionHandle, LLUUID agentID); + + public delegate bool RegionUp(RegionInfo region); + + public delegate bool ChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData); + + + + + public interface IRegionCommsListener + { + event ExpectUserDelegate OnExpectUser; + event ExpectPrimDelegate OnExpectPrim; + event GenericCall2 OnExpectChildAgent; + event AgentCrossing OnAvatarCrossingIntoRegion; + event PrimCrossing OnPrimCrossingIntoRegion; + event AcknowledgeAgentCross OnAcknowledgeAgentCrossed; + event AcknowledgePrimCross OnAcknowledgePrimCrossed; + event UpdateNeighbours OnNeighboursUpdate; + event CloseAgentConnection OnCloseAgentConnection; + event RegionUp OnRegionUp; + event ChildAgentUpdate OnChildAgentUpdate; + + } +} diff --git a/OpenSim/Framework/IScene.cs b/OpenSim/Framework/IScene.cs index 7db0ec238a..991a3767c7 100644 --- a/OpenSim/Framework/IScene.cs +++ b/OpenSim/Framework/IScene.cs @@ -1,67 +1,69 @@ -/* -* 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 libsecondlife; - -namespace OpenSim.Framework -{ - public delegate void restart(RegionInfo thisRegion); - - //public delegate void regionup ( RegionInfo thisRegion ); - - public enum RegionStatus : int - { - Down = 0, - Up = 1, - Crashed = 2, - Starting = 3 - } ; - - public interface IScene - { - event restart OnRestart; - - void AddNewClient(IClientAPI client, bool child); - void RemoveClient(LLUUID agentID); - void RemoveClient(LLUUID agentID, uint circuitCode); - void CloseAllAgents(uint circuitcode); - - void Restart(int seconds); - bool OtherRegionUp(RegionInfo thisRegion); - - RegionInfo RegionInfo { get; } - uint NextLocalId { get; } - - bool PresenceChildStatus(LLUUID avatarID); - - RegionStatus Region_Status { get; set; } - - ClientManager ClientManager { get; } - - bool RexMode { get; set; }//rex - } -} \ No newline at end of file +/* +* 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 libsecondlife; + +namespace OpenSim.Framework +{ + public delegate void restart(RegionInfo thisRegion); + + //public delegate void regionup ( RegionInfo thisRegion ); + + public enum RegionStatus : int + { + Down = 0, + Up = 1, + Crashed = 2, + Starting = 3 + } ; + + public interface IScene + { + event restart OnRestart; + + void AddNewClient(IClientAPI client, bool child); + void RemoveClient(LLUUID agentID); + void RemoveClient(LLUUID agentID, uint circuitCode); + void CloseAllAgents(uint circuitcode); + + void Restart(int seconds); + bool OtherRegionUp(RegionInfo thisRegion); + + string GetSimulatorVersion(); + + RegionInfo RegionInfo { get; } + uint NextLocalId { get; } + + bool PresenceChildStatus(LLUUID avatarID); + + RegionStatus Region_Status { get; set; } + + ClientManager ClientManager { get; } + + bool RexMode { get; set; }//rex + } +} diff --git a/OpenSim/Framework/IUserData.cs b/OpenSim/Framework/IUserData.cs index b8a2b43cb8..77f8f5e149 100644 --- a/OpenSim/Framework/IUserData.cs +++ b/OpenSim/Framework/IUserData.cs @@ -1,195 +1,195 @@ -/* -* 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.Collections.Generic; -using libsecondlife; - -namespace OpenSim.Framework -{ - /// - /// An interface for connecting to user storage servers. - /// - public interface IUserData - { - /// - /// Returns a user profile from a database via their UUID - /// - /// The user's UUID - /// The user data profile. Returns null if no user is found - UserProfileData GetUserByUUID(LLUUID user); - - /// - /// Returns a user profile from a database via their account - /// - /// The account - /// The user data profile - UserProfileData GetUserByAccount(string account); - - /// - /// Returns a users profile by searching their username parts - /// - /// Account firstname - /// Account lastname - /// The user data profile - UserProfileData GetUserByName(string fname, string lname); - - /// - /// Returns a list of UUIDs firstnames and lastnames that match string query entered into the avatar picker. - /// - /// ID associated with the user's query. This must match what the client sent - /// The filtered contents of the search box when the user hit search. - /// The user data profile - List GeneratePickerResults(LLUUID queryID, string query); - - /// - /// Returns the current agent for a user searching by it's UUID - /// - /// The users UUID - /// The current agent session - UserAgentData GetAgentByUUID(LLUUID user); - - /// - /// Returns the current session agent for a user searching by username - /// - /// The users account name - /// The current agent session - UserAgentData GetAgentByName(string name); - - /// - /// Returns the current session agent for a user searching by username parts - /// - /// The users first account name - /// The users account surname - /// The current agent session - UserAgentData GetAgentByName(string fname, string lname); - - /// - /// Adds a new User profile to the database - /// - /// UserProfile to add - void AddNewUserProfile(UserProfileData user); - - /// - /// Updates an existing user profile - /// - /// UserProfile to update - bool UpdateUserProfile(UserProfileData user); - - /// - /// Updates the current region the User is in - /// - /// User Region the Avatar is IN - /// User Region the Avatar is IN - void UpdateUserCurrentRegion(LLUUID avatarid, LLUUID regionuuid); - - /// - /// Log User Off - /// - /// avatar to log off - void LogOffUser(LLUUID avatarid); - - /// - /// Adds a new agent to the database - /// - /// The agent to add - void AddNewUserAgent(UserAgentData agent); - - /// - /// Adds a new friend to the database for XUser - /// - /// The agent that who's friends list is being added to - /// The agent that being added to the friends list of the friends list owner - /// A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects - void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms); - - /// - /// Delete friend on friendlistowner's friendlist. - /// - /// The agent that who's friends list is being updated - /// The Ex-friend agent - void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend); - - /// - /// Update permissions for friend on friendlistowner's friendlist. - /// - /// The agent that who's friends list is being updated - /// The agent that is getting or loosing permissions - /// A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects - void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms); - - /// - /// Returns a list of FriendsListItems that describe the friends and permissions in the friend relationship for LLUUID friendslistowner - /// - /// The agent that we're retreiving the friends Data. - List GetUserFriendList(LLUUID friendlistowner); - /// - /// Attempts to move currency units between accounts (NOT RELIABLE / TRUSTWORTHY. DONT TRY RUN YOUR OWN CURRENCY EXCHANGE WITH REAL VALUES) - /// - /// The account to transfer from - /// The account to transfer to - /// The amount to transfer - /// Successful? - bool MoneyTransferRequest(LLUUID from, LLUUID to, uint amount); - - /// - /// Attempts to move inventory between accounts, if inventory is copyable it will be copied into the target account. - /// - /// User to transfer from - /// User to transfer to - /// Specified inventory item - /// Successful? - bool InventoryTransferRequest(LLUUID from, LLUUID to, LLUUID inventory); - - /// - /// Returns the plugin version - /// - /// Plugin version in MAJOR.MINOR.REVISION.BUILD format - string GetVersion(); - - /// - /// Returns the plugin name - /// - /// Plugin name, eg MySQL User Provider - string getName(); - - /// - /// Initialises the plugin (artificial constructor) - /// - void Initialise(); - } - - public class AvatarPickerAvatar - { - public LLUUID AvatarID; - public string firstName; - public string lastName; - - public AvatarPickerAvatar() - { - } - } -} \ No newline at end of file +/* +* 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.Collections.Generic; +using libsecondlife; + +namespace OpenSim.Framework +{ + /// + /// An interface for connecting to user storage servers. + /// + public interface IUserData + { + /// + /// Returns a user profile from a database via their UUID + /// + /// The user's UUID + /// The user data profile. Returns null if no user is found + UserProfileData GetUserByUUID(LLUUID user); + + /// + /// Returns a user profile from a database via their account + /// + /// The account + /// The user data profile + UserProfileData GetUserByAccount(string account); + + /// + /// Returns a users profile by searching their username parts + /// + /// Account firstname + /// Account lastname + /// The user data profile + UserProfileData GetUserByName(string fname, string lname); + + /// + /// Returns a list of UUIDs firstnames and lastnames that match string query entered into the avatar picker. + /// + /// ID associated with the user's query. This must match what the client sent + /// The filtered contents of the search box when the user hit search. + /// The user data profile + List GeneratePickerResults(LLUUID queryID, string query); + + /// + /// Returns the current agent for a user searching by it's UUID + /// + /// The users UUID + /// The current agent session + UserAgentData GetAgentByUUID(LLUUID user); + + /// + /// Returns the current session agent for a user searching by username + /// + /// The users account name + /// The current agent session + UserAgentData GetAgentByName(string name); + + /// + /// Returns the current session agent for a user searching by username parts + /// + /// The users first account name + /// The users account surname + /// The current agent session + UserAgentData GetAgentByName(string fname, string lname); + + /// + /// Stores new web-login key for user during web page login + /// + /// + void StoreWebLoginKey(LLUUID agentID, LLUUID webLoginKey); + + /// + /// Adds a new User profile to the database + /// + /// UserProfile to add + void AddNewUserProfile(UserProfileData user); + + /// + /// Updates an existing user profile + /// + /// UserProfile to update + bool UpdateUserProfile(UserProfileData user); + + /// + /// Updates the current region the User is in + /// + /// User Region the Avatar is IN + /// User Region the Avatar is IN + void UpdateUserCurrentRegion(LLUUID avatarid, LLUUID regionuuid); + + /// + /// Adds a new agent to the database + /// + /// The agent to add + void AddNewUserAgent(UserAgentData agent); + + /// + /// Adds a new friend to the database for XUser + /// + /// The agent that who's friends list is being added to + /// The agent that being added to the friends list of the friends list owner + /// A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects + void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms); + + /// + /// Delete friend on friendlistowner's friendlist. + /// + /// The agent that who's friends list is being updated + /// The Ex-friend agent + void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend); + + /// + /// Update permissions for friend on friendlistowner's friendlist. + /// + /// The agent that who's friends list is being updated + /// The agent that is getting or loosing permissions + /// A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects + void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms); + + /// + /// Returns a list of FriendsListItems that describe the friends and permissions in the friend relationship for LLUUID friendslistowner + /// + /// The agent that we're retreiving the friends Data. + List GetUserFriendList(LLUUID friendlistowner); + /// + /// Attempts to move currency units between accounts (NOT RELIABLE / TRUSTWORTHY. DONT TRY RUN YOUR OWN CURRENCY EXCHANGE WITH REAL VALUES) + /// + /// The account to transfer from + /// The account to transfer to + /// The amount to transfer + /// Successful? + bool MoneyTransferRequest(LLUUID from, LLUUID to, uint amount); + + /// + /// Attempts to move inventory between accounts, if inventory is copyable it will be copied into the target account. + /// + /// User to transfer from + /// User to transfer to + /// Specified inventory item + /// Successful? + bool InventoryTransferRequest(LLUUID from, LLUUID to, LLUUID inventory); + + /// + /// Returns the plugin version + /// + /// Plugin version in MAJOR.MINOR.REVISION.BUILD format + string GetVersion(); + + /// + /// Returns the plugin name + /// + /// Plugin name, eg MySQL User Provider + string getName(); + + /// + /// Initialises the plugin (artificial constructor) + /// + void Initialise(); + } + + public class AvatarPickerAvatar + { + public LLUUID AvatarID; + public string firstName; + public string lastName; + + public AvatarPickerAvatar() + { + } + } +} diff --git a/OpenSim/Framework/IUserService.cs b/OpenSim/Framework/IUserService.cs index 9fca4fc520..2f5df2e1f6 100644 --- a/OpenSim/Framework/IUserService.cs +++ b/OpenSim/Framework/IUserService.cs @@ -1,88 +1,99 @@ -/* -* 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.Collections.Generic; -using libsecondlife; - -namespace OpenSim.Framework -{ - public interface IUserService - { - UserProfileData GetUserProfile(string firstName, string lastName, string authAddr); - UserProfileData GetUserProfile(string firstName, string authAddr); // must differentiate this from GetUserProfile call - //UserProfileData GetUserProfile(string name); - UserProfileData GetUserProfileByAccount(string account); - UserProfileData GetUserProfile(LLUUID userId, string authAddr); - void clearUserAgent(LLUUID avatarID, string authAddr); - void UpdateUserAgentData(LLUUID agentId, bool agentOnline, LLVector3 currentPos, int logoutTime, string authAddr); - - - List GenerateAgentPickerRequestResponse(LLUUID QueryID, string Query); - - UserProfileData SetupMasterUser(string firstName, string lastName); - UserProfileData SetupMasterUser(string firstName, string lastName, string password); - UserProfileData SetupMasterUser(LLUUID userId); - - bool AuthenticateUser(LLUUID agentID, string sessionhash, out string asAddress);//rex - - /// - /// - /// - /// - LLUUID AddUserProfile(string firstName, string lastName, string pass, uint regX, uint regY); - - - /// - /// Adds a new friend to the database for XUser - /// - /// The agent that who's friends list is being added to - /// The agent that being added to the friends list of the friends list owner - /// A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects - void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms); - - /// - /// Delete friend on friendlistowner's friendlist. - /// - /// The agent that who's friends list is being updated - /// The Ex-friend agent - void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend); - - /// - /// Update permissions for friend on friendlistowner's friendlist. - /// - /// The agent that who's friends list is being updated - /// The agent that is getting or loosing permissions - /// A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects - void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms); - - /// - /// Returns a list of FriendsListItems that describe the friends and permissions in the friend relationship for LLUUID friendslistowner - /// - /// The agent that we're retreiving the friends Data. - List GetUserFriendList(LLUUID friendlistowner); - } -} \ No newline at end of file +/* +* 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.Collections.Generic; +using libsecondlife; + +namespace OpenSim.Framework +{ + public interface IUserService + { + UserProfileData GetUserProfile(string firstName, string lastName, string authAddr); + UserProfileData GetUserProfile(string firstName, string authAddr); // must differentiate this from GetUserProfile call + + //UserProfileData GetUserProfile(string name); + UserProfileData GetUserProfileByAccount(string account); + UserProfileData GetUserProfile(LLUUID userId, string authAddr); + void clearUserAgent(LLUUID avatarID, string authAddr); + void UpdateUserAgentData(LLUUID agentId, bool agentOnline, LLVector3 currentPos, int logoutTime, string authAddr); + + + List GenerateAgentPickerRequestResponse(LLUUID QueryID, string Query); + + UserProfileData SetupMasterUser(string firstName, string lastName); + UserProfileData SetupMasterUser(string firstName, string lastName, string password); + UserProfileData SetupMasterUser(LLUUID userId); + + bool AuthenticateUser(LLUUID agentID, string sessionhash, out string asAddress);//rex + + /// + /// + /// + /// + LLUUID AddUserProfile(string firstName, string lastName, string pass, uint regX, uint regY); + + + /// + /// Adds a new friend to the database for XUser + /// + /// The agent that who's friends list is being added to + /// The agent that being added to the friends list of the friends list owner + /// A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects + void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms); + + /// + /// Delete friend on friendlistowner's friendlist. + /// + /// The agent that who's friends list is being updated + /// The Ex-friend agent + void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend); + + /// + /// Update permissions for friend on friendlistowner's friendlist. + /// + /// The agent that who's friends list is being updated + /// The agent that is getting or loosing permissions + /// A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects + void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms); + + /// + /// Logs off a user on the user server + /// + /// UUID of the user + /// UUID of the Region + /// final position x + /// final position y + /// final position z + void LogOffUser(LLUUID userid, LLUUID regionid, ulong regionhandle, float posx, float posy, float posz); + + /// + /// Returns a list of FriendsListItems that describe the friends and permissions in the friend relationship for LLUUID friendslistowner + /// + /// The agent that we're retreiving the friends Data. + List GetUserFriendList(LLUUID friendlistowner); + } +} diff --git a/OpenSim/Framework/InventoryConfig.cs b/OpenSim/Framework/InventoryConfig.cs index 04951f6893..2df3af54cb 100644 --- a/OpenSim/Framework/InventoryConfig.cs +++ b/OpenSim/Framework/InventoryConfig.cs @@ -1,101 +1,103 @@ -/* -* 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. -* -*/ - -namespace OpenSim.Framework -{ - /// - /// UserConfig -- For User Server Configuration - /// - public class InventoryConfig - { - public string DefaultStartupMsg = ""; - public string UserServerURL = ""; - public string UserSendKey = ""; - public string UserRecvKey = ""; - - public string DatabaseProvider = ""; - public static uint DefaultHttpPort = 8004; - - public uint HttpPort = DefaultHttpPort; - - private ConfigurationMember configMember; - - public InventoryConfig(string description, string filename) - { - configMember = - new ConfigurationMember(filename, description, loadConfigurationOptions, handleIncomingConfiguration, true); - configMember.performConfigurationRetrieve(); - } - - public void loadConfigurationOptions() - { - configMember.addConfigurationOption("default_startup_message", - ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, - "Default Startup Message", "Welcome to OGS", false); - configMember.addConfigurationOption("default_user_server", - ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, - "Default User Server URI", - "http://127.0.0.1:" + UserConfig.DefaultHttpPort.ToString(), false); - configMember.addConfigurationOption("user_send_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "Key to send to user server", "null", false); - configMember.addConfigurationOption("user_recv_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "Key to expect from user server", "null", false); - configMember.addConfigurationOption("database_provider", ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "DLL for database provider", "OpenSim.Framework.Data.SQLite.dll", false); - configMember.addConfigurationOption("http_port", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, - "Http Listener port", DefaultHttpPort.ToString(), false); - } - - public bool handleIncomingConfiguration(string configuration_key, object configuration_result) - { - switch (configuration_key) - { - case "default_startup_message": - DefaultStartupMsg = (string) configuration_result; - break; - case "default_user_server": - UserServerURL = (string) configuration_result; - break; - case "user_send_key": - UserSendKey = (string) configuration_result; - break; - case "user_recv_key": - UserRecvKey = (string) configuration_result; - break; - case "database_provider": - DatabaseProvider = (string) configuration_result; - break; - case "http_port": - HttpPort = (uint) configuration_result; - break; - } - - return true; - } - } -} \ No newline at end of file +/* +* 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 OpenSim.Framework.Console; + +namespace OpenSim.Framework +{ + /// + /// UserConfig -- For User Server Configuration + /// + public class InventoryConfig + { + public string DefaultStartupMsg = System.String.Empty; + public string UserServerURL = System.String.Empty; + public string UserSendKey = System.String.Empty; + public string UserRecvKey = System.String.Empty; + + public string DatabaseProvider = System.String.Empty; + public static uint DefaultHttpPort = 8004; + + public uint HttpPort = DefaultHttpPort; + + private ConfigurationMember configMember; + + public InventoryConfig(string description, string filename) + { + configMember = + new ConfigurationMember(filename, description, loadConfigurationOptions, handleIncomingConfiguration, true); + configMember.performConfigurationRetrieve(); + } + + public void loadConfigurationOptions() + { + configMember.addConfigurationOption("default_startup_message", + ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "Default Startup Message", "Welcome to OGS", false); + configMember.addConfigurationOption("default_user_server", + ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "Default User Server URI", + "http://127.0.0.1:" + UserConfig.DefaultHttpPort.ToString(), false); + configMember.addConfigurationOption("user_send_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "Key to send to user server", "null", false); + configMember.addConfigurationOption("user_recv_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "Key to expect from user server", "null", false); + configMember.addConfigurationOption("database_provider", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "DLL for database provider", "OpenSim.Framework.Data.SQLite.dll", false); + configMember.addConfigurationOption("http_port", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Http Listener port", DefaultHttpPort.ToString(), false); + } + + public bool handleIncomingConfiguration(string configuration_key, object configuration_result) + { + switch (configuration_key) + { + case "default_startup_message": + DefaultStartupMsg = (string) configuration_result; + break; + case "default_user_server": + UserServerURL = (string) configuration_result; + break; + case "user_send_key": + UserSendKey = (string) configuration_result; + break; + case "user_recv_key": + UserRecvKey = (string) configuration_result; + break; + case "database_provider": + DatabaseProvider = (string) configuration_result; + break; + case "http_port": + HttpPort = (uint) configuration_result; + break; + } + + return true; + } + } +} diff --git a/OpenSim/Framework/LandData.cs b/OpenSim/Framework/LandData.cs index 038efd1be6..586c7b626e 100644 --- a/OpenSim/Framework/LandData.cs +++ b/OpenSim/Framework/LandData.cs @@ -1,137 +1,138 @@ -/* -* 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.Collections.Generic; -using libsecondlife; - -namespace OpenSim.Framework -{ - public class LandData - { - public byte[] landBitmapByteArray = new byte[512]; - public string landName = "Your Parcel"; - public string landDesc = ""; - public LLUUID ownerID = LLUUID.Zero; - public bool isGroupOwned = false; - public LLVector3 AABBMin = new LLVector3(); - public LLVector3 AABBMax = new LLVector3(); - public int area = 0; - public uint auctionID = 0; //Unemplemented. If set to 0, not being auctioned - public LLUUID authBuyerID = LLUUID.Zero; //Unemplemented. Authorized Buyer's UUID - public Parcel.ParcelCategory category = new Parcel.ParcelCategory(); //Unemplemented. Parcel's chosen category - public int claimDate = 0; //Unemplemented - public int claimPrice = 0; //Unemplemented - public LLUUID groupID = LLUUID.Zero; //Unemplemented - public int groupPrims = 0; - public int otherPrims = 0; - public int ownerPrims = 0; - public int selectedPrims = 0; - public int simwidePrims = 0; - public int simwideArea = 0; - public int salePrice = 0; //Unemeplemented. Parcels price. - public Parcel.ParcelStatus landStatus = Parcel.ParcelStatus.Leased; - - public uint landFlags = (uint) Parcel.ParcelFlags.AllowFly | (uint) Parcel.ParcelFlags.AllowLandmark | - (uint) Parcel.ParcelFlags.AllowAllObjectEntry | - (uint) Parcel.ParcelFlags.AllowDeedToGroup | (uint) Parcel.ParcelFlags.AllowTerraform | - (uint) Parcel.ParcelFlags.CreateObjects | (uint) Parcel.ParcelFlags.AllowOtherScripts | - (uint) Parcel.ParcelFlags.SoundLocal; - - public byte landingType = 0; - public byte mediaAutoScale = 0; - public LLUUID mediaID = LLUUID.Zero; - public int localID = 0; - public LLUUID globalID = LLUUID.Zero; - - public string mediaURL = ""; - public string musicURL = ""; - public float passHours = 0; - public int passPrice = 0; - public LLUUID snapshotID = LLUUID.Zero; - public LLVector3 userLocation = new LLVector3(); - public LLVector3 userLookAt = new LLVector3(); - - public List parcelAccessList = new List(); - - public LandData() - { - globalID = LLUUID.Random(); - } - - public LandData Copy() - { - LandData landData = new LandData(); - - landData.AABBMax = AABBMax; - landData.AABBMin = AABBMin; - landData.area = area; - landData.auctionID = auctionID; - landData.authBuyerID = authBuyerID; - landData.category = category; - landData.claimDate = claimDate; - landData.claimPrice = claimPrice; - landData.globalID = globalID; - landData.groupID = groupID; - landData.groupPrims = groupPrims; - landData.otherPrims = otherPrims; - landData.ownerPrims = ownerPrims; - landData.selectedPrims = selectedPrims; - landData.isGroupOwned = isGroupOwned; - landData.localID = localID; - landData.landingType = landingType; - landData.mediaAutoScale = mediaAutoScale; - landData.mediaID = mediaID; - landData.mediaURL = mediaURL; - landData.musicURL = musicURL; - landData.ownerID = ownerID; - landData.landBitmapByteArray = (byte[]) landBitmapByteArray.Clone(); - landData.landDesc = landDesc; - landData.landFlags = landFlags; - landData.landName = landName; - landData.landStatus = landStatus; - landData.passHours = passHours; - landData.passPrice = passPrice; - landData.salePrice = salePrice; - landData.snapshotID = snapshotID; - landData.userLocation = userLocation; - landData.userLookAt = userLookAt; - - landData.parcelAccessList.Clear(); - foreach (ParcelManager.ParcelAccessEntry entry in parcelAccessList) - { - ParcelManager.ParcelAccessEntry newEntry = new ParcelManager.ParcelAccessEntry(); - newEntry.AgentID = entry.AgentID; - newEntry.Flags = entry.Flags; - newEntry.Time = entry.Time; - - landData.parcelAccessList.Add(newEntry); - } - - return landData; - } - } -} \ No newline at end of file +/* +* 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.Collections.Generic; +using System; +using libsecondlife; + +namespace OpenSim.Framework +{ + public class LandData + { + public byte[] landBitmapByteArray = new byte[512]; + public string landName = "Your Parcel"; + public string landDesc = String.Empty; + public LLUUID ownerID = LLUUID.Zero; + public bool isGroupOwned = false; + public LLVector3 AABBMin = new LLVector3(); + public LLVector3 AABBMax = new LLVector3(); + public int area = 0; + public uint auctionID = 0; //Unemplemented. If set to 0, not being auctioned + public LLUUID authBuyerID = LLUUID.Zero; //Unemplemented. Authorized Buyer's UUID + public Parcel.ParcelCategory category = new Parcel.ParcelCategory(); //Unemplemented. Parcel's chosen category + public int claimDate = 0; //Unemplemented + public int claimPrice = 0; //Unemplemented + public LLUUID groupID = LLUUID.Zero; //Unemplemented + public int groupPrims = 0; + public int otherPrims = 0; + public int ownerPrims = 0; + public int selectedPrims = 0; + public int simwidePrims = 0; + public int simwideArea = 0; + public int salePrice = 0; //Unemeplemented. Parcels price. + public Parcel.ParcelStatus landStatus = Parcel.ParcelStatus.Leased; + + public uint landFlags = (uint) Parcel.ParcelFlags.AllowFly | (uint) Parcel.ParcelFlags.AllowLandmark | + (uint) Parcel.ParcelFlags.AllowAllObjectEntry | + (uint) Parcel.ParcelFlags.AllowDeedToGroup | (uint) Parcel.ParcelFlags.AllowTerraform | + (uint) Parcel.ParcelFlags.CreateObjects | (uint) Parcel.ParcelFlags.AllowOtherScripts | + (uint) Parcel.ParcelFlags.SoundLocal; + + public byte landingType = 0; + public byte mediaAutoScale = 0; + public LLUUID mediaID = LLUUID.Zero; + public int localID = 0; + public LLUUID globalID = LLUUID.Zero; + + public string mediaURL = String.Empty; + public string musicURL = String.Empty; + public float passHours = 0; + public int passPrice = 0; + public LLUUID snapshotID = LLUUID.Zero; + public LLVector3 userLocation = new LLVector3(); + public LLVector3 userLookAt = new LLVector3(); + + public List parcelAccessList = new List(); + + public LandData() + { + globalID = LLUUID.Random(); + } + + public LandData Copy() + { + LandData landData = new LandData(); + + landData.AABBMax = AABBMax; + landData.AABBMin = AABBMin; + landData.area = area; + landData.auctionID = auctionID; + landData.authBuyerID = authBuyerID; + landData.category = category; + landData.claimDate = claimDate; + landData.claimPrice = claimPrice; + landData.globalID = globalID; + landData.groupID = groupID; + landData.groupPrims = groupPrims; + landData.otherPrims = otherPrims; + landData.ownerPrims = ownerPrims; + landData.selectedPrims = selectedPrims; + landData.isGroupOwned = isGroupOwned; + landData.localID = localID; + landData.landingType = landingType; + landData.mediaAutoScale = mediaAutoScale; + landData.mediaID = mediaID; + landData.mediaURL = mediaURL; + landData.musicURL = musicURL; + landData.ownerID = ownerID; + landData.landBitmapByteArray = (byte[]) landBitmapByteArray.Clone(); + landData.landDesc = landDesc; + landData.landFlags = landFlags; + landData.landName = landName; + landData.landStatus = landStatus; + landData.passHours = passHours; + landData.passPrice = passPrice; + landData.salePrice = salePrice; + landData.snapshotID = snapshotID; + landData.userLocation = userLocation; + landData.userLookAt = userLookAt; + + landData.parcelAccessList.Clear(); + foreach (ParcelManager.ParcelAccessEntry entry in parcelAccessList) + { + ParcelManager.ParcelAccessEntry newEntry = new ParcelManager.ParcelAccessEntry(); + newEntry.AgentID = entry.AgentID; + newEntry.Flags = entry.Flags; + newEntry.Time = entry.Time; + + landData.parcelAccessList.Add(newEntry); + } + + return landData; + } + } +} diff --git a/OpenSim/Framework/Login.cs b/OpenSim/Framework/Login.cs index e3f7ad0c12..60f533f862 100644 --- a/OpenSim/Framework/Login.cs +++ b/OpenSim/Framework/Login.cs @@ -1,55 +1,55 @@ -/* -* 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 libsecondlife; - -namespace OpenSim.Framework -{ - public class Login - { - public string First = "Test"; - public string Last = "User"; - public string ClientVersion = "not set"; //rex - public LLUUID Agent; - public LLUUID Session; - public LLUUID SecureSession = LLUUID.Zero; - public LLUUID InventoryFolder; - public LLUUID BaseFolder; - public uint CircuitCode; - public string CapsPath = ""; - public LLVector3 StartPos; - - public string AuthAddr = ""; - public string asAddress = ""; - - - public Login() - { - StartPos = new LLVector3(128, 128, 70); - } - } -} \ No newline at end of file +/* +* 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 libsecondlife; + +namespace OpenSim.Framework +{ + public class Login + { + public string First = "Test"; + public string Last = "User"; + public string ClientVersion = "not set"; //rex + public LLUUID Agent; + public LLUUID Session; + public LLUUID SecureSession = LLUUID.Zero; + public LLUUID InventoryFolder; + public LLUUID BaseFolder; + public uint CircuitCode; + public string CapsPath = System.String.Empty; + public LLVector3 StartPos; + + public string AuthAddr = ""; + public string asAddress = ""; + + + public Login() + { + StartPos = new LLVector3(128, 128, 70); + } + } +} diff --git a/OpenSim/Framework/MapBlockData.cs b/OpenSim/Framework/MapBlockData.cs index d794015a1d..b5d48db60d 100644 --- a/OpenSim/Framework/MapBlockData.cs +++ b/OpenSim/Framework/MapBlockData.cs @@ -1,50 +1,50 @@ -/* -* 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 libsecondlife; - -namespace OpenSim.Framework -{ - public class MapBlockData - { - public uint Flags; - public ushort X; - public ushort Y; - public byte Agents; - public byte Access; - public byte WaterHeight; - public LLUUID MapImageId; - public String Name; - public uint RegionFlags; - - public MapBlockData() - { - } - } -} \ No newline at end of file +/* +* 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 libsecondlife; + +namespace OpenSim.Framework +{ + public class MapBlockData + { + public uint Flags; + public ushort X; + public ushort Y; + public byte Agents; + public byte Access; + public byte WaterHeight; + public LLUUID MapImageId; + public String Name; + public uint RegionFlags; + + public MapBlockData() + { + } + } +} diff --git a/OpenSim/Framework/MessageServerConfig.cs b/OpenSim/Framework/MessageServerConfig.cs index 32db7a9443..6f92426239 100644 --- a/OpenSim/Framework/MessageServerConfig.cs +++ b/OpenSim/Framework/MessageServerConfig.cs @@ -1,137 +1,138 @@ -/* -* 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.Generic; -using System.Text; - -namespace OpenSim.Framework -{ - /// - /// Message Server Config - Configuration of the Message Server - /// - public class MessageServerConfig - { - public string DefaultStartupMsg = ""; - public string UserServerURL = ""; - public string UserSendKey = ""; - public string UserRecvKey = ""; - - public string GridServerURL = ""; - public string GridSendKey = ""; - public string GridRecvKey = ""; - - public string DatabaseProvider = ""; - public string GridCommsProvider = ""; - - public static uint DefaultHttpPort = 8006; - public static bool DefaultHttpSSL = false; - public uint HttpPort = DefaultHttpPort; - public bool HttpSSL = DefaultHttpSSL; - - private ConfigurationMember configMember; - - public MessageServerConfig(string description, string filename) - { - configMember = - new ConfigurationMember(filename, description, loadConfigurationOptions, handleIncomingConfiguration, true); - configMember.performConfigurationRetrieve(); - } - public void loadConfigurationOptions() - { - - configMember.addConfigurationOption("default_user_server", - ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, - "Default User Server URI", - "http://127.0.0.1:" + MessageServerConfig.DefaultHttpPort.ToString() + "/", false); - configMember.addConfigurationOption("user_send_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "Key to send to user server", "null", false); - configMember.addConfigurationOption("user_recv_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "Key to expect from user server", "null", false); - configMember.addConfigurationOption("default_grid_server", - ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, - "Default Grid Server URI", - "http://127.0.0.1:8002/", false); - configMember.addConfigurationOption("grid_send_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "Key to send to grid server", "null", false); - configMember.addConfigurationOption("grid_recv_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "Key to expect from user server", "null", false); - - configMember.addConfigurationOption("database_provider", ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "DLL for database provider", "OpenSim.Framework.Data.MySQL.dll", false); - - configMember.addConfigurationOption("region_comms_provider", ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "DLL for comms provider", "OpenSim.Region.Communications.OGS1.dll", false); - - configMember.addConfigurationOption("http_port", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, - "Http Listener port", DefaultHttpPort.ToString(), false); - configMember.addConfigurationOption("http_ssl", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN, - "Use SSL? true/false", DefaultHttpSSL.ToString(), false); - - } - - public bool handleIncomingConfiguration(string configuration_key, object configuration_result) - { - switch (configuration_key) - { - - case "default_user_server": - UserServerURL = (string)configuration_result; - break; - case "user_send_key": - UserSendKey = (string)configuration_result; - break; - case "user_recv_key": - UserRecvKey = (string)configuration_result; - break; - case "default_grid_server": - GridServerURL = (string)configuration_result; - break; - case "grid_send_key": - GridSendKey = (string)configuration_result; - break; - case "grid_recv_key": - GridRecvKey = (string)configuration_result; - break; - case "database_provider": - DatabaseProvider = (string)configuration_result; - break; - case "http_port": - HttpPort = (uint)configuration_result; - break; - case "http_ssl": - HttpSSL = (bool)configuration_result; - break; - case "region_comms_provider": - GridCommsProvider = (string)configuration_result; - break; - } - - return true; - } - } -} \ No newline at end of file +/* +* 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.Generic; +using System.Text; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework +{ + /// + /// Message Server Config - Configuration of the Message Server + /// + public class MessageServerConfig + { + public string DefaultStartupMsg = String.Empty; + public string UserServerURL = String.Empty; + public string UserSendKey = String.Empty; + public string UserRecvKey = String.Empty; + + public string GridServerURL = String.Empty; + public string GridSendKey = String.Empty; + public string GridRecvKey = String.Empty; + + public string DatabaseProvider = String.Empty; + public string GridCommsProvider = String.Empty; + + public static uint DefaultHttpPort = 8006; + public static bool DefaultHttpSSL = false; + public uint HttpPort = DefaultHttpPort; + public bool HttpSSL = DefaultHttpSSL; + + private ConfigurationMember configMember; + + public MessageServerConfig(string description, string filename) + { + configMember = + new ConfigurationMember(filename, description, loadConfigurationOptions, handleIncomingConfiguration, true); + configMember.performConfigurationRetrieve(); + } + public void loadConfigurationOptions() + { + + configMember.addConfigurationOption("default_user_server", + ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "Default User Server URI", + "http://127.0.0.1:" + MessageServerConfig.DefaultHttpPort.ToString() + "/", false); + configMember.addConfigurationOption("user_send_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "Key to send to user server", "null", false); + configMember.addConfigurationOption("user_recv_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "Key to expect from user server", "null", false); + configMember.addConfigurationOption("default_grid_server", + ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "Default Grid Server URI", + "http://127.0.0.1:8002/", false); + configMember.addConfigurationOption("grid_send_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "Key to send to grid server", "null", false); + configMember.addConfigurationOption("grid_recv_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "Key to expect from user server", "null", false); + + configMember.addConfigurationOption("database_provider", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "DLL for database provider", "OpenSim.Framework.Data.MySQL.dll", false); + + configMember.addConfigurationOption("region_comms_provider", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "DLL for comms provider", "OpenSim.Region.Communications.OGS1.dll", false); + + configMember.addConfigurationOption("http_port", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Http Listener port", DefaultHttpPort.ToString(), false); + configMember.addConfigurationOption("http_ssl", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN, + "Use SSL? true/false", DefaultHttpSSL.ToString(), false); + + } + + public bool handleIncomingConfiguration(string configuration_key, object configuration_result) + { + switch (configuration_key) + { + + case "default_user_server": + UserServerURL = (string)configuration_result; + break; + case "user_send_key": + UserSendKey = (string)configuration_result; + break; + case "user_recv_key": + UserRecvKey = (string)configuration_result; + break; + case "default_grid_server": + GridServerURL = (string)configuration_result; + break; + case "grid_send_key": + GridSendKey = (string)configuration_result; + break; + case "grid_recv_key": + GridRecvKey = (string)configuration_result; + break; + case "database_provider": + DatabaseProvider = (string)configuration_result; + break; + case "http_port": + HttpPort = (uint)configuration_result; + break; + case "http_ssl": + HttpSSL = (bool)configuration_result; + break; + case "region_comms_provider": + GridCommsProvider = (string)configuration_result; + break; + } + + return true; + } + } +} diff --git a/OpenSim/Framework/NetworkServersInfo.cs b/OpenSim/Framework/NetworkServersInfo.cs index 50eea4ccb1..19d6bbf8fd 100644 --- a/OpenSim/Framework/NetworkServersInfo.cs +++ b/OpenSim/Framework/NetworkServersInfo.cs @@ -1,103 +1,104 @@ -/* -* 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 Nini.Config; - -namespace OpenSim.Framework -{ - public class NetworkServersInfo - { - public string AssetURL = "http://127.0.0.1:" + AssetConfig.DefaultHttpPort.ToString() + "/"; - public string AssetSendKey = ""; - - public string GridURL = ""; - public string GridSendKey = ""; - public string GridRecvKey = ""; - public string UserURL = ""; - public string UserSendKey = ""; - public string UserRecvKey = ""; - public bool isSandbox; - - public string InventoryURL = ""; - - public static uint DefaultHttpListenerPort = 9000; - public uint HttpListenerPort = DefaultHttpListenerPort; - - public static uint RemotingListenerPort = 8895; - - - public NetworkServersInfo() - { - } - - public NetworkServersInfo(uint defaultHomeLocX, uint defaultHomeLocY) - { - m_defaultHomeLocX = defaultHomeLocX; - m_defaultHomeLocY = defaultHomeLocY; - } - - private uint? m_defaultHomeLocX; - - public uint DefaultHomeLocX - { - get { return m_defaultHomeLocX.Value; } - } - - private uint? m_defaultHomeLocY; - - public uint DefaultHomeLocY - { - get { return m_defaultHomeLocY.Value; } - } - - public void loadFromConfiguration(IConfigSource config) - { - m_defaultHomeLocX = (uint) config.Configs["StandAlone"].GetInt("default_location_x", 1000); - m_defaultHomeLocY = (uint) config.Configs["StandAlone"].GetInt("default_location_y", 1000); - - HttpListenerPort = - (uint) config.Configs["Network"].GetInt("http_listener_port", (int) DefaultHttpListenerPort); - RemotingListenerPort = - (uint) config.Configs["Network"].GetInt("remoting_listener_port", (int) RemotingListenerPort); - GridURL = - config.Configs["Network"].GetString("grid_server_url", - "http://127.0.0.1:" + GridConfig.DefaultHttpPort.ToString()); - GridSendKey = config.Configs["Network"].GetString("grid_send_key", "null"); - GridRecvKey = config.Configs["Network"].GetString("grid_recv_key", "null"); - UserURL = - config.Configs["Network"].GetString("user_server_url", - "http://127.0.0.1:" + UserConfig.DefaultHttpPort.ToString()); - UserSendKey = config.Configs["Network"].GetString("user_send_key", "null"); - UserRecvKey = config.Configs["Network"].GetString("user_recv_key", "null"); - AssetURL = config.Configs["Network"].GetString("asset_server_url", AssetURL); - InventoryURL = config.Configs["Network"].GetString("inventory_server_url", - "http://127.0.0.1:" + - InventoryConfig.DefaultHttpPort.ToString()); - } - } -} \ No newline at end of file +/* +* 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 Nini.Config; +using System; + +namespace OpenSim.Framework +{ + public class NetworkServersInfo + { + public string AssetURL = "http://127.0.0.1:" + AssetConfig.DefaultHttpPort.ToString() + "/"; + public string AssetSendKey = String.Empty; + + public string GridURL = String.Empty; + public string GridSendKey = String.Empty; + public string GridRecvKey = String.Empty; + public string UserURL = String.Empty; + public string UserSendKey = String.Empty; + public string UserRecvKey = String.Empty; + public bool isSandbox; + + public string InventoryURL = String.Empty; + + public static uint DefaultHttpListenerPort = 9000; + public uint HttpListenerPort = DefaultHttpListenerPort; + + public static uint RemotingListenerPort = 8895; + + + public NetworkServersInfo() + { + } + + public NetworkServersInfo(uint defaultHomeLocX, uint defaultHomeLocY) + { + m_defaultHomeLocX = defaultHomeLocX; + m_defaultHomeLocY = defaultHomeLocY; + } + + private uint? m_defaultHomeLocX; + + public uint DefaultHomeLocX + { + get { return m_defaultHomeLocX.Value; } + } + + private uint? m_defaultHomeLocY; + + public uint DefaultHomeLocY + { + get { return m_defaultHomeLocY.Value; } + } + + public void loadFromConfiguration(IConfigSource config) + { + m_defaultHomeLocX = (uint) config.Configs["StandAlone"].GetInt("default_location_x", 1000); + m_defaultHomeLocY = (uint) config.Configs["StandAlone"].GetInt("default_location_y", 1000); + + HttpListenerPort = + (uint) config.Configs["Network"].GetInt("http_listener_port", (int) DefaultHttpListenerPort); + RemotingListenerPort = + (uint) config.Configs["Network"].GetInt("remoting_listener_port", (int) RemotingListenerPort); + GridURL = + config.Configs["Network"].GetString("grid_server_url", + "http://127.0.0.1:" + GridConfig.DefaultHttpPort.ToString()); + GridSendKey = config.Configs["Network"].GetString("grid_send_key", "null"); + GridRecvKey = config.Configs["Network"].GetString("grid_recv_key", "null"); + UserURL = + config.Configs["Network"].GetString("user_server_url", + "http://127.0.0.1:" + UserConfig.DefaultHttpPort.ToString()); + UserSendKey = config.Configs["Network"].GetString("user_send_key", "null"); + UserRecvKey = config.Configs["Network"].GetString("user_recv_key", "null"); + AssetURL = config.Configs["Network"].GetString("asset_server_url", AssetURL); + InventoryURL = config.Configs["Network"].GetString("inventory_server_url", + "http://127.0.0.1:" + + InventoryConfig.DefaultHttpPort.ToString()); + } + } +} diff --git a/OpenSim/Framework/PacketPool.cs b/OpenSim/Framework/PacketPool.cs index c31919c012..30b6d6a5e7 100644 --- a/OpenSim/Framework/PacketPool.cs +++ b/OpenSim/Framework/PacketPool.cs @@ -1,158 +1,158 @@ -/* -* 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 libsecondlife.Packets; - -namespace OpenSim.Framework -{ - public sealed class PacketPool - { - // Set up a thread-safe singleton pattern - static PacketPool() - { - } - - private static readonly PacketPool instance = new PacketPool(); - - public static PacketPool Instance - { - get { return instance; } - } - - private Hashtable pool = new Hashtable(); - - public Packet GetPacket(PacketType type) - { - return Packet.BuildPacket(type); -/* Skip until PacketPool performance problems have been resolved (mantis 281) - Packet packet = null; - - lock (pool) - { - if (pool[type] == null || ((Stack) pool[type]).Count == 0) - { - // Creating a new packet if we cannot reuse an old package - packet = Packet.BuildPacket(type); - } - else - { - // Recycle old packages - packet = (Packet) ((Stack) pool[type]).Pop(); - } - } - - return packet; -*/ - } - - // Copied from LibSL, and added a check to avoid overwriting the - // buffer - private void ZeroDecodeCommand(byte[] src, byte[] dest) - { - for (int srcPos = 6, destPos = 6; destPos < 10; ++srcPos) - { - if (src[srcPos] == 0x00) - { - for (byte j = 0; j < src[srcPos + 1] && destPos < 10; ++j) - { - dest[destPos++] = 0x00; - } - ++srcPos; - } - else - { - dest[destPos++] = src[srcPos]; - } - } - } - - private PacketType GetType(byte[] bytes) - { - byte[] decoded_header = new byte[10]; - - ushort id; - libsecondlife.PacketFrequency freq; - - Buffer.BlockCopy(bytes, 0, decoded_header, 0, 10); - - if((bytes[0] & libsecondlife.Helpers.MSG_ZEROCODED)!=0) - { - ZeroDecodeCommand(bytes, decoded_header); - } - - if (decoded_header[6] == 0xFF) - { - if (decoded_header[7] == 0xFF) - { - id = (ushort)((decoded_header[8] << 8) + decoded_header[9]); - freq = libsecondlife.PacketFrequency.Low; - } - else - { - id = (ushort)decoded_header[7]; - freq = libsecondlife.PacketFrequency.Medium; - } - } - else - { - id = (ushort)decoded_header[6]; - freq = libsecondlife.PacketFrequency.High; - } - - return Packet.GetType(id, freq); - } - - public Packet GetPacket(byte[] bytes, ref int packetEnd, byte[] zeroBuffer) - { - PacketType type = GetType(bytes); - - int i = 0; - Packet packet = GetPacket(type); - packet.FromBytes(bytes, ref i, ref packetEnd, zeroBuffer); - return packet; - } - - public void ReturnPacket(Packet packet) - { -/* Skip until PacketPool performance problems have been resolved (mantis 281) - lock (pool) - { - PacketType type = packet.Type; - - if (pool[type] == null) - { - pool[type] = new Stack(); - } - - ((Stack) pool[type]).Push(packet); - } -*/ - } - } -} +/* +* 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 libsecondlife.Packets; + +namespace OpenSim.Framework +{ + public sealed class PacketPool + { + // Set up a thread-safe singleton pattern + static PacketPool() + { + } + + private static readonly PacketPool instance = new PacketPool(); + + public static PacketPool Instance + { + get { return instance; } + } + + private Hashtable pool = new Hashtable(); + + public Packet GetPacket(PacketType type) + { + return Packet.BuildPacket(type); +/* Skip until PacketPool performance problems have been resolved (mantis 281) + Packet packet = null; + + lock (pool) + { + if (pool[type] == null || ((Stack) pool[type]).Count == 0) + { + // Creating a new packet if we cannot reuse an old package + packet = Packet.BuildPacket(type); + } + else + { + // Recycle old packages + packet = (Packet) ((Stack) pool[type]).Pop(); + } + } + + return packet; +*/ + } + + // Copied from LibSL, and added a check to avoid overwriting the + // buffer + private void ZeroDecodeCommand(byte[] src, byte[] dest) + { + for (int srcPos = 6, destPos = 6; destPos < 10; ++srcPos) + { + if (src[srcPos] == 0x00) + { + for (byte j = 0; j < src[srcPos + 1] && destPos < 10; ++j) + { + dest[destPos++] = 0x00; + } + ++srcPos; + } + else + { + dest[destPos++] = src[srcPos]; + } + } + } + + private PacketType GetType(byte[] bytes) + { + byte[] decoded_header = new byte[10]; + + ushort id; + libsecondlife.PacketFrequency freq; + + Buffer.BlockCopy(bytes, 0, decoded_header, 0, 10); + + if((bytes[0] & libsecondlife.Helpers.MSG_ZEROCODED)!=0) + { + ZeroDecodeCommand(bytes, decoded_header); + } + + if (decoded_header[6] == 0xFF) + { + if (decoded_header[7] == 0xFF) + { + id = (ushort)((decoded_header[8] << 8) + decoded_header[9]); + freq = libsecondlife.PacketFrequency.Low; + } + else + { + id = (ushort)decoded_header[7]; + freq = libsecondlife.PacketFrequency.Medium; + } + } + else + { + id = (ushort)decoded_header[6]; + freq = libsecondlife.PacketFrequency.High; + } + + return Packet.GetType(id, freq); + } + + public Packet GetPacket(byte[] bytes, ref int packetEnd, byte[] zeroBuffer) + { + PacketType type = GetType(bytes); + + int i = 0; + Packet packet = GetPacket(type); + packet.FromBytes(bytes, ref i, ref packetEnd, zeroBuffer); + return packet; + } + + public void ReturnPacket(Packet packet) + { +/* Skip until PacketPool performance problems have been resolved (mantis 281) + lock (pool) + { + PacketType type = packet.Type; + + if (pool[type] == null) + { + pool[type] = new Stack(); + } + + ((Stack) pool[type]).Push(packet); + } +*/ + } + } +} diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs index 17a43acb88..12c436b9b2 100644 --- a/OpenSim/Framework/PrimitiveBaseShape.cs +++ b/OpenSim/Framework/PrimitiveBaseShape.cs @@ -1,231 +1,237 @@ -/* -* 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.Xml.Serialization; -using libsecondlife; - -namespace OpenSim.Framework -{ - public enum ProfileShape : byte - { - Circle = 0, - Square = 1, - IsometricTriangle = 2, - EquilateralTriangle = 3, - RightTriangle = 4, - HalfCircle = 5 - } - - public enum HollowShape : byte - { - Same = 0, - Circle = 16, - Square = 32, - Triangle = 48 - } - - public enum PCodeEnum : byte - { - Primitive = 9, - Avatar = 47 - } - - public enum Extrusion : byte - { - Straight = 16, - Curve1 = 32, - Curve2 = 48, - Flexible = 128 - } - - [Serializable] - public class PrimitiveBaseShape - { - private static readonly LLObject.TextureEntry m_defaultTexture; - - public byte State; - public byte PCode; - public ushort PathBegin; - public ushort PathEnd; - public byte PathScaleX; - public byte PathScaleY; - public byte PathShearX; - public byte PathShearY; - public sbyte PathSkew; - public ushort ProfileBegin; - public ushort ProfileEnd; - public LLVector3 Scale; - public byte PathCurve; - public byte ProfileCurve; - public ushort ProfileHollow; - public sbyte PathRadiusOffset; - public byte PathRevolutions; - public sbyte PathTaperX; - public sbyte PathTaperY; - public sbyte PathTwist; - public sbyte PathTwistBegin; - - [XmlIgnore] - public LLObject.TextureEntry Textures - { - get { return new LLObject.TextureEntry(m_textureEntry, 0, m_textureEntry.Length); } - - set { m_textureEntry = value.ToBytes(); } - } - - private byte[] m_textureEntry; - - public byte[] TextureEntry - { - get { return m_textureEntry; } - - set { m_textureEntry = value; } - } - - public byte[] ExtraParams; - - public ProfileShape ProfileShape - { - get { return (ProfileShape)(ProfileCurve & 0xf); } - set - { - byte oldValueMasked = (byte)(ProfileCurve & 0xf0); - ProfileCurve = (byte)(oldValueMasked | (byte)value); - } - } - - [XmlIgnore] - public HollowShape HollowShape - { - get { return (HollowShape)(ProfileCurve & 0xf0); } - set - { - byte oldValueMasked = (byte)(ProfileCurve & 0x0f); - ProfileCurve = (byte)(oldValueMasked | (byte)value); - } - } - - public LLVector3 PrimScale - { - get { return Scale; } - } - - - static PrimitiveBaseShape() - { - m_defaultTexture = - new LLObject.TextureEntry(new LLUUID("89556747-24cb-43ed-920b-47caed15465f")); - } - - public PrimitiveBaseShape() - { - PCode = (byte)PCodeEnum.Primitive; - ExtraParams = new byte[1]; - Textures = m_defaultTexture; - } - - public static PrimitiveBaseShape Create() - { - PrimitiveBaseShape shape = new PrimitiveBaseShape(); - return shape; - } - - public static PrimitiveBaseShape CreateBox() - { - PrimitiveBaseShape shape = Create(); - - shape.PathCurve = (byte)Extrusion.Straight; - shape.ProfileShape = ProfileShape.Square; - shape.PathScaleX = 100; - shape.PathScaleY = 100; - - return shape; - } - - public static PrimitiveBaseShape CreateCylinder() - { - PrimitiveBaseShape shape = Create(); - - shape.PathCurve = (byte)Extrusion.Curve1; - shape.ProfileShape = ProfileShape.Square; - - shape.PathScaleX = 100; - shape.PathScaleY = 100; - - return shape; - } - - public static PrimitiveBaseShape Default - { - get - { - PrimitiveBaseShape boxShape = CreateBox(); - - boxShape.SetScale(0.5f); - - return boxShape; - } - } - - public void SetScale(float side) - { - Scale = new LLVector3(side, side, side); - } - - public void SetHeigth(float heigth) - { - Scale.Z = heigth; - } - - public void SetRadius(float radius) - { - Scale.X = Scale.Y = radius * 2f; - } - - //void returns need to change of course - public virtual void GetMesh() - { - } - - public PrimitiveBaseShape Copy() - { - return (PrimitiveBaseShape)MemberwiseClone(); - } - - public static PrimitiveBaseShape CreateCylinder(float radius, float heigth) - { - PrimitiveBaseShape shape = CreateCylinder( ); - - shape.SetHeigth( heigth ); - shape.SetRadius( radius ); - - return shape; - } - } -} +/* +* 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.Xml.Serialization; +using libsecondlife; + +namespace OpenSim.Framework +{ + public enum ProfileShape : byte + { + Circle = 0, + Square = 1, + IsometricTriangle = 2, + EquilateralTriangle = 3, + RightTriangle = 4, + HalfCircle = 5 + } + + public enum HollowShape : byte + { + Same = 0, + Circle = 16, + Square = 32, + Triangle = 48 + } + + public enum PCodeEnum : byte + { + Primitive = 9, + Avatar = 47 + } + + public enum Extrusion : byte + { + Straight = 16, + Curve1 = 32, + Curve2 = 48, + Flexible = 128 + } + + [Serializable] + public class PrimitiveBaseShape + { + private static readonly LLObject.TextureEntry m_defaultTexture; + public byte[] ExtraParams; + private byte[] m_textureEntry; + + public ushort PathBegin; + public byte PathCurve; + public ushort PathEnd; + public sbyte PathRadiusOffset; + public byte PathRevolutions; + public byte PathScaleX; + public byte PathScaleY; + public byte PathShearX; + public byte PathShearY; + public sbyte PathSkew; + public sbyte PathTaperX; + public sbyte PathTaperY; + public sbyte PathTwist; + public sbyte PathTwistBegin; + public byte PCode; + public ushort ProfileBegin; + + public byte ProfileCurve; + + public ushort ProfileEnd; + public ushort ProfileHollow; + public LLVector3 Scale; + public byte State; + + static PrimitiveBaseShape() + { + m_defaultTexture = + new LLObject.TextureEntry(new LLUUID("89556747-24cb-43ed-920b-47caed15465f")); + } + + public PrimitiveBaseShape() + { + PCode = (byte) PCodeEnum.Primitive; + ExtraParams = new byte[1]; + Textures = m_defaultTexture; + } + + [XmlIgnore] + public LLObject.TextureEntry Textures + { + get { return new LLObject.TextureEntry(m_textureEntry, 0, m_textureEntry.Length); } + + set { m_textureEntry = value.ToBytes(); } + } + + public byte[] TextureEntry + { + get { return m_textureEntry; } + + set { m_textureEntry = value; } + } + + public ProfileShape ProfileShape + { + get { return (ProfileShape) (ProfileCurve & 0xf); } + set + { + byte oldValueMasked = (byte) (ProfileCurve & 0xf0); + ProfileCurve = (byte) (oldValueMasked | (byte) value); + } + } + + public HollowShape HollowShape + { + get { return (HollowShape) (ProfileCurve & 0xf0); } + set + { + byte oldValueMasked = (byte) (ProfileCurve & 0x0f); + ProfileCurve = (byte) (oldValueMasked | (byte) value); + } + } + + public static PrimitiveBaseShape Default + { + get + { + PrimitiveBaseShape boxShape = CreateBox(); + + boxShape.SetScale(0.5f); + + return boxShape; + } + } + + + public static PrimitiveBaseShape Create() + { + PrimitiveBaseShape shape = new PrimitiveBaseShape(); + return shape; + } + + public static PrimitiveBaseShape CreateBox() + { + PrimitiveBaseShape shape = Create(); + + shape.PathCurve = (byte) Extrusion.Straight; + shape.ProfileShape = ProfileShape.Square; + shape.PathScaleX = 100; + shape.PathScaleY = 100; + + return shape; + } + + public static PrimitiveBaseShape CreateCylinder() + { + PrimitiveBaseShape shape = Create(); + + shape.PathCurve = (byte) Extrusion.Curve1; + shape.ProfileShape = ProfileShape.Square; + + shape.PathScaleX = 100; + shape.PathScaleY = 100; + + return shape; + } + + public void SetScale(float side) + { + Scale = new LLVector3(side, side, side); + } + + public void SetHeigth(float heigth) + { + Scale.Z = heigth; + } + + public void SetRadius(float radius) + { + Scale.X = Scale.Y = radius*2f; + } + + //void returns need to change of course + public virtual void GetMesh() + { + } + + public PrimitiveBaseShape Copy() + { + return (PrimitiveBaseShape) MemberwiseClone(); + } + + public static PrimitiveBaseShape CreateCylinder(float radius, float heigth) + { + PrimitiveBaseShape shape = CreateCylinder(); + + shape.SetHeigth(heigth); + shape.SetRadius(radius); + + return shape; + } + + public void SetPathRange(LLVector3 pathRange) + { + PathBegin = LLObject.PackBeginCut(pathRange.X); + PathEnd = LLObject.PackEndCut(pathRange.Y); + } + + public void SetProfileRange(LLVector3 profileRange) + { + ProfileBegin = LLObject.PackBeginCut(profileRange.X); + ProfileEnd = LLObject.PackEndCut(profileRange.Y); + } + } +} diff --git a/OpenSim/Framework/RegionCommsListener.cs b/OpenSim/Framework/RegionCommsListener.cs index 72b9aa4976..ae5279d9c4 100644 --- a/OpenSim/Framework/RegionCommsListener.cs +++ b/OpenSim/Framework/RegionCommsListener.cs @@ -1,182 +1,217 @@ -/* -* 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.Collections.Generic; -using libsecondlife; - -namespace OpenSim.Framework -{ - public class RegionCommsListener : IRegionCommsListener - { - public event ExpectUserDelegate OnExpectUser; - public event ExpectPrimDelegate OnExpectPrim; - public event GenericCall2 OnExpectChildAgent; - public event AgentCrossing OnAvatarCrossingIntoRegion; - public event PrimCrossing OnPrimCrossingIntoRegion; - public event UpdateNeighbours OnNeighboursUpdate; - public event AcknowledgeAgentCross OnAcknowledgeAgentCrossed; - public event AcknowledgePrimCross OnAcknowledgePrimCrossed; - public event CloseAgentConnection OnCloseAgentConnection; - public event RegionUp OnRegionUp; - public event ChildAgentUpdate OnChildAgentUpdate; - - - public string debugRegionName = ""; - - - /// - /// - /// - /// - /// - public virtual bool TriggerExpectUser(ulong regionHandle, AgentCircuitData agent) - { - if (OnExpectUser != null) - { - OnExpectUser(regionHandle, agent); - return true; - } - - return false; - } - - - public virtual bool TriggerExpectPrim(ulong regionHandle, LLUUID primID, string objData) - { - if (OnExpectUser != null) - { - OnExpectPrim(regionHandle, primID, objData); - return true; - } - return false; - } - - public virtual bool TriggerRegionUp(RegionInfo region) - { - if (OnRegionUp != null) - { - OnRegionUp(region); - return true; - } - return false; - } - - public virtual bool TriggerChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData) - { - if (OnChildAgentUpdate != null) - { - OnChildAgentUpdate(regionHandle, cAgentData); - return true; - } - return false; - } - - public virtual bool TriggerExpectAvatarCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, - bool isFlying) - { - if (OnAvatarCrossingIntoRegion != null) - { - OnAvatarCrossingIntoRegion(regionHandle, agentID, position, isFlying); - return true; - } - return false; - } - - public virtual bool TriggerExpectPrimCrossing(ulong regionHandle, LLUUID primID, LLVector3 position, - bool isPhysical) - { - if (OnPrimCrossingIntoRegion != null) - { - OnPrimCrossingIntoRegion(regionHandle, primID, position, isPhysical); - return true; - } - return false; - } - - public virtual bool TriggerAcknowledgeAgentCrossed(ulong regionHandle, LLUUID agentID) - { - if (OnAcknowledgeAgentCrossed != null) - { - OnAcknowledgeAgentCrossed(regionHandle, agentID); - return true; - } - return false; - } - - public virtual bool TriggerAcknowledgePrimCrossed(ulong regionHandle, LLUUID primID) - { - if (OnAcknowledgePrimCrossed != null) - { - OnAcknowledgePrimCrossed(regionHandle, primID); - return true; - } - return false; - } - - public virtual void TriggerCloseAgentConnection(ulong regionHandle, LLUUID agentID) - { - if (OnCloseAgentConnection != null) - { - OnCloseAgentConnection(regionHandle, agentID); - } - } - - /// - /// - /// - /// TODO: Doesnt take any args?? - /// - public virtual bool TriggerExpectChildAgent() - { - if (OnExpectChildAgent != null) - { - OnExpectChildAgent(); - return true; - } - - return false; - } - - /// - /// - /// - /// Added to avoid a unused compiler warning on OnNeighboursUpdate, TODO: Check me - /// - /// - public virtual bool TriggerOnNeighboursUpdate(List neighbours) - { - if (OnNeighboursUpdate != null) - { - OnNeighboursUpdate(neighbours); - return true; - } - - return false; - } - } -} \ No newline at end of file +/* +* 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.Collections.Generic; +using System; +using libsecondlife; + +namespace OpenSim.Framework +{ + public class RegionCommsListener : IRegionCommsListener + { + public event ExpectUserDelegate OnExpectUser; + public event ExpectPrimDelegate OnExpectPrim; + public event GenericCall2 OnExpectChildAgent; + public event AgentCrossing OnAvatarCrossingIntoRegion; + public event PrimCrossing OnPrimCrossingIntoRegion; + public event UpdateNeighbours OnNeighboursUpdate; + public event AcknowledgeAgentCross OnAcknowledgeAgentCrossed; + public event AcknowledgePrimCross OnAcknowledgePrimCrossed; + public event CloseAgentConnection OnCloseAgentConnection; + public event RegionUp OnRegionUp; + public event ChildAgentUpdate OnChildAgentUpdate; + + private ExpectUserDelegate handler001 = null; // OnExpectUser + private ExpectPrimDelegate handler002 = null; // OnExpectPrim; + private GenericCall2 handler003 = null; // OnExpectChildAgent; + private AgentCrossing handler004 = null; // OnAvatarCrossingIntoRegion; + private PrimCrossing handler005 = null; // OnPrimCrossingIntoRegion; + private UpdateNeighbours handler006 = null; // OnNeighboursUpdate; + private AcknowledgeAgentCross handler007 = null; // OnAcknowledgeAgentCrossed; + private AcknowledgePrimCross handler008 = null; // OnAcknowledgePrimCrossed; + private CloseAgentConnection handler009 = null; // OnCloseAgentConnection; + private RegionUp handler010 = null; // OnRegionUp; + private ChildAgentUpdate handler011 = null; // OnChildAgentUpdate; + + public string debugRegionName = String.Empty; + + + /// + /// + /// + /// + /// + public virtual bool TriggerExpectUser(ulong regionHandle, AgentCircuitData agent) + { + handler001 = OnExpectUser; + if (handler001 != null) + { + handler001(regionHandle, agent); + return true; + } + + return false; + } + + + public virtual bool TriggerExpectPrim(ulong regionHandle, LLUUID primID, string objData) + { + handler002 = OnExpectPrim; + if (handler002 != null) + { + handler002(regionHandle, primID, objData); + return true; + } + return false; + } + + public virtual bool TriggerRegionUp(RegionInfo region) + { + handler010 = OnRegionUp; + if (handler010 != null) + { + handler010(region); + return true; + } + return false; + } + + public virtual bool TriggerChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData) + { + handler011 = OnChildAgentUpdate; + if (handler011 != null) + { + handler011(regionHandle, cAgentData); + return true; + } + return false; + } + + public virtual bool TriggerExpectAvatarCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, + bool isFlying) + { + handler004 = OnAvatarCrossingIntoRegion; + if (handler004 != null) + { + handler004(regionHandle, agentID, position, isFlying); + return true; + } + return false; + } + + public virtual bool TriggerExpectPrimCrossing(ulong regionHandle, LLUUID primID, LLVector3 position, + bool isPhysical) + { + handler005 = OnPrimCrossingIntoRegion; + if (handler005 != null) + { + handler005(regionHandle, primID, position, isPhysical); + return true; + } + return false; + } + + public virtual bool TriggerAcknowledgeAgentCrossed(ulong regionHandle, LLUUID agentID) + { + handler007 = OnAcknowledgeAgentCrossed; + if (handler007 != null) + { + handler007(regionHandle, agentID); + return true; + } + return false; + } + + public virtual bool TriggerAcknowledgePrimCrossed(ulong regionHandle, LLUUID primID) + { + handler008 = OnAcknowledgePrimCrossed; + if (handler008 != null) + { + handler008(regionHandle, primID); + return true; + } + return false; + } + + public virtual bool TriggerCloseAgentConnection(ulong regionHandle, LLUUID agentID) + { + handler009 = OnCloseAgentConnection; + if (handler009 != null) + { + handler009(regionHandle, agentID); + return true; + + } + return false; + } + + /// + /// + /// + /// TODO: Doesnt take any args?? + /// + public virtual bool TriggerExpectChildAgent() + { + handler003 = OnExpectChildAgent; + if (handler003 != null) + { + handler003(); + return true; + } + + return false; + } + + /// + /// + /// + /// Added to avoid a unused compiler warning on OnNeighboursUpdate, TODO: Check me + /// + /// + public virtual bool TriggerOnNeighboursUpdate(List neighbours) + { + handler006 = OnNeighboursUpdate; + if (handler006 != null) + { + handler006(neighbours); + return true; + } + + return false; + } + + public bool TriggerTellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID) + { + handler009 = OnCloseAgentConnection; + if (handler009 != null) + return handler009(regionHandle, agentID); + + return false; + } + } +} diff --git a/OpenSim/Framework/RegionHandle.cs b/OpenSim/Framework/RegionHandle.cs index 807a17c7d9..46a885b952 100644 --- a/OpenSim/Framework/RegionHandle.cs +++ b/OpenSim/Framework/RegionHandle.cs @@ -1,150 +1,150 @@ -/* -* 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.Net; -using System.Net.Sockets; - -namespace OpenSim.Framework -{ - /// - /// A class for manipulating RegionHandle coordinates - /// - internal class RegionHandle - { - private UInt64 handle; - - /// - /// Initialises a new grid-aware RegionHandle - /// - /// IP Address of the Grid Server for this region - /// Grid X Coordinate - /// Grid Y Coordinate - public RegionHandle(string ip, short x, short y) - { - IPAddress addr = IPAddress.Parse(ip); - - if (addr.AddressFamily != AddressFamily.InterNetwork) - throw new Exception("Bad RegionHandle Parameter - must be an IPv4 address"); - - uint baseHandle = BitConverter.ToUInt32(addr.GetAddressBytes(), 0); - - // Split the IP address in half - short a = (short) ((baseHandle << 16) & 0xFFFF); - short b = (short) ((baseHandle << 0) & 0xFFFF); - - // Raise the bounds a little - uint nx = (uint) x; - uint ny = (uint) y; - - // Multiply grid coords to get region coords - nx *= 256; - ny *= 256; - - // Stuff the IP address in too - nx = (uint) a << 16; - ny = (uint) b << 16; - - handle = ((UInt64) nx << 32) | (uint) ny; - } - - /// - /// Initialises a new RegionHandle that is not inter-grid aware - /// - /// Grid X Coordinate - /// Grid Y Coordinate - public RegionHandle(uint x, uint y) - { - handle = ((x*256) << 32) | (y*256); - } - - /// - /// Initialises a new RegionHandle from an existing value - /// - /// A U64 RegionHandle - public RegionHandle(UInt64 Region) - { - handle = Region; - } - - /// - /// Returns the Grid Masked RegionHandle - For use in Teleport packets and other packets where sending the grid IP address may be handy. - /// - /// Do not use for SimulatorEnable packets. The client will choke. - /// Region Handle including IP Address encoding - public UInt64 getTeleportHandle() - { - return handle; - } - - /// - /// Returns a RegionHandle which may be used for SimulatorEnable packets. Removes the IP address encoding and returns the lower bounds. - /// - /// A U64 RegionHandle for use in SimulatorEnable packets. - public UInt64 getNeighbourHandle() - { - UInt64 mask = 0x0000FFFF0000FFFF; - - return handle | mask; - } - - /// - /// Returns the IP Address of the GridServer from a Grid-Encoded RegionHandle - /// - /// Grid Server IP Address - public IPAddress getGridIP() - { - uint a = (uint) ((handle >> 16) & 0xFFFF); - uint b = (uint) ((handle >> 48) & 0xFFFF); - - return new IPAddress((long) (a << 16) | (long) b); - } - - /// - /// Returns the X Coordinate from a Grid-Encoded RegionHandle - /// - /// X Coordinate - public uint getGridX() - { - uint x = (uint) ((handle >> 32) & 0xFFFF); - - return x; - } - - /// - /// Returns the Y Coordinate from a Grid-Encoded RegionHandle - /// - /// Y Coordinate - public uint getGridY() - { - uint y = (uint) ((handle >> 0) & 0xFFFF); - - return y; - } - } -} \ No newline at end of file +/* +* 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.Net; +using System.Net.Sockets; + +namespace OpenSim.Framework +{ + /// + /// A class for manipulating RegionHandle coordinates + /// + internal class RegionHandle + { + private UInt64 handle; + + /// + /// Initialises a new grid-aware RegionHandle + /// + /// IP Address of the Grid Server for this region + /// Grid X Coordinate + /// Grid Y Coordinate + public RegionHandle(string ip, short x, short y) + { + IPAddress addr = IPAddress.Parse(ip); + + if (addr.AddressFamily != AddressFamily.InterNetwork) + throw new Exception("Bad RegionHandle Parameter - must be an IPv4 address"); + + uint baseHandle = BitConverter.ToUInt32(addr.GetAddressBytes(), 0); + + // Split the IP address in half + short a = (short) ((baseHandle << 16) & 0xFFFF); + short b = (short) ((baseHandle << 0) & 0xFFFF); + + // Raise the bounds a little + uint nx = (uint) x; + uint ny = (uint) y; + + // Multiply grid coords to get region coords + nx *= Constants.RegionSize; + ny *= Constants.RegionSize; + + // Stuff the IP address in too + nx = (uint) a << 16; + ny = (uint) b << 16; + + handle = ((UInt64) nx << 32) | (uint) ny; + } + + /// + /// Initialises a new RegionHandle that is not inter-grid aware + /// + /// Grid X Coordinate + /// Grid Y Coordinate + public RegionHandle(uint x, uint y) + { + handle = ((x * Constants.RegionSize) << 32) | (y * Constants.RegionSize); + } + + /// + /// Initialises a new RegionHandle from an existing value + /// + /// A U64 RegionHandle + public RegionHandle(UInt64 Region) + { + handle = Region; + } + + /// + /// Returns the Grid Masked RegionHandle - For use in Teleport packets and other packets where sending the grid IP address may be handy. + /// + /// Do not use for SimulatorEnable packets. The client will choke. + /// Region Handle including IP Address encoding + public UInt64 getTeleportHandle() + { + return handle; + } + + /// + /// Returns a RegionHandle which may be used for SimulatorEnable packets. Removes the IP address encoding and returns the lower bounds. + /// + /// A U64 RegionHandle for use in SimulatorEnable packets. + public UInt64 getNeighbourHandle() + { + UInt64 mask = 0x0000FFFF0000FFFF; + + return handle | mask; + } + + /// + /// Returns the IP Address of the GridServer from a Grid-Encoded RegionHandle + /// + /// Grid Server IP Address + public IPAddress getGridIP() + { + uint a = (uint) ((handle >> 16) & 0xFFFF); + uint b = (uint) ((handle >> 48) & 0xFFFF); + + return new IPAddress((long) (a << 16) | (long) b); + } + + /// + /// Returns the X Coordinate from a Grid-Encoded RegionHandle + /// + /// X Coordinate + public uint getGridX() + { + uint x = (uint) ((handle >> 32) & 0xFFFF); + + return x; + } + + /// + /// Returns the Y Coordinate from a Grid-Encoded RegionHandle + /// + /// Y Coordinate + public uint getGridY() + { + uint y = (uint) ((handle >> 0) & 0xFFFF); + + return y; + } + } +} diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index e9fa356d0e..403fd0e7ba 100644 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs @@ -1,406 +1,421 @@ -/* -* 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.Net; -using System.Net.Sockets; -using System.Xml; -using libsecondlife; -using Nini.Config; - -namespace OpenSim.Framework -{ - [Serializable] - public class SimpleRegionInfo - { - public SimpleRegionInfo() - { - } - - public SimpleRegionInfo(uint regionLocX, uint regionLocY, IPEndPoint internalEndPoint, string externalUri) - { - m_regionLocX = regionLocX; - m_regionLocY = regionLocY; - - m_internalEndPoint = internalEndPoint; - m_externalHostName = externalUri; - } - - public SimpleRegionInfo(uint regionLocX, uint regionLocY, string externalUri, uint port) - { - m_regionLocX = regionLocX; - m_regionLocY = regionLocY; - - m_externalHostName = externalUri; - - m_internalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int) port); - } - - public SimpleRegionInfo(RegionInfo ConvertFrom) - { - m_regionLocX = ConvertFrom.RegionLocX; - m_regionLocY = ConvertFrom.RegionLocY; - m_internalEndPoint = ConvertFrom.InternalEndPoint; - m_externalHostName = ConvertFrom.ExternalHostName; - m_remotingPort = ConvertFrom.RemotingPort; - RemotingAddress = ConvertFrom.RemotingAddress; - RegionID = LLUUID.Zero; - } - - public LLUUID RegionID = LLUUID.Zero; - - public uint m_remotingPort; - - public uint RemotingPort - { - get { return m_remotingPort; } - set { m_remotingPort = value; } - } - - public string RemotingAddress; - - public IPEndPoint ExternalEndPoint - { - get - { - // Old one defaults to IPv6 - //return new IPEndPoint( Dns.GetHostAddresses( m_externalHostName )[0], m_internalEndPoint.Port ); - - IPAddress ia = null; - // If it is already an IP, don't resolve it - just return directly - if (IPAddress.TryParse(m_externalHostName, out ia)) - return new IPEndPoint(ia, m_internalEndPoint.Port); - - // Reset for next check - ia = null; - - // New method favors IPv4 - foreach (IPAddress Adr in Dns.GetHostAddresses(m_externalHostName)) - { - if (ia == null) - ia = Adr; - - if (Adr.AddressFamily == AddressFamily.InterNetwork) - { - ia = Adr; - break; - } - } - - return new IPEndPoint(ia, m_internalEndPoint.Port); - } - - set { m_externalHostName = value.ToString(); } - } - - protected string m_externalHostName; - - public string ExternalHostName - { - get { return m_externalHostName; } - set { m_externalHostName = value; } - } - - protected IPEndPoint m_internalEndPoint; - - public IPEndPoint InternalEndPoint - { - get { return m_internalEndPoint; } - set { m_internalEndPoint = value; } - } - - protected uint? m_regionLocX; - - public uint RegionLocX - { - get { return m_regionLocX.Value; } - set { m_regionLocX = value; } - } - - protected uint? m_regionLocY; - - public uint RegionLocY - { - get { return m_regionLocY.Value; } - set { m_regionLocY = value; } - } - - public ulong RegionHandle - { - get { return Util.UIntsToLong((RegionLocX*256), (RegionLocY*256)); } - } - } - - public class RegionInfo : SimpleRegionInfo - { - public string RegionName = ""; - - public string DataStore = ""; - public bool isSandbox = false; - public bool commFailTF = false; - - public LLUUID MasterAvatarAssignedUUID = LLUUID.Zero; - public LLUUID CovenantID = LLUUID.Zero; - public string MasterAvatarFirstName = ""; - public string MasterAvatarLastName = ""; - public string MasterAvatarSandboxPassword = ""; - - public LLUUID SkyboxFront = null; - public LLUUID SkyboxBack = null; - public LLUUID SkyboxLeft = null; - public LLUUID SkyboxRight = null; - public LLUUID SkyboxTop = null; - public LLUUID SkyboxBottom = null; - - // Apparently, we're applying the same estatesettings regardless of whether it's local or remote. - private static EstateSettings m_estateSettings; - - public EstateSettings EstateSettings - { - get - { - if (m_estateSettings == null) - { - m_estateSettings = new EstateSettings(); - } - - return m_estateSettings; - } - } - - public ConfigurationMember configMember; - - public RegionInfo(string description, string filename, bool skipConsoleConfig) - { - configMember = - new ConfigurationMember(filename, description, loadConfigurationOptions, handleIncomingConfiguration,!skipConsoleConfig); - configMember.performConfigurationRetrieve(); - } - - public RegionInfo(string description, XmlNode xmlNode, bool skipConsoleConfig) - { - configMember = - new ConfigurationMember(xmlNode, description, loadConfigurationOptions, handleIncomingConfiguration, !skipConsoleConfig); - configMember.performConfigurationRetrieve(); - } - - public RegionInfo(uint regionLocX, uint regionLocY, IPEndPoint internalEndPoint, string externalUri) : - base(regionLocX, regionLocY, internalEndPoint, externalUri) - { - } - - public RegionInfo() - { - } - - public RegionInfo(SearializableRegionInfo ConvertFrom) - { - m_regionLocX = ConvertFrom.RegionLocX; - m_regionLocY = ConvertFrom.RegionLocY; - m_internalEndPoint = ConvertFrom.InternalEndPoint; - m_externalHostName = ConvertFrom.ExternalHostName; - m_remotingPort = ConvertFrom.RemotingPort; - RemotingAddress = ConvertFrom.RemotingAddress; - RegionID = LLUUID.Zero; - } - - public RegionInfo(SimpleRegionInfo ConvertFrom) - { - m_regionLocX = ConvertFrom.RegionLocX; - m_regionLocY = ConvertFrom.RegionLocY; - m_internalEndPoint = ConvertFrom.InternalEndPoint; - m_externalHostName = ConvertFrom.ExternalHostName; - m_remotingPort = ConvertFrom.RemotingPort; - RemotingAddress = ConvertFrom.RemotingAddress; - RegionID = LLUUID.Zero; - } - - //not in use, should swap to nini though. - public void LoadFromNiniSource(IConfigSource source) - { - LoadFromNiniSource(source, "RegionInfo"); - } - - //not in use, should swap to nini though. - public void LoadFromNiniSource(IConfigSource source, string sectionName) - { - string errorMessage = ""; - RegionID = new LLUUID(source.Configs[sectionName].GetString("Region_ID", LLUUID.Random().ToString())); - RegionName = source.Configs[sectionName].GetString("sim_name", "OpenSim Test"); - m_regionLocX = Convert.ToUInt32(source.Configs[sectionName].GetString("sim_location_x", "1000")); - m_regionLocY = Convert.ToUInt32(source.Configs[sectionName].GetString("sim_location_y", "1000")); - // this.DataStore = source.Configs[sectionName].GetString("datastore", "OpenSim.db"); - - string ipAddress = source.Configs[sectionName].GetString("internal_ip_address", "0.0.0.0"); - IPAddress ipAddressResult; - if (IPAddress.TryParse(ipAddress, out ipAddressResult)) - { - m_internalEndPoint = new IPEndPoint(ipAddressResult, 0); - } - else - { - errorMessage = "needs an IP Address (IPAddress)"; - } - m_internalEndPoint.Port = - source.Configs[sectionName].GetInt("internal_ip_port", (int) NetworkServersInfo.DefaultHttpListenerPort); - - string externalHost = source.Configs[sectionName].GetString("external_host_name", "127.0.0.1"); - if (externalHost != "SYSTEMIP") - { - m_externalHostName = externalHost; - } - else - { - m_externalHostName = Util.GetLocalHost().ToString(); - } - - MasterAvatarFirstName = source.Configs[sectionName].GetString("master_avatar_first", "Test"); - MasterAvatarLastName = source.Configs[sectionName].GetString("master_avatar_last", "User"); - MasterAvatarSandboxPassword = source.Configs[sectionName].GetString("master_avatar_pass", "test"); - - if (errorMessage != "") - { - // a error - } - } - - public void loadConfigurationOptions() - { - configMember.addConfigurationOption("sim_UUID", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, - "UUID of Region (Default is recommended, random UUID)", - LLUUID.Random().ToString(), true); - configMember.addConfigurationOption("sim_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, - "Region Name", "OpenSim Test", false); - configMember.addConfigurationOption("sim_location_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, - "Grid Location (X Axis)", "1000", false); - configMember.addConfigurationOption("sim_location_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, - "Grid Location (Y Axis)", "1000", false); - //configMember.addConfigurationOption("datastore", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Filename for local storage", "OpenSim.db", false); - configMember.addConfigurationOption("internal_ip_address", - ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS, - "Internal IP Address for incoming UDP client connections", "0.0.0.0", - false); - configMember.addConfigurationOption("internal_ip_port", ConfigurationOption.ConfigurationTypes.TYPE_INT32, - "Internal IP Port for incoming UDP client connections", - NetworkServersInfo.DefaultHttpListenerPort.ToString(), false); - configMember.addConfigurationOption("external_host_name", - ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, - "External Host Name", "127.0.0.1", false); - configMember.addConfigurationOption("master_avatar_uuid", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, - "Master Avatar UUID", LLUUID.Zero.ToString(), true); - configMember.addConfigurationOption("estate_covanant_uuid", - ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, "Estate Covenant", - LLUUID.Zero.ToString(), true); - configMember.addConfigurationOption("master_avatar_first", - ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, - "First Name of Master Avatar", "Test", false, - (ConfigurationOption.ConfigurationOptionShouldBeAsked) - shouldMasterAvatarDetailsBeAsked); - configMember.addConfigurationOption("master_avatar_last", - ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, - "Last Name of Master Avatar", "User", false, - (ConfigurationOption.ConfigurationOptionShouldBeAsked) - shouldMasterAvatarDetailsBeAsked); - configMember.addConfigurationOption("master_avatar_pass", ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "(Sandbox Mode Only)Password for Master Avatar account", "test", false, - (ConfigurationOption.ConfigurationOptionShouldBeAsked) - shouldMasterAvatarDetailsBeAsked); - } - - public bool shouldMasterAvatarDetailsBeAsked(string configuration_key) - { - if (MasterAvatarAssignedUUID.Equals(null) || MasterAvatarAssignedUUID.ToString() == LLUUID.Zero.ToString()) - { - return true; - } - return false; - } - - public bool handleIncomingConfiguration(string configuration_key, object configuration_result) - { - switch (configuration_key) - { - case "sim_UUID": - RegionID = (LLUUID) configuration_result; - break; - case "sim_name": - RegionName = (string) configuration_result; - break; - case "sim_location_x": - m_regionLocX = (uint) configuration_result; - break; - case "sim_location_y": - m_regionLocY = (uint) configuration_result; - break; - case "datastore": - DataStore = (string) configuration_result; - break; - case "internal_ip_address": - IPAddress address = (IPAddress) configuration_result; - m_internalEndPoint = new IPEndPoint(address, 0); - break; - case "internal_ip_port": - m_internalEndPoint.Port = (int) configuration_result; - break; - case "external_host_name": - if ((string) configuration_result != "SYSTEMIP") - { - m_externalHostName = (string) configuration_result; - } - else - { - m_externalHostName = Util.GetLocalHost().ToString(); - } - break; - case "master_avatar_uuid": - MasterAvatarAssignedUUID = (LLUUID) configuration_result; - break; - case "estate_covanant_uuid": - CovenantID = (LLUUID) configuration_result; - break; - - case "master_avatar_first": - MasterAvatarFirstName = (string) configuration_result; - break; - case "master_avatar_last": - MasterAvatarLastName = (string) configuration_result; - break; - case "master_avatar_pass": - string tempMD5Passwd = (string) configuration_result; - MasterAvatarSandboxPassword = Util.Md5Hash(Util.Md5Hash(tempMD5Passwd) + ":" + ""); - break; - } - - return true; - } - public void SaveEstatecovenantUUID(LLUUID notecard) - { - configMember.forceSetConfigurationOption("estate_covanant_uuid", notecard.ToString()); - - } - } -} \ No newline at end of file +/* +* 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.Net; +using System.Net.Sockets; +using System.Xml; +using libsecondlife; +using Nini.Config; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework +{ + [Serializable] + public class SimpleRegionInfo + { + public SimpleRegionInfo() + { + } + + public SimpleRegionInfo(uint regionLocX, uint regionLocY, IPEndPoint internalEndPoint, string externalUri) + { + m_regionLocX = regionLocX; + m_regionLocY = regionLocY; + + m_internalEndPoint = internalEndPoint; + m_externalHostName = externalUri; + } + + public SimpleRegionInfo(uint regionLocX, uint regionLocY, string externalUri, uint port) + { + m_regionLocX = regionLocX; + m_regionLocY = regionLocY; + + m_externalHostName = externalUri; + + m_internalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int) port); + } + + public SimpleRegionInfo(RegionInfo ConvertFrom) + { + m_regionLocX = ConvertFrom.RegionLocX; + m_regionLocY = ConvertFrom.RegionLocY; + m_internalEndPoint = ConvertFrom.InternalEndPoint; + m_externalHostName = ConvertFrom.ExternalHostName; + m_remotingPort = ConvertFrom.RemotingPort; + m_allow_alternate_ports = ConvertFrom.m_allow_alternate_ports; + RemotingAddress = ConvertFrom.RemotingAddress; + RegionID = LLUUID.Zero; + } + + public LLUUID RegionID = LLUUID.Zero; + + public uint m_remotingPort; + + public uint RemotingPort + { + get { return m_remotingPort; } + set { m_remotingPort = value; } + } + public bool m_allow_alternate_ports; + + public string RemotingAddress; + + public IPEndPoint ExternalEndPoint + { + get + { + // Old one defaults to IPv6 + //return new IPEndPoint( Dns.GetHostAddresses( m_externalHostName )[0], m_internalEndPoint.Port ); + + IPAddress ia = null; + // If it is already an IP, don't resolve it - just return directly + if (IPAddress.TryParse(m_externalHostName, out ia)) + return new IPEndPoint(ia, m_internalEndPoint.Port); + + // Reset for next check + ia = null; + + // New method favors IPv4 + foreach (IPAddress Adr in Dns.GetHostAddresses(m_externalHostName)) + { + if (ia == null) + ia = Adr; + + if (Adr.AddressFamily == AddressFamily.InterNetwork) + { + ia = Adr; + break; + } + } + + return new IPEndPoint(ia, m_internalEndPoint.Port); + } + + set { m_externalHostName = value.ToString(); } + } + + protected string m_externalHostName; + + public string ExternalHostName + { + get { return m_externalHostName; } + set { m_externalHostName = value; } + } + + protected bool Allow_Alternate_Ports; + + protected IPEndPoint m_internalEndPoint; + + public IPEndPoint InternalEndPoint + { + get { return m_internalEndPoint; } + set { m_internalEndPoint = value; } + } + + protected uint? m_regionLocX; + + public uint RegionLocX + { + get { return m_regionLocX.Value; } + set { m_regionLocX = value; } + } + + protected uint? m_regionLocY; + + public uint RegionLocY + { + get { return m_regionLocY.Value; } + set { m_regionLocY = value; } + } + + public ulong RegionHandle + { + get { return Util.UIntsToLong((RegionLocX * (uint)Constants.RegionSize), (RegionLocY * (uint)Constants.RegionSize)); } + } + } + + public class RegionInfo : SimpleRegionInfo + { + public string RegionName = String.Empty; + + public string DataStore = String.Empty; + public bool isSandbox = false; + public bool commFailTF = false; + +// public bool m_allow_alternate_ports; + + public LLUUID MasterAvatarAssignedUUID = LLUUID.Zero; + public LLUUID CovenantID = LLUUID.Zero; + public string MasterAvatarFirstName = String.Empty; + public string MasterAvatarLastName = String.Empty; + public string MasterAvatarSandboxPassword = String.Empty; + + public LLUUID SkyboxFront = null; + public LLUUID SkyboxBack = null; + public LLUUID SkyboxLeft = null; + public LLUUID SkyboxRight = null; + public LLUUID SkyboxTop = null; + public LLUUID SkyboxBottom = null; + + // Apparently, we're applying the same estatesettings regardless of whether it's local or remote. + private EstateSettings m_estateSettings; + + public EstateSettings EstateSettings + { + get + { + if (m_estateSettings == null) + { + m_estateSettings = new EstateSettings(); + } + + return m_estateSettings; + } + } + + public ConfigurationMember configMember; + + public RegionInfo(string description, string filename, bool skipConsoleConfig) + { + configMember = + new ConfigurationMember(filename, description, loadConfigurationOptions, handleIncomingConfiguration, !skipConsoleConfig); + configMember.performConfigurationRetrieve(); + } + + public RegionInfo(string description, XmlNode xmlNode, bool skipConsoleConfig) + { + configMember = + new ConfigurationMember(xmlNode, description, loadConfigurationOptions, handleIncomingConfiguration, !skipConsoleConfig); + configMember.performConfigurationRetrieve(); + } + + public RegionInfo(uint regionLocX, uint regionLocY, IPEndPoint internalEndPoint, string externalUri) : + base(regionLocX, regionLocY, internalEndPoint, externalUri) + { + } + + public RegionInfo() + { + } + + public RegionInfo(SearializableRegionInfo ConvertFrom) + { + m_regionLocX = ConvertFrom.RegionLocX; + m_regionLocY = ConvertFrom.RegionLocY; + m_internalEndPoint = ConvertFrom.InternalEndPoint; + m_externalHostName = ConvertFrom.ExternalHostName; + m_remotingPort = ConvertFrom.RemotingPort; + m_allow_alternate_ports = ConvertFrom.m_allow_alternate_ports; + RemotingAddress = ConvertFrom.RemotingAddress; + RegionID = LLUUID.Zero; + } + + public RegionInfo(SimpleRegionInfo ConvertFrom) + { + m_regionLocX = ConvertFrom.RegionLocX; + m_regionLocY = ConvertFrom.RegionLocY; + m_internalEndPoint = ConvertFrom.InternalEndPoint; + m_externalHostName = ConvertFrom.ExternalHostName; + m_remotingPort = ConvertFrom.RemotingPort; + m_allow_alternate_ports = ConvertFrom.m_allow_alternate_ports; + RemotingAddress = ConvertFrom.RemotingAddress; + RegionID = LLUUID.Zero; + } + + //not in use, should swap to nini though. + public void LoadFromNiniSource(IConfigSource source) + { + LoadFromNiniSource(source, "RegionInfo"); + } + + //not in use, should swap to nini though. + public void LoadFromNiniSource(IConfigSource source, string sectionName) + { + string errorMessage = String.Empty; + RegionID = new LLUUID(source.Configs[sectionName].GetString("Region_ID", LLUUID.Random().ToString())); + RegionName = source.Configs[sectionName].GetString("sim_name", "OpenSim Test"); + m_regionLocX = Convert.ToUInt32(source.Configs[sectionName].GetString("sim_location_x", "1000")); + m_regionLocY = Convert.ToUInt32(source.Configs[sectionName].GetString("sim_location_y", "1000")); + // this.DataStore = source.Configs[sectionName].GetString("datastore", "OpenSim.db"); + + string ipAddress = source.Configs[sectionName].GetString("internal_ip_address", "0.0.0.0"); + IPAddress ipAddressResult; + if (IPAddress.TryParse(ipAddress, out ipAddressResult)) + { + m_internalEndPoint = new IPEndPoint(ipAddressResult, 0); + } + else + { + errorMessage = "needs an IP Address (IPAddress)"; + } + m_internalEndPoint.Port = + source.Configs[sectionName].GetInt("internal_ip_port", (int) NetworkServersInfo.DefaultHttpListenerPort); + + string externalHost = source.Configs[sectionName].GetString("external_host_name", "127.0.0.1"); + if (externalHost != "SYSTEMIP") + { + m_externalHostName = externalHost; + } + else + { + m_externalHostName = Util.GetLocalHost().ToString(); + } + + MasterAvatarFirstName = source.Configs[sectionName].GetString("master_avatar_first", "Test"); + MasterAvatarLastName = source.Configs[sectionName].GetString("master_avatar_last", "User"); + MasterAvatarSandboxPassword = source.Configs[sectionName].GetString("master_avatar_pass", "test"); + + if (errorMessage != String.Empty) + { + // a error + } + } + + public void loadConfigurationOptions() + { + configMember.addConfigurationOption("sim_UUID", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, + "UUID of Region (Default is recommended, random UUID)", + LLUUID.Random().ToString(), true); + configMember.addConfigurationOption("sim_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "Region Name", "OpenSim Test", false); + configMember.addConfigurationOption("sim_location_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Grid Location (X Axis)", "1000", false); + configMember.addConfigurationOption("sim_location_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Grid Location (Y Axis)", "1000", false); + //configMember.addConfigurationOption("datastore", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Filename for local storage", "OpenSim.db", false); + configMember.addConfigurationOption("internal_ip_address", + ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS, + "Internal IP Address for incoming UDP client connections", "0.0.0.0", + false); + configMember.addConfigurationOption("internal_ip_port", ConfigurationOption.ConfigurationTypes.TYPE_INT32, + "Internal IP Port for incoming UDP client connections", + NetworkServersInfo.DefaultHttpListenerPort.ToString(), false); + configMember.addConfigurationOption("allow_alternate_ports", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN, + "Allow sim to find alternate UDP ports when ports are in use?", + "false", true); + configMember.addConfigurationOption("external_host_name", + ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "External Host Name", "127.0.0.1", false); + configMember.addConfigurationOption("master_avatar_uuid", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, + "Master Avatar UUID", LLUUID.Zero.ToString(), true); + configMember.addConfigurationOption("estate_covanant_uuid", + ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, "Estate Covenant", + LLUUID.Zero.ToString(), true); + configMember.addConfigurationOption("master_avatar_first", + ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "First Name of Master Avatar", "Test", false, + (ConfigurationOption.ConfigurationOptionShouldBeAsked) + shouldMasterAvatarDetailsBeAsked); + configMember.addConfigurationOption("master_avatar_last", + ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "Last Name of Master Avatar", "User", false, + (ConfigurationOption.ConfigurationOptionShouldBeAsked) + shouldMasterAvatarDetailsBeAsked); + configMember.addConfigurationOption("master_avatar_pass", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "(Sandbox Mode Only)Password for Master Avatar account", "test", false, + (ConfigurationOption.ConfigurationOptionShouldBeAsked) + shouldMasterAvatarDetailsBeAsked); + } + + public bool shouldMasterAvatarDetailsBeAsked(string configuration_key) + { + if (MasterAvatarAssignedUUID.Equals(null) || MasterAvatarAssignedUUID.ToString() == LLUUID.Zero.ToString()) + { + return true; + } + return false; + } + + public bool handleIncomingConfiguration(string configuration_key, object configuration_result) + { + switch (configuration_key) + { + case "sim_UUID": + RegionID = (LLUUID) configuration_result; + break; + case "sim_name": + RegionName = (string) configuration_result; + break; + case "sim_location_x": + m_regionLocX = (uint) configuration_result; + break; + case "sim_location_y": + m_regionLocY = (uint) configuration_result; + break; + case "datastore": + DataStore = (string) configuration_result; + break; + case "internal_ip_address": + IPAddress address = (IPAddress) configuration_result; + m_internalEndPoint = new IPEndPoint(address, 0); + break; + case "internal_ip_port": + m_internalEndPoint.Port = (int)configuration_result; + break; + case "allow_alternate_ports": + m_allow_alternate_ports = (bool)configuration_result; + break; + case "external_host_name": + if ((string) configuration_result != "SYSTEMIP") + { + m_externalHostName = (string) configuration_result; + } + else + { + m_externalHostName = Util.GetLocalHost().ToString(); + } + break; + case "master_avatar_uuid": + MasterAvatarAssignedUUID = (LLUUID) configuration_result; + break; + case "estate_covanant_uuid": + CovenantID = (LLUUID) configuration_result; + break; + + case "master_avatar_first": + MasterAvatarFirstName = (string) configuration_result; + break; + case "master_avatar_last": + MasterAvatarLastName = (string) configuration_result; + break; + case "master_avatar_pass": + string tempMD5Passwd = (string) configuration_result; + MasterAvatarSandboxPassword = Util.Md5Hash(Util.Md5Hash(tempMD5Passwd) + ":" + String.Empty); + break; + } + + return true; + } + public void SaveEstatecovenantUUID(LLUUID notecard) + { + configMember.forceSetConfigurationOption("estate_covanant_uuid", notecard.ToString()); + + } + } +} diff --git a/OpenSim/Framework/RegionLoader/Web/RegionLoaderWebServer.cs b/OpenSim/Framework/RegionLoader/Web/RegionLoaderWebServer.cs index d3bc1db3b4..0ce57fd9fc 100644 --- a/OpenSim/Framework/RegionLoader/Web/RegionLoaderWebServer.cs +++ b/OpenSim/Framework/RegionLoader/Web/RegionLoaderWebServer.cs @@ -1,99 +1,100 @@ -/* -* 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.IO; -using System.Net; -using System.Xml; -using Nini.Config; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.RegionLoader.Web -{ - public class RegionLoaderWebServer : IRegionLoader - { - private IniConfigSource m_configSouce; - - public void SetIniConfigSource(IniConfigSource configSource) - { - m_configSouce = configSource; - } - - public RegionInfo[] LoadRegions() - { - if (m_configSouce == null) - { - MainLog.Instance.Error("WEBLOADER", "Unable to load configuration source!"); - return null; - } - else - { - IniConfig startupConfig = (IniConfig) m_configSouce.Configs["Startup"]; - string url = startupConfig.GetString("regionload_webserver_url", "").Trim(); - if (url == "") - { - MainLog.Instance.Error("WEBLOADER", "Unable to load webserver URL - URL was empty."); - return null; - } - else - { - HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(url); - webRequest.Timeout = 30000; //30 Second Timeout - MainLog.Instance.Debug("WEBLOADER", "Sending Download Request..."); - HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse(); - MainLog.Instance.Debug("WEBLOADER", "Downloading Region Information From Remote Server..."); - StreamReader reader = new StreamReader(webResponse.GetResponseStream()); - string xmlSource = ""; - string tempStr = reader.ReadLine(); - while (tempStr != null) - { - xmlSource = xmlSource + tempStr; - tempStr = reader.ReadLine(); - } - MainLog.Instance.Debug("WEBLOADER", - "Done downloading region information from server. Total Bytes: " + - xmlSource.Length); - XmlDocument xmlDoc = new XmlDocument(); - xmlDoc.LoadXml(xmlSource); - if (xmlDoc.FirstChild.Name == "Regions") - { - RegionInfo[] regionInfos = new RegionInfo[xmlDoc.FirstChild.ChildNodes.Count]; - int i; - for (i = 0; i < xmlDoc.FirstChild.ChildNodes.Count; i++) - { - MainLog.Instance.Debug(xmlDoc.FirstChild.ChildNodes[i].OuterXml); - regionInfos[i] = - new RegionInfo("REGION CONFIG #" + (i + 1), xmlDoc.FirstChild.ChildNodes[i],false); - } - - return regionInfos; - } - return null; - } - } - } - } -} \ No newline at end of file +/* +* 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.IO; +using System.Net; +using System.Xml; +using Nini.Config; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.RegionLoader.Web +{ + public class RegionLoaderWebServer : IRegionLoader + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private IniConfigSource m_configSouce; + + public void SetIniConfigSource(IniConfigSource configSource) + { + m_configSouce = configSource; + } + + public RegionInfo[] LoadRegions() + { + if (m_configSouce == null) + { + m_log.Error("[WEBLOADER]: Unable to load configuration source!"); + return null; + } + else + { + IniConfig startupConfig = (IniConfig) m_configSouce.Configs["Startup"]; + string url = startupConfig.GetString("regionload_webserver_url", System.String.Empty).Trim(); + if (url == System.String.Empty) + { + m_log.Error("[WEBLOADER]: Unable to load webserver URL - URL was empty."); + return null; + } + else + { + HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(url); + webRequest.Timeout = 30000; //30 Second Timeout + m_log.Debug("[WEBLOADER]: Sending Download Request..."); + HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse(); + m_log.Debug("[WEBLOADER]: Downloading Region Information From Remote Server..."); + StreamReader reader = new StreamReader(webResponse.GetResponseStream()); + string xmlSource = System.String.Empty; + string tempStr = reader.ReadLine(); + while (tempStr != null) + { + xmlSource = xmlSource + tempStr; + tempStr = reader.ReadLine(); + } + m_log.Debug("[WEBLOADER]: Done downloading region information from server. Total Bytes: " + + xmlSource.Length); + XmlDocument xmlDoc = new XmlDocument(); + xmlDoc.LoadXml(xmlSource); + if (xmlDoc.FirstChild.Name == "Regions") + { + RegionInfo[] regionInfos = new RegionInfo[xmlDoc.FirstChild.ChildNodes.Count]; + int i; + for (i = 0; i < xmlDoc.FirstChild.ChildNodes.Count; i++) + { + m_log.Debug(xmlDoc.FirstChild.ChildNodes[i].OuterXml); + regionInfos[i] = + new RegionInfo("REGION CONFIG #" + (i + 1), xmlDoc.FirstChild.ChildNodes[i],false); + } + + return regionInfos; + } + return null; + } + } + } + } +} diff --git a/OpenSim/Framework/SerializableRegionInfo.cs b/OpenSim/Framework/SerializableRegionInfo.cs index 7db6c2988f..500a667e4b 100644 --- a/OpenSim/Framework/SerializableRegionInfo.cs +++ b/OpenSim/Framework/SerializableRegionInfo.cs @@ -1,159 +1,161 @@ -/* -* 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.Net; -using System.Net.Sockets; -using libsecondlife; - -namespace OpenSim.Framework -{ - [Serializable] - public class SearializableRegionInfo - { - /// - /// This is a serializable version of RegionInfo - /// - public SearializableRegionInfo() - { - } - - public SearializableRegionInfo(RegionInfo ConvertFrom) - { - m_regionLocX = ConvertFrom.RegionLocX; - m_regionLocY = ConvertFrom.RegionLocY; - m_internalEndPoint = ConvertFrom.InternalEndPoint; - m_externalHostName = ConvertFrom.ExternalHostName; - m_remotingPort = ConvertFrom.RemotingPort; - RemotingAddress = ConvertFrom.RemotingAddress; - } - - public SearializableRegionInfo(uint regionLocX, uint regionLocY, IPEndPoint internalEndPoint, string externalUri) - { - m_regionLocX = regionLocX; - m_regionLocY = regionLocY; - - m_internalEndPoint = internalEndPoint; - m_externalHostName = externalUri; - } - - public SearializableRegionInfo(uint regionLocX, uint regionLocY, string externalUri, uint port) - { - m_regionLocX = regionLocX; - m_regionLocY = regionLocY; - - m_externalHostName = externalUri; - - m_internalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int) port); - } - - public Guid RegionID = LLUUID.Zero.UUID; - - public uint m_remotingPort; - - public uint RemotingPort - { - get { return m_remotingPort; } - set { m_remotingPort = value; } - } - - public string RemotingAddress; - - - public IPEndPoint ExternalEndPoint - { - get - { - // Old one defaults to IPv6 - //return new IPEndPoint( Dns.GetHostAddresses( m_externalHostName )[0], m_internalEndPoint.Port ); - - IPAddress ia = null; - // If it is already an IP, don't resolve it - just return directly - if (IPAddress.TryParse(m_externalHostName, out ia)) - return new IPEndPoint(ia, m_internalEndPoint.Port); - - // Reset for next check - ia = null; - - - // New method favors IPv4 - foreach (IPAddress Adr in Dns.GetHostAddresses(m_externalHostName)) - { - if (ia == null) - ia = Adr; - - if (Adr.AddressFamily == AddressFamily.InterNetwork) - { - ia = Adr; - break; - } - } - - return new IPEndPoint(ia, m_internalEndPoint.Port); - } - - set { m_externalHostName = value.ToString(); } - } - - protected string m_externalHostName; - - public string ExternalHostName - { - get { return m_externalHostName; } - set { m_externalHostName = value; } - } - - protected IPEndPoint m_internalEndPoint; - - public IPEndPoint InternalEndPoint - { - get { return m_internalEndPoint; } - set { m_internalEndPoint = value; } - } - - protected uint? m_regionLocX; - - public uint RegionLocX - { - get { return m_regionLocX.Value; } - set { m_regionLocX = value; } - } - - protected uint? m_regionLocY; - - public uint RegionLocY - { - get { return m_regionLocY.Value; } - set { m_regionLocY = value; } - } - - public ulong RegionHandle - { - get { return Util.UIntsToLong((RegionLocX*256), (RegionLocY*256)); } - } - } -} \ No newline at end of file +/* +* 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.Net; +using System.Net.Sockets; +using libsecondlife; + +namespace OpenSim.Framework +{ + [Serializable] + public class SearializableRegionInfo + { + /// + /// This is a serializable version of RegionInfo + /// + public SearializableRegionInfo() + { + } + + public SearializableRegionInfo(RegionInfo ConvertFrom) + { + m_regionLocX = ConvertFrom.RegionLocX; + m_regionLocY = ConvertFrom.RegionLocY; + m_internalEndPoint = ConvertFrom.InternalEndPoint; + m_externalHostName = ConvertFrom.ExternalHostName; + m_remotingPort = ConvertFrom.RemotingPort; + m_allow_alternate_ports = ConvertFrom.m_allow_alternate_ports; + RemotingAddress = ConvertFrom.RemotingAddress; + } + + public SearializableRegionInfo(uint regionLocX, uint regionLocY, IPEndPoint internalEndPoint, string externalUri) + { + m_regionLocX = regionLocX; + m_regionLocY = regionLocY; + + m_internalEndPoint = internalEndPoint; + m_externalHostName = externalUri; + } + + public SearializableRegionInfo(uint regionLocX, uint regionLocY, string externalUri, uint port) + { + m_regionLocX = regionLocX; + m_regionLocY = regionLocY; + + m_externalHostName = externalUri; + + m_internalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int) port); + } + + public Guid RegionID = LLUUID.Zero.UUID; + + public uint m_remotingPort; + + public uint RemotingPort + { + get { return m_remotingPort; } + set { m_remotingPort = value; } + } + public bool m_allow_alternate_ports; + + public string RemotingAddress; + + + public IPEndPoint ExternalEndPoint + { + get + { + // Old one defaults to IPv6 + //return new IPEndPoint( Dns.GetHostAddresses( m_externalHostName )[0], m_internalEndPoint.Port ); + + IPAddress ia = null; + // If it is already an IP, don't resolve it - just return directly + if (IPAddress.TryParse(m_externalHostName, out ia)) + return new IPEndPoint(ia, m_internalEndPoint.Port); + + // Reset for next check + ia = null; + + + // New method favors IPv4 + foreach (IPAddress Adr in Dns.GetHostAddresses(m_externalHostName)) + { + if (ia == null) + ia = Adr; + + if (Adr.AddressFamily == AddressFamily.InterNetwork) + { + ia = Adr; + break; + } + } + + return new IPEndPoint(ia, m_internalEndPoint.Port); + } + + set { m_externalHostName = value.ToString(); } + } + + protected string m_externalHostName; + + public string ExternalHostName + { + get { return m_externalHostName; } + set { m_externalHostName = value; } + } + + protected IPEndPoint m_internalEndPoint; + + public IPEndPoint InternalEndPoint + { + get { return m_internalEndPoint; } + set { m_internalEndPoint = value; } + } + + protected uint? m_regionLocX; + + public uint RegionLocX + { + get { return m_regionLocX.Value; } + set { m_regionLocX = value; } + } + + protected uint? m_regionLocY; + + public uint RegionLocY + { + get { return m_regionLocY.Value; } + set { m_regionLocY = value; } + } + + public ulong RegionHandle + { + get { return Util.UIntsToLong((RegionLocX * (uint)Constants.RegionSize), (RegionLocY * (uint)Constants.RegionSize)); } + } + } +} diff --git a/OpenSim/Framework/Servers/BaseHttpServer.cs b/OpenSim/Framework/Servers/BaseHttpServer.cs index f07423cddb..01478e07f4 100644 --- a/OpenSim/Framework/Servers/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/BaseHttpServer.cs @@ -1,616 +1,650 @@ -/* -* 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.IO; -using System.Net; -using System.Text; -using System.Threading; -using System.Xml; -using Nwc.XmlRpc; -using libsecondlife.StructuredData; -using OpenSim.Framework.Console; - -namespace OpenSim.Framework.Servers -{ - public class BaseHttpServer - { - protected Thread m_workerThread; - protected HttpListener m_httpListener; - protected Dictionary m_rpcHandlers = new Dictionary(); - protected LLSDMethod m_llsdHandler = null; - protected Dictionary m_streamHandlers = new Dictionary(); - protected Dictionary m_HTTPHandlers = new Dictionary(); - - protected uint m_port; - protected bool m_ssl = false; - protected bool m_firstcaps = true; - - public uint Port - { - get { return m_port; } - } - - public BaseHttpServer(uint port) - { - m_port = port; - } - - public BaseHttpServer(uint port, bool ssl) - { - m_ssl = ssl; - m_port = port; - } - - public void AddStreamHandler(IRequestHandler handler) - { - string httpMethod = handler.HttpMethod; - string path = handler.Path; - - string handlerKey = GetHandlerKey(httpMethod, path); - m_streamHandlers.Add(handlerKey, handler); - } - - private static string GetHandlerKey(string httpMethod, string path) - { - return httpMethod + ":" + path; - } - - public bool AddXmlRPCHandler(string method, XmlRpcMethod handler) - { - if (!m_rpcHandlers.ContainsKey(method)) - { - m_rpcHandlers.Add(method, handler); - return true; - } - - //must already have a handler for that path so return false - return false; - } - - public bool AddHTTPHandler(string method, GenericHTTPMethod handler) - { - if (!m_HTTPHandlers.ContainsKey(method)) - { - m_HTTPHandlers.Add(method, handler); - return true; - } - - //must already have a handler for that path so return false - return false; - } - - public bool SetLLSDHandler(LLSDMethod handler) - { - m_llsdHandler = handler; - return true; - } - - public virtual void HandleRequest(Object stateinfo) - { - HttpListenerContext context = (HttpListenerContext) stateinfo; - - HttpListenerRequest request = context.Request; - HttpListenerResponse response = context.Response; - - - response.KeepAlive = false; - response.SendChunked = false; - - string path = request.RawUrl; - string handlerKey = GetHandlerKey(request.HttpMethod, path); - - IRequestHandler requestHandler; - - if (TryGetStreamHandler(handlerKey, out requestHandler)) - { - // Okay, so this is bad, but should be considered temporary until everything is IStreamHandler. - byte[] buffer; - if (requestHandler is IStreamedRequestHandler) - { - IStreamedRequestHandler streamedRequestHandler = requestHandler as IStreamedRequestHandler; - buffer = streamedRequestHandler.Handle(path, request.InputStream); - } - else - { - IStreamHandler streamHandler = (IStreamHandler) requestHandler; - - using (MemoryStream memoryStream = new MemoryStream()) - { - streamHandler.Handle(path, request.InputStream, memoryStream); - memoryStream.Flush(); - buffer = memoryStream.ToArray(); - } - } - - request.InputStream.Close(); - response.ContentType = requestHandler.ContentType; - response.ContentLength64 = buffer.LongLength; - response.OutputStream.Write(buffer, 0, buffer.Length); - response.OutputStream.Close(); - } - else - { - switch (request.ContentType) - { - case null: - case "text/html": - HandleHTTPRequest(request, response); - break; - case "application/xml+llsd": - HandleLLSDRequests(request, response); - break; - case "text/xml": - case "application/xml": - default: - HandleXmlRpcRequests(request, response); - break; - } - } - } - - private bool TryGetStreamHandler(string handlerKey, out IRequestHandler streamHandler) - { - string bestMatch = null; - - foreach (string pattern in m_streamHandlers.Keys) - { - if (handlerKey.StartsWith(pattern)) - { - if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length) - { - bestMatch = pattern; - } - } - } - - if (String.IsNullOrEmpty(bestMatch)) - { - streamHandler = null; - return false; - } - else - { - streamHandler = m_streamHandlers[bestMatch]; - return true; - } - } - - private bool TryGetHTTPHandler(string handlerKey, out GenericHTTPMethod HTTPHandler) - { - string bestMatch = null; - - foreach (string pattern in m_HTTPHandlers.Keys) - { - if (handlerKey.StartsWith(pattern)) - { - if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length) - { - bestMatch = pattern; - } - } - } - - if (String.IsNullOrEmpty(bestMatch)) - { - HTTPHandler = null; - return false; - } - else - { - HTTPHandler = m_HTTPHandlers[bestMatch]; - return true; - } - } - private void HandleXmlRpcRequests(HttpListenerRequest request, HttpListenerResponse response) - { - Stream requestStream = request.InputStream; - - Encoding encoding = Encoding.UTF8; - StreamReader reader = new StreamReader(requestStream, encoding); - - string requestBody = reader.ReadToEnd(); - reader.Close(); - requestStream.Close(); - - string responseString = String.Empty; - XmlRpcRequest xmlRprcRequest = null; - - try - { - xmlRprcRequest = (XmlRpcRequest) (new XmlRpcRequestDeserializer()).Deserialize(requestBody); - } - catch (XmlException e) - { - - } - - if (xmlRprcRequest != null) - { - string methodName = xmlRprcRequest.MethodName; - if (methodName != null) - { - XmlRpcResponse xmlRpcResponse; - - XmlRpcMethod method; - if (m_rpcHandlers.TryGetValue(methodName, out method)) - { - xmlRpcResponse = method(xmlRprcRequest); - } - else - { - xmlRpcResponse = new XmlRpcResponse(); - Hashtable unknownMethodError = new Hashtable(); - unknownMethodError["reason"] = "XmlRequest"; - ; - unknownMethodError["message"] = "Unknown Rpc Request [" + methodName + "]"; - unknownMethodError["login"] = "false"; - xmlRpcResponse.Value = unknownMethodError; - } - - responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse); - } - else - { - System.Console.WriteLine("Handler not found for http request " + request.RawUrl); - responseString = "Error"; - } - } - - response.ContentType = "text/xml"; - - byte[] buffer = Encoding.UTF8.GetBytes(responseString); - - response.SendChunked = false; - response.ContentLength64 = buffer.Length; - response.ContentEncoding = Encoding.UTF8; - try - { - response.OutputStream.Write(buffer, 0, buffer.Length); - } - catch (Exception ex) - { - MainLog.Instance.Warn("HTTPD", "Error - " + ex.Message); - } - finally - { - try - { - response.OutputStream.Flush(); - response.OutputStream.Close(); - } - catch (Exception ex) - { - MainLog.Instance.Warn("HTTPD", "Error closing - " + ex.Message); - } - } - } - - private void HandleLLSDRequests(HttpListenerRequest request, HttpListenerResponse response) - { - Stream requestStream = request.InputStream; - - Encoding encoding = Encoding.UTF8; - StreamReader reader = new StreamReader(requestStream, encoding); - - string requestBody = reader.ReadToEnd(); - reader.Close(); - requestStream.Close(); - - LLSD llsdRequest = null; - LLSD llsdResponse = null; - - try { llsdRequest = LLSDParser.DeserializeXml(requestBody); } - catch (Exception ex) { MainLog.Instance.Warn("HTTPD", "Error - " + ex.Message); } - - if (llsdRequest != null && m_llsdHandler != null) - { - llsdResponse = m_llsdHandler(llsdRequest); - } - else - { - LLSDMap map = new LLSDMap(); - map["reason"] = LLSD.FromString("LLSDRequest"); - map["message"] = LLSD.FromString("No handler registered for LLSD Requests"); - map["login"] = LLSD.FromString("false"); - llsdResponse = map; - } - - response.ContentType = "application/xml+llsd"; - - byte[] buffer = LLSDParser.SerializeXmlBytes(llsdResponse); - - response.SendChunked = false; - response.ContentLength64 = buffer.Length; - response.ContentEncoding = Encoding.UTF8; - - try - { - response.OutputStream.Write(buffer, 0, buffer.Length); - } - catch (Exception ex) - { - MainLog.Instance.Warn("HTTPD", "Error - " + ex.Message); - } - finally - { - try - { - response.OutputStream.Flush(); - response.OutputStream.Close(); - } - catch (Exception ex) - { - MainLog.Instance.Warn("HTTPD", "Error closing - " + ex.Message); - } - } - } - - public void HandleHTTPRequest(HttpListenerRequest request, HttpListenerResponse response) - { - // This is a test. There's a workable alternative.. as this way sucks. - // We'd like to put this into a text file parhaps that's easily editable. - // - // For this test to work, I used the following secondlife.exe parameters - // "C:\Program Files\SecondLifeWindLight\SecondLifeWindLight.exe" -settings settings_windlight.xml -channel "Second Life WindLight" -set SystemLanguage en-us -loginpage http://10.1.1.2:8002/?show_login_form=TRUE -loginuri http://10.1.1.2:8002 -user 10.1.1.2 - // - // Even after all that, there's still an error, but it's a start. - // - // I depend on show_login_form being in the secondlife.exe parameters to figure out - // to display the form, or process it. - // a better way would be nifty. - Stream requestStream = request.InputStream; - - Encoding encoding = Encoding.UTF8; - StreamReader reader = new StreamReader(requestStream, encoding); - - string requestBody = reader.ReadToEnd(); - reader.Close(); - requestStream.Close(); - - string responseString = String.Empty; - - Hashtable keysvals = new Hashtable(); - - string[] querystringkeys = request.QueryString.AllKeys; - string[] rHeaders = request.Headers.AllKeys; - - - foreach (string queryname in querystringkeys) - { - keysvals.Add(queryname, request.QueryString[queryname]); - MainLog.Instance.Warn("HTTP", queryname + "=" + request.QueryString[queryname]); - } - //foreach (string headername in rHeaders) - //{ - //MainLog.Instance.Warn("HEADER", headername + "=" + request.Headers[headername]); - //} - if (keysvals.Contains("method")) - { - MainLog.Instance.Warn("HTTP", "Contains Method"); - string method = (string) keysvals["method"]; - MainLog.Instance.Warn("HTTP", requestBody); - GenericHTTPMethod requestprocessor; - bool foundHandler = TryGetHTTPHandler(method, out requestprocessor); - if (foundHandler) - { - Hashtable responsedata = requestprocessor(keysvals); - DoHTTPGruntWork(responsedata,response); - - //SendHTML500(response); - - } - else - { - MainLog.Instance.Warn("HTTP", "Handler Not Found"); - SendHTML404(response); - } - } - else - { - MainLog.Instance.Warn("HTTP", "No Method specified"); - SendHTML404(response); - } - } - - private void DoHTTPGruntWork(Hashtable responsedata, HttpListenerResponse response) - { - int responsecode = (int)responsedata["int_response_code"]; - string responseString = (string)responsedata["str_response_string"]; - - // We're forgoing the usual error status codes here because the client - // ignores anything but 200 and 301 - - response.StatusCode = 200; - - if (responsecode == 301) - { - response.RedirectLocation = (string)responsedata["str_redirect_location"]; - response.StatusCode = responsecode; - } - response.AddHeader("Content-type", "text/html"); - - byte[] buffer = Encoding.UTF8.GetBytes(responseString); - - response.SendChunked = false; - response.ContentLength64 = buffer.Length; - response.ContentEncoding = Encoding.UTF8; - try - { - response.OutputStream.Write(buffer, 0, buffer.Length); - } - catch (Exception ex) - { - MainLog.Instance.Warn("HTTPD", "Error - " + ex.Message); - } - finally - { - response.OutputStream.Close(); - } - - - } - public void SendHTML404(HttpListenerResponse response) - { - // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s - response.StatusCode = 200; - response.AddHeader("Content-type", "text/html"); - - string responseString = GetHTTP404(); - byte[] buffer = Encoding.UTF8.GetBytes(responseString); - - response.SendChunked = false; - response.ContentLength64 = buffer.Length; - response.ContentEncoding = Encoding.UTF8; - try - { - response.OutputStream.Write(buffer, 0, buffer.Length); - } - catch (Exception ex) - { - MainLog.Instance.Warn("HTTPD", "Error - " + ex.Message); - } - finally - { - response.OutputStream.Close(); - } - } - public void SendHTML500(HttpListenerResponse response) - { - // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s - response.StatusCode = 200; - response.AddHeader("Content-type", "text/html"); - - string responseString = GetHTTP500(); - byte[] buffer = Encoding.UTF8.GetBytes(responseString); - - response.SendChunked = false; - response.ContentLength64 = buffer.Length; - response.ContentEncoding = Encoding.UTF8; - try - { - response.OutputStream.Write(buffer, 0, buffer.Length); - } - catch (Exception ex) - { - MainLog.Instance.Warn("HTTPD", "Error - " + ex.Message); - } - finally - { - response.OutputStream.Close(); - } - } - - public void Start() - { - MainLog.Instance.Verbose("HTTPD", "Starting up HTTP Server"); - - m_workerThread = new Thread(new ThreadStart(StartHTTP)); - m_workerThread.IsBackground = true; - m_workerThread.Start(); - } - - private void StartHTTP() - { - try - { - MainLog.Instance.Verbose("HTTPD", "Spawned main thread OK"); - m_httpListener = new HttpListener(); - - if (!m_ssl) - { - m_httpListener.Prefixes.Add("http://+:" + m_port + "/"); - } - else - { - m_httpListener.Prefixes.Add("https://+:" + m_port + "/"); - } - m_httpListener.Start(); - - HttpListenerContext context; - while (true) - { - context = m_httpListener.GetContext(); - ThreadPool.QueueUserWorkItem(new WaitCallback(HandleRequest), context); - } - } - catch (Exception e) - { - MainLog.Instance.Warn("HTTPD", "Error - " + e.Message); - } - } - - - public void RemoveStreamHandler(string httpMethod, string path) - { - m_streamHandlers.Remove(GetHandlerKey(httpMethod, path)); - } - - public void RemoveHTTPHandler(string httpMethod, string path) - { - m_HTTPHandlers.Remove(GetHandlerKey(httpMethod, path)); - } - - public string GetHTTP404() - { - string file = Path.Combine(Util.configDir(), "http_404.html"); - if (!File.Exists(file)) - return getDefaultHTTP404(); - - StreamReader sr = File.OpenText(file); - string result = sr.ReadToEnd(); - sr.Close(); - return result; - } - - public string GetHTTP500() - { - string file = Path.Combine(Util.configDir(), "http_500.html"); - if (!File.Exists(file)) - return getDefaultHTTP500(); - - StreamReader sr = File.OpenText(file); - string result = sr.ReadToEnd(); - sr.Close(); - return result; - } - - // Fallback HTTP responses in case the HTTP error response files don't exist - private string getDefaultHTTP404() - { - return "404 Page not found

Ooops!

The page you requested has been obsconded with by knomes. Find hippos quick!

"; - } - - private string getDefaultHTTP500() - { - return "500 Internal Server Error

Ooops!

The server you requested is overun by knomes! Find hippos quick!

"; - } - - } -} +/* +* 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.IO; +using System.Net; +using System.Text; +using System.Threading; +using System.Xml; +using Nwc.XmlRpc; +using libsecondlife.StructuredData; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Servers +{ + public class BaseHttpServer + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + protected Thread m_workerThread; + protected HttpListener m_httpListener; + protected Dictionary m_rpcHandlers = new Dictionary(); + protected LLSDMethod m_llsdHandler = null; + protected Dictionary m_streamHandlers = new Dictionary(); + protected Dictionary m_HTTPHandlers = new Dictionary(); + + protected uint m_port; + protected bool m_ssl = false; + protected bool m_firstcaps = true; + + public uint Port + { + get { return m_port; } + } + + public BaseHttpServer(uint port) + { + m_port = port; + } + + public BaseHttpServer(uint port, bool ssl) + { + m_ssl = ssl; + m_port = port; + } + + public void AddStreamHandler(IRequestHandler handler) + { + string httpMethod = handler.HttpMethod; + string path = handler.Path; + + string handlerKey = GetHandlerKey(httpMethod, path); + m_streamHandlers.Add(handlerKey, handler); + } + + private static string GetHandlerKey(string httpMethod, string path) + { + return httpMethod + ":" + path; + } + + public bool AddXmlRPCHandler(string method, XmlRpcMethod handler) + { + if (!m_rpcHandlers.ContainsKey(method)) + { + m_rpcHandlers.Add(method, handler); + return true; + } + + //must already have a handler for that path so return false + return false; + } + + public bool AddHTTPHandler(string method, GenericHTTPMethod handler) + { + if (!m_HTTPHandlers.ContainsKey(method)) + { + m_HTTPHandlers.Add(method, handler); + return true; + } + + //must already have a handler for that path so return false + return false; + } + + public bool SetLLSDHandler(LLSDMethod handler) + { + m_llsdHandler = handler; + return true; + } + + public virtual void HandleRequest(Object stateinfo) + { + HttpListenerContext context = (HttpListenerContext) stateinfo; + + HttpListenerRequest request = context.Request; + HttpListenerResponse response = context.Response; + + + response.KeepAlive = false; + response.SendChunked = false; + + string path = request.RawUrl; + string handlerKey = GetHandlerKey(request.HttpMethod, path); + + IRequestHandler requestHandler; + + if (TryGetStreamHandler(handlerKey, out requestHandler)) + { + // Okay, so this is bad, but should be considered temporary until everything is IStreamHandler. + byte[] buffer; + if (requestHandler is IStreamedRequestHandler) + { + IStreamedRequestHandler streamedRequestHandler = requestHandler as IStreamedRequestHandler; + buffer = streamedRequestHandler.Handle(path, request.InputStream); + } + else + { + IStreamHandler streamHandler = (IStreamHandler) requestHandler; + + using (MemoryStream memoryStream = new MemoryStream()) + { + streamHandler.Handle(path, request.InputStream, memoryStream); + memoryStream.Flush(); + buffer = memoryStream.ToArray(); + } + } + + request.InputStream.Close(); + response.ContentType = requestHandler.ContentType; + response.ContentLength64 = buffer.LongLength; + response.OutputStream.Write(buffer, 0, buffer.Length); + response.OutputStream.Close(); + } + else + { + switch (request.ContentType) + { + case null: + case "text/html": + HandleHTTPRequest(request, response); + break; + case "application/xml+llsd": + HandleLLSDRequests(request, response); + break; + case "text/xml": + case "application/xml": + default: + HandleXmlRpcRequests(request, response); + break; + } + } + } + + private bool TryGetStreamHandler(string handlerKey, out IRequestHandler streamHandler) + { + string bestMatch = null; + + foreach (string pattern in m_streamHandlers.Keys) + { + if (handlerKey.StartsWith(pattern)) + { + if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length) + { + bestMatch = pattern; + } + } + } + + if (String.IsNullOrEmpty(bestMatch)) + { + streamHandler = null; + return false; + } + else + { + streamHandler = m_streamHandlers[bestMatch]; + return true; + } + } + + private bool TryGetHTTPHandler(string handlerKey, out GenericHTTPMethod HTTPHandler) + { + string bestMatch = null; + + foreach (string pattern in m_HTTPHandlers.Keys) + { + if (handlerKey.StartsWith(pattern)) + { + if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length) + { + bestMatch = pattern; + } + } + } + + if (String.IsNullOrEmpty(bestMatch)) + { + HTTPHandler = null; + return false; + } + else + { + HTTPHandler = m_HTTPHandlers[bestMatch]; + return true; + } + } + + /// + /// Try all the registered xmlrpc handlers when an xmlrpc request is received. + /// Sends back an XMLRPC unknown request response if no handler is registered for the requested method. + /// + /// + /// + private void HandleXmlRpcRequests(HttpListenerRequest request, HttpListenerResponse response) + { + Stream requestStream = request.InputStream; + + Encoding encoding = Encoding.UTF8; + StreamReader reader = new StreamReader(requestStream, encoding); + + string requestBody = reader.ReadToEnd(); + reader.Close(); + requestStream.Close(); + + string responseString = String.Empty; + XmlRpcRequest xmlRprcRequest = null; + + try + { + xmlRprcRequest = (XmlRpcRequest) (new XmlRpcRequestDeserializer()).Deserialize(requestBody); + } + catch (XmlException e) + { + + } + + if (xmlRprcRequest != null) + { + string methodName = xmlRprcRequest.MethodName; + if (methodName != null) + { + XmlRpcResponse xmlRpcResponse; + + XmlRpcMethod method; + if (m_rpcHandlers.TryGetValue(methodName, out method)) + { + xmlRpcResponse = method(xmlRprcRequest); + } + else + { + xmlRpcResponse = new XmlRpcResponse(); + // Code set in accordance with http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php + xmlRpcResponse.SetFault(-32601, String.Format("Requested method [{0}] not found", methodName)); + } + + responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse); + } + else + { + System.Console.WriteLine("Handler not found for http request " + request.RawUrl); + responseString = "Error"; + } + } + + response.ContentType = "text/xml"; + + byte[] buffer = Encoding.UTF8.GetBytes(responseString); + + response.SendChunked = false; + response.ContentLength64 = buffer.Length; + response.ContentEncoding = Encoding.UTF8; + try + { + response.OutputStream.Write(buffer, 0, buffer.Length); + } + catch (Exception ex) + { + m_log.Warn("[HTTPD]: Error - " + ex.Message); + } + finally + { + try + { + response.OutputStream.Flush(); + response.OutputStream.Close(); + } + catch (Exception ex) + { + MainLog.Instance.Warn("HTTPD", "Error closing - " + ex.Message); + } + } + } + + private void HandleLLSDRequests(HttpListenerRequest request, HttpListenerResponse response) + { + Stream requestStream = request.InputStream; + + Encoding encoding = Encoding.UTF8; + StreamReader reader = new StreamReader(requestStream, encoding); + + string requestBody = reader.ReadToEnd(); + reader.Close(); + requestStream.Close(); + + LLSD llsdRequest = null; + LLSD llsdResponse = null; + + try { llsdRequest = LLSDParser.DeserializeXml(requestBody); } + catch (Exception ex) { m_log.Warn("[HTTPD]: Error - " + ex.Message); } + + if (llsdRequest != null && m_llsdHandler != null) + { + llsdResponse = m_llsdHandler(llsdRequest); + } + else + { + LLSDMap map = new LLSDMap(); + map["reason"] = LLSD.FromString("LLSDRequest"); + map["message"] = LLSD.FromString("No handler registered for LLSD Requests"); + map["login"] = LLSD.FromString("false"); + llsdResponse = map; + } + + response.ContentType = "application/xml+llsd"; + + byte[] buffer = LLSDParser.SerializeXmlBytes(llsdResponse); + + response.SendChunked = false; + response.ContentLength64 = buffer.Length; + response.ContentEncoding = Encoding.UTF8; + + try + { + response.OutputStream.Write(buffer, 0, buffer.Length); + } + catch (Exception ex) + { + m_log.Warn("[HTTPD]: Error - " + ex.Message); + } + finally + { + try + { + response.OutputStream.Flush(); + response.OutputStream.Close(); + } + catch (Exception ex) + { + MainLog.Instance.Warn("HTTPD", "Error closing - " + ex.Message); + } + } + } + + public void HandleHTTPRequest(HttpListenerRequest request, HttpListenerResponse response) + { + switch( request.HttpMethod ) + { + case "OPTIONS": + response.StatusCode = 200; + return; + + default: + HandleContentVerbs(request, response); + return; + } + } + + private void HandleContentVerbs(HttpListenerRequest request, HttpListenerResponse response) + { + // This is a test. There's a workable alternative.. as this way sucks. + // We'd like to put this into a text file parhaps that's easily editable. + // + // For this test to work, I used the following secondlife.exe parameters + // "C:\Program Files\SecondLifeWindLight\SecondLifeWindLight.exe" -settings settings_windlight.xml -channel "Second Life WindLight" -set SystemLanguage en-us -loginpage http://10.1.1.2:8002/?show_login_form=TRUE -loginuri http://10.1.1.2:8002 -user 10.1.1.2 + // + // Even after all that, there's still an error, but it's a start. + // + // I depend on show_login_form being in the secondlife.exe parameters to figure out + // to display the form, or process it. + // a better way would be nifty. + + + Stream requestStream = request.InputStream; + + Encoding encoding = Encoding.UTF8; + StreamReader reader = new StreamReader(requestStream, encoding); + + string requestBody = reader.ReadToEnd(); + reader.Close(); + requestStream.Close(); + + string responseString = String.Empty; + + Hashtable keysvals = new Hashtable(); + Hashtable headervals = new Hashtable(); + string host = String.Empty; + + string[] querystringkeys = request.QueryString.AllKeys; + string[] rHeaders = request.Headers.AllKeys; + + + foreach (string queryname in querystringkeys) + { + keysvals.Add(queryname, request.QueryString[queryname]); + + } + + foreach (string headername in rHeaders) + { + //m_log.Warn("[HEADER]: " + headername + "=" + request.Headers[headername]); + headervals[headername] = request.Headers[headername]; + } + + if (headervals.Contains("Host")) + { + host = (string)headervals["Host"]; + } + + if (keysvals.Contains("method")) + { + //m_log.Warn("[HTTP]: Contains Method"); + string method = (string) keysvals["method"]; + //m_log.Warn("[HTTP]: " + requestBody); + GenericHTTPMethod requestprocessor; + bool foundHandler = TryGetHTTPHandler(method, out requestprocessor); + if (foundHandler) + { + Hashtable responsedata = requestprocessor(keysvals); + DoHTTPGruntWork(responsedata,response); + + //SendHTML500(response); + + } + else + { + //m_log.Warn("[HTTP]: Handler Not Found"); + SendHTML404(response, host); + } + } + else + { + //m_log.Warn("[HTTP]: No Method specified"); + SendHTML404(response, host); + } + } + + private void DoHTTPGruntWork(Hashtable responsedata, HttpListenerResponse response) + { + int responsecode = (int)responsedata["int_response_code"]; + string responseString = (string)responsedata["str_response_string"]; + + // We're forgoing the usual error status codes here because the client + // ignores anything but 200 and 301 + + response.StatusCode = 200; + + if (responsecode == 301) + { + response.RedirectLocation = (string)responsedata["str_redirect_location"]; + response.StatusCode = responsecode; + } + response.AddHeader("Content-type", "text/html"); + + byte[] buffer = Encoding.UTF8.GetBytes(responseString); + + response.SendChunked = false; + response.ContentLength64 = buffer.Length; + response.ContentEncoding = Encoding.UTF8; + try + { + response.OutputStream.Write(buffer, 0, buffer.Length); + } + catch (Exception ex) + { + m_log.Warn("[HTTPD]: Error - " + ex.Message); + } + finally + { + response.OutputStream.Close(); + } + + + } + public void SendHTML404(HttpListenerResponse response, string host) + { + // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s + response.StatusCode = 200; + response.AddHeader("Content-type", "text/html"); + + string responseString = GetHTTP404(host); + byte[] buffer = Encoding.UTF8.GetBytes(responseString); + + response.SendChunked = false; + response.ContentLength64 = buffer.Length; + response.ContentEncoding = Encoding.UTF8; + try + { + response.OutputStream.Write(buffer, 0, buffer.Length); + } + catch (Exception ex) + { + m_log.Warn("[HTTPD]: Error - " + ex.Message); + } + finally + { + response.OutputStream.Close(); + } + } + public void SendHTML500(HttpListenerResponse response) + { + // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s + response.StatusCode = 200; + response.AddHeader("Content-type", "text/html"); + + string responseString = GetHTTP500(); + byte[] buffer = Encoding.UTF8.GetBytes(responseString); + + response.SendChunked = false; + response.ContentLength64 = buffer.Length; + response.ContentEncoding = Encoding.UTF8; + try + { + response.OutputStream.Write(buffer, 0, buffer.Length); + } + catch (Exception ex) + { + m_log.Warn("[HTTPD]: Error - " + ex.Message); + } + finally + { + response.OutputStream.Close(); + } + } + + public void Start() + { + m_log.Info("[HTTPD]: Starting up HTTP Server"); + + m_workerThread = new Thread(new ThreadStart(StartHTTP)); + m_workerThread.Name = "HttpThread"; + m_workerThread.IsBackground = true; + m_workerThread.Start(); + OpenSim.Framework.ThreadTracker.Add(m_workerThread); + } + + private void StartHTTP() + { + try + { + m_log.Info("[HTTPD]: Spawned main thread OK"); + m_httpListener = new HttpListener(); + + if (!m_ssl) + { + m_httpListener.Prefixes.Add("http://+:" + m_port + "/"); + } + else + { + m_httpListener.Prefixes.Add("https://+:" + m_port + "/"); + } + m_httpListener.Start(); + + HttpListenerContext context; + while (true) + { + context = m_httpListener.GetContext(); + ThreadPool.QueueUserWorkItem(new WaitCallback(HandleRequest), context); + } + } + catch (Exception e) + { + m_log.Warn("[HTTPD]: Error - " + e.Message); + m_log.Warn("Tip: Do you have permission to listen on port " + m_port + "?"); + } + } + + + public void RemoveStreamHandler(string httpMethod, string path) + { + m_streamHandlers.Remove(GetHandlerKey(httpMethod, path)); + } + + public void RemoveHTTPHandler(string httpMethod, string path) + { + m_HTTPHandlers.Remove(GetHandlerKey(httpMethod, path)); + } + + public string GetHTTP404(string host) + { + string file = Path.Combine(Util.configDir(), "http_404.html"); + if (!File.Exists(file)) + return getDefaultHTTP404(host); + + StreamReader sr = File.OpenText(file); + string result = sr.ReadToEnd(); + sr.Close(); + return result; + } + + public string GetHTTP500() + { + string file = Path.Combine(Util.configDir(), "http_500.html"); + if (!File.Exists(file)) + return getDefaultHTTP500(); + + StreamReader sr = File.OpenText(file); + string result = sr.ReadToEnd(); + sr.Close(); + return result; + } + + // Fallback HTTP responses in case the HTTP error response files don't exist + private string getDefaultHTTP404(string host) + { + return "404 Page not found

Ooops!

The page you requested has been obsconded with by knomes. Find hippos quick!

If you are trying to log-in, your link parameters should have: "-loginpage http://" + host + "/?method=login -loginuri http://" + host + "/" in your link

"; + } + + private string getDefaultHTTP500() + { + return "500 Internal Server Error

Ooops!

The server you requested is overun by knomes! Find hippos quick!

"; + } + + } +} diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs new file mode 100644 index 0000000000..4831446b5b --- /dev/null +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -0,0 +1,84 @@ +/* +* 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 OpenSim.Framework.Console; + +namespace OpenSim.Framework.Servers +{ + /// + /// Common base for the main OpenSimServers (user, grid, inventory, region, etc) + /// + public abstract class BaseOpenSimServer + { + protected ConsoleBase m_console; + protected DateTime m_startuptime; + + public BaseOpenSimServer() + { + m_startuptime = DateTime.Now; + } + + /// + /// Runs commands issued by the server console from the operator + /// + /// The first argument of the parameter (the command) + /// Additional arguments passed to the command + public virtual void RunCmd(string command, string[] cmdparams) + { + switch (command) + { + case "help": + m_console.Notice("show uptime - show server startup and uptime."); + break; + + case "show": + if (cmdparams.Length > 0) + { + Show(cmdparams[0]); + } + break; + } + } + + /// + /// Outputs to the console information about the region + /// + /// What information to display (valid arguments are "uptime", "users") + public virtual void Show(string ShowWhat) + { + switch (ShowWhat) + { + case "uptime": + m_console.Notice("Server has been running since " + m_startuptime.ToString()); + m_console.Notice("That is " + (DateTime.Now - m_startuptime).ToString()); + break; + } + } + } +} diff --git a/OpenSim/Framework/Servers/BaseStreamHandler.cs b/OpenSim/Framework/Servers/BaseStreamHandler.cs index 97779d4b36..aed0a5d5ed 100644 --- a/OpenSim/Framework/Servers/BaseStreamHandler.cs +++ b/OpenSim/Framework/Servers/BaseStreamHandler.cs @@ -1,41 +1,41 @@ -/* -* 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.IO; - -namespace OpenSim.Framework.Servers -{ - public abstract class BaseStreamHandler : BaseRequestHandler, IStreamedRequestHandler - { - public abstract byte[] Handle(string path, Stream request); - - protected BaseStreamHandler(string httpMethod, string path) : base(httpMethod, path) - { - } - } -} \ No newline at end of file +/* +* 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.IO; + +namespace OpenSim.Framework.Servers +{ + public abstract class BaseStreamHandler : BaseRequestHandler, IStreamedRequestHandler + { + public abstract byte[] Handle(string path, Stream request); + + protected BaseStreamHandler(string httpMethod, string path) : base(httpMethod, path) + { + } + } +} diff --git a/OpenSim/Framework/Servers/BinaryStreamHandler.cs b/OpenSim/Framework/Servers/BinaryStreamHandler.cs index 4c961a049e..c5cdd150cd 100644 --- a/OpenSim/Framework/Servers/BinaryStreamHandler.cs +++ b/OpenSim/Framework/Servers/BinaryStreamHandler.cs @@ -1,74 +1,74 @@ -/* -* 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.IO; -using System.Text; - -namespace OpenSim.Framework.Servers -{ - public delegate string BinaryMethod(byte[] data, string path, string param); - - public class BinaryStreamHandler : BaseStreamHandler - { - private BinaryMethod m_method; - - public override byte[] Handle(string path, Stream request) - { - byte[] data = ReadFully(request); - string param = GetParam(path); - string responseString = m_method(data, path, param); - - return Encoding.UTF8.GetBytes(responseString); - } - - public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod) - : base(httpMethod, path) - { - m_method = binaryMethod; - } - - private byte[] ReadFully(Stream stream) - { - byte[] buffer = new byte[32768]; - using (MemoryStream ms = new MemoryStream()) - { - while (true) - { - int read = stream.Read(buffer, 0, buffer.Length); - - if (read <= 0) - { - return ms.ToArray(); - } - - ms.Write(buffer, 0, read); - } - } - } - } -} \ No newline at end of file +/* +* 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.IO; +using System.Text; + +namespace OpenSim.Framework.Servers +{ + public delegate string BinaryMethod(byte[] data, string path, string param); + + public class BinaryStreamHandler : BaseStreamHandler + { + private BinaryMethod m_method; + + public override byte[] Handle(string path, Stream request) + { + byte[] data = ReadFully(request); + string param = GetParam(path); + string responseString = m_method(data, path, param); + + return Encoding.UTF8.GetBytes(responseString); + } + + public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod) + : base(httpMethod, path) + { + m_method = binaryMethod; + } + + private byte[] ReadFully(Stream stream) + { + byte[] buffer = new byte[32768]; + using (MemoryStream ms = new MemoryStream()) + { + while (true) + { + int read = stream.Read(buffer, 0, buffer.Length); + + if (read <= 0) + { + return ms.ToArray(); + } + + ms.Write(buffer, 0, read); + } + } + } + } +} diff --git a/OpenSim/Framework/Servers/CheckSumServer.cs b/OpenSim/Framework/Servers/CheckSumServer.cs index 71d2b03264..ae0ead7c49 100644 --- a/OpenSim/Framework/Servers/CheckSumServer.cs +++ b/OpenSim/Framework/Servers/CheckSumServer.cs @@ -1,127 +1,127 @@ -/* -* 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. -* -*/ - -namespace OpenSim.Framework.Servers -{ - /* - public class CheckSumServer : UDPServerBase - { - //protected ConsoleBase m_log; - - public CheckSumServer(int port) - : base(port) - { - } - - protected override void OnReceivedData(IAsyncResult result) - { - ipeSender = new IPEndPoint(IPAddress.Any, 0); - epSender = (EndPoint)ipeSender; - Packet packet = null; - int numBytes = Server.EndReceiveFrom(result, ref epSender); - int packetEnd = numBytes - 1; - - packet = Packet.BuildPacket(RecvBuffer, ref packetEnd, ZeroBuffer); - - if (packet.Type == PacketType.SecuredTemplateChecksumRequest) - { - SecuredTemplateChecksumRequestPacket checksum = (SecuredTemplateChecksumRequestPacket)packet; - TemplateChecksumReplyPacket checkreply = new TemplateChecksumReplyPacket(); - checkreply.DataBlock.Checksum = 3220703154;//180572585; - checkreply.DataBlock.Flags = 0; - checkreply.DataBlock.MajorVersion = 1; - checkreply.DataBlock.MinorVersion = 15; - checkreply.DataBlock.PatchVersion = 0; - checkreply.DataBlock.ServerVersion = 0; - checkreply.TokenBlock.Token = checksum.TokenBlock.Token; - this.SendPacket(checkreply, epSender); - - /* - //if we wanted to echo the the checksum/ version from the client (so that any client worked) - SecuredTemplateChecksumRequestPacket checkrequest = new SecuredTemplateChecksumRequestPacket(); - checkrequest.TokenBlock.Token = checksum.TokenBlock.Token; - this.SendPacket(checkrequest, epSender); - - } - else if (packet.Type == PacketType.TemplateChecksumReply) - { - //echo back the client checksum reply (Hegemon's method) - TemplateChecksumReplyPacket checksum2 = (TemplateChecksumReplyPacket)packet; - TemplateChecksumReplyPacket checkreply2 = new TemplateChecksumReplyPacket(); - checkreply2.DataBlock.Checksum = checksum2.DataBlock.Checksum; - checkreply2.DataBlock.Flags = checksum2.DataBlock.Flags; - checkreply2.DataBlock.MajorVersion = checksum2.DataBlock.MajorVersion; - checkreply2.DataBlock.MinorVersion = checksum2.DataBlock.MinorVersion; - checkreply2.DataBlock.PatchVersion = checksum2.DataBlock.PatchVersion; - checkreply2.DataBlock.ServerVersion = checksum2.DataBlock.ServerVersion; - checkreply2.TokenBlock.Token = checksum2.TokenBlock.Token; - this.SendPacket(checkreply2, epSender); - } - else - { - } - - Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); - } - - private void SendPacket(Packet Pack, EndPoint endp) - { - if (!Pack.Header.Resent) - { - Pack.Header.Sequence = 1; - } - - byte[] ZeroOutBuffer = new byte[4096]; - byte[] sendbuffer; - sendbuffer = Pack.ToBytes(); - - try - { - if (Pack.Header.Zerocoded) - { - int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer); - this.SendPackTo(ZeroOutBuffer, packetsize, SocketFlags.None, endp); - } - else - { - this.SendPackTo(sendbuffer, sendbuffer.Length, SocketFlags.None, endp); - } - } - catch (Exception) - { - MainLog.Instance.Warn("CheckSumServer.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection "); - } - } - - private void SendPackTo(byte[] buffer, int size, SocketFlags flags, EndPoint endp) - { - this.Server.SendTo(buffer, size, flags, endp); - } - * } - */ -} \ No newline at end of file +/* +* 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. +* +*/ + +namespace OpenSim.Framework.Servers +{ + /* + public class CheckSumServer : UDPServerBase + { + private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + public CheckSumServer(int port) + : base(port) + { + } + + protected override void OnReceivedData(IAsyncResult result) + { + ipeSender = new IPEndPoint(IPAddress.Any, 0); + epSender = (EndPoint)ipeSender; + Packet packet = null; + int numBytes = Server.EndReceiveFrom(result, ref epSender); + int packetEnd = numBytes - 1; + + packet = Packet.BuildPacket(RecvBuffer, ref packetEnd, ZeroBuffer); + + if (packet.Type == PacketType.SecuredTemplateChecksumRequest) + { + SecuredTemplateChecksumRequestPacket checksum = (SecuredTemplateChecksumRequestPacket)packet; + TemplateChecksumReplyPacket checkreply = new TemplateChecksumReplyPacket(); + checkreply.DataBlock.Checksum = 3220703154;//180572585; + checkreply.DataBlock.Flags = 0; + checkreply.DataBlock.MajorVersion = 1; + checkreply.DataBlock.MinorVersion = 15; + checkreply.DataBlock.PatchVersion = 0; + checkreply.DataBlock.ServerVersion = 0; + checkreply.TokenBlock.Token = checksum.TokenBlock.Token; + this.SendPacket(checkreply, epSender); + + /* + //if we wanted to echo the the checksum/ version from the client (so that any client worked) + SecuredTemplateChecksumRequestPacket checkrequest = new SecuredTemplateChecksumRequestPacket(); + checkrequest.TokenBlock.Token = checksum.TokenBlock.Token; + this.SendPacket(checkrequest, epSender); + + } + else if (packet.Type == PacketType.TemplateChecksumReply) + { + //echo back the client checksum reply (Hegemon's method) + TemplateChecksumReplyPacket checksum2 = (TemplateChecksumReplyPacket)packet; + TemplateChecksumReplyPacket checkreply2 = new TemplateChecksumReplyPacket(); + checkreply2.DataBlock.Checksum = checksum2.DataBlock.Checksum; + checkreply2.DataBlock.Flags = checksum2.DataBlock.Flags; + checkreply2.DataBlock.MajorVersion = checksum2.DataBlock.MajorVersion; + checkreply2.DataBlock.MinorVersion = checksum2.DataBlock.MinorVersion; + checkreply2.DataBlock.PatchVersion = checksum2.DataBlock.PatchVersion; + checkreply2.DataBlock.ServerVersion = checksum2.DataBlock.ServerVersion; + checkreply2.TokenBlock.Token = checksum2.TokenBlock.Token; + this.SendPacket(checkreply2, epSender); + } + else + { + } + + Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); + } + + private void SendPacket(Packet Pack, EndPoint endp) + { + if (!Pack.Header.Resent) + { + Pack.Header.Sequence = 1; + } + + byte[] ZeroOutBuffer = new byte[4096]; + byte[] sendbuffer; + sendbuffer = Pack.ToBytes(); + + try + { + if (Pack.Header.Zerocoded) + { + int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer); + this.SendPackTo(ZeroOutBuffer, packetsize, SocketFlags.None, endp); + } + else + { + this.SendPackTo(sendbuffer, sendbuffer.Length, SocketFlags.None, endp); + } + } + catch (Exception) + { + m_log.Warn("CheckSumServer.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection "); + } + } + + private void SendPackTo(byte[] buffer, int size, SocketFlags flags, EndPoint endp) + { + this.Server.SendTo(buffer, size, flags, endp); + } + * } + */ +} diff --git a/OpenSim/Framework/Servers/IStreamHandler.cs b/OpenSim/Framework/Servers/IStreamHandler.cs index 0b587e96a7..ddb4d3ade3 100644 --- a/OpenSim/Framework/Servers/IStreamHandler.cs +++ b/OpenSim/Framework/Servers/IStreamHandler.cs @@ -1,61 +1,61 @@ -/* -* 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.Collections; -using System.IO; - -namespace OpenSim.Framework.Servers -{ - public interface IRequestHandler - { - // Return response content type - string ContentType { get; } - - // Return required http method - string HttpMethod { get; } - - // Return path - string Path { get; } - - } - - public interface IStreamedRequestHandler : IRequestHandler - { - // Handle request stream, return byte array - byte[] Handle(string path, Stream request); - } - - public interface IStreamHandler : IRequestHandler - { - // Handle request stream, return byte array - void Handle(string path, Stream request, Stream response); - } - public interface IGenericHTTPHandler : IRequestHandler - { - Hashtable Handle(string path, Hashtable request); - } -} \ No newline at end of file +/* +* 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.Collections; +using System.IO; + +namespace OpenSim.Framework.Servers +{ + public interface IRequestHandler + { + // Return response content type + string ContentType { get; } + + // Return required http method + string HttpMethod { get; } + + // Return path + string Path { get; } + + } + + public interface IStreamedRequestHandler : IRequestHandler + { + // Handle request stream, return byte array + byte[] Handle(string path, Stream request); + } + + public interface IStreamHandler : IRequestHandler + { + // Handle request stream, return byte array + void Handle(string path, Stream request, Stream response); + } + public interface IGenericHTTPHandler : IRequestHandler + { + Hashtable Handle(string path, Hashtable request); + } +} diff --git a/OpenSim/Framework/Servers/RestStreamHandler.cs b/OpenSim/Framework/Servers/RestStreamHandler.cs index e6480ff7a1..a21e5b290a 100644 --- a/OpenSim/Framework/Servers/RestStreamHandler.cs +++ b/OpenSim/Framework/Servers/RestStreamHandler.cs @@ -1,57 +1,57 @@ -/* -* 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.IO; -using System.Text; - -namespace OpenSim.Framework.Servers -{ - public class RestStreamHandler : BaseStreamHandler - { - private RestMethod m_restMethod; - - public override byte[] Handle(string path, Stream request) - { - Encoding encoding = Encoding.UTF8; - StreamReader streamReader = new StreamReader(request, encoding); - - string requestBody = streamReader.ReadToEnd(); - streamReader.Close(); - - string param = GetParam(path); - string responseString = m_restMethod(requestBody, path, param); - - return Encoding.UTF8.GetBytes(responseString); - } - - public RestStreamHandler(string httpMethod, string path, RestMethod restMethod) : base(httpMethod, path) - { - m_restMethod = restMethod; - } - } -} \ No newline at end of file +/* +* 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.IO; +using System.Text; + +namespace OpenSim.Framework.Servers +{ + public class RestStreamHandler : BaseStreamHandler + { + private RestMethod m_restMethod; + + public override byte[] Handle(string path, Stream request) + { + Encoding encoding = Encoding.UTF8; + StreamReader streamReader = new StreamReader(request, encoding); + + string requestBody = streamReader.ReadToEnd(); + streamReader.Close(); + + string param = GetParam(path); + string responseString = m_restMethod(requestBody, path, param); + + return Encoding.UTF8.GetBytes(responseString); + } + + public RestStreamHandler(string httpMethod, string path, RestMethod restMethod) : base(httpMethod, path) + { + m_restMethod = restMethod; + } + } +} diff --git a/OpenSim/Framework/Statistics/AssetStatsReporter.cs b/OpenSim/Framework/Statistics/AssetStatsReporter.cs new file mode 100644 index 0000000000..4f2ef867a8 --- /dev/null +++ b/OpenSim/Framework/Statistics/AssetStatsReporter.cs @@ -0,0 +1,106 @@ +/* +* 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.Text; +using System.Timers; + +namespace OpenSim.Framework.Statistics +{ + /// + /// Collects and reports information on the requests made to the asset server + /// + public class AssetStatsReporter + { + private Timer ageStatsTimer = new Timer(24 * 60 * 60 * 1000); + private DateTime startTime = DateTime.Now; + + private long assetRequestsToday; + private long assetRequestsNotFoundToday; + private long assetRequestsYesterday; + private long assetRequestsNotFoundYesterday; + + public long AssetRequestsToday { get { return assetRequestsToday; } } + public long AssetRequestsNotFoundToday { get { return assetRequestsNotFoundToday; } } + public long AssetRequestsYesterday { get { return assetRequestsYesterday; } } + public long AssetRequestsNotFoundYesterday { get { return assetRequestsNotFoundYesterday; } } + + public AssetStatsReporter() + { + ageStatsTimer.Elapsed += new ElapsedEventHandler(OnAgeing); + ageStatsTimer.Enabled = true; + } + + private void OnAgeing(object source, ElapsedEventArgs e) + { + assetRequestsYesterday = assetRequestsToday; + + // There is a possibility that an asset request could occur between the execution of these + // two statements. But we're better off without the synchronization overhead. + assetRequestsToday = 0; + + assetRequestsNotFoundYesterday = assetRequestsNotFoundToday; + assetRequestsNotFoundToday = 0; + } + + /// + /// Record that an asset request failed to find an asset + /// + public void AddNotFoundRequest() + { + assetRequestsNotFoundToday++; + } + + /// + /// Record that a request was made to the asset server + /// + public void AddRequest() + { + assetRequestsToday++; + } + + /// + /// Report back collected statistical information. + /// + /// + public string Report() + { + double elapsedHours = (DateTime.Now - startTime).TotalHours; + if (elapsedHours <= 0) { elapsedHours = 1; } // prevent divide by zero + + long assetRequestsTodayPerHour = (long)Math.Round(AssetRequestsToday / elapsedHours); + long assetRequestsYesterdayPerHour = (long)Math.Round(AssetRequestsYesterday / 24.0); + + return string.Format( +@"Asset requests today : {0} ({1} per hour) of which {2} were not found +Asset requests yesterday : {3} ({4} per hour) of which {5} were not found", + AssetRequestsToday, assetRequestsTodayPerHour, AssetRequestsNotFoundToday, + AssetRequestsYesterday, assetRequestsYesterdayPerHour, AssetRequestsNotFoundYesterday); + } + } +} diff --git a/OpenSim/Framework/Statistics/Interfaces/IPullStatsProvider.cs b/OpenSim/Framework/Statistics/Interfaces/IPullStatsProvider.cs new file mode 100755 index 0000000000..5a81337569 --- /dev/null +++ b/OpenSim/Framework/Statistics/Interfaces/IPullStatsProvider.cs @@ -0,0 +1,44 @@ +/* +* 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; + +namespace OpenSim.Framework.Statistics.Interfaces +{ + /// + /// Description of IPullStatsProvider. + /// + public interface IPullStatsProvider + { + /// + /// Provide statistical information. Only temporary one long string. + /// + /// + string GetStats(); + } +} diff --git a/OpenSim/Framework/Statistics/SimExtraStatsReporter.cs b/OpenSim/Framework/Statistics/SimExtraStatsReporter.cs new file mode 100644 index 0000000000..a9a4b4e453 --- /dev/null +++ b/OpenSim/Framework/Statistics/SimExtraStatsReporter.cs @@ -0,0 +1,157 @@ +/* +* 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.Generic; +using System.Text; + +using OpenSim.Framework; +using OpenSim.Framework.Statistics.Interfaces; + +using libsecondlife; + +namespace OpenSim.Framework.Statistics +{ + public class SimExtraStatsReporter + { + private long assetsInCache; + private long texturesInCache; + private long assetCacheMemoryUsage; + private long textureCacheMemoryUsage; + + public long AssetsInCache { get { return assetsInCache; } } + public long TexturesInCache { get { return texturesInCache; } } + public long AssetCacheMemoryUsage { get { return assetCacheMemoryUsage; } } + public long TextureCacheMemoryUsage { get { return textureCacheMemoryUsage; } } + + /// + /// Retain a dictionary of all packet queues stats reporters + /// + private IDictionary packetQueueStatsReporters + = new Dictionary(); + + public void AddAsset(AssetBase asset) + { + assetsInCache++; + assetCacheMemoryUsage += asset.Data.Length; + } + + public void AddTexture(AssetBase image) + { + // Tedd: I added null check to avoid exception. Don't know if texturesInCache should ++ anyway? + if (image.Data != null) + { + texturesInCache++; + textureCacheMemoryUsage += image.Data.Length; + } + } + + /// + /// Register as a packet queue stats provider + /// + /// An agent LLUUID + /// + public void RegisterPacketQueueStatsProvider(LLUUID uuid, IPullStatsProvider provider) + { + lock (packetQueueStatsReporters) + { + packetQueueStatsReporters[uuid] = new PacketQueueStatsReporter(provider); + } + } + + /// + /// Deregister a packet queue stats provider + /// + /// An agent LLUUID + public void DeregisterPacketQueueStatsProvider(LLUUID uuid) + { + lock (packetQueueStatsReporters) + { + packetQueueStatsReporters.Remove(uuid); + } + } + + /// + /// Report back collected statistical information. + /// + /// + public string Report() + { + StringBuilder sb = new StringBuilder(Environment.NewLine); + sb.Append("ASSET CACHE STATISTICS"); + sb.Append(Environment.NewLine); + sb.Append( + string.Format( +@"Asset cache contains {0,6} assets using {1,10:0.000}K +Texture cache contains {2,6} textures using {3,10:0.000}K" + Environment.NewLine, + AssetsInCache, AssetCacheMemoryUsage / 1024.0, + TexturesInCache, TextureCacheMemoryUsage / 1024.0)); + + sb.Append(Environment.NewLine); + sb.Append("PACKET QUEUE STATISTICS"); + sb.Append(Environment.NewLine); + sb.Append("Agent UUID "); + sb.Append( + string.Format( + " {0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}", + "Send", "In", "Out", "Resend", "Land", "Wind", "Cloud", "Task", "Texture", "Asset")); + sb.Append(Environment.NewLine); + + foreach (LLUUID key in packetQueueStatsReporters.Keys) + { + sb.Append(string.Format("{0}: ", key)); + sb.Append(packetQueueStatsReporters[key].Report()); + sb.Append(Environment.NewLine); + } + + return sb.ToString(); + } + } + + /// + /// Pull packet queue stats from packet queues and report + /// + public class PacketQueueStatsReporter + { + private IPullStatsProvider m_statsProvider; + + public PacketQueueStatsReporter(IPullStatsProvider provider) + { + m_statsProvider = provider; + } + + /// + /// Report back collected statistical information. + /// + /// + public string Report() + { + return m_statsProvider.GetStats(); + } + } +} diff --git a/OpenSim/Framework/Statistics/StatsManager.cs b/OpenSim/Framework/Statistics/StatsManager.cs new file mode 100644 index 0000000000..842f1f18af --- /dev/null +++ b/OpenSim/Framework/Statistics/StatsManager.cs @@ -0,0 +1,73 @@ +/* +* 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. +* +*/ + +namespace OpenSim.Framework.Statistics +{ + /// + /// Singleton used to provide access to statistics reporters + /// + public class StatsManager + { + private static AssetStatsReporter assetStats; + private static UserStatsReporter userStats; + private static SimExtraStatsReporter simExtraStats; + + public static AssetStatsReporter AssetStats { get { return assetStats; } } + public static UserStatsReporter UserStats { get { return userStats; } } + public static SimExtraStatsReporter SimExtraStats { get { return simExtraStats; } } + + private StatsManager() {} + + /// + /// Start collecting statistics related to assets. + /// Should only be called once. + /// + public static void StartCollectingAssetStats() + { + assetStats = new AssetStatsReporter(); + } + + /// + /// Start collecting statistics related to users. + /// Should only be called once. + /// + public static void StartCollectingUserStats() + { + userStats = new UserStatsReporter(); + } + + /// + /// Start collecting extra sim statistics apart from those collected for the client. + /// Should only be called once. + /// + public static void StartCollectingSimExtraStats() + { + simExtraStats = new SimExtraStatsReporter(); + } + } +} diff --git a/OpenSim/Framework/Statistics/UserStatsReporter.cs b/OpenSim/Framework/Statistics/UserStatsReporter.cs new file mode 100644 index 0000000000..bd4f95b418 --- /dev/null +++ b/OpenSim/Framework/Statistics/UserStatsReporter.cs @@ -0,0 +1,94 @@ +/* +* 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.Text; +using System.Timers; + +namespace OpenSim.Framework.Statistics +{ + /// + /// Description of UserStatsReporter. + /// + public class UserStatsReporter + { + private Timer ageStatsTimer = new Timer(24 * 60 * 60 * 1000); + + private int successfulLoginsToday; + public int SuccessfulLoginsToday { get { return successfulLoginsToday; } } + + private int successfulLoginsYesterday; + public int SuccessfulLoginsYesterday { get { return successfulLoginsYesterday; } } + + private int successfulLogins; + public int SuccessfulLogins { get { return successfulLogins; } } + + private int logouts; + public int Logouts { get { return logouts; } } + + public UserStatsReporter() + { + ageStatsTimer.Elapsed += new ElapsedEventHandler(OnAgeing); + ageStatsTimer.Enabled = true; + } + + private void OnAgeing(object source, ElapsedEventArgs e) + { + successfulLoginsYesterday = successfulLoginsToday; + + // There is a possibility that an asset request could occur between the execution of these + // two statements. But we're better off without the synchronization overhead. + successfulLoginsToday = 0; + } + + /// + /// Record a successful login + /// + public void AddSuccessfulLogin() + { + successfulLogins++; + successfulLoginsToday++; + } + + public void AddLogout() + { + logouts++; + } + + /// + /// Report back collected statistical information. + /// + /// + public string Report() + { + return string.Format( +@"Successful logins total : {0}, today : {1}, yesterday : {2} + Logouts total : {3}", + SuccessfulLogins, SuccessfulLoginsToday, SuccessfulLoginsYesterday, Logouts); + } + } +} diff --git a/OpenSim/Framework/TaskInventoryItem.cs b/OpenSim/Framework/TaskInventoryItem.cs index 2a0b3acccb..8b171a1949 100644 --- a/OpenSim/Framework/TaskInventoryItem.cs +++ b/OpenSim/Framework/TaskInventoryItem.cs @@ -1,101 +1,210 @@ -/* -* 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 libsecondlife; - -namespace OpenSim.Framework -{ - public class TaskInventoryItem - { - /// - /// XXX This should really be factored out into some constants class. - /// - private const uint FULL_MASK_PERMISSIONS_GENERAL = 2147483647; - - /// - /// Inventory types - /// - public static string[] InvTypes = new string[] - { - "texture", - "sound", - "", - "", - "", - "", - "", - "", - "", - "", - "lsl_text", - "" - }; - - /// - /// Asset types - /// - public static string[] Types = new string[] - { - "texture", - "sound", - "", - "", - "", - "", - "", - "", - "", - "", - "lsltext", - "" - }; - - public LLUUID item_id = LLUUID.Zero; - public LLUUID parent_id = LLUUID.Zero; //parent folder id - - public uint base_mask = FULL_MASK_PERMISSIONS_GENERAL; - public uint owner_mask = FULL_MASK_PERMISSIONS_GENERAL; - public uint group_mask = FULL_MASK_PERMISSIONS_GENERAL; - public uint everyone_mask = FULL_MASK_PERMISSIONS_GENERAL; - public uint next_owner_mask = FULL_MASK_PERMISSIONS_GENERAL; - public LLUUID creator_id = LLUUID.Zero; - public LLUUID owner_id = LLUUID.Zero; - public LLUUID last_owner_id = LLUUID.Zero; - public LLUUID group_id = LLUUID.Zero; - - public LLUUID asset_id = LLUUID.Zero; - public string type = ""; - public string inv_type = ""; - public uint flags = 0; - public string name = ""; - public string desc = ""; - public uint creation_date = 0; - - public LLUUID ParentPartID = LLUUID.Zero; - } -} +/* +* 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.Collections.Generic; +using System.Xml; +using System.Xml.Schema; +using System.Xml.Serialization; + +using libsecondlife; +using System; + +namespace OpenSim.Framework +{ + /// + /// A dictionary for task inventory. + /// + /// This class is not thread safe. Callers must synchronize on Dictionary methods. + /// + public class TaskInventoryDictionary : Dictionary, + ICloneable, IXmlSerializable + { + private static XmlSerializer tiiSerializer = new XmlSerializer(typeof(TaskInventoryItem)); + + // The alternative of simply serializing the list doesn't appear to work on mono, since + // we get a + // + // System.TypeInitializationException: An exception was thrown by the type initializer for OpenSim.Framework.TaskInventoryDictionary ---> System.ArgumentOutOfRangeException: < 0 + // Parameter name: length + // at System.String.Substring (Int32 startIndex, Int32 length) [0x00088] in /build/buildd/mono-1.2.4/mcs/class/corlib/System/String.cs:381 + // at System.Xml.Serialization.TypeTranslator.GetTypeData (System.Type runtimeType, System.String xmlDataType) [0x001f6] in /build/buildd/mono-1.2.4/mcs/class/System.XML/System.Xml.Serialization/TypeTranslator.cs:217 + // ... +// private static XmlSerializer tiiSerializer +// = new XmlSerializer(typeof(Dictionary.ValueCollection)); + + // see IXmlSerializable + public XmlSchema GetSchema() + { + return null; + } + + // see IXmlSerializable + public void ReadXml(XmlReader reader) + { + reader.Read(); + while (tiiSerializer.CanDeserialize(reader)) + { + TaskInventoryItem item = (TaskInventoryItem)tiiSerializer.Deserialize(reader); + Add(item.ItemID, item); + } + +// reader.Read(); +// while (reader.Name.Equals("TaskInventoryItem")) +// { +// TaskInventoryItem item = (TaskInventoryItem)tiiSerializer.Deserialize(reader); +// Add(item.ItemID, item); +// } + +// ICollection items +// = (ICollection)tiiSerializer.Deserialize(reader); +// +// foreach (TaskInventoryItem item in items) +// { +// Add(item.ItemID, item); +// } + } + + // see IXmlSerializable + public void WriteXml(XmlWriter writer) + { + lock (this) + { + foreach (TaskInventoryItem item in Values) + { + tiiSerializer.Serialize(writer, item); + } + } + + //tiiSerializer.Serialize(writer, Values); + } + + // see ICloneable + public Object Clone() + { + TaskInventoryDictionary clone = new TaskInventoryDictionary(); + + lock (this) + { + foreach (LLUUID uuid in Keys) + { + clone.Add(uuid, (TaskInventoryItem)this[uuid].Clone()); + } + } + + return clone; + } + } + + /// + /// Represents an item in a task inventory + /// + public class TaskInventoryItem : ICloneable + { + /// + /// XXX This should really be factored out into some constants class. + /// + private const uint FULL_MASK_PERMISSIONS_GENERAL = 2147483647; + + /// + /// Inventory types + /// + public static string[] InvTypes = new string[] + { + "texture", + "sound", + String.Empty, + String.Empty, + String.Empty, + String.Empty, + String.Empty, + String.Empty, + String.Empty, + String.Empty, + "lsl_text", + String.Empty + }; + + /// + /// Asset types + /// + public static string[] Types = new string[] + { + "texture", + "sound", + String.Empty, + String.Empty, + String.Empty, + String.Empty, + String.Empty, + String.Empty, + String.Empty, + String.Empty, + "lsltext", + String.Empty + }; + + public LLUUID ItemID = LLUUID.Zero; + public LLUUID ParentID = LLUUID.Zero; //parent folder id + + public uint BaseMask = FULL_MASK_PERMISSIONS_GENERAL; + public uint OwnerMask = FULL_MASK_PERMISSIONS_GENERAL; + public uint GroupMask = FULL_MASK_PERMISSIONS_GENERAL; + public uint EveryoneMask = FULL_MASK_PERMISSIONS_GENERAL; + public uint NextOwnerMask = FULL_MASK_PERMISSIONS_GENERAL; + public LLUUID CreatorID = LLUUID.Zero; + public LLUUID OwnerID = LLUUID.Zero; + public LLUUID LastOwnerID = LLUUID.Zero; + public LLUUID GroupID = LLUUID.Zero; + + public LLUUID AssetID = LLUUID.Zero; + public int Type = 0; + public int InvType = 0; + public uint Flags = 0; + public string Name = String.Empty; + public string Description = String.Empty; + public uint CreationDate = 0; + + public LLUUID ParentPartID = LLUUID.Zero; + + /// + /// Reset the LLUUIDs for this item. + /// + /// The new part ID to which this item belongs + public void ResetIDs(LLUUID partID) + { + ItemID = LLUUID.Random(); + ParentPartID = partID; + } + + // See ICloneable + public Object Clone() + { + return MemberwiseClone(); + } + } +} diff --git a/OpenSim/Framework/ThreadTracker.cs b/OpenSim/Framework/ThreadTracker.cs new file mode 100644 index 0000000000..2f6d70d599 --- /dev/null +++ b/OpenSim/Framework/ThreadTracker.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text; +using System.Threading; + +namespace OpenSim.Framework +{ + public static class ThreadTracker + { + public static List m_Threads; + public static System.Threading.Thread ThreadTrackerThread; + private static readonly long ThreadTimeout = 30 * 10000000; + + static ThreadTracker() + { +#if DEBUG + m_Threads = new List(); + ThreadTrackerThread = new Thread(ThreadTrackerThreadLoop); + ThreadTrackerThread.Name = "ThreadTrackerThread"; + ThreadTrackerThread.IsBackground = true; + ThreadTrackerThread.Priority = System.Threading.ThreadPriority.BelowNormal; + ThreadTrackerThread.Start(); +#endif + } + + private static void ThreadTrackerThreadLoop() + { + while (true) + { + Thread.Sleep(5000); + CleanUp(); + } + } + + public static void Add(System.Threading.Thread thread) + { +#if DEBUG + lock (m_Threads) + { + ThreadTrackerItem tti = new ThreadTrackerItem(); + tti.Thread = thread; + tti.LastSeenActive = DateTime.Now.Ticks; + m_Threads.Add(tti); + } +#endif + } + + public static void Remove(System.Threading.Thread thread) + { +#if DEBUG + lock (m_Threads) + { + foreach (ThreadTrackerItem tti in new ArrayList(m_Threads)) + { + if (tti.Thread == thread) + m_Threads.Remove(tti); + } + } +#endif + } + + public static void CleanUp() + { + lock (m_Threads) + { + foreach (ThreadTrackerItem tti in new ArrayList(m_Threads)) + { + if (tti.Thread.IsAlive) + { + // Its active + tti.LastSeenActive = DateTime.Now.Ticks; + } + else + { + // Its not active -- if its expired then remove it + if (tti.LastSeenActive + ThreadTimeout < DateTime.Now.Ticks) + m_Threads.Remove(tti); + } + } + } + } + + public static List GetThreads() + { + if (m_Threads == null) + return null; + + List threads = new List(); + lock (m_Threads) + { + foreach (ThreadTrackerItem tti in new ArrayList(m_Threads)) + { + threads.Add(tti.Thread); + } + } + return threads; + } + + public class ThreadTrackerItem + { + public System.Threading.Thread Thread; + public long LastSeenActive; + } + } +} diff --git a/OpenSim/Framework/UserConfig.cs b/OpenSim/Framework/UserConfig.cs index b491e8a5ce..71c5d727b0 100644 --- a/OpenSim/Framework/UserConfig.cs +++ b/OpenSim/Framework/UserConfig.cs @@ -1,139 +1,142 @@ -/* -* 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. -* -*/ - -namespace OpenSim.Framework -{ - /// - /// UserConfig -- For User Server Configuration - /// - public class UserConfig - { - public string DefaultStartupMsg = ""; - public string GridServerURL = ""; - public string GridSendKey = ""; - public string GridRecvKey = ""; - - public string InventoryUrl = ""; - - public string DatabaseProvider = ""; - - public static uint DefaultHttpPort = 8002; - public static bool DefaultHttpSSL = false; - public uint HttpPort = DefaultHttpPort; - public bool HttpSSL = DefaultHttpSSL; - public uint DefaultX = 1000; - public uint DefaultY = 1000; - public bool RexMode = false; - - private ConfigurationMember configMember; - - public UserConfig(string description, string filename) - { - configMember = - new ConfigurationMember(filename, description, loadConfigurationOptions, handleIncomingConfiguration,true); - configMember.performConfigurationRetrieve(); - } - - public void loadConfigurationOptions() - { - configMember.addConfigurationOption("default_startup_message", - ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, - "Default Startup Message", "Welcome to OGS", false); - - configMember.addConfigurationOption("default_grid_server", - ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, - "Default Grid Server URI", - "http://127.0.0.1:" + GridConfig.DefaultHttpPort.ToString() + "/", false); - configMember.addConfigurationOption("grid_send_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "Key to send to grid server", "null", false); - configMember.addConfigurationOption("grid_recv_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "Key to expect from grid server", "null", false); - - configMember.addConfigurationOption("default_inventory_server", - ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, - "Default Inventory Server URI", - "http://127.0.0.1:" + InventoryConfig.DefaultHttpPort.ToString() + "/", - false); - configMember.addConfigurationOption("database_provider", ConfigurationOption.ConfigurationTypes.TYPE_STRING, - "DLL for database provider", "OpenSim.Framework.Data.MySQL.dll", false); - - configMember.addConfigurationOption("http_port", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, - "Http Listener port", DefaultHttpPort.ToString(), false); - configMember.addConfigurationOption("http_ssl", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN, - "Use SSL? true/false", DefaultHttpSSL.ToString(), false); - configMember.addConfigurationOption("default_X", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, - "Known good region X", "1000", false); - configMember.addConfigurationOption("default_Y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, - "Known good region Y", "1000", false); - configMember.addConfigurationOption("rex_mode", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN, - "Run in realXtend mode? true/false", "false", false); - } - - public bool handleIncomingConfiguration(string configuration_key, object configuration_result) - { - switch (configuration_key) - { - case "default_startup_message": - DefaultStartupMsg = (string) configuration_result; - break; - case "default_grid_server": - GridServerURL = (string) configuration_result; - break; - case "grid_send_key": - GridSendKey = (string) configuration_result; - break; - case "grid_recv_key": - GridRecvKey = (string) configuration_result; - break; - case "default_inventory_server": - InventoryUrl = (string) configuration_result; - break; - case "database_provider": - DatabaseProvider = (string) configuration_result; - break; - case "http_port": - HttpPort = (uint) configuration_result; - break; - case "http_ssl": - HttpSSL = (bool) configuration_result; - break; - case "default_X": - DefaultX = (uint) configuration_result; - break; - case "default_Y": - DefaultY = (uint) configuration_result; - break; - case "rex_mode": - RexMode = (bool)configuration_result; - break; - } - - return true; - } - } -} \ No newline at end of file +/* +* 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 OpenSim.Framework.Console; + +namespace OpenSim.Framework +{ + /// + /// UserConfig -- For User Server Configuration + /// + public class UserConfig + { + public string DefaultStartupMsg = String.Empty; + public string GridServerURL = String.Empty; + public string GridSendKey = String.Empty; + public string GridRecvKey = String.Empty; + + public string InventoryUrl = String.Empty; + + public string DatabaseProvider = String.Empty; + + public static uint DefaultHttpPort = 8002; + public static bool DefaultHttpSSL = false; + public uint HttpPort = DefaultHttpPort; + public bool HttpSSL = DefaultHttpSSL; + public uint DefaultX = 1000; + public uint DefaultY = 1000; + public bool RexMode = false; + + private ConfigurationMember configMember; + + public UserConfig(string description, string filename) + { + configMember = + new ConfigurationMember(filename, description, loadConfigurationOptions, handleIncomingConfiguration,true); + configMember.performConfigurationRetrieve(); + } + + public void loadConfigurationOptions() + { + configMember.addConfigurationOption("default_startup_message", + ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "Default Startup Message", "Welcome to OGS", false); + + configMember.addConfigurationOption("default_grid_server", + ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "Default Grid Server URI", + "http://127.0.0.1:" + GridConfig.DefaultHttpPort.ToString() + "/", false); + configMember.addConfigurationOption("grid_send_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "Key to send to grid server", "null", false); + configMember.addConfigurationOption("grid_recv_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "Key to expect from grid server", "null", false); + + configMember.addConfigurationOption("default_inventory_server", + ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "Default Inventory Server URI", + "http://127.0.0.1:" + InventoryConfig.DefaultHttpPort.ToString() + "/", + false); + configMember.addConfigurationOption("database_provider", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "DLL for database provider", "OpenSim.Framework.Data.MySQL.dll", false); + + configMember.addConfigurationOption("http_port", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Http Listener port", DefaultHttpPort.ToString(), false); + configMember.addConfigurationOption("http_ssl", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN, + "Use SSL? true/false", DefaultHttpSSL.ToString(), false); + configMember.addConfigurationOption("default_X", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Known good region X", "1000", false); + configMember.addConfigurationOption("default_Y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Known good region Y", "1000", false); + configMember.addConfigurationOption("rex_mode", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN, + "Run in realXtend mode? true/false", "false", false); + } + + public bool handleIncomingConfiguration(string configuration_key, object configuration_result) + { + switch (configuration_key) + { + case "default_startup_message": + DefaultStartupMsg = (string) configuration_result; + break; + case "default_grid_server": + GridServerURL = (string) configuration_result; + break; + case "grid_send_key": + GridSendKey = (string) configuration_result; + break; + case "grid_recv_key": + GridRecvKey = (string) configuration_result; + break; + case "default_inventory_server": + InventoryUrl = (string) configuration_result; + break; + case "database_provider": + DatabaseProvider = (string) configuration_result; + break; + case "http_port": + HttpPort = (uint) configuration_result; + break; + case "http_ssl": + HttpSSL = (bool) configuration_result; + break; + case "default_X": + DefaultX = (uint) configuration_result; + break; + case "default_Y": + DefaultY = (uint) configuration_result; + break; + case "rex_mode": + RexMode = (bool)configuration_result; + break; + } + + return true; + } + } +} diff --git a/OpenSim/Framework/UserProfileData.cs b/OpenSim/Framework/UserProfileData.cs index e15554bb02..6e63283925 100644 --- a/OpenSim/Framework/UserProfileData.cs +++ b/OpenSim/Framework/UserProfileData.cs @@ -1,236 +1,236 @@ -/* -* 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 libsecondlife; - -namespace OpenSim.Framework -{ - /// - /// Information about a particular user known to the userserver - /// - public class UserProfileData - { - /// - /// The ID value for this user - /// - public LLUUID UUID; - - /// - /// The last used Web_login_key - /// - public LLUUID webLoginKey; - /// - /// The first component of a users account name - /// - public string username; - - /// - /// The second component of a users account name - /// - public string surname; - - /// - /// A salted hash containing the users password, in the format md5(md5(password) + ":" + salt) - /// - /// This is double MD5'd because the client sends an unsalted MD5 to the loginserver - public string passwordHash; - - /// - /// The salt used for the users hash, should be 32 bytes or longer - /// - public string passwordSalt; - - /// - /// The regionhandle of the users preffered home region. If multiple sims occupy the same spot, the grid may decide which region the user logs into - /// - public ulong homeRegion - { - get { return Helpers.UIntsToLong((homeRegionX*256), (homeRegionY*256)); } - set - { - homeRegionX = (uint) (value >> 40); - homeRegionY = (((uint) (value)) >> 8); - } - } - - public uint homeRegionX; - public uint homeRegionY; - - /// - /// The coordinates inside the region of the home location - /// - public LLVector3 homeLocation; - - /// - /// Where the user will be looking when they rez. - /// - public LLVector3 homeLookAt; - - /// - /// A UNIX Timestamp (seconds since epoch) for the users creation - /// - public int created; - - /// - /// A UNIX Timestamp for the users last login date / time - /// - public int lastLogin; - - public LLUUID rootInventoryFolderID; - - /// - /// A URI to the users inventory server, used for foreigners and large grids - /// - public string userInventoryURI = String.Empty; - - /// - /// A URI to the users asset server, used for foreigners and large grids. - /// - public string userAssetURI = String.Empty; - - /// - /// A uint mask containing the "I can do" fields of the users profile - /// - public uint profileCanDoMask; - - /// - /// A uint mask containing the "I want to do" part of the users profile - /// - public uint profileWantDoMask; // Profile window "I want to" mask - - /// - /// The about text listed in a users profile. - /// - public string profileAboutText = String.Empty; - - /// - /// The first life about text listed in a users profile - /// - public string profileFirstText = String.Empty; - - /// - /// The profile image for an avatar stored on the asset server - /// - public LLUUID profileImage; - - /// - /// The profile image for the users first life tab - /// - public LLUUID profileFirstImage; - - /// - /// The users last registered agent (filled in on the user server) - /// - public UserAgentData currentAgent; - - /// - /// Authentication address (used in rex mode) - /// - public string authenticationAddr; - - } - - /// - /// Minimal User Data required to service the AvatarPickerReply - /// - //public class AvatarPickerAvatar - //{ - //public LLUUID AvatarID; - //public string firstName; - //public string lastName; - //public AvatarPickerAvatar() - //{ - //} - //} - /// - /// Information about a users session - /// - public class UserAgentData - { - /// - /// The UUID of the users avatar (not the agent!) - /// - public LLUUID UUID; - - /// - /// The IP address of the user - /// - public string agentIP = String.Empty; - - /// - /// The port of the user - /// - public uint agentPort; - - /// - /// Is the user online? - /// - public bool agentOnline; - - /// - /// The session ID for the user (also the agent ID) - /// - public LLUUID sessionID; - - /// - /// The "secure" session ID for the user - /// - /// Not very secure. Dont rely on it for anything more than Linden Lab does. - public LLUUID secureSessionID; - - /// - /// The region the user logged into initially - /// - public LLUUID regionID; - - /// - /// A unix timestamp from when the user logged in - /// - public int loginTime; - - /// - /// When this agent expired and logged out, 0 if still online - /// - public int logoutTime; - - /// - /// Current region the user is logged into - /// - public LLUUID currentRegion; - - /// - /// Region handle of the current region the user is in - /// - public ulong currentHandle; - - /// - /// The position of the user within the region - /// - public LLVector3 currentPos; - } -} \ No newline at end of file +/* +* 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 libsecondlife; + +namespace OpenSim.Framework +{ + /// + /// Information about a particular user known to the userserver + /// + public class UserProfileData + { + /// + /// The ID value for this user + /// + public LLUUID UUID; + + /// + /// The last used Web_login_key + /// + public LLUUID webLoginKey; + /// + /// The first component of a users account name + /// + public string username; + + /// + /// The second component of a users account name + /// + public string surname; + + /// + /// A salted hash containing the users password, in the format md5(md5(password) + ":" + salt) + /// + /// This is double MD5'd because the client sends an unsalted MD5 to the loginserver + public string passwordHash; + + /// + /// The salt used for the users hash, should be 32 bytes or longer + /// + public string passwordSalt; + + /// + /// The regionhandle of the users preffered home region. If multiple sims occupy the same spot, the grid may decide which region the user logs into + /// + public ulong homeRegion + { + get { return Helpers.UIntsToLong((homeRegionX * (uint)Constants.RegionSize), (homeRegionY * (uint)Constants.RegionSize)); } + set + { + homeRegionX = (uint) (value >> 40); + homeRegionY = (((uint) (value)) >> 8); + } + } + + public uint homeRegionX; + public uint homeRegionY; + + /// + /// The coordinates inside the region of the home location + /// + public LLVector3 homeLocation; + + /// + /// Where the user will be looking when they rez. + /// + public LLVector3 homeLookAt; + + /// + /// A UNIX Timestamp (seconds since epoch) for the users creation + /// + public int created; + + /// + /// A UNIX Timestamp for the users last login date / time + /// + public int lastLogin; + + public LLUUID rootInventoryFolderID; + + /// + /// A URI to the users inventory server, used for foreigners and large grids + /// + public string userInventoryURI = String.Empty; + + /// + /// A URI to the users asset server, used for foreigners and large grids. + /// + public string userAssetURI = String.Empty; + + /// + /// A uint mask containing the "I can do" fields of the users profile + /// + public uint profileCanDoMask; + + /// + /// A uint mask containing the "I want to do" part of the users profile + /// + public uint profileWantDoMask; // Profile window "I want to" mask + + /// + /// The about text listed in a users profile. + /// + public string profileAboutText = String.Empty; + + /// + /// The first life about text listed in a users profile + /// + public string profileFirstText = String.Empty; + + /// + /// The profile image for an avatar stored on the asset server + /// + public LLUUID profileImage; + + /// + /// The profile image for the users first life tab + /// + public LLUUID profileFirstImage; + + /// + /// The users last registered agent (filled in on the user server) + /// + public UserAgentData currentAgent; + + /// + /// Authentication address (used in rex mode) + /// + public string authenticationAddr; + + } + + /// + /// Minimal User Data required to service the AvatarPickerReply + /// + //public class AvatarPickerAvatar + //{ + //public LLUUID AvatarID; + //public string firstName; + //public string lastName; + //public AvatarPickerAvatar() + //{ + //} + //} + /// + /// Information about a users session + /// + public class UserAgentData + { + /// + /// The UUID of the users avatar (not the agent!) + /// + public LLUUID UUID; + + /// + /// The IP address of the user + /// + public string agentIP = String.Empty; + + /// + /// The port of the user + /// + public uint agentPort; + + /// + /// Is the user online? + /// + public bool agentOnline; + + /// + /// The session ID for the user (also the agent ID) + /// + public LLUUID sessionID; + + /// + /// The "secure" session ID for the user + /// + /// Not very secure. Dont rely on it for anything more than Linden Lab does. + public LLUUID secureSessionID; + + /// + /// The region the user logged into initially + /// + public LLUUID regionID; + + /// + /// A unix timestamp from when the user logged in + /// + public int loginTime; + + /// + /// When this agent expired and logged out, 0 if still online + /// + public int logoutTime; + + /// + /// Current region the user is logged into + /// + public LLUUID currentRegion; + + /// + /// Region handle of the current region the user is in + /// + public ulong currentHandle; + + /// + /// The position of the user within the region + /// + public LLVector3 currentPos; + } +} diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 427b53f975..3703926421 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1,476 +1,532 @@ -/* -* 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.Generic; -using System.Data; -using System.IO; -using System.Net; -using System.Net.Sockets; -using System.Security.Cryptography; -using System.Text; -using libsecondlife; -using Nini.Config; - -namespace OpenSim.Framework -{ - // rex, new class - // Adds a way to get to the main ini file settings from anywhere - public sealed class GlobalSettings - { - private static volatile GlobalSettings instance; - private static object syncRoot = new Object(); - - public IniConfigSource ConfigSource; - - public bool m_3d_collision_models = false; - - public static GlobalSettings Instance - { - get - { - if (instance == null) - { - lock (syncRoot) - { - if (instance == null) - instance = new GlobalSettings(); - } - } - return instance; - } - } - - public GlobalSettings() - { } - } - // rex, end class - - - public class Util - { - private static Random randomClass = new Random(); - private static uint nextXferID = 5000; - private static object XferLock = new object(); - private static Dictionary capsURLS = new Dictionary(); - - #region Vector Equasions - - public static double GetDistanceTo(LLVector3 a, LLVector3 b) - { - float dx = a.X - b.X; - float dy = a.Y - b.Y; - float dz = a.Z - b.Z; - return Math.Sqrt(dx*dx + dy*dy + dz*dz); - } - public static double GetMagnitude(LLVector3 a) { - return Math.Sqrt((a.X * a.X) + (a.Y * a.Y) + (a.Z * a.Z)); - } - public static LLVector3 GetNormal(LLVector3 a) - { - float Mag = (float)GetMagnitude(a); - return new LLVector3(a.X / Mag, a.Y / Mag, a.Z / Mag); - - } - # endregion - - public static ulong UIntsToLong(uint X, uint Y) - { - return Helpers.UIntsToLong(X, Y); - } - - public static Random RandomClass - { - get { return randomClass; } - } - - public static uint GetNextXferID() - { - uint id = 0; - lock (XferLock) - { - id = nextXferID; - nextXferID++; - } - return id; - } - - public Util() - { - } - - public static string GetFileName(string file) - { - // Return just the filename on UNIX platforms - // TODO: this should be customisable with a prefix, but that's something to do later. - if (Environment.OSVersion.Platform == PlatformID.Unix) - { - return file; - } - - // Return %APPDATA%/OpenSim/file for 2K/XP/NT/2K3/VISTA - // TODO: Switch this to System.Enviroment.SpecialFolders.ApplicationData - if (Environment.OSVersion.Platform == PlatformID.Win32NT) - { - if (!Directory.Exists("%APPDATA%\\OpenSim\\")) - { - Directory.CreateDirectory("%APPDATA%\\OpenSim"); - } - - return "%APPDATA%\\OpenSim\\" + file; - } - - // Catch all - covers older windows versions - // (but those probably wont work anyway) - return file; - } - - public static bool IsEnvironmentSupported(ref string reason) - { - // Must have .NET 2.0 (Generics / libsl) - if (Environment.Version.Major < 2) - { - reason = ".NET 1.0/1.1 lacks components that is used by OpenSim"; - return false; - } - - // Windows 95/98/ME are unsupported - if (Environment.OSVersion.Platform == PlatformID.Win32Windows && - Environment.OSVersion.Platform != PlatformID.Win32NT) - { - reason = "Windows 95/98/ME will not run OpenSim"; - return false; - } - - // Windows 2000 / Pre-SP2 XP - if (Environment.OSVersion.Version.Major == 5 && ( - Environment.OSVersion.Version.Minor == 0)) - { - reason = "Please update to Windows XP Service Pack 2 or Server2003"; - return false; - } - - return true; - } - - public static int UnixTimeSinceEpoch() - { - TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1)); - int timestamp = (int) t.TotalSeconds; - return timestamp; - } - - public static string Md5Hash(string pass) - { - MD5 md5 = MD5CryptoServiceProvider.Create(); - byte[] dataMd5 = md5.ComputeHash(Encoding.Default.GetBytes(pass)); - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < dataMd5.Length; i++) - sb.AppendFormat("{0:x2}", dataMd5[i]); - return sb.ToString(); - } - - public static string GetRandomCapsPath() - { - LLUUID caps = LLUUID.Random(); - string capsPath = caps.ToString(); - capsPath = capsPath.Remove(capsPath.Length - 4, 4); - return capsPath; - } - - public static int fast_distance2d(int x, int y) - { - x = Math.Abs(x); - y = Math.Abs(y); - - int min = Math.Min(x, y); - - return (x + y - (min >> 1) - (min >> 2) + (min >> 4)); - } - - public static string FieldToString(byte[] bytes) - { - return FieldToString(bytes, String.Empty); - } - - /// - /// Convert a variable length field (byte array) to a string, with a - /// field name prepended to each line of the output - /// - /// If the byte array has unprintable characters in it, a - /// hex dump will be put in the string instead - /// The byte array to convert to a string - /// A field name to prepend to each line of output - /// An ASCII string or a string containing a hex dump, minus - /// the null terminator - public static string FieldToString(byte[] bytes, string fieldName) - { - // Check for a common case - if (bytes.Length == 0) return String.Empty; - - StringBuilder output = new StringBuilder(); - bool printable = true; - - for (int i = 0; i < bytes.Length; ++i) - { - // Check if there are any unprintable characters in the array - if ((bytes[i] < 0x20 || bytes[i] > 0x7E) && bytes[i] != 0x09 - && bytes[i] != 0x0D && bytes[i] != 0x0A && bytes[i] != 0x00) - { - printable = false; - break; - } - } - - if (printable) - { - if (fieldName.Length > 0) - { - output.Append(fieldName); - output.Append(": "); - } - - output.Append(CleanString(UTF8Encoding.UTF8.GetString(bytes, 0, bytes.Length - 1))); - } - else - { - for (int i = 0; i < bytes.Length; i += 16) - { - if (i != 0) - output.Append(Environment.NewLine); - if (fieldName.Length > 0) - { - output.Append(fieldName); - output.Append(": "); - } - - for (int j = 0; j < 16; j++) - { - if ((i + j) < bytes.Length) - output.Append(String.Format("{0:X2} ", bytes[i + j])); - else - output.Append(" "); - } - - for (int j = 0; j < 16 && (i + j) < bytes.Length; j++) - { - if (bytes[i + j] >= 0x20 && bytes[i + j] < 0x7E) - output.Append((char) bytes[i + j]); - else - output.Append("."); - } - } - } - - return output.ToString(); - } - - /// - /// Returns a IP address from a specified DNS, favouring IPv4 addresses. - /// - /// DNS Hostname - /// An IP address, or null - public static IPAddress GetHostFromDNS(string dnsAddress) - { - // Is it already a valid IP? No need to look it up. - IPAddress ipa; - if (IPAddress.TryParse(dnsAddress, out ipa)) - return ipa; - - // Not an IP, lookup required - IPAddress[] hosts = Dns.GetHostEntry(dnsAddress).AddressList; - - foreach (IPAddress host in hosts) - { - if (host.AddressFamily == AddressFamily.InterNetwork) - { - return host; - } - } - - if (hosts.Length > 0) - return hosts[0]; - - return null; - } - - public static IPAddress GetLocalHost() - { - string dnsAddress = "localhost"; - - IPAddress[] hosts = Dns.GetHostEntry(dnsAddress).AddressList; - - foreach (IPAddress host in hosts) - { - if (!IPAddress.IsLoopback(host) && host.AddressFamily == AddressFamily.InterNetwork) - { - return host; - } - } - - if (hosts.Length > 0) - return hosts[0]; - - return null; - } - - // - // directory locations - // - - public static string homeDir() - { - string temp; -// string personal=(Environment.GetFolderPath(Environment.SpecialFolder.Personal)); -// temp = Path.Combine(personal,".OpenSim"); - temp = "."; - return temp; - } - - public static string assetsDir() - { - return Path.Combine(configDir(), "assets"); - } - - public static string inventoryDir() - { - return Path.Combine(configDir(), "inventory"); - } - - public static string configDir() - { - string temp; - temp = "."; - return temp; - } - - public static string dataDir() - { - string temp; - temp = "."; - return temp; - } - - public static string logDir() - { - string temp; - temp = "."; - return temp; - } - - public static string GetCapsURL(LLUUID userID) - { - if (capsURLS.ContainsKey(userID)) - { - return capsURLS[userID]; - } - return ""; - } - - public static void SetCapsURL(LLUUID userID, string url) - { - if (capsURLS.ContainsKey(userID)) - { - capsURLS[userID] = url; - } - else - { - capsURLS.Add(userID, url); - } - } - - // Nini (config) related Methods - public static IConfigSource ConvertDataRowToXMLConfig(DataRow row, string fileName) - { - if (!File.Exists(fileName)) - { - //create new file - } - XmlConfigSource config = new XmlConfigSource(fileName); - AddDataRowToConfig(config, row); - config.Save(); - - return config; - } - - public static void AddDataRowToConfig(IConfigSource config, DataRow row) - { - config.Configs.Add((string) row[0]); - for (int i = 0; i < row.Table.Columns.Count; i++) - { - config.Configs[(string) row[0]].Set(row.Table.Columns[i].ColumnName, row[i]); - } - } - - public static float Clip(float x, float min, float max) - { - return Math.Min(Math.Max(x, min), max); - } - - public static int Clip(int x, int min, int max) - { - return Math.Min(Math.Max(x, min), max); - } - - /// - /// Convert an LLUUID to a raw uuid string. Right now this is a string without hyphens. - /// - /// - /// - public static String ToRawUuidString(LLUUID lluuid) - { - return lluuid.UUID.ToString("n"); - } - - public static string CleanString(string input) - { - if(input.Length == 0) - return input; - - int clip=input.Length; - - // Test for ++ string terminator - int pos=input.IndexOf("\0"); - if(pos != -1 && pos < clip) - clip=pos; - - // Test for CR - pos=input.IndexOf("\r"); - if(pos != -1 && pos < clip) - clip=pos; - - // Test for LF - pos=input.IndexOf("\n"); - if(pos != -1 && pos < clip) - clip=pos; - - // Truncate string before first end-of-line character found - return input.Substring(0, clip); - } - } -} +/* +* 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.Generic; +using System.Data; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Security.Cryptography; +using System.Text; +using libsecondlife; +using Nini.Config; + +namespace OpenSim.Framework +{ + // rex, new class + // Adds a way to get to the main ini file settings from anywhere + public sealed class GlobalSettings + { + private static volatile GlobalSettings instance; + private static object syncRoot = new Object(); + + public IniConfigSource ConfigSource; + + public bool m_3d_collision_models = false; + + public static GlobalSettings Instance + { + get + { + if (instance == null) + { + lock (syncRoot) + { + if (instance == null) + instance = new GlobalSettings(); + } + } + return instance; + } + } + + public GlobalSettings() + { } + } + // rex, end class + + + public class Util + { + private static Random randomClass = new Random(); + private static uint nextXferID = 5000; + private static object XferLock = new object(); + private static Dictionary capsURLS = new Dictionary(); + + #region Vector Equasions + /// + /// Get the distance between two 3d vectors + /// + /// A 3d vector + /// A 3d vector + /// The distance between the two vectors + public static double GetDistanceTo(LLVector3 a, LLVector3 b) + { + float dx = a.X - b.X; + float dy = a.Y - b.Y; + float dz = a.Z - b.Z; + return Math.Sqrt(dx*dx + dy*dy + dz*dz); + } + + /// + /// Get the magnitude of a 3d vector + /// + /// A 3d vector + /// The magnitude of the vector + public static double GetMagnitude(LLVector3 a) { + return Math.Sqrt((a.X * a.X) + (a.Y * a.Y) + (a.Z * a.Z)); + } + + /// + /// Get a normalized form of a 3d vector + /// + /// A 3d vector + /// A new vector which is normalized form of the vector + /// The vector paramater cannot be <0,0,0> + public static LLVector3 GetNormalizedVector(LLVector3 a) + { + if (IsZeroVector(a)) + throw new ArgumentException("Vector paramater cannot be a zero vector."); + + float Mag = (float)GetMagnitude(a); + return new LLVector3(a.X / Mag, a.Y / Mag, a.Z / Mag); + } + + /// + /// Returns if a vector is a zero vector (has all zero components) + /// + /// + public static bool IsZeroVector( LLVector3 v ) + { + if( v.X == 0 && v.Y == 0 && v.Z == 0) + { + return true; + } + + return false; + } + # endregion + + public static ulong UIntsToLong(uint X, uint Y) + { + return Helpers.UIntsToLong(X, Y); + } + + public static Random RandomClass + { + get { return randomClass; } + } + + public static uint GetNextXferID() + { + uint id = 0; + lock (XferLock) + { + id = nextXferID; + nextXferID++; + } + return id; + } + + public Util() + { + } + + public static string GetFileName(string file) + { + // Return just the filename on UNIX platforms + // TODO: this should be customisable with a prefix, but that's something to do later. + if (Environment.OSVersion.Platform == PlatformID.Unix) + { + return file; + } + + // Return %APPDATA%/OpenSim/file for 2K/XP/NT/2K3/VISTA + // TODO: Switch this to System.Enviroment.SpecialFolders.ApplicationData + if (Environment.OSVersion.Platform == PlatformID.Win32NT) + { + if (!Directory.Exists("%APPDATA%\\OpenSim\\")) + { + Directory.CreateDirectory("%APPDATA%\\OpenSim"); + } + + return "%APPDATA%\\OpenSim\\" + file; + } + + // Catch all - covers older windows versions + // (but those probably wont work anyway) + return file; + } + + public static bool IsEnvironmentSupported(ref string reason) + { + // Must have .NET 2.0 (Generics / libsl) + if (Environment.Version.Major < 2) + { + reason = ".NET 1.0/1.1 lacks components that is used by OpenSim"; + return false; + } + + // Windows 95/98/ME are unsupported + if (Environment.OSVersion.Platform == PlatformID.Win32Windows && + Environment.OSVersion.Platform != PlatformID.Win32NT) + { + reason = "Windows 95/98/ME will not run OpenSim"; + return false; + } + + // Windows 2000 / Pre-SP2 XP + if (Environment.OSVersion.Version.Major == 5 && ( + Environment.OSVersion.Version.Minor == 0)) + { + reason = "Please update to Windows XP Service Pack 2 or Server2003"; + return false; + } + + return true; + } + + public static int UnixTimeSinceEpoch() + { + TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1)); + int timestamp = (int) t.TotalSeconds; + return timestamp; + } + + public static string Md5Hash(string pass) + { + MD5 md5 = MD5CryptoServiceProvider.Create(); + byte[] dataMd5 = md5.ComputeHash(Encoding.Default.GetBytes(pass)); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < dataMd5.Length; i++) + sb.AppendFormat("{0:x2}", dataMd5[i]); + return sb.ToString(); + } + + public static string GetRandomCapsPath() + { + LLUUID caps = LLUUID.Random(); + string capsPath = caps.ToString(); + capsPath = capsPath.Remove(capsPath.Length - 4, 4); + return capsPath; + } + + public static int fast_distance2d(int x, int y) + { + x = Math.Abs(x); + y = Math.Abs(y); + + int min = Math.Min(x, y); + + return (x + y - (min >> 1) - (min >> 2) + (min >> 4)); + } + + public static string FieldToString(byte[] bytes) + { + return FieldToString(bytes, String.Empty); + } + + /// + /// Convert a variable length field (byte array) to a string, with a + /// field name prepended to each line of the output + /// + /// If the byte array has unprintable characters in it, a + /// hex dump will be put in the string instead + /// The byte array to convert to a string + /// A field name to prepend to each line of output + /// An ASCII string or a string containing a hex dump, minus + /// the null terminator + public static string FieldToString(byte[] bytes, string fieldName) + { + // Check for a common case + if (bytes.Length == 0) return String.Empty; + + StringBuilder output = new StringBuilder(); + bool printable = true; + + for (int i = 0; i < bytes.Length; ++i) + { + // Check if there are any unprintable characters in the array + if ((bytes[i] < 0x20 || bytes[i] > 0x7E) && bytes[i] != 0x09 + && bytes[i] != 0x0D && bytes[i] != 0x0A && bytes[i] != 0x00) + { + printable = false; + break; + } + } + + if (printable) + { + if (fieldName.Length > 0) + { + output.Append(fieldName); + output.Append(": "); + } + + output.Append(CleanString(UTF8Encoding.UTF8.GetString(bytes, 0, bytes.Length - 1))); + } + else + { + for (int i = 0; i < bytes.Length; i += 16) + { + if (i != 0) + output.Append(Environment.NewLine); + if (fieldName.Length > 0) + { + output.Append(fieldName); + output.Append(": "); + } + + for (int j = 0; j < 16; j++) + { + if ((i + j) < bytes.Length) + output.Append(String.Format("{0:X2} ", bytes[i + j])); + else + output.Append(" "); + } + + for (int j = 0; j < 16 && (i + j) < bytes.Length; j++) + { + if (bytes[i + j] >= 0x20 && bytes[i + j] < 0x7E) + output.Append((char) bytes[i + j]); + else + output.Append("."); + } + } + } + + return output.ToString(); + } + + /// + /// Returns a IP address from a specified DNS, favouring IPv4 addresses. + /// + /// DNS Hostname + /// An IP address, or null + public static IPAddress GetHostFromDNS(string dnsAddress) + { + // Is it already a valid IP? No need to look it up. + IPAddress ipa; + if (IPAddress.TryParse(dnsAddress, out ipa)) + return ipa; + + // Not an IP, lookup required + IPAddress[] hosts = Dns.GetHostEntry(dnsAddress).AddressList; + + foreach (IPAddress host in hosts) + { + if (host.AddressFamily == AddressFamily.InterNetwork) + { + return host; + } + } + + if (hosts.Length > 0) + return hosts[0]; + + return null; + } + + public static IPAddress GetLocalHost() + { + string dnsAddress = "localhost"; + + IPAddress[] hosts = Dns.GetHostEntry(dnsAddress).AddressList; + + foreach (IPAddress host in hosts) + { + if (!IPAddress.IsLoopback(host) && host.AddressFamily == AddressFamily.InterNetwork) + { + return host; + } + } + + if (hosts.Length > 0) + return hosts[0]; + + return null; + } + + // + // directory locations + // + + public static string homeDir() + { + string temp; +// string personal=(Environment.GetFolderPath(Environment.SpecialFolder.Personal)); +// temp = Path.Combine(personal,".OpenSim"); + temp = "."; + return temp; + } + + public static string assetsDir() + { + return Path.Combine(configDir(), "assets"); + } + + public static string inventoryDir() + { + return Path.Combine(configDir(), "inventory"); + } + + public static string configDir() + { + string temp; + temp = "."; + return temp; + } + + public static string dataDir() + { + string temp; + temp = "."; + return temp; + } + + public static string logDir() + { + string temp; + temp = "."; + return temp; + } + + public static string GetCapsURL(LLUUID userID) + { + if (capsURLS.ContainsKey(userID)) + { + return capsURLS[userID]; + } + return String.Empty; + } + + public static void SetCapsURL(LLUUID userID, string url) + { + if (capsURLS.ContainsKey(userID)) + { + capsURLS[userID] = url; + } + else + { + capsURLS.Add(userID, url); + } + } + + // Nini (config) related Methods + public static IConfigSource ConvertDataRowToXMLConfig(DataRow row, string fileName) + { + if (!File.Exists(fileName)) + { + //create new file + } + XmlConfigSource config = new XmlConfigSource(fileName); + AddDataRowToConfig(config, row); + config.Save(); + + return config; + } + + public static void AddDataRowToConfig(IConfigSource config, DataRow row) + { + config.Configs.Add((string) row[0]); + for (int i = 0; i < row.Table.Columns.Count; i++) + { + config.Configs[(string) row[0]].Set(row.Table.Columns[i].ColumnName, row[i]); + } + } + + public static float Clip(float x, float min, float max) + { + return Math.Min(Math.Max(x, min), max); + } + + public static int Clip(int x, int min, int max) + { + return Math.Min(Math.Max(x, min), max); + } + + /// + /// Convert an LLUUID to a raw uuid string. Right now this is a string without hyphens. + /// + /// + /// + public static String ToRawUuidString(LLUUID lluuid) + { + return lluuid.UUID.ToString("n"); + } + + public static string CleanString(string input) + { + if(input.Length == 0) + return input; + + int clip=input.Length; + + // Test for ++ string terminator + int pos=input.IndexOf("\0"); + if(pos != -1 && pos < clip) + clip=pos; + + // Test for CR + pos=input.IndexOf("\r"); + if(pos != -1 && pos < clip) + clip=pos; + + // Test for LF + pos=input.IndexOf("\n"); + if(pos != -1 && pos < clip) + clip=pos; + + // Truncate string before first end-of-line character found + return input.Substring(0, clip); + } + + /// + /// returns the contents of /etc/issue on Unix Systems + /// Use this for where it's absolutely necessary to implement platform specific stuff + /// ( like the ODE library :P + /// + /// + public static string ReadEtcIssue() + { + try + { + StreamReader sr = new StreamReader("/etc/issue.net"); + string issue = sr.ReadToEnd(); + sr.Close(); + return issue; + } + catch (System.Exception) + { + return ""; + } + + } + } +}