diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | 291 |
1 files changed, 200 insertions, 91 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index 8ebcd92..84bad25 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | |||
@@ -49,7 +49,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
49 | /// <param name='targetID'></param> | 49 | /// <param name='targetID'></param> |
50 | /// <param name='fromAgent'></param> | 50 | /// <param name='fromAgent'></param> |
51 | /// <param name='broadcast'></param> | 51 | /// <param name='broadcast'></param> |
52 | protected void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName, | 52 | public void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName, |
53 | UUID fromID, UUID targetID, bool fromAgent, bool broadcast) | 53 | UUID fromID, UUID targetID, bool fromAgent, bool broadcast) |
54 | { | 54 | { |
55 | OSChatMessage args = new OSChatMessage(); | 55 | OSChatMessage args = new OSChatMessage(); |
@@ -60,6 +60,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
60 | args.Position = fromPos; | 60 | args.Position = fromPos; |
61 | args.SenderUUID = fromID; | 61 | args.SenderUUID = fromID; |
62 | args.Scene = this; | 62 | args.Scene = this; |
63 | args.Destination = targetID; | ||
63 | 64 | ||
64 | if (fromAgent) | 65 | if (fromAgent) |
65 | { | 66 | { |
@@ -74,7 +75,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
74 | } | 75 | } |
75 | 76 | ||
76 | args.From = fromName; | 77 | args.From = fromName; |
77 | args.TargetUUID = targetID; | 78 | //args. |
78 | 79 | ||
79 | // m_log.DebugFormat( | 80 | // m_log.DebugFormat( |
80 | // "[SCENE]: Sending message {0} on channel {1}, type {2} from {3}, broadcast {4}", | 81 | // "[SCENE]: Sending message {0} on channel {1}, type {2} from {3}, broadcast {4}", |
@@ -129,19 +130,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
129 | { | 130 | { |
130 | SimChat(message, type, channel, fromPos, fromName, fromID, fromAgent, true); | 131 | SimChat(message, type, channel, fromPos, fromName, fromID, fromAgent, true); |
131 | } | 132 | } |
132 | /// <summary> | ||
133 | /// | ||
134 | /// </summary> | ||
135 | /// <param name="message"></param> | ||
136 | /// <param name="type"></param> | ||
137 | /// <param name="fromPos"></param> | ||
138 | /// <param name="fromName"></param> | ||
139 | /// <param name="fromAgentID"></param> | ||
140 | /// <param name="targetID"></param> | ||
141 | public void SimChatToAgent(UUID targetID, byte[] message, Vector3 fromPos, string fromName, UUID fromID, bool fromAgent) | ||
142 | { | ||
143 | SimChat(message, ChatTypeEnum.Say, 0, fromPos, fromName, fromID, targetID, fromAgent, false); | ||
144 | } | ||
145 | 133 | ||
146 | /// <summary> | 134 | /// <summary> |
147 | /// | 135 | /// |
@@ -176,29 +164,34 @@ namespace OpenSim.Region.Framework.Scenes | |||
176 | /// </summary> | 164 | /// </summary> |
177 | /// <param name="primLocalID"></param> | 165 | /// <param name="primLocalID"></param> |
178 | /// <param name="remoteClient"></param> | 166 | /// <param name="remoteClient"></param> |
179 | public void SelectPrim(uint primLocalID, IClientAPI remoteClient) | 167 | public void SelectPrim(List<uint> primIDs, IClientAPI remoteClient) |
180 | { | 168 | { |
181 | SceneObjectPart part = GetSceneObjectPart(primLocalID); | 169 | foreach(uint primLocalID in primIDs) |
170 | { | ||
171 | SceneObjectPart part = GetSceneObjectPart(primLocalID); | ||
182 | 172 | ||
183 | if (null == part) | 173 | if (part == null) |
184 | return; | 174 | continue; |
185 | 175 | ||
186 | if (part.IsRoot) | ||
187 | { | ||
188 | SceneObjectGroup sog = part.ParentGroup; | 176 | SceneObjectGroup sog = part.ParentGroup; |
189 | sog.SendPropertiesToClient(remoteClient); | 177 | if (sog == null) |
190 | sog.IsSelected = true; | 178 | continue; |
179 | |||
180 | // waste of time because properties do not send prim flags as they should | ||
181 | // if a friend got or lost edit rights after login, a full update is needed | ||
182 | if(sog.OwnerID != remoteClient.AgentId) | ||
183 | part.SendFullUpdate(remoteClient); | ||
191 | 184 | ||
192 | // A prim is only tainted if it's allowed to be edited by the person clicking it. | 185 | // A prim is only tainted if it's allowed to be edited by the person clicking it. |
193 | if (Permissions.CanEditObject(sog.UUID, remoteClient.AgentId) | 186 | if (Permissions.CanChangeSelectedState(part, (ScenePresence)remoteClient.SceneAgent)) |
194 | || Permissions.CanMoveObject(sog.UUID, remoteClient.AgentId)) | ||
195 | { | 187 | { |
196 | EventManager.TriggerParcelPrimCountTainted(); | 188 | bool oldsel = part.IsSelected; |
189 | part.IsSelected = true; | ||
190 | if(!oldsel) | ||
191 | EventManager.TriggerParcelPrimCountTainted(); | ||
197 | } | 192 | } |
198 | } | 193 | |
199 | else | 194 | part.SendPropertiesToClient(remoteClient); |
200 | { | ||
201 | part.SendPropertiesToClient(remoteClient); | ||
202 | } | 195 | } |
203 | } | 196 | } |
204 | 197 | ||
@@ -220,13 +213,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
220 | if (groupID != UUID.Zero) | 213 | if (groupID != UUID.Zero) |
221 | { | 214 | { |
222 | GroupMembershipData gmd = m_groupsModule.GetMembershipData(groupID, remoteClient.AgentId); | 215 | GroupMembershipData gmd = m_groupsModule.GetMembershipData(groupID, remoteClient.AgentId); |
223 | 216 | ||
224 | if (gmd == null) | 217 | if (gmd == null) |
225 | { | 218 | { |
226 | // m_log.WarnFormat( | 219 | // m_log.WarnFormat( |
227 | // "[GROUPS]: User {0} is not a member of group {1} so they can't update {2} to this group", | 220 | // "[GROUPS]: User {0} is not a member of group {1} so they can't update {2} to this group", |
228 | // remoteClient.Name, GroupID, objectLocalID); | 221 | // remoteClient.Name, GroupID, objectLocalID); |
229 | 222 | ||
230 | return; | 223 | return; |
231 | } | 224 | } |
232 | } | 225 | } |
@@ -237,6 +230,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
237 | if (so.OwnerID == remoteClient.AgentId) | 230 | if (so.OwnerID == remoteClient.AgentId) |
238 | { | 231 | { |
239 | so.SetGroup(groupID, remoteClient); | 232 | so.SetGroup(groupID, remoteClient); |
233 | EventManager.TriggerParcelPrimCountTainted(); | ||
240 | } | 234 | } |
241 | } | 235 | } |
242 | } | 236 | } |
@@ -251,40 +245,29 @@ namespace OpenSim.Region.Framework.Scenes | |||
251 | SceneObjectPart part = GetSceneObjectPart(primLocalID); | 245 | SceneObjectPart part = GetSceneObjectPart(primLocalID); |
252 | if (part == null) | 246 | if (part == null) |
253 | return; | 247 | return; |
254 | 248 | ||
255 | // A deselect packet contains all the local prims being deselected. However, since selection is still | 249 | bool oldgprSelect = part.ParentGroup.IsSelected; |
256 | // group based we only want the root prim to trigger a full update - otherwise on objects with many prims | ||
257 | // we end up sending many duplicate ObjectUpdates | ||
258 | if (part.ParentGroup.RootPart.LocalId != part.LocalId) | ||
259 | return; | ||
260 | 250 | ||
261 | // This is wrong, wrong, wrong. Selection should not be | 251 | // This is wrong, wrong, wrong. Selection should not be |
262 | // handled by group, but by prim. Legacy cruft. | 252 | // handled by group, but by prim. Legacy cruft. |
263 | // TODO: Make selection flagging per prim! | 253 | // TODO: Make selection flagging per prim! |
264 | // | 254 | // |
265 | part.ParentGroup.IsSelected = false; | 255 | if (Permissions.CanChangeSelectedState(part, (ScenePresence)remoteClient.SceneAgent)) |
266 | |||
267 | part.ParentGroup.ScheduleGroupForFullUpdate(); | ||
268 | |||
269 | // If it's not an attachment, and we are allowed to move it, | ||
270 | // then we might have done so. If we moved across a parcel | ||
271 | // boundary, we will need to recount prims on the parcels. | ||
272 | // For attachments, that makes no sense. | ||
273 | // | ||
274 | if (!part.ParentGroup.IsAttachment) | ||
275 | { | 256 | { |
276 | if (Permissions.CanEditObject( | 257 | part.IsSelected = false; |
277 | part.UUID, remoteClient.AgentId) | 258 | if (!part.ParentGroup.IsAttachment && oldgprSelect != part.ParentGroup.IsSelected) |
278 | || Permissions.CanMoveObject( | ||
279 | part.UUID, remoteClient.AgentId)) | ||
280 | EventManager.TriggerParcelPrimCountTainted(); | 259 | EventManager.TriggerParcelPrimCountTainted(); |
260 | |||
261 | // restore targetOmega | ||
262 | if (part.AngularVelocity != Vector3.Zero) | ||
263 | part.ScheduleTerseUpdate(); | ||
281 | } | 264 | } |
282 | } | 265 | } |
283 | 266 | ||
284 | public virtual void ProcessMoneyTransferRequest(UUID source, UUID destination, int amount, | 267 | public virtual void ProcessMoneyTransferRequest(UUID source, UUID destination, int amount, |
285 | int transactiontype, string description) | 268 | int transactiontype, string description) |
286 | { | 269 | { |
287 | EventManager.MoneyTransferArgs args = new EventManager.MoneyTransferArgs(source, destination, amount, | 270 | EventManager.MoneyTransferArgs args = new EventManager.MoneyTransferArgs(source, destination, amount, |
288 | transactiontype, description); | 271 | transactiontype, description); |
289 | 272 | ||
290 | EventManager.TriggerMoneyTransfer(this, args); | 273 | EventManager.TriggerMoneyTransfer(this, args); |
@@ -293,8 +276,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
293 | public virtual void ProcessParcelBuy(UUID agentId, UUID groupId, bool final, bool groupOwned, | 276 | public virtual void ProcessParcelBuy(UUID agentId, UUID groupId, bool final, bool groupOwned, |
294 | bool removeContribution, int parcelLocalID, int parcelArea, int parcelPrice, bool authenticated) | 277 | bool removeContribution, int parcelLocalID, int parcelArea, int parcelPrice, bool authenticated) |
295 | { | 278 | { |
296 | EventManager.LandBuyArgs args = new EventManager.LandBuyArgs(agentId, groupId, final, groupOwned, | 279 | EventManager.LandBuyArgs args = new EventManager.LandBuyArgs(agentId, groupId, final, groupOwned, |
297 | removeContribution, parcelLocalID, parcelArea, | 280 | removeContribution, parcelLocalID, parcelArea, |
298 | parcelPrice, authenticated); | 281 | parcelPrice, authenticated); |
299 | 282 | ||
300 | // First, allow all validators a stab at it | 283 | // First, allow all validators a stab at it |
@@ -307,7 +290,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
307 | public virtual void ProcessObjectGrab(uint localID, Vector3 offsetPos, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs) | 290 | public virtual void ProcessObjectGrab(uint localID, Vector3 offsetPos, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs) |
308 | { | 291 | { |
309 | SceneObjectPart part = GetSceneObjectPart(localID); | 292 | SceneObjectPart part = GetSceneObjectPart(localID); |
310 | 293 | ||
311 | if (part == null) | 294 | if (part == null) |
312 | return; | 295 | return; |
313 | 296 | ||
@@ -320,19 +303,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
320 | // Currently only grab/touch for the single prim | 303 | // Currently only grab/touch for the single prim |
321 | // the client handles rez correctly | 304 | // the client handles rez correctly |
322 | obj.ObjectGrabHandler(localID, offsetPos, remoteClient); | 305 | obj.ObjectGrabHandler(localID, offsetPos, remoteClient); |
323 | 306 | ||
324 | // If the touched prim handles touches, deliver it | 307 | // If the touched prim handles touches, deliver it |
325 | // If not, deliver to root prim | ||
326 | if ((part.ScriptEvents & scriptEvents.touch_start) != 0) | 308 | if ((part.ScriptEvents & scriptEvents.touch_start) != 0) |
327 | EventManager.TriggerObjectGrab(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg); | 309 | EventManager.TriggerObjectGrab(part.LocalId, 0, offsetPos, remoteClient, surfaceArg); |
328 | 310 | ||
329 | // Deliver to the root prim if the touched prim doesn't handle touches | 311 | // Deliver to the root prim if the touched prim doesn't handle touches |
330 | // or if we're meant to pass on touches anyway. Don't send to root prim | 312 | // or if we're meant to pass on touches anyway. |
331 | // if prim touched is the root prim as we just did it | ||
332 | if (((part.ScriptEvents & scriptEvents.touch_start) == 0) || | 313 | if (((part.ScriptEvents & scriptEvents.touch_start) == 0) || |
333 | (part.PassTouches && (part.LocalId != obj.RootPart.LocalId))) | 314 | (part.PassTouches && (part.LocalId != obj.RootPart.LocalId))) |
334 | { | 315 | { |
335 | EventManager.TriggerObjectGrab(obj.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg); | 316 | EventManager.TriggerObjectGrab(obj.RootPart.LocalId, part.LocalId, offsetPos, remoteClient, surfaceArg); |
336 | } | 317 | } |
337 | } | 318 | } |
338 | 319 | ||
@@ -343,23 +324,37 @@ namespace OpenSim.Region.Framework.Scenes | |||
343 | if (part == null) | 324 | if (part == null) |
344 | return; | 325 | return; |
345 | 326 | ||
346 | SceneObjectGroup obj = part.ParentGroup; | 327 | SceneObjectGroup group = part.ParentGroup; |
328 | if(group == null || group.IsDeleted) | ||
329 | return; | ||
330 | |||
331 | if (Permissions.CanMoveObject(group, remoteClient))// && PermissionsMngr.) | ||
332 | { | ||
333 | group.GrabMovement(objectID, offset, pos, remoteClient); | ||
334 | } | ||
335 | |||
336 | // This is outside the above permissions condition | ||
337 | // so that if the object is locked the client moving the object | ||
338 | // get's it's position on the simulator even if it was the same as before | ||
339 | // This keeps the moving user's client in sync with the rest of the world. | ||
340 | group.SendGroupTerseUpdate(); | ||
347 | 341 | ||
348 | SurfaceTouchEventArgs surfaceArg = null; | 342 | SurfaceTouchEventArgs surfaceArg = null; |
349 | if (surfaceArgs != null && surfaceArgs.Count > 0) | 343 | if (surfaceArgs != null && surfaceArgs.Count > 0) |
350 | surfaceArg = surfaceArgs[0]; | 344 | surfaceArg = surfaceArgs[0]; |
351 | 345 | ||
346 | Vector3 grabOffset = pos - part.AbsolutePosition; | ||
352 | // If the touched prim handles touches, deliver it | 347 | // If the touched prim handles touches, deliver it |
353 | // If not, deliver to root prim | ||
354 | if ((part.ScriptEvents & scriptEvents.touch) != 0) | 348 | if ((part.ScriptEvents & scriptEvents.touch) != 0) |
355 | EventManager.TriggerObjectGrabbing(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg); | 349 | // EventManager.TriggerObjectGrabbing(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg); |
350 | EventManager.TriggerObjectGrabbing(part.LocalId, 0, grabOffset, remoteClient, surfaceArg); | ||
356 | // Deliver to the root prim if the touched prim doesn't handle touches | 351 | // Deliver to the root prim if the touched prim doesn't handle touches |
357 | // or if we're meant to pass on touches anyway. Don't send to root prim | 352 | // or if we're meant to pass on touches anyway. |
358 | // if prim touched is the root prim as we just did it | ||
359 | if (((part.ScriptEvents & scriptEvents.touch) == 0) || | 353 | if (((part.ScriptEvents & scriptEvents.touch) == 0) || |
360 | (part.PassTouches && (part.LocalId != obj.RootPart.LocalId))) | 354 | (part.PassTouches && (part.LocalId != group.RootPart.LocalId))) |
361 | { | 355 | { |
362 | EventManager.TriggerObjectGrabbing(obj.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg); | 356 | // EventManager.TriggerObjectGrabbing(group.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg); |
357 | EventManager.TriggerObjectGrabbing(group.RootPart.LocalId, part.LocalId, grabOffset, remoteClient, surfaceArg); | ||
363 | } | 358 | } |
364 | } | 359 | } |
365 | 360 | ||
@@ -369,18 +364,77 @@ namespace OpenSim.Region.Framework.Scenes | |||
369 | if (part == null) | 364 | if (part == null) |
370 | return; | 365 | return; |
371 | 366 | ||
372 | SceneObjectGroup obj = part.ParentGroup; | 367 | SceneObjectGroup grp = part.ParentGroup; |
373 | 368 | ||
374 | SurfaceTouchEventArgs surfaceArg = null; | 369 | SurfaceTouchEventArgs surfaceArg = null; |
375 | if (surfaceArgs != null && surfaceArgs.Count > 0) | 370 | if (surfaceArgs != null && surfaceArgs.Count > 0) |
376 | surfaceArg = surfaceArgs[0]; | 371 | surfaceArg = surfaceArgs[0]; |
377 | 372 | ||
378 | // If the touched prim handles touches, deliver it | 373 | // If the touched prim handles touches, deliver it |
379 | // If not, deliver to root prim | ||
380 | if ((part.ScriptEvents & scriptEvents.touch_end) != 0) | 374 | if ((part.ScriptEvents & scriptEvents.touch_end) != 0) |
381 | EventManager.TriggerObjectDeGrab(part.LocalId, 0, remoteClient, surfaceArg); | 375 | EventManager.TriggerObjectDeGrab(part.LocalId, 0, remoteClient, surfaceArg); |
382 | else | 376 | // if not or PassTouchs, send it also to root. |
383 | EventManager.TriggerObjectDeGrab(obj.RootPart.LocalId, part.LocalId, remoteClient, surfaceArg); | 377 | if (((part.ScriptEvents & scriptEvents.touch_end) == 0) || |
378 | (part.PassTouches && (part.LocalId != grp.RootPart.LocalId))) | ||
379 | { | ||
380 | EventManager.TriggerObjectDeGrab(grp.RootPart.LocalId, part.LocalId, remoteClient, surfaceArg); | ||
381 | } | ||
382 | } | ||
383 | |||
384 | /// <summary> | ||
385 | /// Start spinning the given object | ||
386 | /// </summary> | ||
387 | /// <param name="objectID"></param> | ||
388 | /// <param name="rotation"></param> | ||
389 | /// <param name="remoteClient"></param> | ||
390 | public virtual void ProcessSpinStart(UUID objectID, IClientAPI remoteClient) | ||
391 | { | ||
392 | SceneObjectGroup group = GetGroupByPrim(objectID); | ||
393 | if (group != null) | ||
394 | { | ||
395 | if (Permissions.CanMoveObject(group, remoteClient))// && PermissionsMngr.) | ||
396 | { | ||
397 | group.SpinStart(remoteClient); | ||
398 | } | ||
399 | } | ||
400 | } | ||
401 | |||
402 | /// <summary> | ||
403 | /// Spin the given object | ||
404 | /// </summary> | ||
405 | /// <param name="objectID"></param> | ||
406 | /// <param name="rotation"></param> | ||
407 | /// <param name="remoteClient"></param> | ||
408 | public virtual void ProcessSpinObject(UUID objectID, Quaternion rotation, IClientAPI remoteClient) | ||
409 | { | ||
410 | SceneObjectGroup group = GetGroupByPrim(objectID); | ||
411 | if (group != null) | ||
412 | { | ||
413 | if (Permissions.CanMoveObject(group, remoteClient))// && PermissionsMngr.) | ||
414 | { | ||
415 | group.SpinMovement(rotation, remoteClient); | ||
416 | } | ||
417 | // This is outside the above permissions condition | ||
418 | // so that if the object is locked the client moving the object | ||
419 | // get's it's position on the simulator even if it was the same as before | ||
420 | // This keeps the moving user's client in sync with the rest of the world. | ||
421 | group.SendGroupTerseUpdate(); | ||
422 | } | ||
423 | } | ||
424 | |||
425 | public virtual void ProcessSpinObjectStop(UUID objectID, IClientAPI remoteClient) | ||
426 | { | ||
427 | /* no op for now | ||
428 | SceneObjectGroup group = GetGroupByPrim(objectID); | ||
429 | if (group != null) | ||
430 | { | ||
431 | if (Permissions.CanMoveObject(group.UUID, remoteClient.AgentId))// && PermissionsMngr.) | ||
432 | { | ||
433 | // group.SpinMovement(rotation, remoteClient); | ||
434 | } | ||
435 | group.SendGroupTerseUpdate(); | ||
436 | } | ||
437 | */ | ||
384 | } | 438 | } |
385 | 439 | ||
386 | public void ProcessScriptReset(IClientAPI remoteClient, UUID objectID, | 440 | public void ProcessScriptReset(IClientAPI remoteClient, UUID objectID, |
@@ -439,6 +493,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
439 | return Vector3.Distance(other.CameraPosition, thisClient.SceneAgent.AbsolutePosition) < 10; | 493 | return Vector3.Distance(other.CameraPosition, thisClient.SceneAgent.AbsolutePosition) < 10; |
440 | } | 494 | } |
441 | 495 | ||
496 | private class DescendentsRequestData | ||
497 | { | ||
498 | public IClientAPI RemoteClient; | ||
499 | public UUID FolderID; | ||
500 | public UUID OwnerID; | ||
501 | public bool FetchFolders; | ||
502 | public bool FetchItems; | ||
503 | public int SortOrder; | ||
504 | } | ||
505 | |||
506 | private Queue<DescendentsRequestData> m_descendentsRequestQueue = new Queue<DescendentsRequestData>(); | ||
507 | private Object m_descendentsRequestLock = new Object(); | ||
508 | private bool m_descendentsRequestProcessing = false; | ||
509 | |||
442 | /// <summary> | 510 | /// <summary> |
443 | /// Tell the client about the various child items and folders contained in the requested folder. | 511 | /// Tell the client about the various child items and folders contained in the requested folder. |
444 | /// </summary> | 512 | /// </summary> |
@@ -475,11 +543,31 @@ namespace OpenSim.Region.Framework.Scenes | |||
475 | } | 543 | } |
476 | } | 544 | } |
477 | 545 | ||
478 | // We're going to send the reply async, because there may be | 546 | lock (m_descendentsRequestLock) |
479 | // an enormous quantity of packets -- basically the entire inventory! | 547 | { |
480 | // We don't want to block the client thread while all that is happening. | 548 | if (!m_descendentsRequestProcessing) |
481 | SendInventoryDelegate d = SendInventoryAsync; | 549 | { |
482 | d.BeginInvoke(remoteClient, folderID, ownerID, fetchFolders, fetchItems, sortOrder, SendInventoryComplete, d); | 550 | m_descendentsRequestProcessing = true; |
551 | |||
552 | // We're going to send the reply async, because there may be | ||
553 | // an enormous quantity of packets -- basically the entire inventory! | ||
554 | // We don't want to block the client thread while all that is happening. | ||
555 | SendInventoryDelegate d = SendInventoryAsync; | ||
556 | d.BeginInvoke(remoteClient, folderID, ownerID, fetchFolders, fetchItems, sortOrder, SendInventoryComplete, d); | ||
557 | |||
558 | return; | ||
559 | } | ||
560 | |||
561 | DescendentsRequestData req = new DescendentsRequestData(); | ||
562 | req.RemoteClient = remoteClient; | ||
563 | req.FolderID = folderID; | ||
564 | req.OwnerID = ownerID; | ||
565 | req.FetchFolders = fetchFolders; | ||
566 | req.FetchItems = fetchItems; | ||
567 | req.SortOrder = sortOrder; | ||
568 | |||
569 | m_descendentsRequestQueue.Enqueue(req); | ||
570 | } | ||
483 | } | 571 | } |
484 | 572 | ||
485 | delegate void SendInventoryDelegate(IClientAPI remoteClient, UUID folderID, UUID ownerID, bool fetchFolders, bool fetchItems, int sortOrder); | 573 | delegate void SendInventoryDelegate(IClientAPI remoteClient, UUID folderID, UUID ownerID, bool fetchFolders, bool fetchItems, int sortOrder); |
@@ -494,16 +582,32 @@ namespace OpenSim.Region.Framework.Scenes | |||
494 | { | 582 | { |
495 | m_log.Error( | 583 | m_log.Error( |
496 | string.Format( | 584 | string.Format( |
497 | "[AGENT INVENTORY]: Error in SendInventoryAsync() for {0} with folder ID {1}. Exception ", e)); | 585 | "[AGENT INVENTORY]: Error in SendInventoryAsync() for {0} with folder ID {1}. Exception ", e, folderID)); |
498 | } | 586 | } |
587 | Thread.Sleep(20); | ||
499 | } | 588 | } |
500 | 589 | ||
501 | void SendInventoryComplete(IAsyncResult iar) | 590 | void SendInventoryComplete(IAsyncResult iar) |
502 | { | 591 | { |
503 | SendInventoryDelegate d = (SendInventoryDelegate)iar.AsyncState; | 592 | SendInventoryDelegate d = (SendInventoryDelegate)iar.AsyncState; |
504 | d.EndInvoke(iar); | 593 | d.EndInvoke(iar); |
594 | |||
595 | lock (m_descendentsRequestLock) | ||
596 | { | ||
597 | if (m_descendentsRequestQueue.Count > 0) | ||
598 | { | ||
599 | DescendentsRequestData req = m_descendentsRequestQueue.Dequeue(); | ||
600 | |||
601 | d = SendInventoryAsync; | ||
602 | d.BeginInvoke(req.RemoteClient, req.FolderID, req.OwnerID, req.FetchFolders, req.FetchItems, req.SortOrder, SendInventoryComplete, d); | ||
603 | |||
604 | return; | ||
605 | } | ||
606 | |||
607 | m_descendentsRequestProcessing = false; | ||
608 | } | ||
505 | } | 609 | } |
506 | 610 | ||
507 | /// <summary> | 611 | /// <summary> |
508 | /// Handle an inventory folder creation request from the client. | 612 | /// Handle an inventory folder creation request from the client. |
509 | /// </summary> | 613 | /// </summary> |
@@ -543,8 +647,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
543 | // m_log.DebugFormat( | 647 | // m_log.DebugFormat( |
544 | // "[AGENT INVENTORY]: Updating inventory folder {0} {1} for {2} {3}", folderID, name, remoteClient.Name, remoteClient.AgentId); | 648 | // "[AGENT INVENTORY]: Updating inventory folder {0} {1} for {2} {3}", folderID, name, remoteClient.Name, remoteClient.AgentId); |
545 | 649 | ||
546 | InventoryFolderBase folder = new InventoryFolderBase(folderID, remoteClient.AgentId); | 650 | InventoryFolderBase folder = InventoryService.GetFolder(remoteClient.AgentId, folderID); |
547 | folder = InventoryService.GetFolder(folder); | ||
548 | if (folder != null) | 651 | if (folder != null) |
549 | { | 652 | { |
550 | folder.Name = name; | 653 | folder.Name = name; |
@@ -558,11 +661,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
558 | } | 661 | } |
559 | } | 662 | } |
560 | } | 663 | } |
561 | 664 | ||
562 | public void HandleMoveInventoryFolder(IClientAPI remoteClient, UUID folderID, UUID parentID) | 665 | public void HandleMoveInventoryFolder(IClientAPI remoteClient, UUID folderID, UUID parentID) |
563 | { | 666 | { |
564 | InventoryFolderBase folder = new InventoryFolderBase(folderID, remoteClient.AgentId); | 667 | InventoryFolderBase folder = InventoryService.GetFolder(remoteClient.AgentId, folderID); |
565 | folder = InventoryService.GetFolder(folder); | ||
566 | if (folder != null) | 668 | if (folder != null) |
567 | { | 669 | { |
568 | folder.ParentID = parentID; | 670 | folder.ParentID = parentID; |
@@ -601,10 +703,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
601 | { | 703 | { |
602 | InventoryFolderBase folder = new InventoryFolderBase(folderID, userID); | 704 | InventoryFolderBase folder = new InventoryFolderBase(folderID, userID); |
603 | 705 | ||
604 | if (InventoryService.PurgeFolder(folder)) | 706 | try |
605 | m_log.DebugFormat("[AGENT INVENTORY]: folder {0} purged successfully", folderID); | 707 | { |
606 | else | 708 | if (InventoryService.PurgeFolder(folder)) |
607 | m_log.WarnFormat("[AGENT INVENTORY]: could not purge folder {0}", folderID); | 709 | m_log.DebugFormat("[AGENT INVENTORY]: folder {0} purged successfully", folderID); |
710 | else | ||
711 | m_log.WarnFormat("[AGENT INVENTORY]: could not purge folder {0}", folderID); | ||
712 | } | ||
713 | catch (Exception e) | ||
714 | { | ||
715 | m_log.WarnFormat("[AGENT INVENTORY]: Exception on async purge folder for user {0}: {1}", userID, e.Message); | ||
716 | } | ||
608 | } | 717 | } |
609 | 718 | ||
610 | private void PurgeFolderCompleted(IAsyncResult iar) | 719 | private void PurgeFolderCompleted(IAsyncResult iar) |