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.cs233
1 files changed, 156 insertions, 77 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
index ec4dfd0..8add4bb 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
@@ -41,38 +41,74 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
41 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 41 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
42 42
43 /// <summary> 43 /// <summary>
44 /// Upload state.
45 /// </summary>
46 /// <remarks>
47 /// New -> Uploading -> Complete
48 /// </remarks>
49 private enum UploadState
50 {
51 New,
52 Uploading,
53 Complete
54 }
55
56 /// <summary>
44 /// Reference to the object that holds this uploader. Used to remove ourselves from it's list if we 57 /// Reference to the object that holds this uploader. Used to remove ourselves from it's list if we
45 /// are performing a delayed update. 58 /// are performing a delayed update.
46 /// </summary> 59 /// </summary>
47 AgentAssetTransactions m_transactions; 60 AgentAssetTransactions m_transactions;
48 61
62 private UploadState m_uploadState = UploadState.New;
63
49 private AssetBase m_asset; 64 private AssetBase m_asset;
50 private UUID InventFolder = UUID.Zero; 65 private UUID InventFolder = UUID.Zero;
51 private sbyte invType = 0; 66 private sbyte invType = 0;
52 67
53 private bool m_createItem = false; 68 private bool m_createItem;
54 private uint m_createItemCallback = 0; 69 private uint m_createItemCallback;
55 private bool m_updateItem = false; 70
71 private bool m_updateItem;
56 private InventoryItemBase m_updateItemData; 72 private InventoryItemBase m_updateItemData;
57 73
74 private bool m_updateTaskItem;
75 private TaskInventoryItem m_updateTaskItemData;
76
58 private string m_description = String.Empty; 77 private string m_description = String.Empty;
59 private bool m_dumpAssetToFile; 78 private bool m_dumpAssetToFile;
60 private bool m_finished = false;
61 private string m_name = String.Empty; 79 private string m_name = String.Empty;
62 private bool m_storeLocal; 80// private bool m_storeLocal;
63 private uint nextPerm = 0; 81 private uint nextPerm = 0;
64 private IClientAPI ourClient; 82 private IClientAPI ourClient;
65 private UUID TransactionID = UUID.Zero; 83
84 private UUID m_transactionID;
85
66 private sbyte type = 0; 86 private sbyte type = 0;
67 private byte wearableType = 0; 87 private byte wearableType = 0;
68 public ulong XferID; 88 public ulong XferID;
69 private Scene m_Scene; 89 private Scene m_Scene;
70 90
71 public AssetXferUploader(AgentAssetTransactions transactions, Scene scene, UUID assetID, bool dumpAssetToFile) 91 /// <summary>
92 /// AssetXferUploader constructor
93 /// </summary>
94 /// <param name='transactions'>/param>
95 /// <param name='scene'></param>
96 /// <param name='transactionID'></param>
97 /// <param name='dumpAssetToFile'>
98 /// If true then when the asset is uploaded it is dumped to a file with the format
99 /// String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat",
100 /// now.Year, now.Month, now.Day, now.Hour, now.Minute,
101 /// now.Second, m_asset.Name, m_asset.Type);
102 /// for debugging purposes.
103 /// </param>
104 public AssetXferUploader(
105 AgentAssetTransactions transactions, Scene scene, UUID transactionID, bool dumpAssetToFile)
72 { 106 {
107 m_asset = new AssetBase();
108
73 m_transactions = transactions; 109 m_transactions = transactions;
110 m_transactionID = transactionID;
74 m_Scene = scene; 111 m_Scene = scene;
75 m_asset = new AssetBase() { FullID = assetID };
76 m_dumpAssetToFile = dumpAssetToFile; 112 m_dumpAssetToFile = dumpAssetToFile;
77 } 113 }
78 114
@@ -118,30 +154,50 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
118 } 154 }
119 155
120 /// <summary> 156 /// <summary>
121 /// Initialise asset transfer from the client 157 /// Start asset transfer from the client
122 /// </summary> 158 /// </summary>
123 /// <param name="xferID"></param> 159 /// <param name="remoteClient"></param>
124 /// <param name="packetID"></param> 160 /// <param name="assetID"></param>
125 /// <param name="data"></param> 161 /// <param name="transaction"></param>
126 public void Initialise(IClientAPI remoteClient, UUID assetID, 162 /// <param name="type"></param>
127 UUID transaction, sbyte type, byte[] data, bool storeLocal, 163 /// <param name="data">
128 bool tempFile) 164 /// Optional data. If present then the asset is created immediately with this data
165 /// rather than requesting an upload from the client. The data must be longer than 2 bytes.
166 /// </param>
167 /// <param name="storeLocal"></param>
168 /// <param name="tempFile"></param>
169 public void StartUpload(
170 IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, byte[] data, bool storeLocal,
171 bool tempFile)
129 { 172 {
130// m_log.DebugFormat( 173// m_log.DebugFormat(
131// "[ASSET XFER UPLOADER]: Initialised xfer from {0}, asset {1}, transaction {2}, type {3}, storeLocal {4}, tempFile {5}, already received data length {6}", 174// "[ASSET XFER UPLOADER]: Initialised xfer from {0}, asset {1}, transaction {2}, type {3}, storeLocal {4}, tempFile {5}, already received data length {6}",
132// remoteClient.Name, assetID, transaction, type, storeLocal, tempFile, data.Length); 175// remoteClient.Name, assetID, transaction, type, storeLocal, tempFile, data.Length);
133 176
177 lock (this)
178 {
179 if (m_uploadState != UploadState.New)
180 {
181 m_log.WarnFormat(
182 "[ASSET XFER UPLOADER]: Tried to start upload of asset {0}, transaction {1} for {2} but this is already in state {3}. Aborting.",
183 assetID, transaction, remoteClient.Name, m_uploadState);
184
185 return;
186 }
187
188 m_uploadState = UploadState.Uploading;
189 }
190
134 ourClient = remoteClient; 191 ourClient = remoteClient;
135 m_asset.Name = "blank"; 192
136 m_asset.Description = "empty"; 193 m_asset.FullID = assetID;
137 m_asset.Type = type; 194 m_asset.Type = type;
138 m_asset.CreatorID = remoteClient.AgentId.ToString(); 195 m_asset.CreatorID = remoteClient.AgentId.ToString();
139 m_asset.Data = data; 196 m_asset.Data = data;
140 m_asset.Local = storeLocal; 197 m_asset.Local = storeLocal;
141 m_asset.Temporary = tempFile; 198 m_asset.Temporary = tempFile;
142 199
143 TransactionID = transaction; 200// m_storeLocal = storeLocal;
144 m_storeLocal = storeLocal;
145 201
146 if (m_asset.Data.Length > 2) 202 if (m_asset.Data.Length > 2)
147 { 203 {
@@ -166,36 +222,35 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
166 222
167 protected void SendCompleteMessage() 223 protected void SendCompleteMessage()
168 { 224 {
169 ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true,
170 m_asset.FullID);
171
172 // We must lock in order to avoid a race with a separate thread dealing with an inventory item or create 225 // We must lock in order to avoid a race with a separate thread dealing with an inventory item or create
173 // message from other client UDP. 226 // message from other client UDP.
174 lock (this) 227 lock (this)
175 { 228 {
176 m_finished = true; 229 m_uploadState = UploadState.Complete;
230
231 ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, m_asset.FullID);
232
177 if (m_createItem) 233 if (m_createItem)
178 { 234 {
179 DoCreateItem(m_createItemCallback); 235 CompleteCreateItem(m_createItemCallback);
180 } 236 }
181 else if (m_updateItem) 237 else if (m_updateItem)
182 { 238 {
183 StoreAssetForItemUpdate(m_updateItemData); 239 CompleteItemUpdate(m_updateItemData);
184
185 // Remove ourselves from the list of transactions if completion was delayed until the transaction
186 // was complete.
187 // TODO: Should probably do the same for create item.
188 m_transactions.RemoveXferUploader(TransactionID);
189 } 240 }
190 else if (m_storeLocal) 241 else if (m_updateTaskItem)
191 { 242 {
192 m_Scene.AssetService.Store(m_asset); 243 CompleteTaskItemUpdate(m_updateTaskItemData);
193 } 244 }
245// else if (m_storeLocal)
246// {
247// m_Scene.AssetService.Store(m_asset);
248// }
194 } 249 }
195 250
196 m_log.DebugFormat( 251 m_log.DebugFormat(
197 "[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}", 252 "[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}",
198 m_asset.FullID, TransactionID); 253 m_asset.FullID, m_transactionID);
199 254
200 if (m_dumpAssetToFile) 255 if (m_dumpAssetToFile)
201 { 256 {
@@ -223,40 +278,37 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
223 } 278 }
224 279
225 public void RequestCreateInventoryItem(IClientAPI remoteClient, 280 public void RequestCreateInventoryItem(IClientAPI remoteClient,
226 UUID transactionID, UUID folderID, uint callbackID, 281 UUID folderID, uint callbackID,
227 string description, string name, sbyte invType, 282 string description, string name, sbyte invType,
228 sbyte type, byte wearableType, uint nextOwnerMask) 283 sbyte type, byte wearableType, uint nextOwnerMask)
229 { 284 {
230 if (TransactionID == transactionID) 285 InventFolder = folderID;
286 m_name = name;
287 m_description = description;
288 this.type = type;
289 this.invType = invType;
290 this.wearableType = wearableType;
291 nextPerm = nextOwnerMask;
292 m_asset.Name = name;
293 m_asset.Description = description;
294 m_asset.Type = type;
295
296 // We must lock to avoid a race with a separate thread uploading the asset.
297 lock (this)
231 { 298 {
232 InventFolder = folderID; 299 if (m_uploadState == UploadState.Complete)
233 m_name = name;
234 m_description = description;
235 this.type = type;
236 this.invType = invType;
237 this.wearableType = wearableType;
238 nextPerm = nextOwnerMask;
239 m_asset.Name = name;
240 m_asset.Description = description;
241 m_asset.Type = type;
242
243 // We must lock to avoid a race with a separate thread uploading the asset.
244 lock (this)
245 { 300 {
246 if (m_finished) 301 CompleteCreateItem(callbackID);
247 { 302 }
248 DoCreateItem(callbackID); 303 else
249 } 304 {
250 else 305 m_createItem = true; //set flag so the inventory item is created when upload is complete
251 { 306 m_createItemCallback = callbackID;
252 m_createItem = true; //set flag so the inventory item is created when upload is complete
253 m_createItemCallback = callbackID;
254 }
255 } 307 }
256 } 308 }
257 } 309 }
258 310
259 public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item) 311 public void RequestUpdateInventoryItem(IClientAPI remoteClient, InventoryItemBase item)
260 { 312 {
261 // We must lock to avoid a race with a separate thread uploading the asset. 313 // We must lock to avoid a race with a separate thread uploading the asset.
262 lock (this) 314 lock (this)
@@ -271,9 +323,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
271 item.AssetID = m_asset.FullID; 323 item.AssetID = m_asset.FullID;
272 m_Scene.InventoryService.UpdateItem(item); 324 m_Scene.InventoryService.UpdateItem(item);
273 325
274 if (m_finished) 326 if (m_uploadState == UploadState.Complete)
275 { 327 {
276 StoreAssetForItemUpdate(item); 328 CompleteItemUpdate(item);
277 } 329 }
278 else 330 else
279 { 331 {
@@ -287,20 +339,59 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
287 } 339 }
288 } 340 }
289 341
342 public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient, TaskInventoryItem taskItem)
343 {
344 // We must lock to avoid a race with a separate thread uploading the asset.
345 lock (this)
346 {
347 m_asset.Name = taskItem.Name;
348 m_asset.Description = taskItem.Description;
349 m_asset.Type = (sbyte)taskItem.Type;
350 taskItem.AssetID = m_asset.FullID;
351
352 if (m_uploadState == UploadState.Complete)
353 {
354 CompleteTaskItemUpdate(taskItem);
355 }
356 else
357 {
358 m_updateTaskItem = true;
359 m_updateTaskItemData = taskItem;
360 }
361 }
362 }
363
290 /// <summary> 364 /// <summary>
291 /// Store the asset for the given item. 365 /// Store the asset for the given item when it has been uploaded.
292 /// </summary> 366 /// </summary>
293 /// <param name="item"></param> 367 /// <param name="item"></param>
294 private void StoreAssetForItemUpdate(InventoryItemBase item) 368 private void CompleteItemUpdate(InventoryItemBase item)
295 { 369 {
296// m_log.DebugFormat( 370// m_log.DebugFormat(
297// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}", 371// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}",
298// m_asset.FullID, item.Name, ourClient.Name); 372// m_asset.FullID, item.Name, ourClient.Name);
299 373
300 m_Scene.AssetService.Store(m_asset); 374 m_Scene.AssetService.Store(m_asset);
375
376 m_transactions.RemoveXferUploader(m_transactionID);
301 } 377 }
302 378
303 private void DoCreateItem(uint callbackID) 379 /// <summary>
380 /// Store the asset for the given task item when it has been uploaded.
381 /// </summary>
382 /// <param name="taskItem"></param>
383 private void CompleteTaskItemUpdate(TaskInventoryItem taskItem)
384 {
385// m_log.DebugFormat(
386// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier task item update for {1} for {2}",
387// m_asset.FullID, taskItem.Name, ourClient.Name);
388
389 m_Scene.AssetService.Store(m_asset);
390
391 m_transactions.RemoveXferUploader(m_transactionID);
392 }
393
394 private void CompleteCreateItem(uint callbackID)
304 { 395 {
305 m_Scene.AssetService.Store(m_asset); 396 m_Scene.AssetService.Store(m_asset);
306 397
@@ -326,20 +417,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
326 ourClient.SendInventoryItemCreateUpdate(item, callbackID); 417 ourClient.SendInventoryItemCreateUpdate(item, callbackID);
327 else 418 else
328 ourClient.SendAlertMessage("Unable to create inventory item"); 419 ourClient.SendAlertMessage("Unable to create inventory item");
329 }
330
331 /// <summary>
332 /// Get the asset data uploaded in this transfer.
333 /// </summary>
334 /// <returns>null if the asset has not finished uploading</returns>
335 public AssetBase GetAssetData()
336 {
337 if (m_finished)
338 {
339 return m_asset;
340 }
341 420
342 return null; 421 m_transactions.RemoveXferUploader(m_transactionID);
343 } 422 }
344 } 423 }
345} 424} \ No newline at end of file