aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Environment/Modules/TextureDownloadModule.cs216
-rw-r--r--OpenSim/Region/Environment/Modules/TextureSender.cs136
-rw-r--r--OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs98
3 files changed, 236 insertions, 214 deletions
diff --git a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs b/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs
index 6d5d5e8..4e96572 100644
--- a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs
+++ b/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs
@@ -132,6 +132,8 @@ namespace OpenSim.Region.Environment.Modules
132 if (sender.Cancel) 132 if (sender.Cancel)
133 { 133 {
134 TextureSent(sender); 134 TextureSent(sender);
135
136 sender.Cancel = false;
135 } 137 }
136 else 138 else
137 { 139 {
@@ -152,219 +154,5 @@ namespace OpenSim.Region.Environment.Modules
152 { 154 {
153 sender.Sending = false; 155 sender.Sending = false;
154 } 156 }
155
156 public class UserTextureDownloadService
157 {
158 private readonly Dictionary<LLUUID, TextureSender> m_textureSenders = new Dictionary<LLUUID, TextureSender>();
159 private readonly BlockingQueue<TextureSender> m_sharedSendersQueue;
160 private readonly Scene m_scene;
161
162 public UserTextureDownloadService(Scene scene, BlockingQueue<TextureSender> sharedQueue)
163 {
164 m_scene = scene;
165 m_sharedSendersQueue = sharedQueue;
166 }
167
168 public void HandleTextureRequest(IClientAPI client, TextureRequestArgs e)
169 {
170 TextureSender textureSender;
171
172 //TODO: should be working out the data size/ number of packets to be sent for each discard level
173 if ((e.DiscardLevel >= 0) || (e.Priority != 0))
174 {
175 lock (m_textureSenders)
176 {
177 if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender))
178 {
179 textureSender.UpdateRequest(e.DiscardLevel, e.PacketNumber);
180 textureSender.counter = 0;
181
182 if ((textureSender.ImageLoaded) &&
183 (textureSender.Sending == false))
184 {
185 textureSender.Sending = true;
186
187 if (!m_sharedSendersQueue.Contains(textureSender))
188 {
189 m_sharedSendersQueue.Enqueue(textureSender);
190 }
191 }
192 }
193 else
194 {
195 TextureSender requestHandler =
196 new TextureSender(client, e.RequestedAssetID, e.DiscardLevel, e.PacketNumber);
197 m_textureSenders.Add(e.RequestedAssetID, requestHandler);
198 m_scene.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback);
199 }
200 }
201 }
202 else
203 {
204 lock (m_textureSenders)
205 {
206 if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender))
207 {
208 textureSender.Cancel = true;
209 }
210 }
211 }
212 }
213
214 public void TextureCallback(LLUUID textureID, AssetBase asset)
215 {
216 lock (m_textureSenders)
217 {
218 TextureSender textureSender;
219
220 if (m_textureSenders.TryGetValue(textureID, out textureSender))
221 {
222 if (!textureSender.ImageLoaded)
223 {
224 textureSender.TextureReceived(asset);
225 textureSender.Sending = true;
226 textureSender.counter = 0;
227
228 if (!m_sharedSendersQueue.Contains(textureSender))
229 {
230 m_sharedSendersQueue.Enqueue(textureSender);
231 }
232 }
233 }
234 else
235 {
236 throw new Exception("Got a texture with no sender object to handle it, this shouldn't happen");
237 }
238 }
239 }
240 }
241
242 public class TextureSender
243 {
244 public int counter = 0;
245 private AssetBase m_asset;
246 public long DataPointer = 0;
247 public int NumPackets = 0;
248 public int PacketCounter = 0;
249 public bool Cancel = false;
250 public bool ImageLoaded = false;
251
252 public bool Sending = false;
253
254 public IClientAPI RequestUser;
255 public LLUUID RequestedAssetID;
256 public int RequestedDiscardLevel = -1;
257 public uint StartPacketNumber = 0;
258
259 // private int m_sentDiscardLevel = -1;
260
261 public TextureSender(IClientAPI client, LLUUID textureID, int discardLevel, uint packetNumber)
262 {
263 RequestUser = client;
264 RequestedAssetID = textureID;
265 RequestedDiscardLevel = discardLevel;
266 StartPacketNumber = packetNumber;
267 }
268
269 public void TextureReceived(AssetBase asset)
270 {
271 m_asset = asset;
272 NumPackets = CalculateNumPackets(asset.Data.Length);
273 PacketCounter = (int) StartPacketNumber;
274 ImageLoaded = true;
275 }
276
277 public void UpdateRequest(int discardLevel, uint packetNumber)
278 {
279 RequestedDiscardLevel = discardLevel;
280 StartPacketNumber = packetNumber;
281 PacketCounter = (int) StartPacketNumber;
282 }
283
284 public bool SendTexturePacket()
285 {
286 SendPacket();
287 counter++;
288 if ((NumPackets == 0) || (RequestedDiscardLevel == -1) || (PacketCounter > NumPackets) ||
289 ((RequestedDiscardLevel > 0) && (counter > 50 + (NumPackets/(RequestedDiscardLevel + 1)))))
290 {
291 return true;
292 }
293 return false;
294 }
295
296 private void SendPacket()
297 {
298 if (PacketCounter <= NumPackets)
299 {
300 if (PacketCounter == 0)
301 {
302 if (NumPackets == 0)
303 {
304 ImageDataPacket im = new ImageDataPacket();
305 im.Header.Reliable = false;
306 im.ImageID.Packets = 1;
307 im.ImageID.ID = m_asset.FullID;
308 im.ImageID.Size = (uint) m_asset.Data.Length;
309 im.ImageData.Data = m_asset.Data;
310 im.ImageID.Codec = 2;
311 RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
312 PacketCounter++;
313 }
314 else
315 {
316 ImageDataPacket im = new ImageDataPacket();
317 im.Header.Reliable = false;
318 im.ImageID.Packets = (ushort) (NumPackets);
319 im.ImageID.ID = m_asset.FullID;
320 im.ImageID.Size = (uint) m_asset.Data.Length;
321 im.ImageData.Data = new byte[600];
322 Array.Copy(m_asset.Data, 0, im.ImageData.Data, 0, 600);
323 im.ImageID.Codec = 2;
324 RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
325 PacketCounter++;
326 }
327 }
328 else
329 {
330 ImagePacketPacket im = new ImagePacketPacket();
331 im.Header.Reliable = false;
332 im.ImageID.Packet = (ushort) (PacketCounter);
333 im.ImageID.ID = m_asset.FullID;
334 int size = m_asset.Data.Length - 600 - (1000*(PacketCounter - 1));
335 if (size > 1000) size = 1000;
336 im.ImageData.Data = new byte[size];
337 try
338 {
339 Array.Copy(m_asset.Data, 600 + (1000*(PacketCounter - 1)), im.ImageData.Data, 0, size);
340 }
341 catch (ArgumentOutOfRangeException)
342 {
343 MainLog.Instance.Error("TEXTURE",
344 "Unable to separate texture into multiple packets: Array bounds failure on asset:" +
345 m_asset.FullID.ToString() );
346 return;
347 }
348 RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
349 PacketCounter++;
350 }
351 }
352 }
353
354 private int CalculateNumPackets(int length)
355 {
356 int numPackets = 0;
357
358 if (length > 600)
359 {
360 //over 600 bytes so split up file
361 int restData = (length - 600);
362 int restPackets = ((restData + 999)/1000);
363 numPackets = restPackets;
364 }
365
366 return numPackets;
367 }
368 }
369 } 157 }
370} \ No newline at end of file 158} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/TextureSender.cs b/OpenSim/Region/Environment/Modules/TextureSender.cs
new file mode 100644
index 0000000..aba0126
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/TextureSender.cs
@@ -0,0 +1,136 @@
1using System;
2using libsecondlife;
3using libsecondlife.Packets;
4using OpenSim.Framework;
5using OpenSim.Framework.Console;
6
7namespace OpenSim.Region.Environment.Modules
8{
9 public class TextureSender
10 {
11 public int counter = 0;
12 private AssetBase m_asset;
13 public long DataPointer = 0;
14 public int NumPackets = 0;
15 public int PacketCounter = 0;
16 public bool Cancel = false;
17 public bool ImageLoaded = false;
18
19 public bool Sending = false;
20
21 public IClientAPI RequestUser;
22 public LLUUID RequestedAssetID;
23 public int RequestedDiscardLevel = -1;
24 public uint StartPacketNumber = 0;
25
26 // private int m_sentDiscardLevel = -1;
27
28 public TextureSender(IClientAPI client, LLUUID textureID, int discardLevel, uint packetNumber)
29 {
30 RequestUser = client;
31 RequestedAssetID = textureID;
32 RequestedDiscardLevel = discardLevel;
33 StartPacketNumber = packetNumber;
34 }
35
36 public void TextureReceived(AssetBase asset)
37 {
38 m_asset = asset;
39 NumPackets = CalculateNumPackets(asset.Data.Length);
40 PacketCounter = (int) StartPacketNumber;
41 ImageLoaded = true;
42 }
43
44 public void UpdateRequest(int discardLevel, uint packetNumber)
45 {
46 RequestedDiscardLevel = discardLevel;
47 StartPacketNumber = packetNumber;
48 PacketCounter = (int) StartPacketNumber;
49 }
50
51 public bool SendTexturePacket()
52 {
53 SendPacket();
54 counter++;
55 if ((NumPackets == 0) || (RequestedDiscardLevel == -1) || (PacketCounter > NumPackets) ||
56 ((RequestedDiscardLevel > 0) && (counter > 50 + (NumPackets/(RequestedDiscardLevel + 1)))))
57 {
58 return true;
59 }
60 return false;
61 }
62
63 private void SendPacket()
64 {
65 if (PacketCounter <= NumPackets)
66 {
67 if (PacketCounter == 0)
68 {
69 if (NumPackets == 0)
70 {
71 ImageDataPacket im = new ImageDataPacket();
72 im.Header.Reliable = false;
73 im.ImageID.Packets = 1;
74 im.ImageID.ID = m_asset.FullID;
75 im.ImageID.Size = (uint) m_asset.Data.Length;
76 im.ImageData.Data = m_asset.Data;
77 im.ImageID.Codec = 2;
78 RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
79 PacketCounter++;
80 }
81 else
82 {
83 ImageDataPacket im = new ImageDataPacket();
84 im.Header.Reliable = false;
85 im.ImageID.Packets = (ushort) (NumPackets);
86 im.ImageID.ID = m_asset.FullID;
87 im.ImageID.Size = (uint) m_asset.Data.Length;
88 im.ImageData.Data = new byte[600];
89 Array.Copy(m_asset.Data, 0, im.ImageData.Data, 0, 600);
90 im.ImageID.Codec = 2;
91 RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
92 PacketCounter++;
93 }
94 }
95 else
96 {
97 ImagePacketPacket im = new ImagePacketPacket();
98 im.Header.Reliable = false;
99 im.ImageID.Packet = (ushort) (PacketCounter);
100 im.ImageID.ID = m_asset.FullID;
101 int size = m_asset.Data.Length - 600 - (1000*(PacketCounter - 1));
102 if (size > 1000) size = 1000;
103 im.ImageData.Data = new byte[size];
104 try
105 {
106 Array.Copy(m_asset.Data, 600 + (1000*(PacketCounter - 1)), im.ImageData.Data, 0, size);
107 }
108 catch (ArgumentOutOfRangeException)
109 {
110 MainLog.Instance.Error("TEXTURE",
111 "Unable to separate texture into multiple packets: Array bounds failure on asset:" +
112 m_asset.FullID.ToString() );
113 return;
114 }
115 RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
116 PacketCounter++;
117 }
118 }
119 }
120
121 private int CalculateNumPackets(int length)
122 {
123 int numPackets = 0;
124
125 if (length > 600)
126 {
127 //over 600 bytes so split up file
128 int restData = (length - 600);
129 int restPackets = ((restData + 999)/1000);
130 numPackets = restPackets;
131 }
132
133 return numPackets;
134 }
135 }
136} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs b/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs
new file mode 100644
index 0000000..6ee43e2
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs
@@ -0,0 +1,98 @@
1using System;
2using System.Collections.Generic;
3using libsecondlife;
4using OpenSim.Framework;
5using OpenSim.Framework.Console;
6using OpenSim.Region.Environment.Scenes;
7
8namespace OpenSim.Region.Environment.Modules
9{
10 public class UserTextureDownloadService
11 {
12 private readonly Dictionary<LLUUID, TextureSender> m_textureSenders = new Dictionary<LLUUID, TextureSender>();
13 private readonly BlockingQueue<TextureSender> m_sharedSendersQueue;
14 private readonly Scene m_scene;
15
16 public UserTextureDownloadService(Scene scene, BlockingQueue<TextureSender> sharedQueue)
17 {
18 m_scene = scene;
19 m_sharedSendersQueue = sharedQueue;
20 }
21
22 public void HandleTextureRequest(IClientAPI client, TextureRequestArgs e)
23 {
24 TextureSender textureSender;
25
26 //TODO: should be working out the data size/ number of packets to be sent for each discard level
27 if ((e.DiscardLevel >= 0) || (e.Priority != 0))
28 {
29 lock (m_textureSenders)
30 {
31 if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender))
32 {
33 textureSender.UpdateRequest(e.DiscardLevel, e.PacketNumber);
34
35 if ((textureSender.ImageLoaded) &&
36 (textureSender.Sending == false))
37 {
38 EnqueueTextureSender(textureSender);
39 }
40 }
41 else
42 {
43 TextureSender requestHandler =
44 new TextureSender(client, e.RequestedAssetID, e.DiscardLevel, e.PacketNumber);
45 m_textureSenders.Add(e.RequestedAssetID, requestHandler);
46 m_scene.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback);
47 }
48 }
49 }
50 else
51 {
52 lock (m_textureSenders)
53 {
54 if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender))
55 {
56 textureSender.Cancel = true;
57 }
58 }
59 }
60 }
61
62 public void TextureCallback(LLUUID textureID, AssetBase asset)
63 {
64 lock (m_textureSenders)
65 {
66 TextureSender textureSender;
67
68 if (m_textureSenders.TryGetValue(textureID, out textureSender))
69 {
70 if (!textureSender.ImageLoaded)
71 {
72 textureSender.TextureReceived(asset);
73
74 EnqueueTextureSender(textureSender);
75 }
76 }
77 else
78 {
79 throw new Exception("Got a texture with no sender object to handle it, this shouldn't happen");
80 }
81 }
82 }
83
84 private void EnqueueTextureSender(TextureSender textureSender)
85 {
86 MainLog.Instance.Debug( "TEXTUREDOWNLOAD", "Start: ["+textureSender.RequestedAssetID+"] to ["+textureSender.RequestUser.Name+"]");
87
88 textureSender.Cancel = false;
89 textureSender.Sending = true;
90 textureSender.counter = 0;
91
92 if (!m_sharedSendersQueue.Contains(textureSender))
93 {
94 m_sharedSendersQueue.Enqueue(textureSender);
95 }
96 }
97 }
98} \ No newline at end of file