aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs')
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs253
1 files changed, 177 insertions, 76 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
index 4cedfe6..0aa4693 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
@@ -49,39 +49,75 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 50
51 /// <summary> 51 /// <summary>
52 /// Upload state.
53 /// </summary>
54 /// <remarks>
55 /// New -> Uploading -> Complete
56 /// </remarks>
57 private enum UploadState
58 {
59 New,
60 Uploading,
61 Complete
62 }
63
64 /// <summary>
52 /// Reference to the object that holds this uploader. Used to remove ourselves from it's list if we 65 /// Reference to the object that holds this uploader. Used to remove ourselves from it's list if we
53 /// are performing a delayed update. 66 /// are performing a delayed update.
54 /// </summary> 67 /// </summary>
55 AgentAssetTransactions m_transactions; 68 AgentAssetTransactions m_transactions;
56 69
70 private UploadState m_uploadState = UploadState.New;
71
57 private AssetBase m_asset; 72 private AssetBase m_asset;
58 private UUID InventFolder = UUID.Zero; 73 private UUID InventFolder = UUID.Zero;
59 private sbyte invType = 0; 74 private sbyte invType = 0;
60 75
61 private bool m_createItem = false; 76 private bool m_createItem;
62 private uint m_createItemCallback = 0; 77 private uint m_createItemCallback;
63 private bool m_updateItem = false; 78
79 private bool m_updateItem;
64 private InventoryItemBase m_updateItemData; 80 private InventoryItemBase m_updateItemData;
65 81
82 private bool m_updateTaskItem;
83 private TaskInventoryItem m_updateTaskItemData;
84
66 private string m_description = String.Empty; 85 private string m_description = String.Empty;
67 private bool m_dumpAssetToFile; 86 private bool m_dumpAssetToFile;
68 private bool m_finished = false;
69 private string m_name = String.Empty; 87 private string m_name = String.Empty;
70 private bool m_storeLocal; 88// private bool m_storeLocal;
71 private uint nextPerm = 0; 89 private uint nextPerm = 0;
72 private IClientAPI ourClient; 90 private IClientAPI ourClient;
73 private UUID TransactionID = UUID.Zero; 91
92 private UUID m_transactionID;
93
74 private sbyte type = 0; 94 private sbyte type = 0;
75 private byte wearableType = 0; 95 private byte wearableType = 0;
76 private byte[] m_oldData = null; 96 private byte[] m_oldData = null;
77 public ulong XferID; 97 public ulong XferID;
78 private Scene m_Scene; 98 private Scene m_Scene;
79 99
80 public AssetXferUploader(AgentAssetTransactions transactions, Scene scene, UUID assetID, bool dumpAssetToFile) 100 /// <summary>
101 /// AssetXferUploader constructor
102 /// </summary>
103 /// <param name='transactions'>/param>
104 /// <param name='scene'></param>
105 /// <param name='transactionID'></param>
106 /// <param name='dumpAssetToFile'>
107 /// If true then when the asset is uploaded it is dumped to a file with the format
108 /// String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat",
109 /// now.Year, now.Month, now.Day, now.Hour, now.Minute,
110 /// now.Second, m_asset.Name, m_asset.Type);
111 /// for debugging purposes.
112 /// </param>
113 public AssetXferUploader(
114 AgentAssetTransactions transactions, Scene scene, UUID transactionID, bool dumpAssetToFile)
81 { 115 {
116 m_asset = new AssetBase();
117
82 m_transactions = transactions; 118 m_transactions = transactions;
119 m_transactionID = transactionID;
83 m_Scene = scene; 120 m_Scene = scene;
84 m_asset = new AssetBase() { FullID = assetID };
85 m_dumpAssetToFile = dumpAssetToFile; 121 m_dumpAssetToFile = dumpAssetToFile;
86 } 122 }
87 123
@@ -100,18 +136,27 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
100 136
101 if (XferID == xferID) 137 if (XferID == xferID)
102 { 138 {
103 if (m_asset.Data.Length > 1) 139 lock (this)
104 {
105 byte[] destinationArray = new byte[m_asset.Data.Length + data.Length];
106 Array.Copy(m_asset.Data, 0, destinationArray, 0, m_asset.Data.Length);
107 Array.Copy(data, 0, destinationArray, m_asset.Data.Length, data.Length);
108 m_asset.Data = destinationArray;
109 }
110 else
111 { 140 {
112 byte[] buffer2 = new byte[data.Length - 4]; 141 int assetLength = m_asset.Data.Length;
113 Array.Copy(data, 4, buffer2, 0, data.Length - 4); 142 int dataLength = data.Length;
114 m_asset.Data = buffer2; 143
144 if (m_asset.Data.Length > 1)
145 {
146 byte[] destinationArray = new byte[assetLength + dataLength];
147 Array.Copy(m_asset.Data, 0, destinationArray, 0, assetLength);
148 Array.Copy(data, 0, destinationArray, assetLength, dataLength);
149 m_asset.Data = destinationArray;
150 }
151 else
152 {
153 if (dataLength > 4)
154 {
155 byte[] buffer2 = new byte[dataLength - 4];
156 Array.Copy(data, 4, buffer2, 0, dataLength - 4);
157 m_asset.Data = buffer2;
158 }
159 }
115 } 160 }
116 161
117 ourClient.SendConfirmXfer(xferID, packetID); 162 ourClient.SendConfirmXfer(xferID, packetID);
@@ -127,30 +172,50 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
127 } 172 }
128 173
129 /// <summary> 174 /// <summary>
130 /// Initialise asset transfer from the client 175 /// Start asset transfer from the client
131 /// </summary> 176 /// </summary>
132 /// <param name="xferID"></param> 177 /// <param name="remoteClient"></param>
133 /// <param name="packetID"></param> 178 /// <param name="assetID"></param>
134 /// <param name="data"></param> 179 /// <param name="transaction"></param>
135 public void Initialise(IClientAPI remoteClient, UUID assetID, 180 /// <param name="type"></param>
136 UUID transaction, sbyte type, byte[] data, bool storeLocal, 181 /// <param name="data">
137 bool tempFile) 182 /// Optional data. If present then the asset is created immediately with this data
183 /// rather than requesting an upload from the client. The data must be longer than 2 bytes.
184 /// </param>
185 /// <param name="storeLocal"></param>
186 /// <param name="tempFile"></param>
187 public void StartUpload(
188 IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, byte[] data, bool storeLocal,
189 bool tempFile)
138 { 190 {
139// m_log.DebugFormat( 191// m_log.DebugFormat(
140// "[ASSET XFER UPLOADER]: Initialised xfer from {0}, asset {1}, transaction {2}, type {3}, storeLocal {4}, tempFile {5}, already received data length {6}", 192// "[ASSET XFER UPLOADER]: Initialised xfer from {0}, asset {1}, transaction {2}, type {3}, storeLocal {4}, tempFile {5}, already received data length {6}",
141// remoteClient.Name, assetID, transaction, type, storeLocal, tempFile, data.Length); 193// remoteClient.Name, assetID, transaction, type, storeLocal, tempFile, data.Length);
142 194
195 lock (this)
196 {
197 if (m_uploadState != UploadState.New)
198 {
199 m_log.WarnFormat(
200 "[ASSET XFER UPLOADER]: Tried to start upload of asset {0}, transaction {1} for {2} but this is already in state {3}. Aborting.",
201 assetID, transaction, remoteClient.Name, m_uploadState);
202
203 return;
204 }
205
206 m_uploadState = UploadState.Uploading;
207 }
208
143 ourClient = remoteClient; 209 ourClient = remoteClient;
144 m_asset.Name = "blank"; 210
145 m_asset.Description = "empty"; 211 m_asset.FullID = assetID;
146 m_asset.Type = type; 212 m_asset.Type = type;
147 m_asset.CreatorID = remoteClient.AgentId.ToString(); 213 m_asset.CreatorID = remoteClient.AgentId.ToString();
148 m_asset.Data = data; 214 m_asset.Data = data;
149 m_asset.Local = storeLocal; 215 m_asset.Local = storeLocal;
150 m_asset.Temporary = tempFile; 216 m_asset.Temporary = tempFile;
151 217
152 TransactionID = transaction; 218// m_storeLocal = storeLocal;
153 m_storeLocal = storeLocal;
154 219
155 if (m_asset.Data.Length > 2) 220 if (m_asset.Data.Length > 2)
156 { 221 {
@@ -175,36 +240,35 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
175 240
176 protected void SendCompleteMessage() 241 protected void SendCompleteMessage()
177 { 242 {
178 ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true,
179 m_asset.FullID);
180
181 // We must lock in order to avoid a race with a separate thread dealing with an inventory item or create 243 // We must lock in order to avoid a race with a separate thread dealing with an inventory item or create
182 // message from other client UDP. 244 // message from other client UDP.
183 lock (this) 245 lock (this)
184 { 246 {
185 m_finished = true; 247 m_uploadState = UploadState.Complete;
248
249 ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, m_asset.FullID);
250
186 if (m_createItem) 251 if (m_createItem)
187 { 252 {
188 DoCreateItem(m_createItemCallback); 253 CompleteCreateItem(m_createItemCallback);
189 } 254 }
190 else if (m_updateItem) 255 else if (m_updateItem)
191 { 256 {
192 StoreAssetForItemUpdate(m_updateItemData); 257 CompleteItemUpdate(m_updateItemData);
193
194 // Remove ourselves from the list of transactions if completion was delayed until the transaction
195 // was complete.
196 // TODO: Should probably do the same for create item.
197 m_transactions.RemoveXferUploader(TransactionID);
198 } 258 }
199 else if (m_storeLocal) 259 else if (m_updateTaskItem)
200 { 260 {
201 m_Scene.AssetService.Store(m_asset); 261 CompleteTaskItemUpdate(m_updateTaskItemData);
202 } 262 }
263// else if (m_storeLocal)
264// {
265// m_Scene.AssetService.Store(m_asset);
266// }
203 } 267 }
204 268
205 m_log.DebugFormat( 269 m_log.DebugFormat(
206 "[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}", 270 "[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}",
207 m_asset.FullID, TransactionID); 271 m_asset.FullID, m_transactionID);
208 272
209 if (m_dumpAssetToFile) 273 if (m_dumpAssetToFile)
210 { 274 {
@@ -232,40 +296,37 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
232 } 296 }
233 297
234 public void RequestCreateInventoryItem(IClientAPI remoteClient, 298 public void RequestCreateInventoryItem(IClientAPI remoteClient,
235 UUID transactionID, UUID folderID, uint callbackID, 299 UUID folderID, uint callbackID,
236 string description, string name, sbyte invType, 300 string description, string name, sbyte invType,
237 sbyte type, byte wearableType, uint nextOwnerMask) 301 sbyte type, byte wearableType, uint nextOwnerMask)
238 { 302 {
239 if (TransactionID == transactionID) 303 InventFolder = folderID;
304 m_name = name;
305 m_description = description;
306 this.type = type;
307 this.invType = invType;
308 this.wearableType = wearableType;
309 nextPerm = nextOwnerMask;
310 m_asset.Name = name;
311 m_asset.Description = description;
312 m_asset.Type = type;
313
314 // We must lock to avoid a race with a separate thread uploading the asset.
315 lock (this)
240 { 316 {
241 InventFolder = folderID; 317 if (m_uploadState == UploadState.Complete)
242 m_name = name;
243 m_description = description;
244 this.type = type;
245 this.invType = invType;
246 this.wearableType = wearableType;
247 nextPerm = nextOwnerMask;
248 m_asset.Name = name;
249 m_asset.Description = description;
250 m_asset.Type = type;
251
252 // We must lock to avoid a race with a separate thread uploading the asset.
253 lock (this)
254 { 318 {
255 if (m_finished) 319 CompleteCreateItem(callbackID);
256 { 320 }
257 DoCreateItem(callbackID); 321 else
258 } 322 {
259 else 323 m_createItem = true; //set flag so the inventory item is created when upload is complete
260 { 324 m_createItemCallback = callbackID;
261 m_createItem = true; //set flag so the inventory item is created when upload is complete
262 m_createItemCallback = callbackID;
263 }
264 } 325 }
265 } 326 }
266 } 327 }
267 328
268 public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item) 329 public void RequestUpdateInventoryItem(IClientAPI remoteClient, InventoryItemBase item)
269 { 330 {
270 // We must lock to avoid a race with a separate thread uploading the asset. 331 // We must lock to avoid a race with a separate thread uploading the asset.
271 lock (this) 332 lock (this)
@@ -280,9 +341,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
280 item.AssetID = m_asset.FullID; 341 item.AssetID = m_asset.FullID;
281 m_Scene.InventoryService.UpdateItem(item); 342 m_Scene.InventoryService.UpdateItem(item);
282 343
283 if (m_finished) 344 if (m_uploadState == UploadState.Complete)
284 { 345 {
285 StoreAssetForItemUpdate(item); 346 CompleteItemUpdate(item);
286 } 347 }
287 else 348 else
288 { 349 {
@@ -296,20 +357,59 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
296 } 357 }
297 } 358 }
298 359
360 public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient, TaskInventoryItem taskItem)
361 {
362 // We must lock to avoid a race with a separate thread uploading the asset.
363 lock (this)
364 {
365 m_asset.Name = taskItem.Name;
366 m_asset.Description = taskItem.Description;
367 m_asset.Type = (sbyte)taskItem.Type;
368 taskItem.AssetID = m_asset.FullID;
369
370 if (m_uploadState == UploadState.Complete)
371 {
372 CompleteTaskItemUpdate(taskItem);
373 }
374 else
375 {
376 m_updateTaskItem = true;
377 m_updateTaskItemData = taskItem;
378 }
379 }
380 }
381
299 /// <summary> 382 /// <summary>
300 /// Store the asset for the given item. 383 /// Store the asset for the given item when it has been uploaded.
301 /// </summary> 384 /// </summary>
302 /// <param name="item"></param> 385 /// <param name="item"></param>
303 private void StoreAssetForItemUpdate(InventoryItemBase item) 386 private void CompleteItemUpdate(InventoryItemBase item)
304 { 387 {
305// m_log.DebugFormat( 388// m_log.DebugFormat(
306// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}", 389// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}",
307// m_asset.FullID, item.Name, ourClient.Name); 390// m_asset.FullID, item.Name, ourClient.Name);
308 391
309 m_Scene.AssetService.Store(m_asset); 392 m_Scene.AssetService.Store(m_asset);
393
394 m_transactions.RemoveXferUploader(m_transactionID);
310 } 395 }
311 396
312 private void DoCreateItem(uint callbackID) 397 /// <summary>
398 /// Store the asset for the given task item when it has been uploaded.
399 /// </summary>
400 /// <param name="taskItem"></param>
401 private void CompleteTaskItemUpdate(TaskInventoryItem taskItem)
402 {
403// m_log.DebugFormat(
404// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier task item update for {1} for {2}",
405// m_asset.FullID, taskItem.Name, ourClient.Name);
406
407 m_Scene.AssetService.Store(m_asset);
408
409 m_transactions.RemoveXferUploader(m_transactionID);
410 }
411
412 private void CompleteCreateItem(uint callbackID)
313 { 413 {
314 ValidateAssets(); 414 ValidateAssets();
315 m_Scene.AssetService.Store(m_asset); 415 m_Scene.AssetService.Store(m_asset);
@@ -339,6 +439,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
339 ourClient.SendInventoryItemCreateUpdate(item, callbackID); 439 ourClient.SendInventoryItemCreateUpdate(item, callbackID);
340 else 440 else
341 ourClient.SendAlertMessage("Unable to create inventory item"); 441 ourClient.SendAlertMessage("Unable to create inventory item");
442
443 m_transactions.RemoveXferUploader(m_transactionID);
342 } 444 }
343 445
344 private void ValidateAssets() 446 private void ValidateAssets()
@@ -416,7 +518,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
416 /// <returns>null if the asset has not finished uploading</returns> 518 /// <returns>null if the asset has not finished uploading</returns>
417 public AssetBase GetAssetData() 519 public AssetBase GetAssetData()
418 { 520 {
419 if (m_finished) 521 if (m_uploadState == UploadState.Complete)
420 { 522 {
421 ValidateAssets(); 523 ValidateAssets();
422 return m_asset; 524 return m_asset;
@@ -469,4 +571,3 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
469 } 571 }
470 } 572 }
471} 573}
472