diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs | 127 |
1 files changed, 105 insertions, 22 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs index a5dcdcc..4cedfe6 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs | |||
@@ -48,11 +48,21 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
48 | }; | 48 | }; |
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> | ||
52 | /// Reference to the object that holds this uploader. Used to remove ourselves from it's list if we | ||
53 | /// are performing a delayed update. | ||
54 | /// </summary> | ||
55 | AgentAssetTransactions m_transactions; | ||
56 | |||
51 | private AssetBase m_asset; | 57 | private AssetBase m_asset; |
52 | private UUID InventFolder = UUID.Zero; | 58 | private UUID InventFolder = UUID.Zero; |
53 | private sbyte invType = 0; | 59 | private sbyte invType = 0; |
60 | |||
54 | private bool m_createItem = false; | 61 | private bool m_createItem = false; |
55 | private uint m_createItemCallback = 0; | 62 | private uint m_createItemCallback = 0; |
63 | private bool m_updateItem = false; | ||
64 | private InventoryItemBase m_updateItemData; | ||
65 | |||
56 | private string m_description = String.Empty; | 66 | private string m_description = String.Empty; |
57 | private bool m_dumpAssetToFile; | 67 | private bool m_dumpAssetToFile; |
58 | private bool m_finished = false; | 68 | private bool m_finished = false; |
@@ -67,9 +77,11 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
67 | public ulong XferID; | 77 | public ulong XferID; |
68 | private Scene m_Scene; | 78 | private Scene m_Scene; |
69 | 79 | ||
70 | public AssetXferUploader(Scene scene, bool dumpAssetToFile) | 80 | public AssetXferUploader(AgentAssetTransactions transactions, Scene scene, UUID assetID, bool dumpAssetToFile) |
71 | { | 81 | { |
82 | m_transactions = transactions; | ||
72 | m_Scene = scene; | 83 | m_Scene = scene; |
84 | m_asset = new AssetBase() { FullID = assetID }; | ||
73 | m_dumpAssetToFile = dumpAssetToFile; | 85 | m_dumpAssetToFile = dumpAssetToFile; |
74 | } | 86 | } |
75 | 87 | ||
@@ -82,6 +94,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
82 | /// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns> | 94 | /// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns> |
83 | public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data) | 95 | public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data) |
84 | { | 96 | { |
97 | // m_log.DebugFormat( | ||
98 | // "[ASSET XFER UPLOADER]: Received packet {0} for xfer {1} (data length {2})", | ||
99 | // packetID, xferID, data.Length); | ||
100 | |||
85 | if (XferID == xferID) | 101 | if (XferID == xferID) |
86 | { | 102 | { |
87 | if (m_asset.Data.Length > 1) | 103 | if (m_asset.Data.Length > 1) |
@@ -116,16 +132,20 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
116 | /// <param name="xferID"></param> | 132 | /// <param name="xferID"></param> |
117 | /// <param name="packetID"></param> | 133 | /// <param name="packetID"></param> |
118 | /// <param name="data"></param> | 134 | /// <param name="data"></param> |
119 | /// <returns>True if the transfer is complete, false otherwise</returns> | 135 | public void Initialise(IClientAPI remoteClient, UUID assetID, |
120 | public bool Initialise(IClientAPI remoteClient, UUID assetID, | ||
121 | UUID transaction, sbyte type, byte[] data, bool storeLocal, | 136 | UUID transaction, sbyte type, byte[] data, bool storeLocal, |
122 | bool tempFile) | 137 | bool tempFile) |
123 | { | 138 | { |
139 | // 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}", | ||
141 | // remoteClient.Name, assetID, transaction, type, storeLocal, tempFile, data.Length); | ||
142 | |||
124 | ourClient = remoteClient; | 143 | ourClient = remoteClient; |
125 | m_asset = new AssetBase(assetID, "blank", type, | 144 | m_asset.Name = "blank"; |
126 | remoteClient.AgentId.ToString()); | ||
127 | m_asset.Data = data; | ||
128 | m_asset.Description = "empty"; | 145 | m_asset.Description = "empty"; |
146 | m_asset.Type = type; | ||
147 | m_asset.CreatorID = remoteClient.AgentId.ToString(); | ||
148 | m_asset.Data = data; | ||
129 | m_asset.Local = storeLocal; | 149 | m_asset.Local = storeLocal; |
130 | m_asset.Temporary = tempFile; | 150 | m_asset.Temporary = tempFile; |
131 | 151 | ||
@@ -135,21 +155,22 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
135 | if (m_asset.Data.Length > 2) | 155 | if (m_asset.Data.Length > 2) |
136 | { | 156 | { |
137 | SendCompleteMessage(); | 157 | SendCompleteMessage(); |
138 | return true; | ||
139 | } | 158 | } |
140 | else | 159 | else |
141 | { | 160 | { |
142 | RequestStartXfer(); | 161 | RequestStartXfer(); |
143 | } | 162 | } |
144 | |||
145 | return false; | ||
146 | } | 163 | } |
147 | 164 | ||
148 | protected void RequestStartXfer() | 165 | protected void RequestStartXfer() |
149 | { | 166 | { |
150 | XferID = Util.GetNextXferID(); | 167 | XferID = Util.GetNextXferID(); |
151 | ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, | 168 | |
152 | 0, new byte[0]); | 169 | // m_log.DebugFormat( |
170 | // "[ASSET XFER UPLOADER]: Requesting Xfer of asset {0}, type {1}, transfer id {2} from {3}", | ||
171 | // m_asset.FullID, m_asset.Type, XferID, ourClient.Name); | ||
172 | |||
173 | ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, 0, new byte[0]); | ||
153 | } | 174 | } |
154 | 175 | ||
155 | protected void SendCompleteMessage() | 176 | protected void SendCompleteMessage() |
@@ -157,18 +178,32 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
157 | ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, | 178 | ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, |
158 | m_asset.FullID); | 179 | m_asset.FullID); |
159 | 180 | ||
160 | m_finished = true; | 181 | // We must lock in order to avoid a race with a separate thread dealing with an inventory item or create |
161 | if (m_createItem) | 182 | // message from other client UDP. |
183 | lock (this) | ||
162 | { | 184 | { |
163 | DoCreateItem(m_createItemCallback); | 185 | m_finished = true; |
164 | } | 186 | if (m_createItem) |
165 | else if (m_storeLocal) | 187 | { |
166 | { | 188 | DoCreateItem(m_createItemCallback); |
167 | m_Scene.AssetService.Store(m_asset); | 189 | } |
190 | else if (m_updateItem) | ||
191 | { | ||
192 | StoreAssetForItemUpdate(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 | } | ||
199 | else if (m_storeLocal) | ||
200 | { | ||
201 | m_Scene.AssetService.Store(m_asset); | ||
202 | } | ||
168 | } | 203 | } |
169 | 204 | ||
170 | m_log.DebugFormat( | 205 | m_log.DebugFormat( |
171 | "[ASSET TRANSACTIONS]: Uploaded asset {0} for transaction {1}", | 206 | "[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}", |
172 | m_asset.FullID, TransactionID); | 207 | m_asset.FullID, TransactionID); |
173 | 208 | ||
174 | if (m_dumpAssetToFile) | 209 | if (m_dumpAssetToFile) |
@@ -214,18 +249,66 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
214 | m_asset.Description = description; | 249 | m_asset.Description = description; |
215 | m_asset.Type = type; | 250 | m_asset.Type = type; |
216 | 251 | ||
252 | // We must lock to avoid a race with a separate thread uploading the asset. | ||
253 | lock (this) | ||
254 | { | ||
255 | if (m_finished) | ||
256 | { | ||
257 | DoCreateItem(callbackID); | ||
258 | } | ||
259 | else | ||
260 | { | ||
261 | m_createItem = true; //set flag so the inventory item is created when upload is complete | ||
262 | m_createItemCallback = callbackID; | ||
263 | } | ||
264 | } | ||
265 | } | ||
266 | } | ||
267 | |||
268 | public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item) | ||
269 | { | ||
270 | // We must lock to avoid a race with a separate thread uploading the asset. | ||
271 | lock (this) | ||
272 | { | ||
273 | m_asset.Name = item.Name; | ||
274 | m_asset.Description = item.Description; | ||
275 | m_asset.Type = (sbyte)item.AssetType; | ||
276 | |||
277 | // We must always store the item at this point even if the asset hasn't finished uploading, in order | ||
278 | // to avoid a race condition when the appearance module retrieves the item to set the asset id in | ||
279 | // the AvatarAppearance structure. | ||
280 | item.AssetID = m_asset.FullID; | ||
281 | m_Scene.InventoryService.UpdateItem(item); | ||
282 | |||
217 | if (m_finished) | 283 | if (m_finished) |
218 | { | 284 | { |
219 | DoCreateItem(callbackID); | 285 | StoreAssetForItemUpdate(item); |
220 | } | 286 | } |
221 | else | 287 | else |
222 | { | 288 | { |
223 | m_createItem = true; //set flag so the inventory item is created when upload is complete | 289 | // m_log.DebugFormat( |
224 | m_createItemCallback = callbackID; | 290 | // "[ASSET XFER UPLOADER]: Holding update inventory item request {0} for {1} pending completion of asset xfer for transaction {2}", |
291 | // item.Name, remoteClient.Name, transactionID); | ||
292 | |||
293 | m_updateItem = true; | ||
294 | m_updateItemData = item; | ||
225 | } | 295 | } |
226 | } | 296 | } |
227 | } | 297 | } |
228 | 298 | ||
299 | /// <summary> | ||
300 | /// Store the asset for the given item. | ||
301 | /// </summary> | ||
302 | /// <param name="item"></param> | ||
303 | private void StoreAssetForItemUpdate(InventoryItemBase item) | ||
304 | { | ||
305 | // m_log.DebugFormat( | ||
306 | // "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}", | ||
307 | // m_asset.FullID, item.Name, ourClient.Name); | ||
308 | |||
309 | m_Scene.AssetService.Store(m_asset); | ||
310 | } | ||
311 | |||
229 | private void DoCreateItem(uint callbackID) | 312 | private void DoCreateItem(uint callbackID) |
230 | { | 313 | { |
231 | ValidateAssets(); | 314 | ValidateAssets(); |