diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 3435 |
1 files changed, 2079 insertions, 1356 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index b17b822..c18f587 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -62,7 +62,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
62 | /// Handles new client connections | 62 | /// Handles new client connections |
63 | /// Constructor takes a single Packet and authenticates everything | 63 | /// Constructor takes a single Packet and authenticates everything |
64 | /// </summary> | 64 | /// </summary> |
65 | public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientInventory, IStatsCollector | 65 | public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientInventory, IStatsCollector, IClientIPEndpoint |
66 | { | 66 | { |
67 | /// <value> | 67 | /// <value> |
68 | /// Debug packet level. See OpenSim.RegisterConsoleCommands() for more details. | 68 | /// Debug packet level. See OpenSim.RegisterConsoleCommands() for more details. |
@@ -80,6 +80,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
80 | public event ChatMessage OnChatFromClient; | 80 | public event ChatMessage OnChatFromClient; |
81 | public event RezObject OnRezObject; | 81 | public event RezObject OnRezObject; |
82 | public event DeRezObject OnDeRezObject; | 82 | public event DeRezObject OnDeRezObject; |
83 | public event RezRestoreToWorld OnRezRestoreToWorld; | ||
83 | public event ModifyTerrain OnModifyTerrain; | 84 | public event ModifyTerrain OnModifyTerrain; |
84 | public event Action<IClientAPI> OnRegionHandShakeReply; | 85 | public event Action<IClientAPI> OnRegionHandShakeReply; |
85 | public event GenericCall1 OnRequestWearables; | 86 | public event GenericCall1 OnRequestWearables; |
@@ -100,6 +101,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
100 | public event AvatarPickerRequest OnAvatarPickerRequest; | 101 | public event AvatarPickerRequest OnAvatarPickerRequest; |
101 | public event StartAnim OnStartAnim; | 102 | public event StartAnim OnStartAnim; |
102 | public event StopAnim OnStopAnim; | 103 | public event StopAnim OnStopAnim; |
104 | public event ChangeAnim OnChangeAnim; | ||
103 | public event Action<IClientAPI> OnRequestAvatarsData; | 105 | public event Action<IClientAPI> OnRequestAvatarsData; |
104 | public event LinkObjects OnLinkObjects; | 106 | public event LinkObjects OnLinkObjects; |
105 | public event DelinkObjects OnDelinkObjects; | 107 | public event DelinkObjects OnDelinkObjects; |
@@ -127,6 +129,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
127 | public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; | 129 | public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; |
128 | public event UpdatePrimFlags OnUpdatePrimFlags; | 130 | public event UpdatePrimFlags OnUpdatePrimFlags; |
129 | public event UpdatePrimTexture OnUpdatePrimTexture; | 131 | public event UpdatePrimTexture OnUpdatePrimTexture; |
132 | public event ClientChangeObject onClientChangeObject; | ||
130 | public event UpdateVector OnUpdatePrimGroupPosition; | 133 | public event UpdateVector OnUpdatePrimGroupPosition; |
131 | public event UpdateVector OnUpdatePrimSinglePosition; | 134 | public event UpdateVector OnUpdatePrimSinglePosition; |
132 | public event UpdatePrimRotation OnUpdatePrimGroupRotation; | 135 | public event UpdatePrimRotation OnUpdatePrimGroupRotation; |
@@ -156,6 +159,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
156 | public event RequestTaskInventory OnRequestTaskInventory; | 159 | public event RequestTaskInventory OnRequestTaskInventory; |
157 | public event UpdateInventoryItem OnUpdateInventoryItem; | 160 | public event UpdateInventoryItem OnUpdateInventoryItem; |
158 | public event CopyInventoryItem OnCopyInventoryItem; | 161 | public event CopyInventoryItem OnCopyInventoryItem; |
162 | public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy; | ||
159 | public event MoveInventoryItem OnMoveInventoryItem; | 163 | public event MoveInventoryItem OnMoveInventoryItem; |
160 | public event RemoveInventoryItem OnRemoveInventoryItem; | 164 | public event RemoveInventoryItem OnRemoveInventoryItem; |
161 | public event RemoveInventoryFolder OnRemoveInventoryFolder; | 165 | public event RemoveInventoryFolder OnRemoveInventoryFolder; |
@@ -250,7 +254,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
250 | public event ClassifiedInfoRequest OnClassifiedInfoRequest; | 254 | public event ClassifiedInfoRequest OnClassifiedInfoRequest; |
251 | public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; | 255 | public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; |
252 | public event ClassifiedDelete OnClassifiedDelete; | 256 | public event ClassifiedDelete OnClassifiedDelete; |
253 | public event ClassifiedDelete OnClassifiedGodDelete; | 257 | public event ClassifiedGodDelete OnClassifiedGodDelete; |
254 | public event EventNotificationAddRequest OnEventNotificationAddRequest; | 258 | public event EventNotificationAddRequest OnEventNotificationAddRequest; |
255 | public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; | 259 | public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; |
256 | public event EventGodDelete OnEventGodDelete; | 260 | public event EventGodDelete OnEventGodDelete; |
@@ -281,10 +285,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
281 | public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; | 285 | public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; |
282 | public event SimWideDeletesDelegate OnSimWideDeletes; | 286 | public event SimWideDeletesDelegate OnSimWideDeletes; |
283 | public event SendPostcard OnSendPostcard; | 287 | public event SendPostcard OnSendPostcard; |
288 | public event ChangeInventoryItemFlags OnChangeInventoryItemFlags; | ||
284 | public event MuteListEntryUpdate OnUpdateMuteListEntry; | 289 | public event MuteListEntryUpdate OnUpdateMuteListEntry; |
285 | public event MuteListEntryRemove OnRemoveMuteListEntry; | 290 | public event MuteListEntryRemove OnRemoveMuteListEntry; |
286 | public event GodlikeMessage onGodlikeMessage; | 291 | public event GodlikeMessage onGodlikeMessage; |
287 | public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate; | 292 | public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate; |
293 | public event GenericCall2 OnUpdateThrottles; | ||
288 | 294 | ||
289 | #pragma warning disable 0067 | 295 | #pragma warning disable 0067 |
290 | public event GenericMessage OnGenericMessage; | 296 | public event GenericMessage OnGenericMessage; |
@@ -319,6 +325,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
319 | /// </summary> | 325 | /// </summary> |
320 | public LLImageManager ImageManager { get; private set; } | 326 | public LLImageManager ImageManager { get; private set; } |
321 | 327 | ||
328 | public JobEngine m_asyncPacketProcess; | ||
322 | private readonly LLUDPServer m_udpServer; | 329 | private readonly LLUDPServer m_udpServer; |
323 | private readonly LLUDPClient m_udpClient; | 330 | private readonly LLUDPClient m_udpClient; |
324 | private readonly UUID m_sessionId; | 331 | private readonly UUID m_sessionId; |
@@ -328,31 +335,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
328 | private readonly byte[] m_channelVersion = Utils.EmptyBytes; | 335 | private readonly byte[] m_channelVersion = Utils.EmptyBytes; |
329 | private readonly IGroupsModule m_GroupsModule; | 336 | private readonly IGroupsModule m_GroupsModule; |
330 | 337 | ||
331 | private int m_cachedTextureSerial; | 338 | // private int m_cachedTextureSerial; |
332 | private PriorityQueue m_entityUpdates; | 339 | private PriorityQueue m_entityUpdates; |
333 | private PriorityQueue m_entityProps; | 340 | private PriorityQueue m_entityProps; |
334 | private Prioritizer m_prioritizer; | 341 | private Prioritizer m_prioritizer; |
335 | private bool m_disableFacelights = false; | 342 | private bool m_disableFacelights = false; |
336 | private volatile bool m_justEditedTerrain = false; | 343 | |
337 | /// <value> | 344 | // needs optimazation |
338 | /// List used in construction of data blocks for an object update packet. This is to stop us having to | 345 | private HashSet<SceneObjectGroup> GroupsInView = new HashSet<SceneObjectGroup>(); |
339 | /// continually recreate it. | 346 | |
340 | /// </value> | 347 | // private bool m_VelocityInterpolate = false; |
341 | protected List<ObjectUpdatePacket.ObjectDataBlock> m_fullUpdateDataBlocksBuilder; | 348 | private const uint MaxTransferBytesPerPacket = 600; |
342 | 349 | ||
343 | /// <value> | 350 | /// <value> |
344 | /// Maintain a record of all the objects killed. This allows us to stop an update being sent from the | 351 | /// Maintain a record of all the objects killed. This allows us to stop an update being sent from the |
345 | /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an | 352 | /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an |
346 | /// ownerless phantom. | 353 | /// ownerless phantom. |
347 | /// | 354 | /// |
348 | /// All manipulation of this set has to occur under a lock | 355 | /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock |
349 | /// | 356 | /// |
350 | /// </value> | 357 | /// </value> |
351 | protected HashSet<uint> m_killRecord; | 358 | protected List<uint> m_killRecord; |
352 | 359 | ||
353 | // protected HashSet<uint> m_attachmentsSent; | 360 | // protected HashSet<uint> m_attachmentsSent; |
354 | 361 | ||
355 | private int m_animationSequenceNumber = 1; | 362 | private bool m_deliverPackets = true; |
363 | |||
356 | private bool m_SendLogoutPacketWhenClosing = true; | 364 | private bool m_SendLogoutPacketWhenClosing = true; |
357 | 365 | ||
358 | /// <summary> | 366 | /// <summary> |
@@ -371,7 +379,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
371 | protected Scene m_scene; | 379 | protected Scene m_scene; |
372 | protected string m_firstName; | 380 | protected string m_firstName; |
373 | protected string m_lastName; | 381 | protected string m_lastName; |
374 | protected Thread m_clientThread; | ||
375 | protected Vector3 m_startpos; | 382 | protected Vector3 m_startpos; |
376 | protected UUID m_activeGroupID; | 383 | protected UUID m_activeGroupID; |
377 | protected string m_activeGroupName = String.Empty; | 384 | protected string m_activeGroupName = String.Empty; |
@@ -398,18 +405,36 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
398 | get { return m_startpos; } | 405 | get { return m_startpos; } |
399 | set { m_startpos = value; } | 406 | set { m_startpos = value; } |
400 | } | 407 | } |
408 | public bool DeliverPackets | ||
409 | { | ||
410 | get { return m_deliverPackets; } | ||
411 | set { | ||
412 | m_deliverPackets = value; | ||
413 | m_udpClient.m_deliverPackets = value; | ||
414 | } | ||
415 | } | ||
401 | public UUID AgentId { get { return m_agentId; } } | 416 | public UUID AgentId { get { return m_agentId; } } |
402 | public ISceneAgent SceneAgent { get; set; } | 417 | public ISceneAgent SceneAgent { get; set; } |
403 | public UUID ActiveGroupId { get { return m_activeGroupID; } private set { m_activeGroupID = value; } } | 418 | public UUID ActiveGroupId { get { return m_activeGroupID; } set { m_activeGroupID = value; } } |
404 | public string ActiveGroupName { get { return m_activeGroupName; } private set { m_activeGroupName = value; } } | 419 | public string ActiveGroupName { get { return m_activeGroupName; } set { m_activeGroupName = value; } } |
405 | public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } private set { m_activeGroupPowers = value; } } | 420 | public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } set { m_activeGroupPowers = value; } } |
406 | public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); } | 421 | public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); } |
407 | 422 | ||
423 | public int PingTimeMS | ||
424 | { | ||
425 | get | ||
426 | { | ||
427 | if (UDPClient != null) | ||
428 | return UDPClient.PingTimeMS; | ||
429 | return 0; | ||
430 | } | ||
431 | } | ||
432 | |||
408 | /// <summary> | 433 | /// <summary> |
409 | /// Entity update queues | 434 | /// Entity update queues |
410 | /// </summary> | 435 | /// </summary> |
411 | public PriorityQueue EntityUpdateQueue { get { return m_entityUpdates; } } | 436 | public PriorityQueue EntityUpdateQueue { get { return m_entityUpdates; } } |
412 | 437 | ||
413 | /// <summary> | 438 | /// <summary> |
414 | /// First name of the agent/avatar represented by the client | 439 | /// First name of the agent/avatar represented by the client |
415 | /// </summary> | 440 | /// </summary> |
@@ -426,7 +451,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
426 | public string Name { get { return FirstName + " " + LastName; } } | 451 | public string Name { get { return FirstName + " " + LastName; } } |
427 | 452 | ||
428 | public uint CircuitCode { get { return m_circuitCode; } } | 453 | public uint CircuitCode { get { return m_circuitCode; } } |
429 | public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } } | 454 | public int NextAnimationSequenceNumber |
455 | { | ||
456 | get { return m_udpServer.NextAnimationSequenceNumber; } | ||
457 | } | ||
430 | 458 | ||
431 | /// <summary> | 459 | /// <summary> |
432 | /// As well as it's function in IClientAPI, in LLClientView we are locking on this property in order to | 460 | /// As well as it's function in IClientAPI, in LLClientView we are locking on this property in order to |
@@ -447,8 +475,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
447 | set { m_disableFacelights = value; } | 475 | set { m_disableFacelights = value; } |
448 | } | 476 | } |
449 | 477 | ||
478 | public List<uint> SelectedObjects {get; private set;} | ||
479 | |||
450 | public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } } | 480 | public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } } |
451 | 481 | ||
482 | |||
452 | #endregion Properties | 483 | #endregion Properties |
453 | 484 | ||
454 | // ~LLClientView() | 485 | // ~LLClientView() |
@@ -465,6 +496,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
465 | // DebugPacketLevel = 1; | 496 | // DebugPacketLevel = 1; |
466 | 497 | ||
467 | CloseSyncLock = new Object(); | 498 | CloseSyncLock = new Object(); |
499 | SelectedObjects = new List<uint>(); | ||
468 | 500 | ||
469 | RegisterInterface<IClientIM>(this); | 501 | RegisterInterface<IClientIM>(this); |
470 | RegisterInterface<IClientInventory>(this); | 502 | RegisterInterface<IClientInventory>(this); |
@@ -473,8 +505,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
473 | m_scene = scene; | 505 | m_scene = scene; |
474 | m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); | 506 | m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); |
475 | m_entityProps = new PriorityQueue(m_scene.Entities.Count); | 507 | m_entityProps = new PriorityQueue(m_scene.Entities.Count); |
476 | m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); | 508 | m_killRecord = new List<uint>(); |
477 | m_killRecord = new HashSet<uint>(); | ||
478 | // m_attachmentsSent = new HashSet<uint>(); | 509 | // m_attachmentsSent = new HashSet<uint>(); |
479 | 510 | ||
480 | m_assetService = m_scene.RequestModuleInterface<IAssetService>(); | 511 | m_assetService = m_scene.RequestModuleInterface<IAssetService>(); |
@@ -498,18 +529,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
498 | m_prioritizer = new Prioritizer(m_scene); | 529 | m_prioritizer = new Prioritizer(m_scene); |
499 | 530 | ||
500 | RegisterLocalPacketHandlers(); | 531 | RegisterLocalPacketHandlers(); |
501 | 532 | string name = string.Format("AsyncInUDP-{0}",m_agentId.ToString()); | |
533 | m_asyncPacketProcess = new JobEngine(name, name, 10000); | ||
502 | IsActive = true; | 534 | IsActive = true; |
503 | } | 535 | } |
504 | 536 | ||
505 | #region Client Methods | 537 | #region Client Methods |
506 | 538 | ||
539 | |||
540 | /// <summary> | ||
541 | /// Close down the client view | ||
542 | /// </summary> | ||
507 | public void Close() | 543 | public void Close() |
508 | { | 544 | { |
509 | Close(false); | 545 | Close(true, false); |
510 | } | 546 | } |
511 | 547 | ||
512 | public void Close(bool force) | 548 | public void Close(bool sendStop, bool force) |
513 | { | 549 | { |
514 | // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. | 550 | // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. |
515 | // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. | 551 | // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. |
@@ -519,14 +555,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
519 | // there is some unidentified connection problem, not where we have issues due to deadlock | 555 | // there is some unidentified connection problem, not where we have issues due to deadlock |
520 | if (!IsActive && !force) | 556 | if (!IsActive && !force) |
521 | { | 557 | { |
522 | m_log.DebugFormat( "{0} Not attempting to close inactive client {1} in {2} since force flag is not set", | 558 | m_log.DebugFormat( "{0} Not attempting to close inactive client {1} in {2} since force flag is not set", |
523 | LogHeader, Name, m_scene.Name); | 559 | LogHeader, Name, m_scene.Name); |
524 | 560 | ||
525 | return; | 561 | return; |
526 | } | 562 | } |
527 | 563 | ||
528 | IsActive = false; | 564 | IsActive = false; |
529 | CloseWithoutChecks(); | 565 | CloseWithoutChecks(sendStop); |
530 | } | 566 | } |
531 | } | 567 | } |
532 | 568 | ||
@@ -539,19 +575,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
539 | /// | 575 | /// |
540 | /// Callers must lock ClosingSyncLock before calling. | 576 | /// Callers must lock ClosingSyncLock before calling. |
541 | /// </remarks> | 577 | /// </remarks> |
542 | public void CloseWithoutChecks() | 578 | public void CloseWithoutChecks(bool sendStop) |
543 | { | 579 | { |
544 | m_log.DebugFormat( | 580 | m_log.DebugFormat( |
545 | "[CLIENT]: Close has been called for {0} attached to scene {1}", | 581 | "[CLIENT]: Close has been called for {0} attached to scene {1}", |
546 | Name, m_scene.RegionInfo.RegionName); | 582 | Name, m_scene.RegionInfo.RegionName); |
547 | 583 | ||
548 | // Shutdown the image manager | 584 | if (sendStop) |
549 | ImageManager.Close(); | 585 | { |
586 | // Send the STOP packet | ||
587 | DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); | ||
588 | OutPacket(disable, ThrottleOutPacketType.Unknown); | ||
589 | } | ||
590 | |||
550 | 591 | ||
551 | // Fire the callback for this connection closing | 592 | // Fire the callback for this connection closing |
552 | if (OnConnectionClosed != null) | 593 | if (OnConnectionClosed != null) |
553 | OnConnectionClosed(this); | 594 | OnConnectionClosed(this); |
554 | 595 | ||
596 | m_asyncPacketProcess.Stop(); | ||
597 | |||
555 | // Flush all of the packets out of the UDP server for this client | 598 | // Flush all of the packets out of the UDP server for this client |
556 | if (m_udpServer != null) | 599 | if (m_udpServer != null) |
557 | m_udpServer.Flush(m_udpClient); | 600 | m_udpServer.Flush(m_udpClient); |
@@ -565,11 +608,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
565 | //m_scene.CloseAllAgents(CircuitCode); | 608 | //m_scene.CloseAllAgents(CircuitCode); |
566 | 609 | ||
567 | // Disable UDP handling for this client | 610 | // Disable UDP handling for this client |
611 | m_udpClient.OnQueueEmpty -= HandleQueueEmpty; | ||
612 | m_udpClient.HasUpdates -= HandleHasUpdates; | ||
613 | m_udpClient.OnPacketStats -= PopulateStats; | ||
568 | m_udpClient.Shutdown(); | 614 | m_udpClient.Shutdown(); |
569 | 615 | ||
570 | //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false)); | 616 | // Shutdown the image manager |
571 | //GC.Collect(); | 617 | ImageManager.Close(); |
572 | //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true)); | 618 | ImageManager = null; |
619 | |||
620 | m_entityUpdates = new PriorityQueue(1); | ||
621 | m_entityProps = new PriorityQueue(1); | ||
622 | m_killRecord.Clear(); | ||
623 | GroupsInView.Clear(); | ||
624 | |||
625 | if(m_scene.GetNumberOfClients() == 0) | ||
626 | { | ||
627 | GC.Collect(); | ||
628 | GC.WaitForPendingFinalizers(); | ||
629 | GC.Collect(); | ||
630 | } | ||
573 | } | 631 | } |
574 | 632 | ||
575 | public void Kick(string message) | 633 | public void Kick(string message) |
@@ -648,36 +706,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
648 | /// <returns>true if the handler was added. This is currently always the case.</returns> | 706 | /// <returns>true if the handler was added. This is currently always the case.</returns> |
649 | public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync) | 707 | public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync) |
650 | { | 708 | { |
651 | return AddLocalPacketHandler(packetType, handler, doAsync, false); | ||
652 | } | ||
653 | |||
654 | /// <summary> | ||
655 | /// Add a handler for the given packet type. | ||
656 | /// </summary> | ||
657 | /// <param name="packetType"></param> | ||
658 | /// <param name="handler"></param> | ||
659 | /// <param name="doAsync"> | ||
660 | /// If true, when the packet is received handle it on a different thread. Whether this is given direct to | ||
661 | /// a threadpool thread or placed in a queue depends on the inEngine parameter. | ||
662 | /// </param> | ||
663 | /// <param name="inEngine"> | ||
664 | /// If async is false then this parameter is ignored. | ||
665 | /// If async is true and inEngine is false, then the packet is sent directly to a | ||
666 | /// threadpool thread. | ||
667 | /// If async is true and inEngine is true, then the packet is sent to the IncomingPacketAsyncHandlingEngine. | ||
668 | /// This may result in slower handling but reduces the risk of overloading the simulator when there are many | ||
669 | /// simultaneous async requests. | ||
670 | /// </param> | ||
671 | /// <returns>true if the handler was added. This is currently always the case.</returns> | ||
672 | public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync, bool inEngine) | ||
673 | { | ||
674 | bool result = false; | 709 | bool result = false; |
675 | lock (m_packetHandlers) | 710 | lock (m_packetHandlers) |
676 | { | 711 | { |
677 | if (!m_packetHandlers.ContainsKey(packetType)) | 712 | if (!m_packetHandlers.ContainsKey(packetType)) |
678 | { | 713 | { |
679 | m_packetHandlers.Add( | 714 | m_packetHandlers.Add( |
680 | packetType, new PacketProcessor() { method = handler, Async = doAsync, InEngine = inEngine }); | 715 | packetType, new PacketProcessor() { method = handler, Async = doAsync}); |
681 | result = true; | 716 | result = true; |
682 | } | 717 | } |
683 | } | 718 | } |
@@ -712,30 +747,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
712 | PacketProcessor pprocessor; | 747 | PacketProcessor pprocessor; |
713 | if (m_packetHandlers.TryGetValue(packet.Type, out pprocessor)) | 748 | if (m_packetHandlers.TryGetValue(packet.Type, out pprocessor)) |
714 | { | 749 | { |
715 | ClientInfo cinfo = UDPClient.GetClientInfo(); | ||
716 | 750 | ||
717 | //there is a local handler for this packet type | 751 | //there is a local handler for this packet type |
718 | if (pprocessor.Async) | 752 | if (pprocessor.Async) |
719 | { | 753 | { |
720 | if (!cinfo.AsyncRequests.ContainsKey(packet.Type.ToString())) | ||
721 | cinfo.AsyncRequests[packet.Type.ToString()] = 0; | ||
722 | cinfo.AsyncRequests[packet.Type.ToString()]++; | ||
723 | |||
724 | object obj = new AsyncPacketProcess(this, pprocessor.method, packet); | 754 | object obj = new AsyncPacketProcess(this, pprocessor.method, packet); |
725 | 755 | m_asyncPacketProcess.QueueJob(packet.Type.ToString(), () => ProcessSpecificPacketAsync(obj)); | |
726 | if (pprocessor.InEngine) | ||
727 | m_udpServer.IpahEngine.QueueJob(packet.Type.ToString(), () => ProcessSpecificPacketAsync(obj)); | ||
728 | else | ||
729 | Util.FireAndForget(ProcessSpecificPacketAsync, obj, packet.Type.ToString()); | ||
730 | |||
731 | result = true; | 756 | result = true; |
732 | } | 757 | } |
733 | else | 758 | else |
734 | { | 759 | { |
735 | if (!cinfo.SyncRequests.ContainsKey(packet.Type.ToString())) | ||
736 | cinfo.SyncRequests[packet.Type.ToString()] = 0; | ||
737 | cinfo.SyncRequests[packet.Type.ToString()]++; | ||
738 | |||
739 | result = pprocessor.method(this, packet); | 760 | result = pprocessor.method(this, packet); |
740 | } | 761 | } |
741 | } | 762 | } |
@@ -750,11 +771,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
750 | } | 771 | } |
751 | if (found) | 772 | if (found) |
752 | { | 773 | { |
753 | ClientInfo cinfo = UDPClient.GetClientInfo(); | ||
754 | if (!cinfo.GenericRequests.ContainsKey(packet.Type.ToString())) | ||
755 | cinfo.GenericRequests[packet.Type.ToString()] = 0; | ||
756 | cinfo.GenericRequests[packet.Type.ToString()]++; | ||
757 | |||
758 | result = method(this, packet); | 774 | result = method(this, packet); |
759 | } | 775 | } |
760 | } | 776 | } |
@@ -774,7 +790,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
774 | // Make sure that we see any exception caused by the asynchronous operation. | 790 | // Make sure that we see any exception caused by the asynchronous operation. |
775 | m_log.Error( | 791 | m_log.Error( |
776 | string.Format( | 792 | string.Format( |
777 | "[LLCLIENTVIEW]: Caught exception while processing {0} for {1} ", packetObject.Pack, Name), | 793 | "[LLCLIENTVIEW]: Caught exception while processing {0} for {1} ", packetObject.Pack, Name), |
778 | e); | 794 | e); |
779 | } | 795 | } |
780 | } | 796 | } |
@@ -785,9 +801,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
785 | 801 | ||
786 | public virtual void Start() | 802 | public virtual void Start() |
787 | { | 803 | { |
804 | m_asyncPacketProcess.Start(); | ||
788 | m_scene.AddNewAgent(this, PresenceType.User); | 805 | m_scene.AddNewAgent(this, PresenceType.User); |
789 | 806 | ||
790 | RefreshGroupMembership(); | 807 | // RefreshGroupMembership(); |
791 | } | 808 | } |
792 | 809 | ||
793 | # endregion | 810 | # endregion |
@@ -858,6 +875,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
858 | 875 | ||
859 | public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) | 876 | public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) |
860 | { | 877 | { |
878 | m_thisAgentUpdateArgs.CameraAtAxis.X = float.MinValue; | ||
879 | // m_thisAgentUpdateArgs.ControlFlags = uint.MaxValue; | ||
880 | m_thisAgentUpdateArgs.ControlFlags = 0; | ||
881 | |||
861 | AgentMovementCompletePacket mov = (AgentMovementCompletePacket)PacketPool.Instance.GetPacket(PacketType.AgentMovementComplete); | 882 | AgentMovementCompletePacket mov = (AgentMovementCompletePacket)PacketPool.Instance.GetPacket(PacketType.AgentMovementComplete); |
862 | mov.SimData.ChannelVersion = m_channelVersion; | 883 | mov.SimData.ChannelVersion = m_channelVersion; |
863 | mov.AgentData.SessionID = m_sessionId; | 884 | mov.AgentData.SessionID = m_sessionId; |
@@ -893,14 +914,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
893 | reply.ChatData.OwnerID = ownerID; | 914 | reply.ChatData.OwnerID = ownerID; |
894 | reply.ChatData.SourceID = fromAgentID; | 915 | reply.ChatData.SourceID = fromAgentID; |
895 | 916 | ||
896 | OutPacket(reply, ThrottleOutPacketType.Task); | 917 | OutPacket(reply, ThrottleOutPacketType.Unknown); |
897 | } | 918 | } |
898 | 919 | ||
899 | /// <summary> | 920 | /// <summary> |
900 | /// Send an instant message to this client | 921 | /// Send an instant message to this client |
901 | /// </summary> | 922 | /// </summary> |
902 | // | 923 | // |
903 | // Don't remove transaction ID! Groups and item gives need to set it! | ||
904 | public void SendInstantMessage(GridInstantMessage im) | 924 | public void SendInstantMessage(GridInstantMessage im) |
905 | { | 925 | { |
906 | if (((Scene)(m_scene)).Permissions.CanInstantMessage(new UUID(im.fromAgentID), new UUID(im.toAgentID))) | 926 | if (((Scene)(m_scene)).Permissions.CanInstantMessage(new UUID(im.fromAgentID), new UUID(im.toAgentID))) |
@@ -913,6 +933,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
913 | msg.MessageBlock.FromAgentName = Util.StringToBytes256(im.fromAgentName); | 933 | msg.MessageBlock.FromAgentName = Util.StringToBytes256(im.fromAgentName); |
914 | msg.MessageBlock.Dialog = im.dialog; | 934 | msg.MessageBlock.Dialog = im.dialog; |
915 | msg.MessageBlock.FromGroup = im.fromGroup; | 935 | msg.MessageBlock.FromGroup = im.fromGroup; |
936 | // this is odd | ||
916 | if (im.imSessionID == UUID.Zero.Guid) | 937 | if (im.imSessionID == UUID.Zero.Guid) |
917 | msg.MessageBlock.ID = new UUID(im.fromAgentID) ^ new UUID(im.toAgentID); | 938 | msg.MessageBlock.ID = new UUID(im.fromAgentID) ^ new UUID(im.toAgentID); |
918 | else | 939 | else |
@@ -926,32 +947,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
926 | msg.MessageBlock.Message = Util.StringToBytes1024(im.message); | 947 | msg.MessageBlock.Message = Util.StringToBytes1024(im.message); |
927 | msg.MessageBlock.BinaryBucket = im.binaryBucket; | 948 | msg.MessageBlock.BinaryBucket = im.binaryBucket; |
928 | 949 | ||
929 | if (im.message.StartsWith("[grouptest]")) | 950 | OutPacket(msg, ThrottleOutPacketType.Task); |
930 | { // this block is test code for implementing group IM - delete when group IM is finished | ||
931 | IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>(); | ||
932 | if (eq != null) | ||
933 | { | ||
934 | im.dialog = 17; | ||
935 | |||
936 | //eq.ChatterboxInvitation( | ||
937 | // new UUID("00000000-68f9-1111-024e-222222111123"), | ||
938 | // "OpenSimulator Testing", im.fromAgentID, im.message, im.toAgentID, im.fromAgentName, im.dialog, 0, | ||
939 | // false, 0, new Vector3(), 1, im.imSessionID, im.fromGroup, im.binaryBucket); | ||
940 | |||
941 | eq.ChatterboxInvitation( | ||
942 | new UUID("00000000-68f9-1111-024e-222222111123"), | ||
943 | "OpenSimulator Testing", new UUID(im.fromAgentID), im.message, new UUID(im.toAgentID), im.fromAgentName, im.dialog, 0, | ||
944 | false, 0, new Vector3(), 1, new UUID(im.imSessionID), im.fromGroup, Util.StringToBytes256("OpenSimulator Testing")); | ||
945 | |||
946 | eq.ChatterBoxSessionAgentListUpdates( | ||
947 | new UUID("00000000-68f9-1111-024e-222222111123"), | ||
948 | new UUID(im.fromAgentID), new UUID(im.toAgentID), false, false, false); | ||
949 | } | ||
950 | |||
951 | Console.WriteLine("SendInstantMessage: " + msg); | ||
952 | } | ||
953 | else | ||
954 | OutPacket(msg, ThrottleOutPacketType.Task); | ||
955 | } | 951 | } |
956 | } | 952 | } |
957 | 953 | ||
@@ -1182,6 +1178,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1182 | OutPacket(GATRP, ThrottleOutPacketType.Task); | 1178 | OutPacket(GATRP, ThrottleOutPacketType.Task); |
1183 | } | 1179 | } |
1184 | 1180 | ||
1181 | |||
1182 | public virtual bool CanSendLayerData() | ||
1183 | { | ||
1184 | int n = m_udpClient.GetPacketsQueuedCount(ThrottleOutPacketType.Land); | ||
1185 | if ( n > 128) | ||
1186 | return false; | ||
1187 | return true; | ||
1188 | } | ||
1189 | |||
1185 | /// <summary> | 1190 | /// <summary> |
1186 | /// Send the region heightmap to the client | 1191 | /// Send the region heightmap to the client |
1187 | /// This method is only called when not doing intellegent terrain patch sending and | 1192 | /// This method is only called when not doing intellegent terrain patch sending and |
@@ -1192,6 +1197,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1192 | public virtual void SendLayerData(float[] map) | 1197 | public virtual void SendLayerData(float[] map) |
1193 | { | 1198 | { |
1194 | Util.FireAndForget(DoSendLayerData, m_scene.Heightmap.GetTerrainData(), "LLClientView.DoSendLayerData"); | 1199 | Util.FireAndForget(DoSendLayerData, m_scene.Heightmap.GetTerrainData(), "LLClientView.DoSendLayerData"); |
1200 | |||
1201 | // Send it sync, and async. It's not that much data | ||
1202 | // and it improves user experience just so much! | ||
1203 | // DoSendLayerData(map); | ||
1195 | } | 1204 | } |
1196 | 1205 | ||
1197 | /// <summary> | 1206 | /// <summary> |
@@ -1214,7 +1223,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1214 | //} | 1223 | //} |
1215 | 1224 | ||
1216 | // Send LayerData in a spiral pattern. Fun! | 1225 | // Send LayerData in a spiral pattern. Fun! |
1217 | SendLayerTopRight(map, 0, 0, map.SizeX/Constants.TerrainPatchSize-1, map.SizeY/Constants.TerrainPatchSize-1); | 1226 | SendLayerTopRight(map, 0, 0, map.SizeX / Constants.TerrainPatchSize - 1, map.SizeY / Constants.TerrainPatchSize - 1); |
1218 | } | 1227 | } |
1219 | catch (Exception e) | 1228 | catch (Exception e) |
1220 | { | 1229 | { |
@@ -1250,27 +1259,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1250 | SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1); | 1259 | SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1); |
1251 | } | 1260 | } |
1252 | 1261 | ||
1253 | /// <summary> | ||
1254 | /// Sends a set of four patches (x, x+1, ..., x+3) to the client | ||
1255 | /// </summary> | ||
1256 | /// <param name="map">heightmap</param> | ||
1257 | /// <param name="px">X coordinate for patches 0..12</param> | ||
1258 | /// <param name="py">Y coordinate for patches 0..15</param> | ||
1259 | // private void SendLayerPacket(float[] map, int y, int x) | ||
1260 | // { | ||
1261 | // int[] patches = new int[4]; | ||
1262 | // patches[0] = x + 0 + y * 16; | ||
1263 | // patches[1] = x + 1 + y * 16; | ||
1264 | // patches[2] = x + 2 + y * 16; | ||
1265 | // patches[3] = x + 3 + y * 16; | ||
1266 | |||
1267 | // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); | ||
1268 | // OutPacket(layerpack, ThrottleOutPacketType.Land); | ||
1269 | // } | ||
1270 | 1262 | ||
1271 | // Legacy form of invocation that passes around a bare data array. | 1263 | // Legacy form of invocation that passes around a bare data array. |
1272 | // Just ignore what was passed and use the real terrain info that is part of the scene. | 1264 | // Just ignore what was passed and use the real terrain info that is part of the scene. |
1273 | // As a HORRIBLE kludge in an attempt to not change the definition of IClientAPI, | 1265 | // As a HORRIBLE kludge in an attempt to not change the definition of IClientAPI, |
1274 | // there is a special form for specifying multiple terrain patches to send. | 1266 | // there is a special form for specifying multiple terrain patches to send. |
1275 | // The form is to pass 'px' as negative the number of patches to send and to | 1267 | // The form is to pass 'px' as negative the number of patches to send and to |
1276 | // pass the float array as pairs of patch X and Y coordinates. So, passing 'px' | 1268 | // pass the float array as pairs of patch X and Y coordinates. So, passing 'px' |
@@ -1316,6 +1308,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1316 | } | 1308 | } |
1317 | 1309 | ||
1318 | /// <summary> | 1310 | /// <summary> |
1311 | |||
1319 | /// Sends a terrain packet for the point specified. | 1312 | /// Sends a terrain packet for the point specified. |
1320 | /// This is a legacy call that has refarbed the terrain into a flat map of floats. | 1313 | /// This is a legacy call that has refarbed the terrain into a flat map of floats. |
1321 | /// We just use the terrain from the region we know about. | 1314 | /// We just use the terrain from the region we know about. |
@@ -1334,32 +1327,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1334 | { | 1327 | { |
1335 | try | 1328 | try |
1336 | { | 1329 | { |
1337 | /* test code using the terrain compressor in libOpenMetaverse | 1330 | byte landPacketType; |
1338 | int[] patchInd = new int[1]; | 1331 | if (terrData.SizeX > Constants.RegionSize || terrData.SizeY > Constants.RegionSize) |
1339 | patchInd[0] = px + (py * Constants.TerrainPatchSize); | 1332 | landPacketType = (byte)TerrainPatch.LayerType.LandExtended; |
1340 | LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(terrData.GetFloatsSerialized(), patchInd); | 1333 | else |
1341 | */ | 1334 | landPacketType = (byte)TerrainPatch.LayerType.Land; |
1342 | // Many, many patches could have been passed to us. Since the patches will be compressed | ||
1343 | // into variable sized blocks, we cannot pre-compute how many will fit into one | ||
1344 | // packet. While some fancy packing algorithm is possible, 4 seems to always fit. | ||
1345 | int PatchesAssumedToFit = 4; | ||
1346 | for (int pcnt = 0; pcnt < px.Length; pcnt += PatchesAssumedToFit) | ||
1347 | { | ||
1348 | int remaining = Math.Min(px.Length - pcnt, PatchesAssumedToFit); | ||
1349 | int[] xPatches = new int[remaining]; | ||
1350 | int[] yPatches = new int[remaining]; | ||
1351 | for (int ii = 0; ii < remaining; ii++) | ||
1352 | { | ||
1353 | xPatches[ii] = px[pcnt + ii]; | ||
1354 | yPatches[ii] = py[pcnt + ii]; | ||
1355 | } | ||
1356 | LayerDataPacket layerpack = OpenSimTerrainCompressor.CreateLandPacket(terrData, xPatches, yPatches); | ||
1357 | // DebugSendingPatches("SendLayerDataInternal", xPatches, yPatches); | ||
1358 | |||
1359 | SendTheLayerPacket(layerpack); | ||
1360 | } | ||
1361 | // LayerDataPacket layerpack = OpenSimTerrainCompressor.CreateLandPacket(terrData, px, py); | ||
1362 | 1335 | ||
1336 | List<LayerDataPacket> packets = OpenSimTerrainCompressor.CreateLayerDataPackets(terrData, px, py, landPacketType); | ||
1337 | foreach(LayerDataPacket pkt in packets) | ||
1338 | OutPacket(pkt, ThrottleOutPacketType.Land); | ||
1363 | } | 1339 | } |
1364 | catch (Exception e) | 1340 | catch (Exception e) |
1365 | { | 1341 | { |
@@ -1367,110 +1343,125 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1367 | } | 1343 | } |
1368 | } | 1344 | } |
1369 | 1345 | ||
1370 | // When a user edits the terrain, so much data is sent, the data queues up fast and presents a | ||
1371 | // sub optimal editing experience. To alleviate this issue, when the user edits the terrain, we | ||
1372 | // start skipping the queues until they're done editing the terrain. We also make them | ||
1373 | // unreliable because it's extremely likely that multiple packets will be sent for a terrain patch | ||
1374 | // area invalidating previous packets for that area. | ||
1375 | 1346 | ||
1376 | // It's possible for an editing user to flood themselves with edited packets but the majority | 1347 | // wind caching |
1377 | // of use cases are such that only a tiny percentage of users will be editing the terrain. | 1348 | private static Dictionary<ulong,int> lastWindVersion = new Dictionary<ulong,int>(); |
1378 | // Other, non-editing users will see the edits much slower. | 1349 | private static Dictionary<ulong,List<LayerDataPacket>> lastWindPackets = |
1379 | 1350 | new Dictionary<ulong,List<LayerDataPacket>>(); | |
1380 | // One last note on this topic, by the time users are going to be editing the terrain, it's | ||
1381 | // extremely likely that the sim will have rezzed already and therefore this is not likely going | ||
1382 | // to cause any additional issues with lost packets, objects or terrain patches. | ||
1383 | 1351 | ||
1384 | // m_justEditedTerrain is volatile, so test once and duplicate two affected statements so we | ||
1385 | // only have one cache miss. | ||
1386 | private void SendTheLayerPacket(LayerDataPacket layerpack) | ||
1387 | { | ||
1388 | if (m_justEditedTerrain) | ||
1389 | { | ||
1390 | layerpack.Header.Reliable = false; | ||
1391 | OutPacket(layerpack, ThrottleOutPacketType.Unknown ); | ||
1392 | } | ||
1393 | else | ||
1394 | { | ||
1395 | layerpack.Header.Reliable = true; | ||
1396 | OutPacket(layerpack, ThrottleOutPacketType.Land); | ||
1397 | } | ||
1398 | } | ||
1399 | 1352 | ||
1400 | /// <summary> | 1353 | /// <summary> |
1401 | /// Send the wind matrix to the client | 1354 | /// Send the wind matrix to the client |
1402 | /// </summary> | 1355 | /// </summary> |
1403 | /// <param name="windSpeeds">16x16 array of wind speeds</param> | 1356 | /// <param name="windSpeeds">16x16 array of wind speeds</param> |
1404 | public virtual void SendWindData(Vector2[] windSpeeds) | 1357 | public virtual void SendWindData(int version, Vector2[] windSpeeds) |
1405 | { | ||
1406 | Util.FireAndForget(DoSendWindData, windSpeeds, "LLClientView.SendWindData"); | ||
1407 | } | ||
1408 | |||
1409 | /// <summary> | ||
1410 | /// Send the cloud matrix to the client | ||
1411 | /// </summary> | ||
1412 | /// <param name="windSpeeds">16x16 array of cloud densities</param> | ||
1413 | public virtual void SendCloudData(float[] cloudDensity) | ||
1414 | { | ||
1415 | Util.FireAndForget(DoSendCloudData, cloudDensity, "LLClientView.SendCloudData"); | ||
1416 | } | ||
1417 | |||
1418 | /// <summary> | ||
1419 | /// Send wind layer information to the client. | ||
1420 | /// </summary> | ||
1421 | /// <param name="o"></param> | ||
1422 | private void DoSendWindData(object o) | ||
1423 | { | 1358 | { |
1424 | Vector2[] windSpeeds = (Vector2[])o; | 1359 | // Vector2[] windSpeeds = (Vector2[])o; |
1425 | TerrainPatch[] patches = new TerrainPatch[2]; | ||
1426 | patches[0] = new TerrainPatch { Data = new float[16 * 16] }; | ||
1427 | patches[1] = new TerrainPatch { Data = new float[16 * 16] }; | ||
1428 | 1360 | ||
1429 | for (int x = 0; x < 16 * 16; x++) | 1361 | ulong handle = this.Scene.RegionInfo.RegionHandle; |
1362 | bool isNewData; | ||
1363 | lock(lastWindPackets) | ||
1430 | { | 1364 | { |
1431 | patches[0].Data[x] = windSpeeds[x].X; | 1365 | if(!lastWindVersion.ContainsKey(handle) || |
1432 | patches[1].Data[x] = windSpeeds[x].Y; | 1366 | !lastWindPackets.ContainsKey(handle)) |
1367 | { | ||
1368 | lastWindVersion[handle] = 0; | ||
1369 | lastWindPackets[handle] = new List<LayerDataPacket>(); | ||
1370 | isNewData = true; | ||
1371 | } | ||
1372 | else | ||
1373 | isNewData = lastWindVersion[handle] != version; | ||
1433 | } | 1374 | } |
1434 | 1375 | ||
1435 | byte layerType = (byte)TerrainPatch.LayerType.Wind; | 1376 | if(isNewData) |
1436 | if (m_scene.RegionInfo.RegionSizeX > Constants.RegionSize || m_scene.RegionInfo.RegionSizeY > Constants.RegionSize) | 1377 | { |
1437 | layerType = (byte)TerrainPatch.LayerType.WindExtended; | 1378 | TerrainPatch[] patches = new TerrainPatch[2]; |
1379 | patches[0] = new TerrainPatch { Data = new float[16 * 16] }; | ||
1380 | patches[1] = new TerrainPatch { Data = new float[16 * 16] }; | ||
1381 | |||
1382 | for (int x = 0; x < 16 * 16; x++) | ||
1383 | { | ||
1384 | patches[0].Data[x] = windSpeeds[x].X; | ||
1385 | patches[1].Data[x] = windSpeeds[x].Y; | ||
1386 | } | ||
1387 | |||
1388 | // neither we or viewers have extended wind | ||
1389 | byte layerType = (byte)TerrainPatch.LayerType.Wind; | ||
1390 | |||
1391 | LayerDataPacket layerpack = | ||
1392 | OpenSimTerrainCompressor.CreateLayerDataPacketStandardSize( | ||
1393 | patches, layerType); | ||
1394 | layerpack.Header.Zerocoded = true; | ||
1395 | lock(lastWindPackets) | ||
1396 | { | ||
1397 | lastWindPackets[handle].Clear(); | ||
1398 | lastWindPackets[handle].Add(layerpack); | ||
1399 | lastWindVersion[handle] = version; | ||
1400 | } | ||
1401 | } | ||
1438 | 1402 | ||
1439 | // LayerDataPacket layerpack = TerrainCompressor.CreateLayerDataPacket(patches, (TerrainPatch.LayerType)layerType); | 1403 | lock(lastWindPackets) |
1440 | LayerDataPacket layerpack = OpenSimTerrainCompressor.CreateLayerDataPacket(patches, layerType, | 1404 | foreach(LayerDataPacket pkt in lastWindPackets[handle]) |
1441 | (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY); | 1405 | OutPacket(pkt, ThrottleOutPacketType.Wind); |
1442 | layerpack.Header.Zerocoded = true; | ||
1443 | OutPacket(layerpack, ThrottleOutPacketType.Wind); | ||
1444 | } | 1406 | } |
1445 | 1407 | ||
1408 | // cloud caching | ||
1409 | private static Dictionary<ulong,int> lastCloudVersion = new Dictionary<ulong,int>(); | ||
1410 | private static Dictionary<ulong,List<LayerDataPacket>> lastCloudPackets = | ||
1411 | new Dictionary<ulong,List<LayerDataPacket>>(); | ||
1412 | |||
1446 | /// <summary> | 1413 | /// <summary> |
1447 | /// Send cloud layer information to the client. | 1414 | /// Send the cloud matrix to the client |
1448 | /// </summary> | 1415 | /// </summary> |
1449 | /// <param name="o"></param> | 1416 | /// <param name="windSpeeds">16x16 array of cloud densities</param> |
1450 | private void DoSendCloudData(object o) | 1417 | public virtual void SendCloudData(int version, float[] cloudDensity) |
1451 | { | 1418 | { |
1452 | float[] cloudCover = (float[])o; | 1419 | ulong handle = this.Scene.RegionInfo.RegionHandle; |
1453 | TerrainPatch[] patches = new TerrainPatch[1]; | 1420 | bool isNewData; |
1454 | patches[0] = new TerrainPatch(); | 1421 | lock(lastWindPackets) |
1455 | patches[0].Data = new float[16 * 16]; | ||
1456 | |||
1457 | for (int y = 0; y < 16; y++) | ||
1458 | { | 1422 | { |
1459 | for (int x = 0; x < 16; x++) | 1423 | if(!lastCloudVersion.ContainsKey(handle) || |
1424 | !lastCloudPackets.ContainsKey(handle)) | ||
1460 | { | 1425 | { |
1461 | patches[0].Data[y * 16 + x] = cloudCover[y * 16 + x]; | 1426 | lastCloudVersion[handle] = 0; |
1427 | lastCloudPackets[handle] = new List<LayerDataPacket>(); | ||
1428 | isNewData = true; | ||
1462 | } | 1429 | } |
1430 | else | ||
1431 | isNewData = lastCloudVersion[handle] != version; | ||
1463 | } | 1432 | } |
1464 | 1433 | ||
1465 | byte layerType = (byte)TerrainPatch.LayerType.Cloud; | 1434 | if(isNewData) |
1466 | if (m_scene.RegionInfo.RegionSizeX > Constants.RegionSize || m_scene.RegionInfo.RegionSizeY > Constants.RegionSize) | 1435 | { |
1467 | layerType = (byte)TerrainPatch.LayerType.CloudExtended; | 1436 | TerrainPatch[] patches = new TerrainPatch[1]; |
1437 | patches[0] = new TerrainPatch(); | ||
1438 | patches[0].Data = new float[16 * 16]; | ||
1439 | |||
1440 | for (int y = 0; y < 16; y++) | ||
1441 | { | ||
1442 | for (int x = 0; x < 16; x++) | ||
1443 | { | ||
1444 | patches[0].Data[y * 16 + x] = cloudDensity[y * 16 + x]; | ||
1445 | } | ||
1446 | } | ||
1447 | // neither we or viewers have extended clouds | ||
1448 | byte layerType = (byte)TerrainPatch.LayerType.Cloud; | ||
1449 | |||
1450 | LayerDataPacket layerpack = | ||
1451 | OpenSimTerrainCompressor.CreateLayerDataPacketStandardSize( | ||
1452 | patches, layerType); | ||
1453 | layerpack.Header.Zerocoded = true; | ||
1454 | lock(lastCloudPackets) | ||
1455 | { | ||
1456 | lastCloudPackets[handle].Clear(); | ||
1457 | lastCloudPackets[handle].Add(layerpack); | ||
1458 | lastCloudVersion[handle] = version; | ||
1459 | } | ||
1460 | } | ||
1468 | 1461 | ||
1469 | // LayerDataPacket layerpack = TerrainCompressor.CreateLayerDataPacket(patches, (TerrainPatch.LayerType)layerType); | 1462 | lock(lastCloudPackets) |
1470 | LayerDataPacket layerpack = OpenSimTerrainCompressor.CreateLayerDataPacket(patches, layerType, | 1463 | foreach(LayerDataPacket pkt in lastCloudPackets[handle]) |
1471 | (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY); | 1464 | OutPacket(pkt, ThrottleOutPacketType.Cloud); |
1472 | layerpack.Header.Zerocoded = true; | ||
1473 | OutPacket(layerpack, ThrottleOutPacketType.Cloud); | ||
1474 | } | 1465 | } |
1475 | 1466 | ||
1476 | /// <summary> | 1467 | /// <summary> |
@@ -1735,45 +1726,59 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1735 | pc.PingID.OldestUnacked = 0; | 1726 | pc.PingID.OldestUnacked = 0; |
1736 | 1727 | ||
1737 | OutPacket(pc, ThrottleOutPacketType.Unknown); | 1728 | OutPacket(pc, ThrottleOutPacketType.Unknown); |
1729 | UDPClient.m_lastStartpingTimeMS = Util.EnvironmentTickCount(); | ||
1738 | } | 1730 | } |
1739 | 1731 | ||
1740 | public void SendKillObject(List<uint> localIDs) | 1732 | public void SendKillObject(List<uint> localIDs) |
1741 | { | 1733 | { |
1742 | // m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); | 1734 | // foreach (uint id in localIDs) |
1735 | // m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle); | ||
1736 | |||
1737 | // remove pending entities to reduce looping chances. | ||
1738 | lock (m_entityProps.SyncRoot) | ||
1739 | m_entityProps.Remove(localIDs); | ||
1740 | lock (m_entityUpdates.SyncRoot) | ||
1741 | m_entityUpdates.Remove(localIDs); | ||
1743 | 1742 | ||
1744 | KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); | 1743 | KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); |
1745 | // TODO: don't create new blocks if recycling an old packet | 1744 | |
1746 | kill.ObjectData = new KillObjectPacket.ObjectDataBlock[localIDs.Count]; | 1745 | int perpacket = localIDs.Count; |
1746 | if(perpacket > 200) | ||
1747 | perpacket = 200; | ||
1748 | |||
1749 | int nsent = 0; | ||
1750 | |||
1751 | kill.ObjectData = new KillObjectPacket.ObjectDataBlock[perpacket]; | ||
1747 | for (int i = 0 ; i < localIDs.Count ; i++ ) | 1752 | for (int i = 0 ; i < localIDs.Count ; i++ ) |
1748 | { | 1753 | { |
1749 | kill.ObjectData[i] = new KillObjectPacket.ObjectDataBlock(); | 1754 | kill.ObjectData[nsent] = new KillObjectPacket.ObjectDataBlock(); |
1750 | kill.ObjectData[i].ID = localIDs[i]; | 1755 | kill.ObjectData[nsent].ID = localIDs[i]; |
1751 | } | ||
1752 | kill.Header.Reliable = true; | ||
1753 | kill.Header.Zerocoded = true; | ||
1754 | 1756 | ||
1755 | if (localIDs.Count == 1 && m_scene.GetScenePresence(localIDs[0]) != null) | 1757 | if(++nsent >= 200) |
1756 | { | ||
1757 | OutPacket(kill, ThrottleOutPacketType.Task); | ||
1758 | } | ||
1759 | else | ||
1760 | { | ||
1761 | // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race | ||
1762 | // condition where a kill can be processed before an out-of-date update for the same object. | ||
1763 | // ProcessEntityUpdates() also takes the m_killRecord lock. | ||
1764 | lock (m_killRecord) | ||
1765 | { | 1758 | { |
1766 | foreach (uint localID in localIDs) | 1759 | kill.Header.Reliable = true; |
1767 | m_killRecord.Add(localID); | 1760 | kill.Header.Zerocoded = true; |
1768 | |||
1769 | // The throttle queue used here must match that being used for updates. Otherwise, there is a | ||
1770 | // chance that a kill packet put on a separate queue will be sent to the client before an existing | ||
1771 | // update packet on another queue. Receiving updates after kills results in unowned and undeletable | ||
1772 | // scene objects in a viewer until that viewer is relogged in. | ||
1773 | OutPacket(kill, ThrottleOutPacketType.Task); | 1761 | OutPacket(kill, ThrottleOutPacketType.Task); |
1762 | |||
1763 | perpacket = localIDs.Count - i - 1; | ||
1764 | if(perpacket == 0) | ||
1765 | break; | ||
1766 | if(perpacket > 200) | ||
1767 | perpacket = 200; | ||
1768 | |||
1769 | kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); | ||
1770 | kill.ObjectData = new KillObjectPacket.ObjectDataBlock[perpacket]; | ||
1771 | nsent = 0; | ||
1774 | } | 1772 | } |
1775 | } | 1773 | } |
1776 | } | 1774 | |
1775 | if(nsent != 0) | ||
1776 | { | ||
1777 | kill.Header.Reliable = true; | ||
1778 | kill.Header.Zerocoded = true; | ||
1779 | OutPacket(kill, ThrottleOutPacketType.Task); | ||
1780 | } | ||
1781 | } | ||
1777 | 1782 | ||
1778 | /// <summary> | 1783 | /// <summary> |
1779 | /// Send information about the items contained in a folder to the client. | 1784 | /// Send information about the items contained in a folder to the client. |
@@ -1895,7 +1900,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1895 | newBlock.CreationDate = item.CreationDate; | 1900 | newBlock.CreationDate = item.CreationDate; |
1896 | newBlock.SalePrice = item.SalePrice; | 1901 | newBlock.SalePrice = item.SalePrice; |
1897 | newBlock.SaleType = item.SaleType; | 1902 | newBlock.SaleType = item.SaleType; |
1898 | newBlock.Flags = item.Flags; | 1903 | newBlock.Flags = item.Flags & 0x2000ff; |
1899 | 1904 | ||
1900 | newBlock.CRC = | 1905 | newBlock.CRC = |
1901 | Helpers.InventoryCRC(newBlock.CreationDate, newBlock.SaleType, | 1906 | Helpers.InventoryCRC(newBlock.CreationDate, newBlock.SaleType, |
@@ -2151,7 +2156,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2151 | itemBlock.GroupID = item.GroupID; | 2156 | itemBlock.GroupID = item.GroupID; |
2152 | itemBlock.GroupOwned = item.GroupOwned; | 2157 | itemBlock.GroupOwned = item.GroupOwned; |
2153 | itemBlock.GroupMask = item.GroupPermissions; | 2158 | itemBlock.GroupMask = item.GroupPermissions; |
2154 | itemBlock.Flags = item.Flags; | 2159 | itemBlock.Flags = item.Flags & 0x2000ff; |
2155 | itemBlock.SalePrice = item.SalePrice; | 2160 | itemBlock.SalePrice = item.SalePrice; |
2156 | itemBlock.SaleType = item.SaleType; | 2161 | itemBlock.SaleType = item.SaleType; |
2157 | itemBlock.CreationDate = item.CreationDate; | 2162 | itemBlock.CreationDate = item.CreationDate; |
@@ -2218,7 +2223,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2218 | bulkUpdate.ItemData[0].GroupID = item.GroupID; | 2223 | bulkUpdate.ItemData[0].GroupID = item.GroupID; |
2219 | bulkUpdate.ItemData[0].GroupOwned = item.GroupOwned; | 2224 | bulkUpdate.ItemData[0].GroupOwned = item.GroupOwned; |
2220 | bulkUpdate.ItemData[0].GroupMask = item.GroupPermissions; | 2225 | bulkUpdate.ItemData[0].GroupMask = item.GroupPermissions; |
2221 | bulkUpdate.ItemData[0].Flags = item.Flags; | 2226 | bulkUpdate.ItemData[0].Flags = item.Flags & 0x2000ff; |
2222 | bulkUpdate.ItemData[0].SalePrice = item.SalePrice; | 2227 | bulkUpdate.ItemData[0].SalePrice = item.SalePrice; |
2223 | bulkUpdate.ItemData[0].SaleType = item.SaleType; | 2228 | bulkUpdate.ItemData[0].SaleType = item.SaleType; |
2224 | 2229 | ||
@@ -2234,9 +2239,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2234 | OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); | 2239 | OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); |
2235 | } | 2240 | } |
2236 | 2241 | ||
2237 | /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see> | ||
2238 | public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId) | 2242 | public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId) |
2239 | { | 2243 | { |
2244 | SendInventoryItemCreateUpdate(Item, UUID.Zero, callbackId); | ||
2245 | } | ||
2246 | |||
2247 | /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see> | ||
2248 | public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId) | ||
2249 | { | ||
2240 | const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff; | 2250 | const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff; |
2241 | 2251 | ||
2242 | UpdateCreateInventoryItemPacket InventoryReply | 2252 | UpdateCreateInventoryItemPacket InventoryReply |
@@ -2246,6 +2256,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2246 | // TODO: don't create new blocks if recycling an old packet | 2256 | // TODO: don't create new blocks if recycling an old packet |
2247 | InventoryReply.AgentData.AgentID = AgentId; | 2257 | InventoryReply.AgentData.AgentID = AgentId; |
2248 | InventoryReply.AgentData.SimApproved = true; | 2258 | InventoryReply.AgentData.SimApproved = true; |
2259 | InventoryReply.AgentData.TransactionID = transactionID; | ||
2249 | InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1]; | 2260 | InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1]; |
2250 | InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock(); | 2261 | InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock(); |
2251 | InventoryReply.InventoryData[0].ItemID = Item.ID; | 2262 | InventoryReply.InventoryData[0].ItemID = Item.ID; |
@@ -2266,7 +2277,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2266 | InventoryReply.InventoryData[0].GroupID = Item.GroupID; | 2277 | InventoryReply.InventoryData[0].GroupID = Item.GroupID; |
2267 | InventoryReply.InventoryData[0].GroupOwned = Item.GroupOwned; | 2278 | InventoryReply.InventoryData[0].GroupOwned = Item.GroupOwned; |
2268 | InventoryReply.InventoryData[0].GroupMask = Item.GroupPermissions; | 2279 | InventoryReply.InventoryData[0].GroupMask = Item.GroupPermissions; |
2269 | InventoryReply.InventoryData[0].Flags = Item.Flags; | 2280 | InventoryReply.InventoryData[0].Flags = Item.Flags & 0x2000ff; |
2270 | InventoryReply.InventoryData[0].SalePrice = Item.SalePrice; | 2281 | InventoryReply.InventoryData[0].SalePrice = Item.SalePrice; |
2271 | InventoryReply.InventoryData[0].SaleType = Item.SaleType; | 2282 | InventoryReply.InventoryData[0].SaleType = Item.SaleType; |
2272 | InventoryReply.InventoryData[0].CreationDate = Item.CreationDate; | 2283 | InventoryReply.InventoryData[0].CreationDate = Item.CreationDate; |
@@ -2296,11 +2307,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2296 | OutPacket(remove, ThrottleOutPacketType.Asset); | 2307 | OutPacket(remove, ThrottleOutPacketType.Asset); |
2297 | } | 2308 | } |
2298 | 2309 | ||
2310 | /* | ||
2311 | private uint adjustControls(int input) | ||
2312 | { | ||
2313 | uint ret = (uint)input; | ||
2314 | uint masked = ret & 0x0f; | ||
2315 | masked <<= 19; | ||
2316 | ret |= masked; | ||
2317 | return ret; | ||
2318 | } | ||
2319 | */ | ||
2320 | |||
2299 | public void SendTakeControls(int controls, bool passToAgent, bool TakeControls) | 2321 | public void SendTakeControls(int controls, bool passToAgent, bool TakeControls) |
2300 | { | 2322 | { |
2301 | ScriptControlChangePacket scriptcontrol = (ScriptControlChangePacket)PacketPool.Instance.GetPacket(PacketType.ScriptControlChange); | 2323 | ScriptControlChangePacket scriptcontrol = (ScriptControlChangePacket)PacketPool.Instance.GetPacket(PacketType.ScriptControlChange); |
2302 | ScriptControlChangePacket.DataBlock[] data = new ScriptControlChangePacket.DataBlock[1]; | 2324 | ScriptControlChangePacket.DataBlock[] data = new ScriptControlChangePacket.DataBlock[1]; |
2303 | ScriptControlChangePacket.DataBlock ddata = new ScriptControlChangePacket.DataBlock(); | 2325 | ScriptControlChangePacket.DataBlock ddata = new ScriptControlChangePacket.DataBlock(); |
2326 | // ddata.Controls = adjustControls(controls); | ||
2304 | ddata.Controls = (uint)controls; | 2327 | ddata.Controls = (uint)controls; |
2305 | ddata.PassToAgent = passToAgent; | 2328 | ddata.PassToAgent = passToAgent; |
2306 | ddata.TakeControls = TakeControls; | 2329 | ddata.TakeControls = TakeControls; |
@@ -2315,16 +2338,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2315 | replytask.InventoryData.TaskID = taskID; | 2338 | replytask.InventoryData.TaskID = taskID; |
2316 | replytask.InventoryData.Serial = serial; | 2339 | replytask.InventoryData.Serial = serial; |
2317 | replytask.InventoryData.Filename = fileName; | 2340 | replytask.InventoryData.Filename = fileName; |
2341 | // OutPacket(replytask, ThrottleOutPacketType.Task); | ||
2318 | OutPacket(replytask, ThrottleOutPacketType.Asset); | 2342 | OutPacket(replytask, ThrottleOutPacketType.Asset); |
2319 | } | 2343 | } |
2320 | 2344 | ||
2321 | public void SendXferPacket(ulong xferID, uint packet, byte[] data) | 2345 | public void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory) |
2322 | { | 2346 | { |
2347 | ThrottleOutPacketType type = ThrottleOutPacketType.Asset; | ||
2348 | // if (isTaskInventory) | ||
2349 | // type = ThrottleOutPacketType.Task; | ||
2350 | |||
2323 | SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket); | 2351 | SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket); |
2324 | sendXfer.XferID.ID = xferID; | 2352 | sendXfer.XferID.ID = xferID; |
2325 | sendXfer.XferID.Packet = packet; | 2353 | sendXfer.XferID.Packet = packet; |
2326 | sendXfer.DataPacket.Data = data; | 2354 | sendXfer.DataPacket.Data = data; |
2327 | OutPacket(sendXfer, ThrottleOutPacketType.Asset); | 2355 | OutPacket(sendXfer, type); |
2328 | } | 2356 | } |
2329 | 2357 | ||
2330 | public void SendAbortXferPacket(ulong xferID) | 2358 | public void SendAbortXferPacket(ulong xferID) |
@@ -2415,6 +2443,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2415 | OutPacket(alertPack, ThrottleOutPacketType.Task); | 2443 | OutPacket(alertPack, ThrottleOutPacketType.Task); |
2416 | } | 2444 | } |
2417 | 2445 | ||
2446 | public void SendAlertMessage(string message, string info) | ||
2447 | { | ||
2448 | AlertMessagePacket alertPack = (AlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AlertMessage); | ||
2449 | alertPack.AlertData = new AlertMessagePacket.AlertDataBlock(); | ||
2450 | alertPack.AlertData.Message = Util.StringToBytes256(message); | ||
2451 | alertPack.AlertInfo = new AlertMessagePacket.AlertInfoBlock[1]; | ||
2452 | alertPack.AlertInfo[0] = new AlertMessagePacket.AlertInfoBlock(); | ||
2453 | alertPack.AlertInfo[0].Message = Util.StringToBytes256(info); | ||
2454 | alertPack.AlertInfo[0].ExtraParams = new Byte[0]; | ||
2455 | OutPacket(alertPack, ThrottleOutPacketType.Task); | ||
2456 | } | ||
2457 | |||
2418 | /// <summary> | 2458 | /// <summary> |
2419 | /// Send an agent alert message to the client. | 2459 | /// Send an agent alert message to the client. |
2420 | /// </summary> | 2460 | /// </summary> |
@@ -2471,7 +2511,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2471 | // this is the username of the *owner* | 2511 | // this is the username of the *owner* |
2472 | dialog.Data.FirstName = Util.StringToBytes256(ownerFirstName); | 2512 | dialog.Data.FirstName = Util.StringToBytes256(ownerFirstName); |
2473 | dialog.Data.LastName = Util.StringToBytes256(ownerLastName); | 2513 | dialog.Data.LastName = Util.StringToBytes256(ownerLastName); |
2474 | dialog.Data.Message = Util.StringToBytes1024(msg); | 2514 | dialog.Data.Message = Util.StringToBytes(msg,512); |
2475 | dialog.Data.ImageID = textureID; | 2515 | dialog.Data.ImageID = textureID; |
2476 | dialog.Data.ChatChannel = ch; | 2516 | dialog.Data.ChatChannel = ch; |
2477 | ScriptDialogPacket.ButtonsBlock[] buttons = new ScriptDialogPacket.ButtonsBlock[buttonlabels.Length]; | 2517 | ScriptDialogPacket.ButtonsBlock[] buttons = new ScriptDialogPacket.ButtonsBlock[buttonlabels.Length]; |
@@ -2514,6 +2554,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2514 | OutPacket(sound, ThrottleOutPacketType.Task); | 2554 | OutPacket(sound, ThrottleOutPacketType.Task); |
2515 | } | 2555 | } |
2516 | 2556 | ||
2557 | public void SendTransferAbort(TransferRequestPacket transferRequest) | ||
2558 | { | ||
2559 | TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort); | ||
2560 | abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID; | ||
2561 | abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType; | ||
2562 | m_log.Debug("[Assets] Aborting transfer; asset request failed"); | ||
2563 | OutPacket(abort, ThrottleOutPacketType.Task); | ||
2564 | } | ||
2565 | |||
2517 | public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) | 2566 | public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) |
2518 | { | 2567 | { |
2519 | SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); | 2568 | SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); |
@@ -2632,7 +2681,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2632 | OutPacket(packet, ThrottleOutPacketType.Task); | 2681 | OutPacket(packet, ThrottleOutPacketType.Task); |
2633 | } | 2682 | } |
2634 | 2683 | ||
2635 | public void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] charterMember, | 2684 | public void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] membershipType, |
2636 | string flAbout, uint flags, UUID flImageID, UUID imageID, string profileURL, | 2685 | string flAbout, uint flags, UUID flImageID, UUID imageID, string profileURL, |
2637 | UUID partnerID) | 2686 | UUID partnerID) |
2638 | { | 2687 | { |
@@ -2644,7 +2693,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2644 | else | 2693 | else |
2645 | avatarReply.PropertiesData.AboutText = Utils.EmptyBytes; | 2694 | avatarReply.PropertiesData.AboutText = Utils.EmptyBytes; |
2646 | avatarReply.PropertiesData.BornOn = Util.StringToBytes256(bornOn); | 2695 | avatarReply.PropertiesData.BornOn = Util.StringToBytes256(bornOn); |
2647 | avatarReply.PropertiesData.CharterMember = charterMember; | 2696 | avatarReply.PropertiesData.CharterMember = membershipType; |
2648 | if (flAbout != null) | 2697 | if (flAbout != null) |
2649 | avatarReply.PropertiesData.FLAboutText = Util.StringToBytes256(flAbout); | 2698 | avatarReply.PropertiesData.FLAboutText = Util.StringToBytes256(flAbout); |
2650 | else | 2699 | else |
@@ -2730,8 +2779,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2730 | OutPacket(offp, ThrottleOutPacketType.Task); | 2779 | OutPacket(offp, ThrottleOutPacketType.Task); |
2731 | } | 2780 | } |
2732 | 2781 | ||
2733 | public void SendSitResponse(UUID TargetID, Vector3 OffsetPos, Quaternion SitOrientation, bool autopilot, | 2782 | public void SendFindAgent(UUID HunterID, UUID PreyID, double GlobalX, double GlobalY) |
2734 | Vector3 CameraAtOffset, Vector3 CameraEyeOffset, bool ForceMouseLook) | 2783 | { |
2784 | FindAgentPacket fap = new FindAgentPacket(); | ||
2785 | fap.AgentBlock.Hunter = HunterID; | ||
2786 | fap.AgentBlock.Prey = PreyID; | ||
2787 | fap.AgentBlock.SpaceIP = 0; | ||
2788 | |||
2789 | fap.LocationBlock = new FindAgentPacket.LocationBlockBlock[1]; | ||
2790 | fap.LocationBlock[0] = new FindAgentPacket.LocationBlockBlock(); | ||
2791 | fap.LocationBlock[0].GlobalX = GlobalX; | ||
2792 | fap.LocationBlock[0].GlobalY = GlobalY; | ||
2793 | |||
2794 | OutPacket(fap, ThrottleOutPacketType.Task); | ||
2795 | } | ||
2796 | |||
2797 | public void SendSitResponse(UUID TargetID, Vector3 OffsetPos, | ||
2798 | Quaternion SitOrientation, bool autopilot, | ||
2799 | Vector3 CameraAtOffset, Vector3 CameraEyeOffset, bool ForceMouseLook) | ||
2735 | { | 2800 | { |
2736 | AvatarSitResponsePacket avatarSitResponse = new AvatarSitResponsePacket(); | 2801 | AvatarSitResponsePacket avatarSitResponse = new AvatarSitResponsePacket(); |
2737 | avatarSitResponse.SitObject.ID = TargetID; | 2802 | avatarSitResponse.SitObject.ID = TargetID; |
@@ -2763,46 +2828,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2763 | 2828 | ||
2764 | public void SendGroupMembership(GroupMembershipData[] GroupMembership) | 2829 | public void SendGroupMembership(GroupMembershipData[] GroupMembership) |
2765 | { | 2830 | { |
2766 | m_groupPowers.Clear(); | ||
2767 | 2831 | ||
2768 | AgentGroupDataUpdatePacket Groupupdate = new AgentGroupDataUpdatePacket(); | 2832 | UpdateGroupMembership(GroupMembership); |
2769 | AgentGroupDataUpdatePacket.GroupDataBlock[] Groups = new AgentGroupDataUpdatePacket.GroupDataBlock[GroupMembership.Length]; | 2833 | SendAgentGroupDataUpdate(AgentId,GroupMembership); |
2770 | for (int i = 0; i < GroupMembership.Length; i++) | 2834 | } |
2771 | { | ||
2772 | m_groupPowers[GroupMembership[i].GroupID] = GroupMembership[i].GroupPowers; | ||
2773 | 2835 | ||
2774 | AgentGroupDataUpdatePacket.GroupDataBlock Group = new AgentGroupDataUpdatePacket.GroupDataBlock(); | 2836 | public void SendSelectedPartsProprieties(List<ISceneEntity> parts) |
2775 | Group.AcceptNotices = GroupMembership[i].AcceptNotices; | 2837 | { |
2776 | Group.Contribution = GroupMembership[i].Contribution; | 2838 | /* not in use |
2777 | Group.GroupID = GroupMembership[i].GroupID; | 2839 | // udp part |
2778 | Group.GroupInsigniaID = GroupMembership[i].GroupPicture; | 2840 | ObjectPropertiesPacket packet = |
2779 | Group.GroupName = Util.StringToBytes256(GroupMembership[i].GroupName); | 2841 | (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); |
2780 | Group.GroupPowers = GroupMembership[i].GroupPowers; | 2842 | ObjectPropertiesPacket.ObjectDataBlock[] ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[parts.Count]; |
2781 | Groups[i] = Group; | ||
2782 | 2843 | ||
2844 | int i = 0; | ||
2845 | foreach(SceneObjectPart sop in parts) | ||
2846 | ObjectData[i++] = CreateObjectPropertiesBlock(sop); | ||
2783 | 2847 | ||
2784 | } | 2848 | packet.ObjectData = ObjectData; |
2785 | Groupupdate.GroupData = Groups; | 2849 | packet.Header.Zerocoded = true; |
2786 | Groupupdate.AgentData = new AgentGroupDataUpdatePacket.AgentDataBlock(); | 2850 | // udp send splits this mega packets correctly |
2787 | Groupupdate.AgentData.AgentID = AgentId; | 2851 | // mb later will avoid that to reduce gc stress |
2788 | OutPacket(Groupupdate, ThrottleOutPacketType.Task); | 2852 | OutPacket(packet, ThrottleOutPacketType.Task, true); |
2789 | 2853 | ||
2790 | try | 2854 | // caps physics part |
2791 | { | 2855 | IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>(); |
2792 | IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>(); | 2856 | if(eq == null) |
2793 | if (eq != null) | 2857 | return; |
2794 | { | 2858 | |
2795 | eq.GroupMembership(Groupupdate, this.AgentId); | 2859 | OSDArray array = new OSDArray(); |
2796 | } | 2860 | foreach(SceneObjectPart sop in parts) |
2797 | } | ||
2798 | catch (Exception ex) | ||
2799 | { | 2861 | { |
2800 | m_log.Error("Unable to send group membership data via eventqueue - exception: " + ex.ToString()); | 2862 | OSDMap physinfo = new OSDMap(6); |
2801 | m_log.Warn("sending group membership data via UDP"); | 2863 | physinfo["LocalID"] = sop.LocalId; |
2802 | OutPacket(Groupupdate, ThrottleOutPacketType.Task); | 2864 | physinfo["Density"] = sop.Density; |
2865 | physinfo["Friction"] = sop.Friction; | ||
2866 | physinfo["GravityMultiplier"] = sop.GravityModifier; | ||
2867 | physinfo["Restitution"] = sop.Restitution; | ||
2868 | physinfo["PhysicsShapeType"] = (int)sop.PhysicsShapeType; | ||
2869 | array.Add(physinfo); | ||
2803 | } | 2870 | } |
2871 | |||
2872 | OSDMap llsdBody = new OSDMap(1); | ||
2873 | llsdBody.Add("ObjectData", array); | ||
2874 | |||
2875 | eq.Enqueue(BuildEvent("ObjectPhysicsProperties", llsdBody),AgentId); | ||
2876 | */ | ||
2804 | } | 2877 | } |
2805 | 2878 | ||
2879 | |||
2806 | public void SendPartPhysicsProprieties(ISceneEntity entity) | 2880 | public void SendPartPhysicsProprieties(ISceneEntity entity) |
2807 | { | 2881 | { |
2808 | SceneObjectPart part = (SceneObjectPart)entity; | 2882 | SceneObjectPart part = (SceneObjectPart)entity; |
@@ -2819,6 +2893,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2819 | float friction = part.Friction; | 2893 | float friction = part.Friction; |
2820 | float bounce = part.Restitution; | 2894 | float bounce = part.Restitution; |
2821 | float gravmod = part.GravityModifier; | 2895 | float gravmod = part.GravityModifier; |
2896 | |||
2822 | eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId); | 2897 | eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId); |
2823 | } | 2898 | } |
2824 | } | 2899 | } |
@@ -2826,7 +2901,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2826 | { | 2901 | { |
2827 | m_log.Error("Unable to send part Physics Proprieties - exception: " + ex.ToString()); | 2902 | m_log.Error("Unable to send part Physics Proprieties - exception: " + ex.ToString()); |
2828 | } | 2903 | } |
2829 | part.UpdatePhysRequired = false; | ||
2830 | } | 2904 | } |
2831 | } | 2905 | } |
2832 | 2906 | ||
@@ -2883,6 +2957,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2883 | 2957 | ||
2884 | public void SendAsset(AssetRequestToClient req) | 2958 | public void SendAsset(AssetRequestToClient req) |
2885 | { | 2959 | { |
2960 | if (req.AssetInf == null) | ||
2961 | { | ||
2962 | m_log.ErrorFormat("{0} Cannot send asset {1} ({2}), asset is null", | ||
2963 | LogHeader); | ||
2964 | return; | ||
2965 | } | ||
2966 | |||
2886 | if (req.AssetInf.Data == null) | 2967 | if (req.AssetInf.Data == null) |
2887 | { | 2968 | { |
2888 | m_log.ErrorFormat("{0} Cannot send asset {1} ({2}), asset data is null", | 2969 | m_log.ErrorFormat("{0} Cannot send asset {1} ({2}), asset data is null", |
@@ -2890,7 +2971,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2890 | return; | 2971 | return; |
2891 | } | 2972 | } |
2892 | 2973 | ||
2893 | //m_log.Debug("sending asset " + req.RequestAssetID); | 2974 | bool isWearable = false; |
2975 | |||
2976 | isWearable = ((AssetType) req.AssetInf.Type == | ||
2977 | AssetType.Bodypart || (AssetType) req.AssetInf.Type == AssetType.Clothing); | ||
2978 | |||
2979 | |||
2980 | //m_log.Debug("sending asset " + req.RequestAssetID + ", iswearable: " + isWearable); | ||
2981 | |||
2982 | |||
2983 | //if (isWearable) | ||
2984 | // m_log.Debug((AssetType)req.AssetInf.Type); | ||
2985 | |||
2894 | TransferInfoPacket Transfer = new TransferInfoPacket(); | 2986 | TransferInfoPacket Transfer = new TransferInfoPacket(); |
2895 | Transfer.TransferInfo.ChannelType = 2; | 2987 | Transfer.TransferInfo.ChannelType = 2; |
2896 | Transfer.TransferInfo.Status = 0; | 2988 | Transfer.TransferInfo.Status = 0; |
@@ -2912,7 +3004,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2912 | Transfer.TransferInfo.Size = req.AssetInf.Data.Length; | 3004 | Transfer.TransferInfo.Size = req.AssetInf.Data.Length; |
2913 | Transfer.TransferInfo.TransferID = req.TransferRequestID; | 3005 | Transfer.TransferInfo.TransferID = req.TransferRequestID; |
2914 | Transfer.Header.Zerocoded = true; | 3006 | Transfer.Header.Zerocoded = true; |
2915 | OutPacket(Transfer, ThrottleOutPacketType.Asset); | 3007 | OutPacket(Transfer, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset); |
2916 | 3008 | ||
2917 | if (req.NumPackets == 1) | 3009 | if (req.NumPackets == 1) |
2918 | { | 3010 | { |
@@ -2923,12 +3015,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2923 | TransferPacket.TransferData.Data = req.AssetInf.Data; | 3015 | TransferPacket.TransferData.Data = req.AssetInf.Data; |
2924 | TransferPacket.TransferData.Status = 1; | 3016 | TransferPacket.TransferData.Status = 1; |
2925 | TransferPacket.Header.Zerocoded = true; | 3017 | TransferPacket.Header.Zerocoded = true; |
2926 | OutPacket(TransferPacket, ThrottleOutPacketType.Asset); | 3018 | OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset); |
2927 | } | 3019 | } |
2928 | else | 3020 | else |
2929 | { | 3021 | { |
2930 | int processedLength = 0; | 3022 | int processedLength = 0; |
2931 | int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; | 3023 | // int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; |
3024 | |||
3025 | int maxChunkSize = (int) MaxTransferBytesPerPacket; | ||
2932 | int packetNumber = 0; | 3026 | int packetNumber = 0; |
2933 | 3027 | ||
2934 | while (processedLength < req.AssetInf.Data.Length) | 3028 | while (processedLength < req.AssetInf.Data.Length) |
@@ -2954,7 +3048,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2954 | TransferPacket.TransferData.Status = 1; | 3048 | TransferPacket.TransferData.Status = 1; |
2955 | } | 3049 | } |
2956 | TransferPacket.Header.Zerocoded = true; | 3050 | TransferPacket.Header.Zerocoded = true; |
2957 | OutPacket(TransferPacket, ThrottleOutPacketType.Asset); | 3051 | OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset); |
2958 | 3052 | ||
2959 | processedLength += chunkSize; | 3053 | processedLength += chunkSize; |
2960 | packetNumber++; | 3054 | packetNumber++; |
@@ -2990,23 +3084,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2990 | 3084 | ||
2991 | public void SendParcelInfo(RegionInfo info, LandData land, UUID parcelID, uint x, uint y) | 3085 | public void SendParcelInfo(RegionInfo info, LandData land, UUID parcelID, uint x, uint y) |
2992 | { | 3086 | { |
2993 | float dwell = 0.0f; | ||
2994 | IDwellModule dwellModule = m_scene.RequestModuleInterface<IDwellModule>(); | ||
2995 | if (dwellModule != null) | ||
2996 | dwell = dwellModule.GetDwell(land.GlobalID); | ||
2997 | ParcelInfoReplyPacket reply = (ParcelInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelInfoReply); | 3087 | ParcelInfoReplyPacket reply = (ParcelInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelInfoReply); |
2998 | reply.AgentData.AgentID = m_agentId; | 3088 | reply.AgentData.AgentID = m_agentId; |
2999 | reply.Data.ParcelID = parcelID; | 3089 | reply.Data.ParcelID = parcelID; |
3000 | reply.Data.OwnerID = land.OwnerID; | 3090 | reply.Data.OwnerID = land.OwnerID; |
3001 | reply.Data.Name = Utils.StringToBytes(land.Name); | 3091 | reply.Data.Name = Utils.StringToBytes(land.Name); |
3002 | reply.Data.Desc = Utils.StringToBytes(land.Description); | 3092 | if (land.Description != null && land.Description != String.Empty) |
3093 | reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length)); | ||
3094 | else | ||
3095 | reply.Data.Desc = new Byte[0]; | ||
3003 | reply.Data.ActualArea = land.Area; | 3096 | reply.Data.ActualArea = land.Area; |
3004 | reply.Data.BillableArea = land.Area; // TODO: what is this? | 3097 | reply.Data.BillableArea = land.Area; // TODO: what is this? |
3005 | 3098 | ||
3006 | // Bit 0: Mature, bit 7: on sale, other bits: no idea | 3099 | reply.Data.Flags = (byte)Util.ConvertAccessLevelToMaturity((byte)info.AccessLevel); |
3007 | reply.Data.Flags = (byte)( | 3100 | if((land.Flags & (uint)ParcelFlags.ForSale) != 0) |
3008 | (info.AccessLevel > 13 ? (1 << 0) : 0) + | 3101 | reply.Data.Flags |= (byte)((1 << 7)); |
3009 | ((land.Flags & (uint)ParcelFlags.ForSale) != 0 ? (1 << 7) : 0)); | ||
3010 | 3102 | ||
3011 | Vector3 pos = land.UserLocation; | 3103 | Vector3 pos = land.UserLocation; |
3012 | if (pos.Equals(Vector3.Zero)) | 3104 | if (pos.Equals(Vector3.Zero)) |
@@ -3018,7 +3110,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3018 | reply.Data.GlobalZ = pos.Z; | 3110 | reply.Data.GlobalZ = pos.Z; |
3019 | reply.Data.SimName = Utils.StringToBytes(info.RegionName); | 3111 | reply.Data.SimName = Utils.StringToBytes(info.RegionName); |
3020 | reply.Data.SnapshotID = land.SnapshotID; | 3112 | reply.Data.SnapshotID = land.SnapshotID; |
3021 | reply.Data.Dwell = dwell; | 3113 | reply.Data.Dwell = land.Dwell; |
3022 | reply.Data.SalePrice = land.SalePrice; | 3114 | reply.Data.SalePrice = land.SalePrice; |
3023 | reply.Data.AuctionID = (int)land.AuctionID; | 3115 | reply.Data.AuctionID = (int)land.AuctionID; |
3024 | 3116 | ||
@@ -3385,7 +3477,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3385 | AgentData.Add(AgentDataMap); | 3477 | AgentData.Add(AgentDataMap); |
3386 | llsd.Add("AgentData", AgentData); | 3478 | llsd.Add("AgentData", AgentData); |
3387 | OSDArray GroupData = new OSDArray(data.Length); | 3479 | OSDArray GroupData = new OSDArray(data.Length); |
3388 | OSDArray NewGroupData = new OSDArray(data.Length); | 3480 | // OSDArray NewGroupData = new OSDArray(data.Length); |
3389 | foreach (GroupMembershipData m in data) | 3481 | foreach (GroupMembershipData m in data) |
3390 | { | 3482 | { |
3391 | OSDMap GroupDataMap = new OSDMap(6); | 3483 | OSDMap GroupDataMap = new OSDMap(6); |
@@ -3396,12 +3488,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3396 | GroupDataMap.Add("GroupID", OSD.FromUUID(m.GroupID)); | 3488 | GroupDataMap.Add("GroupID", OSD.FromUUID(m.GroupID)); |
3397 | GroupDataMap.Add("GroupName", OSD.FromString(m.GroupName)); | 3489 | GroupDataMap.Add("GroupName", OSD.FromString(m.GroupName)); |
3398 | GroupDataMap.Add("GroupInsigniaID", OSD.FromUUID(m.GroupPicture)); | 3490 | GroupDataMap.Add("GroupInsigniaID", OSD.FromUUID(m.GroupPicture)); |
3399 | NewGroupDataMap.Add("ListInProfile", OSD.FromBoolean(m.ListInProfile)); | 3491 | // NewGroupDataMap.Add("ListInProfile", OSD.FromBoolean(m.ListInProfile)); |
3400 | GroupData.Add(GroupDataMap); | 3492 | GroupData.Add(GroupDataMap); |
3401 | NewGroupData.Add(NewGroupDataMap); | 3493 | // NewGroupData.Add(NewGroupDataMap); |
3402 | } | 3494 | } |
3403 | llsd.Add("GroupData", GroupData); | 3495 | llsd.Add("GroupData", GroupData); |
3404 | llsd.Add("NewGroupData", NewGroupData); | 3496 | // llsd.Add("NewGroupData", NewGroupData); |
3405 | 3497 | ||
3406 | IEventQueue eq = this.Scene.RequestModuleInterface<IEventQueue>(); | 3498 | IEventQueue eq = this.Scene.RequestModuleInterface<IEventQueue>(); |
3407 | if (eq != null) | 3499 | if (eq != null) |
@@ -3410,6 +3502,39 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3410 | } | 3502 | } |
3411 | } | 3503 | } |
3412 | 3504 | ||
3505 | public void SendAgentGroupDataUpdate(UUID avatarID, GroupMembershipData[] data) | ||
3506 | { | ||
3507 | if(avatarID != AgentId) | ||
3508 | m_log.Debug("[CLIENT]: SendAgentGroupDataUpdate avatarID != AgentId"); | ||
3509 | |||
3510 | IEventQueue eq = this.Scene.RequestModuleInterface<IEventQueue>(); | ||
3511 | if(eq != null) | ||
3512 | { | ||
3513 | eq.GroupMembershipData(avatarID,data); | ||
3514 | } | ||
3515 | else | ||
3516 | { | ||
3517 | // use UDP if no caps | ||
3518 | AgentGroupDataUpdatePacket Groupupdate = new AgentGroupDataUpdatePacket(); | ||
3519 | AgentGroupDataUpdatePacket.GroupDataBlock[] Groups = new AgentGroupDataUpdatePacket.GroupDataBlock[data.Length]; | ||
3520 | for (int i = 0; i < data.Length; i++) | ||
3521 | { | ||
3522 | AgentGroupDataUpdatePacket.GroupDataBlock Group = new AgentGroupDataUpdatePacket.GroupDataBlock(); | ||
3523 | Group.AcceptNotices = data[i].AcceptNotices; | ||
3524 | Group.Contribution = data[i].Contribution; | ||
3525 | Group.GroupID = data[i].GroupID; | ||
3526 | Group.GroupInsigniaID = data[i].GroupPicture; | ||
3527 | Group.GroupName = Util.StringToBytes256(data[i].GroupName); | ||
3528 | Group.GroupPowers = data[i].GroupPowers; | ||
3529 | Groups[i] = Group; | ||
3530 | } | ||
3531 | Groupupdate.GroupData = Groups; | ||
3532 | Groupupdate.AgentData = new AgentGroupDataUpdatePacket.AgentDataBlock(); | ||
3533 | Groupupdate.AgentData.AgentID = avatarID; | ||
3534 | OutPacket(Groupupdate, ThrottleOutPacketType.Task); | ||
3535 | } | ||
3536 | } | ||
3537 | |||
3413 | public void SendJoinGroupReply(UUID groupID, bool success) | 3538 | public void SendJoinGroupReply(UUID groupID, bool success) |
3414 | { | 3539 | { |
3415 | JoinGroupReplyPacket p = (JoinGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.JoinGroupReply); | 3540 | JoinGroupReplyPacket p = (JoinGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.JoinGroupReply); |
@@ -3649,6 +3774,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3649 | OutPacket(useCachedMuteList, ThrottleOutPacketType.Task); | 3774 | OutPacket(useCachedMuteList, ThrottleOutPacketType.Task); |
3650 | } | 3775 | } |
3651 | 3776 | ||
3777 | public void SendEmpytMuteList() | ||
3778 | { | ||
3779 | GenericMessagePacket gmp = new GenericMessagePacket(); | ||
3780 | |||
3781 | gmp.AgentData.AgentID = AgentId; | ||
3782 | gmp.AgentData.SessionID = m_sessionId; | ||
3783 | gmp.AgentData.TransactionID = UUID.Zero; | ||
3784 | |||
3785 | gmp.MethodData.Method = Util.StringToBytes256("emptymutelist"); | ||
3786 | gmp.ParamList = new GenericMessagePacket.ParamListBlock[1]; | ||
3787 | gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock(); | ||
3788 | gmp.ParamList[0].Parameter = new byte[0]; | ||
3789 | |||
3790 | OutPacket(gmp, ThrottleOutPacketType.Task); | ||
3791 | } | ||
3792 | |||
3652 | public void SendMuteListUpdate(string filename) | 3793 | public void SendMuteListUpdate(string filename) |
3653 | { | 3794 | { |
3654 | MuteListUpdatePacket muteListUpdate = (MuteListUpdatePacket)PacketPool.Instance.GetPacket(PacketType.MuteListUpdate); | 3795 | MuteListUpdatePacket muteListUpdate = (MuteListUpdatePacket)PacketPool.Instance.GetPacket(PacketType.MuteListUpdate); |
@@ -3706,24 +3847,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3706 | aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count]; | 3847 | aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count]; |
3707 | AgentWearablesUpdatePacket.WearableDataBlock awb; | 3848 | AgentWearablesUpdatePacket.WearableDataBlock awb; |
3708 | int idx = 0; | 3849 | int idx = 0; |
3709 | for (int i = 0; i < wearables.Length; i++) | ||
3710 | { | ||
3711 | for (int j = 0; j < wearables[i].Count; j++) | ||
3712 | { | ||
3713 | awb = new AgentWearablesUpdatePacket.WearableDataBlock(); | ||
3714 | awb.WearableType = (byte)i; | ||
3715 | awb.AssetID = wearables[i][j].AssetID; | ||
3716 | awb.ItemID = wearables[i][j].ItemID; | ||
3717 | aw.WearableData[idx] = awb; | ||
3718 | idx++; | ||
3719 | 3850 | ||
3720 | // m_log.DebugFormat( | 3851 | for (int i = 0; i < wearables.Length; i++) |
3721 | // "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}", | 3852 | { |
3722 | // awb.ItemID, awb.AssetID, i, Name); | 3853 | for (int j = 0; j < wearables[i].Count; j++) |
3723 | } | 3854 | { |
3724 | } | 3855 | awb = new AgentWearablesUpdatePacket.WearableDataBlock(); |
3856 | awb.WearableType = (byte) i; | ||
3857 | awb.AssetID = wearables[i][j].AssetID; | ||
3858 | awb.ItemID = wearables[i][j].ItemID; | ||
3859 | aw.WearableData[idx] = awb; | ||
3860 | idx++; | ||
3861 | |||
3862 | // m_log.DebugFormat( | ||
3863 | // "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}", | ||
3864 | // awb.ItemID, awb.AssetID, i, Name); | ||
3865 | } | ||
3866 | } | ||
3725 | 3867 | ||
3726 | OutPacket(aw, ThrottleOutPacketType.Task); | 3868 | OutPacket(aw, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); |
3727 | } | 3869 | } |
3728 | 3870 | ||
3729 | public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) | 3871 | public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) |
@@ -3749,8 +3891,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3749 | avp.Sender.ID = agentID; | 3891 | avp.Sender.ID = agentID; |
3750 | avp.AppearanceData = new AvatarAppearancePacket.AppearanceDataBlock[0]; | 3892 | avp.AppearanceData = new AvatarAppearancePacket.AppearanceDataBlock[0]; |
3751 | avp.AppearanceHover = new AvatarAppearancePacket.AppearanceHoverBlock[0]; | 3893 | avp.AppearanceHover = new AvatarAppearancePacket.AppearanceHoverBlock[0]; |
3894 | |||
3895 | // this need be use in future ? | ||
3896 | // avp.AppearanceData[0].AppearanceVersion = 0; | ||
3897 | // avp.AppearanceData[0].CofVersion = 0; | ||
3898 | |||
3752 | //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); | 3899 | //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); |
3753 | OutPacket(avp, ThrottleOutPacketType.Task); | 3900 | OutPacket(avp, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); |
3754 | } | 3901 | } |
3755 | 3902 | ||
3756 | public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) | 3903 | public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) |
@@ -3778,7 +3925,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3778 | ani.AnimationSourceList[i].ObjectID = objectIDs[i]; | 3925 | ani.AnimationSourceList[i].ObjectID = objectIDs[i]; |
3779 | } | 3926 | } |
3780 | ani.Header.Reliable = false; | 3927 | ani.Header.Reliable = false; |
3781 | OutPacket(ani, ThrottleOutPacketType.Task); | 3928 | OutPacket(ani, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); |
3782 | } | 3929 | } |
3783 | 3930 | ||
3784 | #endregion | 3931 | #endregion |
@@ -3788,26 +3935,70 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3788 | /// <summary> | 3935 | /// <summary> |
3789 | /// Send an ObjectUpdate packet with information about an avatar | 3936 | /// Send an ObjectUpdate packet with information about an avatar |
3790 | /// </summary> | 3937 | /// </summary> |
3791 | public void SendAvatarDataImmediate(ISceneEntity avatar) | 3938 | public void SendEntityFullUpdateImmediate(ISceneEntity ent) |
3792 | { | 3939 | { |
3793 | // m_log.DebugFormat( | 3940 | // m_log.DebugFormat( |
3794 | // "[LLCLIENTVIEW]: Sending immediate object update for avatar {0} {1} to {2} {3}", | 3941 | // "[LLCLIENTVIEW]: Sending immediate object update for avatar {0} {1} to {2} {3}", |
3795 | // avatar.Name, avatar.UUID, Name, AgentId); | 3942 | // avatar.Name, avatar.UUID, Name, AgentId); |
3796 | 3943 | ||
3797 | ScenePresence presence = avatar as ScenePresence; | 3944 | if (ent == null) |
3798 | if (presence == null) | ||
3799 | return; | 3945 | return; |
3800 | 3946 | ||
3801 | ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); | 3947 | ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); |
3802 | objupdate.Header.Zerocoded = true; | 3948 | objupdate.Header.Zerocoded = true; |
3803 | 3949 | ||
3804 | objupdate.RegionData.RegionHandle = presence.RegionHandle; | 3950 | objupdate.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); |
3805 | objupdate.RegionData.TimeDilation = ushort.MaxValue; | ||
3806 | |||
3807 | objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | 3951 | objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; |
3808 | objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence); | ||
3809 | 3952 | ||
3810 | OutPacket(objupdate, ThrottleOutPacketType.Task); | 3953 | if(ent is ScenePresence) |
3954 | { | ||
3955 | ScenePresence presence = ent as ScenePresence; | ||
3956 | objupdate.RegionData.RegionHandle = presence.RegionHandle; | ||
3957 | objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence); | ||
3958 | } | ||
3959 | else if(ent is SceneObjectPart) | ||
3960 | { | ||
3961 | SceneObjectPart part = ent as SceneObjectPart; | ||
3962 | objupdate.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | ||
3963 | objupdate.ObjectData[0] = CreatePrimUpdateBlock(part, (ScenePresence)SceneAgent); | ||
3964 | } | ||
3965 | |||
3966 | OutPacket(objupdate, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); | ||
3967 | |||
3968 | // We need to record the avatar local id since the root prim of an attachment points to this. | ||
3969 | // m_attachmentsSent.Add(avatar.LocalId); | ||
3970 | } | ||
3971 | |||
3972 | public void SendEntityTerseUpdateImmediate(ISceneEntity ent) | ||
3973 | { | ||
3974 | // m_log.DebugFormat( | ||
3975 | // "[LLCLIENTVIEW]: Sending immediate object update for avatar {0} {1} to {2} {3}", | ||
3976 | // avatar.Name, avatar.UUID, Name, AgentId); | ||
3977 | |||
3978 | if (ent == null) | ||
3979 | return; | ||
3980 | |||
3981 | ImprovedTerseObjectUpdatePacket objupdate = | ||
3982 | (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); | ||
3983 | objupdate.Header.Zerocoded = true; | ||
3984 | |||
3985 | objupdate.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); | ||
3986 | objupdate.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; | ||
3987 | |||
3988 | if(ent is ScenePresence) | ||
3989 | { | ||
3990 | ScenePresence presence = ent as ScenePresence; | ||
3991 | objupdate.RegionData.RegionHandle = presence.RegionHandle; | ||
3992 | objupdate.ObjectData[0] = CreateImprovedTerseBlock(ent, false); | ||
3993 | } | ||
3994 | else if(ent is SceneObjectPart) | ||
3995 | { | ||
3996 | SceneObjectPart part = ent as SceneObjectPart; | ||
3997 | objupdate.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | ||
3998 | objupdate.ObjectData[0] = CreateImprovedTerseBlock(ent, false); | ||
3999 | } | ||
4000 | |||
4001 | OutPacket(objupdate, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); | ||
3811 | 4002 | ||
3812 | // We need to record the avatar local id since the root prim of an attachment points to this. | 4003 | // We need to record the avatar local id since the root prim of an attachment points to this. |
3813 | // m_attachmentsSent.Add(avatar.LocalId); | 4004 | // m_attachmentsSent.Add(avatar.LocalId); |
@@ -3859,13 +4050,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3859 | 4050 | ||
3860 | #region Primitive Packet/Data Sending Methods | 4051 | #region Primitive Packet/Data Sending Methods |
3861 | 4052 | ||
3862 | |||
3863 | /// <summary> | 4053 | /// <summary> |
3864 | /// Generate one of the object update packets based on PrimUpdateFlags | 4054 | /// Generate one of the object update packets based on PrimUpdateFlags |
3865 | /// and broadcast the packet to clients | 4055 | /// and broadcast the packet to clients |
3866 | /// </summary> | 4056 | /// </summary> |
3867 | public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) | 4057 | public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) |
3868 | { | 4058 | { |
4059 | /* | ||
3869 | if (entity.UUID == m_agentId && !updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) | 4060 | if (entity.UUID == m_agentId && !updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) |
3870 | { | 4061 | { |
3871 | ImprovedTerseObjectUpdatePacket packet | 4062 | ImprovedTerseObjectUpdatePacket packet |
@@ -3876,21 +4067,38 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3876 | packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; | 4067 | packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; |
3877 | packet.ObjectData[0] = CreateImprovedTerseBlock(entity, false); | 4068 | packet.ObjectData[0] = CreateImprovedTerseBlock(entity, false); |
3878 | OutPacket(packet, ThrottleOutPacketType.Unknown, true); | 4069 | OutPacket(packet, ThrottleOutPacketType.Unknown, true); |
4070 | return; | ||
3879 | } | 4071 | } |
3880 | else | 4072 | */ |
4073 | if (entity is SceneObjectPart) | ||
3881 | { | 4074 | { |
3882 | //double priority = m_prioritizer.GetUpdatePriority(this, entity); | 4075 | SceneObjectPart p = (SceneObjectPart)entity; |
3883 | uint priority = m_prioritizer.GetUpdatePriority(this, entity); | 4076 | SceneObjectGroup g = p.ParentGroup; |
3884 | 4077 | if (g.HasPrivateAttachmentPoint && g.OwnerID != AgentId) | |
3885 | lock (m_entityUpdates.SyncRoot) | 4078 | return; // Don't send updates for other people's HUDs |
3886 | m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation)); | 4079 | |
4080 | if((updateFlags ^ PrimUpdateFlags.SendInTransit) == 0) | ||
4081 | { | ||
4082 | List<uint> partIDs = (new List<uint> {p.LocalId}); | ||
4083 | lock (m_entityProps.SyncRoot) | ||
4084 | m_entityProps.Remove(partIDs); | ||
4085 | lock (m_entityUpdates.SyncRoot) | ||
4086 | m_entityUpdates.Remove(partIDs); | ||
4087 | return; | ||
4088 | } | ||
3887 | } | 4089 | } |
4090 | |||
4091 | //double priority = m_prioritizer.GetUpdatePriority(this, entity); | ||
4092 | uint priority = m_prioritizer.GetUpdatePriority(this, entity); | ||
4093 | |||
4094 | lock (m_entityUpdates.SyncRoot) | ||
4095 | m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags)); | ||
3888 | } | 4096 | } |
3889 | 4097 | ||
3890 | /// <summary> | 4098 | /// <summary> |
3891 | /// Requeue an EntityUpdate when it was not acknowledged by the client. | 4099 | /// Requeue an EntityUpdate when it was not acknowledged by the client. |
3892 | /// We will update the priority and put it in the correct queue, merging update flags | 4100 | /// We will update the priority and put it in the correct queue, merging update flags |
3893 | /// with any other updates that may be queued for the same entity. | 4101 | /// with any other updates that may be queued for the same entity. |
3894 | /// The original update time is used for the merged update. | 4102 | /// The original update time is used for the merged update. |
3895 | /// </summary> | 4103 | /// </summary> |
3896 | private void ResendPrimUpdate(EntityUpdate update) | 4104 | private void ResendPrimUpdate(EntityUpdate update) |
@@ -3904,9 +4112,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3904 | } | 4112 | } |
3905 | 4113 | ||
3906 | /// <summary> | 4114 | /// <summary> |
3907 | /// Requeue a list of EntityUpdates when they were not acknowledged by the client. | 4115 | /// Requeue a list of EntityUpdates when they were not acknowledged by the client. |
3908 | /// We will update the priority and put it in the correct queue, merging update flags | 4116 | /// We will update the priority and put it in the correct queue, merging update flags |
3909 | /// with any other updates that may be queued for the same entity. | 4117 | /// with any other updates that may be queued for the same entity. |
3910 | /// The original update time is used for the merged update. | 4118 | /// The original update time is used for the merged update. |
3911 | /// </summary> | 4119 | /// </summary> |
3912 | private void ResendPrimUpdates(List<EntityUpdate> updates, OutgoingPacket oPacket) | 4120 | private void ResendPrimUpdates(List<EntityUpdate> updates, OutgoingPacket oPacket) |
@@ -3919,7 +4127,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3919 | m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber); | 4127 | m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber); |
3920 | 4128 | ||
3921 | // Count this as a resent packet since we are going to requeue all of the updates contained in it | 4129 | // Count this as a resent packet since we are going to requeue all of the updates contained in it |
3922 | Interlocked.Increment(ref m_udpClient.PacketsResent); | 4130 | Interlocked.Increment(ref m_udpClient.PacketsResent); |
3923 | 4131 | ||
3924 | // We're not going to worry about interlock yet since its not currently critical that this total count | 4132 | // We're not going to worry about interlock yet since its not currently critical that this total count |
3925 | // is 100% correct | 4133 | // is 100% correct |
@@ -3929,335 +4137,515 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3929 | ResendPrimUpdate(update); | 4137 | ResendPrimUpdate(update); |
3930 | } | 4138 | } |
3931 | 4139 | ||
3932 | // OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); | 4140 | private List<ObjectUpdatePacket.ObjectDataBlock> objectUpdateBlocks = new List<ObjectUpdatePacket.ObjectDataBlock>(); |
3933 | // OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>(); | 4141 | private List<ObjectUpdateCompressedPacket.ObjectDataBlock> compressedUpdateBlocks = new List<ObjectUpdateCompressedPacket.ObjectDataBlock>(); |
3934 | // OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); | 4142 | private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> terseUpdateBlocks = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); |
3935 | // OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); | 4143 | private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> terseAgentUpdateBlocks = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); |
3936 | // | ||
3937 | // OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | ||
3938 | // OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | ||
3939 | // OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | ||
3940 | // OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | ||
3941 | |||
3942 | 4144 | ||
3943 | private void ProcessEntityUpdates(int maxUpdates) | 4145 | private void ProcessEntityUpdates(int maxUpdatesBytes) |
3944 | { | 4146 | { |
3945 | OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); | ||
3946 | OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>(); | ||
3947 | OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); | ||
3948 | OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); | ||
3949 | |||
3950 | OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | 4147 | OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); |
3951 | OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | 4148 | OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); |
3952 | OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | 4149 | OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); |
3953 | OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | 4150 | OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); |
3954 | 4151 | ||
3955 | // objectUpdateBlocks.Value.Clear(); | ||
3956 | // compressedUpdateBlocks.Value.Clear(); | ||
3957 | // terseUpdateBlocks.Value.Clear(); | ||
3958 | // terseAgentUpdateBlocks.Value.Clear(); | ||
3959 | // objectUpdates.Value.Clear(); | ||
3960 | // compressedUpdates.Value.Clear(); | ||
3961 | // terseUpdates.Value.Clear(); | ||
3962 | // terseAgentUpdates.Value.Clear(); | ||
3963 | |||
3964 | // Check to see if this is a flush | 4152 | // Check to see if this is a flush |
3965 | if (maxUpdates <= 0) | 4153 | if (maxUpdatesBytes <= 0) |
3966 | { | 4154 | { |
3967 | maxUpdates = Int32.MaxValue; | 4155 | maxUpdatesBytes = Int32.MaxValue; |
3968 | } | 4156 | } |
3969 | 4157 | ||
3970 | int updatesThisCall = 0; | 4158 | EntityUpdate update; |
4159 | Int32 timeinqueue; // this is just debugging code & can be dropped later | ||
4160 | |||
4161 | bool doCulling = m_scene.ObjectsCullingByDistance; | ||
4162 | float cullingrange = 64.0f; | ||
4163 | HashSet<SceneObjectGroup> GroupsNeedFullUpdate = new HashSet<SceneObjectGroup>(); | ||
4164 | // Vector3 mycamera = Vector3.Zero; | ||
4165 | Vector3 mypos = Vector3.Zero; | ||
4166 | ScenePresence mysp = (ScenePresence)SceneAgent; | ||
4167 | |||
4168 | bool orderedDequeue = m_scene.UpdatePrioritizationScheme == UpdatePrioritizationSchemes.SimpleAngularDistance; | ||
4169 | // we should have a presence | ||
4170 | if(mysp == null) | ||
4171 | return; | ||
3971 | 4172 | ||
3972 | // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race | 4173 | if(doCulling) |
3973 | // condition where a kill can be processed before an out-of-date update for the same object. | ||
3974 | lock (m_killRecord) | ||
3975 | { | 4174 | { |
3976 | float avgTimeDilation = 1.0f; | 4175 | cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f; |
3977 | IEntityUpdate iupdate; | 4176 | // mycamera = mysp.CameraPosition; |
3978 | Int32 timeinqueue; // this is just debugging code & can be dropped later | 4177 | mypos = mysp.AbsolutePosition; |
4178 | } | ||
3979 | 4179 | ||
3980 | while (updatesThisCall < maxUpdates) | 4180 | while (maxUpdatesBytes > 0) |
4181 | { | ||
4182 | lock (m_entityUpdates.SyncRoot) | ||
3981 | { | 4183 | { |
3982 | lock (m_entityUpdates.SyncRoot) | 4184 | if(orderedDequeue) |
3983 | if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue)) | 4185 | { |
4186 | if (!m_entityUpdates.TryOrderedDequeue(out update, out timeinqueue)) | ||
3984 | break; | 4187 | break; |
4188 | } | ||
4189 | else | ||
4190 | { | ||
4191 | if (!m_entityUpdates.TryDequeue(out update, out timeinqueue)) | ||
4192 | break; | ||
4193 | } | ||
4194 | } | ||
3985 | 4195 | ||
3986 | EntityUpdate update = (EntityUpdate)iupdate; | 4196 | PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; |
3987 | |||
3988 | avgTimeDilation += update.TimeDilation; | ||
3989 | avgTimeDilation *= 0.5f; | ||
3990 | 4197 | ||
3991 | if (update.Entity is SceneObjectPart) | 4198 | if(updateFlags.HasFlag(PrimUpdateFlags.Kill)) |
4199 | { | ||
4200 | m_killRecord.Add(update.Entity.LocalId); | ||
4201 | maxUpdatesBytes -= 30; | ||
4202 | continue; | ||
4203 | } | ||
4204 | |||
4205 | if (update.Entity is SceneObjectPart) | ||
4206 | { | ||
4207 | SceneObjectPart part = (SceneObjectPart)update.Entity; | ||
4208 | SceneObjectGroup grp = part.ParentGroup; | ||
4209 | if (grp.inTransit && !update.Flags.HasFlag(PrimUpdateFlags.SendInTransit)) | ||
4210 | continue; | ||
4211 | /* debug | ||
4212 | if (update.Flags.HasFlag(PrimUpdateFlags.SendInTransit)) | ||
4213 | { | ||
4214 | |||
4215 | |||
4216 | } | ||
4217 | */ | ||
4218 | if (grp.IsDeleted) | ||
3992 | { | 4219 | { |
3993 | SceneObjectPart part = (SceneObjectPart)update.Entity; | 4220 | // Don't send updates for objects that have been marked deleted. |
3994 | 4221 | // Instead send another kill object, because the first one may have gotten | |
3995 | // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client | 4222 | // into a race condition |
3996 | // will never receive an update after a prim kill. Even then, keeping the kill record may be a good | 4223 | if (part == grp.RootPart && !m_killRecord.Contains(grp.LocalId)) |
3997 | // safety measure. | ||
3998 | // | ||
3999 | // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update | ||
4000 | // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs | ||
4001 | // updates and kills on different threads with different scheduling strategies, hence this protection. | ||
4002 | // | ||
4003 | // This doesn't appear to apply to child prims - a client will happily ignore these updates | ||
4004 | // after the root prim has been deleted. | ||
4005 | if (m_killRecord.Contains(part.LocalId)) | ||
4006 | { | 4224 | { |
4007 | // m_log.WarnFormat( | 4225 | m_killRecord.Add(grp.LocalId); |
4008 | // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", | 4226 | maxUpdatesBytes -= 30; |
4009 | // part.LocalId, Name); | 4227 | } |
4228 | continue; | ||
4229 | } | ||
4230 | |||
4231 | if (grp.IsAttachment) | ||
4232 | { // Someone else's HUD, why are we getting these? | ||
4233 | if (grp.OwnerID != AgentId && grp.HasPrivateAttachmentPoint) | ||
4234 | continue; | ||
4235 | ScenePresence sp; | ||
4236 | // Owner is not in the sim, don't update it to | ||
4237 | // anyone | ||
4238 | if (!m_scene.TryGetScenePresence(part.OwnerID, out sp)) | ||
4010 | continue; | 4239 | continue; |
4011 | } | 4240 | |
4012 | 4241 | List<SceneObjectGroup> atts = sp.GetAttachments(); | |
4013 | if (part.ParentGroup.IsAttachment && m_disableFacelights) | 4242 | bool found = false; |
4243 | foreach (SceneObjectGroup att in atts) | ||
4014 | { | 4244 | { |
4015 | if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && | 4245 | if (att == grp) |
4016 | part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand) | ||
4017 | { | 4246 | { |
4018 | part.Shape.LightEntry = false; | 4247 | found = true; |
4248 | break; | ||
4019 | } | 4249 | } |
4020 | } | 4250 | } |
4021 | 4251 | ||
4022 | if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh)) | 4252 | // It's an attachment of a valid avatar, but |
4023 | { | 4253 | // doesn't seem to be attached, skip |
4024 | // Ensure that mesh has at least 8 valid faces | 4254 | if (!found) |
4025 | part.Shape.ProfileBegin = 12500; | 4255 | continue; |
4026 | part.Shape.ProfileEnd = 0; | 4256 | |
4027 | part.Shape.ProfileHollow = 27500; | 4257 | // On vehicle crossing, the attachments are received |
4028 | } | 4258 | // while the avatar is still a child. Don't send |
4029 | } | 4259 | // updates here because the LocalId has not yet |
4030 | 4260 | // been updated and the viewer will derender the | |
4031 | #region UpdateFlags to packet type conversion | 4261 | // attachments until the avatar becomes root. |
4032 | 4262 | if (sp.IsChildAgent) | |
4033 | PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; | 4263 | continue; |
4034 | 4264 | ||
4035 | bool canUseCompressed = true; | ||
4036 | bool canUseImproved = true; | ||
4037 | |||
4038 | // Compressed object updates only make sense for LL primitives | ||
4039 | if (!(update.Entity is SceneObjectPart)) | ||
4040 | { | ||
4041 | canUseCompressed = false; | ||
4042 | } | ||
4043 | |||
4044 | if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) | ||
4045 | { | ||
4046 | canUseCompressed = false; | ||
4047 | canUseImproved = false; | ||
4048 | } | 4265 | } |
4049 | else | 4266 | |
4267 | if (grp.IsAttachment && m_disableFacelights) | ||
4050 | { | 4268 | { |
4051 | if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || | 4269 | if (grp.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && |
4052 | updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || | 4270 | grp.RootPart.Shape.State != (byte)AttachmentPoint.RightHand) |
4053 | updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) || | ||
4054 | updateFlags.HasFlag(PrimUpdateFlags.Joint)) | ||
4055 | { | ||
4056 | canUseCompressed = false; | ||
4057 | } | ||
4058 | |||
4059 | if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) || | ||
4060 | updateFlags.HasFlag(PrimUpdateFlags.ParentID) || | ||
4061 | updateFlags.HasFlag(PrimUpdateFlags.Scale) || | ||
4062 | updateFlags.HasFlag(PrimUpdateFlags.PrimData) || | ||
4063 | updateFlags.HasFlag(PrimUpdateFlags.Text) || | ||
4064 | updateFlags.HasFlag(PrimUpdateFlags.NameValue) || | ||
4065 | updateFlags.HasFlag(PrimUpdateFlags.ExtraData) || | ||
4066 | updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) || | ||
4067 | updateFlags.HasFlag(PrimUpdateFlags.Sound) || | ||
4068 | updateFlags.HasFlag(PrimUpdateFlags.Particles) || | ||
4069 | updateFlags.HasFlag(PrimUpdateFlags.Material) || | ||
4070 | updateFlags.HasFlag(PrimUpdateFlags.ClickAction) || | ||
4071 | updateFlags.HasFlag(PrimUpdateFlags.MediaURL) || | ||
4072 | updateFlags.HasFlag(PrimUpdateFlags.Joint)) | ||
4073 | { | 4271 | { |
4074 | canUseImproved = false; | 4272 | part.Shape.LightEntry = false; |
4075 | } | 4273 | } |
4076 | } | 4274 | } |
4077 | 4275 | ||
4078 | #endregion UpdateFlags to packet type conversion | 4276 | if(doCulling && !grp.IsAttachment) |
4079 | |||
4080 | #region Block Construction | ||
4081 | |||
4082 | // TODO: Remove this once we can build compressed updates | ||
4083 | canUseCompressed = false; | ||
4084 | |||
4085 | if (!canUseImproved && !canUseCompressed) | ||
4086 | { | 4277 | { |
4087 | ObjectUpdatePacket.ObjectDataBlock updateBlock; | 4278 | if(GroupsNeedFullUpdate.Contains(grp)) |
4279 | continue; | ||
4088 | 4280 | ||
4089 | if (update.Entity is ScenePresence) | 4281 | bool inview = false; |
4090 | { | 4282 | lock(GroupsInView) |
4091 | updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity); | 4283 | inview = GroupsInView.Contains(grp); |
4092 | } | 4284 | |
4093 | else | 4285 | if(!inview) |
4094 | { | 4286 | { |
4095 | SceneObjectPart part = (SceneObjectPart)update.Entity; | 4287 | float bradius = grp.GetBoundsRadius(); |
4096 | updateBlock = CreatePrimUpdateBlock(part, AgentId); | 4288 | Vector3 partpos = grp.AbsolutePosition + grp.getBoundsCenter(); |
4097 | 4289 | // float dcam = (partpos - mycamera).LengthSquared(); | |
4098 | // If the part has become a private hud since the update was scheduled then we do not | 4290 | float dpos = (partpos - mypos).LengthSquared(); |
4099 | // want to send it to other avatars. | 4291 | // if(dcam < dpos) |
4100 | if (part.ParentGroup.IsAttachment | 4292 | // dpos = dcam; |
4101 | && part.ParentGroup.HasPrivateAttachmentPoint | 4293 | dpos = (float)Math.Sqrt(dpos) - bradius; |
4102 | && part.ParentGroup.AttachedAvatar != AgentId) | 4294 | if(dpos > cullingrange) |
4103 | continue; | 4295 | continue; |
4104 | 4296 | ||
4105 | // If the part has since been deleted, then drop the update. In the case of attachments, | 4297 | GroupsNeedFullUpdate.Add(grp); |
4106 | // this is to avoid spurious updates to other viewers since post-processing of attachments | 4298 | continue; |
4107 | // has to change the IsAttachment flag for various reasons (which will end up in a pass | ||
4108 | // of the test above). | ||
4109 | // | ||
4110 | // Actual deletions (kills) happen in another method. | ||
4111 | if (part.ParentGroup.IsDeleted) | ||
4112 | continue; | ||
4113 | } | 4299 | } |
4300 | } | ||
4301 | } | ||
4302 | else if (update.Entity is ScenePresence) | ||
4303 | { | ||
4304 | ScenePresence presence = (ScenePresence)update.Entity; | ||
4305 | if (presence.IsDeleted) | ||
4306 | continue; | ||
4307 | // If ParentUUID is not UUID.Zero and ParentID is 0, this | ||
4308 | // avatar is in the process of crossing regions while | ||
4309 | // sat on an object. In this state, we don't want any | ||
4310 | // updates because they will visually orbit the avatar. | ||
4311 | // Update will be forced once crossing is completed anyway. | ||
4312 | if (presence.ParentUUID != UUID.Zero && presence.ParentID == 0) | ||
4313 | continue; | ||
4314 | } | ||
4315 | |||
4316 | #region UpdateFlags to packet type conversion | ||
4317 | |||
4318 | bool canUseCompressed = true; | ||
4319 | bool canUseImproved = true; | ||
4320 | |||
4321 | |||
4322 | // Compressed object updates only make sense for LL primitives | ||
4323 | if (!(update.Entity is SceneObjectPart)) | ||
4324 | { | ||
4325 | canUseCompressed = false; | ||
4326 | } | ||
4114 | 4327 | ||
4115 | objectUpdateBlocks.Value.Add(updateBlock); | 4328 | if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) |
4116 | objectUpdates.Value.Add(update); | 4329 | { |
4330 | canUseCompressed = false; | ||
4331 | canUseImproved = false; | ||
4332 | } | ||
4333 | else | ||
4334 | { | ||
4335 | if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || | ||
4336 | updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || | ||
4337 | updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) || | ||
4338 | updateFlags.HasFlag(PrimUpdateFlags.Joint)) | ||
4339 | { | ||
4340 | canUseCompressed = false; | ||
4117 | } | 4341 | } |
4118 | else if (!canUseImproved) | 4342 | |
4343 | if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) || | ||
4344 | updateFlags.HasFlag(PrimUpdateFlags.ParentID) || | ||
4345 | updateFlags.HasFlag(PrimUpdateFlags.Scale) || | ||
4346 | updateFlags.HasFlag(PrimUpdateFlags.PrimData) || | ||
4347 | updateFlags.HasFlag(PrimUpdateFlags.Text) || | ||
4348 | updateFlags.HasFlag(PrimUpdateFlags.NameValue) || | ||
4349 | updateFlags.HasFlag(PrimUpdateFlags.ExtraData) || | ||
4350 | updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) || | ||
4351 | updateFlags.HasFlag(PrimUpdateFlags.Sound) || | ||
4352 | updateFlags.HasFlag(PrimUpdateFlags.Particles) || | ||
4353 | updateFlags.HasFlag(PrimUpdateFlags.Material) || | ||
4354 | updateFlags.HasFlag(PrimUpdateFlags.ClickAction) || | ||
4355 | updateFlags.HasFlag(PrimUpdateFlags.MediaURL) || | ||
4356 | updateFlags.HasFlag(PrimUpdateFlags.Joint)) | ||
4119 | { | 4357 | { |
4120 | SceneObjectPart part = (SceneObjectPart)update.Entity; | 4358 | canUseImproved = false; |
4121 | ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock | 4359 | } |
4122 | = CreateCompressedUpdateBlock(part, updateFlags); | 4360 | } |
4123 | 4361 | ||
4124 | // If the part has since been deleted, then drop the update. In the case of attachments, | 4362 | #endregion UpdateFlags to packet type conversion |
4125 | // this is to avoid spurious updates to other viewers since post-processing of attachments | ||
4126 | // has to change the IsAttachment flag for various reasons (which will end up in a pass | ||
4127 | // of the test above). | ||
4128 | // | ||
4129 | // Actual deletions (kills) happen in another method. | ||
4130 | if (part.ParentGroup.IsDeleted) | ||
4131 | continue; | ||
4132 | 4363 | ||
4133 | compressedUpdateBlocks.Value.Add(compressedBlock); | 4364 | #region Block Construction |
4134 | compressedUpdates.Value.Add(update); | 4365 | |
4366 | // TODO: Remove this once we can build compressed updates | ||
4367 | canUseCompressed = false; | ||
4368 | |||
4369 | if (!canUseImproved && !canUseCompressed) | ||
4370 | { | ||
4371 | ObjectUpdatePacket.ObjectDataBlock ablock; | ||
4372 | if (update.Entity is ScenePresence) | ||
4373 | ablock = CreateAvatarUpdateBlock((ScenePresence)update.Entity); | ||
4374 | else | ||
4375 | ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, mysp); | ||
4376 | objectUpdateBlocks.Add(ablock); | ||
4377 | objectUpdates.Value.Add(update); | ||
4378 | maxUpdatesBytes -= ablock.Length; | ||
4379 | |||
4380 | } | ||
4381 | else if (!canUseImproved) | ||
4382 | { | ||
4383 | ObjectUpdateCompressedPacket.ObjectDataBlock ablock = | ||
4384 | CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags); | ||
4385 | compressedUpdateBlocks.Add(ablock); | ||
4386 | compressedUpdates.Value.Add(update); | ||
4387 | maxUpdatesBytes -= ablock.Length; | ||
4388 | } | ||
4389 | else | ||
4390 | { | ||
4391 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock ablock; | ||
4392 | if (update.Entity is ScenePresence) | ||
4393 | { | ||
4394 | // ALL presence updates go into a special list | ||
4395 | ablock = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)); | ||
4396 | terseAgentUpdateBlocks.Add(ablock); | ||
4397 | terseAgentUpdates.Value.Add(update); | ||
4135 | } | 4398 | } |
4136 | else | 4399 | else |
4137 | { | 4400 | { |
4138 | if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) | 4401 | // Everything else goes here |
4139 | { | 4402 | ablock = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)); |
4140 | // Self updates go into a special list | 4403 | terseUpdateBlocks.Add(ablock); |
4141 | terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); | 4404 | terseUpdates.Value.Add(update); |
4142 | terseAgentUpdates.Value.Add(update); | 4405 | } |
4143 | } | 4406 | maxUpdatesBytes -= ablock.Length; |
4144 | else | 4407 | } |
4145 | { | ||
4146 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock | ||
4147 | = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)); | ||
4148 | 4408 | ||
4149 | // Everything else goes here | 4409 | #endregion Block Construction |
4150 | if (update.Entity is SceneObjectPart) | 4410 | } |
4151 | { | ||
4152 | SceneObjectPart part = (SceneObjectPart)update.Entity; | ||
4153 | |||
4154 | // If the part has become a private hud since the update was scheduled then we do not | ||
4155 | // want to send it to other avatars. | ||
4156 | if (part.ParentGroup.IsAttachment | ||
4157 | && part.ParentGroup.HasPrivateAttachmentPoint | ||
4158 | && part.ParentGroup.AttachedAvatar != AgentId) | ||
4159 | continue; | ||
4160 | |||
4161 | // If the part has since been deleted, then drop the update. In the case of attachments, | ||
4162 | // this is to avoid spurious updates to other viewers since post-processing of attachments | ||
4163 | // has to change the IsAttachment flag for various reasons (which will end up in a pass | ||
4164 | // of the test above). | ||
4165 | // | ||
4166 | // Actual deletions (kills) happen in another method. | ||
4167 | if (part.ParentGroup.IsDeleted) | ||
4168 | continue; | ||
4169 | } | ||
4170 | 4411 | ||
4171 | terseUpdateBlocks.Value.Add(terseUpdateBlock); | 4412 | #region Packet Sending |
4172 | terseUpdates.Value.Add(update); | ||
4173 | } | ||
4174 | } | ||
4175 | 4413 | ||
4176 | ++updatesThisCall; | 4414 | ushort timeDilation; |
4177 | |||
4178 | #endregion Block Construction | ||
4179 | } | ||
4180 | |||
4181 | #region Packet Sending | ||
4182 | ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); | ||
4183 | 4415 | ||
4184 | if (terseAgentUpdateBlocks.IsValueCreated) | 4416 | if(!IsActive) |
4185 | { | 4417 | return; |
4186 | List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; | 4418 | |
4419 | timeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); | ||
4187 | 4420 | ||
4188 | ImprovedTerseObjectUpdatePacket packet | 4421 | if (terseAgentUpdateBlocks.Count > 0) |
4189 | = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); | 4422 | { |
4423 | ImprovedTerseObjectUpdatePacket packet | ||
4424 | = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); | ||
4425 | packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | ||
4426 | packet.RegionData.TimeDilation = timeDilation; | ||
4427 | packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[terseAgentUpdateBlocks.Count]; | ||
4190 | 4428 | ||
4191 | packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | 4429 | for (int i = 0; i < terseAgentUpdateBlocks.Count; i++) |
4192 | packet.RegionData.TimeDilation = timeDilation; | 4430 | packet.ObjectData[i] = terseAgentUpdateBlocks[i]; |
4193 | packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; | ||
4194 | 4431 | ||
4195 | for (int i = 0; i < blocks.Count; i++) | 4432 | terseAgentUpdateBlocks.Clear(); |
4196 | packet.ObjectData[i] = blocks[i]; | 4433 | |
4197 | // If any of the packets created from this call go unacknowledged, all of the updates will be resent | 4434 | OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); }); |
4198 | OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); }); | 4435 | } |
4199 | } | 4436 | |
4437 | if (objectUpdateBlocks.Count > 0) | ||
4438 | { | ||
4439 | ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); | ||
4440 | packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | ||
4441 | packet.RegionData.TimeDilation = timeDilation; | ||
4442 | packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[objectUpdateBlocks.Count]; | ||
4443 | |||
4444 | for (int i = 0; i < objectUpdateBlocks.Count; i++) | ||
4445 | packet.ObjectData[i] = objectUpdateBlocks[i]; | ||
4446 | |||
4447 | objectUpdateBlocks.Clear(); | ||
4448 | |||
4449 | OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); }); | ||
4450 | } | ||
4451 | |||
4452 | if (compressedUpdateBlocks.Count > 0) | ||
4453 | { | ||
4454 | ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); | ||
4455 | packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | ||
4456 | packet.RegionData.TimeDilation = timeDilation; | ||
4457 | packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[compressedUpdateBlocks.Count]; | ||
4458 | |||
4459 | for (int i = 0; i < compressedUpdateBlocks.Count; i++) | ||
4460 | packet.ObjectData[i] = compressedUpdateBlocks[i]; | ||
4461 | |||
4462 | compressedUpdateBlocks.Clear(); | ||
4200 | 4463 | ||
4201 | if (objectUpdateBlocks.IsValueCreated) | 4464 | OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); }); |
4465 | } | ||
4466 | |||
4467 | if (terseUpdateBlocks.Count > 0) | ||
4468 | { | ||
4469 | ImprovedTerseObjectUpdatePacket packet | ||
4470 | = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket( | ||
4471 | PacketType.ImprovedTerseObjectUpdate); | ||
4472 | packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | ||
4473 | packet.RegionData.TimeDilation = timeDilation; | ||
4474 | packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[terseUpdateBlocks.Count]; | ||
4475 | |||
4476 | for (int i = 0; i < terseUpdateBlocks.Count; i++) | ||
4477 | packet.ObjectData[i] = terseUpdateBlocks[i]; | ||
4478 | |||
4479 | terseUpdateBlocks.Clear(); | ||
4480 | |||
4481 | OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); | ||
4482 | } | ||
4483 | |||
4484 | #endregion Packet Sending | ||
4485 | |||
4486 | #region Handle deleted objects | ||
4487 | if (m_killRecord.Count > 0) | ||
4488 | { | ||
4489 | SendKillObject(m_killRecord); | ||
4490 | m_killRecord.Clear(); | ||
4491 | } | ||
4492 | |||
4493 | if(GroupsNeedFullUpdate.Count > 0) | ||
4494 | { | ||
4495 | foreach(SceneObjectGroup grp in GroupsNeedFullUpdate) | ||
4202 | { | 4496 | { |
4203 | List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; | 4497 | foreach(SceneObjectPart p in grp.Parts) |
4204 | 4498 | SendEntityUpdate(p,PrimUpdateFlags.CancelKill); | |
4205 | ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); | 4499 | lock(GroupsInView) |
4206 | packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | 4500 | GroupsInView.Add(grp); |
4207 | packet.RegionData.TimeDilation = timeDilation; | ||
4208 | packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; | ||
4209 | |||
4210 | for (int i = 0; i < blocks.Count; i++) | ||
4211 | packet.ObjectData[i] = blocks[i]; | ||
4212 | // If any of the packets created from this call go unacknowledged, all of the updates will be resent | ||
4213 | OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); }); | ||
4214 | } | 4501 | } |
4215 | 4502 | } | |
4216 | if (compressedUpdateBlocks.IsValueCreated) | 4503 | #endregion |
4504 | } | ||
4505 | |||
4506 | // hack.. dont use | ||
4507 | /* | ||
4508 | public void SendPartFullUpdate(ISceneEntity ent, uint? parentID) | ||
4509 | { | ||
4510 | if (ent is SceneObjectPart) | ||
4511 | { | ||
4512 | SceneObjectPart part = (SceneObjectPart)ent; | ||
4513 | ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); | ||
4514 | packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | ||
4515 | packet.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); | ||
4516 | packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | ||
4517 | |||
4518 | ObjectUpdatePacket.ObjectDataBlock blk = CreatePrimUpdateBlock(part, mysp); | ||
4519 | if (parentID.HasValue) | ||
4217 | { | 4520 | { |
4218 | List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; | 4521 | blk.ParentID = parentID.Value; |
4219 | |||
4220 | ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); | ||
4221 | packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | ||
4222 | packet.RegionData.TimeDilation = timeDilation; | ||
4223 | packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count]; | ||
4224 | |||
4225 | for (int i = 0; i < blocks.Count; i++) | ||
4226 | packet.ObjectData[i] = blocks[i]; | ||
4227 | // If any of the packets created from this call go unacknowledged, all of the updates will be resent | ||
4228 | OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); }); | ||
4229 | } | 4522 | } |
4230 | 4523 | ||
4231 | if (terseUpdateBlocks.IsValueCreated) | 4524 | packet.ObjectData[0] = blk; |
4232 | { | ||
4233 | List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; | ||
4234 | |||
4235 | ImprovedTerseObjectUpdatePacket packet | ||
4236 | = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket( | ||
4237 | PacketType.ImprovedTerseObjectUpdate); | ||
4238 | 4525 | ||
4239 | packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | 4526 | OutPacket(packet, ThrottleOutPacketType.Task, true); |
4240 | packet.RegionData.TimeDilation = timeDilation; | ||
4241 | packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; | ||
4242 | |||
4243 | for (int i = 0; i < blocks.Count; i++) | ||
4244 | packet.ObjectData[i] = blocks[i]; | ||
4245 | // If any of the packets created from this call go unacknowledged, all of the updates will be resent | ||
4246 | OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); | ||
4247 | } | ||
4248 | } | 4527 | } |
4249 | 4528 | ||
4250 | // m_log.DebugFormat( | 4529 | // m_log.DebugFormat( |
4251 | // "[LLCLIENTVIEW]: Sent {0} updates in ProcessEntityUpdates() for {1} {2} in {3}", | 4530 | // "[LLCLIENTVIEW]: Sent {0} updates in ProcessEntityUpdates() for {1} {2} in {3}", |
4252 | // updatesThisCall, Name, SceneAgent.IsChildAgent ? "child" : "root", Scene.Name); | 4531 | // updatesThisCall, Name, SceneAgent.IsChildAgent ? "child" : "root", Scene.Name); |
4253 | // | 4532 | // |
4254 | #endregion Packet Sending | ||
4255 | } | 4533 | } |
4256 | 4534 | */ | |
4257 | public void ReprioritizeUpdates() | 4535 | public void ReprioritizeUpdates() |
4258 | { | 4536 | { |
4259 | lock (m_entityUpdates.SyncRoot) | 4537 | lock (m_entityUpdates.SyncRoot) |
4260 | m_entityUpdates.Reprioritize(UpdatePriorityHandler); | 4538 | m_entityUpdates.Reprioritize(UpdatePriorityHandler); |
4539 | CheckGroupsInView(); | ||
4540 | } | ||
4541 | |||
4542 | private bool CheckGroupsInViewBusy = false; | ||
4543 | |||
4544 | public void CheckGroupsInView() | ||
4545 | { | ||
4546 | bool doCulling = m_scene.ObjectsCullingByDistance; | ||
4547 | if(!doCulling) | ||
4548 | return; | ||
4549 | |||
4550 | if(CheckGroupsInViewBusy) | ||
4551 | return; | ||
4552 | |||
4553 | CheckGroupsInViewBusy = true; | ||
4554 | |||
4555 | float cullingrange = 64.0f; | ||
4556 | // Vector3 mycamera = Vector3.Zero; | ||
4557 | Vector3 mypos = Vector3.Zero; | ||
4558 | ScenePresence mysp = (ScenePresence)SceneAgent; | ||
4559 | if(mysp != null && !mysp.IsDeleted) | ||
4560 | { | ||
4561 | cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f; | ||
4562 | // mycamera = mysp.CameraPosition; | ||
4563 | mypos = mysp.AbsolutePosition; | ||
4564 | } | ||
4565 | else | ||
4566 | { | ||
4567 | CheckGroupsInViewBusy= false; | ||
4568 | return; | ||
4569 | } | ||
4570 | |||
4571 | HashSet<SceneObjectGroup> NewGroupsInView = new HashSet<SceneObjectGroup>(); | ||
4572 | HashSet<SceneObjectGroup> GroupsNeedFullUpdate = new HashSet<SceneObjectGroup>(); | ||
4573 | List<SceneObjectGroup> kills = new List<SceneObjectGroup>(); | ||
4574 | |||
4575 | EntityBase[] entities = m_scene.Entities.GetEntities(); | ||
4576 | foreach (EntityBase e in entities) | ||
4577 | { | ||
4578 | if(!IsActive) | ||
4579 | return; | ||
4580 | |||
4581 | if (e != null && e is SceneObjectGroup) | ||
4582 | { | ||
4583 | SceneObjectGroup grp = (SceneObjectGroup)e; | ||
4584 | if(grp.IsDeleted || grp.IsAttachment) | ||
4585 | continue; | ||
4586 | |||
4587 | float bradius = grp.GetBoundsRadius(); | ||
4588 | Vector3 grppos = grp.AbsolutePosition + grp.getBoundsCenter(); | ||
4589 | // float dcam = (grppos - mycamera).LengthSquared(); | ||
4590 | float dpos = (grppos - mypos).LengthSquared(); | ||
4591 | // if(dcam < dpos) | ||
4592 | // dpos = dcam; | ||
4593 | |||
4594 | dpos = (float)Math.Sqrt(dpos) - bradius; | ||
4595 | |||
4596 | bool inview; | ||
4597 | lock(GroupsInView) | ||
4598 | inview = GroupsInView.Contains(grp); | ||
4599 | |||
4600 | if(dpos > cullingrange) | ||
4601 | { | ||
4602 | if(inview) | ||
4603 | kills.Add(grp); | ||
4604 | } | ||
4605 | else | ||
4606 | { | ||
4607 | if(!inview) | ||
4608 | GroupsNeedFullUpdate.Add(grp); | ||
4609 | NewGroupsInView.Add(grp); | ||
4610 | } | ||
4611 | } | ||
4612 | } | ||
4613 | |||
4614 | lock(GroupsInView) | ||
4615 | GroupsInView = NewGroupsInView; | ||
4616 | |||
4617 | if (kills.Count > 0) | ||
4618 | { | ||
4619 | List<uint> partIDs = new List<uint>(); | ||
4620 | foreach(SceneObjectGroup grp in kills) | ||
4621 | { | ||
4622 | SendEntityUpdate(grp.RootPart,PrimUpdateFlags.Kill); | ||
4623 | foreach(SceneObjectPart p in grp.Parts) | ||
4624 | { | ||
4625 | if(p != grp.RootPart) | ||
4626 | partIDs.Add(p.LocalId); | ||
4627 | } | ||
4628 | } | ||
4629 | kills.Clear(); | ||
4630 | if(partIDs.Count > 0) | ||
4631 | { | ||
4632 | lock (m_entityProps.SyncRoot) | ||
4633 | m_entityProps.Remove(partIDs); | ||
4634 | lock (m_entityUpdates.SyncRoot) | ||
4635 | m_entityUpdates.Remove(partIDs); | ||
4636 | } | ||
4637 | } | ||
4638 | |||
4639 | if(GroupsNeedFullUpdate.Count > 0) | ||
4640 | { | ||
4641 | foreach(SceneObjectGroup grp in GroupsNeedFullUpdate) | ||
4642 | { | ||
4643 | foreach(SceneObjectPart p in grp.Parts) | ||
4644 | SendEntityUpdate(p,PrimUpdateFlags.CancelKill); | ||
4645 | } | ||
4646 | } | ||
4647 | |||
4648 | CheckGroupsInViewBusy = false; | ||
4261 | } | 4649 | } |
4262 | 4650 | ||
4263 | private bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity) | 4651 | private bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity) |
@@ -4285,63 +4673,46 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4285 | // of updates converted to packets. Since we don't want packets | 4673 | // of updates converted to packets. Since we don't want packets |
4286 | // to sit in the queue with old data, only convert enough updates | 4674 | // to sit in the queue with old data, only convert enough updates |
4287 | // to packets that can be sent in 200ms. | 4675 | // to packets that can be sent in 200ms. |
4288 | private Int32 m_LastQueueFill = 0; | 4676 | // private Int32 m_LastQueueFill = 0; |
4289 | private Int32 m_maxUpdates = 0; | 4677 | // private Int32 m_maxUpdates = 0; |
4290 | 4678 | ||
4291 | void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) | 4679 | void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) |
4292 | { | 4680 | { |
4293 | // if (!m_udpServer.IsRunningOutbound) | 4681 | if(m_scene == null) |
4294 | // return; | 4682 | return; |
4295 | 4683 | ||
4296 | if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) | 4684 | if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) |
4297 | { | 4685 | { |
4298 | // if (!m_udpServer.IsRunningOutbound) | 4686 | int maxUpdateBytes = m_udpClient.GetCatBytesCanSend(ThrottleOutPacketType.Task, 30); |
4299 | // return; | ||
4300 | 4687 | ||
4301 | if (m_maxUpdates == 0 || m_LastQueueFill == 0) | ||
4302 | { | ||
4303 | m_maxUpdates = m_udpServer.PrimUpdatesPerCallback; | ||
4304 | } | ||
4305 | else | ||
4306 | { | ||
4307 | if (Util.EnvironmentTickCountSubtract(m_LastQueueFill) < 200) | ||
4308 | m_maxUpdates += 5; | ||
4309 | else | ||
4310 | m_maxUpdates = m_maxUpdates >> 1; | ||
4311 | } | ||
4312 | m_maxUpdates = Util.Clamp<Int32>(m_maxUpdates,10,500); | ||
4313 | m_LastQueueFill = Util.EnvironmentTickCount(); | ||
4314 | |||
4315 | if (m_entityUpdates.Count > 0) | 4688 | if (m_entityUpdates.Count > 0) |
4316 | ProcessEntityUpdates(m_maxUpdates); | 4689 | ProcessEntityUpdates(maxUpdateBytes); |
4317 | 4690 | ||
4318 | if (m_entityProps.Count > 0) | 4691 | if (m_entityProps.Count > 0) |
4319 | ProcessEntityPropertyRequests(m_maxUpdates); | 4692 | ProcessEntityPropertyRequests(maxUpdateBytes); |
4320 | } | 4693 | } |
4321 | 4694 | ||
4322 | if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) | 4695 | if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) |
4323 | ImageManager.ProcessImageQueue(m_udpServer.TextureSendLimit); | 4696 | ImageManager.ProcessImageQueue(m_udpServer.TextureSendLimit); |
4324 | } | 4697 | } |
4325 | 4698 | ||
4326 | internal bool HandleHasUpdates(ThrottleOutPacketTypeFlags categories) | 4699 | internal bool HandleHasUpdates(ThrottleOutPacketTypeFlags categories) |
4327 | { | 4700 | { |
4328 | bool hasUpdates = false; | ||
4329 | |||
4330 | if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) | 4701 | if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) |
4331 | { | 4702 | { |
4332 | if (m_entityUpdates.Count > 0) | 4703 | if (m_entityUpdates.Count > 0) |
4333 | hasUpdates = true; | 4704 | return true; |
4334 | else if (m_entityProps.Count > 0) | 4705 | if (m_entityProps.Count > 0) |
4335 | hasUpdates = true; | 4706 | return true; |
4336 | } | 4707 | } |
4337 | 4708 | ||
4338 | if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) | 4709 | if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) |
4339 | { | 4710 | { |
4340 | if (ImageManager.HasUpdates()) | 4711 | if (ImageManager.HasUpdates()) |
4341 | hasUpdates = true; | 4712 | return true; |
4342 | } | 4713 | } |
4343 | 4714 | ||
4344 | return hasUpdates; | 4715 | return false; |
4345 | } | 4716 | } |
4346 | 4717 | ||
4347 | public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) | 4718 | public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) |
@@ -4443,13 +4814,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4443 | OutPacket(pack, ThrottleOutPacketType.Task); | 4814 | OutPacket(pack, ThrottleOutPacketType.Task); |
4444 | } | 4815 | } |
4445 | 4816 | ||
4446 | private class ObjectPropertyUpdate : IEntityUpdate | 4817 | private class ObjectPropertyUpdate : EntityUpdate |
4447 | { | 4818 | { |
4448 | internal bool SendFamilyProps; | 4819 | internal bool SendFamilyProps; |
4449 | internal bool SendObjectProps; | 4820 | internal bool SendObjectProps; |
4450 | 4821 | ||
4451 | public ObjectPropertyUpdate(ISceneEntity entity, uint flags, bool sendfam, bool sendobj) | 4822 | public ObjectPropertyUpdate(ISceneEntity entity, uint flags, bool sendfam, bool sendobj) |
4452 | : base(entity,flags) | 4823 | : base(entity,(PrimUpdateFlags)flags) |
4453 | { | 4824 | { |
4454 | SendFamilyProps = sendfam; | 4825 | SendFamilyProps = sendfam; |
4455 | SendObjectProps = sendobj; | 4826 | SendObjectProps = sendobj; |
@@ -4462,7 +4833,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4462 | base.Update(update); | 4833 | base.Update(update); |
4463 | } | 4834 | } |
4464 | } | 4835 | } |
4465 | 4836 | ||
4466 | public void SendObjectPropertiesFamilyData(ISceneEntity entity, uint requestFlags) | 4837 | public void SendObjectPropertiesFamilyData(ISceneEntity entity, uint requestFlags) |
4467 | { | 4838 | { |
4468 | uint priority = 0; // time based ordering only | 4839 | uint priority = 0; // time based ordering only |
@@ -4496,7 +4867,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4496 | foreach (ObjectPropertyUpdate update in updates) | 4867 | foreach (ObjectPropertyUpdate update in updates) |
4497 | ResendPropertyUpdate(update); | 4868 | ResendPropertyUpdate(update); |
4498 | } | 4869 | } |
4499 | 4870 | ||
4500 | public void SendObjectPropertiesReply(ISceneEntity entity) | 4871 | public void SendObjectPropertiesReply(ISceneEntity entity) |
4501 | { | 4872 | { |
4502 | uint priority = 0; // time based ordering only | 4873 | uint priority = 0; // time based ordering only |
@@ -4504,29 +4875,40 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4504 | m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,0,false,true)); | 4875 | m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,0,false,true)); |
4505 | } | 4876 | } |
4506 | 4877 | ||
4507 | private void ProcessEntityPropertyRequests(int maxUpdates) | 4878 | List<ObjectPropertiesFamilyPacket.ObjectDataBlock> objectFamilyBlocks = new |
4879 | List<ObjectPropertiesFamilyPacket.ObjectDataBlock>(); | ||
4880 | List<ObjectPropertiesPacket.ObjectDataBlock> objectPropertiesBlocks = | ||
4881 | new List<ObjectPropertiesPacket.ObjectDataBlock>(); | ||
4882 | List<SceneObjectPart> needPhysics = new List<SceneObjectPart>(); | ||
4883 | |||
4884 | private void ProcessEntityPropertyRequests(int maxUpdateBytes) | ||
4508 | { | 4885 | { |
4509 | OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>> objectFamilyBlocks = | 4886 | // OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> familyUpdates = |
4510 | new OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>>(); | 4887 | // new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>(); |
4511 | 4888 | ||
4512 | OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>> objectPropertiesBlocks = | 4889 | // OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> propertyUpdates = |
4513 | new OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>>(); | 4890 | // new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>(); |
4514 | 4891 | ||
4515 | OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> familyUpdates = | 4892 | bool orderedDequeue = m_scene.UpdatePrioritizationScheme == UpdatePrioritizationSchemes.SimpleAngularDistance; |
4516 | new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>(); | ||
4517 | 4893 | ||
4518 | OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> propertyUpdates = | 4894 | EntityUpdate iupdate; |
4519 | new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>(); | ||
4520 | |||
4521 | IEntityUpdate iupdate; | ||
4522 | Int32 timeinqueue; // this is just debugging code & can be dropped later | 4895 | Int32 timeinqueue; // this is just debugging code & can be dropped later |
4523 | 4896 | ||
4524 | int updatesThisCall = 0; | 4897 | while (maxUpdateBytes > 0) |
4525 | while (updatesThisCall < m_maxUpdates) | ||
4526 | { | 4898 | { |
4527 | lock (m_entityProps.SyncRoot) | 4899 | lock (m_entityProps.SyncRoot) |
4528 | if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue)) | 4900 | { |
4529 | break; | 4901 | if(orderedDequeue) |
4902 | { | ||
4903 | if (!m_entityProps.TryOrderedDequeue(out iupdate, out timeinqueue)) | ||
4904 | break; | ||
4905 | } | ||
4906 | else | ||
4907 | { | ||
4908 | if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue)) | ||
4909 | break; | ||
4910 | } | ||
4911 | } | ||
4530 | 4912 | ||
4531 | ObjectPropertyUpdate update = (ObjectPropertyUpdate)iupdate; | 4913 | ObjectPropertyUpdate update = (ObjectPropertyUpdate)iupdate; |
4532 | if (update.SendFamilyProps) | 4914 | if (update.SendFamilyProps) |
@@ -4535,8 +4917,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4535 | { | 4917 | { |
4536 | SceneObjectPart sop = (SceneObjectPart)update.Entity; | 4918 | SceneObjectPart sop = (SceneObjectPart)update.Entity; |
4537 | ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags); | 4919 | ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags); |
4538 | objectFamilyBlocks.Value.Add(objPropDB); | 4920 | objectFamilyBlocks.Add(objPropDB); |
4539 | familyUpdates.Value.Add(update); | 4921 | // familyUpdates.Value.Add(update); |
4922 | maxUpdateBytes -= objPropDB.Length; | ||
4540 | } | 4923 | } |
4541 | } | 4924 | } |
4542 | 4925 | ||
@@ -4545,84 +4928,107 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4545 | if (update.Entity is SceneObjectPart) | 4928 | if (update.Entity is SceneObjectPart) |
4546 | { | 4929 | { |
4547 | SceneObjectPart sop = (SceneObjectPart)update.Entity; | 4930 | SceneObjectPart sop = (SceneObjectPart)update.Entity; |
4931 | needPhysics.Add(sop); | ||
4548 | ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop); | 4932 | ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop); |
4549 | objectPropertiesBlocks.Value.Add(objPropDB); | 4933 | objectPropertiesBlocks.Add(objPropDB); |
4550 | propertyUpdates.Value.Add(update); | 4934 | // propertyUpdates.Value.Add(update); |
4935 | maxUpdateBytes -= objPropDB.Length; | ||
4551 | } | 4936 | } |
4552 | } | 4937 | } |
4553 | |||
4554 | updatesThisCall++; | ||
4555 | } | 4938 | } |
4556 | |||
4557 | 4939 | ||
4558 | // Int32 ppcnt = 0; | 4940 | if (objectPropertiesBlocks.Count > 0) |
4559 | // Int32 pbcnt = 0; | ||
4560 | |||
4561 | if (objectPropertiesBlocks.IsValueCreated) | ||
4562 | { | 4941 | { |
4563 | List<ObjectPropertiesPacket.ObjectDataBlock> blocks = objectPropertiesBlocks.Value; | ||
4564 | List<ObjectPropertyUpdate> updates = propertyUpdates.Value; | ||
4565 | |||
4566 | ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); | 4942 | ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); |
4567 | packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[blocks.Count]; | 4943 | packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[objectPropertiesBlocks.Count]; |
4568 | for (int i = 0; i < blocks.Count; i++) | 4944 | for (int i = 0; i < objectPropertiesBlocks.Count; i++) |
4569 | packet.ObjectData[i] = blocks[i]; | 4945 | packet.ObjectData[i] = objectPropertiesBlocks[i]; |
4570 | 4946 | ||
4947 | |||
4948 | objectPropertiesBlocks.Clear(); | ||
4571 | packet.Header.Zerocoded = true; | 4949 | packet.Header.Zerocoded = true; |
4572 | 4950 | ||
4573 | // Pass in the delegate so that if this packet needs to be resent, we send the current properties | 4951 | // Pass in the delegate so that if this packet needs to be resent, we send the current properties |
4574 | // of the object rather than the properties when the packet was created | 4952 | // of the object rather than the properties when the packet was created |
4575 | OutPacket(packet, ThrottleOutPacketType.Task, true, | 4953 | // HACK : Remove intelligent resending until it's fixed in core |
4576 | delegate(OutgoingPacket oPacket) | 4954 | //OutPacket(packet, ThrottleOutPacketType.Task, true, |
4577 | { | 4955 | // delegate(OutgoingPacket oPacket) |
4578 | ResendPropertyUpdates(updates, oPacket); | 4956 | // { |
4579 | }); | 4957 | // ResendPropertyUpdates(propertyUpdates.Value, oPacket); |
4958 | // }); | ||
4959 | OutPacket(packet, ThrottleOutPacketType.Task, true); | ||
4580 | 4960 | ||
4581 | // pbcnt += blocks.Count; | 4961 | // pbcnt += blocks.Count; |
4582 | // ppcnt++; | 4962 | // ppcnt++; |
4583 | } | 4963 | } |
4584 | 4964 | ||
4585 | // Int32 fpcnt = 0; | 4965 | // Int32 fpcnt = 0; |
4586 | // Int32 fbcnt = 0; | 4966 | // Int32 fbcnt = 0; |
4587 | 4967 | ||
4588 | if (objectFamilyBlocks.IsValueCreated) | 4968 | if (objectFamilyBlocks.Count > 0) |
4589 | { | 4969 | { |
4590 | List<ObjectPropertiesFamilyPacket.ObjectDataBlock> blocks = objectFamilyBlocks.Value; | ||
4591 | |||
4592 | // one packet per object block... uggh... | 4970 | // one packet per object block... uggh... |
4593 | for (int i = 0; i < blocks.Count; i++) | 4971 | for (int i = 0; i < objectFamilyBlocks.Count; i++) |
4594 | { | 4972 | { |
4595 | ObjectPropertiesFamilyPacket packet = | 4973 | ObjectPropertiesFamilyPacket packet = |
4596 | (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily); | 4974 | (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily); |
4597 | 4975 | ||
4598 | packet.ObjectData = blocks[i]; | 4976 | packet.ObjectData = objectFamilyBlocks[i]; |
4599 | packet.Header.Zerocoded = true; | 4977 | packet.Header.Zerocoded = true; |
4600 | 4978 | ||
4601 | // Pass in the delegate so that if this packet needs to be resent, we send the current properties | 4979 | // Pass in the delegate so that if this packet needs to be resent, we send the current properties |
4602 | // of the object rather than the properties when the packet was created | 4980 | // of the object rather than the properties when the packet was created |
4603 | List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); | 4981 | // List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); |
4604 | updates.Add(familyUpdates.Value[i]); | 4982 | // updates.Add(familyUpdates.Value[i]); |
4605 | OutPacket(packet, ThrottleOutPacketType.Task, true, | 4983 | // HACK : Remove intelligent resending until it's fixed in core |
4606 | delegate(OutgoingPacket oPacket) | 4984 | //OutPacket(packet, ThrottleOutPacketType.Task, true, |
4607 | { | 4985 | // delegate(OutgoingPacket oPacket) |
4608 | ResendPropertyUpdates(updates, oPacket); | 4986 | // { |
4609 | }); | 4987 | // ResendPropertyUpdates(updates, oPacket); |
4988 | // }); | ||
4989 | OutPacket(packet, ThrottleOutPacketType.Task, true); | ||
4610 | 4990 | ||
4611 | // fpcnt++; | 4991 | // fpcnt++; |
4612 | // fbcnt++; | 4992 | // fbcnt++; |
4613 | } | 4993 | } |
4614 | 4994 | objectFamilyBlocks.Clear(); | |
4995 | } | ||
4996 | |||
4997 | if(needPhysics.Count > 0) | ||
4998 | { | ||
4999 | IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>(); | ||
5000 | if(eq != null) | ||
5001 | { | ||
5002 | OSDArray array = new OSDArray(); | ||
5003 | foreach(SceneObjectPart sop in needPhysics) | ||
5004 | { | ||
5005 | OSDMap physinfo = new OSDMap(6); | ||
5006 | physinfo["LocalID"] = sop.LocalId; | ||
5007 | physinfo["Density"] = sop.Density; | ||
5008 | physinfo["Friction"] = sop.Friction; | ||
5009 | physinfo["GravityMultiplier"] = sop.GravityModifier; | ||
5010 | physinfo["Restitution"] = sop.Restitution; | ||
5011 | physinfo["PhysicsShapeType"] = (int)sop.PhysicsShapeType; | ||
5012 | array.Add(physinfo); | ||
5013 | } | ||
5014 | |||
5015 | OSDMap llsdBody = new OSDMap(1); | ||
5016 | llsdBody.Add("ObjectData", array); | ||
5017 | |||
5018 | eq.Enqueue(BuildEvent("ObjectPhysicsProperties", llsdBody),AgentId); | ||
5019 | } | ||
5020 | needPhysics.Clear(); | ||
4615 | } | 5021 | } |
4616 | 5022 | ||
4617 | // m_log.WarnFormat("[PACKETCOUNTS] queued {0} property packets with {1} blocks",ppcnt,pbcnt); | 5023 | // m_log.WarnFormat("[PACKETCOUNTS] queued {0} property packets with {1} blocks",ppcnt,pbcnt); |
4618 | // m_log.WarnFormat("[PACKETCOUNTS] queued {0} family property packets with {1} blocks",fpcnt,fbcnt); | 5024 | // m_log.WarnFormat("[PACKETCOUNTS] queued {0} family property packets with {1} blocks",fpcnt,fbcnt); |
4619 | } | 5025 | } |
4620 | 5026 | ||
4621 | private ObjectPropertiesFamilyPacket.ObjectDataBlock CreateObjectPropertiesFamilyBlock(SceneObjectPart sop, uint requestFlags) | 5027 | private ObjectPropertiesFamilyPacket.ObjectDataBlock CreateObjectPropertiesFamilyBlock(SceneObjectPart sop, PrimUpdateFlags requestFlags) |
4622 | { | 5028 | { |
4623 | ObjectPropertiesFamilyPacket.ObjectDataBlock block = new ObjectPropertiesFamilyPacket.ObjectDataBlock(); | 5029 | ObjectPropertiesFamilyPacket.ObjectDataBlock block = new ObjectPropertiesFamilyPacket.ObjectDataBlock(); |
4624 | 5030 | ||
4625 | block.RequestFlags = requestFlags; | 5031 | block.RequestFlags = (uint)requestFlags; |
4626 | block.ObjectID = sop.UUID; | 5032 | block.ObjectID = sop.UUID; |
4627 | if (sop.OwnerID == sop.GroupID) | 5033 | if (sop.OwnerID == sop.GroupID) |
4628 | block.OwnerID = UUID.Zero; | 5034 | block.OwnerID = UUID.Zero; |
@@ -4640,13 +5046,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4640 | block.SaleType = sop.ObjectSaleType; | 5046 | block.SaleType = sop.ObjectSaleType; |
4641 | block.SalePrice = sop.SalePrice; | 5047 | block.SalePrice = sop.SalePrice; |
4642 | block.Category = sop.Category; | 5048 | block.Category = sop.Category; |
4643 | block.LastOwnerID = sop.CreatorID; // copied from old SOG call... is this right? | 5049 | block.LastOwnerID = sop.LastOwnerID; |
4644 | block.Name = Util.StringToBytes256(sop.Name); | 5050 | block.Name = Util.StringToBytes256(sop.Name); |
4645 | block.Description = Util.StringToBytes256(sop.Description); | 5051 | block.Description = Util.StringToBytes256(sop.Description); |
4646 | 5052 | ||
4647 | return block; | 5053 | return block; |
4648 | } | 5054 | } |
4649 | 5055 | ||
4650 | private ObjectPropertiesPacket.ObjectDataBlock CreateObjectPropertiesBlock(SceneObjectPart sop) | 5056 | private ObjectPropertiesPacket.ObjectDataBlock CreateObjectPropertiesBlock(SceneObjectPart sop) |
4651 | { | 5057 | { |
4652 | //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); | 5058 | //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); |
@@ -4672,7 +5078,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4672 | block.FolderID = UUID.Zero; // sog.FromFolderID ?? | 5078 | block.FolderID = UUID.Zero; // sog.FromFolderID ?? |
4673 | block.FromTaskID = UUID.Zero; // ??? | 5079 | block.FromTaskID = UUID.Zero; // ??? |
4674 | block.InventorySerial = (short)sop.InventorySerial; | 5080 | block.InventorySerial = (short)sop.InventorySerial; |
4675 | 5081 | ||
4676 | SceneObjectPart root = sop.ParentGroup.RootPart; | 5082 | SceneObjectPart root = sop.ParentGroup.RootPart; |
4677 | 5083 | ||
4678 | block.TouchName = Util.StringToBytes256(root.TouchName); | 5084 | block.TouchName = Util.StringToBytes256(root.TouchName); |
@@ -4684,7 +5090,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4684 | // { | 5090 | // { |
4685 | // using (BinaryWriter binWriter = new BinaryWriter(memStream)) | 5091 | // using (BinaryWriter binWriter = new BinaryWriter(memStream)) |
4686 | // { | 5092 | // { |
4687 | // for (int i = 0; i < sop.GetNumberOfSides(); i++) | 5093 | // for (int i = 0; i < sop.GetNumberOfSides(); i++) |
4688 | // { | 5094 | // { |
4689 | // Primitive.TextureEntryFace teFace = sop.Shape.Textures.FaceTextures[i]; | 5095 | // Primitive.TextureEntryFace teFace = sop.Shape.Textures.FaceTextures[i]; |
4690 | // | 5096 | // |
@@ -4701,7 +5107,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4701 | // block.TextureID = memStream.ToArray(); | 5107 | // block.TextureID = memStream.ToArray(); |
4702 | // } | 5108 | // } |
4703 | // } | 5109 | // } |
4704 | 5110 | ||
4705 | block.TextureID = new byte[0]; // TextureID ??? | 5111 | block.TextureID = new byte[0]; // TextureID ??? |
4706 | block.SitName = Util.StringToBytes256(root.SitName); | 5112 | block.SitName = Util.StringToBytes256(root.SitName); |
4707 | block.OwnerMask = root.OwnerMask; | 5113 | block.OwnerMask = root.OwnerMask; |
@@ -4728,52 +5134,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4728 | } | 5134 | } |
4729 | 5135 | ||
4730 | public void SendEstateList(UUID invoice, int code, UUID[] Data, uint estateID) | 5136 | public void SendEstateList(UUID invoice, int code, UUID[] Data, uint estateID) |
4731 | |||
4732 | { | 5137 | { |
4733 | EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); | 5138 | int TotalnumberIDs = Data.Length; |
4734 | packet.AgentData.TransactionID = UUID.Random(); | 5139 | int numberIDs; |
4735 | packet.AgentData.AgentID = AgentId; | 5140 | int IDIndex = 0; |
4736 | packet.AgentData.SessionID = SessionId; | ||
4737 | packet.MethodData.Invoice = invoice; | ||
4738 | packet.MethodData.Method = Utils.StringToBytes("setaccess"); | ||
4739 | 5141 | ||
4740 | EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + Data.Length]; | 5142 | do |
4741 | |||
4742 | for (int i = 0; i < (6 + Data.Length); i++) | ||
4743 | { | 5143 | { |
4744 | returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); | 5144 | if(TotalnumberIDs > 63) |
4745 | } | 5145 | numberIDs = 63; |
4746 | int j = 0; | 5146 | else |
5147 | numberIDs = TotalnumberIDs; | ||
4747 | 5148 | ||
4748 | returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; | 5149 | TotalnumberIDs -= numberIDs; |
4749 | returnblock[j].Parameter = Utils.StringToBytes(code.ToString()); j++; | ||
4750 | returnblock[j].Parameter = Utils.StringToBytes("0"); j++; | ||
4751 | returnblock[j].Parameter = Utils.StringToBytes("0"); j++; | ||
4752 | returnblock[j].Parameter = Utils.StringToBytes("0"); j++; | ||
4753 | returnblock[j].Parameter = Utils.StringToBytes("0"); j++; | ||
4754 | 5150 | ||
4755 | j = 2; // Agents | 5151 | EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); |
4756 | if ((code & 2) != 0) | 5152 | packet.AgentData.TransactionID = UUID.Random(); |
4757 | j = 3; // Groups | 5153 | packet.AgentData.AgentID = AgentId; |
4758 | if ((code & 8) != 0) | 5154 | packet.AgentData.SessionID = SessionId; |
4759 | j = 5; // Managers | 5155 | packet.MethodData.Invoice = invoice; |
5156 | packet.MethodData.Method = Utils.StringToBytes("setaccess"); | ||
4760 | 5157 | ||
4761 | returnblock[j].Parameter = Utils.StringToBytes(Data.Length.ToString()); | 5158 | EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + numberIDs]; |
4762 | j = 6; | ||
4763 | 5159 | ||
4764 | for (int i = 0; i < Data.Length; i++) | 5160 | for (int i = 0; i < (6 + numberIDs); i++) |
4765 | { | 5161 | { |
4766 | returnblock[j].Parameter = Data[i].GetBytes(); j++; | 5162 | returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); |
4767 | } | 5163 | } |
4768 | packet.ParamList = returnblock; | 5164 | |
4769 | packet.Header.Reliable = true; | 5165 | returnblock[0].Parameter = Utils.StringToBytes(estateID.ToString()); |
4770 | OutPacket(packet, ThrottleOutPacketType.Task); | 5166 | returnblock[1].Parameter = Utils.StringToBytes(code.ToString()); |
5167 | |||
5168 | if((code & 1) != 0) // allowagents | ||
5169 | returnblock[2].Parameter = Utils.StringToBytes(numberIDs.ToString()); | ||
5170 | else | ||
5171 | returnblock[2].Parameter = Utils.StringToBytes("0"); | ||
5172 | |||
5173 | if((code & 2) != 0) // groups | ||
5174 | returnblock[3].Parameter = Utils.StringToBytes(numberIDs.ToString()); | ||
5175 | else | ||
5176 | returnblock[3].Parameter = Utils.StringToBytes("0"); | ||
5177 | |||
5178 | if((code & 4) != 0) // bans | ||
5179 | returnblock[4].Parameter = Utils.StringToBytes(numberIDs.ToString()); | ||
5180 | else | ||
5181 | returnblock[4].Parameter = Utils.StringToBytes("0"); | ||
5182 | |||
5183 | if((code & 8) != 0) // managers | ||
5184 | returnblock[5].Parameter = Utils.StringToBytes(numberIDs.ToString()); | ||
5185 | else | ||
5186 | returnblock[5].Parameter = Utils.StringToBytes("0"); | ||
5187 | |||
5188 | int j = 6; | ||
5189 | |||
5190 | for (int i = 0; i < numberIDs; i++) | ||
5191 | { | ||
5192 | returnblock[j].Parameter = Data[IDIndex].GetBytes(); | ||
5193 | j++; | ||
5194 | IDIndex++; | ||
5195 | } | ||
5196 | packet.ParamList = returnblock; | ||
5197 | packet.Header.Reliable = true; | ||
5198 | OutPacket(packet, ThrottleOutPacketType.Task); | ||
5199 | } while (TotalnumberIDs > 0); | ||
4771 | } | 5200 | } |
4772 | 5201 | ||
4773 | public void SendBannedUserList(UUID invoice, EstateBan[] bl, uint estateID) | 5202 | public void SendBannedUserList(UUID invoice, EstateBan[] bl, uint estateID) |
4774 | { | 5203 | { |
4775 | List<UUID> BannedUsers = new List<UUID>(); | 5204 | List<UUID> BannedUsers = new List<UUID>(); |
4776 | |||
4777 | for (int i = 0; i < bl.Length; i++) | 5205 | for (int i = 0; i < bl.Length; i++) |
4778 | { | 5206 | { |
4779 | if (bl[i] == null) | 5207 | if (bl[i] == null) |
@@ -4781,44 +5209,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4781 | if (bl[i].BannedUserID == UUID.Zero) | 5209 | if (bl[i].BannedUserID == UUID.Zero) |
4782 | continue; | 5210 | continue; |
4783 | BannedUsers.Add(bl[i].BannedUserID); | 5211 | BannedUsers.Add(bl[i].BannedUserID); |
4784 | |||
4785 | if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0)) | ||
4786 | { | ||
4787 | EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); | ||
4788 | packet.AgentData.TransactionID = UUID.Random(); | ||
4789 | packet.AgentData.AgentID = AgentId; | ||
4790 | packet.AgentData.SessionID = SessionId; | ||
4791 | packet.MethodData.Invoice = invoice; | ||
4792 | packet.MethodData.Method = Utils.StringToBytes("setaccess"); | ||
4793 | |||
4794 | EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; | ||
4795 | |||
4796 | int j; | ||
4797 | for (j = 0; j < (6 + BannedUsers.Count); j++) | ||
4798 | { | ||
4799 | returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock(); | ||
4800 | } | ||
4801 | j = 0; | ||
4802 | |||
4803 | returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; | ||
4804 | returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; | ||
4805 | returnblock[j].Parameter = Utils.StringToBytes("0"); j++; | ||
4806 | returnblock[j].Parameter = Utils.StringToBytes("0"); j++; | ||
4807 | returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; | ||
4808 | returnblock[j].Parameter = Utils.StringToBytes("0"); j++; | ||
4809 | |||
4810 | foreach (UUID banned in BannedUsers) | ||
4811 | { | ||
4812 | returnblock[j].Parameter = banned.GetBytes(); j++; | ||
4813 | } | ||
4814 | packet.ParamList = returnblock; | ||
4815 | packet.Header.Reliable = true; | ||
4816 | OutPacket(packet, ThrottleOutPacketType.Task); | ||
4817 | |||
4818 | BannedUsers.Clear(); | ||
4819 | } | ||
4820 | } | 5212 | } |
4821 | 5213 | SendEstateList(invoice, 4, BannedUsers.ToArray(), estateID); | |
4822 | } | 5214 | } |
4823 | 5215 | ||
4824 | public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) | 5216 | public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) |
@@ -4864,7 +5256,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4864 | public void SendEstateCovenantInformation(UUID covenant) | 5256 | public void SendEstateCovenantInformation(UUID covenant) |
4865 | { | 5257 | { |
4866 | // m_log.DebugFormat("[LLCLIENTVIEW]: Sending estate covenant asset id of {0} to {1}", covenant, Name); | 5258 | // m_log.DebugFormat("[LLCLIENTVIEW]: Sending estate covenant asset id of {0} to {1}", covenant, Name); |
4867 | 5259 | ||
4868 | EstateCovenantReplyPacket einfopack = new EstateCovenantReplyPacket(); | 5260 | EstateCovenantReplyPacket einfopack = new EstateCovenantReplyPacket(); |
4869 | EstateCovenantReplyPacket.DataBlock edata = new EstateCovenantReplyPacket.DataBlock(); | 5261 | EstateCovenantReplyPacket.DataBlock edata = new EstateCovenantReplyPacket.DataBlock(); |
4870 | edata.CovenantID = covenant; | 5262 | edata.CovenantID = covenant; |
@@ -4881,7 +5273,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4881 | { | 5273 | { |
4882 | // m_log.DebugFormat( | 5274 | // m_log.DebugFormat( |
4883 | // "[LLCLIENTVIEW]: Sending detailed estate data to {0} with covenant asset id {1}", Name, covenant); | 5275 | // "[LLCLIENTVIEW]: Sending detailed estate data to {0} with covenant asset id {1}", Name, covenant); |
4884 | 5276 | ||
4885 | EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); | 5277 | EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); |
4886 | packet.MethodData.Invoice = invoice; | 5278 | packet.MethodData.Invoice = invoice; |
4887 | packet.AgentData.TransactionID = UUID.Random(); | 5279 | packet.AgentData.TransactionID = UUID.Random(); |
@@ -4939,17 +5331,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4939 | packet.ParcelData.Data = data; | 5331 | packet.ParcelData.Data = data; |
4940 | packet.ParcelData.SequenceID = sequence_id; | 5332 | packet.ParcelData.SequenceID = sequence_id; |
4941 | packet.Header.Zerocoded = true; | 5333 | packet.Header.Zerocoded = true; |
4942 | OutPacket(packet, ThrottleOutPacketType.Task); | 5334 | // OutPacket(packet, ThrottleOutPacketType.Task); |
5335 | OutPacket(packet, ThrottleOutPacketType.Land); | ||
4943 | } | 5336 | } |
4944 | 5337 | ||
4945 | public void SendLandProperties( | 5338 | public void SendLandProperties( |
4946 | int sequence_id, bool snap_selection, int request_result, ILandObject lo, | 5339 | int sequence_id, bool snap_selection, int request_result, ILandObject lo, |
4947 | float simObjectBonusFactor, int parcelObjectCapacity, int simObjectCapacity, uint regionFlags) | 5340 | float simObjectBonusFactor, int parcelObjectCapacity, int simObjectCapacity, uint regionFlags) |
4948 | { | 5341 | { |
4949 | // m_log.DebugFormat("[LLCLIENTVIEW]: Sending land properties for {0} to {1}", lo.LandData.GlobalID, Name); | 5342 | // m_log.DebugFormat("[LLCLIENTVIEW]: Sending land properties for {0} to {1}", lo.LandData.GlobalID, Name); |
4950 | 5343 | ||
4951 | LandData landData = lo.LandData; | 5344 | LandData landData = lo.LandData; |
4952 | 5345 | ||
4953 | ParcelPropertiesMessage updateMessage = new ParcelPropertiesMessage(); | 5346 | ParcelPropertiesMessage updateMessage = new ParcelPropertiesMessage(); |
4954 | 5347 | ||
4955 | updateMessage.AABBMax = landData.AABBMax; | 5348 | updateMessage.AABBMax = landData.AABBMax; |
@@ -4962,7 +5355,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4962 | updateMessage.Category = landData.Category; | 5355 | updateMessage.Category = landData.Category; |
4963 | updateMessage.ClaimDate = Util.ToDateTime(landData.ClaimDate); | 5356 | updateMessage.ClaimDate = Util.ToDateTime(landData.ClaimDate); |
4964 | updateMessage.ClaimPrice = landData.ClaimPrice; | 5357 | updateMessage.ClaimPrice = landData.ClaimPrice; |
4965 | updateMessage.GroupID = landData.GroupID; | 5358 | updateMessage.GroupID = landData.GroupID; |
4966 | updateMessage.IsGroupOwned = landData.IsGroupOwned; | 5359 | updateMessage.IsGroupOwned = landData.IsGroupOwned; |
4967 | updateMessage.LandingType = (LandingType) landData.LandingType; | 5360 | updateMessage.LandingType = (LandingType) landData.LandingType; |
4968 | updateMessage.LocalID = landData.LocalID; | 5361 | updateMessage.LocalID = landData.LocalID; |
@@ -4983,7 +5376,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4983 | updateMessage.Name = landData.Name; | 5376 | updateMessage.Name = landData.Name; |
4984 | updateMessage.OtherCleanTime = landData.OtherCleanTime; | 5377 | updateMessage.OtherCleanTime = landData.OtherCleanTime; |
4985 | updateMessage.OtherCount = 0; //TODO: Unimplemented | 5378 | updateMessage.OtherCount = 0; //TODO: Unimplemented |
4986 | updateMessage.OwnerID = landData.OwnerID; | 5379 | updateMessage.OwnerID = landData.OwnerID; |
4987 | updateMessage.ParcelFlags = (ParcelFlags) landData.Flags; | 5380 | updateMessage.ParcelFlags = (ParcelFlags) landData.Flags; |
4988 | updateMessage.ParcelPrimBonus = simObjectBonusFactor; | 5381 | updateMessage.ParcelPrimBonus = simObjectBonusFactor; |
4989 | updateMessage.PassHours = landData.PassHours; | 5382 | updateMessage.PassHours = landData.PassHours; |
@@ -4998,20 +5391,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4998 | 5391 | ||
4999 | updateMessage.RentPrice = 0; | 5392 | updateMessage.RentPrice = 0; |
5000 | updateMessage.RequestResult = (ParcelResult) request_result; | 5393 | updateMessage.RequestResult = (ParcelResult) request_result; |
5001 | updateMessage.SalePrice = landData.SalePrice; | 5394 | updateMessage.SalePrice = landData.SalePrice; |
5002 | updateMessage.SelfCount = 0; //TODO: Unimplemented | 5395 | updateMessage.SelfCount = 0; //TODO: Unimplemented |
5003 | updateMessage.SequenceID = sequence_id; | 5396 | updateMessage.SequenceID = sequence_id; |
5004 | 5397 | ||
5005 | if (landData.SimwideArea > 0) | 5398 | if (landData.SimwideArea > 0) |
5006 | { | 5399 | { |
5007 | int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); | 5400 | updateMessage.SimWideMaxPrims = lo.GetSimulatorMaxPrimCount(); |
5008 | updateMessage.SimWideMaxPrims = simulatorCapacity; | ||
5009 | } | 5401 | } |
5010 | else | 5402 | else |
5011 | { | 5403 | { |
5012 | updateMessage.SimWideMaxPrims = 0; | 5404 | updateMessage.SimWideMaxPrims = 0; |
5013 | } | 5405 | } |
5014 | 5406 | ||
5015 | updateMessage.SnapSelection = snap_selection; | 5407 | updateMessage.SnapSelection = snap_selection; |
5016 | updateMessage.SnapshotID = landData.SnapshotID; | 5408 | updateMessage.SnapshotID = landData.SnapshotID; |
5017 | updateMessage.Status = (ParcelStatus) landData.Status; | 5409 | updateMessage.Status = (ParcelStatus) landData.Status; |
@@ -5025,23 +5417,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5025 | updateMessage.MediaLoop = landData.MediaLoop; | 5417 | updateMessage.MediaLoop = landData.MediaLoop; |
5026 | updateMessage.ObscureMusic = landData.ObscureMusic; | 5418 | updateMessage.ObscureMusic = landData.ObscureMusic; |
5027 | updateMessage.ObscureMedia = landData.ObscureMedia; | 5419 | updateMessage.ObscureMedia = landData.ObscureMedia; |
5028 | 5420 | ||
5421 | updateMessage.SeeAVs = landData.SeeAVs; | ||
5422 | updateMessage.AnyAVSounds = landData.AnyAVSounds; | ||
5423 | updateMessage.GroupAVSounds = landData.GroupAVSounds; | ||
5424 | |||
5029 | IPrimCounts pc = lo.PrimCounts; | 5425 | IPrimCounts pc = lo.PrimCounts; |
5030 | updateMessage.OwnerPrims = pc.Owner; | 5426 | updateMessage.OwnerPrims = pc.Owner; |
5031 | updateMessage.GroupPrims = pc.Group; | 5427 | updateMessage.GroupPrims = pc.Group; |
5032 | updateMessage.OtherPrims = pc.Others; | 5428 | updateMessage.OtherPrims = pc.Others; |
5033 | updateMessage.SelectedPrims = pc.Selected; | 5429 | updateMessage.SelectedPrims = pc.Selected; |
5034 | updateMessage.TotalPrims = pc.Total; | 5430 | updateMessage.TotalPrims = pc.Total; |
5035 | updateMessage.SimWideTotalPrims = pc.Simulator; | 5431 | updateMessage.SimWideTotalPrims = pc.Simulator; |
5036 | 5432 | ||
5433 | //m_log.DebugFormat("[YYY]: SimWideMaxPrims={0} OwnerPrims={1} TotalPrims={2} SimWideTotalPrims={3} MaxPrims={4}", | ||
5434 | // updateMessage.SimWideMaxPrims, updateMessage.OwnerPrims, updateMessage.TotalPrims, updateMessage.SimWideTotalPrims, updateMessage.MaxPrims); | ||
5037 | try | 5435 | try |
5038 | { | 5436 | { |
5039 | IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>(); | 5437 | IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>(); |
5040 | if (eq != null) | 5438 | if (eq != null) |
5041 | { | 5439 | { |
5042 | eq.ParcelProperties(updateMessage, this.AgentId); | 5440 | eq.ParcelProperties(updateMessage, this.AgentId); |
5043 | } | 5441 | } |
5044 | else | 5442 | else |
5045 | { | 5443 | { |
5046 | m_log.Warn("[LLCLIENTVIEW]: No EQ Interface when sending parcel data."); | 5444 | m_log.Warn("[LLCLIENTVIEW]: No EQ Interface when sending parcel data."); |
5047 | } | 5445 | } |
@@ -5078,7 +5476,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5078 | public void SendForceClientSelectObjects(List<uint> ObjectIDs) | 5476 | public void SendForceClientSelectObjects(List<uint> ObjectIDs) |
5079 | { | 5477 | { |
5080 | // m_log.DebugFormat("[LLCLIENTVIEW] sending select with {0} objects", ObjectIDs.Count); | 5478 | // m_log.DebugFormat("[LLCLIENTVIEW] sending select with {0} objects", ObjectIDs.Count); |
5081 | 5479 | ||
5082 | bool firstCall = true; | 5480 | bool firstCall = true; |
5083 | const int MAX_OBJECTS_PER_PACKET = 251; | 5481 | const int MAX_OBJECTS_PER_PACKET = 251; |
5084 | ForceObjectSelectPacket pack = (ForceObjectSelectPacket)PacketPool.Instance.GetPacket(PacketType.ForceObjectSelect); | 5482 | ForceObjectSelectPacket pack = (ForceObjectSelectPacket)PacketPool.Instance.GetPacket(PacketType.ForceObjectSelect); |
@@ -5133,14 +5531,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5133 | 5531 | ||
5134 | if (notifyCount > 0) | 5532 | if (notifyCount > 0) |
5135 | { | 5533 | { |
5136 | if (notifyCount > 32) | 5534 | // if (notifyCount > 32) |
5137 | { | 5535 | // { |
5138 | m_log.InfoFormat( | 5536 | // m_log.InfoFormat( |
5139 | "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" | 5537 | // "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" |
5140 | + " - a developer might want to investigate whether this is a hard limit", 32); | 5538 | // + " - a developer might want to investigate whether this is a hard limit", 32); |
5141 | 5539 | // | |
5142 | notifyCount = 32; | 5540 | // notifyCount = 32; |
5143 | } | 5541 | // } |
5144 | 5542 | ||
5145 | ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock | 5543 | ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock |
5146 | = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; | 5544 | = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; |
@@ -5178,6 +5576,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5178 | #endregion | 5576 | #endregion |
5179 | 5577 | ||
5180 | #region Helper Methods | 5578 | #region Helper Methods |
5579 | private void ClampVectorForUint(ref Vector3 v, float max) | ||
5580 | { | ||
5581 | float a,b; | ||
5582 | |||
5583 | a = Math.Abs(v.X); | ||
5584 | b = Math.Abs(v.Y); | ||
5585 | if(b > a) | ||
5586 | a = b; | ||
5587 | b= Math.Abs(v.Z); | ||
5588 | if(b > a) | ||
5589 | a = b; | ||
5590 | |||
5591 | if (a > max) | ||
5592 | { | ||
5593 | a = max / a; | ||
5594 | v.X *= a; | ||
5595 | v.Y *= a; | ||
5596 | v.Z *= a; | ||
5597 | } | ||
5598 | } | ||
5181 | 5599 | ||
5182 | protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(ISceneEntity entity, bool sendTexture) | 5600 | protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(ISceneEntity entity, bool sendTexture) |
5183 | { | 5601 | { |
@@ -5191,45 +5609,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5191 | Quaternion rotation; | 5609 | Quaternion rotation; |
5192 | byte[] textureEntry; | 5610 | byte[] textureEntry; |
5193 | 5611 | ||
5194 | if (entity is ScenePresence) | 5612 | if (avatar) |
5195 | { | 5613 | { |
5196 | ScenePresence presence = (ScenePresence)entity; | 5614 | ScenePresence presence = (ScenePresence)entity; |
5197 | 5615 | ||
5198 | // m_log.DebugFormat( | ||
5199 | // "[LLCLIENTVIEW]: Sending terse update to {0} with pos {1}, vel {2} in {3}", | ||
5200 | // Name, presence.OffsetPosition, presence.Velocity, m_scene.Name); | ||
5201 | |||
5202 | attachPoint = presence.State; | ||
5203 | collisionPlane = presence.CollisionPlane; | ||
5204 | position = presence.OffsetPosition; | 5616 | position = presence.OffsetPosition; |
5205 | velocity = presence.Velocity; | 5617 | velocity = presence.Velocity; |
5206 | acceleration = Vector3.Zero; | 5618 | acceleration = Vector3.Zero; |
5207 | |||
5208 | // Interestingly, sending this to non-zero will cause the client's avatar to start moving & accelerating | ||
5209 | // in that direction, even though we don't model this on the server. Implementing this in the future | ||
5210 | // may improve movement smoothness. | ||
5211 | // acceleration = new Vector3(1, 0, 0); | ||
5212 | |||
5213 | angularVelocity = presence.AngularVelocity; | ||
5214 | |||
5215 | // Whilst not in mouselook, an avatar will transmit only the Z rotation as this is the only axis | ||
5216 | // it rotates around. | ||
5217 | // In mouselook, X and Y co-ordinate will also be sent but when used in Rotation, these cause unwanted | ||
5218 | // excessive up and down movements of the camera when looking up and down. | ||
5219 | // See http://opensimulator.org/mantis/view.php?id=3274 | ||
5220 | // This does not affect head movement, since this is controlled entirely by camera movement rather than | ||
5221 | // body rotation. We still need to transmit X and Y for sitting avatars but mouselook does not change | ||
5222 | // the rotation in this case. | ||
5223 | rotation = presence.Rotation; | 5619 | rotation = presence.Rotation; |
5224 | 5620 | // tpvs can only see rotations around Z in some cases | |
5225 | if (!presence.IsSatOnObject) | 5621 | if(!presence.Flying && !presence.IsSatOnObject) |
5226 | { | 5622 | { |
5227 | rotation.X = 0; | 5623 | rotation.X = 0f; |
5228 | rotation.Y = 0; | 5624 | rotation.Y = 0f; |
5625 | rotation.Normalize(); | ||
5229 | } | 5626 | } |
5627 | angularVelocity = presence.AngularVelocity; | ||
5628 | |||
5629 | // m_log.DebugFormat( | ||
5630 | // "[LLCLIENTVIEW]: Sending terse update to {0} with position {1} in {2}", Name, presence.OffsetPosition, m_scene.Name); | ||
5631 | |||
5632 | attachPoint = presence.State; | ||
5633 | collisionPlane = presence.CollisionPlane; | ||
5230 | 5634 | ||
5231 | if (sendTexture) | 5635 | if (sendTexture) |
5636 | { | ||
5232 | textureEntry = presence.Appearance.Texture.GetBytes(); | 5637 | textureEntry = presence.Appearance.Texture.GetBytes(); |
5638 | } | ||
5233 | else | 5639 | else |
5234 | textureEntry = null; | 5640 | textureEntry = null; |
5235 | } | 5641 | } |
@@ -5287,11 +5693,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5287 | pos += 12; | 5693 | pos += 12; |
5288 | 5694 | ||
5289 | // Velocity | 5695 | // Velocity |
5696 | ClampVectorForUint(ref velocity, 128f); | ||
5290 | Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.X, -128.0f, 128.0f), data, pos); pos += 2; | 5697 | Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.X, -128.0f, 128.0f), data, pos); pos += 2; |
5291 | Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Y, -128.0f, 128.0f), data, pos); pos += 2; | 5698 | Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Y, -128.0f, 128.0f), data, pos); pos += 2; |
5292 | Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Z, -128.0f, 128.0f), data, pos); pos += 2; | 5699 | Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Z, -128.0f, 128.0f), data, pos); pos += 2; |
5293 | 5700 | ||
5294 | // Acceleration | 5701 | // Acceleration |
5702 | ClampVectorForUint(ref acceleration, 64f); | ||
5295 | Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.X, -64.0f, 64.0f), data, pos); pos += 2; | 5703 | Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.X, -64.0f, 64.0f), data, pos); pos += 2; |
5296 | Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Y, -64.0f, 64.0f), data, pos); pos += 2; | 5704 | Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Y, -64.0f, 64.0f), data, pos); pos += 2; |
5297 | Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Z, -64.0f, 64.0f), data, pos); pos += 2; | 5705 | Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Z, -64.0f, 64.0f), data, pos); pos += 2; |
@@ -5303,13 +5711,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5303 | Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.W, -1.0f, 1.0f), data, pos); pos += 2; | 5711 | Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.W, -1.0f, 1.0f), data, pos); pos += 2; |
5304 | 5712 | ||
5305 | // Angular Velocity | 5713 | // Angular Velocity |
5714 | ClampVectorForUint(ref angularVelocity, 64f); | ||
5306 | Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.X, -64.0f, 64.0f), data, pos); pos += 2; | 5715 | Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.X, -64.0f, 64.0f), data, pos); pos += 2; |
5307 | Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2; | 5716 | Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2; |
5308 | Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2; | 5717 | Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2; |
5309 | 5718 | ||
5310 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock block | 5719 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock block |
5311 | = PacketPool.Instance.GetDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | 5720 | = PacketPool.Instance.GetDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); |
5312 | 5721 | ||
5313 | block.Data = data; | 5722 | block.Data = data; |
5314 | 5723 | ||
5315 | if (textureEntry != null && textureEntry.Length > 0) | 5724 | if (textureEntry != null && textureEntry.Length > 0) |
@@ -5333,34 +5742,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5333 | 5742 | ||
5334 | protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) | 5743 | protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) |
5335 | { | 5744 | { |
5745 | Vector3 offsetPosition = data.OffsetPosition; | ||
5746 | Quaternion rotation = data.Rotation; | ||
5747 | uint parentID = data.ParentID; | ||
5748 | |||
5336 | // m_log.DebugFormat( | 5749 | // m_log.DebugFormat( |
5337 | // "[LLCLIENTVIEW]: Sending full update to {0} with pos {1}, vel {2} in {3}", Name, data.OffsetPosition, data.Velocity, m_scene.Name); | 5750 | // "[LLCLIENTVIEW]: Sending full update to {0} with pos {1}, vel {2} in {3}", Name, data.OffsetPosition, data.Velocity, m_scene.Name); |
5338 | 5751 | ||
5339 | byte[] objectData = new byte[76]; | 5752 | byte[] objectData = new byte[76]; |
5340 | 5753 | ||
5341 | data.CollisionPlane.ToBytes(objectData, 0); | 5754 | Vector3 velocity = new Vector3(0, 0, 0); |
5342 | data.OffsetPosition.ToBytes(objectData, 16); | 5755 | Vector3 acceleration = new Vector3(0, 0, 0); |
5343 | data.Velocity.ToBytes(objectData, 28); | 5756 | // tpvs can only see rotations around Z in some cases |
5344 | // data.Acceleration.ToBytes(objectData, 40); | 5757 | if(!data.Flying && !data.IsSatOnObject) |
5345 | |||
5346 | // Whilst not in mouselook, an avatar will transmit only the Z rotation as this is the only axis | ||
5347 | // it rotates around. | ||
5348 | // In mouselook, X and Y co-ordinate will also be sent but when used in Rotation, these cause unwanted | ||
5349 | // excessive up and down movements of the camera when looking up and down. | ||
5350 | // See http://opensimulator.org/mantis/view.php?id=3274 | ||
5351 | // This does not affect head movement, since this is controlled entirely by camera movement rather than | ||
5352 | // body rotation. We still need to transmit X and Y for sitting avatars but mouselook does not change | ||
5353 | // the rotation in this case. | ||
5354 | Quaternion rot = data.Rotation; | ||
5355 | |||
5356 | if (!data.IsSatOnObject) | ||
5357 | { | 5758 | { |
5358 | rot.X = 0; | 5759 | rotation.X = 0f; |
5359 | rot.Y = 0; | 5760 | rotation.Y = 0f; |
5360 | } | 5761 | } |
5762 | rotation.Normalize(); | ||
5361 | 5763 | ||
5362 | rot.ToBytes(objectData, 52); | 5764 | data.CollisionPlane.ToBytes(objectData, 0); |
5363 | //data.AngularVelocity.ToBytes(objectData, 64); | 5765 | offsetPosition.ToBytes(objectData, 16); |
5766 | velocity.ToBytes(objectData, 28); | ||
5767 | acceleration.ToBytes(objectData, 40); | ||
5768 | rotation.ToBytes(objectData, 52); | ||
5769 | data.AngularVelocity.ToBytes(objectData, 64); | ||
5364 | 5770 | ||
5365 | ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); | 5771 | ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); |
5366 | 5772 | ||
@@ -5386,7 +5792,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5386 | update.PCode = (byte)PCode.Avatar; | 5792 | update.PCode = (byte)PCode.Avatar; |
5387 | update.ProfileCurve = 1; | 5793 | update.ProfileCurve = 1; |
5388 | update.PSBlock = Utils.EmptyBytes; | 5794 | update.PSBlock = Utils.EmptyBytes; |
5389 | update.Scale = new Vector3(0.45f, 0.6f, 1.9f); | 5795 | update.Scale = data.Appearance.AvatarSize; |
5796 | // update.Scale.Z -= 0.2f; | ||
5797 | |||
5390 | update.Text = Utils.EmptyBytes; | 5798 | update.Text = Utils.EmptyBytes; |
5391 | update.TextColor = new byte[4]; | 5799 | update.TextColor = new byte[4]; |
5392 | 5800 | ||
@@ -5397,46 +5805,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5397 | update.TextureEntry = Utils.EmptyBytes; | 5805 | update.TextureEntry = Utils.EmptyBytes; |
5398 | // update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; | 5806 | // update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; |
5399 | 5807 | ||
5808 | /* all this flags seem related to prims and not avatars. This allow for wrong viewer side move of a avatar in prim edition mode (anv mantis 854) | ||
5400 | update.UpdateFlags = (uint)( | 5809 | update.UpdateFlags = (uint)( |
5401 | PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | | 5810 | PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | |
5402 | PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | | 5811 | PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | |
5403 | PrimFlags.ObjectOwnerModify); | 5812 | PrimFlags.ObjectOwnerModify); |
5813 | */ | ||
5814 | update.UpdateFlags = 0; | ||
5404 | 5815 | ||
5405 | return update; | 5816 | return update; |
5406 | } | 5817 | } |
5407 | 5818 | ||
5408 | protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID) | 5819 | // protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID) |
5820 | protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart part, ScenePresence sp) | ||
5409 | { | 5821 | { |
5410 | byte[] objectData = new byte[60]; | 5822 | byte[] objectData = new byte[60]; |
5411 | data.RelativePosition.ToBytes(objectData, 0); | 5823 | part.RelativePosition.ToBytes(objectData, 0); |
5412 | data.Velocity.ToBytes(objectData, 12); | 5824 | part.Velocity.ToBytes(objectData, 12); |
5413 | data.Acceleration.ToBytes(objectData, 24); | 5825 | part.Acceleration.ToBytes(objectData, 24); |
5414 | try | 5826 | |
5415 | { | 5827 | Quaternion rotation = part.RotationOffset; |
5416 | data.RotationOffset.ToBytes(objectData, 36); | 5828 | rotation.Normalize(); |
5417 | } | 5829 | rotation.ToBytes(objectData, 36); |
5418 | catch (Exception e) | 5830 | part.AngularVelocity.ToBytes(objectData, 48); |
5419 | { | ||
5420 | m_log.Warn("[LLClientView]: exception converting quaternion to bytes, using Quaternion.Identity. Exception: " + e.ToString()); | ||
5421 | OpenMetaverse.Quaternion.Identity.ToBytes(objectData, 36); | ||
5422 | } | ||
5423 | data.AngularVelocity.ToBytes(objectData, 48); | ||
5424 | 5831 | ||
5425 | ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); | 5832 | ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); |
5426 | update.ClickAction = (byte)data.ClickAction; | 5833 | update.ClickAction = (byte)part.ClickAction; |
5427 | update.CRC = 0; | 5834 | update.CRC = 0; |
5428 | update.ExtraParams = data.Shape.ExtraParams ?? Utils.EmptyBytes; | 5835 | update.ExtraParams = part.Shape.ExtraParams ?? Utils.EmptyBytes; |
5429 | update.FullID = data.UUID; | 5836 | update.FullID = part.UUID; |
5430 | update.ID = data.LocalId; | 5837 | update.ID = part.LocalId; |
5431 | //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated | 5838 | //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated |
5432 | //update.JointPivot = Vector3.Zero; | 5839 | //update.JointPivot = Vector3.Zero; |
5433 | //update.JointType = 0; | 5840 | //update.JointType = 0; |
5434 | update.Material = data.Material; | 5841 | update.Material = part.Material; |
5435 | update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim | 5842 | /* |
5436 | |||
5437 | if (data.ParentGroup.IsAttachment) | 5843 | if (data.ParentGroup.IsAttachment) |
5438 | { | 5844 | { |
5439 | update.NameValue | 5845 | update.NameValue |
5440 | = Util.StringToBytes256( | 5846 | = Util.StringToBytes256( |
5441 | string.Format("AttachItemID STRING RW SV {0}", data.ParentGroup.FromItemID)); | 5847 | string.Format("AttachItemID STRING RW SV {0}", data.ParentGroup.FromItemID)); |
5442 | 5848 | ||
@@ -5458,50 +5864,91 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5458 | // case for attachments may contain conflicting values that can end up crashing the viewer. | 5864 | // case for attachments may contain conflicting values that can end up crashing the viewer. |
5459 | update.State = data.ParentGroup.RootPart.Shape.State; | 5865 | update.State = data.ParentGroup.RootPart.Shape.State; |
5460 | } | 5866 | } |
5867 | */ | ||
5868 | |||
5869 | if (part.ParentGroup.IsAttachment) | ||
5870 | { | ||
5871 | if (part.IsRoot) | ||
5872 | { | ||
5873 | update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + part.ParentGroup.FromItemID); | ||
5874 | } | ||
5875 | else | ||
5876 | update.NameValue = Utils.EmptyBytes; | ||
5877 | |||
5878 | int st = (int)part.ParentGroup.AttachmentPoint; | ||
5879 | update.State = (byte)(((st & 0xf0) >> 4) + ((st & 0x0f) << 4)); ; | ||
5880 | } | ||
5881 | else | ||
5882 | { | ||
5883 | update.NameValue = Utils.EmptyBytes; | ||
5884 | update.State = part.Shape.State; // not sure about this | ||
5885 | } | ||
5461 | 5886 | ||
5462 | update.ObjectData = objectData; | 5887 | update.ObjectData = objectData; |
5463 | update.ParentID = data.ParentID; | 5888 | update.ParentID = part.ParentID; |
5464 | update.PathBegin = data.Shape.PathBegin; | 5889 | update.PathBegin = part.Shape.PathBegin; |
5465 | update.PathCurve = data.Shape.PathCurve; | 5890 | update.PathCurve = part.Shape.PathCurve; |
5466 | update.PathEnd = data.Shape.PathEnd; | 5891 | update.PathEnd = part.Shape.PathEnd; |
5467 | update.PathRadiusOffset = data.Shape.PathRadiusOffset; | 5892 | update.PathRadiusOffset = part.Shape.PathRadiusOffset; |
5468 | update.PathRevolutions = data.Shape.PathRevolutions; | 5893 | update.PathRevolutions = part.Shape.PathRevolutions; |
5469 | update.PathScaleX = data.Shape.PathScaleX; | 5894 | update.PathScaleX = part.Shape.PathScaleX; |
5470 | update.PathScaleY = data.Shape.PathScaleY; | 5895 | update.PathScaleY = part.Shape.PathScaleY; |
5471 | update.PathShearX = data.Shape.PathShearX; | 5896 | update.PathShearX = part.Shape.PathShearX; |
5472 | update.PathShearY = data.Shape.PathShearY; | 5897 | update.PathShearY = part.Shape.PathShearY; |
5473 | update.PathSkew = data.Shape.PathSkew; | 5898 | update.PathSkew = part.Shape.PathSkew; |
5474 | update.PathTaperX = data.Shape.PathTaperX; | 5899 | update.PathTaperX = part.Shape.PathTaperX; |
5475 | update.PathTaperY = data.Shape.PathTaperY; | 5900 | update.PathTaperY = part.Shape.PathTaperY; |
5476 | update.PathTwist = data.Shape.PathTwist; | 5901 | update.PathTwist = part.Shape.PathTwist; |
5477 | update.PathTwistBegin = data.Shape.PathTwistBegin; | 5902 | update.PathTwistBegin = part.Shape.PathTwistBegin; |
5478 | update.PCode = data.Shape.PCode; | 5903 | update.PCode = part.Shape.PCode; |
5479 | update.ProfileBegin = data.Shape.ProfileBegin; | 5904 | update.ProfileBegin = part.Shape.ProfileBegin; |
5480 | update.ProfileCurve = data.Shape.ProfileCurve; | 5905 | update.ProfileCurve = part.Shape.ProfileCurve; |
5481 | update.ProfileEnd = data.Shape.ProfileEnd; | 5906 | |
5482 | update.ProfileHollow = data.Shape.ProfileHollow; | 5907 | ushort profileBegin = part.Shape.ProfileBegin; |
5483 | update.PSBlock = data.ParticleSystem ?? Utils.EmptyBytes; | 5908 | ushort profileHollow = part.Shape.ProfileHollow; |
5484 | update.TextColor = data.GetTextColor().GetBytes(false); | 5909 | |
5485 | update.TextureAnim = data.TextureAnimation ?? Utils.EmptyBytes; | 5910 | if(part.Shape.SculptType == (byte)SculptType.Mesh) // filter out hack |
5486 | update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes; | 5911 | { |
5487 | update.Scale = data.Shape.Scale; | 5912 | update.ProfileCurve = (byte)(part.Shape.ProfileCurve & 0x0f); |
5488 | update.Text = Util.StringToBytes256(data.Text); | 5913 | // fix old values that confused viewers |
5489 | update.MediaURL = Util.StringToBytes256(data.MediaUrl); | 5914 | if(profileBegin == 1) |
5915 | profileBegin = 9375; | ||
5916 | if(profileHollow == 1) | ||
5917 | profileHollow = 27500; | ||
5918 | // fix torus hole size Y that also confuse some viewers | ||
5919 | if(update.ProfileCurve == (byte)ProfileShape.Circle && update.PathScaleY < 150) | ||
5920 | update.PathScaleY = 150; | ||
5921 | } | ||
5922 | else | ||
5923 | { | ||
5924 | update.ProfileCurve = part.Shape.ProfileCurve; | ||
5925 | } | ||
5926 | |||
5927 | update.ProfileHollow = profileHollow; | ||
5928 | update.ProfileBegin = profileBegin; | ||
5929 | update.ProfileEnd = part.Shape.ProfileEnd; | ||
5930 | update.PSBlock = part.ParticleSystem ?? Utils.EmptyBytes; | ||
5931 | update.TextColor = part.GetTextColor().GetBytes(false); | ||
5932 | update.TextureAnim = part.TextureAnimation ?? Utils.EmptyBytes; | ||
5933 | update.TextureEntry = part.Shape.TextureEntry ?? Utils.EmptyBytes; | ||
5934 | update.Scale = part.Shape.Scale; | ||
5935 | update.Text = Util.StringToBytes(part.Text, 255); | ||
5936 | update.MediaURL = Util.StringToBytes(part.MediaUrl, 255); | ||
5490 | 5937 | ||
5491 | #region PrimFlags | 5938 | #region PrimFlags |
5492 | 5939 | ||
5493 | PrimFlags flags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(recipientID, data.UUID); | 5940 | PrimFlags flags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(part, sp); |
5494 | 5941 | ||
5495 | // Don't send the CreateSelected flag to everyone | 5942 | // Don't send the CreateSelected flag to everyone |
5496 | flags &= ~PrimFlags.CreateSelected; | 5943 | flags &= ~PrimFlags.CreateSelected; |
5497 | 5944 | ||
5498 | if (recipientID == data.OwnerID) | 5945 | if (sp.UUID == part.OwnerID) |
5499 | { | 5946 | { |
5500 | if (data.CreateSelected) | 5947 | if (part.CreateSelected) |
5501 | { | 5948 | { |
5502 | // Only send this flag once, then unset it | 5949 | // Only send this flag once, then unset it |
5503 | flags |= PrimFlags.CreateSelected; | 5950 | flags |= PrimFlags.CreateSelected; |
5504 | data.CreateSelected = false; | 5951 | part.CreateSelected = false; |
5505 | } | 5952 | } |
5506 | } | 5953 | } |
5507 | 5954 | ||
@@ -5513,21 +5960,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5513 | 5960 | ||
5514 | #endregion PrimFlags | 5961 | #endregion PrimFlags |
5515 | 5962 | ||
5516 | if (data.Sound != UUID.Zero) | 5963 | if (part.Sound != UUID.Zero) |
5517 | { | 5964 | { |
5518 | update.Sound = data.Sound; | 5965 | update.Sound = part.Sound; |
5519 | update.OwnerID = data.OwnerID; | 5966 | update.OwnerID = part.OwnerID; |
5520 | update.Gain = (float)data.SoundGain; | 5967 | update.Gain = (float)part.SoundGain; |
5521 | update.Radius = (float)data.SoundRadius; | 5968 | update.Radius = (float)part.SoundRadius; |
5522 | update.Flags = data.SoundFlags; | 5969 | update.Flags = part.SoundFlags; |
5523 | } | 5970 | } |
5524 | 5971 | ||
5525 | switch ((PCode)data.Shape.PCode) | 5972 | switch ((PCode)part.Shape.PCode) |
5526 | { | 5973 | { |
5527 | case PCode.Grass: | 5974 | case PCode.Grass: |
5528 | case PCode.Tree: | 5975 | case PCode.Tree: |
5529 | case PCode.NewTree: | 5976 | case PCode.NewTree: |
5530 | update.Data = new byte[] { data.Shape.State }; | 5977 | update.Data = new byte[] { part.Shape.State }; |
5531 | break; | 5978 | break; |
5532 | default: | 5979 | default: |
5533 | update.Data = Utils.EmptyBytes; | 5980 | update.Data = Utils.EmptyBytes; |
@@ -5556,14 +6003,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5556 | OutPacket(packet, ThrottleOutPacketType.Task); | 6003 | OutPacket(packet, ThrottleOutPacketType.Task); |
5557 | } | 6004 | } |
5558 | 6005 | ||
5559 | public ulong GetGroupPowers(UUID groupID) | 6006 | public Dictionary<UUID, ulong> GetGroupPowers() |
5560 | { | 6007 | { |
5561 | if (groupID == ActiveGroupId) | 6008 | lock(m_groupPowers) |
5562 | return ActiveGroupPowers; | 6009 | { |
6010 | return new Dictionary<UUID, ulong>(m_groupPowers); | ||
6011 | } | ||
6012 | } | ||
5563 | 6013 | ||
5564 | if (m_groupPowers.ContainsKey(groupID)) | 6014 | public void SetGroupPowers(Dictionary<UUID, ulong> powers) |
5565 | return m_groupPowers[groupID]; | 6015 | { |
6016 | lock(m_groupPowers) | ||
6017 | { | ||
6018 | m_groupPowers.Clear(); | ||
6019 | m_groupPowers = powers; | ||
6020 | } | ||
6021 | } | ||
5566 | 6022 | ||
6023 | public ulong GetGroupPowers(UUID groupID) | ||
6024 | { | ||
6025 | lock(m_groupPowers) | ||
6026 | { | ||
6027 | if (m_groupPowers.ContainsKey(groupID)) | ||
6028 | return m_groupPowers[groupID]; | ||
6029 | } | ||
5567 | return 0; | 6030 | return 0; |
5568 | } | 6031 | } |
5569 | 6032 | ||
@@ -5579,18 +6042,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5579 | // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs | 6042 | // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs |
5580 | // for each AgentUpdate packet. | 6043 | // for each AgentUpdate packet. |
5581 | AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false); | 6044 | AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false); |
5582 | 6045 | ||
5583 | AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false); | 6046 | AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false); |
6047 | AddLocalPacketHandler(PacketType.VelocityInterpolateOff, HandleVelocityInterpolateOff, false); | ||
6048 | AddLocalPacketHandler(PacketType.VelocityInterpolateOn, HandleVelocityInterpolateOn, false); | ||
5584 | AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); | 6049 | AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); |
5585 | AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); | 6050 | AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); |
5586 | AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false); | 6051 | AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false); |
5587 | AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest, false); | 6052 | AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest, false); |
5588 | AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest); | 6053 | AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest); |
5589 | AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest); | 6054 | AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest); |
5590 | AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage, true, true); | 6055 | AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage); |
5591 | AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest, true, true); | 6056 | AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest); |
5592 | AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer); | 6057 | AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer); |
5593 | AddLocalPacketHandler(PacketType.AvatarPropertiesUpdate, HandlerAvatarPropertiesUpdate, true, true); | 6058 | AddLocalPacketHandler(PacketType.AvatarPropertiesUpdate, HandlerAvatarPropertiesUpdate); |
5594 | AddLocalPacketHandler(PacketType.ScriptDialogReply, HandlerScriptDialogReply); | 6059 | AddLocalPacketHandler(PacketType.ScriptDialogReply, HandlerScriptDialogReply); |
5595 | AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage); | 6060 | AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage); |
5596 | AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship); | 6061 | AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship); |
@@ -5598,6 +6063,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5598 | AddLocalPacketHandler(PacketType.TerminateFriendship, HandlerTerminateFriendship); | 6063 | AddLocalPacketHandler(PacketType.TerminateFriendship, HandlerTerminateFriendship); |
5599 | AddLocalPacketHandler(PacketType.RezObject, HandlerRezObject); | 6064 | AddLocalPacketHandler(PacketType.RezObject, HandlerRezObject); |
5600 | AddLocalPacketHandler(PacketType.DeRezObject, HandlerDeRezObject); | 6065 | AddLocalPacketHandler(PacketType.DeRezObject, HandlerDeRezObject); |
6066 | AddLocalPacketHandler(PacketType.RezRestoreToWorld, HandlerRezRestoreToWorld); | ||
5601 | AddLocalPacketHandler(PacketType.ModifyLand, HandlerModifyLand); | 6067 | AddLocalPacketHandler(PacketType.ModifyLand, HandlerModifyLand); |
5602 | AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply, false); | 6068 | AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply, false); |
5603 | AddLocalPacketHandler(PacketType.AgentWearablesRequest, HandlerAgentWearablesRequest); | 6069 | AddLocalPacketHandler(PacketType.AgentWearablesRequest, HandlerAgentWearablesRequest); |
@@ -5732,6 +6198,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5732 | AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); | 6198 | AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); |
5733 | AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); | 6199 | AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); |
5734 | AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); | 6200 | AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); |
6201 | AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments); | ||
5735 | AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); | 6202 | AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); |
5736 | AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); | 6203 | AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); |
5737 | AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); | 6204 | AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); |
@@ -5775,8 +6242,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5775 | AddLocalPacketHandler(PacketType.PickDelete, HandlePickDelete); | 6242 | AddLocalPacketHandler(PacketType.PickDelete, HandlePickDelete); |
5776 | AddLocalPacketHandler(PacketType.PickGodDelete, HandlePickGodDelete); | 6243 | AddLocalPacketHandler(PacketType.PickGodDelete, HandlePickGodDelete); |
5777 | AddLocalPacketHandler(PacketType.PickInfoUpdate, HandlePickInfoUpdate); | 6244 | AddLocalPacketHandler(PacketType.PickInfoUpdate, HandlePickInfoUpdate); |
5778 | AddLocalPacketHandler(PacketType.AvatarNotesUpdate, HandleAvatarNotesUpdate, true, true); | 6245 | AddLocalPacketHandler(PacketType.AvatarNotesUpdate, HandleAvatarNotesUpdate); |
5779 | AddLocalPacketHandler(PacketType.AvatarInterestsUpdate, HandleAvatarInterestsUpdate, true, true); | 6246 | AddLocalPacketHandler(PacketType.AvatarInterestsUpdate, HandleAvatarInterestsUpdate); |
5780 | AddLocalPacketHandler(PacketType.GrantUserRights, HandleGrantUserRights); | 6247 | AddLocalPacketHandler(PacketType.GrantUserRights, HandleGrantUserRights); |
5781 | AddLocalPacketHandler(PacketType.PlacesQuery, HandlePlacesQuery); | 6248 | AddLocalPacketHandler(PacketType.PlacesQuery, HandlePlacesQuery); |
5782 | AddLocalPacketHandler(PacketType.UpdateMuteListEntry, HandleUpdateMuteListEntry); | 6249 | AddLocalPacketHandler(PacketType.UpdateMuteListEntry, HandleUpdateMuteListEntry); |
@@ -5798,7 +6265,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5798 | AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); | 6265 | AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); |
5799 | AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); | 6266 | AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); |
5800 | AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); | 6267 | AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); |
5801 | 6268 | AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags); | |
6269 | AddLocalPacketHandler(PacketType.RevokePermissions, HandleRevokePermissions); | ||
5802 | AddGenericPacketHandler("autopilot", HandleAutopilot); | 6270 | AddGenericPacketHandler("autopilot", HandleAutopilot); |
5803 | } | 6271 | } |
5804 | 6272 | ||
@@ -5809,7 +6277,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5809 | #region Scene/Avatar | 6277 | #region Scene/Avatar |
5810 | 6278 | ||
5811 | // Threshold for body rotation to be a significant agent update | 6279 | // Threshold for body rotation to be a significant agent update |
5812 | private const float QDELTA = 0.000001f; | 6280 | // use the abs of cos |
6281 | private const float QDELTABody = 1.0f - 0.00005f; | ||
6282 | private const float QDELTAHead = 1.0f - 0.00005f; | ||
5813 | // Threshold for camera rotation to be a significant agent update | 6283 | // Threshold for camera rotation to be a significant agent update |
5814 | private const float VDELTA = 0.01f; | 6284 | private const float VDELTA = 0.01f; |
5815 | 6285 | ||
@@ -5832,27 +6302,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5832 | /// <param name='x'></param> | 6302 | /// <param name='x'></param> |
5833 | private bool CheckAgentMovementUpdateSignificance(AgentUpdatePacket.AgentDataBlock x) | 6303 | private bool CheckAgentMovementUpdateSignificance(AgentUpdatePacket.AgentDataBlock x) |
5834 | { | 6304 | { |
5835 | float qdelta1 = 1 - (float)Math.Pow(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation), 2); | 6305 | if( |
5836 | //qdelta2 = 1 - (float)Math.Pow(Quaternion.Dot(x.HeadRotation, m_thisAgentUpdateArgs.HeadRotation), 2); | 6306 | (x.ControlFlags != m_thisAgentUpdateArgs.ControlFlags) // significant if control flags changed |
5837 | 6307 | // || ((x.ControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0 && | |
5838 | bool movementSignificant = | 6308 | // (x.ControlFlags & 0x3f8dfff) != 0) // we need to rotate the av on fly |
5839 | (qdelta1 > QDELTA) // significant if body rotation above threshold | 6309 | || x.ControlFlags != (byte)AgentManager.ControlFlags.NONE// actually all movement controls need to pass |
5840 | // Ignoring head rotation altogether, because it's not being used for anything interesting up the stack | ||
5841 | // || (qdelta2 > QDELTA * 10) // significant if head rotation above threshold | ||
5842 | || (x.ControlFlags != m_thisAgentUpdateArgs.ControlFlags) // significant if control flags changed | ||
5843 | || (x.ControlFlags != (byte)AgentManager.ControlFlags.NONE) // significant if user supplying any movement update commands | ||
5844 | || (x.Far != m_thisAgentUpdateArgs.Far) // significant if far distance changed | ||
5845 | || (x.Flags != m_thisAgentUpdateArgs.Flags) // significant if Flags changed | 6310 | || (x.Flags != m_thisAgentUpdateArgs.Flags) // significant if Flags changed |
5846 | || (x.State != m_thisAgentUpdateArgs.State) // significant if Stats changed | 6311 | || (x.State != m_thisAgentUpdateArgs.State) // significant if Stats changed |
5847 | ; | 6312 | || (Math.Abs(x.Far - m_thisAgentUpdateArgs.Far) >= 32) // significant if far distance changed |
5848 | //if (movementSignificant) | 6313 | ) |
5849 | //{ | 6314 | return true; |
5850 | //m_log.DebugFormat("[LLCLIENTVIEW]: Bod {0} {1}", | 6315 | |
5851 | // qdelta1, qdelta2); | 6316 | float qdelta1 = Math.Abs(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation)); |
5852 | //m_log.DebugFormat("[LLCLIENTVIEW]: St {0} {1} {2} {3}", | 6317 | //qdelta2 = Math.Abs(Quaternion.Dot(x.HeadRotation, m_thisAgentUpdateArgs.HeadRotation)); |
5853 | // x.ControlFlags, x.Flags, x.Far, x.State); | 6318 | |
5854 | //} | 6319 | if( |
5855 | return movementSignificant; | 6320 | qdelta1 < QDELTABody // significant if body rotation above(below cos) threshold |
6321 | // Ignoring head rotation altogether, because it's not being used for anything interesting up the stack | ||
6322 | // || qdelta2 < QDELTAHead // significant if head rotation above(below cos) threshold | ||
6323 | ) | ||
6324 | return true; | ||
6325 | |||
6326 | return false; | ||
5856 | } | 6327 | } |
5857 | 6328 | ||
5858 | /// <summary> | 6329 | /// <summary> |
@@ -5863,78 +6334,95 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5863 | /// <param name='x'></param> | 6334 | /// <param name='x'></param> |
5864 | private bool CheckAgentCameraUpdateSignificance(AgentUpdatePacket.AgentDataBlock x) | 6335 | private bool CheckAgentCameraUpdateSignificance(AgentUpdatePacket.AgentDataBlock x) |
5865 | { | 6336 | { |
5866 | float vdelta1 = Vector3.Distance(x.CameraAtAxis, m_thisAgentUpdateArgs.CameraAtAxis); | 6337 | if(Math.Abs(x.CameraCenter.X - m_thisAgentUpdateArgs.CameraCenter.X) > VDELTA || |
5867 | float vdelta2 = Vector3.Distance(x.CameraCenter, m_thisAgentUpdateArgs.CameraCenter); | 6338 | Math.Abs(x.CameraCenter.Y - m_thisAgentUpdateArgs.CameraCenter.Y) > VDELTA || |
5868 | float vdelta3 = Vector3.Distance(x.CameraLeftAxis, m_thisAgentUpdateArgs.CameraLeftAxis); | 6339 | Math.Abs(x.CameraCenter.Z - m_thisAgentUpdateArgs.CameraCenter.Z) > VDELTA || |
5869 | float vdelta4 = Vector3.Distance(x.CameraUpAxis, m_thisAgentUpdateArgs.CameraUpAxis); | ||
5870 | 6340 | ||
5871 | bool cameraSignificant = | 6341 | Math.Abs(x.CameraAtAxis.X - m_thisAgentUpdateArgs.CameraAtAxis.X) > VDELTA || |
5872 | (vdelta1 > VDELTA) || | 6342 | Math.Abs(x.CameraAtAxis.Y - m_thisAgentUpdateArgs.CameraAtAxis.Y) > VDELTA || |
5873 | (vdelta2 > VDELTA) || | 6343 | // Math.Abs(x.CameraAtAxis.Z - m_thisAgentUpdateArgs.CameraAtAxis.Z) > VDELTA || |
5874 | (vdelta3 > VDELTA) || | ||
5875 | (vdelta4 > VDELTA) | ||
5876 | ; | ||
5877 | 6344 | ||
5878 | //if (cameraSignificant) | 6345 | Math.Abs(x.CameraLeftAxis.X - m_thisAgentUpdateArgs.CameraLeftAxis.X) > VDELTA || |
5879 | //{ | 6346 | Math.Abs(x.CameraLeftAxis.Y - m_thisAgentUpdateArgs.CameraLeftAxis.Y) > VDELTA || |
5880 | //m_log.DebugFormat("[LLCLIENTVIEW]: Cam1 {0} {1}", | 6347 | // Math.Abs(x.CameraLeftAxis.Z - m_thisAgentUpdateArgs.CameraLeftAxis.Z) > VDELTA || |
5881 | // x.CameraAtAxis, x.CameraCenter); | ||
5882 | //m_log.DebugFormat("[LLCLIENTVIEW]: Cam2 {0} {1}", | ||
5883 | // x.CameraLeftAxis, x.CameraUpAxis); | ||
5884 | //} | ||
5885 | 6348 | ||
5886 | return cameraSignificant; | 6349 | Math.Abs(x.CameraUpAxis.X - m_thisAgentUpdateArgs.CameraUpAxis.X) > VDELTA || |
5887 | } | 6350 | Math.Abs(x.CameraUpAxis.Y - m_thisAgentUpdateArgs.CameraUpAxis.Y) > VDELTA |
6351 | // Math.Abs(x.CameraLeftAxis.Z - m_thisAgentUpdateArgs.CameraLeftAxis.Z) > VDELTA || | ||
6352 | ) | ||
6353 | return true; | ||
5888 | 6354 | ||
5889 | private bool HandleAgentUpdate(IClientAPI sener, Packet packet) | 6355 | return false; |
5890 | { | 6356 | } |
5891 | // We got here, which means that something in agent update was significant | ||
5892 | 6357 | ||
6358 | private bool HandleAgentUpdate(IClientAPI sender, Packet packet) | ||
6359 | { | ||
5893 | AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet; | 6360 | AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet; |
5894 | AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData; | 6361 | AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData; |
5895 | 6362 | ||
5896 | if (x.AgentID != AgentId || x.SessionID != SessionId) | 6363 | if (x.AgentID != AgentId || x.SessionID != SessionId) |
6364 | { | ||
6365 | PacketPool.Instance.ReturnPacket(packet); | ||
5897 | return false; | 6366 | return false; |
6367 | } | ||
6368 | |||
6369 | uint seq = packet.Header.Sequence; | ||
6370 | |||
6371 | TotalAgentUpdates++; | ||
6372 | // dont let ignored updates pollute this throttles | ||
6373 | if(SceneAgent == null || SceneAgent.IsChildAgent || | ||
6374 | SceneAgent.IsInTransit || seq <= m_thisAgentUpdateArgs.lastpacketSequence ) | ||
6375 | { | ||
6376 | // throttle reset is done at MoveAgentIntoRegion() | ||
6377 | // called by scenepresence on completemovement | ||
6378 | PacketPool.Instance.ReturnPacket(packet); | ||
6379 | return true; | ||
6380 | } | ||
6381 | |||
6382 | m_thisAgentUpdateArgs.lastpacketSequence = seq; | ||
5898 | 6383 | ||
5899 | // Before we update the current m_thisAgentUpdateArgs, let's check this again | ||
5900 | // to see what exactly changed | ||
5901 | bool movement = CheckAgentMovementUpdateSignificance(x); | 6384 | bool movement = CheckAgentMovementUpdateSignificance(x); |
5902 | bool camera = CheckAgentCameraUpdateSignificance(x); | 6385 | bool camera = CheckAgentCameraUpdateSignificance(x); |
5903 | 6386 | ||
5904 | m_thisAgentUpdateArgs.AgentID = x.AgentID; | ||
5905 | m_thisAgentUpdateArgs.BodyRotation = x.BodyRotation; | ||
5906 | m_thisAgentUpdateArgs.CameraAtAxis = x.CameraAtAxis; | ||
5907 | m_thisAgentUpdateArgs.CameraCenter = x.CameraCenter; | ||
5908 | m_thisAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis; | ||
5909 | m_thisAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis; | ||
5910 | m_thisAgentUpdateArgs.ControlFlags = x.ControlFlags; | ||
5911 | m_thisAgentUpdateArgs.Far = x.Far; | ||
5912 | m_thisAgentUpdateArgs.Flags = x.Flags; | ||
5913 | m_thisAgentUpdateArgs.HeadRotation = x.HeadRotation; | ||
5914 | m_thisAgentUpdateArgs.SessionID = x.SessionID; | ||
5915 | m_thisAgentUpdateArgs.State = x.State; | ||
5916 | |||
5917 | UpdateAgent handlerAgentUpdate = OnAgentUpdate; | ||
5918 | UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate; | ||
5919 | UpdateAgent handlerAgentCameraUpdate = OnAgentCameraUpdate; | ||
5920 | |||
5921 | // Was there a significant movement/state change? | 6387 | // Was there a significant movement/state change? |
5922 | if (movement) | 6388 | if (movement) |
5923 | { | 6389 | { |
6390 | m_thisAgentUpdateArgs.BodyRotation = x.BodyRotation; | ||
6391 | m_thisAgentUpdateArgs.ControlFlags = x.ControlFlags; | ||
6392 | m_thisAgentUpdateArgs.Far = x.Far; | ||
6393 | m_thisAgentUpdateArgs.Flags = x.Flags; | ||
6394 | m_thisAgentUpdateArgs.HeadRotation = x.HeadRotation; | ||
6395 | m_thisAgentUpdateArgs.State = x.State; | ||
6396 | |||
6397 | m_thisAgentUpdateArgs.NeedsCameraCollision = !camera; | ||
6398 | |||
6399 | UpdateAgent handlerAgentUpdate = OnAgentUpdate; | ||
6400 | UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate; | ||
6401 | |||
5924 | if (handlerPreAgentUpdate != null) | 6402 | if (handlerPreAgentUpdate != null) |
5925 | OnPreAgentUpdate(this, m_thisAgentUpdateArgs); | 6403 | OnPreAgentUpdate(this, m_thisAgentUpdateArgs); |
5926 | 6404 | ||
5927 | if (handlerAgentUpdate != null) | 6405 | if (handlerAgentUpdate != null) |
5928 | OnAgentUpdate(this, m_thisAgentUpdateArgs); | 6406 | OnAgentUpdate(this, m_thisAgentUpdateArgs); |
6407 | |||
5929 | } | 6408 | } |
6409 | |||
5930 | // Was there a significant camera(s) change? | 6410 | // Was there a significant camera(s) change? |
5931 | if (camera) | 6411 | if (camera) |
6412 | { | ||
6413 | m_thisAgentUpdateArgs.CameraAtAxis = x.CameraAtAxis; | ||
6414 | m_thisAgentUpdateArgs.CameraCenter = x.CameraCenter; | ||
6415 | m_thisAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis; | ||
6416 | m_thisAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis; | ||
6417 | |||
6418 | m_thisAgentUpdateArgs.NeedsCameraCollision = true; | ||
6419 | |||
6420 | UpdateAgent handlerAgentCameraUpdate = OnAgentCameraUpdate; | ||
6421 | |||
5932 | if (handlerAgentCameraUpdate != null) | 6422 | if (handlerAgentCameraUpdate != null) |
5933 | handlerAgentCameraUpdate(this, m_thisAgentUpdateArgs); | 6423 | handlerAgentCameraUpdate(this, m_thisAgentUpdateArgs); |
5934 | 6424 | ||
5935 | handlerAgentUpdate = null; | 6425 | } |
5936 | handlerPreAgentUpdate = null; | ||
5937 | handlerAgentCameraUpdate = null; | ||
5938 | 6426 | ||
5939 | PacketPool.Instance.ReturnPacket(packet); | 6427 | PacketPool.Instance.ReturnPacket(packet); |
5940 | 6428 | ||
@@ -5967,6 +6455,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5967 | ParcelGodMarkAsContentPacket ParcelGodMarkAsContent = | 6455 | ParcelGodMarkAsContentPacket ParcelGodMarkAsContent = |
5968 | (ParcelGodMarkAsContentPacket)Packet; | 6456 | (ParcelGodMarkAsContentPacket)Packet; |
5969 | 6457 | ||
6458 | if(SessionId != ParcelGodMarkAsContent.AgentData.SessionID || AgentId != ParcelGodMarkAsContent.AgentData.AgentID) | ||
6459 | return false; | ||
6460 | |||
5970 | ParcelGodMark ParcelGodMarkAsContentHandler = OnParcelGodMark; | 6461 | ParcelGodMark ParcelGodMarkAsContentHandler = OnParcelGodMark; |
5971 | if (ParcelGodMarkAsContentHandler != null) | 6462 | if (ParcelGodMarkAsContentHandler != null) |
5972 | { | 6463 | { |
@@ -5982,6 +6473,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5982 | { | 6473 | { |
5983 | FreezeUserPacket FreezeUser = (FreezeUserPacket)Packet; | 6474 | FreezeUserPacket FreezeUser = (FreezeUserPacket)Packet; |
5984 | 6475 | ||
6476 | if(SessionId != FreezeUser.AgentData.SessionID || AgentId != FreezeUser.AgentData.AgentID) | ||
6477 | return false; | ||
6478 | |||
5985 | FreezeUserUpdate FreezeUserHandler = OnParcelFreezeUser; | 6479 | FreezeUserUpdate FreezeUserHandler = OnParcelFreezeUser; |
5986 | if (FreezeUserHandler != null) | 6480 | if (FreezeUserHandler != null) |
5987 | { | 6481 | { |
@@ -5999,6 +6493,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5999 | EjectUserPacket EjectUser = | 6493 | EjectUserPacket EjectUser = |
6000 | (EjectUserPacket)Packet; | 6494 | (EjectUserPacket)Packet; |
6001 | 6495 | ||
6496 | if(SessionId != EjectUser.AgentData.SessionID || AgentId != EjectUser.AgentData.AgentID) | ||
6497 | return false; | ||
6498 | |||
6002 | EjectUserUpdate EjectUserHandler = OnParcelEjectUser; | 6499 | EjectUserUpdate EjectUserHandler = OnParcelEjectUser; |
6003 | if (EjectUserHandler != null) | 6500 | if (EjectUserHandler != null) |
6004 | { | 6501 | { |
@@ -6016,6 +6513,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6016 | ParcelBuyPassPacket ParcelBuyPass = | 6513 | ParcelBuyPassPacket ParcelBuyPass = |
6017 | (ParcelBuyPassPacket)Packet; | 6514 | (ParcelBuyPassPacket)Packet; |
6018 | 6515 | ||
6516 | if(SessionId != ParcelBuyPass.AgentData.SessionID || AgentId != ParcelBuyPass.AgentData.AgentID) | ||
6517 | return false; | ||
6518 | |||
6019 | ParcelBuyPass ParcelBuyPassHandler = OnParcelBuyPass; | 6519 | ParcelBuyPass ParcelBuyPassHandler = OnParcelBuyPass; |
6020 | if (ParcelBuyPassHandler != null) | 6520 | if (ParcelBuyPassHandler != null) |
6021 | { | 6521 | { |
@@ -6048,8 +6548,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6048 | 6548 | ||
6049 | private bool HandleUUIDGroupNameRequest(IClientAPI sender, Packet Pack) | 6549 | private bool HandleUUIDGroupNameRequest(IClientAPI sender, Packet Pack) |
6050 | { | 6550 | { |
6051 | UUIDGroupNameRequestPacket upack = (UUIDGroupNameRequestPacket)Pack; | 6551 | ScenePresence sp = (ScenePresence)SceneAgent; |
6552 | if(sp == null || sp.IsDeleted || (sp.IsInTransit && !sp.IsInLocalTransit)) | ||
6553 | return true; | ||
6052 | 6554 | ||
6555 | UUIDGroupNameRequestPacket upack = (UUIDGroupNameRequestPacket)Pack; | ||
6053 | 6556 | ||
6054 | for (int i = 0; i < upack.UUIDNameBlock.Length; i++) | 6557 | for (int i = 0; i < upack.UUIDNameBlock.Length; i++) |
6055 | { | 6558 | { |
@@ -6101,7 +6604,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6101 | } | 6604 | } |
6102 | } | 6605 | } |
6103 | } | 6606 | } |
6104 | 6607 | ||
6105 | //m_log.Debug("[LLCLIENTVIEW]: Not handling GenericMessage with method-type of: " + method); | 6608 | //m_log.Debug("[LLCLIENTVIEW]: Not handling GenericMessage with method-type of: " + method); |
6106 | return false; | 6609 | return false; |
6107 | } | 6610 | } |
@@ -6150,6 +6653,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6150 | return true; | 6653 | return true; |
6151 | } | 6654 | } |
6152 | 6655 | ||
6656 | private bool HandleVelocityInterpolateOff(IClientAPI sender, Packet Pack) | ||
6657 | { | ||
6658 | VelocityInterpolateOffPacket p = (VelocityInterpolateOffPacket)Pack; | ||
6659 | if (p.AgentData.SessionID != SessionId || | ||
6660 | p.AgentData.AgentID != AgentId) | ||
6661 | return true; | ||
6662 | |||
6663 | // m_VelocityInterpolate = false; | ||
6664 | return true; | ||
6665 | } | ||
6666 | |||
6667 | private bool HandleVelocityInterpolateOn(IClientAPI sender, Packet Pack) | ||
6668 | { | ||
6669 | VelocityInterpolateOnPacket p = (VelocityInterpolateOnPacket)Pack; | ||
6670 | if (p.AgentData.SessionID != SessionId || | ||
6671 | p.AgentData.AgentID != AgentId) | ||
6672 | return true; | ||
6673 | |||
6674 | // m_VelocityInterpolate = true; | ||
6675 | return true; | ||
6676 | } | ||
6677 | |||
6678 | |||
6153 | private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack) | 6679 | private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack) |
6154 | { | 6680 | { |
6155 | AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack; | 6681 | AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack; |
@@ -6442,11 +6968,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6442 | RezObject handlerRezObject = OnRezObject; | 6968 | RezObject handlerRezObject = OnRezObject; |
6443 | if (handlerRezObject != null) | 6969 | if (handlerRezObject != null) |
6444 | { | 6970 | { |
6445 | handlerRezObject(this, rezPacket.InventoryData.ItemID, rezPacket.RezData.RayEnd, | 6971 | UUID rezGroupID = rezPacket.AgentData.GroupID; |
6446 | rezPacket.RezData.RayStart, rezPacket.RezData.RayTargetID, | 6972 | if(!IsGroupMember(rezGroupID)) |
6447 | rezPacket.RezData.BypassRaycast, rezPacket.RezData.RayEndIsIntersection, | 6973 | rezGroupID = UUID.Zero; |
6448 | rezPacket.RezData.RezSelected, rezPacket.RezData.RemoveItem, | 6974 | handlerRezObject(this, rezPacket.InventoryData.ItemID, rezGroupID, rezPacket.RezData.RayEnd, |
6449 | rezPacket.RezData.FromTaskID); | 6975 | rezPacket.RezData.RayStart, rezPacket.RezData.RayTargetID, |
6976 | rezPacket.RezData.BypassRaycast, rezPacket.RezData.RayEndIsIntersection, | ||
6977 | rezPacket.RezData.RezSelected, rezPacket.RezData.RemoveItem, | ||
6978 | rezPacket.RezData.FromTaskID); | ||
6450 | } | 6979 | } |
6451 | return true; | 6980 | return true; |
6452 | } | 6981 | } |
@@ -6485,6 +7014,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6485 | return true; | 7014 | return true; |
6486 | } | 7015 | } |
6487 | 7016 | ||
7017 | private bool HandlerRezRestoreToWorld(IClientAPI sender, Packet Pack) | ||
7018 | { | ||
7019 | RezRestoreToWorldPacket restore = (RezRestoreToWorldPacket)Pack; | ||
7020 | |||
7021 | #region Packet Session and User Check | ||
7022 | if (m_checkPackets) | ||
7023 | { | ||
7024 | if (restore.AgentData.SessionID != SessionId || | ||
7025 | restore.AgentData.AgentID != AgentId) | ||
7026 | return true; | ||
7027 | } | ||
7028 | #endregion | ||
7029 | |||
7030 | RezRestoreToWorld handlerRezRestoreToWorld = OnRezRestoreToWorld; | ||
7031 | if (handlerRezRestoreToWorld != null) | ||
7032 | handlerRezRestoreToWorld(this, restore.InventoryData.ItemID); | ||
7033 | |||
7034 | return true; | ||
7035 | } | ||
7036 | |||
6488 | private bool HandlerModifyLand(IClientAPI sender, Packet Pack) | 7037 | private bool HandlerModifyLand(IClientAPI sender, Packet Pack) |
6489 | { | 7038 | { |
6490 | ModifyLandPacket modify = (ModifyLandPacket)Pack; | 7039 | ModifyLandPacket modify = (ModifyLandPacket)Pack; |
@@ -6501,9 +7050,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6501 | //m_log.Info("[LAND]: LAND:" + modify.ToString()); | 7050 | //m_log.Info("[LAND]: LAND:" + modify.ToString()); |
6502 | if (modify.ParcelData.Length > 0) | 7051 | if (modify.ParcelData.Length > 0) |
6503 | { | 7052 | { |
6504 | // Note: the ModifyTerrain event handler sends out updated packets before the end of this event. Therefore, | 7053 | // Note: the ModifyTerrain event handler sends out updated packets before the end of this event. Therefore, |
6505 | // a simple boolean value should work and perhaps queue up just a few terrain patch packets at the end of the edit. | 7054 | // a simple boolean value should work and perhaps queue up just a few terrain patch packets at the end of the edit. |
6506 | m_justEditedTerrain = true; // Prevent terrain packet (Land layer) from being queued, make it unreliable | ||
6507 | if (OnModifyTerrain != null) | 7055 | if (OnModifyTerrain != null) |
6508 | { | 7056 | { |
6509 | for (int i = 0; i < modify.ParcelData.Length; i++) | 7057 | for (int i = 0; i < modify.ParcelData.Length; i++) |
@@ -6519,7 +7067,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6519 | } | 7067 | } |
6520 | } | 7068 | } |
6521 | } | 7069 | } |
6522 | m_justEditedTerrain = false; // Queue terrain packet (Land layer) if necessary, make it reliable again | ||
6523 | } | 7070 | } |
6524 | 7071 | ||
6525 | return true; | 7072 | return true; |
@@ -6580,7 +7127,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6580 | byte[] visualparams = new byte[appear.VisualParam.Length]; | 7127 | byte[] visualparams = new byte[appear.VisualParam.Length]; |
6581 | for (int i = 0; i < appear.VisualParam.Length; i++) | 7128 | for (int i = 0; i < appear.VisualParam.Length; i++) |
6582 | visualparams[i] = appear.VisualParam[i].ParamValue; | 7129 | visualparams[i] = appear.VisualParam[i].ParamValue; |
6583 | //var b = appear.WearableData[0]; | 7130 | //var b = appear.WearableData[0]; |
6584 | 7131 | ||
6585 | Primitive.TextureEntry te = null; | 7132 | Primitive.TextureEntry te = null; |
6586 | if (appear.ObjectData.TextureEntry.Length > 1) | 7133 | if (appear.ObjectData.TextureEntry.Length > 1) |
@@ -6588,7 +7135,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6588 | 7135 | ||
6589 | WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length]; | 7136 | WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length]; |
6590 | for (int i=0; i<appear.WearableData.Length;i++) | 7137 | for (int i=0; i<appear.WearableData.Length;i++) |
6591 | cacheitems[i] = new WearableCacheItem(){CacheId = appear.WearableData[i].CacheID,TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex)}; | 7138 | cacheitems[i] = new WearableCacheItem(){ |
7139 | CacheId = appear.WearableData[i].CacheID, | ||
7140 | TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex) | ||
7141 | }; | ||
6592 | 7142 | ||
6593 | 7143 | ||
6594 | 7144 | ||
@@ -6794,13 +7344,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6794 | return true; | 7344 | return true; |
6795 | } | 7345 | } |
6796 | 7346 | ||
6797 | private bool HandleCompleteAgentMovement(IClientAPI sender, Packet Pack) | 7347 | private bool HandleCompleteAgentMovement(IClientAPI sender, Packet Pack) |
6798 | { | 7348 | { |
7349 | m_log.DebugFormat("[LLClientView] HandleCompleteAgentMovement"); | ||
7350 | |||
6799 | Action<IClientAPI, bool> handlerCompleteMovementToRegion = OnCompleteMovementToRegion; | 7351 | Action<IClientAPI, bool> handlerCompleteMovementToRegion = OnCompleteMovementToRegion; |
6800 | if (handlerCompleteMovementToRegion != null) | 7352 | if (handlerCompleteMovementToRegion != null) |
6801 | { | 7353 | { |
6802 | handlerCompleteMovementToRegion(sender, true); | 7354 | handlerCompleteMovementToRegion(sender, true); |
6803 | } | 7355 | } |
7356 | else | ||
7357 | m_log.Debug("HandleCompleteAgentMovement NULL handler"); | ||
7358 | |||
6804 | handlerCompleteMovementToRegion = null; | 7359 | handlerCompleteMovementToRegion = null; |
6805 | 7360 | ||
6806 | return true; | 7361 | return true; |
@@ -6818,7 +7373,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6818 | return true; | 7373 | return true; |
6819 | } | 7374 | } |
6820 | #endregion | 7375 | #endregion |
6821 | 7376 | /* | |
6822 | StartAnim handlerStartAnim = null; | 7377 | StartAnim handlerStartAnim = null; |
6823 | StopAnim handlerStopAnim = null; | 7378 | StopAnim handlerStopAnim = null; |
6824 | 7379 | ||
@@ -6842,6 +7397,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6842 | } | 7397 | } |
6843 | } | 7398 | } |
6844 | return true; | 7399 | return true; |
7400 | */ | ||
7401 | ChangeAnim handlerChangeAnim = null; | ||
7402 | |||
7403 | for (int i = 0; i < AgentAni.AnimationList.Length; i++) | ||
7404 | { | ||
7405 | handlerChangeAnim = OnChangeAnim; | ||
7406 | if (handlerChangeAnim != null) | ||
7407 | { | ||
7408 | handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false); | ||
7409 | } | ||
7410 | } | ||
7411 | |||
7412 | handlerChangeAnim = OnChangeAnim; | ||
7413 | if (handlerChangeAnim != null) | ||
7414 | { | ||
7415 | handlerChangeAnim(UUID.Zero, false, true); | ||
7416 | } | ||
7417 | |||
7418 | return true; | ||
6845 | } | 7419 | } |
6846 | 7420 | ||
6847 | private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) | 7421 | private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) |
@@ -6997,7 +7571,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6997 | SendUserInfoReply(false, true, ""); | 7571 | SendUserInfoReply(false, true, ""); |
6998 | } | 7572 | } |
6999 | return true; | 7573 | return true; |
7000 | |||
7001 | } | 7574 | } |
7002 | 7575 | ||
7003 | private bool HandleUpdateUserInfo(IClientAPI sender, Packet Pack) | 7576 | private bool HandleUpdateUserInfo(IClientAPI sender, Packet Pack) |
@@ -7087,6 +7660,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
7087 | #endregion | 7660 | #endregion |
7088 | 7661 | ||
7089 | m_udpClient.SetThrottles(atpack.Throttle.Throttles); | 7662 | m_udpClient.SetThrottles(atpack.Throttle.Throttles); |
7663 | GenericCall2 handler = OnUpdateThrottles; | ||
7664 | if (handler != null) | ||
7665 | { | ||
7666 | handler(); | ||
7667 | } | ||
7090 | return true; | 7668 | return true; |
7091 | } | 7669 | } |
7092 | 7670 | ||
@@ -7207,7 +7785,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
7207 | 7785 | ||
7208 | AddNewPrim handlerAddPrim = OnAddPrim; | 7786 | AddNewPrim handlerAddPrim = OnAddPrim; |
7209 | if (handlerAddPrim != null) | 7787 | if (handlerAddPrim != null) |
7210 | handlerAddPrim(AgentId, ActiveGroupId, addPacket.ObjectData.RayEnd, addPacket.ObjectData.Rotation, shape, addPacket.ObjectData.BypassRaycast, addPacket.ObjectData.RayStart, addPacket.ObjectData.RayTargetID, addPacket.ObjectData.RayEndIsIntersection); | 7788 | handlerAddPrim(AgentId, addPacket.AgentData.GroupID, addPacket.ObjectData.RayEnd, addPacket.ObjectData.Rotation, shape, addPacket.ObjectData.BypassRaycast, addPacket.ObjectData.RayStart, addPacket.ObjectData.RayTargetID, addPacket.ObjectData.RayEndIsIntersection); |
7211 | } | 7789 | } |
7212 | return true; | 7790 | return true; |
7213 | } | 7791 | } |
@@ -7302,14 +7880,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
7302 | 7880 | ||
7303 | ObjectDuplicate handlerObjectDuplicate = null; | 7881 | ObjectDuplicate handlerObjectDuplicate = null; |
7304 | 7882 | ||
7305 | for (int i = 0; i < dupe.ObjectData.Length; i++) | 7883 | handlerObjectDuplicate = OnObjectDuplicate; |
7884 | if (handlerObjectDuplicate != null) | ||
7306 | { | 7885 | { |
7307 | handlerObjectDuplicate = OnObjectDuplicate; | 7886 | for (int i = 0; i < dupe.ObjectData.Length; i++) |
7308 | if (handlerObjectDuplicate != null) | ||
7309 | { | 7887 | { |
7888 | UUID rezGroupID = dupe.AgentData.GroupID; | ||
7889 | if(!IsGroupMember(rezGroupID)) | ||
7890 | rezGroupID = UUID.Zero; | ||
7310 | handlerObjectDuplicate(dupe.ObjectData[i].ObjectLocalID, dupe.SharedData.Offset, | 7891 | handlerObjectDuplicate(dupe.ObjectData[i].ObjectLocalID, dupe.SharedData.Offset, |
7311 | dupe.SharedData.DuplicateFlags, AgentId, | 7892 | dupe.SharedData.DuplicateFlags, AgentId, |
7312 | ActiveGroupId); | 7893 | rezGroupID); |
7313 | } | 7894 | } |
7314 | } | 7895 | } |
7315 | 7896 | ||
@@ -7354,16 +7935,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
7354 | return true; | 7935 | return true; |
7355 | } | 7936 | } |
7356 | #endregion | 7937 | #endregion |
7357 | 7938 | List<uint> thisSelection = new List<uint>(); | |
7358 | ObjectSelect handlerObjectSelect = null; | 7939 | ObjectSelect handlerObjectSelect = null; |
7359 | 7940 | uint objID; | |
7360 | for (int i = 0; i < incomingselect.ObjectData.Length; i++) | 7941 | handlerObjectSelect = OnObjectSelect; |
7942 | if (handlerObjectSelect != null) | ||
7361 | { | 7943 | { |
7362 | handlerObjectSelect = OnObjectSelect; | 7944 | for (int i = 0; i < incomingselect.ObjectData.Length; i++) |
7363 | if (handlerObjectSelect != null) | ||
7364 | { | 7945 | { |
7365 | handlerObjectSelect(incomingselect.ObjectData[i].ObjectLocalID, this); | 7946 | objID = incomingselect.ObjectData[i].ObjectLocalID; |
7947 | thisSelection.Add(objID); | ||
7366 | } | 7948 | } |
7949 | |||
7950 | handlerObjectSelect(thisSelection, this); | ||
7367 | } | 7951 | } |
7368 | return true; | 7952 | return true; |
7369 | } | 7953 | } |
@@ -7382,13 +7966,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
7382 | #endregion | 7966 | #endregion |
7383 | 7967 | ||
7384 | ObjectDeselect handlerObjectDeselect = null; | 7968 | ObjectDeselect handlerObjectDeselect = null; |
7385 | 7969 | uint objID; | |
7386 | for (int i = 0; i < incomingdeselect.ObjectData.Length; i++) | 7970 | for (int i = 0; i < incomingdeselect.ObjectData.Length; i++) |
7387 | { | 7971 | { |
7972 | objID = incomingdeselect.ObjectData[i].ObjectLocalID; | ||
7973 | |||
7388 | handlerObjectDeselect = OnObjectDeselect; | 7974 | handlerObjectDeselect = OnObjectDeselect; |
7389 | if (handlerObjectDeselect != null) | 7975 | if (handlerObjectDeselect != null) |
7390 | { | 7976 | { |
7391 | OnObjectDeselect(incomingdeselect.ObjectData[i].ObjectLocalID, this); | 7977 | OnObjectDeselect(objID, this); |
7392 | } | 7978 | } |
7393 | } | 7979 | } |
7394 | return true; | 7980 | return true; |
@@ -7511,7 +8097,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
7511 | physdata.Bounce = phsblock.Restitution; | 8097 | physdata.Bounce = phsblock.Restitution; |
7512 | physdata.Density = phsblock.Density; | 8098 | physdata.Density = phsblock.Density; |
7513 | physdata.Friction = phsblock.Friction; | 8099 | physdata.Friction = phsblock.Friction; |
7514 | physdata.GravitationModifier = phsblock.GravityMultiplier; | 8100 | physdata.GravitationModifier = phsblock.GravityMultiplier; |
7515 | } | 8101 | } |
7516 | 8102 | ||
7517 | handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this); | 8103 | handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this); |
@@ -7519,19 +8105,41 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
7519 | return true; | 8105 | return true; |
7520 | } | 8106 | } |
7521 | 8107 | ||
8108 | Dictionary<uint, uint> objImageSeqs = null; | ||
8109 | double lastobjImageSeqsMS = 0.0; | ||
8110 | |||
7522 | private bool HandleObjectImage(IClientAPI sender, Packet Pack) | 8111 | private bool HandleObjectImage(IClientAPI sender, Packet Pack) |
7523 | { | 8112 | { |
7524 | ObjectImagePacket imagePack = (ObjectImagePacket)Pack; | 8113 | ObjectImagePacket imagePack = (ObjectImagePacket)Pack; |
7525 | 8114 | ||
7526 | UpdatePrimTexture handlerUpdatePrimTexture = null; | 8115 | UpdatePrimTexture handlerUpdatePrimTexture = OnUpdatePrimTexture; |
8116 | if (handlerUpdatePrimTexture == null) | ||
8117 | return true; | ||
8118 | |||
8119 | double now = Util.GetTimeStampMS(); | ||
8120 | if(objImageSeqs == null || ( now - lastobjImageSeqsMS > 30000.0)) | ||
8121 | { | ||
8122 | objImageSeqs = null; // yeah i know superstition... | ||
8123 | objImageSeqs = new Dictionary<uint, uint>(16); | ||
8124 | } | ||
8125 | |||
8126 | lastobjImageSeqsMS = now; | ||
8127 | uint seq = Pack.Header.Sequence; | ||
8128 | uint id; | ||
8129 | uint lastseq; | ||
8130 | |||
8131 | ObjectImagePacket.ObjectDataBlock o; | ||
7527 | for (int i = 0; i < imagePack.ObjectData.Length; i++) | 8132 | for (int i = 0; i < imagePack.ObjectData.Length; i++) |
7528 | { | 8133 | { |
7529 | handlerUpdatePrimTexture = OnUpdatePrimTexture; | 8134 | o = imagePack.ObjectData[i]; |
7530 | if (handlerUpdatePrimTexture != null) | 8135 | id = o.ObjectLocalID; |
7531 | { | 8136 | if(objImageSeqs.TryGetValue(id, out lastseq)) |
7532 | handlerUpdatePrimTexture(imagePack.ObjectData[i].ObjectLocalID, | 8137 | { |
7533 | imagePack.ObjectData[i].TextureEntry, this); | 8138 | if(seq <= lastseq) |
7534 | } | 8139 | continue; |
8140 | } | ||
8141 | objImageSeqs[id] = seq; | ||
8142 | handlerUpdatePrimTexture(id, o.TextureEntry, this); | ||
7535 | } | 8143 | } |
7536 | return true; | 8144 | return true; |
7537 | } | 8145 | } |
@@ -7605,6 +8213,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
7605 | touchArgs.Add(arg); | 8213 | touchArgs.Add(arg); |
7606 | } | 8214 | } |
7607 | } | 8215 | } |
8216 | |||
7608 | handlerGrabUpdate(grabUpdate.ObjectData.ObjectID, grabUpdate.ObjectData.GrabOffsetInitial, | 8217 | handlerGrabUpdate(grabUpdate.ObjectData.ObjectID, grabUpdate.ObjectData.GrabOffsetInitial, |
7609 | grabUpdate.ObjectData.GrabPosition, this, touchArgs); | 8218 | grabUpdate.ObjectData.GrabPosition, this, touchArgs); |
7610 | } | 8219 | } |
@@ -7921,10 +8530,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
7921 | handlerObjectDuplicateOnRay = OnObjectDuplicateOnRay; | 8530 | handlerObjectDuplicateOnRay = OnObjectDuplicateOnRay; |
7922 | if (handlerObjectDuplicateOnRay != null) | 8531 | if (handlerObjectDuplicateOnRay != null) |
7923 | { | 8532 | { |
7924 | handlerObjectDuplicateOnRay(dupeOnRay.ObjectData[i].ObjectLocalID, dupeOnRay.AgentData.DuplicateFlags, | 8533 | |
7925 | AgentId, ActiveGroupId, dupeOnRay.AgentData.RayTargetID, dupeOnRay.AgentData.RayEnd, | 8534 | UUID rezGroupID = dupeOnRay.AgentData.GroupID; |
7926 | dupeOnRay.AgentData.RayStart, dupeOnRay.AgentData.BypassRaycast, dupeOnRay.AgentData.RayEndIsIntersection, | 8535 | if(!IsGroupMember(rezGroupID)) |
7927 | dupeOnRay.AgentData.CopyCenters, dupeOnRay.AgentData.CopyRotates); | 8536 | rezGroupID = UUID.Zero; |
8537 | |||
8538 | handlerObjectDuplicateOnRay(dupeOnRay.ObjectData[i].ObjectLocalID, | ||
8539 | dupeOnRay.AgentData.DuplicateFlags, AgentId, rezGroupID, | ||
8540 | dupeOnRay.AgentData.RayTargetID, dupeOnRay.AgentData.RayEnd, | ||
8541 | dupeOnRay.AgentData.RayStart, dupeOnRay.AgentData.BypassRaycast, | ||
8542 | dupeOnRay.AgentData.RayEndIsIntersection, | ||
8543 | dupeOnRay.AgentData.CopyCenters, dupeOnRay.AgentData.CopyRotates); | ||
7928 | } | 8544 | } |
7929 | } | 8545 | } |
7930 | 8546 | ||
@@ -9106,7 +9722,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9106 | if ((locX >= m_scene.RegionInfo.WorldLocX) | 9722 | if ((locX >= m_scene.RegionInfo.WorldLocX) |
9107 | && (locX < (m_scene.RegionInfo.WorldLocX + m_scene.RegionInfo.RegionSizeX)) | 9723 | && (locX < (m_scene.RegionInfo.WorldLocX + m_scene.RegionInfo.RegionSizeX)) |
9108 | && (locY >= m_scene.RegionInfo.WorldLocY) | 9724 | && (locY >= m_scene.RegionInfo.WorldLocY) |
9109 | && (locY < (m_scene.RegionInfo.WorldLocY + m_scene.RegionInfo.RegionSizeY)) ) | 9725 | && (locY < (m_scene.RegionInfo.WorldLocY + m_scene.RegionInfo.RegionSizeY))) |
9110 | { | 9726 | { |
9111 | tpLocReq.Info.RegionHandle = m_scene.RegionInfo.RegionHandle; | 9727 | tpLocReq.Info.RegionHandle = m_scene.RegionInfo.RegionHandle; |
9112 | tpLocReq.Info.Position.X += locX - m_scene.RegionInfo.WorldLocX; | 9728 | tpLocReq.Info.Position.X += locX - m_scene.RegionInfo.WorldLocX; |
@@ -9131,6 +9747,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9131 | 9747 | ||
9132 | private bool HandleUUIDNameRequest(IClientAPI sender, Packet Pack) | 9748 | private bool HandleUUIDNameRequest(IClientAPI sender, Packet Pack) |
9133 | { | 9749 | { |
9750 | ScenePresence sp = (ScenePresence)SceneAgent; | ||
9751 | if(sp == null || sp.IsDeleted || (sp.IsInTransit && !sp.IsInLocalTransit)) | ||
9752 | return true; | ||
9753 | |||
9134 | UUIDNameRequestPacket incoming = (UUIDNameRequestPacket)Pack; | 9754 | UUIDNameRequestPacket incoming = (UUIDNameRequestPacket)Pack; |
9135 | 9755 | ||
9136 | foreach (UUIDNameRequestPacket.UUIDNameBlockBlock UUIDBlock in incoming.UUIDNameBlock) | 9756 | foreach (UUIDNameRequestPacket.UUIDNameBlockBlock UUIDBlock in incoming.UUIDNameBlock) |
@@ -9148,13 +9768,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9148 | 9768 | ||
9149 | private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack) | 9769 | private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack) |
9150 | { | 9770 | { |
9151 | RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; | ||
9152 | |||
9153 | RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; | 9771 | RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; |
9772 | |||
9154 | if (handlerRegionHandleRequest != null) | 9773 | if (handlerRegionHandleRequest != null) |
9155 | { | 9774 | { |
9775 | RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; | ||
9156 | handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); | 9776 | handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); |
9157 | } | 9777 | } |
9778 | |||
9158 | return true; | 9779 | return true; |
9159 | } | 9780 | } |
9160 | 9781 | ||
@@ -9730,6 +10351,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9730 | if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false)) | 10351 | if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false)) |
9731 | { | 10352 | { |
9732 | int estateAccessType = Convert.ToInt16(Utils.BytesToString(messagePacket.ParamList[1].Parameter)); | 10353 | int estateAccessType = Convert.ToInt16(Utils.BytesToString(messagePacket.ParamList[1].Parameter)); |
10354 | |||
9733 | OnUpdateEstateAccessDeltaRequest(this, messagePacket.MethodData.Invoice, estateAccessType, new UUID(Utils.BytesToString(messagePacket.ParamList[2].Parameter))); | 10355 | OnUpdateEstateAccessDeltaRequest(this, messagePacket.MethodData.Invoice, estateAccessType, new UUID(Utils.BytesToString(messagePacket.ParamList[2].Parameter))); |
9734 | 10356 | ||
9735 | } | 10357 | } |
@@ -9765,7 +10387,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9765 | Message = Utils.BytesToString(messagePacket.ParamList[1].Parameter); | 10387 | Message = Utils.BytesToString(messagePacket.ParamList[1].Parameter); |
9766 | } | 10388 | } |
9767 | else | 10389 | else |
9768 | { | 10390 | { |
9769 | SenderID = new UUID(Utils.BytesToString(messagePacket.ParamList[2].Parameter)); | 10391 | SenderID = new UUID(Utils.BytesToString(messagePacket.ParamList[2].Parameter)); |
9770 | SenderName = Utils.BytesToString(messagePacket.ParamList[3].Parameter); | 10392 | SenderName = Utils.BytesToString(messagePacket.ParamList[3].Parameter); |
9771 | Message = Utils.BytesToString(messagePacket.ParamList[4].Parameter); | 10393 | Message = Utils.BytesToString(messagePacket.ParamList[4].Parameter); |
@@ -9907,7 +10529,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9907 | return true; | 10529 | return true; |
9908 | 10530 | ||
9909 | case "kickestate": | 10531 | case "kickestate": |
9910 | 10532 | ||
9911 | if(((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false)) | 10533 | if(((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false)) |
9912 | { | 10534 | { |
9913 | UUID invoice = messagePacket.MethodData.Invoice; | 10535 | UUID invoice = messagePacket.MethodData.Invoice; |
@@ -9986,6 +10608,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9986 | private bool HandleRequestGodlikePowers(IClientAPI sender, Packet Pack) | 10608 | private bool HandleRequestGodlikePowers(IClientAPI sender, Packet Pack) |
9987 | { | 10609 | { |
9988 | RequestGodlikePowersPacket rglpPack = (RequestGodlikePowersPacket)Pack; | 10610 | RequestGodlikePowersPacket rglpPack = (RequestGodlikePowersPacket)Pack; |
10611 | |||
10612 | if (rglpPack.AgentData.SessionID != SessionId || | ||
10613 | rglpPack.AgentData.AgentID != AgentId) | ||
10614 | return true; | ||
10615 | |||
9989 | RequestGodlikePowersPacket.RequestBlockBlock rblock = rglpPack.RequestBlock; | 10616 | RequestGodlikePowersPacket.RequestBlockBlock rblock = rglpPack.RequestBlock; |
9990 | UUID token = rblock.Token; | 10617 | UUID token = rblock.Token; |
9991 | 10618 | ||
@@ -9995,7 +10622,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9995 | 10622 | ||
9996 | if (handlerReqGodlikePowers != null) | 10623 | if (handlerReqGodlikePowers != null) |
9997 | { | 10624 | { |
9998 | handlerReqGodlikePowers(ablock.AgentID, ablock.SessionID, token, rblock.Godlike, this); | 10625 | handlerReqGodlikePowers(ablock.AgentID, ablock.SessionID, token, rblock.Godlike); |
9999 | } | 10626 | } |
10000 | 10627 | ||
10001 | return true; | 10628 | return true; |
@@ -10006,6 +10633,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10006 | GodUpdateRegionInfoPacket GodUpdateRegionInfo = | 10633 | GodUpdateRegionInfoPacket GodUpdateRegionInfo = |
10007 | (GodUpdateRegionInfoPacket)Packet; | 10634 | (GodUpdateRegionInfoPacket)Packet; |
10008 | 10635 | ||
10636 | if (GodUpdateRegionInfo.AgentData.SessionID != SessionId || | ||
10637 | GodUpdateRegionInfo.AgentData.AgentID != AgentId) | ||
10638 | return true; | ||
10639 | |||
10009 | GodUpdateRegionInfoUpdate handlerGodUpdateRegionInfo = OnGodUpdateRegionInfoUpdate; | 10640 | GodUpdateRegionInfoUpdate handlerGodUpdateRegionInfo = OnGodUpdateRegionInfoUpdate; |
10010 | if (handlerGodUpdateRegionInfo != null) | 10641 | if (handlerGodUpdateRegionInfo != null) |
10011 | { | 10642 | { |
@@ -10039,6 +10670,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10039 | GodlikeMessagePacket GodlikeMessage = | 10670 | GodlikeMessagePacket GodlikeMessage = |
10040 | (GodlikeMessagePacket)Packet; | 10671 | (GodlikeMessagePacket)Packet; |
10041 | 10672 | ||
10673 | if (GodlikeMessage.AgentData.SessionID != SessionId || | ||
10674 | GodlikeMessage.AgentData.AgentID != AgentId) | ||
10675 | return true; | ||
10676 | |||
10042 | GodlikeMessage handlerGodlikeMessage = onGodlikeMessage; | 10677 | GodlikeMessage handlerGodlikeMessage = onGodlikeMessage; |
10043 | if (handlerGodlikeMessage != null) | 10678 | if (handlerGodlikeMessage != null) |
10044 | { | 10679 | { |
@@ -10055,6 +10690,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10055 | { | 10690 | { |
10056 | StateSavePacket SaveStateMessage = | 10691 | StateSavePacket SaveStateMessage = |
10057 | (StateSavePacket)Packet; | 10692 | (StateSavePacket)Packet; |
10693 | |||
10694 | if (SaveStateMessage.AgentData.SessionID != SessionId || | ||
10695 | SaveStateMessage.AgentData.AgentID != AgentId) | ||
10696 | return true; | ||
10697 | |||
10058 | SaveStateHandler handlerSaveStatePacket = OnSaveState; | 10698 | SaveStateHandler handlerSaveStatePacket = OnSaveState; |
10059 | if (handlerSaveStatePacket != null) | 10699 | if (handlerSaveStatePacket != null) |
10060 | { | 10700 | { |
@@ -10068,30 +10708,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10068 | { | 10708 | { |
10069 | GodKickUserPacket gkupack = (GodKickUserPacket)Pack; | 10709 | GodKickUserPacket gkupack = (GodKickUserPacket)Pack; |
10070 | 10710 | ||
10071 | if (gkupack.UserInfo.GodSessionID == SessionId && AgentId == gkupack.UserInfo.GodID) | 10711 | if (gkupack.UserInfo.GodSessionID != SessionId || |
10072 | { | 10712 | gkupack.UserInfo.GodID != AgentId) |
10073 | GodKickUser handlerGodKickUser = OnGodKickUser; | 10713 | return true; |
10074 | if (handlerGodKickUser != null) | 10714 | |
10075 | { | 10715 | GodKickUser handlerGodKickUser = OnGodKickUser; |
10076 | handlerGodKickUser(gkupack.UserInfo.GodID, gkupack.UserInfo.GodSessionID, | 10716 | if (handlerGodKickUser != null) |
10077 | gkupack.UserInfo.AgentID, gkupack.UserInfo.KickFlags, gkupack.UserInfo.Reason); | ||
10078 | } | ||
10079 | } | ||
10080 | else | ||
10081 | { | 10717 | { |
10082 | SendAgentAlertMessage("Kick request denied", false); | 10718 | handlerGodKickUser(gkupack.UserInfo.GodID, gkupack.UserInfo.AgentID, gkupack.UserInfo.KickFlags, gkupack.UserInfo.Reason); |
10083 | } | 10719 | } |
10084 | //KickUserPacket kupack = new KickUserPacket(); | ||
10085 | //KickUserPacket.UserInfoBlock kupackib = kupack.UserInfo; | ||
10086 | |||
10087 | //kupack.UserInfo.AgentID = gkupack.UserInfo.AgentID; | ||
10088 | //kupack.UserInfo.SessionID = gkupack.UserInfo.GodSessionID; | ||
10089 | 10720 | ||
10090 | //kupack.TargetBlock.TargetIP = (uint)0; | ||
10091 | //kupack.TargetBlock.TargetPort = (ushort)0; | ||
10092 | //kupack.UserInfo.Reason = gkupack.UserInfo.Reason; | ||
10093 | |||
10094 | //OutPacket(kupack, ThrottleOutPacketType.Task); | ||
10095 | return true; | 10721 | return true; |
10096 | } | 10722 | } |
10097 | #endregion GodPackets | 10723 | #endregion GodPackets |
@@ -10410,9 +11036,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10410 | } | 11036 | } |
10411 | else | 11037 | else |
10412 | { | 11038 | { |
10413 | SendUseCachedMuteList(); | 11039 | if(muteListRequest.MuteData.MuteCRC == 0) |
11040 | SendEmpytMuteList(); | ||
11041 | else | ||
11042 | SendUseCachedMuteList(); | ||
10414 | } | 11043 | } |
10415 | return true; | 11044 | return true; |
10416 | } | 11045 | } |
10417 | 11046 | ||
10418 | private bool HandleUpdateMuteListEntry(IClientAPI client, Packet Packet) | 11047 | private bool HandleUpdateMuteListEntry(IClientAPI client, Packet Packet) |
@@ -10425,7 +11054,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10425 | handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, | 11054 | handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, |
10426 | Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), | 11055 | Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), |
10427 | UpdateMuteListEntry.MuteData.MuteType, | 11056 | UpdateMuteListEntry.MuteData.MuteType, |
10428 | UpdateMuteListEntry.AgentData.AgentID); | 11057 | UpdateMuteListEntry.MuteData.MuteFlags); |
10429 | return true; | 11058 | return true; |
10430 | } | 11059 | } |
10431 | return false; | 11060 | return false; |
@@ -10440,8 +11069,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10440 | { | 11069 | { |
10441 | handlerRemoveMuteListEntry(this, | 11070 | handlerRemoveMuteListEntry(this, |
10442 | RemoveMuteListEntry.MuteData.MuteID, | 11071 | RemoveMuteListEntry.MuteData.MuteID, |
10443 | Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), | 11072 | Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName)); |
10444 | RemoveMuteListEntry.AgentData.AgentID); | ||
10445 | return true; | 11073 | return true; |
10446 | } | 11074 | } |
10447 | return false; | 11075 | return false; |
@@ -10485,16 +11113,62 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10485 | return false; | 11113 | return false; |
10486 | } | 11114 | } |
10487 | 11115 | ||
11116 | private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet) | ||
11117 | { | ||
11118 | ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags = | ||
11119 | (ChangeInventoryItemFlagsPacket)packet; | ||
11120 | ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags; | ||
11121 | if (handlerChangeInventoryItemFlags != null) | ||
11122 | { | ||
11123 | foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData) | ||
11124 | handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags); | ||
11125 | return true; | ||
11126 | } | ||
11127 | return false; | ||
11128 | } | ||
11129 | |||
10488 | private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) | 11130 | private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) |
10489 | { | 11131 | { |
10490 | return true; | 11132 | return true; |
10491 | } | 11133 | } |
10492 | 11134 | ||
11135 | private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack) | ||
11136 | { | ||
11137 | CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack; | ||
11138 | |||
11139 | #region Packet Session and User Check | ||
11140 | if (m_checkPackets) | ||
11141 | { | ||
11142 | if (packet.AgentData.SessionID != SessionId || | ||
11143 | packet.AgentData.AgentID != AgentId) | ||
11144 | return true; | ||
11145 | } | ||
11146 | #endregion | ||
11147 | MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null; | ||
11148 | List<InventoryItemBase> items = new List<InventoryItemBase>(); | ||
11149 | foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData) | ||
11150 | { | ||
11151 | InventoryItemBase b = new InventoryItemBase(); | ||
11152 | b.ID = n.OldItemID; | ||
11153 | b.Folder = n.OldFolderID; | ||
11154 | items.Add(b); | ||
11155 | } | ||
11156 | |||
11157 | handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy; | ||
11158 | if (handlerMoveItemsAndLeaveCopy != null) | ||
11159 | { | ||
11160 | handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID); | ||
11161 | } | ||
11162 | |||
11163 | return true; | ||
11164 | } | ||
11165 | |||
10493 | private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) | 11166 | private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) |
10494 | { | 11167 | { |
10495 | return true; | 11168 | return true; |
10496 | } | 11169 | } |
10497 | 11170 | ||
11171 | |||
10498 | private bool HandleInventoryDescendents(IClientAPI sender, Packet Pack) | 11172 | private bool HandleInventoryDescendents(IClientAPI sender, Packet Pack) |
10499 | { | 11173 | { |
10500 | return true; | 11174 | return true; |
@@ -10748,7 +11422,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10748 | if (m_GroupsModule != null) | 11422 | if (m_GroupsModule != null) |
10749 | { | 11423 | { |
10750 | m_GroupsModule.ActivateGroup(this, activateGroupPacket.AgentData.GroupID); | 11424 | m_GroupsModule.ActivateGroup(this, activateGroupPacket.AgentData.GroupID); |
10751 | m_GroupsModule.SendAgentGroupDataUpdate(this); | ||
10752 | } | 11425 | } |
10753 | return true; | 11426 | return true; |
10754 | 11427 | ||
@@ -10873,11 +11546,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10873 | } | 11546 | } |
10874 | return true; | 11547 | return true; |
10875 | } | 11548 | } |
11549 | |||
11550 | UUID lastGroupProfileRequestID = UUID.Zero; | ||
11551 | double lastGroupProfileRequestTS = Util.GetTimeStampMS(); | ||
11552 | |||
10876 | private bool HandleGroupProfileRequest(IClientAPI sender, Packet Pack) | 11553 | private bool HandleGroupProfileRequest(IClientAPI sender, Packet Pack) |
10877 | { | 11554 | { |
11555 | if(m_GroupsModule == null) | ||
11556 | return true; | ||
11557 | |||
10878 | GroupProfileRequestPacket groupProfileRequest = | 11558 | GroupProfileRequestPacket groupProfileRequest = |
10879 | (GroupProfileRequestPacket)Pack; | 11559 | (GroupProfileRequestPacket)Pack; |
10880 | 11560 | ||
11561 | |||
10881 | #region Packet Session and User Check | 11562 | #region Packet Session and User Check |
10882 | if (m_checkPackets) | 11563 | if (m_checkPackets) |
10883 | { | 11564 | { |
@@ -10887,36 +11568,62 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10887 | } | 11568 | } |
10888 | #endregion | 11569 | #endregion |
10889 | 11570 | ||
10890 | if (m_GroupsModule != null) | 11571 | UUID grpID = groupProfileRequest.GroupData.GroupID; |
10891 | { | 11572 | double ts = Util.GetTimeStampMS(); |
10892 | GroupProfileReplyPacket groupProfileReply = (GroupProfileReplyPacket)PacketPool.Instance.GetPacket(PacketType.GroupProfileReply); | 11573 | if(grpID == lastGroupProfileRequestID && ts - lastGroupProfileRequestTS < 10000) |
11574 | return true; | ||
10893 | 11575 | ||
10894 | groupProfileReply.AgentData = new GroupProfileReplyPacket.AgentDataBlock(); | 11576 | lastGroupProfileRequestID = grpID; |
10895 | groupProfileReply.GroupData = new GroupProfileReplyPacket.GroupDataBlock(); | 11577 | lastGroupProfileRequestTS = ts; |
10896 | groupProfileReply.AgentData.AgentID = AgentId; | ||
10897 | 11578 | ||
10898 | GroupProfileData d = m_GroupsModule.GroupProfileRequest(this, | 11579 | GroupProfileReplyPacket groupProfileReply = (GroupProfileReplyPacket)PacketPool.Instance.GetPacket(PacketType.GroupProfileReply); |
10899 | groupProfileRequest.GroupData.GroupID); | ||
10900 | 11580 | ||
10901 | groupProfileReply.GroupData.GroupID = d.GroupID; | 11581 | groupProfileReply.AgentData = new GroupProfileReplyPacket.AgentDataBlock(); |
10902 | groupProfileReply.GroupData.Name = Util.StringToBytes256(d.Name); | 11582 | groupProfileReply.GroupData = new GroupProfileReplyPacket.GroupDataBlock(); |
10903 | groupProfileReply.GroupData.Charter = Util.StringToBytes1024(d.Charter); | 11583 | groupProfileReply.AgentData.AgentID = AgentId; |
10904 | groupProfileReply.GroupData.ShowInList = d.ShowInList; | ||
10905 | groupProfileReply.GroupData.MemberTitle = Util.StringToBytes256(d.MemberTitle); | ||
10906 | groupProfileReply.GroupData.PowersMask = d.PowersMask; | ||
10907 | groupProfileReply.GroupData.InsigniaID = d.InsigniaID; | ||
10908 | groupProfileReply.GroupData.FounderID = d.FounderID; | ||
10909 | groupProfileReply.GroupData.MembershipFee = d.MembershipFee; | ||
10910 | groupProfileReply.GroupData.OpenEnrollment = d.OpenEnrollment; | ||
10911 | groupProfileReply.GroupData.Money = d.Money; | ||
10912 | groupProfileReply.GroupData.GroupMembershipCount = d.GroupMembershipCount; | ||
10913 | groupProfileReply.GroupData.GroupRolesCount = d.GroupRolesCount; | ||
10914 | groupProfileReply.GroupData.AllowPublish = d.AllowPublish; | ||
10915 | groupProfileReply.GroupData.MaturePublish = d.MaturePublish; | ||
10916 | groupProfileReply.GroupData.OwnerRole = d.OwnerRole; | ||
10917 | 11584 | ||
10918 | OutPacket(groupProfileReply, ThrottleOutPacketType.Task); | 11585 | GroupProfileData d = m_GroupsModule.GroupProfileRequest(this, |
11586 | groupProfileRequest.GroupData.GroupID); | ||
11587 | |||
11588 | if(d.GroupID == UUID.Zero) // don't send broken data | ||
11589 | return true; | ||
11590 | |||
11591 | groupProfileReply.GroupData.GroupID = d.GroupID; | ||
11592 | groupProfileReply.GroupData.Name = Util.StringToBytes256(d.Name); | ||
11593 | groupProfileReply.GroupData.Charter = Util.StringToBytes1024(d.Charter); | ||
11594 | groupProfileReply.GroupData.ShowInList = d.ShowInList; | ||
11595 | groupProfileReply.GroupData.MemberTitle = Util.StringToBytes256(d.MemberTitle); | ||
11596 | groupProfileReply.GroupData.PowersMask = d.PowersMask; | ||
11597 | groupProfileReply.GroupData.InsigniaID = d.InsigniaID; | ||
11598 | groupProfileReply.GroupData.FounderID = d.FounderID; | ||
11599 | groupProfileReply.GroupData.MembershipFee = d.MembershipFee; | ||
11600 | groupProfileReply.GroupData.OpenEnrollment = d.OpenEnrollment; | ||
11601 | groupProfileReply.GroupData.Money = d.Money; | ||
11602 | groupProfileReply.GroupData.GroupMembershipCount = d.GroupMembershipCount; | ||
11603 | groupProfileReply.GroupData.GroupRolesCount = d.GroupRolesCount; | ||
11604 | groupProfileReply.GroupData.AllowPublish = d.AllowPublish; | ||
11605 | groupProfileReply.GroupData.MaturePublish = d.MaturePublish; | ||
11606 | groupProfileReply.GroupData.OwnerRole = d.OwnerRole; | ||
11607 | |||
11608 | Scene scene = (Scene)m_scene; | ||
11609 | if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID))) | ||
11610 | { | ||
11611 | ScenePresence p; | ||
11612 | if (scene.TryGetScenePresence(sender.AgentId, out p)) | ||
11613 | { | ||
11614 | if (p.IsViewerUIGod) | ||
11615 | { | ||
11616 | groupProfileReply.GroupData.OpenEnrollment = true; | ||
11617 | groupProfileReply.GroupData.MembershipFee = 0; | ||
11618 | } | ||
11619 | } | ||
10919 | } | 11620 | } |
11621 | |||
11622 | OutPacket(groupProfileReply, ThrottleOutPacketType.Task); | ||
11623 | |||
11624 | if(grpID == lastGroupProfileRequestID) | ||
11625 | lastGroupProfileRequestTS = Util.GetTimeStampMS() - 7000; | ||
11626 | |||
10920 | return true; | 11627 | return true; |
10921 | } | 11628 | } |
10922 | private bool HandleGroupMembersRequest(IClientAPI sender, Packet Pack) | 11629 | private bool HandleGroupMembersRequest(IClientAPI sender, Packet Pack) |
@@ -10939,12 +11646,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10939 | m_GroupsModule.GroupMembersRequest(this, groupMembersRequestPacket.GroupData.GroupID); | 11646 | m_GroupsModule.GroupMembersRequest(this, groupMembersRequestPacket.GroupData.GroupID); |
10940 | 11647 | ||
10941 | int memberCount = members.Count; | 11648 | int memberCount = members.Count; |
10942 | 11649 | int indx = 0; | |
10943 | while (true) | 11650 | while (indx < memberCount) |
10944 | { | 11651 | { |
10945 | int blockCount = members.Count; | 11652 | int blockCount = memberCount - indx; |
10946 | if (blockCount > 40) | 11653 | if (blockCount > 25) |
10947 | blockCount = 40; | 11654 | blockCount = 25; |
10948 | 11655 | ||
10949 | GroupMembersReplyPacket groupMembersReply = (GroupMembersReplyPacket)PacketPool.Instance.GetPacket(PacketType.GroupMembersReply); | 11656 | GroupMembersReplyPacket groupMembersReply = (GroupMembersReplyPacket)PacketPool.Instance.GetPacket(PacketType.GroupMembersReply); |
10950 | 11657 | ||
@@ -10965,8 +11672,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10965 | 11672 | ||
10966 | for (int i = 0; i < blockCount; i++) | 11673 | for (int i = 0; i < blockCount; i++) |
10967 | { | 11674 | { |
10968 | GroupMembersData m = members[0]; | 11675 | GroupMembersData m = members[indx++]; |
10969 | members.RemoveAt(0); | ||
10970 | 11676 | ||
10971 | groupMembersReply.MemberData[i] = | 11677 | groupMembersReply.MemberData[i] = |
10972 | new GroupMembersReplyPacket.MemberDataBlock(); | 11678 | new GroupMembersReplyPacket.MemberDataBlock(); |
@@ -10984,8 +11690,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10984 | m.IsOwner; | 11690 | m.IsOwner; |
10985 | } | 11691 | } |
10986 | OutPacket(groupMembersReply, ThrottleOutPacketType.Task); | 11692 | OutPacket(groupMembersReply, ThrottleOutPacketType.Task); |
10987 | if (members.Count == 0) | ||
10988 | return true; | ||
10989 | } | 11693 | } |
10990 | } | 11694 | } |
10991 | return true; | 11695 | return true; |
@@ -11488,11 +12192,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11488 | 12192 | ||
11489 | StartLure handlerStartLure = OnStartLure; | 12193 | StartLure handlerStartLure = OnStartLure; |
11490 | if (handlerStartLure != null) | 12194 | if (handlerStartLure != null) |
11491 | handlerStartLure(startLureRequest.Info.LureType, | 12195 | { |
11492 | Utils.BytesToString( | 12196 | for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++) |
11493 | startLureRequest.Info.Message), | 12197 | { |
11494 | startLureRequest.TargetData[0].TargetID, | 12198 | handlerStartLure(startLureRequest.Info.LureType, |
11495 | this); | 12199 | Utils.BytesToString( |
12200 | startLureRequest.Info.Message), | ||
12201 | startLureRequest.TargetData[i].TargetID, | ||
12202 | this); | ||
12203 | } | ||
12204 | } | ||
11496 | return true; | 12205 | return true; |
11497 | } | 12206 | } |
11498 | private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) | 12207 | private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) |
@@ -11606,10 +12315,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11606 | } | 12315 | } |
11607 | #endregion | 12316 | #endregion |
11608 | 12317 | ||
11609 | ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; | 12318 | ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; |
11610 | if (handlerClassifiedGodDelete != null) | 12319 | if (handlerClassifiedGodDelete != null) |
11611 | handlerClassifiedGodDelete( | 12320 | handlerClassifiedGodDelete( |
11612 | classifiedGodDelete.Data.ClassifiedID, | 12321 | classifiedGodDelete.Data.ClassifiedID, |
12322 | classifiedGodDelete.Data.QueryID, | ||
11613 | this); | 12323 | this); |
11614 | return true; | 12324 | return true; |
11615 | } | 12325 | } |
@@ -11833,6 +12543,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11833 | return true; | 12543 | return true; |
11834 | } | 12544 | } |
11835 | 12545 | ||
12546 | private bool HandleRevokePermissions(IClientAPI sender, Packet Pack) | ||
12547 | { | ||
12548 | RevokePermissionsPacket pkt = (RevokePermissionsPacket)Pack; | ||
12549 | if (pkt.AgentData.SessionID != SessionId || | ||
12550 | pkt .AgentData.AgentID != AgentId) | ||
12551 | return true; | ||
12552 | |||
12553 | // don't use multidelegate "event" | ||
12554 | ScenePresence sp = (ScenePresence)SceneAgent; | ||
12555 | if(sp != null && !sp.IsDeleted && !sp.IsInTransit) | ||
12556 | { | ||
12557 | UUID objectID = pkt.Data.ObjectID; | ||
12558 | uint permissions = pkt.Data.ObjectPermissions; | ||
12559 | |||
12560 | sp.HandleRevokePermissions(objectID , permissions); | ||
12561 | } | ||
12562 | return true; | ||
12563 | } | ||
11836 | private bool HandlePlacesQuery(IClientAPI sender, Packet Pack) | 12564 | private bool HandlePlacesQuery(IClientAPI sender, Packet Pack) |
11837 | { | 12565 | { |
11838 | PlacesQueryPacket placesQueryPacket = | 12566 | PlacesQueryPacket placesQueryPacket = |
@@ -11865,7 +12593,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11865 | scriptQuestion.Data.Questions = question; | 12593 | scriptQuestion.Data.Questions = question; |
11866 | scriptQuestion.Data.ObjectName = Util.StringToBytes256(taskName); | 12594 | scriptQuestion.Data.ObjectName = Util.StringToBytes256(taskName); |
11867 | scriptQuestion.Data.ObjectOwner = Util.StringToBytes256(ownerName); | 12595 | scriptQuestion.Data.ObjectOwner = Util.StringToBytes256(ownerName); |
11868 | 12596 | ||
11869 | OutPacket(scriptQuestion, ThrottleOutPacketType.Task); | 12597 | OutPacket(scriptQuestion, ThrottleOutPacketType.Task); |
11870 | } | 12598 | } |
11871 | 12599 | ||
@@ -11912,86 +12640,52 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11912 | /// <param name="simclient"></param> | 12640 | /// <param name="simclient"></param> |
11913 | /// <param name="packet"></param> | 12641 | /// <param name="packet"></param> |
11914 | /// <returns></returns> | 12642 | /// <returns></returns> |
12643 | |||
11915 | protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet) | 12644 | protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet) |
11916 | { | 12645 | { |
12646 | //m_log.Debug("texture cached: " + packet.ToString()); | ||
11917 | AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet; | 12647 | AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet; |
11918 | AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse); | 12648 | AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse); |
11919 | 12649 | ||
11920 | if (cachedtex.AgentData.SessionID != SessionId) | 12650 | if (cachedtex.AgentData.SessionID != SessionId) |
11921 | return false; | 12651 | return false; |
11922 | 12652 | ||
11923 | |||
11924 | // TODO: don't create new blocks if recycling an old packet | 12653 | // TODO: don't create new blocks if recycling an old packet |
11925 | cachedresp.AgentData.AgentID = AgentId; | 12654 | cachedresp.AgentData.AgentID = AgentId; |
11926 | cachedresp.AgentData.SessionID = m_sessionId; | 12655 | cachedresp.AgentData.SessionID = m_sessionId; |
11927 | cachedresp.AgentData.SerialNum = m_cachedTextureSerial; | 12656 | cachedresp.AgentData.SerialNum = cachedtex.AgentData.SerialNum; |
11928 | m_cachedTextureSerial++; | ||
11929 | cachedresp.WearableData = | 12657 | cachedresp.WearableData = |
11930 | new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length]; | 12658 | new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length]; |
11931 | 12659 | ||
11932 | int maxWearablesLoop = cachedtex.WearableData.Length; | 12660 | int cacheHits = 0; |
11933 | if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES) | ||
11934 | maxWearablesLoop = AvatarWearable.MAX_WEARABLES; | ||
11935 | 12661 | ||
11936 | // Find the cached baked textures for this user, if they're available | 12662 | // We need to make sure the asset stored in the bake is available on this server also by it's assetid before we map it to a Cacheid |
11937 | 12663 | ||
11938 | IAssetService cache = m_scene.AssetService; | ||
11939 | IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>(); | ||
11940 | |||
11941 | WearableCacheItem[] cacheItems = null; | 12664 | WearableCacheItem[] cacheItems = null; |
11942 | 12665 | ||
11943 | if (bakedTextureModule != null && cache != null) | 12666 | ScenePresence p = m_scene.GetScenePresence(AgentId); |
11944 | { | ||
11945 | ScenePresence p = m_scene.GetScenePresence(AgentId); | ||
11946 | if (p.Appearance != null) | ||
11947 | { | ||
11948 | if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty) | ||
11949 | { | ||
11950 | try | ||
11951 | { | ||
11952 | cacheItems = bakedTextureModule.Get(AgentId); | ||
11953 | p.Appearance.WearableCacheItems = cacheItems; | ||
11954 | p.Appearance.WearableCacheItemsDirty = false; | ||
11955 | } | ||
11956 | catch (Exception) | ||
11957 | { | ||
11958 | cacheItems = null; | ||
11959 | } | ||
11960 | 12667 | ||
11961 | } | 12668 | if (p != null && p.Appearance != null) |
11962 | else if (p.Appearance.WearableCacheItems != null) | 12669 | { |
11963 | { | 12670 | cacheItems = p.Appearance.WearableCacheItems; |
11964 | cacheItems = p.Appearance.WearableCacheItems; | ||
11965 | } | ||
11966 | } | ||
11967 | } | 12671 | } |
11968 | 12672 | ||
12673 | int maxWearablesLoop = cachedtex.WearableData.Length; | ||
12674 | |||
11969 | if (cacheItems != null) | 12675 | if (cacheItems != null) |
11970 | { | 12676 | { |
11971 | // We need to make sure the asset stored in the bake is available on this server also by its assetid before we map it to a Cacheid. | 12677 | if (maxWearablesLoop > cacheItems.Length) |
11972 | // Copy the baked textures to the sim's assets cache (local only). | 12678 | maxWearablesLoop = cacheItems.Length; |
11973 | foreach (WearableCacheItem item in cacheItems) | ||
11974 | { | ||
11975 | if (cache.GetCached(item.TextureID.ToString()) == null) | ||
11976 | { | ||
11977 | item.TextureAsset.Temporary = true; | ||
11978 | item.TextureAsset.Local = true; | ||
11979 | cache.Store(item.TextureAsset); | ||
11980 | } | ||
11981 | } | ||
11982 | |||
11983 | // Return the cached textures | ||
11984 | for (int i = 0; i < maxWearablesLoop; i++) | 12679 | for (int i = 0; i < maxWearablesLoop; i++) |
11985 | { | 12680 | { |
11986 | WearableCacheItem item = | 12681 | int idx = cachedtex.WearableData[i].TextureIndex; |
11987 | WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex, cacheItems); | ||
11988 | |||
11989 | cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); | 12682 | cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); |
11990 | cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; | 12683 | cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; |
11991 | cachedresp.WearableData[i].HostName = new byte[0]; | 12684 | cachedresp.WearableData[i].HostName = new byte[0]; |
11992 | if (item != null && cachedtex.WearableData[i].ID == item.CacheId) | 12685 | if (cachedtex.WearableData[i].ID == cacheItems[idx].CacheId) |
11993 | { | 12686 | { |
11994 | cachedresp.WearableData[i].TextureID = item.TextureID; | 12687 | cachedresp.WearableData[i].TextureID = cacheItems[idx].TextureID; |
12688 | cacheHits++; | ||
11995 | } | 12689 | } |
11996 | else | 12690 | else |
11997 | { | 12691 | { |
@@ -12001,7 +12695,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12001 | } | 12695 | } |
12002 | else | 12696 | else |
12003 | { | 12697 | { |
12004 | // Cached textures not available | ||
12005 | for (int i = 0; i < maxWearablesLoop; i++) | 12698 | for (int i = 0; i < maxWearablesLoop; i++) |
12006 | { | 12699 | { |
12007 | cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); | 12700 | cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); |
@@ -12010,13 +12703,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12010 | cachedresp.WearableData[i].HostName = new byte[0]; | 12703 | cachedresp.WearableData[i].HostName = new byte[0]; |
12011 | } | 12704 | } |
12012 | } | 12705 | } |
12013 | 12706 | ||
12707 | //m_log.DebugFormat("texture cached: hits {0}", cacheHits); | ||
12708 | |||
12014 | cachedresp.Header.Zerocoded = true; | 12709 | cachedresp.Header.Zerocoded = true; |
12015 | OutPacket(cachedresp, ThrottleOutPacketType.Task); | 12710 | OutPacket(cachedresp, ThrottleOutPacketType.Task); |
12016 | 12711 | ||
12017 | return true; | 12712 | return true; |
12018 | } | 12713 | } |
12019 | 12714 | ||
12020 | /// <summary> | 12715 | /// <summary> |
12021 | /// Send a response back to a client when it asks the asset server (via the region server) if it has | 12716 | /// Send a response back to a client when it asks the asset server (via the region server) if it has |
12022 | /// its appearance texture cached. | 12717 | /// its appearance texture cached. |
@@ -12080,209 +12775,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12080 | } | 12775 | } |
12081 | else | 12776 | else |
12082 | { | 12777 | { |
12083 | // m_log.DebugFormat( | 12778 | ClientChangeObject updatehandler = onClientChangeObject; |
12084 | // "[CLIENT]: Processing block {0} type {1} for {2} {3}", | ||
12085 | // i, block.Type, part.Name, part.LocalId); | ||
12086 | 12779 | ||
12087 | // // Do this once since fetch parts creates a new array. | 12780 | if (updatehandler != null) |
12088 | // SceneObjectPart[] parts = part.ParentGroup.Parts; | 12781 | { |
12089 | // for (int j = 0; j < parts.Length; j++) | 12782 | ObjectChangeData udata = new ObjectChangeData(); |
12090 | // { | ||
12091 | // part.StoreUndoState(); | ||
12092 | // parts[j].IgnoreUndoUpdate = true; | ||
12093 | // } | ||
12094 | 12783 | ||
12095 | UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; | 12784 | /*ubit from ll JIRA: |
12785 | * 0x01 position | ||
12786 | * 0x02 rotation | ||
12787 | * 0x04 scale | ||
12096 | 12788 | ||
12097 | switch (block.Type) | 12789 | * 0x08 LINK_SET |
12098 | { | 12790 | * 0x10 UNIFORM for scale |
12099 | case 1: | 12791 | */ |
12100 | Vector3 pos1 = new Vector3(block.Data, 0); | ||
12101 | 12792 | ||
12102 | UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; | 12793 | // translate to internal changes |
12103 | if (handlerUpdatePrimSinglePosition != null) | 12794 | // not all cases .. just the ones older code did |
12104 | { | ||
12105 | // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); | ||
12106 | handlerUpdatePrimSinglePosition(localId, pos1, this); | ||
12107 | } | ||
12108 | break; | ||
12109 | 12795 | ||
12110 | case 2: | 12796 | switch (block.Type) |
12111 | Quaternion rot1 = new Quaternion(block.Data, 0, true); | 12797 | { |
12798 | case 1: //change position sp | ||
12799 | udata.position = new Vector3(block.Data, 0); | ||
12112 | 12800 | ||
12113 | UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; | 12801 | udata.change = ObjectChangeType.primP; |
12114 | if (handlerUpdatePrimSingleRotation != null) | 12802 | updatehandler(localId, udata, this); |
12115 | { | 12803 | break; |
12116 | // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W); | ||
12117 | handlerUpdatePrimSingleRotation(localId, rot1, this); | ||
12118 | } | ||
12119 | break; | ||
12120 | 12804 | ||
12121 | case 3: | 12805 | case 2: // rotation sp |
12122 | Vector3 rotPos = new Vector3(block.Data, 0); | 12806 | udata.rotation = new Quaternion(block.Data, 0, true); |
12123 | Quaternion rot2 = new Quaternion(block.Data, 12, true); | ||
12124 | 12807 | ||
12125 | UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; | 12808 | udata.change = ObjectChangeType.primR; |
12126 | if (handlerUpdatePrimSingleRotationPosition != null) | 12809 | updatehandler(localId, udata, this); |
12127 | { | 12810 | break; |
12128 | // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z); | ||
12129 | // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W); | ||
12130 | handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this); | ||
12131 | } | ||
12132 | break; | ||
12133 | 12811 | ||
12134 | case 4: | 12812 | case 3: // position plus rotation |
12135 | case 20: | 12813 | udata.position = new Vector3(block.Data, 0); |
12136 | Vector3 scale4 = new Vector3(block.Data, 0); | 12814 | udata.rotation = new Quaternion(block.Data, 12, true); |
12137 | 12815 | ||
12138 | UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; | 12816 | udata.change = ObjectChangeType.primPR; |
12139 | if (handlerUpdatePrimScale != null) | 12817 | updatehandler(localId, udata, this); |
12140 | { | 12818 | break; |
12141 | // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z); | ||
12142 | handlerUpdatePrimScale(localId, scale4, this); | ||
12143 | } | ||
12144 | break; | ||
12145 | 12819 | ||
12146 | case 5: | 12820 | case 4: // scale sp |
12147 | Vector3 scale1 = new Vector3(block.Data, 12); | 12821 | udata.scale = new Vector3(block.Data, 0); |
12148 | Vector3 pos11 = new Vector3(block.Data, 0); | 12822 | udata.change = ObjectChangeType.primS; |
12149 | 12823 | ||
12150 | handlerUpdatePrimScale = OnUpdatePrimScale; | 12824 | updatehandler(localId, udata, this); |
12151 | if (handlerUpdatePrimScale != null) | 12825 | break; |
12152 | { | ||
12153 | // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); | ||
12154 | handlerUpdatePrimScale(localId, scale1, this); | ||
12155 | 12826 | ||
12156 | handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; | 12827 | case 0x14: // uniform scale sp |
12157 | if (handlerUpdatePrimSinglePosition != null) | 12828 | udata.scale = new Vector3(block.Data, 0); |
12158 | { | ||
12159 | handlerUpdatePrimSinglePosition(localId, pos11, this); | ||
12160 | } | ||
12161 | } | ||
12162 | break; | ||
12163 | 12829 | ||
12164 | case 9: | 12830 | udata.change = ObjectChangeType.primUS; |
12165 | Vector3 pos2 = new Vector3(block.Data, 0); | 12831 | updatehandler(localId, udata, this); |
12832 | break; | ||
12166 | 12833 | ||
12167 | UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; | 12834 | case 5: // scale and position sp |
12835 | udata.position = new Vector3(block.Data, 0); | ||
12836 | udata.scale = new Vector3(block.Data, 12); | ||
12168 | 12837 | ||
12169 | if (handlerUpdateVector != null) | 12838 | udata.change = ObjectChangeType.primPS; |
12170 | { | 12839 | updatehandler(localId, udata, this); |
12171 | handlerUpdateVector(localId, pos2, this); | 12840 | break; |
12172 | } | ||
12173 | break; | ||
12174 | 12841 | ||
12175 | case 10: | 12842 | case 0x15: //uniform scale and position |
12176 | Quaternion rot3 = new Quaternion(block.Data, 0, true); | 12843 | udata.position = new Vector3(block.Data, 0); |
12844 | udata.scale = new Vector3(block.Data, 12); | ||
12177 | 12845 | ||
12178 | UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; | 12846 | udata.change = ObjectChangeType.primPUS; |
12179 | if (handlerUpdatePrimRotation != null) | 12847 | updatehandler(localId, udata, this); |
12180 | { | 12848 | break; |
12181 | // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W); | ||
12182 | handlerUpdatePrimRotation(localId, rot3, this); | ||
12183 | } | ||
12184 | break; | ||
12185 | 12849 | ||
12186 | case 11: | 12850 | // now group related (bit 4) |
12187 | Vector3 pos3 = new Vector3(block.Data, 0); | 12851 | case 9: //( 8 + 1 )group position |
12188 | Quaternion rot4 = new Quaternion(block.Data, 12, true); | 12852 | udata.position = new Vector3(block.Data, 0); |
12189 | 12853 | ||
12190 | handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; | 12854 | udata.change = ObjectChangeType.groupP; |
12191 | if (handlerUpdatePrimGroupRotation != null) | 12855 | updatehandler(localId, udata, this); |
12192 | { | 12856 | break; |
12193 | // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z); | ||
12194 | // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W); | ||
12195 | handlerUpdatePrimGroupRotation(localId, pos3, rot4, this); | ||
12196 | } | ||
12197 | break; | ||
12198 | case 12: | ||
12199 | case 28: | ||
12200 | Vector3 scale7 = new Vector3(block.Data, 0); | ||
12201 | 12857 | ||
12202 | UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; | 12858 | case 0x0A: // (8 + 2) group rotation |
12203 | if (handlerUpdatePrimGroupScale != null) | 12859 | udata.rotation = new Quaternion(block.Data, 0, true); |
12204 | { | ||
12205 | // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z); | ||
12206 | handlerUpdatePrimGroupScale(localId, scale7, this); | ||
12207 | } | ||
12208 | break; | ||
12209 | 12860 | ||
12210 | case 13: | 12861 | udata.change = ObjectChangeType.groupR; |
12211 | Vector3 scale2 = new Vector3(block.Data, 12); | 12862 | updatehandler(localId, udata, this); |
12212 | Vector3 pos4 = new Vector3(block.Data, 0); | 12863 | break; |
12213 | 12864 | ||
12214 | handlerUpdatePrimScale = OnUpdatePrimScale; | 12865 | case 0x0B: //( 8 + 2 + 1) group rotation and position |
12215 | if (handlerUpdatePrimScale != null) | 12866 | udata.position = new Vector3(block.Data, 0); |
12216 | { | 12867 | udata.rotation = new Quaternion(block.Data, 12, true); |
12217 | //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); | ||
12218 | handlerUpdatePrimScale(localId, scale2, this); | ||
12219 | 12868 | ||
12220 | // Change the position based on scale (for bug number 246) | 12869 | udata.change = ObjectChangeType.groupPR; |
12221 | handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; | 12870 | updatehandler(localId, udata, this); |
12222 | // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); | 12871 | break; |
12223 | if (handlerUpdatePrimSinglePosition != null) | ||
12224 | { | ||
12225 | handlerUpdatePrimSinglePosition(localId, pos4, this); | ||
12226 | } | ||
12227 | } | ||
12228 | break; | ||
12229 | 12872 | ||
12230 | case 29: | 12873 | case 0x0C: // (8 + 4) group scale |
12231 | Vector3 scale5 = new Vector3(block.Data, 12); | 12874 | // only afects root prim and only sent by viewer editor object tab scaling |
12232 | Vector3 pos5 = new Vector3(block.Data, 0); | 12875 | // mouse edition only allows uniform scaling |
12876 | // SL MAY CHANGE THIS in viewers | ||
12233 | 12877 | ||
12234 | handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; | 12878 | udata.scale = new Vector3(block.Data, 0); |
12235 | if (handlerUpdatePrimGroupScale != null) | ||
12236 | { | ||
12237 | // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); | ||
12238 | part.StoreUndoState(true); | ||
12239 | part.IgnoreUndoUpdate = true; | ||
12240 | handlerUpdatePrimGroupScale(localId, scale5, this); | ||
12241 | handlerUpdateVector = OnUpdatePrimGroupPosition; | ||
12242 | 12879 | ||
12243 | if (handlerUpdateVector != null) | 12880 | udata.change = ObjectChangeType.groupS; |
12244 | { | 12881 | updatehandler(localId, udata, this); |
12245 | handlerUpdateVector(localId, pos5, this); | ||
12246 | } | ||
12247 | 12882 | ||
12248 | part.IgnoreUndoUpdate = false; | 12883 | break; |
12249 | } | ||
12250 | 12884 | ||
12251 | break; | 12885 | case 0x0D: //(8 + 4 + 1) group scale and position |
12886 | // exception as above | ||
12252 | 12887 | ||
12253 | case 21: | 12888 | udata.position = new Vector3(block.Data, 0); |
12254 | Vector3 scale6 = new Vector3(block.Data, 12); | 12889 | udata.scale = new Vector3(block.Data, 12); |
12255 | Vector3 pos6 = new Vector3(block.Data, 0); | ||
12256 | 12890 | ||
12257 | handlerUpdatePrimScale = OnUpdatePrimScale; | 12891 | udata.change = ObjectChangeType.groupPS; |
12258 | if (handlerUpdatePrimScale != null) | 12892 | updatehandler(localId, udata, this); |
12259 | { | 12893 | break; |
12260 | part.StoreUndoState(false); | ||
12261 | part.IgnoreUndoUpdate = true; | ||
12262 | 12894 | ||
12263 | // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); | 12895 | case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM |
12264 | handlerUpdatePrimScale(localId, scale6, this); | 12896 | udata.scale = new Vector3(block.Data, 0); |
12265 | handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; | ||
12266 | if (handlerUpdatePrimSinglePosition != null) | ||
12267 | { | ||
12268 | handlerUpdatePrimSinglePosition(localId, pos6, this); | ||
12269 | } | ||
12270 | 12897 | ||
12271 | part.IgnoreUndoUpdate = false; | 12898 | udata.change = ObjectChangeType.groupUS; |
12272 | } | 12899 | updatehandler(localId, udata, this); |
12273 | break; | 12900 | break; |
12274 | 12901 | ||
12275 | default: | 12902 | case 0x1D: // (UNIFORM + GROUP + SCALE + POS) |
12276 | m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); | 12903 | udata.position = new Vector3(block.Data, 0); |
12277 | break; | 12904 | udata.scale = new Vector3(block.Data, 12); |
12905 | |||
12906 | udata.change = ObjectChangeType.groupPUS; | ||
12907 | updatehandler(localId, udata, this); | ||
12908 | break; | ||
12909 | |||
12910 | default: | ||
12911 | m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); | ||
12912 | break; | ||
12913 | } | ||
12278 | } | 12914 | } |
12279 | 12915 | ||
12280 | // for (int j = 0; j < parts.Length; j++) | ||
12281 | // parts[j].IgnoreUndoUpdate = false; | ||
12282 | } | 12916 | } |
12283 | } | 12917 | } |
12284 | } | 12918 | } |
12285 | |||
12286 | return true; | 12919 | return true; |
12287 | } | 12920 | } |
12288 | 12921 | ||
@@ -12342,7 +12975,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12342 | /// <param name="throttles"></param> | 12975 | /// <param name="throttles"></param> |
12343 | public void SetChildAgentThrottle(byte[] throttles) | 12976 | public void SetChildAgentThrottle(byte[] throttles) |
12344 | { | 12977 | { |
12345 | m_udpClient.SetThrottles(throttles); | 12978 | SetChildAgentThrottle(throttles, 1.0f); |
12979 | } | ||
12980 | |||
12981 | public void SetChildAgentThrottle(byte[] throttles,float factor) | ||
12982 | { | ||
12983 | m_udpClient.SetThrottles(throttles, factor); | ||
12984 | GenericCall2 handler = OnUpdateThrottles; | ||
12985 | if (handler != null) | ||
12986 | { | ||
12987 | handler(); | ||
12988 | } | ||
12989 | } | ||
12990 | |||
12991 | /// <summary> | ||
12992 | /// Sets the throttles from values supplied caller | ||
12993 | /// </summary> | ||
12994 | /// <param name="throttles"></param> | ||
12995 | public void SetAgentThrottleSilent(int throttle, int setting) | ||
12996 | { | ||
12997 | m_udpClient.ForceThrottleSetting(throttle,setting); | ||
12998 | } | ||
12999 | |||
13000 | public int GetAgentThrottleSilent(int throttle) | ||
13001 | { | ||
13002 | return m_udpClient.GetThrottleSetting(throttle); | ||
12346 | } | 13003 | } |
12347 | 13004 | ||
12348 | /// <summary> | 13005 | /// <summary> |
@@ -12403,9 +13060,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12403 | /// provide your own method.</param> | 13060 | /// provide your own method.</param> |
12404 | protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method) | 13061 | protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method) |
12405 | { | 13062 | { |
13063 | |||
13064 | /* this is causing packet loss for some reason | ||
13065 | if(!m_udpClient.IsConnected) | ||
13066 | { | ||
13067 | PacketPool.Instance.ReturnPacket(packet); | ||
13068 | return; | ||
13069 | } | ||
13070 | */ | ||
12406 | if (m_outPacketsToDrop != null) | 13071 | if (m_outPacketsToDrop != null) |
13072 | { | ||
12407 | if (m_outPacketsToDrop.Contains(packet.Type.ToString())) | 13073 | if (m_outPacketsToDrop.Contains(packet.Type.ToString())) |
13074 | { | ||
13075 | PacketPool.Instance.ReturnPacket(packet); | ||
12408 | return; | 13076 | return; |
13077 | } | ||
13078 | } | ||
12409 | 13079 | ||
12410 | if (DebugPacketLevel > 0) | 13080 | if (DebugPacketLevel > 0) |
12411 | { | 13081 | { |
@@ -12424,7 +13094,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12424 | 13094 | ||
12425 | if (DebugPacketLevel <= 100 && (packet.Type == PacketType.AvatarAnimation || packet.Type == PacketType.ViewerEffect)) | 13095 | if (DebugPacketLevel <= 100 && (packet.Type == PacketType.AvatarAnimation || packet.Type == PacketType.ViewerEffect)) |
12426 | logPacket = false; | 13096 | logPacket = false; |
12427 | 13097 | ||
12428 | if (DebugPacketLevel <= 50 | 13098 | if (DebugPacketLevel <= 50 |
12429 | && (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate)) | 13099 | && (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate)) |
12430 | logPacket = false; | 13100 | logPacket = false; |
@@ -12437,7 +13107,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12437 | "[CLIENT]: PACKET OUT to {0} ({1}) in {2} - {3}", | 13107 | "[CLIENT]: PACKET OUT to {0} ({1}) in {2} - {3}", |
12438 | Name, SceneAgent.IsChildAgent ? "child" : "root ", m_scene.RegionInfo.RegionName, packet.Type); | 13108 | Name, SceneAgent.IsChildAgent ? "child" : "root ", m_scene.RegionInfo.RegionName, packet.Type); |
12439 | } | 13109 | } |
12440 | 13110 | ||
12441 | m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting, method); | 13111 | m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting, method); |
12442 | } | 13112 | } |
12443 | 13113 | ||
@@ -12450,8 +13120,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12450 | uint regionY = 0; | 13120 | uint regionY = 0; |
12451 | 13121 | ||
12452 | Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out regionX, out regionY); | 13122 | Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out regionX, out regionY); |
12453 | locx = Convert.ToSingle(args[0]) - (float)regionX; | 13123 | locx = (float)(Convert.ToDouble(args[0]) - (double)regionX); |
12454 | locy = Convert.ToSingle(args[1]) - (float)regionY; | 13124 | locy = (float)(Convert.ToDouble(args[1]) - (double)regionY); |
12455 | locz = Convert.ToSingle(args[2]); | 13125 | locz = Convert.ToSingle(args[2]); |
12456 | 13126 | ||
12457 | Action<Vector3, bool, bool> handlerAutoPilotGo = OnAutoPilotGo; | 13127 | Action<Vector3, bool, bool> handlerAutoPilotGo = OnAutoPilotGo; |
@@ -12677,20 +13347,75 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12677 | 13347 | ||
12678 | public void RefreshGroupMembership() | 13348 | public void RefreshGroupMembership() |
12679 | { | 13349 | { |
12680 | if (m_GroupsModule != null) | 13350 | lock(m_groupPowers) |
12681 | { | 13351 | { |
12682 | GroupMembershipData[] GroupMembership = | 13352 | GroupMembershipData activeMembership = null; |
13353 | if (m_GroupsModule != null) | ||
13354 | { | ||
13355 | GroupMembershipData[] GroupMembership = | ||
12683 | m_GroupsModule.GetMembershipData(AgentId); | 13356 | m_GroupsModule.GetMembershipData(AgentId); |
12684 | 13357 | ||
12685 | m_groupPowers.Clear(); | 13358 | m_groupPowers.Clear(); |
12686 | 13359 | ||
12687 | if (GroupMembership != null) | 13360 | if (GroupMembership != null) |
12688 | { | 13361 | { |
12689 | for (int i = 0; i < GroupMembership.Length; i++) | 13362 | for (int i = 0; i < GroupMembership.Length; i++) |
13363 | { | ||
13364 | m_groupPowers[GroupMembership[i].GroupID] = GroupMembership[i].GroupPowers; | ||
13365 | } | ||
13366 | } | ||
13367 | |||
13368 | activeMembership = m_GroupsModule.GetActiveMembershipData(AgentId); | ||
13369 | if(activeMembership != null) | ||
12690 | { | 13370 | { |
12691 | m_groupPowers[GroupMembership[i].GroupID] = GroupMembership[i].GroupPowers; | 13371 | if(!m_groupPowers.ContainsKey(activeMembership.GroupID)) |
13372 | activeMembership = null; | ||
13373 | else | ||
13374 | { | ||
13375 | m_activeGroupID = activeMembership.GroupID; | ||
13376 | m_activeGroupName = activeMembership.GroupName; | ||
13377 | m_activeGroupPowers = ActiveGroupPowers; | ||
13378 | } | ||
12692 | } | 13379 | } |
12693 | } | 13380 | } |
13381 | |||
13382 | if(activeMembership == null) | ||
13383 | { | ||
13384 | m_activeGroupID = UUID.Zero; | ||
13385 | m_activeGroupName = ""; | ||
13386 | m_activeGroupPowers = 0; | ||
13387 | } | ||
13388 | } | ||
13389 | } | ||
13390 | |||
13391 | public void UpdateGroupMembership(GroupMembershipData[] data) | ||
13392 | { | ||
13393 | lock(m_groupPowers) | ||
13394 | { | ||
13395 | m_groupPowers.Clear(); | ||
13396 | |||
13397 | if (data != null) | ||
13398 | { | ||
13399 | for (int i = 0; i < data.Length; i++) | ||
13400 | m_groupPowers[data[i].GroupID] = data[i].GroupPowers; | ||
13401 | } | ||
13402 | } | ||
13403 | } | ||
13404 | |||
13405 | public void GroupMembershipRemove(UUID GroupID) | ||
13406 | { | ||
13407 | lock(m_groupPowers) | ||
13408 | { | ||
13409 | if(m_groupPowers.ContainsKey(GroupID)) | ||
13410 | m_groupPowers.Remove(GroupID); | ||
13411 | } | ||
13412 | } | ||
13413 | |||
13414 | public void GroupMembershipAddReplace(UUID GroupID,ulong GroupPowers) | ||
13415 | { | ||
13416 | lock(m_groupPowers) | ||
13417 | { | ||
13418 | m_groupPowers[GroupID] = GroupPowers; | ||
12694 | } | 13419 | } |
12695 | } | 13420 | } |
12696 | 13421 | ||
@@ -12736,7 +13461,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12736 | // "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", | 13461 | // "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", |
12737 | // requestID, taskID, (SourceType)sourceType, Name); | 13462 | // requestID, taskID, (SourceType)sourceType, Name); |
12738 | 13463 | ||
13464 | |||
13465 | //Note, the bool returned from the below function is useless since it is always false. | ||
12739 | m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); | 13466 | m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); |
13467 | |||
12740 | } | 13468 | } |
12741 | 13469 | ||
12742 | /// <summary> | 13470 | /// <summary> |
@@ -12782,7 +13510,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12782 | SendAssetNotFound(req); | 13510 | SendAssetNotFound(req); |
12783 | return; | 13511 | return; |
12784 | } | 13512 | } |
12785 | |||
12786 | } | 13513 | } |
12787 | 13514 | ||
12788 | if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset) | 13515 | if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset) |
@@ -12819,7 +13546,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12819 | /// <returns></returns> | 13546 | /// <returns></returns> |
12820 | private static int CalculateNumPackets(byte[] data) | 13547 | private static int CalculateNumPackets(byte[] data) |
12821 | { | 13548 | { |
12822 | const uint m_maxPacketSize = 600; | 13549 | // const uint m_maxPacketSize = 600; |
13550 | uint m_maxPacketSize = MaxTransferBytesPerPacket; | ||
12823 | int numPackets = 1; | 13551 | int numPackets = 1; |
12824 | 13552 | ||
12825 | if (data == null) | 13553 | if (data == null) |
@@ -12858,11 +13586,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12858 | /// </summary> | 13586 | /// </summary> |
12859 | public bool Async { get; set; } | 13587 | public bool Async { get; set; } |
12860 | 13588 | ||
12861 | /// <summary> | ||
12862 | /// If async is true, should this packet be handled in the async engine or given directly to a threadpool | ||
12863 | /// thread? | ||
12864 | /// </summary> | ||
12865 | public bool InEngine { get; set; } | ||
12866 | } | 13589 | } |
12867 | 13590 | ||
12868 | public class AsyncPacketProcess | 13591 | public class AsyncPacketProcess |
@@ -12930,7 +13653,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12930 | // this is the username of the *owner* | 13653 | // this is the username of the *owner* |
12931 | dialog.Data.FirstName = Util.StringToBytes256(ownerFirstName); | 13654 | dialog.Data.FirstName = Util.StringToBytes256(ownerFirstName); |
12932 | dialog.Data.LastName = Util.StringToBytes256(ownerLastName); | 13655 | dialog.Data.LastName = Util.StringToBytes256(ownerLastName); |
12933 | dialog.Data.Message = Util.StringToBytes256(message); | 13656 | dialog.Data.Message = Util.StringToBytes(message,512); |
12934 | 13657 | ||
12935 | ScriptDialogPacket.ButtonsBlock[] buttons = new ScriptDialogPacket.ButtonsBlock[1]; | 13658 | ScriptDialogPacket.ButtonsBlock[] buttons = new ScriptDialogPacket.ButtonsBlock[1]; |
12936 | buttons[0] = new ScriptDialogPacket.ButtonsBlock(); | 13659 | buttons[0] = new ScriptDialogPacket.ButtonsBlock(); |
@@ -12949,7 +13672,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12949 | if (p is ScenePresence) | 13672 | if (p is ScenePresence) |
12950 | { | 13673 | { |
12951 | // m_log.DebugFormat( | 13674 | // m_log.DebugFormat( |
12952 | // "[LLCLIENTVIEW]: Immediately sending terse agent update for {0} to {1} in {2}", | 13675 | // "[LLCLIENTVIEW]: Immediately sending terse agent update for {0} to {1} in {2}", |
12953 | // p.Name, Name, Scene.Name); | 13676 | // p.Name, Name, Scene.Name); |
12954 | 13677 | ||
12955 | // It turns out to get the agent to stop flying, you have to feed it stop flying velocities | 13678 | // It turns out to get the agent to stop flying, you have to feed it stop flying velocities |
@@ -12962,8 +13685,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12962 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = | 13685 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = |
12963 | CreateImprovedTerseBlock(p, false); | 13686 | CreateImprovedTerseBlock(p, false); |
12964 | 13687 | ||
12965 | const float TIME_DILATION = 1.0f; | 13688 | // const float TIME_DILATION = 1.0f; |
12966 | ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f); | 13689 | ushort timeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f);; |
12967 | 13690 | ||
12968 | ImprovedTerseObjectUpdatePacket packet | 13691 | ImprovedTerseObjectUpdatePacket packet |
12969 | = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket( | 13692 | = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket( |
@@ -12986,7 +13709,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12986 | PlacesReplyData[] data) | 13709 | PlacesReplyData[] data) |
12987 | { | 13710 | { |
12988 | PlacesReplyPacket reply = null; | 13711 | PlacesReplyPacket reply = null; |
12989 | PlacesReplyPacket.QueryDataBlock[] dataBlocks = | 13712 | PlacesReplyPacket.QueryDataBlock[] dataBlocks = |
12990 | new PlacesReplyPacket.QueryDataBlock[0]; | 13713 | new PlacesReplyPacket.QueryDataBlock[0]; |
12991 | 13714 | ||
12992 | for (int i = 0 ; i < data.Length ; i++) | 13715 | for (int i = 0 ; i < data.Length ; i++) |
@@ -13164,7 +13887,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
13164 | foreach (InventoryItemBase item in items) | 13887 | foreach (InventoryItemBase item in items) |
13165 | { | 13888 | { |
13166 | OSDMap ItemDataMap = new OSDMap(); | 13889 | OSDMap ItemDataMap = new OSDMap(); |
13167 | 13890 | ||
13168 | ItemDataMap.Add("ItemID", OSD.FromUUID(item.ID)); | 13891 | ItemDataMap.Add("ItemID", OSD.FromUUID(item.ID)); |
13169 | ItemDataMap.Add("FolderID", OSD.FromUUID(item.Folder)); | 13892 | ItemDataMap.Add("FolderID", OSD.FromUUID(item.Folder)); |
13170 | 13893 | ||