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.cs1294
-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, 1027 insertions, 562 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 504df40..ee66485 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,10 @@ 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 bool m_VelocityInterpolate = false;
335 private const uint MaxTransferBytesPerPacket = 600;
336
337
329 /// <value> 338 /// <value>
330 /// List used in construction of data blocks for an object update packet. This is to stop us having to 339 /// List used in construction of data blocks for an object update packet. This is to stop us having to
331 /// continually recreate it. 340 /// continually recreate it.
@@ -337,14 +346,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
337 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 346 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
338 /// ownerless phantom. 347 /// ownerless phantom.
339 /// 348 ///
340 /// All manipulation of this set has to occur under a lock 349 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
341 /// 350 ///
342 /// </value> 351 /// </value>
343 protected HashSet<uint> m_killRecord; 352// protected HashSet<uint> m_killRecord;
344 353
345// protected HashSet<uint> m_attachmentsSent; 354// protected HashSet<uint> m_attachmentsSent;
346 355
347 private int m_moneyBalance; 356 private int m_moneyBalance;
357 private bool m_deliverPackets = true;
348 private int m_animationSequenceNumber = 1; 358 private int m_animationSequenceNumber = 1;
349 private bool m_SendLogoutPacketWhenClosing = true; 359 private bool m_SendLogoutPacketWhenClosing = true;
350 360
@@ -391,6 +401,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
391 get { return m_startpos; } 401 get { return m_startpos; }
392 set { m_startpos = value; } 402 set { m_startpos = value; }
393 } 403 }
404 public bool DeliverPackets
405 {
406 get { return m_deliverPackets; }
407 set {
408 m_deliverPackets = value;
409 m_udpClient.m_deliverPackets = value;
410 }
411 }
394 public UUID AgentId { get { return m_agentId; } } 412 public UUID AgentId { get { return m_agentId; } }
395 public ISceneAgent SceneAgent { get; set; } 413 public ISceneAgent SceneAgent { get; set; }
396 public UUID ActiveGroupId { get { return m_activeGroupID; } } 414 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -468,7 +486,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
468 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 486 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
469 m_entityProps = new PriorityQueue(m_scene.Entities.Count); 487 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
470 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 488 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
471 m_killRecord = new HashSet<uint>(); 489// m_killRecord = new HashSet<uint>();
472// m_attachmentsSent = new HashSet<uint>(); 490// m_attachmentsSent = new HashSet<uint>();
473 491
474 m_assetService = m_scene.RequestModuleInterface<IAssetService>(); 492 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
@@ -498,12 +516,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
498 516
499 #region Client Methods 517 #region Client Methods
500 518
519
520 /// <summary>
521 /// Close down the client view
522 /// </summary>
501 public void Close() 523 public void Close()
502 { 524 {
503 Close(false); 525 Close(true, false);
504 } 526 }
505 527
506 public void Close(bool force) 528 public void Close(bool sendStop, bool force)
507 { 529 {
508 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. 530 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
509 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. 531 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
@@ -515,7 +537,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
515 return; 537 return;
516 538
517 IsActive = false; 539 IsActive = false;
518 CloseWithoutChecks(); 540 CloseWithoutChecks(sendStop);
519 } 541 }
520 } 542 }
521 543
@@ -528,12 +550,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
528 /// 550 ///
529 /// Callers must lock ClosingSyncLock before calling. 551 /// Callers must lock ClosingSyncLock before calling.
530 /// </remarks> 552 /// </remarks>
531 public void CloseWithoutChecks() 553 public void CloseWithoutChecks(bool sendStop)
532 { 554 {
533 m_log.DebugFormat( 555 m_log.DebugFormat(
534 "[CLIENT]: Close has been called for {0} attached to scene {1}", 556 "[CLIENT]: Close has been called for {0} attached to scene {1}",
535 Name, m_scene.RegionInfo.RegionName); 557 Name, m_scene.RegionInfo.RegionName);
536 558
559 if (sendStop)
560 {
561 // Send the STOP packet
562 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
563 OutPacket(disable, ThrottleOutPacketType.Unknown);
564 }
565
537 // Shutdown the image manager 566 // Shutdown the image manager
538 ImageManager.Close(); 567 ImageManager.Close();
539 568
@@ -791,7 +820,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
791 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType); 820 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType);
792 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes; 821 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes;
793 822
794 OutPacket(handshake, ThrottleOutPacketType.Task); 823// OutPacket(handshake, ThrottleOutPacketType.Task);
824 // use same as MoveAgentIntoRegion (both should be task )
825 OutPacket(handshake, ThrottleOutPacketType.Unknown);
795 } 826 }
796 827
797 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) 828 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
@@ -831,7 +862,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
831 reply.ChatData.OwnerID = ownerID; 862 reply.ChatData.OwnerID = ownerID;
832 reply.ChatData.SourceID = fromAgentID; 863 reply.ChatData.SourceID = fromAgentID;
833 864
834 OutPacket(reply, ThrottleOutPacketType.Task); 865 OutPacket(reply, ThrottleOutPacketType.Unknown);
835 } 866 }
836 867
837 /// <summary> 868 /// <summary>
@@ -1117,6 +1148,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1117 public virtual void SendLayerData(float[] map) 1148 public virtual void SendLayerData(float[] map)
1118 { 1149 {
1119 Util.FireAndForget(DoSendLayerData, map); 1150 Util.FireAndForget(DoSendLayerData, map);
1151
1152 // Send it sync, and async. It's not that much data
1153 // and it improves user experience just so much!
1154 DoSendLayerData(map);
1120 } 1155 }
1121 1156
1122 /// <summary> 1157 /// <summary>
@@ -1129,16 +1164,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1129 1164
1130 try 1165 try
1131 { 1166 {
1132 //for (int y = 0; y < 16; y++) 1167 for (int y = 0; y < 16; y++)
1133 //{ 1168 {
1134 // for (int x = 0; x < 16; x++) 1169 for (int x = 0; x < 16; x+=4)
1135 // { 1170 {
1136 // SendLayerData(x, y, map); 1171 SendLayerPacket(x, y, map);
1137 // } 1172 }
1138 //} 1173 }
1139
1140 // Send LayerData in a spiral pattern. Fun!
1141 SendLayerTopRight(map, 0, 0, 15, 15);
1142 } 1174 }
1143 catch (Exception e) 1175 catch (Exception e)
1144 { 1176 {
@@ -1146,51 +1178,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1146 } 1178 }
1147 } 1179 }
1148 1180
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> 1181 /// <summary>
1178 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1182 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1179 /// </summary> 1183 /// </summary>
1180 /// <param name="map">heightmap</param> 1184 /// <param name="map">heightmap</param>
1181 /// <param name="px">X coordinate for patches 0..12</param> 1185 /// <param name="px">X coordinate for patches 0..12</param>
1182 /// <param name="py">Y coordinate for patches 0..15</param> 1186 /// <param name="py">Y coordinate for patches 0..15</param>
1183 // private void SendLayerPacket(float[] map, int y, int x) 1187 private void SendLayerPacket(int x, int y, float[] map)
1184 // { 1188 {
1185 // int[] patches = new int[4]; 1189 int[] patches = new int[4];
1186 // patches[0] = x + 0 + y * 16; 1190 patches[0] = x + 0 + y * 16;
1187 // patches[1] = x + 1 + y * 16; 1191 patches[1] = x + 1 + y * 16;
1188 // patches[2] = x + 2 + y * 16; 1192 patches[2] = x + 2 + y * 16;
1189 // patches[3] = x + 3 + y * 16; 1193 patches[3] = x + 3 + y * 16;
1190 1194
1191 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1195 float[] heightmap = (map.Length == 65536) ?
1192 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1196 map :
1193 // } 1197 LLHeightFieldMoronize(map);
1198
1199 try
1200 {
1201 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1202 OutPacket(layerpack, ThrottleOutPacketType.Land);
1203 }
1204 catch
1205 {
1206 for (int px = x ; px < x + 4 ; px++)
1207 SendLayerData(px, y, map);
1208 }
1209 }
1194 1210
1195 /// <summary> 1211 /// <summary>
1196 /// Sends a specified patch to a client 1212 /// Sends a specified patch to a client
@@ -1210,7 +1226,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1210 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1226 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1211 layerpack.Header.Reliable = true; 1227 layerpack.Header.Reliable = true;
1212 1228
1213 OutPacket(layerpack, ThrottleOutPacketType.Land); 1229 OutPacket(layerpack, ThrottleOutPacketType.Task);
1214 } 1230 }
1215 catch (Exception e) 1231 catch (Exception e)
1216 { 1232 {
@@ -1573,7 +1589,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1573 1589
1574 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1590 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1575 { 1591 {
1576// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1592// foreach (uint id in localIDs)
1593// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1577 1594
1578 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1595 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1579 // TODO: don't create new blocks if recycling an old packet 1596 // TODO: don't create new blocks if recycling an old packet
@@ -1595,17 +1612,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 1612 // 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. 1613 // 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. 1614 // ProcessEntityUpdates() also takes the m_killRecord lock.
1598 lock (m_killRecord) 1615// lock (m_killRecord)
1599 { 1616// {
1600 foreach (uint localID in localIDs) 1617// foreach (uint localID in localIDs)
1601 m_killRecord.Add(localID); 1618// m_killRecord.Add(localID);
1602 1619
1603 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1620 // 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 1621 // 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 1622 // 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. 1623 // scene objects in a viewer until that viewer is relogged in.
1607 OutPacket(kill, ThrottleOutPacketType.Task); 1624 OutPacket(kill, ThrottleOutPacketType.Task);
1608 } 1625// }
1609 } 1626 }
1610 } 1627 }
1611 1628
@@ -2063,9 +2080,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2063 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); 2080 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
2064 } 2081 }
2065 2082
2066 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2067 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId) 2083 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
2068 { 2084 {
2085 SendInventoryItemCreateUpdate(Item, UUID.Zero, callbackId);
2086 }
2087
2088 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2089 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId)
2090 {
2069 const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; 2091 const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All;
2070 2092
2071 UpdateCreateInventoryItemPacket InventoryReply 2093 UpdateCreateInventoryItemPacket InventoryReply
@@ -2075,6 +2097,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2075 // TODO: don't create new blocks if recycling an old packet 2097 // TODO: don't create new blocks if recycling an old packet
2076 InventoryReply.AgentData.AgentID = AgentId; 2098 InventoryReply.AgentData.AgentID = AgentId;
2077 InventoryReply.AgentData.SimApproved = true; 2099 InventoryReply.AgentData.SimApproved = true;
2100 InventoryReply.AgentData.TransactionID = transactionID;
2078 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1]; 2101 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1];
2079 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock(); 2102 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock();
2080 InventoryReply.InventoryData[0].ItemID = Item.ID; 2103 InventoryReply.InventoryData[0].ItemID = Item.ID;
@@ -2144,16 +2167,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2144 replytask.InventoryData.TaskID = taskID; 2167 replytask.InventoryData.TaskID = taskID;
2145 replytask.InventoryData.Serial = serial; 2168 replytask.InventoryData.Serial = serial;
2146 replytask.InventoryData.Filename = fileName; 2169 replytask.InventoryData.Filename = fileName;
2147 OutPacket(replytask, ThrottleOutPacketType.Asset); 2170 OutPacket(replytask, ThrottleOutPacketType.Task);
2148 } 2171 }
2149 2172
2150 public void SendXferPacket(ulong xferID, uint packet, byte[] data) 2173 public void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory)
2151 { 2174 {
2175 ThrottleOutPacketType type = ThrottleOutPacketType.Asset;
2176 if (isTaskInventory)
2177 type = ThrottleOutPacketType.Task;
2178
2152 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket); 2179 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket);
2153 sendXfer.XferID.ID = xferID; 2180 sendXfer.XferID.ID = xferID;
2154 sendXfer.XferID.Packet = packet; 2181 sendXfer.XferID.Packet = packet;
2155 sendXfer.DataPacket.Data = data; 2182 sendXfer.DataPacket.Data = data;
2156 OutPacket(sendXfer, ThrottleOutPacketType.Asset); 2183 OutPacket(sendXfer, type);
2157 } 2184 }
2158 2185
2159 public void SendAbortXferPacket(ulong xferID) 2186 public void SendAbortXferPacket(ulong xferID)
@@ -2335,6 +2362,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2335 OutPacket(sound, ThrottleOutPacketType.Task); 2362 OutPacket(sound, ThrottleOutPacketType.Task);
2336 } 2363 }
2337 2364
2365 public void SendTransferAbort(TransferRequestPacket transferRequest)
2366 {
2367 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2368 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2369 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2370 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2371 OutPacket(abort, ThrottleOutPacketType.Task);
2372 }
2373
2338 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2374 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2339 { 2375 {
2340 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2376 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2627,6 +2663,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2627 } 2663 }
2628 } 2664 }
2629 2665
2666 public void SendPartPhysicsProprieties(ISceneEntity entity)
2667 {
2668 SceneObjectPart part = (SceneObjectPart)entity;
2669 if (part != null && AgentId != UUID.Zero)
2670 {
2671 try
2672 {
2673 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
2674 if (eq != null)
2675 {
2676 uint localid = part.LocalId;
2677 byte physshapetype = part.PhysicsShapeType;
2678 float density = part.Density;
2679 float friction = part.Friction;
2680 float bounce = part.Bounciness;
2681 float gravmod = part.GravityModifier;
2682
2683 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2684 }
2685 }
2686 catch (Exception ex)
2687 {
2688 m_log.Error("Unable to send part Physics Proprieties - exception: " + ex.ToString());
2689 }
2690 part.UpdatePhysRequired = false;
2691 }
2692 }
2693
2694
2630 2695
2631 public void SendGroupNameReply(UUID groupLLUID, string GroupName) 2696 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
2632 { 2697 {
@@ -2724,7 +2789,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2724 else 2789 else
2725 { 2790 {
2726 int processedLength = 0; 2791 int processedLength = 0;
2727 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2792// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2793
2794 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2728 int packetNumber = 0; 2795 int packetNumber = 0;
2729 2796
2730 while (processedLength < req.AssetInf.Data.Length) 2797 while (processedLength < req.AssetInf.Data.Length)
@@ -2795,7 +2862,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2795 reply.Data.ParcelID = parcelID; 2862 reply.Data.ParcelID = parcelID;
2796 reply.Data.OwnerID = land.OwnerID; 2863 reply.Data.OwnerID = land.OwnerID;
2797 reply.Data.Name = Utils.StringToBytes(land.Name); 2864 reply.Data.Name = Utils.StringToBytes(land.Name);
2798 reply.Data.Desc = Utils.StringToBytes(land.Description); 2865 if (land != null && land.Description != null && land.Description != String.Empty)
2866 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2867 else
2868 reply.Data.Desc = new Byte[0];
2799 reply.Data.ActualArea = land.Area; 2869 reply.Data.ActualArea = land.Area;
2800 reply.Data.BillableArea = land.Area; // TODO: what is this? 2870 reply.Data.BillableArea = land.Area; // TODO: what is this?
2801 2871
@@ -3530,7 +3600,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3530 3600
3531 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3601 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3532 // TODO: don't create new blocks if recycling an old packet 3602 // TODO: don't create new blocks if recycling an old packet
3533 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3603 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3534 avp.ObjectData.TextureEntry = textureEntry; 3604 avp.ObjectData.TextureEntry = textureEntry;
3535 3605
3536 AvatarAppearancePacket.VisualParamBlock avblock = null; 3606 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3660,7 +3730,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3660 /// </summary> 3730 /// </summary>
3661 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3731 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3662 { 3732 {
3663 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3733 if (entity is SceneObjectPart)
3734 {
3735 SceneObjectPart e = (SceneObjectPart)entity;
3736 SceneObjectGroup g = e.ParentGroup;
3737 if (g.RootPart.Shape.State > 30) // HUD
3738 if (g.OwnerID != AgentId)
3739 return; // Don't send updates for other people's HUDs
3740 }
3741
3664 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3742 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3665 3743
3666 lock (m_entityUpdates.SyncRoot) 3744 lock (m_entityUpdates.SyncRoot)
@@ -3727,27 +3805,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3727 3805
3728 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3806 // 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. 3807 // condition where a kill can be processed before an out-of-date update for the same object.
3730 lock (m_killRecord) 3808 float avgTimeDilation = 1.0f;
3809 IEntityUpdate iupdate;
3810 Int32 timeinqueue; // this is just debugging code & can be dropped later
3811
3812 while (updatesThisCall < maxUpdates)
3731 { 3813 {
3732 float avgTimeDilation = 1.0f; 3814 lock (m_entityUpdates.SyncRoot)
3733 IEntityUpdate iupdate; 3815 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3734 Int32 timeinqueue; // this is just debugging code & can be dropped later 3816 break;
3735 3817
3736 while (updatesThisCall < maxUpdates) 3818 EntityUpdate update = (EntityUpdate)iupdate;
3819
3820 avgTimeDilation += update.TimeDilation;
3821 avgTimeDilation *= 0.5f;
3822
3823 if (update.Entity is SceneObjectPart)
3737 { 3824 {
3738 lock (m_entityUpdates.SyncRoot) 3825 SceneObjectPart part = (SceneObjectPart)update.Entity;
3739 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3740 break;
3741 3826
3742 EntityUpdate update = (EntityUpdate)iupdate; 3827 if (part.ParentGroup.IsDeleted)
3743 3828 continue;
3744 avgTimeDilation += update.TimeDilation;
3745 avgTimeDilation *= 0.5f;
3746 3829
3747 if (update.Entity is SceneObjectPart) 3830 if (part.ParentGroup.IsAttachment)
3831 { // Someone else's HUD, why are we getting these?
3832 if (part.ParentGroup.OwnerID != AgentId &&
3833 part.ParentGroup.RootPart.Shape.State > 30)
3834 continue;
3835 ScenePresence sp;
3836 // Owner is not in the sim, don't update it to
3837 // anyone
3838 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3839 continue;
3840
3841 List<SceneObjectGroup> atts = sp.GetAttachments();
3842 bool found = false;
3843 foreach (SceneObjectGroup att in atts)
3844 {
3845 if (att == part.ParentGroup)
3846 {
3847 found = true;
3848 break;
3849 }
3850 }
3851
3852 // It's an attachment of a valid avatar, but
3853 // doesn't seem to be attached, skip
3854 if (!found)
3855 continue;
3856
3857 // On vehicle crossing, the attachments are received
3858 // while the avatar is still a child. Don't send
3859 // updates here because the LocalId has not yet
3860 // been updated and the viewer will derender the
3861 // attachments until the avatar becomes root.
3862 if (sp.IsChildAgent)
3863 continue;
3864
3865 // If the object is an attachment we don't want it to be in the kill
3866 // record. Else attaching from inworld and subsequently dropping
3867 // it will no longer work.
3868// lock (m_killRecord)
3869// {
3870// m_killRecord.Remove(part.LocalId);
3871// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3872// }
3873 }
3874 else
3748 { 3875 {
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 3876 // 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 3877 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3753 // safety measure. 3878 // safety measure.
@@ -3758,241 +3883,177 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3758 // 3883 //
3759 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3884 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3760 // after the root prim has been deleted. 3885 // after the root prim has been deleted.
3761 if (m_killRecord.Contains(part.LocalId)) 3886 //
3762 { 3887 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3763 // m_log.WarnFormat( 3888// lock (m_killRecord)
3764 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3889// {
3765 // part.LocalId, Name); 3890// if (m_killRecord.Contains(part.LocalId))
3766 continue; 3891// continue;
3767 } 3892// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3768 3893// continue;
3769 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3894// }
3895 }
3896
3897 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3898 {
3899 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3900 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3770 { 3901 {
3771 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3902 part.Shape.LightEntry = false;
3772 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3773 {
3774 part.Shape.LightEntry = false;
3775 }
3776 } 3903 }
3777 } 3904 }
3778 3905 }
3779 #region UpdateFlags to packet type conversion 3906
3780 3907 ++updatesThisCall;
3781 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; 3908
3782 3909 #region UpdateFlags to packet type conversion
3783 bool canUseCompressed = true; 3910
3784 bool canUseImproved = true; 3911 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3785 3912
3786 // Compressed object updates only make sense for LL primitives 3913 bool canUseCompressed = true;
3787 if (!(update.Entity is SceneObjectPart)) 3914 bool canUseImproved = true;
3915
3916 // Compressed object updates only make sense for LL primitives
3917 if (!(update.Entity is SceneObjectPart))
3918 {
3919 canUseCompressed = false;
3920 }
3921
3922 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3923 {
3924 canUseCompressed = false;
3925 canUseImproved = false;
3926 }
3927 else
3928 {
3929 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3930 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3931 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3932 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3788 { 3933 {
3789 canUseCompressed = false; 3934 canUseCompressed = false;
3790 } 3935 }
3791 3936
3792 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 3937 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3938 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3939 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3940 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3941 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3942 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3943 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3944 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3945 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3946 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3947 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3948 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3949 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3950 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3793 { 3951 {
3794 canUseCompressed = false;
3795 canUseImproved = false; 3952 canUseImproved = false;
3796 } 3953 }
3797 else 3954 }
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 3955
3833 if (!canUseImproved && !canUseCompressed) 3956 #endregion UpdateFlags to packet type conversion
3834 {
3835 ObjectUpdatePacket.ObjectDataBlock updateBlock;
3836 3957
3837 if (update.Entity is ScenePresence) 3958 #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 3959
3863 objectUpdateBlocks.Value.Add(updateBlock); 3960 // TODO: Remove this once we can build compressed updates
3864 objectUpdates.Value.Add(update); 3961 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 3962
3881 compressedUpdateBlocks.Value.Add(compressedBlock); 3963 if (!canUseImproved && !canUseCompressed)
3882 compressedUpdates.Value.Add(update); 3964 {
3965 if (update.Entity is ScenePresence)
3966 {
3967 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3883 } 3968 }
3884 else 3969 else
3885 { 3970 {
3886 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3971 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 } 3972 }
3923
3924 ++updatesThisCall;
3925
3926 #endregion Block Construction
3927 } 3973 }
3928 3974 else if (!canUseImproved)
3929 #region Packet Sending
3930 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3931
3932 if (terseAgentUpdateBlocks.IsValueCreated)
3933 { 3975 {
3934 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 3976 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3977 }
3978 else
3979 {
3980 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3981 // Self updates go into a special list
3982 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3983 else
3984 // Everything else goes here
3985 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3986 }
3935 3987
3936 ImprovedTerseObjectUpdatePacket packet 3988 #endregion Block Construction
3937 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 3989 }
3938 3990
3939 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3991 #region Packet Sending
3940 packet.RegionData.TimeDilation = timeDilation; 3992
3941 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3993 const float TIME_DILATION = 1.0f;
3994 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3995
3996 if (terseAgentUpdateBlocks.IsValueCreated)
3997 {
3998 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3942 3999
3943 for (int i = 0; i < blocks.Count; i++) 4000 ImprovedTerseObjectUpdatePacket packet
3944 packet.ObjectData[i] = blocks[i]; 4001 = (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 4002 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3946 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); }); 4003 packet.RegionData.TimeDilation = timeDilation;
3947 } 4004 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3948 4005
3949 if (objectUpdateBlocks.IsValueCreated) 4006 for (int i = 0; i < blocks.Count; i++)
3950 { 4007 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 4008
3979 if (terseUpdateBlocks.IsValueCreated) 4009 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3980 { 4010 }
3981 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3982
3983 ImprovedTerseObjectUpdatePacket packet
3984 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
3985 PacketType.ImprovedTerseObjectUpdate);
3986 4011
3987 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4012 if (objectUpdateBlocks.IsValueCreated)
3988 packet.RegionData.TimeDilation = timeDilation; 4013 {
3989 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4014 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3990 4015
3991 for (int i = 0; i < blocks.Count; i++) 4016 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3992 packet.ObjectData[i] = blocks[i]; 4017 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 4018 packet.RegionData.TimeDilation = timeDilation;
3994 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 4019 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3995 } 4020
4021 for (int i = 0; i < blocks.Count; i++)
4022 packet.ObjectData[i] = blocks[i];
4023
4024 OutPacket(packet, ThrottleOutPacketType.Task, true);
4025 }
4026
4027 if (compressedUpdateBlocks.IsValueCreated)
4028 {
4029 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4030
4031 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4032 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4033 packet.RegionData.TimeDilation = timeDilation;
4034 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4035
4036 for (int i = 0; i < blocks.Count; i++)
4037 packet.ObjectData[i] = blocks[i];
4038
4039 OutPacket(packet, ThrottleOutPacketType.Task, true);
4040 }
4041
4042 if (terseUpdateBlocks.IsValueCreated)
4043 {
4044 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4045
4046 ImprovedTerseObjectUpdatePacket packet
4047 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4048 PacketType.ImprovedTerseObjectUpdate);
4049 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4050 packet.RegionData.TimeDilation = timeDilation;
4051 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4052
4053 for (int i = 0; i < blocks.Count; i++)
4054 packet.ObjectData[i] = blocks[i];
4055
4056 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3996 } 4057 }
3997 4058
3998 #endregion Packet Sending 4059 #endregion Packet Sending
@@ -4285,11 +4346,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4285 4346
4286 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4347 // 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 4348 // of the object rather than the properties when the packet was created
4288 OutPacket(packet, ThrottleOutPacketType.Task, true, 4349 // HACK : Remove intelligent resending until it's fixed in core
4289 delegate(OutgoingPacket oPacket) 4350 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4290 { 4351 // delegate(OutgoingPacket oPacket)
4291 ResendPropertyUpdates(updates, oPacket); 4352 // {
4292 }); 4353 // ResendPropertyUpdates(updates, oPacket);
4354 // });
4355 OutPacket(packet, ThrottleOutPacketType.Task, true);
4293 4356
4294 // pbcnt += blocks.Count; 4357 // pbcnt += blocks.Count;
4295 // ppcnt++; 4358 // ppcnt++;
@@ -4315,11 +4378,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4315 // of the object rather than the properties when the packet was created 4378 // of the object rather than the properties when the packet was created
4316 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4379 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4317 updates.Add(familyUpdates.Value[i]); 4380 updates.Add(familyUpdates.Value[i]);
4318 OutPacket(packet, ThrottleOutPacketType.Task, true, 4381 // HACK : Remove intelligent resending until it's fixed in core
4319 delegate(OutgoingPacket oPacket) 4382 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4320 { 4383 // delegate(OutgoingPacket oPacket)
4321 ResendPropertyUpdates(updates, oPacket); 4384 // {
4322 }); 4385 // ResendPropertyUpdates(updates, oPacket);
4386 // });
4387 OutPacket(packet, ThrottleOutPacketType.Task, true);
4323 4388
4324 // fpcnt++; 4389 // fpcnt++;
4325 // fbcnt++; 4390 // fbcnt++;
@@ -4691,7 +4756,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4691 4756
4692 if (landData.SimwideArea > 0) 4757 if (landData.SimwideArea > 0)
4693 { 4758 {
4694 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4759 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4760 // Never report more than sim total capacity
4761 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4762 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4695 updateMessage.SimWideMaxPrims = simulatorCapacity; 4763 updateMessage.SimWideMaxPrims = simulatorCapacity;
4696 } 4764 }
4697 else 4765 else
@@ -4820,14 +4888,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4820 4888
4821 if (notifyCount > 0) 4889 if (notifyCount > 0)
4822 { 4890 {
4823 if (notifyCount > 32) 4891// if (notifyCount > 32)
4824 { 4892// {
4825 m_log.InfoFormat( 4893// m_log.InfoFormat(
4826 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4894// "[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); 4895// + " - a developer might want to investigate whether this is a hard limit", 32);
4828 4896//
4829 notifyCount = 32; 4897// notifyCount = 32;
4830 } 4898// }
4831 4899
4832 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4900 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4833 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4901 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4882,9 +4950,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4882 { 4950 {
4883 ScenePresence presence = (ScenePresence)entity; 4951 ScenePresence presence = (ScenePresence)entity;
4884 4952
4953 position = presence.OffsetPosition;
4954 rotation = presence.Rotation;
4955
4956 if (presence.ParentID != 0)
4957 {
4958 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4959 if (part != null && part != part.ParentGroup.RootPart)
4960 {
4961 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4962 rotation = part.RotationOffset * presence.Rotation;
4963 }
4964 }
4965
4885 attachPoint = 0; 4966 attachPoint = 0;
4886 collisionPlane = presence.CollisionPlane; 4967 collisionPlane = presence.CollisionPlane;
4887 position = presence.OffsetPosition;
4888 velocity = presence.Velocity; 4968 velocity = presence.Velocity;
4889 acceleration = Vector3.Zero; 4969 acceleration = Vector3.Zero;
4890 4970
@@ -4892,9 +4972,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4892 // in that direction, even though we don't model this on the server. Implementing this in the future 4972 // in that direction, even though we don't model this on the server. Implementing this in the future
4893 // may improve movement smoothness. 4973 // may improve movement smoothness.
4894// acceleration = new Vector3(1, 0, 0); 4974// acceleration = new Vector3(1, 0, 0);
4895 4975
4896 angularVelocity = Vector3.Zero; 4976 angularVelocity = Vector3.Zero;
4897 rotation = presence.Rotation;
4898 4977
4899 if (sendTexture) 4978 if (sendTexture)
4900 textureEntry = presence.Appearance.Texture.GetBytes(); 4979 textureEntry = presence.Appearance.Texture.GetBytes();
@@ -5001,13 +5080,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5001 5080
5002 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5081 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
5003 { 5082 {
5083 Vector3 offsetPosition = data.OffsetPosition;
5084 Quaternion rotation = data.Rotation;
5085 uint parentID = data.ParentID;
5086
5087 if (parentID != 0)
5088 {
5089 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5090 if (part != null && part != part.ParentGroup.RootPart)
5091 {
5092 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5093 rotation = part.RotationOffset * data.Rotation;
5094 parentID = part.ParentGroup.RootPart.LocalId;
5095 }
5096 }
5097
5004 byte[] objectData = new byte[76]; 5098 byte[] objectData = new byte[76];
5005 5099
5006 data.CollisionPlane.ToBytes(objectData, 0); 5100 data.CollisionPlane.ToBytes(objectData, 0);
5007 data.OffsetPosition.ToBytes(objectData, 16); 5101 offsetPosition.ToBytes(objectData, 16);
5008// data.Velocity.ToBytes(objectData, 28); 5102// data.Velocity.ToBytes(objectData, 28);
5009// data.Acceleration.ToBytes(objectData, 40); 5103// data.Acceleration.ToBytes(objectData, 40);
5010 data.Rotation.ToBytes(objectData, 52); 5104 rotation.ToBytes(objectData, 52);
5011 //data.AngularVelocity.ToBytes(objectData, 64); 5105 //data.AngularVelocity.ToBytes(objectData, 64);
5012 5106
5013 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5107 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -5021,14 +5115,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5021 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5115 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
5022 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5116 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
5023 update.ObjectData = objectData; 5117 update.ObjectData = objectData;
5024 update.ParentID = data.ParentID; 5118 update.ParentID = parentID;
5025 update.PathCurve = 16; 5119 update.PathCurve = 16;
5026 update.PathScaleX = 100; 5120 update.PathScaleX = 100;
5027 update.PathScaleY = 100; 5121 update.PathScaleY = 100;
5028 update.PCode = (byte)PCode.Avatar; 5122 update.PCode = (byte)PCode.Avatar;
5029 update.ProfileCurve = 1; 5123 update.ProfileCurve = 1;
5030 update.PSBlock = Utils.EmptyBytes; 5124 update.PSBlock = Utils.EmptyBytes;
5031 update.Scale = new Vector3(0.45f, 0.6f, 1.9f); 5125 update.Scale = data.Appearance.AvatarSize;
5126// update.Scale.Z -= 0.2f;
5127
5032 update.Text = Utils.EmptyBytes; 5128 update.Text = Utils.EmptyBytes;
5033 update.TextColor = new byte[4]; 5129 update.TextColor = new byte[4];
5034 5130
@@ -5039,10 +5135,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5039 update.TextureEntry = Utils.EmptyBytes; 5135 update.TextureEntry = Utils.EmptyBytes;
5040// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; 5136// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
5041 5137
5138/* 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)( 5139 update.UpdateFlags = (uint)(
5043 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | 5140 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
5044 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | 5141 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
5045 PrimFlags.ObjectOwnerModify); 5142 PrimFlags.ObjectOwnerModify);
5143*/
5144 update.UpdateFlags = 0;
5046 5145
5047 return update; 5146 return update;
5048 } 5147 }
@@ -5213,8 +5312,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5213 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs 5312 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs
5214 // for each AgentUpdate packet. 5313 // for each AgentUpdate packet.
5215 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false); 5314 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false);
5216 5315
5217 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false); 5316 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false);
5317 AddLocalPacketHandler(PacketType.VelocityInterpolateOff, HandleVelocityInterpolateOff, false);
5318 AddLocalPacketHandler(PacketType.VelocityInterpolateOn, HandleVelocityInterpolateOn, false);
5218 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); 5319 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false);
5219 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); 5320 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
5220 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false); 5321 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false);
@@ -5366,6 +5467,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5366 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5467 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5367 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5468 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5368 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5469 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5470 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5369 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5471 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5370 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5472 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5371 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5473 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5432,6 +5534,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5432 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5534 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5433 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5535 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5434 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5536 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5537 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5435 5538
5436 AddGenericPacketHandler("autopilot", HandleAutopilot); 5539 AddGenericPacketHandler("autopilot", HandleAutopilot);
5437 } 5540 }
@@ -5470,6 +5573,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5470 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) || 5573 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) ||
5471 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) || 5574 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) ||
5472 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) || 5575 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) ||
5576 (x.ControlFlags != 0) ||
5473 (x.Far != m_lastAgentUpdateArgs.Far) || 5577 (x.Far != m_lastAgentUpdateArgs.Far) ||
5474 (x.Flags != m_lastAgentUpdateArgs.Flags) || 5578 (x.Flags != m_lastAgentUpdateArgs.Flags) ||
5475 (x.State != m_lastAgentUpdateArgs.State) || 5579 (x.State != m_lastAgentUpdateArgs.State) ||
@@ -5729,6 +5833,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5729 return true; 5833 return true;
5730 } 5834 }
5731 5835
5836 private bool HandleVelocityInterpolateOff(IClientAPI sender, Packet Pack)
5837 {
5838 VelocityInterpolateOffPacket p = (VelocityInterpolateOffPacket)Pack;
5839 if (p.AgentData.SessionID != SessionId ||
5840 p.AgentData.AgentID != AgentId)
5841 return true;
5842
5843 m_VelocityInterpolate = false;
5844 return true;
5845 }
5846
5847 private bool HandleVelocityInterpolateOn(IClientAPI sender, Packet Pack)
5848 {
5849 VelocityInterpolateOnPacket p = (VelocityInterpolateOnPacket)Pack;
5850 if (p.AgentData.SessionID != SessionId ||
5851 p.AgentData.AgentID != AgentId)
5852 return true;
5853
5854 m_VelocityInterpolate = true;
5855 return true;
5856 }
5857
5858
5732 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack) 5859 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack)
5733 { 5860 {
5734 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack; 5861 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack;
@@ -6149,6 +6276,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6149 // Temporarily protect ourselves from the mantis #951 failure. 6276 // Temporarily protect ourselves from the mantis #951 failure.
6150 // However, we could do this for several other handlers where a failure isn't terminal 6277 // However, we could do this for several other handlers where a failure isn't terminal
6151 // for the client session anyway, in order to protect ourselves against bad code in plugins 6278 // for the client session anyway, in order to protect ourselves against bad code in plugins
6279 Vector3 avSize = appear.AgentData.Size;
6152 try 6280 try
6153 { 6281 {
6154 byte[] visualparams = new byte[appear.VisualParam.Length]; 6282 byte[] visualparams = new byte[appear.VisualParam.Length];
@@ -6159,7 +6287,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6159 if (appear.ObjectData.TextureEntry.Length > 1) 6287 if (appear.ObjectData.TextureEntry.Length > 1)
6160 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); 6288 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
6161 6289
6162 handlerSetAppearance(sender, te, visualparams); 6290 handlerSetAppearance(sender, te, visualparams,avSize);
6163 } 6291 }
6164 catch (Exception e) 6292 catch (Exception e)
6165 { 6293 {
@@ -6368,6 +6496,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6368 { 6496 {
6369 handlerCompleteMovementToRegion(sender, true); 6497 handlerCompleteMovementToRegion(sender, true);
6370 } 6498 }
6499 else
6500 m_log.Debug("HandleCompleteAgentMovement NULL handler");
6501
6371 handlerCompleteMovementToRegion = null; 6502 handlerCompleteMovementToRegion = null;
6372 6503
6373 return true; 6504 return true;
@@ -6385,7 +6516,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6385 return true; 6516 return true;
6386 } 6517 }
6387 #endregion 6518 #endregion
6388 6519/*
6389 StartAnim handlerStartAnim = null; 6520 StartAnim handlerStartAnim = null;
6390 StopAnim handlerStopAnim = null; 6521 StopAnim handlerStopAnim = null;
6391 6522
@@ -6409,6 +6540,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6409 } 6540 }
6410 } 6541 }
6411 return true; 6542 return true;
6543*/
6544 ChangeAnim handlerChangeAnim = null;
6545
6546 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6547 {
6548 handlerChangeAnim = OnChangeAnim;
6549 if (handlerChangeAnim != null)
6550 {
6551 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6552 }
6553 }
6554
6555 handlerChangeAnim = OnChangeAnim;
6556 if (handlerChangeAnim != null)
6557 {
6558 handlerChangeAnim(UUID.Zero, false, true);
6559 }
6560
6561 return true;
6412 } 6562 }
6413 6563
6414 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6564 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -6633,6 +6783,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6633 #endregion 6783 #endregion
6634 6784
6635 m_udpClient.SetThrottles(atpack.Throttle.Throttles); 6785 m_udpClient.SetThrottles(atpack.Throttle.Throttles);
6786 GenericCall2 handler = OnUpdateThrottles;
6787 if (handler != null)
6788 {
6789 handler();
6790 }
6636 return true; 6791 return true;
6637 } 6792 }
6638 6793
@@ -7034,10 +7189,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7034 // 46,47,48 are special positions within the packet 7189 // 46,47,48 are special positions within the packet
7035 // This may change so perhaps we need a better way 7190 // This may change so perhaps we need a better way
7036 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) 7191 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
7037 bool UsePhysics = (data[46] != 0) ? true : false; 7192 /*
7038 bool IsTemporary = (data[47] != 0) ? true : false; 7193 bool UsePhysics = (data[46] != 0) ? true : false;
7039 bool IsPhantom = (data[48] != 0) ? true : false; 7194 bool IsTemporary = (data[47] != 0) ? true : false;
7040 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this); 7195 bool IsPhantom = (data[48] != 0) ? true : false;
7196 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this);
7197 */
7198 bool UsePhysics = flags.AgentData.UsePhysics;
7199 bool IsPhantom = flags.AgentData.IsPhantom;
7200 bool IsTemporary = flags.AgentData.IsTemporary;
7201 ObjectFlagUpdatePacket.ExtraPhysicsBlock[] blocks = flags.ExtraPhysics;
7202 ExtraPhysicsData physdata = new ExtraPhysicsData();
7203
7204 if (blocks == null || blocks.Length == 0)
7205 {
7206 physdata.PhysShapeType = PhysShapeType.invalid;
7207 }
7208 else
7209 {
7210 ObjectFlagUpdatePacket.ExtraPhysicsBlock phsblock = blocks[0];
7211 physdata.PhysShapeType = (PhysShapeType)phsblock.PhysicsShapeType;
7212 physdata.Bounce = phsblock.Restitution;
7213 physdata.Density = phsblock.Density;
7214 physdata.Friction = phsblock.Friction;
7215 physdata.GravitationModifier = phsblock.GravityMultiplier;
7216 }
7217
7218 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
7041 } 7219 }
7042 return true; 7220 return true;
7043 } 7221 }
@@ -8638,16 +8816,61 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8638 8816
8639 #region Parcel related packets 8817 #region Parcel related packets
8640 8818
8819 // acumulate several HandleRegionHandleRequest consecutive overlaping requests
8820 // to be done with minimal resources as possible
8821 // variables temporary here while in test
8822
8823 Queue<UUID> RegionHandleRequests = new Queue<UUID>();
8824 bool RegionHandleRequestsInService = false;
8825
8641 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack) 8826 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack)
8642 { 8827 {
8643 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; 8828 UUID currentUUID;
8644 8829
8645 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; 8830 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest;
8646 if (handlerRegionHandleRequest != null) 8831
8832 if (handlerRegionHandleRequest == null)
8833 return true;
8834
8835 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
8836
8837 lock (RegionHandleRequests)
8647 { 8838 {
8648 handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); 8839 if (RegionHandleRequestsInService)
8840 {
8841 // we are already busy doing a previus request
8842 // so enqueue it
8843 RegionHandleRequests.Enqueue(rhrPack.RequestBlock.RegionID);
8844 return true;
8845 }
8846
8847 // else do it
8848 currentUUID = rhrPack.RequestBlock.RegionID;
8849 RegionHandleRequestsInService = true;
8649 } 8850 }
8650 return true; 8851
8852 while (true)
8853 {
8854 handlerRegionHandleRequest(this, currentUUID);
8855
8856 lock (RegionHandleRequests)
8857 {
8858 // exit condition, nothing to do or closed
8859 // current code seems to assume we may loose the handler at anytime,
8860 // so keep checking it
8861 handlerRegionHandleRequest = OnRegionHandleRequest;
8862
8863 if (RegionHandleRequests.Count == 0 || !IsActive || handlerRegionHandleRequest == null)
8864 {
8865 RegionHandleRequests.Clear();
8866 RegionHandleRequestsInService = false;
8867 return true;
8868 }
8869 currentUUID = RegionHandleRequests.Dequeue();
8870 }
8871 }
8872
8873 return true; // actually unreached
8651 } 8874 }
8652 8875
8653 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack) 8876 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack)
@@ -9903,7 +10126,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9903 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 10126 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9904 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 10127 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9905 UpdateMuteListEntry.MuteData.MuteType, 10128 UpdateMuteListEntry.MuteData.MuteType,
9906 UpdateMuteListEntry.AgentData.AgentID); 10129 UpdateMuteListEntry.MuteData.MuteFlags);
9907 return true; 10130 return true;
9908 } 10131 }
9909 return false; 10132 return false;
@@ -9918,8 +10141,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9918 { 10141 {
9919 handlerRemoveMuteListEntry(this, 10142 handlerRemoveMuteListEntry(this,
9920 RemoveMuteListEntry.MuteData.MuteID, 10143 RemoveMuteListEntry.MuteData.MuteID,
9921 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 10144 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9922 RemoveMuteListEntry.AgentData.AgentID);
9923 return true; 10145 return true;
9924 } 10146 }
9925 return false; 10147 return false;
@@ -9963,10 +10185,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9963 return false; 10185 return false;
9964 } 10186 }
9965 10187
10188 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10189 {
10190 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10191 (ChangeInventoryItemFlagsPacket)packet;
10192 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10193 if (handlerChangeInventoryItemFlags != null)
10194 {
10195 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10196 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10197 return true;
10198 }
10199 return false;
10200 }
10201
9966 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10202 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9967 { 10203 {
9968 return true; 10204 return true;
9969 } 10205 }
10206
10207 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10208 {
10209 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10210
10211 #region Packet Session and User Check
10212 if (m_checkPackets)
10213 {
10214 if (packet.AgentData.SessionID != SessionId ||
10215 packet.AgentData.AgentID != AgentId)
10216 return true;
10217 }
10218 #endregion
10219 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10220 List<InventoryItemBase> items = new List<InventoryItemBase>();
10221 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10222 {
10223 InventoryItemBase b = new InventoryItemBase();
10224 b.ID = n.OldItemID;
10225 b.Folder = n.OldFolderID;
10226 items.Add(b);
10227 }
10228
10229 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10230 if (handlerMoveItemsAndLeaveCopy != null)
10231 {
10232 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10233 }
10234
10235 return true;
10236 }
9970 10237
9971 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10238 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9972 { 10239 {
@@ -10393,6 +10660,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10393 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10660 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10394 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10661 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10395 10662
10663 Scene scene = (Scene)m_scene;
10664 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10665 {
10666 ScenePresence p;
10667 if (scene.TryGetScenePresence(sender.AgentId, out p))
10668 {
10669 if (p.GodLevel >= 200)
10670 {
10671 groupProfileReply.GroupData.OpenEnrollment = true;
10672 groupProfileReply.GroupData.MembershipFee = 0;
10673 }
10674 }
10675 }
10676
10396 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10677 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10397 } 10678 }
10398 return true; 10679 return true;
@@ -10966,11 +11247,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10966 11247
10967 StartLure handlerStartLure = OnStartLure; 11248 StartLure handlerStartLure = OnStartLure;
10968 if (handlerStartLure != null) 11249 if (handlerStartLure != null)
10969 handlerStartLure(startLureRequest.Info.LureType, 11250 {
10970 Utils.BytesToString( 11251 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10971 startLureRequest.Info.Message), 11252 {
10972 startLureRequest.TargetData[0].TargetID, 11253 handlerStartLure(startLureRequest.Info.LureType,
10973 this); 11254 Utils.BytesToString(
11255 startLureRequest.Info.Message),
11256 startLureRequest.TargetData[i].TargetID,
11257 this);
11258 }
11259 }
10974 return true; 11260 return true;
10975 } 11261 }
10976 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11262 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -11084,10 +11370,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11084 } 11370 }
11085 #endregion 11371 #endregion
11086 11372
11087 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11373 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11088 if (handlerClassifiedGodDelete != null) 11374 if (handlerClassifiedGodDelete != null)
11089 handlerClassifiedGodDelete( 11375 handlerClassifiedGodDelete(
11090 classifiedGodDelete.Data.ClassifiedID, 11376 classifiedGodDelete.Data.ClassifiedID,
11377 classifiedGodDelete.Data.QueryID,
11091 this); 11378 this);
11092 return true; 11379 return true;
11093 } 11380 }
@@ -11409,14 +11696,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11409 cachedresp.WearableData = 11696 cachedresp.WearableData =
11410 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length]; 11697 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
11411 11698
11412 for (int i = 0; i < cachedtex.WearableData.Length; i++) 11699 IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
11700 if (cache == null)
11413 { 11701 {
11414 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); 11702 for (int i = 0; i < cachedtex.WearableData.Length; i++)
11415 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; 11703 {
11416 cachedresp.WearableData[i].TextureID = UUID.Zero; 11704 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11417 cachedresp.WearableData[i].HostName = new byte[0]; 11705 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11706 cachedresp.WearableData[i].TextureID = UUID.Zero;
11707 cachedresp.WearableData[i].HostName = new byte[0];
11708 }
11709 }
11710 else
11711 {
11712 for (int i = 0; i < cachedtex.WearableData.Length; i++)
11713 {
11714 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11715 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11716 if(cache.Check(cachedtex.WearableData[i].ID.ToString()))
11717 cachedresp.WearableData[i].TextureID = UUID.Zero;
11718 else
11719 cachedresp.WearableData[i].TextureID = UUID.Zero;
11720 cachedresp.WearableData[i].HostName = new byte[0];
11721 }
11418 } 11722 }
11419
11420 cachedresp.Header.Zerocoded = true; 11723 cachedresp.Header.Zerocoded = true;
11421 OutPacket(cachedresp, ThrottleOutPacketType.Task); 11724 OutPacket(cachedresp, ThrottleOutPacketType.Task);
11422 11725
@@ -11453,209 +11756,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11453 } 11756 }
11454 else 11757 else
11455 { 11758 {
11456// m_log.DebugFormat( 11759 ClientChangeObject updatehandler = onClientChangeObject;
11457// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11458// i, block.Type, part.Name, part.LocalId);
11459 11760
11460// // Do this once since fetch parts creates a new array. 11761 if (updatehandler != null)
11461// SceneObjectPart[] parts = part.ParentGroup.Parts; 11762 {
11462// for (int j = 0; j < parts.Length; j++) 11763 ObjectChangeData udata = new ObjectChangeData();
11463// {
11464// part.StoreUndoState();
11465// parts[j].IgnoreUndoUpdate = true;
11466// }
11467 11764
11468 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11765 /*ubit from ll JIRA:
11766 * 0x01 position
11767 * 0x02 rotation
11768 * 0x04 scale
11769
11770 * 0x08 LINK_SET
11771 * 0x10 UNIFORM for scale
11772 */
11469 11773
11470 switch (block.Type) 11774 // translate to internal changes
11471 { 11775 // not all cases .. just the ones older code did
11472 case 1:
11473 Vector3 pos1 = new Vector3(block.Data, 0);
11474 11776
11475 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11777 switch (block.Type)
11476 if (handlerUpdatePrimSinglePosition != null) 11778 {
11477 { 11779 case 1: //change position sp
11478 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11780 udata.position = new Vector3(block.Data, 0);
11479 handlerUpdatePrimSinglePosition(localId, pos1, this);
11480 }
11481 break;
11482 11781
11483 case 2: 11782 udata.change = ObjectChangeType.primP;
11484 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11783 updatehandler(localId, udata, this);
11784 break;
11485 11785
11486 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11786 case 2: // rotation sp
11487 if (handlerUpdatePrimSingleRotation != null) 11787 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 11788
11494 case 3: 11789 udata.change = ObjectChangeType.primR;
11495 Vector3 rotPos = new Vector3(block.Data, 0); 11790 updatehandler(localId, udata, this);
11496 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11791 break;
11497 11792
11498 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11793 case 3: // position plus rotation
11499 if (handlerUpdatePrimSingleRotationPosition != null) 11794 udata.position = new Vector3(block.Data, 0);
11500 { 11795 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 11796
11507 case 4: 11797 udata.change = ObjectChangeType.primPR;
11508 case 20: 11798 updatehandler(localId, udata, this);
11509 Vector3 scale4 = new Vector3(block.Data, 0); 11799 break;
11510 11800
11511 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11801 case 4: // scale sp
11512 if (handlerUpdatePrimScale != null) 11802 udata.scale = new Vector3(block.Data, 0);
11513 { 11803 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 11804
11519 case 5: 11805 updatehandler(localId, udata, this);
11520 Vector3 scale1 = new Vector3(block.Data, 12); 11806 break;
11521 Vector3 pos11 = new Vector3(block.Data, 0);
11522 11807
11523 handlerUpdatePrimScale = OnUpdatePrimScale; 11808 case 0x14: // uniform scale sp
11524 if (handlerUpdatePrimScale != null) 11809 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 11810
11529 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11811 udata.change = ObjectChangeType.primUS;
11530 if (handlerUpdatePrimSinglePosition != null) 11812 updatehandler(localId, udata, this);
11531 { 11813 break;
11532 handlerUpdatePrimSinglePosition(localId, pos11, this);
11533 }
11534 }
11535 break;
11536 11814
11537 case 9: 11815 case 5: // scale and position sp
11538 Vector3 pos2 = new Vector3(block.Data, 0); 11816 udata.position = new Vector3(block.Data, 0);
11817 udata.scale = new Vector3(block.Data, 12);
11539 11818
11540 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11819 udata.change = ObjectChangeType.primPS;
11820 updatehandler(localId, udata, this);
11821 break;
11541 11822
11542 if (handlerUpdateVector != null) 11823 case 0x15: //uniform scale and position
11543 { 11824 udata.position = new Vector3(block.Data, 0);
11544 handlerUpdateVector(localId, pos2, this); 11825 udata.scale = new Vector3(block.Data, 12);
11545 }
11546 break;
11547 11826
11548 case 10: 11827 udata.change = ObjectChangeType.primPUS;
11549 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11828 updatehandler(localId, udata, this);
11829 break;
11550 11830
11551 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11831 // now group related (bit 4)
11552 if (handlerUpdatePrimRotation != null) 11832 case 9: //( 8 + 1 )group position
11553 { 11833 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 11834
11559 case 11: 11835 udata.change = ObjectChangeType.groupP;
11560 Vector3 pos3 = new Vector3(block.Data, 0); 11836 updatehandler(localId, udata, this);
11561 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11837 break;
11562 11838
11563 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11839 case 0x0A: // (8 + 2) group rotation
11564 if (handlerUpdatePrimGroupRotation != null) 11840 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 11841
11575 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11842 udata.change = ObjectChangeType.groupR;
11576 if (handlerUpdatePrimGroupScale != null) 11843 updatehandler(localId, udata, this);
11577 { 11844 break;
11578 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11579 handlerUpdatePrimGroupScale(localId, scale7, this);
11580 }
11581 break;
11582 11845
11583 case 13: 11846 case 0x0B: //( 8 + 2 + 1) group rotation and position
11584 Vector3 scale2 = new Vector3(block.Data, 12); 11847 udata.position = new Vector3(block.Data, 0);
11585 Vector3 pos4 = new Vector3(block.Data, 0); 11848 udata.rotation = new Quaternion(block.Data, 12, true);
11586 11849
11587 handlerUpdatePrimScale = OnUpdatePrimScale; 11850 udata.change = ObjectChangeType.groupPR;
11588 if (handlerUpdatePrimScale != null) 11851 updatehandler(localId, udata, this);
11589 { 11852 break;
11590 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11591 handlerUpdatePrimScale(localId, scale2, this);
11592 11853
11593 // Change the position based on scale (for bug number 246) 11854 case 0x0C: // (8 + 4) group scale
11594 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11855 // 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); 11856 // mouse edition only allows uniform scaling
11596 if (handlerUpdatePrimSinglePosition != null) 11857 // SL MAY CHANGE THIS in viewers
11597 {
11598 handlerUpdatePrimSinglePosition(localId, pos4, this);
11599 }
11600 }
11601 break;
11602 11858
11603 case 29: 11859 udata.scale = new Vector3(block.Data, 0);
11604 Vector3 scale5 = new Vector3(block.Data, 12);
11605 Vector3 pos5 = new Vector3(block.Data, 0);
11606 11860
11607 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11861 udata.change = ObjectChangeType.groupS;
11608 if (handlerUpdatePrimGroupScale != null) 11862 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 11863
11616 if (handlerUpdateVector != null) 11864 break;
11617 {
11618 handlerUpdateVector(localId, pos5, this);
11619 }
11620 11865
11621 part.IgnoreUndoUpdate = false; 11866 case 0x0D: //(8 + 4 + 1) group scale and position
11622 } 11867 // exception as above
11623 11868
11624 break; 11869 udata.position = new Vector3(block.Data, 0);
11870 udata.scale = new Vector3(block.Data, 12);
11625 11871
11626 case 21: 11872 udata.change = ObjectChangeType.groupPS;
11627 Vector3 scale6 = new Vector3(block.Data, 12); 11873 updatehandler(localId, udata, this);
11628 Vector3 pos6 = new Vector3(block.Data, 0); 11874 break;
11629 11875
11630 handlerUpdatePrimScale = OnUpdatePrimScale; 11876 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11631 if (handlerUpdatePrimScale != null) 11877 udata.scale = new Vector3(block.Data, 0);
11632 {
11633 part.StoreUndoState(false);
11634 part.IgnoreUndoUpdate = true;
11635 11878
11636 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 11879 udata.change = ObjectChangeType.groupUS;
11637 handlerUpdatePrimScale(localId, scale6, this); 11880 updatehandler(localId, udata, this);
11638 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11881 break;
11639 if (handlerUpdatePrimSinglePosition != null)
11640 {
11641 handlerUpdatePrimSinglePosition(localId, pos6, this);
11642 }
11643 11882
11644 part.IgnoreUndoUpdate = false; 11883 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11645 } 11884 udata.position = new Vector3(block.Data, 0);
11646 break; 11885 udata.scale = new Vector3(block.Data, 12);
11647 11886
11648 default: 11887 udata.change = ObjectChangeType.groupPUS;
11649 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 11888 updatehandler(localId, udata, this);
11650 break; 11889 break;
11890
11891 default:
11892 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
11893 break;
11894 }
11651 } 11895 }
11652 11896
11653// for (int j = 0; j < parts.Length; j++)
11654// parts[j].IgnoreUndoUpdate = false;
11655 } 11897 }
11656 } 11898 }
11657 } 11899 }
11658
11659 return true; 11900 return true;
11660 } 11901 }
11661 11902
@@ -11716,9 +11957,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11716 public void SetChildAgentThrottle(byte[] throttles) 11957 public void SetChildAgentThrottle(byte[] throttles)
11717 { 11958 {
11718 m_udpClient.SetThrottles(throttles); 11959 m_udpClient.SetThrottles(throttles);
11960 GenericCall2 handler = OnUpdateThrottles;
11961 if (handler != null)
11962 {
11963 handler();
11964 }
11719 } 11965 }
11720 11966
11721 /// <summary> 11967 /// <summary>
11968 /// Sets the throttles from values supplied by the client
11969 /// </summary>
11970 /// <param name="throttles"></param>
11971 public void SetAgentThrottleSilent(int throttle, int setting)
11972 {
11973 m_udpClient.ForceThrottleSetting(throttle,setting);
11974 //m_udpClient.SetThrottles(throttles);
11975
11976 }
11977
11978
11979 /// <summary>
11722 /// Get the current throttles for this client as a packed byte array 11980 /// Get the current throttles for this client as a packed byte array
11723 /// </summary> 11981 /// </summary>
11724 /// <param name="multiplier">Unused</param> 11982 /// <param name="multiplier">Unused</param>
@@ -12105,7 +12363,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12105// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12363// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12106// requestID, taskID, (SourceType)sourceType, Name); 12364// requestID, taskID, (SourceType)sourceType, Name);
12107 12365
12366
12367 //Note, the bool returned from the below function is useless since it is always false.
12108 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12368 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12369
12109 } 12370 }
12110 12371
12111 /// <summary> 12372 /// <summary>
@@ -12171,7 +12432,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12171 /// <returns></returns> 12432 /// <returns></returns>
12172 private static int CalculateNumPackets(byte[] data) 12433 private static int CalculateNumPackets(byte[] data)
12173 { 12434 {
12174 const uint m_maxPacketSize = 600; 12435// const uint m_maxPacketSize = 600;
12436 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12175 int numPackets = 1; 12437 int numPackets = 1;
12176 12438
12177 if (data == null) 12439 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 f143c32..7035e38 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -114,10 +114,6 @@ namespace OpenMetaverse
114 const int SIO_UDP_CONNRESET = -1744830452; 114 const int SIO_UDP_CONNRESET = -1744830452;
115 115
116 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort); 116 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort);
117
118 m_log.DebugFormat(
119 "[UDPBASE]: Binding UDP listener using internal IP address config {0}:{1}",
120 ipep.Address, ipep.Port);
121 117
122 m_udpSocket = new Socket( 118 m_udpSocket = new Socket(
123 AddressFamily.InterNetwork, 119 AddressFamily.InterNetwork,