From 4d34763f8c90dfe87a8a5930bf05fe36b86d15df Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 17 May 2012 23:33:26 +0100 Subject: [PATCH 01/15] Check agent limit against root agent count rather than both root and child agents From sl docs such as http://community.secondlife.com/t5/English-Knowledge-Base/Managing-Private-Regions/ta-p/700115 agent should apply to avatars only. This makes sense from a user perspective, and also from a code perspective since child agents with no physics or actions take up a fraction of root agent resources. As such, the check is now only performed in Scene.QueryAccess() - cross and teleport check this before allowing an agent to translocate. This also removes an off-by-one error that could occur in certain circumstances on teleport when a new child agent was double counted when a pre-teleport agent update was performed. This does not affect an existing bug where limits or other QueryAccess() checks are not applied to avatars logging directly into a region. --- OpenSim/Region/Framework/Scenes/Scene.cs | 47 +++++++++++++------ OpenSim/Region/Framework/Scenes/SceneGraph.cs | 5 -- .../Region/Framework/Scenes/ScenePresence.cs | 13 ++++- 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 2bf3638f6c..3cce370262 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2646,7 +2646,8 @@ namespace OpenSim.Region.Framework.Scenes if (sp == null) { m_log.DebugFormat( - "[SCENE]: Adding new child scene presence {0} to scene {1} at pos {2}", client.Name, RegionInfo.RegionName, client.StartPos); + "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", + client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); m_clientManager.Add(client); SubscribeToClientEvents(client); @@ -3905,8 +3906,7 @@ namespace OpenSim.Region.Framework.Scenes // XPTO: if this agent is not allowed here as root, always return false - // We have to wait until the viewer contacts this region after receiving EAC. - // That calls AddNewClient, which finally creates the ScenePresence + // TODO: This check should probably be in QueryAccess(). ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); if (nearestParcel == null) { @@ -3917,14 +3917,8 @@ namespace OpenSim.Region.Framework.Scenes return false; } - int num = m_sceneGraph.GetNumberOfScenePresences(); - - if (num >= RegionInfo.RegionSettings.AgentLimit) - { - if (!Permissions.IsAdministrator(cAgentData.AgentID)) - return false; - } - + // We have to wait until the viewer contacts this region after receiving EAC. + // That calls AddNewClient, which finally creates the ScenePresence ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); if (childAgentUpdate != null) @@ -3968,14 +3962,28 @@ namespace OpenSim.Region.Framework.Scenes return false; } + /// + /// Poll until the requested ScenePresence appears or we timeout. + /// + /// The scene presence is found, else null. + /// protected virtual ScenePresence WaitGetScenePresence(UUID agentID) { int ntimes = 10; - ScenePresence childAgentUpdate = null; - while ((childAgentUpdate = GetScenePresence(agentID)) == null && (ntimes-- > 0)) + ScenePresence sp = null; + while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0)) Thread.Sleep(1000); - return childAgentUpdate; + if (sp == null) + m_log.WarnFormat( + "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout", + agentID, RegionInfo.RegionName); +// else +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Found presence {0} {1} {2} in {3} after {4} waits", +// sp.Name, sp.UUID, sp.IsChildAgent ? "child" : "root", RegionInfo.RegionName, 10 - ntimes); + + return sp; } public virtual bool IncomingRetrieveRootAgent(UUID id, out IAgentData agent) @@ -5177,13 +5185,22 @@ namespace OpenSim.Region.Framework.Scenes // child agent creation, thereby emulating the SL behavior. public bool QueryAccess(UUID agentID, Vector3 position, out string reason) { - int num = m_sceneGraph.GetNumberOfScenePresences(); + // FIXME: Root agent count is currently known to be inaccurate. This forces a recount before we check. + // However, the long term fix is to make sure root agent count is always accurate. + m_sceneGraph.RecalculateStats(); + + int num = m_sceneGraph.GetRootAgentCount(); if (num >= RegionInfo.RegionSettings.AgentLimit) { if (!Permissions.IsAdministrator(agentID)) { reason = "The region is full"; + + m_log.DebugFormat( + "[SCENE]: Denying presence with id {0} entry into {1} since region is at agent limit of {2}", + agentID, RegionInfo.RegionName, RegionInfo.RegionSettings.AgentLimit); + return false; } } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 481592277d..ddf1550c0a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -779,11 +779,6 @@ namespace OpenSim.Region.Framework.Scenes return m_scenePresenceArray; } - public int GetNumberOfScenePresences() - { - return m_scenePresenceArray.Count; - } - /// /// Request a scene presence by UUID. Fast, indexed lookup. /// diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index bdcef71159..558fd9c564 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1169,6 +1169,12 @@ namespace OpenSim.Region.Framework.Scenes Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); m_callbackURI = null; } +// else +// { +// m_log.DebugFormat( +// "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}", +// client.Name, client.AgentId, m_scene.RegionInfo.RegionName); +// } ValidateAndSendAppearanceAndAgentData(); @@ -2508,7 +2514,7 @@ namespace OpenSim.Region.Framework.Scenes // If we are using the the cached appearance then send it out to everyone if (cachedappearance) { - m_log.DebugFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name); + m_log.DebugFormat("[SCENE PRESENCE]: baked textures are in the cache for {0}", Name); // If the avatars baked textures are all in the cache, then we have a // complete appearance... send it out, if not, then we'll send it when @@ -2970,7 +2976,7 @@ namespace OpenSim.Region.Framework.Scenes public void ChildAgentDataUpdate(AgentData cAgentData) { - //m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); +// m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); if (!IsChildAgent) return; @@ -3110,6 +3116,9 @@ namespace OpenSim.Region.Framework.Scenes m_originRegionID = cAgent.RegionID; m_callbackURI = cAgent.CallbackURI; +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()", +// Name, m_scene.RegionInfo.RegionName, m_callbackURI); m_pos = cAgent.Position; m_velocity = cAgent.Velocity; From b18c8c8e78172abebb82491700a0b5f9f40c1d66 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 17 May 2012 23:59:43 +0100 Subject: [PATCH 02/15] Don't eagerly clear frame collision events when physics actors subscribe and unsubscribe from collisions, in order to avoid a race condition. Since this is done directly from ScenePresence, it can lead to a race condition with the simulator loop. There's no real point doing it anyway since the clear will be done very shortly afterwards by the simulate loop and either there are no events (for a new avatar) or events don't matter (for a departing avatar). This matches existing behaviour in OdePrim --- OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 8397eb4331..1b1c44a95f 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -1261,14 +1261,20 @@ namespace OpenSim.Region.Physics.OdePlugin { m_requestedUpdateFrequency = ms; m_eventsubscription = ms; - CollisionEventsThisFrame.Clear(); + + // Don't clear collision event reporting here. This is called directly from scene code and so can lead + // to a race condition with the simulate loop + _parent_scene.AddCollisionEventReporting(this); } public override void UnSubscribeEvents() { CollisionEventsThisFrame.Clear(); - _parent_scene.RemoveCollisionEventReporting(this); + + // Don't clear collision event reporting here. This is called directly from scene code and so can lead + // to a race condition with the simulate loop + m_requestedUpdateFrequency = 0; m_eventsubscription = 0; } From 6501b1b1bb297eb5ed8a44447f771c7b73b0e905 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 18 May 2012 00:38:29 +0100 Subject: [PATCH 03/15] refactor: move EventQueueGet path generation into common method. Rename some local variables in line with code conventions. Add commented out EQG log lines for future use. --- .../Caps/EventQueue/EventQueueGetModule.cs | 53 ++++++++++++------- .../Region/Physics/OdePlugin/ODECharacter.cs | 2 +- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 1a35d22c3b..005461916c 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -235,19 +235,19 @@ namespace OpenSim.Region.ClientStack.Linden // ClientClosed(client.AgentId); // } - private void ClientClosed(UUID AgentID, Scene scene) + private void ClientClosed(UUID agentID, Scene scene) { -// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", AgentID, m_scene.RegionInfo.RegionName); +// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName); int count = 0; - while (queues.ContainsKey(AgentID) && queues[AgentID].Count > 0 && count++ < 5) + while (queues.ContainsKey(agentID) && queues[agentID].Count > 0 && count++ < 5) { Thread.Sleep(1000); } lock (queues) { - queues.Remove(AgentID); + queues.Remove(agentID); } List removeitems = new List(); @@ -256,7 +256,7 @@ namespace OpenSim.Region.ClientStack.Linden foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys) { // m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID); - if (ky == AgentID) + if (ky == agentID) { removeitems.Add(ky); } @@ -267,7 +267,10 @@ namespace OpenSim.Region.ClientStack.Linden UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky]; m_AvatarQueueUUIDMapping.Remove(ky); - MainServer.Instance.RemovePollServiceHTTPHandler("","/CAPS/EQG/" + eventQueueGetUuid.ToString() + "/"); + string eqgPath = GenerateEqgCapPath(eventQueueGetUuid); + MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath); + +// m_log.DebugFormat("[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1}", eqgPath, agentID); } } @@ -281,7 +284,7 @@ namespace OpenSim.Region.ClientStack.Linden { searchval = m_QueueUUIDAvatarMapping[ky]; - if (searchval == AgentID) + if (searchval == agentID) { removeitems.Add(ky); } @@ -305,6 +308,15 @@ namespace OpenSim.Region.ClientStack.Linden //} } + /// + /// Generate an Event Queue Get handler path for the given eqg uuid. + /// + /// + private string GenerateEqgCapPath(UUID eqgUuid) + { + return string.Format("/CAPS/EQG/{0}/", eqgUuid); + } + public void OnRegisterCaps(UUID agentID, Caps caps) { // Register an event queue for the client @@ -316,8 +328,7 @@ namespace OpenSim.Region.ClientStack.Linden // Let's instantiate a Queue for this agent right now TryGetQueue(agentID); - string capsBase = "/CAPS/EQG/"; - UUID EventQueueGetUUID = UUID.Zero; + UUID eventQueueGetUUID; lock (m_AvatarQueueUUIDMapping) { @@ -325,37 +336,35 @@ namespace OpenSim.Region.ClientStack.Linden if (m_AvatarQueueUUIDMapping.ContainsKey(agentID)) { //m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); - EventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; + eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; } else { - EventQueueGetUUID = UUID.Random(); + eventQueueGetUUID = UUID.Random(); //m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!"); } } lock (m_QueueUUIDAvatarMapping) { - if (!m_QueueUUIDAvatarMapping.ContainsKey(EventQueueGetUUID)) - m_QueueUUIDAvatarMapping.Add(EventQueueGetUUID, agentID); + if (!m_QueueUUIDAvatarMapping.ContainsKey(eventQueueGetUUID)) + m_QueueUUIDAvatarMapping.Add(eventQueueGetUUID, agentID); } lock (m_AvatarQueueUUIDMapping) { if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID)) - m_AvatarQueueUUIDMapping.Add(agentID, EventQueueGetUUID); + m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID); } + string eventQueueGetPath = GenerateEqgCapPath(eventQueueGetUUID); + // Register this as a caps handler // FIXME: Confusingly, we need to register separate as a capability so that the client is told about // EventQueueGet when it receive capability information, but then we replace the rest handler immediately // afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but // really it should be possible to directly register the poll handler as a capability. - caps.RegisterHandler( - "EventQueueGet", - new RestHTTPHandler( - "POST", capsBase + EventQueueGetUUID.ToString() + "/", null)); - + caps.RegisterHandler("EventQueueGet", new RestHTTPHandler("POST", eventQueueGetPath, null)); // delegate(Hashtable m_dhttpMethod) // { // return ProcessQueue(m_dhttpMethod, agentID, caps); @@ -364,9 +373,13 @@ namespace OpenSim.Region.ClientStack.Linden // This will persist this beyond the expiry of the caps handlers // TODO: Add EventQueueGet name/description for diagnostics MainServer.Instance.AddPollServiceHTTPHandler( - capsBase + EventQueueGetUUID.ToString() + "/", + eventQueueGetPath, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID)); +// m_log.DebugFormat( +// "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}", +// eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName); + Random rnd = new Random(Environment.TickCount); lock (m_ids) { diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 1b1c44a95f..54b69a2c73 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -1274,7 +1274,7 @@ namespace OpenSim.Region.Physics.OdePlugin // Don't clear collision event reporting here. This is called directly from scene code and so can lead // to a race condition with the simulate loop - + m_requestedUpdateFrequency = 0; m_eventsubscription = 0; } From 565c73751cd1ac9b09393a0801591ced04d7e635 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 18 May 2012 00:49:39 +0100 Subject: [PATCH 04/15] Invoke log4net configurator in pCampBot.exe in order to get OpenSim sylte logging --- OpenSim/Tools/pCampBot/pCampBot.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OpenSim/Tools/pCampBot/pCampBot.cs b/OpenSim/Tools/pCampBot/pCampBot.cs index 52e750185a..9e82577be5 100644 --- a/OpenSim/Tools/pCampBot/pCampBot.cs +++ b/OpenSim/Tools/pCampBot/pCampBot.cs @@ -29,6 +29,7 @@ using System; using System.Reflection; using System.Threading; using log4net; +using log4net.Config; using Nini.Config; using OpenSim.Framework; using OpenSim.Framework.Console; @@ -52,6 +53,8 @@ namespace pCampBot [STAThread] public static void Main(string[] args) { + XmlConfigurator.Configure(); + IConfig config = ParseConfig(args); if (config.Get("help") != null || config.Get("loginuri") == null) { From 45af29291acd22700d9fc4c442655d2e3f19a0b0 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 18 May 2012 03:43:36 +0100 Subject: [PATCH 05/15] Add level 2 debug eq logging which logs event queue polls. Refactor: eq message logging into common method. --- .../Caps/EventQueue/EventQueueGetModule.cs | 55 +++++++++++-------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 005461916c..6ac19cc5b0 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -109,10 +109,11 @@ namespace OpenSim.Region.ClientStack.Linden "Comms", false, "debug eq", - "debug eq [0|1]", - "Turn on event queue debugging", - "debug eq 1 will turn on event queue debugging. This will log all outgoing event queue messages to clients.\n" - + "debug eq 0 will turn off event queue debugging.", + "debug eq [0|1|2]", + "Turn on event queue debugging", + "<= 0 - turns off all event queue logging", + ">= 1 - turns on outgoing event logging", + ">= 2 - turns on poll notification", HandleDebugEq); } else @@ -270,7 +271,9 @@ namespace OpenSim.Region.ClientStack.Linden string eqgPath = GenerateEqgCapPath(eventQueueGetUuid); MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath); -// m_log.DebugFormat("[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1}", eqgPath, agentID); + m_log.DebugFormat( + "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}", + eqgPath, agentID, m_scene.RegionInfo.RegionName); } } @@ -376,9 +379,9 @@ namespace OpenSim.Region.ClientStack.Linden eventQueueGetPath, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID)); -// m_log.DebugFormat( -// "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}", -// eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName); + m_log.DebugFormat( + "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}", + eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName); Random rnd = new Random(Environment.TickCount); lock (m_ids) @@ -401,9 +404,25 @@ namespace OpenSim.Region.ClientStack.Linden return false; } + /// + /// Logs a debug line for an outbound event queue message if appropriate. + /// + /// Element containing message + private void LogOutboundDebugMessage(OSD element, UUID agentId) + { + if (element is OSDMap) + { + OSDMap ev = (OSDMap)element; + m_log.DebugFormat( + "Eq OUT {0,-30} to {1,-20} {2,-20}", + ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.RegionInfo.RegionName); + } + } + public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request) { -// m_log.DebugFormat("[EVENT QUEUE GET MODULE]: Invoked GetEvents() for {0}", pAgentId); + if (DebugLevel >= 2) + m_log.DebugFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName); Queue queue = TryGetQueue(pAgentId); OSD element; @@ -427,13 +446,8 @@ namespace OpenSim.Region.ClientStack.Linden } else { - if (DebugLevel > 0 && element is OSDMap) - { - OSDMap ev = (OSDMap)element; - m_log.DebugFormat( - "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}", - ev["message"], m_scene.GetScenePresence(pAgentId).Name); - } + if (DebugLevel > 0) + LogOutboundDebugMessage(element, pAgentId); array.Add(element); @@ -443,13 +457,8 @@ namespace OpenSim.Region.ClientStack.Linden { element = queue.Dequeue(); - if (DebugLevel > 0 && element is OSDMap) - { - OSDMap ev = (OSDMap)element; - m_log.DebugFormat( - "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}", - ev["message"], m_scene.GetScenePresence(pAgentId).Name); - } + if (DebugLevel > 0) + LogOutboundDebugMessage(element, pAgentId); array.Add(element); thisID++; From 90722875e8518a6679441b0225ae2f11245bcfe0 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 18 May 2012 03:44:31 +0100 Subject: [PATCH 06/15] Add millisecond logging to pCampBot for debugging purposes --- bin/pCampBot.exe.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/pCampBot.exe.config b/bin/pCampBot.exe.config index 3f19ee855d..9cfb7e91e4 100644 --- a/bin/pCampBot.exe.config +++ b/bin/pCampBot.exe.config @@ -8,7 +8,7 @@ - + From 0147dc63028e2d77a568c6d9d5af1c9f05286f62 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 18 May 2012 03:50:23 +0100 Subject: [PATCH 07/15] Fix build break. Comment out EQG deregister/register logging. --- .../Caps/EventQueue/EventQueueGetModule.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 6ac19cc5b0..ae759caae2 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -110,10 +110,10 @@ namespace OpenSim.Region.ClientStack.Linden false, "debug eq", "debug eq [0|1|2]", - "Turn on event queue debugging", - "<= 0 - turns off all event queue logging", - ">= 1 - turns on outgoing event logging", - ">= 2 - turns on poll notification", + "Turn on event queue debugging" + + "<= 0 - turns off all event queue logging" + + ">= 1 - turns on outgoing event logging" + + ">= 2 - turns on poll notification", HandleDebugEq); } else @@ -271,9 +271,9 @@ namespace OpenSim.Region.ClientStack.Linden string eqgPath = GenerateEqgCapPath(eventQueueGetUuid); MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath); - m_log.DebugFormat( - "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}", - eqgPath, agentID, m_scene.RegionInfo.RegionName); +// m_log.DebugFormat( +// "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}", +// eqgPath, agentID, m_scene.RegionInfo.RegionName); } } @@ -379,9 +379,9 @@ namespace OpenSim.Region.ClientStack.Linden eventQueueGetPath, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID)); - m_log.DebugFormat( - "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}", - eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName); +// m_log.DebugFormat( +// "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}", +// eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName); Random rnd = new Random(Environment.TickCount); lock (m_ids) From c05f87b50c32c08818c291c76e46cb558083d35d Mon Sep 17 00:00:00 2001 From: BlueWall Date: Fri, 18 May 2012 17:47:00 -0400 Subject: [PATCH 08/15] Provide Telehub setting to allow use of landmarks Setting to allow use of landmarks to override telehub routing. Default is off. --- OpenSim/Region/Framework/Scenes/Scene.cs | 7 +++++++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 3 ++- bin/OpenSim.ini.example | 5 +++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 3cce370262..d09b8957cf 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -577,6 +577,12 @@ namespace OpenSim.Region.Framework.Scenes { get { return m_SpawnPointRouting; } } + // allow landmarks to pass + private bool m_TelehubAllowLandmarks; + public bool TelehubAllowLandmarks + { + get { return m_TelehubAllowLandmarks; } + } #endregion Properties @@ -733,6 +739,7 @@ namespace OpenSim.Region.Framework.Scenes m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); m_SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest"); + m_TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false); IConfig packetConfig = m_config.Configs["PacketPool"]; if (packetConfig != null) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 0c66e49ff8..602217596c 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3929,7 +3929,8 @@ namespace OpenSim.Region.Framework.Scenes { if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) || - (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 || + // (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 || + (m_scene.TelehubAllowLandmarks == true ? false : ((m_teleportFlags & TeleportFlags.ViaLandmark) != 0 )) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0) { diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 9f418a40dd..aa29c079ca 100755 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -249,6 +249,11 @@ ;; "sequence" will place the avatar on the next sequential SpawnPoint ; SpawnPointRouting = closest + ;# {TelehubAllowLandmark} {} {Allow users with landmarks to override telehub routing} {true false} false + ;; TelehubAllowLandmark allows users with landmarks to override telehub routing and land at the landmark coordinates when set to true + ;; default is false + ; TelehubAllowLandmark = false + [Estates] ; If these values are commented out then the user will be asked for estate details when required (this is the normal case). ; If these values are uncommented then they will be used to create a default estate as necessary. From 896cd459391809d2fb140fe345c78f8b952232d8 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 18 May 2012 23:55:18 +0100 Subject: [PATCH 09/15] Fix issue where a new outfit folder is not created when a new outfit is saved if there are no previous outfits This was because AddFolder() was disallowing these though they are legal. --- .../Services/InventoryService/XInventoryService.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index 15156d0537..eed88bd391 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -307,14 +307,20 @@ namespace OpenSim.Services.InventoryService if (check != null) return false; - if (folder.Type == (short)AssetType.Folder || folder.Type == (short)AssetType.Unknown || - GetFolderForType(folder.Owner, (AssetType)(folder.Type)) == null) + if (folder.Type == (short)AssetType.Folder + || folder.Type == (short)AssetType.Unknown + || folder.Type == (short)AssetType.OutfitFolder + || GetFolderForType(folder.Owner, (AssetType)(folder.Type)) == null) { XInventoryFolder xFolder = ConvertFromOpenSim(folder); return m_Database.StoreFolder(xFolder); } else - m_log.DebugFormat("[XINVENTORY]: Folder {0} of type {1} already exists", folder.Name, folder.Type); + { + m_log.WarnFormat( + "[XINVENTORY]: Folder of type {0} already exists when tried to add {1} to {2} for {3}", + folder.Type, folder.Name, folder.ParentID, folder.Owner); + } return false; } From 9fa0577c7e4e710a5751c01b568b6453d513558e Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 19 May 2012 00:00:52 +0100 Subject: [PATCH 10/15] Enable FetchInventoryDescendents2 and FetchInventory2 caps by default. This appears to be required now for LL 3.3.1 to work properly. Without this, LL 3.3.1 continually pushes LLInventoryModelFetchDescendentsResponder::error 499 to its log. This cap will be ignored by older viewers - UDP inventory will work normally. --- bin/OpenSimDefaults.ini | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index cb9ef224fb..7962ef8930 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -601,13 +601,12 @@ Cap_ViewerStartAuction = "" Cap_ViewerStats = "" - ; The various fetch inventory caps are supported by OpenSim, but may - ; lead to poor sim performance if served by the simulators, - ; so they are currently disabled by default. + ; Capabilities for fetching inventory over HTTP rather than UDP ; FetchInventoryDescendents2 and FetchInventory2 are the ones used in the latest Linden Lab viewers (from some point in the v2 series and above) + ; It appears that Linden Lab viewer 3.3.1 onwards will not work properly if FetchInventoryDescendents2 and FetchInventory2 are not enabled Cap_WebFetchInventoryDescendents = "" - Cap_FetchInventoryDescendents2 = "" - Cap_FetchInventory2 = "" + Cap_FetchInventoryDescendents2 = "localhost" + Cap_FetchInventory2 = "localhost" [Chat] From 895dadbdbdc0468fd1a0a9e146e1bf65279a2de7 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Fri, 18 May 2012 19:32:26 -0400 Subject: [PATCH 11/15] Cleanup + change properties to set fields with private set : Thanks Justin for the tip. --- OpenSim/Region/Framework/Scenes/Scene.cs | 6 ++++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index d09b8957cf..29eed677bd 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -576,12 +576,14 @@ namespace OpenSim.Region.Framework.Scenes public string SpawnPointRouting { get { return m_SpawnPointRouting; } + private set { m_SpawnPointRouting = value; } } // allow landmarks to pass private bool m_TelehubAllowLandmarks; public bool TelehubAllowLandmarks { get { return m_TelehubAllowLandmarks; } + private set { m_TelehubAllowLandmarks = value; } } #endregion Properties @@ -738,8 +740,8 @@ namespace OpenSim.Region.Framework.Scenes m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); - m_SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest"); - m_TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false); + SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest"); + TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false); IConfig packetConfig = m_config.Configs["PacketPool"]; if (packetConfig != null) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 602217596c..3adafc1b74 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3929,7 +3929,6 @@ namespace OpenSim.Region.Framework.Scenes { if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) || - // (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 || (m_scene.TelehubAllowLandmarks == true ? false : ((m_teleportFlags & TeleportFlags.ViaLandmark) != 0 )) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0) From 247a56593fe132e6412612248ceaacaf324c50d8 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Fri, 18 May 2012 19:56:46 -0400 Subject: [PATCH 12/15] Further refinement on properties --- OpenSim/Region/Framework/Scenes/Scene.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 29eed677bd..5a0f56441f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -569,21 +569,18 @@ namespace OpenSim.Region.Framework.Scenes get { return m_sceneGraph.Entities; } } - // can be closest/random/sequence - private string m_SpawnPointRouting = "closest"; + // used in sequence see: SpawnPoint() private int m_SpawnPoint; + // can be closest/random/sequence public string SpawnPointRouting { - get { return m_SpawnPointRouting; } - private set { m_SpawnPointRouting = value; } + get; private set; } // allow landmarks to pass - private bool m_TelehubAllowLandmarks; public bool TelehubAllowLandmarks { - get { return m_TelehubAllowLandmarks; } - private set { m_TelehubAllowLandmarks = value; } + get; private set; } #endregion Properties From 2b60a5c5d64f38caf243119105416c1101c6eb6c Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 19 May 2012 02:45:17 +0100 Subject: [PATCH 13/15] Add is_megaregion flag into oar control file. Not currently read - for future use. Please do not rely on this remaining here. An adaptation of part of Garmin's patch from http://opensimulator.org/mantis/view.php?id=5975, thanks! Flag only written if the SW corner OAR is saved - this is the only one that captures object data presently (though not land or terrain data). This adds an IRegionCombinerModule interface and the necessary methods on RegionCombinerModule --- .../ArchiveWriteRequestPreparation.cs | 89 +++++++++++++------ .../World/Archiver/ArchiverModule.cs | 20 +++-- .../Interfaces/IRegionCombinerModule.cs | 51 +++++++++++ .../RegionCombinerModule.cs | 22 ++++- 4 files changed, 142 insertions(+), 40 deletions(-) create mode 100644 OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index 5679ad5dcb..838b741fdc 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -67,7 +67,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// Determine whether this archive will save assets. Default is true. /// public bool SaveAssets { get; set; } - + + protected ArchiverModule m_module; protected Scene m_scene; protected Stream m_saveStream; protected Guid m_requestId; @@ -75,13 +76,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// /// Constructor /// - /// + /// Calling module /// The path to which to save data. /// The id associated with this request /// /// If there was a problem opening a stream for the file specified by the savePath /// - public ArchiveWriteRequestPreparation(Scene scene, string savePath, Guid requestId) : this(scene, requestId) + public ArchiveWriteRequestPreparation(ArchiverModule module, string savePath, Guid requestId) : this(module, requestId) { try { @@ -99,17 +100,23 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// /// Constructor. /// - /// + /// Calling module /// The stream to which to save data. /// The id associated with this request - public ArchiveWriteRequestPreparation(Scene scene, Stream saveStream, Guid requestId) : this(scene, requestId) + public ArchiveWriteRequestPreparation(ArchiverModule module, Stream saveStream, Guid requestId) : this(module, requestId) { m_saveStream = saveStream; } - protected ArchiveWriteRequestPreparation(Scene scene, Guid requestId) + protected ArchiveWriteRequestPreparation(ArchiverModule module, Guid requestId) { - m_scene = scene; + m_module = module; + + // FIXME: This is only here for regression test purposes since they do not supply a module. Need to fix + // this. + if (m_module != null) + m_scene = m_module.Scene; + m_requestId = requestId; SaveAssets = true; @@ -364,32 +371,56 @@ namespace OpenSim.Region.CoreModules.World.Archiver //if (majorVersion == 1) //{ // m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR"); - //} + //} + + String s; - StringWriter sw = new StringWriter(); - XmlTextWriter xtw = new XmlTextWriter(sw); - xtw.Formatting = Formatting.Indented; - xtw.WriteStartDocument(); - xtw.WriteStartElement("archive"); - xtw.WriteAttributeString("major_version", majorVersion.ToString()); - xtw.WriteAttributeString("minor_version", minorVersion.ToString()); + using (StringWriter sw = new StringWriter()) + { + using (XmlTextWriter xtw = new XmlTextWriter(sw)) + { + xtw.Formatting = Formatting.Indented; + xtw.WriteStartDocument(); + xtw.WriteStartElement("archive"); + xtw.WriteAttributeString("major_version", majorVersion.ToString()); + xtw.WriteAttributeString("minor_version", minorVersion.ToString()); + + xtw.WriteStartElement("creation_info"); + DateTime now = DateTime.UtcNow; + TimeSpan t = now - new DateTime(1970, 1, 1); + xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString()); + xtw.WriteElementString("id", UUID.Random().ToString()); + xtw.WriteEndElement(); + + xtw.WriteElementString("assets_included", SaveAssets.ToString()); + + bool isMegaregion; - xtw.WriteStartElement("creation_info"); - DateTime now = DateTime.UtcNow; - TimeSpan t = now - new DateTime(1970, 1, 1); - xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString()); - xtw.WriteElementString("id", UUID.Random().ToString()); - xtw.WriteEndElement(); + // FIXME: This is only here for regression test purposes since they do not supply a module. Need to fix + // this, possibly by doing control file creation somewhere else. + if (m_module != null && m_module.RegionCombinerModule != null) + { + IRegionCombinerModule mod = m_module.RegionCombinerModule; + isMegaregion = mod.IsMegaregion && mod.IsRootRegion(m_scene.RegionInfo.RegionID); + } + else + { + isMegaregion = false; + } + + xtw.WriteElementString("is_megaregion", isMegaregion.ToString()); + + xtw.WriteEndElement(); + + xtw.Flush(); + xtw.Close(); + } - xtw.WriteElementString("assets_included", SaveAssets.ToString()); + s = sw.ToString(); + } - xtw.WriteEndElement(); - - xtw.Flush(); - xtw.Close(); - - String s = sw.ToString(); - sw.Close(); +// Console.WriteLine( +// "[ARCHIVE WRITE REQUEST PREPARATION]: Control file for {0} is: {1}", m_scene.RegionInfo.RegionName, s); return s; } diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs index f5a5a8d1be..bf3b1240a4 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs @@ -45,7 +45,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private Scene m_scene; + public Scene Scene { get; private set; } + public IRegionCombinerModule RegionCombinerModule { get; private set; } /// /// The file used to load and save an opensimulator archive if no filename has been specified @@ -70,13 +71,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver public void AddRegion(Scene scene) { - m_scene = scene; - m_scene.RegisterModuleInterface(this); + Scene = scene; + Scene.RegisterModuleInterface(this); //m_log.DebugFormat("[ARCHIVER]: Enabled for region {0}", scene.RegionInfo.RegionName); } public void RegionLoaded(Scene scene) { + RegionCombinerModule = scene.RequestModuleInterface(); } public void RemoveRegion(Scene scene) @@ -165,9 +167,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver public void ArchiveRegion(string savePath, Guid requestId, Dictionary options) { m_log.InfoFormat( - "[ARCHIVER]: Writing archive for region {0} to {1}", m_scene.RegionInfo.RegionName, savePath); + "[ARCHIVER]: Writing archive for region {0} to {1}", Scene.RegionInfo.RegionName, savePath); - new ArchiveWriteRequestPreparation(m_scene, savePath, requestId).ArchiveRegion(options); + new ArchiveWriteRequestPreparation(this, savePath, requestId).ArchiveRegion(options); } public void ArchiveRegion(Stream saveStream) @@ -182,7 +184,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver public void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary options) { - new ArchiveWriteRequestPreparation(m_scene, saveStream, requestId).ArchiveRegion(options); + new ArchiveWriteRequestPreparation(this, saveStream, requestId).ArchiveRegion(options); } public void DearchiveRegion(string loadPath) @@ -193,9 +195,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver public void DearchiveRegion(string loadPath, bool merge, bool skipAssets, Guid requestId) { m_log.InfoFormat( - "[ARCHIVER]: Loading archive to region {0} from {1}", m_scene.RegionInfo.RegionName, loadPath); + "[ARCHIVER]: Loading archive to region {0} from {1}", Scene.RegionInfo.RegionName, loadPath); - new ArchiveReadRequest(m_scene, loadPath, merge, skipAssets, requestId).DearchiveRegion(); + new ArchiveReadRequest(Scene, loadPath, merge, skipAssets, requestId).DearchiveRegion(); } public void DearchiveRegion(Stream loadStream) @@ -205,7 +207,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver public void DearchiveRegion(Stream loadStream, bool merge, bool skipAssets, Guid requestId) { - new ArchiveReadRequest(m_scene, loadStream, merge, skipAssets, requestId).DearchiveRegion(); + new ArchiveReadRequest(Scene, loadStream, merge, skipAssets, requestId).DearchiveRegion(); } } } diff --git a/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs new file mode 100644 index 0000000000..30e49b12a6 --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs @@ -0,0 +1,51 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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.Linq; +using System.Text; +using OpenSim.Region.Framework.Scenes; +using System.IO; +using OpenMetaverse; + +namespace OpenSim.Region.Framework.Interfaces +{ + public interface IRegionCombinerModule + { + /// + /// Is this simulator hosting a megaregion? + /// + /// + bool IsMegaregion { get; } + + /// + /// Does the given id belong to the root region of the megaregion? + /// + bool IsRootRegion(UUID sceneId); + } +} \ No newline at end of file diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index a142f26be2..37b3037ca6 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -43,9 +43,8 @@ using Mono.Addins; [assembly: AddinDependency("OpenSim", "0.5")] namespace OpenSim.Region.RegionCombinerModule { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class RegionCombinerModule : ISharedRegionModule + public class RegionCombinerModule : ISharedRegionModule, IRegionCombinerModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -59,6 +58,15 @@ namespace OpenSim.Region.RegionCombinerModule get { return null; } } + public bool IsMegaregion + { + get + { + lock (m_startingScenes) + return m_startingScenes.Count > 1; + } + } + private Dictionary m_regions = new Dictionary(); private bool enabledYN = false; private Dictionary m_startingScenes = new Dictionary(); @@ -69,9 +77,11 @@ namespace OpenSim.Region.RegionCombinerModule enabledYN = myConfig.GetBoolean("CombineContiguousRegions", false); if (enabledYN) + { MainConsole.Instance.Commands.AddCommand( "RegionCombinerModule", false, "fix-phantoms", "fix-phantoms", "Fixes phantom objects after an import to megaregions", FixPhantoms); + } } public void Close() @@ -80,6 +90,8 @@ namespace OpenSim.Region.RegionCombinerModule public void AddRegion(Scene scene) { + if (enabledYN) + scene.RegisterModuleInterface(this); } public void RemoveRegion(Scene scene) @@ -96,6 +108,12 @@ namespace OpenSim.Region.RegionCombinerModule } } + public bool IsRootRegion(UUID sceneId) + { + lock (m_regions) + return m_regions.ContainsKey(sceneId); + } + private void NewPresence(ScenePresence presence) { if (presence.IsChildAgent) From 26dfcf5395474041e6719da20d7ecb847dd0ee38 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 19 May 2012 03:07:24 +0100 Subject: [PATCH 14/15] Add some method doc to RegionCombinerModule. Clean up log messages. --- .../RegionCombinerModule.cs | 39 ++++++++++++++----- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index 37b3037ca6..3af5cc2b29 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -67,8 +67,22 @@ namespace OpenSim.Region.RegionCombinerModule } } + /// + /// This holds the root regions for the megaregions. + /// + /// + /// At this point we can actually assume there is only ever one megaregion (and hence only one entry here). + /// private Dictionary m_regions = new Dictionary(); + + /// + /// Is this module enabled? + /// private bool enabledYN = false; + + /// + /// The scenes that comprise the megaregion. + /// private Dictionary m_startingScenes = new Dictionary(); public void Initialise(IConfigSource source) @@ -448,9 +462,9 @@ namespace OpenSim.Region.RegionCombinerModule if (!connectedYN) { DoWorkForRootRegion(regionConnections, scene); - } } + // Set up infinite borders around the entire AABB of the combined ConnectedRegions AdjustLargeRegionBounds(); } @@ -469,9 +483,10 @@ namespace OpenSim.Region.RegionCombinerModule conn.UpdateExtents(extents); - m_log.DebugFormat("Scene: {0} to the west of Scene{1} Offset: {2}. Extents:{3}", - conn.RegionScene.RegionInfo.RegionName, - regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); + m_log.DebugFormat( + "[REGION COMBINER MODULE]: Scene {0} to the west of Scene {1}, Offset: {2}, Extents: {3}", + conn.RegionScene.RegionInfo.RegionName, + regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); scene.BordersLocked = true; conn.RegionScene.BordersLocked = true; @@ -547,9 +562,10 @@ namespace OpenSim.Region.RegionCombinerModule ConnectedRegion.RegionScene = scene; conn.ConnectedRegions.Add(ConnectedRegion); - m_log.DebugFormat("Scene: {0} to the northeast of Scene{1} Offset: {2}. Extents:{3}", - conn.RegionScene.RegionInfo.RegionName, - regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); + m_log.DebugFormat( + "[REGION COMBINER MODULE]: Scene: {0} to the northeast of Scene {1}, Offset: {2}, Extents: {3}", + conn.RegionScene.RegionInfo.RegionName, + regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); @@ -602,9 +618,10 @@ namespace OpenSim.Region.RegionCombinerModule conn.ConnectedRegions.Add(ConnectedRegion); - m_log.DebugFormat("Scene: {0} to the NorthEast of Scene{1} Offset: {2}. Extents:{3}", - conn.RegionScene.RegionInfo.RegionName, - regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); + m_log.DebugFormat( + "[REGION COMBINER MODULE]: Scene: {0} to the NorthEast of Scene {1}, Offset: {2}, Extents: {3}", + conn.RegionScene.RegionInfo.RegionName, + regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); @@ -681,6 +698,8 @@ namespace OpenSim.Region.RegionCombinerModule private void DoWorkForRootRegion(RegionConnections regionConnections, Scene scene) { + m_log.DebugFormat("[REGION COMBINER MODULE]: Adding root region {0}", scene.RegionInfo.RegionName); + RegionData rdata = new RegionData(); rdata.Offset = Vector3.Zero; rdata.RegionId = scene.RegionInfo.originRegionID; From 3f2a727b6d6b0cf6c2e2c7ef11ebd0f3f1fefa83 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 19 May 2012 03:17:21 +0100 Subject: [PATCH 15/15] Remove recent IRegionCombinerModule.IsMegaregion(). In theory, there can be more than one megaregion in a simulator, separated by water. Rename IsRootRegion() to IsRootForMegaregion() --- .../Archiver/ArchiveWriteRequestPreparation.cs | 2 +- .../Framework/Interfaces/IRegionCombinerModule.cs | 10 ++-------- .../RegionCombinerModule/RegionCombinerModule.cs | 13 ++----------- 3 files changed, 5 insertions(+), 20 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index 838b741fdc..e54774b339 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -401,7 +401,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver if (m_module != null && m_module.RegionCombinerModule != null) { IRegionCombinerModule mod = m_module.RegionCombinerModule; - isMegaregion = mod.IsMegaregion && mod.IsRootRegion(m_scene.RegionInfo.RegionID); + isMegaregion = mod.IsRootForMegaregion(m_scene.RegionInfo.RegionID); } else { diff --git a/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs index 30e49b12a6..ca4ed5cb2e 100644 --- a/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs @@ -38,14 +38,8 @@ namespace OpenSim.Region.Framework.Interfaces public interface IRegionCombinerModule { /// - /// Is this simulator hosting a megaregion? + /// Does the given id belong to the root region of a megaregion? /// - /// - bool IsMegaregion { get; } - - /// - /// Does the given id belong to the root region of the megaregion? - /// - bool IsRootRegion(UUID sceneId); + bool IsRootForMegaregion(UUID sceneId); } } \ No newline at end of file diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index 3af5cc2b29..fadc30d39f 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -58,20 +58,11 @@ namespace OpenSim.Region.RegionCombinerModule get { return null; } } - public bool IsMegaregion - { - get - { - lock (m_startingScenes) - return m_startingScenes.Count > 1; - } - } - /// /// This holds the root regions for the megaregions. /// /// - /// At this point we can actually assume there is only ever one megaregion (and hence only one entry here). + /// Usually there is only ever one megaregion (and hence only one entry here). /// private Dictionary m_regions = new Dictionary(); @@ -122,7 +113,7 @@ namespace OpenSim.Region.RegionCombinerModule } } - public bool IsRootRegion(UUID sceneId) + public bool IsRootForMegaregion(UUID sceneId) { lock (m_regions) return m_regions.ContainsKey(sceneId);