diff options
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Framework/Util.cs | 2 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 2 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs | 364 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 74 |
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 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using System.Threading; | ||
31 | using Nini.Config; | 32 | using Nini.Config; |
32 | using log4net; | 33 | using log4net; |
33 | using OpenMetaverse; | 34 | using OpenMetaverse; |
34 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
36 | using OpenSim.Framework.Monitoring; | ||
35 | using OpenSim.Region.Framework.Interfaces; | 37 | using OpenSim.Region.Framework.Interfaces; |
36 | using OpenSim.Region.Framework.Scenes; | 38 | using 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() |