From a9b39d6e5d7961a03043e4a793dce8534035214a Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 16 Dec 2011 20:53:50 +0000 Subject: [PATCH 01/17] Tunnel [GroupsModule] DebugEnabled setting down into XmlRpcGroupsServicesConnectorModule so that we can record cache misses --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 9 +-------- .../XmlRpcGroupsServicesConnectorModule.cs | 12 +++++++++--- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index d452905f3f..8baeaa4181 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -29,25 +29,18 @@ using System; using System.Collections.Generic; using System.Reflection; using System.Timers; - using log4net; using Mono.Addins; using Nini.Config; - using OpenMetaverse; using OpenMetaverse.StructuredData; - using OpenSim.Framework; using OpenSim.Framework.Communications; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; - using OpenSim.Services.Interfaces; - using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; - - namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] @@ -90,7 +83,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Configuration settings private bool m_groupsEnabled = false; private bool m_groupNoticesEnabled = true; - private bool m_debugEnabled = true; + private bool m_debugEnabled = false; #region IRegionModuleBase Members diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index a08bcd0e8a..52fc27dcf5 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -52,6 +52,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private bool m_debugEnabled = false; + public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | GroupPowers.Accountable | GroupPowers.JoinChat | @@ -81,7 +83,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private Dictionary> m_groupsAgentsDroppedFromChatSession = new Dictionary>(); private Dictionary> m_groupsAgentsInvitedToChatSession = new Dictionary>(); - #region IRegionModuleBase Members public string Name @@ -115,7 +116,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } - m_log.InfoFormat("[XMLRPC-GROUPS-CONNECTOR]: Initializing {0}", this.Name); + m_log.DebugFormat("[XMLRPC-GROUPS-CONNECTOR]: Initializing {0}", this.Name); m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); if ((m_groupsServerURI == null) || @@ -142,6 +143,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_log.InfoFormat("[XMLRPC-GROUPS-CONNECTOR]: Groups Cache Timeout set to {0}.", m_cacheTimeout); } + m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", false); + // If we got all the config options we need, lets start'er'up m_memoryCache = new ExpiringCache(); m_connectorEnabled = true; @@ -150,7 +153,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void Close() { - m_log.InfoFormat("[XMLRPC-GROUPS-CONNECTOR]: Closing {0}", this.Name); + m_log.DebugFormat("[XMLRPC-GROUPS-CONNECTOR]: Closing {0}", this.Name); } public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) @@ -958,6 +961,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (resp == null) { + if (m_debugEnabled) + m_log.DebugFormat("[XMLRPC-GROUPS-CONNECTOR]: Cache miss for key {0}", CacheKey); + string UserService; UUID SessionID; GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID); From 5d79f857b0020715f4fed4fdd9d9b764c1864960 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 16 Dec 2011 20:54:28 +0000 Subject: [PATCH 02/17] Comment out accidentally left in "Adding physics prim" log message --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index afe646ccf4..f716687275 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -1780,7 +1780,7 @@ namespace OpenSim.Region.Physics.OdePlugin public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, Vector3 size, Quaternion rotation, bool isPhysical, uint localid) { - m_log.DebugFormat("[ODE SCENE]: Adding physics prim {0} {1} to physics scene {2}", primName, localid, Name); +// m_log.DebugFormat("[ODE SCENE]: Adding physics prim {0} {1} to physics scene {2}", primName, localid, Name); return AddPrim(primName, position, size, rotation, pbs, isPhysical, localid); } From 5c4056660fe7678315716e52cfe57da0ba448efe Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 16 Dec 2011 21:16:01 +0000 Subject: [PATCH 03/17] Don't pass on ChaneWaterHeight event from EventManager is new water height is less than 0 This is to stop bad values and subsequent viewer crashes. Thanks to Michelle Argus for this patch. --- OpenSim/Region/Framework/Scenes/EventManager.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 4a4d98fa74..4f71915fe8 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -1564,6 +1564,12 @@ namespace OpenSim.Region.Framework.Scenes public void TriggerRequestChangeWaterHeight(float height) { + if (height < 0) + { + // ignore negative water height + return; + } + RequestChangeWaterHeight handlerRequestChangeWaterHeight = OnRequestChangeWaterHeight; if (handlerRequestChangeWaterHeight != null) { From a3a17e929e7a39566a677672572433fe35d25849 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 16 Dec 2011 23:20:12 +0000 Subject: [PATCH 04/17] Stop generating client flags when we send out full object updates. These were entirely unused. --- .../ClientStack/Linden/UDP/LLClientView.cs | 1 + .../Framework/Scenes/SceneObjectGroup.cs | 5 ++-- .../Framework/Scenes/SceneObjectPart.cs | 26 ++++++------------- .../Region/Framework/Scenes/ScenePresence.cs | 6 ----- 4 files changed, 11 insertions(+), 27 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 9c86c7496c..8b41c493da 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -10345,6 +10345,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } return true; } + private bool HandleGroupRoleMembersRequest(IClientAPI sender, Packet Pack) { GroupRoleMembersRequestPacket groupRoleMembersRequest = diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index f9e0b835c5..20ef8c9d2d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1377,15 +1377,14 @@ namespace OpenSim.Region.Framework.Scenes // Used when the client initially connects and when client sends RequestPrim packet public void SendFullUpdateToClient(IClientAPI remoteClient) { - RootPart.SendFullUpdate( - remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); + RootPart.SendFullUpdate(remoteClient); SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) { SceneObjectPart part = parts[i]; if (part != RootPart) - part.SendFullUpdate(remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); + part.SendFullUpdate(remoteClient); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index f5a00d708c..598b310e9b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2836,8 +2836,7 @@ namespace OpenSim.Region.Framework.Scenes /// Send a full update to the client for the given part /// /// - /// - protected internal void SendFullUpdate(IClientAPI remoteClient, uint clientFlags) + protected internal void SendFullUpdate(IClientAPI remoteClient) { if (ParentGroup == null) return; @@ -2849,16 +2848,16 @@ namespace OpenSim.Region.Framework.Scenes { if (ParentGroup.IsAttachment) { - SendFullUpdateToClient(remoteClient, AttachedPos, clientFlags); + SendFullUpdateToClient(remoteClient, AttachedPos); } else { - SendFullUpdateToClient(remoteClient, AbsolutePosition, clientFlags); + SendFullUpdateToClient(remoteClient, AbsolutePosition); } } else { - SendFullUpdateToClient(remoteClient, clientFlags); + SendFullUpdateToClient(remoteClient); } } @@ -2872,7 +2871,7 @@ namespace OpenSim.Region.Framework.Scenes ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) { - SendFullUpdate(avatar.ControllingClient, avatar.GenerateClientFlags(UUID)); + SendFullUpdate(avatar.ControllingClient); }); } @@ -2880,12 +2879,9 @@ namespace OpenSim.Region.Framework.Scenes /// Sends a full update to the client /// /// - /// - public void SendFullUpdateToClient(IClientAPI remoteClient, uint clientflags) + public void SendFullUpdateToClient(IClientAPI remoteClient) { - Vector3 lPos; - lPos = OffsetPosition; - SendFullUpdateToClient(remoteClient, lPos, clientflags); + SendFullUpdateToClient(remoteClient, OffsetPosition); } /// @@ -2893,8 +2889,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// - /// - public void SendFullUpdateToClient(IClientAPI remoteClient, Vector3 lPos, uint clientFlags) + public void SendFullUpdateToClient(IClientAPI remoteClient, Vector3 lPos) { if (ParentGroup == null) return; @@ -2911,15 +2906,10 @@ namespace OpenSim.Region.Framework.Scenes (ParentGroup.AttachmentPoint >= 31) && (ParentGroup.AttachmentPoint <= 38)) return; - clientFlags &= ~(uint) PrimFlags.CreateSelected; - if (remoteClient.AgentId == OwnerID) { if ((Flags & PrimFlags.CreateSelected) != 0) - { - clientFlags |= (uint) PrimFlags.CreateSelected; Flags &= ~PrimFlags.CreateSelected; - } } //bool isattachment = IsAttachment; //if (LocalId != ParentGroup.RootPart.LocalId) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 800b7e0597..7be95cd9d1 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -784,7 +784,6 @@ namespace OpenSim.Region.Framework.Scenes public void RegisterToEvents() { ControllingClient.OnCompleteMovementToRegion += CompleteMovement; - //ControllingClient.OnCompleteMovementToRegion += SendInitialData; ControllingClient.OnAgentUpdate += HandleAgentUpdate; ControllingClient.OnAgentRequestSit += HandleAgentRequestSit; ControllingClient.OnAgentSit += HandleAgentSit; @@ -832,11 +831,6 @@ namespace OpenSim.Region.Framework.Scenes #endregion - public uint GenerateClientFlags(UUID ObjectID) - { - return m_scene.Permissions.GenerateClientFlags(m_uuid, ObjectID); - } - #region Status Methods /// From 1bf05fbb1f8cc4832d8c8963556d8082181f810a Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 17 Dec 2011 00:11:17 +0000 Subject: [PATCH 05/17] refactor: simplify methods in Scene.PacketHandlers.cs by using GetGroupByPrim() rather than retrieving GetEntities() and inspecting the entire list --- .../Framework/Scenes/Scene.PacketHandlers.cs | 211 ++++++------------ .../Framework/Scenes/SceneObjectGroup.cs | 14 +- 2 files changed, 82 insertions(+), 143 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index 6ba74c7cc6..f9d0e0aab5 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -116,18 +116,10 @@ namespace OpenSim.Region.Framework.Scenes /// public void RequestPrim(uint primLocalID, IClientAPI remoteClient) { - EntityBase[] entityList = GetEntities(); - foreach (EntityBase ent in entityList) - { - if (ent is SceneObjectGroup) - { - if (((SceneObjectGroup)ent).LocalId == primLocalID) - { - ((SceneObjectGroup)ent).SendFullUpdateToClient(remoteClient); - return; - } - } - } + SceneObjectGroup sog = GetGroupByPrim(primLocalID); + + if (sog != null) + sog.SendFullUpdateToClient(remoteClient); } /// @@ -137,47 +129,28 @@ namespace OpenSim.Region.Framework.Scenes /// public void SelectPrim(uint primLocalID, IClientAPI remoteClient) { - EntityBase[] entityList = GetEntities(); - foreach (EntityBase ent in entityList) - { - if (ent is SceneObjectGroup) - { - if (((SceneObjectGroup) ent).LocalId == primLocalID) - { - ((SceneObjectGroup) ent).SendPropertiesToClient(remoteClient); - ((SceneObjectGroup) ent).IsSelected = true; - // A prim is only tainted if it's allowed to be edited by the person clicking it. - if (Permissions.CanEditObject(((SceneObjectGroup)ent).UUID, remoteClient.AgentId) - || Permissions.CanMoveObject(((SceneObjectGroup)ent).UUID, remoteClient.AgentId)) - { - EventManager.TriggerParcelPrimCountTainted(); - } - break; - } - else - { - // We also need to check the children of this prim as they - // can be selected as well and send property information - bool foundPrim = false; - - SceneObjectGroup sog = ent as SceneObjectGroup; + SceneObjectPart part = GetSceneObjectPart(primLocalID); - SceneObjectPart[] partList = sog.Parts; - foreach (SceneObjectPart part in partList) - { - if (part.LocalId == primLocalID) - { - part.SendPropertiesToClient(remoteClient); - foundPrim = true; - break; - } - } - - if (foundPrim) - break; - } + if (null == part) + return; + + if (part.IsRoot) + { + SceneObjectGroup sog = part.ParentGroup; + sog.SendPropertiesToClient(remoteClient); + sog.IsSelected = true; + + // A prim is only tainted if it's allowed to be edited by the person clicking it. + if (Permissions.CanEditObject(sog.UUID, remoteClient.AgentId) + || Permissions.CanMoveObject(sog.UUID, remoteClient.AgentId)) + { + EventManager.TriggerParcelPrimCountTainted(); } } + else + { + part.SendPropertiesToClient(remoteClient); + } } /// @@ -250,121 +223,81 @@ namespace OpenSim.Region.Framework.Scenes public virtual void ProcessObjectGrab(uint localID, Vector3 offsetPos, IClientAPI remoteClient, List surfaceArgs) { - EntityBase[] EntityList = GetEntities(); + SceneObjectPart part = GetSceneObjectPart(localID); + + if (part == null) + return; + + SceneObjectGroup obj = part.ParentGroup; SurfaceTouchEventArgs surfaceArg = null; if (surfaceArgs != null && surfaceArgs.Count > 0) surfaceArg = surfaceArgs[0]; - foreach (EntityBase ent in EntityList) + // Currently only grab/touch for the single prim + // the client handles rez correctly + obj.ObjectGrabHandler(localID, offsetPos, remoteClient); + + // If the touched prim handles touches, deliver it + // If not, deliver to root prim + if ((part.ScriptEvents & scriptEvents.touch_start) != 0) + EventManager.TriggerObjectGrab(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg); + + // Deliver to the root prim if the touched prim doesn't handle touches + // or if we're meant to pass on touches anyway. Don't send to root prim + // if prim touched is the root prim as we just did it + if (((part.ScriptEvents & scriptEvents.touch_start) == 0) || + (part.PassTouches && (part.LocalId != obj.RootPart.LocalId))) { - if (ent is SceneObjectGroup) - { - SceneObjectGroup obj = ent as SceneObjectGroup; - if (obj != null) - { - // Is this prim part of the group - if (obj.HasChildPrim(localID)) - { - // Currently only grab/touch for the single prim - // the client handles rez correctly - obj.ObjectGrabHandler(localID, offsetPos, remoteClient); - - SceneObjectPart part = obj.GetChildPart(localID); - - // If the touched prim handles touches, deliver it - // If not, deliver to root prim - if ((part.ScriptEvents & scriptEvents.touch_start) != 0) - EventManager.TriggerObjectGrab(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg); - // Deliver to the root prim if the touched prim doesn't handle touches - // or if we're meant to pass on touches anyway. Don't send to root prim - // if prim touched is the root prim as we just did it - if (((part.ScriptEvents & scriptEvents.touch_start) == 0) || - (part.PassTouches && (part.LocalId != obj.RootPart.LocalId))) - { - EventManager.TriggerObjectGrab(obj.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg); - } - - return; - } - } - } + EventManager.TriggerObjectGrab(obj.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg); } } - public virtual void ProcessObjectGrabUpdate(UUID objectID, Vector3 offset, Vector3 pos, IClientAPI remoteClient, List surfaceArgs) + public virtual void ProcessObjectGrabUpdate( + UUID objectID, Vector3 offset, Vector3 pos, IClientAPI remoteClient, List surfaceArgs) { - EntityBase[] EntityList = GetEntities(); + SceneObjectPart part = GetSceneObjectPart(objectID); + if (part == null) + return; + + SceneObjectGroup obj = part.ParentGroup; SurfaceTouchEventArgs surfaceArg = null; if (surfaceArgs != null && surfaceArgs.Count > 0) surfaceArg = surfaceArgs[0]; - foreach (EntityBase ent in EntityList) + // If the touched prim handles touches, deliver it + // If not, deliver to root prim + if ((part.ScriptEvents & scriptEvents.touch) != 0) + EventManager.TriggerObjectGrabbing(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg); + // Deliver to the root prim if the touched prim doesn't handle touches + // or if we're meant to pass on touches anyway. Don't send to root prim + // if prim touched is the root prim as we just did it + if (((part.ScriptEvents & scriptEvents.touch) == 0) || + (part.PassTouches && (part.LocalId != obj.RootPart.LocalId))) { - if (ent is SceneObjectGroup) - { - SceneObjectGroup obj = ent as SceneObjectGroup; - if (obj != null) - { - // Is this prim part of the group - if (obj.HasChildPrim(objectID)) - { - SceneObjectPart part = obj.GetChildPart(objectID); - - // If the touched prim handles touches, deliver it - // If not, deliver to root prim - if ((part.ScriptEvents & scriptEvents.touch) != 0) - EventManager.TriggerObjectGrabbing(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg); - // Deliver to the root prim if the touched prim doesn't handle touches - // or if we're meant to pass on touches anyway. Don't send to root prim - // if prim touched is the root prim as we just did it - if (((part.ScriptEvents & scriptEvents.touch) == 0) || - (part.PassTouches && (part.LocalId != obj.RootPart.LocalId))) - { - EventManager.TriggerObjectGrabbing(obj.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg); - } - - return; - } - } - } + EventManager.TriggerObjectGrabbing(obj.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg); } } public virtual void ProcessObjectDeGrab(uint localID, IClientAPI remoteClient, List surfaceArgs) { - EntityBase[] EntityList = GetEntities(); + SceneObjectPart part = GetSceneObjectPart(localID); + if (part == null) + return; + + SceneObjectGroup obj = part.ParentGroup; SurfaceTouchEventArgs surfaceArg = null; if (surfaceArgs != null && surfaceArgs.Count > 0) surfaceArg = surfaceArgs[0]; - foreach (EntityBase ent in EntityList) - { - if (ent is SceneObjectGroup) - { - SceneObjectGroup obj = ent as SceneObjectGroup; - - // Is this prim part of the group - if (obj.HasChildPrim(localID)) - { - SceneObjectPart part=obj.GetChildPart(localID); - if (part != null) - { - // If the touched prim handles touches, deliver it - // If not, deliver to root prim - if ((part.ScriptEvents & scriptEvents.touch_end) != 0) - EventManager.TriggerObjectDeGrab(part.LocalId, 0, remoteClient, surfaceArg); - else - EventManager.TriggerObjectDeGrab(obj.RootPart.LocalId, part.LocalId, remoteClient, surfaceArg); - - return; - } - return; - } - } - } + // If the touched prim handles touches, deliver it + // If not, deliver to root prim + if ((part.ScriptEvents & scriptEvents.touch_end) != 0) + EventManager.TriggerObjectDeGrab(part.LocalId, 0, remoteClient, surfaceArg); + else + EventManager.TriggerObjectDeGrab(obj.RootPart.LocalId, part.LocalId, remoteClient, surfaceArg); } public void ProcessAvatarPickerRequest(IClientAPI client, UUID avatarID, UUID RequestID, string query) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 20ef8c9d2d..7bf8c34281 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1373,8 +1373,13 @@ namespace OpenSim.Region.Framework.Scenes #endregion - // Send the parts of this SOG to a single client - // Used when the client initially connects and when client sends RequestPrim packet + /// + /// Send the parts of this SOG to a single client + /// + /// + /// Used when the client initially connects and when client sends RequestPrim packet + /// + /// public void SendFullUpdateToClient(IClientAPI remoteClient) { RootPart.SendFullUpdate(remoteClient); @@ -1678,10 +1683,11 @@ namespace OpenSim.Region.Framework.Scenes /// /// Reset the UUIDs for all the prims that make up this group. - /// + /// + /// /// This is called by methods which want to add a new group to an existing scene, in order /// to ensure that there are no clashes with groups already present. - /// + /// public void ResetIDs() { lock (m_parts.SyncRoot) From 4f628849f36dd78a7f1608c7177760193c26d6d9 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 17 Dec 2011 00:14:48 +0000 Subject: [PATCH 06/17] Add more documentation to EstateConnectorString in StandaloneCommon.ini.example --- bin/config-include/StandaloneCommon.ini.example | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index b6b1eb5c97..84611ec258 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -13,7 +13,10 @@ ; Change the connection string to your db details ;StorageProvider = "OpenSim.Data.MySQL.dll" ;ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=***;Old Guids=true;" - ; Uncomment this line if you are using MySQL and want to use a different database for estates + + ; Uncomment this line if you are using MySQL and want to use a different database for estates. + ; The usual application for this is to allow estates to be spread out across multiple simulators by share the same database. + ; Most people won't need to do this so only uncomment if you know what you're doing. ;EstateConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=***;Old Guids=true;" ; MSSQL From 7f019cc196c046acd00aa8b58460f9aedcb650bb Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 17 Dec 2011 00:27:19 +0000 Subject: [PATCH 07/17] If a startup simulator script is present, run it after the normal region selection code rather than before. This allows the script to change the selected region without having it immediately undone. Thanks to Garmin Kawaguichi for this patch. --- OpenSim/Region/Application/OpenSim.cs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 8d98cc9b93..ea098936b2 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -188,6 +188,18 @@ namespace OpenSim } } + // Hook up to the watchdog timer + Watchdog.OnWatchdogTimeout += WatchdogTimeoutHandler; + + PrintFileToConsole("startuplogo.txt"); + + // For now, start at the 'root' level by default + if (m_sceneManager.Scenes.Count == 1) // If there is only one region, select it + ChangeSelectedRegion("region", + new string[] {"change", "region", m_sceneManager.Scenes[0].RegionInfo.RegionName}); + else + ChangeSelectedRegion("region", new string[] {"change", "region", "root"}); + //Run Startup Commands if (String.IsNullOrEmpty(m_startupCommandsFile)) { @@ -206,18 +218,6 @@ namespace OpenSim m_scriptTimer.Interval = 1200*1000; m_scriptTimer.Elapsed += RunAutoTimerScript; } - - // Hook up to the watchdog timer - Watchdog.OnWatchdogTimeout += WatchdogTimeoutHandler; - - PrintFileToConsole("startuplogo.txt"); - - // For now, start at the 'root' level by default - if (m_sceneManager.Scenes.Count == 1) // If there is only one region, select it - ChangeSelectedRegion("region", - new string[] {"change", "region", m_sceneManager.Scenes[0].RegionInfo.RegionName}); - else - ChangeSelectedRegion("region", new string[] {"change", "region", "root"}); } /// From 9b56cc69c1ca1dcb61245a49f8ce3b1461f81ed5 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 17 Dec 2011 00:29:42 +0000 Subject: [PATCH 08/17] Add Garmin Kawaguichi to CONTRIBUTORS.txt --- CONTRIBUTORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 961ab9fb04..e0a96e76ad 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -80,6 +80,7 @@ what it is today. * dmiles (Daxtron Labs) * dslake (Intel) * FredoChaplin +* Garmin Kawaguichi * Gerhard * Godfrey * Grumly57 From f9137c923bcdc952efe37c7dd328c2d0d8323317 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 17 Dec 2011 02:23:24 +0000 Subject: [PATCH 09/17] Fix bug where objects could not be set to a new group if the group had been created in that client session, or if no other action has been performed on the object. There were two problems here: 1) On object group update, we looked for the group is the IClientAPI group cache rather than in the groups service. This fails to groups created newly in that session 2) On object group update, we weren't setting the HasGroupChanged flag. This meant that the change was not persisted unless some other action set this flag. This commit fixes these issues and hopefully addresses http://opensimulator.org/mantis/view.php?id=5588 This commit also moves HandleObjectGroupUpdate() to the GroupsModule from the Scene.PacketHandlers.cs file --- OpenSim/Framework/ISceneEntity.cs | 1 + OpenSim/Framework/ISceneObject.cs | 6 +++++ .../World/Permissions/PermissionsModule.cs | 12 ++++++--- OpenSim/Region/Framework/Scenes/Scene.cs | 4 +-- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 14 ---------- .../Framework/Scenes/SceneObjectGroup.cs | 2 ++ .../Framework/Scenes/SceneObjectPart.cs | 5 ++++ .../Avatar/XmlRpcGroups/GroupsModule.cs | 27 ++++++++++++++++++- 8 files changed, 50 insertions(+), 21 deletions(-) diff --git a/OpenSim/Framework/ISceneEntity.cs b/OpenSim/Framework/ISceneEntity.cs index c0ea302247..a9f21d258c 100644 --- a/OpenSim/Framework/ISceneEntity.cs +++ b/OpenSim/Framework/ISceneEntity.cs @@ -34,6 +34,7 @@ namespace OpenSim.Framework string Name { get; set; } UUID UUID { get; } uint LocalId { get; } + Vector3 AbsolutePosition { get; } } } diff --git a/OpenSim/Framework/ISceneObject.cs b/OpenSim/Framework/ISceneObject.cs index 18631f17b1..afac9b84f2 100644 --- a/OpenSim/Framework/ISceneObject.cs +++ b/OpenSim/Framework/ISceneObject.cs @@ -33,6 +33,12 @@ namespace OpenSim.Framework public interface ISceneObject { UUID UUID { get; } + + /// + /// The owner of this object. + /// + UUID OwnerID { get; set; } + ISceneObject CloneForNewScene(); string ToXml2(); string ExtraToXmlString(); diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 776038290b..cdecd2f471 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -384,9 +384,15 @@ namespace OpenSim.Region.CoreModules.World.Permissions if (m_debugPermissions) m_log.Debug("[PERMISSIONS]: " + permissionCalled + " was called from " + m_scene.RegionInfo.RegionName); } - - // Checks if the given group is active and if the user is a group member - // with the powers requested (powers = 0 for no powers check) + + /// + /// Checks if the given group is active and if the user is a group member + /// with the powers requested (powers = 0 for no powers check) + /// + /// + /// + /// + /// protected bool IsGroupMember(UUID groupID, UUID userID, ulong powers) { if (null == m_groupsModule) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index b43b22736c..4914d65c17 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2776,7 +2776,6 @@ namespace OpenSim.Region.Framework.Scenes public virtual void SubscribeToClientParcelEvents(IClientAPI client) { - client.OnObjectGroupRequest += m_sceneGraph.HandleObjectGroupUpdate; client.OnParcelReturnObjectsRequest += LandChannel.ReturnObjectsInParcel; client.OnParcelSetOtherCleanTime += LandChannel.SetParcelOtherCleanTime; client.OnParcelBuy += ProcessParcelBuy; @@ -2903,7 +2902,6 @@ namespace OpenSim.Region.Framework.Scenes public virtual void UnSubscribeToClientParcelEvents(IClientAPI client) { - client.OnObjectGroupRequest -= m_sceneGraph.HandleObjectGroupUpdate; client.OnParcelReturnObjectsRequest -= LandChannel.ReturnObjectsInParcel; client.OnParcelSetOtherCleanTime -= LandChannel.SetParcelOtherCleanTime; client.OnParcelBuy -= ProcessParcelBuy; @@ -4287,7 +4285,7 @@ namespace OpenSim.Region.Framework.Scenes /// Get a scene object group that contains the prim with the given local id /// /// - /// null if no scene object group containing that prim is found + /// null if no scene object group containing that prim is found public SceneObjectGroup GetGroupByPrim(uint localID) { return m_sceneGraph.GetGroupByPrim(localID); diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index af95c28966..a3e4b4638c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -575,20 +575,6 @@ namespace OpenSim.Region.Framework.Scenes } } - protected internal void HandleObjectGroupUpdate( - IClientAPI remoteClient, UUID GroupID, uint objectLocalID, UUID Garbage) - { - if (!remoteClient.IsGroupMember(GroupID)) - return; - - SceneObjectGroup group = GetGroupByPrim(objectLocalID); - if (group != null) - { - if (group.OwnerID == remoteClient.AgentId) - group.SetGroup(GroupID, remoteClient); - } - } - protected internal ScenePresence CreateAndAddChildScenePresence( IClientAPI client, AvatarAppearance appearance, PresenceType type) { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 7bf8c34281..abea7883da 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3211,6 +3211,8 @@ namespace OpenSim.Region.Framework.Scenes part.Inventory.ChangeInventoryGroup(GroupID); } + HasGroupChanged = true; + // 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(); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 598b310e9b..b29ecc6465 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3344,6 +3344,11 @@ namespace OpenSim.Region.Framework.Scenes public void SetGroup(UUID groupID, IClientAPI client) { + // Scene.AddNewPrims() calls with client == null so can't use this. +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Setting group for {0} to {1} for {2}", +// Name, groupID, OwnerID); + GroupID = groupID; if (client != null) SendPropertiesToClient(client); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 8baeaa4181..9969a15801 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -218,6 +218,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; + client.OnObjectGroupRequest += HandleObjectGroupUpdate; client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; client.OnDirFindQuery += OnDirFindQuery; client.OnRequestAvatarProperties += OnRequestAvatarProperties; @@ -225,7 +226,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Used for Notices and Group Invites/Accept/Reject client.OnInstantMessage += OnInstantMessage; - // Send client thier groups information. + // Send client their groups information. SendAgentGroupDataUpdate(client, client.AgentId); } @@ -328,6 +329,30 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups remoteClient.SendGroupNameReply(GroupID, GroupName); } + private void HandleObjectGroupUpdate( + IClientAPI remoteClient, UUID GroupID, uint objectLocalID, UUID Garbage) + { + GroupMembershipData gmd = GetMembershipData(GroupID, remoteClient.AgentId); + + if (gmd == null) + { +// m_log.WarnFormat( +// "[GROUPS]: User {0} is not a member of group {1} so they can't update {2} to this group", +// remoteClient.Name, GroupID, objectLocalID); + + return; + } + + SceneObjectGroup so = ((Scene)remoteClient.Scene).GetGroupByPrim(objectLocalID); + if (so != null) + { + if (so.OwnerID == remoteClient.AgentId) + { + so.SetGroup(GroupID, remoteClient); + } + } + } + private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); From 684482352c2f580f2868704e2ba2236a751c5bc4 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 17 Dec 2011 02:35:08 +0000 Subject: [PATCH 10/17] Fix bug where objects couldn't be set back to the "none" group. This is handled by treating UUID.Zero as a special case. Currently, asking for the "none" group returns nothing because XMLRPC groups, at least, is not properly handling this case. It may be better in the future to have GroupsModule return an appropriate GroupsData structure instead or require the underlying services to behave appropriately. This is a further component of http://opensimulator.org/mantis/view.php?id=5588 --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 9969a15801..e9598213d7 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -332,15 +332,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void HandleObjectGroupUpdate( IClientAPI remoteClient, UUID GroupID, uint objectLocalID, UUID Garbage) { - GroupMembershipData gmd = GetMembershipData(GroupID, remoteClient.AgentId); - - if (gmd == null) + // XXX: Might be better to get rid of this special casing and have GetMembershipData return something + // reasonable for a UUID.Zero group. + if (GroupID != UUID.Zero) { -// m_log.WarnFormat( -// "[GROUPS]: User {0} is not a member of group {1} so they can't update {2} to this group", -// remoteClient.Name, GroupID, objectLocalID); - - return; + GroupMembershipData gmd = GetMembershipData(GroupID, remoteClient.AgentId); + + if (gmd == null) + { +// m_log.WarnFormat( +// "[GROUPS]: User {0} is not a member of group {1} so they can't update {2} to this group", +// remoteClient.Name, GroupID, objectLocalID); + + return; + } } SceneObjectGroup so = ((Scene)remoteClient.Scene).GetGroupByPrim(objectLocalID); From 4d065f04534e4b5f1be451796386808347d6e72e Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 17 Dec 2011 02:42:43 +0000 Subject: [PATCH 11/17] Provide user feedback on execution of "backup" region console command --- OpenSim/Region/Application/OpenSim.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index ea098936b2..3a1a8c7c53 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -796,6 +796,7 @@ namespace OpenSim break; case "backup": + MainConsole.Instance.Output("Triggering save of pending object updates to persistent store"); m_sceneManager.BackupCurrentScene(); break; @@ -806,7 +807,7 @@ namespace OpenSim if (m_sceneManager.TryGetScene(regRemoveName, out removeScene)) RemoveRegion(removeScene, false); else - MainConsole.Instance.Output("no region with that name"); + MainConsole.Instance.Output("No region with that name"); break; case "delete-region": From 6baee2e10baedd72efc714d74b64e26f70d57132 Mon Sep 17 00:00:00 2001 From: nebadon Date: Mon, 19 Dec 2011 11:51:03 -0700 Subject: [PATCH 12/17] addresses mantis #5827 RAdmin - admin_save_oar fails if noassets parameter missing thanks Michelle Argus --- .../ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 0a262fbddb..7106e6aded 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -1463,7 +1463,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController options["profile"] = (string)requestData["profile"]; } - if (requestData["noassets"].ToString() == "true") + if ((string)requestData["noassets"] == "true") { options["noassets"] = (string)requestData["noassets"] ; } From 0b91ec8dd2b78461cb0fcdec567a83e88a76ac87 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 19 Dec 2011 18:58:05 +0000 Subject: [PATCH 13/17] Migrate detailed "appearance show" report generation up to AvatarFactoryModule from AppearanceInfoModule so that it can be used in debug (inactive). Further filters "debug packet " to exclused [Request]ObjectPropertiesFamily if level is below 25. Adjust some method doc Minor changes to some logging messages. --- .../UploadBakedTextureHandler.cs | 4 +- OpenSim/Framework/AvatarAppearance.cs | 21 ++++--- .../ClientStack/Linden/UDP/LLClientView.cs | 17 ++++-- .../AvatarFactory/AvatarFactoryModule.cs | 57 ++++++++++++++++--- .../Interfaces/IAvatarFactoryModule.cs | 11 +++- .../Region/Framework/Scenes/ScenePresence.cs | 2 +- .../Avatar/Appearance/AppearanceInfoModule.cs | 34 +---------- 7 files changed, 90 insertions(+), 56 deletions(-) diff --git a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs index c637ccf180..594ce9dad9 100644 --- a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs @@ -104,7 +104,7 @@ namespace OpenSim.Capabilities.Handlers } catch (Exception e) { - m_log.Error("[UPLOAD BAKED TEXTURE HANDLER]: " + e.ToString()); + m_log.ErrorFormat("[UPLOAD BAKED TEXTURE HANDLER]: {0}{1}", e.Message, e.StackTrace); } return null; @@ -117,7 +117,7 @@ namespace OpenSim.Capabilities.Handlers /// private void BakedTextureUploaded(UUID assetID, byte[] data) { - // m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString()); +// m_log.DebugFormat("[UPLOAD BAKED TEXTURE HANDLER]: Received baked texture {0}", assetID.ToString()); AssetBase asset; asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString()); diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index 6c2a954f07..4f598b04ae 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs @@ -249,10 +249,12 @@ namespace OpenSim.Framework } /// - /// Set up appearance textures. - /// Returns boolean that indicates whether the new entries actually change the - /// existing values. + /// Set up appearance texture ids. /// + /// + /// True if any existing texture id was changed by the new data. + /// False if there were no changes or no existing texture ids. + /// public virtual bool SetTextureEntries(Primitive.TextureEntry textureEntry) { if (textureEntry == null) @@ -269,25 +271,30 @@ namespace OpenSim.Framework if (newface == null) { - if (oldface == null) continue; + if (oldface == null) + continue; } else { - if (oldface != null && oldface.TextureID == newface.TextureID) continue; + if (oldface != null && oldface.TextureID == newface.TextureID) + continue; } changed = true; } m_texture = textureEntry; + return changed; } /// /// Set up visual parameters for the avatar and refresh the avatar height - /// Returns boolean that indicates whether the new entries actually change the - /// existing values. /// + /// + /// True if any existing visual parameter was changed by the new data. + /// False if there were no changes or no existing visual parameters. + /// public virtual bool SetVisualParams(byte[] visualParams) { if (visualParams == null) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 8b41c493da..f9a6643063 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -441,6 +441,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP public LLClientView(EndPoint remoteEP, Scene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo, UUID agentId, UUID sessionId, uint circuitCode) { +// DebugPacketLevel = 1; + RegisterInterface(this); RegisterInterface(this); RegisterInterface(this); @@ -6001,7 +6003,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP // for the client session anyway, in order to protect ourselves against bad code in plugins try { - byte[] visualparams = new byte[appear.VisualParam.Length]; for (int i = 0; i < appear.VisualParam.Length; i++) visualparams[i] = appear.VisualParam[i].ParamValue; @@ -11219,9 +11220,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// /// Send a response back to a client when it asks the asset server (via the region server) if it has /// its appearance texture cached. - /// - /// At the moment, we always reply that there is no cached texture. /// + /// + /// At the moment, we always reply that there is no cached texture. + /// /// /// /// @@ -11231,7 +11233,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet; AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse); - if (cachedtex.AgentData.SessionID != SessionId) return false; + if (cachedtex.AgentData.SessionID != SessionId) + return false; // TODO: don't create new blocks if recycling an old packet cachedresp.AgentData.AgentID = AgentId; @@ -11629,6 +11632,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (DebugPacketLevel <= 50 && packet.Type == PacketType.ImprovedTerseObjectUpdate) logPacket = false; + if (DebugPacketLevel <= 25 && packet.Type == PacketType.ObjectPropertiesFamily) + logPacket = false; + if (logPacket) m_log.DebugFormat( "[CLIENT]: PACKET OUT to {0} ({1}) in {2} - {3}", @@ -11686,6 +11692,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (DebugPacketLevel <= 100 && (packet.Type == PacketType.ViewerEffect || packet.Type == PacketType.AgentAnimation)) logPacket = false; + if (DebugPacketLevel <= 25 && packet.Type == PacketType.RequestObjectPropertiesFamily) + logPacket = false; + if (logPacket) m_log.DebugFormat( "[CLIENT]: PACKET IN from {0} ({1}) in {2} - {3}", diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 29e35800a0..f1a81aecd3 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -26,16 +26,15 @@ */ using System; +using System.Collections.Generic; using System.Reflection; +using System.Threading; +using System.Text; +using System.Timers; using log4net; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; - -using System.Threading; -using System.Timers; -using System.Collections.Generic; - using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; @@ -45,6 +44,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory public class AvatarFactoryModule : IAvatarFactoryModule, IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public const string BAKED_TEXTURES_REPORT_FORMAT = "{0,-9} {1}"; + private Scene m_scene = null; private int m_savetime = 5; // seconds to wait before saving changed appearance @@ -147,9 +149,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // Process the baked texture array if (textureEntry != null) { + m_log.InfoFormat("[AVFACTORY]: received texture update for {0}", sp.UUID); + +// WriteBakedTexturesReport(sp, m_log.DebugFormat); + changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; - m_log.InfoFormat("[AVFACTORY]: received texture update for {0}", sp.UUID); +// WriteBakedTexturesReport(sp, m_log.DebugFormat); ValidateBakedTextureCache(sp, false); // This appears to be set only in the final stage of the appearance @@ -254,9 +260,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory } /// - /// Queue up a request to send appearance, makes it possible to - /// accumulate changes without sending out each one separately. + /// Queue up a request to send appearance. /// + /// + /// Makes it possible to accumulate changes without sending out each one separately. + /// + /// public void QueueAppearanceSend(UUID agentid) { // m_log.DebugFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); @@ -557,5 +566,37 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory } } #endregion + + public void WriteBakedTexturesReport(IScenePresence sp, ReportOutputAction outputAction) + { + outputAction("For {0} in {1}", sp.Name, m_scene.RegionInfo.RegionName); + outputAction(BAKED_TEXTURES_REPORT_FORMAT, "Bake Type", "UUID"); + + Dictionary bakedTextures = GetBakedTextureFaces(sp.UUID); + + foreach (BakeType bt in bakedTextures.Keys) + { + string rawTextureID; + + if (bakedTextures[bt] == null) + { + rawTextureID = "not set"; + } + else + { + rawTextureID = bakedTextures[bt].TextureID.ToString(); + + if (m_scene.AssetService.Get(rawTextureID) == null) + rawTextureID += " (not found)"; + else + rawTextureID += " (uploaded)"; + } + + outputAction(BAKED_TEXTURES_REPORT_FORMAT, bt, rawTextureID); + } + + bool bakedTextureValid = m_scene.AvatarFactory.ValidateBakedTextureCache(sp); + outputAction("{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); + } } } diff --git a/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs index 26bc922748..8670229e8b 100644 --- a/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs @@ -31,9 +31,10 @@ using OpenSim.Framework; namespace OpenSim.Region.Framework.Interfaces { + public delegate void ReportOutputAction(string format, params object[] args); + public interface IAvatarFactoryModule { - void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams); /// @@ -63,5 +64,13 @@ namespace OpenSim.Region.Framework.Interfaces bool ValidateBakedTextureCache(IScenePresence sp); void QueueAppearanceSend(UUID agentid); void QueueAppearanceSave(UUID agentid); + + /// + /// Get a report about the current state of a scene presence's baked appearance textures. + /// + /// + /// + /// + void WriteBakedTexturesReport(IScenePresence sp, ReportOutputAction reportOutputAction); } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 7be95cd9d1..f2e2ce719a 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2667,7 +2667,7 @@ namespace OpenSim.Region.Framework.Scenes public void SendAppearanceToAgent(ScenePresence avatar) { // m_log.DebugFormat( -// "[SCENE PRESENCE] Send appearance from {0} {1} to {2} {3}", Name, m_uuid, avatar.Name, avatar.UUID); +// "[SCENE PRESENCE]: Sending appearance data from {0} {1} to {2} {3}", Name, m_uuid, avatar.Name, avatar.UUID); avatar.ControllingClient.SendAppearance( UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 40cbc606a1..1ce24f1745 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -50,8 +50,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - public const string SHOW_APPEARANCE_FORMAT = "{0,-9} {1}"; - private Dictionary m_scenes = new Dictionary(); // private IAvatarFactoryModule m_avatarFactory; @@ -197,37 +195,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance { ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName); if (sp != null && !sp.IsChildAgent) - { - MainConsole.Instance.OutputFormat("For {0} in {1}", sp.Name, scene.RegionInfo.RegionName); - MainConsole.Instance.OutputFormat(SHOW_APPEARANCE_FORMAT, "Bake Type", "UUID"); - - Dictionary bakedTextures - = scene.AvatarFactory.GetBakedTextureFaces(sp.UUID); - foreach (BakeType bt in bakedTextures.Keys) - { - string rawTextureID; - - if (bakedTextures[bt] == null) - { - rawTextureID = "not set"; - } - else - { - rawTextureID = bakedTextures[bt].TextureID.ToString(); - - if (scene.AssetService.Get(rawTextureID) == null) - rawTextureID += " (not found)"; - else - rawTextureID += " (uploaded)"; - } - - MainConsole.Instance.OutputFormat(SHOW_APPEARANCE_FORMAT, bt, rawTextureID); - } - - bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(sp); - MainConsole.Instance.OutputFormat( - "{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); - } + scene.AvatarFactory.WriteBakedTexturesReport(sp, MainConsole.Instance.OutputFormat); } else { From e8fbeeba5f2c02bf89ade1d8c0fa135d065096e7 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 19 Dec 2011 19:08:24 +0000 Subject: [PATCH 14/17] Fix race condition where the appearance update timer could be stopped just after another thread had started it on QueueAppearanceSave() or *Send() However, the window for this race is very small, and the next queued appearance save or send would restart the timer anyway. --- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index f1a81aecd3..e8aee3eafe 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -417,10 +417,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory m_savequeue.Remove(avatarID); } } - } - if (m_savequeue.Count == 0 && m_sendqueue.Count == 0) - m_updateTimer.Stop(); + // We must lock both queues here so that QueueAppearanceSave() or *Send() don't m_updateTimer.Start() on + // another thread inbetween the first count calls and m_updateTimer.Stop() on this thread. + lock (m_sendqueue) + if (m_savequeue.Count == 0 && m_sendqueue.Count == 0) + m_updateTimer.Stop(); + } } private void SaveAppearance(UUID agentid) From 2899de1a5c8060397e813ee853c525572a81db03 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 19 Dec 2011 19:19:05 +0000 Subject: [PATCH 15/17] Stop unnecessarily sending the TextureEntry in client avatar updates. As far as I know, viewers don't use this mechanism to recieve new TextureEntry data for avatars. This is done via the AvatarAppearance packet instead. Tested this back to viewer 1.23. Replacing with Utils.EmptyBytes since converting the texture entry to bytes on each AvatarUpdate (or which there are many) is not cost-free. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index f9a6643063..b37fd54b9e 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -4895,8 +4895,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP update.Scale = new Vector3(0.45f, 0.6f, 1.9f); update.Text = Utils.EmptyBytes; update.TextColor = new byte[4]; + + // Don't send texture anim for avatars - this has no meaning for them. update.TextureAnim = Utils.EmptyBytes; - update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; + + // Don't send texture entry for avatars here - this is accomplished via the AvatarAppearance packet + update.TextureEntry = Utils.EmptyBytes; +// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; + update.UpdateFlags = (uint)( PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | From 92039f295d7fe66bf1a09b29483f9057e395839e Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 19 Dec 2011 20:13:48 +0000 Subject: [PATCH 16/17] Stop sending the viewer its own AvatarAppearance packet. The viewer warns in the log if it receives this. Stopping this doesn't appear to have adverse effects on viewer 1 or viewer 3 - the viewer gets its own appearance from body parts/clothes and self-baked textures. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f2e2ce719a..9cad3fe612 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2532,7 +2532,10 @@ namespace OpenSim.Region.Framework.Scenes // again here... this comes after the cached appearance check because the avatars // appearance goes into the avatar update packet SendAvatarDataToAllAgents(); - SendAppearanceToAgent(this); + + // Sending us our own appearance does not seem to be necessary, and the viewer warns in the log if you do + // this. +// SendAppearanceToAgent(this); // If we are using the the cached appearance then send it out to everyone if (cachedappearance) From 87a2d8d51b66db12a487014deb8447fb2432e2a3 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 19 Dec 2011 23:03:45 +0000 Subject: [PATCH 17/17] Move HandleObjectGroupUpdate() from GroupsModule to Scene.PacketHandlers.cs as this is updating SOG/SOP.GroupID, which is arguably generic. --- .../Framework/Scenes/Scene.PacketHandlers.cs | 39 +++++++++++++++++++ OpenSim/Region/Framework/Scenes/Scene.cs | 11 +++--- .../Avatar/XmlRpcGroups/GroupsModule.cs | 30 -------------- 3 files changed, 44 insertions(+), 36 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index f9d0e0aab5..3355ebe380 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -153,6 +153,45 @@ namespace OpenSim.Region.Framework.Scenes } } + /// + /// Handle the update of an object's user group. + /// + /// + /// + /// + /// + private void HandleObjectGroupUpdate( + IClientAPI remoteClient, UUID groupID, uint objectLocalID, UUID Garbage) + { + if (m_groupsModule == null) + return; + + // XXX: Might be better to get rid of this special casing and have GetMembershipData return something + // reasonable for a UUID.Zero group. + if (groupID != UUID.Zero) + { + GroupMembershipData gmd = m_groupsModule.GetMembershipData(groupID, remoteClient.AgentId); + + if (gmd == null) + { +// m_log.WarnFormat( +// "[GROUPS]: User {0} is not a member of group {1} so they can't update {2} to this group", +// remoteClient.Name, GroupID, objectLocalID); + + return; + } + } + + SceneObjectGroup so = ((Scene)remoteClient.Scene).GetGroupByPrim(objectLocalID); + if (so != null) + { + if (so.OwnerID == remoteClient.AgentId) + { + so.SetGroup(groupID, remoteClient); + } + } + } + /// /// Handle the deselection of a prim from the client. /// diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 4914d65c17..6666328271 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -139,6 +139,7 @@ namespace OpenSim.Region.Framework.Scenes protected IDialogModule m_dialogModule; protected IEntityTransferModule m_teleportModule; protected ICapabilitiesModule m_capsModule; + protected IGroupsModule m_groupsModule; /// /// Current scene frame number @@ -1164,6 +1165,7 @@ namespace OpenSim.Region.Framework.Scenes m_dialogModule = RequestModuleInterface(); m_capsModule = RequestModuleInterface(); m_teleportModule = RequestModuleInterface(); + m_groupsModule = RequestModuleInterface(); } #endregion @@ -2733,6 +2735,7 @@ namespace OpenSim.Region.Framework.Scenes client.OnObjectDescription += m_sceneGraph.PrimDescription; client.OnObjectIncludeInSearch += m_sceneGraph.MakeObjectSearchable; client.OnObjectOwner += ObjectOwner; + client.OnObjectGroupRequest += HandleObjectGroupUpdate; } public virtual void SubscribeToClientPrimRezEvents(IClientAPI client) @@ -3520,15 +3523,11 @@ namespace OpenSim.Region.Framework.Scenes m_log.ErrorFormat("[CONNECTION BEGIN]: Estate Settings is null!"); } - IGroupsModule groupsModule = - RequestModuleInterface(); - List agentGroups = new List(); - if (groupsModule != null) + if (m_groupsModule != null) { - GroupMembershipData[] GroupMembership = - groupsModule.GetMembershipData(agent.AgentID); + GroupMembershipData[] GroupMembership = m_groupsModule.GetMembershipData(agent.AgentID); if (GroupMembership != null) { diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index e9598213d7..740dbdda39 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -218,7 +218,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; - client.OnObjectGroupRequest += HandleObjectGroupUpdate; client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; client.OnDirFindQuery += OnDirFindQuery; client.OnRequestAvatarProperties += OnRequestAvatarProperties; @@ -329,35 +328,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups remoteClient.SendGroupNameReply(GroupID, GroupName); } - private void HandleObjectGroupUpdate( - IClientAPI remoteClient, UUID GroupID, uint objectLocalID, UUID Garbage) - { - // XXX: Might be better to get rid of this special casing and have GetMembershipData return something - // reasonable for a UUID.Zero group. - if (GroupID != UUID.Zero) - { - GroupMembershipData gmd = GetMembershipData(GroupID, remoteClient.AgentId); - - if (gmd == null) - { -// m_log.WarnFormat( -// "[GROUPS]: User {0} is not a member of group {1} so they can't update {2} to this group", -// remoteClient.Name, GroupID, objectLocalID); - - return; - } - } - - SceneObjectGroup so = ((Scene)remoteClient.Scene).GetGroupByPrim(objectLocalID); - if (so != null) - { - if (so.OwnerID == remoteClient.AgentId) - { - so.SetGroup(GroupID, remoteClient); - } - } - } - private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);