diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | 160 |
1 files changed, 122 insertions, 38 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index 8ebcd92..34b9c5f 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}", |
@@ -85,7 +86,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
85 | else | 86 | else |
86 | EventManager.TriggerOnChatFromWorld(this, args); | 87 | EventManager.TriggerOnChatFromWorld(this, args); |
87 | } | 88 | } |
88 | 89 | ||
89 | protected void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName, | 90 | protected void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName, |
90 | UUID fromID, bool fromAgent, bool broadcast) | 91 | UUID fromID, bool fromAgent, bool broadcast) |
91 | { | 92 | { |
@@ -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 | /// |
@@ -178,27 +166,52 @@ namespace OpenSim.Region.Framework.Scenes | |||
178 | /// <param name="remoteClient"></param> | 166 | /// <param name="remoteClient"></param> |
179 | public void SelectPrim(uint primLocalID, IClientAPI remoteClient) | 167 | public void SelectPrim(uint primLocalID, IClientAPI remoteClient) |
180 | { | 168 | { |
169 | /* | ||
170 | SceneObjectPart part = GetSceneObjectPart(primLocalID); | ||
171 | |||
172 | if (null == part) | ||
173 | return; | ||
174 | |||
175 | if (part.IsRoot) | ||
176 | { | ||
177 | SceneObjectGroup sog = part.ParentGroup; | ||
178 | sog.SendPropertiesToClient(remoteClient); | ||
179 | |||
180 | // A prim is only tainted if it's allowed to be edited by the person clicking it. | ||
181 | if (Permissions.CanEditObject(sog.UUID, remoteClient.AgentId) | ||
182 | || Permissions.CanMoveObject(sog.UUID, remoteClient.AgentId)) | ||
183 | { | ||
184 | sog.IsSelected = true; | ||
185 | EventManager.TriggerParcelPrimCountTainted(); | ||
186 | } | ||
187 | } | ||
188 | else | ||
189 | { | ||
190 | part.SendPropertiesToClient(remoteClient); | ||
191 | } | ||
192 | */ | ||
181 | SceneObjectPart part = GetSceneObjectPart(primLocalID); | 193 | SceneObjectPart part = GetSceneObjectPart(primLocalID); |
182 | 194 | ||
183 | if (null == part) | 195 | if (null == part) |
184 | return; | 196 | return; |
185 | 197 | ||
186 | if (part.IsRoot) | 198 | SceneObjectGroup sog = part.ParentGroup; |
187 | { | 199 | if (sog == null) |
188 | SceneObjectGroup sog = part.ParentGroup; | 200 | return; |
189 | sog.SendPropertiesToClient(remoteClient); | ||
190 | sog.IsSelected = true; | ||
191 | 201 | ||
192 | // A prim is only tainted if it's allowed to be edited by the person clicking it. | 202 | part.SendPropertiesToClient(remoteClient); |
193 | if (Permissions.CanEditObject(sog.UUID, remoteClient.AgentId) | 203 | |
194 | || Permissions.CanMoveObject(sog.UUID, remoteClient.AgentId)) | 204 | // waste of time because properties do not send prim flags as they should |
195 | { | 205 | // if a friend got or lost edit rights after login, a full update is needed |
196 | EventManager.TriggerParcelPrimCountTainted(); | 206 | if(sog.OwnerID != remoteClient.AgentId) |
197 | } | 207 | part.SendFullUpdate(remoteClient); |
198 | } | 208 | |
199 | else | 209 | // A prim is only tainted if it's allowed to be edited by the person clicking it. |
210 | if (Permissions.CanEditObject(sog.UUID, remoteClient.AgentId) | ||
211 | || Permissions.CanMoveObject(sog.UUID, remoteClient.AgentId)) | ||
200 | { | 212 | { |
201 | part.SendPropertiesToClient(remoteClient); | 213 | part.IsSelected = true; |
214 | EventManager.TriggerParcelPrimCountTainted(); | ||
202 | } | 215 | } |
203 | } | 216 | } |
204 | 217 | ||
@@ -251,7 +264,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
251 | SceneObjectPart part = GetSceneObjectPart(primLocalID); | 264 | SceneObjectPart part = GetSceneObjectPart(primLocalID); |
252 | if (part == null) | 265 | if (part == null) |
253 | return; | 266 | return; |
254 | 267 | /* | |
255 | // A deselect packet contains all the local prims being deselected. However, since selection is still | 268 | // A deselect packet contains all the local prims being deselected. However, since selection is still |
256 | // group based we only want the root prim to trigger a full update - otherwise on objects with many prims | 269 | // 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 | 270 | // we end up sending many duplicate ObjectUpdates |
@@ -262,7 +275,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
262 | // handled by group, but by prim. Legacy cruft. | 275 | // handled by group, but by prim. Legacy cruft. |
263 | // TODO: Make selection flagging per prim! | 276 | // TODO: Make selection flagging per prim! |
264 | // | 277 | // |
265 | part.ParentGroup.IsSelected = false; | 278 | if (Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.AgentId) |
279 | || Permissions.CanMoveObject(part.ParentGroup.UUID, remoteClient.AgentId)) | ||
280 | part.ParentGroup.IsSelected = false; | ||
266 | 281 | ||
267 | part.ParentGroup.ScheduleGroupForFullUpdate(); | 282 | part.ParentGroup.ScheduleGroupForFullUpdate(); |
268 | 283 | ||
@@ -279,6 +294,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
279 | part.UUID, remoteClient.AgentId)) | 294 | part.UUID, remoteClient.AgentId)) |
280 | EventManager.TriggerParcelPrimCountTainted(); | 295 | EventManager.TriggerParcelPrimCountTainted(); |
281 | } | 296 | } |
297 | */ | ||
298 | |||
299 | bool oldgprSelect = part.ParentGroup.IsSelected; | ||
300 | |||
301 | // This is wrong, wrong, wrong. Selection should not be | ||
302 | // handled by group, but by prim. Legacy cruft. | ||
303 | // TODO: Make selection flagging per prim! | ||
304 | // | ||
305 | if (Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.AgentId) | ||
306 | || Permissions.CanMoveObject(part.ParentGroup.UUID, remoteClient.AgentId)) | ||
307 | { | ||
308 | part.IsSelected = false; | ||
309 | if (!part.ParentGroup.IsAttachment && oldgprSelect != part.ParentGroup.IsSelected) | ||
310 | EventManager.TriggerParcelPrimCountTainted(); | ||
311 | |||
312 | // restore targetOmega | ||
313 | if (part.AngularVelocity != Vector3.Zero) | ||
314 | part.ScheduleTerseUpdate(); | ||
315 | } | ||
282 | } | 316 | } |
283 | 317 | ||
284 | public virtual void ProcessMoneyTransferRequest(UUID source, UUID destination, int amount, | 318 | public virtual void ProcessMoneyTransferRequest(UUID source, UUID destination, int amount, |
@@ -433,12 +467,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
433 | } | 467 | } |
434 | }); | 468 | }); |
435 | } | 469 | } |
436 | 470 | ||
437 | private bool ShouldSendDiscardableEffect(IClientAPI thisClient, ScenePresence other) | 471 | private bool ShouldSendDiscardableEffect(IClientAPI thisClient, ScenePresence other) |
438 | { | 472 | { |
439 | return Vector3.Distance(other.CameraPosition, thisClient.SceneAgent.AbsolutePosition) < 10; | 473 | return Vector3.Distance(other.CameraPosition, thisClient.SceneAgent.AbsolutePosition) < 10; |
440 | } | 474 | } |
441 | 475 | ||
476 | private class DescendentsRequestData | ||
477 | { | ||
478 | public IClientAPI RemoteClient; | ||
479 | public UUID FolderID; | ||
480 | public UUID OwnerID; | ||
481 | public bool FetchFolders; | ||
482 | public bool FetchItems; | ||
483 | public int SortOrder; | ||
484 | } | ||
485 | |||
486 | private Queue<DescendentsRequestData> m_descendentsRequestQueue = new Queue<DescendentsRequestData>(); | ||
487 | private Object m_descendentsRequestLock = new Object(); | ||
488 | private bool m_descendentsRequestProcessing = false; | ||
489 | |||
442 | /// <summary> | 490 | /// <summary> |
443 | /// Tell the client about the various child items and folders contained in the requested folder. | 491 | /// Tell the client about the various child items and folders contained in the requested folder. |
444 | /// </summary> | 492 | /// </summary> |
@@ -475,11 +523,31 @@ namespace OpenSim.Region.Framework.Scenes | |||
475 | } | 523 | } |
476 | } | 524 | } |
477 | 525 | ||
478 | // We're going to send the reply async, because there may be | 526 | lock (m_descendentsRequestLock) |
479 | // an enormous quantity of packets -- basically the entire inventory! | 527 | { |
480 | // We don't want to block the client thread while all that is happening. | 528 | if (!m_descendentsRequestProcessing) |
481 | SendInventoryDelegate d = SendInventoryAsync; | 529 | { |
482 | d.BeginInvoke(remoteClient, folderID, ownerID, fetchFolders, fetchItems, sortOrder, SendInventoryComplete, d); | 530 | m_descendentsRequestProcessing = true; |
531 | |||
532 | // We're going to send the reply async, because there may be | ||
533 | // an enormous quantity of packets -- basically the entire inventory! | ||
534 | // We don't want to block the client thread while all that is happening. | ||
535 | SendInventoryDelegate d = SendInventoryAsync; | ||
536 | d.BeginInvoke(remoteClient, folderID, ownerID, fetchFolders, fetchItems, sortOrder, SendInventoryComplete, d); | ||
537 | |||
538 | return; | ||
539 | } | ||
540 | |||
541 | DescendentsRequestData req = new DescendentsRequestData(); | ||
542 | req.RemoteClient = remoteClient; | ||
543 | req.FolderID = folderID; | ||
544 | req.OwnerID = ownerID; | ||
545 | req.FetchFolders = fetchFolders; | ||
546 | req.FetchItems = fetchItems; | ||
547 | req.SortOrder = sortOrder; | ||
548 | |||
549 | m_descendentsRequestQueue.Enqueue(req); | ||
550 | } | ||
483 | } | 551 | } |
484 | 552 | ||
485 | delegate void SendInventoryDelegate(IClientAPI remoteClient, UUID folderID, UUID ownerID, bool fetchFolders, bool fetchItems, int sortOrder); | 553 | delegate void SendInventoryDelegate(IClientAPI remoteClient, UUID folderID, UUID ownerID, bool fetchFolders, bool fetchItems, int sortOrder); |
@@ -496,12 +564,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
496 | string.Format( | 564 | string.Format( |
497 | "[AGENT INVENTORY]: Error in SendInventoryAsync() for {0} with folder ID {1}. Exception ", e)); | 565 | "[AGENT INVENTORY]: Error in SendInventoryAsync() for {0} with folder ID {1}. Exception ", e)); |
498 | } | 566 | } |
567 | Thread.Sleep(20); | ||
499 | } | 568 | } |
500 | 569 | ||
501 | void SendInventoryComplete(IAsyncResult iar) | 570 | void SendInventoryComplete(IAsyncResult iar) |
502 | { | 571 | { |
503 | SendInventoryDelegate d = (SendInventoryDelegate)iar.AsyncState; | 572 | SendInventoryDelegate d = (SendInventoryDelegate)iar.AsyncState; |
504 | d.EndInvoke(iar); | 573 | d.EndInvoke(iar); |
574 | |||
575 | lock (m_descendentsRequestLock) | ||
576 | { | ||
577 | if (m_descendentsRequestQueue.Count > 0) | ||
578 | { | ||
579 | DescendentsRequestData req = m_descendentsRequestQueue.Dequeue(); | ||
580 | |||
581 | d = SendInventoryAsync; | ||
582 | d.BeginInvoke(req.RemoteClient, req.FolderID, req.OwnerID, req.FetchFolders, req.FetchItems, req.SortOrder, SendInventoryComplete, d); | ||
583 | |||
584 | return; | ||
585 | } | ||
586 | |||
587 | m_descendentsRequestProcessing = false; | ||
588 | } | ||
505 | } | 589 | } |
506 | 590 | ||
507 | /// <summary> | 591 | /// <summary> |