aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs3
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs1101
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs65
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs4
5 files changed, 691 insertions, 486 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
index afbe56b..3995620 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
@@ -234,6 +234,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
234 m_stopPacket = TexturePacketCount(); 234 m_stopPacket = TexturePacketCount();
235 } 235 }
236 236
237 //Give them at least two packets, to play nice with some broken viewers (SL also behaves this way)
238 if (m_stopPacket == 1 && m_layers[0].End > FIRST_PACKET_SIZE) m_stopPacket++;
239
237 m_currentPacket = StartPacket; 240 m_currentPacket = StartPacket;
238 } 241 }
239 } 242 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 4d6081c..9ae8dfb 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -98,6 +98,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
98 public event AvatarPickerRequest OnAvatarPickerRequest; 98 public event AvatarPickerRequest OnAvatarPickerRequest;
99 public event StartAnim OnStartAnim; 99 public event StartAnim OnStartAnim;
100 public event StopAnim OnStopAnim; 100 public event StopAnim OnStopAnim;
101 public event ChangeAnim OnChangeAnim;
101 public event Action<IClientAPI> OnRequestAvatarsData; 102 public event Action<IClientAPI> OnRequestAvatarsData;
102 public event LinkObjects OnLinkObjects; 103 public event LinkObjects OnLinkObjects;
103 public event DelinkObjects OnDelinkObjects; 104 public event DelinkObjects OnDelinkObjects;
@@ -125,6 +126,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
125 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; 126 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
126 public event UpdatePrimFlags OnUpdatePrimFlags; 127 public event UpdatePrimFlags OnUpdatePrimFlags;
127 public event UpdatePrimTexture OnUpdatePrimTexture; 128 public event UpdatePrimTexture OnUpdatePrimTexture;
129 public event ClientChangeObject onClientChangeObject;
128 public event UpdateVector OnUpdatePrimGroupPosition; 130 public event UpdateVector OnUpdatePrimGroupPosition;
129 public event UpdateVector OnUpdatePrimSinglePosition; 131 public event UpdateVector OnUpdatePrimSinglePosition;
130 public event UpdatePrimRotation OnUpdatePrimGroupRotation; 132 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
@@ -158,6 +160,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
158 public event RequestTaskInventory OnRequestTaskInventory; 160 public event RequestTaskInventory OnRequestTaskInventory;
159 public event UpdateInventoryItem OnUpdateInventoryItem; 161 public event UpdateInventoryItem OnUpdateInventoryItem;
160 public event CopyInventoryItem OnCopyInventoryItem; 162 public event CopyInventoryItem OnCopyInventoryItem;
163 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
161 public event MoveInventoryItem OnMoveInventoryItem; 164 public event MoveInventoryItem OnMoveInventoryItem;
162 public event RemoveInventoryItem OnRemoveInventoryItem; 165 public event RemoveInventoryItem OnRemoveInventoryItem;
163 public event RemoveInventoryFolder OnRemoveInventoryFolder; 166 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -256,7 +259,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
256 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 259 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
257 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 260 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
258 public event ClassifiedDelete OnClassifiedDelete; 261 public event ClassifiedDelete OnClassifiedDelete;
259 public event ClassifiedDelete OnClassifiedGodDelete; 262 public event ClassifiedGodDelete OnClassifiedGodDelete;
260 public event EventNotificationAddRequest OnEventNotificationAddRequest; 263 public event EventNotificationAddRequest OnEventNotificationAddRequest;
261 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 264 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
262 public event EventGodDelete OnEventGodDelete; 265 public event EventGodDelete OnEventGodDelete;
@@ -287,6 +290,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
287 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; 290 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
288 public event SimWideDeletesDelegate OnSimWideDeletes; 291 public event SimWideDeletesDelegate OnSimWideDeletes;
289 public event SendPostcard OnSendPostcard; 292 public event SendPostcard OnSendPostcard;
293 public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
290 public event MuteListEntryUpdate OnUpdateMuteListEntry; 294 public event MuteListEntryUpdate OnUpdateMuteListEntry;
291 public event MuteListEntryRemove OnRemoveMuteListEntry; 295 public event MuteListEntryRemove OnRemoveMuteListEntry;
292 public event GodlikeMessage onGodlikeMessage; 296 public event GodlikeMessage onGodlikeMessage;
@@ -336,7 +340,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
336 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 340 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
337 /// ownerless phantom. 341 /// ownerless phantom.
338 /// 342 ///
339 /// All manipulation of this set has to occur under a lock 343 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
340 /// 344 ///
341 /// </value> 345 /// </value>
342 protected HashSet<uint> m_killRecord; 346 protected HashSet<uint> m_killRecord;
@@ -344,6 +348,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
344// protected HashSet<uint> m_attachmentsSent; 348// protected HashSet<uint> m_attachmentsSent;
345 349
346 private int m_moneyBalance; 350 private int m_moneyBalance;
351 private bool m_deliverPackets = true;
347 private int m_animationSequenceNumber = 1; 352 private int m_animationSequenceNumber = 1;
348 private bool m_SendLogoutPacketWhenClosing = true; 353 private bool m_SendLogoutPacketWhenClosing = true;
349 private AgentUpdateArgs lastarg; 354 private AgentUpdateArgs lastarg;
@@ -383,6 +388,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
383 get { return m_startpos; } 388 get { return m_startpos; }
384 set { m_startpos = value; } 389 set { m_startpos = value; }
385 } 390 }
391 public bool DeliverPackets
392 {
393 get { return m_deliverPackets; }
394 set {
395 m_deliverPackets = value;
396 m_udpClient.m_deliverPackets = value;
397 }
398 }
386 public UUID AgentId { get { return m_agentId; } } 399 public UUID AgentId { get { return m_agentId; } }
387 public ISceneAgent SceneAgent { get; set; } 400 public ISceneAgent SceneAgent { get; set; }
388 public UUID ActiveGroupId { get { return m_activeGroupID; } } 401 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -485,18 +498,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
485 498
486 #region Client Methods 499 #region Client Methods
487 500
501
488 /// <summary> 502 /// <summary>
489 /// Shut down the client view 503 /// Shut down the client view
490 /// </summary> 504 /// </summary>
491 public void Close() 505 public void Close()
492 { 506 {
507 Close(true);
508 }
509
510 /// <summary>
511 /// Shut down the client view
512 /// </summary>
513 public void Close(bool sendStop)
514 {
493 m_log.DebugFormat( 515 m_log.DebugFormat(
494 "[CLIENT]: Close has been called for {0} attached to scene {1}", 516 "[CLIENT]: Close has been called for {0} attached to scene {1}",
495 Name, m_scene.RegionInfo.RegionName); 517 Name, m_scene.RegionInfo.RegionName);
496 518
497 // Send the STOP packet 519 if (sendStop)
498 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); 520 {
499 OutPacket(disable, ThrottleOutPacketType.Unknown); 521 // Send the STOP packet
522 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
523 OutPacket(disable, ThrottleOutPacketType.Unknown);
524 }
500 525
501 IsActive = false; 526 IsActive = false;
502 527
@@ -796,7 +821,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
796 reply.ChatData.OwnerID = fromAgentID; 821 reply.ChatData.OwnerID = fromAgentID;
797 reply.ChatData.SourceID = fromAgentID; 822 reply.ChatData.SourceID = fromAgentID;
798 823
799 OutPacket(reply, ThrottleOutPacketType.Task); 824 OutPacket(reply, ThrottleOutPacketType.Unknown);
800 } 825 }
801 826
802 /// <summary> 827 /// <summary>
@@ -1082,6 +1107,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1082 public virtual void SendLayerData(float[] map) 1107 public virtual void SendLayerData(float[] map)
1083 { 1108 {
1084 Util.FireAndForget(DoSendLayerData, map); 1109 Util.FireAndForget(DoSendLayerData, map);
1110
1111 // Send it sync, and async. It's not that much data
1112 // and it improves user experience just so much!
1113 DoSendLayerData(map);
1085 } 1114 }
1086 1115
1087 /// <summary> 1116 /// <summary>
@@ -1094,16 +1123,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1094 1123
1095 try 1124 try
1096 { 1125 {
1097 //for (int y = 0; y < 16; y++) 1126 for (int y = 0; y < 16; y++)
1098 //{ 1127 {
1099 // for (int x = 0; x < 16; x++) 1128 for (int x = 0; x < 16; x+=4)
1100 // { 1129 {
1101 // SendLayerData(x, y, map); 1130 SendLayerPacket(x, y, map);
1102 // } 1131 }
1103 //} 1132 }
1104
1105 // Send LayerData in a spiral pattern. Fun!
1106 SendLayerTopRight(map, 0, 0, 15, 15);
1107 } 1133 }
1108 catch (Exception e) 1134 catch (Exception e)
1109 { 1135 {
@@ -1111,51 +1137,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1111 } 1137 }
1112 } 1138 }
1113 1139
1114 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1115 {
1116 // Row
1117 for (int i = x1; i <= x2; i++)
1118 SendLayerData(i, y1, map);
1119
1120 // Column
1121 for (int j = y1 + 1; j <= y2; j++)
1122 SendLayerData(x2, j, map);
1123
1124 if (x2 - x1 > 0)
1125 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1126 }
1127
1128 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1129 {
1130 // Row in reverse
1131 for (int i = x2; i >= x1; i--)
1132 SendLayerData(i, y2, map);
1133
1134 // Column in reverse
1135 for (int j = y2 - 1; j >= y1; j--)
1136 SendLayerData(x1, j, map);
1137
1138 if (x2 - x1 > 0)
1139 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1140 }
1141
1142 /// <summary> 1140 /// <summary>
1143 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1141 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1144 /// </summary> 1142 /// </summary>
1145 /// <param name="map">heightmap</param> 1143 /// <param name="map">heightmap</param>
1146 /// <param name="px">X coordinate for patches 0..12</param> 1144 /// <param name="px">X coordinate for patches 0..12</param>
1147 /// <param name="py">Y coordinate for patches 0..15</param> 1145 /// <param name="py">Y coordinate for patches 0..15</param>
1148 // private void SendLayerPacket(float[] map, int y, int x) 1146 private void SendLayerPacket(int x, int y, float[] map)
1149 // { 1147 {
1150 // int[] patches = new int[4]; 1148 int[] patches = new int[4];
1151 // patches[0] = x + 0 + y * 16; 1149 patches[0] = x + 0 + y * 16;
1152 // patches[1] = x + 1 + y * 16; 1150 patches[1] = x + 1 + y * 16;
1153 // patches[2] = x + 2 + y * 16; 1151 patches[2] = x + 2 + y * 16;
1154 // patches[3] = x + 3 + y * 16; 1152 patches[3] = x + 3 + y * 16;
1155 1153
1156 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1154 float[] heightmap = (map.Length == 65536) ?
1157 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1155 map :
1158 // } 1156 LLHeightFieldMoronize(map);
1157
1158 try
1159 {
1160 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1161 OutPacket(layerpack, ThrottleOutPacketType.Land);
1162 }
1163 catch
1164 {
1165 for (int px = x ; px < x + 4 ; px++)
1166 SendLayerData(px, y, map);
1167 }
1168 }
1159 1169
1160 /// <summary> 1170 /// <summary>
1161 /// Sends a specified patch to a client 1171 /// Sends a specified patch to a client
@@ -1175,7 +1185,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1175 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1185 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1176 layerpack.Header.Reliable = true; 1186 layerpack.Header.Reliable = true;
1177 1187
1178 OutPacket(layerpack, ThrottleOutPacketType.Land); 1188 OutPacket(layerpack, ThrottleOutPacketType.Task);
1179 } 1189 }
1180 catch (Exception e) 1190 catch (Exception e)
1181 { 1191 {
@@ -1538,7 +1548,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1538 1548
1539 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1549 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1540 { 1550 {
1541// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1551// foreach (uint id in localIDs)
1552// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1542 1553
1543 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1554 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1544 // TODO: don't create new blocks if recycling an old packet 1555 // TODO: don't create new blocks if recycling an old packet
@@ -2300,6 +2311,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2300 OutPacket(sound, ThrottleOutPacketType.Task); 2311 OutPacket(sound, ThrottleOutPacketType.Task);
2301 } 2312 }
2302 2313
2314 public void SendTransferAbort(TransferRequestPacket transferRequest)
2315 {
2316 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2317 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2318 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2319 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2320 OutPacket(abort, ThrottleOutPacketType.Task);
2321 }
2322
2303 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2323 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2304 { 2324 {
2305 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2325 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2592,6 +2612,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2592 } 2612 }
2593 } 2613 }
2594 2614
2615 public void SendPartPhysicsProprieties(ISceneEntity entity)
2616 {
2617 SceneObjectPart part = (SceneObjectPart)entity;
2618 if (part != null && AgentId != UUID.Zero)
2619 {
2620 try
2621 {
2622 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
2623 if (eq != null)
2624 {
2625 uint localid = part.LocalId;
2626 byte physshapetype = part.PhysicsShapeType;
2627 float density = part.Density;
2628 float friction = part.Friction;
2629 float bounce = part.Bounciness;
2630 float gravmod = part.GravityModifier;
2631
2632 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2633 }
2634 }
2635 catch (Exception ex)
2636 {
2637 m_log.Error("Unable to send part Physics Proprieties - exception: " + ex.ToString());
2638 }
2639 part.UpdatePhysRequired = false;
2640 }
2641 }
2642
2643
2595 2644
2596 public void SendGroupNameReply(UUID groupLLUID, string GroupName) 2645 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
2597 { 2646 {
@@ -2747,7 +2796,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2747 reply.Data.ParcelID = parcelID; 2796 reply.Data.ParcelID = parcelID;
2748 reply.Data.OwnerID = land.OwnerID; 2797 reply.Data.OwnerID = land.OwnerID;
2749 reply.Data.Name = Utils.StringToBytes(land.Name); 2798 reply.Data.Name = Utils.StringToBytes(land.Name);
2750 reply.Data.Desc = Utils.StringToBytes(land.Description); 2799 if (land != null && land.Description != null && land.Description != String.Empty)
2800 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2801 else
2802 reply.Data.Desc = new Byte[0];
2751 reply.Data.ActualArea = land.Area; 2803 reply.Data.ActualArea = land.Area;
2752 reply.Data.BillableArea = land.Area; // TODO: what is this? 2804 reply.Data.BillableArea = land.Area; // TODO: what is this?
2753 2805
@@ -3482,7 +3534,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3482 3534
3483 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3535 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3484 // TODO: don't create new blocks if recycling an old packet 3536 // TODO: don't create new blocks if recycling an old packet
3485 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3537 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3486 avp.ObjectData.TextureEntry = textureEntry; 3538 avp.ObjectData.TextureEntry = textureEntry;
3487 3539
3488 AvatarAppearancePacket.VisualParamBlock avblock = null; 3540 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3610,7 +3662,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3610 /// </summary> 3662 /// </summary>
3611 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3663 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3612 { 3664 {
3613 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3665 if (entity is SceneObjectPart)
3666 {
3667 SceneObjectPart e = (SceneObjectPart)entity;
3668 SceneObjectGroup g = e.ParentGroup;
3669 if (g.RootPart.Shape.State > 30) // HUD
3670 if (g.OwnerID != AgentId)
3671 return; // Don't send updates for other people's HUDs
3672 }
3673
3614 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3674 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3615 3675
3616 lock (m_entityUpdates.SyncRoot) 3676 lock (m_entityUpdates.SyncRoot)
@@ -3677,211 +3737,238 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3677 3737
3678 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3738 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3679 // condition where a kill can be processed before an out-of-date update for the same object. 3739 // condition where a kill can be processed before an out-of-date update for the same object.
3680 lock (m_killRecord) 3740 float avgTimeDilation = 1.0f;
3741 IEntityUpdate iupdate;
3742 Int32 timeinqueue; // this is just debugging code & can be dropped later
3743
3744 while (updatesThisCall < maxUpdates)
3681 { 3745 {
3682 float avgTimeDilation = 1.0f; 3746 lock (m_entityUpdates.SyncRoot)
3683 IEntityUpdate iupdate; 3747 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3684 Int32 timeinqueue; // this is just debugging code & can be dropped later 3748 break;
3685
3686 while (updatesThisCall < maxUpdates)
3687 {
3688 lock (m_entityUpdates.SyncRoot)
3689 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3690 break;
3691 3749
3692 EntityUpdate update = (EntityUpdate)iupdate; 3750 EntityUpdate update = (EntityUpdate)iupdate;
3693 3751
3694 avgTimeDilation += update.TimeDilation; 3752 avgTimeDilation += update.TimeDilation;
3695 avgTimeDilation *= 0.5f; 3753 avgTimeDilation *= 0.5f;
3696 3754
3697 if (update.Entity is SceneObjectPart) 3755 if (update.Entity is SceneObjectPart)
3756 {
3757 SceneObjectPart part = (SceneObjectPart)update.Entity;
3758
3759 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3760 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3761 // safety measure.
3762 //
3763 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3764 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3765 // updates and kills on different threads with different scheduling strategies, hence this protection.
3766 //
3767 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3768 // after the root prim has been deleted.
3769 lock (m_killRecord)
3698 { 3770 {
3699 SceneObjectPart part = (SceneObjectPart)update.Entity;
3700
3701 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3702 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3703 // safety measure.
3704 //
3705 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3706 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3707 // updates and kills on different threads with different scheduling strategies, hence this protection.
3708 //
3709 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3710 // after the root prim has been deleted.
3711 if (m_killRecord.Contains(part.LocalId)) 3771 if (m_killRecord.Contains(part.LocalId))
3712 {
3713 // m_log.WarnFormat(
3714 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3715 // part.LocalId, Name);
3716 continue; 3772 continue;
3717 } 3773 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3718 3774 continue;
3719 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3775 }
3776
3777 if (part.ParentGroup.IsDeleted)
3778 continue;
3779
3780 if (part.ParentGroup.IsAttachment)
3781 { // Someone else's HUD, why are we getting these?
3782 if (part.ParentGroup.OwnerID != AgentId &&
3783 part.ParentGroup.RootPart.Shape.State >= 30)
3784 continue;
3785 ScenePresence sp;
3786 // Owner is not in the sim, don't update it to
3787 // anyone
3788 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3789 continue;
3790
3791 List<SceneObjectGroup> atts = sp.GetAttachments();
3792 bool found = false;
3793 foreach (SceneObjectGroup att in atts)
3720 { 3794 {
3721 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3795 if (att == part.ParentGroup)
3722 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3723 { 3796 {
3724 part.Shape.LightEntry = false; 3797 found = true;
3798 break;
3725 } 3799 }
3726 } 3800 }
3801
3802 // It's an attachment of a valid avatar, but
3803 // doesn't seem to be attached, skip
3804 if (!found)
3805 continue;
3806
3807 // On vehicle crossing, the attachments are received
3808 // while the avatar is still a child. Don't send
3809 // updates here because the LocalId has not yet
3810 // been updated and the viewer will derender the
3811 // attachments until the avatar becomes root.
3812 if (sp.IsChildAgent)
3813 continue;
3727 } 3814 }
3728 3815 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3729 ++updatesThisCall;
3730
3731 #region UpdateFlags to packet type conversion
3732
3733 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3734
3735 bool canUseCompressed = true;
3736 bool canUseImproved = true;
3737
3738 // Compressed object updates only make sense for LL primitives
3739 if (!(update.Entity is SceneObjectPart))
3740 {
3741 canUseCompressed = false;
3742 }
3743
3744 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3745 {
3746 canUseCompressed = false;
3747 canUseImproved = false;
3748 }
3749 else
3750 { 3816 {
3751 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3817 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3752 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3818 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3753 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3754 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3755 {
3756 canUseCompressed = false;
3757 }
3758
3759 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3760 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3761 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3762 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3763 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3764 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3765 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3766 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3767 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3768 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3769 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3770 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3771 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3772 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3773 { 3819 {
3774 canUseImproved = false; 3820 part.Shape.LightEntry = false;
3775 } 3821 }
3776 } 3822 }
3777 3823 }
3778 #endregion UpdateFlags to packet type conversion 3824
3779 3825 ++updatesThisCall;
3780 #region Block Construction 3826
3781 3827 #region UpdateFlags to packet type conversion
3782 // TODO: Remove this once we can build compressed updates 3828
3829 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3830
3831 bool canUseCompressed = true;
3832 bool canUseImproved = true;
3833
3834 // Compressed object updates only make sense for LL primitives
3835 if (!(update.Entity is SceneObjectPart))
3836 {
3783 canUseCompressed = false; 3837 canUseCompressed = false;
3784 3838 }
3785 if (!canUseImproved && !canUseCompressed) 3839
3786 { 3840 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3787 if (update.Entity is ScenePresence) 3841 {
3788 { 3842 canUseCompressed = false;
3789 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3843 canUseImproved = false;
3790 objectUpdates.Value.Add(update); 3844 }
3791 } 3845 else
3792 else 3846 {
3793 { 3847 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3794 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3848 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3795 objectUpdates.Value.Add(update); 3849 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3796 } 3850 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3797 }
3798 else if (!canUseImproved)
3799 { 3851 {
3800 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3852 canUseCompressed = false;
3801 compressedUpdates.Value.Add(update);
3802 } 3853 }
3803 else 3854
3855 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3856 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3857 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3858 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3859 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3860 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3861 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3862 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3863 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3864 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3865 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3866 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3867 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3868 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3804 { 3869 {
3805 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3870 canUseImproved = false;
3806 {
3807 // Self updates go into a special list
3808 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3809 terseAgentUpdates.Value.Add(update);
3810 }
3811 else
3812 {
3813 // Everything else goes here
3814 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3815 terseUpdates.Value.Add(update);
3816 }
3817 } 3871 }
3818
3819 #endregion Block Construction
3820 } 3872 }
3821
3822
3823 #region Packet Sending
3824 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3825 3873
3826 if (terseAgentUpdateBlocks.IsValueCreated) 3874 #endregion UpdateFlags to packet type conversion
3827 {
3828 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3829 3875
3830 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3876 #region Block Construction
3831 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3832 packet.RegionData.TimeDilation = timeDilation;
3833 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3834 3877
3835 for (int i = 0; i < blocks.Count; i++) 3878 // TODO: Remove this once we can build compressed updates
3836 packet.ObjectData[i] = blocks[i]; 3879 canUseCompressed = false;
3837 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3838 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3839 }
3840 3880
3841 if (objectUpdateBlocks.IsValueCreated) 3881 if (!canUseImproved && !canUseCompressed)
3842 { 3882 {
3843 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3883 if (update.Entity is ScenePresence)
3844 3884 {
3845 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3885 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3846 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3886 }
3847 packet.RegionData.TimeDilation = timeDilation; 3887 else
3848 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3888 {
3849 3889 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3850 for (int i = 0; i < blocks.Count; i++) 3890 }
3851 packet.ObjectData[i] = blocks[i];
3852 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3853 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3854 } 3891 }
3855 3892 else if (!canUseImproved)
3856 if (compressedUpdateBlocks.IsValueCreated)
3857 { 3893 {
3858 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3894 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3859
3860 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3861 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3862 packet.RegionData.TimeDilation = timeDilation;
3863 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3864
3865 for (int i = 0; i < blocks.Count; i++)
3866 packet.ObjectData[i] = blocks[i];
3867 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3868 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3869 } 3895 }
3870 3896 else
3871 if (terseUpdateBlocks.IsValueCreated)
3872 { 3897 {
3873 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3898 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3874 3899 // Self updates go into a special list
3875 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3900 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3876 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3901 else
3877 packet.RegionData.TimeDilation = timeDilation; 3902 // Everything else goes here
3878 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3903 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3879
3880 for (int i = 0; i < blocks.Count; i++)
3881 packet.ObjectData[i] = blocks[i];
3882 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3883 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3884 } 3904 }
3905
3906 #endregion Block Construction
3907 }
3908
3909 #region Packet Sending
3910
3911 const float TIME_DILATION = 1.0f;
3912 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3913
3914 if (terseAgentUpdateBlocks.IsValueCreated)
3915 {
3916 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3917
3918 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3919 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3920 packet.RegionData.TimeDilation = timeDilation;
3921 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3922
3923 for (int i = 0; i < blocks.Count; i++)
3924 packet.ObjectData[i] = blocks[i];
3925
3926 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3927 }
3928
3929 if (objectUpdateBlocks.IsValueCreated)
3930 {
3931 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3932
3933 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3934 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3935 packet.RegionData.TimeDilation = timeDilation;
3936 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3937
3938 for (int i = 0; i < blocks.Count; i++)
3939 packet.ObjectData[i] = blocks[i];
3940
3941 OutPacket(packet, ThrottleOutPacketType.Task, true);
3942 }
3943
3944 if (compressedUpdateBlocks.IsValueCreated)
3945 {
3946 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3947
3948 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3949 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3950 packet.RegionData.TimeDilation = timeDilation;
3951 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3952
3953 for (int i = 0; i < blocks.Count; i++)
3954 packet.ObjectData[i] = blocks[i];
3955
3956 OutPacket(packet, ThrottleOutPacketType.Task, true);
3957 }
3958
3959 if (terseUpdateBlocks.IsValueCreated)
3960 {
3961 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3962
3963 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3964 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3965 packet.RegionData.TimeDilation = timeDilation;
3966 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3967
3968 for (int i = 0; i < blocks.Count; i++)
3969 packet.ObjectData[i] = blocks[i];
3970
3971 OutPacket(packet, ThrottleOutPacketType.Task, true);
3885 } 3972 }
3886 3973
3887 #endregion Packet Sending 3974 #endregion Packet Sending
@@ -4174,11 +4261,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4174 4261
4175 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4262 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4176 // of the object rather than the properties when the packet was created 4263 // of the object rather than the properties when the packet was created
4177 OutPacket(packet, ThrottleOutPacketType.Task, true, 4264 // HACK : Remove intelligent resending until it's fixed in core
4178 delegate(OutgoingPacket oPacket) 4265 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4179 { 4266 // delegate(OutgoingPacket oPacket)
4180 ResendPropertyUpdates(updates, oPacket); 4267 // {
4181 }); 4268 // ResendPropertyUpdates(updates, oPacket);
4269 // });
4270 OutPacket(packet, ThrottleOutPacketType.Task, true);
4182 4271
4183 // pbcnt += blocks.Count; 4272 // pbcnt += blocks.Count;
4184 // ppcnt++; 4273 // ppcnt++;
@@ -4204,11 +4293,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4204 // of the object rather than the properties when the packet was created 4293 // of the object rather than the properties when the packet was created
4205 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4294 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4206 updates.Add(familyUpdates.Value[i]); 4295 updates.Add(familyUpdates.Value[i]);
4207 OutPacket(packet, ThrottleOutPacketType.Task, true, 4296 // HACK : Remove intelligent resending until it's fixed in core
4208 delegate(OutgoingPacket oPacket) 4297 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4209 { 4298 // delegate(OutgoingPacket oPacket)
4210 ResendPropertyUpdates(updates, oPacket); 4299 // {
4211 }); 4300 // ResendPropertyUpdates(updates, oPacket);
4301 // });
4302 OutPacket(packet, ThrottleOutPacketType.Task, true);
4212 4303
4213 // fpcnt++; 4304 // fpcnt++;
4214 // fbcnt++; 4305 // fbcnt++;
@@ -4357,37 +4448,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4357 if (bl[i].BannedUserID == UUID.Zero) 4448 if (bl[i].BannedUserID == UUID.Zero)
4358 continue; 4449 continue;
4359 BannedUsers.Add(bl[i].BannedUserID); 4450 BannedUsers.Add(bl[i].BannedUserID);
4360 }
4361 4451
4362 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4452 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4363 packet.AgentData.TransactionID = UUID.Random(); 4453 {
4364 packet.AgentData.AgentID = AgentId; 4454 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4365 packet.AgentData.SessionID = SessionId; 4455 packet.AgentData.TransactionID = UUID.Random();
4366 packet.MethodData.Invoice = invoice; 4456 packet.AgentData.AgentID = AgentId;
4367 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4457 packet.AgentData.SessionID = SessionId;
4458 packet.MethodData.Invoice = invoice;
4459 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4368 4460
4369 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4461 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4370 4462
4371 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4463 int j;
4372 { 4464 for (j = 0; j < (6 + BannedUsers.Count); j++)
4373 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4465 {
4374 } 4466 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4375 int j = 0; 4467 }
4468 j = 0;
4376 4469
4377 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4470 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4378 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4471 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4379 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4472 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4380 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4473 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4381 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4474 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4382 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4475 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4383 4476
4384 foreach (UUID banned in BannedUsers) 4477 foreach (UUID banned in BannedUsers)
4385 { 4478 {
4386 returnblock[j].Parameter = banned.GetBytes(); j++; 4479 returnblock[j].Parameter = banned.GetBytes(); j++;
4480 }
4481 packet.ParamList = returnblock;
4482 packet.Header.Reliable = true;
4483 OutPacket(packet, ThrottleOutPacketType.Task);
4484
4485 BannedUsers.Clear();
4486 }
4387 } 4487 }
4388 packet.ParamList = returnblock; 4488
4389 packet.Header.Reliable = false;
4390 OutPacket(packet, ThrottleOutPacketType.Task);
4391 } 4489 }
4392 4490
4393 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4491 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4573,7 +4671,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4573 4671
4574 if (landData.SimwideArea > 0) 4672 if (landData.SimwideArea > 0)
4575 { 4673 {
4576 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4674 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4675 // Never report more than sim total capacity
4676 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4677 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4577 updateMessage.SimWideMaxPrims = simulatorCapacity; 4678 updateMessage.SimWideMaxPrims = simulatorCapacity;
4578 } 4679 }
4579 else 4680 else
@@ -4702,14 +4803,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4702 4803
4703 if (notifyCount > 0) 4804 if (notifyCount > 0)
4704 { 4805 {
4705 if (notifyCount > 32) 4806// if (notifyCount > 32)
4706 { 4807// {
4707 m_log.InfoFormat( 4808// m_log.InfoFormat(
4708 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4809// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4709 + " - a developer might want to investigate whether this is a hard limit", 32); 4810// + " - a developer might want to investigate whether this is a hard limit", 32);
4710 4811//
4711 notifyCount = 32; 4812// notifyCount = 32;
4712 } 4813// }
4713 4814
4714 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4815 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4715 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4816 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4764,9 +4865,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4764 { 4865 {
4765 ScenePresence presence = (ScenePresence)entity; 4866 ScenePresence presence = (ScenePresence)entity;
4766 4867
4868 position = presence.OffsetPosition;
4869 rotation = presence.Rotation;
4870
4871 if (presence.ParentID != 0)
4872 {
4873 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4874 if (part != null && part != part.ParentGroup.RootPart)
4875 {
4876 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4877 rotation = part.RotationOffset * presence.Rotation;
4878 }
4879 }
4880
4767 attachPoint = 0; 4881 attachPoint = 0;
4768 collisionPlane = presence.CollisionPlane; 4882 collisionPlane = presence.CollisionPlane;
4769 position = presence.OffsetPosition;
4770 velocity = presence.Velocity; 4883 velocity = presence.Velocity;
4771 acceleration = Vector3.Zero; 4884 acceleration = Vector3.Zero;
4772 4885
@@ -4776,7 +4889,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4776// acceleration = new Vector3(1, 0, 0); 4889// acceleration = new Vector3(1, 0, 0);
4777 4890
4778 angularVelocity = Vector3.Zero; 4891 angularVelocity = Vector3.Zero;
4779 rotation = presence.Rotation;
4780 4892
4781 if (sendTexture) 4893 if (sendTexture)
4782 textureEntry = presence.Appearance.Texture.GetBytes(); 4894 textureEntry = presence.Appearance.Texture.GetBytes();
@@ -4881,13 +4993,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4881 4993
4882 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 4994 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
4883 { 4995 {
4996 Vector3 offsetPosition = data.OffsetPosition;
4997 Quaternion rotation = data.Rotation;
4998 uint parentID = data.ParentID;
4999
5000 if (parentID != 0)
5001 {
5002 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5003 if (part != null && part != part.ParentGroup.RootPart)
5004 {
5005 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5006 rotation = part.RotationOffset * data.Rotation;
5007 parentID = part.ParentGroup.RootPart.LocalId;
5008 }
5009 }
5010
4884 byte[] objectData = new byte[76]; 5011 byte[] objectData = new byte[76];
4885 5012
4886 data.CollisionPlane.ToBytes(objectData, 0); 5013 data.CollisionPlane.ToBytes(objectData, 0);
4887 data.OffsetPosition.ToBytes(objectData, 16); 5014 offsetPosition.ToBytes(objectData, 16);
4888// data.Velocity.ToBytes(objectData, 28); 5015// data.Velocity.ToBytes(objectData, 28);
4889// data.Acceleration.ToBytes(objectData, 40); 5016// data.Acceleration.ToBytes(objectData, 40);
4890 data.Rotation.ToBytes(objectData, 52); 5017 rotation.ToBytes(objectData, 52);
4891 //data.AngularVelocity.ToBytes(objectData, 64); 5018 //data.AngularVelocity.ToBytes(objectData, 64);
4892 5019
4893 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5020 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -4901,7 +5028,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4901 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5028 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
4902 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5029 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
4903 update.ObjectData = objectData; 5030 update.ObjectData = objectData;
4904 update.ParentID = data.ParentID; 5031 update.ParentID = parentID;
4905 update.PathCurve = 16; 5032 update.PathCurve = 16;
4906 update.PathScaleX = 100; 5033 update.PathScaleX = 100;
4907 update.PathScaleY = 100; 5034 update.PathScaleY = 100;
@@ -5242,6 +5369,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5242 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5369 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5243 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5370 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5244 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5371 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5372 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5245 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5373 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5246 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5374 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5247 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5375 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5308,6 +5436,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5308 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5436 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5309 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5437 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5310 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5438 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5439 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5311 5440
5312 AddGenericPacketHandler("autopilot", HandleAutopilot); 5441 AddGenericPacketHandler("autopilot", HandleAutopilot);
5313 } 5442 }
@@ -5343,6 +5472,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5343 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5472 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5344 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5473 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5345 (x.ControlFlags != lastarg.ControlFlags) || 5474 (x.ControlFlags != lastarg.ControlFlags) ||
5475 (x.ControlFlags != 0) ||
5346 (x.Far != lastarg.Far) || 5476 (x.Far != lastarg.Far) ||
5347 (x.Flags != lastarg.Flags) || 5477 (x.Flags != lastarg.Flags) ||
5348 (x.State != lastarg.State) || 5478 (x.State != lastarg.State) ||
@@ -5720,7 +5850,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5720 args.Channel = ch; 5850 args.Channel = ch;
5721 args.From = String.Empty; 5851 args.From = String.Empty;
5722 args.Message = Utils.BytesToString(msg); 5852 args.Message = Utils.BytesToString(msg);
5723 args.Type = ChatTypeEnum.Shout; 5853 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5724 args.Position = new Vector3(); 5854 args.Position = new Vector3();
5725 args.Scene = Scene; 5855 args.Scene = Scene;
5726 args.Sender = this; 5856 args.Sender = this;
@@ -6257,7 +6387,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6257 return true; 6387 return true;
6258 } 6388 }
6259 #endregion 6389 #endregion
6260 6390/*
6261 StartAnim handlerStartAnim = null; 6391 StartAnim handlerStartAnim = null;
6262 StopAnim handlerStopAnim = null; 6392 StopAnim handlerStopAnim = null;
6263 6393
@@ -6281,6 +6411,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6281 } 6411 }
6282 } 6412 }
6283 return true; 6413 return true;
6414*/
6415 ChangeAnim handlerChangeAnim = null;
6416
6417 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6418 {
6419 handlerChangeAnim = OnChangeAnim;
6420 if (handlerChangeAnim != null)
6421 {
6422 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6423 }
6424 }
6425
6426 handlerChangeAnim = OnChangeAnim;
6427 if (handlerChangeAnim != null)
6428 {
6429 handlerChangeAnim(UUID.Zero, false, true);
6430 }
6431
6432 return true;
6284 } 6433 }
6285 6434
6286 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6435 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -6906,10 +7055,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6906 // 46,47,48 are special positions within the packet 7055 // 46,47,48 are special positions within the packet
6907 // This may change so perhaps we need a better way 7056 // This may change so perhaps we need a better way
6908 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) 7057 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
6909 bool UsePhysics = (data[46] != 0) ? true : false; 7058 /*
6910 bool IsTemporary = (data[47] != 0) ? true : false; 7059 bool UsePhysics = (data[46] != 0) ? true : false;
6911 bool IsPhantom = (data[48] != 0) ? true : false; 7060 bool IsTemporary = (data[47] != 0) ? true : false;
6912 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this); 7061 bool IsPhantom = (data[48] != 0) ? true : false;
7062 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this);
7063 */
7064 bool UsePhysics = flags.AgentData.UsePhysics;
7065 bool IsPhantom = flags.AgentData.IsPhantom;
7066 bool IsTemporary = flags.AgentData.IsTemporary;
7067 ObjectFlagUpdatePacket.ExtraPhysicsBlock[] blocks = flags.ExtraPhysics;
7068 ExtraPhysicsData physdata = new ExtraPhysicsData();
7069
7070 if (blocks == null || blocks.Length == 0)
7071 {
7072 physdata.PhysShapeType = PhysShapeType.invalid;
7073 }
7074 else
7075 {
7076 ObjectFlagUpdatePacket.ExtraPhysicsBlock phsblock = blocks[0];
7077 physdata.PhysShapeType = (PhysShapeType)phsblock.PhysicsShapeType;
7078 physdata.Bounce = phsblock.Restitution;
7079 physdata.Density = phsblock.Density;
7080 physdata.Friction = phsblock.Friction;
7081 physdata.GravitationModifier = phsblock.GravityMultiplier;
7082 }
7083
7084 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
6913 } 7085 }
6914 return true; 7086 return true;
6915 } 7087 }
@@ -9763,7 +9935,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9763 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9935 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9764 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9936 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9765 UpdateMuteListEntry.MuteData.MuteType, 9937 UpdateMuteListEntry.MuteData.MuteType,
9766 UpdateMuteListEntry.AgentData.AgentID); 9938 UpdateMuteListEntry.MuteData.MuteFlags);
9767 return true; 9939 return true;
9768 } 9940 }
9769 return false; 9941 return false;
@@ -9778,8 +9950,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9778 { 9950 {
9779 handlerRemoveMuteListEntry(this, 9951 handlerRemoveMuteListEntry(this,
9780 RemoveMuteListEntry.MuteData.MuteID, 9952 RemoveMuteListEntry.MuteData.MuteID,
9781 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9953 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9782 RemoveMuteListEntry.AgentData.AgentID);
9783 return true; 9954 return true;
9784 } 9955 }
9785 return false; 9956 return false;
@@ -9823,10 +9994,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9823 return false; 9994 return false;
9824 } 9995 }
9825 9996
9997 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
9998 {
9999 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10000 (ChangeInventoryItemFlagsPacket)packet;
10001 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10002 if (handlerChangeInventoryItemFlags != null)
10003 {
10004 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10005 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10006 return true;
10007 }
10008 return false;
10009 }
10010
9826 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10011 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9827 { 10012 {
9828 return true; 10013 return true;
9829 } 10014 }
10015
10016 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10017 {
10018 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10019
10020 #region Packet Session and User Check
10021 if (m_checkPackets)
10022 {
10023 if (packet.AgentData.SessionID != SessionId ||
10024 packet.AgentData.AgentID != AgentId)
10025 return true;
10026 }
10027 #endregion
10028 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10029 List<InventoryItemBase> items = new List<InventoryItemBase>();
10030 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10031 {
10032 InventoryItemBase b = new InventoryItemBase();
10033 b.ID = n.OldItemID;
10034 b.Folder = n.OldFolderID;
10035 items.Add(b);
10036 }
10037
10038 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10039 if (handlerMoveItemsAndLeaveCopy != null)
10040 {
10041 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10042 }
10043
10044 return true;
10045 }
9830 10046
9831 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10047 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9832 { 10048 {
@@ -10253,6 +10469,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10253 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10469 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10254 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10470 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10255 10471
10472 Scene scene = (Scene)m_scene;
10473 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10474 {
10475 ScenePresence p;
10476 if (scene.TryGetScenePresence(sender.AgentId, out p))
10477 {
10478 if (p.GodLevel >= 200)
10479 {
10480 groupProfileReply.GroupData.OpenEnrollment = true;
10481 groupProfileReply.GroupData.MembershipFee = 0;
10482 }
10483 }
10484 }
10485
10256 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10486 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10257 } 10487 }
10258 return true; 10488 return true;
@@ -10826,11 +11056,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10826 11056
10827 StartLure handlerStartLure = OnStartLure; 11057 StartLure handlerStartLure = OnStartLure;
10828 if (handlerStartLure != null) 11058 if (handlerStartLure != null)
10829 handlerStartLure(startLureRequest.Info.LureType, 11059 {
10830 Utils.BytesToString( 11060 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10831 startLureRequest.Info.Message), 11061 {
10832 startLureRequest.TargetData[0].TargetID, 11062 handlerStartLure(startLureRequest.Info.LureType,
10833 this); 11063 Utils.BytesToString(
11064 startLureRequest.Info.Message),
11065 startLureRequest.TargetData[i].TargetID,
11066 this);
11067 }
11068 }
10834 return true; 11069 return true;
10835 } 11070 }
10836 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11071 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10944,10 +11179,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10944 } 11179 }
10945 #endregion 11180 #endregion
10946 11181
10947 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11182 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10948 if (handlerClassifiedGodDelete != null) 11183 if (handlerClassifiedGodDelete != null)
10949 handlerClassifiedGodDelete( 11184 handlerClassifiedGodDelete(
10950 classifiedGodDelete.Data.ClassifiedID, 11185 classifiedGodDelete.Data.ClassifiedID,
11186 classifiedGodDelete.Data.QueryID,
10951 this); 11187 this);
10952 return true; 11188 return true;
10953 } 11189 }
@@ -11313,209 +11549,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11313 } 11549 }
11314 else 11550 else
11315 { 11551 {
11316// m_log.DebugFormat( 11552 ClientChangeObject updatehandler = onClientChangeObject;
11317// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11318// i, block.Type, part.Name, part.LocalId);
11319 11553
11320// // Do this once since fetch parts creates a new array. 11554 if (updatehandler != null)
11321// SceneObjectPart[] parts = part.ParentGroup.Parts; 11555 {
11322// for (int j = 0; j < parts.Length; j++) 11556 ObjectChangeData udata = new ObjectChangeData();
11323// {
11324// part.StoreUndoState();
11325// parts[j].IgnoreUndoUpdate = true;
11326// }
11327 11557
11328 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11558 /*ubit from ll JIRA:
11559 * 0x01 position
11560 * 0x02 rotation
11561 * 0x04 scale
11562
11563 * 0x08 LINK_SET
11564 * 0x10 UNIFORM for scale
11565 */
11329 11566
11330 switch (block.Type) 11567 // translate to internal changes
11331 { 11568 // not all cases .. just the ones older code did
11332 case 1:
11333 Vector3 pos1 = new Vector3(block.Data, 0);
11334 11569
11335 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11570 switch (block.Type)
11336 if (handlerUpdatePrimSinglePosition != null) 11571 {
11337 { 11572 case 1: //change position sp
11338 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11573 udata.position = new Vector3(block.Data, 0);
11339 handlerUpdatePrimSinglePosition(localId, pos1, this);
11340 }
11341 break;
11342 11574
11343 case 2: 11575 udata.change = ObjectChangeType.primP;
11344 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11576 updatehandler(localId, udata, this);
11577 break;
11345 11578
11346 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11579 case 2: // rotation sp
11347 if (handlerUpdatePrimSingleRotation != null) 11580 udata.rotation = new Quaternion(block.Data, 0, true);
11348 {
11349 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11350 handlerUpdatePrimSingleRotation(localId, rot1, this);
11351 }
11352 break;
11353 11581
11354 case 3: 11582 udata.change = ObjectChangeType.primR;
11355 Vector3 rotPos = new Vector3(block.Data, 0); 11583 updatehandler(localId, udata, this);
11356 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11584 break;
11357 11585
11358 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11586 case 3: // position plus rotation
11359 if (handlerUpdatePrimSingleRotationPosition != null) 11587 udata.position = new Vector3(block.Data, 0);
11360 { 11588 udata.rotation = new Quaternion(block.Data, 12, true);
11361 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11362 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11363 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11364 }
11365 break;
11366 11589
11367 case 4: 11590 udata.change = ObjectChangeType.primPR;
11368 case 20: 11591 updatehandler(localId, udata, this);
11369 Vector3 scale4 = new Vector3(block.Data, 0); 11592 break;
11370 11593
11371 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11594 case 4: // scale sp
11372 if (handlerUpdatePrimScale != null) 11595 udata.scale = new Vector3(block.Data, 0);
11373 { 11596 udata.change = ObjectChangeType.primS;
11374 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11375 handlerUpdatePrimScale(localId, scale4, this);
11376 }
11377 break;
11378 11597
11379 case 5: 11598 updatehandler(localId, udata, this);
11380 Vector3 scale1 = new Vector3(block.Data, 12); 11599 break;
11381 Vector3 pos11 = new Vector3(block.Data, 0);
11382 11600
11383 handlerUpdatePrimScale = OnUpdatePrimScale; 11601 case 0x14: // uniform scale sp
11384 if (handlerUpdatePrimScale != null) 11602 udata.scale = new Vector3(block.Data, 0);
11385 {
11386 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11387 handlerUpdatePrimScale(localId, scale1, this);
11388 11603
11389 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11604 udata.change = ObjectChangeType.primUS;
11390 if (handlerUpdatePrimSinglePosition != null) 11605 updatehandler(localId, udata, this);
11391 { 11606 break;
11392 handlerUpdatePrimSinglePosition(localId, pos11, this);
11393 }
11394 }
11395 break;
11396 11607
11397 case 9: 11608 case 5: // scale and position sp
11398 Vector3 pos2 = new Vector3(block.Data, 0); 11609 udata.position = new Vector3(block.Data, 0);
11610 udata.scale = new Vector3(block.Data, 12);
11399 11611
11400 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11612 udata.change = ObjectChangeType.primPS;
11613 updatehandler(localId, udata, this);
11614 break;
11401 11615
11402 if (handlerUpdateVector != null) 11616 case 0x15: //uniform scale and position
11403 { 11617 udata.position = new Vector3(block.Data, 0);
11404 handlerUpdateVector(localId, pos2, this); 11618 udata.scale = new Vector3(block.Data, 12);
11405 }
11406 break;
11407 11619
11408 case 10: 11620 udata.change = ObjectChangeType.primPUS;
11409 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11621 updatehandler(localId, udata, this);
11622 break;
11410 11623
11411 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11624 // now group related (bit 4)
11412 if (handlerUpdatePrimRotation != null) 11625 case 9: //( 8 + 1 )group position
11413 { 11626 udata.position = new Vector3(block.Data, 0);
11414 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11415 handlerUpdatePrimRotation(localId, rot3, this);
11416 }
11417 break;
11418 11627
11419 case 11: 11628 udata.change = ObjectChangeType.groupP;
11420 Vector3 pos3 = new Vector3(block.Data, 0); 11629 updatehandler(localId, udata, this);
11421 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11630 break;
11422 11631
11423 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11632 case 0x0A: // (8 + 2) group rotation
11424 if (handlerUpdatePrimGroupRotation != null) 11633 udata.rotation = new Quaternion(block.Data, 0, true);
11425 {
11426 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11427 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11428 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11429 }
11430 break;
11431 case 12:
11432 case 28:
11433 Vector3 scale7 = new Vector3(block.Data, 0);
11434 11634
11435 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11635 udata.change = ObjectChangeType.groupR;
11436 if (handlerUpdatePrimGroupScale != null) 11636 updatehandler(localId, udata, this);
11437 { 11637 break;
11438 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11439 handlerUpdatePrimGroupScale(localId, scale7, this);
11440 }
11441 break;
11442 11638
11443 case 13: 11639 case 0x0B: //( 8 + 2 + 1) group rotation and position
11444 Vector3 scale2 = new Vector3(block.Data, 12); 11640 udata.position = new Vector3(block.Data, 0);
11445 Vector3 pos4 = new Vector3(block.Data, 0); 11641 udata.rotation = new Quaternion(block.Data, 12, true);
11446 11642
11447 handlerUpdatePrimScale = OnUpdatePrimScale; 11643 udata.change = ObjectChangeType.groupPR;
11448 if (handlerUpdatePrimScale != null) 11644 updatehandler(localId, udata, this);
11449 { 11645 break;
11450 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11451 handlerUpdatePrimScale(localId, scale2, this);
11452 11646
11453 // Change the position based on scale (for bug number 246) 11647 case 0x0C: // (8 + 4) group scale
11454 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11648 // only afects root prim and only sent by viewer editor object tab scaling
11455 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11649 // mouse edition only allows uniform scaling
11456 if (handlerUpdatePrimSinglePosition != null) 11650 // SL MAY CHANGE THIS in viewers
11457 {
11458 handlerUpdatePrimSinglePosition(localId, pos4, this);
11459 }
11460 }
11461 break;
11462 11651
11463 case 29: 11652 udata.scale = new Vector3(block.Data, 0);
11464 Vector3 scale5 = new Vector3(block.Data, 12);
11465 Vector3 pos5 = new Vector3(block.Data, 0);
11466 11653
11467 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11654 udata.change = ObjectChangeType.groupS;
11468 if (handlerUpdatePrimGroupScale != null) 11655 updatehandler(localId, udata, this);
11469 {
11470 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11471 part.StoreUndoState(true);
11472 part.IgnoreUndoUpdate = true;
11473 handlerUpdatePrimGroupScale(localId, scale5, this);
11474 handlerUpdateVector = OnUpdatePrimGroupPosition;
11475 11656
11476 if (handlerUpdateVector != null) 11657 break;
11477 {
11478 handlerUpdateVector(localId, pos5, this);
11479 }
11480 11658
11481 part.IgnoreUndoUpdate = false; 11659 case 0x0D: //(8 + 4 + 1) group scale and position
11482 } 11660 // exception as above
11483 11661
11484 break; 11662 udata.position = new Vector3(block.Data, 0);
11663 udata.scale = new Vector3(block.Data, 12);
11485 11664
11486 case 21: 11665 udata.change = ObjectChangeType.groupPS;
11487 Vector3 scale6 = new Vector3(block.Data, 12); 11666 updatehandler(localId, udata, this);
11488 Vector3 pos6 = new Vector3(block.Data, 0); 11667 break;
11489 11668
11490 handlerUpdatePrimScale = OnUpdatePrimScale; 11669 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11491 if (handlerUpdatePrimScale != null) 11670 udata.scale = new Vector3(block.Data, 0);
11492 {
11493 part.StoreUndoState(false);
11494 part.IgnoreUndoUpdate = true;
11495 11671
11496 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 11672 udata.change = ObjectChangeType.groupUS;
11497 handlerUpdatePrimScale(localId, scale6, this); 11673 updatehandler(localId, udata, this);
11498 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11674 break;
11499 if (handlerUpdatePrimSinglePosition != null)
11500 {
11501 handlerUpdatePrimSinglePosition(localId, pos6, this);
11502 }
11503 11675
11504 part.IgnoreUndoUpdate = false; 11676 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11505 } 11677 udata.position = new Vector3(block.Data, 0);
11506 break; 11678 udata.scale = new Vector3(block.Data, 12);
11507 11679
11508 default: 11680 udata.change = ObjectChangeType.groupPUS;
11509 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 11681 updatehandler(localId, udata, this);
11510 break; 11682 break;
11683
11684 default:
11685 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
11686 break;
11687 }
11511 } 11688 }
11512 11689
11513// for (int j = 0; j < parts.Length; j++)
11514// parts[j].IgnoreUndoUpdate = false;
11515 } 11690 }
11516 } 11691 }
11517 } 11692 }
11518
11519 return true; 11693 return true;
11520 } 11694 }
11521 11695
@@ -11974,7 +12148,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11974// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12148// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
11975// requestID, taskID, (SourceType)sourceType, Name); 12149// requestID, taskID, (SourceType)sourceType, Name);
11976 12150
12151
12152 //Note, the bool returned from the below function is useless since it is always false.
11977 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12153 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12154
11978 } 12155 }
11979 12156
11980 /// <summary> 12157 /// <summary>
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index ffa3be4..ae72175 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -158,6 +158,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
158 158
159 private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC 159 private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC
160 private int m_maxRTO = 60000; 160 private int m_maxRTO = 60000;
161 public bool m_deliverPackets = true;
161 162
162 /// <summary> 163 /// <summary>
163 /// Default constructor 164 /// Default constructor
@@ -439,6 +440,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
439 if (category >= 0 && category < m_packetOutboxes.Length) 440 if (category >= 0 && category < m_packetOutboxes.Length)
440 { 441 {
441 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; 442 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
443
444 if (m_deliverPackets == false)
445 {
446 queue.Enqueue(packet);
447 return true;
448 }
449
442 TokenBucket bucket = m_throttleCategories[category]; 450 TokenBucket bucket = m_throttleCategories[category];
443 451
444 // Don't send this packet if there is already a packet waiting in the queue 452 // Don't send this packet if there is already a packet waiting in the queue
@@ -488,7 +496,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
488 /// <returns>True if any packets were sent, otherwise false</returns> 496 /// <returns>True if any packets were sent, otherwise false</returns>
489 public bool DequeueOutgoing() 497 public bool DequeueOutgoing()
490 { 498 {
491 OutgoingPacket packet; 499 if (m_deliverPackets == false) return false;
500
501 OutgoingPacket packet = null;
492 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 502 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
493 TokenBucket bucket; 503 TokenBucket bucket;
494 bool packetSent = false; 504 bool packetSent = false;
@@ -520,32 +530,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP
520 // No dequeued packet waiting to be sent, try to pull one off 530 // No dequeued packet waiting to be sent, try to pull one off
521 // this queue 531 // this queue
522 queue = m_packetOutboxes[i]; 532 queue = m_packetOutboxes[i];
523 if (queue.Dequeue(out packet)) 533 if (queue != null)
524 { 534 {
525 // A packet was pulled off the queue. See if we have 535 bool success = false;
526 // enough tokens in the bucket to send it out 536 try
527 if (bucket.RemoveTokens(packet.Buffer.DataLength))
528 { 537 {
529 // Send the packet 538 success = queue.Dequeue(out packet);
530 m_udpServer.SendPacketFinal(packet);
531 packetSent = true;
532 } 539 }
533 else 540 catch
534 { 541 {
535 // Save the dequeued packet for the next iteration 542 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
536 m_nextPackets[i] = packet;
537 } 543 }
538 544 if (success)
539 // If the queue is empty after this dequeue, fire the queue 545 {
540 // empty callback now so it has a chance to fill before we 546 // A packet was pulled off the queue. See if we have
541 // get back here 547 // enough tokens in the bucket to send it out
542 if (queue.Count == 0) 548 if (bucket.RemoveTokens(packet.Buffer.DataLength))
549 {
550 // Send the packet
551 m_udpServer.SendPacketFinal(packet);
552 packetSent = true;
553 }
554 else
555 {
556 // Save the dequeued packet for the next iteration
557 m_nextPackets[i] = packet;
558 }
559
560 // If the queue is empty after this dequeue, fire the queue
561 // empty callback now so it has a chance to fill before we
562 // get back here
563 if (queue.Count == 0)
564 emptyCategories |= CategoryToFlag(i);
565 }
566 else
567 {
568 // No packets in this queue. Fire the queue empty callback
569 // if it has not been called recently
543 emptyCategories |= CategoryToFlag(i); 570 emptyCategories |= CategoryToFlag(i);
571 }
544 } 572 }
545 else 573 else
546 { 574 {
547 // No packets in this queue. Fire the queue empty callback 575 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
548 // if it has not been called recently
549 emptyCategories |= CategoryToFlag(i); 576 emptyCategories |= CategoryToFlag(i);
550 } 577 }
551 } 578 }
@@ -703,4 +730,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP
703 } 730 }
704 } 731 }
705 } 732 }
706} \ No newline at end of file 733}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index edf91cb..dda4444 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -1053,7 +1053,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1053 if (m_scene.TryGetClient(udpClient.AgentID, out client)) 1053 if (m_scene.TryGetClient(udpClient.AgentID, out client))
1054 { 1054 {
1055 client.IsLoggingOut = true; 1055 client.IsLoggingOut = true;
1056 client.Close(); 1056 client.Close(false);
1057 } 1057 }
1058 } 1058 }
1059 1059
@@ -1065,6 +1065,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1065 1065
1066 while (base.IsRunning) 1066 while (base.IsRunning)
1067 { 1067 {
1068 m_scene.ThreadAlive(1);
1068 try 1069 try
1069 { 1070 {
1070 IncomingPacket incomingPacket = null; 1071 IncomingPacket incomingPacket = null;
@@ -1107,6 +1108,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1107 1108
1108 while (base.IsRunning) 1109 while (base.IsRunning)
1109 { 1110 {
1111 m_scene.ThreadAlive(2);
1110 try 1112 try
1111 { 1113 {
1112 m_packetSent = false; 1114 m_packetSent = false;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 039379d..cfe7c9d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -100,10 +100,6 @@ namespace OpenMetaverse
100 const int SIO_UDP_CONNRESET = -1744830452; 100 const int SIO_UDP_CONNRESET = -1744830452;
101 101
102 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort); 102 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort);
103
104 m_log.DebugFormat(
105 "[UDPBASE]: Binding UDP listener using internal IP address config {0}:{1}",
106 ipep.Address, ipep.Port);
107 103
108 m_udpSocket = new Socket( 104 m_udpSocket = new Socket(
109 AddressFamily.InterNetwork, 105 AddressFamily.InterNetwork,