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 1eb953c..b7469ae 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
@@ -1134,6 +1140,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1134 public virtual void SendLayerData(float[] map) 1140 public virtual void SendLayerData(float[] map)
1135 { 1141 {
1136 Util.FireAndForget(DoSendLayerData, map); 1142 Util.FireAndForget(DoSendLayerData, map);
1143
1144 // Send it sync, and async. It's not that much data
1145 // and it improves user experience just so much!
1146 DoSendLayerData(map);
1137 } 1147 }
1138 1148
1139 /// <summary> 1149 /// <summary>
@@ -1146,16 +1156,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1146 1156
1147 try 1157 try
1148 { 1158 {
1149 //for (int y = 0; y < 16; y++) 1159 for (int y = 0; y < 16; y++)
1150 //{ 1160 {
1151 // for (int x = 0; x < 16; x++) 1161 for (int x = 0; x < 16; x+=4)
1152 // { 1162 {
1153 // SendLayerData(x, y, map); 1163 SendLayerPacket(x, y, map);
1154 // } 1164 }
1155 //} 1165 }
1156
1157 // Send LayerData in a spiral pattern. Fun!
1158 SendLayerTopRight(map, 0, 0, 15, 15);
1159 } 1166 }
1160 catch (Exception e) 1167 catch (Exception e)
1161 { 1168 {
@@ -1163,51 +1170,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1163 } 1170 }
1164 } 1171 }
1165 1172
1166 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1167 {
1168 // Row
1169 for (int i = x1; i <= x2; i++)
1170 SendLayerData(i, y1, map);
1171
1172 // Column
1173 for (int j = y1 + 1; j <= y2; j++)
1174 SendLayerData(x2, j, map);
1175
1176 if (x2 - x1 > 0)
1177 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1178 }
1179
1180 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1181 {
1182 // Row in reverse
1183 for (int i = x2; i >= x1; i--)
1184 SendLayerData(i, y2, map);
1185
1186 // Column in reverse
1187 for (int j = y2 - 1; j >= y1; j--)
1188 SendLayerData(x1, j, map);
1189
1190 if (x2 - x1 > 0)
1191 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1192 }
1193
1194 /// <summary> 1173 /// <summary>
1195 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1174 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1196 /// </summary> 1175 /// </summary>
1197 /// <param name="map">heightmap</param> 1176 /// <param name="map">heightmap</param>
1198 /// <param name="px">X coordinate for patches 0..12</param> 1177 /// <param name="px">X coordinate for patches 0..12</param>
1199 /// <param name="py">Y coordinate for patches 0..15</param> 1178 /// <param name="py">Y coordinate for patches 0..15</param>
1200 // private void SendLayerPacket(float[] map, int y, int x) 1179 private void SendLayerPacket(int x, int y, float[] map)
1201 // { 1180 {
1202 // int[] patches = new int[4]; 1181 int[] patches = new int[4];
1203 // patches[0] = x + 0 + y * 16; 1182 patches[0] = x + 0 + y * 16;
1204 // patches[1] = x + 1 + y * 16; 1183 patches[1] = x + 1 + y * 16;
1205 // patches[2] = x + 2 + y * 16; 1184 patches[2] = x + 2 + y * 16;
1206 // patches[3] = x + 3 + y * 16; 1185 patches[3] = x + 3 + y * 16;
1207 1186
1208 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1187 float[] heightmap = (map.Length == 65536) ?
1209 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1188 map :
1210 // } 1189 LLHeightFieldMoronize(map);
1190
1191 try
1192 {
1193 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1194 OutPacket(layerpack, ThrottleOutPacketType.Land);
1195 }
1196 catch
1197 {
1198 for (int px = x ; px < x + 4 ; px++)
1199 SendLayerData(px, y, map);
1200 }
1201 }
1211 1202
1212 /// <summary> 1203 /// <summary>
1213 /// Sends a specified patch to a client 1204 /// Sends a specified patch to a client
@@ -1227,7 +1218,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1227 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1218 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1228 layerpack.Header.Reliable = true; 1219 layerpack.Header.Reliable = true;
1229 1220
1230 OutPacket(layerpack, ThrottleOutPacketType.Land); 1221 OutPacket(layerpack, ThrottleOutPacketType.Task);
1231 } 1222 }
1232 catch (Exception e) 1223 catch (Exception e)
1233 { 1224 {
@@ -1590,7 +1581,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1590 1581
1591 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1582 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1592 { 1583 {
1593// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1584// foreach (uint id in localIDs)
1585// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1594 1586
1595 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1587 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1596 // TODO: don't create new blocks if recycling an old packet 1588 // TODO: don't create new blocks if recycling an old packet
@@ -1612,17 +1604,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1612 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race 1604 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
1613 // condition where a kill can be processed before an out-of-date update for the same object. 1605 // condition where a kill can be processed before an out-of-date update for the same object.
1614 // ProcessEntityUpdates() also takes the m_killRecord lock. 1606 // ProcessEntityUpdates() also takes the m_killRecord lock.
1615 lock (m_killRecord) 1607// lock (m_killRecord)
1616 { 1608// {
1617 foreach (uint localID in localIDs) 1609// foreach (uint localID in localIDs)
1618 m_killRecord.Add(localID); 1610// m_killRecord.Add(localID);
1619 1611
1620 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1612 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1621 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1613 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1622 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1614 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1623 // scene objects in a viewer until that viewer is relogged in. 1615 // scene objects in a viewer until that viewer is relogged in.
1624 OutPacket(kill, ThrottleOutPacketType.Task); 1616 OutPacket(kill, ThrottleOutPacketType.Task);
1625 } 1617// }
1626 } 1618 }
1627 } 1619 }
1628 1620
@@ -2081,9 +2073,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2081 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); 2073 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
2082 } 2074 }
2083 2075
2084 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2085 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId) 2076 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
2086 { 2077 {
2078 SendInventoryItemCreateUpdate(Item, UUID.Zero, callbackId);
2079 }
2080
2081 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2082 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId)
2083 {
2087 const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff; 2084 const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff;
2088 2085
2089 UpdateCreateInventoryItemPacket InventoryReply 2086 UpdateCreateInventoryItemPacket InventoryReply
@@ -2093,6 +2090,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2093 // TODO: don't create new blocks if recycling an old packet 2090 // TODO: don't create new blocks if recycling an old packet
2094 InventoryReply.AgentData.AgentID = AgentId; 2091 InventoryReply.AgentData.AgentID = AgentId;
2095 InventoryReply.AgentData.SimApproved = true; 2092 InventoryReply.AgentData.SimApproved = true;
2093 InventoryReply.AgentData.TransactionID = transactionID;
2096 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1]; 2094 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1];
2097 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock(); 2095 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock();
2098 InventoryReply.InventoryData[0].ItemID = Item.ID; 2096 InventoryReply.InventoryData[0].ItemID = Item.ID;
@@ -2162,16 +2160,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2162 replytask.InventoryData.TaskID = taskID; 2160 replytask.InventoryData.TaskID = taskID;
2163 replytask.InventoryData.Serial = serial; 2161 replytask.InventoryData.Serial = serial;
2164 replytask.InventoryData.Filename = fileName; 2162 replytask.InventoryData.Filename = fileName;
2165 OutPacket(replytask, ThrottleOutPacketType.Asset); 2163 OutPacket(replytask, ThrottleOutPacketType.Task);
2166 } 2164 }
2167 2165
2168 public void SendXferPacket(ulong xferID, uint packet, byte[] data) 2166 public void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory)
2169 { 2167 {
2168 ThrottleOutPacketType type = ThrottleOutPacketType.Asset;
2169 if (isTaskInventory)
2170 type = ThrottleOutPacketType.Task;
2171
2170 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket); 2172 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket);
2171 sendXfer.XferID.ID = xferID; 2173 sendXfer.XferID.ID = xferID;
2172 sendXfer.XferID.Packet = packet; 2174 sendXfer.XferID.Packet = packet;
2173 sendXfer.DataPacket.Data = data; 2175 sendXfer.DataPacket.Data = data;
2174 OutPacket(sendXfer, ThrottleOutPacketType.Asset); 2176 OutPacket(sendXfer, type);
2175 } 2177 }
2176 2178
2177 public void SendAbortXferPacket(ulong xferID) 2179 public void SendAbortXferPacket(ulong xferID)
@@ -2353,6 +2355,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2353 OutPacket(sound, ThrottleOutPacketType.Task); 2355 OutPacket(sound, ThrottleOutPacketType.Task);
2354 } 2356 }
2355 2357
2358 public void SendTransferAbort(TransferRequestPacket transferRequest)
2359 {
2360 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2361 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2362 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2363 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2364 OutPacket(abort, ThrottleOutPacketType.Task);
2365 }
2366
2356 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2367 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2357 { 2368 {
2358 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2369 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2661,6 +2672,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2661 float friction = part.Friction; 2672 float friction = part.Friction;
2662 float bounce = part.Restitution; 2673 float bounce = part.Restitution;
2663 float gravmod = part.GravityModifier; 2674 float gravmod = part.GravityModifier;
2675
2664 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId); 2676 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2665 } 2677 }
2666 } 2678 }
@@ -2731,8 +2743,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2731 req.AssetInf.ID, req.AssetInf.Metadata.ContentType); 2743 req.AssetInf.ID, req.AssetInf.Metadata.ContentType);
2732 return; 2744 return;
2733 } 2745 }
2746 int WearableOut = 0;
2747 bool isWearable = false;
2734 2748
2735 //m_log.Debug("sending asset " + req.RequestAssetID); 2749 if (req.AssetInf != null)
2750 isWearable =
2751 ((AssetType) req.AssetInf.Type ==
2752 AssetType.Bodypart || (AssetType) req.AssetInf.Type == AssetType.Clothing);
2753
2754
2755 //m_log.Debug("sending asset " + req.RequestAssetID + ", iswearable: " + isWearable);
2756
2757
2758 //if (isWearable)
2759 // m_log.Debug((AssetType)req.AssetInf.Type);
2760
2736 TransferInfoPacket Transfer = new TransferInfoPacket(); 2761 TransferInfoPacket Transfer = new TransferInfoPacket();
2737 Transfer.TransferInfo.ChannelType = 2; 2762 Transfer.TransferInfo.ChannelType = 2;
2738 Transfer.TransferInfo.Status = 0; 2763 Transfer.TransferInfo.Status = 0;
@@ -2754,7 +2779,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2754 Transfer.TransferInfo.Size = req.AssetInf.Data.Length; 2779 Transfer.TransferInfo.Size = req.AssetInf.Data.Length;
2755 Transfer.TransferInfo.TransferID = req.TransferRequestID; 2780 Transfer.TransferInfo.TransferID = req.TransferRequestID;
2756 Transfer.Header.Zerocoded = true; 2781 Transfer.Header.Zerocoded = true;
2757 OutPacket(Transfer, ThrottleOutPacketType.Asset); 2782 OutPacket(Transfer, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2758 2783
2759 if (req.NumPackets == 1) 2784 if (req.NumPackets == 1)
2760 { 2785 {
@@ -2765,12 +2790,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2765 TransferPacket.TransferData.Data = req.AssetInf.Data; 2790 TransferPacket.TransferData.Data = req.AssetInf.Data;
2766 TransferPacket.TransferData.Status = 1; 2791 TransferPacket.TransferData.Status = 1;
2767 TransferPacket.Header.Zerocoded = true; 2792 TransferPacket.Header.Zerocoded = true;
2768 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2793 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2769 } 2794 }
2770 else 2795 else
2771 { 2796 {
2772 int processedLength = 0; 2797 int processedLength = 0;
2773 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2798// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2799
2800 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2774 int packetNumber = 0; 2801 int packetNumber = 0;
2775 2802
2776 while (processedLength < req.AssetInf.Data.Length) 2803 while (processedLength < req.AssetInf.Data.Length)
@@ -2796,7 +2823,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2796 TransferPacket.TransferData.Status = 1; 2823 TransferPacket.TransferData.Status = 1;
2797 } 2824 }
2798 TransferPacket.Header.Zerocoded = true; 2825 TransferPacket.Header.Zerocoded = true;
2799 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2826 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2800 2827
2801 processedLength += chunkSize; 2828 processedLength += chunkSize;
2802 packetNumber++; 2829 packetNumber++;
@@ -2841,7 +2868,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2841 reply.Data.ParcelID = parcelID; 2868 reply.Data.ParcelID = parcelID;
2842 reply.Data.OwnerID = land.OwnerID; 2869 reply.Data.OwnerID = land.OwnerID;
2843 reply.Data.Name = Utils.StringToBytes(land.Name); 2870 reply.Data.Name = Utils.StringToBytes(land.Name);
2844 reply.Data.Desc = Utils.StringToBytes(land.Description); 2871 if (land != null && land.Description != null && land.Description != String.Empty)
2872 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2873 else
2874 reply.Data.Desc = new Byte[0];
2845 reply.Data.ActualArea = land.Area; 2875 reply.Data.ActualArea = land.Area;
2846 reply.Data.BillableArea = land.Area; // TODO: what is this? 2876 reply.Data.BillableArea = land.Area; // TODO: what is this?
2847 2877
@@ -3548,24 +3578,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3548 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count]; 3578 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count];
3549 AgentWearablesUpdatePacket.WearableDataBlock awb; 3579 AgentWearablesUpdatePacket.WearableDataBlock awb;
3550 int idx = 0; 3580 int idx = 0;
3551 for (int i = 0; i < wearables.Length; i++) 3581
3552 { 3582 for (int i = 0; i < wearables.Length; i++)
3553 for (int j = 0; j < wearables[i].Count; j++) 3583 {
3554 { 3584 for (int j = 0; j < wearables[i].Count; j++)
3555 awb = new AgentWearablesUpdatePacket.WearableDataBlock(); 3585 {
3556 awb.WearableType = (byte)i; 3586 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
3557 awb.AssetID = wearables[i][j].AssetID; 3587 awb.WearableType = (byte) i;
3558 awb.ItemID = wearables[i][j].ItemID; 3588 awb.AssetID = wearables[i][j].AssetID;
3559 aw.WearableData[idx] = awb; 3589 awb.ItemID = wearables[i][j].ItemID;
3560 idx++; 3590 aw.WearableData[idx] = awb;
3561 3591 idx++;
3562// m_log.DebugFormat( 3592
3563// "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}", 3593 // m_log.DebugFormat(
3564// awb.ItemID, awb.AssetID, i, Name); 3594 // "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}",
3565 } 3595 // awb.ItemID, awb.AssetID, i, Name);
3566 } 3596 }
3597 }
3567 3598
3568 OutPacket(aw, ThrottleOutPacketType.Task); 3599 OutPacket(aw, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority);
3569 } 3600 }
3570 3601
3571 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) 3602 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
@@ -3576,7 +3607,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3576 3607
3577 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3608 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3578 // TODO: don't create new blocks if recycling an old packet 3609 // TODO: don't create new blocks if recycling an old packet
3579 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3610 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3580 avp.ObjectData.TextureEntry = textureEntry; 3611 avp.ObjectData.TextureEntry = textureEntry;
3581 3612
3582 AvatarAppearancePacket.VisualParamBlock avblock = null; 3613 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3707,7 +3738,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3707 /// </summary> 3738 /// </summary>
3708 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3739 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3709 { 3740 {
3710 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3741 if (entity is SceneObjectPart)
3742 {
3743 SceneObjectPart e = (SceneObjectPart)entity;
3744 SceneObjectGroup g = e.ParentGroup;
3745 if (g.RootPart.Shape.State > 30) // HUD
3746 if (g.OwnerID != AgentId)
3747 return; // Don't send updates for other people's HUDs
3748 }
3749
3711 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3750 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3712 3751
3713 lock (m_entityUpdates.SyncRoot) 3752 lock (m_entityUpdates.SyncRoot)
@@ -3774,27 +3813,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3774 3813
3775 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3814 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3776 // condition where a kill can be processed before an out-of-date update for the same object. 3815 // condition where a kill can be processed before an out-of-date update for the same object.
3777 lock (m_killRecord) 3816 float avgTimeDilation = 1.0f;
3817 IEntityUpdate iupdate;
3818 Int32 timeinqueue; // this is just debugging code & can be dropped later
3819
3820 while (updatesThisCall < maxUpdates)
3778 { 3821 {
3779 float avgTimeDilation = 1.0f; 3822 lock (m_entityUpdates.SyncRoot)
3780 IEntityUpdate iupdate; 3823 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3781 Int32 timeinqueue; // this is just debugging code & can be dropped later 3824 break;
3782 3825
3783 while (updatesThisCall < maxUpdates) 3826 EntityUpdate update = (EntityUpdate)iupdate;
3827
3828 avgTimeDilation += update.TimeDilation;
3829 avgTimeDilation *= 0.5f;
3830
3831 if (update.Entity is SceneObjectPart)
3784 { 3832 {
3785 lock (m_entityUpdates.SyncRoot) 3833 SceneObjectPart part = (SceneObjectPart)update.Entity;
3786 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3787 break;
3788 3834
3789 EntityUpdate update = (EntityUpdate)iupdate; 3835 if (part.ParentGroup.IsDeleted)
3790 3836 continue;
3791 avgTimeDilation += update.TimeDilation;
3792 avgTimeDilation *= 0.5f;
3793 3837
3794 if (update.Entity is SceneObjectPart) 3838 if (part.ParentGroup.IsAttachment)
3839 { // Someone else's HUD, why are we getting these?
3840 if (part.ParentGroup.OwnerID != AgentId &&
3841 part.ParentGroup.RootPart.Shape.State > 30)
3842 continue;
3843 ScenePresence sp;
3844 // Owner is not in the sim, don't update it to
3845 // anyone
3846 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3847 continue;
3848
3849 List<SceneObjectGroup> atts = sp.GetAttachments();
3850 bool found = false;
3851 foreach (SceneObjectGroup att in atts)
3852 {
3853 if (att == part.ParentGroup)
3854 {
3855 found = true;
3856 break;
3857 }
3858 }
3859
3860 // It's an attachment of a valid avatar, but
3861 // doesn't seem to be attached, skip
3862 if (!found)
3863 continue;
3864
3865 // On vehicle crossing, the attachments are received
3866 // while the avatar is still a child. Don't send
3867 // updates here because the LocalId has not yet
3868 // been updated and the viewer will derender the
3869 // attachments until the avatar becomes root.
3870 if (sp.IsChildAgent)
3871 continue;
3872
3873 // If the object is an attachment we don't want it to be in the kill
3874 // record. Else attaching from inworld and subsequently dropping
3875 // it will no longer work.
3876// lock (m_killRecord)
3877// {
3878// m_killRecord.Remove(part.LocalId);
3879// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3880// }
3881 }
3882 else
3795 { 3883 {
3796 SceneObjectPart part = (SceneObjectPart)update.Entity;
3797
3798 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3884 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3799 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3885 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3800 // safety measure. 3886 // safety measure.
@@ -3805,21 +3891,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3805 // 3891 //
3806 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3892 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3807 // after the root prim has been deleted. 3893 // after the root prim has been deleted.
3808 if (m_killRecord.Contains(part.LocalId)) 3894 //
3809 { 3895 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3810 // m_log.WarnFormat( 3896// lock (m_killRecord)
3811 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3897// {
3812 // part.LocalId, Name); 3898// if (m_killRecord.Contains(part.LocalId))
3813 continue; 3899// continue;
3814 } 3900// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3815 3901// continue;
3816 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3902// }
3903 }
3904
3905 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3906 {
3907 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3908 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3817 { 3909 {
3818 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3910 part.Shape.LightEntry = false;
3819 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3820 {
3821 part.Shape.LightEntry = false;
3822 }
3823 } 3911 }
3824 3912
3825 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh)) 3913 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
@@ -3830,224 +3918,166 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3830 part.Shape.ProfileHollow = 27500; 3918 part.Shape.ProfileHollow = 27500;
3831 } 3919 }
3832 } 3920 }
3833 3921
3834 #region UpdateFlags to packet type conversion 3922 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
3835
3836 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3837
3838 bool canUseCompressed = true;
3839 bool canUseImproved = true;
3840
3841 // Compressed object updates only make sense for LL primitives
3842 if (!(update.Entity is SceneObjectPart))
3843 { 3923 {
3844 canUseCompressed = false; 3924 // Ensure that mesh has at least 8 valid faces
3925 part.Shape.ProfileBegin = 12500;
3926 part.Shape.ProfileEnd = 0;
3927 part.Shape.ProfileHollow = 27500;
3845 } 3928 }
3846 3929 }
3847 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 3930
3931 ++updatesThisCall;
3932
3933 #region UpdateFlags to packet type conversion
3934
3935 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3936
3937 bool canUseCompressed = true;
3938 bool canUseImproved = true;
3939
3940 // Compressed object updates only make sense for LL primitives
3941 if (!(update.Entity is SceneObjectPart))
3942 {
3943 canUseCompressed = false;
3944 }
3945
3946 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3947 {
3948 canUseCompressed = false;
3949 canUseImproved = false;
3950 }
3951 else
3952 {
3953 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3954 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3955 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3956 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3848 { 3957 {
3849 canUseCompressed = false; 3958 canUseCompressed = false;
3850 canUseImproved = false;
3851 } 3959 }
3852 else 3960
3961 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3962 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3963 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3964 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3965 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3966 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3967 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3968 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3969 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3970 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3971 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3972 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3973 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3974 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3853 { 3975 {
3854 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3976 canUseImproved = false;
3855 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3856 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3857 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3858 {
3859 canUseCompressed = false;
3860 }
3861
3862 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3863 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3864 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3865 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3866 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3867 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3868 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3869 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3870 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3871 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3872 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3873 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3874 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3875 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3876 {
3877 canUseImproved = false;
3878 }
3879 } 3977 }
3978 }
3880 3979
3881 #endregion UpdateFlags to packet type conversion 3980 #endregion UpdateFlags to packet type conversion
3882
3883 #region Block Construction
3884
3885 // TODO: Remove this once we can build compressed updates
3886 canUseCompressed = false;
3887
3888 if (!canUseImproved && !canUseCompressed)
3889 {
3890 ObjectUpdatePacket.ObjectDataBlock updateBlock;
3891 3981
3892 if (update.Entity is ScenePresence) 3982 #region Block Construction
3893 {
3894 updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
3895 }
3896 else
3897 {
3898 SceneObjectPart part = (SceneObjectPart)update.Entity;
3899 updateBlock = CreatePrimUpdateBlock(part, AgentId);
3900
3901 // If the part has become a private hud since the update was scheduled then we do not
3902 // want to send it to other avatars.
3903 if (part.ParentGroup.IsAttachment
3904 && part.ParentGroup.HasPrivateAttachmentPoint
3905 && part.ParentGroup.AttachedAvatar != AgentId)
3906 continue;
3907
3908 // If the part has since been deleted, then drop the update. In the case of attachments,
3909 // this is to avoid spurious updates to other viewers since post-processing of attachments
3910 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3911 // of the test above).
3912 //
3913 // Actual deletions (kills) happen in another method.
3914 if (part.ParentGroup.IsDeleted)
3915 continue;
3916 }
3917 3983
3918 objectUpdateBlocks.Value.Add(updateBlock); 3984 // TODO: Remove this once we can build compressed updates
3919 objectUpdates.Value.Add(update); 3985 canUseCompressed = false;
3920 }
3921 else if (!canUseImproved)
3922 {
3923 SceneObjectPart part = (SceneObjectPart)update.Entity;
3924 ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
3925 = CreateCompressedUpdateBlock(part, updateFlags);
3926
3927 // If the part has since been deleted, then drop the update. In the case of attachments,
3928 // this is to avoid spurious updates to other viewers since post-processing of attachments
3929 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3930 // of the test above).
3931 //
3932 // Actual deletions (kills) happen in another method.
3933 if (part.ParentGroup.IsDeleted)
3934 continue;
3935 3986
3936 compressedUpdateBlocks.Value.Add(compressedBlock); 3987 if (!canUseImproved && !canUseCompressed)
3937 compressedUpdates.Value.Add(update); 3988 {
3989 if (update.Entity is ScenePresence)
3990 {
3991 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3938 } 3992 }
3939 else 3993 else
3940 { 3994 {
3941 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3995 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3942 {
3943 // Self updates go into a special list
3944 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3945 terseAgentUpdates.Value.Add(update);
3946 }
3947 else
3948 {
3949 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
3950 = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
3951
3952 // Everything else goes here
3953 if (update.Entity is SceneObjectPart)
3954 {
3955 SceneObjectPart part = (SceneObjectPart)update.Entity;
3956
3957 // If the part has become a private hud since the update was scheduled then we do not
3958 // want to send it to other avatars.
3959 if (part.ParentGroup.IsAttachment
3960 && part.ParentGroup.HasPrivateAttachmentPoint
3961 && part.ParentGroup.AttachedAvatar != AgentId)
3962 continue;
3963
3964 // If the part has since been deleted, then drop the update. In the case of attachments,
3965 // this is to avoid spurious updates to other viewers since post-processing of attachments
3966 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3967 // of the test above).
3968 //
3969 // Actual deletions (kills) happen in another method.
3970 if (part.ParentGroup.IsDeleted)
3971 continue;
3972 }
3973
3974 terseUpdateBlocks.Value.Add(terseUpdateBlock);
3975 terseUpdates.Value.Add(update);
3976 }
3977 } 3996 }
3978
3979 ++updatesThisCall;
3980
3981 #endregion Block Construction
3982 } 3997 }
3983 3998 else if (!canUseImproved)
3984 #region Packet Sending
3985 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3986
3987 if (terseAgentUpdateBlocks.IsValueCreated)
3988 { 3999 {
3989 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 4000 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
4001 }
4002 else
4003 {
4004 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
4005 // Self updates go into a special list
4006 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
4007 else
4008 // Everything else goes here
4009 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
4010 }
3990 4011
3991 ImprovedTerseObjectUpdatePacket packet 4012 #endregion Block Construction
3992 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 4013 }
3993 4014
3994 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4015 #region Packet Sending
3995 packet.RegionData.TimeDilation = timeDilation; 4016
3996 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4017 const float TIME_DILATION = 1.0f;
4018 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
4019
4020 if (terseAgentUpdateBlocks.IsValueCreated)
4021 {
4022 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3997 4023
3998 for (int i = 0; i < blocks.Count; i++) 4024 ImprovedTerseObjectUpdatePacket packet
3999 packet.ObjectData[i] = blocks[i]; 4025 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
4000 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4026 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4001 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); }); 4027 packet.RegionData.TimeDilation = timeDilation;
4002 } 4028 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4003 4029
4004 if (objectUpdateBlocks.IsValueCreated) 4030 for (int i = 0; i < blocks.Count; i++)
4005 { 4031 packet.ObjectData[i] = blocks[i];
4006 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
4007
4008 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
4009 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4010 packet.RegionData.TimeDilation = timeDilation;
4011 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4012
4013 for (int i = 0; i < blocks.Count; i++)
4014 packet.ObjectData[i] = blocks[i];
4015 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4016 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
4017 }
4018
4019 if (compressedUpdateBlocks.IsValueCreated)
4020 {
4021 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4022
4023 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4024 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4025 packet.RegionData.TimeDilation = timeDilation;
4026 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4027
4028 for (int i = 0; i < blocks.Count; i++)
4029 packet.ObjectData[i] = blocks[i];
4030 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4031 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
4032 }
4033 4032
4034 if (terseUpdateBlocks.IsValueCreated) 4033 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
4035 { 4034 }
4036 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4037
4038 ImprovedTerseObjectUpdatePacket packet
4039 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4040 PacketType.ImprovedTerseObjectUpdate);
4041 4035
4042 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4036 if (objectUpdateBlocks.IsValueCreated)
4043 packet.RegionData.TimeDilation = timeDilation; 4037 {
4044 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4038 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
4045 4039
4046 for (int i = 0; i < blocks.Count; i++) 4040 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
4047 packet.ObjectData[i] = blocks[i]; 4041 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4048 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4042 packet.RegionData.TimeDilation = timeDilation;
4049 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 4043 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4050 } 4044
4045 for (int i = 0; i < blocks.Count; i++)
4046 packet.ObjectData[i] = blocks[i];
4047
4048 OutPacket(packet, ThrottleOutPacketType.Task, true);
4049 }
4050
4051 if (compressedUpdateBlocks.IsValueCreated)
4052 {
4053 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4054
4055 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4056 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4057 packet.RegionData.TimeDilation = timeDilation;
4058 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4059
4060 for (int i = 0; i < blocks.Count; i++)
4061 packet.ObjectData[i] = blocks[i];
4062
4063 OutPacket(packet, ThrottleOutPacketType.Task, true);
4064 }
4065
4066 if (terseUpdateBlocks.IsValueCreated)
4067 {
4068 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4069
4070 ImprovedTerseObjectUpdatePacket packet
4071 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4072 PacketType.ImprovedTerseObjectUpdate);
4073 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4074 packet.RegionData.TimeDilation = timeDilation;
4075 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4076
4077 for (int i = 0; i < blocks.Count; i++)
4078 packet.ObjectData[i] = blocks[i];
4079
4080 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
4051 } 4081 }
4052 4082
4053 #endregion Packet Sending 4083 #endregion Packet Sending
@@ -4340,11 +4370,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4340 4370
4341 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4371 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4342 // of the object rather than the properties when the packet was created 4372 // of the object rather than the properties when the packet was created
4343 OutPacket(packet, ThrottleOutPacketType.Task, true, 4373 // HACK : Remove intelligent resending until it's fixed in core
4344 delegate(OutgoingPacket oPacket) 4374 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4345 { 4375 // delegate(OutgoingPacket oPacket)
4346 ResendPropertyUpdates(updates, oPacket); 4376 // {
4347 }); 4377 // ResendPropertyUpdates(updates, oPacket);
4378 // });
4379 OutPacket(packet, ThrottleOutPacketType.Task, true);
4348 4380
4349 // pbcnt += blocks.Count; 4381 // pbcnt += blocks.Count;
4350 // ppcnt++; 4382 // ppcnt++;
@@ -4370,11 +4402,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4370 // of the object rather than the properties when the packet was created 4402 // of the object rather than the properties when the packet was created
4371 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4403 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4372 updates.Add(familyUpdates.Value[i]); 4404 updates.Add(familyUpdates.Value[i]);
4373 OutPacket(packet, ThrottleOutPacketType.Task, true, 4405 // HACK : Remove intelligent resending until it's fixed in core
4374 delegate(OutgoingPacket oPacket) 4406 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4375 { 4407 // delegate(OutgoingPacket oPacket)
4376 ResendPropertyUpdates(updates, oPacket); 4408 // {
4377 }); 4409 // ResendPropertyUpdates(updates, oPacket);
4410 // });
4411 OutPacket(packet, ThrottleOutPacketType.Task, true);
4378 4412
4379 // fpcnt++; 4413 // fpcnt++;
4380 // fbcnt++; 4414 // fbcnt++;
@@ -4746,7 +4780,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4746 4780
4747 if (landData.SimwideArea > 0) 4781 if (landData.SimwideArea > 0)
4748 { 4782 {
4749 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4783 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4784 // Never report more than sim total capacity
4785 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4786 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4750 updateMessage.SimWideMaxPrims = simulatorCapacity; 4787 updateMessage.SimWideMaxPrims = simulatorCapacity;
4751 } 4788 }
4752 else 4789 else
@@ -4875,14 +4912,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4875 4912
4876 if (notifyCount > 0) 4913 if (notifyCount > 0)
4877 { 4914 {
4878 if (notifyCount > 32) 4915// if (notifyCount > 32)
4879 { 4916// {
4880 m_log.InfoFormat( 4917// m_log.InfoFormat(
4881 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4918// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4882 + " - a developer might want to investigate whether this is a hard limit", 32); 4919// + " - a developer might want to investigate whether this is a hard limit", 32);
4883 4920//
4884 notifyCount = 32; 4921// notifyCount = 32;
4885 } 4922// }
4886 4923
4887 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4924 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4888 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4925 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4937,9 +4974,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4937 { 4974 {
4938 ScenePresence presence = (ScenePresence)entity; 4975 ScenePresence presence = (ScenePresence)entity;
4939 4976
4977 position = presence.OffsetPosition;
4978 rotation = presence.Rotation;
4979
4980 if (presence.ParentID != 0)
4981 {
4982 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4983 if (part != null && part != part.ParentGroup.RootPart)
4984 {
4985 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4986 rotation = part.RotationOffset * presence.Rotation;
4987 }
4988 angularVelocity = Vector3.Zero;
4989 }
4990 else
4991 {
4992 angularVelocity = presence.AngularVelocity;
4993 rotation = presence.Rotation;
4994 }
4995
4940 attachPoint = 0; 4996 attachPoint = 0;
4941 collisionPlane = presence.CollisionPlane; 4997 collisionPlane = presence.CollisionPlane;
4942 position = presence.OffsetPosition;
4943 velocity = presence.Velocity; 4998 velocity = presence.Velocity;
4944 acceleration = Vector3.Zero; 4999 acceleration = Vector3.Zero;
4945 5000
@@ -4948,9 +5003,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4948 // may improve movement smoothness. 5003 // may improve movement smoothness.
4949// acceleration = new Vector3(1, 0, 0); 5004// acceleration = new Vector3(1, 0, 0);
4950 5005
4951 angularVelocity = presence.AngularVelocity;
4952 rotation = presence.Rotation;
4953
4954 if (sendTexture) 5006 if (sendTexture)
4955 textureEntry = presence.Appearance.Texture.GetBytes(); 5007 textureEntry = presence.Appearance.Texture.GetBytes();
4956 else 5008 else
@@ -5056,13 +5108,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5056 5108
5057 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5109 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
5058 { 5110 {
5111 Vector3 offsetPosition = data.OffsetPosition;
5112 Quaternion rotation = data.Rotation;
5113 uint parentID = data.ParentID;
5114
5115 if (parentID != 0)
5116 {
5117 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5118 if (part != null && part != part.ParentGroup.RootPart)
5119 {
5120 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5121 rotation = part.RotationOffset * data.Rotation;
5122 parentID = part.ParentGroup.RootPart.LocalId;
5123 }
5124 }
5125
5059 byte[] objectData = new byte[76]; 5126 byte[] objectData = new byte[76];
5060 5127
5061 data.CollisionPlane.ToBytes(objectData, 0); 5128 data.CollisionPlane.ToBytes(objectData, 0);
5062 data.OffsetPosition.ToBytes(objectData, 16); 5129 offsetPosition.ToBytes(objectData, 16);
5063// data.Velocity.ToBytes(objectData, 28); 5130// data.Velocity.ToBytes(objectData, 28);
5064// data.Acceleration.ToBytes(objectData, 40); 5131// data.Acceleration.ToBytes(objectData, 40);
5065 data.Rotation.ToBytes(objectData, 52); 5132 rotation.ToBytes(objectData, 52);
5066 //data.AngularVelocity.ToBytes(objectData, 64); 5133 //data.AngularVelocity.ToBytes(objectData, 64);
5067 5134
5068 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5135 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -5076,14 +5143,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5076 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5143 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
5077 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5144 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
5078 update.ObjectData = objectData; 5145 update.ObjectData = objectData;
5079 update.ParentID = data.ParentID; 5146 update.ParentID = parentID;
5080 update.PathCurve = 16; 5147 update.PathCurve = 16;
5081 update.PathScaleX = 100; 5148 update.PathScaleX = 100;
5082 update.PathScaleY = 100; 5149 update.PathScaleY = 100;
5083 update.PCode = (byte)PCode.Avatar; 5150 update.PCode = (byte)PCode.Avatar;
5084 update.ProfileCurve = 1; 5151 update.ProfileCurve = 1;
5085 update.PSBlock = Utils.EmptyBytes; 5152 update.PSBlock = Utils.EmptyBytes;
5086 update.Scale = new Vector3(0.45f, 0.6f, 1.9f); 5153 update.Scale = data.Appearance.AvatarSize;
5154// update.Scale.Z -= 0.2f;
5155
5087 update.Text = Utils.EmptyBytes; 5156 update.Text = Utils.EmptyBytes;
5088 update.TextColor = new byte[4]; 5157 update.TextColor = new byte[4];
5089 5158
@@ -5094,10 +5163,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5094 update.TextureEntry = Utils.EmptyBytes; 5163 update.TextureEntry = Utils.EmptyBytes;
5095// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; 5164// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
5096 5165
5166/* 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)
5097 update.UpdateFlags = (uint)( 5167 update.UpdateFlags = (uint)(
5098 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | 5168 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
5099 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | 5169 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
5100 PrimFlags.ObjectOwnerModify); 5170 PrimFlags.ObjectOwnerModify);
5171*/
5172 update.UpdateFlags = 0;
5101 5173
5102 return update; 5174 return update;
5103 } 5175 }
@@ -5268,8 +5340,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5268 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs 5340 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs
5269 // for each AgentUpdate packet. 5341 // for each AgentUpdate packet.
5270 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false); 5342 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false);
5271 5343
5272 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false); 5344 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false);
5345 AddLocalPacketHandler(PacketType.VelocityInterpolateOff, HandleVelocityInterpolateOff, false);
5346 AddLocalPacketHandler(PacketType.VelocityInterpolateOn, HandleVelocityInterpolateOn, false);
5273 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); 5347 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false);
5274 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); 5348 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
5275 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false); 5349 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false);
@@ -5421,6 +5495,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5421 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5495 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5422 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5496 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5423 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5497 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5498 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5424 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5499 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5425 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5500 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5426 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5501 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5487,6 +5562,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5487 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5562 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5488 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5563 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5489 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5564 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5565 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5490 5566
5491 AddGenericPacketHandler("autopilot", HandleAutopilot); 5567 AddGenericPacketHandler("autopilot", HandleAutopilot);
5492 } 5568 }
@@ -5525,6 +5601,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5525 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) || 5601 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) ||
5526 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) || 5602 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) ||
5527 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) || 5603 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) ||
5604 (x.ControlFlags != 0) ||
5528 (x.Far != m_lastAgentUpdateArgs.Far) || 5605 (x.Far != m_lastAgentUpdateArgs.Far) ||
5529 (x.Flags != m_lastAgentUpdateArgs.Flags) || 5606 (x.Flags != m_lastAgentUpdateArgs.Flags) ||
5530 (x.State != m_lastAgentUpdateArgs.State) || 5607 (x.State != m_lastAgentUpdateArgs.State) ||
@@ -5784,6 +5861,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5784 return true; 5861 return true;
5785 } 5862 }
5786 5863
5864 private bool HandleVelocityInterpolateOff(IClientAPI sender, Packet Pack)
5865 {
5866 VelocityInterpolateOffPacket p = (VelocityInterpolateOffPacket)Pack;
5867 if (p.AgentData.SessionID != SessionId ||
5868 p.AgentData.AgentID != AgentId)
5869 return true;
5870
5871 m_VelocityInterpolate = false;
5872 return true;
5873 }
5874
5875 private bool HandleVelocityInterpolateOn(IClientAPI sender, Packet Pack)
5876 {
5877 VelocityInterpolateOnPacket p = (VelocityInterpolateOnPacket)Pack;
5878 if (p.AgentData.SessionID != SessionId ||
5879 p.AgentData.AgentID != AgentId)
5880 return true;
5881
5882 m_VelocityInterpolate = true;
5883 return true;
5884 }
5885
5886
5787 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack) 5887 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack)
5788 { 5888 {
5789 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack; 5889 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack;
@@ -6204,17 +6304,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6204 // Temporarily protect ourselves from the mantis #951 failure. 6304 // Temporarily protect ourselves from the mantis #951 failure.
6205 // However, we could do this for several other handlers where a failure isn't terminal 6305 // However, we could do this for several other handlers where a failure isn't terminal
6206 // for the client session anyway, in order to protect ourselves against bad code in plugins 6306 // for the client session anyway, in order to protect ourselves against bad code in plugins
6307 Vector3 avSize = appear.AgentData.Size;
6207 try 6308 try
6208 { 6309 {
6209 byte[] visualparams = new byte[appear.VisualParam.Length]; 6310 byte[] visualparams = new byte[appear.VisualParam.Length];
6210 for (int i = 0; i < appear.VisualParam.Length; i++) 6311 for (int i = 0; i < appear.VisualParam.Length; i++)
6211 visualparams[i] = appear.VisualParam[i].ParamValue; 6312 visualparams[i] = appear.VisualParam[i].ParamValue;
6212 6313 //var b = appear.WearableData[0];
6314
6213 Primitive.TextureEntry te = null; 6315 Primitive.TextureEntry te = null;
6214 if (appear.ObjectData.TextureEntry.Length > 1) 6316 if (appear.ObjectData.TextureEntry.Length > 1)
6215 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); 6317 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
6318
6319 WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length];
6320 for (int i=0; i<appear.WearableData.Length;i++)
6321 cacheitems[i] = new WearableCacheItem(){CacheId = appear.WearableData[i].CacheID,TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex)};
6322
6323
6216 6324
6217 handlerSetAppearance(sender, te, visualparams); 6325 handlerSetAppearance(sender, te, visualparams,avSize, cacheitems);
6218 } 6326 }
6219 catch (Exception e) 6327 catch (Exception e)
6220 { 6328 {
@@ -6423,6 +6531,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6423 { 6531 {
6424 handlerCompleteMovementToRegion(sender, true); 6532 handlerCompleteMovementToRegion(sender, true);
6425 } 6533 }
6534 else
6535 m_log.Debug("HandleCompleteAgentMovement NULL handler");
6536
6426 handlerCompleteMovementToRegion = null; 6537 handlerCompleteMovementToRegion = null;
6427 6538
6428 return true; 6539 return true;
@@ -6440,7 +6551,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6440 return true; 6551 return true;
6441 } 6552 }
6442 #endregion 6553 #endregion
6443 6554/*
6444 StartAnim handlerStartAnim = null; 6555 StartAnim handlerStartAnim = null;
6445 StopAnim handlerStopAnim = null; 6556 StopAnim handlerStopAnim = null;
6446 6557
@@ -6464,6 +6575,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6464 } 6575 }
6465 } 6576 }
6466 return true; 6577 return true;
6578*/
6579 ChangeAnim handlerChangeAnim = null;
6580
6581 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6582 {
6583 handlerChangeAnim = OnChangeAnim;
6584 if (handlerChangeAnim != null)
6585 {
6586 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6587 }
6588 }
6589
6590 handlerChangeAnim = OnChangeAnim;
6591 if (handlerChangeAnim != null)
6592 {
6593 handlerChangeAnim(UUID.Zero, false, true);
6594 }
6595
6596 return true;
6467 } 6597 }
6468 6598
6469 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6599 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -6689,6 +6819,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6689 #endregion 6819 #endregion
6690 6820
6691 m_udpClient.SetThrottles(atpack.Throttle.Throttles); 6821 m_udpClient.SetThrottles(atpack.Throttle.Throttles);
6822 GenericCall2 handler = OnUpdateThrottles;
6823 if (handler != null)
6824 {
6825 handler();
6826 }
6692 return true; 6827 return true;
6693 } 6828 }
6694 6829
@@ -7113,7 +7248,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7113 physdata.Bounce = phsblock.Restitution; 7248 physdata.Bounce = phsblock.Restitution;
7114 physdata.Density = phsblock.Density; 7249 physdata.Density = phsblock.Density;
7115 physdata.Friction = phsblock.Friction; 7250 physdata.Friction = phsblock.Friction;
7116 physdata.GravitationModifier = phsblock.GravityMultiplier; 7251 physdata.GravitationModifier = phsblock.GravityMultiplier;
7117 } 7252 }
7118 7253
7119 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this); 7254 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
@@ -7699,6 +7834,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7699 // surrounding scene 7834 // surrounding scene
7700 if ((ImageType)block.Type == ImageType.Baked) 7835 if ((ImageType)block.Type == ImageType.Baked)
7701 args.Priority *= 2.0f; 7836 args.Priority *= 2.0f;
7837 int wearableout = 0;
7702 7838
7703 ImageManager.EnqueueReq(args); 7839 ImageManager.EnqueueReq(args);
7704 } 7840 }
@@ -8717,16 +8853,61 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8717 8853
8718 #region Parcel related packets 8854 #region Parcel related packets
8719 8855
8856 // acumulate several HandleRegionHandleRequest consecutive overlaping requests
8857 // to be done with minimal resources as possible
8858 // variables temporary here while in test
8859
8860 Queue<UUID> RegionHandleRequests = new Queue<UUID>();
8861 bool RegionHandleRequestsInService = false;
8862
8720 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack) 8863 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack)
8721 { 8864 {
8722 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; 8865 UUID currentUUID;
8723 8866
8724 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; 8867 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest;
8725 if (handlerRegionHandleRequest != null) 8868
8869 if (handlerRegionHandleRequest == null)
8870 return true;
8871
8872 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
8873
8874 lock (RegionHandleRequests)
8726 { 8875 {
8727 handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); 8876 if (RegionHandleRequestsInService)
8877 {
8878 // we are already busy doing a previus request
8879 // so enqueue it
8880 RegionHandleRequests.Enqueue(rhrPack.RequestBlock.RegionID);
8881 return true;
8882 }
8883
8884 // else do it
8885 currentUUID = rhrPack.RequestBlock.RegionID;
8886 RegionHandleRequestsInService = true;
8728 } 8887 }
8729 return true; 8888
8889 while (true)
8890 {
8891 handlerRegionHandleRequest(this, currentUUID);
8892
8893 lock (RegionHandleRequests)
8894 {
8895 // exit condition, nothing to do or closed
8896 // current code seems to assume we may loose the handler at anytime,
8897 // so keep checking it
8898 handlerRegionHandleRequest = OnRegionHandleRequest;
8899
8900 if (RegionHandleRequests.Count == 0 || !IsActive || handlerRegionHandleRequest == null)
8901 {
8902 RegionHandleRequests.Clear();
8903 RegionHandleRequestsInService = false;
8904 return true;
8905 }
8906 currentUUID = RegionHandleRequests.Dequeue();
8907 }
8908 }
8909
8910 return true; // actually unreached
8730 } 8911 }
8731 8912
8732 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack) 8913 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack)
@@ -9982,7 +10163,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9982 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 10163 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9983 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 10164 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9984 UpdateMuteListEntry.MuteData.MuteType, 10165 UpdateMuteListEntry.MuteData.MuteType,
9985 UpdateMuteListEntry.AgentData.AgentID); 10166 UpdateMuteListEntry.MuteData.MuteFlags);
9986 return true; 10167 return true;
9987 } 10168 }
9988 return false; 10169 return false;
@@ -9997,8 +10178,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9997 { 10178 {
9998 handlerRemoveMuteListEntry(this, 10179 handlerRemoveMuteListEntry(this,
9999 RemoveMuteListEntry.MuteData.MuteID, 10180 RemoveMuteListEntry.MuteData.MuteID,
10000 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 10181 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
10001 RemoveMuteListEntry.AgentData.AgentID);
10002 return true; 10182 return true;
10003 } 10183 }
10004 return false; 10184 return false;
@@ -10042,10 +10222,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10042 return false; 10222 return false;
10043 } 10223 }
10044 10224
10225 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10226 {
10227 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10228 (ChangeInventoryItemFlagsPacket)packet;
10229 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10230 if (handlerChangeInventoryItemFlags != null)
10231 {
10232 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10233 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10234 return true;
10235 }
10236 return false;
10237 }
10238
10045 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10239 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
10046 { 10240 {
10047 return true; 10241 return true;
10048 } 10242 }
10243
10244 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10245 {
10246 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10247
10248 #region Packet Session and User Check
10249 if (m_checkPackets)
10250 {
10251 if (packet.AgentData.SessionID != SessionId ||
10252 packet.AgentData.AgentID != AgentId)
10253 return true;
10254 }
10255 #endregion
10256 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10257 List<InventoryItemBase> items = new List<InventoryItemBase>();
10258 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10259 {
10260 InventoryItemBase b = new InventoryItemBase();
10261 b.ID = n.OldItemID;
10262 b.Folder = n.OldFolderID;
10263 items.Add(b);
10264 }
10265
10266 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10267 if (handlerMoveItemsAndLeaveCopy != null)
10268 {
10269 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10270 }
10271
10272 return true;
10273 }
10049 10274
10050 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10275 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
10051 { 10276 {
@@ -10472,6 +10697,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10472 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10697 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10473 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10698 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10474 10699
10700 Scene scene = (Scene)m_scene;
10701 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10702 {
10703 ScenePresence p;
10704 if (scene.TryGetScenePresence(sender.AgentId, out p))
10705 {
10706 if (p.GodLevel >= 200)
10707 {
10708 groupProfileReply.GroupData.OpenEnrollment = true;
10709 groupProfileReply.GroupData.MembershipFee = 0;
10710 }
10711 }
10712 }
10713
10475 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10714 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10476 } 10715 }
10477 return true; 10716 return true;
@@ -11045,11 +11284,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11045 11284
11046 StartLure handlerStartLure = OnStartLure; 11285 StartLure handlerStartLure = OnStartLure;
11047 if (handlerStartLure != null) 11286 if (handlerStartLure != null)
11048 handlerStartLure(startLureRequest.Info.LureType, 11287 {
11049 Utils.BytesToString( 11288 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
11050 startLureRequest.Info.Message), 11289 {
11051 startLureRequest.TargetData[0].TargetID, 11290 handlerStartLure(startLureRequest.Info.LureType,
11052 this); 11291 Utils.BytesToString(
11292 startLureRequest.Info.Message),
11293 startLureRequest.TargetData[i].TargetID,
11294 this);
11295 }
11296 }
11053 return true; 11297 return true;
11054 } 11298 }
11055 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11299 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -11163,10 +11407,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11163 } 11407 }
11164 #endregion 11408 #endregion
11165 11409
11166 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11410 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11167 if (handlerClassifiedGodDelete != null) 11411 if (handlerClassifiedGodDelete != null)
11168 handlerClassifiedGodDelete( 11412 handlerClassifiedGodDelete(
11169 classifiedGodDelete.Data.ClassifiedID, 11413 classifiedGodDelete.Data.ClassifiedID,
11414 classifiedGodDelete.Data.QueryID,
11170 this); 11415 this);
11171 return true; 11416 return true;
11172 } 11417 }
@@ -11479,6 +11724,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11479 11724
11480 if (cachedtex.AgentData.SessionID != SessionId) 11725 if (cachedtex.AgentData.SessionID != SessionId)
11481 return false; 11726 return false;
11727
11482 11728
11483 // TODO: don't create new blocks if recycling an old packet 11729 // TODO: don't create new blocks if recycling an old packet
11484 cachedresp.AgentData.AgentID = AgentId; 11730 cachedresp.AgentData.AgentID = AgentId;
@@ -11488,14 +11734,140 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11488 cachedresp.WearableData = 11734 cachedresp.WearableData =
11489 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length]; 11735 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
11490 11736
11491 for (int i = 0; i < cachedtex.WearableData.Length; i++) 11737 //IAvatarFactoryModule fac = m_scene.RequestModuleInterface<IAvatarFactoryModule>();
11738 // var item = fac.GetBakedTextureFaces(AgentId);
11739 //WearableCacheItem[] items = fac.GetCachedItems(AgentId);
11740
11741 IAssetService cache = m_scene.AssetService;
11742 IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
11743 //bakedTextureModule = null;
11744 int maxWearablesLoop = cachedtex.WearableData.Length;
11745 if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES)
11746 maxWearablesLoop = AvatarWearable.MAX_WEARABLES;
11747
11748 if (bakedTextureModule != null && cache != null)
11492 { 11749 {
11493 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); 11750 // 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
11494 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; 11751
11495 cachedresp.WearableData[i].TextureID = UUID.Zero; 11752 WearableCacheItem[] cacheItems = null;
11496 cachedresp.WearableData[i].HostName = new byte[0]; 11753 ScenePresence p = m_scene.GetScenePresence(AgentId);
11754 if (p.Appearance != null)
11755 if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty)
11756 {
11757 try
11758 {
11759 cacheItems = bakedTextureModule.Get(AgentId);
11760 p.Appearance.WearableCacheItems = cacheItems;
11761 p.Appearance.WearableCacheItemsDirty = false;
11762 }
11763
11764 /*
11765 * The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception!
11766 *
11767 catch (System.Net.Sockets.SocketException)
11768 {
11769 cacheItems = null;
11770 }
11771 catch (WebException)
11772 {
11773 cacheItems = null;
11774 }
11775 catch (InvalidOperationException)
11776 {
11777 cacheItems = null;
11778 } */
11779 catch (Exception)
11780 {
11781 cacheItems = null;
11782 }
11783
11784 }
11785 else if (p.Appearance.WearableCacheItems != null)
11786 {
11787 cacheItems = p.Appearance.WearableCacheItems;
11788 }
11789
11790 if (cache != null && cacheItems != null)
11791 {
11792 foreach (WearableCacheItem item in cacheItems)
11793 {
11794
11795 if (cache.GetCached(item.TextureID.ToString()) == null)
11796 {
11797 item.TextureAsset.Temporary = true;
11798 cache.Store(item.TextureAsset);
11799 }
11800
11801
11802 }
11803 }
11804
11805 if (cacheItems != null)
11806 {
11807
11808 for (int i = 0; i < maxWearablesLoop; i++)
11809 {
11810 WearableCacheItem item =
11811 WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems);
11812
11813 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11814 cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex;
11815 cachedresp.WearableData[i].HostName = new byte[0];
11816 if (item != null && cachedtex.WearableData[i].ID == item.CacheId)
11817 {
11818
11819 cachedresp.WearableData[i].TextureID = item.TextureID;
11820 }
11821 else
11822 {
11823 cachedresp.WearableData[i].TextureID = UUID.Zero;
11824 }
11825 }
11826 }
11827 else
11828 {
11829 for (int i = 0; i < maxWearablesLoop; i++)
11830 {
11831 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11832 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11833 cachedresp.WearableData[i].TextureID = UUID.Zero;
11834 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11835 cachedresp.WearableData[i].HostName = new byte[0];
11836 }
11837 }
11497 } 11838 }
11839 else
11840 {
11841 if (cache == null)
11842 {
11843 for (int i = 0; i < maxWearablesLoop; i++)
11844 {
11845 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11846 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11847 cachedresp.WearableData[i].TextureID = UUID.Zero;
11848 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11849 cachedresp.WearableData[i].HostName = new byte[0];
11850 }
11851 }
11852 else
11853 {
11854 for (int i = 0; i < maxWearablesLoop; i++)
11855 {
11856 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11857 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11858
11498 11859
11860
11861 if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null)
11862 cachedresp.WearableData[i].TextureID = UUID.Zero;
11863 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11864 else
11865 cachedresp.WearableData[i].TextureID = UUID.Zero;
11866 // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11867 cachedresp.WearableData[i].HostName = new byte[0];
11868 }
11869 }
11870 }
11499 cachedresp.Header.Zerocoded = true; 11871 cachedresp.Header.Zerocoded = true;
11500 OutPacket(cachedresp, ThrottleOutPacketType.Task); 11872 OutPacket(cachedresp, ThrottleOutPacketType.Task);
11501 11873
@@ -11532,209 +11904,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11532 } 11904 }
11533 else 11905 else
11534 { 11906 {
11535// m_log.DebugFormat( 11907 ClientChangeObject updatehandler = onClientChangeObject;
11536// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11537// i, block.Type, part.Name, part.LocalId);
11538 11908
11539// // Do this once since fetch parts creates a new array. 11909 if (updatehandler != null)
11540// SceneObjectPart[] parts = part.ParentGroup.Parts; 11910 {
11541// for (int j = 0; j < parts.Length; j++) 11911 ObjectChangeData udata = new ObjectChangeData();
11542// {
11543// part.StoreUndoState();
11544// parts[j].IgnoreUndoUpdate = true;
11545// }
11546 11912
11547 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11913 /*ubit from ll JIRA:
11914 * 0x01 position
11915 * 0x02 rotation
11916 * 0x04 scale
11917
11918 * 0x08 LINK_SET
11919 * 0x10 UNIFORM for scale
11920 */
11548 11921
11549 switch (block.Type) 11922 // translate to internal changes
11550 { 11923 // not all cases .. just the ones older code did
11551 case 1:
11552 Vector3 pos1 = new Vector3(block.Data, 0);
11553 11924
11554 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11925 switch (block.Type)
11555 if (handlerUpdatePrimSinglePosition != null) 11926 {
11556 { 11927 case 1: //change position sp
11557 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11928 udata.position = new Vector3(block.Data, 0);
11558 handlerUpdatePrimSinglePosition(localId, pos1, this);
11559 }
11560 break;
11561 11929
11562 case 2: 11930 udata.change = ObjectChangeType.primP;
11563 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11931 updatehandler(localId, udata, this);
11932 break;
11564 11933
11565 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11934 case 2: // rotation sp
11566 if (handlerUpdatePrimSingleRotation != null) 11935 udata.rotation = new Quaternion(block.Data, 0, true);
11567 {
11568 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11569 handlerUpdatePrimSingleRotation(localId, rot1, this);
11570 }
11571 break;
11572 11936
11573 case 3: 11937 udata.change = ObjectChangeType.primR;
11574 Vector3 rotPos = new Vector3(block.Data, 0); 11938 updatehandler(localId, udata, this);
11575 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11939 break;
11576 11940
11577 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11941 case 3: // position plus rotation
11578 if (handlerUpdatePrimSingleRotationPosition != null) 11942 udata.position = new Vector3(block.Data, 0);
11579 { 11943 udata.rotation = new Quaternion(block.Data, 12, true);
11580 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11581 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11582 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11583 }
11584 break;
11585 11944
11586 case 4: 11945 udata.change = ObjectChangeType.primPR;
11587 case 20: 11946 updatehandler(localId, udata, this);
11588 Vector3 scale4 = new Vector3(block.Data, 0); 11947 break;
11589 11948
11590 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11949 case 4: // scale sp
11591 if (handlerUpdatePrimScale != null) 11950 udata.scale = new Vector3(block.Data, 0);
11592 { 11951 udata.change = ObjectChangeType.primS;
11593 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11594 handlerUpdatePrimScale(localId, scale4, this);
11595 }
11596 break;
11597 11952
11598 case 5: 11953 updatehandler(localId, udata, this);
11599 Vector3 scale1 = new Vector3(block.Data, 12); 11954 break;
11600 Vector3 pos11 = new Vector3(block.Data, 0);
11601 11955
11602 handlerUpdatePrimScale = OnUpdatePrimScale; 11956 case 0x14: // uniform scale sp
11603 if (handlerUpdatePrimScale != null) 11957 udata.scale = new Vector3(block.Data, 0);
11604 {
11605 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11606 handlerUpdatePrimScale(localId, scale1, this);
11607 11958
11608 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11959 udata.change = ObjectChangeType.primUS;
11609 if (handlerUpdatePrimSinglePosition != null) 11960 updatehandler(localId, udata, this);
11610 { 11961 break;
11611 handlerUpdatePrimSinglePosition(localId, pos11, this);
11612 }
11613 }
11614 break;
11615 11962
11616 case 9: 11963 case 5: // scale and position sp
11617 Vector3 pos2 = new Vector3(block.Data, 0); 11964 udata.position = new Vector3(block.Data, 0);
11965 udata.scale = new Vector3(block.Data, 12);
11618 11966
11619 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11967 udata.change = ObjectChangeType.primPS;
11968 updatehandler(localId, udata, this);
11969 break;
11620 11970
11621 if (handlerUpdateVector != null) 11971 case 0x15: //uniform scale and position
11622 { 11972 udata.position = new Vector3(block.Data, 0);
11623 handlerUpdateVector(localId, pos2, this); 11973 udata.scale = new Vector3(block.Data, 12);
11624 }
11625 break;
11626 11974
11627 case 10: 11975 udata.change = ObjectChangeType.primPUS;
11628 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11976 updatehandler(localId, udata, this);
11977 break;
11629 11978
11630 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11979 // now group related (bit 4)
11631 if (handlerUpdatePrimRotation != null) 11980 case 9: //( 8 + 1 )group position
11632 { 11981 udata.position = new Vector3(block.Data, 0);
11633 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11634 handlerUpdatePrimRotation(localId, rot3, this);
11635 }
11636 break;
11637 11982
11638 case 11: 11983 udata.change = ObjectChangeType.groupP;
11639 Vector3 pos3 = new Vector3(block.Data, 0); 11984 updatehandler(localId, udata, this);
11640 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11985 break;
11641 11986
11642 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11987 case 0x0A: // (8 + 2) group rotation
11643 if (handlerUpdatePrimGroupRotation != null) 11988 udata.rotation = new Quaternion(block.Data, 0, true);
11644 {
11645 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11646 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11647 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11648 }
11649 break;
11650 case 12:
11651 case 28:
11652 Vector3 scale7 = new Vector3(block.Data, 0);
11653 11989
11654 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11990 udata.change = ObjectChangeType.groupR;
11655 if (handlerUpdatePrimGroupScale != null) 11991 updatehandler(localId, udata, this);
11656 { 11992 break;
11657 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11658 handlerUpdatePrimGroupScale(localId, scale7, this);
11659 }
11660 break;
11661 11993
11662 case 13: 11994 case 0x0B: //( 8 + 2 + 1) group rotation and position
11663 Vector3 scale2 = new Vector3(block.Data, 12); 11995 udata.position = new Vector3(block.Data, 0);
11664 Vector3 pos4 = new Vector3(block.Data, 0); 11996 udata.rotation = new Quaternion(block.Data, 12, true);
11665 11997
11666 handlerUpdatePrimScale = OnUpdatePrimScale; 11998 udata.change = ObjectChangeType.groupPR;
11667 if (handlerUpdatePrimScale != null) 11999 updatehandler(localId, udata, this);
11668 { 12000 break;
11669 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11670 handlerUpdatePrimScale(localId, scale2, this);
11671 12001
11672 // Change the position based on scale (for bug number 246) 12002 case 0x0C: // (8 + 4) group scale
11673 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12003 // only afects root prim and only sent by viewer editor object tab scaling
11674 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 12004 // mouse edition only allows uniform scaling
11675 if (handlerUpdatePrimSinglePosition != null) 12005 // SL MAY CHANGE THIS in viewers
11676 {
11677 handlerUpdatePrimSinglePosition(localId, pos4, this);
11678 }
11679 }
11680 break;
11681 12006
11682 case 29: 12007 udata.scale = new Vector3(block.Data, 0);
11683 Vector3 scale5 = new Vector3(block.Data, 12);
11684 Vector3 pos5 = new Vector3(block.Data, 0);
11685 12008
11686 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 12009 udata.change = ObjectChangeType.groupS;
11687 if (handlerUpdatePrimGroupScale != null) 12010 updatehandler(localId, udata, this);
11688 {
11689 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11690 part.StoreUndoState(true);
11691 part.IgnoreUndoUpdate = true;
11692 handlerUpdatePrimGroupScale(localId, scale5, this);
11693 handlerUpdateVector = OnUpdatePrimGroupPosition;
11694 12011
11695 if (handlerUpdateVector != null) 12012 break;
11696 {
11697 handlerUpdateVector(localId, pos5, this);
11698 }
11699 12013
11700 part.IgnoreUndoUpdate = false; 12014 case 0x0D: //(8 + 4 + 1) group scale and position
11701 } 12015 // exception as above
11702 12016
11703 break; 12017 udata.position = new Vector3(block.Data, 0);
12018 udata.scale = new Vector3(block.Data, 12);
11704 12019
11705 case 21: 12020 udata.change = ObjectChangeType.groupPS;
11706 Vector3 scale6 = new Vector3(block.Data, 12); 12021 updatehandler(localId, udata, this);
11707 Vector3 pos6 = new Vector3(block.Data, 0); 12022 break;
11708 12023
11709 handlerUpdatePrimScale = OnUpdatePrimScale; 12024 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11710 if (handlerUpdatePrimScale != null) 12025 udata.scale = new Vector3(block.Data, 0);
11711 {
11712 part.StoreUndoState(false);
11713 part.IgnoreUndoUpdate = true;
11714 12026
11715 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 12027 udata.change = ObjectChangeType.groupUS;
11716 handlerUpdatePrimScale(localId, scale6, this); 12028 updatehandler(localId, udata, this);
11717 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12029 break;
11718 if (handlerUpdatePrimSinglePosition != null)
11719 {
11720 handlerUpdatePrimSinglePosition(localId, pos6, this);
11721 }
11722 12030
11723 part.IgnoreUndoUpdate = false; 12031 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11724 } 12032 udata.position = new Vector3(block.Data, 0);
11725 break; 12033 udata.scale = new Vector3(block.Data, 12);
11726 12034
11727 default: 12035 udata.change = ObjectChangeType.groupPUS;
11728 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 12036 updatehandler(localId, udata, this);
11729 break; 12037 break;
12038
12039 default:
12040 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
12041 break;
12042 }
11730 } 12043 }
11731 12044
11732// for (int j = 0; j < parts.Length; j++)
11733// parts[j].IgnoreUndoUpdate = false;
11734 } 12045 }
11735 } 12046 }
11736 } 12047 }
11737
11738 return true; 12048 return true;
11739 } 12049 }
11740 12050
@@ -11795,9 +12105,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11795 public void SetChildAgentThrottle(byte[] throttles) 12105 public void SetChildAgentThrottle(byte[] throttles)
11796 { 12106 {
11797 m_udpClient.SetThrottles(throttles); 12107 m_udpClient.SetThrottles(throttles);
12108 GenericCall2 handler = OnUpdateThrottles;
12109 if (handler != null)
12110 {
12111 handler();
12112 }
11798 } 12113 }
11799 12114
11800 /// <summary> 12115 /// <summary>
12116 /// Sets the throttles from values supplied by the client
12117 /// </summary>
12118 /// <param name="throttles"></param>
12119 public void SetAgentThrottleSilent(int throttle, int setting)
12120 {
12121 m_udpClient.ForceThrottleSetting(throttle,setting);
12122 //m_udpClient.SetThrottles(throttles);
12123
12124 }
12125
12126
12127 /// <summary>
11801 /// Get the current throttles for this client as a packed byte array 12128 /// Get the current throttles for this client as a packed byte array
11802 /// </summary> 12129 /// </summary>
11803 /// <param name="multiplier">Unused</param> 12130 /// <param name="multiplier">Unused</param>
@@ -12189,7 +12516,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12189// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12516// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12190// requestID, taskID, (SourceType)sourceType, Name); 12517// requestID, taskID, (SourceType)sourceType, Name);
12191 12518
12519
12520 //Note, the bool returned from the below function is useless since it is always false.
12192 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12521 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12522
12193 } 12523 }
12194 12524
12195 /// <summary> 12525 /// <summary>
@@ -12255,7 +12585,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12255 /// <returns></returns> 12585 /// <returns></returns>
12256 private static int CalculateNumPackets(byte[] data) 12586 private static int CalculateNumPackets(byte[] data)
12257 { 12587 {
12258 const uint m_maxPacketSize = 600; 12588// const uint m_maxPacketSize = 600;
12589 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12259 int numPackets = 1; 12590 int numPackets = 1;
12260 12591
12261 if (data == null) 12592 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,