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 a7929ba..ec4dfd0 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs | |||
@@ -40,11 +40,21 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
40 | { | 40 | { |
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> | ||
44 | /// Reference to the object that holds this uploader. Used to remove ourselves from it's list if we | ||
45 | /// are performing a delayed update. | ||
46 | /// </summary> | ||
47 | AgentAssetTransactions m_transactions; | ||
48 | |||
43 | private AssetBase m_asset; | 49 | private AssetBase m_asset; |
44 | private UUID InventFolder = UUID.Zero; | 50 | private UUID InventFolder = UUID.Zero; |
45 | private sbyte invType = 0; | 51 | private sbyte invType = 0; |
52 | |||
46 | private bool m_createItem = false; | 53 | private bool m_createItem = false; |
47 | private uint m_createItemCallback = 0; | 54 | private uint m_createItemCallback = 0; |
55 | private bool m_updateItem = false; | ||
56 | private InventoryItemBase m_updateItemData; | ||
57 | |||
48 | private string m_description = String.Empty; | 58 | private string m_description = String.Empty; |
49 | private bool m_dumpAssetToFile; | 59 | private bool m_dumpAssetToFile; |
50 | private bool m_finished = false; | 60 | private bool m_finished = false; |
@@ -58,9 +68,11 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
58 | public ulong XferID; | 68 | public ulong XferID; |
59 | private Scene m_Scene; | 69 | private Scene m_Scene; |
60 | 70 | ||
61 | public AssetXferUploader(Scene scene, bool dumpAssetToFile) | 71 | public AssetXferUploader(AgentAssetTransactions transactions, Scene scene, UUID assetID, bool dumpAssetToFile) |
62 | { | 72 | { |
73 | m_transactions = transactions; | ||
63 | m_Scene = scene; | 74 | m_Scene = scene; |
75 | m_asset = new AssetBase() { FullID = assetID }; | ||
64 | m_dumpAssetToFile = dumpAssetToFile; | 76 | m_dumpAssetToFile = dumpAssetToFile; |
65 | } | 77 | } |
66 | 78 | ||
@@ -73,6 +85,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
73 | /// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns> | 85 | /// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns> |
74 | public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data) | 86 | public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data) |
75 | { | 87 | { |
88 | // m_log.DebugFormat( | ||
89 | // "[ASSET XFER UPLOADER]: Received packet {0} for xfer {1} (data length {2})", | ||
90 | // packetID, xferID, data.Length); | ||
91 | |||
76 | if (XferID == xferID) | 92 | if (XferID == xferID) |
77 | { | 93 | { |
78 | if (m_asset.Data.Length > 1) | 94 | if (m_asset.Data.Length > 1) |
@@ -107,16 +123,20 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
107 | /// <param name="xferID"></param> | 123 | /// <param name="xferID"></param> |
108 | /// <param name="packetID"></param> | 124 | /// <param name="packetID"></param> |
109 | /// <param name="data"></param> | 125 | /// <param name="data"></param> |
110 | /// <returns>True if the transfer is complete, false otherwise</returns> | 126 | public void Initialise(IClientAPI remoteClient, UUID assetID, |
111 | public bool Initialise(IClientAPI remoteClient, UUID assetID, | ||
112 | UUID transaction, sbyte type, byte[] data, bool storeLocal, | 127 | UUID transaction, sbyte type, byte[] data, bool storeLocal, |
113 | bool tempFile) | 128 | bool tempFile) |
114 | { | 129 | { |
130 | // 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}", | ||
132 | // remoteClient.Name, assetID, transaction, type, storeLocal, tempFile, data.Length); | ||
133 | |||
115 | ourClient = remoteClient; | 134 | ourClient = remoteClient; |
116 | m_asset = new AssetBase(assetID, "blank", type, | 135 | m_asset.Name = "blank"; |
117 | remoteClient.AgentId.ToString()); | ||
118 | m_asset.Data = data; | ||
119 | m_asset.Description = "empty"; | 136 | m_asset.Description = "empty"; |
137 | m_asset.Type = type; | ||
138 | m_asset.CreatorID = remoteClient.AgentId.ToString(); | ||
139 | m_asset.Data = data; | ||
120 | m_asset.Local = storeLocal; | 140 | m_asset.Local = storeLocal; |
121 | m_asset.Temporary = tempFile; | 141 | m_asset.Temporary = tempFile; |
122 | 142 | ||
@@ -126,21 +146,22 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
126 | if (m_asset.Data.Length > 2) | 146 | if (m_asset.Data.Length > 2) |
127 | { | 147 | { |
128 | SendCompleteMessage(); | 148 | SendCompleteMessage(); |
129 | return true; | ||
130 | } | 149 | } |
131 | else | 150 | else |
132 | { | 151 | { |
133 | RequestStartXfer(); | 152 | RequestStartXfer(); |
134 | } | 153 | } |
135 | |||
136 | return false; | ||
137 | } | 154 | } |
138 | 155 | ||
139 | protected void RequestStartXfer() | 156 | protected void RequestStartXfer() |
140 | { | 157 | { |
141 | XferID = Util.GetNextXferID(); | 158 | XferID = Util.GetNextXferID(); |
142 | ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, | 159 | |
143 | 0, new byte[0]); | 160 | // m_log.DebugFormat( |
161 | // "[ASSET XFER UPLOADER]: Requesting Xfer of asset {0}, type {1}, transfer id {2} from {3}", | ||
162 | // m_asset.FullID, m_asset.Type, XferID, ourClient.Name); | ||
163 | |||
164 | ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, 0, new byte[0]); | ||
144 | } | 165 | } |
145 | 166 | ||
146 | protected void SendCompleteMessage() | 167 | protected void SendCompleteMessage() |
@@ -148,18 +169,32 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
148 | ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, | 169 | ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, |
149 | m_asset.FullID); | 170 | m_asset.FullID); |
150 | 171 | ||
151 | m_finished = true; | 172 | // We must lock in order to avoid a race with a separate thread dealing with an inventory item or create |
152 | if (m_createItem) | 173 | // message from other client UDP. |
153 | { | 174 | lock (this) |
154 | DoCreateItem(m_createItemCallback); | ||
155 | } | ||
156 | else if (m_storeLocal) | ||
157 | { | 175 | { |
158 | m_Scene.AssetService.Store(m_asset); | 176 | m_finished = true; |
177 | if (m_createItem) | ||
178 | { | ||
179 | DoCreateItem(m_createItemCallback); | ||
180 | } | ||
181 | else if (m_updateItem) | ||
182 | { | ||
183 | StoreAssetForItemUpdate(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 | } | ||
190 | else if (m_storeLocal) | ||
191 | { | ||
192 | m_Scene.AssetService.Store(m_asset); | ||
193 | } | ||
159 | } | 194 | } |
160 | 195 | ||
161 | m_log.DebugFormat( | 196 | m_log.DebugFormat( |
162 | "[ASSET TRANSACTIONS]: Uploaded asset {0} for transaction {1}", | 197 | "[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}", |
163 | m_asset.FullID, TransactionID); | 198 | m_asset.FullID, TransactionID); |
164 | 199 | ||
165 | if (m_dumpAssetToFile) | 200 | if (m_dumpAssetToFile) |
@@ -205,18 +240,66 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
205 | m_asset.Description = description; | 240 | m_asset.Description = description; |
206 | m_asset.Type = type; | 241 | m_asset.Type = type; |
207 | 242 | ||
243 | // We must lock to avoid a race with a separate thread uploading the asset. | ||
244 | lock (this) | ||
245 | { | ||
246 | if (m_finished) | ||
247 | { | ||
248 | DoCreateItem(callbackID); | ||
249 | } | ||
250 | else | ||
251 | { | ||
252 | m_createItem = true; //set flag so the inventory item is created when upload is complete | ||
253 | m_createItemCallback = callbackID; | ||
254 | } | ||
255 | } | ||
256 | } | ||
257 | } | ||
258 | |||
259 | public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item) | ||
260 | { | ||
261 | // We must lock to avoid a race with a separate thread uploading the asset. | ||
262 | lock (this) | ||
263 | { | ||
264 | m_asset.Name = item.Name; | ||
265 | m_asset.Description = item.Description; | ||
266 | m_asset.Type = (sbyte)item.AssetType; | ||
267 | |||
268 | // We must always store the item at this point even if the asset hasn't finished uploading, in order | ||
269 | // to avoid a race condition when the appearance module retrieves the item to set the asset id in | ||
270 | // the AvatarAppearance structure. | ||
271 | item.AssetID = m_asset.FullID; | ||
272 | m_Scene.InventoryService.UpdateItem(item); | ||
273 | |||
208 | if (m_finished) | 274 | if (m_finished) |
209 | { | 275 | { |
210 | DoCreateItem(callbackID); | 276 | StoreAssetForItemUpdate(item); |
211 | } | 277 | } |
212 | else | 278 | else |
213 | { | 279 | { |
214 | m_createItem = true; //set flag so the inventory item is created when upload is complete | 280 | // m_log.DebugFormat( |
215 | m_createItemCallback = callbackID; | 281 | // "[ASSET XFER UPLOADER]: Holding update inventory item request {0} for {1} pending completion of asset xfer for transaction {2}", |
282 | // item.Name, remoteClient.Name, transactionID); | ||
283 | |||
284 | m_updateItem = true; | ||
285 | m_updateItemData = item; | ||
216 | } | 286 | } |
217 | } | 287 | } |
218 | } | 288 | } |
219 | 289 | ||
290 | /// <summary> | ||
291 | /// Store the asset for the given item. | ||
292 | /// </summary> | ||
293 | /// <param name="item"></param> | ||
294 | private void StoreAssetForItemUpdate(InventoryItemBase item) | ||
295 | { | ||
296 | // m_log.DebugFormat( | ||
297 | // "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}", | ||
298 | // m_asset.FullID, item.Name, ourClient.Name); | ||
299 | |||
300 | m_Scene.AssetService.Store(m_asset); | ||
301 | } | ||
302 | |||
220 | private void DoCreateItem(uint callbackID) | 303 | private void DoCreateItem(uint callbackID) |
221 | { | 304 | { |
222 | m_Scene.AssetService.Store(m_asset); | 305 | m_Scene.AssetService.Store(m_asset); |