From d167686adb2d4a08759cf7c23ced9d9edd209b77 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 2 Mar 2010 21:12:53 -0800 Subject: [PATCH 01/18] Better error handling on PasswordAuthenticationService --- .../PasswordAuthenticationService.cs | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs b/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs index 021dcf3e91..2fc92487d6 100644 --- a/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs +++ b/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs @@ -47,9 +47,9 @@ namespace OpenSim.Services.AuthenticationService public class PasswordAuthenticationService : AuthenticationServiceBase, IAuthenticationService { - //private static readonly ILog m_log = - // LogManager.GetLogger( - // MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); public PasswordAuthenticationService(IConfigSource config) : base(config) @@ -59,23 +59,27 @@ namespace OpenSim.Services.AuthenticationService public string Authenticate(UUID principalID, string password, int lifetime) { AuthenticationData data = m_Database.Get(principalID); - - if (!data.Data.ContainsKey("passwordHash") || - !data.Data.ContainsKey("passwordSalt")) + + if (data != null && data.Data != null) { - return String.Empty; - } - - string hashed = Util.Md5Hash(password + ":" + - data.Data["passwordSalt"].ToString()); - - //m_log.DebugFormat("[PASS AUTH]: got {0}; hashed = {1}; stored = {2}", password, hashed, data.Data["passwordHash"].ToString()); - - if (data.Data["passwordHash"].ToString() == hashed) - { - return GetToken(principalID, lifetime); + if (!data.Data.ContainsKey("passwordHash") || + !data.Data.ContainsKey("passwordSalt")) + { + return String.Empty; + } + + string hashed = Util.Md5Hash(password + ":" + + data.Data["passwordSalt"].ToString()); + + //m_log.DebugFormat("[PASS AUTH]: got {0}; hashed = {1}; stored = {2}", password, hashed, data.Data["passwordHash"].ToString()); + + if (data.Data["passwordHash"].ToString() == hashed) + { + return GetToken(principalID, lifetime); + } } + m_log.DebugFormat("[AUTH SERVICE]: PrincipalID {0} or its data not found", principalID); return String.Empty; } } From 9fda5c51acf6b8b1f6cbb072e4bf72a05d35b491 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 2 Mar 2010 22:20:44 -0800 Subject: [PATCH 02/18] More debug. --- OpenSim/Services/LLLoginService/LLLoginService.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 1d734ebc2f..ee93f73cde 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -247,6 +247,7 @@ namespace OpenSim.Services.LLLoginService LLLoginResponse response = new LLLoginResponse(account, aCircuit, presence, destination, inventorySkel, friendsList, m_LibraryService, where, startLocation, position, lookAt, m_WelcomeMessage, home, clientIP); + m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to client."); return response; } catch (Exception e) From aee887afaf3982253a2a5bf0724828a6718a406b Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 3 Mar 2010 09:16:21 -0800 Subject: [PATCH 03/18] Added empty service URLs upon account creation. --- .../Services/UserAccountService/UserAccountService.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/OpenSim/Services/UserAccountService/UserAccountService.cs b/OpenSim/Services/UserAccountService/UserAccountService.cs index e498bd5e70..ca6e44ac14 100644 --- a/OpenSim/Services/UserAccountService/UserAccountService.cs +++ b/OpenSim/Services/UserAccountService/UserAccountService.cs @@ -280,6 +280,15 @@ namespace OpenSim.Services.UserAccountService if (null == account) { account = new UserAccount(UUID.Zero, firstName, lastName, email); + if (account.ServiceURLs == null) + { + account.ServiceURLs = new Dictionary(); + account.ServiceURLs["HomeURI"] = string.Empty; + account.ServiceURLs["GatekeeperURI"] = string.Empty; + account.ServiceURLs["InventoryServerURI"] = string.Empty; + account.ServiceURLs["AssetServerURI"] = string.Empty; + } + if (StoreUserAccount(account)) { bool success = false; From d83b86e4bf1f064781723b37534555a74e3e3c03 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 3 Mar 2010 09:34:51 -0800 Subject: [PATCH 04/18] Fixed prebuild errors that have emerged with the merge --- prebuild.xml | 44 -------------------------------------------- 1 file changed, 44 deletions(-) diff --git a/prebuild.xml b/prebuild.xml index e19e636443..09d78e9e22 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1539,42 +1539,6 @@ - - - - ../../../../bin/ - - - - - ../../../../bin/ - - - - ../../../../bin/ - - - - - - - - - - - - - - - - - - - - - - - @@ -1599,7 +1563,6 @@ - @@ -1639,7 +1602,6 @@ - @@ -1713,10 +1675,7 @@ - - - @@ -2785,7 +2744,6 @@ - @@ -3019,7 +2977,6 @@ - @@ -3083,7 +3040,6 @@ - From 1c68ad2bba43b87e204cf6eafb7f0a31d3272c01 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 3 Mar 2010 17:50:05 +0000 Subject: [PATCH 05/18] remove references to OpenSim.Framework.Commuications.Tests.dll since all relevant test code has been obsoleted this allows the tests to pass on my local system --- .nant/local.include | 22 ------------------- .../ClientStack/LindenUDP/LLClientView.cs | 16 +++++++++++--- .../Region/Framework/Scenes/SceneManager.cs | 2 +- 3 files changed, 14 insertions(+), 26 deletions(-) diff --git a/.nant/local.include b/.nant/local.include index 5e02665f2a..c611bd2391 100644 --- a/.nant/local.include +++ b/.nant/local.include @@ -43,11 +43,6 @@ - - - - - @@ -106,17 +101,6 @@ - - - - - - - - - - - - diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index ef492052fc..569dc8db25 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -97,6 +97,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientIPEndpoint, IStatsCollector { + /// + /// Debug packet level. At the moment, only 255 does anything (prints out all in and out packets). + /// + protected int m_debugPacketLevel = 0; + #region Events public event GenericMessage OnGenericMessage; @@ -472,6 +477,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void SetDebugPacketLevel(int newDebug) { + m_debugPacketLevel = newDebug; } #region Client Methods @@ -10952,7 +10958,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP LLUDPServer.LogPacketHeader(false, m_circuitCode, 0, packet.Type, (ushort)packet.Length); #endregion BinaryStats - m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, true); + OutPacket(packet, throttlePacketType, true); } /// @@ -10965,6 +10971,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// handles splitting manually protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting) { + if (m_debugPacketLevel >= 255) + m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type); + m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting); } @@ -11036,10 +11045,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// OpenMetaverse.packet public void ProcessInPacket(Packet Pack) { -// m_log.DebugFormat("[CLIENT]: Packet IN {0}", Pack); + if (m_debugPacketLevel >= 255) + m_log.DebugFormat("[CLIENT]: Packet IN {0}", Pack.Type); if (!ProcessPacketMethod(Pack)) - m_log.Warn("[CLIENT]: unhandled packet " + Pack); + m_log.Warn("[CLIENT]: unhandled packet " + Pack.Type); PacketPool.Instance.ReturnPacket(Pack); } diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs index 6395d9868b..680c39a622 100644 --- a/OpenSim/Region/Framework/Scenes/SceneManager.cs +++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs @@ -422,7 +422,7 @@ namespace OpenSim.Region.Framework.Scenes if (!scenePresence.IsChildAgent) { - m_log.ErrorFormat("Packet debug for {0} {1} set to {2}", + m_log.DebugFormat("Packet debug for {0} {1} set to {2}", scenePresence.Firstname, scenePresence.Lastname, newDebug); From 296c68a9de2d8253bdb88c67529619398d8ec6c9 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 3 Mar 2010 18:28:30 +0000 Subject: [PATCH 06/18] Make the service loader pump out the error to the log (in red) and include the dll/interface/args that caused the problem This gives people more of a fighting chance of finding out what went wrong --- OpenSim/Services/Base/ServiceBase.cs | 20 +++++++++++++++++-- .../Services/Friends/FriendsServiceBase.cs | 9 ++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/OpenSim/Services/Base/ServiceBase.cs b/OpenSim/Services/Base/ServiceBase.cs index 8e24d8517c..91d5c5650c 100644 --- a/OpenSim/Services/Base/ServiceBase.cs +++ b/OpenSim/Services/Base/ServiceBase.cs @@ -26,7 +26,9 @@ */ using System; +using System.Collections.Generic; using System.Reflection; +using log4net; using Nini.Config; using OpenSim.Services.Interfaces; @@ -34,6 +36,8 @@ namespace OpenSim.Services.Base { public class ServiceBase { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + public T LoadPlugin(string dllName) where T:class { return LoadPlugin(dllName, new Object[0]); @@ -61,8 +65,12 @@ namespace OpenSim.Services.Base { Assembly pluginAssembly = Assembly.LoadFrom(dllName); +// m_log.DebugFormat("[SERVICE BASE]: Found assembly {0}", dllName); + foreach (Type pluginType in pluginAssembly.GetTypes()) { +// m_log.DebugFormat("[SERVICE BASE]: Found type {0}", pluginType); + if (pluginType.IsPublic) { if (className != String.Empty && @@ -86,7 +94,15 @@ namespace OpenSim.Services.Base } catch (Exception e) { - Console.WriteLine("XXX Exception " + e.StackTrace); + List strArgs = new List(); + foreach (Object arg in args) + strArgs.Add(arg.ToString()); + + m_log.Error( + string.Format( + "[SERVICE BASE]: Failed to load plugin {0} from {1} with args {2}", + interfaceName, dllName, string.Join(", ", strArgs.ToArray())), e); + return null; } } @@ -95,4 +111,4 @@ namespace OpenSim.Services.Base { } } -} +} \ No newline at end of file diff --git a/OpenSim/Services/Friends/FriendsServiceBase.cs b/OpenSim/Services/Friends/FriendsServiceBase.cs index 9858972311..6ab0bff0a8 100644 --- a/OpenSim/Services/Friends/FriendsServiceBase.cs +++ b/OpenSim/Services/Friends/FriendsServiceBase.cs @@ -27,13 +27,12 @@ using System; using System.Reflection; +using log4net; using Nini.Config; using OpenSim.Framework; using OpenSim.Data; using OpenSim.Services.Interfaces; using OpenSim.Services.Base; -using Nini.Config; -using log4net; namespace OpenSim.Services.Friends { @@ -80,7 +79,11 @@ namespace OpenSim.Services.Friends m_Database = LoadPlugin(dllName, new Object[] { connString, realm }); if (m_Database == null) - throw new Exception("Could not find a storage interface in the given module"); + { + throw new Exception( + string.Format( + "Could not find a storage interface {0} in the given StorageProvider {1}", "IFriendsData", dllName)); + } } } } From 660ebe52cf37828d32647030de940c8928d3c9f2 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 1 Feb 2010 20:15:36 +0000 Subject: [PATCH 07/18] Actually make EventManager.OnAttach() fire when an object is attached. Previously, only detach was firing! --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 369552f481..b7fcd7d558 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -540,6 +540,9 @@ namespace OpenSim.Region.Framework.Scenes // Fire after attach, so we don't get messy perms dialogs // 3 == AttachedRez objatt.CreateScriptInstances(0, true, m_parentScene.DefaultScriptEngine, 3); + + // Do this last so that event listeners have access to all the effects of the attachment + m_parentScene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId); } return objatt; } From a6e23a32750e1333c45ccc69ede98f522e804216 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Wed, 3 Mar 2010 10:59:05 -0800 Subject: [PATCH 08/18] * Fixed bad start position clamping in MakeRootAgent() --- .../Region/Framework/Scenes/ScenePresence.cs | 40 ++++--------------- 1 file changed, 7 insertions(+), 33 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f83a4d2287..6a9f0160ca 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -830,41 +830,15 @@ namespace OpenSim.Region.Framework.Scenes pos.Y = crossedBorder.BorderLine.Z - 1; } - - if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) + if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) { - Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128); - - if (pos.X < 0) - { - emergencyPos.X = (int)Constants.RegionSize + pos.X; - if (!(pos.Y < 0)) - emergencyPos.Y = pos.Y; - if (!(pos.Z < 0)) - emergencyPos.X = pos.X; - } - if (pos.Y < 0) - { - emergencyPos.Y = (int)Constants.RegionSize + pos.Y; - if (!(pos.X < 0)) - emergencyPos.X = pos.X; - if (!(pos.Z < 0)) - emergencyPos.Z = pos.Z; - } - if (pos.Z < 0) - { - if (!(pos.X < 0)) - emergencyPos.X = pos.X; - if (!(pos.Y < 0)) - emergencyPos.Y = pos.Y; - //Leave as 128 - } - m_log.WarnFormat( - "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", - pos, Name, UUID, emergencyPos); + "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", + pos, Name, UUID); - pos = emergencyPos; + if (pos.X < 0f) pos.X = 0f; + if (pos.Y < 0f) pos.Y = 0f; + if (pos.Z < 0f) pos.Z = 0f; } float localAVHeight = 1.56f; @@ -875,7 +849,7 @@ namespace OpenSim.Region.Framework.Scenes float posZLimit = 0; - if (pos.X Date: Wed, 3 Mar 2010 12:12:32 -0800 Subject: [PATCH 09/18] Removing the sLLVector3 dinosaur --- OpenSim/Framework/ChildAgentDataUpdate.cs | 13 +++-- OpenSim/Framework/sLLVector3.cs | 51 ------------------- .../Region/Framework/Scenes/ScenePresence.cs | 6 +-- 3 files changed, 9 insertions(+), 61 deletions(-) delete mode 100644 OpenSim/Framework/sLLVector3.cs diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index fee71f01c4..a1ac84c039 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -41,14 +41,14 @@ namespace OpenSim.Framework public Guid AgentID; public bool alwaysrun; public float AVHeight; - public sLLVector3 cameraPosition; + public Vector3 cameraPosition; public float drawdistance; public float godlevel; public uint GroupAccess; - public sLLVector3 Position; + public Vector3 Position; public ulong regionHandle; public byte[] throttles; - public sLLVector3 Velocity; + public Vector3 Velocity; public ChildAgentDataUpdate() { @@ -177,14 +177,13 @@ namespace OpenSim.Framework Size = new Vector3(); Size.Z = cAgent.AVHeight; - Center = new Vector3(cAgent.cameraPosition.x, cAgent.cameraPosition.y, cAgent.cameraPosition.z); + Center = cAgent.cameraPosition; Far = cAgent.drawdistance; - Position = new Vector3(cAgent.Position.x, cAgent.Position.y, cAgent.Position.z); + Position = cAgent.Position; RegionHandle = cAgent.regionHandle; Throttles = cAgent.throttles; - Velocity = new Vector3(cAgent.Velocity.x, cAgent.Velocity.y, cAgent.Velocity.z); + Velocity = cAgent.Velocity; } - } public class AgentGroupData diff --git a/OpenSim/Framework/sLLVector3.cs b/OpenSim/Framework/sLLVector3.cs deleted file mode 100644 index 49940c46f8..0000000000 --- a/OpenSim/Framework/sLLVector3.cs +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the 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 OpenMetaverse; - -namespace OpenSim.Framework -{ - [Serializable] - public class sLLVector3 - { - public float x = 0; - public float y = 0; - public float z = 0; - - public sLLVector3() - { - } - - public sLLVector3(Vector3 v) - { - x = v.X; - y = v.Y; - z = v.Z; - } - } -} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 6a9f0160ca..c7008dfccf 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2675,13 +2675,13 @@ namespace OpenSim.Region.Framework.Scenes cadu.AgentID = UUID.Guid; cadu.alwaysrun = m_setAlwaysRun; cadu.AVHeight = m_avHeight; - sLLVector3 tempCameraCenter = new sLLVector3(new Vector3(m_CameraCenter.X, m_CameraCenter.Y, m_CameraCenter.Z)); + Vector3 tempCameraCenter = m_CameraCenter; cadu.cameraPosition = tempCameraCenter; cadu.drawdistance = m_DrawDistance; if (m_scene.Permissions.IsGod(new UUID(cadu.AgentID))) cadu.godlevel = m_godlevel; cadu.GroupAccess = 0; - cadu.Position = new sLLVector3(AbsolutePosition); + cadu.Position = AbsolutePosition; cadu.regionHandle = m_rootRegionHandle; float multiplier = 1; int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); @@ -2696,7 +2696,7 @@ namespace OpenSim.Region.Framework.Scenes //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString()); cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier); - cadu.Velocity = new sLLVector3(Velocity); + cadu.Velocity = Velocity; AgentPosition agentpos = new AgentPosition(); agentpos.CopyFrom(cadu); From fc233d4e1e2601fd0c86e84849873d4bd8b55420 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Wed, 3 Mar 2010 12:34:21 -0800 Subject: [PATCH 10/18] * Adjusted the significant movement magic value from 0.5m to 2.0m and added an explanation of what it does --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index c7008dfccf..465e916f2c 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2659,7 +2659,12 @@ namespace OpenSim.Region.Framework.Scenes /// protected void CheckForSignificantMovement() { - if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > 0.5) + // Movement updates for agents in neighboring regions are sent directly to clients. + // This value only affects how often agent positions are sent to neighbor regions + // for things such as distance-based update prioritization + const float SIGNIFICANT_MOVEMENT = 2.0f; + + if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT) { posLastSignificantMove = AbsolutePosition; m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient); From edb176447ba9cd6d29bd45d9b3714aa0dab9cbf9 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 3 Mar 2010 22:14:06 +0000 Subject: [PATCH 11/18] Fix bug where approximately half the time, attachments would rez only their root prim until right clicked (or otherwise updated). The root cause of this problem was that multiple ObjectUpdates were being sent on attachment which differed enough to confuse the client. Sometimes these would eliminate each other and sometimes not, depending on whether the scheduler looked at the queued updates. The solution here is to only schedule the ObjectUpdate once the attachment code has done all it needs to do. --- .../InventoryAccess/InventoryAccessModule.cs | 16 ++++--- .../Framework/Scenes/Scene.Inventory.cs | 44 ++++++++++++++++--- OpenSim/Region/Framework/Scenes/Scene.cs | 40 +++++++++++++---- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 43 +++++++++++++----- .../Framework/Scenes/SceneObjectGroup.cs | 35 ++++++++++++--- bin/OpenSim.exe.config | 2 +- bin/config-include/Standalone.ini | 8 ++-- 7 files changed, 145 insertions(+), 43 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index e0df2881ed..0fc467bc43 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -411,6 +411,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess /// /// Rez an object into the scene from the user's inventory /// + /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing + /// things to the scene. The caller should be doing that, I think. /// /// /// @@ -500,13 +502,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess group.RootPart.IsAttachment = true; } - m_Scene.AddNewSceneObject(group, true); + // For attachments, we must make sure that only a single object update occurs after we've finished + // all the necessary operations. + m_Scene.AddNewSceneObject(group, true, false); // m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z); // if attachment we set it's asset id so object updates can reflect that // if not, we set it's position in world. if (!attachment) { + group.ScheduleGroupForFullUpdate(); + float offsetHeight = 0; pos = m_Scene.GetNewRezLocation( RayStart, RayEnd, RayTargetID, Quaternion.Identity, @@ -562,6 +568,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess part.GroupMask = 0; // DO NOT propagate here } } + group.ApplyNextOwnerPermissions(); } } @@ -569,7 +576,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess foreach (SceneObjectPart part in partList) { if (part.OwnerID != item.Owner) - { + { part.LastOwnerID = part.OwnerID; part.OwnerID = item.Owner; part.Inventory.ChangeInventoryOwner(item.Owner); @@ -591,10 +598,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess { group.ClearPartAttachmentData(); } - } - - if (!attachment) - { + // Fire on_rez group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 0); diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 6df25d6e29..5f3cd8cf4d 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1842,9 +1842,18 @@ namespace OpenSim.Region.Framework.Scenes EventManager.TriggerOnAttach(localID, itemID, avatarID); } - public UUID RezSingleAttachment(IClientAPI remoteClient, UUID itemID, - uint AttachmentPt) + /// + /// Called when the client receives a request to rez a single attachment on to the avatar from inventory + /// (RezSingleAttachmentFromInv packet). + /// + /// + /// + /// + /// + public UUID RezSingleAttachment(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) { + m_log.DebugFormat("[USER INVENTORY]: Rezzing single attachment from item {0} for {1}", itemID, remoteClient.Name); + SceneObjectGroup att = m_sceneGraph.RezSingleAttachment(remoteClient, itemID, AttachmentPt); if (att == null) @@ -1856,9 +1865,20 @@ namespace OpenSim.Region.Framework.Scenes return RezSingleAttachment(att, remoteClient, itemID, AttachmentPt); } - public UUID RezSingleAttachment(SceneObjectGroup att, - IClientAPI remoteClient, UUID itemID, uint AttachmentPt) + /// + /// Update the user inventory to reflect an attachment + /// + /// + /// + /// + /// + /// + public UUID RezSingleAttachment(SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt) { + m_log.DebugFormat( + "[USER INVENTORY]: Updating inventory of {0} to show attachment of {1} (item ID {2})", + remoteClient.Name, att.Name, itemID); + if (!att.IsDeleted) AttachmentPt = att.RootPart.AttachmentPoint; @@ -1897,8 +1917,19 @@ namespace OpenSim.Region.Framework.Scenes return m_sceneGraph.AttachObject(controllingClient, localID, attachPoint, rot, pos, silent); } + /// + /// This registers the item as attached in a user's inventory + /// + /// + /// + /// + /// public void AttachObject(IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att) { +// m_log.DebugFormat( +// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", +// att.Name, remoteClient.Name, AttachmentPt, itemID); + if (UUID.Zero == itemID) { m_log.Error("[SCENE INVENTORY]: Unable to save attachment. Error inventory item ID."); @@ -1926,10 +1957,7 @@ namespace OpenSim.Region.Framework.Scenes presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /* att.UUID */); if (m_AvatarFactory != null) - { m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); - } - } } @@ -2012,6 +2040,7 @@ namespace OpenSim.Region.Framework.Scenes { sog.SetOwnerId(ownerID); sog.SetGroup(groupID, remoteClient); + sog.ScheduleGroupForFullUpdate(); foreach (SceneObjectPart child in sog.Children.Values) child.Inventory.ChangeInventoryOwner(ownerID); @@ -2033,6 +2062,7 @@ namespace OpenSim.Region.Framework.Scenes sog.SetOwnerId(groupID); sog.ApplyNextOwnerPermissions(); } + } foreach (uint localID in localIDs) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 5e5a52e981..a880fe7d59 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1906,14 +1906,22 @@ namespace OpenSim.Region.Framework.Scenes //m_log.DebugFormat( // "[SCENE]: Scene.AddNewPrim() pcode {0} called for {1} in {2}", shape.PCode, ownerID, RegionInfo.RegionName); + SceneObjectGroup sceneObject = null; + // If an entity creator has been registered for this prim type then use that if (m_entityCreators.ContainsKey((PCode)shape.PCode)) - return m_entityCreators[(PCode)shape.PCode].CreateEntity(ownerID, groupID, pos, rot, shape); + { + sceneObject = m_entityCreators[(PCode)shape.PCode].CreateEntity(ownerID, groupID, pos, rot, shape); + } + else + { + // Otherwise, use this default creation code; + sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape); + AddNewSceneObject(sceneObject, true); + sceneObject.SetGroup(groupID, null); + } - // Otherwise, use this default creation code; - SceneObjectGroup sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape); - AddNewSceneObject(sceneObject, true); - sceneObject.SetGroup(groupID, null); + sceneObject.ScheduleGroupForFullUpdate(); return sceneObject; } @@ -1941,7 +1949,7 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Add a newly created object to the scene + /// Add a newly created object to the scene. Updates are also sent to viewers. /// /// /// @@ -1950,8 +1958,25 @@ namespace OpenSim.Region.Framework.Scenes /// public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup) { - return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup); + return AddNewSceneObject(sceneObject, attachToBackup, true); } + + /// + /// Add a newly created object to the scene + /// + /// + /// + /// If true, the object is made persistent into the scene. + /// If false, the object will not persist over server restarts + /// + /// + /// If true, updates for the new scene object are sent to all viewers in range. + /// If false, it is left to the caller to schedule the update + /// + public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) + { + return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates); + } /// /// Delete every object from the scene @@ -3143,7 +3168,6 @@ namespace OpenSim.Region.Framework.Scenes m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid; m_sceneGridService.KiPrimitive += SendKillObject; m_sceneGridService.OnGetLandData += GetLandData; - } /// diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index b7fcd7d558..22613e925f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -229,7 +229,7 @@ namespace OpenSim.Region.Framework.Scenes sceneObject.HasGroupChanged = true; } - return AddSceneObject(sceneObject, attachToBackup); + return AddSceneObject(sceneObject, attachToBackup, true); } /// @@ -244,12 +244,12 @@ namespace OpenSim.Region.Framework.Scenes /// /// true if the object was added, false if an object with the same uuid was already in the scene /// - protected internal bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup) + protected internal bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) { // Ensure that we persist this new scene object sceneObject.HasGroupChanged = true; - return AddSceneObject(sceneObject, attachToBackup); + return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates); } /// @@ -261,12 +261,19 @@ namespace OpenSim.Region.Framework.Scenes /// If true, the object is made persistent into the scene. /// If false, the object will not persist over server restarts /// - /// true if the object was added, false if an object with the same uuid was already in the scene + /// + /// If true, updates for the new scene object are sent to all viewers in range. + /// If false, it is left to the caller to schedule the update + /// + /// + /// true if the object was added, false if an object with the same uuid was already in the scene /// - protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup) + protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) { if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero) return false; + + bool alreadyExisted = false; if (m_parentScene.m_clampPrimSize) { @@ -287,6 +294,9 @@ namespace OpenSim.Region.Framework.Scenes sceneObject.AttachToScene(m_parentScene); + if (sendClientUpdates) + sceneObject.ScheduleGroupForFullUpdate(); + lock (sceneObject) { if (!Entities.ContainsKey(sceneObject.UUID)) @@ -310,12 +320,14 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; } } - - return true; + } + else + { + alreadyExisted = true; } } - return false; + return alreadyExisted; } /// @@ -525,7 +537,10 @@ namespace OpenSim.Region.Framework.Scenes itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, false, false, remoteClient.AgentId, true); - +// m_log.DebugFormat( +// "[SCENE GRAPH]: Retrieved single object {0} for attachment to {1} on point {2}", +// objatt.Name, remoteClient.Name, AttachmentPt); + if (objatt != null) { bool tainted = false; @@ -533,7 +548,7 @@ namespace OpenSim.Region.Framework.Scenes tainted = true; AttachObject(remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false); - objatt.ScheduleGroupForFullUpdate(); + //objatt.ScheduleGroupForFullUpdate(); if (tainted) objatt.HasGroupChanged = true; @@ -544,8 +559,16 @@ namespace OpenSim.Region.Framework.Scenes // Do this last so that event listeners have access to all the effects of the attachment m_parentScene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId); } + else + { + m_log.WarnFormat( + "[SCENE GRAPH]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", + itemID, remoteClient.Name, AttachmentPt); + } + return objatt; } + return null; } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index c5a6171207..c14b39ad85 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -567,8 +567,10 @@ namespace OpenSim.Region.Framework.Scenes } ApplyPhysics(m_scene.m_physicalPrim); - - ScheduleGroupForFullUpdate(); + + // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled + // for the same object with very different properties. The caller must schedule the update. + //ScheduleGroupForFullUpdate(); } public Vector3 GroupScale() @@ -956,10 +958,11 @@ namespace OpenSim.Region.Framework.Scenes // don't attach attachments to child agents if (avatar.IsChildAgent) return; +// m_log.DebugFormat("[SOG]: Adding attachment {0} to avatar {1}", Name, avatar.Name); + DetachFromBackup(); // Remove from database and parcel prim count - // m_scene.DeleteFromStorage(UUID); m_scene.EventManager.TriggerParcelPrimCountTainted(); @@ -985,7 +988,6 @@ namespace OpenSim.Region.Framework.Scenes SetAttachmentPoint(Convert.ToByte(attachmentpoint)); avatar.AddAttachment(this); - m_log.Debug("[SOG]: Added attachment " + UUID + " to avatar " + avatar.UUID); if (!silent) { @@ -1002,6 +1004,12 @@ namespace OpenSim.Region.Framework.Scenes ScheduleGroupForFullUpdate(); } } + else + { + m_log.WarnFormat( + "[SOG]: Tried to add attachment {0} to avatar with UUID {1} in region {2} but the avatar is not present", + UUID, agentID, Scene.RegionInfo.RegionName); + } } public byte GetAttachmentPoint() @@ -1986,6 +1994,8 @@ namespace OpenSim.Region.Framework.Scenes public void ScheduleFullUpdateToAvatar(ScenePresence presence) { +// m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1} just to avatar {2}", Name, UUID, presence.Name); + RootPart.AddFullUpdateToAvatar(presence); lock (m_parts) @@ -2000,6 +2010,8 @@ namespace OpenSim.Region.Framework.Scenes public void ScheduleTerseUpdateToAvatar(ScenePresence presence) { +// m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1} just to avatar {2}", Name, UUID, presence.Name); + lock (m_parts) { foreach (SceneObjectPart part in m_parts.Values) @@ -2014,6 +2026,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void ScheduleGroupForFullUpdate() { +// m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, UUID); + checkAtTargets(); RootPart.ScheduleFullUpdate(); @@ -2032,6 +2046,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void ScheduleGroupForTerseUpdate() { +// m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID); + lock (m_parts) { foreach (SceneObjectPart part in m_parts.Values) @@ -2045,9 +2061,11 @@ namespace OpenSim.Region.Framework.Scenes /// Immediately send a full update for this scene object. /// public void SendGroupFullUpdate() - { + { if (IsDeleted) return; + +// m_log.DebugFormat("[SOG]: Sending immediate full group update for {0} {1}", Name, UUID); RootPart.SendFullUpdateToAllClients(); @@ -2064,7 +2082,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// Immediately send an update for this scene object's root prim only. /// This is for updates regarding the object as a whole, and none of its parts in particular. - /// Note: this may not be cused by opensim (it probably should) but it's used by + /// Note: this may not be used by opensim (it probably should) but it's used by /// external modules. /// public void SendGroupRootTerseUpdate() @@ -2079,6 +2097,7 @@ namespace OpenSim.Region.Framework.Scenes { if (m_scene == null) // Need to check here as it's null during object creation return; + m_scene.SceneGraph.AddToUpdateList(this); } @@ -3557,7 +3576,9 @@ namespace OpenSim.Region.Framework.Scenes HasGroupChanged = true; } - ScheduleGroupForFullUpdate(); + // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled + // for the same object with very different properties. The caller must schedule the update. + //ScheduleGroupForFullUpdate(); } public void TriggerScriptChangedEvent(Changed val) diff --git a/bin/OpenSim.exe.config b/bin/OpenSim.exe.config index 3c7adf5419..4e7ef51bd8 100755 --- a/bin/OpenSim.exe.config +++ b/bin/OpenSim.exe.config @@ -12,7 +12,7 @@ - + diff --git a/bin/config-include/Standalone.ini b/bin/config-include/Standalone.ini index bf693a18ec..dc65ffd07f 100644 --- a/bin/config-include/Standalone.ini +++ b/bin/config-include/Standalone.ini @@ -31,14 +31,14 @@ [AvatarService] LocalServiceModule = "OpenSim.Services.AvatarService.dll:AvatarService" - ConnectionString = "URI=file:avatars.db,version=3" + ; ConnectionString = "URI=file:avatars.db,version=3" [AuthorizationService] LocalServiceModule = "OpenSim.Services.AuthorizationService.dll:AuthorizationService" [AuthenticationService] LocalServiceModule = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService" - ConnectionString = "URI=file:auth.db,version=3" + ; ConnectionString = "URI=file:auth.db,version=3" [GridService] LocalServiceModule = "OpenSim.Services.GridService.dll:GridService" @@ -51,7 +51,7 @@ [UserAccountService] LocalServiceModule = "OpenSim.Services.UserAccountService.dll:UserAccountService" - ConnectionString = "URI=file:userprofiles.db,version=3" + ; ConnectionString = "URI=file:userprofiles.db,version=3" ;; These are for creating new accounts AuthenticationService = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService" PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService" @@ -60,7 +60,7 @@ [FriendsService] LocalServiceModule = "OpenSim.Services.FriendsService.dll" - ConnectionString = "URI=file:friends.db,version=3" + ; ConnectionString = "URI=file:friends.db,version=3" [Friends] Connector = "OpenSim.Services.FriendsService.dll" From e97ba577888ae0da6f227fea6a2b78cca1a5d886 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 3 Mar 2010 22:20:06 +0000 Subject: [PATCH 12/18] reset the accidental local configuration changes --- bin/OpenSim.exe.config | 2 +- bin/config-include/Standalone.ini | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/bin/OpenSim.exe.config b/bin/OpenSim.exe.config index 4e7ef51bd8..3c7adf5419 100755 --- a/bin/OpenSim.exe.config +++ b/bin/OpenSim.exe.config @@ -12,7 +12,7 @@ - + diff --git a/bin/config-include/Standalone.ini b/bin/config-include/Standalone.ini index dc65ffd07f..30113708a1 100644 --- a/bin/config-include/Standalone.ini +++ b/bin/config-include/Standalone.ini @@ -24,21 +24,22 @@ [InventoryService] LocalServiceModule = "OpenSim.Services.InventoryService.dll:InventoryService" + [LibraryService] - LocalServiceModule = "OpenSim.Services.InventoryService.dll:LibraryService" - LibraryName = "OpenSim Library" - DefaultLibrary = "./inventory/Libraries.xml" + LocalServiceModule = "OpenSim.Services.InventoryService.dll:LibraryService" + LibraryName = "OpenSim Library" + DefaultLibrary = "./inventory/Libraries.xml" [AvatarService] LocalServiceModule = "OpenSim.Services.AvatarService.dll:AvatarService" - ; ConnectionString = "URI=file:avatars.db,version=3" + ConnectionString = "URI=file:avatars.db,version=3" [AuthorizationService] LocalServiceModule = "OpenSim.Services.AuthorizationService.dll:AuthorizationService" [AuthenticationService] LocalServiceModule = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService" - ; ConnectionString = "URI=file:auth.db,version=3" + ConnectionString = "URI=file:auth.db,version=3" [GridService] LocalServiceModule = "OpenSim.Services.GridService.dll:GridService" @@ -51,7 +52,8 @@ [UserAccountService] LocalServiceModule = "OpenSim.Services.UserAccountService.dll:UserAccountService" - ; ConnectionString = "URI=file:userprofiles.db,version=3" + ConnectionString = "URI=file:userprofiles.db,version=3" + ;; These are for creating new accounts AuthenticationService = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService" PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService" @@ -60,7 +62,7 @@ [FriendsService] LocalServiceModule = "OpenSim.Services.FriendsService.dll" - ; ConnectionString = "URI=file:friends.db,version=3" + ConnectionString = "URI=file:friends.db,version=3" [Friends] Connector = "OpenSim.Services.FriendsService.dll" From 61a63ff85124d932cca5a2aeba9ae685fa7f146f Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Wed, 3 Mar 2010 14:38:00 -0800 Subject: [PATCH 13/18] * Added three new helper utility files to OpenSim.Framework. MultipartForm is used for constructing multipart/form-data requests. UntrustedWebRequest places sanity checks and policy on requests to HTTP endpoints that are not in the same trust domain (useful for Hypergrid, OpenID, etc). WebUtil contains misc. functions for managing URLs and network streams --- OpenSim/Framework/MultipartForm.cs | 117 ++++++++ OpenSim/Framework/UntrustedWebRequest.cs | 203 ++++++++++++++ OpenSim/Framework/WebUtil.cs | 330 +++++++++++++++++++++++ prebuild.xml | 1 + 4 files changed, 651 insertions(+) create mode 100644 OpenSim/Framework/MultipartForm.cs create mode 100644 OpenSim/Framework/UntrustedWebRequest.cs create mode 100644 OpenSim/Framework/WebUtil.cs diff --git a/OpenSim/Framework/MultipartForm.cs b/OpenSim/Framework/MultipartForm.cs new file mode 100644 index 0000000000..8ba6d22683 --- /dev/null +++ b/OpenSim/Framework/MultipartForm.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.IO; +using System.Text; + +namespace OpenSim.Framework +{ + public static class MultipartForm + { + #region Helper Classes + + public abstract class Element + { + public string Name; + } + + public class File : Element + { + public string Filename; + public string ContentType; + public byte[] Data; + + public File(string name, string filename, string contentType, byte[] data) + { + Name = name; + Filename = filename; + ContentType = contentType; + Data = data; + } + } + + public class Parameter : Element + { + public string Value; + + public Parameter(string name, string value) + { + Name = name; + Value = value; + } + } + + #endregion Helper Classes + + public static HttpWebResponse Post(HttpWebRequest request, List postParameters) + { + string boundary = Boundary(); + + // Set up the request properties + request.Method = "POST"; + request.ContentType = "multipart/form-data; boundary=" + boundary; + + #region Stream Writing + + using (MemoryStream formDataStream = new MemoryStream()) + { + foreach (var param in postParameters) + { + if (param is File) + { + File file = (File)param; + + // Add just the first part of this param, since we will write the file data directly to the Stream + string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n", + boundary, + file.Name, + !String.IsNullOrEmpty(file.Filename) ? file.Filename : "tempfile", + file.ContentType); + + formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, header.Length); + formDataStream.Write(file.Data, 0, file.Data.Length); + } + else + { + Parameter parameter = (Parameter)param; + + string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}\r\n", + boundary, + parameter.Name, + parameter.Value); + formDataStream.Write(Encoding.UTF8.GetBytes(postData), 0, postData.Length); + } + } + + // Add the end of the request + byte[] footer = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n"); + formDataStream.Write(footer, 0, footer.Length); + + request.ContentLength = formDataStream.Length; + + // Copy the temporary stream to the network stream + formDataStream.Seek(0, SeekOrigin.Begin); + using (Stream requestStream = request.GetRequestStream()) + formDataStream.CopyTo(requestStream, (int)formDataStream.Length); + } + + #endregion Stream Writing + + return request.GetResponse() as HttpWebResponse; + } + + private static string Boundary() + { + Random rnd = new Random(); + string formDataBoundary = String.Empty; + + while (formDataBoundary.Length < 15) + formDataBoundary = formDataBoundary + rnd.Next(); + + formDataBoundary = formDataBoundary.Substring(0, 15); + formDataBoundary = "-----------------------------" + formDataBoundary; + + return formDataBoundary; + } + } +} diff --git a/OpenSim/Framework/UntrustedWebRequest.cs b/OpenSim/Framework/UntrustedWebRequest.cs new file mode 100644 index 0000000000..1af7c41558 --- /dev/null +++ b/OpenSim/Framework/UntrustedWebRequest.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Net.Security; +using System.Text; +using log4net; + +namespace OpenSim.Framework +{ + /// + /// Used for requests to untrusted endpoints that may potentially be + /// malicious + /// + public static class UntrustedHttpWebRequest + { + /// Setting this to true will allow HTTP connections to localhost + private const bool DEBUG = true; + + private static readonly ILog m_log = + LogManager.GetLogger( + System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private static readonly ICollection allowableSchemes = new List { "http", "https" }; + + /// + /// Creates an HttpWebRequest that is hardened against malicious + /// endpoints after ensuring the given Uri is safe to retrieve + /// + /// Web location to request + /// A hardened HttpWebRequest if the uri was determined to be safe + /// If uri is null + /// If uri is unsafe + public static HttpWebRequest Create(Uri uri) + { + return Create(uri, DEBUG, 1000 * 5, 1000 * 20, 10); + } + + /// + /// Creates an HttpWebRequest that is hardened against malicious + /// endpoints after ensuring the given Uri is safe to retrieve + /// + /// Web location to request + /// True to allow connections to localhost, otherwise false + /// Read write timeout, in milliseconds + /// Connection timeout, in milliseconds + /// Maximum number of allowed redirects + /// A hardened HttpWebRequest if the uri was determined to be safe + /// If uri is null + /// If uri is unsafe + public static HttpWebRequest Create(Uri uri, bool allowLoopback, int readWriteTimeoutMS, int timeoutMS, int maximumRedirects) + { + if (uri == null) + throw new ArgumentNullException("uri"); + + if (!IsUriAllowable(uri, allowLoopback)) + throw new ArgumentException("Uri " + uri + " was rejected"); + + HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(uri); + httpWebRequest.MaximumAutomaticRedirections = maximumRedirects; + httpWebRequest.ReadWriteTimeout = readWriteTimeoutMS; + httpWebRequest.Timeout = timeoutMS; + httpWebRequest.KeepAlive = false; + + return httpWebRequest; + } + + public static string PostToUntrustedUrl(Uri url, string data) + { + try + { + byte[] requestData = System.Text.Encoding.UTF8.GetBytes(data); + + HttpWebRequest request = Create(url); + request.Method = "POST"; + request.ContentLength = requestData.Length; + request.ContentType = "application/x-www-form-urlencoded"; + + using (Stream requestStream = request.GetRequestStream()) + requestStream.Write(requestData, 0, requestData.Length); + + using (WebResponse response = request.GetResponse()) + { + using (Stream responseStream = response.GetResponseStream()) + return responseStream.GetStreamString(); + } + } + catch (Exception ex) + { + m_log.Warn("POST to untrusted URL " + url + " failed: " + ex.Message); + return null; + } + } + + public static string GetUntrustedUrl(Uri url) + { + try + { + HttpWebRequest request = Create(url); + + using (WebResponse response = request.GetResponse()) + { + using (Stream responseStream = response.GetResponseStream()) + return responseStream.GetStreamString(); + } + } + catch (Exception ex) + { + m_log.Warn("GET from untrusted URL " + url + " failed: " + ex.Message); + return null; + } + } + + /// + /// Determines whether a URI is allowed based on scheme and host name. + /// No requireSSL check is done here + /// + /// True to allow loopback addresses to be used + /// The URI to test for whether it should be allowed. + /// + /// true if [is URI allowable] [the specified URI]; otherwise, false. + /// + private static bool IsUriAllowable(Uri uri, bool allowLoopback) + { + if (!allowableSchemes.Contains(uri.Scheme)) + { + m_log.WarnFormat("Rejecting URL {0} because it uses a disallowed scheme.", uri); + return false; + } + + // Try to interpret the hostname as an IP address so we can test for internal + // IP address ranges. Note that IP addresses can appear in many forms + // (e.g. http://127.0.0.1, http://2130706433, http://0x0100007f, http://::1 + // So we convert them to a canonical IPAddress instance, and test for all + // non-routable IP ranges: 10.*.*.*, 127.*.*.*, ::1 + // Note that Uri.IsLoopback is very unreliable, not catching many of these variants. + IPAddress hostIPAddress; + if (IPAddress.TryParse(uri.DnsSafeHost, out hostIPAddress)) + { + byte[] addressBytes = hostIPAddress.GetAddressBytes(); + + // The host is actually an IP address. + switch (hostIPAddress.AddressFamily) + { + case System.Net.Sockets.AddressFamily.InterNetwork: + if (!allowLoopback && (addressBytes[0] == 127 || addressBytes[0] == 10)) + { + m_log.WarnFormat("Rejecting URL {0} because it is a loopback address.", uri); + return false; + } + break; + case System.Net.Sockets.AddressFamily.InterNetworkV6: + if (!allowLoopback && IsIPv6Loopback(hostIPAddress)) + { + m_log.WarnFormat("Rejecting URL {0} because it is a loopback address.", uri); + return false; + } + break; + default: + m_log.WarnFormat("Rejecting URL {0} because it does not use an IPv4 or IPv6 address.", uri); + return false; + } + } + else + { + // The host is given by name. We require names to contain periods to + // help make sure it's not an internal address. + if (!allowLoopback && !uri.Host.Contains(".")) + { + m_log.WarnFormat("Rejecting URL {0} because it does not contain a period in the host name.", uri); + return false; + } + } + + return true; + } + + /// + /// Determines whether an IP address is the IPv6 equivalent of "localhost/127.0.0.1". + /// + /// The ip address to check. + /// + /// true if this is a loopback IP address; false otherwise. + /// + private static bool IsIPv6Loopback(IPAddress ip) + { + if (ip == null) + throw new ArgumentNullException("ip"); + + byte[] addressBytes = ip.GetAddressBytes(); + for (int i = 0; i < addressBytes.Length - 1; i++) + { + if (addressBytes[i] != 0) + return false; + } + + if (addressBytes[addressBytes.Length - 1] != 1) + return false; + + return true; + } + } +} diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs new file mode 100644 index 0000000000..d9782ff9ac --- /dev/null +++ b/OpenSim/Framework/WebUtil.cs @@ -0,0 +1,330 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.IO; +using System.Net; +using System.Net.Security; +using System.Reflection; +using System.Text; +using System.Web; +using log4net; +using OpenSim.Framework.Servers.HttpServer; +using OpenMetaverse.StructuredData; + +namespace OpenSim.Framework +{ + /// + /// Miscellaneous static methods and extension methods related to the web + /// + public static class WebUtil + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// Send LLSD to an HTTP client in application/llsd+json form + /// + /// HTTP response to send the data in + /// LLSD to send to the client + public static void SendJSONResponse(OSHttpResponse response, OSDMap body) + { + byte[] responseData = Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(body)); + + response.ContentEncoding = Encoding.UTF8; + response.ContentLength = responseData.Length; + response.ContentType = "application/llsd+json"; + response.Body.Write(responseData, 0, responseData.Length); + } + + /// + /// Send LLSD to an HTTP client in application/llsd+xml form + /// + /// HTTP response to send the data in + /// LLSD to send to the client + public static void SendXMLResponse(OSHttpResponse response, OSDMap body) + { + byte[] responseData = OSDParser.SerializeLLSDXmlBytes(body); + + response.ContentEncoding = Encoding.UTF8; + response.ContentLength = responseData.Length; + response.ContentType = "application/llsd+xml"; + response.Body.Write(responseData, 0, responseData.Length); + } + + /// + /// Make a GET or GET-like request to a web service that returns LLSD + /// or JSON data + /// + public static OSDMap ServiceRequest(string url, string httpVerb) + { + string errorMessage; + + try + { + HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); + request.Method = httpVerb; + + using (WebResponse response = request.GetResponse()) + { + using (Stream responseStream = response.GetResponseStream()) + { + try + { + string responseStr = responseStream.GetStreamString(); + OSD responseOSD = OSDParser.Deserialize(responseStr); + if (responseOSD.Type == OSDType.Map) + return (OSDMap)responseOSD; + else + errorMessage = "Response format was invalid."; + } + catch + { + errorMessage = "Failed to parse the response."; + } + } + } + } + catch (Exception ex) + { + m_log.Warn("GET from URL " + url + " failed: " + ex.Message); + errorMessage = ex.Message; + } + + return new OSDMap { { "Message", OSD.FromString("Service request failed. " + errorMessage) } }; + } + + /// + /// POST URL-encoded form data to a web service that returns LLSD or + /// JSON data + /// + public static OSDMap PostToService(string url, NameValueCollection data) + { + string errorMessage; + + try + { + string queryString = BuildQueryString(data); + byte[] requestData = System.Text.Encoding.UTF8.GetBytes(queryString); + + HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); + request.Method = "POST"; + request.ContentLength = requestData.Length; + request.ContentType = "application/x-www-form-urlencoded"; + + using (Stream requestStream = request.GetRequestStream()) + requestStream.Write(requestData, 0, requestData.Length); + + using (WebResponse response = request.GetResponse()) + { + using (Stream responseStream = response.GetResponseStream()) + { + try + { + string responseStr = responseStream.GetStreamString(); + OSD responseOSD = OSDParser.Deserialize(responseStr); + if (responseOSD.Type == OSDType.Map) + return (OSDMap)responseOSD; + else + errorMessage = "Response format was invalid."; + } + catch + { + errorMessage = "Failed to parse the response."; + } + } + } + } + catch (Exception ex) + { + m_log.Warn("POST to URL " + url + " failed: " + ex.Message); + errorMessage = ex.Message; + } + + return new OSDMap { { "Message", OSD.FromString("Service request failed. " + errorMessage) } }; + } + + #region Uri + + /// + /// Combines a Uri that can contain both a base Uri and relative path + /// with a second relative path fragment + /// + /// Starting (base) Uri + /// Relative path fragment to append to the end + /// of the Uri + /// The combined Uri + /// This is similar to the Uri constructor that takes a base + /// Uri and the relative path, except this method can append a relative + /// path fragment on to an existing relative path + public static Uri Combine(this Uri uri, string fragment) + { + string fragment1 = uri.Fragment; + string fragment2 = fragment; + + if (!fragment1.EndsWith("/")) + fragment1 = fragment1 + '/'; + if (fragment2.StartsWith("/")) + fragment2 = fragment2.Substring(1); + + return new Uri(uri, fragment1 + fragment2); + } + + /// + /// Combines a Uri that can contain both a base Uri and relative path + /// with a second relative path fragment. If the fragment is absolute, + /// it will be returned without modification + /// + /// Starting (base) Uri + /// Relative path fragment to append to the end + /// of the Uri, or an absolute Uri to return unmodified + /// The combined Uri + public static Uri Combine(this Uri uri, Uri fragment) + { + if (fragment.IsAbsoluteUri) + return fragment; + + string fragment1 = uri.Fragment; + string fragment2 = fragment.ToString(); + + if (!fragment1.EndsWith("/")) + fragment1 = fragment1 + '/'; + if (fragment2.StartsWith("/")) + fragment2 = fragment2.Substring(1); + + return new Uri(uri, fragment1 + fragment2); + } + + /// + /// Appends a query string to a Uri that may or may not have existing + /// query parameters + /// + /// Uri to append the query to + /// Query string to append. Can either start with ? + /// or just containg key/value pairs + /// String representation of the Uri with the query string + /// appended + public static string AppendQuery(this Uri uri, string query) + { + if (String.IsNullOrEmpty(query)) + return uri.ToString(); + + if (query[0] == '?' || query[0] == '&') + query = query.Substring(1); + + string uriStr = uri.ToString(); + + if (uriStr.Contains("?")) + return uriStr + '&' + query; + else + return uriStr + '?' + query; + } + + #endregion Uri + + #region NameValueCollection + + /// + /// Convert a NameValueCollection into a query string. This is the + /// inverse of HttpUtility.ParseQueryString() + /// + /// Collection of key/value pairs to convert + /// A query string with URL-escaped values + public static string BuildQueryString(NameValueCollection parameters) + { + List items = new List(parameters.Count); + + foreach (string key in parameters.Keys) + { + foreach (string value in parameters.GetValues(key)) + items.Add(String.Concat(key, "=", HttpUtility.UrlEncode(value ?? String.Empty))); + } + + return String.Join("&", items.ToArray()); + } + + /// + /// + /// + /// + /// + /// + public static string GetOne(this NameValueCollection collection, string key) + { + string[] values = collection.GetValues(key); + if (values != null && values.Length > 0) + return values[0]; + + return null; + } + + #endregion NameValueCollection + + #region Stream + + /// + /// Copies the contents of one stream to another, starting at the + /// current position of each stream + /// + /// The stream to copy from, at the position + /// where copying should begin + /// The stream to copy to, at the position where + /// bytes should be written + /// The maximum bytes to copy + /// The total number of bytes copied + /// + /// Copying begins at the streams' current positions. The positions are + /// NOT reset after copying is complete. + /// + public static int CopyTo(this Stream copyFrom, Stream copyTo, int maximumBytesToCopy) + { + byte[] buffer = new byte[4096]; + int readBytes; + int totalCopiedBytes = 0; + + while ((readBytes = copyFrom.Read(buffer, 0, Math.Min(4096, maximumBytesToCopy))) > 0) + { + int writeBytes = Math.Min(maximumBytesToCopy, readBytes); + copyTo.Write(buffer, 0, writeBytes); + totalCopiedBytes += writeBytes; + maximumBytesToCopy -= writeBytes; + } + + return totalCopiedBytes; + } + + /// + /// Converts an entire stream to a string, regardless of current stream + /// position + /// + /// The stream to convert to a string + /// + /// When this method is done, the stream position will be + /// reset to its previous position before this method was called + public static string GetStreamString(this Stream stream) + { + string value = null; + + if (stream != null && stream.CanRead) + { + long rewindPos = -1; + + if (stream.CanSeek) + { + rewindPos = stream.Position; + stream.Seek(0, SeekOrigin.Begin); + } + + StreamReader reader = new StreamReader(stream); + value = reader.ReadToEnd(); + + if (rewindPos >= 0) + stream.Seek(rewindPos, SeekOrigin.Begin); + } + + return value; + } + + #endregion Stream + } +} diff --git a/prebuild.xml b/prebuild.xml index 09d78e9e22..98a471bb9f 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -157,6 +157,7 @@ + From 60fde0c83a90211fffb0732ecffe9100424dee33 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 3 Mar 2010 23:03:41 +0000 Subject: [PATCH 14/18] minor: remove a couple of compiler warnings --- OpenSim/Framework/RegionCommsListener.cs | 2 +- OpenSim/Framework/RegionInfo.cs | 18 ++++-------------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/OpenSim/Framework/RegionCommsListener.cs b/OpenSim/Framework/RegionCommsListener.cs index 718a5563e9..3e0955d073 100644 --- a/OpenSim/Framework/RegionCommsListener.cs +++ b/OpenSim/Framework/RegionCommsListener.cs @@ -45,7 +45,7 @@ namespace OpenSim.Framework private GenericCall2 handlerExpectChildAgent = null; // OnExpectChildAgent; private ExpectUserDelegate handlerExpectUser = null; // OnExpectUser private UpdateNeighbours handlerNeighboursUpdate = null; // OnNeighboursUpdate; - private PrimCrossing handlerPrimCrossingIntoRegion = null; // OnPrimCrossingIntoRegion; +// private PrimCrossing handlerPrimCrossingIntoRegion = null; // OnPrimCrossingIntoRegion; private LogOffUser handlerLogOffUser = null; private GetLandData handlerGetLandData = null; diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index ac38ac2971..5d63da7b14 100644 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs @@ -351,7 +351,7 @@ namespace OpenSim.Framework private void ReadNiniConfig(IConfigSource source, string name) { - bool creatingNew = false; +// bool creatingNew = false; if (source.Configs.Count == 0) { @@ -368,7 +368,7 @@ namespace OpenSim.Framework source.AddConfig(name); - creatingNew = true; +// creatingNew = true; } if (name == String.Empty) @@ -378,7 +378,7 @@ namespace OpenSim.Framework { source.AddConfig(name); - creatingNew = true; +// creatingNew = true; } IConfig config = source.Configs[name]; @@ -397,15 +397,8 @@ namespace OpenSim.Framework RegionID = new UUID(regionUUID); originRegionID = RegionID; // What IS this?! - - - // Region name - // + RegionName = name; - - - // Region location - // string location = config.GetString("Location", String.Empty); if (location == String.Empty) @@ -421,12 +414,9 @@ namespace OpenSim.Framework // Datastore (is this implemented? Omitted from example!) - // DataStore = config.GetString("Datastore", String.Empty); - // Internal IP - // IPAddress address; if (config.Contains("InternalAddress")) From 5dd75931792149d81d410e64722575c33805e885 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 3 Mar 2010 23:05:48 +0000 Subject: [PATCH 15/18] remove a final trace of the old framework.communications.tests This might make panda pass again! --- .nant/local.include | 1 - 1 file changed, 1 deletion(-) diff --git a/.nant/local.include b/.nant/local.include index c611bd2391..29674ab671 100644 --- a/.nant/local.include +++ b/.nant/local.include @@ -254,7 +254,6 @@ - From 8305e6af076cd2fdf7c016926a5ea48718dcf955 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 3 Mar 2010 23:29:09 +0000 Subject: [PATCH 16/18] refactor: push sog.SendPartFullUpdate() down into sop where it better belongs no functional changes --- .../Framework/Scenes/SceneObjectGroup.cs | 37 ++---------- .../Framework/Scenes/SceneObjectPart.cs | 59 ++++++++++++++----- 2 files changed, 47 insertions(+), 49 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index c14b39ad85..19144a7101 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1490,51 +1490,22 @@ namespace OpenSim.Region.Framework.Scenes #endregion - #region Client Updating - public void SendFullUpdateToClient(IClientAPI remoteClient) { - SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); + RootPart.SendFullUpdate( + remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); lock (m_parts) { foreach (SceneObjectPart part in m_parts.Values) { if (part != RootPart) - SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); + part.SendFullUpdate( + remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); } } } - /// - /// Send a full update to the client for the given part - /// - /// - /// - internal void SendPartFullUpdate(IClientAPI remoteClient, SceneObjectPart part, uint clientFlags) - { -// m_log.DebugFormat( -// "[SOG]: Sendinging part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId); - - if (m_rootPart.UUID == part.UUID) - { - if (IsAttachment) - { - part.SendFullUpdateToClient(remoteClient, m_rootPart.AttachedPos, clientFlags); - } - else - { - part.SendFullUpdateToClient(remoteClient, AbsolutePosition, clientFlags); - } - } - else - { - part.SendFullUpdateToClient(remoteClient, clientFlags); - } - } - - #endregion - #region Copying /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 5c283bc4fe..b8c8d88e7a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2834,29 +2834,59 @@ namespace OpenSim.Region.Framework.Scenes } } - /// - /// - /// - /// - public void SendFullUpdate(IClientAPI remoteClient, uint clientFlags) - { - m_parentGroup.SendPartFullUpdate(remoteClient, this, clientFlags); - } +// /// +// /// +// /// +// /// +// public void SendFullUpdate(IClientAPI remoteClient, uint clientFlags) +// { +// m_parentGroup.SendPartFullUpdate(remoteClient, this, clientFlags); +// } + /// - /// + /// Send a full update to the client for the given part + /// + /// + /// + protected internal void SendFullUpdate(IClientAPI remoteClient, uint clientFlags) + { +// m_log.DebugFormat( +// "[SOG]: Sendinging part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId); + + if (IsRoot) + { + if (IsAttachment) + { + SendFullUpdateToClient(remoteClient, AttachedPos, clientFlags); + } + else + { + SendFullUpdateToClient(remoteClient, AbsolutePosition, clientFlags); + } + } + else + { + SendFullUpdateToClient(remoteClient, clientFlags); + } + } + + /// + /// Send a full update for this part to all clients. /// public void SendFullUpdateToAllClients() { ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); for (int i = 0; i < avatars.Length; i++) { - // Ugly reference :( - m_parentGroup.SendPartFullUpdate(avatars[i].ControllingClient, this, - avatars[i].GenerateClientFlags(UUID)); + SendFullUpdate(avatars[i].ControllingClient, avatars[i].GenerateClientFlags(UUID)); } } + /// + /// Send a full update to all clients except the one nominated. + /// + /// public void SendFullUpdateToAllClientsExcept(UUID agentID) { ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); @@ -2864,10 +2894,7 @@ namespace OpenSim.Region.Framework.Scenes { // Ugly reference :( if (avatars[i].UUID != agentID) - { - m_parentGroup.SendPartFullUpdate(avatars[i].ControllingClient, this, - avatars[i].GenerateClientFlags(UUID)); - } + SendFullUpdate(avatars[i].ControllingClient, avatars[i].GenerateClientFlags(UUID)); } } From c4ba2e5dfb0202677969b01c76371c4080d8dcb9 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 3 Mar 2010 23:35:23 +0000 Subject: [PATCH 17/18] minor: remove some compiler warnings --- .../Framework/Scenes/SceneCommunicationService.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index e87f7ca261..bd8ccce6e1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -103,15 +103,15 @@ namespace OpenSim.Region.Framework.Scenes /// public event GetLandData OnGetLandData; - private AgentCrossing handlerAvatarCrossingIntoRegion = null; // OnAvatarCrossingIntoRegion; - private ExpectUserDelegate handlerExpectUser = null; // OnExpectUser; - private CloseAgentConnection handlerCloseAgentConnection = null; // OnCloseAgentConnection; - private PrimCrossing handlerPrimCrossingIntoRegion = null; // OnPrimCrossingIntoRegion; +// private AgentCrossing handlerAvatarCrossingIntoRegion = null; // OnAvatarCrossingIntoRegion; +// private ExpectUserDelegate handlerExpectUser = null; // OnExpectUser; +// private CloseAgentConnection handlerCloseAgentConnection = null; // OnCloseAgentConnection; +// private PrimCrossing handlerPrimCrossingIntoRegion = null; // OnPrimCrossingIntoRegion; //private RegionUp handlerRegionUp = null; // OnRegionUp; - private ChildAgentUpdate handlerChildAgentUpdate = null; // OnChildAgentUpdate; +// private ChildAgentUpdate handlerChildAgentUpdate = null; // OnChildAgentUpdate; //private RemoveKnownRegionsFromAvatarList handlerRemoveKnownRegionFromAvatar = null; // OnRemoveKnownRegionFromAvatar; - private LogOffUser handlerLogOffUser = null; - private GetLandData handlerGetLandData = null; // OnGetLandData +// private LogOffUser handlerLogOffUser = null; +// private GetLandData handlerGetLandData = null; // OnGetLandData public KiPrimitiveDelegate KiPrimitive; From 716e6f20e1393a1968778588ee1d963b42e063fd Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 3 Mar 2010 23:40:32 +0000 Subject: [PATCH 18/18] compiler warnings revealed that public PlaySoundSlavePrims properties were changing the wrong protected fields. correcting these may resolve the sound problems seen recently on the mailing list, though not guaranteed. --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 4 ++-- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 19144a7101..37b4fd6348 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -417,8 +417,8 @@ namespace OpenSim.Region.Framework.Scenes private List m_PlaySoundSlavePrims = new List(); public List PlaySoundSlavePrims { - get { return m_LoopSoundSlavePrims; } - set { m_LoopSoundSlavePrims = value; } + get { return m_PlaySoundSlavePrims; } + set { m_PlaySoundSlavePrims = value; } } private SceneObjectPart m_LoopSoundMasterPrim = null; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index b8c8d88e7a..10a186e164 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -568,8 +568,8 @@ namespace OpenSim.Region.Framework.Scenes private List m_PlaySoundSlavePrims = new List(); public List PlaySoundSlavePrims { - get { return m_LoopSoundSlavePrims; } - set { m_LoopSoundSlavePrims = value; } + get { return m_PlaySoundSlavePrims; } + set { m_PlaySoundSlavePrims = value; } } private SceneObjectPart m_LoopSoundMasterPrim = null;