diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 3bf2ffd373..f6ce29142f 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -1049,24 +1049,6 @@ namespace OpenSim MainConsole.Instance.Output(handlers.ToString()); break; - case "pending-objects": - System.Text.StringBuilder pending = new System.Text.StringBuilder("Pending objects:\n"); - m_sceneManager.ForEachScene( - delegate(Scene scene) - { - scene.ForEachScenePresence( - delegate(ScenePresence sp) - { - pending.AppendFormat("{0}: {1} {2} pending\n", - scene.RegionInfo.RegionName, sp.Name, sp.SceneViewer.GetPendingObjectsCount()); - } - ); - } - ); - - MainConsole.Instance.Output(pending.ToString()); - break; - case "modules": MainConsole.Instance.Output("The currently loaded shared modules are:"); foreach (IRegionModule module in m_moduleLoader.GetLoadedSharedModules) diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 8e5de7dbdd..0c81bb2882 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -572,10 +572,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends { m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", client.AgentId, friendID); - AddFriend(client, friendID); + AddFriendship(client, friendID); } - public void AddFriend(IClientAPI client, UUID friendID) + public void AddFriendship(IClientAPI client, UUID friendID) { StoreFriendships(client.AgentId, friendID); diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs index 942091c4c1..c945dcf12c 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs @@ -87,8 +87,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId); SceneHelpers.AddScenePresence(m_scene, user2Id); - // This friendship is currently only one-way, which might be pathalogical in Second Life. - m_fm.AddFriend(sp.ControllingClient, user2Id); + // This fiendship is two-way but without a connector, only the first user will receive the online + // notification. + m_fm.AddFriendship(sp.ControllingClient, user2Id); Assert.That(((TestClient)sp.ControllingClient).OfflineNotificationsReceived.Count, Is.EqualTo(0)); Assert.That(((TestClient)sp.ControllingClient).OnlineNotificationsReceived.Count, Is.EqualTo(1)); diff --git a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs index 8143164283..fdede340fc 100644 --- a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs @@ -34,18 +34,15 @@ namespace OpenSim.Region.Framework.Interfaces public interface IFriendsModule { /// - /// Add a friend for the given user. + /// Add a friendship between two users. /// /// - /// This is a one-way friendship. To make a two way friendship you will need to call this again with the - /// client and friend reversed. - /// /// Ultimately, it would be more useful to take in a user account here rather than having to have a user /// present in the scene. /// /// /// - void AddFriend(IClientAPI client, UUID friendID); + void AddFriendship(IClientAPI client, UUID friendID); uint GetFriendPerms(UUID PrincipalID, UUID FriendID); bool SendFriendsOnlineIfNeeded(IClientAPI client); diff --git a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs b/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs deleted file mode 100644 index e715e706f2..0000000000 --- a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs +++ /dev/null @@ -1,50 +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 OpenSim.Region.Framework.Scenes; - -namespace OpenSim.Region.Framework.Interfaces -{ - /// - /// Sends scheduled updates to it's associated ScenePresence. - /// - public interface ISceneViewer - { -// void Reset(); - void Close(); - - /// - /// Add the part to the queue of parts for which we need to send an update to the client - /// - /// - void QueuePartForUpdate(SceneObjectPart part); - - void SendPrimUpdates(); - int GetPendingObjectsCount(); - } -} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index e668790154..149d2d37d5 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2657,6 +2657,16 @@ namespace OpenSim.Region.Framework.Scenes land.SendLandUpdateToClient(client); } } + + // Send all scene object to the new client + Util.FireAndForget(delegate + { + Entities.ForEach(delegate(EntityBase e) + { + if (e != null && e is SceneObjectGroup) + ((SceneObjectGroup)e).SendFullUpdateToClient(client); + }); + }); } /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index da105050aa..dd5e986b19 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2148,30 +2148,6 @@ 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); - - SceneObjectPart[] parts = m_parts.GetArray(); - for (int i = 0; i < parts.Length; i++) - { - SceneObjectPart part = parts[i]; - if (part != RootPart) - part.AddFullUpdateToAvatar(presence); - } - } - - public void ScheduleTerseUpdateToAvatar(ScenePresence presence) - { -// m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1} just to avatar {2}", Name, UUID, presence.Name); - - SceneObjectPart[] parts = m_parts.GetArray(); - for (int i = 0; i < parts.Length; i++) - parts[i].AddTerseUpdateToAvatar(presence); - } - /// /// Schedule a full update for this scene object /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 7025551cb5..45ca0b75ac 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1425,25 +1425,6 @@ namespace OpenSim.Region.Framework.Scenes // m_log.Debug("Aprev: " + prevflag.ToString() + " curr: " + Flags.ToString()); } - /// - /// Tell all scene presences that they should send updates for this part to their clients - /// - public void AddFullUpdateToAllAvatars() - { - ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) - { - AddFullUpdateToAvatar(avatar); - }); - } - - /// - /// Tell the scene presence that it should send updates for this part to its client - /// - public void AddFullUpdateToAvatar(ScenePresence presence) - { - presence.SceneViewer.QueuePartForUpdate(this); - } - public void AddNewParticleSystem(Primitive.ParticleSystem pSystem) { m_particleSystem = pSystem.GetBytes(); @@ -1454,20 +1435,6 @@ namespace OpenSim.Region.Framework.Scenes m_particleSystem = new byte[0]; } - /// Terse updates - public void AddTerseUpdateToAllAvatars() - { - ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) - { - AddTerseUpdateToAvatar(avatar); - }); - } - - public void AddTerseUpdateToAvatar(ScenePresence presence) - { - presence.SceneViewer.QueuePartForUpdate(this); - } - public void AddTextureAnimation(Primitive.TextureAnimation pTexAnim) { byte[] data = new byte[16]; @@ -2703,8 +2670,6 @@ namespace OpenSim.Region.Framework.Scenes //ParentGroup.RootPart.m_groupPosition = newpos; } ScheduleTerseUpdate(); - - //SendTerseUpdateToAllClients(); } public void PreloadSound(string sound) @@ -2888,6 +2853,13 @@ namespace OpenSim.Region.Framework.Scenes if (ParentGroup == null) return; + // This was pulled from SceneViewer. Attachments always receive full updates. + // I could not verify if this is a requirement but this maintains existing behavior + if (ParentGroup.IsAttachment) + { + ScheduleFullUpdate(); + } + if (UpdateFlag == UpdateRequired.NONE) { ParentGroup.HasGroupChanged = true; @@ -2981,23 +2953,6 @@ namespace OpenSim.Region.Framework.Scenes }); } - /// - /// Send a full update to all clients except the one nominated. - /// - /// - public void SendFullUpdateToAllClientsExcept(UUID agentID) - { - if (ParentGroup == null) - return; - - ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) - { - // Ugly reference :( - if (avatar.UUID != agentID) - SendFullUpdate(avatar.ControllingClient, avatar.GenerateClientFlags(UUID)); - }); - } - /// /// Sends a full update to the client /// @@ -3074,7 +3029,8 @@ namespace OpenSim.Region.Framework.Scenes !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) { - AddTerseUpdateToAllAvatars(); + + SendTerseUpdateToAllClients(); ClearUpdateSchedule(); // Update the "last" values @@ -3089,7 +3045,7 @@ namespace OpenSim.Region.Framework.Scenes } case UpdateRequired.FULL: { - AddFullUpdateToAllAvatars(); + SendFullUpdateToAllClients(); break; } } @@ -3193,9 +3149,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendTerseUpdateToAllClients() { - ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) + ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) { - SendTerseUpdateToClient(avatar.ControllingClient); + SendTerseUpdateToClient(client); }); } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 8906c6ff74..839259ffaf 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -135,7 +135,6 @@ namespace OpenSim.Region.Framework.Scenes private Vector3 m_lastPosition; private Quaternion m_lastRotation; private Vector3 m_lastVelocity; - //private int m_lastTerseSent; private Vector3? m_forceToApply; private int m_userFlags; @@ -645,14 +644,6 @@ namespace OpenSim.Region.Framework.Scenes set { m_health = value; } } - private ISceneViewer m_sceneViewer; - - public ISceneViewer SceneViewer - { - get { return m_sceneViewer; } - private set { m_sceneViewer = value; } - } - public void AdjustKnownSeeds() { Dictionary seeds; @@ -756,7 +747,6 @@ namespace OpenSim.Region.Framework.Scenes AttachmentsSyncLock = new Object(); m_sendCourseLocationsMethod = SendCoarseLocationsDefault; - SceneViewer = new SceneViewer(this); Animator = new ScenePresenceAnimator(this); PresenceType = type; DrawDistance = world.DefaultDrawDistance; @@ -867,16 +857,6 @@ namespace OpenSim.Region.Framework.Scenes return m_scene.Permissions.GenerateClientFlags(m_uuid, ObjectID); } - /// - /// Send updates to the client about prims which have been placed on the update queue. We don't - /// necessarily send updates for all the parts on the queue, e.g. if an updates with a more recent - /// timestamp has already been sent. - /// - public void SendPrimUpdates() - { - SceneViewer.SendPrimUpdates(); - } - #region Status Methods /// @@ -2420,10 +2400,6 @@ namespace OpenSim.Region.Framework.Scenes const float ROTATION_TOLERANCE = 0.01f; const float VELOCITY_TOLERANCE = 0.001f; const float POSITION_TOLERANCE = 0.05f; - //const int TIME_MS_TOLERANCE = 3000; - - if (!sendingPrims) - Util.FireAndForget(delegate { sendingPrims = true; SendPrimUpdates(); sendingPrims = false; }); if (IsChildAgent == false) { @@ -2435,7 +2411,6 @@ namespace OpenSim.Region.Framework.Scenes if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)) - //Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) { SendTerseUpdateToAllClients(); @@ -2443,7 +2418,6 @@ namespace OpenSim.Region.Framework.Scenes m_lastPosition = m_pos; m_lastRotation = Rotation; m_lastVelocity = Velocity; - //m_lastTerseSent = Environment.TickCount; } // followed suggestion from mic bowman. reversed the two lines below. @@ -3430,8 +3404,6 @@ namespace OpenSim.Region.Framework.Scenes // unsetting the elapsed callback should be enough to allow for cleanup however. // m_reprioritizationTimer.Dispose(); - SceneViewer.Close(); - RemoveFromPhysicalScene(); Animator.Close(); Animator = null; diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs deleted file mode 100644 index 2c3084ca08..0000000000 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ /dev/null @@ -1,251 +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 System.Collections.Generic; -using OpenMetaverse; -using log4net; -using OpenSim.Framework; -using OpenSim.Framework.Client; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes.Types; - -namespace OpenSim.Region.Framework.Scenes -{ - public class SceneViewer : ISceneViewer - { - /// - /// Is this scene viewer enabled? - /// - private bool IsEnabled { get; set; } - - /// - /// The scene presence serviced by this viewer. - /// - protected ScenePresence m_presence; - - /// - /// The queue of parts for which we need to send out updates. - /// - protected UpdateQueue m_partsUpdateQueue = new UpdateQueue(); - - /// - /// The queue of objects for which we need to send out updates. - /// - protected Queue m_pendingObjects; - - /// - /// The last update assocated with a given part update. - /// - protected Dictionary m_updateTimes = new Dictionary(); - - public SceneViewer(ScenePresence presence) - { - m_presence = presence; - IsEnabled = true; - } - - public void QueuePartForUpdate(SceneObjectPart part) - { - if (!IsEnabled) - return; - - lock (m_partsUpdateQueue) - { - m_partsUpdateQueue.Enqueue(part); - } - } - - public void SendPrimUpdates() - { - if (m_pendingObjects == null) - { - m_pendingObjects = new Queue(); - - lock (m_pendingObjects) - { - EntityBase[] entities = m_presence.Scene.Entities.GetEntities(); - foreach (EntityBase e in entities) - { - if (e != null && e is SceneObjectGroup) - m_pendingObjects.Enqueue((SceneObjectGroup)e); - } - } - } - - lock (m_pendingObjects) - { - // We must do this under lock so that we don't suffer a race condition if another thread closes the - // viewer - if (!IsEnabled) - return; - - while (m_pendingObjects != null && m_pendingObjects.Count > 0) - { - SceneObjectGroup g = m_pendingObjects.Dequeue(); - // Yes, this can really happen - if (g == null) - continue; - - // This is where we should check for draw distance - // do culling and stuff. Problem with that is that until - // we recheck in movement, that won't work right. - // So it's not implemented now. - // - - // Don't even queue if we have sent this one - // - if (!m_updateTimes.ContainsKey(g.UUID)) - g.ScheduleFullUpdateToAvatar(m_presence); - } - - while (m_partsUpdateQueue != null && m_partsUpdateQueue.Count != null && m_partsUpdateQueue.Count > 0) - { - SceneObjectPart part = m_partsUpdateQueue.Dequeue(); - - if (part.ParentGroup.IsDeleted) - continue; - - if (m_updateTimes.ContainsKey(part.UUID)) - { - ScenePartUpdate update = m_updateTimes[part.UUID]; - - // We deal with the possibility that two updates occur at - // the same unix time at the update point itself. - if ((update.LastFullUpdateTime < part.TimeStampFull) || part.ParentGroup.IsAttachment) - { - // m_log.DebugFormat( - // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", - // part.Name, part.UUID, part.TimeStampFull); - - part.SendFullUpdate(m_presence.ControllingClient, - m_presence.GenerateClientFlags(part.UUID)); - - // We'll update to the part's timestamp rather than - // the current time to avoid the race condition - // whereby the next tick occurs while we are doing - // this update. If this happened, then subsequent - // updates which occurred on the same tick or the - // next tick of the last update would be ignored. - update.LastFullUpdateTime = part.TimeStampFull; - } - else if (update.LastTerseUpdateTime <= part.TimeStampTerse) - { - // m_log.DebugFormat( - // "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", - // part.Name, part.UUID, part.TimeStampTerse); - - part.SendTerseUpdateToClient(m_presence.ControllingClient); - - update.LastTerseUpdateTime = part.TimeStampTerse; - } - } - else - { - //never been sent to client before so do full update - ScenePartUpdate update = new ScenePartUpdate(); - update.FullID = part.UUID; - update.LastFullUpdateTime = part.TimeStampFull; - m_updateTimes.Add(part.UUID, update); - - // Attachment handling - // - if (part.ParentGroup.RootPart.Shape.PCode == 9 && part.ParentGroup.RootPart.Shape.State != 0) - { - if (part != part.ParentGroup.RootPart) - continue; - - part.ParentGroup.SendFullUpdateToClient(m_presence.ControllingClient); - continue; - } - - part.SendFullUpdate(m_presence.ControllingClient, - m_presence.GenerateClientFlags(part.UUID)); - } - } - } - } - -// public void Reset() -// { -// if (m_pendingObjects == null) -// return; -// -// lock (m_pendingObjects) -// { -// if (m_pendingObjects != null) -// { -// m_pendingObjects.Clear(); -// m_pendingObjects = null; -// } -// } -// } - - public void Close() - { - lock (m_pendingObjects) - { - // We perform this under the m_pendingObjects lock in order to avoid a race condition with another - // thread on SendPrimUpdates() - IsEnabled = false; - - lock (m_updateTimes) - { - m_updateTimes.Clear(); - } - - lock (m_partsUpdateQueue) - { - m_partsUpdateQueue.Clear(); - } - } - } - - public int GetPendingObjectsCount() - { - if (m_pendingObjects != null) - lock (m_pendingObjects) - return m_pendingObjects.Count; - - return 0; - } - - public class ScenePartUpdate - { - public UUID FullID; - public uint LastFullUpdateTime; - public uint LastTerseUpdateTime; - - public ScenePartUpdate() - { - FullID = UUID.Zero; - LastFullUpdateTime = 0; - LastTerseUpdateTime = 0; - } - } - } -}