aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorMelanie2010-12-23 17:20:45 +0000
committerMelanie2010-12-23 17:20:45 +0000
commit70bb54272726da9f6f76dcabf0c51b9ba66c6a4c (patch)
tree4039fa412be5400223487fc58ae0ccf6f4c0d2f8
parentMerge branch 'master' into careminster-presence-refactor (diff)
parentMerge branch 'master' of ssh://MyConnection/var/git/opensim (diff)
downloadopensim-SC_OLD-70bb54272726da9f6f76dcabf0c51b9ba66c6a4c.zip
opensim-SC_OLD-70bb54272726da9f6f76dcabf0c51b9ba66c6a4c.tar.gz
opensim-SC_OLD-70bb54272726da9f6f76dcabf0c51b9ba66c6a4c.tar.bz2
opensim-SC_OLD-70bb54272726da9f6f76dcabf0c51b9ba66c6a4c.tar.xz
Merge branch 'master' into careminster-presence-refactor
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs40
-rw-r--r--OpenSim/Region/CoreModules/Agent/TextureDownload/TextureDownloadModule.cs302
-rw-r--r--OpenSim/Region/CoreModules/Agent/TextureDownload/TextureNotFoundSender.cs87
-rw-r--r--OpenSim/Region/CoreModules/Agent/TextureDownload/UserTextureDownloadService.cs265
-rw-r--r--OpenSim/Region/CoreModules/Agent/TextureSender/TextureSender.cs212
-rw-r--r--OpenSim/Region/Framework/Interfaces/ITextureSender.cs58
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs14
7 files changed, 26 insertions, 952 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 56f8880..870ce3e 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -7262,34 +7262,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7262 //handlerTextureRequest = null; 7262 //handlerTextureRequest = null;
7263 for (int i = 0; i < imageRequest.RequestImage.Length; i++) 7263 for (int i = 0; i < imageRequest.RequestImage.Length; i++)
7264 { 7264 {
7265 if (OnRequestTexture != null) 7265 TextureRequestArgs args = new TextureRequestArgs();
7266 {
7267 TextureRequestArgs args = new TextureRequestArgs();
7268
7269 RequestImagePacket.RequestImageBlock block = imageRequest.RequestImage[i];
7270
7271 args.RequestedAssetID = block.Image;
7272 args.DiscardLevel = block.DiscardLevel;
7273 args.PacketNumber = block.Packet;
7274 args.Priority = block.DownloadPriority;
7275 args.requestSequence = imageRequest.Header.Sequence;
7276 7266
7277 // NOTE: This is not a built in part of the LLUDP protocol, but we double the 7267 RequestImagePacket.RequestImageBlock block = imageRequest.RequestImage[i];
7278 // priority of avatar textures to get avatars rezzing in faster than the
7279 // surrounding scene
7280 if ((ImageType)block.Type == ImageType.Baked)
7281 args.Priority *= 2.0f;
7282 7268
7283 //handlerTextureRequest = OnRequestTexture; 7269 args.RequestedAssetID = block.Image;
7270 args.DiscardLevel = block.DiscardLevel;
7271 args.PacketNumber = block.Packet;
7272 args.Priority = block.DownloadPriority;
7273 args.requestSequence = imageRequest.Header.Sequence;
7284 7274
7285 //if (handlerTextureRequest != null) 7275 // NOTE: This is not a built in part of the LLUDP protocol, but we double the
7286 //OnRequestTexture(this, args); 7276 // priority of avatar textures to get avatars rezzing in faster than the
7277 // surrounding scene
7278 if ((ImageType)block.Type == ImageType.Baked)
7279 args.Priority *= 2.0f;
7287 7280
7288 // in the end, we null this, so we have to check if it's null 7281 // in the end, we null this, so we have to check if it's null
7289 if (m_imageManager != null) 7282 if (m_imageManager != null)
7290 { 7283 {
7291 m_imageManager.EnqueueReq(args); 7284 m_imageManager.EnqueueReq(args);
7292 }
7293 } 7285 }
7294 } 7286 }
7295 return true; 7287 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 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Threading;
32using log4net;
33using Nini.Config;
34using OpenMetaverse;
35using OpenSim.Framework;
36
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using BlockingQueue = OpenSim.Framework.BlockingQueue<OpenSim.Region.Framework.Interfaces.ITextureSender>;
40using OpenSim.Services.Interfaces;
41
42namespace OpenSim.Region.CoreModules.Agent.TextureDownload
43{
44 public class TextureDownloadModule : IRegionModule
45 {
46 private static readonly ILog m_log
47 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48
49 /// <summary>
50 /// There is one queue for all textures waiting to be sent, regardless of the requesting user.
51 /// </summary>
52 private readonly BlockingQueue m_queueSenders
53 = new BlockingQueue();
54
55 /// <summary>
56 /// Each user has their own texture download service.
57 /// </summary>
58 private readonly Dictionary<UUID, UserTextureDownloadService> m_userTextureServices =
59 new Dictionary<UUID, UserTextureDownloadService>();
60
61 private Scene m_scene;
62 private List<Scene> m_scenes = new List<Scene>();
63
64 public TextureDownloadModule()
65 {
66 }
67
68 #region IRegionModule Members
69
70 public void Initialise(Scene scene, IConfigSource config)
71 {
72
73 if (m_scene == null)
74 {
75 //m_log.Debug("Creating Texture download module");
76 m_scene = scene;
77 //m_thread = new Thread(new ThreadStart(ProcessTextureSenders));
78 //m_thread.Name = "ProcessTextureSenderThread";
79 //m_thread.IsBackground = true;
80 //m_thread.Start();
81 //ThreadTracker.Add(m_thread);
82 }
83
84 if (!m_scenes.Contains(scene))
85 {
86 m_scenes.Add(scene);
87 m_scene = scene;
88 m_scene.EventManager.OnNewClient += NewClient;
89 m_scene.EventManager.OnRemovePresence += EventManager_OnRemovePresence;
90 }
91 }
92
93 public void PostInitialise()
94 {
95 }
96
97 public void Close()
98 {
99 }
100
101 public string Name
102 {
103 get { return "TextureDownloadModule"; }
104 }
105
106 public bool IsSharedModule
107 {
108 get { return false; }
109 }
110
111 #endregion
112
113 /// <summary>
114 /// Cleanup the texture service related objects for the removed presence.
115 /// </summary>
116 /// <param name="agentId"> </param>
117 private void EventManager_OnRemovePresence(UUID agentId)
118 {
119 UserTextureDownloadService textureService;
120
121 lock (m_userTextureServices)
122 {
123 if (m_userTextureServices.TryGetValue(agentId, out textureService))
124 {
125 textureService.Close();
126 //m_log.DebugFormat("[TEXTURE MODULE]: Removing UserTextureServices from {0}", m_scene.RegionInfo.RegionName);
127 m_userTextureServices.Remove(agentId);
128 }
129 }
130 }
131
132 public void NewClient(IClientAPI client)
133 {
134 UserTextureDownloadService textureService;
135
136 lock (m_userTextureServices)
137 {
138 if (m_userTextureServices.TryGetValue(client.AgentId, out textureService))
139 {
140 textureService.Close();
141 //m_log.DebugFormat("[TEXTURE MODULE]: Removing outdated UserTextureServices from {0}", m_scene.RegionInfo.RegionName);
142 m_userTextureServices.Remove(client.AgentId);
143 }
144 m_userTextureServices.Add(client.AgentId, new UserTextureDownloadService(client, m_scene, m_queueSenders));
145 }
146
147 client.OnRequestTexture += TextureRequest;
148 }
149
150 /// I'm commenting this out, and replacing it with the implementation below, which
151 /// may return a null value. This is necessary for avoiding race conditions
152 /// recreating UserTextureServices for clients that have just been closed.
153 /// That behavior of always returning a UserTextureServices was causing the
154 /// A-B-A problem (mantis #2855).
155 ///
156 ///// <summary>
157 ///// Does this user have a registered texture download service?
158 ///// </summary>
159 ///// <param name="userID"></param>
160 ///// <param name="textureService"></param>
161 ///// <returns>Always returns true, since a service is created if one does not already exist</returns>
162 //private bool TryGetUserTextureService(
163 // IClientAPI client, out UserTextureDownloadService textureService)
164 //{
165 // lock (m_userTextureServices)
166 // {
167 // if (m_userTextureServices.TryGetValue(client.AgentId, out textureService))
168 // {
169 // //m_log.DebugFormat("[TEXTURE MODULE]: Found existing UserTextureServices in ", m_scene.RegionInfo.RegionName);
170 // return true;
171 // }
172
173 // m_log.DebugFormat("[TEXTURE MODULE]: Creating new UserTextureServices in ", m_scene.RegionInfo.RegionName);
174 // textureService = new UserTextureDownloadService(client, m_scene, m_queueSenders);
175 // m_userTextureServices.Add(client.AgentId, textureService);
176
177 // return true;
178 // }
179 //}
180
181 /// <summary>
182 /// Does this user have a registered texture download service?
183 /// </summary>
184 /// <param name="userID"></param>
185 /// <param name="textureService"></param>
186 /// <returns>A UserTextureDownloadService or null in the output parameter, and true or false accordingly.</returns>
187 private bool TryGetUserTextureService(IClientAPI client, out UserTextureDownloadService textureService)
188 {
189 lock (m_userTextureServices)
190 {
191 if (m_userTextureServices.TryGetValue(client.AgentId, out textureService))
192 {
193 //m_log.DebugFormat("[TEXTURE MODULE]: Found existing UserTextureServices in ", m_scene.RegionInfo.RegionName);
194 return true;
195 }
196
197 textureService = null;
198 return false;
199 }
200 }
201
202 /// <summary>
203 /// Start the process of requesting a given texture.
204 /// </summary>
205 /// <param name="sender"> </param>
206 /// <param name="e"></param>
207 public void TextureRequest(Object sender, TextureRequestArgs e)
208 {
209 IClientAPI client = (IClientAPI)sender;
210
211 if (e.Priority == 1016001f) // Preview
212 {
213 if (client.Scene is Scene)
214 {
215 Scene scene = (Scene)client.Scene;
216
217 ScenePresence sp = scene.GetScenePresence(client.AgentId);
218 if (sp == null) // Deny unknown user
219 return;
220
221 IInventoryService invService = scene.InventoryService;
222 if (invService.GetRootFolder(client.AgentId) == null) // Deny no inventory
223 return;
224
225 // Diva 2009-08-13: this test doesn't make any sense to many devs
226 //if (profile.UserProfile.GodLevel < 200 && profile.RootFolder.FindAsset(e.RequestedAssetID) == null) // Deny if not owned
227 //{
228 // m_log.WarnFormat("[TEXTURE]: user {0} doesn't have permissions to texture {1}");
229 // return;
230 //}
231
232 m_log.Debug("Texture preview");
233 }
234 }
235
236 UserTextureDownloadService textureService;
237
238 if (TryGetUserTextureService(client, out textureService))
239 {
240 textureService.HandleTextureRequest(e);
241 }
242 }
243
244 /// <summary>
245 /// Entry point for the thread dedicated to processing the texture queue.
246 /// </summary>
247 public void ProcessTextureSenders()
248 {
249 ITextureSender sender = null;
250
251 try
252 {
253 while (true)
254 {
255 sender = m_queueSenders.Dequeue();
256
257 if (sender.Cancel)
258 {
259 TextureSent(sender);
260
261 sender.Cancel = false;
262 }
263 else
264 {
265 bool finished = sender.SendTexturePacket();
266 if (finished)
267 {
268 TextureSent(sender);
269 }
270 else
271 {
272 m_queueSenders.Enqueue(sender);
273 }
274 }
275
276 // Make sure that any sender we currently have can get garbage collected
277 sender = null;
278
279 //m_log.InfoFormat("[TEXTURE] Texture sender queue size: {0}", m_queueSenders.Count());
280 }
281 }
282 catch (Exception e)
283 {
284 // TODO: Let users in the sim and those entering it and possibly an external watchdog know what has happened
285 m_log.ErrorFormat(
286 "[TEXTURE]: Texture send thread terminating with exception. PLEASE REBOOT YOUR SIM - TEXTURES WILL NOT BE AVAILABLE UNTIL YOU DO. Exception is {0}",
287 e);
288 }
289 }
290
291 /// <summary>
292 /// Called when the texture has finished sending.
293 /// </summary>
294 /// <param name="sender"></param>
295 private void TextureSent(ITextureSender sender)
296 {
297 sender.Sending = false;
298 //m_log.DebugFormat("[TEXTURE]: Removing download stat for {0}", sender.assetID);
299 m_scene.StatsReporter.AddPendingDownloads(-1);
300 }
301 }
302}
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 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenMetaverse;
29using OpenSim.Framework;
30using OpenSim.Region.Framework.Interfaces;
31
32namespace OpenSim.Region.CoreModules.Agent.TextureDownload
33{
34 /// <summary>
35 /// Sends a 'texture not found' packet back to the client
36 /// </summary>
37 public class TextureNotFoundSender : ITextureSender
38 {
39 // private static readonly log4net.ILog m_log
40 // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
41
42 // private IClientAPI m_client;
43 // private UUID m_textureId;
44
45 public TextureNotFoundSender(IClientAPI client, UUID textureID)
46 {
47 //m_client = client;
48 //m_textureId = textureID;
49 }
50
51 #region ITextureSender Members
52
53 public bool Sending
54 {
55 get { return false; }
56 set { }
57 }
58
59 public bool Cancel
60 {
61 get { return false; }
62 set { }
63 }
64
65 // See ITextureSender
66 public void UpdateRequest(int discardLevel, uint packetNumber)
67 {
68 // No need to implement since priority changes don't affect this operation
69 }
70
71 // See ITextureSender
72 public bool SendTexturePacket()
73 {
74 // m_log.DebugFormat(
75 // "[TEXTURE NOT FOUND SENDER]: Informing the client that texture {0} cannot be found",
76 // m_textureId);
77
78 // XXX Temporarily disabling as this appears to be causing client crashes on at least
79 // 1.19.0(5) of the Linden Second Life client.
80 // m_client.SendImageNotFound(m_textureId);
81
82 return true;
83 }
84
85 #endregion
86 }
87}
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 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using log4net;
32using OpenMetaverse;
33using OpenSim.Framework;
34using OpenSim.Framework.Communications.Limit;
35using OpenSim.Framework.Statistics;
36using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes;
38
39namespace OpenSim.Region.CoreModules.Agent.TextureDownload
40{
41 /// <summary>
42 /// This module sets up texture senders in response to client texture requests, and places them on a
43 /// processing queue once those senders have the appropriate data (i.e. a texture retrieved from the
44 /// asset cache).
45 /// </summary>
46 public class UserTextureDownloadService
47 {
48// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49
50 /// <summary>
51 /// True if the service has been closed, probably because a user with texture requests still queued
52 /// logged out.
53 /// </summary>
54 private bool closed;
55
56 /// <summary>
57 /// We will allow the client to request the same texture n times before dropping further requests
58 ///
59 /// This number includes repeated requests for the same texture at different resolutions (which we don't
60 /// currently handle properly as far as I know). However, this situation should be handled in a more
61 /// sophisticated way.
62 /// </summary>
63// private static readonly int MAX_ALLOWED_TEXTURE_REQUESTS = 5;
64
65 /// <summary>
66 /// XXX Also going to limit requests for found textures.
67 /// </summary>
68// private readonly IRequestLimitStrategy<UUID> foundTextureLimitStrategy
69// = new RepeatLimitStrategy<UUID>(MAX_ALLOWED_TEXTURE_REQUESTS);
70
71// private readonly IClientAPI m_client;
72 private readonly Scene m_scene;
73
74 /// <summary>
75 /// Texture Senders are placed in this queue once they have received their texture from the asset
76 /// cache. Another module actually invokes the send.
77 /// </summary>
78// private readonly OpenSim.Framework.BlockingQueue<ITextureSender> m_sharedSendersQueue;
79
80 /// <summary>
81 /// Holds texture senders before they have received the appropriate texture from the asset cache.
82 /// </summary>
83 private readonly Dictionary<UUID, TextureSender.TextureSender> m_textureSenders = new Dictionary<UUID, TextureSender.TextureSender>();
84
85 /// <summary>
86 /// We're going to limit requests for the same missing texture.
87 /// XXX This is really a temporary solution to deal with the situation where a client continually requests
88 /// the same missing textures
89 /// </summary>
90// private readonly IRequestLimitStrategy<UUID> missingTextureLimitStrategy
91// = new RepeatLimitStrategy<UUID>(MAX_ALLOWED_TEXTURE_REQUESTS);
92
93 public UserTextureDownloadService(
94 IClientAPI client, Scene scene, OpenSim.Framework.BlockingQueue<ITextureSender> sharedQueue)
95 {
96// m_client = client;
97 m_scene = scene;
98// m_sharedSendersQueue = sharedQueue;
99 }
100
101 /// <summary>
102 /// Handle a texture request. This involves creating a texture sender and placing it on the
103 /// previously passed in shared queue.
104 /// </summary>
105 /// <param name="e"></param>
106 public void HandleTextureRequest(TextureRequestArgs e)
107 {
108
109 //TextureSender.TextureSender textureSender;
110
111 //TODO: should be working out the data size/ number of packets to be sent for each discard level
112 //if ((e.DiscardLevel >= 0) || (e.Priority != 0))
113 //{
114 //lock (m_textureSenders)
115 //{
116 //if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender))
117 //{
118 // If we've received new non UUID information for this request and it hasn't dispatched
119 // yet, then update the request accordingly.
120 // textureSender.UpdateRequest(e.DiscardLevel, e.PacketNumber);
121 //}
122 //else
123 //{
124 // m_log.DebugFormat("[TEXTURE]: Received a request for texture {0}", e.RequestedAssetID);
125
126 //if (!foundTextureLimitStrategy.AllowRequest(e.RequestedAssetID))
127 //{
128 // m_log.DebugFormat(
129 // "[TEXTURE]: Refusing request for {0} from client {1}",
130 // e.RequestedAssetID, m_client.AgentId);
131
132 //return;
133 //}
134 //else if (!missingTextureLimitStrategy.AllowRequest(e.RequestedAssetID))
135 //{
136 // if (missingTextureLimitStrategy.IsFirstRefusal(e.RequestedAssetID))
137 // {
138 // if (StatsManager.SimExtraStats != null)
139 // StatsManager.SimExtraStats.AddBlockedMissingTextureRequest();
140
141 // Commenting out this message for now as it causes too much noise with other
142 // debug messages.
143 // m_log.DebugFormat(
144 // "[TEXTURE]: Dropping requests for notified missing texture {0} for client {1} since we have received more than {2} requests",
145 // e.RequestedAssetID, m_client.AgentId, MAX_ALLOWED_TEXTURE_REQUESTS);
146 // }
147
148 // return;
149 //}
150
151 m_scene.StatsReporter.AddPendingDownloads(1);
152
153 //TextureSender.TextureSender requestHandler = new TextureSender.TextureSender(m_client, e.DiscardLevel, e.PacketNumber);
154 //m_textureSenders.Add(e.RequestedAssetID, null);
155
156 m_scene.AssetService.Get(e.RequestedAssetID.ToString(), this, TextureReceived);
157
158
159 }
160
161 protected void TextureReceived(string id, Object sender, AssetBase asset)
162 {
163 if (asset != null)
164 TextureCallback(asset.FullID, asset);
165 }
166
167 /// <summary>
168 /// The callback for the asset cache when a texture has been retrieved. This method queues the
169 /// texture sender for processing.
170 /// </summary>
171 /// <param name="textureID"></param>
172 /// <param name="texture"></param>
173 public void TextureCallback(UUID textureID, AssetBase texture)
174 {
175 //m_log.DebugFormat("[USER TEXTURE DOWNLOAD SERVICE]: Calling TextureCallback with {0}, texture == null is {1}", textureID, (texture == null ? true : false));
176
177 // There may still be texture requests pending for a logged out client
178 if (closed)
179 return;
180
181 /*
182 lock (m_textureSenders)
183 {
184 TextureSender.TextureSender textureSender;
185 if (m_textureSenders.TryGetValue(textureID, out textureSender))
186 {
187 // XXX It may be perfectly valid for a texture to have no data... but if we pass
188 // this on to the TextureSender it will blow up, so just discard for now.
189 // Needs investigation.
190 if (texture == null || texture.Data == null)
191 {
192 if (!missingTextureLimitStrategy.IsMonitoringRequests(textureID))
193 {
194 missingTextureLimitStrategy.MonitorRequests(textureID);
195
196 // m_log.DebugFormat(
197 // "[TEXTURE]: Queueing first TextureNotFoundSender for {0}, client {1}",
198 // textureID, m_client.AgentId);
199 }
200
201 ITextureSender textureNotFoundSender = new TextureNotFoundSender(m_client, textureID);
202 EnqueueTextureSender(textureNotFoundSender);
203 }
204 else
205 {
206 if (!textureSender.ImageLoaded)
207 {
208 textureSender.TextureReceived(texture);
209 EnqueueTextureSender(textureSender);
210
211 foundTextureLimitStrategy.MonitorRequests(textureID);
212 }
213 }
214
215 //m_log.InfoFormat("[TEXTURE] Removing texture sender with uuid {0}", textureID);
216 m_textureSenders.Remove(textureID);
217 //m_log.InfoFormat("[TEXTURE] Current texture senders in dictionary: {0}", m_textureSenders.Count);
218 }
219 else
220 {
221 m_log.WarnFormat(
222 "[TEXTURE]: Got a texture uuid {0} with no sender object to handle it, this shouldn't happen",
223 textureID);
224 }
225 }
226 */
227 }
228
229 /// <summary>
230 /// Place a ready texture sender on the processing queue.
231 /// </summary>
232 /// <param name="textureSender"></param>
233// private void EnqueueTextureSender(ITextureSender textureSender)
234// {
235// textureSender.Cancel = false;
236// textureSender.Sending = true;
237//
238// if (!m_sharedSendersQueue.Contains(textureSender))
239// {
240// m_sharedSendersQueue.Enqueue(textureSender);
241// }
242// }
243
244 /// <summary>
245 /// Close this module.
246 /// </summary>
247 internal void Close()
248 {
249 closed = true;
250
251 lock (m_textureSenders)
252 {
253 foreach (TextureSender.TextureSender textureSender in m_textureSenders.Values)
254 {
255 textureSender.Cancel = true;
256 }
257
258 m_textureSenders.Clear();
259 }
260
261 // XXX: It might be possible to also remove pending texture requests from the asset cache queues,
262 // though this might also be more trouble than it's worth.
263 }
264 }
265}
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 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using log4net;
31using OpenSim.Framework;
32using OpenSim.Region.Framework.Interfaces;
33
34namespace OpenSim.Region.CoreModules.Agent.TextureSender
35{
36 /// <summary>
37 /// A TextureSender handles the process of receiving a texture requested by the client from the
38 /// AssetCache, and then sending that texture back to the client.
39 /// </summary>
40 public class TextureSender : ITextureSender
41 {
42 private static readonly ILog m_log
43 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44
45 /// <summary>
46 /// Records the number of times texture send has been called.
47 /// </summary>
48 public int counter = 0;
49
50 public bool ImageLoaded = false;
51
52 /// <summary>
53 /// Holds the texture asset to send.
54 /// </summary>
55 private AssetBase m_asset;
56
57 //public UUID assetID { get { return m_asset.FullID; } }
58
59 // private bool m_cancel = false;
60
61 // See ITextureSender
62
63 // private bool m_sending = false;
64
65 /// <summary>
66 /// This is actually the number of extra packets required to send the texture data! We always assume
67 /// at least one is required.
68 /// </summary>
69 private int NumPackets = 0;
70
71 /// <summary>
72 /// Holds the packet number to send next. In this case, each packet is 1000 bytes long and starts
73 /// at the 600th byte (0th indexed).
74 /// </summary>
75 private int PacketCounter = 0;
76
77 private int RequestedDiscardLevel = -1;
78 private IClientAPI RequestUser;
79 private uint StartPacketNumber = 0;
80
81 public TextureSender(IClientAPI client, int discardLevel, uint packetNumber)
82 {
83 RequestUser = client;
84 RequestedDiscardLevel = discardLevel;
85 StartPacketNumber = packetNumber;
86 }
87
88 #region ITextureSender Members
89
90 public bool Cancel
91 {
92 get { return false; }
93 set
94 {
95 // m_cancel = value;
96 }
97 }
98
99 public bool Sending
100 {
101 get { return false; }
102 set
103 {
104 // m_sending = value;
105 }
106 }
107
108 // See ITextureSender
109 public void UpdateRequest(int discardLevel, uint packetNumber)
110 {
111 RequestedDiscardLevel = discardLevel;
112 StartPacketNumber = packetNumber;
113 PacketCounter = (int)StartPacketNumber;
114 }
115
116 // See ITextureSender
117 public bool SendTexturePacket()
118 {
119 //m_log.DebugFormat("[TEXTURE SENDER]: Sending packet for {0}", m_asset.FullID);
120
121 SendPacket();
122 counter++;
123 if ((NumPackets == 0) || (RequestedDiscardLevel == -1) || (PacketCounter > NumPackets) ||
124 ((RequestedDiscardLevel > 0) && (counter > 50 + (NumPackets / (RequestedDiscardLevel + 1)))))
125 {
126 return true;
127 }
128 return false;
129 }
130
131 #endregion
132
133 /// <summary>
134 /// Load up the texture data to send.
135 /// </summary>
136 /// <param name="asset"></param>
137 public void TextureReceived(AssetBase asset)
138 {
139 m_asset = asset;
140 NumPackets = CalculateNumPackets(asset.Data.Length);
141 PacketCounter = (int)StartPacketNumber;
142 ImageLoaded = true;
143 }
144
145 /// <summary>
146 /// Sends a texture packet to the client.
147 /// </summary>
148 private void SendPacket()
149 {
150 if (PacketCounter <= NumPackets)
151 {
152 if (PacketCounter == 0)
153 {
154 if (NumPackets == 0)
155 {
156 RequestUser.SendImageFirstPart(1, m_asset.FullID, (uint)m_asset.Data.Length, m_asset.Data, 2);
157 PacketCounter++;
158 }
159 else
160 {
161 byte[] ImageData1 = new byte[600];
162 Array.Copy(m_asset.Data, 0, ImageData1, 0, 600);
163
164 RequestUser.SendImageFirstPart(
165 (ushort)(NumPackets), m_asset.FullID, (uint)m_asset.Data.Length, ImageData1, 2);
166 PacketCounter++;
167 }
168 }
169 else
170 {
171 int size = m_asset.Data.Length - 600 - (1000 * (PacketCounter - 1));
172 if (size > 1000) size = 1000;
173 byte[] imageData = new byte[size];
174 try
175 {
176 Array.Copy(m_asset.Data, 600 + (1000 * (PacketCounter - 1)), imageData, 0, size);
177 }
178 catch (ArgumentOutOfRangeException)
179 {
180 m_log.Error("[TEXTURE SENDER]: Unable to separate texture into multiple packets: Array bounds failure on asset:" +
181 m_asset.ID);
182 return;
183 }
184
185 RequestUser.SendImageNextPart((ushort)PacketCounter, m_asset.FullID, imageData);
186 PacketCounter++;
187 }
188 }
189 }
190
191 /// <summary>
192 /// Calculate the number of packets that will be required to send the texture loaded into this sender
193 /// This is actually the number of 1000 byte packets not including an initial 600 byte packet...
194 /// </summary>
195 /// <param name="length"></param>
196 /// <returns></returns>
197 private int CalculateNumPackets(int length)
198 {
199 int numPackets = 0;
200
201 if (length > 600)
202 {
203 //over 600 bytes so split up file
204 int restData = (length - 600);
205 int restPackets = ((restData + 999) / 1000);
206 numPackets = restPackets;
207 }
208
209 return numPackets;
210 }
211 }
212}
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 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28namespace OpenSim.Region.Framework.Interfaces
29{
30 /// <summary>
31 /// Interface for an object which can send texture information to a client
32 /// </summary>
33 public interface ITextureSender
34 {
35 /// <summary>
36 /// Are we in the process of sending the texture?
37 /// </summary>
38 bool Sending { get; set; }
39
40 /// <summary>
41 /// Has the texture send been cancelled?
42 /// </summary>
43 bool Cancel { get; set; }
44
45 /// <summary>
46 /// Update the non data properties of a texture request
47 /// </summary>
48 /// <param name="discardLevel"></param>
49 /// <param name="packetNumber"></param>
50 void UpdateRequest(int discardLevel, uint packetNumber);
51
52 /// <summary>
53 /// Send a texture packet to the client.
54 /// </summary>
55 /// <returns>True if the last packet has been sent, false otherwise.</returns>
56 bool SendTexturePacket();
57 }
58}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 47c574a..ee51e80 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -692,10 +692,16 @@ namespace OpenSim.Region.Framework.Scenes
692 item.BasePermissions, item.CurrentPermissions, item.EveryOnePermissions, item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch()); 692 item.BasePermissions, item.CurrentPermissions, item.EveryOnePermissions, item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch());
693 } 693 }
694 else 694 else
695 { 695 {
696 CreateNewInventoryItem( 696 // If item is transfer or permissions are off or calling agent is allowed to copy item owner's inventory item.
697 remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType, 697 if (((item.CurrentPermissions & (uint)PermissionMask.Transfer) != 0) || m_permissions.BypassPermissions() || m_permissions.CanCopyUserInventory(remoteClient.AgentId, oldItemID))
698 item.NextPermissions, item.NextPermissions, item.EveryOnePermissions & item.NextPermissions, item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch()); 698 {
699 CreateNewInventoryItem(
700 remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID,
701 asset, (sbyte) item.InvType,
702 item.NextPermissions, item.NextPermissions, item.EveryOnePermissions & item.NextPermissions,
703 item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch());
704 }
699 } 705 }
700 } 706 }
701 else 707 else