From 46db73b62baec7baf0e33d83efbaafaadcd4db0d Mon Sep 17 00:00:00 2001 From: Teravus Ovares (Dan Olivares) Date: Thu, 23 Dec 2010 03:30:09 -0500 Subject: * Re-Adding Scene TimeDilation to Object Update Packets. * Added Calculating Time Dilation in the OdePlubin * When multiple object updates are stuffed into one packet, average the time dilation between them as a compromise. * Time Dilation on the update is calculated when the EntityUpdate object is created. The pre-calc-ed TD is stored in the Entity update and used when it goes out on the wire. Previously, it was 1.0 all the time. The time dilation is tied to when the update is created, not when the update is sent. --- OpenSim/Framework/IClientAPI.cs | 4 +++- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 18 ++++++++++++------ OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | 19 +++++++++++++++++++ 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 6bca6eb..21ffa9a 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -574,11 +574,13 @@ namespace OpenSim.Framework { public ISceneEntity Entity; public PrimUpdateFlags Flags; + public float TimeDilation; - public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags) + public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, float timedilation) { Entity = entity; Flags = flags; + TimeDilation = timedilation; } } diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 929f282..f27a6eb 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -3554,7 +3554,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP double priority = m_prioritizer.GetUpdatePriority(this, entity); lock (m_entityUpdates.SyncRoot) - m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags), entity.LocalId); + m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation), entity.LocalId); } private void ProcessEntityUpdates(int maxUpdates) @@ -3570,14 +3570,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race // condition where a kill can be processed before an out-of-date update for the same object. lock (m_killRecord) - { + { + float avgTimeDilation = 1.0f; EntityUpdate update; while (updatesThisCall < maxUpdates) { lock (m_entityUpdates.SyncRoot) if (!m_entityUpdates.TryDequeue(out update)) break; - + avgTimeDilation += update.TimeDilation; + avgTimeDilation *= 0.5f; + if (update.Entity is SceneObjectPart) { SceneObjectPart part = (SceneObjectPart)update.Entity; @@ -3725,8 +3728,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region Packet Sending - const float TIME_DILATION = 1.0f; - ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f); + //const float TIME_DILATION = 1.0f; + + + ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); if (terseAgentUpdateBlocks.IsValueCreated) { @@ -3739,7 +3744,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int i = 0; i < blocks.Count; i++) packet.ObjectData[i] = blocks[i]; - + + OutPacket(packet, ThrottleOutPacketType.Unknown, true); } diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index 7fd59a0..eb97f41 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs @@ -287,6 +287,9 @@ namespace OpenSim.Region.Physics.OdePlugin private OdePrim cp1; private OdeCharacter cc2; private OdePrim cp2; + private int tickCountFrameRun; + + private int latertickcount=0; //private int cStartStop = 0; //private string cDictKey = ""; @@ -3123,6 +3126,22 @@ namespace OpenSim.Region.Physics.OdePlugin } d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); } + latertickcount = Util.EnvironmentTickCount() - tickCountFrameRun; + + // OpenSimulator above does 10 fps. 10 fps = means that the main thread loop and physics + // has a max of 100 ms to run theoretically. + // If the main loop stalls, it calls Simulate later which makes the tick count ms larger. + // If Physics stalls, it takes longer which makes the tick count ms larger. + + if (latertickcount < 100) + m_timeDilation = 1.0f; + else + { + m_timeDilation = 100f / latertickcount; + //m_timeDilation = Math.Min((Math.Max(100 - (Util.EnvironmentTickCount() - tickCountFrameRun), 1) / 100f), 1.0f); + } + + tickCountFrameRun = Util.EnvironmentTickCount(); } return fps; -- cgit v1.1 From 26e601a77603e593c8b4ba3a07f0580ff2a2a740 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 23 Dec 2010 11:50:53 +0000 Subject: Put back a commented section of code. With some viewers, object inventory transfers just don't start without it. Observed my Nebadon and yours truly. --- OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs index c5a6e62..4f9e32b 100644 --- a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs +++ b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs @@ -105,12 +105,11 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer } } - // This should not be here - //if (Requests.ContainsKey(fileName)) - //{ - // RequestXfer(Requests[fileName].remoteClient, Requests[fileName].xferID, fileName); - // Requests.Remove(fileName); - //} + if (Requests.ContainsKey(fileName)) + { + RequestXfer(Requests[fileName].remoteClient, Requests[fileName].xferID, fileName); + Requests.Remove(fileName); + } return true; } -- cgit v1.1 From 54418c5e69c5085750762e2bd3220ae7a6808471 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 23 Dec 2010 10:05:08 -0800 Subject: Removed unused code -- this was the previous version of UDP texture sending, which now lives entirely in LindenUDP space. --- .../Region/ClientStack/LindenUDP/LLClientView.cs | 40 ++- .../Agent/TextureDownload/TextureDownloadModule.cs | 302 --------------------- .../Agent/TextureDownload/TextureNotFoundSender.cs | 87 ------ .../TextureDownload/UserTextureDownloadService.cs | 265 ------------------ .../Agent/TextureSender/TextureSender.cs | 212 --------------- .../Region/Framework/Interfaces/ITextureSender.cs | 58 ---- 6 files changed, 16 insertions(+), 948 deletions(-) delete mode 100644 OpenSim/Region/CoreModules/Agent/TextureDownload/TextureDownloadModule.cs delete mode 100644 OpenSim/Region/CoreModules/Agent/TextureDownload/TextureNotFoundSender.cs delete mode 100644 OpenSim/Region/CoreModules/Agent/TextureDownload/UserTextureDownloadService.cs delete mode 100644 OpenSim/Region/CoreModules/Agent/TextureSender/TextureSender.cs delete mode 100644 OpenSim/Region/Framework/Interfaces/ITextureSender.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 929f282..4e4ecea 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -7189,34 +7189,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP //handlerTextureRequest = null; for (int i = 0; i < imageRequest.RequestImage.Length; i++) { - if (OnRequestTexture != null) - { - TextureRequestArgs args = new TextureRequestArgs(); - - RequestImagePacket.RequestImageBlock block = imageRequest.RequestImage[i]; - - args.RequestedAssetID = block.Image; - args.DiscardLevel = block.DiscardLevel; - args.PacketNumber = block.Packet; - args.Priority = block.DownloadPriority; - args.requestSequence = imageRequest.Header.Sequence; + TextureRequestArgs args = new TextureRequestArgs(); - // NOTE: This is not a built in part of the LLUDP protocol, but we double the - // priority of avatar textures to get avatars rezzing in faster than the - // surrounding scene - if ((ImageType)block.Type == ImageType.Baked) - args.Priority *= 2.0f; + RequestImagePacket.RequestImageBlock block = imageRequest.RequestImage[i]; - //handlerTextureRequest = OnRequestTexture; + args.RequestedAssetID = block.Image; + args.DiscardLevel = block.DiscardLevel; + args.PacketNumber = block.Packet; + args.Priority = block.DownloadPriority; + args.requestSequence = imageRequest.Header.Sequence; - //if (handlerTextureRequest != null) - //OnRequestTexture(this, args); + // NOTE: This is not a built in part of the LLUDP protocol, but we double the + // priority of avatar textures to get avatars rezzing in faster than the + // surrounding scene + if ((ImageType)block.Type == ImageType.Baked) + args.Priority *= 2.0f; - // in the end, we null this, so we have to check if it's null - if (m_imageManager != null) - { - m_imageManager.EnqueueReq(args); - } + // in the end, we null this, so we have to check if it's null + if (m_imageManager != null) + { + m_imageManager.EnqueueReq(args); } } return true; diff --git a/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureDownloadModule.cs b/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureDownloadModule.cs deleted file mode 100644 index c7bf6c8..0000000 --- a/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureDownloadModule.cs +++ /dev/null @@ -1,302 +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 System.Reflection; -using System.Threading; -using log4net; -using Nini.Config; -using OpenMetaverse; -using OpenSim.Framework; - -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using BlockingQueue = OpenSim.Framework.BlockingQueue; -using OpenSim.Services.Interfaces; - -namespace OpenSim.Region.CoreModules.Agent.TextureDownload -{ - public class TextureDownloadModule : IRegionModule - { - private static readonly ILog m_log - = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - /// - /// There is one queue for all textures waiting to be sent, regardless of the requesting user. - /// - private readonly BlockingQueue m_queueSenders - = new BlockingQueue(); - - /// - /// Each user has their own texture download service. - /// - private readonly Dictionary m_userTextureServices = - new Dictionary(); - - private Scene m_scene; - private List m_scenes = new List(); - - public TextureDownloadModule() - { - } - - #region IRegionModule Members - - public void Initialise(Scene scene, IConfigSource config) - { - - if (m_scene == null) - { - //m_log.Debug("Creating Texture download module"); - m_scene = scene; - //m_thread = new Thread(new ThreadStart(ProcessTextureSenders)); - //m_thread.Name = "ProcessTextureSenderThread"; - //m_thread.IsBackground = true; - //m_thread.Start(); - //ThreadTracker.Add(m_thread); - } - - if (!m_scenes.Contains(scene)) - { - m_scenes.Add(scene); - m_scene = scene; - m_scene.EventManager.OnNewClient += NewClient; - m_scene.EventManager.OnRemovePresence += EventManager_OnRemovePresence; - } - } - - public void PostInitialise() - { - } - - public void Close() - { - } - - public string Name - { - get { return "TextureDownloadModule"; } - } - - public bool IsSharedModule - { - get { return false; } - } - - #endregion - - /// - /// Cleanup the texture service related objects for the removed presence. - /// - /// - private void EventManager_OnRemovePresence(UUID agentId) - { - UserTextureDownloadService textureService; - - lock (m_userTextureServices) - { - if (m_userTextureServices.TryGetValue(agentId, out textureService)) - { - textureService.Close(); - //m_log.DebugFormat("[TEXTURE MODULE]: Removing UserTextureServices from {0}", m_scene.RegionInfo.RegionName); - m_userTextureServices.Remove(agentId); - } - } - } - - public void NewClient(IClientAPI client) - { - UserTextureDownloadService textureService; - - lock (m_userTextureServices) - { - if (m_userTextureServices.TryGetValue(client.AgentId, out textureService)) - { - textureService.Close(); - //m_log.DebugFormat("[TEXTURE MODULE]: Removing outdated UserTextureServices from {0}", m_scene.RegionInfo.RegionName); - m_userTextureServices.Remove(client.AgentId); - } - m_userTextureServices.Add(client.AgentId, new UserTextureDownloadService(client, m_scene, m_queueSenders)); - } - - client.OnRequestTexture += TextureRequest; - } - - /// I'm commenting this out, and replacing it with the implementation below, which - /// may return a null value. This is necessary for avoiding race conditions - /// recreating UserTextureServices for clients that have just been closed. - /// That behavior of always returning a UserTextureServices was causing the - /// A-B-A problem (mantis #2855). - /// - ///// - ///// Does this user have a registered texture download service? - ///// - ///// - ///// - ///// Always returns true, since a service is created if one does not already exist - //private bool TryGetUserTextureService( - // IClientAPI client, out UserTextureDownloadService textureService) - //{ - // lock (m_userTextureServices) - // { - // if (m_userTextureServices.TryGetValue(client.AgentId, out textureService)) - // { - // //m_log.DebugFormat("[TEXTURE MODULE]: Found existing UserTextureServices in ", m_scene.RegionInfo.RegionName); - // return true; - // } - - // m_log.DebugFormat("[TEXTURE MODULE]: Creating new UserTextureServices in ", m_scene.RegionInfo.RegionName); - // textureService = new UserTextureDownloadService(client, m_scene, m_queueSenders); - // m_userTextureServices.Add(client.AgentId, textureService); - - // return true; - // } - //} - - /// - /// Does this user have a registered texture download service? - /// - /// - /// - /// A UserTextureDownloadService or null in the output parameter, and true or false accordingly. - private bool TryGetUserTextureService(IClientAPI client, out UserTextureDownloadService textureService) - { - lock (m_userTextureServices) - { - if (m_userTextureServices.TryGetValue(client.AgentId, out textureService)) - { - //m_log.DebugFormat("[TEXTURE MODULE]: Found existing UserTextureServices in ", m_scene.RegionInfo.RegionName); - return true; - } - - textureService = null; - return false; - } - } - - /// - /// Start the process of requesting a given texture. - /// - /// - /// - public void TextureRequest(Object sender, TextureRequestArgs e) - { - IClientAPI client = (IClientAPI)sender; - - if (e.Priority == 1016001f) // Preview - { - if (client.Scene is Scene) - { - Scene scene = (Scene)client.Scene; - - ScenePresence sp = scene.GetScenePresence(client.AgentId); - if (sp == null) // Deny unknown user - return; - - IInventoryService invService = scene.InventoryService; - if (invService.GetRootFolder(client.AgentId) == null) // Deny no inventory - return; - - // Diva 2009-08-13: this test doesn't make any sense to many devs - //if (profile.UserProfile.GodLevel < 200 && profile.RootFolder.FindAsset(e.RequestedAssetID) == null) // Deny if not owned - //{ - // m_log.WarnFormat("[TEXTURE]: user {0} doesn't have permissions to texture {1}"); - // return; - //} - - m_log.Debug("Texture preview"); - } - } - - UserTextureDownloadService textureService; - - if (TryGetUserTextureService(client, out textureService)) - { - textureService.HandleTextureRequest(e); - } - } - - /// - /// Entry point for the thread dedicated to processing the texture queue. - /// - public void ProcessTextureSenders() - { - ITextureSender sender = null; - - try - { - while (true) - { - sender = m_queueSenders.Dequeue(); - - if (sender.Cancel) - { - TextureSent(sender); - - sender.Cancel = false; - } - else - { - bool finished = sender.SendTexturePacket(); - if (finished) - { - TextureSent(sender); - } - else - { - m_queueSenders.Enqueue(sender); - } - } - - // Make sure that any sender we currently have can get garbage collected - sender = null; - - //m_log.InfoFormat("[TEXTURE] Texture sender queue size: {0}", m_queueSenders.Count()); - } - } - catch (Exception e) - { - // TODO: Let users in the sim and those entering it and possibly an external watchdog know what has happened - m_log.ErrorFormat( - "[TEXTURE]: Texture send thread terminating with exception. PLEASE REBOOT YOUR SIM - TEXTURES WILL NOT BE AVAILABLE UNTIL YOU DO. Exception is {0}", - e); - } - } - - /// - /// Called when the texture has finished sending. - /// - /// - private void TextureSent(ITextureSender sender) - { - sender.Sending = false; - //m_log.DebugFormat("[TEXTURE]: Removing download stat for {0}", sender.assetID); - m_scene.StatsReporter.AddPendingDownloads(-1); - } - } -} diff --git a/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureNotFoundSender.cs b/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureNotFoundSender.cs deleted file mode 100644 index ba735a7..0000000 --- a/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureNotFoundSender.cs +++ /dev/null @@ -1,87 +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 OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; - -namespace OpenSim.Region.CoreModules.Agent.TextureDownload -{ - /// - /// Sends a 'texture not found' packet back to the client - /// - public class TextureNotFoundSender : ITextureSender - { - // private static readonly log4net.ILog m_log - // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - - // private IClientAPI m_client; - // private UUID m_textureId; - - public TextureNotFoundSender(IClientAPI client, UUID textureID) - { - //m_client = client; - //m_textureId = textureID; - } - - #region ITextureSender Members - - public bool Sending - { - get { return false; } - set { } - } - - public bool Cancel - { - get { return false; } - set { } - } - - // See ITextureSender - public void UpdateRequest(int discardLevel, uint packetNumber) - { - // No need to implement since priority changes don't affect this operation - } - - // See ITextureSender - public bool SendTexturePacket() - { - // m_log.DebugFormat( - // "[TEXTURE NOT FOUND SENDER]: Informing the client that texture {0} cannot be found", - // m_textureId); - - // XXX Temporarily disabling as this appears to be causing client crashes on at least - // 1.19.0(5) of the Linden Second Life client. - // m_client.SendImageNotFound(m_textureId); - - return true; - } - - #endregion - } -} diff --git a/OpenSim/Region/CoreModules/Agent/TextureDownload/UserTextureDownloadService.cs b/OpenSim/Region/CoreModules/Agent/TextureDownload/UserTextureDownloadService.cs deleted file mode 100644 index 19f0f90..0000000 --- a/OpenSim/Region/CoreModules/Agent/TextureDownload/UserTextureDownloadService.cs +++ /dev/null @@ -1,265 +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 System.Reflection; -using log4net; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Framework.Communications.Limit; -using OpenSim.Framework.Statistics; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; - -namespace OpenSim.Region.CoreModules.Agent.TextureDownload -{ - /// - /// This module sets up texture senders in response to client texture requests, and places them on a - /// processing queue once those senders have the appropriate data (i.e. a texture retrieved from the - /// asset cache). - /// - public class UserTextureDownloadService - { -// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - /// - /// True if the service has been closed, probably because a user with texture requests still queued - /// logged out. - /// - private bool closed; - - /// - /// We will allow the client to request the same texture n times before dropping further requests - /// - /// This number includes repeated requests for the same texture at different resolutions (which we don't - /// currently handle properly as far as I know). However, this situation should be handled in a more - /// sophisticated way. - /// -// private static readonly int MAX_ALLOWED_TEXTURE_REQUESTS = 5; - - /// - /// XXX Also going to limit requests for found textures. - /// -// private readonly IRequestLimitStrategy foundTextureLimitStrategy -// = new RepeatLimitStrategy(MAX_ALLOWED_TEXTURE_REQUESTS); - -// private readonly IClientAPI m_client; - private readonly Scene m_scene; - - /// - /// Texture Senders are placed in this queue once they have received their texture from the asset - /// cache. Another module actually invokes the send. - /// -// private readonly OpenSim.Framework.BlockingQueue m_sharedSendersQueue; - - /// - /// Holds texture senders before they have received the appropriate texture from the asset cache. - /// - private readonly Dictionary m_textureSenders = new Dictionary(); - - /// - /// We're going to limit requests for the same missing texture. - /// XXX This is really a temporary solution to deal with the situation where a client continually requests - /// the same missing textures - /// -// private readonly IRequestLimitStrategy missingTextureLimitStrategy -// = new RepeatLimitStrategy(MAX_ALLOWED_TEXTURE_REQUESTS); - - public UserTextureDownloadService( - IClientAPI client, Scene scene, OpenSim.Framework.BlockingQueue sharedQueue) - { -// m_client = client; - m_scene = scene; -// m_sharedSendersQueue = sharedQueue; - } - - /// - /// Handle a texture request. This involves creating a texture sender and placing it on the - /// previously passed in shared queue. - /// - /// - public void HandleTextureRequest(TextureRequestArgs e) - { - - //TextureSender.TextureSender textureSender; - - //TODO: should be working out the data size/ number of packets to be sent for each discard level - //if ((e.DiscardLevel >= 0) || (e.Priority != 0)) - //{ - //lock (m_textureSenders) - //{ - //if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender)) - //{ - // If we've received new non UUID information for this request and it hasn't dispatched - // yet, then update the request accordingly. - // textureSender.UpdateRequest(e.DiscardLevel, e.PacketNumber); - //} - //else - //{ - // m_log.DebugFormat("[TEXTURE]: Received a request for texture {0}", e.RequestedAssetID); - - //if (!foundTextureLimitStrategy.AllowRequest(e.RequestedAssetID)) - //{ - // m_log.DebugFormat( - // "[TEXTURE]: Refusing request for {0} from client {1}", - // e.RequestedAssetID, m_client.AgentId); - - //return; - //} - //else if (!missingTextureLimitStrategy.AllowRequest(e.RequestedAssetID)) - //{ - // if (missingTextureLimitStrategy.IsFirstRefusal(e.RequestedAssetID)) - // { - // if (StatsManager.SimExtraStats != null) - // StatsManager.SimExtraStats.AddBlockedMissingTextureRequest(); - - // Commenting out this message for now as it causes too much noise with other - // debug messages. - // m_log.DebugFormat( - // "[TEXTURE]: Dropping requests for notified missing texture {0} for client {1} since we have received more than {2} requests", - // e.RequestedAssetID, m_client.AgentId, MAX_ALLOWED_TEXTURE_REQUESTS); - // } - - // return; - //} - - m_scene.StatsReporter.AddPendingDownloads(1); - - //TextureSender.TextureSender requestHandler = new TextureSender.TextureSender(m_client, e.DiscardLevel, e.PacketNumber); - //m_textureSenders.Add(e.RequestedAssetID, null); - - m_scene.AssetService.Get(e.RequestedAssetID.ToString(), this, TextureReceived); - - - } - - protected void TextureReceived(string id, Object sender, AssetBase asset) - { - if (asset != null) - TextureCallback(asset.FullID, asset); - } - - /// - /// The callback for the asset cache when a texture has been retrieved. This method queues the - /// texture sender for processing. - /// - /// - /// - public void TextureCallback(UUID textureID, AssetBase texture) - { - //m_log.DebugFormat("[USER TEXTURE DOWNLOAD SERVICE]: Calling TextureCallback with {0}, texture == null is {1}", textureID, (texture == null ? true : false)); - - // There may still be texture requests pending for a logged out client - if (closed) - return; - - /* - lock (m_textureSenders) - { - TextureSender.TextureSender textureSender; - if (m_textureSenders.TryGetValue(textureID, out textureSender)) - { - // XXX It may be perfectly valid for a texture to have no data... but if we pass - // this on to the TextureSender it will blow up, so just discard for now. - // Needs investigation. - if (texture == null || texture.Data == null) - { - if (!missingTextureLimitStrategy.IsMonitoringRequests(textureID)) - { - missingTextureLimitStrategy.MonitorRequests(textureID); - - // m_log.DebugFormat( - // "[TEXTURE]: Queueing first TextureNotFoundSender for {0}, client {1}", - // textureID, m_client.AgentId); - } - - ITextureSender textureNotFoundSender = new TextureNotFoundSender(m_client, textureID); - EnqueueTextureSender(textureNotFoundSender); - } - else - { - if (!textureSender.ImageLoaded) - { - textureSender.TextureReceived(texture); - EnqueueTextureSender(textureSender); - - foundTextureLimitStrategy.MonitorRequests(textureID); - } - } - - //m_log.InfoFormat("[TEXTURE] Removing texture sender with uuid {0}", textureID); - m_textureSenders.Remove(textureID); - //m_log.InfoFormat("[TEXTURE] Current texture senders in dictionary: {0}", m_textureSenders.Count); - } - else - { - m_log.WarnFormat( - "[TEXTURE]: Got a texture uuid {0} with no sender object to handle it, this shouldn't happen", - textureID); - } - } - */ - } - - /// - /// Place a ready texture sender on the processing queue. - /// - /// -// private void EnqueueTextureSender(ITextureSender textureSender) -// { -// textureSender.Cancel = false; -// textureSender.Sending = true; -// -// if (!m_sharedSendersQueue.Contains(textureSender)) -// { -// m_sharedSendersQueue.Enqueue(textureSender); -// } -// } - - /// - /// Close this module. - /// - internal void Close() - { - closed = true; - - lock (m_textureSenders) - { - foreach (TextureSender.TextureSender textureSender in m_textureSenders.Values) - { - textureSender.Cancel = true; - } - - m_textureSenders.Clear(); - } - - // XXX: It might be possible to also remove pending texture requests from the asset cache queues, - // though this might also be more trouble than it's worth. - } - } -} diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/TextureSender.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/TextureSender.cs deleted file mode 100644 index 62c5a32..0000000 --- a/OpenSim/Region/CoreModules/Agent/TextureSender/TextureSender.cs +++ /dev/null @@ -1,212 +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.Reflection; -using log4net; -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; - -namespace OpenSim.Region.CoreModules.Agent.TextureSender -{ - /// - /// A TextureSender handles the process of receiving a texture requested by the client from the - /// AssetCache, and then sending that texture back to the client. - /// - public class TextureSender : ITextureSender - { - private static readonly ILog m_log - = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - /// - /// Records the number of times texture send has been called. - /// - public int counter = 0; - - public bool ImageLoaded = false; - - /// - /// Holds the texture asset to send. - /// - private AssetBase m_asset; - - //public UUID assetID { get { return m_asset.FullID; } } - - // private bool m_cancel = false; - - // See ITextureSender - - // private bool m_sending = false; - - /// - /// This is actually the number of extra packets required to send the texture data! We always assume - /// at least one is required. - /// - private int NumPackets = 0; - - /// - /// Holds the packet number to send next. In this case, each packet is 1000 bytes long and starts - /// at the 600th byte (0th indexed). - /// - private int PacketCounter = 0; - - private int RequestedDiscardLevel = -1; - private IClientAPI RequestUser; - private uint StartPacketNumber = 0; - - public TextureSender(IClientAPI client, int discardLevel, uint packetNumber) - { - RequestUser = client; - RequestedDiscardLevel = discardLevel; - StartPacketNumber = packetNumber; - } - - #region ITextureSender Members - - public bool Cancel - { - get { return false; } - set - { - // m_cancel = value; - } - } - - public bool Sending - { - get { return false; } - set - { - // m_sending = value; - } - } - - // See ITextureSender - public void UpdateRequest(int discardLevel, uint packetNumber) - { - RequestedDiscardLevel = discardLevel; - StartPacketNumber = packetNumber; - PacketCounter = (int)StartPacketNumber; - } - - // See ITextureSender - public bool SendTexturePacket() - { - //m_log.DebugFormat("[TEXTURE SENDER]: Sending packet for {0}", m_asset.FullID); - - SendPacket(); - counter++; - if ((NumPackets == 0) || (RequestedDiscardLevel == -1) || (PacketCounter > NumPackets) || - ((RequestedDiscardLevel > 0) && (counter > 50 + (NumPackets / (RequestedDiscardLevel + 1))))) - { - return true; - } - return false; - } - - #endregion - - /// - /// Load up the texture data to send. - /// - /// - public void TextureReceived(AssetBase asset) - { - m_asset = asset; - NumPackets = CalculateNumPackets(asset.Data.Length); - PacketCounter = (int)StartPacketNumber; - ImageLoaded = true; - } - - /// - /// Sends a texture packet to the client. - /// - private void SendPacket() - { - if (PacketCounter <= NumPackets) - { - if (PacketCounter == 0) - { - if (NumPackets == 0) - { - RequestUser.SendImageFirstPart(1, m_asset.FullID, (uint)m_asset.Data.Length, m_asset.Data, 2); - PacketCounter++; - } - else - { - byte[] ImageData1 = new byte[600]; - Array.Copy(m_asset.Data, 0, ImageData1, 0, 600); - - RequestUser.SendImageFirstPart( - (ushort)(NumPackets), m_asset.FullID, (uint)m_asset.Data.Length, ImageData1, 2); - PacketCounter++; - } - } - else - { - int size = m_asset.Data.Length - 600 - (1000 * (PacketCounter - 1)); - if (size > 1000) size = 1000; - byte[] imageData = new byte[size]; - try - { - Array.Copy(m_asset.Data, 600 + (1000 * (PacketCounter - 1)), imageData, 0, size); - } - catch (ArgumentOutOfRangeException) - { - m_log.Error("[TEXTURE SENDER]: Unable to separate texture into multiple packets: Array bounds failure on asset:" + - m_asset.ID); - return; - } - - RequestUser.SendImageNextPart((ushort)PacketCounter, m_asset.FullID, imageData); - PacketCounter++; - } - } - } - - /// - /// Calculate the number of packets that will be required to send the texture loaded into this sender - /// This is actually the number of 1000 byte packets not including an initial 600 byte packet... - /// - /// - /// - private int CalculateNumPackets(int length) - { - int numPackets = 0; - - if (length > 600) - { - //over 600 bytes so split up file - int restData = (length - 600); - int restPackets = ((restData + 999) / 1000); - numPackets = restPackets; - } - - return numPackets; - } - } -} diff --git a/OpenSim/Region/Framework/Interfaces/ITextureSender.cs b/OpenSim/Region/Framework/Interfaces/ITextureSender.cs deleted file mode 100644 index c469ae8..0000000 --- a/OpenSim/Region/Framework/Interfaces/ITextureSender.cs +++ /dev/null @@ -1,58 +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. - */ - -namespace OpenSim.Region.Framework.Interfaces -{ - /// - /// Interface for an object which can send texture information to a client - /// - public interface ITextureSender - { - /// - /// Are we in the process of sending the texture? - /// - bool Sending { get; set; } - - /// - /// Has the texture send been cancelled? - /// - bool Cancel { get; set; } - - /// - /// Update the non data properties of a texture request - /// - /// - /// - void UpdateRequest(int discardLevel, uint packetNumber); - - /// - /// Send a texture packet to the client. - /// - /// True if the last packet has been sent, false otherwise. - bool SendTexturePacket(); - } -} -- cgit v1.1