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.cs1506
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs115
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs122
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs4
5 files changed, 1119 insertions, 631 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
index a168bfe..dfc4419 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 9784d15..45c901e 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -101,6 +101,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
101 public event AvatarPickerRequest OnAvatarPickerRequest; 101 public event AvatarPickerRequest OnAvatarPickerRequest;
102 public event StartAnim OnStartAnim; 102 public event StartAnim OnStartAnim;
103 public event StopAnim OnStopAnim; 103 public event StopAnim OnStopAnim;
104 public event ChangeAnim OnChangeAnim;
104 public event Action<IClientAPI> OnRequestAvatarsData; 105 public event Action<IClientAPI> OnRequestAvatarsData;
105 public event LinkObjects OnLinkObjects; 106 public event LinkObjects OnLinkObjects;
106 public event DelinkObjects OnDelinkObjects; 107 public event DelinkObjects OnDelinkObjects;
@@ -128,6 +129,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
128 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; 129 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
129 public event UpdatePrimFlags OnUpdatePrimFlags; 130 public event UpdatePrimFlags OnUpdatePrimFlags;
130 public event UpdatePrimTexture OnUpdatePrimTexture; 131 public event UpdatePrimTexture OnUpdatePrimTexture;
132 public event ClientChangeObject onClientChangeObject;
131 public event UpdateVector OnUpdatePrimGroupPosition; 133 public event UpdateVector OnUpdatePrimGroupPosition;
132 public event UpdateVector OnUpdatePrimSinglePosition; 134 public event UpdateVector OnUpdatePrimSinglePosition;
133 public event UpdatePrimRotation OnUpdatePrimGroupRotation; 135 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
@@ -161,6 +163,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
161 public event RequestTaskInventory OnRequestTaskInventory; 163 public event RequestTaskInventory OnRequestTaskInventory;
162 public event UpdateInventoryItem OnUpdateInventoryItem; 164 public event UpdateInventoryItem OnUpdateInventoryItem;
163 public event CopyInventoryItem OnCopyInventoryItem; 165 public event CopyInventoryItem OnCopyInventoryItem;
166 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
164 public event MoveInventoryItem OnMoveInventoryItem; 167 public event MoveInventoryItem OnMoveInventoryItem;
165 public event RemoveInventoryItem OnRemoveInventoryItem; 168 public event RemoveInventoryItem OnRemoveInventoryItem;
166 public event RemoveInventoryFolder OnRemoveInventoryFolder; 169 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -259,7 +262,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
259 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 262 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
260 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 263 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
261 public event ClassifiedDelete OnClassifiedDelete; 264 public event ClassifiedDelete OnClassifiedDelete;
262 public event ClassifiedDelete OnClassifiedGodDelete; 265 public event ClassifiedGodDelete OnClassifiedGodDelete;
263 public event EventNotificationAddRequest OnEventNotificationAddRequest; 266 public event EventNotificationAddRequest OnEventNotificationAddRequest;
264 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 267 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
265 public event EventGodDelete OnEventGodDelete; 268 public event EventGodDelete OnEventGodDelete;
@@ -290,10 +293,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
290 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; 293 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
291 public event SimWideDeletesDelegate OnSimWideDeletes; 294 public event SimWideDeletesDelegate OnSimWideDeletes;
292 public event SendPostcard OnSendPostcard; 295 public event SendPostcard OnSendPostcard;
296 public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
293 public event MuteListEntryUpdate OnUpdateMuteListEntry; 297 public event MuteListEntryUpdate OnUpdateMuteListEntry;
294 public event MuteListEntryRemove OnRemoveMuteListEntry; 298 public event MuteListEntryRemove OnRemoveMuteListEntry;
295 public event GodlikeMessage onGodlikeMessage; 299 public event GodlikeMessage onGodlikeMessage;
296 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate; 300 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
301 public event GenericCall2 OnUpdateThrottles;
297 302
298 #endregion Events 303 #endregion Events
299 304
@@ -322,11 +327,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
322 private readonly byte[] m_channelVersion = Utils.EmptyBytes; 327 private readonly byte[] m_channelVersion = Utils.EmptyBytes;
323 private readonly IGroupsModule m_GroupsModule; 328 private readonly IGroupsModule m_GroupsModule;
324 329
330 private int m_cachedTextureSerial;
325 private PriorityQueue m_entityUpdates; 331 private PriorityQueue m_entityUpdates;
326 private PriorityQueue m_entityProps; 332 private PriorityQueue m_entityProps;
327 private Prioritizer m_prioritizer; 333 private Prioritizer m_prioritizer;
328 private bool m_disableFacelights = false; 334 private bool m_disableFacelights = false;
329 335
336 private bool m_VelocityInterpolate = false;
337 private const uint MaxTransferBytesPerPacket = 600;
338
339
330 /// <value> 340 /// <value>
331 /// List used in construction of data blocks for an object update packet. This is to stop us having to 341 /// List used in construction of data blocks for an object update packet. This is to stop us having to
332 /// continually recreate it. 342 /// continually recreate it.
@@ -338,13 +348,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
338 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 348 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
339 /// ownerless phantom. 349 /// ownerless phantom.
340 /// 350 ///
341 /// All manipulation of this set has to occur under a lock 351 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
342 /// 352 ///
343 /// </value> 353 /// </value>
344 protected HashSet<uint> m_killRecord; 354// protected HashSet<uint> m_killRecord;
345 355
346// protected HashSet<uint> m_attachmentsSent; 356// protected HashSet<uint> m_attachmentsSent;
347 357
358 private bool m_deliverPackets = true;
348 private int m_animationSequenceNumber = 1; 359 private int m_animationSequenceNumber = 1;
349 private bool m_SendLogoutPacketWhenClosing = true; 360 private bool m_SendLogoutPacketWhenClosing = true;
350 361
@@ -391,6 +402,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
391 get { return m_startpos; } 402 get { return m_startpos; }
392 set { m_startpos = value; } 403 set { m_startpos = value; }
393 } 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 }
394 public UUID AgentId { get { return m_agentId; } } 413 public UUID AgentId { get { return m_agentId; } }
395 public ISceneAgent SceneAgent { get; set; } 414 public ISceneAgent SceneAgent { get; set; }
396 public UUID ActiveGroupId { get { return m_activeGroupID; } } 415 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -441,6 +460,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
441 } 460 }
442 461
443 public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } } 462 public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } }
463
444 464
445 #endregion Properties 465 #endregion Properties
446 466
@@ -467,7 +487,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
467 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 487 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
468 m_entityProps = new PriorityQueue(m_scene.Entities.Count); 488 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
469 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 489 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
470 m_killRecord = new HashSet<uint>(); 490// m_killRecord = new HashSet<uint>();
471// m_attachmentsSent = new HashSet<uint>(); 491// m_attachmentsSent = new HashSet<uint>();
472 492
473 m_assetService = m_scene.RequestModuleInterface<IAssetService>(); 493 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
@@ -496,12 +516,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
496 516
497 #region Client Methods 517 #region Client Methods
498 518
519
520 /// <summary>
521 /// Close down the client view
522 /// </summary>
499 public void Close() 523 public void Close()
500 { 524 {
501 Close(false); 525 Close(true, false);
502 } 526 }
503 527
504 public void Close(bool force) 528 public void Close(bool sendStop, bool force)
505 { 529 {
506 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. 530 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
507 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. 531 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
@@ -513,7 +537,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
513 return; 537 return;
514 538
515 IsActive = false; 539 IsActive = false;
516 CloseWithoutChecks(); 540 CloseWithoutChecks(sendStop);
517 } 541 }
518 } 542 }
519 543
@@ -526,12 +550,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
526 /// 550 ///
527 /// Callers must lock ClosingSyncLock before calling. 551 /// Callers must lock ClosingSyncLock before calling.
528 /// </remarks> 552 /// </remarks>
529 public void CloseWithoutChecks() 553 public void CloseWithoutChecks(bool sendStop)
530 { 554 {
531 m_log.DebugFormat( 555 m_log.DebugFormat(
532 "[CLIENT]: Close has been called for {0} attached to scene {1}", 556 "[CLIENT]: Close has been called for {0} attached to scene {1}",
533 Name, m_scene.RegionInfo.RegionName); 557 Name, m_scene.RegionInfo.RegionName);
534 558
559 if (sendStop)
560 {
561 // Send the STOP packet
562 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
563 OutPacket(disable, ThrottleOutPacketType.Unknown);
564 }
565
535 // Shutdown the image manager 566 // Shutdown the image manager
536 ImageManager.Close(); 567 ImageManager.Close();
537 568
@@ -554,6 +585,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
554 // Disable UDP handling for this client 585 // Disable UDP handling for this client
555 m_udpClient.Shutdown(); 586 m_udpClient.Shutdown();
556 587
588
557 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 589 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false));
558 //GC.Collect(); 590 //GC.Collect();
559 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true)); 591 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true));
@@ -794,7 +826,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
794 handshake.RegionInfo4[0].RegionFlagsExtended = args.regionFlags; 826 handshake.RegionInfo4[0].RegionFlagsExtended = args.regionFlags;
795 handshake.RegionInfo4[0].RegionProtocols = 0; // 1 here would indicate that SSB is supported 827 handshake.RegionInfo4[0].RegionProtocols = 0; // 1 here would indicate that SSB is supported
796 828
797 OutPacket(handshake, ThrottleOutPacketType.Task); 829 OutPacket(handshake, ThrottleOutPacketType.Unknown);
798 } 830 }
799 831
800 832
@@ -835,7 +867,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
835 reply.ChatData.OwnerID = ownerID; 867 reply.ChatData.OwnerID = ownerID;
836 reply.ChatData.SourceID = fromAgentID; 868 reply.ChatData.SourceID = fromAgentID;
837 869
838 OutPacket(reply, ThrottleOutPacketType.Task); 870 OutPacket(reply, ThrottleOutPacketType.Unknown);
839 } 871 }
840 872
841 /// <summary> 873 /// <summary>
@@ -868,32 +900,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
868 msg.MessageBlock.Message = Util.StringToBytes1024(im.message); 900 msg.MessageBlock.Message = Util.StringToBytes1024(im.message);
869 msg.MessageBlock.BinaryBucket = im.binaryBucket; 901 msg.MessageBlock.BinaryBucket = im.binaryBucket;
870 902
871 if (im.message.StartsWith("[grouptest]")) 903 OutPacket(msg, ThrottleOutPacketType.Task);
872 { // this block is test code for implementing group IM - delete when group IM is finished
873 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
874 if (eq != null)
875 {
876 im.dialog = 17;
877
878 //eq.ChatterboxInvitation(
879 // new UUID("00000000-68f9-1111-024e-222222111123"),
880 // "OpenSimulator Testing", im.fromAgentID, im.message, im.toAgentID, im.fromAgentName, im.dialog, 0,
881 // false, 0, new Vector3(), 1, im.imSessionID, im.fromGroup, im.binaryBucket);
882
883 eq.ChatterboxInvitation(
884 new UUID("00000000-68f9-1111-024e-222222111123"),
885 "OpenSimulator Testing", new UUID(im.fromAgentID), im.message, new UUID(im.toAgentID), im.fromAgentName, im.dialog, 0,
886 false, 0, new Vector3(), 1, new UUID(im.imSessionID), im.fromGroup, Util.StringToBytes256("OpenSimulator Testing"));
887
888 eq.ChatterBoxSessionAgentListUpdates(
889 new UUID("00000000-68f9-1111-024e-222222111123"),
890 new UUID(im.fromAgentID), new UUID(im.toAgentID), false, false, false);
891 }
892
893 Console.WriteLine("SendInstantMessage: " + msg);
894 }
895 else
896 OutPacket(msg, ThrottleOutPacketType.Task);
897 } 904 }
898 } 905 }
899 906
@@ -1131,6 +1138,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1131 public virtual void SendLayerData(float[] map) 1138 public virtual void SendLayerData(float[] map)
1132 { 1139 {
1133 Util.FireAndForget(DoSendLayerData, map); 1140 Util.FireAndForget(DoSendLayerData, map);
1141
1142 // Send it sync, and async. It's not that much data
1143 // and it improves user experience just so much!
1144 DoSendLayerData(map);
1134 } 1145 }
1135 1146
1136 /// <summary> 1147 /// <summary>
@@ -1143,16 +1154,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1143 1154
1144 try 1155 try
1145 { 1156 {
1146 //for (int y = 0; y < 16; y++) 1157 for (int y = 0; y < 16; y++)
1147 //{ 1158 {
1148 // for (int x = 0; x < 16; x++) 1159 for (int x = 0; x < 16; x+=4)
1149 // { 1160 {
1150 // SendLayerData(x, y, map); 1161 SendLayerPacket(x, y, map);
1151 // } 1162 }
1152 //} 1163 }
1153
1154 // Send LayerData in a spiral pattern. Fun!
1155 SendLayerTopRight(map, 0, 0, 15, 15);
1156 } 1164 }
1157 catch (Exception e) 1165 catch (Exception e)
1158 { 1166 {
@@ -1160,51 +1168,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1160 } 1168 }
1161 } 1169 }
1162 1170
1163 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1164 {
1165 // Row
1166 for (int i = x1; i <= x2; i++)
1167 SendLayerData(i, y1, map);
1168
1169 // Column
1170 for (int j = y1 + 1; j <= y2; j++)
1171 SendLayerData(x2, j, map);
1172
1173 if (x2 - x1 > 0)
1174 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1175 }
1176
1177 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1178 {
1179 // Row in reverse
1180 for (int i = x2; i >= x1; i--)
1181 SendLayerData(i, y2, map);
1182
1183 // Column in reverse
1184 for (int j = y2 - 1; j >= y1; j--)
1185 SendLayerData(x1, j, map);
1186
1187 if (x2 - x1 > 0)
1188 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1189 }
1190
1191 /// <summary> 1171 /// <summary>
1192 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1172 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1193 /// </summary> 1173 /// </summary>
1194 /// <param name="map">heightmap</param> 1174 /// <param name="map">heightmap</param>
1195 /// <param name="px">X coordinate for patches 0..12</param> 1175 /// <param name="px">X coordinate for patches 0..12</param>
1196 /// <param name="py">Y coordinate for patches 0..15</param> 1176 /// <param name="py">Y coordinate for patches 0..15</param>
1197 // private void SendLayerPacket(float[] map, int y, int x) 1177 private void SendLayerPacket(int x, int y, float[] map)
1198 // { 1178 {
1199 // int[] patches = new int[4]; 1179 int[] patches = new int[4];
1200 // patches[0] = x + 0 + y * 16; 1180 patches[0] = x + 0 + y * 16;
1201 // patches[1] = x + 1 + y * 16; 1181 patches[1] = x + 1 + y * 16;
1202 // patches[2] = x + 2 + y * 16; 1182 patches[2] = x + 2 + y * 16;
1203 // patches[3] = x + 3 + y * 16; 1183 patches[3] = x + 3 + y * 16;
1204 1184
1205 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1185 float[] heightmap = (map.Length == 65536) ?
1206 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1186 map :
1207 // } 1187 LLHeightFieldMoronize(map);
1188
1189 try
1190 {
1191 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1192 OutPacket(layerpack, ThrottleOutPacketType.Land);
1193 }
1194 catch
1195 {
1196 for (int px = x ; px < x + 4 ; px++)
1197 SendLayerData(px, y, map);
1198 }
1199 }
1208 1200
1209 /// <summary> 1201 /// <summary>
1210 /// Sends a specified patch to a client 1202 /// Sends a specified patch to a client
@@ -1224,7 +1216,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1224 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1216 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1225 layerpack.Header.Reliable = true; 1217 layerpack.Header.Reliable = true;
1226 1218
1227 OutPacket(layerpack, ThrottleOutPacketType.Land); 1219 OutPacket(layerpack, ThrottleOutPacketType.Task);
1228 } 1220 }
1229 catch (Exception e) 1221 catch (Exception e)
1230 { 1222 {
@@ -1594,7 +1586,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1594 1586
1595 public void SendKillObject(List<uint> localIDs) 1587 public void SendKillObject(List<uint> localIDs)
1596 { 1588 {
1597// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1589// foreach (uint id in localIDs)
1590// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1598 1591
1599 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1592 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1600 // TODO: don't create new blocks if recycling an old packet 1593 // TODO: don't create new blocks if recycling an old packet
@@ -1616,17 +1609,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1616 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race 1609 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
1617 // condition where a kill can be processed before an out-of-date update for the same object. 1610 // condition where a kill can be processed before an out-of-date update for the same object.
1618 // ProcessEntityUpdates() also takes the m_killRecord lock. 1611 // ProcessEntityUpdates() also takes the m_killRecord lock.
1619 lock (m_killRecord) 1612// lock (m_killRecord)
1620 { 1613// {
1621 foreach (uint localID in localIDs) 1614// foreach (uint localID in localIDs)
1622 m_killRecord.Add(localID); 1615// m_killRecord.Add(localID);
1623 1616
1624 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1617 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1625 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1618 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1626 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1619 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1627 // scene objects in a viewer until that viewer is relogged in. 1620 // scene objects in a viewer until that viewer is relogged in.
1628 OutPacket(kill, ThrottleOutPacketType.Task); 1621 OutPacket(kill, ThrottleOutPacketType.Task);
1629 } 1622// }
1630 } 1623 }
1631 } 1624 }
1632 1625
@@ -1748,7 +1741,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1748 newBlock.CreationDate = item.CreationDate; 1741 newBlock.CreationDate = item.CreationDate;
1749 newBlock.SalePrice = item.SalePrice; 1742 newBlock.SalePrice = item.SalePrice;
1750 newBlock.SaleType = item.SaleType; 1743 newBlock.SaleType = item.SaleType;
1751 newBlock.Flags = item.Flags; 1744 newBlock.Flags = item.Flags & 0xff;
1752 1745
1753 newBlock.CRC = 1746 newBlock.CRC =
1754 Helpers.InventoryCRC(newBlock.CreationDate, newBlock.SaleType, 1747 Helpers.InventoryCRC(newBlock.CreationDate, newBlock.SaleType,
@@ -2002,7 +1995,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2002 itemBlock.GroupID = item.GroupID; 1995 itemBlock.GroupID = item.GroupID;
2003 itemBlock.GroupOwned = item.GroupOwned; 1996 itemBlock.GroupOwned = item.GroupOwned;
2004 itemBlock.GroupMask = item.GroupPermissions; 1997 itemBlock.GroupMask = item.GroupPermissions;
2005 itemBlock.Flags = item.Flags; 1998 itemBlock.Flags = item.Flags & 0xff;
2006 itemBlock.SalePrice = item.SalePrice; 1999 itemBlock.SalePrice = item.SalePrice;
2007 itemBlock.SaleType = item.SaleType; 2000 itemBlock.SaleType = item.SaleType;
2008 itemBlock.CreationDate = item.CreationDate; 2001 itemBlock.CreationDate = item.CreationDate;
@@ -2069,7 +2062,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2069 bulkUpdate.ItemData[0].GroupID = item.GroupID; 2062 bulkUpdate.ItemData[0].GroupID = item.GroupID;
2070 bulkUpdate.ItemData[0].GroupOwned = item.GroupOwned; 2063 bulkUpdate.ItemData[0].GroupOwned = item.GroupOwned;
2071 bulkUpdate.ItemData[0].GroupMask = item.GroupPermissions; 2064 bulkUpdate.ItemData[0].GroupMask = item.GroupPermissions;
2072 bulkUpdate.ItemData[0].Flags = item.Flags; 2065 bulkUpdate.ItemData[0].Flags = item.Flags & 0xff;
2073 bulkUpdate.ItemData[0].SalePrice = item.SalePrice; 2066 bulkUpdate.ItemData[0].SalePrice = item.SalePrice;
2074 bulkUpdate.ItemData[0].SaleType = item.SaleType; 2067 bulkUpdate.ItemData[0].SaleType = item.SaleType;
2075 2068
@@ -2085,9 +2078,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2085 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); 2078 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
2086 } 2079 }
2087 2080
2088 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2089 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId) 2081 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
2090 { 2082 {
2083 SendInventoryItemCreateUpdate(Item, UUID.Zero, callbackId);
2084 }
2085
2086 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2087 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId)
2088 {
2091 const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff; 2089 const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff;
2092 2090
2093 UpdateCreateInventoryItemPacket InventoryReply 2091 UpdateCreateInventoryItemPacket InventoryReply
@@ -2097,6 +2095,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2097 // TODO: don't create new blocks if recycling an old packet 2095 // TODO: don't create new blocks if recycling an old packet
2098 InventoryReply.AgentData.AgentID = AgentId; 2096 InventoryReply.AgentData.AgentID = AgentId;
2099 InventoryReply.AgentData.SimApproved = true; 2097 InventoryReply.AgentData.SimApproved = true;
2098 InventoryReply.AgentData.TransactionID = transactionID;
2100 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1]; 2099 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1];
2101 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock(); 2100 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock();
2102 InventoryReply.InventoryData[0].ItemID = Item.ID; 2101 InventoryReply.InventoryData[0].ItemID = Item.ID;
@@ -2117,7 +2116,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2117 InventoryReply.InventoryData[0].GroupID = Item.GroupID; 2116 InventoryReply.InventoryData[0].GroupID = Item.GroupID;
2118 InventoryReply.InventoryData[0].GroupOwned = Item.GroupOwned; 2117 InventoryReply.InventoryData[0].GroupOwned = Item.GroupOwned;
2119 InventoryReply.InventoryData[0].GroupMask = Item.GroupPermissions; 2118 InventoryReply.InventoryData[0].GroupMask = Item.GroupPermissions;
2120 InventoryReply.InventoryData[0].Flags = Item.Flags; 2119 InventoryReply.InventoryData[0].Flags = Item.Flags & 0xff;
2121 InventoryReply.InventoryData[0].SalePrice = Item.SalePrice; 2120 InventoryReply.InventoryData[0].SalePrice = Item.SalePrice;
2122 InventoryReply.InventoryData[0].SaleType = Item.SaleType; 2121 InventoryReply.InventoryData[0].SaleType = Item.SaleType;
2123 InventoryReply.InventoryData[0].CreationDate = Item.CreationDate; 2122 InventoryReply.InventoryData[0].CreationDate = Item.CreationDate;
@@ -2166,16 +2165,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2166 replytask.InventoryData.TaskID = taskID; 2165 replytask.InventoryData.TaskID = taskID;
2167 replytask.InventoryData.Serial = serial; 2166 replytask.InventoryData.Serial = serial;
2168 replytask.InventoryData.Filename = fileName; 2167 replytask.InventoryData.Filename = fileName;
2169 OutPacket(replytask, ThrottleOutPacketType.Asset); 2168 OutPacket(replytask, ThrottleOutPacketType.Task);
2170 } 2169 }
2171 2170
2172 public void SendXferPacket(ulong xferID, uint packet, byte[] data) 2171 public void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory)
2173 { 2172 {
2173 ThrottleOutPacketType type = ThrottleOutPacketType.Asset;
2174 if (isTaskInventory)
2175 type = ThrottleOutPacketType.Task;
2176
2174 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket); 2177 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket);
2175 sendXfer.XferID.ID = xferID; 2178 sendXfer.XferID.ID = xferID;
2176 sendXfer.XferID.Packet = packet; 2179 sendXfer.XferID.Packet = packet;
2177 sendXfer.DataPacket.Data = data; 2180 sendXfer.DataPacket.Data = data;
2178 OutPacket(sendXfer, ThrottleOutPacketType.Asset); 2181 OutPacket(sendXfer, type);
2179 } 2182 }
2180 2183
2181 public void SendAbortXferPacket(ulong xferID) 2184 public void SendAbortXferPacket(ulong xferID)
@@ -2362,6 +2365,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2362 OutPacket(sound, ThrottleOutPacketType.Task); 2365 OutPacket(sound, ThrottleOutPacketType.Task);
2363 } 2366 }
2364 2367
2368 public void SendTransferAbort(TransferRequestPacket transferRequest)
2369 {
2370 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2371 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2372 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2373 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2374 OutPacket(abort, ThrottleOutPacketType.Task);
2375 }
2376
2365 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2377 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2366 { 2378 {
2367 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2379 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2670,6 +2682,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2670 float friction = part.Friction; 2682 float friction = part.Friction;
2671 float bounce = part.Restitution; 2683 float bounce = part.Restitution;
2672 float gravmod = part.GravityModifier; 2684 float gravmod = part.GravityModifier;
2685
2673 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId); 2686 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2674 } 2687 }
2675 } 2688 }
@@ -2740,8 +2753,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2740 req.AssetInf.ID, req.AssetInf.Metadata.ContentType); 2753 req.AssetInf.ID, req.AssetInf.Metadata.ContentType);
2741 return; 2754 return;
2742 } 2755 }
2756 int WearableOut = 0;
2757 bool isWearable = false;
2758
2759 if (req.AssetInf != null)
2760 isWearable =
2761 ((AssetType) req.AssetInf.Type ==
2762 AssetType.Bodypart || (AssetType) req.AssetInf.Type == AssetType.Clothing);
2743 2763
2744 //m_log.Debug("sending asset " + req.RequestAssetID); 2764
2765 //m_log.Debug("sending asset " + req.RequestAssetID + ", iswearable: " + isWearable);
2766
2767
2768 //if (isWearable)
2769 // m_log.Debug((AssetType)req.AssetInf.Type);
2770
2745 TransferInfoPacket Transfer = new TransferInfoPacket(); 2771 TransferInfoPacket Transfer = new TransferInfoPacket();
2746 Transfer.TransferInfo.ChannelType = 2; 2772 Transfer.TransferInfo.ChannelType = 2;
2747 Transfer.TransferInfo.Status = 0; 2773 Transfer.TransferInfo.Status = 0;
@@ -2763,7 +2789,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2763 Transfer.TransferInfo.Size = req.AssetInf.Data.Length; 2789 Transfer.TransferInfo.Size = req.AssetInf.Data.Length;
2764 Transfer.TransferInfo.TransferID = req.TransferRequestID; 2790 Transfer.TransferInfo.TransferID = req.TransferRequestID;
2765 Transfer.Header.Zerocoded = true; 2791 Transfer.Header.Zerocoded = true;
2766 OutPacket(Transfer, ThrottleOutPacketType.Asset); 2792 OutPacket(Transfer, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2767 2793
2768 if (req.NumPackets == 1) 2794 if (req.NumPackets == 1)
2769 { 2795 {
@@ -2774,12 +2800,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2774 TransferPacket.TransferData.Data = req.AssetInf.Data; 2800 TransferPacket.TransferData.Data = req.AssetInf.Data;
2775 TransferPacket.TransferData.Status = 1; 2801 TransferPacket.TransferData.Status = 1;
2776 TransferPacket.Header.Zerocoded = true; 2802 TransferPacket.Header.Zerocoded = true;
2777 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2803 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2778 } 2804 }
2779 else 2805 else
2780 { 2806 {
2781 int processedLength = 0; 2807 int processedLength = 0;
2782 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2808// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2809
2810 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2783 int packetNumber = 0; 2811 int packetNumber = 0;
2784 2812
2785 while (processedLength < req.AssetInf.Data.Length) 2813 while (processedLength < req.AssetInf.Data.Length)
@@ -2805,7 +2833,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2805 TransferPacket.TransferData.Status = 1; 2833 TransferPacket.TransferData.Status = 1;
2806 } 2834 }
2807 TransferPacket.Header.Zerocoded = true; 2835 TransferPacket.Header.Zerocoded = true;
2808 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2836 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority : ThrottleOutPacketType.Asset);
2809 2837
2810 processedLength += chunkSize; 2838 processedLength += chunkSize;
2811 packetNumber++; 2839 packetNumber++;
@@ -2850,7 +2878,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2850 reply.Data.ParcelID = parcelID; 2878 reply.Data.ParcelID = parcelID;
2851 reply.Data.OwnerID = land.OwnerID; 2879 reply.Data.OwnerID = land.OwnerID;
2852 reply.Data.Name = Utils.StringToBytes(land.Name); 2880 reply.Data.Name = Utils.StringToBytes(land.Name);
2853 reply.Data.Desc = Utils.StringToBytes(land.Description); 2881 if (land != null && land.Description != null && land.Description != String.Empty)
2882 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2883 else
2884 reply.Data.Desc = new Byte[0];
2854 reply.Data.ActualArea = land.Area; 2885 reply.Data.ActualArea = land.Area;
2855 reply.Data.BillableArea = land.Area; // TODO: what is this? 2886 reply.Data.BillableArea = land.Area; // TODO: what is this?
2856 2887
@@ -3557,24 +3588,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3557 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count]; 3588 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count];
3558 AgentWearablesUpdatePacket.WearableDataBlock awb; 3589 AgentWearablesUpdatePacket.WearableDataBlock awb;
3559 int idx = 0; 3590 int idx = 0;
3560 for (int i = 0; i < wearables.Length; i++) 3591
3561 { 3592 for (int i = 0; i < wearables.Length; i++)
3562 for (int j = 0; j < wearables[i].Count; j++) 3593 {
3563 { 3594 for (int j = 0; j < wearables[i].Count; j++)
3564 awb = new AgentWearablesUpdatePacket.WearableDataBlock(); 3595 {
3565 awb.WearableType = (byte)i; 3596 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
3566 awb.AssetID = wearables[i][j].AssetID; 3597 awb.WearableType = (byte) i;
3567 awb.ItemID = wearables[i][j].ItemID; 3598 awb.AssetID = wearables[i][j].AssetID;
3568 aw.WearableData[idx] = awb; 3599 awb.ItemID = wearables[i][j].ItemID;
3569 idx++; 3600 aw.WearableData[idx] = awb;
3570 3601 idx++;
3571// m_log.DebugFormat( 3602
3572// "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}", 3603 // m_log.DebugFormat(
3573// awb.ItemID, awb.AssetID, i, Name); 3604 // "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}",
3574 } 3605 // awb.ItemID, awb.AssetID, i, Name);
3575 } 3606 }
3607 }
3576 3608
3577 OutPacket(aw, ThrottleOutPacketType.Task); 3609 OutPacket(aw, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority);
3578 } 3610 }
3579 3611
3580 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) 3612 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
@@ -3585,7 +3617,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3585 3617
3586 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3618 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3587 // TODO: don't create new blocks if recycling an old packet 3619 // TODO: don't create new blocks if recycling an old packet
3588 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3620 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3589 avp.ObjectData.TextureEntry = textureEntry; 3621 avp.ObjectData.TextureEntry = textureEntry;
3590 3622
3591 AvatarAppearancePacket.VisualParamBlock avblock = null; 3623 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3716,7 +3748,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3716 /// </summary> 3748 /// </summary>
3717 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3749 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3718 { 3750 {
3719 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3751 if (entity is SceneObjectPart)
3752 {
3753 SceneObjectPart e = (SceneObjectPart)entity;
3754 SceneObjectGroup g = e.ParentGroup;
3755 if (g.RootPart.Shape.State > 30) // HUD
3756 if (g.OwnerID != AgentId)
3757 return; // Don't send updates for other people's HUDs
3758 }
3759
3720 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3760 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3721 3761
3722 lock (m_entityUpdates.SyncRoot) 3762 lock (m_entityUpdates.SyncRoot)
@@ -3783,27 +3823,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3783 3823
3784 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3824 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3785 // condition where a kill can be processed before an out-of-date update for the same object. 3825 // condition where a kill can be processed before an out-of-date update for the same object.
3786 lock (m_killRecord) 3826 float avgTimeDilation = 1.0f;
3827 IEntityUpdate iupdate;
3828 Int32 timeinqueue; // this is just debugging code & can be dropped later
3829
3830 while (updatesThisCall < maxUpdates)
3787 { 3831 {
3788 float avgTimeDilation = 1.0f; 3832 lock (m_entityUpdates.SyncRoot)
3789 IEntityUpdate iupdate; 3833 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3790 Int32 timeinqueue; // this is just debugging code & can be dropped later 3834 break;
3791 3835
3792 while (updatesThisCall < maxUpdates) 3836 EntityUpdate update = (EntityUpdate)iupdate;
3837
3838 avgTimeDilation += update.TimeDilation;
3839 avgTimeDilation *= 0.5f;
3840
3841 if (update.Entity is SceneObjectPart)
3793 { 3842 {
3794 lock (m_entityUpdates.SyncRoot) 3843 SceneObjectPart part = (SceneObjectPart)update.Entity;
3795 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3796 break;
3797 3844
3798 EntityUpdate update = (EntityUpdate)iupdate; 3845 if (part.ParentGroup.IsDeleted)
3799 3846 continue;
3800 avgTimeDilation += update.TimeDilation;
3801 avgTimeDilation *= 0.5f;
3802 3847
3803 if (update.Entity is SceneObjectPart) 3848 if (part.ParentGroup.IsAttachment)
3849 { // Someone else's HUD, why are we getting these?
3850 if (part.ParentGroup.OwnerID != AgentId &&
3851 part.ParentGroup.RootPart.Shape.State > 30)
3852 continue;
3853 ScenePresence sp;
3854 // Owner is not in the sim, don't update it to
3855 // anyone
3856 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3857 continue;
3858
3859 List<SceneObjectGroup> atts = sp.GetAttachments();
3860 bool found = false;
3861 foreach (SceneObjectGroup att in atts)
3862 {
3863 if (att == part.ParentGroup)
3864 {
3865 found = true;
3866 break;
3867 }
3868 }
3869
3870 // It's an attachment of a valid avatar, but
3871 // doesn't seem to be attached, skip
3872 if (!found)
3873 continue;
3874
3875 // On vehicle crossing, the attachments are received
3876 // while the avatar is still a child. Don't send
3877 // updates here because the LocalId has not yet
3878 // been updated and the viewer will derender the
3879 // attachments until the avatar becomes root.
3880 if (sp.IsChildAgent)
3881 continue;
3882
3883 // If the object is an attachment we don't want it to be in the kill
3884 // record. Else attaching from inworld and subsequently dropping
3885 // it will no longer work.
3886// lock (m_killRecord)
3887// {
3888// m_killRecord.Remove(part.LocalId);
3889// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3890// }
3891 }
3892 else
3804 { 3893 {
3805 SceneObjectPart part = (SceneObjectPart)update.Entity;
3806
3807 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3894 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3808 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3895 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3809 // safety measure. 3896 // safety measure.
@@ -3814,21 +3901,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3814 // 3901 //
3815 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3902 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3816 // after the root prim has been deleted. 3903 // after the root prim has been deleted.
3817 if (m_killRecord.Contains(part.LocalId)) 3904 //
3818 { 3905 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3819 // m_log.WarnFormat( 3906// lock (m_killRecord)
3820 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3907// {
3821 // part.LocalId, Name); 3908// if (m_killRecord.Contains(part.LocalId))
3822 continue; 3909// continue;
3823 } 3910// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3824 3911// continue;
3825 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3912// }
3913 }
3914
3915 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3916 {
3917 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3918 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3826 { 3919 {
3827 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3920 part.Shape.LightEntry = false;
3828 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3829 {
3830 part.Shape.LightEntry = false;
3831 }
3832 } 3921 }
3833 3922
3834 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh)) 3923 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
@@ -3839,224 +3928,166 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3839 part.Shape.ProfileHollow = 27500; 3928 part.Shape.ProfileHollow = 27500;
3840 } 3929 }
3841 } 3930 }
3842 3931
3843 #region UpdateFlags to packet type conversion 3932 if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
3844
3845 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3846
3847 bool canUseCompressed = true;
3848 bool canUseImproved = true;
3849
3850 // Compressed object updates only make sense for LL primitives
3851 if (!(update.Entity is SceneObjectPart))
3852 { 3933 {
3853 canUseCompressed = false; 3934 // Ensure that mesh has at least 8 valid faces
3935 part.Shape.ProfileBegin = 12500;
3936 part.Shape.ProfileEnd = 0;
3937 part.Shape.ProfileHollow = 27500;
3854 } 3938 }
3855 3939 }
3856 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 3940
3941 ++updatesThisCall;
3942
3943 #region UpdateFlags to packet type conversion
3944
3945 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3946
3947 bool canUseCompressed = true;
3948 bool canUseImproved = true;
3949
3950 // Compressed object updates only make sense for LL primitives
3951 if (!(update.Entity is SceneObjectPart))
3952 {
3953 canUseCompressed = false;
3954 }
3955
3956 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3957 {
3958 canUseCompressed = false;
3959 canUseImproved = false;
3960 }
3961 else
3962 {
3963 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3964 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3965 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3966 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3857 { 3967 {
3858 canUseCompressed = false; 3968 canUseCompressed = false;
3859 canUseImproved = false;
3860 } 3969 }
3861 else 3970
3971 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3972 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3973 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3974 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3975 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3976 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3977 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3978 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3979 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3980 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3981 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3982 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3983 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3984 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3862 { 3985 {
3863 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3986 canUseImproved = false;
3864 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3865 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3866 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3867 {
3868 canUseCompressed = false;
3869 }
3870
3871 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3872 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3873 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3874 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3875 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3876 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3877 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3878 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3879 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3880 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3881 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3882 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3883 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3884 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3885 {
3886 canUseImproved = false;
3887 }
3888 } 3987 }
3988 }
3889 3989
3890 #endregion UpdateFlags to packet type conversion 3990 #endregion UpdateFlags to packet type conversion
3891
3892 #region Block Construction
3893
3894 // TODO: Remove this once we can build compressed updates
3895 canUseCompressed = false;
3896
3897 if (!canUseImproved && !canUseCompressed)
3898 {
3899 ObjectUpdatePacket.ObjectDataBlock updateBlock;
3900 3991
3901 if (update.Entity is ScenePresence) 3992 #region Block Construction
3902 {
3903 updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
3904 }
3905 else
3906 {
3907 SceneObjectPart part = (SceneObjectPart)update.Entity;
3908 updateBlock = CreatePrimUpdateBlock(part, AgentId);
3909
3910 // If the part has become a private hud since the update was scheduled then we do not
3911 // want to send it to other avatars.
3912 if (part.ParentGroup.IsAttachment
3913 && part.ParentGroup.HasPrivateAttachmentPoint
3914 && part.ParentGroup.AttachedAvatar != AgentId)
3915 continue;
3916
3917 // If the part has since been deleted, then drop the update. In the case of attachments,
3918 // this is to avoid spurious updates to other viewers since post-processing of attachments
3919 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3920 // of the test above).
3921 //
3922 // Actual deletions (kills) happen in another method.
3923 if (part.ParentGroup.IsDeleted)
3924 continue;
3925 }
3926 3993
3927 objectUpdateBlocks.Value.Add(updateBlock); 3994 // TODO: Remove this once we can build compressed updates
3928 objectUpdates.Value.Add(update); 3995 canUseCompressed = false;
3929 }
3930 else if (!canUseImproved)
3931 {
3932 SceneObjectPart part = (SceneObjectPart)update.Entity;
3933 ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
3934 = CreateCompressedUpdateBlock(part, updateFlags);
3935
3936 // If the part has since been deleted, then drop the update. In the case of attachments,
3937 // this is to avoid spurious updates to other viewers since post-processing of attachments
3938 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3939 // of the test above).
3940 //
3941 // Actual deletions (kills) happen in another method.
3942 if (part.ParentGroup.IsDeleted)
3943 continue;
3944 3996
3945 compressedUpdateBlocks.Value.Add(compressedBlock); 3997 if (!canUseImproved && !canUseCompressed)
3946 compressedUpdates.Value.Add(update); 3998 {
3999 if (update.Entity is ScenePresence)
4000 {
4001 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3947 } 4002 }
3948 else 4003 else
3949 { 4004 {
3950 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 4005 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3951 {
3952 // Self updates go into a special list
3953 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3954 terseAgentUpdates.Value.Add(update);
3955 }
3956 else
3957 {
3958 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
3959 = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
3960
3961 // Everything else goes here
3962 if (update.Entity is SceneObjectPart)
3963 {
3964 SceneObjectPart part = (SceneObjectPart)update.Entity;
3965
3966 // If the part has become a private hud since the update was scheduled then we do not
3967 // want to send it to other avatars.
3968 if (part.ParentGroup.IsAttachment
3969 && part.ParentGroup.HasPrivateAttachmentPoint
3970 && part.ParentGroup.AttachedAvatar != AgentId)
3971 continue;
3972
3973 // If the part has since been deleted, then drop the update. In the case of attachments,
3974 // this is to avoid spurious updates to other viewers since post-processing of attachments
3975 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3976 // of the test above).
3977 //
3978 // Actual deletions (kills) happen in another method.
3979 if (part.ParentGroup.IsDeleted)
3980 continue;
3981 }
3982
3983 terseUpdateBlocks.Value.Add(terseUpdateBlock);
3984 terseUpdates.Value.Add(update);
3985 }
3986 } 4006 }
3987
3988 ++updatesThisCall;
3989
3990 #endregion Block Construction
3991 } 4007 }
3992 4008 else if (!canUseImproved)
3993 #region Packet Sending 4009 {
3994 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); 4010 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3995 4011 }
3996 if (terseAgentUpdateBlocks.IsValueCreated) 4012 else
3997 { 4013 {
3998 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 4014 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
4015 // Self updates go into a special list
4016 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
4017 else
4018 // Everything else goes here
4019 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
4020 }
3999 4021
4000 ImprovedTerseObjectUpdatePacket packet 4022 #endregion Block Construction
4001 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 4023 }
4002 4024
4003 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4025 #region Packet Sending
4004 packet.RegionData.TimeDilation = timeDilation; 4026
4005 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4027 const float TIME_DILATION = 1.0f;
4028 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
4029
4030 if (terseAgentUpdateBlocks.IsValueCreated)
4031 {
4032 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
4006 4033
4007 for (int i = 0; i < blocks.Count; i++) 4034 ImprovedTerseObjectUpdatePacket packet
4008 packet.ObjectData[i] = blocks[i]; 4035 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
4009 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4036 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4010 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); }); 4037 packet.RegionData.TimeDilation = timeDilation;
4011 } 4038 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4012 4039
4013 if (objectUpdateBlocks.IsValueCreated) 4040 for (int i = 0; i < blocks.Count; i++)
4014 { 4041 packet.ObjectData[i] = blocks[i];
4015 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
4016
4017 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
4018 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4019 packet.RegionData.TimeDilation = timeDilation;
4020 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4021
4022 for (int i = 0; i < blocks.Count; i++)
4023 packet.ObjectData[i] = blocks[i];
4024 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4025 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
4026 }
4027
4028 if (compressedUpdateBlocks.IsValueCreated)
4029 {
4030 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4031
4032 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4033 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4034 packet.RegionData.TimeDilation = timeDilation;
4035 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4036
4037 for (int i = 0; i < blocks.Count; i++)
4038 packet.ObjectData[i] = blocks[i];
4039 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
4040 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
4041 }
4042 4042
4043 if (terseUpdateBlocks.IsValueCreated) 4043 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
4044 { 4044 }
4045 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4046
4047 ImprovedTerseObjectUpdatePacket packet
4048 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4049 PacketType.ImprovedTerseObjectUpdate);
4050 4045
4051 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4046 if (objectUpdateBlocks.IsValueCreated)
4052 packet.RegionData.TimeDilation = timeDilation; 4047 {
4053 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4048 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
4054 4049
4055 for (int i = 0; i < blocks.Count; i++) 4050 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
4056 packet.ObjectData[i] = blocks[i]; 4051 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4057 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4052 packet.RegionData.TimeDilation = timeDilation;
4058 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 4053 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4059 } 4054
4055 for (int i = 0; i < blocks.Count; i++)
4056 packet.ObjectData[i] = blocks[i];
4057
4058 OutPacket(packet, ThrottleOutPacketType.Task, true);
4059 }
4060
4061 if (compressedUpdateBlocks.IsValueCreated)
4062 {
4063 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4064
4065 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4066 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4067 packet.RegionData.TimeDilation = timeDilation;
4068 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4069
4070 for (int i = 0; i < blocks.Count; i++)
4071 packet.ObjectData[i] = blocks[i];
4072
4073 OutPacket(packet, ThrottleOutPacketType.Task, true);
4074 }
4075
4076 if (terseUpdateBlocks.IsValueCreated)
4077 {
4078 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4079
4080 ImprovedTerseObjectUpdatePacket packet
4081 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4082 PacketType.ImprovedTerseObjectUpdate);
4083 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4084 packet.RegionData.TimeDilation = timeDilation;
4085 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4086
4087 for (int i = 0; i < blocks.Count; i++)
4088 packet.ObjectData[i] = blocks[i];
4089
4090 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
4060 } 4091 }
4061 4092
4062 #endregion Packet Sending 4093 #endregion Packet Sending
@@ -4349,11 +4380,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4349 4380
4350 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4381 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4351 // of the object rather than the properties when the packet was created 4382 // of the object rather than the properties when the packet was created
4352 OutPacket(packet, ThrottleOutPacketType.Task, true, 4383 // HACK : Remove intelligent resending until it's fixed in core
4353 delegate(OutgoingPacket oPacket) 4384 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4354 { 4385 // delegate(OutgoingPacket oPacket)
4355 ResendPropertyUpdates(updates, oPacket); 4386 // {
4356 }); 4387 // ResendPropertyUpdates(updates, oPacket);
4388 // });
4389 OutPacket(packet, ThrottleOutPacketType.Task, true);
4357 4390
4358 // pbcnt += blocks.Count; 4391 // pbcnt += blocks.Count;
4359 // ppcnt++; 4392 // ppcnt++;
@@ -4379,11 +4412,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4379 // of the object rather than the properties when the packet was created 4412 // of the object rather than the properties when the packet was created
4380 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4413 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4381 updates.Add(familyUpdates.Value[i]); 4414 updates.Add(familyUpdates.Value[i]);
4382 OutPacket(packet, ThrottleOutPacketType.Task, true, 4415 // HACK : Remove intelligent resending until it's fixed in core
4383 delegate(OutgoingPacket oPacket) 4416 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4384 { 4417 // delegate(OutgoingPacket oPacket)
4385 ResendPropertyUpdates(updates, oPacket); 4418 // {
4386 }); 4419 // ResendPropertyUpdates(updates, oPacket);
4420 // });
4421 OutPacket(packet, ThrottleOutPacketType.Task, true);
4387 4422
4388 // fpcnt++; 4423 // fpcnt++;
4389 // fbcnt++; 4424 // fbcnt++;
@@ -4755,7 +4790,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4755 4790
4756 if (landData.SimwideArea > 0) 4791 if (landData.SimwideArea > 0)
4757 { 4792 {
4758 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4793 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4794 // Never report more than sim total capacity
4795 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4796 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4759 updateMessage.SimWideMaxPrims = simulatorCapacity; 4797 updateMessage.SimWideMaxPrims = simulatorCapacity;
4760 } 4798 }
4761 else 4799 else
@@ -4884,14 +4922,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4884 4922
4885 if (notifyCount > 0) 4923 if (notifyCount > 0)
4886 { 4924 {
4887 if (notifyCount > 32) 4925// if (notifyCount > 32)
4888 { 4926// {
4889 m_log.InfoFormat( 4927// m_log.InfoFormat(
4890 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4928// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4891 + " - a developer might want to investigate whether this is a hard limit", 32); 4929// + " - a developer might want to investigate whether this is a hard limit", 32);
4892 4930//
4893 notifyCount = 32; 4931// notifyCount = 32;
4894 } 4932// }
4895 4933
4896 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4934 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4897 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4935 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4946,9 +4984,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4946 { 4984 {
4947 ScenePresence presence = (ScenePresence)entity; 4985 ScenePresence presence = (ScenePresence)entity;
4948 4986
4987 position = presence.OffsetPosition;
4988 rotation = presence.Rotation;
4989
4990 if (presence.ParentID != 0)
4991 {
4992 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4993 if (part != null && part != part.ParentGroup.RootPart)
4994 {
4995 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4996 rotation = part.RotationOffset * presence.Rotation;
4997 }
4998 angularVelocity = Vector3.Zero;
4999 }
5000 else
5001 {
5002 angularVelocity = presence.AngularVelocity;
5003 rotation = presence.Rotation;
5004 }
5005
4949 attachPoint = 0; 5006 attachPoint = 0;
4950 collisionPlane = presence.CollisionPlane; 5007 collisionPlane = presence.CollisionPlane;
4951 position = presence.OffsetPosition;
4952 velocity = presence.Velocity; 5008 velocity = presence.Velocity;
4953 acceleration = Vector3.Zero; 5009 acceleration = Vector3.Zero;
4954 5010
@@ -4957,9 +5013,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4957 // may improve movement smoothness. 5013 // may improve movement smoothness.
4958// acceleration = new Vector3(1, 0, 0); 5014// acceleration = new Vector3(1, 0, 0);
4959 5015
4960 angularVelocity = presence.AngularVelocity;
4961 rotation = presence.Rotation;
4962
4963 if (sendTexture) 5016 if (sendTexture)
4964 textureEntry = presence.Appearance.Texture.GetBytes(); 5017 textureEntry = presence.Appearance.Texture.GetBytes();
4965 else 5018 else
@@ -5065,13 +5118,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5065 5118
5066 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5119 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
5067 { 5120 {
5121 Vector3 offsetPosition = data.OffsetPosition;
5122 Quaternion rotation = data.Rotation;
5123 uint parentID = data.ParentID;
5124
5125 if (parentID != 0)
5126 {
5127 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5128 if (part != null && part != part.ParentGroup.RootPart)
5129 {
5130 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5131 rotation = part.RotationOffset * data.Rotation;
5132 parentID = part.ParentGroup.RootPart.LocalId;
5133 }
5134 }
5135
5068 byte[] objectData = new byte[76]; 5136 byte[] objectData = new byte[76];
5069 5137
5070 data.CollisionPlane.ToBytes(objectData, 0); 5138 data.CollisionPlane.ToBytes(objectData, 0);
5071 data.OffsetPosition.ToBytes(objectData, 16); 5139 offsetPosition.ToBytes(objectData, 16);
5140 Vector3 velocity = new Vector3(0, 0, 0);
5141 Vector3 acceleration = new Vector3(0, 0, 0);
5142 velocity.ToBytes(objectData, 28);
5143 acceleration.ToBytes(objectData, 40);
5072// data.Velocity.ToBytes(objectData, 28); 5144// data.Velocity.ToBytes(objectData, 28);
5073// data.Acceleration.ToBytes(objectData, 40); 5145// data.Acceleration.ToBytes(objectData, 40);
5074 data.Rotation.ToBytes(objectData, 52); 5146 rotation.ToBytes(objectData, 52);
5075 //data.AngularVelocity.ToBytes(objectData, 64); 5147 //data.AngularVelocity.ToBytes(objectData, 64);
5076 5148
5077 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5149 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -5085,14 +5157,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5085 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5157 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
5086 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5158 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
5087 update.ObjectData = objectData; 5159 update.ObjectData = objectData;
5088 update.ParentID = data.ParentID; 5160 update.ParentID = parentID;
5089 update.PathCurve = 16; 5161 update.PathCurve = 16;
5090 update.PathScaleX = 100; 5162 update.PathScaleX = 100;
5091 update.PathScaleY = 100; 5163 update.PathScaleY = 100;
5092 update.PCode = (byte)PCode.Avatar; 5164 update.PCode = (byte)PCode.Avatar;
5093 update.ProfileCurve = 1; 5165 update.ProfileCurve = 1;
5094 update.PSBlock = Utils.EmptyBytes; 5166 update.PSBlock = Utils.EmptyBytes;
5095 update.Scale = new Vector3(0.45f, 0.6f, 1.9f); 5167 update.Scale = data.Appearance.AvatarSize;
5168// update.Scale.Z -= 0.2f;
5169
5096 update.Text = Utils.EmptyBytes; 5170 update.Text = Utils.EmptyBytes;
5097 update.TextColor = new byte[4]; 5171 update.TextColor = new byte[4];
5098 5172
@@ -5103,10 +5177,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5103 update.TextureEntry = Utils.EmptyBytes; 5177 update.TextureEntry = Utils.EmptyBytes;
5104// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; 5178// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
5105 5179
5180/* 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)
5106 update.UpdateFlags = (uint)( 5181 update.UpdateFlags = (uint)(
5107 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | 5182 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
5108 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | 5183 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
5109 PrimFlags.ObjectOwnerModify); 5184 PrimFlags.ObjectOwnerModify);
5185*/
5186 update.UpdateFlags = 0;
5110 5187
5111 return update; 5188 return update;
5112 } 5189 }
@@ -5277,8 +5354,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5277 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs 5354 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs
5278 // for each AgentUpdate packet. 5355 // for each AgentUpdate packet.
5279 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false); 5356 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false);
5280 5357
5281 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false); 5358 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false);
5359 AddLocalPacketHandler(PacketType.VelocityInterpolateOff, HandleVelocityInterpolateOff, false);
5360 AddLocalPacketHandler(PacketType.VelocityInterpolateOn, HandleVelocityInterpolateOn, false);
5282 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); 5361 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false);
5283 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); 5362 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
5284 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false); 5363 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false);
@@ -5430,6 +5509,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5430 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5509 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5431 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5510 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5432 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5511 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5512 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5433 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5513 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5434 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5514 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5435 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5515 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5496,6 +5576,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5496 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5576 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5497 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5577 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5498 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5578 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5579 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5499 5580
5500 AddGenericPacketHandler("autopilot", HandleAutopilot); 5581 AddGenericPacketHandler("autopilot", HandleAutopilot);
5501 } 5582 }
@@ -5534,6 +5615,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5534 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) || 5615 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) ||
5535 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) || 5616 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) ||
5536 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) || 5617 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) ||
5618 (x.ControlFlags != 0) ||
5537 (x.Far != m_lastAgentUpdateArgs.Far) || 5619 (x.Far != m_lastAgentUpdateArgs.Far) ||
5538 (x.Flags != m_lastAgentUpdateArgs.Flags) || 5620 (x.Flags != m_lastAgentUpdateArgs.Flags) ||
5539 (x.State != m_lastAgentUpdateArgs.State) || 5621 (x.State != m_lastAgentUpdateArgs.State) ||
@@ -5793,6 +5875,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5793 return true; 5875 return true;
5794 } 5876 }
5795 5877
5878 private bool HandleVelocityInterpolateOff(IClientAPI sender, Packet Pack)
5879 {
5880 VelocityInterpolateOffPacket p = (VelocityInterpolateOffPacket)Pack;
5881 if (p.AgentData.SessionID != SessionId ||
5882 p.AgentData.AgentID != AgentId)
5883 return true;
5884
5885 m_VelocityInterpolate = false;
5886 return true;
5887 }
5888
5889 private bool HandleVelocityInterpolateOn(IClientAPI sender, Packet Pack)
5890 {
5891 VelocityInterpolateOnPacket p = (VelocityInterpolateOnPacket)Pack;
5892 if (p.AgentData.SessionID != SessionId ||
5893 p.AgentData.AgentID != AgentId)
5894 return true;
5895
5896 m_VelocityInterpolate = true;
5897 return true;
5898 }
5899
5900
5796 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack) 5901 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack)
5797 { 5902 {
5798 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack; 5903 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack;
@@ -6213,26 +6318,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6213 // Temporarily protect ourselves from the mantis #951 failure. 6318 // Temporarily protect ourselves from the mantis #951 failure.
6214 // However, we could do this for several other handlers where a failure isn't terminal 6319 // However, we could do this for several other handlers where a failure isn't terminal
6215 // for the client session anyway, in order to protect ourselves against bad code in plugins 6320 // for the client session anyway, in order to protect ourselves against bad code in plugins
6321 Vector3 avSize = appear.AgentData.Size;
6216 try 6322 try
6217 { 6323 {
6218 byte[] visualparams = new byte[appear.VisualParam.Length]; 6324 byte[] visualparams = new byte[appear.VisualParam.Length];
6219 for (int i = 0; i < appear.VisualParam.Length; i++) 6325 for (int i = 0; i < appear.VisualParam.Length; i++)
6220 visualparams[i] = appear.VisualParam[i].ParamValue; 6326 visualparams[i] = appear.VisualParam[i].ParamValue;
6221 6327 //var b = appear.WearableData[0];
6328
6222 Primitive.TextureEntry te = null; 6329 Primitive.TextureEntry te = null;
6223 if (appear.ObjectData.TextureEntry.Length > 1) 6330 if (appear.ObjectData.TextureEntry.Length > 1)
6224 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); 6331 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
6332
6333 WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length];
6334 for (int i=0; i<appear.WearableData.Length;i++)
6335 cacheitems[i] = new WearableCacheItem(){CacheId = appear.WearableData[i].CacheID,TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex)};
6225 6336
6226 List<CachedTextureRequestArg> hashes = new List<CachedTextureRequestArg>(); 6337
6227 for (int i = 0; i < appear.WearableData.Length; i++)
6228 {
6229 CachedTextureRequestArg arg = new CachedTextureRequestArg();
6230 arg.BakedTextureIndex = appear.WearableData[i].TextureIndex;
6231 arg.WearableHashID = appear.WearableData[i].CacheID;
6232 hashes.Add(arg);
6233 }
6234 6338
6235 handlerSetAppearance(sender, te, visualparams, hashes); 6339 handlerSetAppearance(sender, te, visualparams,avSize, cacheitems);
6236 } 6340 }
6237 catch (Exception e) 6341 catch (Exception e)
6238 { 6342 {
@@ -6441,6 +6545,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6441 { 6545 {
6442 handlerCompleteMovementToRegion(sender, true); 6546 handlerCompleteMovementToRegion(sender, true);
6443 } 6547 }
6548 else
6549 m_log.Debug("HandleCompleteAgentMovement NULL handler");
6550
6444 handlerCompleteMovementToRegion = null; 6551 handlerCompleteMovementToRegion = null;
6445 6552
6446 return true; 6553 return true;
@@ -6458,7 +6565,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6458 return true; 6565 return true;
6459 } 6566 }
6460 #endregion 6567 #endregion
6461 6568/*
6462 StartAnim handlerStartAnim = null; 6569 StartAnim handlerStartAnim = null;
6463 StopAnim handlerStopAnim = null; 6570 StopAnim handlerStopAnim = null;
6464 6571
@@ -6482,6 +6589,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6482 } 6589 }
6483 } 6590 }
6484 return true; 6591 return true;
6592*/
6593 ChangeAnim handlerChangeAnim = null;
6594
6595 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6596 {
6597 handlerChangeAnim = OnChangeAnim;
6598 if (handlerChangeAnim != null)
6599 {
6600 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6601 }
6602 }
6603
6604 handlerChangeAnim = OnChangeAnim;
6605 if (handlerChangeAnim != null)
6606 {
6607 handlerChangeAnim(UUID.Zero, false, true);
6608 }
6609
6610 return true;
6485 } 6611 }
6486 6612
6487 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6613 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -6707,6 +6833,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6707 #endregion 6833 #endregion
6708 6834
6709 m_udpClient.SetThrottles(atpack.Throttle.Throttles); 6835 m_udpClient.SetThrottles(atpack.Throttle.Throttles);
6836 GenericCall2 handler = OnUpdateThrottles;
6837 if (handler != null)
6838 {
6839 handler();
6840 }
6710 return true; 6841 return true;
6711 } 6842 }
6712 6843
@@ -7131,7 +7262,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7131 physdata.Bounce = phsblock.Restitution; 7262 physdata.Bounce = phsblock.Restitution;
7132 physdata.Density = phsblock.Density; 7263 physdata.Density = phsblock.Density;
7133 physdata.Friction = phsblock.Friction; 7264 physdata.Friction = phsblock.Friction;
7134 physdata.GravitationModifier = phsblock.GravityMultiplier; 7265 physdata.GravitationModifier = phsblock.GravityMultiplier;
7135 } 7266 }
7136 7267
7137 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this); 7268 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
@@ -7717,6 +7848,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7717 // surrounding scene 7848 // surrounding scene
7718 if ((ImageType)block.Type == ImageType.Baked) 7849 if ((ImageType)block.Type == ImageType.Baked)
7719 args.Priority *= 2.0f; 7850 args.Priority *= 2.0f;
7851 int wearableout = 0;
7720 7852
7721 ImageManager.EnqueueReq(args); 7853 ImageManager.EnqueueReq(args);
7722 } 7854 }
@@ -8735,16 +8867,61 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8735 8867
8736 #region Parcel related packets 8868 #region Parcel related packets
8737 8869
8870 // acumulate several HandleRegionHandleRequest consecutive overlaping requests
8871 // to be done with minimal resources as possible
8872 // variables temporary here while in test
8873
8874 Queue<UUID> RegionHandleRequests = new Queue<UUID>();
8875 bool RegionHandleRequestsInService = false;
8876
8738 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack) 8877 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack)
8739 { 8878 {
8740 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; 8879 UUID currentUUID;
8741 8880
8742 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; 8881 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest;
8743 if (handlerRegionHandleRequest != null) 8882
8883 if (handlerRegionHandleRequest == null)
8884 return true;
8885
8886 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
8887
8888 lock (RegionHandleRequests)
8744 { 8889 {
8745 handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); 8890 if (RegionHandleRequestsInService)
8891 {
8892 // we are already busy doing a previus request
8893 // so enqueue it
8894 RegionHandleRequests.Enqueue(rhrPack.RequestBlock.RegionID);
8895 return true;
8896 }
8897
8898 // else do it
8899 currentUUID = rhrPack.RequestBlock.RegionID;
8900 RegionHandleRequestsInService = true;
8746 } 8901 }
8747 return true; 8902
8903 while (true)
8904 {
8905 handlerRegionHandleRequest(this, currentUUID);
8906
8907 lock (RegionHandleRequests)
8908 {
8909 // exit condition, nothing to do or closed
8910 // current code seems to assume we may loose the handler at anytime,
8911 // so keep checking it
8912 handlerRegionHandleRequest = OnRegionHandleRequest;
8913
8914 if (RegionHandleRequests.Count == 0 || !IsActive || handlerRegionHandleRequest == null)
8915 {
8916 RegionHandleRequests.Clear();
8917 RegionHandleRequestsInService = false;
8918 return true;
8919 }
8920 currentUUID = RegionHandleRequests.Dequeue();
8921 }
8922 }
8923
8924 return true; // actually unreached
8748 } 8925 }
8749 8926
8750 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack) 8927 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack)
@@ -10000,7 +10177,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10000 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 10177 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
10001 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 10178 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
10002 UpdateMuteListEntry.MuteData.MuteType, 10179 UpdateMuteListEntry.MuteData.MuteType,
10003 UpdateMuteListEntry.AgentData.AgentID); 10180 UpdateMuteListEntry.MuteData.MuteFlags);
10004 return true; 10181 return true;
10005 } 10182 }
10006 return false; 10183 return false;
@@ -10015,8 +10192,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10015 { 10192 {
10016 handlerRemoveMuteListEntry(this, 10193 handlerRemoveMuteListEntry(this,
10017 RemoveMuteListEntry.MuteData.MuteID, 10194 RemoveMuteListEntry.MuteData.MuteID,
10018 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 10195 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
10019 RemoveMuteListEntry.AgentData.AgentID);
10020 return true; 10196 return true;
10021 } 10197 }
10022 return false; 10198 return false;
@@ -10060,10 +10236,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10060 return false; 10236 return false;
10061 } 10237 }
10062 10238
10239 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10240 {
10241 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10242 (ChangeInventoryItemFlagsPacket)packet;
10243 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10244 if (handlerChangeInventoryItemFlags != null)
10245 {
10246 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10247 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10248 return true;
10249 }
10250 return false;
10251 }
10252
10063 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10253 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
10064 { 10254 {
10065 return true; 10255 return true;
10066 } 10256 }
10257
10258 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10259 {
10260 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10261
10262 #region Packet Session and User Check
10263 if (m_checkPackets)
10264 {
10265 if (packet.AgentData.SessionID != SessionId ||
10266 packet.AgentData.AgentID != AgentId)
10267 return true;
10268 }
10269 #endregion
10270 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10271 List<InventoryItemBase> items = new List<InventoryItemBase>();
10272 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10273 {
10274 InventoryItemBase b = new InventoryItemBase();
10275 b.ID = n.OldItemID;
10276 b.Folder = n.OldFolderID;
10277 items.Add(b);
10278 }
10279
10280 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10281 if (handlerMoveItemsAndLeaveCopy != null)
10282 {
10283 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10284 }
10285
10286 return true;
10287 }
10067 10288
10068 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10289 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
10069 { 10290 {
@@ -10490,6 +10711,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10490 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10711 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10491 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10712 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10492 10713
10714 Scene scene = (Scene)m_scene;
10715 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10716 {
10717 ScenePresence p;
10718 if (scene.TryGetScenePresence(sender.AgentId, out p))
10719 {
10720 if (p.GodLevel >= 200)
10721 {
10722 groupProfileReply.GroupData.OpenEnrollment = true;
10723 groupProfileReply.GroupData.MembershipFee = 0;
10724 }
10725 }
10726 }
10727
10493 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10728 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10494 } 10729 }
10495 return true; 10730 return true;
@@ -11063,11 +11298,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11063 11298
11064 StartLure handlerStartLure = OnStartLure; 11299 StartLure handlerStartLure = OnStartLure;
11065 if (handlerStartLure != null) 11300 if (handlerStartLure != null)
11066 handlerStartLure(startLureRequest.Info.LureType, 11301 {
11067 Utils.BytesToString( 11302 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
11068 startLureRequest.Info.Message), 11303 {
11069 startLureRequest.TargetData[0].TargetID, 11304 handlerStartLure(startLureRequest.Info.LureType,
11070 this); 11305 Utils.BytesToString(
11306 startLureRequest.Info.Message),
11307 startLureRequest.TargetData[i].TargetID,
11308 this);
11309 }
11310 }
11071 return true; 11311 return true;
11072 } 11312 }
11073 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11313 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -11181,10 +11421,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11181 } 11421 }
11182 #endregion 11422 #endregion
11183 11423
11184 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11424 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11185 if (handlerClassifiedGodDelete != null) 11425 if (handlerClassifiedGodDelete != null)
11186 handlerClassifiedGodDelete( 11426 handlerClassifiedGodDelete(
11187 classifiedGodDelete.Data.ClassifiedID, 11427 classifiedGodDelete.Data.ClassifiedID,
11428 classifiedGodDelete.Data.QueryID,
11188 this); 11429 this);
11189 return true; 11430 return true;
11190 } 11431 }
@@ -11487,12 +11728,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11487 /// <param name="simclient"></param> 11728 /// <param name="simclient"></param>
11488 /// <param name="packet"></param> 11729 /// <param name="packet"></param>
11489 /// <returns></returns> 11730 /// <returns></returns>
11490 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet) 11731 // TODO: Convert old handler to use new method
11732 /*protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
11491 { 11733 {
11492 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet; 11734 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
11493 11735
11494 if (cachedtex.AgentData.SessionID != SessionId) 11736 if (cachedtex.AgentData.SessionID != SessionId)
11495 return false; 11737 return false;
11738
11496 11739
11497 List<CachedTextureRequestArg> requestArgs = new List<CachedTextureRequestArg>(); 11740 List<CachedTextureRequestArg> requestArgs = new List<CachedTextureRequestArg>();
11498 11741
@@ -11505,23 +11748,173 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11505 requestArgs.Add(arg); 11748 requestArgs.Add(arg);
11506 } 11749 }
11507 11750
11508 try 11751 CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest;
11752 if (handlerCachedTextureRequest != null)
11509 { 11753 {
11510 CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest; 11754 handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs);
11511 if (handlerCachedTextureRequest != null) 11755 }
11756
11757 return true;
11758 }*/
11759
11760 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
11761 {
11762 //m_log.Debug("texture cached: " + packet.ToString());
11763 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
11764 AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse);
11765
11766 if (cachedtex.AgentData.SessionID != SessionId)
11767 return false;
11768
11769
11770 // TODO: don't create new blocks if recycling an old packet
11771 cachedresp.AgentData.AgentID = AgentId;
11772 cachedresp.AgentData.SessionID = m_sessionId;
11773 cachedresp.AgentData.SerialNum = m_cachedTextureSerial;
11774 m_cachedTextureSerial++;
11775 cachedresp.WearableData =
11776 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
11777
11778 //IAvatarFactoryModule fac = m_scene.RequestModuleInterface<IAvatarFactoryModule>();
11779 // var item = fac.GetBakedTextureFaces(AgentId);
11780 //WearableCacheItem[] items = fac.GetCachedItems(AgentId);
11781
11782 IAssetService cache = m_scene.AssetService;
11783 IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
11784 //bakedTextureModule = null;
11785 int maxWearablesLoop = cachedtex.WearableData.Length;
11786 if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES)
11787 maxWearablesLoop = AvatarWearable.MAX_WEARABLES;
11788
11789 if (bakedTextureModule != null && cache != null)
11790 {
11791 // 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
11792
11793 WearableCacheItem[] cacheItems = null;
11794 ScenePresence p = m_scene.GetScenePresence(AgentId);
11795 if (p.Appearance != null)
11796 if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty)
11797 {
11798 try
11799 {
11800 cacheItems = bakedTextureModule.Get(AgentId);
11801 p.Appearance.WearableCacheItems = cacheItems;
11802 p.Appearance.WearableCacheItemsDirty = false;
11803 }
11804
11805 /*
11806 * The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception!
11807 *
11808 catch (System.Net.Sockets.SocketException)
11809 {
11810 cacheItems = null;
11811 }
11812 catch (WebException)
11813 {
11814 cacheItems = null;
11815 }
11816 catch (InvalidOperationException)
11817 {
11818 cacheItems = null;
11819 } */
11820 catch (Exception)
11821 {
11822 cacheItems = null;
11823 }
11824
11825 }
11826 else if (p.Appearance.WearableCacheItems != null)
11827 {
11828 cacheItems = p.Appearance.WearableCacheItems;
11829 }
11830
11831 if (cache != null && cacheItems != null)
11512 { 11832 {
11513 handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs); 11833 foreach (WearableCacheItem item in cacheItems)
11834 {
11835
11836 if (cache.GetCached(item.TextureID.ToString()) == null)
11837 {
11838 item.TextureAsset.Temporary = true;
11839 cache.Store(item.TextureAsset);
11840 }
11841
11842
11843 }
11844 }
11845
11846 if (cacheItems != null)
11847 {
11848
11849 for (int i = 0; i < maxWearablesLoop; i++)
11850 {
11851 WearableCacheItem item =
11852 WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems);
11853
11854 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11855 cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex;
11856 cachedresp.WearableData[i].HostName = new byte[0];
11857 if (item != null && cachedtex.WearableData[i].ID == item.CacheId)
11858 {
11859
11860 cachedresp.WearableData[i].TextureID = item.TextureID;
11861 }
11862 else
11863 {
11864 cachedresp.WearableData[i].TextureID = UUID.Zero;
11865 }
11866 }
11867 }
11868 else
11869 {
11870 for (int i = 0; i < maxWearablesLoop; i++)
11871 {
11872 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11873 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11874 cachedresp.WearableData[i].TextureID = UUID.Zero;
11875 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11876 cachedresp.WearableData[i].HostName = new byte[0];
11877 }
11514 } 11878 }
11515 } 11879 }
11516 catch (Exception e) 11880 else
11517 { 11881 {
11518 m_log.ErrorFormat("[CLIENT VIEW]: AgentTextureCached packet handler threw an exception, {0}", e); 11882 if (cache == null)
11519 return false; 11883 {
11884 for (int i = 0; i < maxWearablesLoop; i++)
11885 {
11886 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11887 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11888 cachedresp.WearableData[i].TextureID = UUID.Zero;
11889 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11890 cachedresp.WearableData[i].HostName = new byte[0];
11891 }
11892 }
11893 else
11894 {
11895 for (int i = 0; i < maxWearablesLoop; i++)
11896 {
11897 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11898 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11899
11900
11901
11902 if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null)
11903 cachedresp.WearableData[i].TextureID = UUID.Zero;
11904 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11905 else
11906 cachedresp.WearableData[i].TextureID = UUID.Zero;
11907 // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11908 cachedresp.WearableData[i].HostName = new byte[0];
11909 }
11910 }
11520 } 11911 }
11521 11912 cachedresp.Header.Zerocoded = true;
11913 OutPacket(cachedresp, ThrottleOutPacketType.Task);
11914
11522 return true; 11915 return true;
11523 } 11916 }
11524 11917
11525 /// <summary> 11918 /// <summary>
11526 /// Send a response back to a client when it asks the asset server (via the region server) if it has 11919 /// Send a response back to a client when it asks the asset server (via the region server) if it has
11527 /// its appearance texture cached. 11920 /// its appearance texture cached.
@@ -11585,209 +11978,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11585 } 11978 }
11586 else 11979 else
11587 { 11980 {
11588// m_log.DebugFormat( 11981 ClientChangeObject updatehandler = onClientChangeObject;
11589// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11590// i, block.Type, part.Name, part.LocalId);
11591 11982
11592// // Do this once since fetch parts creates a new array. 11983 if (updatehandler != null)
11593// SceneObjectPart[] parts = part.ParentGroup.Parts; 11984 {
11594// for (int j = 0; j < parts.Length; j++) 11985 ObjectChangeData udata = new ObjectChangeData();
11595// {
11596// part.StoreUndoState();
11597// parts[j].IgnoreUndoUpdate = true;
11598// }
11599 11986
11600 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11987 /*ubit from ll JIRA:
11988 * 0x01 position
11989 * 0x02 rotation
11990 * 0x04 scale
11991
11992 * 0x08 LINK_SET
11993 * 0x10 UNIFORM for scale
11994 */
11601 11995
11602 switch (block.Type) 11996 // translate to internal changes
11603 { 11997 // not all cases .. just the ones older code did
11604 case 1:
11605 Vector3 pos1 = new Vector3(block.Data, 0);
11606 11998
11607 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11999 switch (block.Type)
11608 if (handlerUpdatePrimSinglePosition != null) 12000 {
11609 { 12001 case 1: //change position sp
11610 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 12002 udata.position = new Vector3(block.Data, 0);
11611 handlerUpdatePrimSinglePosition(localId, pos1, this);
11612 }
11613 break;
11614 12003
11615 case 2: 12004 udata.change = ObjectChangeType.primP;
11616 Quaternion rot1 = new Quaternion(block.Data, 0, true); 12005 updatehandler(localId, udata, this);
12006 break;
11617 12007
11618 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 12008 case 2: // rotation sp
11619 if (handlerUpdatePrimSingleRotation != null) 12009 udata.rotation = new Quaternion(block.Data, 0, true);
11620 {
11621 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11622 handlerUpdatePrimSingleRotation(localId, rot1, this);
11623 }
11624 break;
11625 12010
11626 case 3: 12011 udata.change = ObjectChangeType.primR;
11627 Vector3 rotPos = new Vector3(block.Data, 0); 12012 updatehandler(localId, udata, this);
11628 Quaternion rot2 = new Quaternion(block.Data, 12, true); 12013 break;
11629 12014
11630 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 12015 case 3: // position plus rotation
11631 if (handlerUpdatePrimSingleRotationPosition != null) 12016 udata.position = new Vector3(block.Data, 0);
11632 { 12017 udata.rotation = new Quaternion(block.Data, 12, true);
11633 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11634 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11635 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11636 }
11637 break;
11638 12018
11639 case 4: 12019 udata.change = ObjectChangeType.primPR;
11640 case 20: 12020 updatehandler(localId, udata, this);
11641 Vector3 scale4 = new Vector3(block.Data, 0); 12021 break;
11642 12022
11643 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 12023 case 4: // scale sp
11644 if (handlerUpdatePrimScale != null) 12024 udata.scale = new Vector3(block.Data, 0);
11645 { 12025 udata.change = ObjectChangeType.primS;
11646 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11647 handlerUpdatePrimScale(localId, scale4, this);
11648 }
11649 break;
11650 12026
11651 case 5: 12027 updatehandler(localId, udata, this);
11652 Vector3 scale1 = new Vector3(block.Data, 12); 12028 break;
11653 Vector3 pos11 = new Vector3(block.Data, 0);
11654 12029
11655 handlerUpdatePrimScale = OnUpdatePrimScale; 12030 case 0x14: // uniform scale sp
11656 if (handlerUpdatePrimScale != null) 12031 udata.scale = new Vector3(block.Data, 0);
11657 {
11658 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11659 handlerUpdatePrimScale(localId, scale1, this);
11660 12032
11661 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12033 udata.change = ObjectChangeType.primUS;
11662 if (handlerUpdatePrimSinglePosition != null) 12034 updatehandler(localId, udata, this);
11663 { 12035 break;
11664 handlerUpdatePrimSinglePosition(localId, pos11, this);
11665 }
11666 }
11667 break;
11668 12036
11669 case 9: 12037 case 5: // scale and position sp
11670 Vector3 pos2 = new Vector3(block.Data, 0); 12038 udata.position = new Vector3(block.Data, 0);
12039 udata.scale = new Vector3(block.Data, 12);
11671 12040
11672 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 12041 udata.change = ObjectChangeType.primPS;
12042 updatehandler(localId, udata, this);
12043 break;
11673 12044
11674 if (handlerUpdateVector != null) 12045 case 0x15: //uniform scale and position
11675 { 12046 udata.position = new Vector3(block.Data, 0);
11676 handlerUpdateVector(localId, pos2, this); 12047 udata.scale = new Vector3(block.Data, 12);
11677 }
11678 break;
11679 12048
11680 case 10: 12049 udata.change = ObjectChangeType.primPUS;
11681 Quaternion rot3 = new Quaternion(block.Data, 0, true); 12050 updatehandler(localId, udata, this);
12051 break;
11682 12052
11683 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 12053 // now group related (bit 4)
11684 if (handlerUpdatePrimRotation != null) 12054 case 9: //( 8 + 1 )group position
11685 { 12055 udata.position = new Vector3(block.Data, 0);
11686 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11687 handlerUpdatePrimRotation(localId, rot3, this);
11688 }
11689 break;
11690 12056
11691 case 11: 12057 udata.change = ObjectChangeType.groupP;
11692 Vector3 pos3 = new Vector3(block.Data, 0); 12058 updatehandler(localId, udata, this);
11693 Quaternion rot4 = new Quaternion(block.Data, 12, true); 12059 break;
11694 12060
11695 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 12061 case 0x0A: // (8 + 2) group rotation
11696 if (handlerUpdatePrimGroupRotation != null) 12062 udata.rotation = new Quaternion(block.Data, 0, true);
11697 {
11698 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11699 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11700 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11701 }
11702 break;
11703 case 12:
11704 case 28:
11705 Vector3 scale7 = new Vector3(block.Data, 0);
11706 12063
11707 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 12064 udata.change = ObjectChangeType.groupR;
11708 if (handlerUpdatePrimGroupScale != null) 12065 updatehandler(localId, udata, this);
11709 { 12066 break;
11710 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11711 handlerUpdatePrimGroupScale(localId, scale7, this);
11712 }
11713 break;
11714 12067
11715 case 13: 12068 case 0x0B: //( 8 + 2 + 1) group rotation and position
11716 Vector3 scale2 = new Vector3(block.Data, 12); 12069 udata.position = new Vector3(block.Data, 0);
11717 Vector3 pos4 = new Vector3(block.Data, 0); 12070 udata.rotation = new Quaternion(block.Data, 12, true);
11718 12071
11719 handlerUpdatePrimScale = OnUpdatePrimScale; 12072 udata.change = ObjectChangeType.groupPR;
11720 if (handlerUpdatePrimScale != null) 12073 updatehandler(localId, udata, this);
11721 { 12074 break;
11722 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11723 handlerUpdatePrimScale(localId, scale2, this);
11724 12075
11725 // Change the position based on scale (for bug number 246) 12076 case 0x0C: // (8 + 4) group scale
11726 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12077 // only afects root prim and only sent by viewer editor object tab scaling
11727 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 12078 // mouse edition only allows uniform scaling
11728 if (handlerUpdatePrimSinglePosition != null) 12079 // SL MAY CHANGE THIS in viewers
11729 {
11730 handlerUpdatePrimSinglePosition(localId, pos4, this);
11731 }
11732 }
11733 break;
11734 12080
11735 case 29: 12081 udata.scale = new Vector3(block.Data, 0);
11736 Vector3 scale5 = new Vector3(block.Data, 12);
11737 Vector3 pos5 = new Vector3(block.Data, 0);
11738 12082
11739 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 12083 udata.change = ObjectChangeType.groupS;
11740 if (handlerUpdatePrimGroupScale != null) 12084 updatehandler(localId, udata, this);
11741 {
11742 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11743 part.StoreUndoState(true);
11744 part.IgnoreUndoUpdate = true;
11745 handlerUpdatePrimGroupScale(localId, scale5, this);
11746 handlerUpdateVector = OnUpdatePrimGroupPosition;
11747 12085
11748 if (handlerUpdateVector != null) 12086 break;
11749 {
11750 handlerUpdateVector(localId, pos5, this);
11751 }
11752 12087
11753 part.IgnoreUndoUpdate = false; 12088 case 0x0D: //(8 + 4 + 1) group scale and position
11754 } 12089 // exception as above
11755 12090
11756 break; 12091 udata.position = new Vector3(block.Data, 0);
12092 udata.scale = new Vector3(block.Data, 12);
11757 12093
11758 case 21: 12094 udata.change = ObjectChangeType.groupPS;
11759 Vector3 scale6 = new Vector3(block.Data, 12); 12095 updatehandler(localId, udata, this);
11760 Vector3 pos6 = new Vector3(block.Data, 0); 12096 break;
11761 12097
11762 handlerUpdatePrimScale = OnUpdatePrimScale; 12098 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11763 if (handlerUpdatePrimScale != null) 12099 udata.scale = new Vector3(block.Data, 0);
11764 {
11765 part.StoreUndoState(false);
11766 part.IgnoreUndoUpdate = true;
11767 12100
11768 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 12101 udata.change = ObjectChangeType.groupUS;
11769 handlerUpdatePrimScale(localId, scale6, this); 12102 updatehandler(localId, udata, this);
11770 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12103 break;
11771 if (handlerUpdatePrimSinglePosition != null)
11772 {
11773 handlerUpdatePrimSinglePosition(localId, pos6, this);
11774 }
11775 12104
11776 part.IgnoreUndoUpdate = false; 12105 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11777 } 12106 udata.position = new Vector3(block.Data, 0);
11778 break; 12107 udata.scale = new Vector3(block.Data, 12);
11779 12108
11780 default: 12109 udata.change = ObjectChangeType.groupPUS;
11781 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 12110 updatehandler(localId, udata, this);
11782 break; 12111 break;
12112
12113 default:
12114 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
12115 break;
12116 }
11783 } 12117 }
11784 12118
11785// for (int j = 0; j < parts.Length; j++)
11786// parts[j].IgnoreUndoUpdate = false;
11787 } 12119 }
11788 } 12120 }
11789 } 12121 }
11790
11791 return true; 12122 return true;
11792 } 12123 }
11793 12124
@@ -11848,9 +12179,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11848 public void SetChildAgentThrottle(byte[] throttles) 12179 public void SetChildAgentThrottle(byte[] throttles)
11849 { 12180 {
11850 m_udpClient.SetThrottles(throttles); 12181 m_udpClient.SetThrottles(throttles);
12182 GenericCall2 handler = OnUpdateThrottles;
12183 if (handler != null)
12184 {
12185 handler();
12186 }
11851 } 12187 }
11852 12188
11853 /// <summary> 12189 /// <summary>
12190 /// Sets the throttles from values supplied by the client
12191 /// </summary>
12192 /// <param name="throttles"></param>
12193 public void SetAgentThrottleSilent(int throttle, int setting)
12194 {
12195 m_udpClient.ForceThrottleSetting(throttle,setting);
12196 //m_udpClient.SetThrottles(throttles);
12197
12198 }
12199
12200
12201 /// <summary>
11854 /// Get the current throttles for this client as a packed byte array 12202 /// Get the current throttles for this client as a packed byte array
11855 /// </summary> 12203 /// </summary>
11856 /// <param name="multiplier">Unused</param> 12204 /// <param name="multiplier">Unused</param>
@@ -12231,7 +12579,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12231// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12579// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12232// requestID, taskID, (SourceType)sourceType, Name); 12580// requestID, taskID, (SourceType)sourceType, Name);
12233 12581
12582
12583 //Note, the bool returned from the below function is useless since it is always false.
12234 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12584 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12585
12235 } 12586 }
12236 12587
12237 /// <summary> 12588 /// <summary>
@@ -12297,7 +12648,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12297 /// <returns></returns> 12648 /// <returns></returns>
12298 private static int CalculateNumPackets(byte[] data) 12649 private static int CalculateNumPackets(byte[] data)
12299 { 12650 {
12300 const uint m_maxPacketSize = 600; 12651// const uint m_maxPacketSize = 600;
12652 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12301 int numPackets = 1; 12653 int numPackets = 1;
12302 12654
12303 if (data == null) 12655 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 8eb2e06..d008702 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
@@ -1376,10 +1419,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1376 { 1419 {
1377 AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code); 1420 AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code);
1378 bool tp = (aCircuit.teleportFlags > 0); 1421 bool tp = (aCircuit.teleportFlags > 0);
1379 // Let's delay this for TP agents, otherwise the viewer doesn't know where to get meshes from
1380 if (!tp) 1422 if (!tp)
1381 client.SceneAgent.SendInitialDataToMe(); 1423 client.SceneAgent.SendInitialDataToMe();
1382 } 1424 }
1425
1426 // Now we know we can handle more data
1427 Thread.Sleep(200);
1428
1429 // Obtain the queue and remove it from the cache
1430 Queue<UDPPacketBuffer> queue = null;
1431
1432 lock (m_pendingCache)
1433 {
1434 if (!m_pendingCache.TryGetValue(endPoint, out queue))
1435 {
1436 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1437 return;
1438 }
1439 m_pendingCache.Remove(endPoint);
1440 }
1441
1442 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
1443
1444 // Reinject queued packets
1445 while(queue.Count > 0)
1446 {
1447 UDPPacketBuffer buf = queue.Dequeue();
1448 PacketReceived(buf);
1449 }
1450 queue = null;
1383 } 1451 }
1384 else 1452 else
1385 { 1453 {
@@ -1387,6 +1455,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1387 m_log.WarnFormat( 1455 m_log.WarnFormat(
1388 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1456 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
1389 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); 1457 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
1458 lock (m_pendingCache)
1459 m_pendingCache.Remove(endPoint);
1390 } 1460 }
1391 1461
1392 // m_log.DebugFormat( 1462 // m_log.DebugFormat(
@@ -1505,7 +1575,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1505 if (!client.SceneAgent.IsChildAgent) 1575 if (!client.SceneAgent.IsChildAgent)
1506 client.Kick("Simulator logged you out due to connection timeout"); 1576 client.Kick("Simulator logged you out due to connection timeout");
1507 1577
1508 client.CloseWithoutChecks(); 1578 client.CloseWithoutChecks(true);
1509 } 1579 }
1510 } 1580 }
1511 1581
@@ -1517,6 +1587,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1517 1587
1518 while (IsRunningInbound) 1588 while (IsRunningInbound)
1519 { 1589 {
1590 m_scene.ThreadAlive(1);
1520 try 1591 try
1521 { 1592 {
1522 IncomingPacket incomingPacket = null; 1593 IncomingPacket incomingPacket = null;
@@ -1564,6 +1635,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1564 1635
1565 while (base.IsRunningOutbound) 1636 while (base.IsRunningOutbound)
1566 { 1637 {
1638 m_scene.ThreadAlive(2);
1567 try 1639 try
1568 { 1640 {
1569 m_packetSent = false; 1641 m_packetSent = false;
@@ -1794,8 +1866,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1794 Packet packet = incomingPacket.Packet; 1866 Packet packet = incomingPacket.Packet;
1795 LLClientView client = incomingPacket.Client; 1867 LLClientView client = incomingPacket.Client;
1796 1868
1797 if (client.IsActive) 1869// if (client.IsActive)
1798 { 1870// {
1799 m_currentIncomingClient = client; 1871 m_currentIncomingClient = client;
1800 1872
1801 try 1873 try
@@ -1822,13 +1894,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1822 { 1894 {
1823 m_currentIncomingClient = null; 1895 m_currentIncomingClient = null;
1824 } 1896 }
1825 } 1897// }
1826 else 1898// else
1827 { 1899// {
1828 m_log.DebugFormat( 1900// m_log.DebugFormat(
1829 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 1901// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
1830 packet.Type, client.Name, m_scene.RegionInfo.RegionName); 1902// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
1831 } 1903// }
1832 1904
1833 IncomingPacketsProcessed++; 1905 IncomingPacketsProcessed++;
1834 } 1906 }
@@ -1840,8 +1912,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1840 if (!client.IsLoggingOut) 1912 if (!client.IsLoggingOut)
1841 { 1913 {
1842 client.IsLoggingOut = true; 1914 client.IsLoggingOut = true;
1843 client.Close(); 1915 client.Close(false, false);
1844 } 1916 }
1845 } 1917 }
1846 } 1918 }
1847} \ No newline at end of file 1919}
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,