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.cs1451
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs115
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs121
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs4
5 files changed, 1081 insertions, 613 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 1609012..166dcda 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -100,6 +100,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
100 public event AvatarPickerRequest OnAvatarPickerRequest; 100 public event AvatarPickerRequest OnAvatarPickerRequest;
101 public event StartAnim OnStartAnim; 101 public event StartAnim OnStartAnim;
102 public event StopAnim OnStopAnim; 102 public event StopAnim OnStopAnim;
103 public event ChangeAnim OnChangeAnim;
103 public event Action<IClientAPI> OnRequestAvatarsData; 104 public event Action<IClientAPI> OnRequestAvatarsData;
104 public event LinkObjects OnLinkObjects; 105 public event LinkObjects OnLinkObjects;
105 public event DelinkObjects OnDelinkObjects; 106 public event DelinkObjects OnDelinkObjects;
@@ -127,6 +128,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
127 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; 128 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
128 public event UpdatePrimFlags OnUpdatePrimFlags; 129 public event UpdatePrimFlags OnUpdatePrimFlags;
129 public event UpdatePrimTexture OnUpdatePrimTexture; 130 public event UpdatePrimTexture OnUpdatePrimTexture;
131 public event ClientChangeObject onClientChangeObject;
130 public event UpdateVector OnUpdatePrimGroupPosition; 132 public event UpdateVector OnUpdatePrimGroupPosition;
131 public event UpdateVector OnUpdatePrimSinglePosition; 133 public event UpdateVector OnUpdatePrimSinglePosition;
132 public event UpdatePrimRotation OnUpdatePrimGroupRotation; 134 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
@@ -160,6 +162,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
160 public event RequestTaskInventory OnRequestTaskInventory; 162 public event RequestTaskInventory OnRequestTaskInventory;
161 public event UpdateInventoryItem OnUpdateInventoryItem; 163 public event UpdateInventoryItem OnUpdateInventoryItem;
162 public event CopyInventoryItem OnCopyInventoryItem; 164 public event CopyInventoryItem OnCopyInventoryItem;
165 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
163 public event MoveInventoryItem OnMoveInventoryItem; 166 public event MoveInventoryItem OnMoveInventoryItem;
164 public event RemoveInventoryItem OnRemoveInventoryItem; 167 public event RemoveInventoryItem OnRemoveInventoryItem;
165 public event RemoveInventoryFolder OnRemoveInventoryFolder; 168 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -258,7 +261,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
258 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 261 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
259 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 262 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
260 public event ClassifiedDelete OnClassifiedDelete; 263 public event ClassifiedDelete OnClassifiedDelete;
261 public event ClassifiedDelete OnClassifiedGodDelete; 264 public event ClassifiedGodDelete OnClassifiedGodDelete;
262 public event EventNotificationAddRequest OnEventNotificationAddRequest; 265 public event EventNotificationAddRequest OnEventNotificationAddRequest;
263 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 266 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
264 public event EventGodDelete OnEventGodDelete; 267 public event EventGodDelete OnEventGodDelete;
@@ -289,10 +292,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
289 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; 292 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
290 public event SimWideDeletesDelegate OnSimWideDeletes; 293 public event SimWideDeletesDelegate OnSimWideDeletes;
291 public event SendPostcard OnSendPostcard; 294 public event SendPostcard OnSendPostcard;
295 public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
292 public event MuteListEntryUpdate OnUpdateMuteListEntry; 296 public event MuteListEntryUpdate OnUpdateMuteListEntry;
293 public event MuteListEntryRemove OnRemoveMuteListEntry; 297 public event MuteListEntryRemove OnRemoveMuteListEntry;
294 public event GodlikeMessage onGodlikeMessage; 298 public event GodlikeMessage onGodlikeMessage;
295 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate; 299 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
300 public event GenericCall2 OnUpdateThrottles;
296 301
297 #endregion Events 302 #endregion Events
298 303
@@ -327,6 +332,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
327 private Prioritizer m_prioritizer; 332 private Prioritizer m_prioritizer;
328 private bool m_disableFacelights = false; 333 private bool m_disableFacelights = false;
329 334
335 private bool m_VelocityInterpolate = false;
336 private const uint MaxTransferBytesPerPacket = 600;
337
338
330 /// <value> 339 /// <value>
331 /// List used in construction of data blocks for an object update packet. This is to stop us having to 340 /// List used in construction of data blocks for an object update packet. This is to stop us having to
332 /// continually recreate it. 341 /// continually recreate it.
@@ -338,14 +347,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
338 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 347 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
339 /// ownerless phantom. 348 /// ownerless phantom.
340 /// 349 ///
341 /// All manipulation of this set has to occur under a lock 350 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
342 /// 351 ///
343 /// </value> 352 /// </value>
344 protected HashSet<uint> m_killRecord; 353// protected HashSet<uint> m_killRecord;
345 354
346// protected HashSet<uint> m_attachmentsSent; 355// protected HashSet<uint> m_attachmentsSent;
347 356
348 private int m_moneyBalance; 357 private int m_moneyBalance;
358 private bool m_deliverPackets = true;
349 private int m_animationSequenceNumber = 1; 359 private int m_animationSequenceNumber = 1;
350 private bool m_SendLogoutPacketWhenClosing = true; 360 private bool m_SendLogoutPacketWhenClosing = true;
351 361
@@ -392,6 +402,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
392 get { return m_startpos; } 402 get { return m_startpos; }
393 set { m_startpos = value; } 403 set { m_startpos = value; }
394 } 404 }
405 public bool DeliverPackets
406 {
407 get { return m_deliverPackets; }
408 set {
409 m_deliverPackets = value;
410 m_udpClient.m_deliverPackets = value;
411 }
412 }
395 public UUID AgentId { get { return m_agentId; } } 413 public UUID AgentId { get { return m_agentId; } }
396 public ISceneAgent SceneAgent { get; set; } 414 public ISceneAgent SceneAgent { get; set; }
397 public UUID ActiveGroupId { get { return m_activeGroupID; } } 415 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -443,6 +461,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
443 } 461 }
444 462
445 public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } } 463 public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } }
464
446 465
447 #endregion Properties 466 #endregion Properties
448 467
@@ -469,7 +488,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
469 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 488 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
470 m_entityProps = new PriorityQueue(m_scene.Entities.Count); 489 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
471 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 490 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
472 m_killRecord = new HashSet<uint>(); 491// m_killRecord = new HashSet<uint>();
473// m_attachmentsSent = new HashSet<uint>(); 492// m_attachmentsSent = new HashSet<uint>();
474 493
475 m_assetService = m_scene.RequestModuleInterface<IAssetService>(); 494 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
@@ -499,12 +518,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
499 518
500 #region Client Methods 519 #region Client Methods
501 520
521
522 /// <summary>
523 /// Close down the client view
524 /// </summary>
502 public void Close() 525 public void Close()
503 { 526 {
504 Close(false); 527 Close(true, false);
505 } 528 }
506 529
507 public void Close(bool force) 530 public void Close(bool sendStop, bool force)
508 { 531 {
509 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. 532 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
510 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. 533 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
@@ -516,7 +539,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
516 return; 539 return;
517 540
518 IsActive = false; 541 IsActive = false;
519 CloseWithoutChecks(); 542 CloseWithoutChecks(sendStop);
520 } 543 }
521 } 544 }
522 545
@@ -529,12 +552,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
529 /// 552 ///
530 /// Callers must lock ClosingSyncLock before calling. 553 /// Callers must lock ClosingSyncLock before calling.
531 /// </remarks> 554 /// </remarks>
532 public void CloseWithoutChecks() 555 public void CloseWithoutChecks(bool sendStop)
533 { 556 {
534 m_log.DebugFormat( 557 m_log.DebugFormat(
535 "[CLIENT]: Close has been called for {0} attached to scene {1}", 558 "[CLIENT]: Close has been called for {0} attached to scene {1}",
536 Name, m_scene.RegionInfo.RegionName); 559 Name, m_scene.RegionInfo.RegionName);
537 560
561 if (sendStop)
562 {
563 // Send the STOP packet
564 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
565 OutPacket(disable, ThrottleOutPacketType.Unknown);
566 }
567
538 // Shutdown the image manager 568 // Shutdown the image manager
539 ImageManager.Close(); 569 ImageManager.Close();
540 570
@@ -557,6 +587,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
557 // Disable UDP handling for this client 587 // Disable UDP handling for this client
558 m_udpClient.Shutdown(); 588 m_udpClient.Shutdown();
559 589
590
560 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 591 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false));
561 //GC.Collect(); 592 //GC.Collect();
562 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true)); 593 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true));
@@ -797,7 +828,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
797 handshake.RegionInfo4[0].RegionFlagsExtended = args.regionFlags; 828 handshake.RegionInfo4[0].RegionFlagsExtended = args.regionFlags;
798 handshake.RegionInfo4[0].RegionProtocols = 0; // 1 here would indicate that SSB is supported 829 handshake.RegionInfo4[0].RegionProtocols = 0; // 1 here would indicate that SSB is supported
799 830
800 OutPacket(handshake, ThrottleOutPacketType.Task); 831 OutPacket(handshake, ThrottleOutPacketType.Unknown);
801 } 832 }
802 833
803 834
@@ -838,7 +869,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
838 reply.ChatData.OwnerID = ownerID; 869 reply.ChatData.OwnerID = ownerID;
839 reply.ChatData.SourceID = fromAgentID; 870 reply.ChatData.SourceID = fromAgentID;
840 871
841 OutPacket(reply, ThrottleOutPacketType.Task); 872 OutPacket(reply, ThrottleOutPacketType.Unknown);
842 } 873 }
843 874
844 /// <summary> 875 /// <summary>
@@ -871,32 +902,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
871 msg.MessageBlock.Message = Util.StringToBytes1024(im.message); 902 msg.MessageBlock.Message = Util.StringToBytes1024(im.message);
872 msg.MessageBlock.BinaryBucket = im.binaryBucket; 903 msg.MessageBlock.BinaryBucket = im.binaryBucket;
873 904
874 if (im.message.StartsWith("[grouptest]")) 905 OutPacket(msg, ThrottleOutPacketType.Task);
875 { // this block is test code for implementing group IM - delete when group IM is finished
876 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
877 if (eq != null)
878 {
879 im.dialog = 17;
880
881 //eq.ChatterboxInvitation(
882 // new UUID("00000000-68f9-1111-024e-222222111123"),
883 // "OpenSimulator Testing", im.fromAgentID, im.message, im.toAgentID, im.fromAgentName, im.dialog, 0,
884 // false, 0, new Vector3(), 1, im.imSessionID, im.fromGroup, im.binaryBucket);
885
886 eq.ChatterboxInvitation(
887 new UUID("00000000-68f9-1111-024e-222222111123"),
888 "OpenSimulator Testing", new UUID(im.fromAgentID), im.message, new UUID(im.toAgentID), im.fromAgentName, im.dialog, 0,
889 false, 0, new Vector3(), 1, new UUID(im.imSessionID), im.fromGroup, Util.StringToBytes256("OpenSimulator Testing"));
890
891 eq.ChatterBoxSessionAgentListUpdates(
892 new UUID("00000000-68f9-1111-024e-222222111123"),
893 new UUID(im.fromAgentID), new UUID(im.toAgentID), false, false, false);
894 }
895
896 Console.WriteLine("SendInstantMessage: " + msg);
897 }
898 else
899 OutPacket(msg, ThrottleOutPacketType.Task);
900 } 906 }
901 } 907 }
902 908
@@ -1124,6 +1130,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1124 public virtual void SendLayerData(float[] map) 1130 public virtual void SendLayerData(float[] map)
1125 { 1131 {
1126 Util.FireAndForget(DoSendLayerData, map); 1132 Util.FireAndForget(DoSendLayerData, map);
1133
1134 // Send it sync, and async. It's not that much data
1135 // and it improves user experience just so much!
1136 DoSendLayerData(map);
1127 } 1137 }
1128 1138
1129 /// <summary> 1139 /// <summary>
@@ -1136,16 +1146,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1136 1146
1137 try 1147 try
1138 { 1148 {
1139 //for (int y = 0; y < 16; y++) 1149 for (int y = 0; y < 16; y++)
1140 //{ 1150 {
1141 // for (int x = 0; x < 16; x++) 1151 for (int x = 0; x < 16; x+=4)
1142 // { 1152 {
1143 // SendLayerData(x, y, map); 1153 SendLayerPacket(x, y, map);
1144 // } 1154 }
1145 //} 1155 }
1146
1147 // Send LayerData in a spiral pattern. Fun!
1148 SendLayerTopRight(map, 0, 0, 15, 15);
1149 } 1156 }
1150 catch (Exception e) 1157 catch (Exception e)
1151 { 1158 {
@@ -1153,51 +1160,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1153 } 1160 }
1154 } 1161 }
1155 1162
1156 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1157 {
1158 // Row
1159 for (int i = x1; i <= x2; i++)
1160 SendLayerData(i, y1, map);
1161
1162 // Column
1163 for (int j = y1 + 1; j <= y2; j++)
1164 SendLayerData(x2, j, map);
1165
1166 if (x2 - x1 > 0)
1167 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1168 }
1169
1170 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1171 {
1172 // Row in reverse
1173 for (int i = x2; i >= x1; i--)
1174 SendLayerData(i, y2, map);
1175
1176 // Column in reverse
1177 for (int j = y2 - 1; j >= y1; j--)
1178 SendLayerData(x1, j, map);
1179
1180 if (x2 - x1 > 0)
1181 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1182 }
1183
1184 /// <summary> 1163 /// <summary>
1185 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1164 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1186 /// </summary> 1165 /// </summary>
1187 /// <param name="map">heightmap</param> 1166 /// <param name="map">heightmap</param>
1188 /// <param name="px">X coordinate for patches 0..12</param> 1167 /// <param name="px">X coordinate for patches 0..12</param>
1189 /// <param name="py">Y coordinate for patches 0..15</param> 1168 /// <param name="py">Y coordinate for patches 0..15</param>
1190 // private void SendLayerPacket(float[] map, int y, int x) 1169 private void SendLayerPacket(int x, int y, float[] map)
1191 // { 1170 {
1192 // int[] patches = new int[4]; 1171 int[] patches = new int[4];
1193 // patches[0] = x + 0 + y * 16; 1172 patches[0] = x + 0 + y * 16;
1194 // patches[1] = x + 1 + y * 16; 1173 patches[1] = x + 1 + y * 16;
1195 // patches[2] = x + 2 + y * 16; 1174 patches[2] = x + 2 + y * 16;
1196 // patches[3] = x + 3 + y * 16; 1175 patches[3] = x + 3 + y * 16;
1197 1176
1198 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1177 float[] heightmap = (map.Length == 65536) ?
1199 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1178 map :
1200 // } 1179 LLHeightFieldMoronize(map);
1180
1181 try
1182 {
1183 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1184 OutPacket(layerpack, ThrottleOutPacketType.Land);
1185 }
1186 catch
1187 {
1188 for (int px = x ; px < x + 4 ; px++)
1189 SendLayerData(px, y, map);
1190 }
1191 }
1201 1192
1202 /// <summary> 1193 /// <summary>
1203 /// Sends a specified patch to a client 1194 /// Sends a specified patch to a client
@@ -1217,7 +1208,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1217 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1208 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1218 layerpack.Header.Reliable = true; 1209 layerpack.Header.Reliable = true;
1219 1210
1220 OutPacket(layerpack, ThrottleOutPacketType.Land); 1211 OutPacket(layerpack, ThrottleOutPacketType.Task);
1221 } 1212 }
1222 catch (Exception e) 1213 catch (Exception e)
1223 { 1214 {
@@ -1580,7 +1571,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1580 1571
1581 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1572 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1582 { 1573 {
1583// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1574// foreach (uint id in localIDs)
1575// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1584 1576
1585 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1577 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1586 // TODO: don't create new blocks if recycling an old packet 1578 // TODO: don't create new blocks if recycling an old packet
@@ -1602,17 +1594,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1602 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race 1594 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
1603 // condition where a kill can be processed before an out-of-date update for the same object. 1595 // condition where a kill can be processed before an out-of-date update for the same object.
1604 // ProcessEntityUpdates() also takes the m_killRecord lock. 1596 // ProcessEntityUpdates() also takes the m_killRecord lock.
1605 lock (m_killRecord) 1597// lock (m_killRecord)
1606 { 1598// {
1607 foreach (uint localID in localIDs) 1599// foreach (uint localID in localIDs)
1608 m_killRecord.Add(localID); 1600// m_killRecord.Add(localID);
1609 1601
1610 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1602 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1611 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1603 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1612 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1604 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1613 // scene objects in a viewer until that viewer is relogged in. 1605 // scene objects in a viewer until that viewer is relogged in.
1614 OutPacket(kill, ThrottleOutPacketType.Task); 1606 OutPacket(kill, ThrottleOutPacketType.Task);
1615 } 1607// }
1616 } 1608 }
1617 } 1609 }
1618 1610
@@ -2071,9 +2063,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2071 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); 2063 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
2072 } 2064 }
2073 2065
2074 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2075 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId) 2066 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
2076 { 2067 {
2068 SendInventoryItemCreateUpdate(Item, UUID.Zero, callbackId);
2069 }
2070
2071 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2072 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId)
2073 {
2077 const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff; 2074 const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff;
2078 2075
2079 UpdateCreateInventoryItemPacket InventoryReply 2076 UpdateCreateInventoryItemPacket InventoryReply
@@ -2083,6 +2080,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2083 // TODO: don't create new blocks if recycling an old packet 2080 // TODO: don't create new blocks if recycling an old packet
2084 InventoryReply.AgentData.AgentID = AgentId; 2081 InventoryReply.AgentData.AgentID = AgentId;
2085 InventoryReply.AgentData.SimApproved = true; 2082 InventoryReply.AgentData.SimApproved = true;
2083 InventoryReply.AgentData.TransactionID = transactionID;
2086 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1]; 2084 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1];
2087 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock(); 2085 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock();
2088 InventoryReply.InventoryData[0].ItemID = Item.ID; 2086 InventoryReply.InventoryData[0].ItemID = Item.ID;
@@ -2152,16 +2150,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2152 replytask.InventoryData.TaskID = taskID; 2150 replytask.InventoryData.TaskID = taskID;
2153 replytask.InventoryData.Serial = serial; 2151 replytask.InventoryData.Serial = serial;
2154 replytask.InventoryData.Filename = fileName; 2152 replytask.InventoryData.Filename = fileName;
2155 OutPacket(replytask, ThrottleOutPacketType.Asset); 2153 OutPacket(replytask, ThrottleOutPacketType.Task);
2156 } 2154 }
2157 2155
2158 public void SendXferPacket(ulong xferID, uint packet, byte[] data) 2156 public void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory)
2159 { 2157 {
2158 ThrottleOutPacketType type = ThrottleOutPacketType.Asset;
2159 if (isTaskInventory)
2160 type = ThrottleOutPacketType.Task;
2161
2160 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket); 2162 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket);
2161 sendXfer.XferID.ID = xferID; 2163 sendXfer.XferID.ID = xferID;
2162 sendXfer.XferID.Packet = packet; 2164 sendXfer.XferID.Packet = packet;
2163 sendXfer.DataPacket.Data = data; 2165 sendXfer.DataPacket.Data = data;
2164 OutPacket(sendXfer, ThrottleOutPacketType.Asset); 2166 OutPacket(sendXfer, type);
2165 } 2167 }
2166 2168
2167 public void SendAbortXferPacket(ulong xferID) 2169 public void SendAbortXferPacket(ulong xferID)
@@ -2343,6 +2345,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2343 OutPacket(sound, ThrottleOutPacketType.Task); 2345 OutPacket(sound, ThrottleOutPacketType.Task);
2344 } 2346 }
2345 2347
2348 public void SendTransferAbort(TransferRequestPacket transferRequest)
2349 {
2350 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2351 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2352 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2353 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2354 OutPacket(abort, ThrottleOutPacketType.Task);
2355 }
2356
2346 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2357 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2347 { 2358 {
2348 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2359 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2651,6 +2662,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2651 float friction = part.Friction; 2662 float friction = part.Friction;
2652 float bounce = part.Restitution; 2663 float bounce = part.Restitution;
2653 float gravmod = part.GravityModifier; 2664 float gravmod = part.GravityModifier;
2665
2654 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId); 2666 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2655 } 2667 }
2656 } 2668 }
@@ -2721,8 +2733,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2721 req.AssetInf.ID, req.AssetInf.Metadata.ContentType); 2733 req.AssetInf.ID, req.AssetInf.Metadata.ContentType);
2722 return; 2734 return;
2723 } 2735 }
2736 int WearableOut = 0;
2737 bool isWearable = false;
2724 2738
2725 //m_log.Debug("sending asset " + req.RequestAssetID); 2739 if (req.AssetInf != null)
2740 isWearable =
2741 ((AssetType) req.AssetInf.Type ==
2742 AssetType.Bodypart || (AssetType) req.AssetInf.Type == AssetType.Clothing);
2743
2744
2745 //m_log.Debug("sending asset " + req.RequestAssetID + ", iswearable: " + isWearable);
2746
2747
2748 //if (isWearable)
2749 // m_log.Debug((AssetType)req.AssetInf.Type);
2750
2726 TransferInfoPacket Transfer = new TransferInfoPacket(); 2751 TransferInfoPacket Transfer = new TransferInfoPacket();
2727 Transfer.TransferInfo.ChannelType = 2; 2752 Transfer.TransferInfo.ChannelType = 2;
2728 Transfer.TransferInfo.Status = 0; 2753 Transfer.TransferInfo.Status = 0;
@@ -2744,7 +2769,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2744 Transfer.TransferInfo.Size = req.AssetInf.Data.Length; 2769 Transfer.TransferInfo.Size = req.AssetInf.Data.Length;
2745 Transfer.TransferInfo.TransferID = req.TransferRequestID; 2770 Transfer.TransferInfo.TransferID = req.TransferRequestID;
2746 Transfer.Header.Zerocoded = true; 2771 Transfer.Header.Zerocoded = true;
2747 OutPacket(Transfer, ThrottleOutPacketType.Asset); 2772 OutPacket(Transfer, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2748 2773
2749 if (req.NumPackets == 1) 2774 if (req.NumPackets == 1)
2750 { 2775 {
@@ -2755,12 +2780,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2755 TransferPacket.TransferData.Data = req.AssetInf.Data; 2780 TransferPacket.TransferData.Data = req.AssetInf.Data;
2756 TransferPacket.TransferData.Status = 1; 2781 TransferPacket.TransferData.Status = 1;
2757 TransferPacket.Header.Zerocoded = true; 2782 TransferPacket.Header.Zerocoded = true;
2758 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2783 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2759 } 2784 }
2760 else 2785 else
2761 { 2786 {
2762 int processedLength = 0; 2787 int processedLength = 0;
2763 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2788// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2789
2790 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2764 int packetNumber = 0; 2791 int packetNumber = 0;
2765 2792
2766 while (processedLength < req.AssetInf.Data.Length) 2793 while (processedLength < req.AssetInf.Data.Length)
@@ -2786,7 +2813,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2786 TransferPacket.TransferData.Status = 1; 2813 TransferPacket.TransferData.Status = 1;
2787 } 2814 }
2788 TransferPacket.Header.Zerocoded = true; 2815 TransferPacket.Header.Zerocoded = true;
2789 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2816 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2790 2817
2791 processedLength += chunkSize; 2818 processedLength += chunkSize;
2792 packetNumber++; 2819 packetNumber++;
@@ -2831,7 +2858,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2831 reply.Data.ParcelID = parcelID; 2858 reply.Data.ParcelID = parcelID;
2832 reply.Data.OwnerID = land.OwnerID; 2859 reply.Data.OwnerID = land.OwnerID;
2833 reply.Data.Name = Utils.StringToBytes(land.Name); 2860 reply.Data.Name = Utils.StringToBytes(land.Name);
2834 reply.Data.Desc = Utils.StringToBytes(land.Description); 2861 if (land != null && land.Description != null && land.Description != String.Empty)
2862 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2863 else
2864 reply.Data.Desc = new Byte[0];
2835 reply.Data.ActualArea = land.Area; 2865 reply.Data.ActualArea = land.Area;
2836 reply.Data.BillableArea = land.Area; // TODO: what is this? 2866 reply.Data.BillableArea = land.Area; // TODO: what is this?
2837 2867
@@ -3538,24 +3568,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3538 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count]; 3568 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count];
3539 AgentWearablesUpdatePacket.WearableDataBlock awb; 3569 AgentWearablesUpdatePacket.WearableDataBlock awb;
3540 int idx = 0; 3570 int idx = 0;
3541 for (int i = 0; i < wearables.Length; i++) 3571
3542 { 3572 for (int i = 0; i < wearables.Length; i++)
3543 for (int j = 0; j < wearables[i].Count; j++) 3573 {
3544 { 3574 for (int j = 0; j < wearables[i].Count; j++)
3545 awb = new AgentWearablesUpdatePacket.WearableDataBlock(); 3575 {
3546 awb.WearableType = (byte)i; 3576 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
3547 awb.AssetID = wearables[i][j].AssetID; 3577 awb.WearableType = (byte) i;
3548 awb.ItemID = wearables[i][j].ItemID; 3578 awb.AssetID = wearables[i][j].AssetID;
3549 aw.WearableData[idx] = awb; 3579 awb.ItemID = wearables[i][j].ItemID;
3550 idx++; 3580 aw.WearableData[idx] = awb;
3551 3581 idx++;
3552// m_log.DebugFormat( 3582
3553// "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}", 3583 // m_log.DebugFormat(
3554// awb.ItemID, awb.AssetID, i, Name); 3584 // "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}",
3555 } 3585 // awb.ItemID, awb.AssetID, i, Name);
3556 } 3586 }
3587 }
3557 3588
3558 OutPacket(aw, ThrottleOutPacketType.Task); 3589 OutPacket(aw, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority);
3559 } 3590 }
3560 3591
3561 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) 3592 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
@@ -3566,7 +3597,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3566 3597
3567 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3598 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3568 // TODO: don't create new blocks if recycling an old packet 3599 // TODO: don't create new blocks if recycling an old packet
3569 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3600 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3570 avp.ObjectData.TextureEntry = textureEntry; 3601 avp.ObjectData.TextureEntry = textureEntry;
3571 3602
3572 AvatarAppearancePacket.VisualParamBlock avblock = null; 3603 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3697,7 +3728,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3697 /// </summary> 3728 /// </summary>
3698 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3729 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3699 { 3730 {
3700 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3731 if (entity is SceneObjectPart)
3732 {
3733 SceneObjectPart e = (SceneObjectPart)entity;
3734 SceneObjectGroup g = e.ParentGroup;
3735 if (g.RootPart.Shape.State > 30) // HUD
3736 if (g.OwnerID != AgentId)
3737 return; // Don't send updates for other people's HUDs
3738 }
3739
3701 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3740 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3702 3741
3703 lock (m_entityUpdates.SyncRoot) 3742 lock (m_entityUpdates.SyncRoot)
@@ -3764,27 +3803,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3764 3803
3765 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3804 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3766 // condition where a kill can be processed before an out-of-date update for the same object. 3805 // condition where a kill can be processed before an out-of-date update for the same object.
3767 lock (m_killRecord) 3806 float avgTimeDilation = 1.0f;
3807 IEntityUpdate iupdate;
3808 Int32 timeinqueue; // this is just debugging code & can be dropped later
3809
3810 while (updatesThisCall < maxUpdates)
3768 { 3811 {
3769 float avgTimeDilation = 1.0f; 3812 lock (m_entityUpdates.SyncRoot)
3770 IEntityUpdate iupdate; 3813 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3771 Int32 timeinqueue; // this is just debugging code & can be dropped later 3814 break;
3772 3815
3773 while (updatesThisCall < maxUpdates) 3816 EntityUpdate update = (EntityUpdate)iupdate;
3817
3818 avgTimeDilation += update.TimeDilation;
3819 avgTimeDilation *= 0.5f;
3820
3821 if (update.Entity is SceneObjectPart)
3774 { 3822 {
3775 lock (m_entityUpdates.SyncRoot) 3823 SceneObjectPart part = (SceneObjectPart)update.Entity;
3776 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3777 break;
3778 3824
3779 EntityUpdate update = (EntityUpdate)iupdate; 3825 if (part.ParentGroup.IsDeleted)
3780 3826 continue;
3781 avgTimeDilation += update.TimeDilation;
3782 avgTimeDilation *= 0.5f;
3783 3827
3784 if (update.Entity is SceneObjectPart) 3828 if (part.ParentGroup.IsAttachment)
3829 { // Someone else's HUD, why are we getting these?
3830 if (part.ParentGroup.OwnerID != AgentId &&
3831 part.ParentGroup.RootPart.Shape.State > 30)
3832 continue;
3833 ScenePresence sp;
3834 // Owner is not in the sim, don't update it to
3835 // anyone
3836 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3837 continue;
3838
3839 List<SceneObjectGroup> atts = sp.GetAttachments();
3840 bool found = false;
3841 foreach (SceneObjectGroup att in atts)
3842 {
3843 if (att == part.ParentGroup)
3844 {
3845 found = true;
3846 break;
3847 }
3848 }
3849
3850 // It's an attachment of a valid avatar, but
3851 // doesn't seem to be attached, skip
3852 if (!found)
3853 continue;
3854
3855 // On vehicle crossing, the attachments are received
3856 // while the avatar is still a child. Don't send
3857 // updates here because the LocalId has not yet
3858 // been updated and the viewer will derender the
3859 // attachments until the avatar becomes root.
3860 if (sp.IsChildAgent)
3861 continue;
3862
3863 // If the object is an attachment we don't want it to be in the kill
3864 // record. Else attaching from inworld and subsequently dropping
3865 // it will no longer work.
3866// lock (m_killRecord)
3867// {
3868// m_killRecord.Remove(part.LocalId);
3869// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3870// }
3871 }
3872 else
3785 { 3873 {
3786 SceneObjectPart part = (SceneObjectPart)update.Entity;
3787
3788 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3874 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3789 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3875 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3790 // safety measure. 3876 // safety measure.
@@ -3795,21 +3881,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3795 // 3881 //
3796 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3882 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3797 // after the root prim has been deleted. 3883 // after the root prim has been deleted.
3798 if (m_killRecord.Contains(part.LocalId)) 3884 //
3799 { 3885 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3800 // m_log.WarnFormat( 3886// lock (m_killRecord)
3801 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3887// {
3802 // part.LocalId, Name); 3888// if (m_killRecord.Contains(part.LocalId))
3803 continue; 3889// continue;
3804 } 3890// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3805 3891// continue;
3806 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3892// }
3893 }
3894
3895 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3896 {
3897 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3898 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3807 { 3899 {
3808 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3900 part.Shape.LightEntry = false;
3809 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3810 {
3811 part.Shape.LightEntry = false;
3812 }
3813 } 3901 }
3814 3902
3815 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh)) 3903 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
@@ -3820,224 +3908,166 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3820 part.Shape.ProfileHollow = 27500; 3908 part.Shape.ProfileHollow = 27500;
3821 } 3909 }
3822 } 3910 }
3823 3911
3824 #region UpdateFlags to packet type conversion 3912 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
3825
3826 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3827
3828 bool canUseCompressed = true;
3829 bool canUseImproved = true;
3830
3831 // Compressed object updates only make sense for LL primitives
3832 if (!(update.Entity is SceneObjectPart))
3833 { 3913 {
3834 canUseCompressed = false; 3914 // Ensure that mesh has at least 8 valid faces
3915 part.Shape.ProfileBegin = 12500;
3916 part.Shape.ProfileEnd = 0;
3917 part.Shape.ProfileHollow = 27500;
3835 } 3918 }
3836 3919 }
3837 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 3920
3921 ++updatesThisCall;
3922
3923 #region UpdateFlags to packet type conversion
3924
3925 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3926
3927 bool canUseCompressed = true;
3928 bool canUseImproved = true;
3929
3930 // Compressed object updates only make sense for LL primitives
3931 if (!(update.Entity is SceneObjectPart))
3932 {
3933 canUseCompressed = false;
3934 }
3935
3936 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3937 {
3938 canUseCompressed = false;
3939 canUseImproved = false;
3940 }
3941 else
3942 {
3943 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3944 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3945 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3946 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3838 { 3947 {
3839 canUseCompressed = false; 3948 canUseCompressed = false;
3840 canUseImproved = false;
3841 } 3949 }
3842 else 3950
3951 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3952 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3953 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3954 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3955 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3956 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3957 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3958 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3959 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3960 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3961 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3962 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3963 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3964 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3843 { 3965 {
3844 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3966 canUseImproved = false;
3845 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3846 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3847 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3848 {
3849 canUseCompressed = false;
3850 }
3851
3852 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3853 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3854 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3855 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3856 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3857 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3858 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3859 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3860 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3861 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3862 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3863 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3864 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3865 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3866 {
3867 canUseImproved = false;
3868 }
3869 } 3967 }
3968 }
3870 3969
3871 #endregion UpdateFlags to packet type conversion 3970 #endregion UpdateFlags to packet type conversion
3872
3873 #region Block Construction
3874
3875 // TODO: Remove this once we can build compressed updates
3876 canUseCompressed = false;
3877
3878 if (!canUseImproved && !canUseCompressed)
3879 {
3880 ObjectUpdatePacket.ObjectDataBlock updateBlock;
3881 3971
3882 if (update.Entity is ScenePresence) 3972 #region Block Construction
3883 {
3884 updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
3885 }
3886 else
3887 {
3888 SceneObjectPart part = (SceneObjectPart)update.Entity;
3889 updateBlock = CreatePrimUpdateBlock(part, AgentId);
3890
3891 // If the part has become a private hud since the update was scheduled then we do not
3892 // want to send it to other avatars.
3893 if (part.ParentGroup.IsAttachment
3894 && part.ParentGroup.HasPrivateAttachmentPoint
3895 && part.ParentGroup.AttachedAvatar != AgentId)
3896 continue;
3897
3898 // If the part has since been deleted, then drop the update. In the case of attachments,
3899 // this is to avoid spurious updates to other viewers since post-processing of attachments
3900 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3901 // of the test above).
3902 //
3903 // Actual deletions (kills) happen in another method.
3904 if (part.ParentGroup.IsDeleted)
3905 continue;
3906 }
3907 3973
3908 objectUpdateBlocks.Value.Add(updateBlock); 3974 // TODO: Remove this once we can build compressed updates
3909 objectUpdates.Value.Add(update); 3975 canUseCompressed = false;
3910 }
3911 else if (!canUseImproved)
3912 {
3913 SceneObjectPart part = (SceneObjectPart)update.Entity;
3914 ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
3915 = CreateCompressedUpdateBlock(part, updateFlags);
3916
3917 // If the part has since been deleted, then drop the update. In the case of attachments,
3918 // this is to avoid spurious updates to other viewers since post-processing of attachments
3919 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3920 // of the test above).
3921 //
3922 // Actual deletions (kills) happen in another method.
3923 if (part.ParentGroup.IsDeleted)
3924 continue;
3925 3976
3926 compressedUpdateBlocks.Value.Add(compressedBlock); 3977 if (!canUseImproved && !canUseCompressed)
3927 compressedUpdates.Value.Add(update); 3978 {
3979 if (update.Entity is ScenePresence)
3980 {
3981 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3928 } 3982 }
3929 else 3983 else
3930 { 3984 {
3931 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3985 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3932 {
3933 // Self updates go into a special list
3934 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3935 terseAgentUpdates.Value.Add(update);
3936 }
3937 else
3938 {
3939 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
3940 = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
3941
3942 // Everything else goes here
3943 if (update.Entity is SceneObjectPart)
3944 {
3945 SceneObjectPart part = (SceneObjectPart)update.Entity;
3946
3947 // If the part has become a private hud since the update was scheduled then we do not
3948 // want to send it to other avatars.
3949 if (part.ParentGroup.IsAttachment
3950 && part.ParentGroup.HasPrivateAttachmentPoint
3951 && part.ParentGroup.AttachedAvatar != AgentId)
3952 continue;
3953
3954 // If the part has since been deleted, then drop the update. In the case of attachments,
3955 // this is to avoid spurious updates to other viewers since post-processing of attachments
3956 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3957 // of the test above).
3958 //
3959 // Actual deletions (kills) happen in another method.
3960 if (part.ParentGroup.IsDeleted)
3961 continue;
3962 }
3963
3964 terseUpdateBlocks.Value.Add(terseUpdateBlock);
3965 terseUpdates.Value.Add(update);
3966 }
3967 } 3986 }
3968
3969 ++updatesThisCall;
3970
3971 #endregion Block Construction
3972 } 3987 }
3973 3988 else if (!canUseImproved)
3974 #region Packet Sending
3975 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3976
3977 if (terseAgentUpdateBlocks.IsValueCreated)
3978 { 3989 {
3979 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 3990 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3991 }
3992 else
3993 {
3994 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3995 // Self updates go into a special list
3996 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3997 else
3998 // Everything else goes here
3999 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
4000 }
3980 4001
3981 ImprovedTerseObjectUpdatePacket packet 4002 #endregion Block Construction
3982 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 4003 }
3983 4004
3984 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4005 #region Packet Sending
3985 packet.RegionData.TimeDilation = timeDilation; 4006
3986 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4007 const float TIME_DILATION = 1.0f;
4008 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
4009
4010 if (terseAgentUpdateBlocks.IsValueCreated)
4011 {
4012 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3987 4013
3988 for (int i = 0; i < blocks.Count; i++) 4014 ImprovedTerseObjectUpdatePacket packet
3989 packet.ObjectData[i] = blocks[i]; 4015 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3990 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4016 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3991 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); }); 4017 packet.RegionData.TimeDilation = timeDilation;
3992 } 4018 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3993 4019
3994 if (objectUpdateBlocks.IsValueCreated) 4020 for (int i = 0; i < blocks.Count; i++)
3995 { 4021 packet.ObjectData[i] = blocks[i];
3996 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3997
3998 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3999 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4000 packet.RegionData.TimeDilation = timeDilation;
4001 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4002
4003 for (int i = 0; i < blocks.Count; i++)
4004 packet.ObjectData[i] = blocks[i];
4005 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4006 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
4007 }
4008
4009 if (compressedUpdateBlocks.IsValueCreated)
4010 {
4011 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4012
4013 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4014 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4015 packet.RegionData.TimeDilation = timeDilation;
4016 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4017
4018 for (int i = 0; i < blocks.Count; i++)
4019 packet.ObjectData[i] = blocks[i];
4020 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4021 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
4022 }
4023 4022
4024 if (terseUpdateBlocks.IsValueCreated) 4023 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
4025 { 4024 }
4026 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4027
4028 ImprovedTerseObjectUpdatePacket packet
4029 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4030 PacketType.ImprovedTerseObjectUpdate);
4031 4025
4032 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4026 if (objectUpdateBlocks.IsValueCreated)
4033 packet.RegionData.TimeDilation = timeDilation; 4027 {
4034 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4028 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
4035 4029
4036 for (int i = 0; i < blocks.Count; i++) 4030 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
4037 packet.ObjectData[i] = blocks[i]; 4031 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4038 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4032 packet.RegionData.TimeDilation = timeDilation;
4039 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 4033 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4040 } 4034
4035 for (int i = 0; i < blocks.Count; i++)
4036 packet.ObjectData[i] = blocks[i];
4037
4038 OutPacket(packet, ThrottleOutPacketType.Task, true);
4039 }
4040
4041 if (compressedUpdateBlocks.IsValueCreated)
4042 {
4043 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4044
4045 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4046 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4047 packet.RegionData.TimeDilation = timeDilation;
4048 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4049
4050 for (int i = 0; i < blocks.Count; i++)
4051 packet.ObjectData[i] = blocks[i];
4052
4053 OutPacket(packet, ThrottleOutPacketType.Task, true);
4054 }
4055
4056 if (terseUpdateBlocks.IsValueCreated)
4057 {
4058 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4059
4060 ImprovedTerseObjectUpdatePacket packet
4061 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4062 PacketType.ImprovedTerseObjectUpdate);
4063 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4064 packet.RegionData.TimeDilation = timeDilation;
4065 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4066
4067 for (int i = 0; i < blocks.Count; i++)
4068 packet.ObjectData[i] = blocks[i];
4069
4070 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
4041 } 4071 }
4042 4072
4043 #endregion Packet Sending 4073 #endregion Packet Sending
@@ -4330,11 +4360,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4330 4360
4331 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4361 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4332 // of the object rather than the properties when the packet was created 4362 // of the object rather than the properties when the packet was created
4333 OutPacket(packet, ThrottleOutPacketType.Task, true, 4363 // HACK : Remove intelligent resending until it's fixed in core
4334 delegate(OutgoingPacket oPacket) 4364 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4335 { 4365 // delegate(OutgoingPacket oPacket)
4336 ResendPropertyUpdates(updates, oPacket); 4366 // {
4337 }); 4367 // ResendPropertyUpdates(updates, oPacket);
4368 // });
4369 OutPacket(packet, ThrottleOutPacketType.Task, true);
4338 4370
4339 // pbcnt += blocks.Count; 4371 // pbcnt += blocks.Count;
4340 // ppcnt++; 4372 // ppcnt++;
@@ -4360,11 +4392,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4360 // of the object rather than the properties when the packet was created 4392 // of the object rather than the properties when the packet was created
4361 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4393 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4362 updates.Add(familyUpdates.Value[i]); 4394 updates.Add(familyUpdates.Value[i]);
4363 OutPacket(packet, ThrottleOutPacketType.Task, true, 4395 // HACK : Remove intelligent resending until it's fixed in core
4364 delegate(OutgoingPacket oPacket) 4396 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4365 { 4397 // delegate(OutgoingPacket oPacket)
4366 ResendPropertyUpdates(updates, oPacket); 4398 // {
4367 }); 4399 // ResendPropertyUpdates(updates, oPacket);
4400 // });
4401 OutPacket(packet, ThrottleOutPacketType.Task, true);
4368 4402
4369 // fpcnt++; 4403 // fpcnt++;
4370 // fbcnt++; 4404 // fbcnt++;
@@ -4736,7 +4770,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4736 4770
4737 if (landData.SimwideArea > 0) 4771 if (landData.SimwideArea > 0)
4738 { 4772 {
4739 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4773 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4774 // Never report more than sim total capacity
4775 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4776 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4740 updateMessage.SimWideMaxPrims = simulatorCapacity; 4777 updateMessage.SimWideMaxPrims = simulatorCapacity;
4741 } 4778 }
4742 else 4779 else
@@ -4865,14 +4902,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4865 4902
4866 if (notifyCount > 0) 4903 if (notifyCount > 0)
4867 { 4904 {
4868 if (notifyCount > 32) 4905// if (notifyCount > 32)
4869 { 4906// {
4870 m_log.InfoFormat( 4907// m_log.InfoFormat(
4871 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4908// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4872 + " - a developer might want to investigate whether this is a hard limit", 32); 4909// + " - a developer might want to investigate whether this is a hard limit", 32);
4873 4910//
4874 notifyCount = 32; 4911// notifyCount = 32;
4875 } 4912// }
4876 4913
4877 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4914 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4878 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4915 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4927,9 +4964,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4927 { 4964 {
4928 ScenePresence presence = (ScenePresence)entity; 4965 ScenePresence presence = (ScenePresence)entity;
4929 4966
4967 position = presence.OffsetPosition;
4968 rotation = presence.Rotation;
4969
4970 if (presence.ParentID != 0)
4971 {
4972 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4973 if (part != null && part != part.ParentGroup.RootPart)
4974 {
4975 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4976 rotation = part.RotationOffset * presence.Rotation;
4977 }
4978 angularVelocity = Vector3.Zero;
4979 }
4980 else
4981 {
4982 angularVelocity = presence.AngularVelocity;
4983 rotation = presence.Rotation;
4984 }
4985
4930 attachPoint = 0; 4986 attachPoint = 0;
4931 collisionPlane = presence.CollisionPlane; 4987 collisionPlane = presence.CollisionPlane;
4932 position = presence.OffsetPosition;
4933 velocity = presence.Velocity; 4988 velocity = presence.Velocity;
4934 acceleration = Vector3.Zero; 4989 acceleration = Vector3.Zero;
4935 4990
@@ -4938,9 +4993,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4938 // may improve movement smoothness. 4993 // may improve movement smoothness.
4939// acceleration = new Vector3(1, 0, 0); 4994// acceleration = new Vector3(1, 0, 0);
4940 4995
4941 angularVelocity = presence.AngularVelocity;
4942 rotation = presence.Rotation;
4943
4944 if (sendTexture) 4996 if (sendTexture)
4945 textureEntry = presence.Appearance.Texture.GetBytes(); 4997 textureEntry = presence.Appearance.Texture.GetBytes();
4946 else 4998 else
@@ -5046,13 +5098,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5046 5098
5047 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5099 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
5048 { 5100 {
5101 Vector3 offsetPosition = data.OffsetPosition;
5102 Quaternion rotation = data.Rotation;
5103 uint parentID = data.ParentID;
5104
5105 if (parentID != 0)
5106 {
5107 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5108 if (part != null && part != part.ParentGroup.RootPart)
5109 {
5110 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5111 rotation = part.RotationOffset * data.Rotation;
5112 parentID = part.ParentGroup.RootPart.LocalId;
5113 }
5114 }
5115
5049 byte[] objectData = new byte[76]; 5116 byte[] objectData = new byte[76];
5050 5117
5051 data.CollisionPlane.ToBytes(objectData, 0); 5118 data.CollisionPlane.ToBytes(objectData, 0);
5052 data.OffsetPosition.ToBytes(objectData, 16); 5119 offsetPosition.ToBytes(objectData, 16);
5053// data.Velocity.ToBytes(objectData, 28); 5120// data.Velocity.ToBytes(objectData, 28);
5054// data.Acceleration.ToBytes(objectData, 40); 5121// data.Acceleration.ToBytes(objectData, 40);
5055 data.Rotation.ToBytes(objectData, 52); 5122 rotation.ToBytes(objectData, 52);
5056 //data.AngularVelocity.ToBytes(objectData, 64); 5123 //data.AngularVelocity.ToBytes(objectData, 64);
5057 5124
5058 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5125 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -5066,14 +5133,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5066 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5133 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
5067 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5134 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
5068 update.ObjectData = objectData; 5135 update.ObjectData = objectData;
5069 update.ParentID = data.ParentID; 5136 update.ParentID = parentID;
5070 update.PathCurve = 16; 5137 update.PathCurve = 16;
5071 update.PathScaleX = 100; 5138 update.PathScaleX = 100;
5072 update.PathScaleY = 100; 5139 update.PathScaleY = 100;
5073 update.PCode = (byte)PCode.Avatar; 5140 update.PCode = (byte)PCode.Avatar;
5074 update.ProfileCurve = 1; 5141 update.ProfileCurve = 1;
5075 update.PSBlock = Utils.EmptyBytes; 5142 update.PSBlock = Utils.EmptyBytes;
5076 update.Scale = new Vector3(0.45f, 0.6f, 1.9f); 5143 update.Scale = data.Appearance.AvatarSize;
5144// update.Scale.Z -= 0.2f;
5145
5077 update.Text = Utils.EmptyBytes; 5146 update.Text = Utils.EmptyBytes;
5078 update.TextColor = new byte[4]; 5147 update.TextColor = new byte[4];
5079 5148
@@ -5084,10 +5153,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5084 update.TextureEntry = Utils.EmptyBytes; 5153 update.TextureEntry = Utils.EmptyBytes;
5085// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; 5154// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
5086 5155
5156/* 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)
5087 update.UpdateFlags = (uint)( 5157 update.UpdateFlags = (uint)(
5088 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | 5158 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
5089 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | 5159 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
5090 PrimFlags.ObjectOwnerModify); 5160 PrimFlags.ObjectOwnerModify);
5161*/
5162 update.UpdateFlags = 0;
5091 5163
5092 return update; 5164 return update;
5093 } 5165 }
@@ -5258,8 +5330,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5258 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs 5330 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs
5259 // for each AgentUpdate packet. 5331 // for each AgentUpdate packet.
5260 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false); 5332 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false);
5261 5333
5262 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false); 5334 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false);
5335 AddLocalPacketHandler(PacketType.VelocityInterpolateOff, HandleVelocityInterpolateOff, false);
5336 AddLocalPacketHandler(PacketType.VelocityInterpolateOn, HandleVelocityInterpolateOn, false);
5263 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); 5337 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false);
5264 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); 5338 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
5265 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false); 5339 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false);
@@ -5411,6 +5485,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5411 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5485 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5412 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5486 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5413 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5487 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5488 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5414 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5489 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5415 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5490 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5416 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5491 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5477,6 +5552,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5477 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5552 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5478 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5553 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5479 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5554 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5555 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5480 5556
5481 AddGenericPacketHandler("autopilot", HandleAutopilot); 5557 AddGenericPacketHandler("autopilot", HandleAutopilot);
5482 } 5558 }
@@ -5515,6 +5591,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5515 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) || 5591 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) ||
5516 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) || 5592 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) ||
5517 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) || 5593 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) ||
5594 (x.ControlFlags != 0) ||
5518 (x.Far != m_lastAgentUpdateArgs.Far) || 5595 (x.Far != m_lastAgentUpdateArgs.Far) ||
5519 (x.Flags != m_lastAgentUpdateArgs.Flags) || 5596 (x.Flags != m_lastAgentUpdateArgs.Flags) ||
5520 (x.State != m_lastAgentUpdateArgs.State) || 5597 (x.State != m_lastAgentUpdateArgs.State) ||
@@ -5774,6 +5851,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5774 return true; 5851 return true;
5775 } 5852 }
5776 5853
5854 private bool HandleVelocityInterpolateOff(IClientAPI sender, Packet Pack)
5855 {
5856 VelocityInterpolateOffPacket p = (VelocityInterpolateOffPacket)Pack;
5857 if (p.AgentData.SessionID != SessionId ||
5858 p.AgentData.AgentID != AgentId)
5859 return true;
5860
5861 m_VelocityInterpolate = false;
5862 return true;
5863 }
5864
5865 private bool HandleVelocityInterpolateOn(IClientAPI sender, Packet Pack)
5866 {
5867 VelocityInterpolateOnPacket p = (VelocityInterpolateOnPacket)Pack;
5868 if (p.AgentData.SessionID != SessionId ||
5869 p.AgentData.AgentID != AgentId)
5870 return true;
5871
5872 m_VelocityInterpolate = true;
5873 return true;
5874 }
5875
5876
5777 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack) 5877 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack)
5778 { 5878 {
5779 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack; 5879 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack;
@@ -6194,17 +6294,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6194 // Temporarily protect ourselves from the mantis #951 failure. 6294 // Temporarily protect ourselves from the mantis #951 failure.
6195 // However, we could do this for several other handlers where a failure isn't terminal 6295 // However, we could do this for several other handlers where a failure isn't terminal
6196 // for the client session anyway, in order to protect ourselves against bad code in plugins 6296 // for the client session anyway, in order to protect ourselves against bad code in plugins
6297 Vector3 avSize = appear.AgentData.Size;
6197 try 6298 try
6198 { 6299 {
6199 byte[] visualparams = new byte[appear.VisualParam.Length]; 6300 byte[] visualparams = new byte[appear.VisualParam.Length];
6200 for (int i = 0; i < appear.VisualParam.Length; i++) 6301 for (int i = 0; i < appear.VisualParam.Length; i++)
6201 visualparams[i] = appear.VisualParam[i].ParamValue; 6302 visualparams[i] = appear.VisualParam[i].ParamValue;
6202 6303 //var b = appear.WearableData[0];
6304
6203 Primitive.TextureEntry te = null; 6305 Primitive.TextureEntry te = null;
6204 if (appear.ObjectData.TextureEntry.Length > 1) 6306 if (appear.ObjectData.TextureEntry.Length > 1)
6205 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); 6307 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
6308
6309 WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length];
6310 for (int i=0; i<appear.WearableData.Length;i++)
6311 cacheitems[i] = new WearableCacheItem(){CacheId = appear.WearableData[i].CacheID,TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex)};
6312
6313
6206 6314
6207 handlerSetAppearance(sender, te, visualparams); 6315 handlerSetAppearance(sender, te, visualparams,avSize, cacheitems);
6208 } 6316 }
6209 catch (Exception e) 6317 catch (Exception e)
6210 { 6318 {
@@ -6413,6 +6521,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6413 { 6521 {
6414 handlerCompleteMovementToRegion(sender, true); 6522 handlerCompleteMovementToRegion(sender, true);
6415 } 6523 }
6524 else
6525 m_log.Debug("HandleCompleteAgentMovement NULL handler");
6526
6416 handlerCompleteMovementToRegion = null; 6527 handlerCompleteMovementToRegion = null;
6417 6528
6418 return true; 6529 return true;
@@ -6430,7 +6541,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6430 return true; 6541 return true;
6431 } 6542 }
6432 #endregion 6543 #endregion
6433 6544/*
6434 StartAnim handlerStartAnim = null; 6545 StartAnim handlerStartAnim = null;
6435 StopAnim handlerStopAnim = null; 6546 StopAnim handlerStopAnim = null;
6436 6547
@@ -6454,6 +6565,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6454 } 6565 }
6455 } 6566 }
6456 return true; 6567 return true;
6568*/
6569 ChangeAnim handlerChangeAnim = null;
6570
6571 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6572 {
6573 handlerChangeAnim = OnChangeAnim;
6574 if (handlerChangeAnim != null)
6575 {
6576 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6577 }
6578 }
6579
6580 handlerChangeAnim = OnChangeAnim;
6581 if (handlerChangeAnim != null)
6582 {
6583 handlerChangeAnim(UUID.Zero, false, true);
6584 }
6585
6586 return true;
6457 } 6587 }
6458 6588
6459 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6589 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -6679,6 +6809,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6679 #endregion 6809 #endregion
6680 6810
6681 m_udpClient.SetThrottles(atpack.Throttle.Throttles); 6811 m_udpClient.SetThrottles(atpack.Throttle.Throttles);
6812 GenericCall2 handler = OnUpdateThrottles;
6813 if (handler != null)
6814 {
6815 handler();
6816 }
6682 return true; 6817 return true;
6683 } 6818 }
6684 6819
@@ -7103,7 +7238,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7103 physdata.Bounce = phsblock.Restitution; 7238 physdata.Bounce = phsblock.Restitution;
7104 physdata.Density = phsblock.Density; 7239 physdata.Density = phsblock.Density;
7105 physdata.Friction = phsblock.Friction; 7240 physdata.Friction = phsblock.Friction;
7106 physdata.GravitationModifier = phsblock.GravityMultiplier; 7241 physdata.GravitationModifier = phsblock.GravityMultiplier;
7107 } 7242 }
7108 7243
7109 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this); 7244 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
@@ -7689,6 +7824,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7689 // surrounding scene 7824 // surrounding scene
7690 if ((ImageType)block.Type == ImageType.Baked) 7825 if ((ImageType)block.Type == ImageType.Baked)
7691 args.Priority *= 2.0f; 7826 args.Priority *= 2.0f;
7827 int wearableout = 0;
7692 7828
7693 ImageManager.EnqueueReq(args); 7829 ImageManager.EnqueueReq(args);
7694 } 7830 }
@@ -8707,16 +8843,61 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8707 8843
8708 #region Parcel related packets 8844 #region Parcel related packets
8709 8845
8846 // acumulate several HandleRegionHandleRequest consecutive overlaping requests
8847 // to be done with minimal resources as possible
8848 // variables temporary here while in test
8849
8850 Queue<UUID> RegionHandleRequests = new Queue<UUID>();
8851 bool RegionHandleRequestsInService = false;
8852
8710 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack) 8853 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack)
8711 { 8854 {
8712 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; 8855 UUID currentUUID;
8713 8856
8714 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; 8857 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest;
8715 if (handlerRegionHandleRequest != null) 8858
8859 if (handlerRegionHandleRequest == null)
8860 return true;
8861
8862 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
8863
8864 lock (RegionHandleRequests)
8716 { 8865 {
8717 handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); 8866 if (RegionHandleRequestsInService)
8867 {
8868 // we are already busy doing a previus request
8869 // so enqueue it
8870 RegionHandleRequests.Enqueue(rhrPack.RequestBlock.RegionID);
8871 return true;
8872 }
8873
8874 // else do it
8875 currentUUID = rhrPack.RequestBlock.RegionID;
8876 RegionHandleRequestsInService = true;
8718 } 8877 }
8719 return true; 8878
8879 while (true)
8880 {
8881 handlerRegionHandleRequest(this, currentUUID);
8882
8883 lock (RegionHandleRequests)
8884 {
8885 // exit condition, nothing to do or closed
8886 // current code seems to assume we may loose the handler at anytime,
8887 // so keep checking it
8888 handlerRegionHandleRequest = OnRegionHandleRequest;
8889
8890 if (RegionHandleRequests.Count == 0 || !IsActive || handlerRegionHandleRequest == null)
8891 {
8892 RegionHandleRequests.Clear();
8893 RegionHandleRequestsInService = false;
8894 return true;
8895 }
8896 currentUUID = RegionHandleRequests.Dequeue();
8897 }
8898 }
8899
8900 return true; // actually unreached
8720 } 8901 }
8721 8902
8722 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack) 8903 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack)
@@ -9972,7 +10153,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9972 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 10153 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9973 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 10154 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9974 UpdateMuteListEntry.MuteData.MuteType, 10155 UpdateMuteListEntry.MuteData.MuteType,
9975 UpdateMuteListEntry.AgentData.AgentID); 10156 UpdateMuteListEntry.MuteData.MuteFlags);
9976 return true; 10157 return true;
9977 } 10158 }
9978 return false; 10159 return false;
@@ -9987,8 +10168,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9987 { 10168 {
9988 handlerRemoveMuteListEntry(this, 10169 handlerRemoveMuteListEntry(this,
9989 RemoveMuteListEntry.MuteData.MuteID, 10170 RemoveMuteListEntry.MuteData.MuteID,
9990 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 10171 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9991 RemoveMuteListEntry.AgentData.AgentID);
9992 return true; 10172 return true;
9993 } 10173 }
9994 return false; 10174 return false;
@@ -10032,10 +10212,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10032 return false; 10212 return false;
10033 } 10213 }
10034 10214
10215 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10216 {
10217 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10218 (ChangeInventoryItemFlagsPacket)packet;
10219 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10220 if (handlerChangeInventoryItemFlags != null)
10221 {
10222 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10223 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10224 return true;
10225 }
10226 return false;
10227 }
10228
10035 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10229 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
10036 { 10230 {
10037 return true; 10231 return true;
10038 } 10232 }
10233
10234 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10235 {
10236 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10237
10238 #region Packet Session and User Check
10239 if (m_checkPackets)
10240 {
10241 if (packet.AgentData.SessionID != SessionId ||
10242 packet.AgentData.AgentID != AgentId)
10243 return true;
10244 }
10245 #endregion
10246 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10247 List<InventoryItemBase> items = new List<InventoryItemBase>();
10248 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10249 {
10250 InventoryItemBase b = new InventoryItemBase();
10251 b.ID = n.OldItemID;
10252 b.Folder = n.OldFolderID;
10253 items.Add(b);
10254 }
10255
10256 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10257 if (handlerMoveItemsAndLeaveCopy != null)
10258 {
10259 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10260 }
10261
10262 return true;
10263 }
10039 10264
10040 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10265 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
10041 { 10266 {
@@ -10462,6 +10687,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10462 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10687 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10463 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10688 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10464 10689
10690 Scene scene = (Scene)m_scene;
10691 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10692 {
10693 ScenePresence p;
10694 if (scene.TryGetScenePresence(sender.AgentId, out p))
10695 {
10696 if (p.GodLevel >= 200)
10697 {
10698 groupProfileReply.GroupData.OpenEnrollment = true;
10699 groupProfileReply.GroupData.MembershipFee = 0;
10700 }
10701 }
10702 }
10703
10465 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10704 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10466 } 10705 }
10467 return true; 10706 return true;
@@ -11035,11 +11274,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11035 11274
11036 StartLure handlerStartLure = OnStartLure; 11275 StartLure handlerStartLure = OnStartLure;
11037 if (handlerStartLure != null) 11276 if (handlerStartLure != null)
11038 handlerStartLure(startLureRequest.Info.LureType, 11277 {
11039 Utils.BytesToString( 11278 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
11040 startLureRequest.Info.Message), 11279 {
11041 startLureRequest.TargetData[0].TargetID, 11280 handlerStartLure(startLureRequest.Info.LureType,
11042 this); 11281 Utils.BytesToString(
11282 startLureRequest.Info.Message),
11283 startLureRequest.TargetData[i].TargetID,
11284 this);
11285 }
11286 }
11043 return true; 11287 return true;
11044 } 11288 }
11045 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11289 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -11153,10 +11397,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11153 } 11397 }
11154 #endregion 11398 #endregion
11155 11399
11156 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11400 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11157 if (handlerClassifiedGodDelete != null) 11401 if (handlerClassifiedGodDelete != null)
11158 handlerClassifiedGodDelete( 11402 handlerClassifiedGodDelete(
11159 classifiedGodDelete.Data.ClassifiedID, 11403 classifiedGodDelete.Data.ClassifiedID,
11404 classifiedGodDelete.Data.QueryID,
11160 this); 11405 this);
11161 return true; 11406 return true;
11162 } 11407 }
@@ -11469,6 +11714,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11469 11714
11470 if (cachedtex.AgentData.SessionID != SessionId) 11715 if (cachedtex.AgentData.SessionID != SessionId)
11471 return false; 11716 return false;
11717
11472 11718
11473 // TODO: don't create new blocks if recycling an old packet 11719 // TODO: don't create new blocks if recycling an old packet
11474 cachedresp.AgentData.AgentID = AgentId; 11720 cachedresp.AgentData.AgentID = AgentId;
@@ -11478,14 +11724,140 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11478 cachedresp.WearableData = 11724 cachedresp.WearableData =
11479 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length]; 11725 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
11480 11726
11481 for (int i = 0; i < cachedtex.WearableData.Length; i++) 11727 //IAvatarFactoryModule fac = m_scene.RequestModuleInterface<IAvatarFactoryModule>();
11728 // var item = fac.GetBakedTextureFaces(AgentId);
11729 //WearableCacheItem[] items = fac.GetCachedItems(AgentId);
11730
11731 IAssetService cache = m_scene.AssetService;
11732 IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
11733 //bakedTextureModule = null;
11734 int maxWearablesLoop = cachedtex.WearableData.Length;
11735 if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES)
11736 maxWearablesLoop = AvatarWearable.MAX_WEARABLES;
11737
11738 if (bakedTextureModule != null && cache != null)
11482 { 11739 {
11483 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); 11740 // We need to make sure the asset stored in the bake is available on this server also by it's assetid before we map it to a Cacheid
11484 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; 11741
11485 cachedresp.WearableData[i].TextureID = UUID.Zero; 11742 WearableCacheItem[] cacheItems = null;
11486 cachedresp.WearableData[i].HostName = new byte[0]; 11743 ScenePresence p = m_scene.GetScenePresence(AgentId);
11744 if (p.Appearance != null)
11745 if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty)
11746 {
11747 try
11748 {
11749 cacheItems = bakedTextureModule.Get(AgentId);
11750 p.Appearance.WearableCacheItems = cacheItems;
11751 p.Appearance.WearableCacheItemsDirty = false;
11752 }
11753
11754 /*
11755 * The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception!
11756 *
11757 catch (System.Net.Sockets.SocketException)
11758 {
11759 cacheItems = null;
11760 }
11761 catch (WebException)
11762 {
11763 cacheItems = null;
11764 }
11765 catch (InvalidOperationException)
11766 {
11767 cacheItems = null;
11768 } */
11769 catch (Exception)
11770 {
11771 cacheItems = null;
11772 }
11773
11774 }
11775 else if (p.Appearance.WearableCacheItems != null)
11776 {
11777 cacheItems = p.Appearance.WearableCacheItems;
11778 }
11779
11780 if (cache != null && cacheItems != null)
11781 {
11782 foreach (WearableCacheItem item in cacheItems)
11783 {
11784
11785 if (cache.GetCached(item.TextureID.ToString()) == null)
11786 {
11787 item.TextureAsset.Temporary = true;
11788 cache.Store(item.TextureAsset);
11789 }
11790
11791
11792 }
11793 }
11794
11795 if (cacheItems != null)
11796 {
11797
11798 for (int i = 0; i < maxWearablesLoop; i++)
11799 {
11800 WearableCacheItem item =
11801 WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems);
11802
11803 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11804 cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex;
11805 cachedresp.WearableData[i].HostName = new byte[0];
11806 if (item != null && cachedtex.WearableData[i].ID == item.CacheId)
11807 {
11808
11809 cachedresp.WearableData[i].TextureID = item.TextureID;
11810 }
11811 else
11812 {
11813 cachedresp.WearableData[i].TextureID = UUID.Zero;
11814 }
11815 }
11816 }
11817 else
11818 {
11819 for (int i = 0; i < maxWearablesLoop; i++)
11820 {
11821 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11822 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11823 cachedresp.WearableData[i].TextureID = UUID.Zero;
11824 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11825 cachedresp.WearableData[i].HostName = new byte[0];
11826 }
11827 }
11487 } 11828 }
11829 else
11830 {
11831 if (cache == null)
11832 {
11833 for (int i = 0; i < maxWearablesLoop; i++)
11834 {
11835 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11836 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11837 cachedresp.WearableData[i].TextureID = UUID.Zero;
11838 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11839 cachedresp.WearableData[i].HostName = new byte[0];
11840 }
11841 }
11842 else
11843 {
11844 for (int i = 0; i < maxWearablesLoop; i++)
11845 {
11846 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11847 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11848
11488 11849
11850
11851 if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null)
11852 cachedresp.WearableData[i].TextureID = UUID.Zero;
11853 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11854 else
11855 cachedresp.WearableData[i].TextureID = UUID.Zero;
11856 // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11857 cachedresp.WearableData[i].HostName = new byte[0];
11858 }
11859 }
11860 }
11489 cachedresp.Header.Zerocoded = true; 11861 cachedresp.Header.Zerocoded = true;
11490 OutPacket(cachedresp, ThrottleOutPacketType.Task); 11862 OutPacket(cachedresp, ThrottleOutPacketType.Task);
11491 11863
@@ -11522,209 +11894,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11522 } 11894 }
11523 else 11895 else
11524 { 11896 {
11525// m_log.DebugFormat( 11897 ClientChangeObject updatehandler = onClientChangeObject;
11526// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11527// i, block.Type, part.Name, part.LocalId);
11528 11898
11529// // Do this once since fetch parts creates a new array. 11899 if (updatehandler != null)
11530// SceneObjectPart[] parts = part.ParentGroup.Parts; 11900 {
11531// for (int j = 0; j < parts.Length; j++) 11901 ObjectChangeData udata = new ObjectChangeData();
11532// {
11533// part.StoreUndoState();
11534// parts[j].IgnoreUndoUpdate = true;
11535// }
11536 11902
11537 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11903 /*ubit from ll JIRA:
11904 * 0x01 position
11905 * 0x02 rotation
11906 * 0x04 scale
11907
11908 * 0x08 LINK_SET
11909 * 0x10 UNIFORM for scale
11910 */
11538 11911
11539 switch (block.Type) 11912 // translate to internal changes
11540 { 11913 // not all cases .. just the ones older code did
11541 case 1:
11542 Vector3 pos1 = new Vector3(block.Data, 0);
11543 11914
11544 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11915 switch (block.Type)
11545 if (handlerUpdatePrimSinglePosition != null) 11916 {
11546 { 11917 case 1: //change position sp
11547 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11918 udata.position = new Vector3(block.Data, 0);
11548 handlerUpdatePrimSinglePosition(localId, pos1, this);
11549 }
11550 break;
11551 11919
11552 case 2: 11920 udata.change = ObjectChangeType.primP;
11553 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11921 updatehandler(localId, udata, this);
11922 break;
11554 11923
11555 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11924 case 2: // rotation sp
11556 if (handlerUpdatePrimSingleRotation != null) 11925 udata.rotation = new Quaternion(block.Data, 0, true);
11557 {
11558 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11559 handlerUpdatePrimSingleRotation(localId, rot1, this);
11560 }
11561 break;
11562 11926
11563 case 3: 11927 udata.change = ObjectChangeType.primR;
11564 Vector3 rotPos = new Vector3(block.Data, 0); 11928 updatehandler(localId, udata, this);
11565 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11929 break;
11566 11930
11567 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11931 case 3: // position plus rotation
11568 if (handlerUpdatePrimSingleRotationPosition != null) 11932 udata.position = new Vector3(block.Data, 0);
11569 { 11933 udata.rotation = new Quaternion(block.Data, 12, true);
11570 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11571 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11572 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11573 }
11574 break;
11575 11934
11576 case 4: 11935 udata.change = ObjectChangeType.primPR;
11577 case 20: 11936 updatehandler(localId, udata, this);
11578 Vector3 scale4 = new Vector3(block.Data, 0); 11937 break;
11579 11938
11580 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11939 case 4: // scale sp
11581 if (handlerUpdatePrimScale != null) 11940 udata.scale = new Vector3(block.Data, 0);
11582 { 11941 udata.change = ObjectChangeType.primS;
11583 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11584 handlerUpdatePrimScale(localId, scale4, this);
11585 }
11586 break;
11587 11942
11588 case 5: 11943 updatehandler(localId, udata, this);
11589 Vector3 scale1 = new Vector3(block.Data, 12); 11944 break;
11590 Vector3 pos11 = new Vector3(block.Data, 0);
11591 11945
11592 handlerUpdatePrimScale = OnUpdatePrimScale; 11946 case 0x14: // uniform scale sp
11593 if (handlerUpdatePrimScale != null) 11947 udata.scale = new Vector3(block.Data, 0);
11594 {
11595 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11596 handlerUpdatePrimScale(localId, scale1, this);
11597 11948
11598 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11949 udata.change = ObjectChangeType.primUS;
11599 if (handlerUpdatePrimSinglePosition != null) 11950 updatehandler(localId, udata, this);
11600 { 11951 break;
11601 handlerUpdatePrimSinglePosition(localId, pos11, this);
11602 }
11603 }
11604 break;
11605 11952
11606 case 9: 11953 case 5: // scale and position sp
11607 Vector3 pos2 = new Vector3(block.Data, 0); 11954 udata.position = new Vector3(block.Data, 0);
11955 udata.scale = new Vector3(block.Data, 12);
11608 11956
11609 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11957 udata.change = ObjectChangeType.primPS;
11958 updatehandler(localId, udata, this);
11959 break;
11610 11960
11611 if (handlerUpdateVector != null) 11961 case 0x15: //uniform scale and position
11612 { 11962 udata.position = new Vector3(block.Data, 0);
11613 handlerUpdateVector(localId, pos2, this); 11963 udata.scale = new Vector3(block.Data, 12);
11614 }
11615 break;
11616 11964
11617 case 10: 11965 udata.change = ObjectChangeType.primPUS;
11618 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11966 updatehandler(localId, udata, this);
11967 break;
11619 11968
11620 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11969 // now group related (bit 4)
11621 if (handlerUpdatePrimRotation != null) 11970 case 9: //( 8 + 1 )group position
11622 { 11971 udata.position = new Vector3(block.Data, 0);
11623 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11624 handlerUpdatePrimRotation(localId, rot3, this);
11625 }
11626 break;
11627 11972
11628 case 11: 11973 udata.change = ObjectChangeType.groupP;
11629 Vector3 pos3 = new Vector3(block.Data, 0); 11974 updatehandler(localId, udata, this);
11630 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11975 break;
11631 11976
11632 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11977 case 0x0A: // (8 + 2) group rotation
11633 if (handlerUpdatePrimGroupRotation != null) 11978 udata.rotation = new Quaternion(block.Data, 0, true);
11634 {
11635 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11636 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11637 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11638 }
11639 break;
11640 case 12:
11641 case 28:
11642 Vector3 scale7 = new Vector3(block.Data, 0);
11643 11979
11644 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11980 udata.change = ObjectChangeType.groupR;
11645 if (handlerUpdatePrimGroupScale != null) 11981 updatehandler(localId, udata, this);
11646 { 11982 break;
11647 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11648 handlerUpdatePrimGroupScale(localId, scale7, this);
11649 }
11650 break;
11651 11983
11652 case 13: 11984 case 0x0B: //( 8 + 2 + 1) group rotation and position
11653 Vector3 scale2 = new Vector3(block.Data, 12); 11985 udata.position = new Vector3(block.Data, 0);
11654 Vector3 pos4 = new Vector3(block.Data, 0); 11986 udata.rotation = new Quaternion(block.Data, 12, true);
11655 11987
11656 handlerUpdatePrimScale = OnUpdatePrimScale; 11988 udata.change = ObjectChangeType.groupPR;
11657 if (handlerUpdatePrimScale != null) 11989 updatehandler(localId, udata, this);
11658 { 11990 break;
11659 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11660 handlerUpdatePrimScale(localId, scale2, this);
11661 11991
11662 // Change the position based on scale (for bug number 246) 11992 case 0x0C: // (8 + 4) group scale
11663 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11993 // only afects root prim and only sent by viewer editor object tab scaling
11664 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11994 // mouse edition only allows uniform scaling
11665 if (handlerUpdatePrimSinglePosition != null) 11995 // SL MAY CHANGE THIS in viewers
11666 {
11667 handlerUpdatePrimSinglePosition(localId, pos4, this);
11668 }
11669 }
11670 break;
11671 11996
11672 case 29: 11997 udata.scale = new Vector3(block.Data, 0);
11673 Vector3 scale5 = new Vector3(block.Data, 12);
11674 Vector3 pos5 = new Vector3(block.Data, 0);
11675 11998
11676 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11999 udata.change = ObjectChangeType.groupS;
11677 if (handlerUpdatePrimGroupScale != null) 12000 updatehandler(localId, udata, this);
11678 {
11679 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11680 part.StoreUndoState(true);
11681 part.IgnoreUndoUpdate = true;
11682 handlerUpdatePrimGroupScale(localId, scale5, this);
11683 handlerUpdateVector = OnUpdatePrimGroupPosition;
11684 12001
11685 if (handlerUpdateVector != null) 12002 break;
11686 {
11687 handlerUpdateVector(localId, pos5, this);
11688 }
11689 12003
11690 part.IgnoreUndoUpdate = false; 12004 case 0x0D: //(8 + 4 + 1) group scale and position
11691 } 12005 // exception as above
11692 12006
11693 break; 12007 udata.position = new Vector3(block.Data, 0);
12008 udata.scale = new Vector3(block.Data, 12);
11694 12009
11695 case 21: 12010 udata.change = ObjectChangeType.groupPS;
11696 Vector3 scale6 = new Vector3(block.Data, 12); 12011 updatehandler(localId, udata, this);
11697 Vector3 pos6 = new Vector3(block.Data, 0); 12012 break;
11698 12013
11699 handlerUpdatePrimScale = OnUpdatePrimScale; 12014 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11700 if (handlerUpdatePrimScale != null) 12015 udata.scale = new Vector3(block.Data, 0);
11701 {
11702 part.StoreUndoState(false);
11703 part.IgnoreUndoUpdate = true;
11704 12016
11705 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 12017 udata.change = ObjectChangeType.groupUS;
11706 handlerUpdatePrimScale(localId, scale6, this); 12018 updatehandler(localId, udata, this);
11707 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12019 break;
11708 if (handlerUpdatePrimSinglePosition != null)
11709 {
11710 handlerUpdatePrimSinglePosition(localId, pos6, this);
11711 }
11712 12020
11713 part.IgnoreUndoUpdate = false; 12021 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11714 } 12022 udata.position = new Vector3(block.Data, 0);
11715 break; 12023 udata.scale = new Vector3(block.Data, 12);
11716 12024
11717 default: 12025 udata.change = ObjectChangeType.groupPUS;
11718 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 12026 updatehandler(localId, udata, this);
11719 break; 12027 break;
12028
12029 default:
12030 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
12031 break;
12032 }
11720 } 12033 }
11721 12034
11722// for (int j = 0; j < parts.Length; j++)
11723// parts[j].IgnoreUndoUpdate = false;
11724 } 12035 }
11725 } 12036 }
11726 } 12037 }
11727
11728 return true; 12038 return true;
11729 } 12039 }
11730 12040
@@ -11785,9 +12095,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11785 public void SetChildAgentThrottle(byte[] throttles) 12095 public void SetChildAgentThrottle(byte[] throttles)
11786 { 12096 {
11787 m_udpClient.SetThrottles(throttles); 12097 m_udpClient.SetThrottles(throttles);
12098 GenericCall2 handler = OnUpdateThrottles;
12099 if (handler != null)
12100 {
12101 handler();
12102 }
11788 } 12103 }
11789 12104
11790 /// <summary> 12105 /// <summary>
12106 /// Sets the throttles from values supplied by the client
12107 /// </summary>
12108 /// <param name="throttles"></param>
12109 public void SetAgentThrottleSilent(int throttle, int setting)
12110 {
12111 m_udpClient.ForceThrottleSetting(throttle,setting);
12112 //m_udpClient.SetThrottles(throttles);
12113
12114 }
12115
12116
12117 /// <summary>
11791 /// Get the current throttles for this client as a packed byte array 12118 /// Get the current throttles for this client as a packed byte array
11792 /// </summary> 12119 /// </summary>
11793 /// <param name="multiplier">Unused</param> 12120 /// <param name="multiplier">Unused</param>
@@ -12179,7 +12506,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12179// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12506// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12180// requestID, taskID, (SourceType)sourceType, Name); 12507// requestID, taskID, (SourceType)sourceType, Name);
12181 12508
12509
12510 //Note, the bool returned from the below function is useless since it is always false.
12182 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12511 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12512
12183 } 12513 }
12184 12514
12185 /// <summary> 12515 /// <summary>
@@ -12245,7 +12575,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12245 /// <returns></returns> 12575 /// <returns></returns>
12246 private static int CalculateNumPackets(byte[] data) 12576 private static int CalculateNumPackets(byte[] data)
12247 { 12577 {
12248 const uint m_maxPacketSize = 600; 12578// const uint m_maxPacketSize = 600;
12579 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12249 int numPackets = 1; 12580 int numPackets = 1;
12250 12581
12251 if (data == null) 12582 if (data == null)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index 621e0fd..e52ac37 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -92,7 +92,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
92 /// <summary>Packets we have sent that need to be ACKed by the client</summary> 92 /// <summary>Packets we have sent that need to be ACKed by the client</summary>
93 public readonly UnackedPacketCollection NeedAcks = new UnackedPacketCollection(); 93 public readonly UnackedPacketCollection NeedAcks = new UnackedPacketCollection();
94 /// <summary>ACKs that are queued up, waiting to be sent to the client</summary> 94 /// <summary>ACKs that are queued up, waiting to be sent to the client</summary>
95 public readonly OpenSim.Framework.LocklessQueue<uint> PendingAcks = new OpenSim.Framework.LocklessQueue<uint>(); 95 public readonly DoubleLocklessQueue<uint> PendingAcks = new DoubleLocklessQueue<uint>();
96 96
97 /// <summary>Current packet sequence number</summary> 97 /// <summary>Current packet sequence number</summary>
98 public int CurrentSequence; 98 public int CurrentSequence;
@@ -146,7 +146,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
146 /// <summary>Throttle buckets for each packet category</summary> 146 /// <summary>Throttle buckets for each packet category</summary>
147 private readonly TokenBucket[] m_throttleCategories; 147 private readonly TokenBucket[] m_throttleCategories;
148 /// <summary>Outgoing queues for throttled packets</summary> 148 /// <summary>Outgoing queues for throttled packets</summary>
149 private readonly OpenSim.Framework.LocklessQueue<OutgoingPacket>[] m_packetOutboxes = new OpenSim.Framework.LocklessQueue<OutgoingPacket>[THROTTLE_CATEGORY_COUNT]; 149 private readonly DoubleLocklessQueue<OutgoingPacket>[] m_packetOutboxes = new DoubleLocklessQueue<OutgoingPacket>[THROTTLE_CATEGORY_COUNT];
150 /// <summary>A container that can hold one packet for each outbox, used to store 150 /// <summary>A container that can hold one packet for each outbox, used to store
151 /// dequeued packets that are being held for throttling</summary> 151 /// dequeued packets that are being held for throttling</summary>
152 private readonly OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT]; 152 private readonly OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT];
@@ -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
@@ -201,7 +202,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
201 ThrottleOutPacketType type = (ThrottleOutPacketType)i; 202 ThrottleOutPacketType type = (ThrottleOutPacketType)i;
202 203
203 // Initialize the packet outboxes, where packets sit while they are waiting for tokens 204 // Initialize the packet outboxes, where packets sit while they are waiting for tokens
204 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); 205 m_packetOutboxes[i] = new DoubleLocklessQueue<OutgoingPacket>();
205 // Initialize the token buckets that control the throttling for each category 206 // Initialize the token buckets that control the throttling for each category
206 m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetRate(type)); 207 m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetRate(type));
207 } 208 }
@@ -429,11 +430,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
429 /// </returns> 430 /// </returns>
430 public bool EnqueueOutgoing(OutgoingPacket packet, bool forceQueue) 431 public bool EnqueueOutgoing(OutgoingPacket packet, bool forceQueue)
431 { 432 {
433 return EnqueueOutgoing(packet, forceQueue, false);
434 }
435
436 public bool EnqueueOutgoing(OutgoingPacket packet, bool forceQueue, bool highPriority)
437 {
432 int category = (int)packet.Category; 438 int category = (int)packet.Category;
433 439
434 if (category >= 0 && category < m_packetOutboxes.Length) 440 if (category >= 0 && category < m_packetOutboxes.Length)
435 { 441 {
436 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; 442 DoubleLocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
443
444 if (m_deliverPackets == false)
445 {
446 queue.Enqueue(packet, highPriority);
447 return true;
448 }
449
437 TokenBucket bucket = m_throttleCategories[category]; 450 TokenBucket bucket = m_throttleCategories[category];
438 451
439 // Don't send this packet if there is already a packet waiting in the queue 452 // Don't send this packet if there is already a packet waiting in the queue
@@ -441,7 +454,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
441 // queued packets 454 // queued packets
442 if (queue.Count > 0) 455 if (queue.Count > 0)
443 { 456 {
444 queue.Enqueue(packet); 457 queue.Enqueue(packet, highPriority);
445 return true; 458 return true;
446 } 459 }
447 460
@@ -454,7 +467,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
454 else 467 else
455 { 468 {
456 // Force queue specified or not enough tokens in the bucket, queue this packet 469 // Force queue specified or not enough tokens in the bucket, queue this packet
457 queue.Enqueue(packet); 470 queue.Enqueue(packet, highPriority);
458 return true; 471 return true;
459 } 472 }
460 } 473 }
@@ -483,8 +496,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
483 /// <returns>True if any packets were sent, otherwise false</returns> 496 /// <returns>True if any packets were sent, otherwise false</returns>
484 public bool DequeueOutgoing() 497 public bool DequeueOutgoing()
485 { 498 {
486 OutgoingPacket packet; 499 if (m_deliverPackets == false) return false;
487 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 500
501 OutgoingPacket packet = null;
502 DoubleLocklessQueue<OutgoingPacket> queue;
488 TokenBucket bucket; 503 TokenBucket bucket;
489 bool packetSent = false; 504 bool packetSent = false;
490 ThrottleOutPacketTypeFlags emptyCategories = 0; 505 ThrottleOutPacketTypeFlags emptyCategories = 0;
@@ -515,32 +530,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP
515 // No dequeued packet waiting to be sent, try to pull one off 530 // No dequeued packet waiting to be sent, try to pull one off
516 // this queue 531 // this queue
517 queue = m_packetOutboxes[i]; 532 queue = m_packetOutboxes[i];
518 if (queue.Dequeue(out packet)) 533 if (queue != null)
519 { 534 {
520 // A packet was pulled off the queue. See if we have 535 bool success = false;
521 // enough tokens in the bucket to send it out 536 try
522 if (bucket.RemoveTokens(packet.Buffer.DataLength))
523 { 537 {
524 // Send the packet 538 success = queue.Dequeue(out packet);
525 m_udpServer.SendPacketFinal(packet);
526 packetSent = true;
527 } 539 }
528 else 540 catch
529 { 541 {
530 // Save the dequeued packet for the next iteration 542 m_packetOutboxes[i] = new DoubleLocklessQueue<OutgoingPacket>();
531 m_nextPackets[i] = packet;
532 } 543 }
533 544 if (success)
534 // If the queue is empty after this dequeue, fire the queue 545 {
535 // empty callback now so it has a chance to fill before we 546 // A packet was pulled off the queue. See if we have
536 // get back here 547 // enough tokens in the bucket to send it out
537 if (queue.Count == 0) 548 if (bucket.RemoveTokens(packet.Buffer.DataLength))
549 {
550 // Send the packet
551 m_udpServer.SendPacketFinal(packet);
552 packetSent = true;
553 }
554 else
555 {
556 // Save the dequeued packet for the next iteration
557 m_nextPackets[i] = packet;
558 }
559
560 // If the queue is empty after this dequeue, fire the queue
561 // empty callback now so it has a chance to fill before we
562 // get back here
563 if (queue.Count == 0)
564 emptyCategories |= CategoryToFlag(i);
565 }
566 else
567 {
568 // No packets in this queue. Fire the queue empty callback
569 // if it has not been called recently
538 emptyCategories |= CategoryToFlag(i); 570 emptyCategories |= CategoryToFlag(i);
571 }
539 } 572 }
540 else 573 else
541 { 574 {
542 // No packets in this queue. Fire the queue empty callback 575 m_packetOutboxes[i] = new DoubleLocklessQueue<OutgoingPacket>();
543 // if it has not been called recently
544 emptyCategories |= CategoryToFlag(i); 576 emptyCategories |= CategoryToFlag(i);
545 } 577 }
546 } 578 }
@@ -649,6 +681,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
649 if (m_nextOnQueueEmpty == 0) 681 if (m_nextOnQueueEmpty == 0)
650 m_nextOnQueueEmpty = 1; 682 m_nextOnQueueEmpty = 1;
651 } 683 }
684 internal void ForceThrottleSetting(int throttle, int setting)
685 {
686 m_throttleCategories[throttle].RequestedDripRate = Math.Max(setting, LLUDPServer.MTU); ;
687 }
652 688
653 /// <summary> 689 /// <summary>
654 /// Converts a <seealso cref="ThrottleOutPacketType"/> integer to a 690 /// Converts a <seealso cref="ThrottleOutPacketType"/> integer to a
@@ -693,4 +729,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
693 } 729 }
694 } 730 }
695 } 731 }
732
733 public class DoubleLocklessQueue<T> : OpenSim.Framework.LocklessQueue<T>
734 {
735 OpenSim.Framework.LocklessQueue<T> highQueue = new OpenSim.Framework.LocklessQueue<T>();
736
737 public override int Count
738 {
739 get
740 {
741 return base.Count + highQueue.Count;
742 }
743 }
744
745 public override bool Dequeue(out T item)
746 {
747 if (highQueue.Dequeue(out item))
748 return true;
749
750 return base.Dequeue(out item);
751 }
752
753 public void Enqueue(T item, bool highPriority)
754 {
755 if (highPriority)
756 highQueue.Enqueue(item);
757 else
758 Enqueue(item);
759 }
760 }
696} 761}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 985aa4d..33ca08c 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -121,7 +121,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
121 /// <summary>Handlers for incoming packets</summary> 121 /// <summary>Handlers for incoming packets</summary>
122 //PacketEventDictionary packetEvents = new PacketEventDictionary(); 122 //PacketEventDictionary packetEvents = new PacketEventDictionary();
123 /// <summary>Incoming packets that are awaiting handling</summary> 123 /// <summary>Incoming packets that are awaiting handling</summary>
124 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 124 //private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
125
126 private DoubleQueue<IncomingPacket> packetInbox = new DoubleQueue<IncomingPacket>();
125 127
126 /// <summary></summary> 128 /// <summary></summary>
127 //private UDPClientCollection m_clients = new UDPClientCollection(); 129 //private UDPClientCollection m_clients = new UDPClientCollection();
@@ -176,6 +178,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
176 /// <summary>Flag to signal when clients should send pings</summary> 178 /// <summary>Flag to signal when clients should send pings</summary>
177 protected bool m_sendPing; 179 protected bool m_sendPing;
178 180
181 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
179 private Pool<IncomingPacket> m_incomingPacketPool; 182 private Pool<IncomingPacket> m_incomingPacketPool;
180 183
181 /// <summary> 184 /// <summary>
@@ -782,6 +785,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
782 785
783 #region Queue or Send 786 #region Queue or Send
784 787
788 bool highPriority = false;
789
790 if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0)
791 {
792 category = (ThrottleOutPacketType)((int)category & 127);
793 highPriority = true;
794 }
795
785 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); 796 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
786 // If we were not provided a method for handling unacked, use the UDPServer default method 797 // If we were not provided a method for handling unacked, use the UDPServer default method
787 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); 798 outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
@@ -790,7 +801,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
790 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object 801 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object
791 // packet so that it isn't sent before a queued update packet. 802 // packet so that it isn't sent before a queued update packet.
792 bool requestQueue = type == PacketType.KillObject; 803 bool requestQueue = type == PacketType.KillObject;
793 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue)) 804 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue, highPriority))
794 SendPacketFinal(outgoingPacket); 805 SendPacketFinal(outgoingPacket);
795 806
796 #endregion Queue or Send 807 #endregion Queue or Send
@@ -1075,21 +1086,46 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1075 1086
1076 #region Packet to Client Mapping 1087 #region Packet to Client Mapping
1077 1088
1078 // UseCircuitCode handling 1089 // If there is already a client for this endpoint, don't process UseCircuitCode
1079 if (packet.Type == PacketType.UseCircuitCode) 1090 IClientAPI client = null;
1091 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1080 { 1092 {
1081 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1093 // UseCircuitCode handling
1082 // buffer. 1094 if (packet.Type == PacketType.UseCircuitCode)
1083 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1095 {
1096 // And if there is a UseCircuitCode pending, also drop it
1097 lock (m_pendingCache)
1098 {
1099 if (m_pendingCache.Contains(endPoint))
1100 return;
1084 1101
1085 Util.FireAndForget(HandleUseCircuitCode, array); 1102 m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60);
1103 }
1086 1104
1087 return; 1105 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1106 // buffer.
1107 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1108
1109 Util.FireAndForget(HandleUseCircuitCode, array);
1110
1111 return;
1112 }
1113 }
1114
1115 // If this is a pending connection, enqueue, don't process yet
1116 lock (m_pendingCache)
1117 {
1118 Queue<UDPPacketBuffer> queue;
1119 if (m_pendingCache.TryGetValue(endPoint, out queue))
1120 {
1121 //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type);
1122 queue.Enqueue(buffer);
1123 return;
1124 }
1088 } 1125 }
1089 1126
1090 // Determine which agent this packet came from 1127 // Determine which agent this packet came from
1091 IClientAPI client; 1128 if (client == null || !(client is LLClientView))
1092 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1093 { 1129 {
1094 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); 1130 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
1095 return; 1131 return;
@@ -1098,7 +1134,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1098 udpClient = ((LLClientView)client).UDPClient; 1134 udpClient = ((LLClientView)client).UDPClient;
1099 1135
1100 if (!udpClient.IsConnected) 1136 if (!udpClient.IsConnected)
1137 {
1138// m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName);
1101 return; 1139 return;
1140 }
1102 1141
1103 #endregion Packet to Client Mapping 1142 #endregion Packet to Client Mapping
1104 1143
@@ -1228,7 +1267,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1228 incomingPacket = new IncomingPacket((LLClientView)client, packet); 1267 incomingPacket = new IncomingPacket((LLClientView)client, packet);
1229 } 1268 }
1230 1269
1231 packetInbox.Enqueue(incomingPacket); 1270 if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
1271 incomingPacket.Packet.Type == PacketType.ChatFromViewer)
1272 packetInbox.EnqueueHigh(incomingPacket);
1273 else
1274 packetInbox.EnqueueLow(incomingPacket);
1232 } 1275 }
1233 1276
1234 #region BinaryStats 1277 #region BinaryStats
@@ -1374,6 +1417,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1374 // We only want to send initial data to new clients, not ones which are being converted from child to root. 1417 // We only want to send initial data to new clients, not ones which are being converted from child to root.
1375 if (client != null) 1418 if (client != null)
1376 client.SceneAgent.SendInitialDataToMe(); 1419 client.SceneAgent.SendInitialDataToMe();
1420
1421 // Now we know we can handle more data
1422 Thread.Sleep(200);
1423
1424 // Obtain the queue and remove it from the cache
1425 Queue<UDPPacketBuffer> queue = null;
1426
1427 lock (m_pendingCache)
1428 {
1429 if (!m_pendingCache.TryGetValue(endPoint, out queue))
1430 {
1431 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1432 return;
1433 }
1434 m_pendingCache.Remove(endPoint);
1435 }
1436
1437 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
1438
1439 // Reinject queued packets
1440 while(queue.Count > 0)
1441 {
1442 UDPPacketBuffer buf = queue.Dequeue();
1443 PacketReceived(buf);
1444 }
1445 queue = null;
1377 } 1446 }
1378 else 1447 else
1379 { 1448 {
@@ -1381,6 +1450,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1381 m_log.WarnFormat( 1450 m_log.WarnFormat(
1382 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1451 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
1383 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); 1452 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
1453 lock (m_pendingCache)
1454 m_pendingCache.Remove(endPoint);
1384 } 1455 }
1385 1456
1386 // m_log.DebugFormat( 1457 // m_log.DebugFormat(
@@ -1499,7 +1570,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1499 if (!client.SceneAgent.IsChildAgent) 1570 if (!client.SceneAgent.IsChildAgent)
1500 client.Kick("Simulator logged you out due to connection timeout"); 1571 client.Kick("Simulator logged you out due to connection timeout");
1501 1572
1502 client.CloseWithoutChecks(); 1573 client.CloseWithoutChecks(true);
1503 } 1574 }
1504 } 1575 }
1505 1576
@@ -1511,6 +1582,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1511 1582
1512 while (IsRunningInbound) 1583 while (IsRunningInbound)
1513 { 1584 {
1585 m_scene.ThreadAlive(1);
1514 try 1586 try
1515 { 1587 {
1516 IncomingPacket incomingPacket = null; 1588 IncomingPacket incomingPacket = null;
@@ -1558,6 +1630,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1558 1630
1559 while (base.IsRunningOutbound) 1631 while (base.IsRunningOutbound)
1560 { 1632 {
1633 m_scene.ThreadAlive(2);
1561 try 1634 try
1562 { 1635 {
1563 m_packetSent = false; 1636 m_packetSent = false;
@@ -1788,8 +1861,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1788 Packet packet = incomingPacket.Packet; 1861 Packet packet = incomingPacket.Packet;
1789 LLClientView client = incomingPacket.Client; 1862 LLClientView client = incomingPacket.Client;
1790 1863
1791 if (client.IsActive) 1864// if (client.IsActive)
1792 { 1865// {
1793 m_currentIncomingClient = client; 1866 m_currentIncomingClient = client;
1794 1867
1795 try 1868 try
@@ -1816,13 +1889,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1816 { 1889 {
1817 m_currentIncomingClient = null; 1890 m_currentIncomingClient = null;
1818 } 1891 }
1819 } 1892// }
1820 else 1893// else
1821 { 1894// {
1822 m_log.DebugFormat( 1895// m_log.DebugFormat(
1823 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 1896// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
1824 packet.Type, client.Name, m_scene.RegionInfo.RegionName); 1897// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
1825 } 1898// }
1826 1899
1827 IncomingPacketsProcessed++; 1900 IncomingPacketsProcessed++;
1828 } 1901 }
@@ -1834,8 +1907,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1834 if (!client.IsLoggingOut) 1907 if (!client.IsLoggingOut)
1835 { 1908 {
1836 client.IsLoggingOut = true; 1909 client.IsLoggingOut = true;
1837 client.Close(); 1910 client.Close(false, false);
1838 } 1911 }
1839 } 1912 }
1840 } 1913 }
1841} \ No newline at end of file 1914}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index f143c32..7035e38 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -114,10 +114,6 @@ namespace OpenMetaverse
114 const int SIO_UDP_CONNRESET = -1744830452; 114 const int SIO_UDP_CONNRESET = -1744830452;
115 115
116 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort); 116 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort);
117
118 m_log.DebugFormat(
119 "[UDPBASE]: Binding UDP listener using internal IP address config {0}:{1}",
120 ipep.Address, ipep.Port);
121 117
122 m_udpSocket = new Socket( 118 m_udpSocket = new Socket(
123 AddressFamily.InterNetwork, 119 AddressFamily.InterNetwork,