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.cs1198
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs65
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs218
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs4
5 files changed, 943 insertions, 545 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 0869bd5..6ccabf1 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -98,6 +98,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
98 public event AvatarPickerRequest OnAvatarPickerRequest; 98 public event AvatarPickerRequest OnAvatarPickerRequest;
99 public event StartAnim OnStartAnim; 99 public event StartAnim OnStartAnim;
100 public event StopAnim OnStopAnim; 100 public event StopAnim OnStopAnim;
101 public event ChangeAnim OnChangeAnim;
101 public event Action<IClientAPI> OnRequestAvatarsData; 102 public event Action<IClientAPI> OnRequestAvatarsData;
102 public event LinkObjects OnLinkObjects; 103 public event LinkObjects OnLinkObjects;
103 public event DelinkObjects OnDelinkObjects; 104 public event DelinkObjects OnDelinkObjects;
@@ -125,6 +126,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
125 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; 126 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
126 public event UpdatePrimFlags OnUpdatePrimFlags; 127 public event UpdatePrimFlags OnUpdatePrimFlags;
127 public event UpdatePrimTexture OnUpdatePrimTexture; 128 public event UpdatePrimTexture OnUpdatePrimTexture;
129 public event ClientChangeObject onClientChangeObject;
128 public event UpdateVector OnUpdatePrimGroupPosition; 130 public event UpdateVector OnUpdatePrimGroupPosition;
129 public event UpdateVector OnUpdatePrimSinglePosition; 131 public event UpdateVector OnUpdatePrimSinglePosition;
130 public event UpdatePrimRotation OnUpdatePrimGroupRotation; 132 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
@@ -158,6 +160,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
158 public event RequestTaskInventory OnRequestTaskInventory; 160 public event RequestTaskInventory OnRequestTaskInventory;
159 public event UpdateInventoryItem OnUpdateInventoryItem; 161 public event UpdateInventoryItem OnUpdateInventoryItem;
160 public event CopyInventoryItem OnCopyInventoryItem; 162 public event CopyInventoryItem OnCopyInventoryItem;
163 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
161 public event MoveInventoryItem OnMoveInventoryItem; 164 public event MoveInventoryItem OnMoveInventoryItem;
162 public event RemoveInventoryItem OnRemoveInventoryItem; 165 public event RemoveInventoryItem OnRemoveInventoryItem;
163 public event RemoveInventoryFolder OnRemoveInventoryFolder; 166 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -256,7 +259,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
256 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 259 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
257 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 260 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
258 public event ClassifiedDelete OnClassifiedDelete; 261 public event ClassifiedDelete OnClassifiedDelete;
259 public event ClassifiedDelete OnClassifiedGodDelete; 262 public event ClassifiedGodDelete OnClassifiedGodDelete;
260 public event EventNotificationAddRequest OnEventNotificationAddRequest; 263 public event EventNotificationAddRequest OnEventNotificationAddRequest;
261 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 264 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
262 public event EventGodDelete OnEventGodDelete; 265 public event EventGodDelete OnEventGodDelete;
@@ -287,6 +290,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
287 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; 290 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
288 public event SimWideDeletesDelegate OnSimWideDeletes; 291 public event SimWideDeletesDelegate OnSimWideDeletes;
289 public event SendPostcard OnSendPostcard; 292 public event SendPostcard OnSendPostcard;
293 public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
290 public event MuteListEntryUpdate OnUpdateMuteListEntry; 294 public event MuteListEntryUpdate OnUpdateMuteListEntry;
291 public event MuteListEntryRemove OnRemoveMuteListEntry; 295 public event MuteListEntryRemove OnRemoveMuteListEntry;
292 public event GodlikeMessage onGodlikeMessage; 296 public event GodlikeMessage onGodlikeMessage;
@@ -325,6 +329,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
325 private Prioritizer m_prioritizer; 329 private Prioritizer m_prioritizer;
326 private bool m_disableFacelights = false; 330 private bool m_disableFacelights = false;
327 331
332 private const uint MaxTransferBytesPerPacket = 600;
333
334
328 /// <value> 335 /// <value>
329 /// List used in construction of data blocks for an object update packet. This is to stop us having to 336 /// List used in construction of data blocks for an object update packet. This is to stop us having to
330 /// continually recreate it. 337 /// continually recreate it.
@@ -336,14 +343,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
336 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 343 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
337 /// ownerless phantom. 344 /// ownerless phantom.
338 /// 345 ///
339 /// All manipulation of this set has to occur under a lock 346 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
340 /// 347 ///
341 /// </value> 348 /// </value>
342 protected HashSet<uint> m_killRecord; 349// protected HashSet<uint> m_killRecord;
343 350
344// protected HashSet<uint> m_attachmentsSent; 351// protected HashSet<uint> m_attachmentsSent;
345 352
346 private int m_moneyBalance; 353 private int m_moneyBalance;
354 private bool m_deliverPackets = true;
347 private int m_animationSequenceNumber = 1; 355 private int m_animationSequenceNumber = 1;
348 private bool m_SendLogoutPacketWhenClosing = true; 356 private bool m_SendLogoutPacketWhenClosing = true;
349 private AgentUpdateArgs lastarg; 357 private AgentUpdateArgs lastarg;
@@ -380,6 +388,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
380 get { return m_startpos; } 388 get { return m_startpos; }
381 set { m_startpos = value; } 389 set { m_startpos = value; }
382 } 390 }
391 public bool DeliverPackets
392 {
393 get { return m_deliverPackets; }
394 set {
395 m_deliverPackets = value;
396 m_udpClient.m_deliverPackets = value;
397 }
398 }
383 public UUID AgentId { get { return m_agentId; } } 399 public UUID AgentId { get { return m_agentId; } }
384 public ISceneAgent SceneAgent { get; set; } 400 public ISceneAgent SceneAgent { get; set; }
385 public UUID ActiveGroupId { get { return m_activeGroupID; } } 401 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -457,7 +473,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
457 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 473 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
458 m_entityProps = new PriorityQueue(m_scene.Entities.Count); 474 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
459 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 475 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
460 m_killRecord = new HashSet<uint>(); 476// m_killRecord = new HashSet<uint>();
461// m_attachmentsSent = new HashSet<uint>(); 477// m_attachmentsSent = new HashSet<uint>();
462 478
463 m_assetService = m_scene.RequestModuleInterface<IAssetService>(); 479 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
@@ -487,12 +503,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
487 503
488 #region Client Methods 504 #region Client Methods
489 505
506
507 /// <summary>
508 /// Close down the client view
509 /// </summary>
490 public void Close() 510 public void Close()
491 { 511 {
492 Close(false); 512 Close(true, false);
493 } 513 }
494 514
495 public void Close(bool force) 515 public void Close(bool sendStop, bool force)
496 { 516 {
497 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. 517 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
498 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. 518 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
@@ -504,7 +524,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
504 return; 524 return;
505 525
506 IsActive = false; 526 IsActive = false;
507 CloseWithoutChecks(); 527 CloseWithoutChecks(sendStop);
508 } 528 }
509 } 529 }
510 530
@@ -517,12 +537,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
517 /// 537 ///
518 /// Callers must lock ClosingSyncLock before calling. 538 /// Callers must lock ClosingSyncLock before calling.
519 /// </remarks> 539 /// </remarks>
520 public void CloseWithoutChecks() 540 public void CloseWithoutChecks(bool sendStop)
521 { 541 {
522 m_log.DebugFormat( 542 m_log.DebugFormat(
523 "[CLIENT]: Close has been called for {0} attached to scene {1}", 543 "[CLIENT]: Close has been called for {0} attached to scene {1}",
524 Name, m_scene.RegionInfo.RegionName); 544 Name, m_scene.RegionInfo.RegionName);
525 545
546 if (sendStop)
547 {
548 // Send the STOP packet
549 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
550 OutPacket(disable, ThrottleOutPacketType.Unknown);
551 }
552
526 // Shutdown the image manager 553 // Shutdown the image manager
527 ImageManager.Close(); 554 ImageManager.Close();
528 555
@@ -780,7 +807,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
780 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType); 807 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType);
781 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes; 808 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes;
782 809
783 OutPacket(handshake, ThrottleOutPacketType.Task); 810// OutPacket(handshake, ThrottleOutPacketType.Task);
811 // use same as MoveAgentIntoRegion (both should be task )
812 OutPacket(handshake, ThrottleOutPacketType.Unknown);
784 } 813 }
785 814
786 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) 815 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
@@ -819,7 +848,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
819 reply.ChatData.OwnerID = fromAgentID; 848 reply.ChatData.OwnerID = fromAgentID;
820 reply.ChatData.SourceID = fromAgentID; 849 reply.ChatData.SourceID = fromAgentID;
821 850
822 OutPacket(reply, ThrottleOutPacketType.Task); 851 OutPacket(reply, ThrottleOutPacketType.Unknown);
823 } 852 }
824 853
825 /// <summary> 854 /// <summary>
@@ -1105,6 +1134,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1105 public virtual void SendLayerData(float[] map) 1134 public virtual void SendLayerData(float[] map)
1106 { 1135 {
1107 Util.FireAndForget(DoSendLayerData, map); 1136 Util.FireAndForget(DoSendLayerData, map);
1137
1138 // Send it sync, and async. It's not that much data
1139 // and it improves user experience just so much!
1140 DoSendLayerData(map);
1108 } 1141 }
1109 1142
1110 /// <summary> 1143 /// <summary>
@@ -1117,16 +1150,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1117 1150
1118 try 1151 try
1119 { 1152 {
1120 //for (int y = 0; y < 16; y++) 1153 for (int y = 0; y < 16; y++)
1121 //{ 1154 {
1122 // for (int x = 0; x < 16; x++) 1155 for (int x = 0; x < 16; x+=4)
1123 // { 1156 {
1124 // SendLayerData(x, y, map); 1157 SendLayerPacket(x, y, map);
1125 // } 1158 }
1126 //} 1159 }
1127
1128 // Send LayerData in a spiral pattern. Fun!
1129 SendLayerTopRight(map, 0, 0, 15, 15);
1130 } 1160 }
1131 catch (Exception e) 1161 catch (Exception e)
1132 { 1162 {
@@ -1134,51 +1164,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1134 } 1164 }
1135 } 1165 }
1136 1166
1137 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1138 {
1139 // Row
1140 for (int i = x1; i <= x2; i++)
1141 SendLayerData(i, y1, map);
1142
1143 // Column
1144 for (int j = y1 + 1; j <= y2; j++)
1145 SendLayerData(x2, j, map);
1146
1147 if (x2 - x1 > 0)
1148 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1149 }
1150
1151 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1152 {
1153 // Row in reverse
1154 for (int i = x2; i >= x1; i--)
1155 SendLayerData(i, y2, map);
1156
1157 // Column in reverse
1158 for (int j = y2 - 1; j >= y1; j--)
1159 SendLayerData(x1, j, map);
1160
1161 if (x2 - x1 > 0)
1162 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1163 }
1164
1165 /// <summary> 1167 /// <summary>
1166 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1168 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1167 /// </summary> 1169 /// </summary>
1168 /// <param name="map">heightmap</param> 1170 /// <param name="map">heightmap</param>
1169 /// <param name="px">X coordinate for patches 0..12</param> 1171 /// <param name="px">X coordinate for patches 0..12</param>
1170 /// <param name="py">Y coordinate for patches 0..15</param> 1172 /// <param name="py">Y coordinate for patches 0..15</param>
1171 // private void SendLayerPacket(float[] map, int y, int x) 1173 private void SendLayerPacket(int x, int y, float[] map)
1172 // { 1174 {
1173 // int[] patches = new int[4]; 1175 int[] patches = new int[4];
1174 // patches[0] = x + 0 + y * 16; 1176 patches[0] = x + 0 + y * 16;
1175 // patches[1] = x + 1 + y * 16; 1177 patches[1] = x + 1 + y * 16;
1176 // patches[2] = x + 2 + y * 16; 1178 patches[2] = x + 2 + y * 16;
1177 // patches[3] = x + 3 + y * 16; 1179 patches[3] = x + 3 + y * 16;
1178 1180
1179 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1181 float[] heightmap = (map.Length == 65536) ?
1180 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1182 map :
1181 // } 1183 LLHeightFieldMoronize(map);
1184
1185 try
1186 {
1187 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1188 OutPacket(layerpack, ThrottleOutPacketType.Land);
1189 }
1190 catch
1191 {
1192 for (int px = x ; px < x + 4 ; px++)
1193 SendLayerData(px, y, map);
1194 }
1195 }
1182 1196
1183 /// <summary> 1197 /// <summary>
1184 /// Sends a specified patch to a client 1198 /// Sends a specified patch to a client
@@ -1198,7 +1212,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1198 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1212 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1199 layerpack.Header.Reliable = true; 1213 layerpack.Header.Reliable = true;
1200 1214
1201 OutPacket(layerpack, ThrottleOutPacketType.Land); 1215 OutPacket(layerpack, ThrottleOutPacketType.Task);
1202 } 1216 }
1203 catch (Exception e) 1217 catch (Exception e)
1204 { 1218 {
@@ -1561,7 +1575,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1561 1575
1562 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1576 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1563 { 1577 {
1564// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1578// foreach (uint id in localIDs)
1579// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1565 1580
1566 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1581 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1567 // TODO: don't create new blocks if recycling an old packet 1582 // TODO: don't create new blocks if recycling an old packet
@@ -1583,17 +1598,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1583 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race 1598 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
1584 // condition where a kill can be processed before an out-of-date update for the same object. 1599 // condition where a kill can be processed before an out-of-date update for the same object.
1585 // ProcessEntityUpdates() also takes the m_killRecord lock. 1600 // ProcessEntityUpdates() also takes the m_killRecord lock.
1586 lock (m_killRecord) 1601// lock (m_killRecord)
1587 { 1602// {
1588 foreach (uint localID in localIDs) 1603// foreach (uint localID in localIDs)
1589 m_killRecord.Add(localID); 1604// m_killRecord.Add(localID);
1590 1605
1591 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1606 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1592 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1607 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1593 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1608 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1594 // scene objects in a viewer until that viewer is relogged in. 1609 // scene objects in a viewer until that viewer is relogged in.
1595 OutPacket(kill, ThrottleOutPacketType.Task); 1610 OutPacket(kill, ThrottleOutPacketType.Task);
1596 } 1611// }
1597 } 1612 }
1598 } 1613 }
1599 1614
@@ -2051,9 +2066,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2051 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); 2066 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
2052 } 2067 }
2053 2068
2054 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2055 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId) 2069 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
2056 { 2070 {
2071 SendInventoryItemCreateUpdate(Item, UUID.Zero, callbackId);
2072 }
2073
2074 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2075 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId)
2076 {
2057 const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; 2077 const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All;
2058 2078
2059 UpdateCreateInventoryItemPacket InventoryReply 2079 UpdateCreateInventoryItemPacket InventoryReply
@@ -2063,6 +2083,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2063 // TODO: don't create new blocks if recycling an old packet 2083 // TODO: don't create new blocks if recycling an old packet
2064 InventoryReply.AgentData.AgentID = AgentId; 2084 InventoryReply.AgentData.AgentID = AgentId;
2065 InventoryReply.AgentData.SimApproved = true; 2085 InventoryReply.AgentData.SimApproved = true;
2086 InventoryReply.AgentData.TransactionID = transactionID;
2066 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1]; 2087 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1];
2067 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock(); 2088 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock();
2068 InventoryReply.InventoryData[0].ItemID = Item.ID; 2089 InventoryReply.InventoryData[0].ItemID = Item.ID;
@@ -2132,16 +2153,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2132 replytask.InventoryData.TaskID = taskID; 2153 replytask.InventoryData.TaskID = taskID;
2133 replytask.InventoryData.Serial = serial; 2154 replytask.InventoryData.Serial = serial;
2134 replytask.InventoryData.Filename = fileName; 2155 replytask.InventoryData.Filename = fileName;
2135 OutPacket(replytask, ThrottleOutPacketType.Asset); 2156 OutPacket(replytask, ThrottleOutPacketType.Task);
2136 } 2157 }
2137 2158
2138 public void SendXferPacket(ulong xferID, uint packet, byte[] data) 2159 public void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory)
2139 { 2160 {
2161 ThrottleOutPacketType type = ThrottleOutPacketType.Asset;
2162 if (isTaskInventory)
2163 type = ThrottleOutPacketType.Task;
2164
2140 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket); 2165 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket);
2141 sendXfer.XferID.ID = xferID; 2166 sendXfer.XferID.ID = xferID;
2142 sendXfer.XferID.Packet = packet; 2167 sendXfer.XferID.Packet = packet;
2143 sendXfer.DataPacket.Data = data; 2168 sendXfer.DataPacket.Data = data;
2144 OutPacket(sendXfer, ThrottleOutPacketType.Asset); 2169 OutPacket(sendXfer, type);
2145 } 2170 }
2146 2171
2147 public void SendAbortXferPacket(ulong xferID) 2172 public void SendAbortXferPacket(ulong xferID)
@@ -2323,6 +2348,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2323 OutPacket(sound, ThrottleOutPacketType.Task); 2348 OutPacket(sound, ThrottleOutPacketType.Task);
2324 } 2349 }
2325 2350
2351 public void SendTransferAbort(TransferRequestPacket transferRequest)
2352 {
2353 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2354 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2355 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2356 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2357 OutPacket(abort, ThrottleOutPacketType.Task);
2358 }
2359
2326 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2360 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2327 { 2361 {
2328 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2362 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2615,6 +2649,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2615 } 2649 }
2616 } 2650 }
2617 2651
2652 public void SendPartPhysicsProprieties(ISceneEntity entity)
2653 {
2654 SceneObjectPart part = (SceneObjectPart)entity;
2655 if (part != null && AgentId != UUID.Zero)
2656 {
2657 try
2658 {
2659 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
2660 if (eq != null)
2661 {
2662 uint localid = part.LocalId;
2663 byte physshapetype = part.PhysicsShapeType;
2664 float density = part.Density;
2665 float friction = part.Friction;
2666 float bounce = part.Bounciness;
2667 float gravmod = part.GravityModifier;
2668
2669 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2670 }
2671 }
2672 catch (Exception ex)
2673 {
2674 m_log.Error("Unable to send part Physics Proprieties - exception: " + ex.ToString());
2675 }
2676 part.UpdatePhysRequired = false;
2677 }
2678 }
2679
2680
2618 2681
2619 public void SendGroupNameReply(UUID groupLLUID, string GroupName) 2682 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
2620 { 2683 {
@@ -2712,7 +2775,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2712 else 2775 else
2713 { 2776 {
2714 int processedLength = 0; 2777 int processedLength = 0;
2715 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2778// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2779
2780 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2716 int packetNumber = 0; 2781 int packetNumber = 0;
2717 2782
2718 while (processedLength < req.AssetInf.Data.Length) 2783 while (processedLength < req.AssetInf.Data.Length)
@@ -2783,7 +2848,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2783 reply.Data.ParcelID = parcelID; 2848 reply.Data.ParcelID = parcelID;
2784 reply.Data.OwnerID = land.OwnerID; 2849 reply.Data.OwnerID = land.OwnerID;
2785 reply.Data.Name = Utils.StringToBytes(land.Name); 2850 reply.Data.Name = Utils.StringToBytes(land.Name);
2786 reply.Data.Desc = Utils.StringToBytes(land.Description); 2851 if (land != null && land.Description != null && land.Description != String.Empty)
2852 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2853 else
2854 reply.Data.Desc = new Byte[0];
2787 reply.Data.ActualArea = land.Area; 2855 reply.Data.ActualArea = land.Area;
2788 reply.Data.BillableArea = land.Area; // TODO: what is this? 2856 reply.Data.BillableArea = land.Area; // TODO: what is this?
2789 2857
@@ -3518,7 +3586,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3518 3586
3519 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3587 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3520 // TODO: don't create new blocks if recycling an old packet 3588 // TODO: don't create new blocks if recycling an old packet
3521 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3589 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3522 avp.ObjectData.TextureEntry = textureEntry; 3590 avp.ObjectData.TextureEntry = textureEntry;
3523 3591
3524 AvatarAppearancePacket.VisualParamBlock avblock = null; 3592 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3648,7 +3716,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3648 /// </summary> 3716 /// </summary>
3649 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3717 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3650 { 3718 {
3651 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3719 if (entity is SceneObjectPart)
3720 {
3721 SceneObjectPart e = (SceneObjectPart)entity;
3722 SceneObjectGroup g = e.ParentGroup;
3723 if (g.RootPart.Shape.State > 30) // HUD
3724 if (g.OwnerID != AgentId)
3725 return; // Don't send updates for other people's HUDs
3726 }
3727
3652 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3728 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3653 3729
3654 lock (m_entityUpdates.SyncRoot) 3730 lock (m_entityUpdates.SyncRoot)
@@ -3715,27 +3791,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3715 3791
3716 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3792 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3717 // condition where a kill can be processed before an out-of-date update for the same object. 3793 // condition where a kill can be processed before an out-of-date update for the same object.
3718 lock (m_killRecord) 3794 float avgTimeDilation = 1.0f;
3795 IEntityUpdate iupdate;
3796 Int32 timeinqueue; // this is just debugging code & can be dropped later
3797
3798 while (updatesThisCall < maxUpdates)
3719 { 3799 {
3720 float avgTimeDilation = 1.0f; 3800 lock (m_entityUpdates.SyncRoot)
3721 IEntityUpdate iupdate; 3801 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3722 Int32 timeinqueue; // this is just debugging code & can be dropped later 3802 break;
3803
3804 EntityUpdate update = (EntityUpdate)iupdate;
3805
3806 avgTimeDilation += update.TimeDilation;
3807 avgTimeDilation *= 0.5f;
3723 3808
3724 while (updatesThisCall < maxUpdates) 3809 if (update.Entity is SceneObjectPart)
3725 { 3810 {
3726 lock (m_entityUpdates.SyncRoot) 3811 SceneObjectPart part = (SceneObjectPart)update.Entity;
3727 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3728 break;
3729 3812
3730 EntityUpdate update = (EntityUpdate)iupdate; 3813 if (part.ParentGroup.IsDeleted)
3731 3814 continue;
3732 avgTimeDilation += update.TimeDilation;
3733 avgTimeDilation *= 0.5f;
3734 3815
3735 if (update.Entity is SceneObjectPart) 3816 if (part.ParentGroup.IsAttachment)
3817 { // Someone else's HUD, why are we getting these?
3818 if (part.ParentGroup.OwnerID != AgentId &&
3819 part.ParentGroup.RootPart.Shape.State > 30)
3820 continue;
3821 ScenePresence sp;
3822 // Owner is not in the sim, don't update it to
3823 // anyone
3824 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3825 continue;
3826
3827 List<SceneObjectGroup> atts = sp.GetAttachments();
3828 bool found = false;
3829 foreach (SceneObjectGroup att in atts)
3830 {
3831 if (att == part.ParentGroup)
3832 {
3833 found = true;
3834 break;
3835 }
3836 }
3837
3838 // It's an attachment of a valid avatar, but
3839 // doesn't seem to be attached, skip
3840 if (!found)
3841 continue;
3842
3843 // On vehicle crossing, the attachments are received
3844 // while the avatar is still a child. Don't send
3845 // updates here because the LocalId has not yet
3846 // been updated and the viewer will derender the
3847 // attachments until the avatar becomes root.
3848 if (sp.IsChildAgent)
3849 continue;
3850
3851 // If the object is an attachment we don't want it to be in the kill
3852 // record. Else attaching from inworld and subsequently dropping
3853 // it will no longer work.
3854// lock (m_killRecord)
3855// {
3856// m_killRecord.Remove(part.LocalId);
3857// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3858// }
3859 }
3860 else
3736 { 3861 {
3737 SceneObjectPart part = (SceneObjectPart)update.Entity;
3738
3739 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3862 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3740 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3863 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3741 // safety measure. 3864 // safety measure.
@@ -3746,236 +3869,174 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3746 // 3869 //
3747 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3870 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3748 // after the root prim has been deleted. 3871 // after the root prim has been deleted.
3749 if (m_killRecord.Contains(part.LocalId)) 3872 //
3750 { 3873 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3751 // m_log.WarnFormat( 3874// lock (m_killRecord)
3752 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3875// {
3753 // part.LocalId, Name); 3876// if (m_killRecord.Contains(part.LocalId))
3754 continue; 3877// continue;
3755 } 3878// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3756 3879// continue;
3757 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3880// }
3881 }
3882
3883 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3884 {
3885 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3886 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3758 { 3887 {
3759 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3888 part.Shape.LightEntry = false;
3760 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3761 {
3762 part.Shape.LightEntry = false;
3763 }
3764 } 3889 }
3765 } 3890 }
3766 3891 }
3767 #region UpdateFlags to packet type conversion 3892
3768 3893 ++updatesThisCall;
3769 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; 3894
3770 3895 #region UpdateFlags to packet type conversion
3771 bool canUseCompressed = true; 3896
3772 bool canUseImproved = true; 3897 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3773 3898
3774 // Compressed object updates only make sense for LL primitives 3899 bool canUseCompressed = true;
3775 if (!(update.Entity is SceneObjectPart)) 3900 bool canUseImproved = true;
3901
3902 // Compressed object updates only make sense for LL primitives
3903 if (!(update.Entity is SceneObjectPart))
3904 {
3905 canUseCompressed = false;
3906 }
3907
3908 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3909 {
3910 canUseCompressed = false;
3911 canUseImproved = false;
3912 }
3913 else
3914 {
3915 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3916 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3917 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3918 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3776 { 3919 {
3777 canUseCompressed = false; 3920 canUseCompressed = false;
3778 } 3921 }
3779 3922
3780 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 3923 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3924 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3925 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3926 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3927 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3928 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3929 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3930 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3931 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3932 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3933 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3934 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3935 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3936 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3781 { 3937 {
3782 canUseCompressed = false;
3783 canUseImproved = false; 3938 canUseImproved = false;
3784 } 3939 }
3785 else 3940 }
3786 {
3787 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3788 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3789 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3790 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3791 {
3792 canUseCompressed = false;
3793 }
3794
3795 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3796 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3797 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3798 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3799 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3800 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3801 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3802 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3803 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3804 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3805 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3806 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3807 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3808 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3809 {
3810 canUseImproved = false;
3811 }
3812 }
3813
3814 #endregion UpdateFlags to packet type conversion
3815
3816 #region Block Construction
3817
3818 // TODO: Remove this once we can build compressed updates
3819 canUseCompressed = false;
3820 3941
3821 if (!canUseImproved && !canUseCompressed) 3942 #endregion UpdateFlags to packet type conversion
3822 {
3823 ObjectUpdatePacket.ObjectDataBlock updateBlock;
3824 3943
3825 if (update.Entity is ScenePresence) 3944 #region Block Construction
3826 {
3827 updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
3828 }
3829 else
3830 {
3831 SceneObjectPart part = (SceneObjectPart)update.Entity;
3832 updateBlock = CreatePrimUpdateBlock(part, AgentId);
3833
3834 // If the part has become a private hud since the update was scheduled then we do not
3835 // want to send it to other avatars.
3836 if (part.ParentGroup.IsAttachment
3837 && part.ParentGroup.HasPrivateAttachmentPoint
3838 && part.ParentGroup.AttachedAvatar != AgentId)
3839 continue;
3840
3841 // If the part has since been deleted, then drop the update. In the case of attachments,
3842 // this is to avoid spurious updates to other viewers since post-processing of attachments
3843 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3844 // of the test above).
3845 //
3846 // Actual deletions (kills) happen in another method.
3847 if (part.ParentGroup.IsDeleted)
3848 continue;
3849 }
3850 3945
3851 objectUpdateBlocks.Value.Add(updateBlock); 3946 // TODO: Remove this once we can build compressed updates
3852 objectUpdates.Value.Add(update); 3947 canUseCompressed = false;
3853 }
3854 else if (!canUseImproved)
3855 {
3856 SceneObjectPart part = (SceneObjectPart)update.Entity;
3857 ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
3858 = CreateCompressedUpdateBlock(part, updateFlags);
3859
3860 // If the part has since been deleted, then drop the update. In the case of attachments,
3861 // this is to avoid spurious updates to other viewers since post-processing of attachments
3862 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3863 // of the test above).
3864 //
3865 // Actual deletions (kills) happen in another method.
3866 if (part.ParentGroup.IsDeleted)
3867 continue;
3868 3948
3869 compressedUpdateBlocks.Value.Add(compressedBlock); 3949 if (!canUseImproved && !canUseCompressed)
3870 compressedUpdates.Value.Add(update); 3950 {
3951 if (update.Entity is ScenePresence)
3952 {
3953 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3871 } 3954 }
3872 else 3955 else
3873 { 3956 {
3874 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3957 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3875 {
3876 // Self updates go into a special list
3877 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3878 terseAgentUpdates.Value.Add(update);
3879 }
3880 else
3881 {
3882 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
3883 = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
3884
3885 // Everything else goes here
3886 if (update.Entity is SceneObjectPart)
3887 {
3888 SceneObjectPart part = (SceneObjectPart)update.Entity;
3889
3890 // If the part has become a private hud since the update was scheduled then we do not
3891 // want to send it to other avatars.
3892 if (part.ParentGroup.IsAttachment
3893 && part.ParentGroup.HasPrivateAttachmentPoint
3894 && part.ParentGroup.AttachedAvatar != AgentId)
3895 continue;
3896
3897 // If the part has since been deleted, then drop the update. In the case of attachments,
3898 // this is to avoid spurious updates to other viewers since post-processing of attachments
3899 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3900 // of the test above).
3901 //
3902 // Actual deletions (kills) happen in another method.
3903 if (part.ParentGroup.IsDeleted)
3904 continue;
3905 }
3906
3907 terseUpdateBlocks.Value.Add(terseUpdateBlock);
3908 terseUpdates.Value.Add(update);
3909 }
3910 } 3958 }
3959 }
3960 else if (!canUseImproved)
3961 {
3962 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3963 }
3964 else
3965 {
3966 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3967 // Self updates go into a special list
3968 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3969 else
3970 // Everything else goes here
3971 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3972 }
3973
3974 #endregion Block Construction
3975 }
3911 3976
3912 ++updatesThisCall; 3977 #region Packet Sending
3913 3978
3914 #endregion Block Construction 3979 const float TIME_DILATION = 1.0f;
3915 } 3980 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3916 3981
3917 #region Packet Sending 3982 if (terseAgentUpdateBlocks.IsValueCreated)
3918 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); 3983 {
3984 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3919 3985
3920 if (terseAgentUpdateBlocks.IsValueCreated) 3986 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3921 { 3987 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3922 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 3988 packet.RegionData.TimeDilation = timeDilation;
3989 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3923 3990
3924 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3991 for (int i = 0; i < blocks.Count; i++)
3925 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3992 packet.ObjectData[i] = blocks[i];
3926 packet.RegionData.TimeDilation = timeDilation;
3927 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3928 3993
3929 for (int i = 0; i < blocks.Count; i++) 3994 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3930 packet.ObjectData[i] = blocks[i]; 3995 }
3931 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3932 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3933 }
3934 3996
3935 if (objectUpdateBlocks.IsValueCreated) 3997 if (objectUpdateBlocks.IsValueCreated)
3936 { 3998 {
3937 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3999 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3938 4000
3939 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 4001 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3940 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4002 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3941 packet.RegionData.TimeDilation = timeDilation; 4003 packet.RegionData.TimeDilation = timeDilation;
3942 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4004 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3943 4005
3944 for (int i = 0; i < blocks.Count; i++) 4006 for (int i = 0; i < blocks.Count; i++)
3945 packet.ObjectData[i] = blocks[i]; 4007 packet.ObjectData[i] = blocks[i];
3946 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4008
3947 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); }); 4009 OutPacket(packet, ThrottleOutPacketType.Task, true);
3948 } 4010 }
3949 4011
3950 if (compressedUpdateBlocks.IsValueCreated) 4012 if (compressedUpdateBlocks.IsValueCreated)
3951 { 4013 {
3952 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 4014 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3953 4015
3954 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); 4016 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3955 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4017 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3956 packet.RegionData.TimeDilation = timeDilation; 4018 packet.RegionData.TimeDilation = timeDilation;
3957 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count]; 4019 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3958
3959 for (int i = 0; i < blocks.Count; i++)
3960 packet.ObjectData[i] = blocks[i];
3961 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3962 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3963 }
3964 4020
3965 if (terseUpdateBlocks.IsValueCreated) 4021 for (int i = 0; i < blocks.Count; i++)
3966 { 4022 packet.ObjectData[i] = blocks[i];
3967 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 4023
3968 4024 OutPacket(packet, ThrottleOutPacketType.Task, true);
3969 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 4025 }
3970 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4026
3971 packet.RegionData.TimeDilation = timeDilation; 4027 if (terseUpdateBlocks.IsValueCreated)
3972 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4028 {
3973 4029 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3974 for (int i = 0; i < blocks.Count; i++) 4030
3975 packet.ObjectData[i] = blocks[i]; 4031 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3976 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4032 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3977 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 4033 packet.RegionData.TimeDilation = timeDilation;
3978 } 4034 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.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);
3979 } 4040 }
3980 4041
3981 #endregion Packet Sending 4042 #endregion Packet Sending
@@ -4268,11 +4329,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4268 4329
4269 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4330 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4270 // of the object rather than the properties when the packet was created 4331 // of the object rather than the properties when the packet was created
4271 OutPacket(packet, ThrottleOutPacketType.Task, true, 4332 // HACK : Remove intelligent resending until it's fixed in core
4272 delegate(OutgoingPacket oPacket) 4333 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4273 { 4334 // delegate(OutgoingPacket oPacket)
4274 ResendPropertyUpdates(updates, oPacket); 4335 // {
4275 }); 4336 // ResendPropertyUpdates(updates, oPacket);
4337 // });
4338 OutPacket(packet, ThrottleOutPacketType.Task, true);
4276 4339
4277 // pbcnt += blocks.Count; 4340 // pbcnt += blocks.Count;
4278 // ppcnt++; 4341 // ppcnt++;
@@ -4298,11 +4361,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4298 // of the object rather than the properties when the packet was created 4361 // of the object rather than the properties when the packet was created
4299 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4362 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4300 updates.Add(familyUpdates.Value[i]); 4363 updates.Add(familyUpdates.Value[i]);
4301 OutPacket(packet, ThrottleOutPacketType.Task, true, 4364 // HACK : Remove intelligent resending until it's fixed in core
4302 delegate(OutgoingPacket oPacket) 4365 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4303 { 4366 // delegate(OutgoingPacket oPacket)
4304 ResendPropertyUpdates(updates, oPacket); 4367 // {
4305 }); 4368 // ResendPropertyUpdates(updates, oPacket);
4369 // });
4370 OutPacket(packet, ThrottleOutPacketType.Task, true);
4306 4371
4307 // fpcnt++; 4372 // fpcnt++;
4308 // fbcnt++; 4373 // fbcnt++;
@@ -4674,7 +4739,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4674 4739
4675 if (landData.SimwideArea > 0) 4740 if (landData.SimwideArea > 0)
4676 { 4741 {
4677 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4742 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4743 // Never report more than sim total capacity
4744 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4745 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4678 updateMessage.SimWideMaxPrims = simulatorCapacity; 4746 updateMessage.SimWideMaxPrims = simulatorCapacity;
4679 } 4747 }
4680 else 4748 else
@@ -4803,14 +4871,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4803 4871
4804 if (notifyCount > 0) 4872 if (notifyCount > 0)
4805 { 4873 {
4806 if (notifyCount > 32) 4874// if (notifyCount > 32)
4807 { 4875// {
4808 m_log.InfoFormat( 4876// m_log.InfoFormat(
4809 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4877// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4810 + " - a developer might want to investigate whether this is a hard limit", 32); 4878// + " - a developer might want to investigate whether this is a hard limit", 32);
4811 4879//
4812 notifyCount = 32; 4880// notifyCount = 32;
4813 } 4881// }
4814 4882
4815 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4883 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4816 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4884 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4865,9 +4933,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4865 { 4933 {
4866 ScenePresence presence = (ScenePresence)entity; 4934 ScenePresence presence = (ScenePresence)entity;
4867 4935
4936 position = presence.OffsetPosition;
4937 rotation = presence.Rotation;
4938
4939 if (presence.ParentID != 0)
4940 {
4941 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4942 if (part != null && part != part.ParentGroup.RootPart)
4943 {
4944 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4945 rotation = part.RotationOffset * presence.Rotation;
4946 }
4947 }
4948
4868 attachPoint = 0; 4949 attachPoint = 0;
4869 collisionPlane = presence.CollisionPlane; 4950 collisionPlane = presence.CollisionPlane;
4870 position = presence.OffsetPosition;
4871 velocity = presence.Velocity; 4951 velocity = presence.Velocity;
4872 acceleration = Vector3.Zero; 4952 acceleration = Vector3.Zero;
4873 4953
@@ -4877,7 +4957,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4877// acceleration = new Vector3(1, 0, 0); 4957// acceleration = new Vector3(1, 0, 0);
4878 4958
4879 angularVelocity = Vector3.Zero; 4959 angularVelocity = Vector3.Zero;
4880 rotation = presence.Rotation;
4881 4960
4882 if (sendTexture) 4961 if (sendTexture)
4883 textureEntry = presence.Appearance.Texture.GetBytes(); 4962 textureEntry = presence.Appearance.Texture.GetBytes();
@@ -4982,13 +5061,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4982 5061
4983 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5062 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
4984 { 5063 {
5064 Vector3 offsetPosition = data.OffsetPosition;
5065 Quaternion rotation = data.Rotation;
5066 uint parentID = data.ParentID;
5067
5068 if (parentID != 0)
5069 {
5070 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5071 if (part != null && part != part.ParentGroup.RootPart)
5072 {
5073 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5074 rotation = part.RotationOffset * data.Rotation;
5075 parentID = part.ParentGroup.RootPart.LocalId;
5076 }
5077 }
5078
4985 byte[] objectData = new byte[76]; 5079 byte[] objectData = new byte[76];
4986 5080
4987 data.CollisionPlane.ToBytes(objectData, 0); 5081 data.CollisionPlane.ToBytes(objectData, 0);
4988 data.OffsetPosition.ToBytes(objectData, 16); 5082 offsetPosition.ToBytes(objectData, 16);
4989// data.Velocity.ToBytes(objectData, 28); 5083// data.Velocity.ToBytes(objectData, 28);
4990// data.Acceleration.ToBytes(objectData, 40); 5084// data.Acceleration.ToBytes(objectData, 40);
4991 data.Rotation.ToBytes(objectData, 52); 5085 rotation.ToBytes(objectData, 52);
4992 //data.AngularVelocity.ToBytes(objectData, 64); 5086 //data.AngularVelocity.ToBytes(objectData, 64);
4993 5087
4994 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5088 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -5002,7 +5096,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5002 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5096 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
5003 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5097 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
5004 update.ObjectData = objectData; 5098 update.ObjectData = objectData;
5005 update.ParentID = data.ParentID; 5099 update.ParentID = parentID;
5006 update.PathCurve = 16; 5100 update.PathCurve = 16;
5007 update.PathScaleX = 100; 5101 update.PathScaleX = 100;
5008 update.PathScaleY = 100; 5102 update.PathScaleY = 100;
@@ -5020,10 +5114,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5020 update.TextureEntry = Utils.EmptyBytes; 5114 update.TextureEntry = Utils.EmptyBytes;
5021// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; 5115// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
5022 5116
5117/* 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)
5023 update.UpdateFlags = (uint)( 5118 update.UpdateFlags = (uint)(
5024 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | 5119 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
5025 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | 5120 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
5026 PrimFlags.ObjectOwnerModify); 5121 PrimFlags.ObjectOwnerModify);
5122*/
5123 update.UpdateFlags = 0;
5027 5124
5028 return update; 5125 return update;
5029 } 5126 }
@@ -5343,6 +5440,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5343 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5440 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5344 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5441 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5345 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5442 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5443 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5346 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5444 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5347 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5445 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5348 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5446 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5409,6 +5507,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5409 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5507 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5410 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5508 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5411 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5509 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5510 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5412 5511
5413 AddGenericPacketHandler("autopilot", HandleAutopilot); 5512 AddGenericPacketHandler("autopilot", HandleAutopilot);
5414 } 5513 }
@@ -5444,6 +5543,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5444 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5543 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5445 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5544 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5446 (x.ControlFlags != lastarg.ControlFlags) || 5545 (x.ControlFlags != lastarg.ControlFlags) ||
5546 (x.ControlFlags != 0) ||
5447 (x.Far != lastarg.Far) || 5547 (x.Far != lastarg.Far) ||
5448 (x.Flags != lastarg.Flags) || 5548 (x.Flags != lastarg.Flags) ||
5449 (x.State != lastarg.State) || 5549 (x.State != lastarg.State) ||
@@ -6342,6 +6442,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6342 { 6442 {
6343 handlerCompleteMovementToRegion(sender, true); 6443 handlerCompleteMovementToRegion(sender, true);
6344 } 6444 }
6445 else
6446 m_log.Debug("HandleCompleteAgentMovement NULL handler");
6447
6345 handlerCompleteMovementToRegion = null; 6448 handlerCompleteMovementToRegion = null;
6346 6449
6347 return true; 6450 return true;
@@ -6359,7 +6462,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6359 return true; 6462 return true;
6360 } 6463 }
6361 #endregion 6464 #endregion
6362 6465/*
6363 StartAnim handlerStartAnim = null; 6466 StartAnim handlerStartAnim = null;
6364 StopAnim handlerStopAnim = null; 6467 StopAnim handlerStopAnim = null;
6365 6468
@@ -6383,6 +6486,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6383 } 6486 }
6384 } 6487 }
6385 return true; 6488 return true;
6489*/
6490 ChangeAnim handlerChangeAnim = null;
6491
6492 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6493 {
6494 handlerChangeAnim = OnChangeAnim;
6495 if (handlerChangeAnim != null)
6496 {
6497 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6498 }
6499 }
6500
6501 handlerChangeAnim = OnChangeAnim;
6502 if (handlerChangeAnim != null)
6503 {
6504 handlerChangeAnim(UUID.Zero, false, true);
6505 }
6506
6507 return true;
6386 } 6508 }
6387 6509
6388 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6510 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -7008,10 +7130,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7008 // 46,47,48 are special positions within the packet 7130 // 46,47,48 are special positions within the packet
7009 // This may change so perhaps we need a better way 7131 // This may change so perhaps we need a better way
7010 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) 7132 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
7011 bool UsePhysics = (data[46] != 0) ? true : false; 7133 /*
7012 bool IsTemporary = (data[47] != 0) ? true : false; 7134 bool UsePhysics = (data[46] != 0) ? true : false;
7013 bool IsPhantom = (data[48] != 0) ? true : false; 7135 bool IsTemporary = (data[47] != 0) ? true : false;
7014 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this); 7136 bool IsPhantom = (data[48] != 0) ? true : false;
7137 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this);
7138 */
7139 bool UsePhysics = flags.AgentData.UsePhysics;
7140 bool IsPhantom = flags.AgentData.IsPhantom;
7141 bool IsTemporary = flags.AgentData.IsTemporary;
7142 ObjectFlagUpdatePacket.ExtraPhysicsBlock[] blocks = flags.ExtraPhysics;
7143 ExtraPhysicsData physdata = new ExtraPhysicsData();
7144
7145 if (blocks == null || blocks.Length == 0)
7146 {
7147 physdata.PhysShapeType = PhysShapeType.invalid;
7148 }
7149 else
7150 {
7151 ObjectFlagUpdatePacket.ExtraPhysicsBlock phsblock = blocks[0];
7152 physdata.PhysShapeType = (PhysShapeType)phsblock.PhysicsShapeType;
7153 physdata.Bounce = phsblock.Restitution;
7154 physdata.Density = phsblock.Density;
7155 physdata.Friction = phsblock.Friction;
7156 physdata.GravitationModifier = phsblock.GravityMultiplier;
7157 }
7158
7159 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
7015 } 7160 }
7016 return true; 7161 return true;
7017 } 7162 }
@@ -8612,16 +8757,61 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8612 8757
8613 #region Parcel related packets 8758 #region Parcel related packets
8614 8759
8760 // acumulate several HandleRegionHandleRequest consecutive overlaping requests
8761 // to be done with minimal resources as possible
8762 // variables temporary here while in test
8763
8764 Queue<UUID> RegionHandleRequests = new Queue<UUID>();
8765 bool RegionHandleRequestsInService = false;
8766
8615 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack) 8767 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack)
8616 { 8768 {
8617 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; 8769 UUID currentUUID;
8618 8770
8619 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; 8771 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest;
8620 if (handlerRegionHandleRequest != null) 8772
8773 if (handlerRegionHandleRequest == null)
8774 return true;
8775
8776 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
8777
8778 lock (RegionHandleRequests)
8621 { 8779 {
8622 handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); 8780 if (RegionHandleRequestsInService)
8781 {
8782 // we are already busy doing a previus request
8783 // so enqueue it
8784 RegionHandleRequests.Enqueue(rhrPack.RequestBlock.RegionID);
8785 return true;
8786 }
8787
8788 // else do it
8789 currentUUID = rhrPack.RequestBlock.RegionID;
8790 RegionHandleRequestsInService = true;
8623 } 8791 }
8624 return true; 8792
8793 while (true)
8794 {
8795 handlerRegionHandleRequest(this, currentUUID);
8796
8797 lock (RegionHandleRequests)
8798 {
8799 // exit condition, nothing to do or closed
8800 // current code seems to assume we may loose the handler at anytime,
8801 // so keep checking it
8802 handlerRegionHandleRequest = OnRegionHandleRequest;
8803
8804 if (RegionHandleRequests.Count == 0 || !IsActive || handlerRegionHandleRequest == null)
8805 {
8806 RegionHandleRequests.Clear();
8807 RegionHandleRequestsInService = false;
8808 return true;
8809 }
8810 currentUUID = RegionHandleRequests.Dequeue();
8811 }
8812 }
8813
8814 return true; // actually unreached
8625 } 8815 }
8626 8816
8627 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack) 8817 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack)
@@ -9865,7 +10055,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9865 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 10055 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9866 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 10056 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9867 UpdateMuteListEntry.MuteData.MuteType, 10057 UpdateMuteListEntry.MuteData.MuteType,
9868 UpdateMuteListEntry.AgentData.AgentID); 10058 UpdateMuteListEntry.MuteData.MuteFlags);
9869 return true; 10059 return true;
9870 } 10060 }
9871 return false; 10061 return false;
@@ -9880,8 +10070,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9880 { 10070 {
9881 handlerRemoveMuteListEntry(this, 10071 handlerRemoveMuteListEntry(this,
9882 RemoveMuteListEntry.MuteData.MuteID, 10072 RemoveMuteListEntry.MuteData.MuteID,
9883 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 10073 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9884 RemoveMuteListEntry.AgentData.AgentID);
9885 return true; 10074 return true;
9886 } 10075 }
9887 return false; 10076 return false;
@@ -9925,10 +10114,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9925 return false; 10114 return false;
9926 } 10115 }
9927 10116
10117 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10118 {
10119 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10120 (ChangeInventoryItemFlagsPacket)packet;
10121 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10122 if (handlerChangeInventoryItemFlags != null)
10123 {
10124 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10125 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10126 return true;
10127 }
10128 return false;
10129 }
10130
9928 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10131 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9929 { 10132 {
9930 return true; 10133 return true;
9931 } 10134 }
10135
10136 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10137 {
10138 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10139
10140 #region Packet Session and User Check
10141 if (m_checkPackets)
10142 {
10143 if (packet.AgentData.SessionID != SessionId ||
10144 packet.AgentData.AgentID != AgentId)
10145 return true;
10146 }
10147 #endregion
10148 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10149 List<InventoryItemBase> items = new List<InventoryItemBase>();
10150 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10151 {
10152 InventoryItemBase b = new InventoryItemBase();
10153 b.ID = n.OldItemID;
10154 b.Folder = n.OldFolderID;
10155 items.Add(b);
10156 }
10157
10158 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10159 if (handlerMoveItemsAndLeaveCopy != null)
10160 {
10161 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10162 }
10163
10164 return true;
10165 }
9932 10166
9933 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10167 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9934 { 10168 {
@@ -10355,6 +10589,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10355 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10589 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10356 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10590 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10357 10591
10592 Scene scene = (Scene)m_scene;
10593 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10594 {
10595 ScenePresence p;
10596 if (scene.TryGetScenePresence(sender.AgentId, out p))
10597 {
10598 if (p.GodLevel >= 200)
10599 {
10600 groupProfileReply.GroupData.OpenEnrollment = true;
10601 groupProfileReply.GroupData.MembershipFee = 0;
10602 }
10603 }
10604 }
10605
10358 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10606 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10359 } 10607 }
10360 return true; 10608 return true;
@@ -10928,11 +11176,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10928 11176
10929 StartLure handlerStartLure = OnStartLure; 11177 StartLure handlerStartLure = OnStartLure;
10930 if (handlerStartLure != null) 11178 if (handlerStartLure != null)
10931 handlerStartLure(startLureRequest.Info.LureType, 11179 {
10932 Utils.BytesToString( 11180 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10933 startLureRequest.Info.Message), 11181 {
10934 startLureRequest.TargetData[0].TargetID, 11182 handlerStartLure(startLureRequest.Info.LureType,
10935 this); 11183 Utils.BytesToString(
11184 startLureRequest.Info.Message),
11185 startLureRequest.TargetData[i].TargetID,
11186 this);
11187 }
11188 }
10936 return true; 11189 return true;
10937 } 11190 }
10938 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11191 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -11046,10 +11299,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11046 } 11299 }
11047 #endregion 11300 #endregion
11048 11301
11049 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11302 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11050 if (handlerClassifiedGodDelete != null) 11303 if (handlerClassifiedGodDelete != null)
11051 handlerClassifiedGodDelete( 11304 handlerClassifiedGodDelete(
11052 classifiedGodDelete.Data.ClassifiedID, 11305 classifiedGodDelete.Data.ClassifiedID,
11306 classifiedGodDelete.Data.QueryID,
11053 this); 11307 this);
11054 return true; 11308 return true;
11055 } 11309 }
@@ -11415,209 +11669,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11415 } 11669 }
11416 else 11670 else
11417 { 11671 {
11418// m_log.DebugFormat( 11672 ClientChangeObject updatehandler = onClientChangeObject;
11419// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11420// i, block.Type, part.Name, part.LocalId);
11421 11673
11422// // Do this once since fetch parts creates a new array. 11674 if (updatehandler != null)
11423// SceneObjectPart[] parts = part.ParentGroup.Parts; 11675 {
11424// for (int j = 0; j < parts.Length; j++) 11676 ObjectChangeData udata = new ObjectChangeData();
11425// {
11426// part.StoreUndoState();
11427// parts[j].IgnoreUndoUpdate = true;
11428// }
11429 11677
11430 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11678 /*ubit from ll JIRA:
11679 * 0x01 position
11680 * 0x02 rotation
11681 * 0x04 scale
11682
11683 * 0x08 LINK_SET
11684 * 0x10 UNIFORM for scale
11685 */
11431 11686
11432 switch (block.Type) 11687 // translate to internal changes
11433 { 11688 // not all cases .. just the ones older code did
11434 case 1:
11435 Vector3 pos1 = new Vector3(block.Data, 0);
11436 11689
11437 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11690 switch (block.Type)
11438 if (handlerUpdatePrimSinglePosition != null) 11691 {
11439 { 11692 case 1: //change position sp
11440 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11693 udata.position = new Vector3(block.Data, 0);
11441 handlerUpdatePrimSinglePosition(localId, pos1, this);
11442 }
11443 break;
11444 11694
11445 case 2: 11695 udata.change = ObjectChangeType.primP;
11446 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11696 updatehandler(localId, udata, this);
11697 break;
11447 11698
11448 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11699 case 2: // rotation sp
11449 if (handlerUpdatePrimSingleRotation != null) 11700 udata.rotation = new Quaternion(block.Data, 0, true);
11450 {
11451 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11452 handlerUpdatePrimSingleRotation(localId, rot1, this);
11453 }
11454 break;
11455 11701
11456 case 3: 11702 udata.change = ObjectChangeType.primR;
11457 Vector3 rotPos = new Vector3(block.Data, 0); 11703 updatehandler(localId, udata, this);
11458 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11704 break;
11459 11705
11460 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11706 case 3: // position plus rotation
11461 if (handlerUpdatePrimSingleRotationPosition != null) 11707 udata.position = new Vector3(block.Data, 0);
11462 { 11708 udata.rotation = new Quaternion(block.Data, 12, true);
11463 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11464 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11465 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11466 }
11467 break;
11468 11709
11469 case 4: 11710 udata.change = ObjectChangeType.primPR;
11470 case 20: 11711 updatehandler(localId, udata, this);
11471 Vector3 scale4 = new Vector3(block.Data, 0); 11712 break;
11472 11713
11473 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11714 case 4: // scale sp
11474 if (handlerUpdatePrimScale != null) 11715 udata.scale = new Vector3(block.Data, 0);
11475 { 11716 udata.change = ObjectChangeType.primS;
11476 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11477 handlerUpdatePrimScale(localId, scale4, this);
11478 }
11479 break;
11480 11717
11481 case 5: 11718 updatehandler(localId, udata, this);
11482 Vector3 scale1 = new Vector3(block.Data, 12); 11719 break;
11483 Vector3 pos11 = new Vector3(block.Data, 0);
11484 11720
11485 handlerUpdatePrimScale = OnUpdatePrimScale; 11721 case 0x14: // uniform scale sp
11486 if (handlerUpdatePrimScale != null) 11722 udata.scale = new Vector3(block.Data, 0);
11487 {
11488 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11489 handlerUpdatePrimScale(localId, scale1, this);
11490 11723
11491 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11724 udata.change = ObjectChangeType.primUS;
11492 if (handlerUpdatePrimSinglePosition != null) 11725 updatehandler(localId, udata, this);
11493 { 11726 break;
11494 handlerUpdatePrimSinglePosition(localId, pos11, this);
11495 }
11496 }
11497 break;
11498 11727
11499 case 9: 11728 case 5: // scale and position sp
11500 Vector3 pos2 = new Vector3(block.Data, 0); 11729 udata.position = new Vector3(block.Data, 0);
11730 udata.scale = new Vector3(block.Data, 12);
11501 11731
11502 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11732 udata.change = ObjectChangeType.primPS;
11733 updatehandler(localId, udata, this);
11734 break;
11503 11735
11504 if (handlerUpdateVector != null) 11736 case 0x15: //uniform scale and position
11505 { 11737 udata.position = new Vector3(block.Data, 0);
11506 handlerUpdateVector(localId, pos2, this); 11738 udata.scale = new Vector3(block.Data, 12);
11507 }
11508 break;
11509 11739
11510 case 10: 11740 udata.change = ObjectChangeType.primPUS;
11511 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11741 updatehandler(localId, udata, this);
11742 break;
11512 11743
11513 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11744 // now group related (bit 4)
11514 if (handlerUpdatePrimRotation != null) 11745 case 9: //( 8 + 1 )group position
11515 { 11746 udata.position = new Vector3(block.Data, 0);
11516 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11517 handlerUpdatePrimRotation(localId, rot3, this);
11518 }
11519 break;
11520 11747
11521 case 11: 11748 udata.change = ObjectChangeType.groupP;
11522 Vector3 pos3 = new Vector3(block.Data, 0); 11749 updatehandler(localId, udata, this);
11523 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11750 break;
11524 11751
11525 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11752 case 0x0A: // (8 + 2) group rotation
11526 if (handlerUpdatePrimGroupRotation != null) 11753 udata.rotation = new Quaternion(block.Data, 0, true);
11527 {
11528 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11529 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11530 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11531 }
11532 break;
11533 case 12:
11534 case 28:
11535 Vector3 scale7 = new Vector3(block.Data, 0);
11536 11754
11537 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11755 udata.change = ObjectChangeType.groupR;
11538 if (handlerUpdatePrimGroupScale != null) 11756 updatehandler(localId, udata, this);
11539 { 11757 break;
11540 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11541 handlerUpdatePrimGroupScale(localId, scale7, this);
11542 }
11543 break;
11544 11758
11545 case 13: 11759 case 0x0B: //( 8 + 2 + 1) group rotation and position
11546 Vector3 scale2 = new Vector3(block.Data, 12); 11760 udata.position = new Vector3(block.Data, 0);
11547 Vector3 pos4 = new Vector3(block.Data, 0); 11761 udata.rotation = new Quaternion(block.Data, 12, true);
11548 11762
11549 handlerUpdatePrimScale = OnUpdatePrimScale; 11763 udata.change = ObjectChangeType.groupPR;
11550 if (handlerUpdatePrimScale != null) 11764 updatehandler(localId, udata, this);
11551 { 11765 break;
11552 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11553 handlerUpdatePrimScale(localId, scale2, this);
11554 11766
11555 // Change the position based on scale (for bug number 246) 11767 case 0x0C: // (8 + 4) group scale
11556 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11768 // only afects root prim and only sent by viewer editor object tab scaling
11557 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11769 // mouse edition only allows uniform scaling
11558 if (handlerUpdatePrimSinglePosition != null) 11770 // SL MAY CHANGE THIS in viewers
11559 {
11560 handlerUpdatePrimSinglePosition(localId, pos4, this);
11561 }
11562 }
11563 break;
11564 11771
11565 case 29: 11772 udata.scale = new Vector3(block.Data, 0);
11566 Vector3 scale5 = new Vector3(block.Data, 12);
11567 Vector3 pos5 = new Vector3(block.Data, 0);
11568 11773
11569 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11774 udata.change = ObjectChangeType.groupS;
11570 if (handlerUpdatePrimGroupScale != null) 11775 updatehandler(localId, udata, this);
11571 {
11572 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11573 part.StoreUndoState(true);
11574 part.IgnoreUndoUpdate = true;
11575 handlerUpdatePrimGroupScale(localId, scale5, this);
11576 handlerUpdateVector = OnUpdatePrimGroupPosition;
11577 11776
11578 if (handlerUpdateVector != null) 11777 break;
11579 {
11580 handlerUpdateVector(localId, pos5, this);
11581 }
11582 11778
11583 part.IgnoreUndoUpdate = false; 11779 case 0x0D: //(8 + 4 + 1) group scale and position
11584 } 11780 // exception as above
11585 11781
11586 break; 11782 udata.position = new Vector3(block.Data, 0);
11783 udata.scale = new Vector3(block.Data, 12);
11587 11784
11588 case 21: 11785 udata.change = ObjectChangeType.groupPS;
11589 Vector3 scale6 = new Vector3(block.Data, 12); 11786 updatehandler(localId, udata, this);
11590 Vector3 pos6 = new Vector3(block.Data, 0); 11787 break;
11591 11788
11592 handlerUpdatePrimScale = OnUpdatePrimScale; 11789 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11593 if (handlerUpdatePrimScale != null) 11790 udata.scale = new Vector3(block.Data, 0);
11594 {
11595 part.StoreUndoState(false);
11596 part.IgnoreUndoUpdate = true;
11597 11791
11598 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 11792 udata.change = ObjectChangeType.groupUS;
11599 handlerUpdatePrimScale(localId, scale6, this); 11793 updatehandler(localId, udata, this);
11600 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11794 break;
11601 if (handlerUpdatePrimSinglePosition != null)
11602 {
11603 handlerUpdatePrimSinglePosition(localId, pos6, this);
11604 }
11605 11795
11606 part.IgnoreUndoUpdate = false; 11796 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11607 } 11797 udata.position = new Vector3(block.Data, 0);
11608 break; 11798 udata.scale = new Vector3(block.Data, 12);
11609 11799
11610 default: 11800 udata.change = ObjectChangeType.groupPUS;
11611 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 11801 updatehandler(localId, udata, this);
11612 break; 11802 break;
11803
11804 default:
11805 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
11806 break;
11807 }
11613 } 11808 }
11614 11809
11615// for (int j = 0; j < parts.Length; j++)
11616// parts[j].IgnoreUndoUpdate = false;
11617 } 11810 }
11618 } 11811 }
11619 } 11812 }
11620
11621 return true; 11813 return true;
11622 } 11814 }
11623 11815
@@ -12067,7 +12259,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12067// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12259// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12068// requestID, taskID, (SourceType)sourceType, Name); 12260// requestID, taskID, (SourceType)sourceType, Name);
12069 12261
12262
12263 //Note, the bool returned from the below function is useless since it is always false.
12070 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12264 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12265
12071 } 12266 }
12072 12267
12073 /// <summary> 12268 /// <summary>
@@ -12133,7 +12328,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12133 /// <returns></returns> 12328 /// <returns></returns>
12134 private static int CalculateNumPackets(byte[] data) 12329 private static int CalculateNumPackets(byte[] data)
12135 { 12330 {
12136 const uint m_maxPacketSize = 600; 12331// const uint m_maxPacketSize = 600;
12332 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12137 int numPackets = 1; 12333 int numPackets = 1;
12138 12334
12139 if (data == null) 12335 if (data == null)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index 8963756..c472176 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 }
@@ -704,4 +731,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP
704 } 731 }
705 } 732 }
706 } 733 }
707} \ No newline at end of file 734}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index d11fcbf..b3db064 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -110,7 +110,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
110 /// <summary>Handlers for incoming packets</summary> 110 /// <summary>Handlers for incoming packets</summary>
111 //PacketEventDictionary packetEvents = new PacketEventDictionary(); 111 //PacketEventDictionary packetEvents = new PacketEventDictionary();
112 /// <summary>Incoming packets that are awaiting handling</summary> 112 /// <summary>Incoming packets that are awaiting handling</summary>
113 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 113 //private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
114
115 private DoubleQueue<IncomingPacket> packetInbox = new DoubleQueue<IncomingPacket>();
116
114 /// <summary></summary> 117 /// <summary></summary>
115 //private UDPClientCollection m_clients = new UDPClientCollection(); 118 //private UDPClientCollection m_clients = new UDPClientCollection();
116 /// <summary>Bandwidth throttle for this UDP server</summary> 119 /// <summary>Bandwidth throttle for this UDP server</summary>
@@ -155,6 +158,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
155 /// <summary>Flag to signal when clients should send pings</summary> 158 /// <summary>Flag to signal when clients should send pings</summary>
156 protected bool m_sendPing; 159 protected bool m_sendPing;
157 160
161 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
162
158 private int m_defaultRTO = 0; 163 private int m_defaultRTO = 0;
159 private int m_maxRTO = 0; 164 private int m_maxRTO = 0;
160 private int m_ackTimeout = 0; 165 private int m_ackTimeout = 0;
@@ -774,19 +779,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
774 779
775 #region Packet to Client Mapping 780 #region Packet to Client Mapping
776 781
777 // UseCircuitCode handling 782 // If there is already a client for this endpoint, don't process UseCircuitCode
778 if (packet.Type == PacketType.UseCircuitCode) 783 IClientAPI client = null;
784 if (!m_scene.TryGetClient(address, out client))
779 { 785 {
780 object[] array = new object[] { buffer, packet }; 786 // UseCircuitCode handling
787 if (packet.Type == PacketType.UseCircuitCode)
788 {
789 // And if there is a UseCircuitCode pending, also drop it
790 lock (m_pendingCache)
791 {
792 if (m_pendingCache.Contains(address))
793 return;
781 794
782 Util.FireAndForget(HandleUseCircuitCode, array); 795 m_pendingCache.AddOrUpdate(address, new Queue<UDPPacketBuffer>(), 60);
796 }
783 797
784 return; 798 object[] array = new object[] { buffer, packet };
799
800 Util.FireAndForget(HandleUseCircuitCode, array);
801
802 return;
803 }
804 }
805
806 // If this is a pending connection, enqueue, don't process yet
807 lock (m_pendingCache)
808 {
809 Queue<UDPPacketBuffer> queue;
810 if (m_pendingCache.TryGetValue(address, out queue))
811 {
812 //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type);
813 queue.Enqueue(buffer);
814 return;
815 }
785 } 816 }
786 817
787 // Determine which agent this packet came from 818 // Determine which agent this packet came from
788 IClientAPI client; 819 if (client == null || !(client is LLClientView))
789 if (!m_scene.TryGetClient(address, out client) || !(client is LLClientView))
790 { 820 {
791 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); 821 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
792 return; 822 return;
@@ -795,7 +825,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
795 udpClient = ((LLClientView)client).UDPClient; 825 udpClient = ((LLClientView)client).UDPClient;
796 826
797 if (!udpClient.IsConnected) 827 if (!udpClient.IsConnected)
828 {
829// m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName);
798 return; 830 return;
831 }
799 832
800 #endregion Packet to Client Mapping 833 #endregion Packet to Client Mapping
801 834
@@ -898,7 +931,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
898 #endregion Ping Check Handling 931 #endregion Ping Check Handling
899 932
900 // Inbox insertion 933 // Inbox insertion
901 packetInbox.Enqueue(new IncomingPacket((LLClientView)client, packet)); 934 if (packet.Type == PacketType.AgentUpdate ||
935 packet.Type == PacketType.ChatFromViewer)
936 packetInbox.EnqueueHigh(new IncomingPacket((LLClientView)client, packet));
937 else
938 packetInbox.EnqueueLow(new IncomingPacket((LLClientView)client, packet));
939// packetInbox.Enqueue(new IncomingPacket((LLClientView)client, packet));
902 } 940 }
903 941
904 #region BinaryStats 942 #region BinaryStats
@@ -1020,6 +1058,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1020 // We only want to send initial data to new clients, not ones which are being converted from child to root. 1058 // We only want to send initial data to new clients, not ones which are being converted from child to root.
1021 if (client != null) 1059 if (client != null)
1022 client.SceneAgent.SendInitialDataToMe(); 1060 client.SceneAgent.SendInitialDataToMe();
1061
1062 // Now we know we can handle more data
1063 Thread.Sleep(200);
1064
1065 // Obtain the queue and remove it from the cache
1066 Queue<UDPPacketBuffer> queue = null;
1067
1068 lock (m_pendingCache)
1069 {
1070 if (!m_pendingCache.TryGetValue(remoteEndPoint, out queue))
1071 {
1072 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1073 return;
1074 }
1075 m_pendingCache.Remove(remoteEndPoint);
1076 }
1077
1078 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
1079
1080 // Reinject queued packets
1081 while(queue.Count > 0)
1082 {
1083 UDPPacketBuffer buf = queue.Dequeue();
1084 PacketReceived(buf);
1085 }
1086 queue = null;
1023 } 1087 }
1024 else 1088 else
1025 { 1089 {
@@ -1027,6 +1091,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1027 m_log.WarnFormat( 1091 m_log.WarnFormat(
1028 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1092 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
1029 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, remoteEndPoint); 1093 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, remoteEndPoint);
1094 lock (m_pendingCache)
1095 m_pendingCache.Remove(remoteEndPoint);
1030 } 1096 }
1031 1097
1032 // m_log.DebugFormat( 1098 // m_log.DebugFormat(
@@ -1145,7 +1211,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1145 if (!client.SceneAgent.IsChildAgent) 1211 if (!client.SceneAgent.IsChildAgent)
1146 client.Kick("Simulator logged you out due to connection timeout"); 1212 client.Kick("Simulator logged you out due to connection timeout");
1147 1213
1148 client.CloseWithoutChecks(); 1214 client.CloseWithoutChecks(true);
1149 } 1215 }
1150 } 1216 }
1151 1217
@@ -1157,6 +1223,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1157 1223
1158 while (base.IsRunning) 1224 while (base.IsRunning)
1159 { 1225 {
1226 m_scene.ThreadAlive(1);
1160 try 1227 try
1161 { 1228 {
1162 IncomingPacket incomingPacket = null; 1229 IncomingPacket incomingPacket = null;
@@ -1199,6 +1266,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1199 1266
1200 while (base.IsRunning) 1267 while (base.IsRunning)
1201 { 1268 {
1269 m_scene.ThreadAlive(2);
1202 try 1270 try
1203 { 1271 {
1204 m_packetSent = false; 1272 m_packetSent = false;
@@ -1420,8 +1488,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1420 Packet packet = incomingPacket.Packet; 1488 Packet packet = incomingPacket.Packet;
1421 LLClientView client = incomingPacket.Client; 1489 LLClientView client = incomingPacket.Client;
1422 1490
1423 if (client.IsActive) 1491// if (client.IsActive)
1424 { 1492// {
1425 m_currentIncomingClient = client; 1493 m_currentIncomingClient = client;
1426 1494
1427 try 1495 try
@@ -1448,13 +1516,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1448 { 1516 {
1449 m_currentIncomingClient = null; 1517 m_currentIncomingClient = null;
1450 } 1518 }
1451 } 1519// }
1452 else 1520// else
1453 { 1521// {
1454 m_log.DebugFormat( 1522// m_log.DebugFormat(
1455 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 1523// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
1456 packet.Type, client.Name, m_scene.RegionInfo.RegionName); 1524// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
1457 } 1525// }
1458 } 1526 }
1459 1527
1460 protected void LogoutHandler(IClientAPI client) 1528 protected void LogoutHandler(IClientAPI client)
@@ -1464,8 +1532,116 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1464 if (!client.IsLoggingOut) 1532 if (!client.IsLoggingOut)
1465 { 1533 {
1466 client.IsLoggingOut = true; 1534 client.IsLoggingOut = true;
1467 client.Close(); 1535 client.Close(false, false);
1536 }
1537 }
1538 }
1539
1540 internal class DoubleQueue<T> where T:class
1541 {
1542 private Queue<T> m_lowQueue = new Queue<T>();
1543 private Queue<T> m_highQueue = new Queue<T>();
1544
1545 private object m_syncRoot = new object();
1546 private Semaphore m_s = new Semaphore(0, 1);
1547
1548 public DoubleQueue()
1549 {
1550 }
1551
1552 public virtual int Count
1553 {
1554 get { return m_highQueue.Count + m_lowQueue.Count; }
1555 }
1556
1557 public virtual void Enqueue(T data)
1558 {
1559 Enqueue(m_lowQueue, data);
1560 }
1561
1562 public virtual void EnqueueLow(T data)
1563 {
1564 Enqueue(m_lowQueue, data);
1565 }
1566
1567 public virtual void EnqueueHigh(T data)
1568 {
1569 Enqueue(m_highQueue, data);
1570 }
1571
1572 private void Enqueue(Queue<T> q, T data)
1573 {
1574 lock (m_syncRoot)
1575 {
1576 m_lowQueue.Enqueue(data);
1577 m_s.WaitOne(0);
1578 m_s.Release();
1579 }
1580 }
1581
1582 public virtual T Dequeue()
1583 {
1584 return Dequeue(Timeout.Infinite);
1585 }
1586
1587 public virtual T Dequeue(int tmo)
1588 {
1589 return Dequeue(TimeSpan.FromMilliseconds(tmo));
1590 }
1591
1592 public virtual T Dequeue(TimeSpan wait)
1593 {
1594 T res = null;
1595
1596 if (!Dequeue(wait, ref res))
1597 return null;
1598
1599 return res;
1600 }
1601
1602 public bool Dequeue(int timeout, ref T res)
1603 {
1604 return Dequeue(TimeSpan.FromMilliseconds(timeout), ref res);
1605 }
1606
1607 public bool Dequeue(TimeSpan wait, ref T res)
1608 {
1609 if (!m_s.WaitOne(wait))
1610 return false;
1611
1612 lock (m_syncRoot)
1613 {
1614 if (m_highQueue.Count > 0)
1615 res = m_highQueue.Dequeue();
1616 else
1617 res = m_lowQueue.Dequeue();
1618
1619 if (m_highQueue.Count == 0 && m_lowQueue.Count == 0)
1620 return true;
1621
1622 try
1623 {
1624 m_s.Release();
1625 }
1626 catch
1627 {
1628 }
1629
1630 return true;
1631 }
1632 }
1633
1634 public virtual void Clear()
1635 {
1636
1637 lock (m_syncRoot)
1638 {
1639 // Make sure sem count is 0
1640 m_s.WaitOne(0);
1641
1642 m_lowQueue.Clear();
1643 m_highQueue.Clear();
1468 } 1644 }
1469 } 1645 }
1470 } 1646 }
1471} \ No newline at end of file 1647}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 039379d..cfe7c9d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -100,10 +100,6 @@ namespace OpenMetaverse
100 const int SIO_UDP_CONNRESET = -1744830452; 100 const int SIO_UDP_CONNRESET = -1744830452;
101 101
102 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort); 102 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort);
103
104 m_log.DebugFormat(
105 "[UDPBASE]: Binding UDP listener using internal IP address config {0}:{1}",
106 ipep.Address, ipep.Port);
107 103
108 m_udpSocket = new Socket( 104 m_udpSocket = new Socket(
109 AddressFamily.InterNetwork, 105 AddressFamily.InterNetwork,