aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Communications/Cache/AssetCache.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Communications/Cache/AssetCache.cs')
-rw-r--r--OpenSim/Framework/Communications/Cache/AssetCache.cs561
1 files changed, 561 insertions, 0 deletions
diff --git a/OpenSim/Framework/Communications/Cache/AssetCache.cs b/OpenSim/Framework/Communications/Cache/AssetCache.cs
new file mode 100644
index 0000000..3d0fd76
--- /dev/null
+++ b/OpenSim/Framework/Communications/Cache/AssetCache.cs
@@ -0,0 +1,561 @@
1/*
2* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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;
30using System.Collections.Generic;
31using System.Text;
32using System.Reflection;
33using System.Threading;
34using libsecondlife;
35using libsecondlife.Packets;
36using OpenSim.Framework.Interfaces;
37using OpenSim.Framework.Servers;
38using OpenSim.Framework.Types;
39using OpenSim.Framework.Utilities;
40
41namespace OpenSim.Framework.Communications.Caches
42{
43 public delegate void DownloadComplete(AssetCache.TextureSender sender);
44
45 public class AssetCache : IAssetReceiver
46 {
47 // Fields
48 private Thread _assetCacheThread;
49 private IAssetServer _assetServer;
50 public List<AssetRequest> AssetRequests;
51 public Dictionary<LLUUID, AssetInfo> Assets;
52 public Dictionary<LLUUID, AssetRequest> RequestedAssets;
53 public Dictionary<LLUUID, AssetRequest> RequestedTextures;
54 public Dictionary<LLUUID, TextureSender> SendingTextures;
55 private LLUUID[] textureList;
56 public List<AssetRequest> TextureRequests;
57 public Dictionary<LLUUID, TextureImage> Textures;
58
59 // Methods
60 public AssetCache(IAssetServer assetServer)
61 {
62 this.AssetRequests = new List<AssetRequest>();
63 this.TextureRequests = new List<AssetRequest>();
64 this.RequestedAssets = new Dictionary<LLUUID, AssetRequest>();
65 this.RequestedTextures = new Dictionary<LLUUID, AssetRequest>();
66 this.SendingTextures = new Dictionary<LLUUID, TextureSender>();
67 this.textureList = new LLUUID[5];
68 Console.WriteLine("Creating Asset cache");
69 this._assetServer = assetServer;
70 this._assetServer.SetReceiver(this);
71 this.Assets = new Dictionary<LLUUID, AssetInfo>();
72 this.Textures = new Dictionary<LLUUID, TextureImage>();
73 this._assetCacheThread = new Thread(new ThreadStart(this.RunAssetManager));
74 this._assetCacheThread.IsBackground = true;
75 this._assetCacheThread.Start();
76 }
77
78 public AssetCache(string assetServerDLLName, string assetServerURL, string assetServerKey)
79 {
80 this.AssetRequests = new List<AssetRequest>();
81 this.TextureRequests = new List<AssetRequest>();
82 this.RequestedAssets = new Dictionary<LLUUID, AssetRequest>();
83 this.RequestedTextures = new Dictionary<LLUUID, AssetRequest>();
84 this.SendingTextures = new Dictionary<LLUUID, TextureSender>();
85 this.textureList = new LLUUID[5];
86 Console.WriteLine("Creating Asset cache");
87 this._assetServer = this.LoadAssetDll(assetServerDLLName);
88 this._assetServer.SetServerInfo(assetServerURL, assetServerKey);
89 this._assetServer.SetReceiver(this);
90 this.Assets = new Dictionary<LLUUID, AssetInfo>();
91 this.Textures = new Dictionary<LLUUID, TextureImage>();
92 this._assetCacheThread = new Thread(new ThreadStart(this.RunAssetManager));
93 this._assetCacheThread.IsBackground = true;
94 this._assetCacheThread.Start();
95 }
96
97 public void AddAsset(AssetBase asset)
98 {
99 if (asset.Type == 0)
100 {
101 if (!this.Textures.ContainsKey(asset.FullID))
102 {
103 TextureImage image = new TextureImage(asset);
104 this.Textures.Add(image.FullID, image);
105 this._assetServer.UploadNewAsset(asset);
106 }
107 }
108 else if (!this.Assets.ContainsKey(asset.FullID))
109 {
110 AssetInfo info = new AssetInfo(asset);
111 this.Assets.Add(info.FullID, info);
112 this._assetServer.UploadNewAsset(asset);
113 }
114 }
115
116 public void AddAssetRequest(IClientAPI userInfo, TransferRequestPacket transferRequest)
117 {
118 LLUUID assetID = new LLUUID(transferRequest.TransferInfo.Params, 0);
119 if (!this.Assets.ContainsKey(assetID))
120 {
121 if (!this.RequestedAssets.ContainsKey(assetID))
122 {
123 AssetRequest request = new AssetRequest();
124 request.RequestUser = userInfo;
125 request.RequestAssetID = assetID;
126 request.TransferRequestID = transferRequest.TransferInfo.TransferID;
127 this.RequestedAssets.Add(assetID, request);
128 this._assetServer.RequestAsset(assetID, false);
129 }
130 }
131 else
132 {
133 AssetInfo info = this.Assets[assetID];
134 AssetRequest request2 = new AssetRequest();
135 request2.RequestUser = userInfo;
136 request2.RequestAssetID = assetID;
137 request2.TransferRequestID = transferRequest.TransferInfo.TransferID;
138 request2.AssetInf = info;
139 if (info.Data.LongLength > 600)
140 {
141 request2.NumPackets = 1 + (((info.Data.Length - 600) + 0x3e7) / 0x3e8);
142 }
143 else
144 {
145 request2.NumPackets = 1;
146 }
147 this.AssetRequests.Add(request2);
148 }
149 }
150
151 public void AddTextureRequest(IClientAPI userInfo, LLUUID imageID)
152 {
153 if (!this.Textures.ContainsKey(imageID))
154 {
155 if (!this.RequestedTextures.ContainsKey(imageID))
156 {
157 AssetRequest request = new AssetRequest();
158 request.RequestUser = userInfo;
159 request.RequestAssetID = imageID;
160 request.IsTextureRequest = true;
161 this.RequestedTextures.Add(imageID, request);
162 this._assetServer.RequestAsset(imageID, true);
163 }
164 }
165 else
166 {
167 TextureImage image = this.Textures[imageID];
168 AssetRequest request2 = new AssetRequest();
169 request2.RequestUser = userInfo;
170 request2.RequestAssetID = imageID;
171 request2.IsTextureRequest = true;
172 request2.ImageInfo = image;
173 if (image.Data.LongLength > 600)
174 {
175 request2.NumPackets = 1 + (((image.Data.Length - 600) + 0x3e7) / 0x3e8);
176 }
177 else
178 {
179 request2.NumPackets = 1;
180 }
181 this.TextureRequests.Add(request2);
182 }
183 }
184
185 public void AssetNotFound(AssetBase asset)
186 {
187 }
188
189 public void AssetReceived(AssetBase asset, bool IsTexture)
190 {
191 if (asset.FullID != LLUUID.Zero)
192 {
193 if (IsTexture)
194 {
195 TextureImage image = new TextureImage(asset);
196 this.Textures.Add(image.FullID, image);
197 if (this.RequestedTextures.ContainsKey(image.FullID))
198 {
199 AssetRequest request = this.RequestedTextures[image.FullID];
200 request.ImageInfo = image;
201 if (image.Data.LongLength > 600)
202 {
203 request.NumPackets = 1 + (((image.Data.Length - 600) + 0x3e7) / 0x3e8);
204 }
205 else
206 {
207 request.NumPackets = 1;
208 }
209 this.RequestedTextures.Remove(image.FullID);
210 this.TextureRequests.Add(request);
211 }
212 }
213 else
214 {
215 AssetInfo info = new AssetInfo(asset);
216 this.Assets.Add(info.FullID, info);
217 if (this.RequestedAssets.ContainsKey(info.FullID))
218 {
219 AssetRequest request2 = this.RequestedAssets[info.FullID];
220 request2.AssetInf = info;
221 if (info.Data.LongLength > 600)
222 {
223 request2.NumPackets = 1 + (((info.Data.Length - 600) + 0x3e7) / 0x3e8);
224 }
225 else
226 {
227 request2.NumPackets = 1;
228 }
229 this.RequestedAssets.Remove(info.FullID);
230 this.AssetRequests.Add(request2);
231 }
232 }
233 }
234 }
235
236 public AssetInfo CloneAsset(LLUUID newOwner, AssetInfo sourceAsset)
237 {
238 AssetInfo info = new AssetInfo();
239 info.Data = new byte[sourceAsset.Data.Length];
240 Array.Copy(sourceAsset.Data, info.Data, sourceAsset.Data.Length);
241 info.FullID = LLUUID.Random();
242 info.Type = sourceAsset.Type;
243 info.InvType = sourceAsset.InvType;
244 return info;
245 }
246
247 public TextureImage CloneImage(LLUUID newOwner, TextureImage source)
248 {
249 TextureImage image = new TextureImage();
250 image.Data = new byte[source.Data.Length];
251 Array.Copy(source.Data, image.Data, source.Data.Length);
252 image.FullID = LLUUID.Random();
253 image.Name = source.Name;
254 return image;
255 }
256
257 public AssetBase[] CreateNewInventorySet(LLUUID agentID)
258 {
259 AssetBase[] baseArray = new AssetBase[this.textureList.Length];
260 for (int i = 0; i < this.textureList.Length; i++)
261 {
262 if (this.Textures.ContainsKey(this.textureList[i]))
263 {
264 baseArray[i] = this.CloneImage(agentID, this.Textures[this.textureList[i]]);
265 TextureImage asset = new TextureImage(baseArray[i]);
266 this.Textures.Add(asset.FullID, asset);
267 this._assetServer.UploadNewAsset(asset);
268 }
269 }
270 return baseArray;
271 }
272
273 public AssetBase GetAsset(LLUUID assetID)
274 {
275 AssetBase base2 = null;
276 if (this.Textures.ContainsKey(assetID))
277 {
278 return this.Textures[assetID];
279 }
280 if (this.Assets.ContainsKey(assetID))
281 {
282 base2 = this.Assets[assetID];
283 }
284 return base2;
285 }
286
287 private IAssetServer LoadAssetDll(string dllName)
288 {
289 Assembly assembly = Assembly.LoadFrom(dllName);
290 IAssetServer assetServer = null;
291 foreach (Type type in assembly.GetTypes())
292 {
293 if (type.IsPublic && !type.IsAbstract)
294 {
295 if (type.GetInterface("IAssetPlugin", true) != null)
296 {
297 assetServer = ((IAssetPlugin)Activator.CreateInstance(assembly.GetType(type.ToString()))).GetAssetServer();
298 break;
299 }
300 }
301 }
302 assembly = null;
303 return assetServer;
304 }
305
306 public void LoadDefaultTextureSet()
307 {
308 this.textureList[0] = new LLUUID("00000000-0000-0000-9999-000000000001");
309 this.textureList[1] = new LLUUID("00000000-0000-0000-9999-000000000002");
310 this.textureList[2] = new LLUUID("00000000-0000-0000-9999-000000000003");
311 this.textureList[3] = new LLUUID("00000000-0000-0000-9999-000000000004");
312 this.textureList[4] = new LLUUID("00000000-0000-0000-9999-000000000005");
313 for (int i = 0; i < this.textureList.Length; i++)
314 {
315 this._assetServer.RequestAsset(this.textureList[i], true);
316 }
317 }
318
319 private void ProcessAssetQueue()
320 {
321 if (this.AssetRequests.Count != 0)
322 {
323 int num;
324 if (this.AssetRequests.Count < 5)
325 {
326 num = this.AssetRequests.Count;
327 }
328 else
329 {
330 num = 5;
331 }
332 for (int i = 0; i < num; i++)
333 {
334 AssetRequest request = this.AssetRequests[i];
335 TransferInfoPacket newPack = new TransferInfoPacket();
336 newPack.TransferInfo.ChannelType = 2;
337 newPack.TransferInfo.Status = 0;
338 newPack.TransferInfo.TargetType = 0;
339 newPack.TransferInfo.Params = request.RequestAssetID.GetBytes();
340 newPack.TransferInfo.Size = request.AssetInf.Data.Length;
341 newPack.TransferInfo.TransferID = request.TransferRequestID;
342 request.RequestUser.OutPacket(newPack);
343 if (request.NumPackets == 1)
344 {
345 TransferPacketPacket packet2 = new TransferPacketPacket();
346 packet2.TransferData.Packet = 0;
347 packet2.TransferData.ChannelType = 2;
348 packet2.TransferData.TransferID = request.TransferRequestID;
349 packet2.TransferData.Data = request.AssetInf.Data;
350 packet2.TransferData.Status = 1;
351 request.RequestUser.OutPacket(packet2);
352 }
353 else
354 {
355 TransferPacketPacket packet3 = new TransferPacketPacket();
356 packet3.TransferData.Packet = 0;
357 packet3.TransferData.ChannelType = 2;
358 packet3.TransferData.TransferID = request.TransferRequestID;
359 byte[] destinationArray = new byte[0x3e8];
360 Array.Copy(request.AssetInf.Data, destinationArray, 0x3e8);
361 packet3.TransferData.Data = destinationArray;
362 packet3.TransferData.Status = 0;
363 request.RequestUser.OutPacket(packet3);
364 packet3 = new TransferPacketPacket();
365 packet3.TransferData.Packet = 1;
366 packet3.TransferData.ChannelType = 2;
367 packet3.TransferData.TransferID = request.TransferRequestID;
368 byte[] buffer2 = new byte[request.AssetInf.Data.Length - 0x3e8];
369 Array.Copy(request.AssetInf.Data, 0x3e8, buffer2, 0, buffer2.Length);
370 packet3.TransferData.Data = buffer2;
371 packet3.TransferData.Status = 1;
372 request.RequestUser.OutPacket(packet3);
373 }
374 }
375 for (int j = 0; j < num; j++)
376 {
377 this.AssetRequests.RemoveAt(0);
378 }
379 }
380 }
381
382 private void ProcessTextureQueue()
383 {
384 if (this.TextureRequests.Count != 0)
385 {
386 int num = this.TextureRequests.Count;
387 for (int i = 0; i < num; i++)
388 {
389 AssetRequest req = this.TextureRequests[i];
390 if (!this.SendingTextures.ContainsKey(req.ImageInfo.FullID))
391 {
392 TextureSender sender = new TextureSender(req);
393 sender.OnComplete += new DownloadComplete(this.TextureSent);
394 lock (this.SendingTextures)
395 {
396 this.SendingTextures.Add(req.ImageInfo.FullID, sender);
397 }
398 }
399 }
400 this.TextureRequests.Clear();
401 }
402 }
403
404 public void RunAssetManager()
405 {
406 Label_0000:
407 try
408 {
409 this.ProcessAssetQueue();
410 this.ProcessTextureQueue();
411 Thread.Sleep(500);
412 goto Label_0000;
413 }
414 catch (Exception exception)
415 {
416 Console.WriteLine(exception.Message);
417 goto Label_0000;
418 }
419 }
420
421 public void TextureSent(TextureSender sender)
422 {
423 if (this.SendingTextures.ContainsKey(sender.request.ImageInfo.FullID))
424 {
425 lock (this.SendingTextures)
426 {
427 this.SendingTextures.Remove(sender.request.ImageInfo.FullID);
428 }
429 }
430 }
431
432 // Nested Types
433 public class AssetInfo : AssetBase
434 {
435 // Methods
436 public AssetInfo()
437 {
438 }
439
440 public AssetInfo(AssetBase aBase)
441 {
442 base.Data = aBase.Data;
443 base.FullID = aBase.FullID;
444 base.Type = aBase.Type;
445 base.InvType = aBase.InvType;
446 base.Name = aBase.Name;
447 base.Description = aBase.Description;
448 }
449 }
450
451 public class AssetRequest
452 {
453 // Fields
454 public AssetCache.AssetInfo AssetInf;
455 public long DataPointer;
456 public AssetCache.TextureImage ImageInfo;
457 public bool IsTextureRequest;
458 public int NumPackets;
459 public int PacketCounter;
460 public LLUUID RequestAssetID;
461 public IClientAPI RequestUser;
462 public LLUUID TransferRequestID;
463 }
464
465 public class TextureImage : AssetBase
466 {
467 // Methods
468 public TextureImage()
469 {
470 }
471
472 public TextureImage(AssetBase aBase)
473 {
474 base.Data = aBase.Data;
475 base.FullID = aBase.FullID;
476 base.Type = aBase.Type;
477 base.InvType = aBase.InvType;
478 base.Name = aBase.Name;
479 base.Description = aBase.Description;
480 }
481 }
482
483 public class TextureSender
484 {
485 // Fields
486 private Thread m_thread;
487 public AssetCache.AssetRequest request;
488
489 // Events
490 public event DownloadComplete OnComplete;
491
492 // Methods
493 public TextureSender(AssetCache.AssetRequest req)
494 {
495 this.request = req;
496 this.m_thread = new Thread(new ThreadStart(this.SendTexture));
497 this.m_thread.IsBackground = true;
498 this.m_thread.Start();
499 }
500
501 public void SendPacket()
502 {
503 AssetCache.AssetRequest request = this.request;
504 if (request.PacketCounter == 0)
505 {
506 if (request.NumPackets == 1)
507 {
508 ImageDataPacket newPack = new ImageDataPacket();
509 newPack.ImageID.Packets = 1;
510 newPack.ImageID.ID = request.ImageInfo.FullID;
511 newPack.ImageID.Size = (uint)request.ImageInfo.Data.Length;
512 newPack.ImageData.Data = request.ImageInfo.Data;
513 newPack.ImageID.Codec = 2;
514 request.RequestUser.OutPacket(newPack);
515 request.PacketCounter++;
516 }
517 else
518 {
519 ImageDataPacket packet2 = new ImageDataPacket();
520 packet2.ImageID.Packets = (ushort)request.NumPackets;
521 packet2.ImageID.ID = request.ImageInfo.FullID;
522 packet2.ImageID.Size = (uint)request.ImageInfo.Data.Length;
523 packet2.ImageData.Data = new byte[600];
524 Array.Copy(request.ImageInfo.Data, 0, packet2.ImageData.Data, 0, 600);
525 packet2.ImageID.Codec = 2;
526 request.RequestUser.OutPacket(packet2);
527 request.PacketCounter++;
528 }
529 }
530 else
531 {
532 ImagePacketPacket packet3 = new ImagePacketPacket();
533 packet3.ImageID.Packet = (ushort)request.PacketCounter;
534 packet3.ImageID.ID = request.ImageInfo.FullID;
535 int length = (request.ImageInfo.Data.Length - 600) - (0x3e8 * (request.PacketCounter - 1));
536 if (length > 0x3e8)
537 {
538 length = 0x3e8;
539 }
540 packet3.ImageData.Data = new byte[length];
541 Array.Copy(request.ImageInfo.Data, 600 + (0x3e8 * (request.PacketCounter - 1)), packet3.ImageData.Data, 0, length);
542 request.RequestUser.OutPacket(packet3);
543 request.PacketCounter++;
544 }
545 }
546
547 public void SendTexture()
548 {
549 while (this.request.PacketCounter != this.request.NumPackets)
550 {
551 this.SendPacket();
552 Thread.Sleep(500);
553 }
554 if (this.OnComplete != null)
555 {
556 this.OnComplete(this);
557 }
558 }
559 }
560 }
561}