diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 004b1a67a2..881f815a46 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -717,7 +717,7 @@ namespace OpenSim.Framework /// The scene agent for this client. This will only be set if the client has an agent in a scene (i.e. if it /// is connected). /// - ISceneAgent SceneAgent { get; } + ISceneAgent SceneAgent { get; set; } UUID SessionId { get; } diff --git a/OpenSim/Framework/LandData.cs b/OpenSim/Framework/LandData.cs index 9a9a6bf607..dcaa46d960 100644 --- a/OpenSim/Framework/LandData.cs +++ b/OpenSim/Framework/LandData.cs @@ -69,7 +69,7 @@ namespace OpenSim.Framework (uint) ParcelFlags.AllowAPrimitiveEntry | (uint) ParcelFlags.AllowDeedToGroup | (uint) ParcelFlags.CreateObjects | (uint) ParcelFlags.AllowOtherScripts | - (uint) ParcelFlags.SoundLocal; + (uint) ParcelFlags.SoundLocal | (uint) ParcelFlags.AllowVoiceChat; private byte _landingType = 0; private string _name = "Your Parcel"; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index d0920d26ee..54fc7f44f7 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -396,7 +396,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } public UUID AgentId { get { return m_agentId; } } - public ISceneAgent SceneAgent { get; private set; } + public ISceneAgent SceneAgent { get; set; } public UUID ActiveGroupId { get { return m_activeGroupID; } } public string ActiveGroupName { get { return m_activeGroupName; } } public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } } @@ -719,7 +719,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public virtual void Start() { - SceneAgent = m_scene.AddNewClient(this, PresenceType.User); + m_scene.AddNewClient(this, PresenceType.User); RefreshGroupMembership(); } diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 8e32fcc133..4cc0e1972b 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -57,7 +57,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends { public UUID PrincipalID; public FriendInfo[] Friends; - public int Refcount; public bool IsFriend(string friend) { @@ -255,6 +254,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends private void OnNewClient(IClientAPI client) { + if (client.SceneAgent.IsChildAgent) + return; + client.OnInstantMessage += OnInstantMessage; client.OnApproveFriendRequest += OnApproveFriendRequest; client.OnDenyFriendRequest += OnDenyFriendRequest; @@ -281,23 +283,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends UUID agentID = client.AgentId; lock (m_Friends) { - UserFriendData friendsData; - if (m_Friends.TryGetValue(agentID, out friendsData)) - { - friendsData.Refcount++; - return false; - } - else - { - friendsData = new UserFriendData(); - friendsData.PrincipalID = agentID; - friendsData.Friends = GetFriendsFromService(client); - friendsData.Refcount = 1; + UserFriendData friendsData = new UserFriendData(); + friendsData.PrincipalID = agentID; + friendsData.Friends = GetFriendsFromService(client); - m_Friends[agentID] = friendsData; - return true; - } + m_Friends[agentID] = friendsData; } + + return true; } private void OnClientClosed(UUID agentID, Scene scene) @@ -307,23 +300,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends { // do this for root agents closing out StatusChange(agentID, false); - } - lock (m_Friends) - { - UserFriendData friendsData; - if (m_Friends.TryGetValue(agentID, out friendsData)) - { - friendsData.Refcount--; - if (friendsData.Refcount <= 0) - m_Friends.Remove(agentID); - } + lock (m_Friends) + m_Friends.Remove(agentID); } } private void OnMakeRootAgent(ScenePresence sp) { - RecacheFriends(sp.ControllingClient); + // FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event + // is on the critical path for transferring an avatar from one region to another. + CacheFriends(sp.ControllingClient); } private void OnClientLogin(IClientAPI client) @@ -628,8 +615,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends ccm.CreateCallingCard(client.AgentId, friendID, UUID.Zero); } - // Update the local cache - RecacheFriends(client); + // Update the local cache. + CacheFriends(client); // // Notify the friend @@ -691,7 +678,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends client.SendAlertMessage("Unable to terminate friendship on this sim."); // Update local cache - RecacheFriends(client); + CacheFriends(client); client.SendTerminateFriend(exfriendID); @@ -812,7 +799,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends // Update the local cache - RecacheFriends(friendClient); + CacheFriends(friendClient); // we're done return true; @@ -845,7 +832,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends // the friend in this sim as root agent friendClient.SendTerminateFriend(exfriendID); // update local cache - RecacheFriends(friendClient); + CacheFriends(friendClient); // we're done return true; } @@ -946,19 +933,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends return FriendsService.GetFriends(client.AgentId); } - protected void RecacheFriends(IClientAPI client) - { - // FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event - // is on the critical path for transferring an avatar from one region to another. - UUID agentID = client.AgentId; - lock (m_Friends) - { - UserFriendData friendsData; - if (m_Friends.TryGetValue(agentID, out friendsData)) - friendsData.Friends = GetFriendsFromService(client); - } - } - /// /// Are friends cached on this simulator for a particular user? /// @@ -1052,4 +1026,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index e50a84a76e..7bc30181a0 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -121,7 +121,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends { UUID agentID = client.AgentId; // we do this only for the root agent - if (m_Friends[agentID].Refcount == 1) + if (!client.SceneAgent.IsChildAgent) { // We need to preload the user management cache with the names // of foreign friends, just like we do with SOPs' creators @@ -426,14 +426,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode); agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); - RecacheFriends(agentClient); + CacheFriends(agentClient); } if (friendClient != null) { friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode); friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit); friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); - RecacheFriends(friendClient); + CacheFriends(friendClient); } m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}", diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index aaba7fde36..6fc8e4d434 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -71,7 +71,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (name == Name) { InitialiseCommon(source); - IConfig transferConfig = source.Configs["HGEntityTransfer"]; + IConfig transferConfig = source.Configs["HGEntityTransferModule"]; if (transferConfig != null) m_RestrictInventoryAccessAbroad = transferConfig.GetBoolean("RestrictInventoryAccessAbroad", false); @@ -94,6 +94,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer client.OnTeleportHomeRequest += TriggerTeleportHome; client.OnTeleportLandmarkRequest += RequestTeleportLandmark; client.OnConnectionClosed += new Action(OnConnectionClosed); + client.OnCompleteMovementToRegion += new Action(OnCompleteMovementToRegion); + } + + protected void OnCompleteMovementToRegion(IClientAPI client, bool arg2) + { + // HACK HACK -- just seeing how the viewer responds + // Let's send the Suitcase or the real root folder folder for incoming HG agents + // Visiting agents get their suitcase contents; incoming local users get their real root folder's content + m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: OnCompleteMovementToRegion of user {0}", client.AgentId); + object sp = null; + if (client.Scene.TryGetScenePresence(client.AgentId, out sp)) + { + if (sp is ScenePresence) + { + AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId); + if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) + { + m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: ViaHGLogin"); + if (m_RestrictInventoryAccessAbroad) + { + RestoreRootFolderContents(client); + } + } + } + } } @@ -105,6 +130,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); m_Initialized = true; + + scene.AddCommand( + "HG", this, "send inventory", + "send inventory", + "Don't use this", + HandleSendInventory); + } } @@ -374,7 +406,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer InventoryFolderBase root = m_Scenes[0].InventoryService.GetRootFolder(client.AgentId); if (root != null) { - m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Removing root inventory"); + m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Removing root inventory for user {0}", client.AgentId); InventoryCollection content = m_Scenes[0].InventoryService.GetFolderContent(client.AgentId, root.ID); UUID[] ids = new UUID[content.Folders.Count]; int i = 0; @@ -393,12 +425,26 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer private void RestoreRootFolderContents(IClientAPI client) { - // Restore the user's inventory, because we removed it earlier on - InventoryFolderBase root = m_Scenes[0].InventoryService.GetRootFolder(client.AgentId); - if (root != null) + if (client is IClientCore) { - m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Restoring root inventory"); - client.SendBulkUpdateInventory(root); + IClientCore core = (IClientCore)client; + IClientInventory inv; + + if (core.TryGet(out inv)) + { + InventoryFolderBase root = m_Scenes[0].InventoryService.GetRootFolder(client.AgentId); + client.SendBulkUpdateInventory(root); + //if (root != null) + //{ + // m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Restoring root inventory for user {0}", client.AgentId); + // InventoryCollection content = m_Scenes[0].InventoryService.GetFolderContent(client.AgentId, root.ID); + // m_log.DebugFormat("[XXX]: Folder name {0}, id {1}, parent {2}", root.Name, root.ID, root.ParentID); + // foreach (InventoryItemBase i in content.Items) + // m_log.DebugFormat("[XXX]: Name={0}, folderID={1}", i.Name, i.Folder); + + // inv.SendBulkUpdateInventory(content.Folders.ToArray(), content.Items.ToArray()); + //} + } } } @@ -418,5 +464,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), (int)0); return region; } + + protected void HandleSendInventory(string module, string[] cmd) + { + m_Scenes[0].ForEachClient(delegate(IClientAPI client) + { + RestoreRootFolderContents(client); + }); + } + } } diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 470ce2e4a1..741d23336e 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -75,6 +75,7 @@ namespace OpenSim.Region.Framework.Scenes /// Triggered when a new client is added to the scene. /// /// + /// This is triggered for both child and root agent client connections. /// Triggered before OnClientLogin. /// public event OnNewClientDelegate OnNewClient; @@ -195,7 +196,7 @@ namespace OpenSim.Region.Framework.Scenes public delegate void ClientClosed(UUID clientID, Scene scene); /// - /// Fired when a client is removed from a scene. + /// Fired when a client is removed from a scene whether it's a child or a root agent. /// /// /// At the point of firing, the scene still contains the client's scene presence. diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index cac178d3f6..cf3270da1e 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2795,6 +2795,10 @@ namespace OpenSim.Region.Framework.Scenes sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); } + // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the + // client is for a root or child agent. + client.SceneAgent = sp; + m_LastLogin = Util.EnvironmentTickCount(); // Cache the user's name diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index ee8a236f50..ed3a7f11fa 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1237,22 +1237,6 @@ namespace OpenSim.Region.Framework.Scenes friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); } - // HACK HACK -- just seeing how the viewer responds - // Let's send the Suitcase or the real root folder folder for incoming HG agents - // Visiting agents get their suitcase contents; incoming local users get their real root folder's content - AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(UUID); - if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) - { - // HACK FOR NOW. JUST TESTING, SO KEEPING EVERYONE ELSE OUT OF THESE TESTS - IConfig config = m_scene.Config.Configs["HGEntityTransferModule"]; - if (config != null && config.GetBoolean("RestrictInventoryAccessAbroad", false)) - { - m_log.DebugFormat("[SCENE]: Sending root folder to viewer..."); - InventoryFolderBase root = m_scene.InventoryService.GetRootFolder(client.AgentId); - //InventoryCollection rootContents = InventoryService.GetFolderContent(client.AgentId, root.ID); - client.SendBulkUpdateInventory(root); - } - } // m_log.DebugFormat( // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 655f3a5097..a37e99714d 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -55,7 +55,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server private UUID m_agentID = UUID.Random(); - public ISceneAgent SceneAgent { get; private set; } + public ISceneAgent SceneAgent { get; set; } private string m_username; private string m_nick; @@ -903,7 +903,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server public void Start() { - SceneAgent = m_scene.AddNewClient(this, PresenceType.User); + m_scene.AddNewClient(this, PresenceType.User); // Mimicking LLClientView which gets always set appearance from client. AvatarAppearance appearance; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index a2375fe548..c3335f099e 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -72,7 +72,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC get { return m_ownerID; } } - public ISceneAgent SceneAgent { get { throw new NotImplementedException(); } } + public ISceneAgent SceneAgent { get; set; } public void Say(string message) { diff --git a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs new file mode 100644 index 0000000000..a9998866d2 --- /dev/null +++ b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs @@ -0,0 +1,368 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using OpenMetaverse; +using log4net; +using Nini.Config; +using System.Reflection; +using OpenSim.Services.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Services.InventoryService; +using OpenSim.Data; +using OpenSim.Framework; +using OpenSim.Server.Base; + +namespace OpenSim.Services.HypergridService +{ + /// + /// Hypergrid inventory service. It serves the IInventoryService interface, + /// but implements it in ways that are appropriate for inter-grid + /// inventory exchanges. Specifically, it does not performs deletions + /// and it responds to GetRootFolder requests with the ID of the + /// Suitcase folder, not the actual "My Inventory" folder. + /// + public class HGSuitcaseInventoryService : XInventoryService, IInventoryService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_HomeURL; + private IUserAccountService m_UserAccountService; + + private UserAccountCache m_Cache; + + public HGSuitcaseInventoryService(IConfigSource config, string configName) + : base(config, configName) + { + m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Starting with config name {0}", configName); + if (configName != string.Empty) + m_ConfigName = configName; + + if (m_Database == null) + m_log.WarnFormat("[XXX]: m_Database is null!"); + + // + // Try reading the [InventoryService] section, if it exists + // + IConfig invConfig = config.Configs[m_ConfigName]; + if (invConfig != null) + { + // realm = authConfig.GetString("Realm", realm); + string userAccountsDll = invConfig.GetString("UserAccountsService", string.Empty); + if (userAccountsDll == string.Empty) + throw new Exception("Please specify UserAccountsService in HGInventoryService configuration"); + + Object[] args = new Object[] { config }; + m_UserAccountService = ServerUtils.LoadPlugin(userAccountsDll, args); + if (m_UserAccountService == null) + throw new Exception(String.Format("Unable to create UserAccountService from {0}", userAccountsDll)); + + // legacy configuration [obsolete] + m_HomeURL = invConfig.GetString("ProfileServerURI", string.Empty); + // Preferred + m_HomeURL = invConfig.GetString("HomeURI", m_HomeURL); + + m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService); + } + + m_log.Debug("[HG SUITCASE INVENTORY SERVICE]: Starting..."); + } + + public override bool CreateUserInventory(UUID principalID) + { + // NOGO + return false; + } + + + public override List GetInventorySkeleton(UUID principalID) + { + // NOGO for this inventory service + return new List(); + } + + public override InventoryFolderBase GetRootFolder(UUID principalID) + { + m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetRootFolder for {0}", principalID); + if (m_Database == null) + m_log.ErrorFormat("[XXX]: m_Database is NULL!"); + + // Let's find out the local root folder + XInventoryFolder root = GetRootXFolder(principalID); ; + if (root == null) + { + m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: Unable to retrieve local root folder for user {0}", principalID); + } + + // Warp! Root folder for travelers is the suitcase folder + XInventoryFolder suitcase = GetSuitcaseXFolder(principalID); + + if (suitcase == null) + { + m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: User {0} does not have a Suitcase folder. Creating it...", principalID); + // make one, and let's add it to the user's inventory as a direct child of the root folder + suitcase = CreateFolder(principalID, root.folderID, 100, "My Suitcase"); + if (suitcase == null) + m_log.ErrorFormat("[HG SUITCASE INVENTORY SERVICE]: Unable to create suitcase folder"); + + m_Database.StoreFolder(suitcase); + } + + // Now let's change the folder ID to match that of the real root folder + SetAsRootFolder(suitcase, root.folderID); + + return ConvertToOpenSim(suitcase); + } + + public override InventoryFolderBase GetFolderForType(UUID principalID, AssetType type) + { + //m_log.DebugFormat("[HG INVENTORY SERVICE]: GetFolderForType for {0} {0}", principalID, type); + return GetRootFolder(principalID); + } + + // + // Use the inherited methods + // + public override InventoryCollection GetFolderContent(UUID principalID, UUID folderID) + { + InventoryCollection coll = null; + XInventoryFolder root = GetRootXFolder(principalID); + if (folderID == root.folderID) // someone's asking for the root folder, we'll give them the suitcase + { + XInventoryFolder suitcase = GetSuitcaseXFolder(principalID); + if (suitcase != null) + { + coll = base.GetFolderContent(principalID, suitcase.folderID); + foreach (InventoryFolderBase f in coll.Folders) + f.ParentID = root.folderID; + foreach (InventoryItemBase i in coll.Items) + i.Folder = root.folderID; + m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetFolderContent for root folder returned content for suitcase folder"); + } + } + else + { + coll = base.GetFolderContent(principalID, folderID); + m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetFolderContent for non-root folder {0}", folderID); + } + if (coll == null) + { + m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: Something wrong with user {0}'s suitcase folder", principalID); + coll = new InventoryCollection(); + } + return coll; + } + + //public List GetFolderItems(UUID principalID, UUID folderID) + //{ + //} + + //public override bool AddFolder(InventoryFolderBase folder) + //{ + // // Check if it's under the Suitcase folder + // List skel = base.GetInventorySkeleton(folder.Owner); + // InventoryFolderBase suitcase = GetRootFolder(folder.Owner); + // List suitDescendents = GetDescendents(skel, suitcase.ID); + + // foreach (InventoryFolderBase f in suitDescendents) + // if (folder.ParentID == f.ID) + // { + // XInventoryFolder xFolder = ConvertFromOpenSim(folder); + // return m_Database.StoreFolder(xFolder); + // } + // return false; + //} + + private List GetDescendents(List lst, UUID root) + { + List direct = lst.FindAll(delegate(InventoryFolderBase f) { return f.ParentID == root; }); + if (direct == null) + return new List(); + + List indirect = new List(); + foreach (InventoryFolderBase f in direct) + indirect.AddRange(GetDescendents(lst, f.ID)); + + direct.AddRange(indirect); + return direct; + } + + // Use inherited method + //public bool UpdateFolder(InventoryFolderBase folder) + //{ + //} + + //public override bool MoveFolder(InventoryFolderBase folder) + //{ + // XInventoryFolder[] x = m_Database.GetFolders( + // new string[] { "folderID" }, + // new string[] { folder.ID.ToString() }); + + // if (x.Length == 0) + // return false; + + // // Check if it's under the Suitcase folder + // List skel = base.GetInventorySkeleton(folder.Owner); + // InventoryFolderBase suitcase = GetRootFolder(folder.Owner); + // List suitDescendents = GetDescendents(skel, suitcase.ID); + + // foreach (InventoryFolderBase f in suitDescendents) + // if (folder.ParentID == f.ID) + // { + // x[0].parentFolderID = folder.ParentID; + // return m_Database.StoreFolder(x[0]); + // } + + // return false; + //} + + public override bool DeleteFolders(UUID principalID, List folderIDs) + { + // NOGO + return false; + } + + public override bool PurgeFolder(InventoryFolderBase folder) + { + // NOGO + return false; + } + + // Unfortunately we need to use the inherited method because of how DeRez works. + // The viewer sends the folderID hard-wired in the derez message + //public override bool AddItem(InventoryItemBase item) + //{ + // // Check if it's under the Suitcase folder + // List skel = base.GetInventorySkeleton(item.Owner); + // InventoryFolderBase suitcase = GetRootFolder(item.Owner); + // List suitDescendents = GetDescendents(skel, suitcase.ID); + + // foreach (InventoryFolderBase f in suitDescendents) + // if (item.Folder == f.ID) + // return m_Database.StoreItem(ConvertFromOpenSim(item)); + + // return false; + //} + + //public override bool UpdateItem(InventoryItemBase item) + //{ + // // Check if it's under the Suitcase folder + // List skel = base.GetInventorySkeleton(item.Owner); + // InventoryFolderBase suitcase = GetRootFolder(item.Owner); + // List suitDescendents = GetDescendents(skel, suitcase.ID); + + // foreach (InventoryFolderBase f in suitDescendents) + // if (item.Folder == f.ID) + // return m_Database.StoreItem(ConvertFromOpenSim(item)); + + // return false; + //} + + //public override bool MoveItems(UUID principalID, List items) + //{ + // // Principal is b0rked. *sigh* + // // + // // Let's assume they all have the same principal + // // Check if it's under the Suitcase folder + // List skel = base.GetInventorySkeleton(items[0].Owner); + // InventoryFolderBase suitcase = GetRootFolder(items[0].Owner); + // List suitDescendents = GetDescendents(skel, suitcase.ID); + + // foreach (InventoryItemBase i in items) + // { + // foreach (InventoryFolderBase f in suitDescendents) + // if (i.Folder == f.ID) + // m_Database.MoveItem(i.ID.ToString(), i.Folder.ToString()); + // } + + // return true; + //} + + // Let these pass. Use inherited methods. + //public bool DeleteItems(UUID principalID, List itemIDs) + //{ + //} + + //public override InventoryItemBase GetItem(InventoryItemBase item) + //{ + // InventoryItemBase it = base.GetItem(item); + // if (it != null) + // { + // UserAccount user = m_Cache.GetUser(it.CreatorId); + + // // Adjust the creator data + // if (user != null && it != null && (it.CreatorData == null || it.CreatorData == string.Empty)) + // it.CreatorData = m_HomeURL + ";" + user.FirstName + " " + user.LastName; + // } + // return it; + //} + + //public InventoryFolderBase GetFolder(InventoryFolderBase folder) + //{ + //} + + //public List GetActiveGestures(UUID principalID) + //{ + //} + + //public int GetAssetPermissions(UUID principalID, UUID assetID) + //{ + //} + + private XInventoryFolder GetRootXFolder(UUID principalID) + { + XInventoryFolder[] folders = m_Database.GetFolders( + new string[] { "agentID", "folderName", "type" }, + new string[] { principalID.ToString(), "My Inventory", ((int)AssetType.RootFolder).ToString() }); + + if (folders != null && folders.Length > 0) + return folders[0]; + return null; + } + + private XInventoryFolder GetSuitcaseXFolder(UUID principalID) + { + // Warp! Root folder for travelers + XInventoryFolder[] folders = m_Database.GetFolders( + new string[] { "agentID", "type" }, + new string[] { principalID.ToString(), "100" }); // This is a special folder type... + + if (folders != null && folders.Length > 0) + return folders[0]; + return null; + } + + private void SetAsRootFolder(XInventoryFolder suitcase, UUID rootID) + { + suitcase.folderID = rootID; + suitcase.parentFolderID = UUID.Zero; + } + } +} diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 81a5cf7cfd..64dd1e48d1 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -329,7 +329,7 @@ namespace OpenSim.Tests.Common.Mock /// private UUID m_agentId; - public ISceneAgent SceneAgent { get { throw new NotImplementedException(); } } + public ISceneAgent SceneAgent { get; set; } /// /// The last caps seed url that this client was given. diff --git a/bin/Physics/OpenSim.Region.Physics.BulletSPlugin.dll.config b/bin/Physics/OpenSim.Region.Physics.BulletSPlugin.dll.config index 026417a410..1bc7e413ff 100755 --- a/bin/Physics/OpenSim.Region.Physics.BulletSPlugin.dll.config +++ b/bin/Physics/OpenSim.Region.Physics.BulletSPlugin.dll.config @@ -1,6 +1,6 @@ - - - - + + + + diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll index 5bef6e9a22..2c28063f4c 100755 Binary files a/bin/lib32/BulletSim.dll and b/bin/lib32/BulletSim.dll differ diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so index 9882f5b8b1..f40f446213 100755 Binary files a/bin/lib32/libBulletSim.so and b/bin/lib32/libBulletSim.so differ diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll index 9f09ef8bf5..d9e5e89874 100755 Binary files a/bin/lib64/BulletSim.dll and b/bin/lib64/BulletSim.dll differ diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so index fa47bf1830..06770a4e69 100755 Binary files a/bin/lib64/libBulletSim.so and b/bin/lib64/libBulletSim.so differ diff --git a/bin/libBulletSim-x86_64.so b/bin/libBulletSim-x86_64.so deleted file mode 100755 index 527eda5780..0000000000 Binary files a/bin/libBulletSim-x86_64.so and /dev/null differ diff --git a/bin/libBulletSim.so b/bin/libBulletSim.so deleted file mode 100755 index 9f91bfd411..0000000000 Binary files a/bin/libBulletSim.so and /dev/null differ