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.cs1196
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs65
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs80
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs4
5 files changed, 796 insertions, 552 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 01ceeed..f7bb817 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;
@@ -325,6 +329,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
325 private Prioritizer m_prioritizer; 329 private Prioritizer m_prioritizer;
326 private bool m_disableFacelights = false; 330 private bool m_disableFacelights = false;
327 331
332 private const uint MaxTransferBytesPerPacket = 600;
333
334
328 /// <value> 335 /// <value>
329 /// List used in construction of data blocks for an object update packet. This is to stop us having to 336 /// List used in construction of data blocks for an object update packet. This is to stop us having to
330 /// continually recreate it. 337 /// continually recreate it.
@@ -336,14 +343,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
336 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 343 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
337 /// ownerless phantom. 344 /// ownerless phantom.
338 /// 345 ///
339 /// All manipulation of this set has to occur under a lock 346 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
340 /// 347 ///
341 /// </value> 348 /// </value>
342 protected HashSet<uint> m_killRecord; 349// protected HashSet<uint> m_killRecord;
343 350
344// protected HashSet<uint> m_attachmentsSent; 351// protected HashSet<uint> m_attachmentsSent;
345 352
346 private int m_moneyBalance; 353 private int m_moneyBalance;
354 private bool m_deliverPackets = true;
347 private int m_animationSequenceNumber = 1; 355 private int m_animationSequenceNumber = 1;
348 private bool m_SendLogoutPacketWhenClosing = true; 356 private bool m_SendLogoutPacketWhenClosing = true;
349 private AgentUpdateArgs lastarg; 357 private AgentUpdateArgs lastarg;
@@ -380,6 +388,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
380 get { return m_startpos; } 388 get { return m_startpos; }
381 set { m_startpos = value; } 389 set { m_startpos = value; }
382 } 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 }
383 public UUID AgentId { get { return m_agentId; } } 399 public UUID AgentId { get { return m_agentId; } }
384 public ISceneAgent SceneAgent { get; set; } 400 public ISceneAgent SceneAgent { get; set; }
385 public UUID ActiveGroupId { get { return m_activeGroupID; } } 401 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -457,7 +473,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
457 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 473 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
458 m_entityProps = new PriorityQueue(m_scene.Entities.Count); 474 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
459 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 475 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
460 m_killRecord = new HashSet<uint>(); 476// m_killRecord = new HashSet<uint>();
461// m_attachmentsSent = new HashSet<uint>(); 477// m_attachmentsSent = new HashSet<uint>();
462 478
463 m_assetService = m_scene.RequestModuleInterface<IAssetService>(); 479 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
@@ -487,11 +503,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
487 503
488 #region Client Methods 504 #region Client Methods
489 505
506
490 /// <summary> 507 /// <summary>
491 /// Close down the client view 508 /// Close down the client view
492 /// </summary> 509 /// </summary>
493 public void Close() 510 public void Close()
494 { 511 {
512 Close(true);
513 }
514
515 /// <summary>
516 /// Shut down the client view
517 /// </summary>
518 public void Close(bool sendStop)
519 {
520 IsActive = false;
495 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. 521 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
496 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. 522 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
497 lock (CloseSyncLock) 523 lock (CloseSyncLock)
@@ -500,7 +526,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
500 return; 526 return;
501 527
502 IsActive = false; 528 IsActive = false;
503 CloseWithoutChecks(); 529 CloseWithoutChecks(sendStop);
504 } 530 }
505 } 531 }
506 532
@@ -513,12 +539,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
513 /// 539 ///
514 /// Callers must lock ClosingSyncLock before calling. 540 /// Callers must lock ClosingSyncLock before calling.
515 /// </remarks> 541 /// </remarks>
516 public void CloseWithoutChecks() 542 public void CloseWithoutChecks(bool sendStop)
517 { 543 {
518 m_log.DebugFormat( 544 m_log.DebugFormat(
519 "[CLIENT]: Close has been called for {0} attached to scene {1}", 545 "[CLIENT]: Close has been called for {0} attached to scene {1}",
520 Name, m_scene.RegionInfo.RegionName); 546 Name, m_scene.RegionInfo.RegionName);
521 547
548 if (sendStop)
549 {
550 // Send the STOP packet
551 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
552 OutPacket(disable, ThrottleOutPacketType.Unknown);
553 }
554
555 IsActive = false;
556
522 // Shutdown the image manager 557 // Shutdown the image manager
523 ImageManager.Close(); 558 ImageManager.Close();
524 559
@@ -815,7 +850,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
815 reply.ChatData.OwnerID = fromAgentID; 850 reply.ChatData.OwnerID = fromAgentID;
816 reply.ChatData.SourceID = fromAgentID; 851 reply.ChatData.SourceID = fromAgentID;
817 852
818 OutPacket(reply, ThrottleOutPacketType.Task); 853 OutPacket(reply, ThrottleOutPacketType.Unknown);
819 } 854 }
820 855
821 /// <summary> 856 /// <summary>
@@ -1101,6 +1136,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1101 public virtual void SendLayerData(float[] map) 1136 public virtual void SendLayerData(float[] map)
1102 { 1137 {
1103 Util.FireAndForget(DoSendLayerData, map); 1138 Util.FireAndForget(DoSendLayerData, map);
1139
1140 // Send it sync, and async. It's not that much data
1141 // and it improves user experience just so much!
1142 DoSendLayerData(map);
1104 } 1143 }
1105 1144
1106 /// <summary> 1145 /// <summary>
@@ -1113,16 +1152,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1113 1152
1114 try 1153 try
1115 { 1154 {
1116 //for (int y = 0; y < 16; y++) 1155 for (int y = 0; y < 16; y++)
1117 //{ 1156 {
1118 // for (int x = 0; x < 16; x++) 1157 for (int x = 0; x < 16; x+=4)
1119 // { 1158 {
1120 // SendLayerData(x, y, map); 1159 SendLayerPacket(x, y, map);
1121 // } 1160 }
1122 //} 1161 }
1123
1124 // Send LayerData in a spiral pattern. Fun!
1125 SendLayerTopRight(map, 0, 0, 15, 15);
1126 } 1162 }
1127 catch (Exception e) 1163 catch (Exception e)
1128 { 1164 {
@@ -1130,51 +1166,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1130 } 1166 }
1131 } 1167 }
1132 1168
1133 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1134 {
1135 // Row
1136 for (int i = x1; i <= x2; i++)
1137 SendLayerData(i, y1, map);
1138
1139 // Column
1140 for (int j = y1 + 1; j <= y2; j++)
1141 SendLayerData(x2, j, map);
1142
1143 if (x2 - x1 > 0)
1144 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1145 }
1146
1147 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1148 {
1149 // Row in reverse
1150 for (int i = x2; i >= x1; i--)
1151 SendLayerData(i, y2, map);
1152
1153 // Column in reverse
1154 for (int j = y2 - 1; j >= y1; j--)
1155 SendLayerData(x1, j, map);
1156
1157 if (x2 - x1 > 0)
1158 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1159 }
1160
1161 /// <summary> 1169 /// <summary>
1162 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1170 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1163 /// </summary> 1171 /// </summary>
1164 /// <param name="map">heightmap</param> 1172 /// <param name="map">heightmap</param>
1165 /// <param name="px">X coordinate for patches 0..12</param> 1173 /// <param name="px">X coordinate for patches 0..12</param>
1166 /// <param name="py">Y coordinate for patches 0..15</param> 1174 /// <param name="py">Y coordinate for patches 0..15</param>
1167 // private void SendLayerPacket(float[] map, int y, int x) 1175 private void SendLayerPacket(int x, int y, float[] map)
1168 // { 1176 {
1169 // int[] patches = new int[4]; 1177 int[] patches = new int[4];
1170 // patches[0] = x + 0 + y * 16; 1178 patches[0] = x + 0 + y * 16;
1171 // patches[1] = x + 1 + y * 16; 1179 patches[1] = x + 1 + y * 16;
1172 // patches[2] = x + 2 + y * 16; 1180 patches[2] = x + 2 + y * 16;
1173 // patches[3] = x + 3 + y * 16; 1181 patches[3] = x + 3 + y * 16;
1174 1182
1175 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1183 float[] heightmap = (map.Length == 65536) ?
1176 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1184 map :
1177 // } 1185 LLHeightFieldMoronize(map);
1186
1187 try
1188 {
1189 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1190 OutPacket(layerpack, ThrottleOutPacketType.Land);
1191 }
1192 catch
1193 {
1194 for (int px = x ; px < x + 4 ; px++)
1195 SendLayerData(px, y, map);
1196 }
1197 }
1178 1198
1179 /// <summary> 1199 /// <summary>
1180 /// Sends a specified patch to a client 1200 /// Sends a specified patch to a client
@@ -1194,7 +1214,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1194 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1214 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1195 layerpack.Header.Reliable = true; 1215 layerpack.Header.Reliable = true;
1196 1216
1197 OutPacket(layerpack, ThrottleOutPacketType.Land); 1217 OutPacket(layerpack, ThrottleOutPacketType.Task);
1198 } 1218 }
1199 catch (Exception e) 1219 catch (Exception e)
1200 { 1220 {
@@ -1557,7 +1577,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1557 1577
1558 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1578 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1559 { 1579 {
1560// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1580// foreach (uint id in localIDs)
1581// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1561 1582
1562 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1583 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1563 // TODO: don't create new blocks if recycling an old packet 1584 // TODO: don't create new blocks if recycling an old packet
@@ -1579,17 +1600,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1579 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race 1600 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
1580 // condition where a kill can be processed before an out-of-date update for the same object. 1601 // condition where a kill can be processed before an out-of-date update for the same object.
1581 // ProcessEntityUpdates() also takes the m_killRecord lock. 1602 // ProcessEntityUpdates() also takes the m_killRecord lock.
1582 lock (m_killRecord) 1603// lock (m_killRecord)
1583 { 1604// {
1584 foreach (uint localID in localIDs) 1605// foreach (uint localID in localIDs)
1585 m_killRecord.Add(localID); 1606// m_killRecord.Add(localID);
1586 1607
1587 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1608 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1588 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1609 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1589 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1610 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1590 // scene objects in a viewer until that viewer is relogged in. 1611 // scene objects in a viewer until that viewer is relogged in.
1591 OutPacket(kill, ThrottleOutPacketType.Task); 1612 OutPacket(kill, ThrottleOutPacketType.Task);
1592 } 1613// }
1593 } 1614 }
1594 } 1615 }
1595 1616
@@ -2128,16 +2149,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2128 replytask.InventoryData.TaskID = taskID; 2149 replytask.InventoryData.TaskID = taskID;
2129 replytask.InventoryData.Serial = serial; 2150 replytask.InventoryData.Serial = serial;
2130 replytask.InventoryData.Filename = fileName; 2151 replytask.InventoryData.Filename = fileName;
2131 OutPacket(replytask, ThrottleOutPacketType.Asset); 2152 OutPacket(replytask, ThrottleOutPacketType.Task);
2132 } 2153 }
2133 2154
2134 public void SendXferPacket(ulong xferID, uint packet, byte[] data) 2155 public void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory)
2135 { 2156 {
2157 ThrottleOutPacketType type = ThrottleOutPacketType.Asset;
2158 if (isTaskInventory)
2159 type = ThrottleOutPacketType.Task;
2160
2136 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket); 2161 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket);
2137 sendXfer.XferID.ID = xferID; 2162 sendXfer.XferID.ID = xferID;
2138 sendXfer.XferID.Packet = packet; 2163 sendXfer.XferID.Packet = packet;
2139 sendXfer.DataPacket.Data = data; 2164 sendXfer.DataPacket.Data = data;
2140 OutPacket(sendXfer, ThrottleOutPacketType.Asset); 2165 OutPacket(sendXfer, type);
2141 } 2166 }
2142 2167
2143 public void SendAbortXferPacket(ulong xferID) 2168 public void SendAbortXferPacket(ulong xferID)
@@ -2319,6 +2344,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2319 OutPacket(sound, ThrottleOutPacketType.Task); 2344 OutPacket(sound, ThrottleOutPacketType.Task);
2320 } 2345 }
2321 2346
2347 public void SendTransferAbort(TransferRequestPacket transferRequest)
2348 {
2349 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2350 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2351 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2352 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2353 OutPacket(abort, ThrottleOutPacketType.Task);
2354 }
2355
2322 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2356 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2323 { 2357 {
2324 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2358 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2611,6 +2645,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2611 } 2645 }
2612 } 2646 }
2613 2647
2648 public void SendPartPhysicsProprieties(ISceneEntity entity)
2649 {
2650 SceneObjectPart part = (SceneObjectPart)entity;
2651 if (part != null && AgentId != UUID.Zero)
2652 {
2653 try
2654 {
2655 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
2656 if (eq != null)
2657 {
2658 uint localid = part.LocalId;
2659 byte physshapetype = part.PhysicsShapeType;
2660 float density = part.Density;
2661 float friction = part.Friction;
2662 float bounce = part.Bounciness;
2663 float gravmod = part.GravityModifier;
2664
2665 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2666 }
2667 }
2668 catch (Exception ex)
2669 {
2670 m_log.Error("Unable to send part Physics Proprieties - exception: " + ex.ToString());
2671 }
2672 part.UpdatePhysRequired = false;
2673 }
2674 }
2675
2676
2614 2677
2615 public void SendGroupNameReply(UUID groupLLUID, string GroupName) 2678 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
2616 { 2679 {
@@ -2708,7 +2771,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2708 else 2771 else
2709 { 2772 {
2710 int processedLength = 0; 2773 int processedLength = 0;
2711 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2774// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2775
2776 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2712 int packetNumber = 0; 2777 int packetNumber = 0;
2713 2778
2714 while (processedLength < req.AssetInf.Data.Length) 2779 while (processedLength < req.AssetInf.Data.Length)
@@ -2779,7 +2844,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2779 reply.Data.ParcelID = parcelID; 2844 reply.Data.ParcelID = parcelID;
2780 reply.Data.OwnerID = land.OwnerID; 2845 reply.Data.OwnerID = land.OwnerID;
2781 reply.Data.Name = Utils.StringToBytes(land.Name); 2846 reply.Data.Name = Utils.StringToBytes(land.Name);
2782 reply.Data.Desc = Utils.StringToBytes(land.Description); 2847 if (land != null && land.Description != null && land.Description != String.Empty)
2848 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2849 else
2850 reply.Data.Desc = new Byte[0];
2783 reply.Data.ActualArea = land.Area; 2851 reply.Data.ActualArea = land.Area;
2784 reply.Data.BillableArea = land.Area; // TODO: what is this? 2852 reply.Data.BillableArea = land.Area; // TODO: what is this?
2785 2853
@@ -3514,7 +3582,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3514 3582
3515 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3583 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3516 // TODO: don't create new blocks if recycling an old packet 3584 // TODO: don't create new blocks if recycling an old packet
3517 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3585 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3518 avp.ObjectData.TextureEntry = textureEntry; 3586 avp.ObjectData.TextureEntry = textureEntry;
3519 3587
3520 AvatarAppearancePacket.VisualParamBlock avblock = null; 3588 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3644,7 +3712,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3644 /// </summary> 3712 /// </summary>
3645 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3713 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3646 { 3714 {
3647 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3715 if (entity is SceneObjectPart)
3716 {
3717 SceneObjectPart e = (SceneObjectPart)entity;
3718 SceneObjectGroup g = e.ParentGroup;
3719 if (g.RootPart.Shape.State > 30) // HUD
3720 if (g.OwnerID != AgentId)
3721 return; // Don't send updates for other people's HUDs
3722 }
3723
3648 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3724 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3649 3725
3650 lock (m_entityUpdates.SyncRoot) 3726 lock (m_entityUpdates.SyncRoot)
@@ -3711,27 +3787,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3711 3787
3712 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3788 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3713 // condition where a kill can be processed before an out-of-date update for the same object. 3789 // condition where a kill can be processed before an out-of-date update for the same object.
3714 lock (m_killRecord) 3790 float avgTimeDilation = 1.0f;
3791 IEntityUpdate iupdate;
3792 Int32 timeinqueue; // this is just debugging code & can be dropped later
3793
3794 while (updatesThisCall < maxUpdates)
3715 { 3795 {
3716 float avgTimeDilation = 1.0f; 3796 lock (m_entityUpdates.SyncRoot)
3717 IEntityUpdate iupdate; 3797 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3718 Int32 timeinqueue; // this is just debugging code & can be dropped later 3798 break;
3719 3799
3720 while (updatesThisCall < maxUpdates) 3800 EntityUpdate update = (EntityUpdate)iupdate;
3801
3802 avgTimeDilation += update.TimeDilation;
3803 avgTimeDilation *= 0.5f;
3804
3805 if (update.Entity is SceneObjectPart)
3721 { 3806 {
3722 lock (m_entityUpdates.SyncRoot) 3807 SceneObjectPart part = (SceneObjectPart)update.Entity;
3723 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3724 break;
3725 3808
3726 EntityUpdate update = (EntityUpdate)iupdate; 3809 if (part.ParentGroup.IsDeleted)
3727 3810 continue;
3728 avgTimeDilation += update.TimeDilation;
3729 avgTimeDilation *= 0.5f;
3730 3811
3731 if (update.Entity is SceneObjectPart) 3812 if (part.ParentGroup.IsAttachment)
3813 { // Someone else's HUD, why are we getting these?
3814 if (part.ParentGroup.OwnerID != AgentId &&
3815 part.ParentGroup.RootPart.Shape.State >= 30)
3816 continue;
3817 ScenePresence sp;
3818 // Owner is not in the sim, don't update it to
3819 // anyone
3820 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3821 continue;
3822
3823 List<SceneObjectGroup> atts = sp.GetAttachments();
3824 bool found = false;
3825 foreach (SceneObjectGroup att in atts)
3826 {
3827 if (att == part.ParentGroup)
3828 {
3829 found = true;
3830 break;
3831 }
3832 }
3833
3834 // It's an attachment of a valid avatar, but
3835 // doesn't seem to be attached, skip
3836 if (!found)
3837 continue;
3838
3839 // On vehicle crossing, the attachments are received
3840 // while the avatar is still a child. Don't send
3841 // updates here because the LocalId has not yet
3842 // been updated and the viewer will derender the
3843 // attachments until the avatar becomes root.
3844 if (sp.IsChildAgent)
3845 continue;
3846
3847 // If the object is an attachment we don't want it to be in the kill
3848 // record. Else attaching from inworld and subsequently dropping
3849 // it will no longer work.
3850// lock (m_killRecord)
3851// {
3852// m_killRecord.Remove(part.LocalId);
3853// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3854// }
3855 }
3856 else
3732 { 3857 {
3733 SceneObjectPart part = (SceneObjectPart)update.Entity;
3734
3735 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3858 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3736 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3859 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3737 // safety measure. 3860 // safety measure.
@@ -3742,236 +3865,174 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3742 // 3865 //
3743 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3866 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3744 // after the root prim has been deleted. 3867 // after the root prim has been deleted.
3745 if (m_killRecord.Contains(part.LocalId)) 3868 //
3746 { 3869 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3747 // m_log.WarnFormat( 3870// lock (m_killRecord)
3748 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3871// {
3749 // part.LocalId, Name); 3872// if (m_killRecord.Contains(part.LocalId))
3750 continue; 3873// continue;
3751 } 3874// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3752 3875// continue;
3753 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3876// }
3877 }
3878
3879 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3880 {
3881 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3882 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3754 { 3883 {
3755 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3884 part.Shape.LightEntry = false;
3756 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3757 {
3758 part.Shape.LightEntry = false;
3759 }
3760 } 3885 }
3761 } 3886 }
3762 3887 }
3763 #region UpdateFlags to packet type conversion 3888
3764 3889 ++updatesThisCall;
3765 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; 3890
3766 3891 #region UpdateFlags to packet type conversion
3767 bool canUseCompressed = true; 3892
3768 bool canUseImproved = true; 3893 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3769 3894
3770 // Compressed object updates only make sense for LL primitives 3895 bool canUseCompressed = true;
3771 if (!(update.Entity is SceneObjectPart)) 3896 bool canUseImproved = true;
3897
3898 // Compressed object updates only make sense for LL primitives
3899 if (!(update.Entity is SceneObjectPart))
3900 {
3901 canUseCompressed = false;
3902 }
3903
3904 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3905 {
3906 canUseCompressed = false;
3907 canUseImproved = false;
3908 }
3909 else
3910 {
3911 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3912 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3913 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3914 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3772 { 3915 {
3773 canUseCompressed = false; 3916 canUseCompressed = false;
3774 } 3917 }
3775 3918
3776 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 3919 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3920 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3921 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3922 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3923 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3924 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3925 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3926 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3927 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3928 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3929 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3930 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3931 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3932 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3777 { 3933 {
3778 canUseCompressed = false;
3779 canUseImproved = false; 3934 canUseImproved = false;
3780 } 3935 }
3781 else 3936 }
3782 {
3783 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3784 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3785 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3786 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3787 {
3788 canUseCompressed = false;
3789 }
3790
3791 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3792 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3793 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3794 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3795 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3796 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3797 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3798 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3799 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3800 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3801 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3802 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3803 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3804 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3805 {
3806 canUseImproved = false;
3807 }
3808 }
3809
3810 #endregion UpdateFlags to packet type conversion
3811
3812 #region Block Construction
3813
3814 // TODO: Remove this once we can build compressed updates
3815 canUseCompressed = false;
3816 3937
3817 if (!canUseImproved && !canUseCompressed) 3938 #endregion UpdateFlags to packet type conversion
3818 {
3819 ObjectUpdatePacket.ObjectDataBlock updateBlock;
3820 3939
3821 if (update.Entity is ScenePresence) 3940 #region Block Construction
3822 {
3823 updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
3824 }
3825 else
3826 {
3827 SceneObjectPart part = (SceneObjectPart)update.Entity;
3828 updateBlock = CreatePrimUpdateBlock(part, AgentId);
3829
3830 // If the part has become a private hud since the update was scheduled then we do not
3831 // want to send it to other avatars.
3832 if (part.ParentGroup.IsAttachment
3833 && part.ParentGroup.HasPrivateAttachmentPoint
3834 && part.ParentGroup.AttachedAvatar != AgentId)
3835 continue;
3836
3837 // If the part has since been deleted, then drop the update. In the case of attachments,
3838 // this is to avoid spurious updates to other viewers since post-processing of attachments
3839 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3840 // of the test above).
3841 //
3842 // Actual deletions (kills) happen in another method.
3843 if (part.ParentGroup.IsDeleted)
3844 continue;
3845 }
3846 3941
3847 objectUpdateBlocks.Value.Add(updateBlock); 3942 // TODO: Remove this once we can build compressed updates
3848 objectUpdates.Value.Add(update); 3943 canUseCompressed = false;
3849 }
3850 else if (!canUseImproved)
3851 {
3852 SceneObjectPart part = (SceneObjectPart)update.Entity;
3853 ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
3854 = CreateCompressedUpdateBlock(part, updateFlags);
3855
3856 // If the part has since been deleted, then drop the update. In the case of attachments,
3857 // this is to avoid spurious updates to other viewers since post-processing of attachments
3858 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3859 // of the test above).
3860 //
3861 // Actual deletions (kills) happen in another method.
3862 if (part.ParentGroup.IsDeleted)
3863 continue;
3864 3944
3865 compressedUpdateBlocks.Value.Add(compressedBlock); 3945 if (!canUseImproved && !canUseCompressed)
3866 compressedUpdates.Value.Add(update); 3946 {
3947 if (update.Entity is ScenePresence)
3948 {
3949 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3867 } 3950 }
3868 else 3951 else
3869 { 3952 {
3870 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3953 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3871 {
3872 // Self updates go into a special list
3873 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3874 terseAgentUpdates.Value.Add(update);
3875 }
3876 else
3877 {
3878 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
3879 = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
3880
3881 // Everything else goes here
3882 if (update.Entity is SceneObjectPart)
3883 {
3884 SceneObjectPart part = (SceneObjectPart)update.Entity;
3885
3886 // If the part has become a private hud since the update was scheduled then we do not
3887 // want to send it to other avatars.
3888 if (part.ParentGroup.IsAttachment
3889 && part.ParentGroup.HasPrivateAttachmentPoint
3890 && part.ParentGroup.AttachedAvatar != AgentId)
3891 continue;
3892
3893 // If the part has since been deleted, then drop the update. In the case of attachments,
3894 // this is to avoid spurious updates to other viewers since post-processing of attachments
3895 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3896 // of the test above).
3897 //
3898 // Actual deletions (kills) happen in another method.
3899 if (part.ParentGroup.IsDeleted)
3900 continue;
3901 }
3902
3903 terseUpdateBlocks.Value.Add(terseUpdateBlock);
3904 terseUpdates.Value.Add(update);
3905 }
3906 } 3954 }
3955 }
3956 else if (!canUseImproved)
3957 {
3958 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3959 }
3960 else
3961 {
3962 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3963 // Self updates go into a special list
3964 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3965 else
3966 // Everything else goes here
3967 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3968 }
3969
3970 #endregion Block Construction
3971 }
3907 3972
3908 ++updatesThisCall; 3973 #region Packet Sending
3909 3974
3910 #endregion Block Construction 3975 const float TIME_DILATION = 1.0f;
3911 } 3976 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3912 3977
3913 #region Packet Sending 3978 if (terseAgentUpdateBlocks.IsValueCreated)
3914 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); 3979 {
3980 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3915 3981
3916 if (terseAgentUpdateBlocks.IsValueCreated) 3982 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3917 { 3983 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3918 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 3984 packet.RegionData.TimeDilation = timeDilation;
3985 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3919 3986
3920 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3987 for (int i = 0; i < blocks.Count; i++)
3921 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3988 packet.ObjectData[i] = blocks[i];
3922 packet.RegionData.TimeDilation = timeDilation;
3923 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3924 3989
3925 for (int i = 0; i < blocks.Count; i++) 3990 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3926 packet.ObjectData[i] = blocks[i]; 3991 }
3927 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3928 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3929 }
3930 3992
3931 if (objectUpdateBlocks.IsValueCreated) 3993 if (objectUpdateBlocks.IsValueCreated)
3932 { 3994 {
3933 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3995 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3934 3996
3935 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3997 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3936 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3998 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3937 packet.RegionData.TimeDilation = timeDilation; 3999 packet.RegionData.TimeDilation = timeDilation;
3938 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4000 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3939 4001
3940 for (int i = 0; i < blocks.Count; i++) 4002 for (int i = 0; i < blocks.Count; i++)
3941 packet.ObjectData[i] = blocks[i]; 4003 packet.ObjectData[i] = blocks[i];
3942 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4004
3943 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); }); 4005 OutPacket(packet, ThrottleOutPacketType.Task, true);
3944 } 4006 }
3945 4007
3946 if (compressedUpdateBlocks.IsValueCreated) 4008 if (compressedUpdateBlocks.IsValueCreated)
3947 { 4009 {
3948 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 4010 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3949 4011
3950 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); 4012 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3951 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4013 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3952 packet.RegionData.TimeDilation = timeDilation; 4014 packet.RegionData.TimeDilation = timeDilation;
3953 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count]; 4015 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3954
3955 for (int i = 0; i < blocks.Count; i++)
3956 packet.ObjectData[i] = blocks[i];
3957 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3958 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3959 }
3960 4016
3961 if (terseUpdateBlocks.IsValueCreated) 4017 for (int i = 0; i < blocks.Count; i++)
3962 { 4018 packet.ObjectData[i] = blocks[i];
3963 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 4019
3964 4020 OutPacket(packet, ThrottleOutPacketType.Task, true);
3965 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 4021 }
3966 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4022
3967 packet.RegionData.TimeDilation = timeDilation; 4023 if (terseUpdateBlocks.IsValueCreated)
3968 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4024 {
3969 4025 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3970 for (int i = 0; i < blocks.Count; i++) 4026
3971 packet.ObjectData[i] = blocks[i]; 4027 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3972 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4028 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3973 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 4029 packet.RegionData.TimeDilation = timeDilation;
3974 } 4030 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4031
4032 for (int i = 0; i < blocks.Count; i++)
4033 packet.ObjectData[i] = blocks[i];
4034
4035 OutPacket(packet, ThrottleOutPacketType.Task, true);
3975 } 4036 }
3976 4037
3977 #endregion Packet Sending 4038 #endregion Packet Sending
@@ -4264,11 +4325,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4264 4325
4265 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4326 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4266 // of the object rather than the properties when the packet was created 4327 // of the object rather than the properties when the packet was created
4267 OutPacket(packet, ThrottleOutPacketType.Task, true, 4328 // HACK : Remove intelligent resending until it's fixed in core
4268 delegate(OutgoingPacket oPacket) 4329 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4269 { 4330 // delegate(OutgoingPacket oPacket)
4270 ResendPropertyUpdates(updates, oPacket); 4331 // {
4271 }); 4332 // ResendPropertyUpdates(updates, oPacket);
4333 // });
4334 OutPacket(packet, ThrottleOutPacketType.Task, true);
4272 4335
4273 // pbcnt += blocks.Count; 4336 // pbcnt += blocks.Count;
4274 // ppcnt++; 4337 // ppcnt++;
@@ -4294,11 +4357,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4294 // of the object rather than the properties when the packet was created 4357 // of the object rather than the properties when the packet was created
4295 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4358 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4296 updates.Add(familyUpdates.Value[i]); 4359 updates.Add(familyUpdates.Value[i]);
4297 OutPacket(packet, ThrottleOutPacketType.Task, true, 4360 // HACK : Remove intelligent resending until it's fixed in core
4298 delegate(OutgoingPacket oPacket) 4361 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4299 { 4362 // delegate(OutgoingPacket oPacket)
4300 ResendPropertyUpdates(updates, oPacket); 4363 // {
4301 }); 4364 // ResendPropertyUpdates(updates, oPacket);
4365 // });
4366 OutPacket(packet, ThrottleOutPacketType.Task, true);
4302 4367
4303 // fpcnt++; 4368 // fpcnt++;
4304 // fbcnt++; 4369 // fbcnt++;
@@ -4447,37 +4512,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4447 if (bl[i].BannedUserID == UUID.Zero) 4512 if (bl[i].BannedUserID == UUID.Zero)
4448 continue; 4513 continue;
4449 BannedUsers.Add(bl[i].BannedUserID); 4514 BannedUsers.Add(bl[i].BannedUserID);
4450 }
4451 4515
4452 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4516 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4453 packet.AgentData.TransactionID = UUID.Random(); 4517 {
4454 packet.AgentData.AgentID = AgentId; 4518 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4455 packet.AgentData.SessionID = SessionId; 4519 packet.AgentData.TransactionID = UUID.Random();
4456 packet.MethodData.Invoice = invoice; 4520 packet.AgentData.AgentID = AgentId;
4457 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4521 packet.AgentData.SessionID = SessionId;
4522 packet.MethodData.Invoice = invoice;
4523 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4458 4524
4459 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4525 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4460 4526
4461 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4527 int j;
4462 { 4528 for (j = 0; j < (6 + BannedUsers.Count); j++)
4463 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4529 {
4464 } 4530 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4465 int j = 0; 4531 }
4532 j = 0;
4466 4533
4467 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4534 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4468 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4535 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4469 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4536 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4470 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4537 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4471 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4538 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4472 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4539 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4473 4540
4474 foreach (UUID banned in BannedUsers) 4541 foreach (UUID banned in BannedUsers)
4475 { 4542 {
4476 returnblock[j].Parameter = banned.GetBytes(); j++; 4543 returnblock[j].Parameter = banned.GetBytes(); j++;
4544 }
4545 packet.ParamList = returnblock;
4546 packet.Header.Reliable = true;
4547 OutPacket(packet, ThrottleOutPacketType.Task);
4548
4549 BannedUsers.Clear();
4550 }
4477 } 4551 }
4478 packet.ParamList = returnblock; 4552
4479 packet.Header.Reliable = false;
4480 OutPacket(packet, ThrottleOutPacketType.Task);
4481 } 4553 }
4482 4554
4483 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4555 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4663,7 +4735,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4663 4735
4664 if (landData.SimwideArea > 0) 4736 if (landData.SimwideArea > 0)
4665 { 4737 {
4666 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4738 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4739 // Never report more than sim total capacity
4740 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4741 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4667 updateMessage.SimWideMaxPrims = simulatorCapacity; 4742 updateMessage.SimWideMaxPrims = simulatorCapacity;
4668 } 4743 }
4669 else 4744 else
@@ -4792,14 +4867,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4792 4867
4793 if (notifyCount > 0) 4868 if (notifyCount > 0)
4794 { 4869 {
4795 if (notifyCount > 32) 4870// if (notifyCount > 32)
4796 { 4871// {
4797 m_log.InfoFormat( 4872// m_log.InfoFormat(
4798 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4873// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4799 + " - a developer might want to investigate whether this is a hard limit", 32); 4874// + " - a developer might want to investigate whether this is a hard limit", 32);
4800 4875//
4801 notifyCount = 32; 4876// notifyCount = 32;
4802 } 4877// }
4803 4878
4804 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4879 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4805 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4880 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4854,9 +4929,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4854 { 4929 {
4855 ScenePresence presence = (ScenePresence)entity; 4930 ScenePresence presence = (ScenePresence)entity;
4856 4931
4932 position = presence.OffsetPosition;
4933 rotation = presence.Rotation;
4934
4935 if (presence.ParentID != 0)
4936 {
4937 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4938 if (part != null && part != part.ParentGroup.RootPart)
4939 {
4940 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4941 rotation = part.RotationOffset * presence.Rotation;
4942 }
4943 }
4944
4857 attachPoint = 0; 4945 attachPoint = 0;
4858 collisionPlane = presence.CollisionPlane; 4946 collisionPlane = presence.CollisionPlane;
4859 position = presence.OffsetPosition;
4860 velocity = presence.Velocity; 4947 velocity = presence.Velocity;
4861 acceleration = Vector3.Zero; 4948 acceleration = Vector3.Zero;
4862 4949
@@ -4866,7 +4953,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4866// acceleration = new Vector3(1, 0, 0); 4953// acceleration = new Vector3(1, 0, 0);
4867 4954
4868 angularVelocity = Vector3.Zero; 4955 angularVelocity = Vector3.Zero;
4869 rotation = presence.Rotation;
4870 4956
4871 if (sendTexture) 4957 if (sendTexture)
4872 textureEntry = presence.Appearance.Texture.GetBytes(); 4958 textureEntry = presence.Appearance.Texture.GetBytes();
@@ -4971,13 +5057,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4971 5057
4972 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5058 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
4973 { 5059 {
5060 Vector3 offsetPosition = data.OffsetPosition;
5061 Quaternion rotation = data.Rotation;
5062 uint parentID = data.ParentID;
5063
5064 if (parentID != 0)
5065 {
5066 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5067 if (part != null && part != part.ParentGroup.RootPart)
5068 {
5069 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5070 rotation = part.RotationOffset * data.Rotation;
5071 parentID = part.ParentGroup.RootPart.LocalId;
5072 }
5073 }
5074
4974 byte[] objectData = new byte[76]; 5075 byte[] objectData = new byte[76];
4975 5076
4976 data.CollisionPlane.ToBytes(objectData, 0); 5077 data.CollisionPlane.ToBytes(objectData, 0);
4977 data.OffsetPosition.ToBytes(objectData, 16); 5078 offsetPosition.ToBytes(objectData, 16);
4978// data.Velocity.ToBytes(objectData, 28); 5079// data.Velocity.ToBytes(objectData, 28);
4979// data.Acceleration.ToBytes(objectData, 40); 5080// data.Acceleration.ToBytes(objectData, 40);
4980 data.Rotation.ToBytes(objectData, 52); 5081 rotation.ToBytes(objectData, 52);
4981 //data.AngularVelocity.ToBytes(objectData, 64); 5082 //data.AngularVelocity.ToBytes(objectData, 64);
4982 5083
4983 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5084 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -4991,7 +5092,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4991 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5092 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
4992 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5093 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
4993 update.ObjectData = objectData; 5094 update.ObjectData = objectData;
4994 update.ParentID = data.ParentID; 5095 update.ParentID = parentID;
4995 update.PathCurve = 16; 5096 update.PathCurve = 16;
4996 update.PathScaleX = 100; 5097 update.PathScaleX = 100;
4997 update.PathScaleY = 100; 5098 update.PathScaleY = 100;
@@ -5009,10 +5110,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5009 update.TextureEntry = Utils.EmptyBytes; 5110 update.TextureEntry = Utils.EmptyBytes;
5010// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; 5111// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
5011 5112
5113/* 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)
5012 update.UpdateFlags = (uint)( 5114 update.UpdateFlags = (uint)(
5013 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | 5115 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
5014 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | 5116 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
5015 PrimFlags.ObjectOwnerModify); 5117 PrimFlags.ObjectOwnerModify);
5118*/
5119 update.UpdateFlags = 0;
5016 5120
5017 return update; 5121 return update;
5018 } 5122 }
@@ -5332,6 +5436,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5332 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5436 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5333 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5437 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5334 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5438 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5439 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5335 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5440 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5336 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5441 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5337 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5442 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5398,6 +5503,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5398 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5503 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5399 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5504 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5400 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5505 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5506 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5401 5507
5402 AddGenericPacketHandler("autopilot", HandleAutopilot); 5508 AddGenericPacketHandler("autopilot", HandleAutopilot);
5403 } 5509 }
@@ -5433,6 +5539,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5433 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5539 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5434 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5540 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5435 (x.ControlFlags != lastarg.ControlFlags) || 5541 (x.ControlFlags != lastarg.ControlFlags) ||
5542 (x.ControlFlags != 0) ||
5436 (x.Far != lastarg.Far) || 5543 (x.Far != lastarg.Far) ||
5437 (x.Flags != lastarg.Flags) || 5544 (x.Flags != lastarg.Flags) ||
5438 (x.State != lastarg.State) || 5545 (x.State != lastarg.State) ||
@@ -5810,7 +5917,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5810 args.Channel = ch; 5917 args.Channel = ch;
5811 args.From = String.Empty; 5918 args.From = String.Empty;
5812 args.Message = Utils.BytesToString(msg); 5919 args.Message = Utils.BytesToString(msg);
5813 args.Type = ChatTypeEnum.Shout; 5920 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5814 args.Position = new Vector3(); 5921 args.Position = new Vector3();
5815 args.Scene = Scene; 5922 args.Scene = Scene;
5816 args.Sender = this; 5923 args.Sender = this;
@@ -6330,6 +6437,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6330 { 6437 {
6331 handlerCompleteMovementToRegion(sender, true); 6438 handlerCompleteMovementToRegion(sender, true);
6332 } 6439 }
6440 else
6441 m_log.Debug("HandleCompleteAgentMovement NULL handler");
6442
6333 handlerCompleteMovementToRegion = null; 6443 handlerCompleteMovementToRegion = null;
6334 6444
6335 return true; 6445 return true;
@@ -6347,7 +6457,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6347 return true; 6457 return true;
6348 } 6458 }
6349 #endregion 6459 #endregion
6350 6460/*
6351 StartAnim handlerStartAnim = null; 6461 StartAnim handlerStartAnim = null;
6352 StopAnim handlerStopAnim = null; 6462 StopAnim handlerStopAnim = null;
6353 6463
@@ -6371,6 +6481,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6371 } 6481 }
6372 } 6482 }
6373 return true; 6483 return true;
6484*/
6485 ChangeAnim handlerChangeAnim = null;
6486
6487 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6488 {
6489 handlerChangeAnim = OnChangeAnim;
6490 if (handlerChangeAnim != null)
6491 {
6492 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6493 }
6494 }
6495
6496 handlerChangeAnim = OnChangeAnim;
6497 if (handlerChangeAnim != null)
6498 {
6499 handlerChangeAnim(UUID.Zero, false, true);
6500 }
6501
6502 return true;
6374 } 6503 }
6375 6504
6376 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6505 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -6996,10 +7125,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6996 // 46,47,48 are special positions within the packet 7125 // 46,47,48 are special positions within the packet
6997 // This may change so perhaps we need a better way 7126 // This may change so perhaps we need a better way
6998 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) 7127 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
6999 bool UsePhysics = (data[46] != 0) ? true : false; 7128 /*
7000 bool IsTemporary = (data[47] != 0) ? true : false; 7129 bool UsePhysics = (data[46] != 0) ? true : false;
7001 bool IsPhantom = (data[48] != 0) ? true : false; 7130 bool IsTemporary = (data[47] != 0) ? true : false;
7002 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this); 7131 bool IsPhantom = (data[48] != 0) ? true : false;
7132 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this);
7133 */
7134 bool UsePhysics = flags.AgentData.UsePhysics;
7135 bool IsPhantom = flags.AgentData.IsPhantom;
7136 bool IsTemporary = flags.AgentData.IsTemporary;
7137 ObjectFlagUpdatePacket.ExtraPhysicsBlock[] blocks = flags.ExtraPhysics;
7138 ExtraPhysicsData physdata = new ExtraPhysicsData();
7139
7140 if (blocks == null || blocks.Length == 0)
7141 {
7142 physdata.PhysShapeType = PhysShapeType.invalid;
7143 }
7144 else
7145 {
7146 ObjectFlagUpdatePacket.ExtraPhysicsBlock phsblock = blocks[0];
7147 physdata.PhysShapeType = (PhysShapeType)phsblock.PhysicsShapeType;
7148 physdata.Bounce = phsblock.Restitution;
7149 physdata.Density = phsblock.Density;
7150 physdata.Friction = phsblock.Friction;
7151 physdata.GravitationModifier = phsblock.GravityMultiplier;
7152 }
7153
7154 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
7003 } 7155 }
7004 return true; 7156 return true;
7005 } 7157 }
@@ -9853,7 +10005,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9853 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 10005 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9854 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 10006 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9855 UpdateMuteListEntry.MuteData.MuteType, 10007 UpdateMuteListEntry.MuteData.MuteType,
9856 UpdateMuteListEntry.AgentData.AgentID); 10008 UpdateMuteListEntry.MuteData.MuteFlags);
9857 return true; 10009 return true;
9858 } 10010 }
9859 return false; 10011 return false;
@@ -9868,8 +10020,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9868 { 10020 {
9869 handlerRemoveMuteListEntry(this, 10021 handlerRemoveMuteListEntry(this,
9870 RemoveMuteListEntry.MuteData.MuteID, 10022 RemoveMuteListEntry.MuteData.MuteID,
9871 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 10023 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9872 RemoveMuteListEntry.AgentData.AgentID);
9873 return true; 10024 return true;
9874 } 10025 }
9875 return false; 10026 return false;
@@ -9913,10 +10064,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9913 return false; 10064 return false;
9914 } 10065 }
9915 10066
10067 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10068 {
10069 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10070 (ChangeInventoryItemFlagsPacket)packet;
10071 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10072 if (handlerChangeInventoryItemFlags != null)
10073 {
10074 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10075 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10076 return true;
10077 }
10078 return false;
10079 }
10080
9916 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10081 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9917 { 10082 {
9918 return true; 10083 return true;
9919 } 10084 }
10085
10086 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10087 {
10088 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10089
10090 #region Packet Session and User Check
10091 if (m_checkPackets)
10092 {
10093 if (packet.AgentData.SessionID != SessionId ||
10094 packet.AgentData.AgentID != AgentId)
10095 return true;
10096 }
10097 #endregion
10098 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10099 List<InventoryItemBase> items = new List<InventoryItemBase>();
10100 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10101 {
10102 InventoryItemBase b = new InventoryItemBase();
10103 b.ID = n.OldItemID;
10104 b.Folder = n.OldFolderID;
10105 items.Add(b);
10106 }
10107
10108 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10109 if (handlerMoveItemsAndLeaveCopy != null)
10110 {
10111 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10112 }
10113
10114 return true;
10115 }
9920 10116
9921 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10117 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9922 { 10118 {
@@ -10343,6 +10539,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10343 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10539 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10344 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10540 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10345 10541
10542 Scene scene = (Scene)m_scene;
10543 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10544 {
10545 ScenePresence p;
10546 if (scene.TryGetScenePresence(sender.AgentId, out p))
10547 {
10548 if (p.GodLevel >= 200)
10549 {
10550 groupProfileReply.GroupData.OpenEnrollment = true;
10551 groupProfileReply.GroupData.MembershipFee = 0;
10552 }
10553 }
10554 }
10555
10346 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10556 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10347 } 10557 }
10348 return true; 10558 return true;
@@ -10916,11 +11126,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10916 11126
10917 StartLure handlerStartLure = OnStartLure; 11127 StartLure handlerStartLure = OnStartLure;
10918 if (handlerStartLure != null) 11128 if (handlerStartLure != null)
10919 handlerStartLure(startLureRequest.Info.LureType, 11129 {
10920 Utils.BytesToString( 11130 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10921 startLureRequest.Info.Message), 11131 {
10922 startLureRequest.TargetData[0].TargetID, 11132 handlerStartLure(startLureRequest.Info.LureType,
10923 this); 11133 Utils.BytesToString(
11134 startLureRequest.Info.Message),
11135 startLureRequest.TargetData[i].TargetID,
11136 this);
11137 }
11138 }
10924 return true; 11139 return true;
10925 } 11140 }
10926 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11141 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -11034,10 +11249,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11034 } 11249 }
11035 #endregion 11250 #endregion
11036 11251
11037 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11252 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11038 if (handlerClassifiedGodDelete != null) 11253 if (handlerClassifiedGodDelete != null)
11039 handlerClassifiedGodDelete( 11254 handlerClassifiedGodDelete(
11040 classifiedGodDelete.Data.ClassifiedID, 11255 classifiedGodDelete.Data.ClassifiedID,
11256 classifiedGodDelete.Data.QueryID,
11041 this); 11257 this);
11042 return true; 11258 return true;
11043 } 11259 }
@@ -11403,209 +11619,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11403 } 11619 }
11404 else 11620 else
11405 { 11621 {
11406// m_log.DebugFormat( 11622 ClientChangeObject updatehandler = onClientChangeObject;
11407// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11408// i, block.Type, part.Name, part.LocalId);
11409 11623
11410// // Do this once since fetch parts creates a new array. 11624 if (updatehandler != null)
11411// SceneObjectPart[] parts = part.ParentGroup.Parts; 11625 {
11412// for (int j = 0; j < parts.Length; j++) 11626 ObjectChangeData udata = new ObjectChangeData();
11413// {
11414// part.StoreUndoState();
11415// parts[j].IgnoreUndoUpdate = true;
11416// }
11417 11627
11418 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11628 /*ubit from ll JIRA:
11629 * 0x01 position
11630 * 0x02 rotation
11631 * 0x04 scale
11632
11633 * 0x08 LINK_SET
11634 * 0x10 UNIFORM for scale
11635 */
11419 11636
11420 switch (block.Type) 11637 // translate to internal changes
11421 { 11638 // not all cases .. just the ones older code did
11422 case 1:
11423 Vector3 pos1 = new Vector3(block.Data, 0);
11424 11639
11425 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11640 switch (block.Type)
11426 if (handlerUpdatePrimSinglePosition != null) 11641 {
11427 { 11642 case 1: //change position sp
11428 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11643 udata.position = new Vector3(block.Data, 0);
11429 handlerUpdatePrimSinglePosition(localId, pos1, this);
11430 }
11431 break;
11432 11644
11433 case 2: 11645 udata.change = ObjectChangeType.primP;
11434 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11646 updatehandler(localId, udata, this);
11647 break;
11435 11648
11436 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11649 case 2: // rotation sp
11437 if (handlerUpdatePrimSingleRotation != null) 11650 udata.rotation = new Quaternion(block.Data, 0, true);
11438 {
11439 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11440 handlerUpdatePrimSingleRotation(localId, rot1, this);
11441 }
11442 break;
11443 11651
11444 case 3: 11652 udata.change = ObjectChangeType.primR;
11445 Vector3 rotPos = new Vector3(block.Data, 0); 11653 updatehandler(localId, udata, this);
11446 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11654 break;
11447 11655
11448 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11656 case 3: // position plus rotation
11449 if (handlerUpdatePrimSingleRotationPosition != null) 11657 udata.position = new Vector3(block.Data, 0);
11450 { 11658 udata.rotation = new Quaternion(block.Data, 12, true);
11451 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11452 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11453 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11454 }
11455 break;
11456 11659
11457 case 4: 11660 udata.change = ObjectChangeType.primPR;
11458 case 20: 11661 updatehandler(localId, udata, this);
11459 Vector3 scale4 = new Vector3(block.Data, 0); 11662 break;
11460 11663
11461 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11664 case 4: // scale sp
11462 if (handlerUpdatePrimScale != null) 11665 udata.scale = new Vector3(block.Data, 0);
11463 { 11666 udata.change = ObjectChangeType.primS;
11464 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11465 handlerUpdatePrimScale(localId, scale4, this);
11466 }
11467 break;
11468 11667
11469 case 5: 11668 updatehandler(localId, udata, this);
11470 Vector3 scale1 = new Vector3(block.Data, 12); 11669 break;
11471 Vector3 pos11 = new Vector3(block.Data, 0);
11472 11670
11473 handlerUpdatePrimScale = OnUpdatePrimScale; 11671 case 0x14: // uniform scale sp
11474 if (handlerUpdatePrimScale != null) 11672 udata.scale = new Vector3(block.Data, 0);
11475 {
11476 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11477 handlerUpdatePrimScale(localId, scale1, this);
11478 11673
11479 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11674 udata.change = ObjectChangeType.primUS;
11480 if (handlerUpdatePrimSinglePosition != null) 11675 updatehandler(localId, udata, this);
11481 { 11676 break;
11482 handlerUpdatePrimSinglePosition(localId, pos11, this);
11483 }
11484 }
11485 break;
11486 11677
11487 case 9: 11678 case 5: // scale and position sp
11488 Vector3 pos2 = new Vector3(block.Data, 0); 11679 udata.position = new Vector3(block.Data, 0);
11680 udata.scale = new Vector3(block.Data, 12);
11489 11681
11490 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11682 udata.change = ObjectChangeType.primPS;
11683 updatehandler(localId, udata, this);
11684 break;
11491 11685
11492 if (handlerUpdateVector != null) 11686 case 0x15: //uniform scale and position
11493 { 11687 udata.position = new Vector3(block.Data, 0);
11494 handlerUpdateVector(localId, pos2, this); 11688 udata.scale = new Vector3(block.Data, 12);
11495 }
11496 break;
11497 11689
11498 case 10: 11690 udata.change = ObjectChangeType.primPUS;
11499 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11691 updatehandler(localId, udata, this);
11692 break;
11500 11693
11501 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11694 // now group related (bit 4)
11502 if (handlerUpdatePrimRotation != null) 11695 case 9: //( 8 + 1 )group position
11503 { 11696 udata.position = new Vector3(block.Data, 0);
11504 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11505 handlerUpdatePrimRotation(localId, rot3, this);
11506 }
11507 break;
11508 11697
11509 case 11: 11698 udata.change = ObjectChangeType.groupP;
11510 Vector3 pos3 = new Vector3(block.Data, 0); 11699 updatehandler(localId, udata, this);
11511 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11700 break;
11512 11701
11513 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11702 case 0x0A: // (8 + 2) group rotation
11514 if (handlerUpdatePrimGroupRotation != null) 11703 udata.rotation = new Quaternion(block.Data, 0, true);
11515 {
11516 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11517 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11518 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11519 }
11520 break;
11521 case 12:
11522 case 28:
11523 Vector3 scale7 = new Vector3(block.Data, 0);
11524 11704
11525 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11705 udata.change = ObjectChangeType.groupR;
11526 if (handlerUpdatePrimGroupScale != null) 11706 updatehandler(localId, udata, this);
11527 { 11707 break;
11528 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11529 handlerUpdatePrimGroupScale(localId, scale7, this);
11530 }
11531 break;
11532 11708
11533 case 13: 11709 case 0x0B: //( 8 + 2 + 1) group rotation and position
11534 Vector3 scale2 = new Vector3(block.Data, 12); 11710 udata.position = new Vector3(block.Data, 0);
11535 Vector3 pos4 = new Vector3(block.Data, 0); 11711 udata.rotation = new Quaternion(block.Data, 12, true);
11536 11712
11537 handlerUpdatePrimScale = OnUpdatePrimScale; 11713 udata.change = ObjectChangeType.groupPR;
11538 if (handlerUpdatePrimScale != null) 11714 updatehandler(localId, udata, this);
11539 { 11715 break;
11540 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11541 handlerUpdatePrimScale(localId, scale2, this);
11542 11716
11543 // Change the position based on scale (for bug number 246) 11717 case 0x0C: // (8 + 4) group scale
11544 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11718 // only afects root prim and only sent by viewer editor object tab scaling
11545 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11719 // mouse edition only allows uniform scaling
11546 if (handlerUpdatePrimSinglePosition != null) 11720 // SL MAY CHANGE THIS in viewers
11547 {
11548 handlerUpdatePrimSinglePosition(localId, pos4, this);
11549 }
11550 }
11551 break;
11552 11721
11553 case 29: 11722 udata.scale = new Vector3(block.Data, 0);
11554 Vector3 scale5 = new Vector3(block.Data, 12);
11555 Vector3 pos5 = new Vector3(block.Data, 0);
11556 11723
11557 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11724 udata.change = ObjectChangeType.groupS;
11558 if (handlerUpdatePrimGroupScale != null) 11725 updatehandler(localId, udata, this);
11559 {
11560 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11561 part.StoreUndoState(true);
11562 part.IgnoreUndoUpdate = true;
11563 handlerUpdatePrimGroupScale(localId, scale5, this);
11564 handlerUpdateVector = OnUpdatePrimGroupPosition;
11565 11726
11566 if (handlerUpdateVector != null) 11727 break;
11567 {
11568 handlerUpdateVector(localId, pos5, this);
11569 }
11570 11728
11571 part.IgnoreUndoUpdate = false; 11729 case 0x0D: //(8 + 4 + 1) group scale and position
11572 } 11730 // exception as above
11573 11731
11574 break; 11732 udata.position = new Vector3(block.Data, 0);
11733 udata.scale = new Vector3(block.Data, 12);
11575 11734
11576 case 21: 11735 udata.change = ObjectChangeType.groupPS;
11577 Vector3 scale6 = new Vector3(block.Data, 12); 11736 updatehandler(localId, udata, this);
11578 Vector3 pos6 = new Vector3(block.Data, 0); 11737 break;
11579 11738
11580 handlerUpdatePrimScale = OnUpdatePrimScale; 11739 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11581 if (handlerUpdatePrimScale != null) 11740 udata.scale = new Vector3(block.Data, 0);
11582 {
11583 part.StoreUndoState(false);
11584 part.IgnoreUndoUpdate = true;
11585 11741
11586 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 11742 udata.change = ObjectChangeType.groupUS;
11587 handlerUpdatePrimScale(localId, scale6, this); 11743 updatehandler(localId, udata, this);
11588 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11744 break;
11589 if (handlerUpdatePrimSinglePosition != null)
11590 {
11591 handlerUpdatePrimSinglePosition(localId, pos6, this);
11592 }
11593 11745
11594 part.IgnoreUndoUpdate = false; 11746 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11595 } 11747 udata.position = new Vector3(block.Data, 0);
11596 break; 11748 udata.scale = new Vector3(block.Data, 12);
11597 11749
11598 default: 11750 udata.change = ObjectChangeType.groupPUS;
11599 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 11751 updatehandler(localId, udata, this);
11600 break; 11752 break;
11753
11754 default:
11755 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
11756 break;
11757 }
11601 } 11758 }
11602 11759
11603// for (int j = 0; j < parts.Length; j++)
11604// parts[j].IgnoreUndoUpdate = false;
11605 } 11760 }
11606 } 11761 }
11607 } 11762 }
11608
11609 return true; 11763 return true;
11610 } 11764 }
11611 11765
@@ -12055,7 +12209,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12055// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12209// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12056// requestID, taskID, (SourceType)sourceType, Name); 12210// requestID, taskID, (SourceType)sourceType, Name);
12057 12211
12212
12213 //Note, the bool returned from the below function is useless since it is always false.
12058 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12214 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12215
12059 } 12216 }
12060 12217
12061 /// <summary> 12218 /// <summary>
@@ -12121,7 +12278,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12121 /// <returns></returns> 12278 /// <returns></returns>
12122 private static int CalculateNumPackets(byte[] data) 12279 private static int CalculateNumPackets(byte[] data)
12123 { 12280 {
12124 const uint m_maxPacketSize = 600; 12281// const uint m_maxPacketSize = 600;
12282 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12125 int numPackets = 1; 12283 int numPackets = 1;
12126 12284
12127 if (data == null) 12285 if (data == null)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index 8963756..c472176 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
@@ -440,6 +441,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
440 if (category >= 0 && category < m_packetOutboxes.Length) 441 if (category >= 0 && category < m_packetOutboxes.Length)
441 { 442 {
442 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; 443 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
444
445 if (m_deliverPackets == false)
446 {
447 queue.Enqueue(packet);
448 return true;
449 }
450
443 TokenBucket bucket = m_throttleCategories[category]; 451 TokenBucket bucket = m_throttleCategories[category];
444 452
445 // Don't send this packet if there is already a packet waiting in the queue 453 // Don't send this packet if there is already a packet waiting in the queue
@@ -489,7 +497,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
489 /// <returns>True if any packets were sent, otherwise false</returns> 497 /// <returns>True if any packets were sent, otherwise false</returns>
490 public bool DequeueOutgoing() 498 public bool DequeueOutgoing()
491 { 499 {
492 OutgoingPacket packet; 500 if (m_deliverPackets == false) return false;
501
502 OutgoingPacket packet = null;
493 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 503 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
494 TokenBucket bucket; 504 TokenBucket bucket;
495 bool packetSent = false; 505 bool packetSent = false;
@@ -521,32 +531,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP
521 // No dequeued packet waiting to be sent, try to pull one off 531 // No dequeued packet waiting to be sent, try to pull one off
522 // this queue 532 // this queue
523 queue = m_packetOutboxes[i]; 533 queue = m_packetOutboxes[i];
524 if (queue.Dequeue(out packet)) 534 if (queue != null)
525 { 535 {
526 // A packet was pulled off the queue. See if we have 536 bool success = false;
527 // enough tokens in the bucket to send it out 537 try
528 if (bucket.RemoveTokens(packet.Buffer.DataLength))
529 { 538 {
530 // Send the packet 539 success = queue.Dequeue(out packet);
531 m_udpServer.SendPacketFinal(packet);
532 packetSent = true;
533 } 540 }
534 else 541 catch
535 { 542 {
536 // Save the dequeued packet for the next iteration 543 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
537 m_nextPackets[i] = packet;
538 } 544 }
539 545 if (success)
540 // If the queue is empty after this dequeue, fire the queue 546 {
541 // empty callback now so it has a chance to fill before we 547 // A packet was pulled off the queue. See if we have
542 // get back here 548 // enough tokens in the bucket to send it out
543 if (queue.Count == 0) 549 if (bucket.RemoveTokens(packet.Buffer.DataLength))
550 {
551 // Send the packet
552 m_udpServer.SendPacketFinal(packet);
553 packetSent = true;
554 }
555 else
556 {
557 // Save the dequeued packet for the next iteration
558 m_nextPackets[i] = packet;
559 }
560
561 // If the queue is empty after this dequeue, fire the queue
562 // empty callback now so it has a chance to fill before we
563 // get back here
564 if (queue.Count == 0)
565 emptyCategories |= CategoryToFlag(i);
566 }
567 else
568 {
569 // No packets in this queue. Fire the queue empty callback
570 // if it has not been called recently
544 emptyCategories |= CategoryToFlag(i); 571 emptyCategories |= CategoryToFlag(i);
572 }
545 } 573 }
546 else 574 else
547 { 575 {
548 // No packets in this queue. Fire the queue empty callback 576 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
549 // if it has not been called recently
550 emptyCategories |= CategoryToFlag(i); 577 emptyCategories |= CategoryToFlag(i);
551 } 578 }
552 } 579 }
@@ -704,4 +731,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP
704 } 731 }
705 } 732 }
706 } 733 }
707} \ No newline at end of file 734}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 55780d6..7042c9a 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -155,6 +155,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
155 /// <summary>Flag to signal when clients should send pings</summary> 155 /// <summary>Flag to signal when clients should send pings</summary>
156 protected bool m_sendPing; 156 protected bool m_sendPing;
157 157
158 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
159
158 private int m_defaultRTO = 0; 160 private int m_defaultRTO = 0;
159 private int m_maxRTO = 0; 161 private int m_maxRTO = 0;
160 private int m_ackTimeout = 0; 162 private int m_ackTimeout = 0;
@@ -765,19 +767,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
765 767
766 #region Packet to Client Mapping 768 #region Packet to Client Mapping
767 769
768 // UseCircuitCode handling 770 // If there is already a client for this endpoint, don't process UseCircuitCode
769 if (packet.Type == PacketType.UseCircuitCode) 771 IClientAPI client = null;
772 if (!m_scene.TryGetClient(address, out client))
770 { 773 {
771 object[] array = new object[] { buffer, packet }; 774 // UseCircuitCode handling
775 if (packet.Type == PacketType.UseCircuitCode)
776 {
777 // And if there is a UseCircuitCode pending, also drop it
778 lock (m_pendingCache)
779 {
780 if (m_pendingCache.Contains(address))
781 return;
772 782
773 Util.FireAndForget(HandleUseCircuitCode, array); 783 m_pendingCache.AddOrUpdate(address, new Queue<UDPPacketBuffer>(), 60);
784 }
774 785
775 return; 786 object[] array = new object[] { buffer, packet };
787
788 Util.FireAndForget(HandleUseCircuitCode, array);
789
790 return;
791 }
792 }
793
794 // If this is a pending connection, enqueue, don't process yet
795 lock (m_pendingCache)
796 {
797 Queue<UDPPacketBuffer> queue;
798 if (m_pendingCache.TryGetValue(address, out queue))
799 {
800 //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type);
801 queue.Enqueue(buffer);
802 return;
803 }
776 } 804 }
777 805
778 // Determine which agent this packet came from 806 // Determine which agent this packet came from
779 IClientAPI client; 807 if (client == null || !(client is LLClientView))
780 if (!m_scene.TryGetClient(address, out client) || !(client is LLClientView))
781 { 808 {
782 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); 809 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
783 return; 810 return;
@@ -786,7 +813,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
786 udpClient = ((LLClientView)client).UDPClient; 813 udpClient = ((LLClientView)client).UDPClient;
787 814
788 if (!udpClient.IsConnected) 815 if (!udpClient.IsConnected)
816 {
817// m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName);
789 return; 818 return;
819 }
790 820
791 #endregion Packet to Client Mapping 821 #endregion Packet to Client Mapping
792 822
@@ -1011,6 +1041,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1011 // We only want to send initial data to new clients, not ones which are being converted from child to root. 1041 // We only want to send initial data to new clients, not ones which are being converted from child to root.
1012 if (client != null) 1042 if (client != null)
1013 client.SceneAgent.SendInitialDataToMe(); 1043 client.SceneAgent.SendInitialDataToMe();
1044
1045 // Now we know we can handle more data
1046 Thread.Sleep(200);
1047
1048 // Obtain the queue and remove it from the cache
1049 Queue<UDPPacketBuffer> queue = null;
1050
1051 lock (m_pendingCache)
1052 {
1053 if (!m_pendingCache.TryGetValue(remoteEndPoint, out queue))
1054 {
1055 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1056 return;
1057 }
1058 m_pendingCache.Remove(remoteEndPoint);
1059 }
1060
1061 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
1062
1063 // Reinject queued packets
1064 while(queue.Count > 0)
1065 {
1066 UDPPacketBuffer buf = queue.Dequeue();
1067 PacketReceived(buf);
1068 }
1069 queue = null;
1014 } 1070 }
1015 else 1071 else
1016 { 1072 {
@@ -1018,6 +1074,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1018 m_log.WarnFormat( 1074 m_log.WarnFormat(
1019 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1075 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
1020 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, remoteEndPoint); 1076 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, remoteEndPoint);
1077 lock (m_pendingCache)
1078 m_pendingCache.Remove(remoteEndPoint);
1021 } 1079 }
1022 1080
1023 // m_log.DebugFormat( 1081 // m_log.DebugFormat(
@@ -1136,7 +1194,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1136 if (!client.SceneAgent.IsChildAgent) 1194 if (!client.SceneAgent.IsChildAgent)
1137 client.Kick("Simulator logged you out due to connection timeout"); 1195 client.Kick("Simulator logged you out due to connection timeout");
1138 1196
1139 client.CloseWithoutChecks(); 1197 client.CloseWithoutChecks(true);
1140 } 1198 }
1141 } 1199 }
1142 1200
@@ -1148,6 +1206,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1148 1206
1149 while (base.IsRunning) 1207 while (base.IsRunning)
1150 { 1208 {
1209 m_scene.ThreadAlive(1);
1151 try 1210 try
1152 { 1211 {
1153 IncomingPacket incomingPacket = null; 1212 IncomingPacket incomingPacket = null;
@@ -1190,6 +1249,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1190 1249
1191 while (base.IsRunning) 1250 while (base.IsRunning)
1192 { 1251 {
1252 m_scene.ThreadAlive(2);
1193 try 1253 try
1194 { 1254 {
1195 m_packetSent = false; 1255 m_packetSent = false;
@@ -1455,8 +1515,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1455 if (!client.IsLoggingOut) 1515 if (!client.IsLoggingOut)
1456 { 1516 {
1457 client.IsLoggingOut = true; 1517 client.IsLoggingOut = true;
1458 client.Close(); 1518 client.Close(false);
1459 } 1519 }
1460 } 1520 }
1461 } 1521 }
1462} \ No newline at end of file 1522}
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,