30 using System.Reflection;
31 using System.Collections.Generic;
34 using OpenSim.Framework;
35 using OpenSim.Region.Framework.Interfaces;
36 using OpenSim.Region.Framework.Scenes;
37 using OpenSim.Services.Interfaces;
40 namespace OpenSim.
Region.CoreModules.
Agent.AssetTransaction
45 private List<UUID> defaultIDs =
new List<UUID> {
47 new UUID(
"5748decc-f629-461c-9a36-a35a221fe21f"),
48 new UUID(
"7ca39b4c-bd19-4699-aff7-f93fd03d3e7b"),
49 new UUID(
"6522e74d-1660-4e7f-b601-6f48c1659a77"),
50 new UUID(
"c228d1cf-4b5d-4ba8-84f4-899a0796aa97"),
51 new UUID(
"8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"),
53 new UUID(
"00000000-0000-1111-9999-000000000010"),
54 new UUID(
"00000000-0000-1111-9999-000000000011"),
55 new UUID(
"00000000-0000-1111-9999-000000000012"),
57 new UUID(
"3a367d1c-bef1-6d43-7595-e88c1e3aadb3"),
58 new UUID(
"1578a2b1-5179-4b53-b618-fe00ca5a5594"),
61 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
69 private enum UploadState
82 private UploadState m_uploadState = UploadState.New;
85 private UUID InventFolder = UUID.Zero;
86 private sbyte invType = 0;
88 private bool m_createItem;
89 private uint m_createItemCallback;
91 private bool m_updateItem;
94 private bool m_updateTaskItem;
97 private string m_description = String.Empty;
98 private bool m_dumpAssetToFile;
99 private string m_name = String.Empty;
101 private uint nextPerm = 0;
104 private UUID m_transactionID;
106 private sbyte type = 0;
107 private byte wearableType = 0;
108 private byte[] m_oldData = null;
110 private Scene m_Scene;
130 m_transactions = transactions;
131 m_transactionID = transactionID;
133 m_dumpAssetToFile = dumpAssetToFile;
149 if (XferID == xferID)
153 int assetLength = m_asset.Data.Length;
154 int dataLength = data.Length;
156 if (m_asset.Data.Length > 1)
158 byte[] destinationArray =
new byte[assetLength + dataLength];
159 Array.Copy(m_asset.Data, 0, destinationArray, 0, assetLength);
160 Array.Copy(data, 0, destinationArray, assetLength, dataLength);
161 m_asset.Data = destinationArray;
167 byte[] buffer2 =
new byte[dataLength - 4];
168 Array.Copy(data, 4, buffer2, 0, dataLength - 4);
169 m_asset.Data = buffer2;
174 ourClient.SendConfirmXfer(xferID, packetID);
176 if ((packetID & 0x80000000) != 0)
178 SendCompleteMessage();
200 IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, byte[] data,
bool storeLocal,
209 if (m_uploadState != UploadState.New)
212 "[ASSET XFER UPLOADER]: Tried to start upload of asset {0}, transaction {1} for {2} but this is already in state {3}. Aborting.",
213 assetID, transaction, remoteClient.Name, m_uploadState);
218 m_uploadState = UploadState.Uploading;
221 ourClient = remoteClient;
223 m_asset.FullID = assetID;
225 m_asset.CreatorID = remoteClient.AgentId.ToString();
227 m_asset.Local = storeLocal;
228 m_asset.Temporary = tempFile;
232 if (m_asset.Data.Length > 2)
234 SendCompleteMessage();
244 XferID = Util.GetNextXferID();
250 ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, 0,
new byte[0]);
259 m_uploadState = UploadState.Complete;
261 ourClient.SendAssetUploadCompleteMessage(m_asset.Type,
true, m_asset.FullID);
265 CompleteCreateItem(m_createItemCallback);
267 else if (m_updateItem)
269 CompleteItemUpdate(m_updateItemData);
271 else if (m_updateTaskItem)
273 CompleteTaskItemUpdate(m_updateTaskItemData);
275 else if (m_asset.Local)
277 m_Scene.AssetService.Store(m_asset);
282 "[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}",
283 m_asset.FullID, m_transactionID);
285 if (m_dumpAssetToFile)
287 DateTime now = DateTime.Now;
289 String.Format(
"{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat",
290 now.Year, now.Month, now.Day, now.Hour, now.Minute,
291 now.Second, m_asset.Name, m_asset.Type);
292 SaveAssetToFile(filename, m_asset.Data);
296 private void SaveAssetToFile(
string filename, byte[] data)
298 string assetPath =
"UserAssets";
299 if (!Directory.Exists(assetPath))
301 Directory.CreateDirectory(assetPath);
303 FileStream fs = File.Create(Path.Combine(assetPath, filename));
304 BinaryWriter bw =
new BinaryWriter(fs);
311 UUID folderID, uint callbackID,
312 string description,
string name, sbyte invType,
313 sbyte type, byte wearableType, uint nextOwnerMask)
315 InventFolder = folderID;
317 m_description = description;
319 this.invType = invType;
320 this.wearableType = wearableType;
321 nextPerm = nextOwnerMask;
323 m_asset.Description = description;
329 if (m_uploadState == UploadState.Complete)
331 CompleteCreateItem(callbackID);
336 m_createItemCallback = callbackID;
346 m_asset.Name = item.Name;
347 m_asset.Description = item.Description;
361 if (m_uploadState == UploadState.Complete)
363 CompleteItemUpdate(item);
368 if (m_asset.FullID !=
UUID.Zero)
373 item.AssetID = m_asset.FullID;
374 m_Scene.InventoryService.UpdateItem(item);
383 m_updateItemData = item;
393 m_asset.Name = taskItem.Name;
394 m_asset.Description = taskItem.Description;
395 m_asset.Type = (sbyte)taskItem.
Type;
396 taskItem.
AssetID = m_asset.FullID;
398 if (m_uploadState == UploadState.Complete)
400 CompleteTaskItemUpdate(taskItem);
404 m_updateTaskItem =
true;
405 m_updateTaskItemData = taskItem;
421 m_Scene.AssetService.Store(m_asset);
422 if (m_asset.FullID !=
UUID.Zero)
424 item.AssetID = m_asset.FullID;
425 m_Scene.InventoryService.UpdateItem(item);
428 ourClient.SendInventoryItemCreateUpdate(item, m_transactionID, 0);
430 m_transactions.RemoveXferUploader(m_transactionID);
432 m_Scene.EventManager.TriggerOnNewInventoryItemUploadComplete(ourClient.AgentId, (AssetType)type, m_asset.FullID, m_asset.Name, 0);
446 m_Scene.AssetService.Store(m_asset);
448 m_transactions.RemoveXferUploader(m_transactionID);
451 private void CompleteCreateItem(uint callbackID)
454 m_Scene.AssetService.Store(m_asset);
457 item.Owner = ourClient.AgentId;
458 item.CreatorId = ourClient.AgentId.ToString();
459 item.ID = UUID.Random();
460 item.AssetID = m_asset.FullID;
461 item.Description = m_description;
463 item.AssetType = type;
464 item.InvType = invType;
465 item.Folder = InventFolder;
467 item.CurrentPermissions = item.BasePermissions;
468 item.GroupPermissions=0;
469 item.EveryOnePermissions=0;
470 item.NextPermissions = nextPerm;
471 item.Flags = (uint) wearableType;
472 item.CreationDate = Util.UnixTimeSinceEpoch();
474 m_log.DebugFormat(
"[XFER]: Created item {0} with asset {1}",
475 item.ID, item.AssetID);
477 if (m_Scene.AddInventoryItem(item))
478 ourClient.SendInventoryItemCreateUpdate(item, m_transactionID, callbackID);
480 ourClient.SendAlertMessage(
"Unable to create inventory item");
482 m_transactions.RemoveXferUploader(m_transactionID);
486 private void ValidateAssets()
492 bool allOk = animSet.Validate(x => {
493 int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, x);
495 if ((perms & required) != required)
501 m_asset.Data = animSet.ToBytes();
504 if (m_asset.Type == (sbyte)AssetType.Clothing ||
505 m_asset.Type == (sbyte)AssetType.Bodypart)
507 string content = System.Text.Encoding.ASCII.GetString(m_asset.Data);
508 string[] lines = content.Split(
new char[] {
'\n'});
510 List<string> validated =
new List<string>();
512 Dictionary<int, UUID> allowed = ExtractTexturesFromOldData();
516 foreach (
string line
in lines)
520 if (line.StartsWith(
"textures "))
522 textures = Convert.ToInt32(line.Substring(9));
525 else if (textures > 0)
527 string[] parts = line.Split(
new char[] {
' '});
530 int id = Convert.ToInt32(parts[0]);
532 if (defaultIDs.Contains(tx) || tx == UUID.Zero ||
533 (allowed.ContainsKey(id) && allowed[
id] == tx))
535 validated.Add(parts[0] +
" " + tx.ToString());
539 int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx);
542 if ((perms & full) != full)
544 m_log.ErrorFormat(
"[ASSET UPLOADER]: REJECTED update with texture {0} from {1} because they do not own the texture", tx, ourClient.AgentId);
545 validated.Add(parts[0] +
" " + UUID.Zero.ToString());
565 string final = String.Join(
"\n", validated.ToArray());
567 m_asset.Data = System.Text.Encoding.ASCII.GetBytes(
final);
577 if (m_uploadState == UploadState.Complete)
591 private Dictionary<int,UUID> ExtractTexturesFromOldData()
593 Dictionary<int,UUID> result =
new Dictionary<int,UUID>();
594 if (m_oldData == null)
597 string content = System.Text.Encoding.ASCII.GetString(m_oldData);
598 string[] lines = content.Split(
new char[] {
'\n'});
602 foreach (
string line
in lines)
606 if (line.StartsWith(
"textures "))
608 textures = Convert.ToInt32(line.Substring(9));
610 else if (textures > 0)
612 string[] parts = line.Split(
new char[] {
' '});
615 int id = Convert.ToInt32(parts[0]);
void RequestUpdateTaskInventoryItem(IClientAPI remoteClient, TaskInventoryItem taskItem)
Represents an item in a task inventory
void SendCompleteMessage()
void SetOldData(byte[] d)
Asset class. All Assets are reference by this class or a class derived from this class ...
void StartUpload(IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, byte[] data, bool storeLocal, bool tempFile)
Start asset transfer from the client
void RequestUpdateInventoryItem(IClientAPI remoteClient, InventoryItemBase item)
bool HandleXferPacket(ulong xferID, uint packetID, byte[] data)
Process transfer data received from the client.
Inventory Item - contains all the properties associated with an individual inventory piece...
AssetXferUploader(AgentAssetTransactions transactions, Scene scene, UUID transactionID, bool dumpAssetToFile)
AssetXferUploader constructor
void RequestCreateInventoryItem(IClientAPI remoteClient, UUID folderID, uint callbackID, string description, string name, sbyte invType, sbyte type, byte wearableType, uint nextOwnerMask)
AssetBase GetAssetData()
Get the asset data uploaded in this transfer.
OpenSim.Framework.PermissionMask PermissionMask
OpenSim.Region.Framework.Scenes.Animation.AnimationSet AnimationSet
Manage asset transactions for a single agent.