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.cs794
1 files changed, 457 insertions, 337 deletions
diff --git a/OpenSim/Framework/Communications/Cache/AssetCache.cs b/OpenSim/Framework/Communications/Cache/AssetCache.cs
index a3480ec..32ba830 100644
--- a/OpenSim/Framework/Communications/Cache/AssetCache.cs
+++ b/OpenSim/Framework/Communications/Cache/AssetCache.cs
@@ -25,537 +25,657 @@
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26* 26*
27*/ 27*/
28
28using System; 29using System;
29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Text;
32using System.Reflection; 31using System.Reflection;
33using System.Threading; 32using System.Threading;
34using libsecondlife; 33using libsecondlife;
35using libsecondlife.Packets; 34using libsecondlife.Packets;
36using OpenSim.Framework.Interfaces; 35using OpenSim.Framework.Interfaces;
37using OpenSim.Framework.Servers;
38using OpenSim.Framework.Types; 36using OpenSim.Framework.Types;
39using OpenSim.Framework.Utilities;
40 37
41namespace OpenSim.Framework.Communications.Caches 38namespace OpenSim.Framework.Communications.Caches
42{ 39{
43 public delegate void DownloadComplete(AssetCache.TextureSender sender); 40 public delegate void DownloadComplete(AssetCache.TextureSender sender);
44 41
42 /// <summary>
43 /// Manages local cache of assets and their sending to viewers.
44 /// </summary>
45 public class AssetCache : IAssetReceiver 45 public class AssetCache : IAssetReceiver
46 { 46 {
47 // Fields
48 private Thread _assetCacheThread;
49 private IAssetServer _assetServer;
50 public List<AssetRequest> AssetRequests;
51 public Dictionary<LLUUID, AssetInfo> Assets; 47 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; 48 public Dictionary<LLUUID, TextureImage> Textures;
58 49
59 // Methods 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 public Dictionary<LLUUID, TextureSender> SendingTextures = new Dictionary<LLUUID, TextureSender>();
57 private IAssetServer _assetServer;
58 private Thread _assetCacheThread;
59
60 /// <summary>
61 ///
62 /// </summary>
60 public AssetCache(IAssetServer assetServer) 63 public AssetCache(IAssetServer assetServer)
61 { 64 {
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"); 65 Console.WriteLine("Creating Asset cache");
69 this._assetServer = assetServer; 66 _assetServer = assetServer;
70 this._assetServer.SetReceiver(this); 67 _assetServer.SetReceiver(this);
71 this.Assets = new Dictionary<LLUUID, AssetInfo>(); 68 Assets = new Dictionary<LLUUID, AssetInfo>();
72 this.Textures = new Dictionary<LLUUID, TextureImage>(); 69 Textures = new Dictionary<LLUUID, TextureImage>();
73 this._assetCacheThread = new Thread(new ThreadStart(this.RunAssetManager)); 70 this._assetCacheThread = new Thread(new ThreadStart(RunAssetManager));
74 this._assetCacheThread.IsBackground = true; 71 this._assetCacheThread.IsBackground = true;
75 this._assetCacheThread.Start(); 72 this._assetCacheThread.Start();
73
76 } 74 }
77 75
78 public AssetCache(string assetServerDLLName, string assetServerURL, string assetServerKey) 76 public AssetCache(string assetServerDLLName, string assetServerURL, string assetServerKey)
79 { 77 {
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"); 78 Console.WriteLine("Creating Asset cache");
87 this._assetServer = this.LoadAssetDll(assetServerDLLName); 79 _assetServer = this.LoadAssetDll(assetServerDLLName);
88 this._assetServer.SetServerInfo(assetServerURL, assetServerKey); 80 _assetServer.SetServerInfo(assetServerURL, assetServerKey);
89 this._assetServer.SetReceiver(this); 81 _assetServer.SetReceiver(this);
90 this.Assets = new Dictionary<LLUUID, AssetInfo>(); 82 Assets = new Dictionary<LLUUID, AssetInfo>();
91 this.Textures = new Dictionary<LLUUID, TextureImage>(); 83 Textures = new Dictionary<LLUUID, TextureImage>();
92 this._assetCacheThread = new Thread(new ThreadStart(this.RunAssetManager)); 84 this._assetCacheThread = new Thread(new ThreadStart(RunAssetManager));
93 this._assetCacheThread.IsBackground = true; 85 this._assetCacheThread.IsBackground = true;
94 this._assetCacheThread.Start(); 86 this._assetCacheThread.Start();
87
95 } 88 }
96 89
97 public void AddAsset(AssetBase asset) 90 /// <summary>
91 ///
92 /// </summary>
93 public void RunAssetManager()
98 { 94 {
99 if (asset.Type == 0) 95 while (true)
100 { 96 {
101 if (!this.Textures.ContainsKey(asset.FullID)) 97 try
102 { 98 {
103 TextureImage image = new TextureImage(asset); 99 this.ProcessAssetQueue();
104 this.Textures.Add(image.FullID, image); 100 this.ProcessTextureQueue();
105 this._assetServer.UploadNewAsset(asset); 101 Thread.Sleep(500);
102 }
103 catch (Exception e)
104 {
105 Console.WriteLine(e.Message + " : " + e.StackTrace);
106 } 106 }
107 } 107 }
108 else if (!this.Assets.ContainsKey(asset.FullID)) 108 }
109
110
111 public AssetBase GetAsset(LLUUID assetID)
112 {
113 AssetBase asset = null;
114 if (this.Textures.ContainsKey(assetID))
115 {
116 asset = this.Textures[assetID];
117 }
118 else if (this.Assets.ContainsKey(assetID))
109 { 119 {
110 AssetInfo info = new AssetInfo(asset); 120 asset = this.Assets[assetID];
111 this.Assets.Add(info.FullID, info);
112 this._assetServer.UploadNewAsset(asset);
113 } 121 }
122 return asset;
114 } 123 }
115 124
116 public void AddAssetRequest(IClientAPI userInfo, TransferRequestPacket transferRequest) 125 public void AddAsset(AssetBase asset)
117 { 126 {
118 LLUUID assetID = new LLUUID(transferRequest.TransferInfo.Params, 0); 127 // Console.WriteLine("adding asset " + asset.FullID.ToStringHyphenated());
119 if (!this.Assets.ContainsKey(assetID)) 128 if (asset.Type == 0)
120 { 129 {
121 if (!this.RequestedAssets.ContainsKey(assetID)) 130 //Console.WriteLine("which is a texture");
122 { 131 if (!this.Textures.ContainsKey(asset.FullID))
123 AssetRequest request = new AssetRequest(); 132 { //texture
124 request.RequestUser = userInfo; 133 TextureImage textur = new TextureImage(asset);
125 request.RequestAssetID = assetID; 134 this.Textures.Add(textur.FullID, textur);
126 request.TransferRequestID = transferRequest.TransferInfo.TransferID; 135 this._assetServer.UploadNewAsset(asset);
127 this.RequestedAssets.Add(assetID, request);
128 this._assetServer.RequestAsset(assetID, false);
129 } 136 }
130 } 137 }
131 else 138 else
132 { 139 {
133 AssetInfo info = this.Assets[assetID]; 140 if (!this.Assets.ContainsKey(asset.FullID))
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 { 141 {
145 request2.NumPackets = 1; 142 AssetInfo assetInf = new AssetInfo(asset);
143 this.Assets.Add(assetInf.FullID, assetInf);
144 this._assetServer.UploadNewAsset(asset);
146 } 145 }
147 this.AssetRequests.Add(request2);
148 } 146 }
149 } 147 }
150 148
151 public void AddTextureRequest(IClientAPI userInfo, LLUUID imageID) 149 /// <summary>
150 ///
151 /// </summary>
152 private void ProcessTextureQueue()
152 { 153 {
153 if (!this.Textures.ContainsKey(imageID)) 154 if (this.TextureRequests.Count == 0)
154 { 155 {
155 if (!this.RequestedTextures.ContainsKey(imageID)) 156 //no requests waiting
156 { 157 return;
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 } 158 }
165 else 159 int num;
160 num = this.TextureRequests.Count;
161
162 AssetRequest req;
163 for (int i = 0; i < num; i++)
166 { 164 {
167 TextureImage image = this.Textures[imageID]; 165 req = (AssetRequest)this.TextureRequests[i];
168 AssetRequest request2 = new AssetRequest(); 166 if (!this.SendingTextures.ContainsKey(req.ImageInfo.FullID))
169 request2.RequestUser = userInfo;
170 request2.RequestAssetID = imageID;
171 request2.IsTextureRequest = true;
172 request2.ImageInfo = image;
173 if (image.Data.LongLength > 600)
174 { 167 {
175 request2.NumPackets = 1 + (((image.Data.Length - 600) + 0x3e7) / 0x3e8); 168 TextureSender sender = new TextureSender(req);
176 } 169 sender.OnComplete += this.TextureSent;
177 else 170 lock (this.SendingTextures)
178 { 171 {
179 request2.NumPackets = 1; 172 this.SendingTextures.Add(req.ImageInfo.FullID, sender);
173 }
180 } 174 }
181 this.TextureRequests.Add(request2); 175
182 } 176 }
177
178 this.TextureRequests.Clear();
183 } 179 }
184 180
185 public void AssetNotFound(AssetBase asset) 181 /// <summary>
182 /// Event handler, called by a TextureSender object to say that texture has been sent
183 /// </summary>
184 /// <param name="sender"></param>
185 public void TextureSent(TextureSender sender)
186 { 186 {
187 if (this.SendingTextures.ContainsKey(sender.request.ImageInfo.FullID))
188 {
189 lock (this.SendingTextures)
190 {
191 this.SendingTextures.Remove(sender.request.ImageInfo.FullID);
192 }
193 }
187 } 194 }
188 195
189 public void AssetReceived(AssetBase asset, bool IsTexture) 196 public void AssetReceived(AssetBase asset, bool IsTexture)
190 { 197 {
191 if (asset.FullID != LLUUID.Zero) 198 if (asset.FullID != LLUUID.Zero) // if it is set to zero then the asset wasn't found by the server
192 { 199 {
200 //check if it is a texture or not
201 //then add to the correct cache list
202 //then check for waiting requests for this asset/texture (in the Requested lists)
203 //and move those requests into the Requests list.
193 if (IsTexture) 204 if (IsTexture)
194 { 205 {
195 TextureImage image = new TextureImage(asset); 206 TextureImage image = new TextureImage(asset);
196 this.Textures.Add(image.FullID, image); 207 this.Textures.Add(image.FullID, image);
197 if (this.RequestedTextures.ContainsKey(image.FullID)) 208 if (this.RequestedTextures.ContainsKey(image.FullID))
198 { 209 {
199 AssetRequest request = this.RequestedTextures[image.FullID]; 210 AssetRequest req = this.RequestedTextures[image.FullID];
200 request.ImageInfo = image; 211 req.ImageInfo = image;
201 if (image.Data.LongLength > 600) 212 if (image.Data.LongLength > 600)
202 { 213 {
203 request.NumPackets = 1 + (((image.Data.Length - 600) + 0x3e7) / 0x3e8); 214 //over 600 bytes so split up file
215 req.NumPackets = 1 + (int)(image.Data.Length - 600 + 999) / 1000;
204 } 216 }
205 else 217 else
206 { 218 {
207 request.NumPackets = 1; 219 req.NumPackets = 1;
208 } 220 }
209 this.RequestedTextures.Remove(image.FullID); 221 this.RequestedTextures.Remove(image.FullID);
210 this.TextureRequests.Add(request); 222 this.TextureRequests.Add(req);
211 } 223 }
212 } 224 }
213 else 225 else
214 { 226 {
215 AssetInfo info = new AssetInfo(asset); 227 AssetInfo assetInf = new AssetInfo(asset);
216 this.Assets.Add(info.FullID, info); 228 this.Assets.Add(assetInf.FullID, assetInf);
217 if (this.RequestedAssets.ContainsKey(info.FullID)) 229 if (this.RequestedAssets.ContainsKey(assetInf.FullID))
218 { 230 {
219 AssetRequest request2 = this.RequestedAssets[info.FullID]; 231 AssetRequest req = this.RequestedAssets[assetInf.FullID];
220 request2.AssetInf = info; 232 req.AssetInf = assetInf;
221 if (info.Data.LongLength > 600) 233 if (assetInf.Data.LongLength > 600)
222 { 234 {
223 request2.NumPackets = 1 + (((info.Data.Length - 600) + 0x3e7) / 0x3e8); 235 //over 600 bytes so split up file
236 req.NumPackets = 1 + (int)(assetInf.Data.Length - 600 + 999) / 1000;
224 } 237 }
225 else 238 else
226 { 239 {
227 request2.NumPackets = 1; 240 req.NumPackets = 1;
228 } 241 }
229 this.RequestedAssets.Remove(info.FullID); 242 this.RequestedAssets.Remove(assetInf.FullID);
230 this.AssetRequests.Add(request2); 243 this.AssetRequests.Add(req);
231 } 244 }
232 } 245 }
233 } 246 }
234 } 247 }
235 248
236 public AssetInfo CloneAsset(LLUUID newOwner, AssetInfo sourceAsset) 249 public void AssetNotFound(AssetBase asset)
237 { 250 {
238 AssetInfo info = new AssetInfo(); 251 //the asset server had no knowledge of requested asset
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 252
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 } 253 }
256 254
257 public AssetBase[] CreateNewInventorySet(LLUUID agentID) 255 #region Assets
256 /// <summary>
257 ///
258 /// </summary>
259 /// <param name="userInfo"></param>
260 /// <param name="transferRequest"></param>
261 public void AddAssetRequest(IClientAPI userInfo, TransferRequestPacket transferRequest)
258 { 262 {
259 AssetBase[] baseArray = new AssetBase[this.textureList.Length]; 263 LLUUID requestID = null;
260 for (int i = 0; i < this.textureList.Length; i++) 264 byte source = 2;
265 if (transferRequest.TransferInfo.SourceType == 2)
266 {
267 //direct asset request
268 requestID = new LLUUID(transferRequest.TransferInfo.Params, 0);
269 }
270 else if (transferRequest.TransferInfo.SourceType == 3)
271 {
272 //inventory asset request
273 requestID = new LLUUID(transferRequest.TransferInfo.Params, 80);
274 source = 3;
275 }
276 //check to see if asset is in local cache, if not we need to request it from asset server.
277 //Console.WriteLine("asset request " + requestID);
278 if (!this.Assets.ContainsKey(requestID))
261 { 279 {
262 if (this.Textures.ContainsKey(this.textureList[i])) 280 //not found asset
281 // so request from asset server
282 if (!this.RequestedAssets.ContainsKey(requestID))
263 { 283 {
264 baseArray[i] = this.CloneImage(agentID, this.Textures[this.textureList[i]]); 284 AssetRequest request = new AssetRequest();
265 TextureImage asset = new TextureImage(baseArray[i]); 285 request.RequestUser = userInfo;
266 this.Textures.Add(asset.FullID, asset); 286 request.RequestAssetID = requestID;
267 this._assetServer.UploadNewAsset(asset); 287 request.TransferRequestID = transferRequest.TransferInfo.TransferID;
288 request.AssetRequestSource = source;
289 request.Params = transferRequest.TransferInfo.Params;
290 this.RequestedAssets.Add(requestID, request);
291 this._assetServer.RequestAsset(requestID, false);
268 } 292 }
293 return;
269 } 294 }
270 return baseArray; 295 //it is in our cache
271 } 296 AssetInfo asset = this.Assets[requestID];
272 297
273 public AssetBase GetAsset(LLUUID assetID) 298 //work out how many packets it should be sent in
274 { 299 // and add to the AssetRequests list
275 AssetBase base2 = null; 300 AssetRequest req = new AssetRequest();
276 if (this.Textures.ContainsKey(assetID)) 301 req.RequestUser = userInfo;
302 req.RequestAssetID = requestID;
303 req.TransferRequestID = transferRequest.TransferInfo.TransferID;
304 req.AssetRequestSource = source;
305 req.Params = transferRequest.TransferInfo.Params;
306 req.AssetInf = asset;
307
308 if (asset.Data.LongLength > 600)
277 { 309 {
278 return this.Textures[assetID]; 310 //over 600 bytes so split up file
311 req.NumPackets = 1 + (int)(asset.Data.Length - 600 + 999) / 1000;
279 } 312 }
280 if (this.Assets.ContainsKey(assetID)) 313 else
281 { 314 {
282 base2 = this.Assets[assetID]; 315 req.NumPackets = 1;
283 } 316 }
284 return base2; 317
318 this.AssetRequests.Add(req);
285 } 319 }
286 320
287 private IAssetServer LoadAssetDll(string dllName) 321 /// <summary>
322 ///
323 /// </summary>
324 private void ProcessAssetQueue()
288 { 325 {
289 Assembly assembly = Assembly.LoadFrom(dllName); 326 if (this.AssetRequests.Count == 0)
290 IAssetServer assetServer = null;
291 foreach (Type type in assembly.GetTypes())
292 { 327 {
293 if (type.IsPublic && !type.IsAbstract) 328 //no requests waiting
294 { 329 return;
295 if (type.GetInterface("IAssetPlugin", true) != null)
296 {
297 assetServer = ((IAssetPlugin)Activator.CreateInstance(assembly.GetType(type.ToString()))).GetAssetServer();
298 break;
299 }
300 }
301 } 330 }
302 assembly = null; 331 int num;
303 return assetServer;
304 }
305 332
306 public void LoadDefaultTextureSet() 333 if (this.AssetRequests.Count < 5)
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 { 334 {
315 this._assetServer.RequestAsset(this.textureList[i], true); 335 //lower than 5 so do all of them
336 num = this.AssetRequests.Count;
316 } 337 }
317 } 338 else
318 339 {
319 private void ProcessAssetQueue() 340 num = 5;
320 { 341 }
321 if (this.AssetRequests.Count != 0) 342 AssetRequest req;
343 for (int i = 0; i < num; i++)
322 { 344 {
323 int num; 345 req = (AssetRequest)this.AssetRequests[i];
324 if (this.AssetRequests.Count < 5) 346 //Console.WriteLine("sending asset " + req.RequestAssetID);
347 TransferInfoPacket Transfer = new TransferInfoPacket();
348 Transfer.TransferInfo.ChannelType = 2;
349 Transfer.TransferInfo.Status = 0;
350 Transfer.TransferInfo.TargetType = 0;
351 if (req.AssetRequestSource == 2)
325 { 352 {
326 num = this.AssetRequests.Count; 353 //Transfer.TransferInfo.Params = req.Params;
354 Transfer.TransferInfo.Params = new byte[20];
355 Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
356 int assType = (int)req.AssetInf.Type;
357 Array.Copy(Helpers.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4);
327 } 358 }
328 else 359 else if (req.AssetRequestSource == 3)
329 { 360 {
330 num = 5; 361 Transfer.TransferInfo.Params = req.Params;
362 // Transfer.TransferInfo.Params = new byte[100];
363 //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
364 //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16);
331 } 365 }
332 for (int i = 0; i < num; i++) 366 Transfer.TransferInfo.Size = (int)req.AssetInf.Data.Length;
367 Transfer.TransferInfo.TransferID = req.TransferRequestID;
368 req.RequestUser.OutPacket(Transfer);
369
370 if (req.NumPackets == 1)
333 { 371 {
334 AssetRequest request = this.AssetRequests[i]; 372 TransferPacketPacket TransferPacket = new TransferPacketPacket();
335 TransferInfoPacket newPack = new TransferInfoPacket(); 373 TransferPacket.TransferData.Packet = 0;
336 newPack.TransferInfo.ChannelType = 2; 374 TransferPacket.TransferData.ChannelType = 2;
337 newPack.TransferInfo.Status = 0; 375 TransferPacket.TransferData.TransferID = req.TransferRequestID;
338 newPack.TransferInfo.TargetType = 0; 376 TransferPacket.TransferData.Data = req.AssetInf.Data;
339 newPack.TransferInfo.Params = request.RequestAssetID.GetBytes(); 377 TransferPacket.TransferData.Status = 1;
340 newPack.TransferInfo.Size = request.AssetInf.Data.Length; 378 req.RequestUser.OutPacket(TransferPacket);
341 newPack.TransferInfo.TransferID = request.TransferRequestID; 379 }
342 request.RequestUser.OutPacket(newPack); 380 else
343 if (request.NumPackets == 1) 381 {
382 //more than one packet so split file up , for now it can't be bigger than 2000 bytes
383 TransferPacketPacket TransferPacket = new TransferPacketPacket();
384 TransferPacket.TransferData.Packet = 0;
385 TransferPacket.TransferData.ChannelType = 2;
386 TransferPacket.TransferData.TransferID = req.TransferRequestID;
387 byte[] chunk = null;
388 if (req.AssetInf.Data.Length <= 1000)
344 { 389 {
345 TransferPacketPacket packet2 = new TransferPacketPacket(); 390 chunk = new byte[req.AssetInf.Data.Length];
346 packet2.TransferData.Packet = 0; 391 Array.Copy(req.AssetInf.Data, chunk, req.AssetInf.Data.Length);
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 } 392 }
353 else 393 else
354 { 394 {
355 TransferPacketPacket packet3 = new TransferPacketPacket(); 395 chunk = new byte[1000];
356 packet3.TransferData.Packet = 0; 396 Array.Copy(req.AssetInf.Data, chunk, 1000);
357 packet3.TransferData.ChannelType = 2; 397 }
358 packet3.TransferData.TransferID = request.TransferRequestID; 398
359 byte[] destinationArray = new byte[0x3e8]; 399 TransferPacket.TransferData.Data = chunk;
360 Array.Copy(request.AssetInf.Data, destinationArray, 0x3e8); 400 TransferPacket.TransferData.Status = 0;
361 packet3.TransferData.Data = destinationArray; 401 req.RequestUser.OutPacket(TransferPacket);
362 packet3.TransferData.Status = 0; 402
363 request.RequestUser.OutPacket(packet3); 403 if (req.AssetInf.Data.Length > 1000)
364 packet3 = new TransferPacketPacket(); 404 {
365 packet3.TransferData.Packet = 1; 405 TransferPacket = new TransferPacketPacket();
366 packet3.TransferData.ChannelType = 2; 406 TransferPacket.TransferData.Packet = 1;
367 packet3.TransferData.TransferID = request.TransferRequestID; 407 TransferPacket.TransferData.ChannelType = 2;
368 byte[] buffer2 = new byte[request.AssetInf.Data.Length - 0x3e8]; 408 TransferPacket.TransferData.TransferID = req.TransferRequestID;
369 Array.Copy(request.AssetInf.Data, 0x3e8, buffer2, 0, buffer2.Length); 409 byte[] chunk1 = new byte[(req.AssetInf.Data.Length - 1000)];
370 packet3.TransferData.Data = buffer2; 410 Array.Copy(req.AssetInf.Data, 1000, chunk1, 0, chunk1.Length);
371 packet3.TransferData.Status = 1; 411 TransferPacket.TransferData.Data = chunk1;
372 request.RequestUser.OutPacket(packet3); 412 TransferPacket.TransferData.Status = 1;
413 req.RequestUser.OutPacket(TransferPacket);
373 } 414 }
374 } 415 }
375 for (int j = 0; j < num; j++) 416
376 {
377 this.AssetRequests.RemoveAt(0);
378 }
379 } 417 }
418
419 //remove requests that have been completed
420 for (int i = 0; i < num; i++)
421 {
422 this.AssetRequests.RemoveAt(0);
423 }
424
380 } 425 }
381 426
382 private void ProcessTextureQueue() 427 public AssetInfo CloneAsset(LLUUID newOwner, AssetInfo sourceAsset)
428 {
429 AssetInfo newAsset = new AssetInfo();
430 newAsset.Data = new byte[sourceAsset.Data.Length];
431 Array.Copy(sourceAsset.Data, newAsset.Data, sourceAsset.Data.Length);
432 newAsset.FullID = LLUUID.Random();
433 newAsset.Type = sourceAsset.Type;
434 newAsset.InvType = sourceAsset.InvType;
435 return (newAsset);
436 }
437 #endregion
438
439 #region Textures
440 /// <summary>
441 ///
442 /// </summary>
443 /// <param name="userInfo"></param>
444 /// <param name="imageID"></param>
445 public void AddTextureRequest(IClientAPI userInfo, LLUUID imageID)
383 { 446 {
384 if (this.TextureRequests.Count != 0) 447 //Console.WriteLine("texture request for " + imageID.ToStringHyphenated());
448 //check to see if texture is in local cache, if not request from asset server
449 if (!this.Textures.ContainsKey(imageID))
385 { 450 {
386 int num = this.TextureRequests.Count; 451 if (!this.RequestedTextures.ContainsKey(imageID))
387 for (int i = 0; i < num; i++)
388 { 452 {
389 AssetRequest req = this.TextureRequests[i]; 453 //not is cache so request from asset server
390 if (!this.SendingTextures.ContainsKey(req.ImageInfo.FullID)) 454 AssetRequest request = new AssetRequest();
391 { 455 request.RequestUser = userInfo;
392 TextureSender sender = new TextureSender(req); 456 request.RequestAssetID = imageID;
393 sender.OnComplete += new DownloadComplete(this.TextureSent); 457 request.IsTextureRequest = true;
394 lock (this.SendingTextures) 458 this.RequestedTextures.Add(imageID, request);
395 { 459 this._assetServer.RequestAsset(imageID, true);
396 this.SendingTextures.Add(req.ImageInfo.FullID, sender);
397 }
398 }
399 } 460 }
400 this.TextureRequests.Clear(); 461 return;
401 } 462 }
402 }
403 463
404 public void RunAssetManager() 464 //Console.WriteLine("texture already in cache");
405 { 465 TextureImage imag = this.Textures[imageID];
406 Label_0000: 466 AssetRequest req = new AssetRequest();
407 try 467 req.RequestUser = userInfo;
468 req.RequestAssetID = imageID;
469 req.IsTextureRequest = true;
470 req.ImageInfo = imag;
471
472 if (imag.Data.LongLength > 600)
408 { 473 {
409 this.ProcessAssetQueue(); 474 //over 600 bytes so split up file
410 this.ProcessTextureQueue(); 475 req.NumPackets = 1 + (int)(imag.Data.Length - 600 + 999) / 1000;
411 Thread.Sleep(500);
412 goto Label_0000;
413 } 476 }
414 catch (Exception exception) 477 else
415 { 478 {
416 Console.WriteLine(exception.Message); 479 req.NumPackets = 1;
417 goto Label_0000;
418 } 480 }
481 this.TextureRequests.Add(req);
419 } 482 }
420 483
421 public void TextureSent(TextureSender sender) 484 public TextureImage CloneImage(LLUUID newOwner, TextureImage source)
422 { 485 {
423 if (this.SendingTextures.ContainsKey(sender.request.ImageInfo.FullID)) 486 TextureImage newImage = new TextureImage();
487 newImage.Data = new byte[source.Data.Length];
488 Array.Copy(source.Data, newImage.Data, source.Data.Length);
489 //newImage.filename = source.filename;
490 newImage.FullID = LLUUID.Random();
491 newImage.Name = source.Name;
492 return (newImage);
493 }
494 #endregion
495
496 private IAssetServer LoadAssetDll(string dllName)
497 {
498 Assembly pluginAssembly = Assembly.LoadFrom(dllName);
499 IAssetServer server = null;
500
501 foreach (Type pluginType in pluginAssembly.GetTypes())
424 { 502 {
425 lock (this.SendingTextures) 503 if (pluginType.IsPublic)
426 { 504 {
427 this.SendingTextures.Remove(sender.request.ImageInfo.FullID); 505 if (!pluginType.IsAbstract)
506 {
507 Type typeInterface = pluginType.GetInterface("IAssetPlugin", true);
508
509 if (typeInterface != null)
510 {
511 IAssetPlugin plug = (IAssetPlugin)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
512 server = plug.GetAssetServer();
513 break;
514 }
515
516 typeInterface = null;
517 }
428 } 518 }
429 } 519 }
520 pluginAssembly = null;
521 return server;
522 }
523
524 public class AssetRequest
525 {
526 public IClientAPI RequestUser;
527 public LLUUID RequestAssetID;
528 public AssetInfo AssetInf;
529 public TextureImage ImageInfo;
530 public LLUUID TransferRequestID;
531 public long DataPointer = 0;
532 public int NumPackets = 0;
533 public int PacketCounter = 0;
534 public bool IsTextureRequest;
535 public byte AssetRequestSource = 2;
536 public byte[] Params = null;
537 //public bool AssetInCache;
538 //public int TimeRequested;
539
540 public AssetRequest()
541 {
542
543 }
430 } 544 }
431 545
432 // Nested Types
433 public class AssetInfo : AssetBase 546 public class AssetInfo : AssetBase
434 { 547 {
435 // Methods
436 public AssetInfo() 548 public AssetInfo()
437 { 549 {
550
438 } 551 }
439 552
440 public AssetInfo(AssetBase aBase) 553 public AssetInfo(AssetBase aBase)
441 { 554 {
442 base.Data = aBase.Data; 555 Data = aBase.Data;
443 base.FullID = aBase.FullID; 556 FullID = aBase.FullID;
444 base.Type = aBase.Type; 557 Type = aBase.Type;
445 base.InvType = aBase.InvType; 558 InvType = aBase.InvType;
446 base.Name = aBase.Name; 559 Name = aBase.Name;
447 base.Description = aBase.Description; 560 Description = aBase.Description;
448 } 561 }
449 } 562 }
450 563
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 564 public class TextureImage : AssetBase
466 { 565 {
467 // Methods
468 public TextureImage() 566 public TextureImage()
469 { 567 {
568
470 } 569 }
471 570
472 public TextureImage(AssetBase aBase) 571 public TextureImage(AssetBase aBase)
473 { 572 {
474 base.Data = aBase.Data; 573 Data = aBase.Data;
475 base.FullID = aBase.FullID; 574 FullID = aBase.FullID;
476 base.Type = aBase.Type; 575 Type = aBase.Type;
477 base.InvType = aBase.InvType; 576 InvType = aBase.InvType;
478 base.Name = aBase.Name; 577 Name = aBase.Name;
479 base.Description = aBase.Description; 578 Description = aBase.Description;
480 } 579 }
481 } 580 }
482 581
483 public class TextureSender 582 public class TextureSender
484 { 583 {
485 // Fields 584 public AssetRequest request;
486 private Thread m_thread;
487 public AssetCache.AssetRequest request;
488
489 // Events
490 public event DownloadComplete OnComplete; 585 public event DownloadComplete OnComplete;
586 Thread m_thread;
587 public TextureSender(AssetRequest req)
588 {
589 request = req;
590 //Console.WriteLine("creating worker thread for texture " + req.ImageInfo.FullID.ToStringHyphenated());
591 //Console.WriteLine("texture data length is " + req.ImageInfo.Data.Length);
592 // Console.WriteLine("in " + req.NumPackets + " packets");
593 //ThreadPool.QueueUserWorkItem(new WaitCallback(SendTexture), new object());
491 594
492 // Methods 595 //need some sort of custom threadpool here, as using the .net one, overloads it and stops the handling of incoming packets etc
493 public TextureSender(AssetCache.AssetRequest req) 596 //but don't really want to create a thread for every texture download
597 m_thread = new Thread(new ThreadStart(SendTexture));
598 m_thread.IsBackground = true;
599 m_thread.Start();
600 }
601
602 public void SendTexture()
494 { 603 {
495 this.request = req; 604 //Console.WriteLine("starting to send sending texture " + request.ImageInfo.FullID.ToStringHyphenated());
496 this.m_thread = new Thread(new ThreadStart(this.SendTexture)); 605 while (request.PacketCounter != request.NumPackets)
497 this.m_thread.IsBackground = true; 606 {
498 this.m_thread.Start(); 607 SendPacket();
608 Thread.Sleep(500);
609 }
610
611 //Console.WriteLine("finished sending texture " + request.ImageInfo.FullID.ToStringHyphenated());
612 if (OnComplete != null)
613 {
614 OnComplete(this);
615 }
499 } 616 }
500 617
501 public void SendPacket() 618 public void SendPacket()
502 { 619 {
503 AssetCache.AssetRequest request = this.request; 620 AssetRequest req = request;
504 if (request.PacketCounter == 0) 621 // Console.WriteLine("sending " + req.ImageInfo.FullID);
622
623 // if (req.ImageInfo.FullID == new LLUUID("00000000-0000-0000-5005-000000000005"))
624 if (req.PacketCounter == 0)
505 { 625 {
506 if (request.NumPackets == 1) 626 //first time for this request so send imagedata packet
627 if (req.NumPackets == 1)
507 { 628 {
508 ImageDataPacket newPack = new ImageDataPacket(); 629 //only one packet so send whole file
509 newPack.ImageID.Packets = 1; 630 ImageDataPacket im = new ImageDataPacket();
510 newPack.ImageID.ID = request.ImageInfo.FullID; 631 im.ImageID.Packets = 1;
511 newPack.ImageID.Size = (uint)request.ImageInfo.Data.Length; 632 im.ImageID.ID = req.ImageInfo.FullID;
512 newPack.ImageData.Data = request.ImageInfo.Data; 633 im.ImageID.Size = (uint)req.ImageInfo.Data.Length;
513 newPack.ImageID.Codec = 2; 634 im.ImageData.Data = req.ImageInfo.Data;
514 request.RequestUser.OutPacket(newPack); 635 im.ImageID.Codec = 2;
515 request.PacketCounter++; 636 req.RequestUser.OutPacket(im);
637 req.PacketCounter++;
638 //req.ImageInfo.l= time;
639 //System.Console.WriteLine("sent texture: " + req.ImageInfo.FullID);
640 // Console.WriteLine("sending packet 1 for " + req.ImageInfo.FullID.ToStringHyphenated());
516 } 641 }
517 else 642 else
518 { 643 {
519 ImageDataPacket packet2 = new ImageDataPacket(); 644 //more than one packet so split file up
520 packet2.ImageID.Packets = (ushort)request.NumPackets; 645 ImageDataPacket im = new ImageDataPacket();
521 packet2.ImageID.ID = request.ImageInfo.FullID; 646 im.ImageID.Packets = (ushort)req.NumPackets;
522 packet2.ImageID.Size = (uint)request.ImageInfo.Data.Length; 647 im.ImageID.ID = req.ImageInfo.FullID;
523 packet2.ImageData.Data = new byte[600]; 648 im.ImageID.Size = (uint)req.ImageInfo.Data.Length;
524 Array.Copy(request.ImageInfo.Data, 0, packet2.ImageData.Data, 0, 600); 649 im.ImageData.Data = new byte[600];
525 packet2.ImageID.Codec = 2; 650 Array.Copy(req.ImageInfo.Data, 0, im.ImageData.Data, 0, 600);
526 request.RequestUser.OutPacket(packet2); 651 im.ImageID.Codec = 2;
527 request.PacketCounter++; 652 req.RequestUser.OutPacket(im);
653 req.PacketCounter++;
654 //req.ImageInfo.last_used = time;
655 //System.Console.WriteLine("sent first packet of texture:
656 // Console.WriteLine("sending packet 1 for " + req.ImageInfo.FullID.ToStringHyphenated());
528 } 657 }
529 } 658 }
530 else 659 else
531 { 660 {
532 ImagePacketPacket packet3 = new ImagePacketPacket(); 661 //Console.WriteLine("sending packet" + req.PacketCounter + "for " + req.ImageInfo.FullID.ToStringHyphenated());
533 packet3.ImageID.Packet = (ushort)request.PacketCounter; 662 //send imagepacket
534 packet3.ImageID.ID = request.ImageInfo.FullID; 663 //more than one packet so split file up
535 int length = (request.ImageInfo.Data.Length - 600) - (0x3e8 * (request.PacketCounter - 1)); 664 ImagePacketPacket im = new ImagePacketPacket();
536 if (length > 0x3e8) 665 im.ImageID.Packet = (ushort)req.PacketCounter;
537 { 666 im.ImageID.ID = req.ImageInfo.FullID;
538 length = 0x3e8; 667 int size = req.ImageInfo.Data.Length - 600 - 1000 * (req.PacketCounter - 1);
539 } 668 if (size > 1000) size = 1000;
540 packet3.ImageData.Data = new byte[length]; 669 im.ImageData.Data = new byte[size];
541 Array.Copy(request.ImageInfo.Data, 600 + (0x3e8 * (request.PacketCounter - 1)), packet3.ImageData.Data, 0, length); 670 Array.Copy(req.ImageInfo.Data, 600 + 1000 * (req.PacketCounter - 1), im.ImageData.Data, 0, size);
542 request.RequestUser.OutPacket(packet3); 671 req.RequestUser.OutPacket(im);
543 request.PacketCounter++; 672 req.PacketCounter++;
673 //req.ImageInfo.last_used = time;
674 //System.Console.WriteLine("sent a packet of texture: "+req.image_info.FullID);
544 } 675 }
545 }
546 676
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 } 677 }
559 } 678 }
560 } 679 }
561} 680}
681