From 549dc5aeb9e693f1f575896796d19b03ec3a732f Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 28 Apr 2011 08:58:04 -0700 Subject: [PATCH 01/41] Eliminated sAgentCircuitData, a data structure that has been obsolete for quite some time. --- OpenSim/Framework/AgentCircuitData.cs | 69 ------------------- OpenSim/Framework/ClientInfo.cs | 2 +- .../ClientStack/LindenUDP/LLClientView.cs | 2 +- 3 files changed, 2 insertions(+), 71 deletions(-) diff --git a/OpenSim/Framework/AgentCircuitData.cs b/OpenSim/Framework/AgentCircuitData.cs index 3dbc215d46..dbd47d392a 100644 --- a/OpenSim/Framework/AgentCircuitData.cs +++ b/OpenSim/Framework/AgentCircuitData.cs @@ -151,27 +151,6 @@ namespace OpenSim.Framework { } - /// - /// Create AgentCircuitData from a Serializable AgentCircuitData - /// - /// - public AgentCircuitData(sAgentCircuitData cAgent) - { - AgentID = new UUID(cAgent.AgentID); - SessionID = new UUID(cAgent.SessionID); - SecureSessionID = new UUID(cAgent.SecureSessionID); - startpos = new Vector3(cAgent.startposx, cAgent.startposy, cAgent.startposz); - firstname = cAgent.firstname; - lastname = cAgent.lastname; - circuitcode = cAgent.circuitcode; - child = cAgent.child; - InventoryFolder = new UUID(cAgent.InventoryFolder); - BaseFolder = new UUID(cAgent.BaseFolder); - CapsPath = cAgent.CapsPath; - ChildrenCapSeeds = cAgent.ChildrenCapSeeds; - Viewer = cAgent.Viewer; - } - /// /// Pack AgentCircuitData into an OSDMap for transmission over LLSD XML or LLSD json /// @@ -369,52 +348,4 @@ namespace OpenSim.Framework } - /// - /// Serializable Agent Circuit Data - /// - [Serializable] - public class sAgentCircuitData - { - public Guid AgentID; - public Guid BaseFolder; - public string CapsPath = String.Empty; - public Dictionary ChildrenCapSeeds; - public bool child; - public uint circuitcode; - public string firstname; - public Guid InventoryFolder; - public string lastname; - public Guid SecureSessionID; - public Guid SessionID; - public float startposx; - public float startposy; - public float startposz; - public string Viewer; - public string Channel; - public string Mac; - public string Id0; - - public sAgentCircuitData() - { - } - - public sAgentCircuitData(AgentCircuitData cAgent) - { - AgentID = cAgent.AgentID.Guid; - SessionID = cAgent.SessionID.Guid; - SecureSessionID = cAgent.SecureSessionID.Guid; - 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.Guid; - BaseFolder = cAgent.BaseFolder.Guid; - CapsPath = cAgent.CapsPath; - ChildrenCapSeeds = cAgent.ChildrenCapSeeds; - Viewer = cAgent.Viewer; - } - } } diff --git a/OpenSim/Framework/ClientInfo.cs b/OpenSim/Framework/ClientInfo.cs index fbd18b5636..8292c6aa0b 100644 --- a/OpenSim/Framework/ClientInfo.cs +++ b/OpenSim/Framework/ClientInfo.cs @@ -34,7 +34,7 @@ namespace OpenSim.Framework [Serializable] public class ClientInfo { - public sAgentCircuitData agentcircuit; + public AgentCircuitData agentcircuit; public Dictionary needAck; diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 22bad99641..43903ce1bd 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -11635,7 +11635,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP info.userEP = m_userEndPoint; info.proxyEP = null; - info.agentcircuit = new sAgentCircuitData(RequestClientInfo()); + info.agentcircuit = RequestClientInfo(); return info; } From 35f190cc920d3c6fd94c48928d29e15a9b143abf Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 28 Apr 2011 09:06:57 -0700 Subject: [PATCH 02/41] One less [Serializable] -- ClientInfo. --- OpenSim/Framework/ClientInfo.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/OpenSim/Framework/ClientInfo.cs b/OpenSim/Framework/ClientInfo.cs index 8292c6aa0b..62acb70566 100644 --- a/OpenSim/Framework/ClientInfo.cs +++ b/OpenSim/Framework/ClientInfo.cs @@ -31,7 +31,6 @@ using System.Net; namespace OpenSim.Framework { - [Serializable] public class ClientInfo { public AgentCircuitData agentcircuit; From 9892e115ccdcc8567087041917fb5c7694aa8836 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 28 Apr 2011 20:19:54 -0700 Subject: [PATCH 03/41] Fatpack message on agent transfers: 1 message only (UpdateAgent) containing the agent and all attachments. Preserves backwards compatibility -- older sims get passed attachments one by one. Meaning that I finally introduced versioning in the simulation service. --- OpenSim/Framework/ChildAgentDataUpdate.cs | 57 +++++++- .../Framework/Tests/MundaneFrameworkTests.cs | 2 +- .../Avatar/Attachments/AttachmentsModule.cs | 13 +- .../EntityTransfer/EntityTransferModule.cs | 61 +++++---- .../EntityTransfer/HGEntityTransferModule.cs | 5 +- .../Simulation/LocalSimulationConnector.cs | 6 +- .../Simulation/RemoteSimulationConnector.cs | 7 +- OpenSim/Region/Framework/Scenes/Scene.cs | 4 +- .../Framework/Scenes/SceneObjectGroup.cs | 2 + .../Region/Framework/Scenes/ScenePresence.cs | 124 ++++-------------- .../Handlers/Simulation/AgentHandlers.cs | 9 +- .../Simulation/SimulationServiceConnector.cs | 21 +-- .../Services/Interfaces/ISimulationService.cs | 2 +- 13 files changed, 157 insertions(+), 156 deletions(-) diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index ce0b2fb784..a626b82302 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -62,7 +62,7 @@ namespace OpenSim.Framework UUID AgentID { get; set; } OSDMap Pack(); - void Unpack(OSDMap map); + void Unpack(OSDMap map, IScene scene); } /// @@ -122,7 +122,7 @@ namespace OpenSim.Framework return args; } - public void Unpack(OSDMap args) + public void Unpack(OSDMap args, IScene scene) { if (args.ContainsKey("region_handle")) UInt64.TryParse(args["region_handle"].AsString(), out RegionHandle); @@ -329,6 +329,10 @@ namespace OpenSim.Framework public string CallbackURI; + // These two must have the same Count + public List AttachmentObjects; + public List AttachmentObjectStates; + public virtual OSDMap Pack() { m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data"); @@ -441,7 +445,30 @@ namespace OpenSim.Framework if ((CallbackURI != null) && (!CallbackURI.Equals(""))) args["callback_uri"] = OSD.FromString(CallbackURI); + // Attachment objects for fatpack messages + if (AttachmentObjects != null) + { + int i = 0; + OSDArray attObjs = new OSDArray(AttachmentObjects.Count); + foreach (ISceneObject so in AttachmentObjects) + { + OSDMap info = new OSDMap(4); + info["sog"] = OSD.FromString(so.ToXml2()); + info["extra"] = OSD.FromString(so.ExtraToXmlString()); + info["modified"] = OSD.FromBoolean(so.HasGroupChanged); + try + { + info["state"] = OSD.FromString(AttachmentObjectStates[i++]); + } + catch (IndexOutOfRangeException e) + { + m_log.WarnFormat("[CHILD AGENT DATA]: scrtips list is shorter than object list."); + } + attObjs.Add(info); + } + args["attach_objects"] = attObjs; + } return args; } @@ -450,7 +477,7 @@ namespace OpenSim.Framework /// Avoiding reflection makes it painful to write, but that's the price! /// /// - public virtual void Unpack(OSDMap args) + public virtual void Unpack(OSDMap args, IScene scene) { m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Unpack data"); @@ -628,6 +655,26 @@ namespace OpenSim.Framework if (args["callback_uri"] != null) CallbackURI = args["callback_uri"].AsString(); + + // Attachment objects + if (args["attach_objects"] != null && args["attach_objects"].Type == OSDType.Array) + { + OSDArray attObjs = (OSDArray)(args["attach_objects"]); + AttachmentObjects = new List(); + AttachmentObjectStates = new List(); + foreach (OSD o in attObjs) + { + if (o.Type == OSDType.Map) + { + OSDMap info = (OSDMap)o; + ISceneObject so = scene.DeserializeObject(info["sog"].AsString()); + so.ExtraFromXmlString(info["extra"].AsString()); + so.HasGroupChanged = info["modified"].AsBoolean(); + AttachmentObjects.Add(so); + AttachmentObjectStates.Add(info["state"].AsString()); + } + } + } } public AgentData() @@ -655,9 +702,9 @@ namespace OpenSim.Framework return base.Pack(); } - public override void Unpack(OSDMap map) + public override void Unpack(OSDMap map, IScene scene) { - base.Unpack(map); + base.Unpack(map, scene); } } } diff --git a/OpenSim/Framework/Tests/MundaneFrameworkTests.cs b/OpenSim/Framework/Tests/MundaneFrameworkTests.cs index e7f8bfc1f0..76de6be267 100644 --- a/OpenSim/Framework/Tests/MundaneFrameworkTests.cs +++ b/OpenSim/Framework/Tests/MundaneFrameworkTests.cs @@ -115,7 +115,7 @@ namespace OpenSim.Framework.Tests position2 = new AgentPosition(); Assert.IsFalse(position2.AgentID == position1.AgentID, "Test Error, position2 should be a blank uninitialized AgentPosition"); - position2.Unpack(position1.Pack()); + position2.Unpack(position1.Pack(), null); Assert.IsTrue(position2.AgentID == position1.AgentID, "Agent ID didn't unpack the same way it packed"); Assert.IsTrue(position2.Position == position1.Position, "Position didn't unpack the same way it packed"); diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index ff262648e5..520d794e74 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -562,14 +562,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// /// - /// + /// /// - protected void AttachToAgent(ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 AttachOffset, bool silent) + protected void AttachToAgent(ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) { - // don't attach attachments to child agents - if (avatar.IsChildAgent) return; -// m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1}", Name, avatar.Name); + m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", Name, avatar.Name, + attachmentpoint, attachOffset, so.RootPart.AttachedPos); so.DetachFromBackup(); @@ -590,8 +589,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments so.RootPart.PhysActor = null; } - so.AbsolutePosition = AttachOffset; - so.RootPart.AttachedPos = AttachOffset; + so.AbsolutePosition = attachOffset; + so.RootPart.AttachedPos = attachOffset; so.RootPart.IsAttachment = true; so.RootPart.SetParentLocalId(avatar.LocalId); diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index c88be7ddb0..10547857f7 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -285,11 +285,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } string reason; - if (!m_aScene.SimulationService.QueryAccess(finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out reason)) + string version; + if (!m_aScene.SimulationService.QueryAccess(finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) { sp.ControllingClient.SendTeleportFailed("Teleport failed: " + reason); return; } + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); sp.ControllingClient.SendTeleportStart(teleportFlags); @@ -371,20 +373,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); } - // Expect avatar crossing is a heavy-duty function at the destination. - // That is where MakeRoot is called, which fetches appearance and inventory. - // Plus triggers OnMakeRoot, which spawns a series of asynchronous updates. - //m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, - // position, false); - - //{ - // avatar.ControllingClient.SendTeleportFailed("Problem with destination."); - // // We should close that agent we just created over at destination... - // List lst = new List(); - // lst.Add(reg.RegionHandle); - // SendCloseChildAgentAsync(avatar.UUID, lst); - // return; - //} SetInTransit(sp.UUID); @@ -426,7 +414,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation - // that the client contacted the destination before we send the attachments and close things here. + // that the client contacted the destination before we close things here. if (!WaitForCallback(sp.UUID)) { m_log.WarnFormat( @@ -437,14 +425,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it - CrossAttachmentsIntoNewRegion(finalDestination, sp, true); + // For backwards compatibility + if (version == "Unknown" || version == string.Empty) + { + // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old simulator, sending attachments one by one..."); + CrossAttachmentsIntoNewRegion(finalDestination, sp, true); + } + + // May need to logout or other cleanup + AgentHasMovedAway(sp, logout); // Well, this is it. The agent is over there. KillEntity(sp.Scene, sp.LocalId); - // May need to logout or other cleanup - AgentHasMovedAway(sp.ControllingClient.SessionId, logout); // Now let's make it officially a child agent sp.MakeChildAgent(); @@ -513,8 +507,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } - protected virtual void AgentHasMovedAway(UUID sessionID, bool logout) + protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout) { + foreach (SceneObjectGroup sop in sp.Attachments) + { + sop.Scene.DeleteSceneObject(sop, true); + } + sp.Attachments.Clear(); } protected void KillEntity(Scene scene, uint localID) @@ -784,7 +783,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); string reason; - if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out reason)) + string version; + if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason)) { agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); if (r == null) @@ -804,7 +804,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.InTransit(); CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; - d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, CrossAgentToNewRegionCompleted, d); + d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); return true; } @@ -861,17 +861,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer icon.EndInvoke(iar); } - public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying); + public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); /// /// This Closes child agents on neighbouring regions /// Calls an asynchronous method to do so.. so it doesn't lag the sim. /// - protected ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying) + protected ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version) { ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3}", agent.Firstname, agent.Lastname, neighbourx, neighboury); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", agent.Firstname, agent.Lastname, neighbourx, neighboury, version); Scene m_scene = agent.Scene; @@ -945,7 +945,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.SendOtherAgentsAvatarDataToMe(); agent.SendOtherAgentsAppearanceToMe(); - CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); + // Backwards compatibility + if (version == "Unknown" || version == string.Empty) + { + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old neighbor, passing attachments one by one..."); + CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); + } + + AgentHasMovedAway(agent, false); // the user may change their profile information in other region, // so the userinfo in UserProfileCache is not reliable any more, delete it diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 79e76b4cbf..5c53f787bf 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -142,11 +142,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return false; } - protected override void AgentHasMovedAway(UUID sessionID, bool logout) + protected override void AgentHasMovedAway(ScenePresence sp, bool logout) { + base.AgentHasMovedAway(sp, logout); if (logout) // Log them out of this grid - m_aScene.PresenceService.LogoutAgent(sessionID); + m_aScene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId); } protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index a298b65820..2cf02b5544 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs @@ -41,6 +41,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation public class LocalSimulationConnectorModule : ISharedRegionModule, ISimulationService { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + // Version of this service + private const string m_Version = "SIMULATION/0.1"; + private List m_sceneList = new List(); private IEntityTransferModule m_AgentTransferModule; @@ -257,9 +260,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return false; } - public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string reason) + public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason) { reason = "Communications failure"; + version = m_Version; if (destination == null) return false; diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs index 67f4d6030c..7858f2afd3 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs @@ -229,19 +229,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation } - public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string reason) + public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason) { reason = "Communications failure"; + version = "Unknown"; if (destination == null) return false; // Try local first - if (m_localBackend.QueryAccess(destination, id, position, out reason)) + if (m_localBackend.QueryAccess(destination, id, position, out version, out reason)) return true; // else do the remote thing if (!m_localBackend.IsLocalRegion(destination.RegionHandle)) - return m_remoteConnector.QueryAccess(destination, id, position, out reason); + return m_remoteConnector.QueryAccess(destination, id, position, out version, out reason); return false; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 01de82451f..696c6ee453 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2316,7 +2316,9 @@ namespace OpenSim.Region.Framework.Scenes /// public bool IncomingCreateObject(ISceneObject sog) { - //m_log.Debug(" >>> IncomingCreateObject(sog) <<< " + ((SceneObjectGroup)sog).AbsolutePosition + " deleted? " + ((SceneObjectGroup)sog).IsDeleted); + //m_log.DebugFormat(" >>> IncomingCreateObject(sog) <<< {0} deleted? {1} isAttach? {2}", ((SceneObjectGroup)sog).AbsolutePosition, + // ((SceneObjectGroup)sog).IsDeleted, ((SceneObjectGroup)sog).RootPart.IsAttachment); + SceneObjectGroup newObject; try { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 19a95062b4..bccbe683f7 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3361,6 +3361,8 @@ namespace OpenSim.Region.Framework.Scenes { SceneObjectGroup sog = Copy(false); sog.m_isDeleted = false; + sog.RootPart.IsAttachment = false; + sog.RootPart.GroupPosition = sog.RootPart.AttachedPos; return sog; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index e4413a95c9..507fc50f99 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3078,54 +3078,6 @@ namespace OpenSim.Region.Framework.Scenes cAgent.Appearance = new AvatarAppearance(m_appearance); -/* - try - { - // We might not pass the Wearables in all cases... - // They're only needed so that persistent changes to the appearance - // are preserved in the new region where the user is moving to. - // But in Hypergrid we might not let this happen. - int i = 0; - UUID[] wears = new UUID[m_appearance.Wearables.Length * 2]; - foreach (AvatarWearable aw in m_appearance.Wearables) - { - if (aw != null) - { - wears[i++] = aw.ItemID; - wears[i++] = aw.AssetID; - } - else - { - wears[i++] = UUID.Zero; - wears[i++] = UUID.Zero; - } - } - cAgent.Wearables = wears; - - cAgent.VisualParams = m_appearance.VisualParams; - - if (m_appearance.Texture != null) - cAgent.AgentTextures = m_appearance.Texture.GetBytes(); - } - catch (Exception e) - { - m_log.Warn("[SCENE PRESENCE]: exception in CopyTo " + e.Message); - } - - //Attachments - List attPoints = m_appearance.GetAttachedPoints(); - if (attPoints != null) - { - //m_log.DebugFormat("[SCENE PRESENCE]: attachments {0}", attPoints.Count); - int i = 0; - AvatarAttachment[] attachs = new AvatarAttachment[attPoints.Count]; - foreach (int point in attPoints) - { - attachs[i++] = new AvatarAttachment(point, m_appearance.GetAttachedItem(point), m_appearance.GetAttachedAsset(point)); - } - cAgent.Attachments = attachs; - } -*/ lock (scriptedcontrols) { ControllerData[] controls = new ControllerData[scriptedcontrols.Count]; @@ -3145,9 +3097,21 @@ namespace OpenSim.Region.Framework.Scenes } catch { } - // cAgent.GroupID = ?? - // Groups??? - + // Attachment objects + if (m_attachments != null && m_attachments.Count > 0) + { + cAgent.AttachmentObjects = new List(); + cAgent.AttachmentObjectStates = new List(); + IScriptModule se = m_scene.RequestModuleInterface(); + foreach (SceneObjectGroup sog in m_attachments) + { + // We need to make a copy and pass that copy + // because of transfers withn the same sim + ISceneObject clone = sog.CloneForNewScene(); + cAgent.AttachmentObjects.Add(clone); + cAgent.AttachmentObjectStates.Add(sog.GetStateSnapshot()); + } + } } public void CopyFrom(AgentData cAgent) @@ -3188,50 +3152,6 @@ namespace OpenSim.Region.Framework.Scenes AddToPhysicalScene(isFlying); } -/* - uint i = 0; - try - { - if (cAgent.Wearables == null) - cAgent.Wearables = new UUID[0]; - AvatarWearable[] wears = new AvatarWearable[cAgent.Wearables.Length / 2]; - for (uint n = 0; n < cAgent.Wearables.Length; n += 2) - { - UUID itemId = cAgent.Wearables[n]; - UUID assetId = cAgent.Wearables[n + 1]; - wears[i++] = new AvatarWearable(itemId, assetId); - } - // m_appearance.Wearables = wears; - Primitive.TextureEntry textures = null; - if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1) - textures = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length); - - byte[] visuals = null; - - if ((cAgent.VisualParams != null) && (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT)) - visuals = (byte[])cAgent.VisualParams.Clone(); - - m_appearance = new AvatarAppearance(cAgent.AgentID,wears,textures,visuals); - } - catch (Exception e) - { - m_log.Warn("[SCENE PRESENCE]: exception in CopyFrom " + e.Message); - } - - // Attachments - try - { - if (cAgent.Attachments != null) - { - m_appearance.ClearAttachments(); - foreach (AvatarAttachment att in cAgent.Attachments) - { - m_appearance.SetAttachment(att.AttachPoint, att.ItemID, att.AssetID); - } - } - } - catch { } -*/ try { lock (scriptedcontrols) @@ -3261,8 +3181,18 @@ namespace OpenSim.Region.Framework.Scenes } catch { } - //cAgent.GroupID = ?? - //Groups??? + if (cAgent.AttachmentObjects != null && cAgent.AttachmentObjects.Count > 0) + { + m_attachments = new List(); + int i = 0; + foreach (ISceneObject so in cAgent.AttachmentObjects) + { + ((SceneObjectGroup)so).LocalId = 0; + ((SceneObjectGroup)so).RootPart.UpdateFlag = 0; + so.SetState(cAgent.AttachmentObjectStates[i++], m_scene); + m_scene.IncomingCreateObject(so); + } + } } public bool CopyAgent(out IAgentData agent) diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index 372a59c038..8b6fb4f5c1 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs @@ -50,6 +50,7 @@ namespace OpenSim.Server.Handlers.Simulation public class AgentHandler { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private ISimulationService m_SimulationService; protected bool m_Proxy = false; @@ -275,7 +276,7 @@ namespace OpenSim.Server.Handlers.Simulation AgentData agent = new AgentData(); try { - agent.Unpack(args); + agent.Unpack(args, m_SimulationService.GetScene(destination.RegionHandle)); } catch (Exception ex) { @@ -295,7 +296,7 @@ namespace OpenSim.Server.Handlers.Simulation AgentPosition agent = new AgentPosition(); try { - agent.Unpack(args); + agent.Unpack(args, m_SimulationService.GetScene(destination.RegionHandle)); } catch (Exception ex) { @@ -342,7 +343,8 @@ namespace OpenSim.Server.Handlers.Simulation destination.RegionID = regionID; string reason; - bool result = m_SimulationService.QueryAccess(destination, id, position, out reason); + string version; + bool result = m_SimulationService.QueryAccess(destination, id, position, out version, out reason); responsedata["int_response_code"] = HttpStatusCode.OK; @@ -350,6 +352,7 @@ namespace OpenSim.Server.Handlers.Simulation resp["success"] = OSD.FromBoolean(result); resp["reason"] = OSD.FromString(reason); + resp["version"] = OSD.FromString(version); responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp); } diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index 93b3ae62a9..415b4f0d37 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -241,7 +241,7 @@ namespace OpenSim.Services.Connectors.Simulation if (args != null) { agent = new CompleteAgentData(); - agent.Unpack(args); + agent.Unpack(args, null); return true; } } @@ -256,9 +256,10 @@ namespace OpenSim.Services.Connectors.Simulation /// /// - public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string reason) + public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason) { reason = "Failed to contact destination"; + version = "Unknown"; // m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess start, position={0}", position); @@ -274,23 +275,27 @@ namespace OpenSim.Services.Connectors.Simulation try { OSDMap result = WebUtil.ServiceOSDRequest(uri, request, "QUERYACCESS", 10000); - bool success = result["success"].AsBoolean(); - reason = result["reason"].AsString(); + OSDMap data = (OSDMap)result["_Result"]; - //m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess to {0} returned {1}", uri, success); + bool success = result["success"].AsBoolean(); + reason = data["reason"].AsString(); + if (data["version"] != null) + version = data["version"].AsString(); + + m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess to {0} returned {1} version {2} ({3})", uri, success, version, data["version"].AsString()); if (!success) { - if (result.ContainsKey("Message")) + if (data.ContainsKey("Message")) { - string message = result["Message"].AsString(); + string message = data["Message"].AsString(); if (message == "Service request failed: [MethodNotAllowed] MethodNotAllowed") // Old style region { m_log.Info("[REMOTE SIMULATION CONNECTOR]: The above web util error was caused by a TP to a sim that doesn't support QUERYACCESS and can be ignored"); return true; } - reason = result["Message"]; + reason = data["Message"]; } else { diff --git a/OpenSim/Services/Interfaces/ISimulationService.cs b/OpenSim/Services/Interfaces/ISimulationService.cs index 55c9cc5717..5f9ce6d8b8 100644 --- a/OpenSim/Services/Interfaces/ISimulationService.cs +++ b/OpenSim/Services/Interfaces/ISimulationService.cs @@ -67,7 +67,7 @@ namespace OpenSim.Services.Interfaces bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent); - bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string reason); + bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason); /// /// Message from receiving region to departing region, telling it got contacted by the client. From e462b926acc2810303d4ce5fc00f494f4765a7ad Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 29 Apr 2011 08:01:44 -0700 Subject: [PATCH 04/41] Minor improvement in version checking (Simulation service) --- .../Connectors/Simulation/SimulationServiceConnector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index 415b4f0d37..7545db8200 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -279,7 +279,7 @@ namespace OpenSim.Services.Connectors.Simulation bool success = result["success"].AsBoolean(); reason = data["reason"].AsString(); - if (data["version"] != null) + if (data["version"] != null && data["version"].AsString() != string.Empty) version = data["version"].AsString(); m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess to {0} returned {1} version {2} ({3})", uri, success, version, data["version"].AsString()); From 73caa4e94abc920269c2eba8423be49192ef184b Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 29 Apr 2011 08:42:51 -0700 Subject: [PATCH 05/41] Minor correction to yesterday's changes. Make normal prim crossing (no attach) work well again. --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 2 -- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index bccbe683f7..19a95062b4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3361,8 +3361,6 @@ namespace OpenSim.Region.Framework.Scenes { SceneObjectGroup sog = Copy(false); sog.m_isDeleted = false; - sog.RootPart.IsAttachment = false; - sog.RootPart.GroupPosition = sog.RootPart.AttachedPos; return sog; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 507fc50f99..fe4a7d1fa7 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3108,6 +3108,9 @@ namespace OpenSim.Region.Framework.Scenes // We need to make a copy and pass that copy // because of transfers withn the same sim ISceneObject clone = sog.CloneForNewScene(); + // Attachment module assumes that GroupPosition holds the offsets...! + ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; + ((SceneObjectGroup)clone).RootPart.IsAttachment = false; cAgent.AttachmentObjects.Add(clone); cAgent.AttachmentObjectStates.Add(sog.GetStateSnapshot()); } From d565041e163d3bb47d6f5e3b7432871ee24edc13 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Fri, 29 Apr 2011 15:49:10 -0700 Subject: [PATCH 06/41] Fix crash when [Mesh] section is missing from configuration files --- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 64774d8ee5..f89b824614 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -88,7 +88,8 @@ namespace OpenSim.Region.Physics.Meshing decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache"); cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps); - useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); + if(mesh_config != null) + useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); try { From 0d49611f6db017da16b6099c440b6c1e2b2218b9 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 29 Apr 2011 15:52:06 -0700 Subject: [PATCH 07/41] Remove the scripts of the attachments in the departing region and recreate them if fail. --- .../Framework/EntityTransfer/EntityTransferModule.cs | 12 ++++++++++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 ++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 10547857f7..b985fbb371 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -479,7 +479,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Fail. Reset it back sp.IsChildAgent = false; - + ReInstantiateScripts(sp); ResetFromTransit(sp.UUID); EnableChildAgents(sp); @@ -930,6 +930,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!WaitForCallback(agent.UUID)) { m_log.Debug("[ENTITY TRANSFER MODULE]: Callback never came in crossing agent"); + ReInstantiateScripts(agent); ResetFromTransit(agent.UUID); // Yikes! We should just have a ref to scene here. @@ -1756,7 +1757,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return false; } - + protected void ReInstantiateScripts(ScenePresence sp) + { + sp.Attachments.ForEach(delegate(SceneObjectGroup sog) + { + sog.CreateScriptInstances(0, false, sp.Scene.DefaultScriptEngine, 0); + sog.ResumeScripts(); + }); + } #endregion } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index fe4a7d1fa7..9b9d9dabc8 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3113,6 +3113,8 @@ namespace OpenSim.Region.Framework.Scenes ((SceneObjectGroup)clone).RootPart.IsAttachment = false; cAgent.AttachmentObjects.Add(clone); cAgent.AttachmentObjectStates.Add(sog.GetStateSnapshot()); + // Let's remove the scripts of the original object here + sog.RemoveScriptInstances(true); } } } From 4d5d6222f7edd7cd9c659571f280076c863a0fb1 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 29 Apr 2011 17:09:48 -0700 Subject: [PATCH 08/41] Delaying starting the scripts on TPs and crossings until the agent is root. --- OpenSim/Region/Framework/Scenes/Scene.cs | 22 ++++------ .../Region/Framework/Scenes/ScenePresence.cs | 41 +++++++++++++++---- 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 696c6ee453..2cbe4dc7fd 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1229,7 +1229,6 @@ namespace OpenSim.Region.Framework.Scenes // Increment the frame counter ++Frame; - try { // Check if any objects have reached their targets @@ -2336,9 +2335,13 @@ namespace OpenSim.Region.Framework.Scenes return false; } - newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); - - newObject.ResumeScripts(); + // For attachments, we need to wait until the agent is root + // before we restart the scripts, or else some functions won't work. + if (!newObject.IsAttachment) + { + newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); + newObject.ResumeScripts(); + } // Do this as late as possible so that listeners have full access to the incoming object EventManager.TriggerOnIncomingSceneObject(newObject); @@ -2455,17 +2458,8 @@ namespace OpenSim.Region.Framework.Scenes ScenePresence sp = GetScenePresence(sog.OwnerID); if (sp != null) - { - AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(sp.UUID); + return sp.GetStateSource(); - if (aCircuit != null && (aCircuit.teleportFlags != (uint)TeleportFlags.Default)) - { - // This will get your attention - //m_log.Error("[XXX] Triggering CHANGED_TELEPORT"); - - return 5; // StateSource.Teleporting - } - } return 2; // StateSource.PrimCrossing } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 9b9d9dabc8..1aac09ddbf 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -840,6 +840,9 @@ namespace OpenSim.Region.Framework.Scenes //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); + bool wasChild = m_isChildAgent; + m_isChildAgent = false; + IGroupsModule gm = m_scene.RequestModuleInterface(); if (gm != null) m_grouptitle = gm.GetGroupTitle(m_uuid); @@ -929,14 +932,21 @@ namespace OpenSim.Region.Framework.Scenes // Animator.SendAnimPack(); m_scene.SwapRootAgentCount(false); - - //CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(m_uuid); - //if (userInfo != null) - // userInfo.FetchInventory(); - //else - // m_log.ErrorFormat("[SCENE]: Could not find user info for {0} when making it a root agent", m_uuid); - - m_isChildAgent = false; + + // The initial login scene presence is already root when it gets here + // and it has already rezzed the attachments and started their scripts. + // We do the following only for non-login agents, because their scripts + // haven't started yet. + if (wasChild) + { + m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); + // Resume scripts + Attachments.ForEach(delegate(SceneObjectGroup sog) + { + sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); + sog.ResumeScripts(); + }); + } // send the animations of the other presences to me m_scene.ForEachScenePresence(delegate(ScenePresence presence) @@ -948,6 +958,20 @@ namespace OpenSim.Region.Framework.Scenes m_scene.EventManager.TriggerOnMakeRootAgent(this); } + public int GetStateSource() + { + AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(UUID); + + if (aCircuit != null && (aCircuit.teleportFlags != (uint)TeleportFlags.Default)) + { + // This will get your attention + //m_log.Error("[XXX] Triggering CHANGED_TELEPORT"); + + return 5; // StateSource.Teleporting + } + return 2; // StateSource.PrimCrossing + } + /// /// This turns a root agent into a child agent /// when an agent departs this region for a neighbor, this gets called. @@ -1139,7 +1163,6 @@ namespace OpenSim.Region.Framework.Scenes AbsolutePosition = pos; } - m_isChildAgent = false; bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); MakeRootAgent(AbsolutePosition, m_flying); From 99b35d3ca63bb5d1cd8d02087675b97c092c6ecb Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 30 Apr 2011 16:01:54 +0200 Subject: [PATCH 09/41] When coming in from a legacy region without fatpacks, start scripts the usual way --- OpenSim/Region/Framework/Scenes/Scene.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 2cbe4dc7fd..7c5e24652c 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2342,6 +2342,22 @@ namespace OpenSim.Region.Framework.Scenes newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); newObject.ResumeScripts(); } + else + { + ScenePresence sp; + if (TryGetScenePresence(newObject.OwnerID, out sp)) + { + // If the scene presence is here and already a root + // agent, we came from a ;egacy region. Start the scripts + // here as they used to start. + // TODO: Remove in 0.7.3 + if (!sp.IsChildAgent) + { + newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); + newObject.ResumeScripts(); + } + } + } // Do this as late as possible so that listeners have full access to the incoming object EventManager.TriggerOnIncomingSceneObject(newObject); From d8ee0cbe1cf93ca521f52ce39aa2a15cb5784e48 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 30 Apr 2011 09:24:15 -0700 Subject: [PATCH 10/41] First stab at cleaning up Caps. Compiles. Untested. --- .../Caps}/EventQueue/EventQueueGetModule.cs | 12 ++++- .../Caps}/EventQueue/EventQueueHelper.cs | 18 +++---- .../UDP}/IncomingPacket.cs | 0 .../UDP}/IncomingPacketHistoryCollection.cs | 0 .../{LindenUDP => Linden/UDP}/J2KImage.cs | 0 .../{LindenUDP => Linden/UDP}/LLClientView.cs | 0 .../UDP}/LLImageManager.cs | 0 .../{LindenUDP => Linden/UDP}/LLUDPClient.cs | 0 .../{LindenUDP => Linden/UDP}/LLUDPServer.cs | 0 .../UDP}/OpenSimUDPBase.cs | 0 .../UDP}/OutgoingPacket.cs | 0 .../UDP}/Tests/BasicCircuitTests.cs | 0 .../UDP}/Tests/MockScene.cs | 0 .../UDP}/Tests/PacketHandlerTests.cs | 0 .../UDP}/Tests/TestLLPacketServer.cs | 0 .../UDP}/Tests/TestLLUDPServer.cs | 0 .../UDP}/ThrottleRates.cs | 0 .../{LindenUDP => Linden/UDP}/TokenBucket.cs | 0 .../UDP}/UnackedPacketCollection.cs | 0 .../Framework/Interfaces/IEventQueue.cs | 2 + .../XmlRpcGroups/GroupsMessagingModule.cs | 3 +- .../Avatar/XmlRpcGroups/GroupsModule.cs | 3 +- .../Region/ScriptEngine/XEngine/XEngine.cs | 3 +- prebuild.xml | 49 +++++++++++++++++-- 24 files changed, 70 insertions(+), 20 deletions(-) rename OpenSim/Region/{CoreModules/Framework => ClientStack/Linden/Caps}/EventQueue/EventQueueGetModule.cs (98%) rename OpenSim/Region/{CoreModules/Framework => ClientStack/Linden/Caps}/EventQueue/EventQueueHelper.cs (97%) rename OpenSim/Region/ClientStack/{LindenUDP => Linden/UDP}/IncomingPacket.cs (100%) rename OpenSim/Region/ClientStack/{LindenUDP => Linden/UDP}/IncomingPacketHistoryCollection.cs (100%) rename OpenSim/Region/ClientStack/{LindenUDP => Linden/UDP}/J2KImage.cs (100%) rename OpenSim/Region/ClientStack/{LindenUDP => Linden/UDP}/LLClientView.cs (100%) rename OpenSim/Region/ClientStack/{LindenUDP => Linden/UDP}/LLImageManager.cs (100%) rename OpenSim/Region/ClientStack/{LindenUDP => Linden/UDP}/LLUDPClient.cs (100%) rename OpenSim/Region/ClientStack/{LindenUDP => Linden/UDP}/LLUDPServer.cs (100%) rename OpenSim/Region/ClientStack/{LindenUDP => Linden/UDP}/OpenSimUDPBase.cs (100%) rename OpenSim/Region/ClientStack/{LindenUDP => Linden/UDP}/OutgoingPacket.cs (100%) rename OpenSim/Region/ClientStack/{LindenUDP => Linden/UDP}/Tests/BasicCircuitTests.cs (100%) rename OpenSim/Region/ClientStack/{LindenUDP => Linden/UDP}/Tests/MockScene.cs (100%) rename OpenSim/Region/ClientStack/{LindenUDP => Linden/UDP}/Tests/PacketHandlerTests.cs (100%) rename OpenSim/Region/ClientStack/{LindenUDP => Linden/UDP}/Tests/TestLLPacketServer.cs (100%) rename OpenSim/Region/ClientStack/{LindenUDP => Linden/UDP}/Tests/TestLLUDPServer.cs (100%) rename OpenSim/Region/ClientStack/{LindenUDP => Linden/UDP}/ThrottleRates.cs (100%) rename OpenSim/Region/ClientStack/{LindenUDP => Linden/UDP}/TokenBucket.cs (100%) rename OpenSim/Region/ClientStack/{LindenUDP => Linden/UDP}/UnackedPacketCollection.cs (100%) diff --git a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs similarity index 98% rename from OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs rename to OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 05fe3eee04..fe97bf22cd 100644 --- a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -45,7 +45,7 @@ using OpenSim.Region.Framework.Scenes; using BlockingLLSDQueue = OpenSim.Framework.BlockingQueue; using Caps=OpenSim.Framework.Capabilities.Caps; -namespace OpenSim.Region.CoreModules.Framework.EventQueue +namespace OpenSim.Region.ClientStack.Linden { public struct QueueItem { @@ -715,5 +715,15 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue OSD item = EventQueueHelper.PlacesQuery(groupUpdate); Enqueue(item, avatarID); } + + public OSD ScriptRunningEvent(UUID objectID, UUID itemID, bool running, bool mono) + { + return EventQueueHelper.ScriptRunningReplyEvent(objectID, itemID, running, mono); + } + + public OSD BuildEvent(string eventName, OSD eventBody) + { + return EventQueueHelper.BuildEvent(eventName, eventBody); + } } } diff --git a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueHelper.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs similarity index 97% rename from OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueHelper.cs rename to OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs index 0d7d16a2ba..3f49abaf56 100644 --- a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueHelper.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs @@ -32,7 +32,7 @@ using OpenMetaverse.Packets; using OpenMetaverse.StructuredData; using OpenMetaverse.Messages.Linden; -namespace OpenSim.Region.CoreModules.Framework.EventQueue +namespace OpenSim.Region.ClientStack.Linden { public class EventQueueHelper { @@ -61,7 +61,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue // return result; // } - public static OSD buildEvent(string eventName, OSD eventBody) + public static OSD BuildEvent(string eventName, OSD eventBody) { OSDMap llsdEvent = new OSDMap(2); llsdEvent.Add("message", new OSDString(eventName)); @@ -84,7 +84,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue OSDMap llsdBody = new OSDMap(1); llsdBody.Add("SimulatorInfo", arr); - return buildEvent("EnableSimulator", llsdBody); + return BuildEvent("EnableSimulator", llsdBody); } public static OSD DisableSimulator(ulong handle) @@ -99,7 +99,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue OSDMap llsdBody = new OSDMap(0); //llsdBody.Add("SimulatorInfo", arr); - return buildEvent("DisableSimulator", llsdBody); + return BuildEvent("DisableSimulator", llsdBody); } public static OSD CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt, @@ -144,7 +144,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue llsdBody.Add("AgentData", agentDataArr); llsdBody.Add("RegionData", regionDataArr); - return buildEvent("CrossedRegion", llsdBody); + return BuildEvent("CrossedRegion", llsdBody); } public static OSD TeleportFinishEvent( @@ -167,7 +167,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue OSDMap body = new OSDMap(); body.Add("Info", infoArr); - return buildEvent("TeleportFinish", body); + return BuildEvent("TeleportFinish", body); } public static OSD ScriptRunningReplyEvent(UUID objectID, UUID itemID, bool running, bool mono) @@ -184,7 +184,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue OSDMap body = new OSDMap(); body.Add("Script", scriptArr); - return buildEvent("ScriptRunningReply", body); + return BuildEvent("ScriptRunningReply", body); } public static OSD EstablishAgentCommunication(UUID agentID, string simIpAndPort, string seedcap) @@ -194,12 +194,12 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue body.Add("sim-ip-and-port", new OSDString(simIpAndPort)); body.Add("seed-capability", new OSDString(seedcap)); - return buildEvent("EstablishAgentCommunication", body); + return BuildEvent("EstablishAgentCommunication", body); } public static OSD KeepAliveEvent() { - return buildEvent("FAKEEVENT", new OSDMap()); + return BuildEvent("FAKEEVENT", new OSDMap()); } public static OSD AgentParams(UUID agentID, bool checkEstate, int godLevel, bool limitedToEstate) diff --git a/OpenSim/Region/ClientStack/LindenUDP/IncomingPacket.cs b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/IncomingPacket.cs rename to OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/IncomingPacketHistoryCollection.cs b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacketHistoryCollection.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/IncomingPacketHistoryCollection.cs rename to OpenSim/Region/ClientStack/Linden/UDP/IncomingPacketHistoryCollection.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs rename to OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs rename to OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs rename to OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs rename to OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs rename to OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs rename to OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs b/OpenSim/Region/ClientStack/Linden/UDP/OutgoingPacket.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs rename to OpenSim/Region/ClientStack/Linden/UDP/OutgoingPacket.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/Tests/BasicCircuitTests.cs rename to OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/Tests/MockScene.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/Tests/MockScene.cs rename to OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/Tests/PacketHandlerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/Tests/PacketHandlerTests.cs rename to OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/Tests/TestLLPacketServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLPacketServer.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/Tests/TestLLPacketServer.cs rename to OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLPacketServer.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/Tests/TestLLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/Tests/TestLLUDPServer.cs rename to OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs b/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs rename to OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs rename to OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs rename to OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs diff --git a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs index 81e4952afe..bfa5d1717d 100644 --- a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs +++ b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs @@ -57,5 +57,7 @@ namespace OpenSim.Region.Framework.Interfaces bool isModerator, bool textMute); void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID); void GroupMembership(AgentGroupDataUpdatePacket groupUpdate, UUID avatarID); + OSD ScriptRunningEvent(UUID objectID, UUID itemID, bool running, bool mono); + OSD BuildEvent(string eventName, OSD eventBody); } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 8c01d75b8f..dcbcd85bd4 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -34,7 +34,6 @@ using Nini.Config; using OpenMetaverse; using OpenMetaverse.StructuredData; using OpenSim.Framework; -using OpenSim.Region.CoreModules.Framework.EventQueue; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -472,7 +471,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (queue != null) { - queue.Enqueue(EventQueueHelper.buildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId); + queue.Enqueue(queue.BuildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId); } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index a8dec63def..d9168b06f0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -39,7 +39,6 @@ using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Framework.Communications; -using OpenSim.Region.CoreModules.Framework.EventQueue; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -1154,7 +1153,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (queue != null) { - queue.Enqueue(EventQueueHelper.buildEvent("AgentGroupDataUpdate", llDataStruct), GetRequestingAgentID(remoteClient)); + queue.Enqueue(queue.BuildEvent("AgentGroupDataUpdate", llDataStruct), GetRequestingAgentID(remoteClient)); } } diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 86296740ef..97ab411dd2 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -41,7 +41,6 @@ using log4net; using Nini.Config; using Amib.Threading; using OpenSim.Framework; -using OpenSim.Region.CoreModules.Framework.EventQueue; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.ScriptEngine.Shared; @@ -1283,7 +1282,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine } else { - eq.Enqueue(EventQueueHelper.ScriptRunningReplyEvent(objectID, itemID, GetScriptState(itemID), true), + eq.Enqueue(eq.ScriptRunningEvent(objectID, itemID, GetScriptState(itemID), true), controllingClient.AgentId); } } diff --git a/prebuild.xml b/prebuild.xml index 1102c11c09..7b38556678 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -660,6 +660,7 @@ + @@ -694,6 +694,7 @@ +--> @@ -1310,6 +1311,42 @@ + + + + ../../../bin/ + + + + + ../../../bin/ + + + + ../../../bin/ + + + + + + + + + + + + + + + + + + + + + + + @@ -1513,7 +1550,7 @@ - + ../../../../bin/ @@ -1536,8 +1573,10 @@ + + @@ -1549,7 +1588,9 @@ - + + + @@ -1582,8 +1623,8 @@ - + From 3e79842312ace5b4294e3d6501b1d35ffea5f1b5 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 30 Apr 2011 11:03:22 -0700 Subject: [PATCH 11/41] Renamed OpenSim.Framework.Capabilities.dll to OpenSim.Capabilities.dll --- OpenSim/{Framework => }/Capabilities/Caps.cs | 0 .../Capabilities/CapsHandlers.cs | 0 OpenSim/{Framework => }/Capabilities/LLSD.cs | 0 .../{Framework => }/Capabilities/LLSDArray.cs | 0 .../Capabilities/LLSDAssetUploadComplete.cs | 0 .../Capabilities/LLSDAssetUploadRequest.cs | 0 .../Capabilities/LLSDAssetUploadResponse.cs | 0 .../Capabilities/LLSDCapEvent.cs | 0 .../{Framework => }/Capabilities/LLSDEmpty.cs | 0 .../Capabilities/LLSDHelpers.cs | 0 .../Capabilities/LLSDInventoryFolder.cs | 0 .../Capabilities/LLSDInventoryItem.cs | 0 .../Capabilities/LLSDItemUpdate.cs | 0 .../Capabilities/LLSDMapLayer.cs | 0 .../Capabilities/LLSDMapLayerResponse.cs | 0 .../Capabilities/LLSDMapRequest.cs | 0 .../Capabilities/LLSDMethod.cs | 0 .../Capabilities/LLSDMethodString.cs | 0 .../LLSDParcelVoiceInfoResponse.cs | 0 .../Capabilities/LLSDRemoteParcelResponse.cs | 0 .../Capabilities/LLSDStreamHandler.cs | 0 .../LLSDTaskInventoryUploadComplete.cs | 0 .../Capabilities/LLSDTaskScriptUpdate.cs | 0 .../LLSDTaskScriptUploadComplete.cs | 0 .../{Framework => }/Capabilities/LLSDTest.cs | 0 .../{Framework => }/Capabilities/LLSDType.cs | 0 .../Capabilities/LLSDVoiceAccountResponse.cs | 0 .../Framework/{Capabilities => }/CapsUtil.cs | 2 +- .../Region/DataSnapshot/DataRequestHandler.cs | 2 +- .../XmlRpcGroups/GroupsMessagingModule.cs | 2 - .../Avatar/XmlRpcGroups/GroupsModule.cs | 1 - .../Region/UserStatistics/WebStatsModule.cs | 1 - .../LLLoginService/LLLoginResponse.cs | 1 - .../Services/LLLoginService/LLLoginService.cs | 1 - prebuild.xml | 64 ++++--------------- 35 files changed, 14 insertions(+), 60 deletions(-) rename OpenSim/{Framework => }/Capabilities/Caps.cs (100%) rename OpenSim/{Framework => }/Capabilities/CapsHandlers.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSD.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDArray.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDAssetUploadComplete.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDAssetUploadRequest.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDAssetUploadResponse.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDCapEvent.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDEmpty.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDHelpers.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDInventoryFolder.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDInventoryItem.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDItemUpdate.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDMapLayer.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDMapLayerResponse.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDMapRequest.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDMethod.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDMethodString.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDParcelVoiceInfoResponse.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDRemoteParcelResponse.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDStreamHandler.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDTaskInventoryUploadComplete.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDTaskScriptUpdate.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDTaskScriptUploadComplete.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDTest.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDType.cs (100%) rename OpenSim/{Framework => }/Capabilities/LLSDVoiceAccountResponse.cs (100%) rename OpenSim/Framework/{Capabilities => }/CapsUtil.cs (98%) diff --git a/OpenSim/Framework/Capabilities/Caps.cs b/OpenSim/Capabilities/Caps.cs similarity index 100% rename from OpenSim/Framework/Capabilities/Caps.cs rename to OpenSim/Capabilities/Caps.cs diff --git a/OpenSim/Framework/Capabilities/CapsHandlers.cs b/OpenSim/Capabilities/CapsHandlers.cs similarity index 100% rename from OpenSim/Framework/Capabilities/CapsHandlers.cs rename to OpenSim/Capabilities/CapsHandlers.cs diff --git a/OpenSim/Framework/Capabilities/LLSD.cs b/OpenSim/Capabilities/LLSD.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSD.cs rename to OpenSim/Capabilities/LLSD.cs diff --git a/OpenSim/Framework/Capabilities/LLSDArray.cs b/OpenSim/Capabilities/LLSDArray.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDArray.cs rename to OpenSim/Capabilities/LLSDArray.cs diff --git a/OpenSim/Framework/Capabilities/LLSDAssetUploadComplete.cs b/OpenSim/Capabilities/LLSDAssetUploadComplete.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDAssetUploadComplete.cs rename to OpenSim/Capabilities/LLSDAssetUploadComplete.cs diff --git a/OpenSim/Framework/Capabilities/LLSDAssetUploadRequest.cs b/OpenSim/Capabilities/LLSDAssetUploadRequest.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDAssetUploadRequest.cs rename to OpenSim/Capabilities/LLSDAssetUploadRequest.cs diff --git a/OpenSim/Framework/Capabilities/LLSDAssetUploadResponse.cs b/OpenSim/Capabilities/LLSDAssetUploadResponse.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDAssetUploadResponse.cs rename to OpenSim/Capabilities/LLSDAssetUploadResponse.cs diff --git a/OpenSim/Framework/Capabilities/LLSDCapEvent.cs b/OpenSim/Capabilities/LLSDCapEvent.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDCapEvent.cs rename to OpenSim/Capabilities/LLSDCapEvent.cs diff --git a/OpenSim/Framework/Capabilities/LLSDEmpty.cs b/OpenSim/Capabilities/LLSDEmpty.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDEmpty.cs rename to OpenSim/Capabilities/LLSDEmpty.cs diff --git a/OpenSim/Framework/Capabilities/LLSDHelpers.cs b/OpenSim/Capabilities/LLSDHelpers.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDHelpers.cs rename to OpenSim/Capabilities/LLSDHelpers.cs diff --git a/OpenSim/Framework/Capabilities/LLSDInventoryFolder.cs b/OpenSim/Capabilities/LLSDInventoryFolder.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDInventoryFolder.cs rename to OpenSim/Capabilities/LLSDInventoryFolder.cs diff --git a/OpenSim/Framework/Capabilities/LLSDInventoryItem.cs b/OpenSim/Capabilities/LLSDInventoryItem.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDInventoryItem.cs rename to OpenSim/Capabilities/LLSDInventoryItem.cs diff --git a/OpenSim/Framework/Capabilities/LLSDItemUpdate.cs b/OpenSim/Capabilities/LLSDItemUpdate.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDItemUpdate.cs rename to OpenSim/Capabilities/LLSDItemUpdate.cs diff --git a/OpenSim/Framework/Capabilities/LLSDMapLayer.cs b/OpenSim/Capabilities/LLSDMapLayer.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDMapLayer.cs rename to OpenSim/Capabilities/LLSDMapLayer.cs diff --git a/OpenSim/Framework/Capabilities/LLSDMapLayerResponse.cs b/OpenSim/Capabilities/LLSDMapLayerResponse.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDMapLayerResponse.cs rename to OpenSim/Capabilities/LLSDMapLayerResponse.cs diff --git a/OpenSim/Framework/Capabilities/LLSDMapRequest.cs b/OpenSim/Capabilities/LLSDMapRequest.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDMapRequest.cs rename to OpenSim/Capabilities/LLSDMapRequest.cs diff --git a/OpenSim/Framework/Capabilities/LLSDMethod.cs b/OpenSim/Capabilities/LLSDMethod.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDMethod.cs rename to OpenSim/Capabilities/LLSDMethod.cs diff --git a/OpenSim/Framework/Capabilities/LLSDMethodString.cs b/OpenSim/Capabilities/LLSDMethodString.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDMethodString.cs rename to OpenSim/Capabilities/LLSDMethodString.cs diff --git a/OpenSim/Framework/Capabilities/LLSDParcelVoiceInfoResponse.cs b/OpenSim/Capabilities/LLSDParcelVoiceInfoResponse.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDParcelVoiceInfoResponse.cs rename to OpenSim/Capabilities/LLSDParcelVoiceInfoResponse.cs diff --git a/OpenSim/Framework/Capabilities/LLSDRemoteParcelResponse.cs b/OpenSim/Capabilities/LLSDRemoteParcelResponse.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDRemoteParcelResponse.cs rename to OpenSim/Capabilities/LLSDRemoteParcelResponse.cs diff --git a/OpenSim/Framework/Capabilities/LLSDStreamHandler.cs b/OpenSim/Capabilities/LLSDStreamHandler.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDStreamHandler.cs rename to OpenSim/Capabilities/LLSDStreamHandler.cs diff --git a/OpenSim/Framework/Capabilities/LLSDTaskInventoryUploadComplete.cs b/OpenSim/Capabilities/LLSDTaskInventoryUploadComplete.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDTaskInventoryUploadComplete.cs rename to OpenSim/Capabilities/LLSDTaskInventoryUploadComplete.cs diff --git a/OpenSim/Framework/Capabilities/LLSDTaskScriptUpdate.cs b/OpenSim/Capabilities/LLSDTaskScriptUpdate.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDTaskScriptUpdate.cs rename to OpenSim/Capabilities/LLSDTaskScriptUpdate.cs diff --git a/OpenSim/Framework/Capabilities/LLSDTaskScriptUploadComplete.cs b/OpenSim/Capabilities/LLSDTaskScriptUploadComplete.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDTaskScriptUploadComplete.cs rename to OpenSim/Capabilities/LLSDTaskScriptUploadComplete.cs diff --git a/OpenSim/Framework/Capabilities/LLSDTest.cs b/OpenSim/Capabilities/LLSDTest.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDTest.cs rename to OpenSim/Capabilities/LLSDTest.cs diff --git a/OpenSim/Framework/Capabilities/LLSDType.cs b/OpenSim/Capabilities/LLSDType.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDType.cs rename to OpenSim/Capabilities/LLSDType.cs diff --git a/OpenSim/Framework/Capabilities/LLSDVoiceAccountResponse.cs b/OpenSim/Capabilities/LLSDVoiceAccountResponse.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDVoiceAccountResponse.cs rename to OpenSim/Capabilities/LLSDVoiceAccountResponse.cs diff --git a/OpenSim/Framework/Capabilities/CapsUtil.cs b/OpenSim/Framework/CapsUtil.cs similarity index 98% rename from OpenSim/Framework/Capabilities/CapsUtil.cs rename to OpenSim/Framework/CapsUtil.cs index faf2708541..4baf505784 100644 --- a/OpenSim/Framework/Capabilities/CapsUtil.cs +++ b/OpenSim/Framework/CapsUtil.cs @@ -27,7 +27,7 @@ using OpenMetaverse; -namespace OpenSim.Framework.Capabilities +namespace OpenSim.Framework { /// /// Capabilities utility methods diff --git a/OpenSim/Region/DataSnapshot/DataRequestHandler.cs b/OpenSim/Region/DataSnapshot/DataRequestHandler.cs index 964e4b9d28..a505999608 100644 --- a/OpenSim/Region/DataSnapshot/DataRequestHandler.cs +++ b/OpenSim/Region/DataSnapshot/DataRequestHandler.cs @@ -36,7 +36,7 @@ using OpenSim.Framework.Capabilities; using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Scenes; -using Caps=OpenSim.Framework.Capabilities.Caps; +using Caps = OpenSim.Framework.Capabilities.Caps; namespace OpenSim.Region.DataSnapshot { diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index dcbcd85bd4..2bf8489df8 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -37,8 +37,6 @@ using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -using Caps = OpenSim.Framework.Capabilities.Caps; - namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index d9168b06f0..1c791b9d36 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -44,7 +44,6 @@ using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; -using Caps = OpenSim.Framework.Capabilities.Caps; using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs index a03cc4cf50..3139b8ade1 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs @@ -44,7 +44,6 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using Mono.Data.SqliteClient; - using Caps = OpenSim.Framework.Capabilities.Caps; using OSD = OpenMetaverse.StructuredData.OSD; diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs index ebd6f7c1cf..ddc8855145 100644 --- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs +++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs @@ -32,7 +32,6 @@ using System.Net; using System.Reflection; using OpenSim.Framework; -using OpenSim.Framework.Capabilities; using OpenSim.Services.Interfaces; using GridRegion = OpenSim.Services.Interfaces.GridRegion; using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 9bcc3dd225..2ca2d1566c 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -38,7 +38,6 @@ using Nini.Config; using OpenMetaverse; using OpenSim.Framework; -using OpenSim.Framework.Capabilities; using OpenSim.Framework.Console; using OpenSim.Server.Base; using OpenSim.Services.Interfaces; diff --git a/prebuild.xml b/prebuild.xml index 7b38556678..90ee1eb437 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -660,20 +660,19 @@ - + @@ -715,7 +714,6 @@ - @@ -761,7 +759,7 @@ - + @@ -1186,7 +1184,6 @@ - @@ -1218,7 +1215,6 @@ - @@ -1310,43 +1306,6 @@ - - - - - ../../../bin/ - - - - - ../../../bin/ - - - - ../../../bin/ - - - - - - - - - - - - - - - - - - - - - - - @@ -1439,8 +1398,8 @@ + - @@ -1570,13 +1529,13 @@ + - @@ -1615,10 +1574,10 @@ + - @@ -1955,8 +1914,8 @@ + - @@ -2387,13 +2346,14 @@ + - + From c062138dad42ef7e52bbcb27c346ddecab94c5af Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 30 Apr 2011 12:23:40 -0700 Subject: [PATCH 12/41] Moved several cap-based-service-providing modules from where they were into a newly created CoreModules/Caps. Not all. --- .../{Agent/Capabilities => Caps}/CapabilitiesModule.cs | 2 +- .../Region/CoreModules/{Avatar/Assets => Caps}/GetMeshModule.cs | 2 +- .../CoreModules/{Avatar/Assets => Caps}/GetTextureModule.cs | 2 +- .../Assets => Caps}/NewFileAgentInventoryVariablePriceModule.cs | 2 +- .../Region/CoreModules/{Avatar => Caps}/ObjectCaps/ObjectAdd.cs | 2 +- .../{Avatar => Caps}/ObjectCaps/UploadObjectAssetModule.cs | 2 +- OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs | 1 - 7 files changed, 6 insertions(+), 7 deletions(-) rename OpenSim/Region/CoreModules/{Agent/Capabilities => Caps}/CapabilitiesModule.cs (99%) rename OpenSim/Region/CoreModules/{Avatar/Assets => Caps}/GetMeshModule.cs (99%) rename OpenSim/Region/CoreModules/{Avatar/Assets => Caps}/GetTextureModule.cs (99%) rename OpenSim/Region/CoreModules/{Avatar/Assets => Caps}/NewFileAgentInventoryVariablePriceModule.cs (99%) rename OpenSim/Region/CoreModules/{Avatar => Caps}/ObjectCaps/ObjectAdd.cs (99%) rename OpenSim/Region/CoreModules/{Avatar => Caps}/ObjectCaps/UploadObjectAssetModule.cs (99%) diff --git a/OpenSim/Region/CoreModules/Agent/Capabilities/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Caps/CapabilitiesModule.cs similarity index 99% rename from OpenSim/Region/CoreModules/Agent/Capabilities/CapabilitiesModule.cs rename to OpenSim/Region/CoreModules/Caps/CapabilitiesModule.cs index 1d8e70ed54..ab388b9cc6 100644 --- a/OpenSim/Region/CoreModules/Agent/Capabilities/CapabilitiesModule.cs +++ b/OpenSim/Region/CoreModules/Caps/CapabilitiesModule.cs @@ -38,7 +38,7 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using Caps=OpenSim.Framework.Capabilities.Caps; -namespace OpenSim.Region.CoreModules.Agent.Capabilities +namespace OpenSim.Region.CoreModules.Capabilities { public class CapabilitiesModule : INonSharedRegionModule, ICapabilitiesModule { diff --git a/OpenSim/Region/CoreModules/Avatar/Assets/GetMeshModule.cs b/OpenSim/Region/CoreModules/Caps/GetMeshModule.cs similarity index 99% rename from OpenSim/Region/CoreModules/Avatar/Assets/GetMeshModule.cs rename to OpenSim/Region/CoreModules/Caps/GetMeshModule.cs index fc1ddef38c..46b2378c64 100644 --- a/OpenSim/Region/CoreModules/Avatar/Assets/GetMeshModule.cs +++ b/OpenSim/Region/CoreModules/Caps/GetMeshModule.cs @@ -44,7 +44,7 @@ using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using Caps = OpenSim.Framework.Capabilities.Caps; -namespace OpenSim.Region.CoreModules.Avatar.Assets +namespace OpenSim.Region.CoreModules.Capabilities { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class GetMeshModule : INonSharedRegionModule diff --git a/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs b/OpenSim/Region/CoreModules/Caps/GetTextureModule.cs similarity index 99% rename from OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs rename to OpenSim/Region/CoreModules/Caps/GetTextureModule.cs index df4d561024..34095a244c 100644 --- a/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs +++ b/OpenSim/Region/CoreModules/Caps/GetTextureModule.cs @@ -46,7 +46,7 @@ using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using Caps = OpenSim.Framework.Capabilities.Caps; -namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps +namespace OpenSim.Region.CoreModules.Capabilities { #region Stream Handler diff --git a/OpenSim/Region/CoreModules/Avatar/Assets/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/CoreModules/Caps/NewFileAgentInventoryVariablePriceModule.cs similarity index 99% rename from OpenSim/Region/CoreModules/Avatar/Assets/NewFileAgentInventoryVariablePriceModule.cs rename to OpenSim/Region/CoreModules/Caps/NewFileAgentInventoryVariablePriceModule.cs index 3d4c7b7527..3ebaf1fcb7 100644 --- a/OpenSim/Region/CoreModules/Avatar/Assets/NewFileAgentInventoryVariablePriceModule.cs +++ b/OpenSim/Region/CoreModules/Caps/NewFileAgentInventoryVariablePriceModule.cs @@ -45,7 +45,7 @@ using OpenSim.Services.Interfaces; using Caps = OpenSim.Framework.Capabilities.Caps; using OpenSim.Framework.Capabilities; -namespace OpenSim.Region.CoreModules.Avatar.Assets +namespace OpenSim.Region.CoreModules.Capabilities { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class NewFileAgentInventoryVariablePriceModule : INonSharedRegionModule diff --git a/OpenSim/Region/CoreModules/Avatar/ObjectCaps/ObjectAdd.cs b/OpenSim/Region/CoreModules/Caps/ObjectCaps/ObjectAdd.cs similarity index 99% rename from OpenSim/Region/CoreModules/Avatar/ObjectCaps/ObjectAdd.cs rename to OpenSim/Region/CoreModules/Caps/ObjectCaps/ObjectAdd.cs index a0d72ede22..5cd0fe732d 100644 --- a/OpenSim/Region/CoreModules/Avatar/ObjectCaps/ObjectAdd.cs +++ b/OpenSim/Region/CoreModules/Caps/ObjectCaps/ObjectAdd.cs @@ -39,7 +39,7 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using Caps=OpenSim.Framework.Capabilities.Caps; -namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps +namespace OpenSim.Region.CoreModules.Capabilities { public class ObjectAdd : IRegionModule { diff --git a/OpenSim/Region/CoreModules/Avatar/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/CoreModules/Caps/ObjectCaps/UploadObjectAssetModule.cs similarity index 99% rename from OpenSim/Region/CoreModules/Avatar/ObjectCaps/UploadObjectAssetModule.cs rename to OpenSim/Region/CoreModules/Caps/ObjectCaps/UploadObjectAssetModule.cs index 3114d7ff59..33bffeb0d3 100644 --- a/OpenSim/Region/CoreModules/Avatar/ObjectCaps/UploadObjectAssetModule.cs +++ b/OpenSim/Region/CoreModules/Caps/ObjectCaps/UploadObjectAssetModule.cs @@ -49,7 +49,7 @@ using OSDMap = OpenMetaverse.StructuredData.OSDMap; using OpenSim.Framework.Capabilities; using ExtraParamType = OpenMetaverse.ExtraParamType; -namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps +namespace OpenSim.Region.CoreModules.Capabilities { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class UploadObjectAssetModule : INonSharedRegionModule diff --git a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs index 99517d2b19..d1224099e2 100644 --- a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs +++ b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs @@ -39,7 +39,6 @@ using OpenSim.Region.Physics.Manager; using OpenSim.Region.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.CoreModules.Agent.Capabilities; using OpenSim.Region.CoreModules.Avatar.Gods; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Authentication; From e3c27d852720ad8b743952ab4aac3b2648468a11 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 30 Apr 2011 13:24:25 -0700 Subject: [PATCH 13/41] Nope, that didn't feel right. Moving all those modules to Linden space. --- .../Linden}/Caps/CapabilitiesModule.cs | 4 +++- .../ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs | 2 ++ .../{CoreModules => ClientStack/Linden}/Caps/GetMeshModule.cs | 2 +- .../Linden}/Caps/GetTextureModule.cs | 4 +++- .../Linden}/Caps/NewFileAgentInventoryVariablePriceModule.cs | 2 +- .../Linden}/Caps/ObjectCaps/ObjectAdd.cs | 2 +- .../Linden}/Caps/ObjectCaps/UploadObjectAssetModule.cs | 2 +- prebuild.xml | 4 +++- 8 files changed, 15 insertions(+), 7 deletions(-) rename OpenSim/Region/{CoreModules => ClientStack/Linden}/Caps/CapabilitiesModule.cs (98%) rename OpenSim/Region/{CoreModules => ClientStack/Linden}/Caps/GetMeshModule.cs (99%) rename OpenSim/Region/{CoreModules => ClientStack/Linden}/Caps/GetTextureModule.cs (99%) rename OpenSim/Region/{CoreModules => ClientStack/Linden}/Caps/NewFileAgentInventoryVariablePriceModule.cs (99%) rename OpenSim/Region/{CoreModules => ClientStack/Linden}/Caps/ObjectCaps/ObjectAdd.cs (99%) rename OpenSim/Region/{CoreModules => ClientStack/Linden}/Caps/ObjectCaps/UploadObjectAssetModule.cs (99%) diff --git a/OpenSim/Region/CoreModules/Caps/CapabilitiesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/CapabilitiesModule.cs similarity index 98% rename from OpenSim/Region/CoreModules/Caps/CapabilitiesModule.cs rename to OpenSim/Region/ClientStack/Linden/Caps/CapabilitiesModule.cs index ab388b9cc6..b136555c5f 100644 --- a/OpenSim/Region/CoreModules/Caps/CapabilitiesModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/CapabilitiesModule.cs @@ -31,6 +31,7 @@ using System.Collections.Generic; using System.Reflection; using log4net; using Nini.Config; +using Mono.Addins; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Console; @@ -38,8 +39,9 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using Caps=OpenSim.Framework.Capabilities.Caps; -namespace OpenSim.Region.CoreModules.Capabilities +namespace OpenSim.Region.ClientStack.Linden { + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class CapabilitiesModule : INonSharedRegionModule, ICapabilitiesModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index fe97bf22cd..4827baab27 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -33,6 +33,7 @@ using System.Reflection; using System.Threading; using log4net; using Nini.Config; +using Mono.Addins; using OpenMetaverse; using OpenMetaverse.Messages.Linden; using OpenMetaverse.Packets; @@ -53,6 +54,7 @@ namespace OpenSim.Region.ClientStack.Linden public OSDMap body; } + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class EventQueueGetModule : IEventQueue, IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); diff --git a/OpenSim/Region/CoreModules/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs similarity index 99% rename from OpenSim/Region/CoreModules/Caps/GetMeshModule.cs rename to OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs index 46b2378c64..1d5714398f 100644 --- a/OpenSim/Region/CoreModules/Caps/GetMeshModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs @@ -44,7 +44,7 @@ using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using Caps = OpenSim.Framework.Capabilities.Caps; -namespace OpenSim.Region.CoreModules.Capabilities +namespace OpenSim.Region.ClientStack.Linden { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class GetMeshModule : INonSharedRegionModule diff --git a/OpenSim/Region/CoreModules/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs similarity index 99% rename from OpenSim/Region/CoreModules/Caps/GetTextureModule.cs rename to OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index 34095a244c..58dbc14d55 100644 --- a/OpenSim/Region/CoreModules/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs @@ -35,6 +35,7 @@ using System.IO; using System.Web; using log4net; using Nini.Config; +using Mono.Addins; using OpenMetaverse; using OpenMetaverse.StructuredData; using OpenMetaverse.Imaging; @@ -46,7 +47,7 @@ using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using Caps = OpenSim.Framework.Capabilities.Caps; -namespace OpenSim.Region.CoreModules.Capabilities +namespace OpenSim.Region.ClientStack.Linden { #region Stream Handler @@ -70,6 +71,7 @@ namespace OpenSim.Region.CoreModules.Capabilities #endregion Stream Handler + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class GetTextureModule : IRegionModule { private static readonly ILog m_log = diff --git a/OpenSim/Region/CoreModules/Caps/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs similarity index 99% rename from OpenSim/Region/CoreModules/Caps/NewFileAgentInventoryVariablePriceModule.cs rename to OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs index 3ebaf1fcb7..eddc288f0c 100644 --- a/OpenSim/Region/CoreModules/Caps/NewFileAgentInventoryVariablePriceModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs @@ -45,7 +45,7 @@ using OpenSim.Services.Interfaces; using Caps = OpenSim.Framework.Capabilities.Caps; using OpenSim.Framework.Capabilities; -namespace OpenSim.Region.CoreModules.Capabilities +namespace OpenSim.Region.ClientStack.Linden { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class NewFileAgentInventoryVariablePriceModule : INonSharedRegionModule diff --git a/OpenSim/Region/CoreModules/Caps/ObjectCaps/ObjectAdd.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs similarity index 99% rename from OpenSim/Region/CoreModules/Caps/ObjectCaps/ObjectAdd.cs rename to OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs index 5cd0fe732d..15139a3500 100644 --- a/OpenSim/Region/CoreModules/Caps/ObjectCaps/ObjectAdd.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs @@ -39,7 +39,7 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using Caps=OpenSim.Framework.Capabilities.Caps; -namespace OpenSim.Region.CoreModules.Capabilities +namespace OpenSim.Region.ClientStack.Linden { public class ObjectAdd : IRegionModule { diff --git a/OpenSim/Region/CoreModules/Caps/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs similarity index 99% rename from OpenSim/Region/CoreModules/Caps/ObjectCaps/UploadObjectAssetModule.cs rename to OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs index 33bffeb0d3..3809f84380 100644 --- a/OpenSim/Region/CoreModules/Caps/ObjectCaps/UploadObjectAssetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs @@ -49,7 +49,7 @@ using OSDMap = OpenMetaverse.StructuredData.OSDMap; using OpenSim.Framework.Capabilities; using ExtraParamType = OpenMetaverse.ExtraParamType; -namespace OpenSim.Region.CoreModules.Capabilities +namespace OpenSim.Region.ClientStack.Linden { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class UploadObjectAssetModule : INonSharedRegionModule diff --git a/prebuild.xml b/prebuild.xml index 90ee1eb437..6a0b07a360 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1524,7 +1524,9 @@ ../../../../bin/ + + @@ -1540,7 +1542,7 @@ - + From 00e94b0ba8e22b1bfdcbebc7c3d5c879d22b52a4 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 30 Apr 2011 16:53:11 -0700 Subject: [PATCH 14/41] Check for RegionID instead of RegionHandle. Other minor tweaks --- .../Simulation/RemoteSimulationConnector.cs | 4 ++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs index 7858f2afd3..f8cea71b43 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs @@ -179,7 +179,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return true; // else do the remote thing - if (!m_localBackend.IsLocalRegion(destination.RegionHandle)) + if (!m_localBackend.IsLocalRegion(destination.RegionID)) { return m_remoteConnector.CreateAgent(destination, aCircuit, teleportFlags, out reason); } @@ -241,7 +241,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return true; // else do the remote thing - if (!m_localBackend.IsLocalRegion(destination.RegionHandle)) + if (!m_localBackend.IsLocalRegion(destination.RegionID)) return m_remoteConnector.QueryAccess(destination, id, position, out version, out reason); return false; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 1aac09ddbf..5b86735ef3 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -937,7 +937,7 @@ namespace OpenSim.Region.Framework.Scenes // and it has already rezzed the attachments and started their scripts. // We do the following only for non-login agents, because their scripts // haven't started yet. - if (wasChild) + if (wasChild && Attachments != null && Attachments.Count > 0) { m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); // Resume scripts From 56df7461330b1d193f3f60274525eb1b128315ef Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 30 Apr 2011 16:53:43 -0700 Subject: [PATCH 15/41] XXX DEBUGGING! --- OpenSim/Framework/ChildAgentDataUpdate.cs | 3 ++- OpenSim/Framework/WebUtil.cs | 11 ++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index a626b82302..c4b5ddecb1 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -454,6 +454,7 @@ namespace OpenSim.Framework { OSDMap info = new OSDMap(4); info["sog"] = OSD.FromString(so.ToXml2()); + m_log.DebugFormat("[XXX] {0}", so.ToXml2()); info["extra"] = OSD.FromString(so.ExtraToXmlString()); info["modified"] = OSD.FromBoolean(so.HasGroupChanged); try @@ -462,7 +463,7 @@ namespace OpenSim.Framework } catch (IndexOutOfRangeException e) { - m_log.WarnFormat("[CHILD AGENT DATA]: scrtips list is shorter than object list."); + m_log.WarnFormat("[CHILD AGENT DATA]: scripts list is shorter than object list."); } attObjs.Add(info); diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index 9d70f63189..5449a6faf9 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs @@ -177,7 +177,16 @@ namespace OpenSim.Framework // If there is some input, write it into the request if (data != null) { - string strBuffer = OSDParser.SerializeJsonString(data); + string strBuffer = string.Empty; + try + { + strBuffer = OSDParser.SerializeJsonString(data); + } + catch (Exception e) + { + m_log.DebugFormat("[WEB UTIL]: Exception serializing data {0}", e.Message); + throw e; + } byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer); request.ContentType = "application/json"; From 91a604d4b6822130871f35ddbc2c53f3468c2a01 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 30 Apr 2011 17:40:21 -0700 Subject: [PATCH 16/41] Removed XXX Debug. Increased ReadWriteTimeout on ServiceOSDRequest, because it was _way_ too low and is probably making writes abort in the middle. --- OpenSim/Framework/ChildAgentDataUpdate.cs | 1 - OpenSim/Framework/WebUtil.cs | 15 +++------------ 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index c4b5ddecb1..28fe3ba889 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -454,7 +454,6 @@ namespace OpenSim.Framework { OSDMap info = new OSDMap(4); info["sog"] = OSD.FromString(so.ToXml2()); - m_log.DebugFormat("[XXX] {0}", so.ToXml2()); info["extra"] = OSD.FromString(so.ExtraToXmlString()); info["modified"] = OSD.FromBoolean(so.HasGroupChanged); try diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index 5449a6faf9..f6fed33d69 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs @@ -171,24 +171,15 @@ namespace OpenSim.Framework request.Timeout = timeout; request.KeepAlive = false; request.MaximumAutomaticRedirections = 10; - request.ReadWriteTimeout = timeout / 4; + request.ReadWriteTimeout = timeout * 8; request.Headers[OSHeaderRequestID] = reqnum.ToString(); // If there is some input, write it into the request if (data != null) { - string strBuffer = string.Empty; - try - { - strBuffer = OSDParser.SerializeJsonString(data); - } - catch (Exception e) - { - m_log.DebugFormat("[WEB UTIL]: Exception serializing data {0}", e.Message); - throw e; - } + string strBuffer = OSDParser.SerializeJsonString(data); byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer); - + request.ContentType = "application/json"; request.ContentLength = buffer.Length; //Count bytes to send using (Stream requestStream = request.GetRequestStream()) From d4323dd7530734ed2c35138722ed8c9c01d53d4e Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 30 Apr 2011 18:08:48 -0700 Subject: [PATCH 17/41] Increased Timeout to 30 secs. --- OpenSim/Framework/WebUtil.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index f6fed33d69..ac0828b90e 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs @@ -142,17 +142,17 @@ namespace OpenSim.Framework /// public static OSDMap PutToService(string url, OSDMap data) { - return ServiceOSDRequest(url,data,"PUT",10000); + return ServiceOSDRequest(url,data,"PUT",30000); } public static OSDMap PostToService(string url, OSDMap data) { - return ServiceOSDRequest(url,data,"POST",10000); + return ServiceOSDRequest(url,data,"POST",30000); } public static OSDMap GetFromService(string url) { - return ServiceOSDRequest(url,null,"GET",10000); + return ServiceOSDRequest(url,null,"GET",30000); } public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout) From 6b2b036387784a74cf88f35715219071ee8718d2 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 1 May 2011 09:08:18 -0700 Subject: [PATCH 18/41] Added OpenSim.Capabilities.Handlers. For the moment it has only the GetTexture handler. The region module in Linden space uses it. WARNING: nothing of this works yet, it just compiles. --- .../Handlers/CapsServerConnector.cs | 73 ++++ .../Handlers/GetTextureHandler.cs | 356 ++++++++++++++++++ .../Linden/Caps/GetTextureModule.cs | 315 +--------------- prebuild.xml | 46 ++- 4 files changed, 476 insertions(+), 314 deletions(-) create mode 100644 OpenSim/Capabilities/Handlers/CapsServerConnector.cs create mode 100644 OpenSim/Capabilities/Handlers/GetTextureHandler.cs diff --git a/OpenSim/Capabilities/Handlers/CapsServerConnector.cs b/OpenSim/Capabilities/Handlers/CapsServerConnector.cs new file mode 100644 index 0000000000..561d767c0c --- /dev/null +++ b/OpenSim/Capabilities/Handlers/CapsServerConnector.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 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 Nini.Config; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Server.Handlers.Base; +using OpenMetaverse; +using Caps = OpenSim.Framework.Capabilities.Caps; + +namespace OpenSim.Capabilities.Handlers +{ + public class CapsServerConnector : ServiceConnector + { + private IAssetService m_AssetService; + private string m_ConfigName = "CapsService"; + + public CapsServerConnector(IConfigSource config, IHttpServer server, string configName) : + base(config, server, configName) + { + if (configName != String.Empty) + m_ConfigName = configName; + + IConfig serverConfig = config.Configs[m_ConfigName]; + if (serverConfig == null) + throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName)); + + string assetService = serverConfig.GetString("LocalServiceModule", + String.Empty); + + if (assetService == String.Empty) + throw new Exception("No LocalServiceModule in config file"); + + Object[] args = new Object[] { config }; + m_AssetService = + ServerUtils.LoadPlugin(assetService, args); + + if (m_AssetService == null) + throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName)); + + bool allowDelete = serverConfig.GetBoolean("AllowRemoteDelete", false); + + server.AddStreamHandler(new GetTextureHandler("/CAPS/" + UUID.Random() + "/", m_AssetService)); + } + + } +} diff --git a/OpenSim/Capabilities/Handlers/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTextureHandler.cs new file mode 100644 index 0000000000..00186eef27 --- /dev/null +++ b/OpenSim/Capabilities/Handlers/GetTextureHandler.cs @@ -0,0 +1,356 @@ +/* + * 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; +using System.Collections.Specialized; +using System.Drawing; +using System.Drawing.Imaging; +using System.Reflection; +using System.IO; +using System.Web; +using log4net; +using Nini.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenMetaverse.Imaging; +using OpenSim.Framework; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Services.Interfaces; +using Caps = OpenSim.Framework.Capabilities.Caps; + +namespace OpenSim.Capabilities.Handlers +{ + + public class GetTextureHandler : BaseStreamHandler + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private IAssetService m_assetService; + + public const string DefaultFormat = "x-j2c"; + + // TODO: Change this to a config option + const string REDIRECT_URL = null; + + public GetTextureHandler(string path, IAssetService assService) : + base("GET", path) + { + m_assetService = assService; + } + + public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + //m_log.DebugFormat("[GETTEXTURE]: called in {0}", m_scene.RegionInfo.RegionName); + + // Try to parse the texture ID from the request URL + NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); + string textureStr = query.GetOne("texture_id"); + string format = query.GetOne("format"); + + if (m_assetService == null) + { + m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service"); + httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + return null; + } + + UUID textureID; + if (!String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out textureID)) + { + string[] formats; + if (format != null && format != string.Empty) + { + formats = new string[1] { format.ToLower() }; + } + else + { + formats = WebUtil.GetPreferredImageTypes(httpRequest.Headers.Get("Accept")); + if (formats.Length == 0) + formats = new string[1] { DefaultFormat }; // default + + } + // OK, we have an array with preferred formats, possibly with only one entry + + httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + foreach (string f in formats) + { + if (FetchTexture(httpRequest, httpResponse, textureID, f)) + break; + } + + } + else + { + m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url); + } + + httpResponse.Send(); + return null; + } + + /// + /// + /// + /// + /// + /// + /// + /// False for "caller try another codec"; true otherwise + private bool FetchTexture(OSHttpRequest httpRequest, OSHttpResponse httpResponse, UUID textureID, string format) + { +// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format); + AssetBase texture; + + string fullID = textureID.ToString(); + if (format != DefaultFormat) + fullID = fullID + "-" + format; + + if (!String.IsNullOrEmpty(REDIRECT_URL)) + { + // Only try to fetch locally cached textures. Misses are redirected + texture = m_assetService.GetCached(fullID); + + if (texture != null) + { + if (texture.Type != (sbyte)AssetType.Texture) + { + httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + return true; + } + WriteTextureData(httpRequest, httpResponse, texture, format); + } + else + { + string textureUrl = REDIRECT_URL + textureID.ToString(); + m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl); + httpResponse.RedirectLocation = textureUrl; + return true; + } + } + else // no redirect + { + // try the cache + texture = m_assetService.GetCached(fullID); + + if (texture == null) + { + //m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache"); + + // Fetch locally or remotely. Misses return a 404 + texture = m_assetService.Get(textureID.ToString()); + + if (texture != null) + { + if (texture.Type != (sbyte)AssetType.Texture) + { + httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + return true; + } + if (format == DefaultFormat) + { + WriteTextureData(httpRequest, httpResponse, texture, format); + return true; + } + else + { + AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID); + newTexture.Data = ConvertTextureData(texture, format); + if (newTexture.Data.Length == 0) + return false; // !!! Caller try another codec, please! + + newTexture.Flags = AssetFlags.Collectable; + newTexture.Temporary = true; + m_assetService.Store(newTexture); + WriteTextureData(httpRequest, httpResponse, newTexture, format); + return true; + } + } + } + else // it was on the cache + { + //m_log.DebugFormat("[GETTEXTURE]: texture was in the cache"); + WriteTextureData(httpRequest, httpResponse, texture, format); + return true; + } + } + + // not found +// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); + httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + return true; + } + + private void WriteTextureData(OSHttpRequest request, OSHttpResponse response, AssetBase texture, string format) + { + string range = request.Headers.GetOne("Range"); + //m_log.DebugFormat("[GETTEXTURE]: Range {0}", range); + if (!String.IsNullOrEmpty(range)) // JP2's only + { + // Range request + int start, end; + if (TryParseRange(range, out start, out end)) + { + // Before clamping start make sure we can satisfy it in order to avoid + // sending back the last byte instead of an error status + if (start >= texture.Data.Length) + { + response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable; + return; + } + + end = Utils.Clamp(end, 0, texture.Data.Length - 1); + start = Utils.Clamp(start, 0, end); + int len = end - start + 1; + + //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); + + if (len < texture.Data.Length) + response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent; + + response.ContentLength = len; + response.ContentType = texture.Metadata.ContentType; + response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length)); + + response.Body.Write(texture.Data, start, len); + } + else + { + m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range); + response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest; + } + } + else // JP2's or other formats + { + // Full content request + response.StatusCode = (int)System.Net.HttpStatusCode.OK; + response.ContentLength = texture.Data.Length; + if (format == DefaultFormat) + response.ContentType = texture.Metadata.ContentType; + else + response.ContentType = "image/" + format; + response.Body.Write(texture.Data, 0, texture.Data.Length); + } + } + + private bool TryParseRange(string header, out int start, out int end) + { + if (header.StartsWith("bytes=")) + { + string[] rangeValues = header.Substring(6).Split('-'); + if (rangeValues.Length == 2) + { + if (Int32.TryParse(rangeValues[0], out start) && Int32.TryParse(rangeValues[1], out end)) + return true; + } + } + + start = end = 0; + return false; + } + + + private byte[] ConvertTextureData(AssetBase texture, string format) + { + m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format); + byte[] data = new byte[0]; + + MemoryStream imgstream = new MemoryStream(); + Bitmap mTexture = new Bitmap(1, 1); + ManagedImage managedImage; + Image image = (Image)mTexture; + + try + { + // Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data + + imgstream = new MemoryStream(); + + // Decode image to System.Drawing.Image + if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image)) + { + // Save to bitmap + mTexture = new Bitmap(image); + + EncoderParameters myEncoderParameters = new EncoderParameters(); + myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 95L); + + // Save bitmap to stream + ImageCodecInfo codec = GetEncoderInfo("image/" + format); + if (codec != null) + { + mTexture.Save(imgstream, codec, myEncoderParameters); + // Write the stream to a byte array for output + data = imgstream.ToArray(); + } + else + m_log.WarnFormat("[GETTEXTURE]: No such codec {0}", format); + + } + } + catch (Exception e) + { + m_log.WarnFormat("[GETTEXTURE]: Unable to convert texture {0} to {1}: {2}", texture.ID, format, e.Message); + } + finally + { + // Reclaim memory, these are unmanaged resources + // If we encountered an exception, one or more of these will be null + if (mTexture != null) + mTexture.Dispose(); + + if (image != null) + image.Dispose(); + + if (imgstream != null) + { + imgstream.Close(); + imgstream.Dispose(); + } + } + + return data; + } + + // From msdn + private static ImageCodecInfo GetEncoderInfo(String mimeType) + { + ImageCodecInfo[] encoders; + encoders = ImageCodecInfo.GetImageEncoders(); + for (int j = 0; j < encoders.Length; ++j) + { + if (encoders[j].MimeType == mimeType) + return encoders[j]; + } + return null; + } + + + } +} diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index 58dbc14d55..341240d971 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs @@ -46,30 +46,10 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using Caps = OpenSim.Framework.Capabilities.Caps; +using OpenSim.Capabilities.Handlers; namespace OpenSim.Region.ClientStack.Linden { - #region Stream Handler - - public delegate byte[] StreamHandlerCallback(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse); - - public class StreamHandler : BaseStreamHandler - { - StreamHandlerCallback m_callback; - - public StreamHandler(string httpMethod, string path, StreamHandlerCallback callback) - : base(httpMethod, path) - { - m_callback = callback; - } - - public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - return m_callback(path, request, httpRequest, httpResponse); - } - } - - #endregion Stream Handler [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class GetTextureModule : IRegionModule @@ -107,298 +87,11 @@ namespace OpenSim.Region.ClientStack.Linden { UUID capID = UUID.Random(); -// m_log.InfoFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); - caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); + // m_log.InfoFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); + //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); + caps.RegisterHandler("GetTexture", new GetTextureHandler("/CAPS/" + capID + "/", m_assetService)); } #endregion - - private byte[] ProcessGetTexture(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - //m_log.DebugFormat("[GETTEXTURE]: called in {0}", m_scene.RegionInfo.RegionName); - - // Try to parse the texture ID from the request URL - NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); - string textureStr = query.GetOne("texture_id"); - string format = query.GetOne("format"); - - if (m_assetService == null) - { - m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service"); - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - return null; - } - - UUID textureID; - if (!String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out textureID)) - { - string[] formats; - if (format != null && format != string.Empty) - { - formats = new string[1] { format.ToLower() }; - } - else - { - formats = WebUtil.GetPreferredImageTypes(httpRequest.Headers.Get("Accept")); - if (formats.Length == 0) - formats = new string[1] { DefaultFormat }; // default - - } - // OK, we have an array with preferred formats, possibly with only one entry - - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - foreach (string f in formats) - { - if (FetchTexture(httpRequest, httpResponse, textureID, f)) - break; - } - - } - else - { - m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url); - } - - httpResponse.Send(); - return null; - } - - /// - /// - /// - /// - /// - /// - /// - /// False for "caller try another codec"; true otherwise - private bool FetchTexture(OSHttpRequest httpRequest, OSHttpResponse httpResponse, UUID textureID, string format) - { -// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format); - AssetBase texture; - - string fullID = textureID.ToString(); - if (format != DefaultFormat) - fullID = fullID + "-" + format; - - if (!String.IsNullOrEmpty(REDIRECT_URL)) - { - // Only try to fetch locally cached textures. Misses are redirected - texture = m_assetService.GetCached(fullID); - - if (texture != null) - { - if (texture.Type != (sbyte)AssetType.Texture) - { - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - return true; - } - WriteTextureData(httpRequest, httpResponse, texture, format); - } - else - { - string textureUrl = REDIRECT_URL + textureID.ToString(); - m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl); - httpResponse.RedirectLocation = textureUrl; - return true; - } - } - else // no redirect - { - // try the cache - texture = m_assetService.GetCached(fullID); - - if (texture == null) - { - //m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache"); - - // Fetch locally or remotely. Misses return a 404 - texture = m_assetService.Get(textureID.ToString()); - - if (texture != null) - { - if (texture.Type != (sbyte)AssetType.Texture) - { - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - return true; - } - if (format == DefaultFormat) - { - WriteTextureData(httpRequest, httpResponse, texture, format); - return true; - } - else - { - AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID); - newTexture.Data = ConvertTextureData(texture, format); - if (newTexture.Data.Length == 0) - return false; // !!! Caller try another codec, please! - - newTexture.Flags = AssetFlags.Collectable; - newTexture.Temporary = true; - m_assetService.Store(newTexture); - WriteTextureData(httpRequest, httpResponse, newTexture, format); - return true; - } - } - } - else // it was on the cache - { - //m_log.DebugFormat("[GETTEXTURE]: texture was in the cache"); - WriteTextureData(httpRequest, httpResponse, texture, format); - return true; - } - } - - // not found -// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - return true; - } - - private void WriteTextureData(OSHttpRequest request, OSHttpResponse response, AssetBase texture, string format) - { - string range = request.Headers.GetOne("Range"); - //m_log.DebugFormat("[GETTEXTURE]: Range {0}", range); - if (!String.IsNullOrEmpty(range)) // JP2's only - { - // Range request - int start, end; - if (TryParseRange(range, out start, out end)) - { - // Before clamping start make sure we can satisfy it in order to avoid - // sending back the last byte instead of an error status - if (start >= texture.Data.Length) - { - response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable; - return; - } - - end = Utils.Clamp(end, 0, texture.Data.Length - 1); - start = Utils.Clamp(start, 0, end); - int len = end - start + 1; - - //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); - - if (len < texture.Data.Length) - response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent; - - response.ContentLength = len; - response.ContentType = texture.Metadata.ContentType; - response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length)); - - response.Body.Write(texture.Data, start, len); - } - else - { - m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range); - response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest; - } - } - else // JP2's or other formats - { - // Full content request - response.StatusCode = (int)System.Net.HttpStatusCode.OK; - response.ContentLength = texture.Data.Length; - if (format == DefaultFormat) - response.ContentType = texture.Metadata.ContentType; - else - response.ContentType = "image/" + format; - response.Body.Write(texture.Data, 0, texture.Data.Length); - } - } - - private bool TryParseRange(string header, out int start, out int end) - { - if (header.StartsWith("bytes=")) - { - string[] rangeValues = header.Substring(6).Split('-'); - if (rangeValues.Length == 2) - { - if (Int32.TryParse(rangeValues[0], out start) && Int32.TryParse(rangeValues[1], out end)) - return true; - } - } - - start = end = 0; - return false; - } - - - private byte[] ConvertTextureData(AssetBase texture, string format) - { - m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format); - byte[] data = new byte[0]; - - MemoryStream imgstream = new MemoryStream(); - Bitmap mTexture = new Bitmap(1, 1); - ManagedImage managedImage; - Image image = (Image)mTexture; - - try - { - // Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data - - imgstream = new MemoryStream(); - - // Decode image to System.Drawing.Image - if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image)) - { - // Save to bitmap - mTexture = new Bitmap(image); - - EncoderParameters myEncoderParameters = new EncoderParameters(); - myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 95L); - - // Save bitmap to stream - ImageCodecInfo codec = GetEncoderInfo("image/" + format); - if (codec != null) - { - mTexture.Save(imgstream, codec, myEncoderParameters); - // Write the stream to a byte array for output - data = imgstream.ToArray(); - } - else - m_log.WarnFormat("[GETTEXTURE]: No such codec {0}", format); - - } - } - catch (Exception e) - { - m_log.WarnFormat("[GETTEXTURE]: Unable to convert texture {0} to {1}: {2}", texture.ID, format, e.Message); - } - finally - { - // Reclaim memory, these are unmanaged resources - // If we encountered an exception, one or more of these will be null - if (mTexture != null) - mTexture.Dispose(); - - if (image != null) - image.Dispose(); - - if (imgstream != null) - { - imgstream.Close(); - imgstream.Dispose(); - } - } - - return data; - } - - // From msdn - private static ImageCodecInfo GetEncoderInfo(String mimeType) - { - ImageCodecInfo[] encoders; - encoders = ImageCodecInfo.GetImageEncoders(); - for (int j = 0; j < encoders.Length; ++j) - { - if (encoders[j].MimeType == mimeType) - return encoders[j]; - } - return null; - } - - } } diff --git a/prebuild.xml b/prebuild.xml index 6a0b07a360..4fa48d140b 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -687,7 +687,7 @@ - + @@ -1268,7 +1268,6 @@ - @@ -1306,6 +1305,47 @@ + + + + + ../../../bin/ + + + + + ../../../bin/ + + + + ../../../bin/ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1532,6 +1572,7 @@ + @@ -2355,7 +2396,6 @@ - From bbe41c75e17764a238f301bfdebdc095cc4a64cd Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 1 May 2011 09:30:23 -0700 Subject: [PATCH 19/41] Fixed confusing OSDMap that comes as the response of QueryAccess in the case it fails. --- .../Simulation/SimulationServiceConnector.cs | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index 7545db8200..5cb82699d6 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -275,27 +275,30 @@ namespace OpenSim.Services.Connectors.Simulation try { OSDMap result = WebUtil.ServiceOSDRequest(uri, request, "QUERYACCESS", 10000); - OSDMap data = (OSDMap)result["_Result"]; - bool success = result["success"].AsBoolean(); - reason = data["reason"].AsString(); - if (data["version"] != null && data["version"].AsString() != string.Empty) - version = data["version"].AsString(); + if (result.ContainsKey("_Result")) + { + OSDMap data = (OSDMap)result["_Result"]; - m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess to {0} returned {1} version {2} ({3})", uri, success, version, data["version"].AsString()); + reason = data["reason"].AsString(); + if (data["version"] != null && data["version"].AsString() != string.Empty) + version = data["version"].AsString(); + + m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess to {0} returned {1} version {2} ({3})", uri, success, version, data["version"].AsString()); + } if (!success) { - if (data.ContainsKey("Message")) + if (result.ContainsKey("Message")) { - string message = data["Message"].AsString(); + string message = result["Message"].AsString(); if (message == "Service request failed: [MethodNotAllowed] MethodNotAllowed") // Old style region { m_log.Info("[REMOTE SIMULATION CONNECTOR]: The above web util error was caused by a TP to a sim that doesn't support QUERYACCESS and can be ignored"); return true; } - reason = data["Message"]; + reason = result["Message"]; } else { From f10666c7ba6d3af9822d20026674afd74a6bb3fc Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 1 May 2011 10:07:54 -0700 Subject: [PATCH 20/41] How this might look like from a configuration perspective. Changes OpenSimDefaults.ini. --- OpenSim/Capabilities/Caps.cs | 13 ++++++++ bin/OpenSimDefaults.ini | 59 ++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/OpenSim/Capabilities/Caps.cs b/OpenSim/Capabilities/Caps.cs index 3be97b5c89..c98498d7ff 100644 --- a/OpenSim/Capabilities/Caps.cs +++ b/OpenSim/Capabilities/Caps.cs @@ -85,6 +85,7 @@ namespace OpenSim.Framework.Capabilities public string CapsObjectPath { get { return m_capsObjectPath; } } private CapsHandlers m_capsHandlers; + private Dictionary m_externalCapsHandlers; private static readonly string m_requestPath = "0000/"; // private static readonly string m_mapLayerPath = "0001/"; @@ -167,6 +168,7 @@ namespace OpenSim.Framework.Capabilities m_agentID = agent; m_dumpAssetsToFile = dumpAssetsToFile; m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, (httpServer == null) ? false : httpServer.UseSSL); + m_externalCapsHandlers = new Dictionary(); m_regionName = regionName; } @@ -266,6 +268,17 @@ namespace OpenSim.Framework.Capabilities //m_log.DebugFormat("[CAPS]: Registering handler for \"{0}\": path {1}", capName, handler.Path); } + /// + /// Register an external handler. The service for this capability is somewhere else + /// given by the URL. + /// + /// + /// + public void RegisterHandler(string capsName, string url) + { + m_externalCapsHandlers.Add(capsName, url); + } + /// /// Remove all CAPS service handlers. /// diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 35e8079cf5..35287b1313 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -408,6 +408,65 @@ ; ;DisableFacelights = "false" +[ClientStack.LindenCaps] + Cap_AttachmentResources = "localhost" + Cap_AvatarPickerSearch = "localhost" + Cap_ChatSessionRequest = "localhost" + Cap_CopyInventoryFromNotecard = "localhost" + Cap_DispatchRegionInfo = "localhost" + Cap_EstateChangeInfo = "localhost" + Cap_EventQueueGet = "localhost" + Cap_FetchInventory = "localhost" + Cap_ObjectMedia = "localhost" + Cap_ObjectMediaNavigate = "localhost" + Cap_FetchLib = "localhost" + Cap_FetchLibDescendents = "localhost" + Cap_GetDisplayNames = "localhost" + Cap_GetTexture = "localhost" + Cap_GetMesh = "localhost" + Cap_GetObjectCost = "localhost" + Cap_GetObjectPhysicsData = "localhost" + Cap_GroupProposalBallot = "localhost" + Cap_HomeLocation = "localhost" + Cap_LandResources = "localhost" + Cap_MapLayer = "localhost" + Cap_MapLayerGod = "localhost" + Cap_NewFileAgentInventory = "localhost" + Cap_NewFileAgentInventoryVariablePrice = "localhost" + Cap_ObjectAdd = "localhost" + Cap_ParcelPropertiesUpdate = "localhost" + Cap_ParcelMediaURLFilterList = "localhost" + Cap_ParcelNavigateMedia = "localhost" + Cap_ParcelVoiceInfoRequest = "localhost" + Cap_ProductInfoRequest = "localhost" + Cap_ProvisionVoiceAccountRequest = "localhost" + Cap_RemoteParcelRequest = "localhost" + Cap_RequestTextureDownload = "localhost" + Cap_SearchStatRequest = "localhost" + Cap_SearchStatTracking = "localhost" + Cap_SendPostcard = "localhost" + Cap_SendUserReport = "localhost" + Cap_SendUserReportWithScreenshot = "localhost" + Cap_ServerReleaseNotes = "localhost" + Cap_SimConsole = "localhost" + Cap_SimulatorFeatures = "localhost" + Cap_SetDisplayName = "localhost" + Cap_StartGroupProposal = "localhost" + Cap_TextureStats = "localhost" + Cap_UntrustedSimulatorMessage = "localhost" + Cap_UpdateAgentInformation = "localhost" + Cap_UpdateAgentLanguage = "localhost" + Cap_UpdateGestureAgentInventory = "localhost" + Cap_UpdateNotecardAgentInventory = "localhost" + Cap_UpdateScriptAgent = "localhost" + Cap_UpdateGestureTaskInventory = "localhost" + Cap_UpdateNotecardTaskInventory = "localhost" + Cap_UpdateScriptTask = "localhost" + Cap_UploadBakedTexture = "localhost" + Cap_UploadObjectAsset = "localhost" + Cap_ViewerStartAuction = "localhost" + Cap_ViewerStats = "localhost" + Cap_WebFetchInventoryDescendents = "localhost" [Chat] ; Controls whether the chat module is enabled. Default is true. From 126d2adeba40cc8cf4a6e387e07906a03cfa0ab5 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 1 May 2011 12:02:07 -0700 Subject: [PATCH 21/41] Move CapabilitiesModule back to CoreModules. This one belongs there. --- .../Linden => CoreModules/Framework}/Caps/CapabilitiesModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename OpenSim/Region/{ClientStack/Linden => CoreModules/Framework}/Caps/CapabilitiesModule.cs (99%) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs similarity index 99% rename from OpenSim/Region/ClientStack/Linden/Caps/CapabilitiesModule.cs rename to OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs index b136555c5f..e684a0d770 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/CapabilitiesModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs @@ -39,7 +39,7 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using Caps=OpenSim.Framework.Capabilities.Caps; -namespace OpenSim.Region.ClientStack.Linden +namespace OpenSim.Region.CoreModules.Framework { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class CapabilitiesModule : INonSharedRegionModule, ICapabilitiesModule From 275046cf0248c61db161bf75cb3b4356a9ecc0e9 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 1 May 2011 12:03:00 -0700 Subject: [PATCH 22/41] Change GetTextureModule.cs to conform to the new IRegion module interface. NOTHING OF THIS WORKS. Compiles. --- .../Linden/Caps/GetTextureModule.cs | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index 341240d971..86c990fff8 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs @@ -52,7 +52,7 @@ namespace OpenSim.Region.ClientStack.Linden { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class GetTextureModule : IRegionModule + public class GetTextureModule : ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -64,12 +64,22 @@ namespace OpenSim.Region.ClientStack.Linden // TODO: Change this to a config option const string REDIRECT_URL = null; + #region ISharedRegionModule Members - #region IRegionModule Members - - public void Initialise(Scene pScene, IConfigSource pSource) + public void Initialise(IConfigSource pSource) + { + } + + public void AddRegion(Scene s) + { + } + + public void RemoveRegion(Scene s) + { + } + + public void RegionLoaded(Scene s) { - m_scene = pScene; } public void PostInitialise() @@ -81,7 +91,13 @@ namespace OpenSim.Region.ClientStack.Linden public void Close() { } public string Name { get { return "GetTextureModule"; } } - public bool IsSharedModule { get { return false; } } + + public Type ReplaceableInterface + { + get { return null; } + } + + #endregion public void RegisterCaps(UUID agentID, Caps caps) { @@ -92,6 +108,5 @@ namespace OpenSim.Region.ClientStack.Linden caps.RegisterHandler("GetTexture", new GetTextureHandler("/CAPS/" + capID + "/", m_assetService)); } - #endregion } } From f79400e94ca6f8b609f5d4cbe25c5bbc04b61b77 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 1 May 2011 18:22:53 -0700 Subject: [PATCH 23/41] Broke down Caps.cs into a generic Caps object that simply registers/unregisters capabilities and a specific bunch of capability implementations in Linden space called BunchOfCaps. Renamed a few methods that were misnomers. Compiles but doesn't work. --- OpenSim/Capabilities/Caps.cs | 1261 +---------------- .../Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 1210 ++++++++++++++++ .../Caps/BunchOfCaps/BunchOfCapsModule.cs | 87 ++ .../Caps/EventQueue/EventQueueGetModule.cs | 2 +- ...ewFileAgentInventoryVariablePriceModule.cs | 4 +- .../Framework/Caps/CapabilitiesModule.cs | 50 +- .../InterGrid/OpenGridProtocolModule.cs | 4 +- .../Interfaces/ICapabilitiesModule.cs | 14 +- OpenSim/Region/Framework/Scenes/Scene.cs | 8 +- 9 files changed, 1357 insertions(+), 1283 deletions(-) create mode 100644 OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs create mode 100644 OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs diff --git a/OpenSim/Capabilities/Caps.cs b/OpenSim/Capabilities/Caps.cs index c98498d7ff..95bb465763 100644 --- a/OpenSim/Capabilities/Caps.cs +++ b/OpenSim/Capabilities/Caps.cs @@ -41,28 +41,6 @@ using OpenSim.Services.Interfaces; namespace OpenSim.Framework.Capabilities { - public delegate void UpLoadedAsset( - string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder, - byte[] data, string inventoryType, string assetType); - - public delegate void UploadedBakedTexture(UUID assetID, byte[] data); - - public delegate UUID UpdateItem(UUID itemID, byte[] data); - - public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors); - - public delegate void NewInventoryItem(UUID userID, InventoryItemBase item); - - public delegate void NewAsset(AssetBase asset); - - public delegate UUID ItemUpdatedCallback(UUID userID, UUID itemID, byte[] data); - - public delegate ArrayList TaskScriptUpdatedCallback(UUID userID, UUID itemID, UUID primID, - bool isScriptRunning, byte[] data); - - public delegate InventoryCollection FetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID, - bool fetchFolders, bool fetchItems, int sortOrder, out int version); - /// /// XXX Probably not a particularly nice way of allow us to get the scene presence from the scene (chiefly so that /// we can popup a message on the user's client if the inventory service has permanently failed). But I didn't want @@ -87,34 +65,34 @@ namespace OpenSim.Framework.Capabilities private CapsHandlers m_capsHandlers; private Dictionary m_externalCapsHandlers; - private static readonly string m_requestPath = "0000/"; - // private static readonly string m_mapLayerPath = "0001/"; - private static readonly string m_newInventory = "0002/"; - //private static readonly string m_requestTexture = "0003/"; - private static readonly string m_notecardUpdatePath = "0004/"; - private static readonly string m_notecardTaskUpdatePath = "0005/"; -// private static readonly string m_fetchInventoryPath = "0006/"; - - // The following entries are in a module, however, they are also here so that we don't re-assign - // the path to another cap by mistake. - // private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; // This is in a module. - // private static readonly string m_provisionVoiceAccountRequestPath = "0008/";// This is in a module. - - // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule. - private static readonly string m_uploadBakedTexturePath = "0010/";// This is in the LandManagementModule. - - //private string eventQueue = "0100/"; - private IScene m_Scene; private IHttpServer m_httpListener; private UUID m_agentID; - private IAssetService m_assetCache; - private int m_eventQueueCount = 1; - private Queue m_capsEventQueue = new Queue(); - private bool m_dumpAssetsToFile; private string m_regionName; - private object m_fetchLock = new Object(); - private bool m_persistBakedTextures = false; + public UUID AgentID + { + get { return m_agentID; } + } + + public string RegionName + { + get { return m_regionName; } + } + + public string HostName + { + get { return m_httpListenerHostName; } + } + + public uint Port + { + get { return m_httpListenPort; } + } + + public IHttpServer HttpListener + { + get { return m_httpListener; } + } public bool SSLCaps { @@ -129,35 +107,15 @@ namespace OpenSim.Framework.Capabilities get { return m_capsHandlers; } } - // 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 NewAsset AddNewAsset = null; - public ItemUpdatedCallback ItemUpdatedCall = null; - public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null; - public FetchInventoryDescendentsCAPS CAPSFetchInventoryDescendents = null; - public GetClientDelegate GetClient = null; - - public Caps(IScene scene, IAssetService assetCache, IHttpServer httpServer, string httpListen, uint httpPort, string capsPath, - UUID agent, bool dumpAssetsToFile, string regionName) + public Caps(IHttpServer httpServer, string httpListen, uint httpPort, string capsPath, + UUID agent, string regionName) { - m_Scene = scene; - m_assetCache = assetCache; m_capsObjectPath = capsPath; m_httpListener = httpServer; m_httpListenerHostName = httpListen; m_httpListenPort = httpPort; - m_persistBakedTextures = false; - IConfigSource config = m_Scene.Config; - if (config != null) - { - IConfig sconfig = config.Configs["Startup"]; - if (sconfig != null) - m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures",m_persistBakedTextures); - } - if (httpServer != null && httpServer.UseSSL) { m_httpListenPort = httpServer.SSLPort; @@ -166,97 +124,11 @@ namespace OpenSim.Framework.Capabilities } m_agentID = agent; - m_dumpAssetsToFile = dumpAssetsToFile; m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, (httpServer == null) ? false : httpServer.UseSSL); m_externalCapsHandlers = new Dictionary(); m_regionName = regionName; } - /// - /// Register all CAPS http service handlers - /// - public void RegisterHandlers() - { - DeregisterHandlers(); - - string capsBase = "/CAPS/" + m_capsObjectPath; - - RegisterRegionServiceHandlers(capsBase); - RegisterInventoryServiceHandlers(capsBase); - } - - public void RegisterRegionServiceHandlers(string capsBase) - { - try - { - // the root of all evil - m_capsHandlers["SEED"] = new RestStreamHandler("POST", capsBase + m_requestPath, CapsRequest); - m_log.DebugFormat( - "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_agentID); - - //m_capsHandlers["MapLayer"] = - // new LLSDStreamhandler("POST", - // capsBase + m_mapLayerPath, - // GetMapLayer); - m_capsHandlers["UpdateScriptTaskInventory"] = - new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory); - m_capsHandlers["UpdateScriptTask"] = m_capsHandlers["UpdateScriptTaskInventory"]; - m_capsHandlers["UploadBakedTexture"] = - new RestStreamHandler("POST", capsBase + m_uploadBakedTexturePath, UploadBakedTexture); - - } - catch (Exception e) - { - m_log.Error("[CAPS]: " + e.ToString()); - } - } - - public void RegisterInventoryServiceHandlers(string capsBase) - { - try - { - // I don't think this one works... - m_capsHandlers["NewFileAgentInventory"] = - new LLSDStreamhandler("POST", - capsBase + m_newInventory, - NewAgentInventoryRequest); - m_capsHandlers["UpdateNotecardAgentInventory"] = - new RestStreamHandler("POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory); - m_capsHandlers["UpdateScriptAgentInventory"] = m_capsHandlers["UpdateNotecardAgentInventory"]; - m_capsHandlers["UpdateScriptAgent"] = m_capsHandlers["UpdateScriptAgentInventory"]; - - // As of RC 1.22.9 of the Linden client this is - // supported - - //m_capsHandlers["WebFetchInventoryDescendents"] =new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryDescendentsRequest); - - // justincc: I've disabled the CAPS service for now to fix problems with selecting textures, and - // subsequent inventory breakage, in the edit object pane (such as mantis 1085). This requires - // enhancements (probably filling out the folder part of the LLSD reply) to our CAPS service, - // but when I went on the Linden grid, the - // simulators I visited (version 1.21) were, surprisingly, no longer supplying this capability. Instead, - // the 1.19.1.4 client appeared to be happily flowing inventory data over UDP - // - // This is very probably just a temporary measure - once the CAPS service appears again on the Linden grid - // we will be - // able to get the data we need to implement the necessary part of the protocol to fix the issue above. - // m_capsHandlers["FetchInventoryDescendents"] = - // new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryRequest); - - // m_capsHandlers["FetchInventoryDescendents"] = - // new LLSDStreamhandler("POST", - // capsBase + m_fetchInventory, - // FetchInventory)); - // m_capsHandlers["RequestTextureDownload"] = new RestStreamHandler("POST", - // capsBase + m_requestTexture, - // RequestTexture); - } - catch (Exception e) - { - m_log.Error("[CAPS]: " + e.ToString()); - } - } - /// /// Register a handler. This allows modules to register handlers. /// @@ -296,1086 +168,5 @@ namespace OpenSim.Framework.Capabilities } } } - - /// - /// Construct a client response detailing all the capabilities this server can provide. - /// - /// - /// - /// - /// HTTP request header object - /// HTTP response header object - /// - public string CapsRequest(string request, string path, string param, - OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName); - - if (!m_Scene.CheckClient(m_agentID, httpRequest.RemoteIPEndPoint)) - { - m_log.DebugFormat("[CAPS]: Unauthorized CAPS client"); - return string.Empty; - } - - string result = LLSDHelpers.SerialiseLLSDReply(m_capsHandlers.CapsDetails); - - //m_log.DebugFormat("[CAPS] CapsRequest {0}", result); - - return result; - } - - // FIXME: these all should probably go into the respective region - // modules - - /// - /// Processes a fetch inventory request and sends the reply - - /// - /// - /// - /// - /// - // Request is like: - // - // folders - // - // - // fetch-folders1fetch-items1folder-id8e1e3a30-b9bf-11dc-95ff-0800200c9a66owner-id11111111-1111-0000-0000-000100bba000sort-order1 - // - // - // - // - // - // multiple fetch-folder maps are allowed within the larger folders map. - public string FetchInventoryRequest(string request, string path, string param) - { - // string unmodifiedRequest = request.ToString(); - - //m_log.DebugFormat("[AGENT INVENTORY]: Received CAPS fetch inventory request {0}", unmodifiedRequest); - m_log.Debug("[CAPS]: Inventory Request in region: " + m_regionName); - - Hashtable hash = new Hashtable(); - try - { - hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); - } - catch (LLSD.LLSDParseException pe) - { - m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message); - m_log.Error("Request: " + request.ToString()); - } - - ArrayList foldersrequested = (ArrayList)hash["folders"]; - - string response = ""; - - for (int i = 0; i < foldersrequested.Count; i++) - { - string inventoryitemstr = ""; - Hashtable inventoryhash = (Hashtable)foldersrequested[i]; - - LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); - LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest); - LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest); - - inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); - inventoryitemstr = inventoryitemstr.Replace("folders", ""); - inventoryitemstr = inventoryitemstr.Replace("", ""); - - response += inventoryitemstr; - } - - if (response.Length == 0) - { - // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants. - // Therefore, I'm concluding that the client only has so many threads available to do requests - // and when a thread stalls.. is stays stalled. - // Therefore we need to return something valid - response = "folders"; - } - else - { - response = "folders" + response + ""; - } - - //m_log.DebugFormat("[AGENT INVENTORY]: Replying to CAPS fetch inventory request with following xml"); - //m_log.Debug(Util.GetFormattedXml(response)); - - return response; - } - - public string FetchInventoryDescendentsRequest(string request, string path, string param,OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - // nasty temporary hack here, the linden client falsely - // identifies the uuid 00000000-0000-0000-0000-000000000000 - // as a string which breaks us - // - // correctly mark it as a uuid - // - request = request.Replace("00000000-0000-0000-0000-000000000000", "00000000-0000-0000-0000-000000000000"); - - // another hack 1 results in a - // System.ArgumentException: Object type System.Int32 cannot - // be converted to target type: System.Boolean - // - request = request.Replace("fetch_folders0", "fetch_folders0"); - request = request.Replace("fetch_folders1", "fetch_folders1"); - - Hashtable hash = new Hashtable(); - try - { - hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); - } - catch (LLSD.LLSDParseException pe) - { - m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message); - m_log.Error("Request: " + request.ToString()); - } - - ArrayList foldersrequested = (ArrayList)hash["folders"]; - - string response = ""; - lock (m_fetchLock) - { - for (int i = 0; i < foldersrequested.Count; i++) - { - string inventoryitemstr = ""; - Hashtable inventoryhash = (Hashtable)foldersrequested[i]; - - LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); - - try{ - LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest); - } - catch(Exception e) - { - m_log.Debug("[CAPS]: caught exception doing OSD deserialize" + e); - } - LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest); - - inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); - inventoryitemstr = inventoryitemstr.Replace("folders", ""); - inventoryitemstr = inventoryitemstr.Replace("", ""); - - response += inventoryitemstr; - } - - - if (response.Length == 0) - { - // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants. - // Therefore, I'm concluding that the client only has so many threads available to do requests - // and when a thread stalls.. is stays stalled. - // Therefore we need to return something valid - response = "folders"; - } - else - { - response = "folders" + response + ""; - } - - //m_log.DebugFormat("[CAPS]: Replying to CAPS fetch inventory request with following xml"); - //m_log.Debug("[CAPS] "+response); - - } - return response; - } - - - - /// - /// Construct an LLSD reply packet to a CAPS inventory request - /// - /// - /// - private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch) - { - LLSDInventoryDescendents reply = new LLSDInventoryDescendents(); - LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents(); - contents.agent_id = m_agentID; - contents.owner_id = invFetch.owner_id; - contents.folder_id = invFetch.folder_id; - - reply.folders.Array.Add(contents); - InventoryCollection inv = new InventoryCollection(); - inv.Folders = new List(); - inv.Items = new List(); - int version = 0; - if (CAPSFetchInventoryDescendents != null) - { - inv = CAPSFetchInventoryDescendents(m_agentID, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version); - } - - if (inv.Folders != null) - { - foreach (InventoryFolderBase invFolder in inv.Folders) - { - contents.categories.Array.Add(ConvertInventoryFolder(invFolder)); - } - } - - if (inv.Items != null) - { - foreach (InventoryItemBase invItem in inv.Items) - { - contents.items.Array.Add(ConvertInventoryItem(invItem)); - } - } - - contents.descendents = contents.items.Array.Count + contents.categories.Array.Count; - contents.version = version; - - return reply; - } - - /// - /// Convert an internal inventory folder object into an LLSD object. - /// - /// - /// - private LLSDInventoryFolder ConvertInventoryFolder(InventoryFolderBase invFolder) - { - LLSDInventoryFolder llsdFolder = new LLSDInventoryFolder(); - llsdFolder.folder_id = invFolder.ID; - llsdFolder.parent_id = invFolder.ParentID; - llsdFolder.name = invFolder.Name; - if (invFolder.Type < 0 || invFolder.Type >= TaskInventoryItem.Types.Length) - llsdFolder.type = "-1"; - else - llsdFolder.type = TaskInventoryItem.Types[invFolder.Type]; - llsdFolder.preferred_type = "-1"; - - return llsdFolder; - } - - /// - /// Convert an internal inventory item object into an LLSD object. - /// - /// - /// - private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem) - { - LLSDInventoryItem llsdItem = new LLSDInventoryItem(); - llsdItem.asset_id = invItem.AssetID; - llsdItem.created_at = invItem.CreationDate; - llsdItem.desc = invItem.Description; - llsdItem.flags = (int)invItem.Flags; - llsdItem.item_id = invItem.ID; - llsdItem.name = invItem.Name; - llsdItem.parent_id = invItem.Folder; - try - { - // TODO reevaluate after upgrade to libomv >= r2566. Probably should use UtilsConversions. - llsdItem.type = TaskInventoryItem.Types[invItem.AssetType]; - llsdItem.inv_type = TaskInventoryItem.InvTypes[invItem.InvType]; - } - catch (Exception e) - { - m_log.Error("[CAPS]: Problem setting asset/inventory type while converting inventory item " + invItem.Name + " to LLSD:", e); - } - llsdItem.permissions = new LLSDPermissions(); - llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid; - llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions; - llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions; - llsdItem.permissions.group_id = invItem.GroupID; - llsdItem.permissions.group_mask = (int)invItem.GroupPermissions; - llsdItem.permissions.is_owner_group = invItem.GroupOwned; - llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions; - llsdItem.permissions.owner_id = m_agentID; - llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions; - llsdItem.sale_info = new LLSDSaleInfo(); - llsdItem.sale_info.sale_price = invItem.SalePrice; - switch (invItem.SaleType) - { - default: - llsdItem.sale_info.sale_type = "not"; - break; - case 1: - llsdItem.sale_info.sale_type = "original"; - break; - case 2: - llsdItem.sale_info.sale_type = "copy"; - break; - case 3: - llsdItem.sale_info.sale_type = "contents"; - break; - } - - return llsdItem; - } - - /// - /// - /// - /// - /// - public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq) - { - m_log.Debug("[CAPS]: MapLayer Request in region: " + m_regionName); - LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); - mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); - return mapResponse; - } - - /// - /// - /// - /// - protected static OSDMapLayer GetOSDMapLayerResponse() - { - OSDMapLayer mapLayer = new OSDMapLayer(); - mapLayer.Right = 5000; - mapLayer.Top = 5000; - mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006"); - - return mapLayer; - } - - /// - /// - /// - /// - /// - /// - /// - public string RequestTexture(string request, string path, string param) - { - m_log.Debug("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 - - /// - /// Called by the script task update handler. Provides a URL to which the client can upload a new asset. - /// - /// - /// - /// - /// HTTP request header object - /// HTTP response header object - /// - public string ScriptTaskInventory(string request, string path, string param, - OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - try - { - m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName); - //m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param); - - Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(Utils.StringToBytes(request)); - LLSDTaskScriptUpdate llsdUpdateRequest = new LLSDTaskScriptUpdate(); - LLSDHelpers.DeserialiseOSDMap(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 protocol = "http://"; - - if (m_httpListener.UseSSL) - protocol = "https://"; - - string uploaderURL = protocol + 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; - } - - public string UploadBakedTexture(string request, string path, - string param, OSHttpRequest httpRequest, - OSHttpResponse httpResponse) - { - try - { -// m_log.Debug("[CAPS]: UploadBakedTexture Request in region: " + -// m_regionName); - - string capsBase = "/CAPS/" + m_capsObjectPath; - string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); - - BakedTextureUploader uploader = - new BakedTextureUploader(capsBase + uploaderPath, - m_httpListener); - uploader.OnUpLoad += BakedTextureUploaded; - - m_httpListener.AddStreamHandler( - new BinaryStreamHandler("POST", capsBase + uploaderPath, - uploader.uploaderCaps)); - - string protocol = "http://"; - - if (m_httpListener.UseSSL) - protocol = "https://"; - - string uploaderURL = protocol + m_httpListenerHostName + ":" + - m_httpListenPort.ToString() + capsBase + uploaderPath; - - LLSDAssetUploadResponse uploadResponse = - new LLSDAssetUploadResponse(); - uploadResponse.uploader = uploaderURL; - uploadResponse.state = "upload"; - - return LLSDHelpers.SerialiseLLSDReply(uploadResponse); - } - catch (Exception e) - { - m_log.Error("[CAPS]: " + e.ToString()); - } - - return null; - } - - /// - /// Called by the notecard update handler. Provides a URL to which the client can upload a new asset. - /// - /// - /// - /// - /// - public string NoteCardAgentInventory(string request, string path, string param, - OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - //m_log.Debug("[CAPS]: NoteCardAgentInventory Request in region: " + m_regionName + "\n" + request); - //m_log.Debug("[CAPS]: NoteCardAgentInventory Request is: " + request); - - //OpenMetaverse.StructuredData.OSDMap hash = (OpenMetaverse.StructuredData.OSDMap)OpenMetaverse.StructuredData.LLSDParser.DeserializeBinary(Utils.StringToBytes(request)); - Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(Utils.StringToBytes(request)); - LLSDItemUpdate llsdRequest = new LLSDItemUpdate(); - LLSDHelpers.DeserialiseOSDMap(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 protocol = "http://"; - - if (m_httpListener.UseSSL) - protocol = "https://"; - - string uploaderURL = protocol + 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) - { - //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString()); - //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type); - - if (llsdRequest.asset_type == "texture" || - llsdRequest.asset_type == "animation" || - llsdRequest.asset_type == "sound") - { - IClientAPI client = null; - IScene scene = null; - if (GetClient != null) - { - client = GetClient(m_agentID); - scene = client.Scene; - - IMoneyModule mm = scene.RequestModuleInterface(); - - if (mm != null) - { - if (!mm.UploadCovered(client, mm.UploadCharge)) - { - if (client != null) - client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); - - LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse(); - errorResponse.uploader = ""; - errorResponse.state = "error"; - return errorResponse; - } - } - } - } - - - string assetName = llsdRequest.name; - string assetDes = llsdRequest.description; - string capsBase = "/CAPS/" + m_capsObjectPath; - UUID newAsset = UUID.Random(); - UUID newInvItem = UUID.Random(); - UUID parentFolder = llsdRequest.folder_id; - string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); - - 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 protocol = "http://"; - - if (m_httpListener.UseSSL) - protocol = "https://"; - - string uploaderURL = protocol + 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, UUID assetID, - UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType, - string assetType) - { - sbyte assType = 0; - sbyte inType = 0; - - if (inventoryType == "sound") - { - inType = 1; - assType = 1; - } - else if (inventoryType == "animation") - { - inType = 19; - assType = 20; - } - else if (inventoryType == "wearable") - { - inType = 18; - switch (assetType) - { - case "bodypart": - assType = 13; - break; - case "clothing": - assType = 5; - break; - } - } - - AssetBase asset; - asset = new AssetBase(assetID, assetName, assType, m_agentID.ToString()); - asset.Data = data; - if (AddNewAsset != null) - AddNewAsset(asset); - else if (m_assetCache != null) - m_assetCache.Store(asset); - - InventoryItemBase item = new InventoryItemBase(); - item.Owner = m_agentID; - item.CreatorId = m_agentID.ToString(); - item.CreatorData = String.Empty; - item.ID = inventoryItem; - item.AssetID = asset.FullID; - item.Description = assetDescription; - item.Name = assetName; - item.AssetType = assType; - item.InvType = inType; - item.Folder = parentFolder; - item.CurrentPermissions = (uint)PermissionMask.All; - item.BasePermissions = (uint)PermissionMask.All; - item.EveryOnePermissions = 0; - item.NextPermissions = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer); - item.CreationDate = Util.UnixTimeSinceEpoch(); - - if (AddNewInventoryItem != null) - { - AddNewInventoryItem(m_agentID, item); - } - } - - public void BakedTextureUploaded(UUID assetID, byte[] data) - { -// m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString()); - - AssetBase asset; - asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_agentID.ToString()); - asset.Data = data; - asset.Temporary = true; - asset.Local = ! m_persistBakedTextures; // Local assets aren't persisted, non-local are - m_assetCache.Store(asset); - } - - /// - /// Called when new asset data for an agent inventory item update has been uploaded. - /// - /// Item to update - /// New asset data - /// - public UUID ItemUpdated(UUID itemID, byte[] data) - { - if (ItemUpdatedCall != null) - { - return ItemUpdatedCall(m_agentID, itemID, data); - } - - return UUID.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(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors) - { - if (TaskScriptUpdatedCall != null) - { - ArrayList e = TaskScriptUpdatedCall(m_agentID, itemID, primID, isScriptRunning, data); - foreach (Object item in e) - errors.Add(item); - } - } - - public class AssetUploader - { - public event UpLoadedAsset OnUpLoad; - private UpLoadedAsset handlerUpLoad = null; - - private string uploaderPath = String.Empty; - private UUID newAssetID; - private UUID inventoryItemID; - private UUID parentFolder; - private IHttpServer 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, UUID assetID, UUID inventoryItem, - UUID parentFolderID, string invType, string assetType, string path, - IHttpServer 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) - { - UUID 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); - - // TODO: probably make this a better set of extensions here - string extension = ".jp2"; - if (m_invType != "image") - { - extension = ".dat"; - } - - if (m_dumpAssetsToFile) - { - SaveAssetToFile(m_assetName + extension, data); - } - handlerUpLoad = OnUpLoad; - if (handlerUpLoad != null) - { - handlerUpLoad(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 static void SaveAssetToFile(string filename, byte[] data) - { - string assetPath = "UserAssets"; - if (!Directory.Exists(assetPath)) - { - Directory.CreateDirectory(assetPath); - } - FileStream fs = File.Create(Path.Combine(assetPath, Util.safeFileName(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 handlerUpdateItem = null; - - private string uploaderPath = String.Empty; - private UUID inventoryItemID; - private IHttpServer httpListener; - private bool m_dumpAssetToFile; - - public ItemUpdater(UUID inventoryItem, string path, IHttpServer httpServer, bool dumpAssetToFile) - { - m_dumpAssetToFile = dumpAssetToFile; - - inventoryItemID = inventoryItem; - uploaderPath = path; - httpListener = httpServer; - } - - /// - /// - /// - /// - /// - /// - /// - public string uploaderCaps(byte[] data, string path, string param) - { - UUID inv = inventoryItemID; - string res = String.Empty; - LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); - UUID assetID = UUID.Zero; - handlerUpdateItem = OnUpLoad; - if (handlerUpdateItem != null) - { - assetID = handlerUpdateItem(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 static 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 handlerUpdateTaskScript = null; - - private string uploaderPath = String.Empty; - private UUID inventoryItemID; - private UUID primID; - private bool isScriptRunning; - private IHttpServer httpListener; - private bool m_dumpAssetToFile; - - public TaskInventoryScriptUpdater(UUID inventoryItemID, UUID primID, int isScriptRunning, - string path, IHttpServer 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; - LLSDTaskScriptUploadComplete uploadComplete = new LLSDTaskScriptUploadComplete(); - - ArrayList errors = new ArrayList(); - handlerUpdateTaskScript = OnUpLoad; - if (handlerUpdateTaskScript != null) - { - handlerUpdateTaskScript(inventoryItemID, primID, isScriptRunning, data, ref errors); - } - - uploadComplete.new_asset = inventoryItemID; - uploadComplete.compiled = errors.Count > 0 ? false : true; - uploadComplete.state = "complete"; - uploadComplete.errors = new OSDArray(); - uploadComplete.errors.Array = errors; - - 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 static 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 class BakedTextureUploader - { - public event UploadedBakedTexture OnUpLoad; - private UploadedBakedTexture handlerUpLoad = null; - - private string uploaderPath = String.Empty; - private UUID newAssetID; - private IHttpServer httpListener; - - public BakedTextureUploader(string path, IHttpServer httpServer) - { - newAssetID = UUID.Random(); - uploaderPath = path; - httpListener = httpServer; -// m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID); - } - - /// - /// - /// - /// - /// - /// - /// - public string uploaderCaps(byte[] data, string path, string param) - { - handlerUpLoad = OnUpLoad; - if (handlerUpLoad != null) - { - Util.FireAndForget(delegate(object o) { handlerUpLoad(newAssetID, data); }); - } - - string res = String.Empty; - LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); - uploadComplete.new_asset = newAssetID.ToString(); - uploadComplete.new_inventory_item = UUID.Zero; - uploadComplete.state = "complete"; - - res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); - - httpListener.RemoveStreamHandler("POST", uploaderPath); - -// m_log.InfoFormat("[CAPS] baked texture upload completed for {0}",newAssetID); - - return res; - } - } } } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs new file mode 100644 index 0000000000..7a7964e131 --- /dev/null +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -0,0 +1,1210 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Reflection; + +using OpenMetaverse; +using Nini.Config; +using log4net; + +using OpenSim.Framework; +using OpenSim.Framework.Capabilities; +using OpenSim.Region.Framework; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Services.Interfaces; + +using Caps = OpenSim.Framework.Capabilities.Caps; + +namespace OpenSim.Region.ClientStack.Linden +{ + public delegate void UpLoadedAsset( + string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder, + byte[] data, string inventoryType, string assetType); + + public delegate void UploadedBakedTexture(UUID assetID, byte[] data); + + public delegate UUID UpdateItem(UUID itemID, byte[] data); + + public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors); + + public delegate void NewInventoryItem(UUID userID, InventoryItemBase item); + + public delegate void NewAsset(AssetBase asset); + + public delegate UUID ItemUpdatedCallback(UUID userID, UUID itemID, byte[] data); + + public delegate ArrayList TaskScriptUpdatedCallback(UUID userID, UUID itemID, UUID primID, + bool isScriptRunning, byte[] data); + + public delegate InventoryCollection FetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID, + bool fetchFolders, bool fetchItems, int sortOrder, out int version); + + /// + /// XXX Probably not a particularly nice way of allow us to get the scene presence from the scene (chiefly so that + /// we can popup a message on the user's client if the inventory service has permanently failed). But I didn't want + /// to just pass the whole Scene into CAPS. + /// + public delegate IClientAPI GetClientDelegate(UUID agentID); + + public class BunchOfCaps + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Scene m_Scene; + private Caps m_HostCapsObj; + + private static readonly string m_requestPath = "0000/"; + // private static readonly string m_mapLayerPath = "0001/"; + private static readonly string m_newInventory = "0002/"; + //private static readonly string m_requestTexture = "0003/"; + private static readonly string m_notecardUpdatePath = "0004/"; + private static readonly string m_notecardTaskUpdatePath = "0005/"; + // private static readonly string m_fetchInventoryPath = "0006/"; + // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule. + private static readonly string m_uploadBakedTexturePath = "0010/";// This is in the LandManagementModule. + + + // 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 NewAsset AddNewAsset = null; + public ItemUpdatedCallback ItemUpdatedCall = null; + public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null; + public FetchInventoryDescendentsCAPS CAPSFetchInventoryDescendents = null; + public GetClientDelegate GetClient = null; + + private bool m_persistBakedTextures = false; + private IAssetService m_assetCache; + private bool m_dumpAssetsToFile; + private string m_regionName; + private object m_fetchLock = new Object(); + + public BunchOfCaps(Scene scene, Caps caps) + { + m_Scene = scene; + m_HostCapsObj = caps; + IConfigSource config = m_Scene.Config; + if (config != null) + { + IConfig sconfig = config.Configs["Startup"]; + if (sconfig != null) + m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures); + } + + RegisterHandlers(); + + AddNewInventoryItem = m_Scene.AddUploadedInventoryItem; + ItemUpdatedCall = m_Scene.CapsUpdateInventoryItemAsset; + TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset; + CAPSFetchInventoryDescendents = m_Scene.HandleFetchInventoryDescendentsCAPS; + GetClient = m_Scene.SceneContents.GetControllingClient; + + } + + /// + /// Register a bunch of CAPS http service handlers + /// + public void RegisterHandlers() + { + m_HostCapsObj.DeregisterHandlers(); + + string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; + + RegisterRegionServiceHandlers(capsBase); + RegisterInventoryServiceHandlers(capsBase); + } + + public void RegisterRegionServiceHandlers(string capsBase) + { + try + { + // the root of all evil + m_HostCapsObj.RegisterHandler("SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest)); + m_log.DebugFormat( + "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID); + + //m_capsHandlers["MapLayer"] = + // new LLSDStreamhandler("POST", + // capsBase + m_mapLayerPath, + // GetMapLayer); + IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory); + m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req); + m_HostCapsObj.RegisterHandler("UpdateScriptTask", req); + m_HostCapsObj.RegisterHandler("UploadBakedTexture", new RestStreamHandler("POST", capsBase + m_uploadBakedTexturePath, UploadBakedTexture)); + + } + catch (Exception e) + { + m_log.Error("[CAPS]: " + e.ToString()); + } + } + + public void RegisterInventoryServiceHandlers(string capsBase) + { + try + { + // I don't think this one works... + m_HostCapsObj.RegisterHandler("NewFileAgentInventory", new LLSDStreamhandler("POST", + capsBase + m_newInventory, + NewAgentInventoryRequest)); + IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory); + m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req); + m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req); + m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req); + + // As of RC 1.22.9 of the Linden client this is + // supported + + //m_capsHandlers["WebFetchInventoryDescendents"] =new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryDescendentsRequest); + + // justincc: I've disabled the CAPS service for now to fix problems with selecting textures, and + // subsequent inventory breakage, in the edit object pane (such as mantis 1085). This requires + // enhancements (probably filling out the folder part of the LLSD reply) to our CAPS service, + // but when I went on the Linden grid, the + // simulators I visited (version 1.21) were, surprisingly, no longer supplying this capability. Instead, + // the 1.19.1.4 client appeared to be happily flowing inventory data over UDP + // + // This is very probably just a temporary measure - once the CAPS service appears again on the Linden grid + // we will be + // able to get the data we need to implement the necessary part of the protocol to fix the issue above. + // m_capsHandlers["FetchInventoryDescendents"] = + // new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryRequest); + + // m_capsHandlers["FetchInventoryDescendents"] = + // new LLSDStreamhandler("POST", + // capsBase + m_fetchInventory, + // FetchInventory)); + // m_capsHandlers["RequestTextureDownload"] = new RestStreamHandler("POST", + // capsBase + m_requestTexture, + // RequestTexture); + } + catch (Exception e) + { + m_log.Error("[CAPS]: " + e.ToString()); + } + } + + /// + /// Construct a client response detailing all the capabilities this server can provide. + /// + /// + /// + /// + /// HTTP request header object + /// HTTP response header object + /// + public string SeedCapRequest(string request, string path, string param, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName); + + if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint)) + { + m_log.DebugFormat("[CAPS]: Unauthorized CAPS client"); + return string.Empty; + } + + // WARNING: Add the external too + string result = LLSDHelpers.SerialiseLLSDReply(m_HostCapsObj.CapsHandlers.CapsDetails); + + //m_log.DebugFormat("[CAPS] CapsRequest {0}", result); + + return result; + } + + /// + /// Called by the script task update handler. Provides a URL to which the client can upload a new asset. + /// + /// + /// + /// + /// HTTP request header object + /// HTTP response header object + /// + public string ScriptTaskInventory(string request, string path, string param, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + try + { + m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName); + //m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param); + + Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); + LLSDTaskScriptUpdate llsdUpdateRequest = new LLSDTaskScriptUpdate(); + LLSDHelpers.DeserialiseOSDMap(hash, llsdUpdateRequest); + + string capsBase = "/CAPS/" + m_HostCapsObj.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_HostCapsObj.HttpListener, + m_dumpAssetsToFile); + uploader.OnUpLoad += TaskScriptUpdated; + + m_HostCapsObj.HttpListener.AddStreamHandler(new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); + + string protocol = "http://"; + + if (m_HostCapsObj.SSLCaps) + protocol = "https://"; + + string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.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; + } + + /// + /// 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(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors) + { + if (TaskScriptUpdatedCall != null) + { + ArrayList e = TaskScriptUpdatedCall(m_HostCapsObj.AgentID, itemID, primID, isScriptRunning, data); + foreach (Object item in e) + errors.Add(item); + } + } + + public string UploadBakedTexture(string request, string path, + string param, OSHttpRequest httpRequest, + OSHttpResponse httpResponse) + { + try + { + // m_log.Debug("[CAPS]: UploadBakedTexture Request in region: " + + // m_regionName); + + string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; + string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); + + BakedTextureUploader uploader = + new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener); + uploader.OnUpLoad += BakedTextureUploaded; + + m_HostCapsObj.HttpListener.AddStreamHandler( + new BinaryStreamHandler("POST", capsBase + uploaderPath, + uploader.uploaderCaps)); + + string protocol = "http://"; + + if (m_HostCapsObj.SSLCaps) + protocol = "https://"; + + string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + + m_HostCapsObj.Port.ToString() + capsBase + uploaderPath; + + LLSDAssetUploadResponse uploadResponse = + new LLSDAssetUploadResponse(); + uploadResponse.uploader = uploaderURL; + uploadResponse.state = "upload"; + + return LLSDHelpers.SerialiseLLSDReply(uploadResponse); + } + catch (Exception e) + { + m_log.Error("[CAPS]: " + e.ToString()); + } + + return null; + } + + public void BakedTextureUploaded(UUID assetID, byte[] data) + { + // m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString()); + + AssetBase asset; + asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString()); + asset.Data = data; + asset.Temporary = true; + asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are + m_assetCache.Store(asset); + } + + /// + /// Called when new asset data for an agent inventory item update has been uploaded. + /// + /// Item to update + /// New asset data + /// + public UUID ItemUpdated(UUID itemID, byte[] data) + { + if (ItemUpdatedCall != null) + { + return ItemUpdatedCall(m_HostCapsObj.AgentID, itemID, data); + } + + return UUID.Zero; + } + + /// + /// + /// + /// + /// + public LLSDAssetUploadResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest) + { + //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString()); + //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type); + + if (llsdRequest.asset_type == "texture" || + llsdRequest.asset_type == "animation" || + llsdRequest.asset_type == "sound") + { + IClientAPI client = null; + IScene scene = null; + if (GetClient != null) + { + client = GetClient(m_HostCapsObj.AgentID); + scene = client.Scene; + + IMoneyModule mm = scene.RequestModuleInterface(); + + if (mm != null) + { + if (!mm.UploadCovered(client, mm.UploadCharge)) + { + if (client != null) + client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); + + LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse(); + errorResponse.uploader = ""; + errorResponse.state = "error"; + return errorResponse; + } + } + } + } + + string assetName = llsdRequest.name; + string assetDes = llsdRequest.description; + string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; + UUID newAsset = UUID.Random(); + UUID newInvItem = UUID.Random(); + UUID parentFolder = llsdRequest.folder_id; + string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); + + AssetUploader uploader = + new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, + llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile); + m_HostCapsObj.HttpListener.AddStreamHandler( + new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); + + string protocol = "http://"; + + if (m_HostCapsObj.SSLCaps) + protocol = "https://"; + + string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.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, UUID assetID, + UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType, + string assetType) + { + sbyte assType = 0; + sbyte inType = 0; + + if (inventoryType == "sound") + { + inType = 1; + assType = 1; + } + else if (inventoryType == "animation") + { + inType = 19; + assType = 20; + } + else if (inventoryType == "wearable") + { + inType = 18; + switch (assetType) + { + case "bodypart": + assType = 13; + break; + case "clothing": + assType = 5; + break; + } + } + + AssetBase asset; + asset = new AssetBase(assetID, assetName, assType, m_HostCapsObj.AgentID.ToString()); + asset.Data = data; + if (AddNewAsset != null) + AddNewAsset(asset); + else if (m_assetCache != null) + m_assetCache.Store(asset); + + InventoryItemBase item = new InventoryItemBase(); + item.Owner = m_HostCapsObj.AgentID; + item.CreatorId = m_HostCapsObj.AgentID.ToString(); + item.CreatorData = String.Empty; + item.ID = inventoryItem; + item.AssetID = asset.FullID; + item.Description = assetDescription; + item.Name = assetName; + item.AssetType = assType; + item.InvType = inType; + item.Folder = parentFolder; + item.CurrentPermissions = (uint)PermissionMask.All; + item.BasePermissions = (uint)PermissionMask.All; + item.EveryOnePermissions = 0; + item.NextPermissions = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer); + item.CreationDate = Util.UnixTimeSinceEpoch(); + + if (AddNewInventoryItem != null) + { + AddNewInventoryItem(m_HostCapsObj.AgentID, item); + } + } + + /// + /// Processes a fetch inventory request and sends the reply + + /// + /// + /// + /// + /// + // Request is like: + // + // folders + // + // + // fetch-folders1fetch-items1folder-id8e1e3a30-b9bf-11dc-95ff-0800200c9a66owner-id11111111-1111-0000-0000-000100bba000sort-order1 + // + // + // + // + // + // multiple fetch-folder maps are allowed within the larger folders map. + public string FetchInventoryRequest(string request, string path, string param) + { + // string unmodifiedRequest = request.ToString(); + + //m_log.DebugFormat("[AGENT INVENTORY]: Received CAPS fetch inventory request {0}", unmodifiedRequest); + m_log.Debug("[CAPS]: Inventory Request in region: " + m_regionName); + + Hashtable hash = new Hashtable(); + try + { + hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); + } + catch (LLSD.LLSDParseException pe) + { + m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message); + m_log.Error("Request: " + request.ToString()); + } + + ArrayList foldersrequested = (ArrayList)hash["folders"]; + + string response = ""; + + for (int i = 0; i < foldersrequested.Count; i++) + { + string inventoryitemstr = ""; + Hashtable inventoryhash = (Hashtable)foldersrequested[i]; + + LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); + LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest); + LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest); + + inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); + inventoryitemstr = inventoryitemstr.Replace("folders", ""); + inventoryitemstr = inventoryitemstr.Replace("", ""); + + response += inventoryitemstr; + } + + if (response.Length == 0) + { + // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants. + // Therefore, I'm concluding that the client only has so many threads available to do requests + // and when a thread stalls.. is stays stalled. + // Therefore we need to return something valid + response = "folders"; + } + else + { + response = "folders" + response + ""; + } + + //m_log.DebugFormat("[AGENT INVENTORY]: Replying to CAPS fetch inventory request with following xml"); + //m_log.Debug(Util.GetFormattedXml(response)); + + return response; + } + + public string FetchInventoryDescendentsRequest(string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + // nasty temporary hack here, the linden client falsely + // identifies the uuid 00000000-0000-0000-0000-000000000000 + // as a string which breaks us + // + // correctly mark it as a uuid + // + request = request.Replace("00000000-0000-0000-0000-000000000000", "00000000-0000-0000-0000-000000000000"); + + // another hack 1 results in a + // System.ArgumentException: Object type System.Int32 cannot + // be converted to target type: System.Boolean + // + request = request.Replace("fetch_folders0", "fetch_folders0"); + request = request.Replace("fetch_folders1", "fetch_folders1"); + + Hashtable hash = new Hashtable(); + try + { + hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); + } + catch (LLSD.LLSDParseException pe) + { + m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message); + m_log.Error("Request: " + request.ToString()); + } + + ArrayList foldersrequested = (ArrayList)hash["folders"]; + + string response = ""; + lock (m_fetchLock) + { + for (int i = 0; i < foldersrequested.Count; i++) + { + string inventoryitemstr = ""; + Hashtable inventoryhash = (Hashtable)foldersrequested[i]; + + LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); + + try + { + LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest); + } + catch (Exception e) + { + m_log.Debug("[CAPS]: caught exception doing OSD deserialize" + e); + } + LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest); + + inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); + inventoryitemstr = inventoryitemstr.Replace("folders", ""); + inventoryitemstr = inventoryitemstr.Replace("", ""); + + response += inventoryitemstr; + } + + + if (response.Length == 0) + { + // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants. + // Therefore, I'm concluding that the client only has so many threads available to do requests + // and when a thread stalls.. is stays stalled. + // Therefore we need to return something valid + response = "folders"; + } + else + { + response = "folders" + response + ""; + } + + //m_log.DebugFormat("[CAPS]: Replying to CAPS fetch inventory request with following xml"); + //m_log.Debug("[CAPS] "+response); + + } + return response; + } + + + + /// + /// Construct an LLSD reply packet to a CAPS inventory request + /// + /// + /// + private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch) + { + LLSDInventoryDescendents reply = new LLSDInventoryDescendents(); + LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents(); + contents.agent_id = m_HostCapsObj.AgentID; + contents.owner_id = invFetch.owner_id; + contents.folder_id = invFetch.folder_id; + + reply.folders.Array.Add(contents); + InventoryCollection inv = new InventoryCollection(); + inv.Folders = new List(); + inv.Items = new List(); + int version = 0; + if (CAPSFetchInventoryDescendents != null) + { + inv = CAPSFetchInventoryDescendents(m_HostCapsObj.AgentID, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version); + } + + if (inv.Folders != null) + { + foreach (InventoryFolderBase invFolder in inv.Folders) + { + contents.categories.Array.Add(ConvertInventoryFolder(invFolder)); + } + } + + if (inv.Items != null) + { + foreach (InventoryItemBase invItem in inv.Items) + { + contents.items.Array.Add(ConvertInventoryItem(invItem)); + } + } + + contents.descendents = contents.items.Array.Count + contents.categories.Array.Count; + contents.version = version; + + return reply; + } + + /// + /// Convert an internal inventory folder object into an LLSD object. + /// + /// + /// + private LLSDInventoryFolder ConvertInventoryFolder(InventoryFolderBase invFolder) + { + LLSDInventoryFolder llsdFolder = new LLSDInventoryFolder(); + llsdFolder.folder_id = invFolder.ID; + llsdFolder.parent_id = invFolder.ParentID; + llsdFolder.name = invFolder.Name; + if (invFolder.Type < 0 || invFolder.Type >= TaskInventoryItem.Types.Length) + llsdFolder.type = "-1"; + else + llsdFolder.type = TaskInventoryItem.Types[invFolder.Type]; + llsdFolder.preferred_type = "-1"; + + return llsdFolder; + } + + /// + /// Convert an internal inventory item object into an LLSD object. + /// + /// + /// + private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem) + { + LLSDInventoryItem llsdItem = new LLSDInventoryItem(); + llsdItem.asset_id = invItem.AssetID; + llsdItem.created_at = invItem.CreationDate; + llsdItem.desc = invItem.Description; + llsdItem.flags = (int)invItem.Flags; + llsdItem.item_id = invItem.ID; + llsdItem.name = invItem.Name; + llsdItem.parent_id = invItem.Folder; + try + { + // TODO reevaluate after upgrade to libomv >= r2566. Probably should use UtilsConversions. + llsdItem.type = TaskInventoryItem.Types[invItem.AssetType]; + llsdItem.inv_type = TaskInventoryItem.InvTypes[invItem.InvType]; + } + catch (Exception e) + { + m_log.Error("[CAPS]: Problem setting asset/inventory type while converting inventory item " + invItem.Name + " to LLSD:", e); + } + llsdItem.permissions = new LLSDPermissions(); + llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid; + llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions; + llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions; + llsdItem.permissions.group_id = invItem.GroupID; + llsdItem.permissions.group_mask = (int)invItem.GroupPermissions; + llsdItem.permissions.is_owner_group = invItem.GroupOwned; + llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions; + llsdItem.permissions.owner_id = m_HostCapsObj.AgentID; + llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions; + llsdItem.sale_info = new LLSDSaleInfo(); + llsdItem.sale_info.sale_price = invItem.SalePrice; + switch (invItem.SaleType) + { + default: + llsdItem.sale_info.sale_type = "not"; + break; + case 1: + llsdItem.sale_info.sale_type = "original"; + break; + case 2: + llsdItem.sale_info.sale_type = "copy"; + break; + case 3: + llsdItem.sale_info.sale_type = "contents"; + break; + } + + return llsdItem; + } + + /// + /// + /// + /// + /// + public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq) + { + m_log.Debug("[CAPS]: MapLayer Request in region: " + m_regionName); + LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); + mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); + return mapResponse; + } + + /// + /// + /// + /// + protected static OSDMapLayer GetOSDMapLayerResponse() + { + OSDMapLayer mapLayer = new OSDMapLayer(); + mapLayer.Right = 5000; + mapLayer.Top = 5000; + mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006"); + + return mapLayer; + } + + /// + /// + /// + /// + /// + /// + /// + public string RequestTexture(string request, string path, string param) + { + m_log.Debug("texture request " + request); + // Needs implementing (added to remove compiler warning) + return String.Empty; + } + + + /// + /// Called by the notecard update handler. Provides a URL to which the client can upload a new asset. + /// + /// + /// + /// + /// + public string NoteCardAgentInventory(string request, string path, string param, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + //m_log.Debug("[CAPS]: NoteCardAgentInventory Request in region: " + m_regionName + "\n" + request); + //m_log.Debug("[CAPS]: NoteCardAgentInventory Request is: " + request); + + //OpenMetaverse.StructuredData.OSDMap hash = (OpenMetaverse.StructuredData.OSDMap)OpenMetaverse.StructuredData.LLSDParser.DeserializeBinary(Utils.StringToBytes(request)); + Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); + LLSDItemUpdate llsdRequest = new LLSDItemUpdate(); + LLSDHelpers.DeserialiseOSDMap(hash, llsdRequest); + + string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; + string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); + + ItemUpdater uploader = + new ItemUpdater(llsdRequest.item_id, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile); + uploader.OnUpLoad += ItemUpdated; + + m_HostCapsObj.HttpListener.AddStreamHandler( + new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); + + string protocol = "http://"; + + if (m_HostCapsObj.SSLCaps) + protocol = "https://"; + + string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.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 class AssetUploader + { + public event UpLoadedAsset OnUpLoad; + private UpLoadedAsset handlerUpLoad = null; + + private string uploaderPath = String.Empty; + private UUID newAssetID; + private UUID inventoryItemID; + private UUID parentFolder; + private IHttpServer 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, UUID assetID, UUID inventoryItem, + UUID parentFolderID, string invType, string assetType, string path, + IHttpServer 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) + { + UUID 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); + + // TODO: probably make this a better set of extensions here + string extension = ".jp2"; + if (m_invType != "image") + { + extension = ".dat"; + } + + if (m_dumpAssetsToFile) + { + SaveAssetToFile(m_assetName + extension, data); + } + handlerUpLoad = OnUpLoad; + if (handlerUpLoad != null) + { + handlerUpLoad(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 static void SaveAssetToFile(string filename, byte[] data) + { + string assetPath = "UserAssets"; + if (!Directory.Exists(assetPath)) + { + Directory.CreateDirectory(assetPath); + } + FileStream fs = File.Create(Path.Combine(assetPath, Util.safeFileName(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 handlerUpdateItem = null; + + private string uploaderPath = String.Empty; + private UUID inventoryItemID; + private IHttpServer httpListener; + private bool m_dumpAssetToFile; + + public ItemUpdater(UUID inventoryItem, string path, IHttpServer httpServer, bool dumpAssetToFile) + { + m_dumpAssetToFile = dumpAssetToFile; + + inventoryItemID = inventoryItem; + uploaderPath = path; + httpListener = httpServer; + } + + /// + /// + /// + /// + /// + /// + /// + public string uploaderCaps(byte[] data, string path, string param) + { + UUID inv = inventoryItemID; + string res = String.Empty; + LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); + UUID assetID = UUID.Zero; + handlerUpdateItem = OnUpLoad; + if (handlerUpdateItem != null) + { + assetID = handlerUpdateItem(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 static 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 + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public event UpdateTaskScript OnUpLoad; + + private UpdateTaskScript handlerUpdateTaskScript = null; + + private string uploaderPath = String.Empty; + private UUID inventoryItemID; + private UUID primID; + private bool isScriptRunning; + private IHttpServer httpListener; + private bool m_dumpAssetToFile; + + public TaskInventoryScriptUpdater(UUID inventoryItemID, UUID primID, int isScriptRunning, + string path, IHttpServer 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; + LLSDTaskScriptUploadComplete uploadComplete = new LLSDTaskScriptUploadComplete(); + + ArrayList errors = new ArrayList(); + handlerUpdateTaskScript = OnUpLoad; + if (handlerUpdateTaskScript != null) + { + handlerUpdateTaskScript(inventoryItemID, primID, isScriptRunning, data, ref errors); + } + + uploadComplete.new_asset = inventoryItemID; + uploadComplete.compiled = errors.Count > 0 ? false : true; + uploadComplete.state = "complete"; + uploadComplete.errors = new OSDArray(); + uploadComplete.errors.Array = errors; + + 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 static 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 class BakedTextureUploader + { + public event UploadedBakedTexture OnUpLoad; + private UploadedBakedTexture handlerUpLoad = null; + + private string uploaderPath = String.Empty; + private UUID newAssetID; + private IHttpServer httpListener; + + public BakedTextureUploader(string path, IHttpServer httpServer) + { + newAssetID = UUID.Random(); + uploaderPath = path; + httpListener = httpServer; + // m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID); + } + + /// + /// + /// + /// + /// + /// + /// + public string uploaderCaps(byte[] data, string path, string param) + { + handlerUpLoad = OnUpLoad; + if (handlerUpLoad != null) + { + Util.FireAndForget(delegate(object o) { handlerUpLoad(newAssetID, data); }); + } + + string res = String.Empty; + LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); + uploadComplete.new_asset = newAssetID.ToString(); + uploadComplete.new_inventory_item = UUID.Zero; + uploadComplete.state = "complete"; + + res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); + + httpListener.RemoveStreamHandler("POST", uploaderPath); + + // m_log.InfoFormat("[CAPS] baked texture upload completed for {0}",newAssetID); + + return res; + } + } + +} diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs new file mode 100644 index 0000000000..4436d4c795 --- /dev/null +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs @@ -0,0 +1,87 @@ +/* + * 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 System.Reflection; + +using log4net; +using Nini.Config; +using OpenMetaverse; + +using OpenSim.Framework; +using OpenSim.Region.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using Caps = OpenSim.Framework.Capabilities.Caps; + +namespace OpenSim.Region.ClientStack.Linden +{ + + public class BunchOfCapsModule : INonSharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Scene m_Scene; + + #region INonSharedRegionModule + + public string Name { get { return "BunchOfCapsModule"; } } + + public Type ReplaceableInterface { get { return null; } } + + public void Initialise(IConfigSource source) + { + } + + public void Close() { } + + public void AddRegion(Scene scene) + { + m_Scene = scene; + m_Scene.EventManager.OnRegisterCaps += OnRegisterCaps; + } + + public void RemoveRegion(Scene scene) + { + } + + public void RegionLoaded(Scene scene) + { + } + + public void PostInitialise() { } + #endregion + + private void OnRegisterCaps(UUID agentID, Caps caps) + { + new BunchOfCaps(m_Scene, caps); + } + + } +} diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 4827baab27..4920347fdb 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -522,7 +522,7 @@ namespace OpenSim.Region.ClientStack.Linden } if (AvatarID != UUID.Zero) { - return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsHandlerForUser(AvatarID)); + return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsForUser(AvatarID)); } else { diff --git a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs index eddc288f0c..b7e79cc698 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs @@ -171,8 +171,8 @@ namespace OpenSim.Region.ClientStack.Linden UUID parentFolder = llsdRequest.folder_id; string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000") + "/"; - Caps.AssetUploader uploader = - new Caps.AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, + AssetUploader uploader = + new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile); MainServer.Instance.AddStreamHandler( new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs index e684a0d770..5e22c8c560 100644 --- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs @@ -51,7 +51,7 @@ namespace OpenSim.Region.CoreModules.Framework /// /// Each agent has its own capabilities handler. /// - protected Dictionary m_capsHandlers = new Dictionary(); + protected Dictionary m_capsObjects = new Dictionary(); protected Dictionary capsPaths = new Dictionary(); protected Dictionary> childrenSeeds @@ -95,19 +95,19 @@ namespace OpenSim.Region.CoreModules.Framework get { return null; } } - public void AddCapsHandler(UUID agentId) + public void CreateCaps(UUID agentId) { if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId)) return; String capsObjectPath = GetCapsPath(agentId); - if (m_capsHandlers.ContainsKey(agentId)) + if (m_capsObjects.ContainsKey(agentId)) { - Caps oldCaps = m_capsHandlers[agentId]; + Caps oldCaps = m_capsObjects[agentId]; m_log.DebugFormat( - "[CAPS]: Reregistering caps for agent {0}. Old caps path {1}, new caps path {2}. ", + "[CAPS]: Recreating caps for agent {0}. Old caps path {1}, new caps path {2}. ", agentId, oldCaps.CapsObjectPath, capsObjectPath); // This should not happen. The caller code is confused. We need to fix that. // CAPs can never be reregistered, or the client will be confused. @@ -115,39 +115,29 @@ namespace OpenSim.Region.CoreModules.Framework //return; } - Caps caps - = new Caps(m_scene, - m_scene.AssetService, MainServer.Instance, m_scene.RegionInfo.ExternalHostName, + Caps caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName, (MainServer.Instance == null) ? 0: MainServer.Instance.Port, - capsObjectPath, agentId, m_scene.DumpAssetsToFile, m_scene.RegionInfo.RegionName); + capsObjectPath, agentId, m_scene.RegionInfo.RegionName); - caps.RegisterHandlers(); + m_capsObjects[agentId] = caps; m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps); - - caps.AddNewInventoryItem = m_scene.AddUploadedInventoryItem; - caps.ItemUpdatedCall = m_scene.CapsUpdateInventoryItemAsset; - caps.TaskScriptUpdatedCall = m_scene.CapsUpdateTaskInventoryScriptAsset; - caps.CAPSFetchInventoryDescendents = m_scene.HandleFetchInventoryDescendentsCAPS; - caps.GetClient = m_scene.SceneContents.GetControllingClient; - - m_capsHandlers[agentId] = caps; } - public void RemoveCapsHandler(UUID agentId) + public void RemoveCaps(UUID agentId) { if (childrenSeeds.ContainsKey(agentId)) { childrenSeeds.Remove(agentId); } - lock (m_capsHandlers) + lock (m_capsObjects) { - if (m_capsHandlers.ContainsKey(agentId)) + if (m_capsObjects.ContainsKey(agentId)) { - m_capsHandlers[agentId].DeregisterHandlers(); - m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsHandlers[agentId]); - m_capsHandlers.Remove(agentId); + m_capsObjects[agentId].DeregisterHandlers(); + m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsObjects[agentId]); + m_capsObjects.Remove(agentId); } else { @@ -158,20 +148,20 @@ namespace OpenSim.Region.CoreModules.Framework } } - public Caps GetCapsHandlerForUser(UUID agentId) + public Caps GetCapsForUser(UUID agentId) { - lock (m_capsHandlers) + lock (m_capsObjects) { - if (m_capsHandlers.ContainsKey(agentId)) + if (m_capsObjects.ContainsKey(agentId)) { - return m_capsHandlers[agentId]; + return m_capsObjects[agentId]; } } return null; } - public void NewUserConnection(AgentCircuitData agent) + public void SetAgentCapsSeeds(AgentCircuitData agent) { capsPaths[agent.AgentID] = agent.CapsPath; childrenSeeds[agent.AgentID] @@ -241,7 +231,7 @@ namespace OpenSim.Region.CoreModules.Framework System.Text.StringBuilder caps = new System.Text.StringBuilder(); caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName); - foreach (KeyValuePair kvp in m_capsHandlers) + foreach (KeyValuePair kvp in m_capsObjects) { caps.AppendFormat("** User {0}:\n", kvp.Key); for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.CapsDetails.GetEnumerator(); kvp2.MoveNext(); ) diff --git a/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs b/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs index 2dd7767d76..07999d16c1 100644 --- a/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs +++ b/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs @@ -575,7 +575,7 @@ namespace OpenSim.Region.CoreModules.InterGrid string derezAvatarPath = "/agent/" + AvatarRezCapUUID + "/rez_avatar/derez"; // Get a reference to the user's cap so we can pull out the Caps Object Path Caps userCap - = homeScene.CapsModule.GetCapsHandlerForUser(agentData.AgentID); + = homeScene.CapsModule.GetCapsForUser(agentData.AgentID); string rezHttpProtocol = "http://"; string regionCapsHttpProtocol = "http://"; @@ -700,7 +700,7 @@ namespace OpenSim.Region.CoreModules.InterGrid { // Get a referenceokay - to their Cap object so we can pull out the capobjectroot Caps userCap - = homeScene.CapsModule.GetCapsHandlerForUser(userData.AgentID); + = homeScene.CapsModule.GetCapsForUser(userData.AgentID); //Update the circuit data in the region so this user is authorized homeScene.UpdateCircuitData(userData); diff --git a/OpenSim/Region/Framework/Interfaces/ICapabilitiesModule.cs b/OpenSim/Region/Framework/Interfaces/ICapabilitiesModule.cs index 73bffa02f1..522c82d40f 100644 --- a/OpenSim/Region/Framework/Interfaces/ICapabilitiesModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ICapabilitiesModule.cs @@ -34,31 +34,27 @@ namespace OpenSim.Region.Framework.Interfaces { public interface ICapabilitiesModule { - void NewUserConnection(AgentCircuitData agent); - /// /// Add a caps handler for the given agent. If the CAPS handler already exists for this agent, /// then it is replaced by a new CAPS handler. - /// - /// FIXME: On login this is called twice, once for the login and once when the connection is made. - /// This is somewhat innefficient and should be fixed. The initial login creation is necessary - /// since the client asks for capabilities immediately after being informed of the seed. /// /// /// - void AddCapsHandler(UUID agentId); + void CreateCaps(UUID agentId); /// /// Remove the caps handler for a given agent. /// /// - void RemoveCapsHandler(UUID agentId); + void RemoveCaps(UUID agentId); /// /// Will return null if the agent doesn't have a caps handler registered /// /// - Caps GetCapsHandlerForUser(UUID agentId); + Caps GetCapsForUser(UUID agentId); + + void SetAgentCapsSeeds(AgentCircuitData agent); Dictionary GetChildrenSeeds(UUID agentID); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 7c5e24652c..b537381a0b 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3033,7 +3033,7 @@ namespace OpenSim.Region.Framework.Scenes m_sceneGraph.removeUserCount(!childagentYN); if (CapsModule != null) - CapsModule.RemoveCapsHandler(agentID); + CapsModule.RemoveCaps(agentID); // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever // this method is doing is HORRIBLE!!! @@ -3290,8 +3290,8 @@ namespace OpenSim.Region.Framework.Scenes if (CapsModule != null) { - CapsModule.NewUserConnection(agent); - CapsModule.AddCapsHandler(agent.AgentID); + CapsModule.SetAgentCapsSeeds(agent); + CapsModule.CreateCaps(agent.AgentID); } } else @@ -3309,7 +3309,7 @@ namespace OpenSim.Region.Framework.Scenes sp.AdjustKnownSeeds(); if (CapsModule != null) - CapsModule.NewUserConnection(agent); + CapsModule.SetAgentCapsSeeds(agent); } } From 2d21052fa35f6d29017d8806bee4b81a96d1b052 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 1 May 2011 19:09:08 -0700 Subject: [PATCH 24/41] Start to drill down on GetTexture. Read the config and do different things. --- .../ClientStack/Linden/Caps/GetTextureModule.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index 86c990fff8..21041ec683 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs @@ -59,15 +59,20 @@ namespace OpenSim.Region.ClientStack.Linden private Scene m_scene; private IAssetService m_assetService; - public const string DefaultFormat = "x-j2c"; - // TODO: Change this to a config option const string REDIRECT_URL = null; + private string m_URL; + #region ISharedRegionModule Members - public void Initialise(IConfigSource pSource) + public void Initialise(IConfigSource source) { + IConfig config = source.Configs["ClientStack.LindenCaps"]; + if (config == null) + return; + + m_URL = config.GetString("Cap_GetTexture", "localhost"); } public void AddRegion(Scene s) @@ -105,7 +110,10 @@ namespace OpenSim.Region.ClientStack.Linden // m_log.InfoFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); - caps.RegisterHandler("GetTexture", new GetTextureHandler("/CAPS/" + capID + "/", m_assetService)); + if (m_URL == "localhost") + caps.RegisterHandler("GetTexture", new GetTextureHandler("/CAPS/" + capID + "/", m_assetService)); + else + caps.RegisterHandler("GetTexture", m_URL); } } From 10180760b741edf22cec23db0ec490669407425f Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 2 May 2011 08:48:55 -0700 Subject: [PATCH 25/41] Works! --- .../Handlers/GetTextureHandler.cs | 3 +- ...nector.cs => GetTextureServerConnector.cs} | 12 ++-- .../Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 11 +-- .../Caps/BunchOfCaps/BunchOfCapsModule.cs | 4 ++ .../Caps/EventQueue/EventQueueGetModule.cs | 2 +- .../Linden/Caps/GetTextureModule.cs | 27 ++++++-- .../Resources/CoreModulePlugin.addin.xml | 2 +- prebuild.xml | 69 +++++++++++++++---- 8 files changed, 95 insertions(+), 35 deletions(-) rename OpenSim/Capabilities/Handlers/{CapsServerConnector.cs => GetTextureServerConnector.cs} (85%) diff --git a/OpenSim/Capabilities/Handlers/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTextureHandler.cs index 00186eef27..00ff3d0b5b 100644 --- a/OpenSim/Capabilities/Handlers/GetTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetTextureHandler.cs @@ -67,13 +67,14 @@ namespace OpenSim.Capabilities.Handlers public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) { - //m_log.DebugFormat("[GETTEXTURE]: called in {0}", m_scene.RegionInfo.RegionName); // Try to parse the texture ID from the request URL NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); string textureStr = query.GetOne("texture_id"); string format = query.GetOne("format"); + m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr); + if (m_assetService == null) { m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service"); diff --git a/OpenSim/Capabilities/Handlers/CapsServerConnector.cs b/OpenSim/Capabilities/Handlers/GetTextureServerConnector.cs similarity index 85% rename from OpenSim/Capabilities/Handlers/CapsServerConnector.cs rename to OpenSim/Capabilities/Handlers/GetTextureServerConnector.cs index 561d767c0c..0335eace8b 100644 --- a/OpenSim/Capabilities/Handlers/CapsServerConnector.cs +++ b/OpenSim/Capabilities/Handlers/GetTextureServerConnector.cs @@ -32,16 +32,15 @@ using OpenSim.Services.Interfaces; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Server.Handlers.Base; using OpenMetaverse; -using Caps = OpenSim.Framework.Capabilities.Caps; namespace OpenSim.Capabilities.Handlers { - public class CapsServerConnector : ServiceConnector + public class GetTextureServerConnector : ServiceConnector { private IAssetService m_AssetService; private string m_ConfigName = "CapsService"; - public CapsServerConnector(IConfigSource config, IHttpServer server, string configName) : + public GetTextureServerConnector(IConfigSource config, IHttpServer server, string configName) : base(config, server, configName) { if (configName != String.Empty) @@ -51,11 +50,10 @@ namespace OpenSim.Capabilities.Handlers if (serverConfig == null) throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName)); - string assetService = serverConfig.GetString("LocalServiceModule", - String.Empty); + string assetService = serverConfig.GetString("AssetService", String.Empty); if (assetService == String.Empty) - throw new Exception("No LocalServiceModule in config file"); + throw new Exception("No AssetService in config file"); Object[] args = new Object[] { config }; m_AssetService = @@ -64,8 +62,6 @@ namespace OpenSim.Capabilities.Handlers if (m_AssetService == null) throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName)); - bool allowDelete = serverConfig.GetBoolean("AllowRemoteDelete", false); - server.AddStreamHandler(new GetTextureHandler("/CAPS/" + UUID.Random() + "/", m_AssetService)); } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index 7a7964e131..7945d5e5ca 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -78,7 +78,7 @@ namespace OpenSim.Region.ClientStack.Linden public GetClientDelegate GetClient = null; private bool m_persistBakedTextures = false; - private IAssetService m_assetCache; + private IAssetService m_assetService; private bool m_dumpAssetsToFile; private string m_regionName; private object m_fetchLock = new Object(); @@ -95,6 +95,9 @@ namespace OpenSim.Region.ClientStack.Linden m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures); } + m_assetService = m_Scene.AssetService; + m_regionName = m_Scene.RegionInfo.RegionName; + RegisterHandlers(); AddNewInventoryItem = m_Scene.AddUploadedInventoryItem; @@ -347,7 +350,7 @@ namespace OpenSim.Region.ClientStack.Linden asset.Data = data; asset.Temporary = true; asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are - m_assetCache.Store(asset); + m_assetService.Store(asset); } /// @@ -476,8 +479,8 @@ namespace OpenSim.Region.ClientStack.Linden asset.Data = data; if (AddNewAsset != null) AddNewAsset(asset); - else if (m_assetCache != null) - m_assetCache.Store(asset); + else if (m_assetService != null) + m_assetService.Store(asset); InventoryItemBase item = new InventoryItemBase(); item.Owner = m_HostCapsObj.AgentID; diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs index 4436d4c795..14160ae7cd 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs @@ -32,6 +32,7 @@ using System.Reflection; using log4net; using Nini.Config; using OpenMetaverse; +using Mono.Addins; using OpenSim.Framework; using OpenSim.Region.Framework; @@ -39,9 +40,12 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using Caps = OpenSim.Framework.Capabilities.Caps; +[assembly: Addin("LindenCaps", "0.1")] +[assembly: AddinDependency("OpenSim", "0.5")] namespace OpenSim.Region.ClientStack.Linden { + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class BunchOfCapsModule : INonSharedRegionModule { private static readonly ILog m_log = diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 4920347fdb..4a8bb53584 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -54,7 +54,7 @@ namespace OpenSim.Region.ClientStack.Linden public OSDMap body; } - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + //[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class EventQueueGetModule : IEventQueue, IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index 21041ec683..d697f5ea7b 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs @@ -52,13 +52,15 @@ namespace OpenSim.Region.ClientStack.Linden { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class GetTextureModule : ISharedRegionModule + public class GetTextureModule : INonSharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; private IAssetService m_assetService; + private bool m_Enabled = false; + // TODO: Change this to a config option const string REDIRECT_URL = null; @@ -72,11 +74,18 @@ namespace OpenSim.Region.ClientStack.Linden if (config == null) return; - m_URL = config.GetString("Cap_GetTexture", "localhost"); + m_URL = config.GetString("Cap_GetTexture", string.Empty); + // Cap doesn't exist + if (m_URL != string.Empty) + m_Enabled = true; } public void AddRegion(Scene s) { + if (!m_Enabled) + return; + + m_scene = s; } public void RemoveRegion(Scene s) @@ -85,12 +94,15 @@ namespace OpenSim.Region.ClientStack.Linden public void RegionLoaded(Scene s) { + if (!m_Enabled) + return; + + m_assetService = m_scene.RequestModuleInterface(); + m_scene.EventManager.OnRegisterCaps += RegisterCaps; } public void PostInitialise() { - m_assetService = m_scene.RequestModuleInterface(); - m_scene.EventManager.OnRegisterCaps += RegisterCaps; } public void Close() { } @@ -108,12 +120,17 @@ namespace OpenSim.Region.ClientStack.Linden { UUID capID = UUID.Random(); - // m_log.InfoFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); if (m_URL == "localhost") + { + m_log.InfoFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); caps.RegisterHandler("GetTexture", new GetTextureHandler("/CAPS/" + capID + "/", m_assetService)); + } else + { + m_log.InfoFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); caps.RegisterHandler("GetTexture", m_URL); + } } } diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml index a9d247a2b8..a0009a869f 100644 --- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml +++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml @@ -17,7 +17,7 @@ - + diff --git a/prebuild.xml b/prebuild.xml index 4fa48d140b..cc7743636f 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1549,30 +1549,28 @@ - + - ../../../../bin/ + ../../../../../bin/ - ../../../../bin/ + ../../../../../bin/ - ../../../../bin/ + ../../../../../bin/ - - - + + + - - @@ -1581,13 +1579,54 @@ + + + + + + + + + + + + + + + + + + ../../../../../bin/ + + + + + ../../../../../bin/ + + + + ../../../../../bin/ + + + + + + + + + + + + + + + - - - - - + + + + @@ -1626,7 +1665,7 @@ - + From 8cc547c2776f957abd0fa09c33c02bf42de70340 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 2 May 2011 09:04:34 -0700 Subject: [PATCH 26/41] Turns out that it's a bad idea to let Agent position updates linger for a long time on certain versions of mono. It's better to abort them if they take too long. So timeout is now an argument. Currently: 20secs for CreateAgent, 100secs for UpdateAgent (fat), 10 secs for UpdateAgent (Position); all of these divided by 4, for ReadWrite, as Mic had before. --- OpenSim/Framework/WebUtil.cs | 18 +++++++++--------- .../Simulation/SimulationServiceConnector.cs | 14 +++++++------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index ac0828b90e..4734fc1f83 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs @@ -140,19 +140,19 @@ namespace OpenSim.Framework /// PUT JSON-encoded data to a web service that returns LLSD or /// JSON data /// - public static OSDMap PutToService(string url, OSDMap data) + public static OSDMap PutToService(string url, OSDMap data, int timeout) { - return ServiceOSDRequest(url,data,"PUT",30000); + return ServiceOSDRequest(url,data, "PUT", timeout); } - - public static OSDMap PostToService(string url, OSDMap data) + + public static OSDMap PostToService(string url, OSDMap data, int timeout) { - return ServiceOSDRequest(url,data,"POST",30000); + return ServiceOSDRequest(url, data, "POST", timeout); } - - public static OSDMap GetFromService(string url) + + public static OSDMap GetFromService(string url, int timeout) { - return ServiceOSDRequest(url,null,"GET",30000); + return ServiceOSDRequest(url, null, "GET", timeout); } public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout) @@ -171,7 +171,7 @@ namespace OpenSim.Framework request.Timeout = timeout; request.KeepAlive = false; request.MaximumAutomaticRedirections = 10; - request.ReadWriteTimeout = timeout * 8; + request.ReadWriteTimeout = timeout / 4; request.Headers[OSHeaderRequestID] = reqnum.ToString(); // If there is some input, write it into the request diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index 5cb82699d6..0f2ced14ca 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -102,7 +102,7 @@ namespace OpenSim.Services.Connectors.Simulation args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString()); args["teleport_flags"] = OSD.FromString(flags.ToString()); - OSDMap result = WebUtil.PostToService(uri,args); + OSDMap result = WebUtil.PostToService(uri, args, 20000); if (result["Success"].AsBoolean()) return true; @@ -126,7 +126,7 @@ namespace OpenSim.Services.Connectors.Simulation /// public bool UpdateAgent(GridRegion destination, AgentData data) { - return UpdateAgent(destination, (IAgentData)data); + return UpdateAgent(destination, (IAgentData)data, 100000); // yes, 100 seconds } /// @@ -181,7 +181,7 @@ namespace OpenSim.Services.Connectors.Simulation } } - UpdateAgent(destination,(IAgentData)pos); + UpdateAgent(destination, (IAgentData)pos, 10000); } // unreachable @@ -191,7 +191,7 @@ namespace OpenSim.Services.Connectors.Simulation /// /// This is the worker function to send AgentData to a neighbor region /// - private bool UpdateAgent(GridRegion destination, IAgentData cAgentData) + private bool UpdateAgent(GridRegion destination, IAgentData cAgentData, int timeout) { // m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: UpdateAgent start"); @@ -207,7 +207,7 @@ namespace OpenSim.Services.Connectors.Simulation args["destination_name"] = OSD.FromString(destination.RegionName); args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString()); - OSDMap result = WebUtil.PutToService(uri,args); + OSDMap result = WebUtil.PutToService(uri, args, timeout); return result["Success"].AsBoolean(); } catch (Exception e) @@ -233,7 +233,7 @@ namespace OpenSim.Services.Connectors.Simulation try { - OSDMap result = WebUtil.GetFromService(uri); + OSDMap result = WebUtil.GetFromService(uri, 10000); if (result["Success"].AsBoolean()) { // OSDMap args = Util.GetOSDMap(result["_RawResult"].AsString()); @@ -392,7 +392,7 @@ namespace OpenSim.Services.Connectors.Simulation args["destination_name"] = OSD.FromString(destination.RegionName); args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString()); - WebUtil.PostToService(uri, args); + WebUtil.PostToService(uri, args, 40000); } catch (Exception e) { From 51d0b8b4e9179d5dbfd289a34e7103d2889c4b71 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 2 May 2011 09:06:21 -0700 Subject: [PATCH 27/41] Oops, forgot this one. --- .../Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs index 8ab323ad41..0430ef60d7 100644 --- a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs @@ -314,7 +314,7 @@ namespace OpenSim.Services.Connectors.Hypergrid args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString()); args["teleport_flags"] = OSD.FromString(flags.ToString()); - OSDMap result = WebUtil.PostToService(uri,args); + OSDMap result = WebUtil.PostToService(uri, args, 20000); if (result["Success"].AsBoolean()) { OSDMap unpacked = (OSDMap)result["_Result"]; From f7d37201265b45ce8449c1361fa51928931d6bfd Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 2 May 2011 09:20:08 -0700 Subject: [PATCH 28/41] Increased timeout for fat UpdateAgent to 200secs. Nebadon's 3800-prim alien avatar takes 6secs to transfer between sims on the same machine... --- .../Connectors/Simulation/SimulationServiceConnector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index 0f2ced14ca..cef6473b78 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -126,7 +126,7 @@ namespace OpenSim.Services.Connectors.Simulation /// public bool UpdateAgent(GridRegion destination, AgentData data) { - return UpdateAgent(destination, (IAgentData)data, 100000); // yes, 100 seconds + return UpdateAgent(destination, (IAgentData)data, 200000); // yes, 200 seconds } /// From aba9ffdbd008920f94cfbd7d4ff4a0fa92e92321 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 2 May 2011 11:56:40 -0700 Subject: [PATCH 29/41] Refactored the GetMesh module into a handler and a module, to be the same as GetTexture. --- .../Handlers/GetMesh/GetMeshHandler.cs | 143 +++++++++++++++++ .../GetMesh/GetMeshServerConnector.cs | 79 ++++++++++ .../{ => GetTexture}/GetTextureHandler.cs | 0 .../GetTextureServerConnector.cs | 0 .../ClientStack/Linden/Caps/GetMeshModule.cs | 149 +++++------------- .../Linden/Caps/GetTextureModule.cs | 2 + 6 files changed, 261 insertions(+), 112 deletions(-) create mode 100644 OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs create mode 100644 OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs rename OpenSim/Capabilities/Handlers/{ => GetTexture}/GetTextureHandler.cs (100%) rename OpenSim/Capabilities/Handlers/{ => GetTexture}/GetTextureServerConnector.cs (100%) diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs new file mode 100644 index 0000000000..c60abb1fb1 --- /dev/null +++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs @@ -0,0 +1,143 @@ +/* + * 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; +using System.Collections.Specialized; +using System.Reflection; +using System.IO; +using System.Web; +using log4net; +using Nini.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Services.Interfaces; +using Caps = OpenSim.Framework.Capabilities.Caps; + +namespace OpenSim.Capabilities.Handlers +{ + public class GetMeshHandler + { +// private static readonly ILog m_log = +// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private IAssetService m_assetService; + + public GetMeshHandler(IAssetService assService) + { + m_assetService = assService; + } + + public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap) + { + + Hashtable responsedata = new Hashtable(); + responsedata["int_response_code"] = 400; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "Request wasn't what was expected"; + + string meshStr = string.Empty; + + if (request.ContainsKey("mesh_id")) + meshStr = request["mesh_id"].ToString(); + + + UUID meshID = UUID.Zero; + if (!String.IsNullOrEmpty(meshStr) && UUID.TryParse(meshStr, out meshID)) + { + if (m_assetService == null) + { + responsedata["int_response_code"] = 404; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh."; + return responsedata; + } + + AssetBase mesh; + // Only try to fetch locally cached textures. Misses are redirected + mesh = m_assetService.GetCached(meshID.ToString()); + if (mesh != null) + { + if (mesh.Type == (SByte)AssetType.Mesh) + { + responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); + responsedata["content_type"] = "application/vnd.ll.mesh"; + responsedata["int_response_code"] = 200; + } + // Optionally add additional mesh types here + else + { + responsedata["int_response_code"] = 404; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh."; + return responsedata; + } + } + else + { + mesh = m_assetService.Get(meshID.ToString()); + if (mesh != null) + { + if (mesh.Type == (SByte)AssetType.Mesh) + { + responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); + responsedata["content_type"] = "application/vnd.ll.mesh"; + responsedata["int_response_code"] = 200; + } + // Optionally add additional mesh types here + else + { + responsedata["int_response_code"] = 404; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh."; + return responsedata; + } + } + + else + { + responsedata["int_response_code"] = 404; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!"; + return responsedata; + } + } + + } + + return responsedata; + } + } +} diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs new file mode 100644 index 0000000000..fa5f7555d6 --- /dev/null +++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs @@ -0,0 +1,79 @@ +/* + * 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; +using Nini.Config; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Server.Handlers.Base; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Servers.HttpServer; + +using OpenMetaverse; + +namespace OpenSim.Capabilities.Handlers +{ + public class GetMeshServerConnector : ServiceConnector + { + private IAssetService m_AssetService; + private string m_ConfigName = "CapsService"; + + public GetMeshServerConnector(IConfigSource config, IHttpServer server, string configName) : + base(config, server, configName) + { + if (configName != String.Empty) + m_ConfigName = configName; + + IConfig serverConfig = config.Configs[m_ConfigName]; + if (serverConfig == null) + throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName)); + + string assetService = serverConfig.GetString("AssetService", String.Empty); + + if (assetService == String.Empty) + throw new Exception("No AssetService in config file"); + + Object[] args = new Object[] { config }; + m_AssetService = + ServerUtils.LoadPlugin(assetService, args); + + if (m_AssetService == null) + throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName)); + + GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService); + IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), + delegate(Hashtable m_dhttpMethod) + { + return gmeshHandler.ProcessGetMesh(m_dhttpMethod, UUID.Zero, null); + }); + server.AddStreamHandler(reqHandler); + } + + } +} diff --git a/OpenSim/Capabilities/Handlers/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs similarity index 100% rename from OpenSim/Capabilities/Handlers/GetTextureHandler.cs rename to OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs diff --git a/OpenSim/Capabilities/Handlers/GetTextureServerConnector.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs similarity index 100% rename from OpenSim/Capabilities/Handlers/GetTextureServerConnector.cs rename to OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs index 1d5714398f..f2f765c3e8 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs @@ -36,6 +36,7 @@ using log4net; using Nini.Config; using OpenMetaverse; using OpenMetaverse.StructuredData; +using OpenSim.Capabilities.Handlers; using OpenSim.Framework; using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; @@ -49,16 +50,16 @@ namespace OpenSim.Region.ClientStack.Linden [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class GetMeshModule : INonSharedRegionModule { -// private static readonly ILog m_log = -// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; - private IAssetService m_assetService; - private bool m_enabled = true; + private IAssetService m_AssetService; + private bool m_Enabled = true; + private string m_URL; #region IRegionModuleBase Members - public Type ReplaceableInterface { get { return null; } @@ -66,146 +67,70 @@ namespace OpenSim.Region.ClientStack.Linden public void Initialise(IConfigSource source) { - IConfig meshConfig = source.Configs["Mesh"]; - if (meshConfig == null) + IConfig config = source.Configs["ClientStack.LindenCaps"]; + if (config == null) return; - m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true); + m_URL = config.GetString("Cap_GetMesh", string.Empty); + // Cap doesn't exist + if (m_URL != string.Empty) + m_Enabled = true; } public void AddRegion(Scene pScene) { + if (!m_Enabled) + return; + m_scene = pScene; } public void RemoveRegion(Scene scene) { - m_scene.EventManager.OnRegisterCaps -= RegisterCaps; m_scene = null; } public void RegionLoaded(Scene scene) { - - m_assetService = m_scene.RequestModuleInterface(); + if (!m_Enabled) + return; + + m_AssetService = m_scene.RequestModuleInterface(); m_scene.EventManager.OnRegisterCaps += RegisterCaps; } - #endregion - - - #region IRegionModule Members - - public void Close() { } public string Name { get { return "GetMeshModule"; } } + #endregion + public void RegisterCaps(UUID agentID, Caps caps) { - if(!m_enabled) - return; - UUID capID = UUID.Random(); -// m_log.Info("[GETMESH]: /CAPS/" + capID); - - caps.RegisterHandler("GetMesh", - new RestHTTPHandler("GET", "/CAPS/" + capID, - delegate(Hashtable m_dhttpMethod) - { - return ProcessGetMesh(m_dhttpMethod, agentID, caps); - })); - } - - #endregion - - public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap) - { - - Hashtable responsedata = new Hashtable(); - responsedata["int_response_code"] = 400; //501; //410; //404; - responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; - responsedata["str_response_string"] = "Request wasn't what was expected"; - - string meshStr = string.Empty; - - if (request.ContainsKey("mesh_id")) - meshStr = request["mesh_id"].ToString(); - - - UUID meshID = UUID.Zero; - if (!String.IsNullOrEmpty(meshStr) && UUID.TryParse(meshStr, out meshID)) + //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); + if (m_URL == "localhost") { - if (m_assetService == null) - { - responsedata["int_response_code"] = 404; //501; //410; //404; - responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; - responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh."; - return responsedata; - } - - AssetBase mesh; - // Only try to fetch locally cached textures. Misses are redirected - mesh = m_assetService.GetCached(meshID.ToString()); - if (mesh != null) - { - if (mesh.Type == (SByte)AssetType.Mesh) - { - responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); - responsedata["content_type"] = "application/vnd.ll.mesh"; - responsedata["int_response_code"] = 200; - } - // Optionally add additional mesh types here - else - { - responsedata["int_response_code"] = 404; //501; //410; //404; - responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; - responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh."; - return responsedata; - } - } - else - { - mesh = m_assetService.Get(meshID.ToString()); - if (mesh != null) - { - if (mesh.Type == (SByte)AssetType.Mesh) - { - responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); - responsedata["content_type"] = "application/vnd.ll.mesh"; - responsedata["int_response_code"] = 200; - } - // Optionally add additional mesh types here - else - { - responsedata["int_response_code"] = 404; //501; //410; //404; - responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; - responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh."; - return responsedata; - } - } - - else - { - responsedata["int_response_code"] = 404; //501; //410; //404; - responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; - responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!"; - return responsedata; - } - } + m_log.InfoFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); + GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService); + IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), + delegate(Hashtable m_dhttpMethod) + { + return gmeshHandler.ProcessGetMesh(m_dhttpMethod, UUID.Zero, null); + }); + caps.RegisterHandler("GetMesh", reqHandler); + } + else + { + m_log.InfoFormat("[GETMESH]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); + caps.RegisterHandler("GetMesh", m_URL); } - - return responsedata; } + } } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index d697f5ea7b..564ef31f93 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs @@ -90,6 +90,8 @@ namespace OpenSim.Region.ClientStack.Linden public void RemoveRegion(Scene s) { + m_scene.EventManager.OnRegisterCaps -= RegisterCaps; + m_scene = null; } public void RegionLoaded(Scene s) From 883f21dd026cbed55f2e12af491e2f9902b80d4a Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 2 May 2011 14:33:34 -0700 Subject: [PATCH 30/41] WebFetchInventoryDescendents working. Tested with robust. --- OpenSim/Capabilities/Caps.cs | 4 + .../WebFetchInvDescHandler.cs | 299 ++++++++++++++++++ .../WebFetchInvDescServerConnector.cs | 76 +++++ .../Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 285 +---------------- .../Linden/Caps/WebFetchInvDescModule.cs | 131 ++++++++ 5 files changed, 516 insertions(+), 279 deletions(-) create mode 100644 OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs create mode 100644 OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescServerConnector.cs create mode 100644 OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs diff --git a/OpenSim/Capabilities/Caps.cs b/OpenSim/Capabilities/Caps.cs index 95bb465763..e188896bc5 100644 --- a/OpenSim/Capabilities/Caps.cs +++ b/OpenSim/Capabilities/Caps.cs @@ -106,6 +106,10 @@ namespace OpenSim.Framework.Capabilities { get { return m_capsHandlers; } } + public Dictionary ExternalCapsHandlers + { + get { return m_externalCapsHandlers; } + } public Caps(IHttpServer httpServer, string httpListen, uint httpPort, string capsPath, UUID agent, string regionName) diff --git a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs new file mode 100644 index 0000000000..6fd79469a4 --- /dev/null +++ b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs @@ -0,0 +1,299 @@ +/* + * 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; +using System.Collections.Generic; +using System.Reflection; +using log4net; +using Nini.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Framework.Capabilities; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Services.Interfaces; +using Caps = OpenSim.Framework.Capabilities.Caps; + +namespace OpenSim.Capabilities.Handlers +{ + + public class WebFetchInvDescHandler + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private IInventoryService m_InventoryService; + private ILibraryService m_LibraryService; + private object m_fetchLock = new Object(); + + public WebFetchInvDescHandler(IInventoryService invService, ILibraryService libService) + { + m_InventoryService = invService; + m_LibraryService = libService; + } + + public string FetchInventoryDescendentsRequest(string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + // nasty temporary hack here, the linden client falsely + // identifies the uuid 00000000-0000-0000-0000-000000000000 + // as a string which breaks us + // + // correctly mark it as a uuid + // + request = request.Replace("00000000-0000-0000-0000-000000000000", "00000000-0000-0000-0000-000000000000"); + + // another hack 1 results in a + // System.ArgumentException: Object type System.Int32 cannot + // be converted to target type: System.Boolean + // + request = request.Replace("fetch_folders0", "fetch_folders0"); + request = request.Replace("fetch_folders1", "fetch_folders1"); + + Hashtable hash = new Hashtable(); + try + { + hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); + } + catch (LLSD.LLSDParseException pe) + { + m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message); + m_log.Error("Request: " + request.ToString()); + } + + ArrayList foldersrequested = (ArrayList)hash["folders"]; + + string response = ""; + lock (m_fetchLock) + { + for (int i = 0; i < foldersrequested.Count; i++) + { + string inventoryitemstr = ""; + Hashtable inventoryhash = (Hashtable)foldersrequested[i]; + + LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); + + try + { + LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest); + } + catch (Exception e) + { + m_log.Debug("[CAPS]: caught exception doing OSD deserialize" + e); + } + LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest); + + inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); + inventoryitemstr = inventoryitemstr.Replace("folders", ""); + inventoryitemstr = inventoryitemstr.Replace("", ""); + + response += inventoryitemstr; + } + + + if (response.Length == 0) + { + // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants. + // Therefore, I'm concluding that the client only has so many threads available to do requests + // and when a thread stalls.. is stays stalled. + // Therefore we need to return something valid + response = "folders"; + } + else + { + response = "folders" + response + ""; + } + + //m_log.DebugFormat("[CAPS]: Replying to CAPS fetch inventory request with following xml"); + //m_log.Debug("[CAPS] "+response); + + } + return response; + } + + /// + /// Construct an LLSD reply packet to a CAPS inventory request + /// + /// + /// + private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch) + { + LLSDInventoryDescendents reply = new LLSDInventoryDescendents(); + LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents(); + contents.agent_id = invFetch.owner_id; + contents.owner_id = invFetch.owner_id; + contents.folder_id = invFetch.folder_id; + + reply.folders.Array.Add(contents); + InventoryCollection inv = new InventoryCollection(); + inv.Folders = new List(); + inv.Items = new List(); + int version = 0; + + inv = Fetch(invFetch.owner_id, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version); + + if (inv.Folders != null) + { + foreach (InventoryFolderBase invFolder in inv.Folders) + { + contents.categories.Array.Add(ConvertInventoryFolder(invFolder)); + } + } + + if (inv.Items != null) + { + foreach (InventoryItemBase invItem in inv.Items) + { + contents.items.Array.Add(ConvertInventoryItem(invItem)); + } + } + + contents.descendents = contents.items.Array.Count + contents.categories.Array.Count; + contents.version = version; + + return reply; + } + + public InventoryCollection Fetch(UUID agentID, UUID folderID, UUID ownerID, + bool fetchFolders, bool fetchItems, int sortOrder, out int version) + { + m_log.DebugFormat( + "[WEBFETCHINVENTORYDESCENDANTS]: Fetching folders ({0}), items ({1}) from {2} for agent {3}", + fetchFolders, fetchItems, folderID, agentID); + + version = 0; + InventoryFolderImpl fold; + if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null && agentID == m_LibraryService.LibraryRootFolder.Owner) + if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(folderID)) != null) + { + InventoryCollection ret = new InventoryCollection(); + ret.Folders = new List(); + ret.Items = fold.RequestListOfItems(); + + return ret; + } + + InventoryCollection contents = new InventoryCollection(); + + if (folderID != UUID.Zero) + { + contents = m_InventoryService.GetFolderContent(agentID, folderID); + InventoryFolderBase containingFolder = new InventoryFolderBase(); + containingFolder.ID = folderID; + containingFolder.Owner = agentID; + containingFolder = m_InventoryService.GetFolder(containingFolder); + if (containingFolder != null) + version = containingFolder.Version; + } + else + { + // Lost itemsm don't really need a version + version = 1; + } + + return contents; + + } + /// + /// Convert an internal inventory folder object into an LLSD object. + /// + /// + /// + private LLSDInventoryFolder ConvertInventoryFolder(InventoryFolderBase invFolder) + { + LLSDInventoryFolder llsdFolder = new LLSDInventoryFolder(); + llsdFolder.folder_id = invFolder.ID; + llsdFolder.parent_id = invFolder.ParentID; + llsdFolder.name = invFolder.Name; + if (invFolder.Type < 0 || invFolder.Type >= TaskInventoryItem.Types.Length) + llsdFolder.type = "-1"; + else + llsdFolder.type = TaskInventoryItem.Types[invFolder.Type]; + llsdFolder.preferred_type = "-1"; + + return llsdFolder; + } + + /// + /// Convert an internal inventory item object into an LLSD object. + /// + /// + /// + private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem) + { + LLSDInventoryItem llsdItem = new LLSDInventoryItem(); + llsdItem.asset_id = invItem.AssetID; + llsdItem.created_at = invItem.CreationDate; + llsdItem.desc = invItem.Description; + llsdItem.flags = (int)invItem.Flags; + llsdItem.item_id = invItem.ID; + llsdItem.name = invItem.Name; + llsdItem.parent_id = invItem.Folder; + try + { + // TODO reevaluate after upgrade to libomv >= r2566. Probably should use UtilsConversions. + llsdItem.type = TaskInventoryItem.Types[invItem.AssetType]; + llsdItem.inv_type = TaskInventoryItem.InvTypes[invItem.InvType]; + } + catch (Exception e) + { + m_log.ErrorFormat("[CAPS]: Problem setting asset {0} inventory {1} types while converting inventory item {2}: {3}", invItem.AssetType, invItem.InvType, invItem.Name, e.Message); + } + llsdItem.permissions = new LLSDPermissions(); + llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid; + llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions; + llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions; + llsdItem.permissions.group_id = invItem.GroupID; + llsdItem.permissions.group_mask = (int)invItem.GroupPermissions; + llsdItem.permissions.is_owner_group = invItem.GroupOwned; + llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions; + llsdItem.permissions.owner_id = invItem.Owner; + llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions; + llsdItem.sale_info = new LLSDSaleInfo(); + llsdItem.sale_info.sale_price = invItem.SalePrice; + switch (invItem.SaleType) + { + default: + llsdItem.sale_info.sale_type = "not"; + break; + case 1: + llsdItem.sale_info.sale_type = "original"; + break; + case 2: + llsdItem.sale_info.sale_type = "copy"; + break; + case 3: + llsdItem.sale_info.sale_type = "contents"; + break; + } + + return llsdItem; + } + + } +} diff --git a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescServerConnector.cs b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescServerConnector.cs new file mode 100644 index 0000000000..92eeb140d0 --- /dev/null +++ b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescServerConnector.cs @@ -0,0 +1,76 @@ +/* + * 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 Nini.Config; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Server.Handlers.Base; +using OpenMetaverse; + +namespace OpenSim.Capabilities.Handlers +{ + public class WebFetchInvDescServerConnector : ServiceConnector + { + private IInventoryService m_InventoryService; + private ILibraryService m_LibraryService; + private string m_ConfigName = "CapsService"; + + public WebFetchInvDescServerConnector(IConfigSource config, IHttpServer server, string configName) : + base(config, server, configName) + { + if (configName != String.Empty) + m_ConfigName = configName; + + IConfig serverConfig = config.Configs[m_ConfigName]; + if (serverConfig == null) + throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName)); + + string invService = serverConfig.GetString("InventoryService", String.Empty); + + if (invService == String.Empty) + throw new Exception("No InventoryService in config file"); + + Object[] args = new Object[] { config }; + m_InventoryService = + ServerUtils.LoadPlugin(invService, args); + + if (m_InventoryService == null) + throw new Exception(String.Format("Failed to load InventoryService from {0}; config is {1}", invService, m_ConfigName)); + + string libService = serverConfig.GetString("LibraryService", String.Empty); + m_LibraryService = + ServerUtils.LoadPlugin(libService, args); + + WebFetchInvDescHandler webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService); + IRequestHandler reqHandler = new RestStreamHandler("POST", "/CAPS/WebFetchInvDesc/" /*+ UUID.Random()*/, webFetchHandler.FetchInventoryDescendentsRequest); + server.AddStreamHandler(reqHandler); + } + + } +} diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index 7945d5e5ca..2f1b9aa61d 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -81,7 +81,6 @@ namespace OpenSim.Region.ClientStack.Linden private IAssetService m_assetService; private bool m_dumpAssetsToFile; private string m_regionName; - private object m_fetchLock = new Object(); public BunchOfCaps(Scene scene, Caps caps) { @@ -211,8 +210,12 @@ namespace OpenSim.Region.ClientStack.Linden return string.Empty; } - // WARNING: Add the external too - string result = LLSDHelpers.SerialiseLLSDReply(m_HostCapsObj.CapsHandlers.CapsDetails); + Hashtable caps = m_HostCapsObj.CapsHandlers.CapsDetails; + // Add the external too + foreach (KeyValuePair kvp in m_HostCapsObj.ExternalCapsHandlers) + caps[kvp.Key] = kvp.Value; + + string result = LLSDHelpers.SerialiseLLSDReply(caps); //m_log.DebugFormat("[CAPS] CapsRequest {0}", result); @@ -505,283 +508,7 @@ namespace OpenSim.Region.ClientStack.Linden } } - /// - /// Processes a fetch inventory request and sends the reply - /// - /// - /// - /// - /// - // Request is like: - // - // folders - // - // - // fetch-folders1fetch-items1folder-id8e1e3a30-b9bf-11dc-95ff-0800200c9a66owner-id11111111-1111-0000-0000-000100bba000sort-order1 - // - // - // - // - // - // multiple fetch-folder maps are allowed within the larger folders map. - public string FetchInventoryRequest(string request, string path, string param) - { - // string unmodifiedRequest = request.ToString(); - - //m_log.DebugFormat("[AGENT INVENTORY]: Received CAPS fetch inventory request {0}", unmodifiedRequest); - m_log.Debug("[CAPS]: Inventory Request in region: " + m_regionName); - - Hashtable hash = new Hashtable(); - try - { - hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); - } - catch (LLSD.LLSDParseException pe) - { - m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message); - m_log.Error("Request: " + request.ToString()); - } - - ArrayList foldersrequested = (ArrayList)hash["folders"]; - - string response = ""; - - for (int i = 0; i < foldersrequested.Count; i++) - { - string inventoryitemstr = ""; - Hashtable inventoryhash = (Hashtable)foldersrequested[i]; - - LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); - LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest); - LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest); - - inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); - inventoryitemstr = inventoryitemstr.Replace("folders", ""); - inventoryitemstr = inventoryitemstr.Replace("", ""); - - response += inventoryitemstr; - } - - if (response.Length == 0) - { - // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants. - // Therefore, I'm concluding that the client only has so many threads available to do requests - // and when a thread stalls.. is stays stalled. - // Therefore we need to return something valid - response = "folders"; - } - else - { - response = "folders" + response + ""; - } - - //m_log.DebugFormat("[AGENT INVENTORY]: Replying to CAPS fetch inventory request with following xml"); - //m_log.Debug(Util.GetFormattedXml(response)); - - return response; - } - - public string FetchInventoryDescendentsRequest(string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - // nasty temporary hack here, the linden client falsely - // identifies the uuid 00000000-0000-0000-0000-000000000000 - // as a string which breaks us - // - // correctly mark it as a uuid - // - request = request.Replace("00000000-0000-0000-0000-000000000000", "00000000-0000-0000-0000-000000000000"); - - // another hack 1 results in a - // System.ArgumentException: Object type System.Int32 cannot - // be converted to target type: System.Boolean - // - request = request.Replace("fetch_folders0", "fetch_folders0"); - request = request.Replace("fetch_folders1", "fetch_folders1"); - - Hashtable hash = new Hashtable(); - try - { - hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); - } - catch (LLSD.LLSDParseException pe) - { - m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message); - m_log.Error("Request: " + request.ToString()); - } - - ArrayList foldersrequested = (ArrayList)hash["folders"]; - - string response = ""; - lock (m_fetchLock) - { - for (int i = 0; i < foldersrequested.Count; i++) - { - string inventoryitemstr = ""; - Hashtable inventoryhash = (Hashtable)foldersrequested[i]; - - LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); - - try - { - LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest); - } - catch (Exception e) - { - m_log.Debug("[CAPS]: caught exception doing OSD deserialize" + e); - } - LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest); - - inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); - inventoryitemstr = inventoryitemstr.Replace("folders", ""); - inventoryitemstr = inventoryitemstr.Replace("", ""); - - response += inventoryitemstr; - } - - - if (response.Length == 0) - { - // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants. - // Therefore, I'm concluding that the client only has so many threads available to do requests - // and when a thread stalls.. is stays stalled. - // Therefore we need to return something valid - response = "folders"; - } - else - { - response = "folders" + response + ""; - } - - //m_log.DebugFormat("[CAPS]: Replying to CAPS fetch inventory request with following xml"); - //m_log.Debug("[CAPS] "+response); - - } - return response; - } - - - - /// - /// Construct an LLSD reply packet to a CAPS inventory request - /// - /// - /// - private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch) - { - LLSDInventoryDescendents reply = new LLSDInventoryDescendents(); - LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents(); - contents.agent_id = m_HostCapsObj.AgentID; - contents.owner_id = invFetch.owner_id; - contents.folder_id = invFetch.folder_id; - - reply.folders.Array.Add(contents); - InventoryCollection inv = new InventoryCollection(); - inv.Folders = new List(); - inv.Items = new List(); - int version = 0; - if (CAPSFetchInventoryDescendents != null) - { - inv = CAPSFetchInventoryDescendents(m_HostCapsObj.AgentID, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version); - } - - if (inv.Folders != null) - { - foreach (InventoryFolderBase invFolder in inv.Folders) - { - contents.categories.Array.Add(ConvertInventoryFolder(invFolder)); - } - } - - if (inv.Items != null) - { - foreach (InventoryItemBase invItem in inv.Items) - { - contents.items.Array.Add(ConvertInventoryItem(invItem)); - } - } - - contents.descendents = contents.items.Array.Count + contents.categories.Array.Count; - contents.version = version; - - return reply; - } - - /// - /// Convert an internal inventory folder object into an LLSD object. - /// - /// - /// - private LLSDInventoryFolder ConvertInventoryFolder(InventoryFolderBase invFolder) - { - LLSDInventoryFolder llsdFolder = new LLSDInventoryFolder(); - llsdFolder.folder_id = invFolder.ID; - llsdFolder.parent_id = invFolder.ParentID; - llsdFolder.name = invFolder.Name; - if (invFolder.Type < 0 || invFolder.Type >= TaskInventoryItem.Types.Length) - llsdFolder.type = "-1"; - else - llsdFolder.type = TaskInventoryItem.Types[invFolder.Type]; - llsdFolder.preferred_type = "-1"; - - return llsdFolder; - } - - /// - /// Convert an internal inventory item object into an LLSD object. - /// - /// - /// - private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem) - { - LLSDInventoryItem llsdItem = new LLSDInventoryItem(); - llsdItem.asset_id = invItem.AssetID; - llsdItem.created_at = invItem.CreationDate; - llsdItem.desc = invItem.Description; - llsdItem.flags = (int)invItem.Flags; - llsdItem.item_id = invItem.ID; - llsdItem.name = invItem.Name; - llsdItem.parent_id = invItem.Folder; - try - { - // TODO reevaluate after upgrade to libomv >= r2566. Probably should use UtilsConversions. - llsdItem.type = TaskInventoryItem.Types[invItem.AssetType]; - llsdItem.inv_type = TaskInventoryItem.InvTypes[invItem.InvType]; - } - catch (Exception e) - { - m_log.Error("[CAPS]: Problem setting asset/inventory type while converting inventory item " + invItem.Name + " to LLSD:", e); - } - llsdItem.permissions = new LLSDPermissions(); - llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid; - llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions; - llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions; - llsdItem.permissions.group_id = invItem.GroupID; - llsdItem.permissions.group_mask = (int)invItem.GroupPermissions; - llsdItem.permissions.is_owner_group = invItem.GroupOwned; - llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions; - llsdItem.permissions.owner_id = m_HostCapsObj.AgentID; - llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions; - llsdItem.sale_info = new LLSDSaleInfo(); - llsdItem.sale_info.sale_price = invItem.SalePrice; - switch (invItem.SaleType) - { - default: - llsdItem.sale_info.sale_type = "not"; - break; - case 1: - llsdItem.sale_info.sale_type = "original"; - break; - case 2: - llsdItem.sale_info.sale_type = "copy"; - break; - case 3: - llsdItem.sale_info.sale_type = "contents"; - break; - } - - return llsdItem; - } /// /// diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs new file mode 100644 index 0000000000..55f220d163 --- /dev/null +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -0,0 +1,131 @@ +/* + * 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; +using System.Reflection; +using log4net; +using Nini.Config; +using Mono.Addins; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using Caps = OpenSim.Framework.Capabilities.Caps; +using OpenSim.Capabilities.Handlers; + +namespace OpenSim.Region.ClientStack.Linden +{ + + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class WebFetchInvDescModule : INonSharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private Scene m_scene; + + private IInventoryService m_InventoryService; + private ILibraryService m_LibraryService; + private bool m_Enabled = false; + private string m_URL; + + #region ISharedRegionModule Members + + public void Initialise(IConfigSource source) + { + IConfig config = source.Configs["ClientStack.LindenCaps"]; + if (config == null) + return; + + m_URL = config.GetString("Cap_WebFetchInventoryDescendents", string.Empty); + // Cap doesn't exist + if (m_URL != string.Empty) + m_Enabled = true; + } + + public void AddRegion(Scene s) + { + if (!m_Enabled) + return; + + m_scene = s; + } + + public void RemoveRegion(Scene s) + { + m_scene.EventManager.OnRegisterCaps -= RegisterCaps; + m_scene = null; + } + + public void RegionLoaded(Scene s) + { + if (!m_Enabled) + return; + + m_InventoryService = m_scene.InventoryService; ; + m_LibraryService = m_scene.LibraryService; + m_scene.EventManager.OnRegisterCaps += RegisterCaps; + } + + public void PostInitialise() + { + } + + public void Close() { } + + public string Name { get { return "WebFetchInvDescModule"; } } + + public Type ReplaceableInterface + { + get { return null; } + } + + #endregion + + public void RegisterCaps(UUID agentID, Caps caps) + { + UUID capID = UUID.Random(); + + //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); + if (m_URL == "localhost") + { + m_log.InfoFormat("[WEBFETCHINVENTORYDESCENDANTS]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); + WebFetchInvDescHandler webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService); + IRequestHandler reqHandler = new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), webFetchHandler.FetchInventoryDescendentsRequest); + caps.RegisterHandler("WebFetchInventoryDescendents", reqHandler); + } + else + { + m_log.InfoFormat("[WEBFETCHINVENTORYDESCENDANTS]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); + caps.RegisterHandler("WebFetchInventoryDescendents", m_URL); + } + } + + } +} From 6b52c1d6cdded66993b55d69dee3793e6b98f8c6 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 2 May 2011 16:16:10 -0700 Subject: [PATCH 31/41] Fix the GetTexture path to /CAPS/GetTexture for now until we have real capabilities. --- .../Handlers/GetTexture/GetTextureServerConnector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs index 0335eace8b..0d072f71ff 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs @@ -62,7 +62,7 @@ namespace OpenSim.Capabilities.Handlers if (m_AssetService == null) throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName)); - server.AddStreamHandler(new GetTextureHandler("/CAPS/" + UUID.Random() + "/", m_AssetService)); + server.AddStreamHandler(new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService)); } } From ac9697edbebd8c4e59191823950dbda08207177b Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 2 May 2011 19:45:47 -0700 Subject: [PATCH 32/41] Fixed: EventQueueGet and other caps were being wrongly deregistered. Also CapabilitiesModule was being instantiated twice (damn Mono.Addins). --- .../ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 2 -- .../Linden/Caps/EventQueue/EventQueueGetModule.cs | 6 +++--- .../Region/CoreModules/Resources/CoreModulePlugin.addin.xml | 1 - 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index 2f1b9aa61d..95713e9b87 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -112,8 +112,6 @@ namespace OpenSim.Region.ClientStack.Linden /// public void RegisterHandlers() { - m_HostCapsObj.DeregisterHandlers(); - string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; RegisterRegionServiceHandlers(capsBase); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 4a8bb53584..139d8b8902 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -272,9 +272,9 @@ namespace OpenSim.Region.ClientStack.Linden public void OnRegisterCaps(UUID agentID, Caps caps) { // Register an event queue for the client - + //m_log.DebugFormat( - // "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}", + // "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}", // agentID, caps, m_scene.RegionInfo.RegionName); // Let's instantiate a Queue for this agent right now @@ -317,7 +317,7 @@ namespace OpenSim.Region.ClientStack.Linden { return ProcessQueue(m_dhttpMethod, agentID, caps); })); - + // This will persist this beyond the expiry of the caps handlers MainServer.Instance.AddPollServiceHTTPHandler( capsBase + EventQueueGetUUID.ToString() + "/", EventQueuePoll, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID)); diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml index a0009a869f..8a6735f378 100644 --- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml +++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml @@ -17,7 +17,6 @@ - From 98b84802e40b872a505575088c2e7127f619d24b Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 2 May 2011 20:19:36 -0700 Subject: [PATCH 33/41] Changed the defaults, so that it behaves exactly is it has been behaving (no WebFetch cap by default). --- .../Framework/Caps/CapabilitiesModule.cs | 2 + bin/OpenSim.ini.example | 14 +++ bin/OpenSimDefaults.ini | 89 ++++++++++--------- 3 files changed, 65 insertions(+), 40 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs index 5e22c8c560..111d80859c 100644 --- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs @@ -239,6 +239,8 @@ namespace OpenSim.Region.CoreModules.Framework Uri uri = new Uri(kvp2.Value.ToString()); caps.AppendFormat(" {0} = {1}\n", kvp2.Key, uri.PathAndQuery); } + foreach (KeyValuePair kvp3 in kvp.Value.ExternalCapsHandlers) + caps.AppendFormat(" {0} = {1}\n", kvp3.Key, kvp3.Value); } MainConsole.Instance.Output(caps.ToString()); diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 5389b4455a..13dc9a67ab 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -292,6 +292,20 @@ ;; building's lights to possibly not be rendered. ; DisableFacelights = "false" +[ClientStack.LindenCaps] + ;; For the long list of capabilities, see OpenSimDefaults.ini + ;; Here are the few ones you may want to change. Possible values + ;; are: + ;; "" -- empty, capability disabled + ;; "localhost" -- capability enabled and served by the simulator + ;; "" -- capability enabled and served by some other server + ;; + ; These are enabled by default to localhost. Change if you see fit. + Cap_GetTexture = "localhost" + Cap_GetMesh = "localhost" + ; This is disabled by default. Change if you see fit. Note that + ; serving this cap from the simulators may lead to poor performace. + Cap_WebFetchInventoryDescendents = "" [Chat] ;# {whisper_distance} {} {Distance at which a whisper is heard, in meters?} {} 10 diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 35287b1313..6d2d54daca 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -409,64 +409,73 @@ ;DisableFacelights = "false" [ClientStack.LindenCaps] - Cap_AttachmentResources = "localhost" - Cap_AvatarPickerSearch = "localhost" - Cap_ChatSessionRequest = "localhost" - Cap_CopyInventoryFromNotecard = "localhost" - Cap_DispatchRegionInfo = "localhost" - Cap_EstateChangeInfo = "localhost" + ;; Long list of capabilities taken from + ;; http://wiki.secondlife.com/wiki/Current_Sim_Capabilities + ;; Not all are supported by OpenSim. The ones supported are + ;; set to localhost. These defaults can be overwritten + ;; in OpenSim.ini + ;; + Cap_AttachmentResources = "" + Cap_AvatarPickerSearch = "" + Cap_ChatSessionRequest = "" + Cap_CopyInventoryFromNotecard = "" + Cap_DispatchRegionInfo = "" + Cap_EstateChangeInfo = "" Cap_EventQueueGet = "localhost" - Cap_FetchInventory = "localhost" + Cap_FetchInventory = "" Cap_ObjectMedia = "localhost" Cap_ObjectMediaNavigate = "localhost" - Cap_FetchLib = "localhost" - Cap_FetchLibDescendents = "localhost" - Cap_GetDisplayNames = "localhost" + Cap_FetchLib = "" + Cap_FetchLibDescendents = "" + Cap_GetDisplayNames = "" Cap_GetTexture = "localhost" Cap_GetMesh = "localhost" - Cap_GetObjectCost = "localhost" - Cap_GetObjectPhysicsData = "localhost" - Cap_GroupProposalBallot = "localhost" - Cap_HomeLocation = "localhost" - Cap_LandResources = "localhost" + Cap_GetObjectCost = "" + Cap_GetObjectPhysicsData = "" + Cap_GroupProposalBallot = "" + Cap_HomeLocation = "" + Cap_LandResources = "" Cap_MapLayer = "localhost" Cap_MapLayerGod = "localhost" Cap_NewFileAgentInventory = "localhost" Cap_NewFileAgentInventoryVariablePrice = "localhost" Cap_ObjectAdd = "localhost" Cap_ParcelPropertiesUpdate = "localhost" - Cap_ParcelMediaURLFilterList = "localhost" - Cap_ParcelNavigateMedia = "localhost" - Cap_ParcelVoiceInfoRequest = "localhost" - Cap_ProductInfoRequest = "localhost" - Cap_ProvisionVoiceAccountRequest = "localhost" + Cap_ParcelMediaURLFilterList = "" + Cap_ParcelNavigateMedia = "" + Cap_ParcelVoiceInfoRequest = "" + Cap_ProductInfoRequest = "" + Cap_ProvisionVoiceAccountRequest = "" Cap_RemoteParcelRequest = "localhost" - Cap_RequestTextureDownload = "localhost" - Cap_SearchStatRequest = "localhost" - Cap_SearchStatTracking = "localhost" - Cap_SendPostcard = "localhost" - Cap_SendUserReport = "localhost" - Cap_SendUserReportWithScreenshot = "localhost" - Cap_ServerReleaseNotes = "localhost" - Cap_SimConsole = "localhost" - Cap_SimulatorFeatures = "localhost" - Cap_SetDisplayName = "localhost" - Cap_StartGroupProposal = "localhost" - Cap_TextureStats = "localhost" - Cap_UntrustedSimulatorMessage = "localhost" - Cap_UpdateAgentInformation = "localhost" - Cap_UpdateAgentLanguage = "localhost" - Cap_UpdateGestureAgentInventory = "localhost" + Cap_RequestTextureDownload = "" + Cap_SearchStatRequest = "" + Cap_SearchStatTracking = "" + Cap_SendPostcard = "" + Cap_SendUserReport = "" + Cap_SendUserReportWithScreenshot = "" + Cap_ServerReleaseNotes = "" + Cap_SimConsole = "" + Cap_SimulatorFeatures = "" + Cap_SetDisplayName = "" + Cap_StartGroupProposal = "" + Cap_TextureStats = "" + Cap_UntrustedSimulatorMessage = "" + Cap_UpdateAgentInformation = "" + Cap_UpdateAgentLanguage = "" + Cap_UpdateGestureAgentInventory = "" Cap_UpdateNotecardAgentInventory = "localhost" Cap_UpdateScriptAgent = "localhost" - Cap_UpdateGestureTaskInventory = "localhost" + Cap_UpdateGestureTaskInventory = "" Cap_UpdateNotecardTaskInventory = "localhost" Cap_UpdateScriptTask = "localhost" Cap_UploadBakedTexture = "localhost" Cap_UploadObjectAsset = "localhost" - Cap_ViewerStartAuction = "localhost" - Cap_ViewerStats = "localhost" - Cap_WebFetchInventoryDescendents = "localhost" + Cap_ViewerStartAuction = "" + Cap_ViewerStats = "" + ; This last one is supported by OpenSim, but may + ; lead to poor sim performance if served by the simulators, + ; so it is disabled by default. + Cap_WebFetchInventoryDescendents = "" [Chat] ; Controls whether the chat module is enabled. Default is true. From 13ab00e45a1e52b4668a472130eb83cdf45850ca Mon Sep 17 00:00:00 2001 From: dahlia Date: Tue, 3 May 2011 19:47:50 -0700 Subject: [PATCH 34/41] adjust terse avatar update filtering to send updates when distance traveled does not match expected distance, rather than at a fixed time period. this should smooth avatar motion somewhat when moving in a straight line and velocity is constant. --- .../Region/Framework/Scenes/ScenePresence.cs | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 5b86735ef3..feab35cbd7 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2395,6 +2395,7 @@ namespace OpenSim.Region.Framework.Scenes // vars to support reduced update frequency when velocity is unchanged private Vector3 lastVelocitySentToAllClients = Vector3.Zero; + private Vector3 lastPositionSentToAllClients = Vector3.Zero; private int lastTerseUpdateToAllClientsTick = Util.EnvironmentTickCount(); /// @@ -2404,14 +2405,27 @@ namespace OpenSim.Region.Framework.Scenes { int currentTick = Util.EnvironmentTickCount(); - // decrease update frequency when avatar is moving but velocity is not changing + // Decrease update frequency when avatar is moving but velocity is + // not changing. + // If there is a mismatch between distance travelled and expected + // distance based on last velocity sent and velocity hasnt changed, + // then send a new terse update + + float timeSinceLastUpdate = (currentTick - lastTerseUpdateToAllClientsTick) * 0.001f; + + Vector3 expectedPosition = lastPositionSentToAllClients + lastVelocitySentToAllClients * timeSinceLastUpdate; + + float absoluteDistanceError = (float)Math.Abs(Vector3.Distance(m_pos, expectedPosition)); + + if (m_velocity.Length() < 0.01f - || Vector3.Distance(lastVelocitySentToAllClients, m_velocity) > 0.01f - || currentTick - lastTerseUpdateToAllClientsTick > 1500) + || absoluteDistanceError > 0.25f // arbitrary distance error threshold + || Vector3.Distance(lastVelocitySentToAllClients, m_velocity) > 0.01f) { m_perfMonMS = currentTick; lastVelocitySentToAllClients = m_velocity; lastTerseUpdateToAllClientsTick = currentTick; + lastPositionSentToAllClients = m_pos; m_scene.ForEachClient(SendTerseUpdateToClient); From 4c59d57596d8c955a3634d9ffc35b4557e0b56fe Mon Sep 17 00:00:00 2001 From: dahlia Date: Wed, 4 May 2011 03:29:06 -0700 Subject: [PATCH 35/41] use getters instead of member variables in velocity network filter code and add some more descriptive comments. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index feab35cbd7..1e90d564a2 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2415,17 +2415,19 @@ namespace OpenSim.Region.Framework.Scenes Vector3 expectedPosition = lastPositionSentToAllClients + lastVelocitySentToAllClients * timeSinceLastUpdate; - float absoluteDistanceError = (float)Math.Abs(Vector3.Distance(m_pos, expectedPosition)); + float distanceError = Vector3.Distance(OffsetPosition, expectedPosition); + float speed = Velocity.Length(); + float velocidyDiff = Vector3.Distance(lastVelocitySentToAllClients, Velocity); - if (m_velocity.Length() < 0.01f - || absoluteDistanceError > 0.25f // arbitrary distance error threshold - || Vector3.Distance(lastVelocitySentToAllClients, m_velocity) > 0.01f) + if (speed < 0.01f // allow rotation updates if avatar position is unchanged + || Math.Abs(distanceError) > 0.25f // arbitrary distance error threshold + || velocidyDiff > 0.01f) // did velocity change from last update? { m_perfMonMS = currentTick; - lastVelocitySentToAllClients = m_velocity; + lastVelocitySentToAllClients = Velocity; lastTerseUpdateToAllClientsTick = currentTick; - lastPositionSentToAllClients = m_pos; + lastPositionSentToAllClients = OffsetPosition; m_scene.ForEachClient(SendTerseUpdateToClient); From df7dacd004de3742f183656f2ce44a11e30a7224 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 4 May 2011 11:34:18 -0700 Subject: [PATCH 36/41] Fixes mantis #5461. --- .../Framework/InventoryAccess/InventoryAccessModule.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 6b3df9ddd6..1370b1fe8e 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -371,7 +371,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } // This is a hook to do some per-asset post-processing for subclasses that need that - ExportAsset(remoteClient.AgentId, assetID); + if (remoteClient != null) + ExportAsset(remoteClient.AgentId, assetID); return assetID; } From 6c503e75acb459e4cdda423bbfbf4cb22611315e Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 4 May 2011 12:04:35 -0700 Subject: [PATCH 37/41] Put the previous state back in the attachments in case the agent transfer fails. --- .../EntityTransfer/EntityTransferModule.cs | 4 ++++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index b985fbb371..e38006752a 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1759,11 +1759,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected void ReInstantiateScripts(ScenePresence sp) { + int i = 0; sp.Attachments.ForEach(delegate(SceneObjectGroup sog) { + sog.SetState(sp.InTransitScriptStates[i++], sp.Scene); sog.CreateScriptInstances(0, false, sp.Scene.DefaultScriptEngine, 0); sog.ResumeScripts(); }); + + sp.InTransitScriptStates.Clear(); } #endregion diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 1e90d564a2..631c91b29e 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -231,6 +231,16 @@ namespace OpenSim.Region.Framework.Scenes // holds the seed cap for the child agent in that region private Dictionary m_knownChildRegions = new Dictionary(); + /// + /// Copy of the script states while the agent is in transit. This state may + /// need to be placed back in case of transfer fail. + /// + public List InTransitScriptStates + { + get { return m_InTransitScriptStates; } + } + private List m_InTransitScriptStates = new List(); + /// /// Implemented Control Flags /// @@ -3142,6 +3152,7 @@ namespace OpenSim.Region.Framework.Scenes cAgent.AttachmentObjects = new List(); cAgent.AttachmentObjectStates = new List(); IScriptModule se = m_scene.RequestModuleInterface(); + m_InTransitScriptStates.Clear(); foreach (SceneObjectGroup sog in m_attachments) { // We need to make a copy and pass that copy @@ -3151,7 +3162,9 @@ namespace OpenSim.Region.Framework.Scenes ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; ((SceneObjectGroup)clone).RootPart.IsAttachment = false; cAgent.AttachmentObjects.Add(clone); - cAgent.AttachmentObjectStates.Add(sog.GetStateSnapshot()); + string state = sog.GetStateSnapshot(); + cAgent.AttachmentObjectStates.Add(state); + m_InTransitScriptStates.Add(state); // Let's remove the scripts of the original object here sog.RemoveScriptInstances(true); } From e8944d6c3163d25d7f6a8f278546b42db62b6b30 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 4 May 2011 20:40:25 -0700 Subject: [PATCH 38/41] Test m_Enabled on RemoveRegion. --- OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs | 3 +++ OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs | 3 +++ .../Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs | 3 +++ 3 files changed, 9 insertions(+) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs index f2f765c3e8..e0807eea98 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs @@ -87,6 +87,9 @@ namespace OpenSim.Region.ClientStack.Linden public void RemoveRegion(Scene scene) { + if (!m_Enabled) + return; + m_scene.EventManager.OnRegisterCaps -= RegisterCaps; m_scene = null; } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index 564ef31f93..35eedb48ab 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs @@ -90,6 +90,9 @@ namespace OpenSim.Region.ClientStack.Linden public void RemoveRegion(Scene s) { + if (!m_Enabled) + return; + m_scene.EventManager.OnRegisterCaps -= RegisterCaps; m_scene = null; } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 55f220d163..94629a2ee9 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -79,6 +79,9 @@ namespace OpenSim.Region.ClientStack.Linden public void RemoveRegion(Scene s) { + if (!m_Enabled) + return; + m_scene.EventManager.OnRegisterCaps -= RegisterCaps; m_scene = null; } From 4f588ad7ba82b018b032041803c51aa3b93fff67 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 5 May 2011 12:13:56 +0100 Subject: [PATCH 39/41] Fix up some paths in prebuild --- prebuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/prebuild.xml b/prebuild.xml index cc7743636f..328abcec42 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -681,10 +681,10 @@ - - - - + + + + From f5bb6edd85776594551dcb35b31384f80e73d36e Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 5 May 2011 13:01:46 +0100 Subject: [PATCH 40/41] Squish a warning --- OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs index fa5f7555d6..2ecfa3c23b 100644 --- a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs +++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs @@ -33,7 +33,6 @@ using OpenSim.Services.Interfaces; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Server.Handlers.Base; using OpenSim.Framework.Servers; -using OpenSim.Framework.Servers.HttpServer; using OpenMetaverse; From 1bdac6ed190466684fd50424908f3ebeaf91699c Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 5 May 2011 13:27:44 +0100 Subject: [PATCH 41/41] Fix up nant linux build break --- prebuild.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/prebuild.xml b/prebuild.xml index 328abcec42..a07ad14154 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1323,6 +1323,7 @@ + @@ -1623,7 +1624,7 @@ - +