aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs184
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs25
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs127
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs19
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs7
5 files changed, 258 insertions, 104 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
index ff4ec4c..eed7cd5 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
@@ -41,14 +41,13 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
41 /// </summary> 41 /// </summary>
42 public class AgentAssetTransactions 42 public class AgentAssetTransactions
43 { 43 {
44// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 45
46 // Fields 46 // Fields
47 private bool m_dumpAssetsToFile; 47 private bool m_dumpAssetsToFile;
48 private Scene m_Scene; 48 private Scene m_Scene;
49 public UUID UserID; 49 private UUID UserID;
50 public Dictionary<UUID, AssetXferUploader> XferUploaders = 50 private Dictionary<UUID, AssetXferUploader> XferUploaders = new Dictionary<UUID, AssetXferUploader>();
51 new Dictionary<UUID, AssetXferUploader>();
52 51
53 // Methods 52 // Methods
54 public AgentAssetTransactions(UUID agentID, Scene scene, 53 public AgentAssetTransactions(UUID agentID, Scene scene,
@@ -59,36 +58,94 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
59 m_dumpAssetsToFile = dumpAssetsToFile; 58 m_dumpAssetsToFile = dumpAssetsToFile;
60 } 59 }
61 60
62 public AssetXferUploader RequestXferUploader(UUID transactionID) 61 /// <summary>
62 /// Return a xfer uploader if one does not already exist.
63 /// </summary>
64 /// <param name="transactionID"></param>
65 /// <param name="assetID">
66 /// We must transfer the new asset ID into the uploader on creation, otherwise
67 /// we can see race conditions with other threads which can retrieve an item before it is updated with the new
68 /// asset id.
69 /// </param>
70 /// <returns>
71 /// The xfer uploader requested. Null if one is already in existence.
72 /// FIXME: This is a bizarre thing to do, and is probably meant to signal an error condition if multiple
73 /// transfers are made. Needs to be corrected.
74 /// </returns>
75 public AssetXferUploader RequestXferUploader(UUID transactionID, UUID assetID)
63 { 76 {
64 if (!XferUploaders.ContainsKey(transactionID)) 77 lock (XferUploaders)
65 { 78 {
66 AssetXferUploader uploader = new AssetXferUploader(m_Scene, 79 if (!XferUploaders.ContainsKey(transactionID))
67 m_dumpAssetsToFile);
68
69 lock (XferUploaders)
70 { 80 {
81 AssetXferUploader uploader = new AssetXferUploader(this, m_Scene, assetID, m_dumpAssetsToFile);
82
83// m_log.DebugFormat(
84// "[AGENT ASSETS TRANSACTIONS]: Adding asset xfer uploader {0} since it didn't previously exist", transactionID);
85
71 XferUploaders.Add(transactionID, uploader); 86 XferUploaders.Add(transactionID, uploader);
72 }
73 87
74 return uploader; 88 return uploader;
89 }
75 } 90 }
91
92 m_log.WarnFormat("[AGENT ASSETS TRANSACTIONS]: Ignoring request for asset xfer uploader {0} since it already exists", transactionID);
93
76 return null; 94 return null;
77 } 95 }
78 96
79 public void HandleXfer(ulong xferID, uint packetID, byte[] data) 97 public void HandleXfer(ulong xferID, uint packetID, byte[] data)
80 { 98 {
99 AssetXferUploader foundUploader = null;
100
81 lock (XferUploaders) 101 lock (XferUploaders)
82 { 102 {
83 foreach (AssetXferUploader uploader in XferUploaders.Values) 103 foreach (AssetXferUploader uploader in XferUploaders.Values)
84 { 104 {
105// m_log.DebugFormat(
106// "[AGENT ASSETS TRANSACTIONS]: In HandleXfer, inspect xfer upload with xfer id {0}",
107// uploader.XferID);
108
85 if (uploader.XferID == xferID) 109 if (uploader.XferID == xferID)
86 { 110 {
87 uploader.HandleXferPacket(xferID, packetID, data); 111 foundUploader = uploader;
88 break; 112 break;
89 } 113 }
90 } 114 }
91 } 115 }
116
117 if (foundUploader != null)
118 {
119// m_log.DebugFormat(
120// "[AGENT ASSETS TRANSACTIONS]: Found xfer uploader for xfer id {0}, packet id {1}, data length {2}",
121// xferID, packetID, data.Length);
122
123 foundUploader.HandleXferPacket(xferID, packetID, data);
124 }
125 else
126 {
127 m_log.ErrorFormat(
128 "[AGENT ASSET TRANSACTIONS]: Could not find uploader for xfer id {0}, packet id {1}, data length {2}",
129 xferID, packetID, data.Length);
130 }
131 }
132
133 public bool RemoveXferUploader(UUID transactionID)
134 {
135 lock (XferUploaders)
136 {
137 bool removed = XferUploaders.Remove(transactionID);
138
139 if (!removed)
140 m_log.WarnFormat(
141 "[AGENT ASSET TRANSACTIONS]: Received request to remove xfer uploader with transaction ID {0} but none found",
142 transactionID);
143// else
144// m_log.DebugFormat(
145// "[AGENT ASSET TRANSACTIONS]: Removed xfer uploader with transaction ID {0}", transactionID);
146
147 return removed;
148 }
92 } 149 }
93 150
94 public void RequestCreateInventoryItem(IClientAPI remoteClient, 151 public void RequestCreateInventoryItem(IClientAPI remoteClient,
@@ -96,16 +153,24 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
96 string description, string name, sbyte invType, 153 string description, string name, sbyte invType,
97 sbyte type, byte wearableType, uint nextOwnerMask) 154 sbyte type, byte wearableType, uint nextOwnerMask)
98 { 155 {
99 if (XferUploaders.ContainsKey(transactionID)) 156 AssetXferUploader uploader = null;
157
158 lock (XferUploaders)
100 { 159 {
101 XferUploaders[transactionID].RequestCreateInventoryItem( 160 if (XferUploaders.ContainsKey(transactionID))
102 remoteClient, transactionID, folderID, 161 uploader = XferUploaders[transactionID];
103 callbackID, description, name, invType, type,
104 wearableType, nextOwnerMask);
105 } 162 }
106 }
107
108 163
164 if (uploader != null)
165 uploader.RequestCreateInventoryItem(
166 remoteClient, transactionID, folderID,
167 callbackID, description, name, invType, type,
168 wearableType, nextOwnerMask);
169 else
170 m_log.ErrorFormat(
171 "[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to create inventory item {1} from {2}",
172 transactionID, name, remoteClient.Name);
173 }
109 174
110 /// <summary> 175 /// <summary>
111 /// Get an uploaded asset. If the data is successfully retrieved, 176 /// Get an uploaded asset. If the data is successfully retrieved,
@@ -113,19 +178,18 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
113 /// </summary> 178 /// </summary>
114 /// <param name="transactionID"></param> 179 /// <param name="transactionID"></param>
115 /// <returns>The asset if the upload has completed, null if it has not.</returns> 180 /// <returns>The asset if the upload has completed, null if it has not.</returns>
116 public AssetBase GetTransactionAsset(UUID transactionID) 181 private AssetBase GetTransactionAsset(UUID transactionID)
117 { 182 {
118 if (XferUploaders.ContainsKey(transactionID)) 183 lock (XferUploaders)
119 { 184 {
120 AssetXferUploader uploader = XferUploaders[transactionID]; 185 if (XferUploaders.ContainsKey(transactionID))
121 AssetBase asset = uploader.GetAssetData();
122
123 lock (XferUploaders)
124 { 186 {
125 XferUploaders.Remove(transactionID); 187 AssetXferUploader uploader = XferUploaders[transactionID];
126 } 188 AssetBase asset = uploader.GetAssetData();
189 RemoveXferUploader(transactionID);
127 190
128 return asset; 191 return asset;
192 }
129 } 193 }
130 194
131 return null; 195 return null;
@@ -135,7 +199,15 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
135 SceneObjectPart part, UUID transactionID, 199 SceneObjectPart part, UUID transactionID,
136 TaskInventoryItem item) 200 TaskInventoryItem item)
137 { 201 {
138 if (XferUploaders.ContainsKey(transactionID)) 202 AssetXferUploader uploader = null;
203
204 lock (XferUploaders)
205 {
206 if (XferUploaders.ContainsKey(transactionID))
207 uploader = XferUploaders[transactionID];
208 }
209
210 if (uploader != null)
139 { 211 {
140 AssetBase asset = GetTransactionAsset(transactionID); 212 AssetBase asset = GetTransactionAsset(transactionID);
141 213
@@ -161,44 +233,34 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
161 m_Scene.AssetService.Store(asset); 233 m_Scene.AssetService.Store(asset);
162 } 234 }
163 } 235 }
236 else
237 {
238 m_log.ErrorFormat(
239 "[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to update task inventory item {1} in {2}",
240 transactionID, item.Name, part.Name);
241 }
164 } 242 }
165 243
166 public void RequestUpdateInventoryItem(IClientAPI remoteClient, 244 public void RequestUpdateInventoryItem(IClientAPI remoteClient,
167 UUID transactionID, InventoryItemBase item) 245 UUID transactionID, InventoryItemBase item)
168 { 246 {
169 if (XferUploaders.ContainsKey(transactionID)) 247 AssetXferUploader uploader = null;
170 {
171// m_log.DebugFormat("[XFER]: Asked to update item {0} ({1})",
172// item.Name, item.ID);
173
174 // Here we need to get the old asset to extract the
175 // texture UUIDs if it's a wearable.
176 if (item.AssetType == (int)AssetType.Bodypart ||
177 item.AssetType == (int)AssetType.Clothing)
178 {
179 AssetBase oldAsset = m_Scene.AssetService.Get(item.AssetID.ToString());
180 if (oldAsset != null)
181 XferUploaders[transactionID].SetOldData(oldAsset.Data);
182 }
183
184 AssetBase asset = GetTransactionAsset(transactionID);
185 248
186 if (asset != null) 249 lock (XferUploaders)
187 { 250 {
188 asset.FullID = UUID.Random(); 251 if (XferUploaders.ContainsKey(transactionID))
189 asset.Name = item.Name; 252 uploader = XferUploaders[transactionID];
190 asset.Description = item.Description; 253 }
191 asset.Type = (sbyte)item.AssetType;
192 item.AssetID = asset.FullID;
193
194 m_Scene.AssetService.Store(asset);
195
196 IInventoryService invService = m_Scene.InventoryService;
197 invService.UpdateItem(item);
198 254
199// m_log.DebugFormat("[XFER]: Updated item {0} ({1}) with asset {2}", 255 if (uploader != null)
200// item.Name, item.ID, asset.FullID); 256 {
201 } 257 uploader.RequestUpdateInventoryItem(remoteClient, transactionID, item);
258 }
259 else
260 {
261 m_log.ErrorFormat(
262 "[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to update inventory item {1} for {2}",
263 transactionID, item.Name, remoteClient.Name);
202 } 264 }
203 } 265 }
204 } 266 }
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
index 82558de..a28d5d7 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
@@ -172,11 +172,12 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
172 /// <summary> 172 /// <summary>
173 /// Update an inventory item with data that has been received through a 173 /// Update an inventory item with data that has been received through a
174 /// transaction. 174 /// transaction.
175 /// 175 /// </summary>
176 /// <remarks>
176 /// This is called when clothing or body parts are updated (for 177 /// This is called when clothing or body parts are updated (for
177 /// instance, with new textures or colours). It may also be called in 178 /// instance, with new textures or colours). It may also be called in
178 /// other situations. 179 /// other situations.
179 /// </summary> 180 /// </remarks>
180 /// <param name="remoteClient"></param> 181 /// <param name="remoteClient"></param>
181 /// <param name="transactionID"></param> 182 /// <param name="transactionID"></param>
182 /// <param name="item"></param> 183 /// <param name="item"></param>
@@ -184,14 +185,12 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
184 UUID transactionID, InventoryItemBase item) 185 UUID transactionID, InventoryItemBase item)
185 { 186 {
186// m_log.DebugFormat( 187// m_log.DebugFormat(
187// "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}", 188// "[ASSET TRANSACTION MODULE]: Called HandleItemUpdateFromTransaction with item {0}",
188// item.Name); 189// item.Name);
189 190
190 AgentAssetTransactions transactions = 191 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
191 GetUserTransactions(remoteClient.AgentId);
192 192
193 transactions.RequestUpdateInventoryItem(remoteClient, 193 transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item);
194 transactionID, item);
195 } 194 }
196 195
197 /// <summary> 196 /// <summary>
@@ -255,11 +254,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
255 } 254 }
256 } 255 }
257 256
258 AgentAssetTransactions transactions = 257 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
259 GetUserTransactions(remoteClient.AgentId); 258 AssetXferUploader uploader = transactions.RequestXferUploader(transaction, assetID);
260
261 AssetXferUploader uploader =
262 transactions.RequestXferUploader(transaction);
263 259
264 if (uploader != null) 260 if (uploader != null)
265 { 261 {
@@ -279,9 +275,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
279 public void HandleXfer(IClientAPI remoteClient, ulong xferID, 275 public void HandleXfer(IClientAPI remoteClient, ulong xferID,
280 uint packetID, byte[] data) 276 uint packetID, byte[] data)
281 { 277 {
282 //m_log.Debug("xferID: " + xferID + " packetID: " + packetID + " data!"); 278// m_log.Debug("xferID: " + xferID + " packetID: " + packetID + " data length " + data.Length);
283 AgentAssetTransactions transactions = 279 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
284 GetUserTransactions(remoteClient.AgentId);
285 280
286 transactions.HandleXfer(xferID, packetID, data); 281 transactions.HandleXfer(xferID, packetID, data);
287 } 282 }
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();
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index bb63bcd..0cadd83 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -211,6 +211,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
211 // Process the visual params, this may change height as well 211 // Process the visual params, this may change height as well
212 if (visualParams != null) 212 if (visualParams != null)
213 { 213 {
214// string[] visualParamsStrings = new string[visualParams.Length];
215// for (int i = 0; i < visualParams.Length; i++)
216// visualParamsStrings[i] = visualParams[i].ToString();
217// m_log.DebugFormat(
218// "[AVFACTORY]: Setting visual params for {0} to {1}",
219// client.Name, string.Join(", ", visualParamsStrings));
220
214 float oldHeight = sp.Appearance.AvatarHeight; 221 float oldHeight = sp.Appearance.AvatarHeight;
215 changed = sp.Appearance.SetVisualParams(visualParams); 222 changed = sp.Appearance.SetVisualParams(visualParams);
216 223
@@ -418,6 +425,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
418 425
419 // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid); 426 // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid);
420 427
428 // This could take awhile since it needs to pull inventory
429 // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape
430 // assets and item asset id changes to complete.
431 // I don't think we need to worry about doing this within m_setAppearanceLock since the queueing avoids
432 // multiple save requests.
433 SetAppearanceAssets(sp.UUID, sp.Appearance);
434
421 m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); 435 m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
422 } 436 }
423 437
@@ -504,9 +518,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
504 518
505 avatAppearance.GetAssetsFrom(sp.Appearance); 519 avatAppearance.GetAssetsFrom(sp.Appearance);
506 520
507 // This could take awhile since it needs to pull inventory
508 SetAppearanceAssets(sp.UUID, ref avatAppearance);
509
510 lock (m_setAppearanceLock) 521 lock (m_setAppearanceLock)
511 { 522 {
512 // Update only those fields that we have changed. This is important because the viewer 523 // Update only those fields that we have changed. This is important because the viewer
@@ -540,7 +551,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
540 return true; 551 return true;
541 } 552 }
542 553
543 private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) 554 private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
544 { 555 {
545 IInventoryService invService = m_scene.InventoryService; 556 IInventoryService invService = m_scene.InventoryService;
546 557
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 931fedc..53f0f2e 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -316,6 +316,10 @@ namespace OpenSim.Region.Framework.Scenes
316 public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID, 316 public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID,
317 UUID itemID, InventoryItemBase itemUpd) 317 UUID itemID, InventoryItemBase itemUpd)
318 { 318 {
319// m_log.DebugFormat(
320// "[USER INVENTORY]: Updating asset for item {0} {1}, transaction ID {2} for {3}",
321// itemID, itemUpd.Name, transactionID, remoteClient.Name);
322
319 // This one will let people set next perms on items in agent 323 // This one will let people set next perms on items in agent
320 // inventory. Rut-Roh. Whatever. Make this secure. Yeah. 324 // inventory. Rut-Roh. Whatever. Make this secure. Yeah.
321 // 325 //
@@ -368,8 +372,7 @@ namespace OpenSim.Region.Framework.Scenes
368 IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>(); 372 IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
369 if (agentTransactions != null) 373 if (agentTransactions != null)
370 { 374 {
371 agentTransactions.HandleItemUpdateFromTransaction( 375 agentTransactions.HandleItemUpdateFromTransaction(remoteClient, transactionID, item);
372 remoteClient, transactionID, item);
373 } 376 }
374 } 377 }
375 } 378 }