aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorMelanie Thielker2016-07-11 22:32:27 +0100
committerMelanie Thielker2016-07-11 22:32:27 +0100
commitf87d5d07808d19fa53d0fb71cde06519701491e1 (patch)
treea142a866062b3a4406ace454a8ea9f43c6dcd9a8 /OpenSim
parentChange the user verification call back to use the host name instead of the (diff)
parentreduce xfer burst if we are busy (diff)
downloadopensim-SC_OLD-f87d5d07808d19fa53d0fb71cde06519701491e1.zip
opensim-SC_OLD-f87d5d07808d19fa53d0fb71cde06519701491e1.tar.gz
opensim-SC_OLD-f87d5d07808d19fa53d0fb71cde06519701491e1.tar.bz2
opensim-SC_OLD-f87d5d07808d19fa53d0fb71cde06519701491e1.tar.xz
Merge branch 'master' of opensimulator.org:/var/git/opensim
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Framework/Util.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs2
-rw-r--r--OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs364
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs74
4 files changed, 302 insertions, 140 deletions
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index 65b2a5c..1b3a4c3 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -1303,7 +1303,7 @@ namespace OpenSim.Framework
1303 } 1303 }
1304 catch (Exception e) 1304 catch (Exception e)
1305 { 1305 {
1306 m_log.WarnFormat("[UTILS]: Exception copying configuration file {0} to {1}: {2}", configFile, exampleConfigFile, e.Message); 1306 m_log.WarnFormat("[UTILS]: Exception copying configuration file {0} to {1}: {2}", exampleConfigFile, configFile, e.Message);
1307 return false; 1307 return false;
1308 } 1308 }
1309 } 1309 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 383031c..a84d902 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -4796,7 +4796,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4796 block.SaleType = sop.ObjectSaleType; 4796 block.SaleType = sop.ObjectSaleType;
4797 block.SalePrice = sop.SalePrice; 4797 block.SalePrice = sop.SalePrice;
4798 block.Category = sop.Category; 4798 block.Category = sop.Category;
4799 block.LastOwnerID = sop.CreatorID; // copied from old SOG call... is this right? 4799 block.LastOwnerID = sop.LastOwnerID;
4800 block.Name = Util.StringToBytes256(sop.Name); 4800 block.Name = Util.StringToBytes256(sop.Name);
4801 block.Description = Util.StringToBytes256(sop.Description); 4801 block.Description = Util.StringToBytes256(sop.Description);
4802 4802
diff --git a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs
index 7113f4f..41ce860 100644
--- a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs
@@ -28,10 +28,12 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using System.Threading;
31using Nini.Config; 32using Nini.Config;
32using log4net; 33using log4net;
33using OpenMetaverse; 34using OpenMetaverse;
34using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Framework.Monitoring;
35using OpenSim.Region.Framework.Interfaces; 37using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes; 38using OpenSim.Region.Framework.Scenes;
37 39
@@ -45,9 +47,13 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
45 private Scene m_scene; 47 private Scene m_scene;
46 private Dictionary<string, FileData> NewFiles = new Dictionary<string, FileData>(); 48 private Dictionary<string, FileData> NewFiles = new Dictionary<string, FileData>();
47 private Dictionary<ulong, XferDownLoad> Transfers = new Dictionary<ulong, XferDownLoad>(); 49 private Dictionary<ulong, XferDownLoad> Transfers = new Dictionary<ulong, XferDownLoad>();
48
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 51
52 private object timeTickLock = new object();
53 private double lastTimeTick = 0.0;
54 private double lastFilesExpire = 0.0;
55 private bool inTimeTick = false;
56
51 public struct XferRequest 57 public struct XferRequest
52 { 58 {
53 public IClientAPI remoteClient; 59 public IClientAPI remoteClient;
@@ -59,26 +65,30 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
59 private class FileData 65 private class FileData
60 { 66 {
61 public byte[] Data; 67 public byte[] Data;
62 public int Count; 68 public int refsCount;
69 public double timeStampMS;
63 } 70 }
64 71
65 #region INonSharedRegionModule Members 72 #region INonSharedRegionModule Members
66 73
67 public void Initialise(IConfigSource config) 74 public void Initialise(IConfigSource config)
68 { 75 {
76 lastTimeTick = Util.GetTimeStampMS() + 30000.0;
77 lastFilesExpire = lastTimeTick + 180000.0;
69 } 78 }
70 79
71 public void AddRegion(Scene scene) 80 public void AddRegion(Scene scene)
72 { 81 {
73 m_scene = scene; 82 m_scene = scene;
74 m_scene.EventManager.OnNewClient += NewClient;
75
76 m_scene.RegisterModuleInterface<IXfer>(this); 83 m_scene.RegisterModuleInterface<IXfer>(this);
84 m_scene.EventManager.OnNewClient += NewClient;
85 m_scene.EventManager.OnRegionHeartbeatEnd += OnTimeTick;
77 } 86 }
78 87
79 public void RemoveRegion(Scene scene) 88 public void RemoveRegion(Scene scene)
80 { 89 {
81 m_scene.EventManager.OnNewClient -= NewClient; 90 m_scene.EventManager.OnNewClient -= NewClient;
91 m_scene.EventManager.OnRegionHeartbeatEnd -= OnTimeTick;
82 92
83 m_scene.UnregisterModuleInterface<IXfer>(this); 93 m_scene.UnregisterModuleInterface<IXfer>(this);
84 m_scene = null; 94 m_scene = null;
@@ -104,6 +114,35 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
104 114
105 #endregion 115 #endregion
106 116
117 public void OnTimeTick(Scene scene)
118 {
119 // we are on a heartbeat thread we there can be several
120 if(Monitor.TryEnter(timeTickLock))
121 {
122 if(!inTimeTick)
123 {
124 double now = Util.GetTimeStampMS();
125 if(now - lastTimeTick > 1750.0)
126 {
127 inTimeTick = true;
128
129 //don't overload busy heartbeat
130 WorkManager.RunInThread(
131 delegate
132 {
133 transfersTimeTick(now);
134 expireFiles(now);
135
136 lastTimeTick = now;
137 inTimeTick = false;
138 },
139 null,
140 "XferTimeTick");
141 }
142 }
143 Monitor.Exit(timeTickLock);
144 }
145 }
107 #region IXfer Members 146 #region IXfer Members
108 147
109 /// <summary> 148 /// <summary>
@@ -118,25 +157,46 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
118 { 157 {
119 lock (NewFiles) 158 lock (NewFiles)
120 { 159 {
160 double now = Util.GetTimeStampMS();
121 if (NewFiles.ContainsKey(fileName)) 161 if (NewFiles.ContainsKey(fileName))
122 { 162 {
123 NewFiles[fileName].Count++; 163 NewFiles[fileName].refsCount++;
124 NewFiles[fileName].Data = data; 164 NewFiles[fileName].Data = data;
165 NewFiles[fileName].timeStampMS = now;
125 } 166 }
126 else 167 else
127 { 168 {
128 FileData fd = new FileData(); 169 FileData fd = new FileData();
129 fd.Count = 1; 170 fd.refsCount = 1;
130 fd.Data = data; 171 fd.Data = data;
172 fd.timeStampMS = now;
131 NewFiles.Add(fileName, fd); 173 NewFiles.Add(fileName, fd);
132 } 174 }
133 } 175 }
134
135 return true; 176 return true;
136 } 177 }
137 178
138 #endregion 179 #endregion
139 180 public void expireFiles(double now)
181 {
182 lock (NewFiles)
183 {
184 // hopefully we will not have many files so nasty code will do it
185 if(now - lastFilesExpire > 120000.0)
186 {
187 lastFilesExpire = now;
188 List<string> expires = new List<string>();
189 foreach(string fname in NewFiles.Keys)
190 {
191 if(NewFiles[fname].refsCount == 0 && now - NewFiles[fname].timeStampMS > 120000.0)
192 expires.Add(fname);
193 }
194 foreach(string fname in expires)
195 NewFiles.Remove(fname);
196 }
197 }
198 }
199
140 public void NewClient(IClientAPI client) 200 public void NewClient(IClientAPI client)
141 { 201 {
142 client.OnRequestXfer += RequestXfer; 202 client.OnRequestXfer += RequestXfer;
@@ -144,6 +204,51 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
144 client.OnAbortXfer += AbortXfer; 204 client.OnAbortXfer += AbortXfer;
145 } 205 }
146 206
207 public void OnClientClosed(IClientAPI client)
208 {
209 client.OnRequestXfer -= RequestXfer;
210 client.OnConfirmXfer -= AckPacket;
211 client.OnAbortXfer -= AbortXfer;
212 }
213
214 private void RemoveOrDecrementFile(string fileName)
215 {
216 // NewFiles must be locked
217
218 if (NewFiles.ContainsKey(fileName))
219 {
220 if (NewFiles[fileName].refsCount == 1)
221 NewFiles.Remove(fileName);
222 else
223 NewFiles[fileName].refsCount--;
224 }
225 }
226
227 public void transfersTimeTick(double now)
228 {
229 XferDownLoad[] xfrs;
230 lock(Transfers)
231 {
232 if(Transfers.Count == 0)
233 return;
234
235 xfrs = new XferDownLoad[Transfers.Count];
236 Transfers.Values.CopyTo(xfrs,0);
237 }
238 foreach(XferDownLoad xfr in xfrs)
239 {
240 if(xfr.checkTime(now))
241 {
242 ulong xfrID = xfr.XferID;
243 lock(Transfers)
244 {
245 if(Transfers.ContainsKey(xfrID))
246 Transfers.Remove(xfrID);
247 }
248 }
249 }
250 }
251
147 /// <summary> 252 /// <summary>
148 /// 253 ///
149 /// </summary> 254 /// </summary>
@@ -156,80 +261,52 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
156 { 261 {
157 if (NewFiles.ContainsKey(fileName)) 262 if (NewFiles.ContainsKey(fileName))
158 { 263 {
159 if (!Transfers.ContainsKey(xferID)) 264 lock(Transfers)
160 { 265 {
161 byte[] fileData = NewFiles[fileName].Data; 266 if (!Transfers.ContainsKey(xferID))
162 XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient); 267 {
163 if (fileName.StartsWith("inventory_")) 268 byte[] fileData = NewFiles[fileName].Data;
164 transaction.isTaskInventory = true; 269 int burstSize = remoteClient.GetAgentThrottleSilent((int)ThrottleOutPacketType.Asset) >> 11;
165 270 if(Transfers.Count > 1)
166 Transfers.Add(xferID, transaction); 271 burstSize /= Transfers.Count;
167 272 XferDownLoad transaction =
168 if (transaction.StartSend()) 273 new XferDownLoad(fileName, fileData, xferID, remoteClient, burstSize);
169 RemoveXferData(xferID); 274
170 275 Transfers.Add(xferID, transaction);
171 // The transaction for this file is either complete or on its way 276
172 RemoveOrDecrement(fileName); 277 transaction.StartSend();
173 278
279 // The transaction for this file is on its way
280 RemoveOrDecrementFile(fileName);
281 }
174 } 282 }
175 } 283 }
176 else 284 else
177 m_log.WarnFormat("[Xfer]: {0} not found", fileName); 285 m_log.WarnFormat("[Xfer]: {0} not found", fileName);
178
179 } 286 }
180 } 287 }
181 288
182 public void AckPacket(IClientAPI remoteClient, ulong xferID, uint packet) 289 public void AckPacket(IClientAPI remoteClient, ulong xferID, uint packet)
183 { 290 {
184 lock (NewFiles) // This is actually to lock Transfers 291 lock (Transfers)
185 { 292 {
186 if (Transfers.ContainsKey(xferID)) 293 if (Transfers.ContainsKey(xferID))
187 { 294 {
188 XferDownLoad dl = Transfers[xferID];
189 if (Transfers[xferID].AckPacket(packet)) 295 if (Transfers[xferID].AckPacket(packet))
190 { 296 Transfers.Remove(xferID);
191 RemoveXferData(xferID);
192 RemoveOrDecrement(dl.FileName);
193 }
194 } 297 }
195 } 298 }
196 } 299 }
197 300
198 private void RemoveXferData(ulong xferID)
199 {
200 // NewFiles must be locked!
201 if (Transfers.ContainsKey(xferID))
202 {
203 XferModule.XferDownLoad xferItem = Transfers[xferID];
204 //string filename = xferItem.FileName;
205 Transfers.Remove(xferID);
206 xferItem.Data = new byte[0]; // Clear the data
207 xferItem.DataPointer = 0;
208
209 }
210 }
211
212 public void AbortXfer(IClientAPI remoteClient, ulong xferID) 301 public void AbortXfer(IClientAPI remoteClient, ulong xferID)
213 { 302 {
214 lock (NewFiles) 303 lock (Transfers)
215 { 304 {
216 if (Transfers.ContainsKey(xferID)) 305 if (Transfers.ContainsKey(xferID))
217 RemoveOrDecrement(Transfers[xferID].FileName); 306 {
218 307 Transfers[xferID].done();
219 RemoveXferData(xferID); 308 Transfers.Remove(xferID);
220 } 309 }
221 }
222
223 private void RemoveOrDecrement(string fileName)
224 {
225 // NewFiles must be locked
226
227 if (NewFiles.ContainsKey(fileName))
228 {
229 if (NewFiles[fileName].Count == 1)
230 NewFiles.Remove(fileName);
231 else
232 NewFiles[fileName].Count--;
233 } 310 }
234 } 311 }
235 312
@@ -238,53 +315,124 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
238 public class XferDownLoad 315 public class XferDownLoad
239 { 316 {
240 public IClientAPI Client; 317 public IClientAPI Client;
241 private bool complete;
242 public byte[] Data = new byte[0]; 318 public byte[] Data = new byte[0];
243 public int DataPointer = 0;
244 public string FileName = String.Empty; 319 public string FileName = String.Empty;
245 public uint Packet = 0;
246 public uint Serial = 1;
247 public ulong XferID = 0; 320 public ulong XferID = 0;
248 public bool isTaskInventory = false; 321 public bool isDeleted = false;
249 322
250 public XferDownLoad(string fileName, byte[] data, ulong xferID, IClientAPI client) 323 private object myLock = new object();
324 private double lastsendTimeMS;
325 private int LastPacket;
326 private int lastBytes;
327 private int lastSentPacket;
328 private int lastAckPacket;
329 private int burstSize;
330 private int retries = 0;
331
332 public XferDownLoad(string fileName, byte[] data, ulong xferID, IClientAPI client, int burstsz)
251 { 333 {
252 FileName = fileName; 334 FileName = fileName;
253 Data = data; 335 Data = data;
254 XferID = xferID; 336 XferID = xferID;
255 Client = client; 337 Client = client;
338 burstSize = burstsz;
256 } 339 }
257 340
258 public XferDownLoad() 341 public XferDownLoad()
259 { 342 {
260 } 343 }
261 344
345 public void done()
346 {
347 if(!isDeleted)
348 {
349 Data = new byte[0];
350 isDeleted = true;
351 }
352 }
353
262 /// <summary> 354 /// <summary>
263 /// Start a transfer 355 /// Start a transfer
264 /// </summary> 356 /// </summary>
265 /// <returns>True if the transfer is complete, false if not</returns> 357 /// <returns>True if the transfer is complete, false if not</returns>
266 public bool StartSend() 358 public void StartSend()
267 { 359 {
268 if (Data.Length < 1000) 360 lock(myLock)
269 { 361 {
270 // for now (testing) we only support files under 1000 bytes 362 if(Data.Length == 0) //??
271 byte[] transferData = new byte[Data.Length + 4]; 363 {
272 Array.Copy(Utils.IntToBytes(Data.Length), 0, transferData, 0, 4); 364 LastPacket = 0;
273 Array.Copy(Data, 0, transferData, 4, Data.Length); 365 lastBytes = 0;
274 Client.SendXferPacket(XferID, 0 + 0x80000000, transferData, isTaskInventory); 366 burstSize = 0;
275 complete = true; 367 }
368 else
369 {
370 // payload of 1024bytes
371 LastPacket = Data.Length >> 10;
372 lastBytes = Data.Length & 0x3ff;
373 if(lastBytes == 0)
374 {
375 lastBytes = 1024;
376 LastPacket--;
377 }
378
379 }
380
381 lastAckPacket = -1;
382 lastSentPacket = -1;
383
384 double now = Util.GetTimeStampMS();
385
386 SendBurst(now);
387 return;
388 }
389 }
390
391 private void SendBurst(double now)
392 {
393 int start = lastAckPacket + 1;
394 int end = start + burstSize;
395 if (end > LastPacket)
396 end = LastPacket;
397 while(start <= end)
398 SendPacket(start++ , now);
399 }
400
401 private void SendPacket(int pkt, double now)
402 {
403 if(pkt > LastPacket)
404 return;
405
406 int pktsize;
407 uint pktid;
408 if (pkt == LastPacket)
409 {
410 pktsize = lastBytes;
411 pktid = (uint)pkt | 0x80000000u;
276 } 412 }
277 else 413 else
278 { 414 {
279 byte[] transferData = new byte[1000 + 4]; 415 pktsize = 1024;
416 pktid = (uint)pkt;
417 }
418
419 byte[] transferData;
420 if(pkt == 0)
421 {
422 transferData = new byte[pktsize + 4];
280 Array.Copy(Utils.IntToBytes(Data.Length), 0, transferData, 0, 4); 423 Array.Copy(Utils.IntToBytes(Data.Length), 0, transferData, 0, 4);
281 Array.Copy(Data, 0, transferData, 4, 1000); 424 Array.Copy(Data, 0, transferData, 4, pktsize);
282 Client.SendXferPacket(XferID, 0, transferData, isTaskInventory);
283 Packet++;
284 DataPointer = 1000;
285 } 425 }
426 else
427 {
428 transferData = new byte[pktsize];
429 Array.Copy(Data, pkt << 10, transferData, 0, pktsize);
430 }
431
432 Client.SendXferPacket(XferID, pktid, transferData, false);
286 433
287 return complete; 434 lastSentPacket = pkt;
435 lastsendTimeMS = now;
288 } 436 }
289 437
290 /// <summary> 438 /// <summary>
@@ -294,30 +442,46 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
294 /// <returns>True if the transfer is complete, false otherwise</returns> 442 /// <returns>True if the transfer is complete, false otherwise</returns>
295 public bool AckPacket(uint packet) 443 public bool AckPacket(uint packet)
296 { 444 {
297 if (!complete) 445 lock(myLock)
298 { 446 {
299 if ((Data.Length - DataPointer) > 1000) 447 if(isDeleted)
448 return true;
449
450 packet &= 0x7fffffff;
451 if(lastAckPacket < packet)
452 lastAckPacket = (int)packet;
453
454 if(lastAckPacket == LastPacket)
300 { 455 {
301 byte[] transferData = new byte[1000]; 456 done();
302 Array.Copy(Data, DataPointer, transferData, 0, 1000); 457 return true;
303 Client.SendXferPacket(XferID, Packet, transferData, isTaskInventory);
304 Packet++;
305 DataPointer += 1000;
306 } 458 }
307 else 459 double now = Util.GetTimeStampMS();
460 SendPacket(lastSentPacket + 1, now);
461 return false;
462 }
463 }
464
465 public bool checkTime(double now)
466 {
467 if(Monitor.TryEnter(myLock))
468 {
469 if(!isDeleted)
308 { 470 {
309 byte[] transferData = new byte[Data.Length - DataPointer]; 471 double timeMS = now - lastsendTimeMS;
310 Array.Copy(Data, DataPointer, transferData, 0, Data.Length - DataPointer); 472 if(timeMS > 60000.0)
311 uint endPacket = Packet |= (uint) 0x80000000; 473 done();
312 Client.SendXferPacket(XferID, endPacket, transferData, isTaskInventory); 474 else if(timeMS > 3500.0 && retries++ < 3)
313 Packet++; 475 {
314 DataPointer += (Data.Length - DataPointer); 476 burstSize >>= 1;
315 477 SendBurst(now);
316 complete = true; 478 }
317 } 479 }
318 }
319 480
320 return complete; 481 Monitor.Exit(myLock);
482 return isDeleted;
483 }
484 return false;
321 } 485 }
322 } 486 }
323 487
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 3b029f2..5b64aac 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -48,6 +48,8 @@ namespace OpenSim.Region.Framework.Scenes
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 49
50 private byte[] m_inventoryFileData = new byte[0]; 50 private byte[] m_inventoryFileData = new byte[0];
51 private byte[] m_inventoryFileNameBytes = new byte[0];
52 private string m_inventoryFileName = "";
51 private uint m_inventoryFileNameSerial = 0; 53 private uint m_inventoryFileNameSerial = 0;
52 private bool m_inventoryPrivileged = false; 54 private bool m_inventoryPrivileged = false;
53 private object m_inventoryFileLock = new object(); 55 private object m_inventoryFileLock = new object();
@@ -1112,28 +1114,9 @@ namespace OpenSim.Region.Framework.Scenes
1112 /// <param name="xferManager"></param> 1114 /// <param name="xferManager"></param>
1113 public void RequestInventoryFile(IClientAPI client, IXfer xferManager) 1115 public void RequestInventoryFile(IClientAPI client, IXfer xferManager)
1114 { 1116 {
1115
1116 lock (m_inventoryFileLock) 1117 lock (m_inventoryFileLock)
1117 { 1118 {
1118 string filename = "inventory_" + UUID.Random().ToString() + ".tmp";
1119
1120 bool changed = false; 1119 bool changed = false;
1121 if (m_inventoryFileNameSerial < m_inventorySerial)
1122 {
1123 m_inventoryFileNameSerial = m_inventorySerial;
1124 changed = true;
1125 }
1126
1127 if (m_inventoryFileData.Length < 2)
1128 changed = true;
1129
1130 bool includeAssets = false;
1131 if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId))
1132 includeAssets = true;
1133
1134 if (m_inventoryPrivileged != includeAssets)
1135 changed = true;
1136
1137 1120
1138 Items.LockItemsForRead(true); 1121 Items.LockItemsForRead(true);
1139 1122
@@ -1141,7 +1124,6 @@ namespace OpenSim.Region.Framework.Scenes
1141 { 1124 {
1142 Items.LockItemsForRead(false); 1125 Items.LockItemsForRead(false);
1143 client.SendTaskInventory(m_part.UUID, 0, new byte[0]); 1126 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1144
1145 return; 1127 return;
1146 } 1128 }
1147 1129
@@ -1152,14 +1134,29 @@ namespace OpenSim.Region.Framework.Scenes
1152 return; 1134 return;
1153 } 1135 }
1154 1136
1155 if (!changed) 1137 if (m_inventoryFileNameSerial != m_inventorySerial)
1156 { 1138 {
1157 Items.LockItemsForRead(false); 1139 m_inventoryFileNameSerial = m_inventorySerial;
1140 changed = true;
1141 }
1142
1143 Items.LockItemsForRead(false);
1144
1145 if (m_inventoryFileData.Length < 2)
1146 changed = true;
1158 1147
1159 xferManager.AddNewFile(filename, 1148 bool includeAssets = false;
1160 m_inventoryFileData); 1149 if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId))
1150 includeAssets = true;
1151
1152 if (m_inventoryPrivileged != includeAssets)
1153 changed = true;
1154
1155 if (!changed)
1156 {
1157 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData);
1161 client.SendTaskInventory(m_part.UUID, (short)m_inventoryFileNameSerial, 1158 client.SendTaskInventory(m_part.UUID, (short)m_inventoryFileNameSerial,
1162 Util.StringToBytes256(filename)); 1159 m_inventoryFileNameBytes);
1163 1160
1164 return; 1161 return;
1165 } 1162 }
@@ -1168,6 +1165,8 @@ namespace OpenSim.Region.Framework.Scenes
1168 1165
1169 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 1166 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
1170 1167
1168 Items.LockItemsForRead(true);
1169
1171 foreach (TaskInventoryItem item in m_items.Values) 1170 foreach (TaskInventoryItem item in m_items.Values)
1172 { 1171 {
1173 UUID ownerID = item.OwnerID; 1172 UUID ownerID = item.OwnerID;
@@ -1222,9 +1221,10 @@ namespace OpenSim.Region.Framework.Scenes
1222 1221
1223 if (m_inventoryFileData.Length > 2) 1222 if (m_inventoryFileData.Length > 2)
1224 { 1223 {
1225 xferManager.AddNewFile(filename, m_inventoryFileData); 1224 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp";
1226 client.SendTaskInventory(m_part.UUID, (short)m_inventoryFileNameSerial, 1225 m_inventoryFileNameBytes = Util.StringToBytes256(m_inventoryFileName);
1227 Util.StringToBytes256(filename)); 1226 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData);
1227 client.SendTaskInventory(m_part.UUID, (short)m_inventoryFileNameSerial,m_inventoryFileNameBytes);
1228 return; 1228 return;
1229 } 1229 }
1230 1230
@@ -1267,26 +1267,22 @@ namespace OpenSim.Region.Framework.Scenes
1267 AddNameValueLine("obj_id", folderID.ToString()); 1267 AddNameValueLine("obj_id", folderID.ToString());
1268 AddNameValueLine("parent_id", parentID.ToString()); 1268 AddNameValueLine("parent_id", parentID.ToString());
1269 AddNameValueLine("type", "category"); 1269 AddNameValueLine("type", "category");
1270 AddNameValueLine("name", "Contents|"); 1270 AddNameValueLine("name", "Contents|\n\t}");
1271 AddSectionEnd();
1272 } 1271 }
1273 1272
1274 public void AddItemStart() 1273 public void AddItemStart()
1275 { 1274 {
1276 BuildString.Append("\tinv_item\t0\n"); 1275 BuildString.Append("\tinv_item\t0\n\t{\n");
1277 AddSectionStart();
1278 } 1276 }
1279 1277
1280 public void AddPermissionsStart() 1278 public void AddPermissionsStart()
1281 { 1279 {
1282 BuildString.Append("\tpermissions 0\n"); 1280 BuildString.Append("\tpermissions 0\n\t{\n");
1283 AddSectionStart();
1284 } 1281 }
1285 1282
1286 public void AddSaleStart() 1283 public void AddSaleStart()
1287 { 1284 {
1288 BuildString.Append("\tsale_info\t0\n"); 1285 BuildString.Append("\tsale_info\t0\n\t{\n");
1289 AddSectionStart();
1290 } 1286 }
1291 1287
1292 protected void AddSectionStart() 1288 protected void AddSectionStart()
@@ -1307,8 +1303,10 @@ namespace OpenSim.Region.Framework.Scenes
1307 public void AddNameValueLine(string name, string value) 1303 public void AddNameValueLine(string name, string value)
1308 { 1304 {
1309 BuildString.Append("\t\t"); 1305 BuildString.Append("\t\t");
1310 BuildString.Append(name + "\t"); 1306 BuildString.Append(name);
1311 BuildString.Append(value + "\n"); 1307 BuildString.Append("\t");
1308 BuildString.Append(value);
1309 BuildString.Append("\n");
1312 } 1310 }
1313 1311
1314 public String GetString() 1312 public String GetString()