aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Communications/Cache/AgentAssetTransactions.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Communications/Cache/AgentAssetTransactions.cs')
-rw-r--r--OpenSim/Framework/Communications/Cache/AgentAssetTransactions.cs509
1 files changed, 509 insertions, 0 deletions
diff --git a/OpenSim/Framework/Communications/Cache/AgentAssetTransactions.cs b/OpenSim/Framework/Communications/Cache/AgentAssetTransactions.cs
new file mode 100644
index 0000000..e74a06b
--- /dev/null
+++ b/OpenSim/Framework/Communications/Cache/AgentAssetTransactions.cs
@@ -0,0 +1,509 @@
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 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.Generic;
30using System.IO;
31using libsecondlife;
32using libsecondlife.Packets;
33using OpenSim.Framework.Servers;
34using OpenSim.Region.Capabilities;
35
36namespace OpenSim.Framework.Communications.Cache
37{
38 /// <summary>
39 /// Manage asset transactions for a single agent.
40 /// </summary>
41 public class AgentAssetTransactions
42 {
43 private static readonly log4net.ILog m_log
44 = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
45
46 // Fields
47 public List<AssetCapsUploader> CapsUploaders = new List<AssetCapsUploader>();
48 public List<NoteCardCapsUpdate> NotecardUpdaters = new List<NoteCardCapsUpdate>();
49 public LLUUID UserID;
50 public Dictionary<LLUUID, AssetXferUploader> XferUploaders = new Dictionary<LLUUID, AssetXferUploader>();
51 public AgentAssetTransactionsManager Manager;
52 private bool m_dumpAssetsToFile;
53
54 // Methods
55 public AgentAssetTransactions(LLUUID agentID, AgentAssetTransactionsManager manager, bool dumpAssetsToFile)
56 {
57 UserID = agentID;
58 Manager = manager;
59 m_dumpAssetsToFile = dumpAssetsToFile;
60 }
61
62 public AssetCapsUploader RequestCapsUploader()
63 {
64 AssetCapsUploader uploader = new AssetCapsUploader();
65 CapsUploaders.Add(uploader);
66 return uploader;
67 }
68
69 public NoteCardCapsUpdate RequestNoteCardUpdater()
70 {
71 NoteCardCapsUpdate update = new NoteCardCapsUpdate();
72 NotecardUpdaters.Add(update);
73 return update;
74 }
75
76 public AssetXferUploader RequestXferUploader(LLUUID transactionID)
77 {
78 if (!XferUploaders.ContainsKey(transactionID))
79 {
80 AssetXferUploader uploader = new AssetXferUploader(this, m_dumpAssetsToFile);
81
82 lock (XferUploaders)
83 {
84 XferUploaders.Add(transactionID, uploader);
85 }
86
87 return uploader;
88 }
89 return null;
90 }
91
92 public void HandleXfer(ulong xferID, uint packetID, byte[] data)
93 {
94 AssetXferUploader uploaderFound = null;
95
96 lock (XferUploaders)
97 {
98 foreach (AssetXferUploader uploader in XferUploaders.Values)
99 {
100 if (uploader.XferID == xferID)
101 {
102 if (uploader.HandleXferPacket(xferID, packetID, data))
103 {
104 uploaderFound = uploader;
105 }
106
107 break;
108 }
109 }
110
111 // Remove the uploader once the uploader is complete
112 //[don't think we can be sure a upload has finished from here, uploads are multi part things]
113 // [or maybe we can if we do more checking like data lenght checks]
114 if (uploaderFound != null)
115 {
116// m_log.Info(
117// String.Format(
118// "[ASSET TRANSACTIONS] Removing asset xfer uploader with transfer id {0}, transaction {1}",
119// xferID, uploaderFound.TransactionID));
120
121 // XferUploaders.Remove(uploaderFound.TransactionID);
122
123 //m_log.InfoFormat("[ASSET TRANSACTIONS] Current uploaders: {0}", XferUploaders.Count);
124 }
125 }
126 }
127
128 public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID,
129 uint callbackID, string description, string name, sbyte invType,
130 sbyte type, byte wearableType, uint nextOwnerMask)
131 {
132 if (XferUploaders.ContainsKey(transactionID))
133 {
134 XferUploaders[transactionID].RequestCreateInventoryItem(remoteClient, transactionID, folderID,
135 callbackID, description, name, invType, type,
136 wearableType, nextOwnerMask);
137 }
138 }
139
140 /// <summary>
141 /// Get an uploaded asset. If the data is successfully retrieved, the transaction will be removed.
142 /// </summary>
143 /// <param name="transactionID"></param>
144 /// <returns>The asset if the upload has completed, null if it has not.</returns>
145 public AssetBase GetTransactionAsset(LLUUID transactionID)
146 {
147 if (XferUploaders.ContainsKey(transactionID))
148 {
149 AssetXferUploader uploader = XferUploaders[transactionID];
150 AssetBase asset = uploader.GetAssetData();
151
152 lock (XferUploaders)
153 {
154 XferUploaders.Remove(transactionID);
155 }
156
157 return asset;
158 }
159
160 return null;
161 }
162
163 // Nested Types
164 public class AssetXferUploader
165 {
166 // Fields
167 public bool AddToInventory;
168 public AssetBase Asset;
169 public LLUUID InventFolder = LLUUID.Zero;
170 private IClientAPI ourClient;
171 public LLUUID TransactionID = LLUUID.Zero;
172 public bool UploadComplete;
173 public ulong XferID;
174 private string m_name = String.Empty;
175 private string m_description = String.Empty;
176 private sbyte type = 0;
177 private sbyte invType = 0;
178 private uint nextPerm = 0;
179 private bool m_finished = false;
180 private bool m_createItem = false;
181 private AgentAssetTransactions m_userTransactions;
182 private bool m_storeLocal;
183 private bool m_dumpAssetToFile;
184
185 public AssetXferUploader(AgentAssetTransactions transactions, bool dumpAssetToFile)
186 {
187 m_userTransactions = transactions;
188 m_dumpAssetToFile = dumpAssetToFile;
189 }
190
191 /// <summary>
192 /// Process transfer data received from the client.
193 /// </summary>
194 /// <param name="xferID"></param>
195 /// <param name="packetID"></param>
196 /// <param name="data"></param>
197 /// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns>
198 public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data)
199 {
200 if (XferID == xferID)
201 {
202 if (Asset.Data.Length > 1)
203 {
204 byte[] destinationArray = new byte[Asset.Data.Length + data.Length];
205 Array.Copy(Asset.Data, 0, destinationArray, 0, Asset.Data.Length);
206 Array.Copy(data, 0, destinationArray, Asset.Data.Length, data.Length);
207 Asset.Data = destinationArray;
208 }
209 else
210 {
211 byte[] buffer2 = new byte[data.Length - 4];
212 Array.Copy(data, 4, buffer2, 0, data.Length - 4);
213 Asset.Data = buffer2;
214 }
215 ConfirmXferPacketPacket newPack = new ConfirmXferPacketPacket();
216 newPack.XferID.ID = xferID;
217 newPack.XferID.Packet = packetID;
218 ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset);
219 if ((packetID & 0x80000000) != 0)
220 {
221 SendCompleteMessage();
222 return true;
223 }
224 }
225
226 return false;
227 }
228
229 /// <summary>
230 /// Initialise asset transfer from the client
231 /// </summary>
232 /// <param name="xferID"></param>
233 /// <param name="packetID"></param>
234 /// <param name="data"></param>
235 /// <returns>True if the transfer is complete, false otherwise</returns>
236 public bool Initialise(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data,
237 bool storeLocal, bool tempFile)
238 {
239 ourClient = remoteClient;
240 Asset = new AssetBase();
241 Asset.FullID = assetID;
242 Asset.InvType = type;
243 Asset.Type = type;
244 Asset.Data = data;
245 Asset.Name = "blank";
246 Asset.Description = "empty";
247 Asset.Local = storeLocal;
248 Asset.Temporary = tempFile;
249
250 TransactionID = transaction;
251 m_storeLocal = storeLocal;
252 if (Asset.Data.Length > 2)
253 {
254 SendCompleteMessage();
255 return true;
256 }
257 else
258 {
259 ReqestStartXfer();
260 }
261
262 return false;
263 }
264
265 protected void ReqestStartXfer()
266 {
267 UploadComplete = false;
268 XferID = Util.GetNextXferID();
269 RequestXferPacket newPack = new RequestXferPacket();
270 newPack.XferID.ID = XferID;
271 newPack.XferID.VFileType = Asset.Type;
272 newPack.XferID.VFileID = Asset.FullID;
273 newPack.XferID.FilePath = 0;
274 newPack.XferID.Filename = new byte[0];
275 ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset);
276 }
277
278 protected void SendCompleteMessage()
279 {
280 UploadComplete = true;
281 AssetUploadCompletePacket newPack = new AssetUploadCompletePacket();
282 newPack.AssetBlock.Type = Asset.Type;
283 newPack.AssetBlock.Success = true;
284 newPack.AssetBlock.UUID = Asset.FullID;
285 ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset);
286 m_finished = true;
287 if (m_createItem)
288 {
289 DoCreateItem();
290 }
291 else if (m_storeLocal)
292 {
293 m_userTransactions.Manager.CommsManager.AssetCache.AddAsset(Asset);
294 }
295
296 // Console.WriteLine("upload complete "+ this.TransactionID);
297
298 if (m_dumpAssetToFile)
299 {
300 DateTime now = DateTime.Now;
301 string filename =
302 String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat", now.Year, now.Month, now.Day,
303 now.Hour, now.Minute, now.Second, Asset.Name, Asset.Type);
304 SaveAssetToFile(filename, Asset.Data);
305 }
306 }
307
308 ///Left this in and commented in case there are unforseen issues
309 //private void SaveAssetToFile(string filename, byte[] data)
310 //{
311 // FileStream fs = File.Create(filename);
312 // BinaryWriter bw = new BinaryWriter(fs);
313 // bw.Write(data);
314 // bw.Close();
315 // fs.Close();
316 //}
317 private void SaveAssetToFile(string filename, byte[] data)
318 {
319 string assetPath = "UserAssets";
320 if (!Directory.Exists(assetPath))
321 {
322 Directory.CreateDirectory(assetPath);
323 }
324 FileStream fs = File.Create(Path.Combine(assetPath, filename));
325 BinaryWriter bw = new BinaryWriter(fs);
326 bw.Write(data);
327 bw.Close();
328 fs.Close();
329 }
330
331 public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID,
332 uint callbackID, string description, string name, sbyte invType,
333 sbyte type, byte wearableType, uint nextOwnerMask)
334 {
335 if (TransactionID == transactionID)
336 {
337 InventFolder = folderID;
338 m_name = name;
339 m_description = description;
340 this.type = type;
341 this.invType = invType;
342 nextPerm = nextOwnerMask;
343 Asset.Name = name;
344 Asset.Description = description;
345 Asset.Type = type;
346 Asset.InvType = invType;
347 m_createItem = true;
348 if (m_finished)
349 {
350 DoCreateItem();
351 }
352 }
353 }
354
355 private void DoCreateItem()
356 {
357 //really need to fix this call, if lbsa71 saw this he would die.
358 m_userTransactions.Manager.CommsManager.AssetCache.AddAsset(Asset);
359 CachedUserInfo userInfo =
360 m_userTransactions.Manager.CommsManager.UserProfileCacheService.GetUserDetails(ourClient.AgentId);
361 if (userInfo != null)
362 {
363 InventoryItemBase item = new InventoryItemBase();
364 item.avatarID = ourClient.AgentId;
365 item.creatorsID = ourClient.AgentId;
366 item.inventoryID = LLUUID.Random();
367 item.assetID = Asset.FullID;
368 item.inventoryDescription = m_description;
369 item.inventoryName = m_name;
370 item.assetType = type;
371 item.invType = invType;
372 item.parentFolderID = InventFolder;
373 item.inventoryBasePermissions = 2147483647;
374 item.inventoryCurrentPermissions = 2147483647;
375 item.inventoryNextPermissions = nextPerm;
376
377 userInfo.AddItem(ourClient.AgentId, item);
378 ourClient.SendInventoryItemCreateUpdate(item);
379 }
380 }
381
382 public AssetBase GetAssetData()
383 {
384 if (m_finished)
385 {
386 return Asset;
387 }
388 return null;
389 }
390 }
391
392 #region Nested Classes currently not in use (waiting for them to be enabled)
393
394 public class AssetCapsUploader
395 {
396 // Fields
397 private BaseHttpServer httpListener;
398 private LLUUID inventoryItemID;
399 private string m_assetDescription = String.Empty;
400 private string m_assetName = String.Empty;
401 private LLUUID m_folderID;
402 private LLUUID newAssetID;
403 private bool m_dumpImageToFile;
404 private string uploaderPath = String.Empty;
405
406 // Events
407 public event UpLoadedAsset OnUpLoad;
408
409 // Methods
410 public void Initialise(string assetName, string assetDescription, LLUUID assetID, LLUUID inventoryItem,
411 LLUUID folderID, string path, BaseHttpServer httpServer, bool dumpImageToFile)
412 {
413 m_assetName = assetName;
414 m_assetDescription = assetDescription;
415 m_folderID = folderID;
416 newAssetID = assetID;
417 inventoryItemID = inventoryItem;
418 uploaderPath = path;
419 httpListener = httpServer;
420 m_dumpImageToFile = dumpImageToFile;
421 }
422
423 private void SaveImageToFile(string filename, byte[] data)
424 {
425 FileStream output = File.Create(filename);
426 BinaryWriter writer = new BinaryWriter(output);
427 writer.Write(data);
428 writer.Close();
429 output.Close();
430 }
431
432 public string uploaderCaps(byte[] data, string path, string param)
433 {
434 LLUUID inventoryItemID = this.inventoryItemID;
435 string text = String.Empty;
436 LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete();
437 complete.new_asset = newAssetID.ToString();
438 complete.new_inventory_item = inventoryItemID;
439 complete.state = "complete";
440 text = LLSDHelpers.SerialiseLLSDReply(complete);
441 httpListener.RemoveStreamHandler("POST", uploaderPath);
442 if (m_dumpImageToFile)
443 {
444 SaveImageToFile(m_assetName + ".jp2", data);
445 }
446 if (OnUpLoad != null)
447 {
448 OnUpLoad(m_assetName, "description", newAssetID, inventoryItemID, LLUUID.Zero, data, String.Empty, String.Empty);
449 }
450 return text;
451 }
452 }
453
454 public class NoteCardCapsUpdate
455 {
456 // Fields
457 private BaseHttpServer httpListener;
458 private LLUUID inventoryItemID;
459 private string m_assetName = String.Empty;
460 private LLUUID newAssetID;
461 private bool SaveImages = false;
462 private string uploaderPath = String.Empty;
463
464 // Events
465 public event UpLoadedAsset OnUpLoad;
466
467 // Methods
468 public void Initialise(LLUUID inventoryItem, string path, BaseHttpServer httpServer)
469 {
470 inventoryItemID = inventoryItem;
471 uploaderPath = path;
472 httpListener = httpServer;
473 newAssetID = LLUUID.Random();
474 }
475
476 private void SaveImageToFile(string filename, byte[] data)
477 {
478 FileStream output = File.Create(filename);
479 BinaryWriter writer = new BinaryWriter(output);
480 writer.Write(data);
481 writer.Close();
482 output.Close();
483 }
484
485 public string uploaderCaps(byte[] data, string path, string param)
486 {
487 LLUUID inventoryItemID = this.inventoryItemID;
488 string text = String.Empty;
489 LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete();
490 complete.new_asset = newAssetID.ToString();
491 complete.new_inventory_item = inventoryItemID;
492 complete.state = "complete";
493 text = LLSDHelpers.SerialiseLLSDReply(complete);
494 httpListener.RemoveStreamHandler("POST", uploaderPath);
495 if (SaveImages)
496 {
497 SaveImageToFile(m_assetName + "notecard.txt", data);
498 }
499 if (OnUpLoad != null)
500 {
501 OnUpLoad(m_assetName, "description", newAssetID, inventoryItemID, LLUUID.Zero, data, String.Empty, String.Empty);
502 }
503 return text;
504 }
505 }
506
507 #endregion
508 }
509}