aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/OpenSim.RegionServer/Assets/AssetCache.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/OpenSim.RegionServer/Assets/AssetCache.cs')
-rw-r--r--OpenSim/OpenSim.RegionServer/Assets/AssetCache.cs572
1 files changed, 0 insertions, 572 deletions
diff --git a/OpenSim/OpenSim.RegionServer/Assets/AssetCache.cs b/OpenSim/OpenSim.RegionServer/Assets/AssetCache.cs
deleted file mode 100644
index 466f9f9..0000000
--- a/OpenSim/OpenSim.RegionServer/Assets/AssetCache.cs
+++ /dev/null
@@ -1,572 +0,0 @@
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*/
28
29using System;
30using System.Collections.Generic;
31using System.Threading;
32using libsecondlife;
33using libsecondlife.Packets;
34using OpenSim.Framework.Interfaces;
35using OpenSim.Framework.Types;
36using OpenSim.Framework.Utilities;
37using OpenSim.Framework.Console;
38using OpenSim.RegionServer.Client;
39
40namespace OpenSim.RegionServer.Assets
41{
42 /// <summary>
43 /// Manages local cache of assets and their sending to viewers.
44 /// </summary>
45 public class AssetCache : IAssetReceiver
46 {
47 public Dictionary<libsecondlife.LLUUID, AssetInfo> Assets;
48 public Dictionary<libsecondlife.LLUUID, TextureImage> Textures;
49
50 public List<AssetRequest> AssetRequests = new List<AssetRequest>(); //assets ready to be sent to viewers
51 public List<AssetRequest> TextureRequests = new List<AssetRequest>(); //textures ready to be sent
52
53 public Dictionary<LLUUID, AssetRequest> RequestedAssets = new Dictionary<LLUUID, AssetRequest>(); //Assets requested from the asset server
54 public Dictionary<LLUUID, AssetRequest> RequestedTextures = new Dictionary<LLUUID, AssetRequest>(); //Textures requested from the asset server
55
56 private IAssetServer _assetServer;
57 private Thread _assetCacheThread;
58 private LLUUID[] textureList = new LLUUID[5];
59
60 /// <summary>
61 ///
62 /// </summary>
63 public AssetCache(IAssetServer assetServer)
64 {
65 MainConsole.Instance.Verbose("Creating Asset cache");
66 _assetServer = assetServer;
67 _assetServer.SetReceiver(this);
68 Assets = new Dictionary<libsecondlife.LLUUID, AssetInfo>();
69 Textures = new Dictionary<libsecondlife.LLUUID, TextureImage>();
70 this._assetCacheThread = new Thread(new ThreadStart(RunAssetManager));
71 this._assetCacheThread.IsBackground = true;
72 this._assetCacheThread.Start();
73
74 }
75
76 /// <summary>
77 ///
78 /// </summary>
79 public void RunAssetManager()
80 {
81 while (true)
82 {
83 try
84 {
85 this.ProcessAssetQueue();
86 this.ProcessTextureQueue();
87 Thread.Sleep(500);
88 }
89 catch (Exception e)
90 {
91 MainConsole.Instance.Error(e.Message);
92 }
93 }
94 }
95
96 public void LoadDefaultTextureSet()
97 {
98 //hack: so we can give each user a set of textures
99 textureList[0] = new LLUUID("00000000-0000-0000-9999-000000000001");
100 textureList[1] = new LLUUID("00000000-0000-0000-9999-000000000002");
101 textureList[2] = new LLUUID("00000000-0000-0000-9999-000000000003");
102 textureList[3] = new LLUUID("00000000-0000-0000-9999-000000000004");
103 textureList[4] = new LLUUID("00000000-0000-0000-9999-000000000005");
104
105 for (int i = 0; i < textureList.Length; i++)
106 {
107 this._assetServer.RequestAsset(textureList[i], true);
108 }
109
110 }
111
112 public AssetBase[] CreateNewInventorySet(LLUUID agentID)
113 {
114 AssetBase[] inventorySet = new AssetBase[this.textureList.Length];
115 for (int i = 0; i < textureList.Length; i++)
116 {
117 if (this.Textures.ContainsKey(textureList[i]))
118 {
119 inventorySet[i] = this.CloneImage(agentID, this.Textures[textureList[i]]);
120 TextureImage image = new TextureImage(inventorySet[i]);
121 this.Textures.Add(image.FullID, image);
122 this._assetServer.UploadNewAsset(image); //save the asset to the asset server
123 }
124 }
125 return inventorySet;
126 }
127
128 public AssetBase GetAsset(LLUUID assetID)
129 {
130 AssetBase asset = null;
131 if(this.Textures.ContainsKey(assetID))
132 {
133 asset = this.Textures[assetID];
134 }
135 else if (this.Assets.ContainsKey(assetID))
136 {
137 asset = this.Assets[assetID];
138 }
139 return asset;
140 }
141
142 public void AddAsset(AssetBase asset)
143 {
144 if (asset.Type == 0)
145 {
146 if (!this.Textures.ContainsKey(asset.FullID))
147 { //texture
148 TextureImage textur = new TextureImage(asset);
149 this.Textures.Add(textur.FullID, textur);
150 this._assetServer.UploadNewAsset(asset);
151 }
152 }
153 else
154 {
155 if (!this.Assets.ContainsKey(asset.FullID))
156 {
157 AssetInfo assetInf = new AssetInfo(asset);
158 this.Assets.Add(assetInf.FullID, assetInf);
159 this._assetServer.UploadNewAsset(asset);
160 }
161 }
162 }
163
164 /// <summary>
165 ///
166 /// </summary>
167 private void ProcessTextureQueue()
168 {
169 if (this.TextureRequests.Count == 0)
170 {
171 //no requests waiting
172 return;
173 }
174 int num;
175
176 if (this.TextureRequests.Count < 5)
177 {
178 //lower than 5 so do all of them
179 num = this.TextureRequests.Count;
180 }
181 else
182 {
183 num = 5;
184 }
185 AssetRequest req;
186 for (int i = 0; i < num; i++)
187 {
188 req = (AssetRequest)this.TextureRequests[i];
189 if (req.PacketCounter != req.NumPackets)
190 {
191 // if (req.ImageInfo.FullID == new LLUUID("00000000-0000-0000-5005-000000000005"))
192 if (req.PacketCounter == 0)
193 {
194 //first time for this request so send imagedata packet
195 if (req.NumPackets == 1)
196 {
197 //only one packet so send whole file
198 ImageDataPacket im = new ImageDataPacket();
199 im.ImageID.Packets = 1;
200 im.ImageID.ID = req.ImageInfo.FullID;
201 im.ImageID.Size = (uint)req.ImageInfo.Data.Length;
202 im.ImageData.Data = req.ImageInfo.Data;
203 im.ImageID.Codec = 2;
204 req.RequestUser.OutPacket(im);
205 req.PacketCounter++;
206 //req.ImageInfo.l= time;
207 }
208 else
209 {
210 //more than one packet so split file up
211 ImageDataPacket im = new ImageDataPacket();
212 im.ImageID.Packets = (ushort)req.NumPackets;
213 im.ImageID.ID = req.ImageInfo.FullID;
214 im.ImageID.Size = (uint)req.ImageInfo.Data.Length;
215 im.ImageData.Data = new byte[600];
216 Array.Copy(req.ImageInfo.Data, 0, im.ImageData.Data, 0, 600);
217 im.ImageID.Codec = 2;
218 req.RequestUser.OutPacket(im);
219 req.PacketCounter++;
220 //req.ImageInfo.last_used = time;
221 }
222 }
223 else
224 {
225 //send imagepacket
226 //more than one packet so split file up
227 ImagePacketPacket im = new ImagePacketPacket();
228 im.ImageID.Packet = (ushort)req.PacketCounter;
229 im.ImageID.ID = req.ImageInfo.FullID;
230 int size = req.ImageInfo.Data.Length - 600 - 1000 * (req.PacketCounter - 1);
231 if (size > 1000) size = 1000;
232 im.ImageData.Data = new byte[size];
233 Array.Copy(req.ImageInfo.Data, 600 + 1000 * (req.PacketCounter - 1), im.ImageData.Data, 0, size);
234 req.RequestUser.OutPacket(im);
235 req.PacketCounter++;
236 //req.ImageInfo.last_used = time;
237 }
238 }
239 }
240
241 //remove requests that have been completed
242 int count = 0;
243 for (int i = 0; i < num; i++)
244 {
245 if (this.TextureRequests.Count > count)
246 {
247 req = (AssetRequest)this.TextureRequests[count];
248 if (req.PacketCounter == req.NumPackets)
249 {
250 this.TextureRequests.Remove(req);
251 }
252 else
253 {
254 count++;
255 }
256 }
257 }
258
259 }
260 public void AssetReceived(AssetBase asset, bool IsTexture)
261 {
262 if (asset.FullID != LLUUID.Zero) // if it is set to zero then the asset wasn't found by the server
263 {
264 //check if it is a texture or not
265 //then add to the correct cache list
266 //then check for waiting requests for this asset/texture (in the Requested lists)
267 //and move those requests into the Requests list.
268 if (IsTexture)
269 {
270 TextureImage image = new TextureImage(asset);
271 this.Textures.Add(image.FullID, image);
272 if (this.RequestedTextures.ContainsKey(image.FullID))
273 {
274 AssetRequest req = this.RequestedTextures[image.FullID];
275 req.ImageInfo = image;
276 if (image.Data.LongLength > 600)
277 {
278 //over 600 bytes so split up file
279 req.NumPackets = 1 + (int)(image.Data.Length - 600 + 999) / 1000;
280 }
281 else
282 {
283 req.NumPackets = 1;
284 }
285 this.RequestedTextures.Remove(image.FullID);
286 this.TextureRequests.Add(req);
287 }
288 }
289 else
290 {
291 AssetInfo assetInf = new AssetInfo(asset);
292 this.Assets.Add(assetInf.FullID, assetInf);
293 if (this.RequestedAssets.ContainsKey(assetInf.FullID))
294 {
295 AssetRequest req = this.RequestedAssets[assetInf.FullID];
296 req.AssetInf = assetInf;
297 if (assetInf.Data.LongLength > 600)
298 {
299 //over 600 bytes so split up file
300 req.NumPackets = 1 + (int)(assetInf.Data.Length - 600 + 999) / 1000;
301 }
302 else
303 {
304 req.NumPackets = 1;
305 }
306 this.RequestedAssets.Remove(assetInf.FullID);
307 this.AssetRequests.Add(req);
308 }
309 }
310 }
311 }
312
313 public void AssetNotFound(AssetBase asset)
314 {
315 //the asset server had no knowledge of requested asset
316
317 }
318
319 #region Assets
320 /// <summary>
321 ///
322 /// </summary>
323 /// <param name="userInfo"></param>
324 /// <param name="transferRequest"></param>
325 public void AddAssetRequest(ClientView userInfo, TransferRequestPacket transferRequest)
326 {
327 LLUUID requestID = new LLUUID(transferRequest.TransferInfo.Params, 0);
328 //check to see if asset is in local cache, if not we need to request it from asset server.
329 if (!this.Assets.ContainsKey(requestID))
330 {
331 //not found asset
332 // so request from asset server
333 if (!this.RequestedAssets.ContainsKey(requestID))
334 {
335 AssetRequest request = new AssetRequest();
336 request.RequestUser = userInfo;
337 request.RequestAssetID = requestID;
338 request.TransferRequestID = transferRequest.TransferInfo.TransferID;
339 this.RequestedAssets.Add(requestID, request);
340 this._assetServer.RequestAsset(requestID, false);
341 }
342 return;
343 }
344 //it is in our cache
345 AssetInfo asset = this.Assets[requestID];
346
347 //work out how many packets it should be sent in
348 // and add to the AssetRequests list
349 AssetRequest req = new AssetRequest();
350 req.RequestUser = userInfo;
351 req.RequestAssetID = requestID;
352 req.TransferRequestID = transferRequest.TransferInfo.TransferID;
353 req.AssetInf = asset;
354
355 if (asset.Data.LongLength > 600)
356 {
357 //over 600 bytes so split up file
358 req.NumPackets = 1 + (int)(asset.Data.Length - 600 + 999) / 1000;
359 }
360 else
361 {
362 req.NumPackets = 1;
363 }
364
365 this.AssetRequests.Add(req);
366 }
367
368 /// <summary>
369 ///
370 /// </summary>
371 private void ProcessAssetQueue()
372 {
373 if (this.AssetRequests.Count == 0)
374 {
375 //no requests waiting
376 return;
377 }
378 int num;
379
380 if (this.AssetRequests.Count < 5)
381 {
382 //lower than 5 so do all of them
383 num = this.AssetRequests.Count;
384 }
385 else
386 {
387 num = 5;
388 }
389 AssetRequest req;
390 for (int i = 0; i < num; i++)
391 {
392 req = (AssetRequest)this.AssetRequests[i];
393
394 TransferInfoPacket Transfer = new TransferInfoPacket();
395 Transfer.TransferInfo.ChannelType = 2;
396 Transfer.TransferInfo.Status = 0;
397 Transfer.TransferInfo.TargetType = 0;
398 Transfer.TransferInfo.Params = req.RequestAssetID.GetBytes();
399 Transfer.TransferInfo.Size = (int)req.AssetInf.Data.Length;
400 Transfer.TransferInfo.TransferID = req.TransferRequestID;
401 req.RequestUser.OutPacket(Transfer);
402
403 if (req.NumPackets == 1)
404 {
405 TransferPacketPacket TransferPacket = new TransferPacketPacket();
406 TransferPacket.TransferData.Packet = 0;
407 TransferPacket.TransferData.ChannelType = 2;
408 TransferPacket.TransferData.TransferID = req.TransferRequestID;
409 TransferPacket.TransferData.Data = req.AssetInf.Data;
410 TransferPacket.TransferData.Status = 1;
411 req.RequestUser.OutPacket(TransferPacket);
412 }
413 else
414 {
415 //more than one packet so split file up , for now it can't be bigger than 2000 bytes
416 TransferPacketPacket TransferPacket = new TransferPacketPacket();
417 TransferPacket.TransferData.Packet = 0;
418 TransferPacket.TransferData.ChannelType = 2;
419 TransferPacket.TransferData.TransferID = req.TransferRequestID;
420 byte[] chunk = new byte[1000];
421 Array.Copy(req.AssetInf.Data, chunk, 1000);
422 TransferPacket.TransferData.Data = chunk;
423 TransferPacket.TransferData.Status = 0;
424 req.RequestUser.OutPacket(TransferPacket);
425
426 TransferPacket = new TransferPacketPacket();
427 TransferPacket.TransferData.Packet = 1;
428 TransferPacket.TransferData.ChannelType = 2;
429 TransferPacket.TransferData.TransferID = req.TransferRequestID;
430 byte[] chunk1 = new byte[(req.AssetInf.Data.Length - 1000)];
431 Array.Copy(req.AssetInf.Data, 1000, chunk1, 0, chunk1.Length);
432 TransferPacket.TransferData.Data = chunk1;
433 TransferPacket.TransferData.Status = 1;
434 req.RequestUser.OutPacket(TransferPacket);
435 }
436
437 }
438
439 //remove requests that have been completed
440 for (int i = 0; i < num; i++)
441 {
442 this.AssetRequests.RemoveAt(0);
443 }
444
445 }
446
447 public AssetInfo CloneAsset(LLUUID newOwner, AssetInfo sourceAsset)
448 {
449 AssetInfo newAsset = new AssetInfo();
450 newAsset.Data = new byte[sourceAsset.Data.Length];
451 Array.Copy(sourceAsset.Data, newAsset.Data, sourceAsset.Data.Length);
452 newAsset.FullID = LLUUID.Random();
453 newAsset.Type = sourceAsset.Type;
454 newAsset.InvType = sourceAsset.InvType;
455 return (newAsset);
456 }
457 #endregion
458
459 #region Textures
460 /// <summary>
461 ///
462 /// </summary>
463 /// <param name="userInfo"></param>
464 /// <param name="imageID"></param>
465 public void AddTextureRequest(ClientView userInfo, LLUUID imageID)
466 {
467 //check to see if texture is in local cache, if not request from asset server
468 if (!this.Textures.ContainsKey(imageID))
469 {
470 if (!this.RequestedTextures.ContainsKey(imageID))
471 {
472 //not is cache so request from asset server
473 AssetRequest request = new AssetRequest();
474 request.RequestUser = userInfo;
475 request.RequestAssetID = imageID;
476 request.IsTextureRequest = true;
477 this.RequestedTextures.Add(imageID, request);
478 this._assetServer.RequestAsset(imageID, true);
479 }
480 return;
481 }
482
483 TextureImage imag = this.Textures[imageID];
484 AssetRequest req = new AssetRequest();
485 req.RequestUser = userInfo;
486 req.RequestAssetID = imageID;
487 req.IsTextureRequest = true;
488 req.ImageInfo = imag;
489
490 if (imag.Data.LongLength > 600)
491 {
492 //over 600 bytes so split up file
493 req.NumPackets = 1 + (int)(imag.Data.Length - 600 + 999) / 1000;
494 }
495 else
496 {
497 req.NumPackets = 1;
498 }
499 this.TextureRequests.Add(req);
500 }
501
502 public TextureImage CloneImage(LLUUID newOwner, TextureImage source)
503 {
504 TextureImage newImage = new TextureImage();
505 newImage.Data = new byte[source.Data.Length];
506 Array.Copy(source.Data, newImage.Data, source.Data.Length);
507 //newImage.filename = source.filename;
508 newImage.FullID = LLUUID.Random();
509 newImage.Name = source.Name;
510 return (newImage);
511 }
512 #endregion
513
514 }
515
516 public class AssetRequest
517 {
518 public ClientView RequestUser;
519 public LLUUID RequestAssetID;
520 public AssetInfo AssetInf;
521 public TextureImage ImageInfo;
522 public LLUUID TransferRequestID;
523 public long DataPointer = 0;
524 public int NumPackets = 0;
525 public int PacketCounter = 0;
526 public bool IsTextureRequest;
527 //public bool AssetInCache;
528 //public int TimeRequested;
529
530 public AssetRequest()
531 {
532
533 }
534 }
535
536 public class AssetInfo : AssetBase
537 {
538 public AssetInfo()
539 {
540
541 }
542
543 public AssetInfo(AssetBase aBase)
544 {
545 Data = aBase.Data;
546 FullID = aBase.FullID;
547 Type = aBase.Type;
548 InvType = aBase.InvType;
549 Name = aBase.Name;
550 Description = aBase.Description;
551 }
552 }
553
554 public class TextureImage : AssetBase
555 {
556 public TextureImage()
557 {
558
559 }
560
561 public TextureImage(AssetBase aBase)
562 {
563 Data = aBase.Data;
564 FullID = aBase.FullID;
565 Type = aBase.Type;
566 InvType = aBase.InvType;
567 Name = aBase.Name;
568 Description = aBase.Description;
569 }
570 }
571
572}