aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
diff options
context:
space:
mode:
authoronefang2019-05-19 21:24:15 +1000
committeronefang2019-05-19 21:24:15 +1000
commit5e4d6cab00cb29cd088ab7b62ab13aff103b64cb (patch)
treea9fbc62df9eb2d1d9ba2698d8552eae71eca20d8 /OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
parentAdd a build script. (diff)
downloadopensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.zip
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.gz
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.bz2
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.xz
Dump OpenSim 0.9.0.1 into it's own branch.
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs3435
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..2ff6ced 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;
@@ -333,26 +340,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
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,14 +2511,14 @@ 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];
2478 for (int i = 0; i < buttonlabels.Length; i++) 2518 for (int i = 0; i < buttonlabels.Length; i++)
2479 { 2519 {
2480 buttons[i] = new ScriptDialogPacket.ButtonsBlock(); 2520 buttons[i] = new ScriptDialogPacket.ButtonsBlock();
2481 buttons[i].ButtonLabel = Util.StringToBytes256(buttonlabels[i]); 2521 buttons[i].ButtonLabel = Util.StringToBytes(buttonlabels[i],24);
2482 } 2522 }
2483 dialog.Buttons = buttons; 2523 dialog.Buttons = buttons;
2484 2524
@@ -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