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.cs1229
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs69
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs219
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs4
5 files changed, 972 insertions, 552 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
index afbe56b..3995620 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
@@ -234,6 +234,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
234 m_stopPacket = TexturePacketCount(); 234 m_stopPacket = TexturePacketCount();
235 } 235 }
236 236
237 //Give them at least two packets, to play nice with some broken viewers (SL also behaves this way)
238 if (m_stopPacket == 1 && m_layers[0].End > FIRST_PACKET_SIZE) m_stopPacket++;
239
237 m_currentPacket = StartPacket; 240 m_currentPacket = StartPacket;
238 } 241 }
239 } 242 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 4fd81fa..8e0b72f 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -99,6 +99,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
99 public event AvatarPickerRequest OnAvatarPickerRequest; 99 public event AvatarPickerRequest OnAvatarPickerRequest;
100 public event StartAnim OnStartAnim; 100 public event StartAnim OnStartAnim;
101 public event StopAnim OnStopAnim; 101 public event StopAnim OnStopAnim;
102 public event ChangeAnim OnChangeAnim;
102 public event Action<IClientAPI> OnRequestAvatarsData; 103 public event Action<IClientAPI> OnRequestAvatarsData;
103 public event LinkObjects OnLinkObjects; 104 public event LinkObjects OnLinkObjects;
104 public event DelinkObjects OnDelinkObjects; 105 public event DelinkObjects OnDelinkObjects;
@@ -126,6 +127,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
126 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; 127 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
127 public event UpdatePrimFlags OnUpdatePrimFlags; 128 public event UpdatePrimFlags OnUpdatePrimFlags;
128 public event UpdatePrimTexture OnUpdatePrimTexture; 129 public event UpdatePrimTexture OnUpdatePrimTexture;
130 public event ClientChangeObject onClientChangeObject;
129 public event UpdateVector OnUpdatePrimGroupPosition; 131 public event UpdateVector OnUpdatePrimGroupPosition;
130 public event UpdateVector OnUpdatePrimSinglePosition; 132 public event UpdateVector OnUpdatePrimSinglePosition;
131 public event UpdatePrimRotation OnUpdatePrimGroupRotation; 133 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
@@ -159,6 +161,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
159 public event RequestTaskInventory OnRequestTaskInventory; 161 public event RequestTaskInventory OnRequestTaskInventory;
160 public event UpdateInventoryItem OnUpdateInventoryItem; 162 public event UpdateInventoryItem OnUpdateInventoryItem;
161 public event CopyInventoryItem OnCopyInventoryItem; 163 public event CopyInventoryItem OnCopyInventoryItem;
164 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
162 public event MoveInventoryItem OnMoveInventoryItem; 165 public event MoveInventoryItem OnMoveInventoryItem;
163 public event RemoveInventoryItem OnRemoveInventoryItem; 166 public event RemoveInventoryItem OnRemoveInventoryItem;
164 public event RemoveInventoryFolder OnRemoveInventoryFolder; 167 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -257,7 +260,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
257 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 260 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
258 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 261 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
259 public event ClassifiedDelete OnClassifiedDelete; 262 public event ClassifiedDelete OnClassifiedDelete;
260 public event ClassifiedDelete OnClassifiedGodDelete; 263 public event ClassifiedGodDelete OnClassifiedGodDelete;
261 public event EventNotificationAddRequest OnEventNotificationAddRequest; 264 public event EventNotificationAddRequest OnEventNotificationAddRequest;
262 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 265 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
263 public event EventGodDelete OnEventGodDelete; 266 public event EventGodDelete OnEventGodDelete;
@@ -288,10 +291,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
288 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; 291 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
289 public event SimWideDeletesDelegate OnSimWideDeletes; 292 public event SimWideDeletesDelegate OnSimWideDeletes;
290 public event SendPostcard OnSendPostcard; 293 public event SendPostcard OnSendPostcard;
294 public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
291 public event MuteListEntryUpdate OnUpdateMuteListEntry; 295 public event MuteListEntryUpdate OnUpdateMuteListEntry;
292 public event MuteListEntryRemove OnRemoveMuteListEntry; 296 public event MuteListEntryRemove OnRemoveMuteListEntry;
293 public event GodlikeMessage onGodlikeMessage; 297 public event GodlikeMessage onGodlikeMessage;
294 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate; 298 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
299 public event GenericCall2 OnUpdateThrottles;
295 300
296 #endregion Events 301 #endregion Events
297 302
@@ -326,6 +331,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
326 private Prioritizer m_prioritizer; 331 private Prioritizer m_prioritizer;
327 private bool m_disableFacelights = false; 332 private bool m_disableFacelights = false;
328 333
334 private const uint MaxTransferBytesPerPacket = 600;
335
336
329 /// <value> 337 /// <value>
330 /// List used in construction of data blocks for an object update packet. This is to stop us having to 338 /// List used in construction of data blocks for an object update packet. This is to stop us having to
331 /// continually recreate it. 339 /// continually recreate it.
@@ -337,14 +345,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
337 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 345 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
338 /// ownerless phantom. 346 /// ownerless phantom.
339 /// 347 ///
340 /// All manipulation of this set has to occur under a lock 348 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
341 /// 349 ///
342 /// </value> 350 /// </value>
343 protected HashSet<uint> m_killRecord; 351// protected HashSet<uint> m_killRecord;
344 352
345// protected HashSet<uint> m_attachmentsSent; 353// protected HashSet<uint> m_attachmentsSent;
346 354
347 private int m_moneyBalance; 355 private int m_moneyBalance;
356 private bool m_deliverPackets = true;
348 private int m_animationSequenceNumber = 1; 357 private int m_animationSequenceNumber = 1;
349 private bool m_SendLogoutPacketWhenClosing = true; 358 private bool m_SendLogoutPacketWhenClosing = true;
350 359
@@ -391,6 +400,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
391 get { return m_startpos; } 400 get { return m_startpos; }
392 set { m_startpos = value; } 401 set { m_startpos = value; }
393 } 402 }
403 public bool DeliverPackets
404 {
405 get { return m_deliverPackets; }
406 set {
407 m_deliverPackets = value;
408 m_udpClient.m_deliverPackets = value;
409 }
410 }
394 public UUID AgentId { get { return m_agentId; } } 411 public UUID AgentId { get { return m_agentId; } }
395 public ISceneAgent SceneAgent { get; set; } 412 public ISceneAgent SceneAgent { get; set; }
396 public UUID ActiveGroupId { get { return m_activeGroupID; } } 413 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -468,7 +485,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
468 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 485 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
469 m_entityProps = new PriorityQueue(m_scene.Entities.Count); 486 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
470 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 487 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
471 m_killRecord = new HashSet<uint>(); 488// m_killRecord = new HashSet<uint>();
472// m_attachmentsSent = new HashSet<uint>(); 489// m_attachmentsSent = new HashSet<uint>();
473 490
474 m_assetService = m_scene.RequestModuleInterface<IAssetService>(); 491 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
@@ -498,12 +515,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
498 515
499 #region Client Methods 516 #region Client Methods
500 517
518
519 /// <summary>
520 /// Close down the client view
521 /// </summary>
501 public void Close() 522 public void Close()
502 { 523 {
503 Close(false); 524 Close(true, false);
504 } 525 }
505 526
506 public void Close(bool force) 527 public void Close(bool sendStop, bool force)
507 { 528 {
508 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. 529 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
509 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. 530 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
@@ -515,7 +536,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
515 return; 536 return;
516 537
517 IsActive = false; 538 IsActive = false;
518 CloseWithoutChecks(); 539 CloseWithoutChecks(sendStop);
519 } 540 }
520 } 541 }
521 542
@@ -528,12 +549,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
528 /// 549 ///
529 /// Callers must lock ClosingSyncLock before calling. 550 /// Callers must lock ClosingSyncLock before calling.
530 /// </remarks> 551 /// </remarks>
531 public void CloseWithoutChecks() 552 public void CloseWithoutChecks(bool sendStop)
532 { 553 {
533 m_log.DebugFormat( 554 m_log.DebugFormat(
534 "[CLIENT]: Close has been called for {0} attached to scene {1}", 555 "[CLIENT]: Close has been called for {0} attached to scene {1}",
535 Name, m_scene.RegionInfo.RegionName); 556 Name, m_scene.RegionInfo.RegionName);
536 557
558 if (sendStop)
559 {
560 // Send the STOP packet
561 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
562 OutPacket(disable, ThrottleOutPacketType.Unknown);
563 }
564
537 // Shutdown the image manager 565 // Shutdown the image manager
538 ImageManager.Close(); 566 ImageManager.Close();
539 567
@@ -791,7 +819,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
791 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType); 819 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType);
792 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes; 820 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes;
793 821
794 OutPacket(handshake, ThrottleOutPacketType.Task); 822// OutPacket(handshake, ThrottleOutPacketType.Task);
823 // use same as MoveAgentIntoRegion (both should be task )
824 OutPacket(handshake, ThrottleOutPacketType.Unknown);
795 } 825 }
796 826
797 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) 827 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
@@ -831,7 +861,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
831 reply.ChatData.OwnerID = ownerID; 861 reply.ChatData.OwnerID = ownerID;
832 reply.ChatData.SourceID = fromAgentID; 862 reply.ChatData.SourceID = fromAgentID;
833 863
834 OutPacket(reply, ThrottleOutPacketType.Task); 864 OutPacket(reply, ThrottleOutPacketType.Unknown);
835 } 865 }
836 866
837 /// <summary> 867 /// <summary>
@@ -1117,6 +1147,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1117 public virtual void SendLayerData(float[] map) 1147 public virtual void SendLayerData(float[] map)
1118 { 1148 {
1119 Util.FireAndForget(DoSendLayerData, map); 1149 Util.FireAndForget(DoSendLayerData, map);
1150
1151 // Send it sync, and async. It's not that much data
1152 // and it improves user experience just so much!
1153 DoSendLayerData(map);
1120 } 1154 }
1121 1155
1122 /// <summary> 1156 /// <summary>
@@ -1129,16 +1163,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1129 1163
1130 try 1164 try
1131 { 1165 {
1132 //for (int y = 0; y < 16; y++) 1166 for (int y = 0; y < 16; y++)
1133 //{ 1167 {
1134 // for (int x = 0; x < 16; x++) 1168 for (int x = 0; x < 16; x+=4)
1135 // { 1169 {
1136 // SendLayerData(x, y, map); 1170 SendLayerPacket(x, y, map);
1137 // } 1171 }
1138 //} 1172 }
1139
1140 // Send LayerData in a spiral pattern. Fun!
1141 SendLayerTopRight(map, 0, 0, 15, 15);
1142 } 1173 }
1143 catch (Exception e) 1174 catch (Exception e)
1144 { 1175 {
@@ -1146,51 +1177,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1146 } 1177 }
1147 } 1178 }
1148 1179
1149 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1150 {
1151 // Row
1152 for (int i = x1; i <= x2; i++)
1153 SendLayerData(i, y1, map);
1154
1155 // Column
1156 for (int j = y1 + 1; j <= y2; j++)
1157 SendLayerData(x2, j, map);
1158
1159 if (x2 - x1 > 0)
1160 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1161 }
1162
1163 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1164 {
1165 // Row in reverse
1166 for (int i = x2; i >= x1; i--)
1167 SendLayerData(i, y2, map);
1168
1169 // Column in reverse
1170 for (int j = y2 - 1; j >= y1; j--)
1171 SendLayerData(x1, j, map);
1172
1173 if (x2 - x1 > 0)
1174 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1175 }
1176
1177 /// <summary> 1180 /// <summary>
1178 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1181 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1179 /// </summary> 1182 /// </summary>
1180 /// <param name="map">heightmap</param> 1183 /// <param name="map">heightmap</param>
1181 /// <param name="px">X coordinate for patches 0..12</param> 1184 /// <param name="px">X coordinate for patches 0..12</param>
1182 /// <param name="py">Y coordinate for patches 0..15</param> 1185 /// <param name="py">Y coordinate for patches 0..15</param>
1183 // private void SendLayerPacket(float[] map, int y, int x) 1186 private void SendLayerPacket(int x, int y, float[] map)
1184 // { 1187 {
1185 // int[] patches = new int[4]; 1188 int[] patches = new int[4];
1186 // patches[0] = x + 0 + y * 16; 1189 patches[0] = x + 0 + y * 16;
1187 // patches[1] = x + 1 + y * 16; 1190 patches[1] = x + 1 + y * 16;
1188 // patches[2] = x + 2 + y * 16; 1191 patches[2] = x + 2 + y * 16;
1189 // patches[3] = x + 3 + y * 16; 1192 patches[3] = x + 3 + y * 16;
1190 1193
1191 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1194 float[] heightmap = (map.Length == 65536) ?
1192 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1195 map :
1193 // } 1196 LLHeightFieldMoronize(map);
1197
1198 try
1199 {
1200 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1201 OutPacket(layerpack, ThrottleOutPacketType.Land);
1202 }
1203 catch
1204 {
1205 for (int px = x ; px < x + 4 ; px++)
1206 SendLayerData(px, y, map);
1207 }
1208 }
1194 1209
1195 /// <summary> 1210 /// <summary>
1196 /// Sends a specified patch to a client 1211 /// Sends a specified patch to a client
@@ -1210,7 +1225,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1210 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1225 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1211 layerpack.Header.Reliable = true; 1226 layerpack.Header.Reliable = true;
1212 1227
1213 OutPacket(layerpack, ThrottleOutPacketType.Land); 1228 OutPacket(layerpack, ThrottleOutPacketType.Task);
1214 } 1229 }
1215 catch (Exception e) 1230 catch (Exception e)
1216 { 1231 {
@@ -1573,7 +1588,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1573 1588
1574 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1589 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1575 { 1590 {
1576// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1591// foreach (uint id in localIDs)
1592// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1577 1593
1578 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1594 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1579 // TODO: don't create new blocks if recycling an old packet 1595 // TODO: don't create new blocks if recycling an old packet
@@ -1595,17 +1611,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1595 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race 1611 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
1596 // condition where a kill can be processed before an out-of-date update for the same object. 1612 // condition where a kill can be processed before an out-of-date update for the same object.
1597 // ProcessEntityUpdates() also takes the m_killRecord lock. 1613 // ProcessEntityUpdates() also takes the m_killRecord lock.
1598 lock (m_killRecord) 1614// lock (m_killRecord)
1599 { 1615// {
1600 foreach (uint localID in localIDs) 1616// foreach (uint localID in localIDs)
1601 m_killRecord.Add(localID); 1617// m_killRecord.Add(localID);
1602 1618
1603 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1619 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1604 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1620 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1605 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1621 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1606 // scene objects in a viewer until that viewer is relogged in. 1622 // scene objects in a viewer until that viewer is relogged in.
1607 OutPacket(kill, ThrottleOutPacketType.Task); 1623 OutPacket(kill, ThrottleOutPacketType.Task);
1608 } 1624// }
1609 } 1625 }
1610 } 1626 }
1611 1627
@@ -2063,9 +2079,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2063 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); 2079 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
2064 } 2080 }
2065 2081
2066 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2067 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId) 2082 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
2068 { 2083 {
2084 SendInventoryItemCreateUpdate(Item, UUID.Zero, callbackId);
2085 }
2086
2087 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2088 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId)
2089 {
2069 const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; 2090 const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All;
2070 2091
2071 UpdateCreateInventoryItemPacket InventoryReply 2092 UpdateCreateInventoryItemPacket InventoryReply
@@ -2075,6 +2096,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2075 // TODO: don't create new blocks if recycling an old packet 2096 // TODO: don't create new blocks if recycling an old packet
2076 InventoryReply.AgentData.AgentID = AgentId; 2097 InventoryReply.AgentData.AgentID = AgentId;
2077 InventoryReply.AgentData.SimApproved = true; 2098 InventoryReply.AgentData.SimApproved = true;
2099 InventoryReply.AgentData.TransactionID = transactionID;
2078 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1]; 2100 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1];
2079 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock(); 2101 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock();
2080 InventoryReply.InventoryData[0].ItemID = Item.ID; 2102 InventoryReply.InventoryData[0].ItemID = Item.ID;
@@ -2144,16 +2166,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2144 replytask.InventoryData.TaskID = taskID; 2166 replytask.InventoryData.TaskID = taskID;
2145 replytask.InventoryData.Serial = serial; 2167 replytask.InventoryData.Serial = serial;
2146 replytask.InventoryData.Filename = fileName; 2168 replytask.InventoryData.Filename = fileName;
2147 OutPacket(replytask, ThrottleOutPacketType.Asset); 2169 OutPacket(replytask, ThrottleOutPacketType.Task);
2148 } 2170 }
2149 2171
2150 public void SendXferPacket(ulong xferID, uint packet, byte[] data) 2172 public void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory)
2151 { 2173 {
2174 ThrottleOutPacketType type = ThrottleOutPacketType.Asset;
2175 if (isTaskInventory)
2176 type = ThrottleOutPacketType.Task;
2177
2152 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket); 2178 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket);
2153 sendXfer.XferID.ID = xferID; 2179 sendXfer.XferID.ID = xferID;
2154 sendXfer.XferID.Packet = packet; 2180 sendXfer.XferID.Packet = packet;
2155 sendXfer.DataPacket.Data = data; 2181 sendXfer.DataPacket.Data = data;
2156 OutPacket(sendXfer, ThrottleOutPacketType.Asset); 2182 OutPacket(sendXfer, type);
2157 } 2183 }
2158 2184
2159 public void SendAbortXferPacket(ulong xferID) 2185 public void SendAbortXferPacket(ulong xferID)
@@ -2335,6 +2361,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2335 OutPacket(sound, ThrottleOutPacketType.Task); 2361 OutPacket(sound, ThrottleOutPacketType.Task);
2336 } 2362 }
2337 2363
2364 public void SendTransferAbort(TransferRequestPacket transferRequest)
2365 {
2366 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2367 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2368 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2369 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2370 OutPacket(abort, ThrottleOutPacketType.Task);
2371 }
2372
2338 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2373 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2339 { 2374 {
2340 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2375 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2627,6 +2662,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2627 } 2662 }
2628 } 2663 }
2629 2664
2665 public void SendPartPhysicsProprieties(ISceneEntity entity)
2666 {
2667 SceneObjectPart part = (SceneObjectPart)entity;
2668 if (part != null && AgentId != UUID.Zero)
2669 {
2670 try
2671 {
2672 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
2673 if (eq != null)
2674 {
2675 uint localid = part.LocalId;
2676 byte physshapetype = part.PhysicsShapeType;
2677 float density = part.Density;
2678 float friction = part.Friction;
2679 float bounce = part.Bounciness;
2680 float gravmod = part.GravityModifier;
2681
2682 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2683 }
2684 }
2685 catch (Exception ex)
2686 {
2687 m_log.Error("Unable to send part Physics Proprieties - exception: " + ex.ToString());
2688 }
2689 part.UpdatePhysRequired = false;
2690 }
2691 }
2692
2693
2630 2694
2631 public void SendGroupNameReply(UUID groupLLUID, string GroupName) 2695 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
2632 { 2696 {
@@ -2724,7 +2788,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2724 else 2788 else
2725 { 2789 {
2726 int processedLength = 0; 2790 int processedLength = 0;
2727 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2791// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2792
2793 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2728 int packetNumber = 0; 2794 int packetNumber = 0;
2729 2795
2730 while (processedLength < req.AssetInf.Data.Length) 2796 while (processedLength < req.AssetInf.Data.Length)
@@ -2795,7 +2861,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2795 reply.Data.ParcelID = parcelID; 2861 reply.Data.ParcelID = parcelID;
2796 reply.Data.OwnerID = land.OwnerID; 2862 reply.Data.OwnerID = land.OwnerID;
2797 reply.Data.Name = Utils.StringToBytes(land.Name); 2863 reply.Data.Name = Utils.StringToBytes(land.Name);
2798 reply.Data.Desc = Utils.StringToBytes(land.Description); 2864 if (land != null && land.Description != null && land.Description != String.Empty)
2865 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2866 else
2867 reply.Data.Desc = new Byte[0];
2799 reply.Data.ActualArea = land.Area; 2868 reply.Data.ActualArea = land.Area;
2800 reply.Data.BillableArea = land.Area; // TODO: what is this? 2869 reply.Data.BillableArea = land.Area; // TODO: what is this?
2801 2870
@@ -3530,7 +3599,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3530 3599
3531 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3600 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3532 // TODO: don't create new blocks if recycling an old packet 3601 // TODO: don't create new blocks if recycling an old packet
3533 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3602 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3534 avp.ObjectData.TextureEntry = textureEntry; 3603 avp.ObjectData.TextureEntry = textureEntry;
3535 3604
3536 AvatarAppearancePacket.VisualParamBlock avblock = null; 3605 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3660,7 +3729,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3660 /// </summary> 3729 /// </summary>
3661 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3730 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3662 { 3731 {
3663 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3732 if (entity is SceneObjectPart)
3733 {
3734 SceneObjectPart e = (SceneObjectPart)entity;
3735 SceneObjectGroup g = e.ParentGroup;
3736 if (g.RootPart.Shape.State > 30) // HUD
3737 if (g.OwnerID != AgentId)
3738 return; // Don't send updates for other people's HUDs
3739 }
3740
3664 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3741 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3665 3742
3666 lock (m_entityUpdates.SyncRoot) 3743 lock (m_entityUpdates.SyncRoot)
@@ -3727,27 +3804,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3727 3804
3728 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3805 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3729 // condition where a kill can be processed before an out-of-date update for the same object. 3806 // condition where a kill can be processed before an out-of-date update for the same object.
3730 lock (m_killRecord) 3807 float avgTimeDilation = 1.0f;
3808 IEntityUpdate iupdate;
3809 Int32 timeinqueue; // this is just debugging code & can be dropped later
3810
3811 while (updatesThisCall < maxUpdates)
3731 { 3812 {
3732 float avgTimeDilation = 1.0f; 3813 lock (m_entityUpdates.SyncRoot)
3733 IEntityUpdate iupdate; 3814 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3734 Int32 timeinqueue; // this is just debugging code & can be dropped later 3815 break;
3816
3817 EntityUpdate update = (EntityUpdate)iupdate;
3818
3819 avgTimeDilation += update.TimeDilation;
3820 avgTimeDilation *= 0.5f;
3735 3821
3736 while (updatesThisCall < maxUpdates) 3822 if (update.Entity is SceneObjectPart)
3737 { 3823 {
3738 lock (m_entityUpdates.SyncRoot) 3824 SceneObjectPart part = (SceneObjectPart)update.Entity;
3739 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3740 break;
3741 3825
3742 EntityUpdate update = (EntityUpdate)iupdate; 3826 if (part.ParentGroup.IsDeleted)
3743 3827 continue;
3744 avgTimeDilation += update.TimeDilation;
3745 avgTimeDilation *= 0.5f;
3746 3828
3747 if (update.Entity is SceneObjectPart) 3829 if (part.ParentGroup.IsAttachment)
3830 { // Someone else's HUD, why are we getting these?
3831 if (part.ParentGroup.OwnerID != AgentId &&
3832 part.ParentGroup.RootPart.Shape.State > 30)
3833 continue;
3834 ScenePresence sp;
3835 // Owner is not in the sim, don't update it to
3836 // anyone
3837 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3838 continue;
3839
3840 List<SceneObjectGroup> atts = sp.GetAttachments();
3841 bool found = false;
3842 foreach (SceneObjectGroup att in atts)
3843 {
3844 if (att == part.ParentGroup)
3845 {
3846 found = true;
3847 break;
3848 }
3849 }
3850
3851 // It's an attachment of a valid avatar, but
3852 // doesn't seem to be attached, skip
3853 if (!found)
3854 continue;
3855
3856 // On vehicle crossing, the attachments are received
3857 // while the avatar is still a child. Don't send
3858 // updates here because the LocalId has not yet
3859 // been updated and the viewer will derender the
3860 // attachments until the avatar becomes root.
3861 if (sp.IsChildAgent)
3862 continue;
3863
3864 // If the object is an attachment we don't want it to be in the kill
3865 // record. Else attaching from inworld and subsequently dropping
3866 // it will no longer work.
3867// lock (m_killRecord)
3868// {
3869// m_killRecord.Remove(part.LocalId);
3870// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3871// }
3872 }
3873 else
3748 { 3874 {
3749 SceneObjectPart part = (SceneObjectPart)update.Entity;
3750
3751 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3875 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3752 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3876 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3753 // safety measure. 3877 // safety measure.
@@ -3758,241 +3882,177 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3758 // 3882 //
3759 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3883 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3760 // after the root prim has been deleted. 3884 // after the root prim has been deleted.
3761 if (m_killRecord.Contains(part.LocalId)) 3885 //
3762 { 3886 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3763 // m_log.WarnFormat( 3887// lock (m_killRecord)
3764 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3888// {
3765 // part.LocalId, Name); 3889// if (m_killRecord.Contains(part.LocalId))
3766 continue; 3890// continue;
3767 } 3891// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3768 3892// continue;
3769 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3893// }
3894 }
3895
3896 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3897 {
3898 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3899 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3770 { 3900 {
3771 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3901 part.Shape.LightEntry = false;
3772 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3773 {
3774 part.Shape.LightEntry = false;
3775 }
3776 } 3902 }
3777 } 3903 }
3778 3904 }
3779 #region UpdateFlags to packet type conversion 3905
3780 3906 ++updatesThisCall;
3781 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; 3907
3782 3908 #region UpdateFlags to packet type conversion
3783 bool canUseCompressed = true; 3909
3784 bool canUseImproved = true; 3910 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3785 3911
3786 // Compressed object updates only make sense for LL primitives 3912 bool canUseCompressed = true;
3787 if (!(update.Entity is SceneObjectPart)) 3913 bool canUseImproved = true;
3914
3915 // Compressed object updates only make sense for LL primitives
3916 if (!(update.Entity is SceneObjectPart))
3917 {
3918 canUseCompressed = false;
3919 }
3920
3921 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3922 {
3923 canUseCompressed = false;
3924 canUseImproved = false;
3925 }
3926 else
3927 {
3928 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3929 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3930 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3931 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3788 { 3932 {
3789 canUseCompressed = false; 3933 canUseCompressed = false;
3790 } 3934 }
3791 3935
3792 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 3936 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3937 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3938 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3939 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3940 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3941 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3942 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3943 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3944 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3945 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3946 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3947 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3948 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3949 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3793 { 3950 {
3794 canUseCompressed = false;
3795 canUseImproved = false; 3951 canUseImproved = false;
3796 } 3952 }
3797 else 3953 }
3798 {
3799 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3800 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3801 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3802 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3803 {
3804 canUseCompressed = false;
3805 }
3806
3807 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3808 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3809 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3810 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3811 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3812 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3813 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3814 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3815 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3816 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3817 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3818 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3819 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3820 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3821 {
3822 canUseImproved = false;
3823 }
3824 }
3825
3826 #endregion UpdateFlags to packet type conversion
3827
3828 #region Block Construction
3829
3830 // TODO: Remove this once we can build compressed updates
3831 canUseCompressed = false;
3832 3954
3833 if (!canUseImproved && !canUseCompressed) 3955 #endregion UpdateFlags to packet type conversion
3834 {
3835 ObjectUpdatePacket.ObjectDataBlock updateBlock;
3836 3956
3837 if (update.Entity is ScenePresence) 3957 #region Block Construction
3838 {
3839 updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
3840 }
3841 else
3842 {
3843 SceneObjectPart part = (SceneObjectPart)update.Entity;
3844 updateBlock = CreatePrimUpdateBlock(part, AgentId);
3845
3846 // If the part has become a private hud since the update was scheduled then we do not
3847 // want to send it to other avatars.
3848 if (part.ParentGroup.IsAttachment
3849 && part.ParentGroup.HasPrivateAttachmentPoint
3850 && part.ParentGroup.AttachedAvatar != AgentId)
3851 continue;
3852
3853 // If the part has since been deleted, then drop the update. In the case of attachments,
3854 // this is to avoid spurious updates to other viewers since post-processing of attachments
3855 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3856 // of the test above).
3857 //
3858 // Actual deletions (kills) happen in another method.
3859 if (part.ParentGroup.IsDeleted)
3860 continue;
3861 }
3862 3958
3863 objectUpdateBlocks.Value.Add(updateBlock); 3959 // TODO: Remove this once we can build compressed updates
3864 objectUpdates.Value.Add(update); 3960 canUseCompressed = false;
3865 }
3866 else if (!canUseImproved)
3867 {
3868 SceneObjectPart part = (SceneObjectPart)update.Entity;
3869 ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
3870 = CreateCompressedUpdateBlock(part, updateFlags);
3871
3872 // If the part has since been deleted, then drop the update. In the case of attachments,
3873 // this is to avoid spurious updates to other viewers since post-processing of attachments
3874 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3875 // of the test above).
3876 //
3877 // Actual deletions (kills) happen in another method.
3878 if (part.ParentGroup.IsDeleted)
3879 continue;
3880 3961
3881 compressedUpdateBlocks.Value.Add(compressedBlock); 3962 if (!canUseImproved && !canUseCompressed)
3882 compressedUpdates.Value.Add(update); 3963 {
3964 if (update.Entity is ScenePresence)
3965 {
3966 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3883 } 3967 }
3884 else 3968 else
3885 { 3969 {
3886 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3970 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3887 {
3888 // Self updates go into a special list
3889 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3890 terseAgentUpdates.Value.Add(update);
3891 }
3892 else
3893 {
3894 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
3895 = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
3896
3897 // Everything else goes here
3898 if (update.Entity is SceneObjectPart)
3899 {
3900 SceneObjectPart part = (SceneObjectPart)update.Entity;
3901
3902 // If the part has become a private hud since the update was scheduled then we do not
3903 // want to send it to other avatars.
3904 if (part.ParentGroup.IsAttachment
3905 && part.ParentGroup.HasPrivateAttachmentPoint
3906 && part.ParentGroup.AttachedAvatar != AgentId)
3907 continue;
3908
3909 // If the part has since been deleted, then drop the update. In the case of attachments,
3910 // this is to avoid spurious updates to other viewers since post-processing of attachments
3911 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3912 // of the test above).
3913 //
3914 // Actual deletions (kills) happen in another method.
3915 if (part.ParentGroup.IsDeleted)
3916 continue;
3917 }
3918
3919 terseUpdateBlocks.Value.Add(terseUpdateBlock);
3920 terseUpdates.Value.Add(update);
3921 }
3922 } 3971 }
3923
3924 ++updatesThisCall;
3925
3926 #endregion Block Construction
3927 } 3972 }
3928 3973 else if (!canUseImproved)
3929 #region Packet Sending 3974 {
3930 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); 3975 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3931 3976 }
3932 if (terseAgentUpdateBlocks.IsValueCreated) 3977 else
3933 { 3978 {
3934 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 3979 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3980 // Self updates go into a special list
3981 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3982 else
3983 // Everything else goes here
3984 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3985 }
3935 3986
3936 ImprovedTerseObjectUpdatePacket packet 3987 #endregion Block Construction
3937 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 3988 }
3938 3989
3939 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3990 #region Packet Sending
3940 packet.RegionData.TimeDilation = timeDilation; 3991
3941 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3992 const float TIME_DILATION = 1.0f;
3993 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3994
3995 if (terseAgentUpdateBlocks.IsValueCreated)
3996 {
3997 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3942 3998
3943 for (int i = 0; i < blocks.Count; i++) 3999 ImprovedTerseObjectUpdatePacket packet
3944 packet.ObjectData[i] = blocks[i]; 4000 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3945 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4001 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3946 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); }); 4002 packet.RegionData.TimeDilation = timeDilation;
3947 } 4003 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3948 4004
3949 if (objectUpdateBlocks.IsValueCreated) 4005 for (int i = 0; i < blocks.Count; i++)
3950 { 4006 packet.ObjectData[i] = blocks[i];
3951 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3952
3953 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3954 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3955 packet.RegionData.TimeDilation = timeDilation;
3956 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3957
3958 for (int i = 0; i < blocks.Count; i++)
3959 packet.ObjectData[i] = blocks[i];
3960 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3961 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3962 }
3963
3964 if (compressedUpdateBlocks.IsValueCreated)
3965 {
3966 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3967
3968 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3969 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3970 packet.RegionData.TimeDilation = timeDilation;
3971 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3972
3973 for (int i = 0; i < blocks.Count; i++)
3974 packet.ObjectData[i] = blocks[i];
3975 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3976 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3977 }
3978 4007
3979 if (terseUpdateBlocks.IsValueCreated) 4008 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3980 { 4009 }
3981 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3982
3983 ImprovedTerseObjectUpdatePacket packet
3984 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
3985 PacketType.ImprovedTerseObjectUpdate);
3986 4010
3987 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4011 if (objectUpdateBlocks.IsValueCreated)
3988 packet.RegionData.TimeDilation = timeDilation; 4012 {
3989 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4013 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3990 4014
3991 for (int i = 0; i < blocks.Count; i++) 4015 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3992 packet.ObjectData[i] = blocks[i]; 4016 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3993 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4017 packet.RegionData.TimeDilation = timeDilation;
3994 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 4018 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3995 } 4019
4020 for (int i = 0; i < blocks.Count; i++)
4021 packet.ObjectData[i] = blocks[i];
4022
4023 OutPacket(packet, ThrottleOutPacketType.Task, true);
4024 }
4025
4026 if (compressedUpdateBlocks.IsValueCreated)
4027 {
4028 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4029
4030 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4031 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4032 packet.RegionData.TimeDilation = timeDilation;
4033 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4034
4035 for (int i = 0; i < blocks.Count; i++)
4036 packet.ObjectData[i] = blocks[i];
4037
4038 OutPacket(packet, ThrottleOutPacketType.Task, true);
4039 }
4040
4041 if (terseUpdateBlocks.IsValueCreated)
4042 {
4043 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4044
4045 ImprovedTerseObjectUpdatePacket packet
4046 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4047 PacketType.ImprovedTerseObjectUpdate);
4048 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4049 packet.RegionData.TimeDilation = timeDilation;
4050 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4051
4052 for (int i = 0; i < blocks.Count; i++)
4053 packet.ObjectData[i] = blocks[i];
4054
4055 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3996 } 4056 }
3997 4057
3998 #endregion Packet Sending 4058 #endregion Packet Sending
@@ -4285,11 +4345,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4285 4345
4286 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4346 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4287 // of the object rather than the properties when the packet was created 4347 // of the object rather than the properties when the packet was created
4288 OutPacket(packet, ThrottleOutPacketType.Task, true, 4348 // HACK : Remove intelligent resending until it's fixed in core
4289 delegate(OutgoingPacket oPacket) 4349 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4290 { 4350 // delegate(OutgoingPacket oPacket)
4291 ResendPropertyUpdates(updates, oPacket); 4351 // {
4292 }); 4352 // ResendPropertyUpdates(updates, oPacket);
4353 // });
4354 OutPacket(packet, ThrottleOutPacketType.Task, true);
4293 4355
4294 // pbcnt += blocks.Count; 4356 // pbcnt += blocks.Count;
4295 // ppcnt++; 4357 // ppcnt++;
@@ -4315,11 +4377,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4315 // of the object rather than the properties when the packet was created 4377 // of the object rather than the properties when the packet was created
4316 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4378 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4317 updates.Add(familyUpdates.Value[i]); 4379 updates.Add(familyUpdates.Value[i]);
4318 OutPacket(packet, ThrottleOutPacketType.Task, true, 4380 // HACK : Remove intelligent resending until it's fixed in core
4319 delegate(OutgoingPacket oPacket) 4381 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4320 { 4382 // delegate(OutgoingPacket oPacket)
4321 ResendPropertyUpdates(updates, oPacket); 4383 // {
4322 }); 4384 // ResendPropertyUpdates(updates, oPacket);
4385 // });
4386 OutPacket(packet, ThrottleOutPacketType.Task, true);
4323 4387
4324 // fpcnt++; 4388 // fpcnt++;
4325 // fbcnt++; 4389 // fbcnt++;
@@ -4691,7 +4755,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4691 4755
4692 if (landData.SimwideArea > 0) 4756 if (landData.SimwideArea > 0)
4693 { 4757 {
4694 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4758 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4759 // Never report more than sim total capacity
4760 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4761 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4695 updateMessage.SimWideMaxPrims = simulatorCapacity; 4762 updateMessage.SimWideMaxPrims = simulatorCapacity;
4696 } 4763 }
4697 else 4764 else
@@ -4820,14 +4887,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4820 4887
4821 if (notifyCount > 0) 4888 if (notifyCount > 0)
4822 { 4889 {
4823 if (notifyCount > 32) 4890// if (notifyCount > 32)
4824 { 4891// {
4825 m_log.InfoFormat( 4892// m_log.InfoFormat(
4826 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4893// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4827 + " - a developer might want to investigate whether this is a hard limit", 32); 4894// + " - a developer might want to investigate whether this is a hard limit", 32);
4828 4895//
4829 notifyCount = 32; 4896// notifyCount = 32;
4830 } 4897// }
4831 4898
4832 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4899 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4833 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4900 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4882,9 +4949,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4882 { 4949 {
4883 ScenePresence presence = (ScenePresence)entity; 4950 ScenePresence presence = (ScenePresence)entity;
4884 4951
4952 position = presence.OffsetPosition;
4953 rotation = presence.Rotation;
4954
4955 if (presence.ParentID != 0)
4956 {
4957 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4958 if (part != null && part != part.ParentGroup.RootPart)
4959 {
4960 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4961 rotation = part.RotationOffset * presence.Rotation;
4962 }
4963 }
4964
4885 attachPoint = 0; 4965 attachPoint = 0;
4886 collisionPlane = presence.CollisionPlane; 4966 collisionPlane = presence.CollisionPlane;
4887 position = presence.OffsetPosition;
4888 velocity = presence.Velocity; 4967 velocity = presence.Velocity;
4889 acceleration = Vector3.Zero; 4968 acceleration = Vector3.Zero;
4890 4969
@@ -4894,7 +4973,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4894// acceleration = new Vector3(1, 0, 0); 4973// acceleration = new Vector3(1, 0, 0);
4895 4974
4896 angularVelocity = Vector3.Zero; 4975 angularVelocity = Vector3.Zero;
4897 rotation = presence.Rotation;
4898 4976
4899 if (sendTexture) 4977 if (sendTexture)
4900 textureEntry = presence.Appearance.Texture.GetBytes(); 4978 textureEntry = presence.Appearance.Texture.GetBytes();
@@ -5001,13 +5079,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5001 5079
5002 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5080 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
5003 { 5081 {
5082 Vector3 offsetPosition = data.OffsetPosition;
5083 Quaternion rotation = data.Rotation;
5084 uint parentID = data.ParentID;
5085
5086 if (parentID != 0)
5087 {
5088 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5089 if (part != null && part != part.ParentGroup.RootPart)
5090 {
5091 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5092 rotation = part.RotationOffset * data.Rotation;
5093 parentID = part.ParentGroup.RootPart.LocalId;
5094 }
5095 }
5096
5004 byte[] objectData = new byte[76]; 5097 byte[] objectData = new byte[76];
5005 5098
5006 data.CollisionPlane.ToBytes(objectData, 0); 5099 data.CollisionPlane.ToBytes(objectData, 0);
5007 data.OffsetPosition.ToBytes(objectData, 16); 5100 offsetPosition.ToBytes(objectData, 16);
5008// data.Velocity.ToBytes(objectData, 28); 5101// data.Velocity.ToBytes(objectData, 28);
5009// data.Acceleration.ToBytes(objectData, 40); 5102// data.Acceleration.ToBytes(objectData, 40);
5010 data.Rotation.ToBytes(objectData, 52); 5103 rotation.ToBytes(objectData, 52);
5011 //data.AngularVelocity.ToBytes(objectData, 64); 5104 //data.AngularVelocity.ToBytes(objectData, 64);
5012 5105
5013 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5106 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -5021,7 +5114,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5021 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5114 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
5022 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5115 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
5023 update.ObjectData = objectData; 5116 update.ObjectData = objectData;
5024 update.ParentID = data.ParentID; 5117 update.ParentID = parentID;
5025 update.PathCurve = 16; 5118 update.PathCurve = 16;
5026 update.PathScaleX = 100; 5119 update.PathScaleX = 100;
5027 update.PathScaleY = 100; 5120 update.PathScaleY = 100;
@@ -5039,10 +5132,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5039 update.TextureEntry = Utils.EmptyBytes; 5132 update.TextureEntry = Utils.EmptyBytes;
5040// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; 5133// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
5041 5134
5135/* 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)
5042 update.UpdateFlags = (uint)( 5136 update.UpdateFlags = (uint)(
5043 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | 5137 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
5044 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | 5138 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
5045 PrimFlags.ObjectOwnerModify); 5139 PrimFlags.ObjectOwnerModify);
5140*/
5141 update.UpdateFlags = 0;
5046 5142
5047 return update; 5143 return update;
5048 } 5144 }
@@ -5366,6 +5462,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5366 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5462 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5367 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5463 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5368 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5464 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5465 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5369 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5466 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5370 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5467 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5371 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5468 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5432,6 +5529,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5432 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5529 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5433 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5530 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5434 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5531 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5532 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5435 5533
5436 AddGenericPacketHandler("autopilot", HandleAutopilot); 5534 AddGenericPacketHandler("autopilot", HandleAutopilot);
5437 } 5535 }
@@ -5470,6 +5568,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5470 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) || 5568 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) ||
5471 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) || 5569 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) ||
5472 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) || 5570 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) ||
5571 (x.ControlFlags != 0) ||
5473 (x.Far != m_lastAgentUpdateArgs.Far) || 5572 (x.Far != m_lastAgentUpdateArgs.Far) ||
5474 (x.Flags != m_lastAgentUpdateArgs.Flags) || 5573 (x.Flags != m_lastAgentUpdateArgs.Flags) ||
5475 (x.State != m_lastAgentUpdateArgs.State) || 5574 (x.State != m_lastAgentUpdateArgs.State) ||
@@ -6368,6 +6467,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6368 { 6467 {
6369 handlerCompleteMovementToRegion(sender, true); 6468 handlerCompleteMovementToRegion(sender, true);
6370 } 6469 }
6470 else
6471 m_log.Debug("HandleCompleteAgentMovement NULL handler");
6472
6371 handlerCompleteMovementToRegion = null; 6473 handlerCompleteMovementToRegion = null;
6372 6474
6373 return true; 6475 return true;
@@ -6385,7 +6487,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6385 return true; 6487 return true;
6386 } 6488 }
6387 #endregion 6489 #endregion
6388 6490/*
6389 StartAnim handlerStartAnim = null; 6491 StartAnim handlerStartAnim = null;
6390 StopAnim handlerStopAnim = null; 6492 StopAnim handlerStopAnim = null;
6391 6493
@@ -6409,6 +6511,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6409 } 6511 }
6410 } 6512 }
6411 return true; 6513 return true;
6514*/
6515 ChangeAnim handlerChangeAnim = null;
6516
6517 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6518 {
6519 handlerChangeAnim = OnChangeAnim;
6520 if (handlerChangeAnim != null)
6521 {
6522 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6523 }
6524 }
6525
6526 handlerChangeAnim = OnChangeAnim;
6527 if (handlerChangeAnim != null)
6528 {
6529 handlerChangeAnim(UUID.Zero, false, true);
6530 }
6531
6532 return true;
6412 } 6533 }
6413 6534
6414 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6535 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -6633,6 +6754,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6633 #endregion 6754 #endregion
6634 6755
6635 m_udpClient.SetThrottles(atpack.Throttle.Throttles); 6756 m_udpClient.SetThrottles(atpack.Throttle.Throttles);
6757 GenericCall2 handler = OnUpdateThrottles;
6758 if (handler != null)
6759 {
6760 handler();
6761 }
6636 return true; 6762 return true;
6637 } 6763 }
6638 6764
@@ -7034,10 +7160,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7034 // 46,47,48 are special positions within the packet 7160 // 46,47,48 are special positions within the packet
7035 // This may change so perhaps we need a better way 7161 // This may change so perhaps we need a better way
7036 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) 7162 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
7037 bool UsePhysics = (data[46] != 0) ? true : false; 7163 /*
7038 bool IsTemporary = (data[47] != 0) ? true : false; 7164 bool UsePhysics = (data[46] != 0) ? true : false;
7039 bool IsPhantom = (data[48] != 0) ? true : false; 7165 bool IsTemporary = (data[47] != 0) ? true : false;
7040 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this); 7166 bool IsPhantom = (data[48] != 0) ? true : false;
7167 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this);
7168 */
7169 bool UsePhysics = flags.AgentData.UsePhysics;
7170 bool IsPhantom = flags.AgentData.IsPhantom;
7171 bool IsTemporary = flags.AgentData.IsTemporary;
7172 ObjectFlagUpdatePacket.ExtraPhysicsBlock[] blocks = flags.ExtraPhysics;
7173 ExtraPhysicsData physdata = new ExtraPhysicsData();
7174
7175 if (blocks == null || blocks.Length == 0)
7176 {
7177 physdata.PhysShapeType = PhysShapeType.invalid;
7178 }
7179 else
7180 {
7181 ObjectFlagUpdatePacket.ExtraPhysicsBlock phsblock = blocks[0];
7182 physdata.PhysShapeType = (PhysShapeType)phsblock.PhysicsShapeType;
7183 physdata.Bounce = phsblock.Restitution;
7184 physdata.Density = phsblock.Density;
7185 physdata.Friction = phsblock.Friction;
7186 physdata.GravitationModifier = phsblock.GravityMultiplier;
7187 }
7188
7189 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
7041 } 7190 }
7042 return true; 7191 return true;
7043 } 7192 }
@@ -8638,16 +8787,61 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8638 8787
8639 #region Parcel related packets 8788 #region Parcel related packets
8640 8789
8790 // acumulate several HandleRegionHandleRequest consecutive overlaping requests
8791 // to be done with minimal resources as possible
8792 // variables temporary here while in test
8793
8794 Queue<UUID> RegionHandleRequests = new Queue<UUID>();
8795 bool RegionHandleRequestsInService = false;
8796
8641 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack) 8797 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack)
8642 { 8798 {
8643 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; 8799 UUID currentUUID;
8644 8800
8645 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; 8801 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest;
8646 if (handlerRegionHandleRequest != null) 8802
8803 if (handlerRegionHandleRequest == null)
8804 return true;
8805
8806 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
8807
8808 lock (RegionHandleRequests)
8647 { 8809 {
8648 handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); 8810 if (RegionHandleRequestsInService)
8811 {
8812 // we are already busy doing a previus request
8813 // so enqueue it
8814 RegionHandleRequests.Enqueue(rhrPack.RequestBlock.RegionID);
8815 return true;
8816 }
8817
8818 // else do it
8819 currentUUID = rhrPack.RequestBlock.RegionID;
8820 RegionHandleRequestsInService = true;
8649 } 8821 }
8650 return true; 8822
8823 while (true)
8824 {
8825 handlerRegionHandleRequest(this, currentUUID);
8826
8827 lock (RegionHandleRequests)
8828 {
8829 // exit condition, nothing to do or closed
8830 // current code seems to assume we may loose the handler at anytime,
8831 // so keep checking it
8832 handlerRegionHandleRequest = OnRegionHandleRequest;
8833
8834 if (RegionHandleRequests.Count == 0 || !IsActive || handlerRegionHandleRequest == null)
8835 {
8836 RegionHandleRequests.Clear();
8837 RegionHandleRequestsInService = false;
8838 return true;
8839 }
8840 currentUUID = RegionHandleRequests.Dequeue();
8841 }
8842 }
8843
8844 return true; // actually unreached
8651 } 8845 }
8652 8846
8653 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack) 8847 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack)
@@ -9903,7 +10097,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9903 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 10097 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9904 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 10098 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9905 UpdateMuteListEntry.MuteData.MuteType, 10099 UpdateMuteListEntry.MuteData.MuteType,
9906 UpdateMuteListEntry.AgentData.AgentID); 10100 UpdateMuteListEntry.MuteData.MuteFlags);
9907 return true; 10101 return true;
9908 } 10102 }
9909 return false; 10103 return false;
@@ -9918,8 +10112,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9918 { 10112 {
9919 handlerRemoveMuteListEntry(this, 10113 handlerRemoveMuteListEntry(this,
9920 RemoveMuteListEntry.MuteData.MuteID, 10114 RemoveMuteListEntry.MuteData.MuteID,
9921 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 10115 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9922 RemoveMuteListEntry.AgentData.AgentID);
9923 return true; 10116 return true;
9924 } 10117 }
9925 return false; 10118 return false;
@@ -9963,10 +10156,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9963 return false; 10156 return false;
9964 } 10157 }
9965 10158
10159 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10160 {
10161 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10162 (ChangeInventoryItemFlagsPacket)packet;
10163 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10164 if (handlerChangeInventoryItemFlags != null)
10165 {
10166 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10167 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10168 return true;
10169 }
10170 return false;
10171 }
10172
9966 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10173 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9967 { 10174 {
9968 return true; 10175 return true;
9969 } 10176 }
10177
10178 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10179 {
10180 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10181
10182 #region Packet Session and User Check
10183 if (m_checkPackets)
10184 {
10185 if (packet.AgentData.SessionID != SessionId ||
10186 packet.AgentData.AgentID != AgentId)
10187 return true;
10188 }
10189 #endregion
10190 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10191 List<InventoryItemBase> items = new List<InventoryItemBase>();
10192 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10193 {
10194 InventoryItemBase b = new InventoryItemBase();
10195 b.ID = n.OldItemID;
10196 b.Folder = n.OldFolderID;
10197 items.Add(b);
10198 }
10199
10200 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10201 if (handlerMoveItemsAndLeaveCopy != null)
10202 {
10203 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10204 }
10205
10206 return true;
10207 }
9970 10208
9971 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10209 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9972 { 10210 {
@@ -10393,6 +10631,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10393 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10631 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10394 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10632 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10395 10633
10634 Scene scene = (Scene)m_scene;
10635 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10636 {
10637 ScenePresence p;
10638 if (scene.TryGetScenePresence(sender.AgentId, out p))
10639 {
10640 if (p.GodLevel >= 200)
10641 {
10642 groupProfileReply.GroupData.OpenEnrollment = true;
10643 groupProfileReply.GroupData.MembershipFee = 0;
10644 }
10645 }
10646 }
10647
10396 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10648 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10397 } 10649 }
10398 return true; 10650 return true;
@@ -10966,11 +11218,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10966 11218
10967 StartLure handlerStartLure = OnStartLure; 11219 StartLure handlerStartLure = OnStartLure;
10968 if (handlerStartLure != null) 11220 if (handlerStartLure != null)
10969 handlerStartLure(startLureRequest.Info.LureType, 11221 {
10970 Utils.BytesToString( 11222 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10971 startLureRequest.Info.Message), 11223 {
10972 startLureRequest.TargetData[0].TargetID, 11224 handlerStartLure(startLureRequest.Info.LureType,
10973 this); 11225 Utils.BytesToString(
11226 startLureRequest.Info.Message),
11227 startLureRequest.TargetData[i].TargetID,
11228 this);
11229 }
11230 }
10974 return true; 11231 return true;
10975 } 11232 }
10976 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11233 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -11084,10 +11341,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11084 } 11341 }
11085 #endregion 11342 #endregion
11086 11343
11087 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11344 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11088 if (handlerClassifiedGodDelete != null) 11345 if (handlerClassifiedGodDelete != null)
11089 handlerClassifiedGodDelete( 11346 handlerClassifiedGodDelete(
11090 classifiedGodDelete.Data.ClassifiedID, 11347 classifiedGodDelete.Data.ClassifiedID,
11348 classifiedGodDelete.Data.QueryID,
11091 this); 11349 this);
11092 return true; 11350 return true;
11093 } 11351 }
@@ -11453,209 +11711,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11453 } 11711 }
11454 else 11712 else
11455 { 11713 {
11456// m_log.DebugFormat( 11714 ClientChangeObject updatehandler = onClientChangeObject;
11457// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11458// i, block.Type, part.Name, part.LocalId);
11459 11715
11460// // Do this once since fetch parts creates a new array. 11716 if (updatehandler != null)
11461// SceneObjectPart[] parts = part.ParentGroup.Parts; 11717 {
11462// for (int j = 0; j < parts.Length; j++) 11718 ObjectChangeData udata = new ObjectChangeData();
11463// {
11464// part.StoreUndoState();
11465// parts[j].IgnoreUndoUpdate = true;
11466// }
11467 11719
11468 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11720 /*ubit from ll JIRA:
11721 * 0x01 position
11722 * 0x02 rotation
11723 * 0x04 scale
11724
11725 * 0x08 LINK_SET
11726 * 0x10 UNIFORM for scale
11727 */
11469 11728
11470 switch (block.Type) 11729 // translate to internal changes
11471 { 11730 // not all cases .. just the ones older code did
11472 case 1:
11473 Vector3 pos1 = new Vector3(block.Data, 0);
11474 11731
11475 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11732 switch (block.Type)
11476 if (handlerUpdatePrimSinglePosition != null) 11733 {
11477 { 11734 case 1: //change position sp
11478 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11735 udata.position = new Vector3(block.Data, 0);
11479 handlerUpdatePrimSinglePosition(localId, pos1, this);
11480 }
11481 break;
11482 11736
11483 case 2: 11737 udata.change = ObjectChangeType.primP;
11484 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11738 updatehandler(localId, udata, this);
11739 break;
11485 11740
11486 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11741 case 2: // rotation sp
11487 if (handlerUpdatePrimSingleRotation != null) 11742 udata.rotation = new Quaternion(block.Data, 0, true);
11488 {
11489 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11490 handlerUpdatePrimSingleRotation(localId, rot1, this);
11491 }
11492 break;
11493 11743
11494 case 3: 11744 udata.change = ObjectChangeType.primR;
11495 Vector3 rotPos = new Vector3(block.Data, 0); 11745 updatehandler(localId, udata, this);
11496 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11746 break;
11497 11747
11498 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11748 case 3: // position plus rotation
11499 if (handlerUpdatePrimSingleRotationPosition != null) 11749 udata.position = new Vector3(block.Data, 0);
11500 { 11750 udata.rotation = new Quaternion(block.Data, 12, true);
11501 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11502 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11503 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11504 }
11505 break;
11506 11751
11507 case 4: 11752 udata.change = ObjectChangeType.primPR;
11508 case 20: 11753 updatehandler(localId, udata, this);
11509 Vector3 scale4 = new Vector3(block.Data, 0); 11754 break;
11510 11755
11511 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11756 case 4: // scale sp
11512 if (handlerUpdatePrimScale != null) 11757 udata.scale = new Vector3(block.Data, 0);
11513 { 11758 udata.change = ObjectChangeType.primS;
11514 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11515 handlerUpdatePrimScale(localId, scale4, this);
11516 }
11517 break;
11518 11759
11519 case 5: 11760 updatehandler(localId, udata, this);
11520 Vector3 scale1 = new Vector3(block.Data, 12); 11761 break;
11521 Vector3 pos11 = new Vector3(block.Data, 0);
11522 11762
11523 handlerUpdatePrimScale = OnUpdatePrimScale; 11763 case 0x14: // uniform scale sp
11524 if (handlerUpdatePrimScale != null) 11764 udata.scale = new Vector3(block.Data, 0);
11525 {
11526 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11527 handlerUpdatePrimScale(localId, scale1, this);
11528 11765
11529 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11766 udata.change = ObjectChangeType.primUS;
11530 if (handlerUpdatePrimSinglePosition != null) 11767 updatehandler(localId, udata, this);
11531 { 11768 break;
11532 handlerUpdatePrimSinglePosition(localId, pos11, this);
11533 }
11534 }
11535 break;
11536 11769
11537 case 9: 11770 case 5: // scale and position sp
11538 Vector3 pos2 = new Vector3(block.Data, 0); 11771 udata.position = new Vector3(block.Data, 0);
11772 udata.scale = new Vector3(block.Data, 12);
11539 11773
11540 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11774 udata.change = ObjectChangeType.primPS;
11775 updatehandler(localId, udata, this);
11776 break;
11541 11777
11542 if (handlerUpdateVector != null) 11778 case 0x15: //uniform scale and position
11543 { 11779 udata.position = new Vector3(block.Data, 0);
11544 handlerUpdateVector(localId, pos2, this); 11780 udata.scale = new Vector3(block.Data, 12);
11545 }
11546 break;
11547 11781
11548 case 10: 11782 udata.change = ObjectChangeType.primPUS;
11549 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11783 updatehandler(localId, udata, this);
11784 break;
11550 11785
11551 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11786 // now group related (bit 4)
11552 if (handlerUpdatePrimRotation != null) 11787 case 9: //( 8 + 1 )group position
11553 { 11788 udata.position = new Vector3(block.Data, 0);
11554 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11555 handlerUpdatePrimRotation(localId, rot3, this);
11556 }
11557 break;
11558 11789
11559 case 11: 11790 udata.change = ObjectChangeType.groupP;
11560 Vector3 pos3 = new Vector3(block.Data, 0); 11791 updatehandler(localId, udata, this);
11561 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11792 break;
11562 11793
11563 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11794 case 0x0A: // (8 + 2) group rotation
11564 if (handlerUpdatePrimGroupRotation != null) 11795 udata.rotation = new Quaternion(block.Data, 0, true);
11565 {
11566 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11567 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11568 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11569 }
11570 break;
11571 case 12:
11572 case 28:
11573 Vector3 scale7 = new Vector3(block.Data, 0);
11574 11796
11575 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11797 udata.change = ObjectChangeType.groupR;
11576 if (handlerUpdatePrimGroupScale != null) 11798 updatehandler(localId, udata, this);
11577 { 11799 break;
11578 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11579 handlerUpdatePrimGroupScale(localId, scale7, this);
11580 }
11581 break;
11582 11800
11583 case 13: 11801 case 0x0B: //( 8 + 2 + 1) group rotation and position
11584 Vector3 scale2 = new Vector3(block.Data, 12); 11802 udata.position = new Vector3(block.Data, 0);
11585 Vector3 pos4 = new Vector3(block.Data, 0); 11803 udata.rotation = new Quaternion(block.Data, 12, true);
11586 11804
11587 handlerUpdatePrimScale = OnUpdatePrimScale; 11805 udata.change = ObjectChangeType.groupPR;
11588 if (handlerUpdatePrimScale != null) 11806 updatehandler(localId, udata, this);
11589 { 11807 break;
11590 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11591 handlerUpdatePrimScale(localId, scale2, this);
11592 11808
11593 // Change the position based on scale (for bug number 246) 11809 case 0x0C: // (8 + 4) group scale
11594 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11810 // only afects root prim and only sent by viewer editor object tab scaling
11595 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11811 // mouse edition only allows uniform scaling
11596 if (handlerUpdatePrimSinglePosition != null) 11812 // SL MAY CHANGE THIS in viewers
11597 {
11598 handlerUpdatePrimSinglePosition(localId, pos4, this);
11599 }
11600 }
11601 break;
11602 11813
11603 case 29: 11814 udata.scale = new Vector3(block.Data, 0);
11604 Vector3 scale5 = new Vector3(block.Data, 12);
11605 Vector3 pos5 = new Vector3(block.Data, 0);
11606 11815
11607 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11816 udata.change = ObjectChangeType.groupS;
11608 if (handlerUpdatePrimGroupScale != null) 11817 updatehandler(localId, udata, this);
11609 {
11610 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11611 part.StoreUndoState(true);
11612 part.IgnoreUndoUpdate = true;
11613 handlerUpdatePrimGroupScale(localId, scale5, this);
11614 handlerUpdateVector = OnUpdatePrimGroupPosition;
11615 11818
11616 if (handlerUpdateVector != null) 11819 break;
11617 {
11618 handlerUpdateVector(localId, pos5, this);
11619 }
11620 11820
11621 part.IgnoreUndoUpdate = false; 11821 case 0x0D: //(8 + 4 + 1) group scale and position
11622 } 11822 // exception as above
11623 11823
11624 break; 11824 udata.position = new Vector3(block.Data, 0);
11825 udata.scale = new Vector3(block.Data, 12);
11625 11826
11626 case 21: 11827 udata.change = ObjectChangeType.groupPS;
11627 Vector3 scale6 = new Vector3(block.Data, 12); 11828 updatehandler(localId, udata, this);
11628 Vector3 pos6 = new Vector3(block.Data, 0); 11829 break;
11629 11830
11630 handlerUpdatePrimScale = OnUpdatePrimScale; 11831 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11631 if (handlerUpdatePrimScale != null) 11832 udata.scale = new Vector3(block.Data, 0);
11632 {
11633 part.StoreUndoState(false);
11634 part.IgnoreUndoUpdate = true;
11635 11833
11636 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 11834 udata.change = ObjectChangeType.groupUS;
11637 handlerUpdatePrimScale(localId, scale6, this); 11835 updatehandler(localId, udata, this);
11638 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11836 break;
11639 if (handlerUpdatePrimSinglePosition != null)
11640 {
11641 handlerUpdatePrimSinglePosition(localId, pos6, this);
11642 }
11643 11837
11644 part.IgnoreUndoUpdate = false; 11838 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11645 } 11839 udata.position = new Vector3(block.Data, 0);
11646 break; 11840 udata.scale = new Vector3(block.Data, 12);
11647 11841
11648 default: 11842 udata.change = ObjectChangeType.groupPUS;
11649 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 11843 updatehandler(localId, udata, this);
11650 break; 11844 break;
11845
11846 default:
11847 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
11848 break;
11849 }
11651 } 11850 }
11652 11851
11653// for (int j = 0; j < parts.Length; j++)
11654// parts[j].IgnoreUndoUpdate = false;
11655 } 11852 }
11656 } 11853 }
11657 } 11854 }
11658
11659 return true; 11855 return true;
11660 } 11856 }
11661 11857
@@ -11716,8 +11912,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11716 public void SetChildAgentThrottle(byte[] throttles) 11912 public void SetChildAgentThrottle(byte[] throttles)
11717 { 11913 {
11718 m_udpClient.SetThrottles(throttles); 11914 m_udpClient.SetThrottles(throttles);
11915 GenericCall2 handler = OnUpdateThrottles;
11916 if (handler != null)
11917 {
11918 handler();
11919 }
11920 }
11921
11922 /// <summary>
11923 /// Sets the throttles from values supplied by the client
11924 /// </summary>
11925 /// <param name="throttles"></param>
11926 public void SetAgentThrottleSilent(int throttle, int setting)
11927 {
11928 m_udpClient.ForceThrottleSetting(throttle,setting);
11929 //m_udpClient.SetThrottles(throttles);
11930
11719 } 11931 }
11720 11932
11933
11721 /// <summary> 11934 /// <summary>
11722 /// Get the current throttles for this client as a packed byte array 11935 /// Get the current throttles for this client as a packed byte array
11723 /// </summary> 11936 /// </summary>
@@ -12103,7 +12316,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12103// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12316// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12104// requestID, taskID, (SourceType)sourceType, Name); 12317// requestID, taskID, (SourceType)sourceType, Name);
12105 12318
12319
12320 //Note, the bool returned from the below function is useless since it is always false.
12106 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12321 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12322
12107 } 12323 }
12108 12324
12109 /// <summary> 12325 /// <summary>
@@ -12169,7 +12385,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12169 /// <returns></returns> 12385 /// <returns></returns>
12170 private static int CalculateNumPackets(byte[] data) 12386 private static int CalculateNumPackets(byte[] data)
12171 { 12387 {
12172 const uint m_maxPacketSize = 600; 12388// const uint m_maxPacketSize = 600;
12389 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12173 int numPackets = 1; 12390 int numPackets = 1;
12174 12391
12175 if (data == null) 12392 if (data == null)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index 8963756..f675377 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -158,6 +158,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
158 158
159 private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC 159 private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC
160 private int m_maxRTO = 60000; 160 private int m_maxRTO = 60000;
161 public bool m_deliverPackets = true;
161 162
162 /// <summary> 163 /// <summary>
163 /// Default constructor 164 /// Default constructor
@@ -440,6 +441,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
440 if (category >= 0 && category < m_packetOutboxes.Length) 441 if (category >= 0 && category < m_packetOutboxes.Length)
441 { 442 {
442 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; 443 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
444
445 if (m_deliverPackets == false)
446 {
447 queue.Enqueue(packet);
448 return true;
449 }
450
443 TokenBucket bucket = m_throttleCategories[category]; 451 TokenBucket bucket = m_throttleCategories[category];
444 452
445 // Don't send this packet if there is already a packet waiting in the queue 453 // Don't send this packet if there is already a packet waiting in the queue
@@ -489,7 +497,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
489 /// <returns>True if any packets were sent, otherwise false</returns> 497 /// <returns>True if any packets were sent, otherwise false</returns>
490 public bool DequeueOutgoing() 498 public bool DequeueOutgoing()
491 { 499 {
492 OutgoingPacket packet; 500 if (m_deliverPackets == false) return false;
501
502 OutgoingPacket packet = null;
493 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 503 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
494 TokenBucket bucket; 504 TokenBucket bucket;
495 bool packetSent = false; 505 bool packetSent = false;
@@ -521,32 +531,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP
521 // No dequeued packet waiting to be sent, try to pull one off 531 // No dequeued packet waiting to be sent, try to pull one off
522 // this queue 532 // this queue
523 queue = m_packetOutboxes[i]; 533 queue = m_packetOutboxes[i];
524 if (queue.Dequeue(out packet)) 534 if (queue != null)
525 { 535 {
526 // A packet was pulled off the queue. See if we have 536 bool success = false;
527 // enough tokens in the bucket to send it out 537 try
528 if (bucket.RemoveTokens(packet.Buffer.DataLength))
529 { 538 {
530 // Send the packet 539 success = queue.Dequeue(out packet);
531 m_udpServer.SendPacketFinal(packet);
532 packetSent = true;
533 } 540 }
534 else 541 catch
535 { 542 {
536 // Save the dequeued packet for the next iteration 543 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
537 m_nextPackets[i] = packet;
538 } 544 }
539 545 if (success)
540 // If the queue is empty after this dequeue, fire the queue 546 {
541 // empty callback now so it has a chance to fill before we 547 // A packet was pulled off the queue. See if we have
542 // get back here 548 // enough tokens in the bucket to send it out
543 if (queue.Count == 0) 549 if (bucket.RemoveTokens(packet.Buffer.DataLength))
550 {
551 // Send the packet
552 m_udpServer.SendPacketFinal(packet);
553 packetSent = true;
554 }
555 else
556 {
557 // Save the dequeued packet for the next iteration
558 m_nextPackets[i] = packet;
559 }
560
561 // If the queue is empty after this dequeue, fire the queue
562 // empty callback now so it has a chance to fill before we
563 // get back here
564 if (queue.Count == 0)
565 emptyCategories |= CategoryToFlag(i);
566 }
567 else
568 {
569 // No packets in this queue. Fire the queue empty callback
570 // if it has not been called recently
544 emptyCategories |= CategoryToFlag(i); 571 emptyCategories |= CategoryToFlag(i);
572 }
545 } 573 }
546 else 574 else
547 { 575 {
548 // No packets in this queue. Fire the queue empty callback 576 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
549 // if it has not been called recently
550 emptyCategories |= CategoryToFlag(i); 577 emptyCategories |= CategoryToFlag(i);
551 } 578 }
552 } 579 }
@@ -655,6 +682,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
655 if (m_nextOnQueueEmpty == 0) 682 if (m_nextOnQueueEmpty == 0)
656 m_nextOnQueueEmpty = 1; 683 m_nextOnQueueEmpty = 1;
657 } 684 }
685 internal void ForceThrottleSetting(int throttle, int setting)
686 {
687 m_throttleCategories[throttle].RequestedDripRate = Math.Max(setting, LLUDPServer.MTU); ;
688 }
658 689
659 /// <summary> 690 /// <summary>
660 /// Converts a <seealso cref="ThrottleOutPacketType"/> integer to a 691 /// Converts a <seealso cref="ThrottleOutPacketType"/> integer to a
@@ -704,4 +735,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP
704 } 735 }
705 } 736 }
706 } 737 }
707} \ No newline at end of file 738}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index a7628d2..9a4abd4 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -126,7 +126,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
126 /// <summary>Handlers for incoming packets</summary> 126 /// <summary>Handlers for incoming packets</summary>
127 //PacketEventDictionary packetEvents = new PacketEventDictionary(); 127 //PacketEventDictionary packetEvents = new PacketEventDictionary();
128 /// <summary>Incoming packets that are awaiting handling</summary> 128 /// <summary>Incoming packets that are awaiting handling</summary>
129 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 129 //private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
130
131 private DoubleQueue<IncomingPacket> packetInbox = new DoubleQueue<IncomingPacket>();
130 132
131 /// <summary></summary> 133 /// <summary></summary>
132 //private UDPClientCollection m_clients = new UDPClientCollection(); 134 //private UDPClientCollection m_clients = new UDPClientCollection();
@@ -181,6 +183,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
181 /// <summary>Flag to signal when clients should send pings</summary> 183 /// <summary>Flag to signal when clients should send pings</summary>
182 protected bool m_sendPing; 184 protected bool m_sendPing;
183 185
186 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
184 private Pool<IncomingPacket> m_incomingPacketPool; 187 private Pool<IncomingPacket> m_incomingPacketPool;
185 188
186 /// <summary> 189 /// <summary>
@@ -1093,21 +1096,46 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1093 1096
1094 #region Packet to Client Mapping 1097 #region Packet to Client Mapping
1095 1098
1096 // UseCircuitCode handling 1099 // If there is already a client for this endpoint, don't process UseCircuitCode
1097 if (packet.Type == PacketType.UseCircuitCode) 1100 IClientAPI client = null;
1101 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1098 { 1102 {
1099 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1103 // UseCircuitCode handling
1100 // buffer. 1104 if (packet.Type == PacketType.UseCircuitCode)
1101 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1105 {
1106 // And if there is a UseCircuitCode pending, also drop it
1107 lock (m_pendingCache)
1108 {
1109 if (m_pendingCache.Contains(endPoint))
1110 return;
1102 1111
1103 Util.FireAndForget(HandleUseCircuitCode, array); 1112 m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60);
1113 }
1104 1114
1105 return; 1115 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1116 // buffer.
1117 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1118
1119 Util.FireAndForget(HandleUseCircuitCode, array);
1120
1121 return;
1122 }
1123 }
1124
1125 // If this is a pending connection, enqueue, don't process yet
1126 lock (m_pendingCache)
1127 {
1128 Queue<UDPPacketBuffer> queue;
1129 if (m_pendingCache.TryGetValue(endPoint, out queue))
1130 {
1131 //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type);
1132 queue.Enqueue(buffer);
1133 return;
1134 }
1106 } 1135 }
1107 1136
1108 // Determine which agent this packet came from 1137 // Determine which agent this packet came from
1109 IClientAPI client; 1138 if (client == null || !(client is LLClientView))
1110 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1111 { 1139 {
1112 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); 1140 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
1113 return; 1141 return;
@@ -1116,7 +1144,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1116 udpClient = ((LLClientView)client).UDPClient; 1144 udpClient = ((LLClientView)client).UDPClient;
1117 1145
1118 if (!udpClient.IsConnected) 1146 if (!udpClient.IsConnected)
1147 {
1148// m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName);
1119 return; 1149 return;
1150 }
1120 1151
1121 #endregion Packet to Client Mapping 1152 #endregion Packet to Client Mapping
1122 1153
@@ -1246,7 +1277,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1246 incomingPacket = new IncomingPacket((LLClientView)client, packet); 1277 incomingPacket = new IncomingPacket((LLClientView)client, packet);
1247 } 1278 }
1248 1279
1249 packetInbox.Enqueue(incomingPacket); 1280 if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
1281 incomingPacket.Packet.Type == PacketType.ChatFromViewer)
1282 packetInbox.EnqueueHigh(incomingPacket);
1283 else
1284 packetInbox.EnqueueLow(incomingPacket);
1250 } 1285 }
1251 1286
1252 #region BinaryStats 1287 #region BinaryStats
@@ -1366,6 +1401,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1366 // We only want to send initial data to new clients, not ones which are being converted from child to root. 1401 // We only want to send initial data to new clients, not ones which are being converted from child to root.
1367 if (client != null) 1402 if (client != null)
1368 client.SceneAgent.SendInitialDataToMe(); 1403 client.SceneAgent.SendInitialDataToMe();
1404
1405 // Now we know we can handle more data
1406 Thread.Sleep(200);
1407
1408 // Obtain the queue and remove it from the cache
1409 Queue<UDPPacketBuffer> queue = null;
1410
1411 lock (m_pendingCache)
1412 {
1413 if (!m_pendingCache.TryGetValue(endPoint, out queue))
1414 {
1415 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1416 return;
1417 }
1418 m_pendingCache.Remove(endPoint);
1419 }
1420
1421 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
1422
1423 // Reinject queued packets
1424 while(queue.Count > 0)
1425 {
1426 UDPPacketBuffer buf = queue.Dequeue();
1427 PacketReceived(buf);
1428 }
1429 queue = null;
1369 } 1430 }
1370 else 1431 else
1371 { 1432 {
@@ -1373,6 +1434,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1373 m_log.WarnFormat( 1434 m_log.WarnFormat(
1374 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1435 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
1375 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); 1436 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
1437 lock (m_pendingCache)
1438 m_pendingCache.Remove(endPoint);
1376 } 1439 }
1377 1440
1378 // m_log.DebugFormat( 1441 // m_log.DebugFormat(
@@ -1491,7 +1554,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1491 if (!client.SceneAgent.IsChildAgent) 1554 if (!client.SceneAgent.IsChildAgent)
1492 client.Kick("Simulator logged you out due to connection timeout"); 1555 client.Kick("Simulator logged you out due to connection timeout");
1493 1556
1494 client.CloseWithoutChecks(); 1557 client.CloseWithoutChecks(true);
1495 } 1558 }
1496 } 1559 }
1497 1560
@@ -1503,6 +1566,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1503 1566
1504 while (IsRunningInbound) 1567 while (IsRunningInbound)
1505 { 1568 {
1569 m_scene.ThreadAlive(1);
1506 try 1570 try
1507 { 1571 {
1508 IncomingPacket incomingPacket = null; 1572 IncomingPacket incomingPacket = null;
@@ -1550,6 +1614,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1550 1614
1551 while (base.IsRunningOutbound) 1615 while (base.IsRunningOutbound)
1552 { 1616 {
1617 m_scene.ThreadAlive(2);
1553 try 1618 try
1554 { 1619 {
1555 m_packetSent = false; 1620 m_packetSent = false;
@@ -1780,8 +1845,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1780 Packet packet = incomingPacket.Packet; 1845 Packet packet = incomingPacket.Packet;
1781 LLClientView client = incomingPacket.Client; 1846 LLClientView client = incomingPacket.Client;
1782 1847
1783 if (client.IsActive) 1848// if (client.IsActive)
1784 { 1849// {
1785 m_currentIncomingClient = client; 1850 m_currentIncomingClient = client;
1786 1851
1787 try 1852 try
@@ -1808,13 +1873,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1808 { 1873 {
1809 m_currentIncomingClient = null; 1874 m_currentIncomingClient = null;
1810 } 1875 }
1811 } 1876// }
1812 else 1877// else
1813 { 1878// {
1814 m_log.DebugFormat( 1879// m_log.DebugFormat(
1815 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 1880// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
1816 packet.Type, client.Name, m_scene.RegionInfo.RegionName); 1881// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
1817 } 1882// }
1818 1883
1819 IncomingPacketsProcessed++; 1884 IncomingPacketsProcessed++;
1820 } 1885 }
@@ -1826,8 +1891,116 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1826 if (!client.IsLoggingOut) 1891 if (!client.IsLoggingOut)
1827 { 1892 {
1828 client.IsLoggingOut = true; 1893 client.IsLoggingOut = true;
1829 client.Close(); 1894 client.Close(false, false);
1895 }
1896 }
1897 }
1898
1899 internal class DoubleQueue<T> where T:class
1900 {
1901 private Queue<T> m_lowQueue = new Queue<T>();
1902 private Queue<T> m_highQueue = new Queue<T>();
1903
1904 private object m_syncRoot = new object();
1905 private Semaphore m_s = new Semaphore(0, 1);
1906
1907 public DoubleQueue()
1908 {
1909 }
1910
1911 public virtual int Count
1912 {
1913 get { return m_highQueue.Count + m_lowQueue.Count; }
1914 }
1915
1916 public virtual void Enqueue(T data)
1917 {
1918 Enqueue(m_lowQueue, data);
1919 }
1920
1921 public virtual void EnqueueLow(T data)
1922 {
1923 Enqueue(m_lowQueue, data);
1924 }
1925
1926 public virtual void EnqueueHigh(T data)
1927 {
1928 Enqueue(m_highQueue, data);
1929 }
1930
1931 private void Enqueue(Queue<T> q, T data)
1932 {
1933 lock (m_syncRoot)
1934 {
1935 m_lowQueue.Enqueue(data);
1936 m_s.WaitOne(0);
1937 m_s.Release();
1938 }
1939 }
1940
1941 public virtual T Dequeue()
1942 {
1943 return Dequeue(Timeout.Infinite);
1944 }
1945
1946 public virtual T Dequeue(int tmo)
1947 {
1948 return Dequeue(TimeSpan.FromMilliseconds(tmo));
1949 }
1950
1951 public virtual T Dequeue(TimeSpan wait)
1952 {
1953 T res = null;
1954
1955 if (!Dequeue(wait, ref res))
1956 return null;
1957
1958 return res;
1959 }
1960
1961 public bool Dequeue(int timeout, ref T res)
1962 {
1963 return Dequeue(TimeSpan.FromMilliseconds(timeout), ref res);
1964 }
1965
1966 public bool Dequeue(TimeSpan wait, ref T res)
1967 {
1968 if (!m_s.WaitOne(wait))
1969 return false;
1970
1971 lock (m_syncRoot)
1972 {
1973 if (m_highQueue.Count > 0)
1974 res = m_highQueue.Dequeue();
1975 else
1976 res = m_lowQueue.Dequeue();
1977
1978 if (m_highQueue.Count == 0 && m_lowQueue.Count == 0)
1979 return true;
1980
1981 try
1982 {
1983 m_s.Release();
1984 }
1985 catch
1986 {
1987 }
1988
1989 return true;
1990 }
1991 }
1992
1993 public virtual void Clear()
1994 {
1995
1996 lock (m_syncRoot)
1997 {
1998 // Make sure sem count is 0
1999 m_s.WaitOne(0);
2000
2001 m_lowQueue.Clear();
2002 m_highQueue.Clear();
1830 } 2003 }
1831 } 2004 }
1832 } 2005 }
1833} \ No newline at end of file 2006}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 3f7ca2b..2aeb4cc 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,