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.cs1471
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs67
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs219
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs4
5 files changed, 1182 insertions, 582 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 0ccd69a..12e9d4d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -99,6 +99,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
99 public event AvatarPickerRequest OnAvatarPickerRequest; 99 public event AvatarPickerRequest OnAvatarPickerRequest;
100 public event StartAnim OnStartAnim; 100 public event StartAnim OnStartAnim;
101 public event StopAnim OnStopAnim; 101 public event StopAnim OnStopAnim;
102 public event ChangeAnim OnChangeAnim;
102 public event Action<IClientAPI> OnRequestAvatarsData; 103 public event Action<IClientAPI> OnRequestAvatarsData;
103 public event LinkObjects OnLinkObjects; 104 public event LinkObjects OnLinkObjects;
104 public event DelinkObjects OnDelinkObjects; 105 public event DelinkObjects OnDelinkObjects;
@@ -126,6 +127,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
126 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; 127 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
127 public event UpdatePrimFlags OnUpdatePrimFlags; 128 public event UpdatePrimFlags OnUpdatePrimFlags;
128 public event UpdatePrimTexture OnUpdatePrimTexture; 129 public event UpdatePrimTexture OnUpdatePrimTexture;
130 public event ClientChangeObject onClientChangeObject;
129 public event UpdateVector OnUpdatePrimGroupPosition; 131 public event UpdateVector OnUpdatePrimGroupPosition;
130 public event UpdateVector OnUpdatePrimSinglePosition; 132 public event UpdateVector OnUpdatePrimSinglePosition;
131 public event UpdatePrimRotation OnUpdatePrimGroupRotation; 133 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
@@ -159,6 +161,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
159 public event RequestTaskInventory OnRequestTaskInventory; 161 public event RequestTaskInventory OnRequestTaskInventory;
160 public event UpdateInventoryItem OnUpdateInventoryItem; 162 public event UpdateInventoryItem OnUpdateInventoryItem;
161 public event CopyInventoryItem OnCopyInventoryItem; 163 public event CopyInventoryItem OnCopyInventoryItem;
164 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
162 public event MoveInventoryItem OnMoveInventoryItem; 165 public event MoveInventoryItem OnMoveInventoryItem;
163 public event RemoveInventoryItem OnRemoveInventoryItem; 166 public event RemoveInventoryItem OnRemoveInventoryItem;
164 public event RemoveInventoryFolder OnRemoveInventoryFolder; 167 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -257,7 +260,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
257 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 260 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
258 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 261 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
259 public event ClassifiedDelete OnClassifiedDelete; 262 public event ClassifiedDelete OnClassifiedDelete;
260 public event ClassifiedDelete OnClassifiedGodDelete; 263 public event ClassifiedGodDelete OnClassifiedGodDelete;
261 public event EventNotificationAddRequest OnEventNotificationAddRequest; 264 public event EventNotificationAddRequest OnEventNotificationAddRequest;
262 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 265 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
263 public event EventGodDelete OnEventGodDelete; 266 public event EventGodDelete OnEventGodDelete;
@@ -288,10 +291,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
288 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; 291 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
289 public event SimWideDeletesDelegate OnSimWideDeletes; 292 public event SimWideDeletesDelegate OnSimWideDeletes;
290 public event SendPostcard OnSendPostcard; 293 public event SendPostcard OnSendPostcard;
294 public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
291 public event MuteListEntryUpdate OnUpdateMuteListEntry; 295 public event MuteListEntryUpdate OnUpdateMuteListEntry;
292 public event MuteListEntryRemove OnRemoveMuteListEntry; 296 public event MuteListEntryRemove OnRemoveMuteListEntry;
293 public event GodlikeMessage onGodlikeMessage; 297 public event GodlikeMessage onGodlikeMessage;
294 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate; 298 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
299 public event GenericCall2 OnUpdateThrottles;
295 300
296 #endregion Events 301 #endregion Events
297 302
@@ -326,6 +331,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
326 private Prioritizer m_prioritizer; 331 private Prioritizer m_prioritizer;
327 private bool m_disableFacelights = false; 332 private bool m_disableFacelights = false;
328 333
334 private bool m_VelocityInterpolate = false;
335 private const uint MaxTransferBytesPerPacket = 600;
336
337
329 /// <value> 338 /// <value>
330 /// List used in construction of data blocks for an object update packet. This is to stop us having to 339 /// List used in construction of data blocks for an object update packet. This is to stop us having to
331 /// continually recreate it. 340 /// continually recreate it.
@@ -337,14 +346,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
337 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 346 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
338 /// ownerless phantom. 347 /// ownerless phantom.
339 /// 348 ///
340 /// All manipulation of this set has to occur under a lock 349 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
341 /// 350 ///
342 /// </value> 351 /// </value>
343 protected HashSet<uint> m_killRecord; 352// protected HashSet<uint> m_killRecord;
344 353
345// protected HashSet<uint> m_attachmentsSent; 354// protected HashSet<uint> m_attachmentsSent;
346 355
347 private int m_moneyBalance; 356 private int m_moneyBalance;
357 private bool m_deliverPackets = true;
348 private int m_animationSequenceNumber = 1; 358 private int m_animationSequenceNumber = 1;
349 private bool m_SendLogoutPacketWhenClosing = true; 359 private bool m_SendLogoutPacketWhenClosing = true;
350 360
@@ -391,6 +401,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
391 get { return m_startpos; } 401 get { return m_startpos; }
392 set { m_startpos = value; } 402 set { m_startpos = value; }
393 } 403 }
404 public bool DeliverPackets
405 {
406 get { return m_deliverPackets; }
407 set {
408 m_deliverPackets = value;
409 m_udpClient.m_deliverPackets = value;
410 }
411 }
394 public UUID AgentId { get { return m_agentId; } } 412 public UUID AgentId { get { return m_agentId; } }
395 public ISceneAgent SceneAgent { get; set; } 413 public ISceneAgent SceneAgent { get; set; }
396 public UUID ActiveGroupId { get { return m_activeGroupID; } } 414 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -442,6 +460,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
442 } 460 }
443 461
444 public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } } 462 public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } }
463
445 464
446 #endregion Properties 465 #endregion Properties
447 466
@@ -468,7 +487,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
468 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 487 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
469 m_entityProps = new PriorityQueue(m_scene.Entities.Count); 488 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
470 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 489 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
471 m_killRecord = new HashSet<uint>(); 490// m_killRecord = new HashSet<uint>();
472// m_attachmentsSent = new HashSet<uint>(); 491// m_attachmentsSent = new HashSet<uint>();
473 492
474 m_assetService = m_scene.RequestModuleInterface<IAssetService>(); 493 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
@@ -498,12 +517,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
498 517
499 #region Client Methods 518 #region Client Methods
500 519
520
521 /// <summary>
522 /// Close down the client view
523 /// </summary>
501 public void Close() 524 public void Close()
502 { 525 {
503 Close(false); 526 Close(true, false);
504 } 527 }
505 528
506 public void Close(bool force) 529 public void Close(bool sendStop, bool force)
507 { 530 {
508 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. 531 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
509 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. 532 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
@@ -515,7 +538,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
515 return; 538 return;
516 539
517 IsActive = false; 540 IsActive = false;
518 CloseWithoutChecks(); 541 CloseWithoutChecks(sendStop);
519 } 542 }
520 } 543 }
521 544
@@ -528,12 +551,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
528 /// 551 ///
529 /// Callers must lock ClosingSyncLock before calling. 552 /// Callers must lock ClosingSyncLock before calling.
530 /// </remarks> 553 /// </remarks>
531 public void CloseWithoutChecks() 554 public void CloseWithoutChecks(bool sendStop)
532 { 555 {
533 m_log.DebugFormat( 556 m_log.DebugFormat(
534 "[CLIENT]: Close has been called for {0} attached to scene {1}", 557 "[CLIENT]: Close has been called for {0} attached to scene {1}",
535 Name, m_scene.RegionInfo.RegionName); 558 Name, m_scene.RegionInfo.RegionName);
536 559
560 if (sendStop)
561 {
562 // Send the STOP packet
563 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
564 OutPacket(disable, ThrottleOutPacketType.Unknown);
565 }
566
537 // Shutdown the image manager 567 // Shutdown the image manager
538 ImageManager.Close(); 568 ImageManager.Close();
539 569
@@ -556,6 +586,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
556 // Disable UDP handling for this client 586 // Disable UDP handling for this client
557 m_udpClient.Shutdown(); 587 m_udpClient.Shutdown();
558 588
589
559 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 590 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false));
560 //GC.Collect(); 591 //GC.Collect();
561 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true)); 592 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true));
@@ -791,7 +822,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
791 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType); 822 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType);
792 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes; 823 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes;
793 824
794 OutPacket(handshake, ThrottleOutPacketType.Task); 825// OutPacket(handshake, ThrottleOutPacketType.Task);
826 // use same as MoveAgentIntoRegion (both should be task )
827 OutPacket(handshake, ThrottleOutPacketType.Unknown);
795 } 828 }
796 829
797 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) 830 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
@@ -831,7 +864,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
831 reply.ChatData.OwnerID = ownerID; 864 reply.ChatData.OwnerID = ownerID;
832 reply.ChatData.SourceID = fromAgentID; 865 reply.ChatData.SourceID = fromAgentID;
833 866
834 OutPacket(reply, ThrottleOutPacketType.Task); 867 OutPacket(reply, ThrottleOutPacketType.Unknown);
835 } 868 }
836 869
837 /// <summary> 870 /// <summary>
@@ -1117,6 +1150,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1117 public virtual void SendLayerData(float[] map) 1150 public virtual void SendLayerData(float[] map)
1118 { 1151 {
1119 Util.FireAndForget(DoSendLayerData, map); 1152 Util.FireAndForget(DoSendLayerData, map);
1153
1154 // Send it sync, and async. It's not that much data
1155 // and it improves user experience just so much!
1156 DoSendLayerData(map);
1120 } 1157 }
1121 1158
1122 /// <summary> 1159 /// <summary>
@@ -1129,16 +1166,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1129 1166
1130 try 1167 try
1131 { 1168 {
1132 //for (int y = 0; y < 16; y++) 1169 for (int y = 0; y < 16; y++)
1133 //{ 1170 {
1134 // for (int x = 0; x < 16; x++) 1171 for (int x = 0; x < 16; x+=4)
1135 // { 1172 {
1136 // SendLayerData(x, y, map); 1173 SendLayerPacket(x, y, map);
1137 // } 1174 }
1138 //} 1175 }
1139
1140 // Send LayerData in a spiral pattern. Fun!
1141 SendLayerTopRight(map, 0, 0, 15, 15);
1142 } 1176 }
1143 catch (Exception e) 1177 catch (Exception e)
1144 { 1178 {
@@ -1146,51 +1180,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1146 } 1180 }
1147 } 1181 }
1148 1182
1149 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1150 {
1151 // Row
1152 for (int i = x1; i <= x2; i++)
1153 SendLayerData(i, y1, map);
1154
1155 // Column
1156 for (int j = y1 + 1; j <= y2; j++)
1157 SendLayerData(x2, j, map);
1158
1159 if (x2 - x1 > 0)
1160 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1161 }
1162
1163 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1164 {
1165 // Row in reverse
1166 for (int i = x2; i >= x1; i--)
1167 SendLayerData(i, y2, map);
1168
1169 // Column in reverse
1170 for (int j = y2 - 1; j >= y1; j--)
1171 SendLayerData(x1, j, map);
1172
1173 if (x2 - x1 > 0)
1174 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1175 }
1176
1177 /// <summary> 1183 /// <summary>
1178 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1184 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1179 /// </summary> 1185 /// </summary>
1180 /// <param name="map">heightmap</param> 1186 /// <param name="map">heightmap</param>
1181 /// <param name="px">X coordinate for patches 0..12</param> 1187 /// <param name="px">X coordinate for patches 0..12</param>
1182 /// <param name="py">Y coordinate for patches 0..15</param> 1188 /// <param name="py">Y coordinate for patches 0..15</param>
1183 // private void SendLayerPacket(float[] map, int y, int x) 1189 private void SendLayerPacket(int x, int y, float[] map)
1184 // { 1190 {
1185 // int[] patches = new int[4]; 1191 int[] patches = new int[4];
1186 // patches[0] = x + 0 + y * 16; 1192 patches[0] = x + 0 + y * 16;
1187 // patches[1] = x + 1 + y * 16; 1193 patches[1] = x + 1 + y * 16;
1188 // patches[2] = x + 2 + y * 16; 1194 patches[2] = x + 2 + y * 16;
1189 // patches[3] = x + 3 + y * 16; 1195 patches[3] = x + 3 + y * 16;
1190 1196
1191 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1197 float[] heightmap = (map.Length == 65536) ?
1192 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1198 map :
1193 // } 1199 LLHeightFieldMoronize(map);
1200
1201 try
1202 {
1203 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1204 OutPacket(layerpack, ThrottleOutPacketType.Land);
1205 }
1206 catch
1207 {
1208 for (int px = x ; px < x + 4 ; px++)
1209 SendLayerData(px, y, map);
1210 }
1211 }
1194 1212
1195 /// <summary> 1213 /// <summary>
1196 /// Sends a specified patch to a client 1214 /// Sends a specified patch to a client
@@ -1210,7 +1228,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1210 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1228 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1211 layerpack.Header.Reliable = true; 1229 layerpack.Header.Reliable = true;
1212 1230
1213 OutPacket(layerpack, ThrottleOutPacketType.Land); 1231 OutPacket(layerpack, ThrottleOutPacketType.Task);
1214 } 1232 }
1215 catch (Exception e) 1233 catch (Exception e)
1216 { 1234 {
@@ -1573,7 +1591,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1573 1591
1574 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1592 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1575 { 1593 {
1576// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1594// foreach (uint id in localIDs)
1595// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1577 1596
1578 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1597 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1579 // TODO: don't create new blocks if recycling an old packet 1598 // TODO: don't create new blocks if recycling an old packet
@@ -1595,17 +1614,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1595 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race 1614 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
1596 // condition where a kill can be processed before an out-of-date update for the same object. 1615 // condition where a kill can be processed before an out-of-date update for the same object.
1597 // ProcessEntityUpdates() also takes the m_killRecord lock. 1616 // ProcessEntityUpdates() also takes the m_killRecord lock.
1598 lock (m_killRecord) 1617// lock (m_killRecord)
1599 { 1618// {
1600 foreach (uint localID in localIDs) 1619// foreach (uint localID in localIDs)
1601 m_killRecord.Add(localID); 1620// m_killRecord.Add(localID);
1602 1621
1603 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1622 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1604 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1623 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1605 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1624 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1606 // scene objects in a viewer until that viewer is relogged in. 1625 // scene objects in a viewer until that viewer is relogged in.
1607 OutPacket(kill, ThrottleOutPacketType.Task); 1626 OutPacket(kill, ThrottleOutPacketType.Task);
1608 } 1627// }
1609 } 1628 }
1610 } 1629 }
1611 1630
@@ -2063,9 +2082,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2063 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); 2082 OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
2064 } 2083 }
2065 2084
2066 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2067 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId) 2085 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
2068 { 2086 {
2087 SendInventoryItemCreateUpdate(Item, UUID.Zero, callbackId);
2088 }
2089
2090 /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
2091 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId)
2092 {
2069 const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; 2093 const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All;
2070 2094
2071 UpdateCreateInventoryItemPacket InventoryReply 2095 UpdateCreateInventoryItemPacket InventoryReply
@@ -2075,6 +2099,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2075 // TODO: don't create new blocks if recycling an old packet 2099 // TODO: don't create new blocks if recycling an old packet
2076 InventoryReply.AgentData.AgentID = AgentId; 2100 InventoryReply.AgentData.AgentID = AgentId;
2077 InventoryReply.AgentData.SimApproved = true; 2101 InventoryReply.AgentData.SimApproved = true;
2102 InventoryReply.AgentData.TransactionID = transactionID;
2078 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1]; 2103 InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1];
2079 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock(); 2104 InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock();
2080 InventoryReply.InventoryData[0].ItemID = Item.ID; 2105 InventoryReply.InventoryData[0].ItemID = Item.ID;
@@ -2144,16 +2169,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2144 replytask.InventoryData.TaskID = taskID; 2169 replytask.InventoryData.TaskID = taskID;
2145 replytask.InventoryData.Serial = serial; 2170 replytask.InventoryData.Serial = serial;
2146 replytask.InventoryData.Filename = fileName; 2171 replytask.InventoryData.Filename = fileName;
2147 OutPacket(replytask, ThrottleOutPacketType.Asset); 2172 OutPacket(replytask, ThrottleOutPacketType.Task);
2148 } 2173 }
2149 2174
2150 public void SendXferPacket(ulong xferID, uint packet, byte[] data) 2175 public void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory)
2151 { 2176 {
2177 ThrottleOutPacketType type = ThrottleOutPacketType.Asset;
2178 if (isTaskInventory)
2179 type = ThrottleOutPacketType.Task;
2180
2152 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket); 2181 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket);
2153 sendXfer.XferID.ID = xferID; 2182 sendXfer.XferID.ID = xferID;
2154 sendXfer.XferID.Packet = packet; 2183 sendXfer.XferID.Packet = packet;
2155 sendXfer.DataPacket.Data = data; 2184 sendXfer.DataPacket.Data = data;
2156 OutPacket(sendXfer, ThrottleOutPacketType.Asset); 2185 OutPacket(sendXfer, type);
2157 } 2186 }
2158 2187
2159 public void SendAbortXferPacket(ulong xferID) 2188 public void SendAbortXferPacket(ulong xferID)
@@ -2335,6 +2364,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2335 OutPacket(sound, ThrottleOutPacketType.Task); 2364 OutPacket(sound, ThrottleOutPacketType.Task);
2336 } 2365 }
2337 2366
2367 public void SendTransferAbort(TransferRequestPacket transferRequest)
2368 {
2369 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2370 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2371 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2372 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2373 OutPacket(abort, ThrottleOutPacketType.Task);
2374 }
2375
2338 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2376 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2339 { 2377 {
2340 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2378 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2627,6 +2665,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2627 } 2665 }
2628 } 2666 }
2629 2667
2668 public void SendPartPhysicsProprieties(ISceneEntity entity)
2669 {
2670 SceneObjectPart part = (SceneObjectPart)entity;
2671 if (part != null && AgentId != UUID.Zero)
2672 {
2673 try
2674 {
2675 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
2676 if (eq != null)
2677 {
2678 uint localid = part.LocalId;
2679 byte physshapetype = part.PhysicsShapeType;
2680 float density = part.Density;
2681 float friction = part.Friction;
2682 float bounce = part.Bounciness;
2683 float gravmod = part.GravityModifier;
2684
2685 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2686 }
2687 }
2688 catch (Exception ex)
2689 {
2690 m_log.Error("Unable to send part Physics Proprieties - exception: " + ex.ToString());
2691 }
2692 part.UpdatePhysRequired = false;
2693 }
2694 }
2695
2696
2630 2697
2631 public void SendGroupNameReply(UUID groupLLUID, string GroupName) 2698 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
2632 { 2699 {
@@ -2685,8 +2752,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2685 req.AssetInf.ID, req.AssetInf.Metadata.ContentType); 2752 req.AssetInf.ID, req.AssetInf.Metadata.ContentType);
2686 return; 2753 return;
2687 } 2754 }
2755 int WearableOut = 0;
2756 bool isWearable = false;
2757
2758 if (req.AssetInf != null)
2759 isWearable =
2760 ((AssetType) req.AssetInf.Type ==
2761 AssetType.Bodypart || (AssetType) req.AssetInf.Type == AssetType.Clothing);
2688 2762
2689 //m_log.Debug("sending asset " + req.RequestAssetID); 2763
2764 //m_log.Debug("sending asset " + req.RequestAssetID + ", iswearable: " + isWearable);
2765
2766
2767 //if (isWearable)
2768 // m_log.Debug((AssetType)req.AssetInf.Type);
2769
2690 TransferInfoPacket Transfer = new TransferInfoPacket(); 2770 TransferInfoPacket Transfer = new TransferInfoPacket();
2691 Transfer.TransferInfo.ChannelType = 2; 2771 Transfer.TransferInfo.ChannelType = 2;
2692 Transfer.TransferInfo.Status = 0; 2772 Transfer.TransferInfo.Status = 0;
@@ -2708,7 +2788,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2708 Transfer.TransferInfo.Size = req.AssetInf.Data.Length; 2788 Transfer.TransferInfo.Size = req.AssetInf.Data.Length;
2709 Transfer.TransferInfo.TransferID = req.TransferRequestID; 2789 Transfer.TransferInfo.TransferID = req.TransferRequestID;
2710 Transfer.Header.Zerocoded = true; 2790 Transfer.Header.Zerocoded = true;
2711 OutPacket(Transfer, ThrottleOutPacketType.Asset); 2791 OutPacket(Transfer, isWearable ? ThrottleOutPacketType.Task : ThrottleOutPacketType.Asset);
2712 2792
2713 if (req.NumPackets == 1) 2793 if (req.NumPackets == 1)
2714 { 2794 {
@@ -2719,12 +2799,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2719 TransferPacket.TransferData.Data = req.AssetInf.Data; 2799 TransferPacket.TransferData.Data = req.AssetInf.Data;
2720 TransferPacket.TransferData.Status = 1; 2800 TransferPacket.TransferData.Status = 1;
2721 TransferPacket.Header.Zerocoded = true; 2801 TransferPacket.Header.Zerocoded = true;
2722 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2802 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task : ThrottleOutPacketType.Asset);
2723 } 2803 }
2724 else 2804 else
2725 { 2805 {
2726 int processedLength = 0; 2806 int processedLength = 0;
2727 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2807// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2808
2809 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2728 int packetNumber = 0; 2810 int packetNumber = 0;
2729 2811
2730 while (processedLength < req.AssetInf.Data.Length) 2812 while (processedLength < req.AssetInf.Data.Length)
@@ -2750,7 +2832,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2750 TransferPacket.TransferData.Status = 1; 2832 TransferPacket.TransferData.Status = 1;
2751 } 2833 }
2752 TransferPacket.Header.Zerocoded = true; 2834 TransferPacket.Header.Zerocoded = true;
2753 OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 2835 OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task : ThrottleOutPacketType.Asset);
2754 2836
2755 processedLength += chunkSize; 2837 processedLength += chunkSize;
2756 packetNumber++; 2838 packetNumber++;
@@ -2795,7 +2877,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2795 reply.Data.ParcelID = parcelID; 2877 reply.Data.ParcelID = parcelID;
2796 reply.Data.OwnerID = land.OwnerID; 2878 reply.Data.OwnerID = land.OwnerID;
2797 reply.Data.Name = Utils.StringToBytes(land.Name); 2879 reply.Data.Name = Utils.StringToBytes(land.Name);
2798 reply.Data.Desc = Utils.StringToBytes(land.Description); 2880 if (land != null && land.Description != null && land.Description != String.Empty)
2881 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2882 else
2883 reply.Data.Desc = new Byte[0];
2799 reply.Data.ActualArea = land.Area; 2884 reply.Data.ActualArea = land.Area;
2800 reply.Data.BillableArea = land.Area; // TODO: what is this? 2885 reply.Data.BillableArea = land.Area; // TODO: what is this?
2801 2886
@@ -3502,22 +3587,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3502 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count]; 3587 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count];
3503 AgentWearablesUpdatePacket.WearableDataBlock awb; 3588 AgentWearablesUpdatePacket.WearableDataBlock awb;
3504 int idx = 0; 3589 int idx = 0;
3505 for (int i = 0; i < wearables.Length; i++) 3590
3506 { 3591 for (int i = 0; i < wearables.Length; i++)
3507 for (int j = 0; j < wearables[i].Count; j++) 3592 {
3508 { 3593 for (int j = 0; j < wearables[i].Count; j++)
3509 awb = new AgentWearablesUpdatePacket.WearableDataBlock(); 3594 {
3510 awb.WearableType = (byte)i; 3595 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
3511 awb.AssetID = wearables[i][j].AssetID; 3596 awb.WearableType = (byte) i;
3512 awb.ItemID = wearables[i][j].ItemID; 3597 awb.AssetID = wearables[i][j].AssetID;
3513 aw.WearableData[idx] = awb; 3598 awb.ItemID = wearables[i][j].ItemID;
3514 idx++; 3599 aw.WearableData[idx] = awb;
3515 3600 idx++;
3516// m_log.DebugFormat( 3601
3517// "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}", 3602 // m_log.DebugFormat(
3518// awb.ItemID, awb.AssetID, i, Name); 3603 // "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}",
3519 } 3604 // awb.ItemID, awb.AssetID, i, Name);
3520 } 3605 }
3606 }
3521 3607
3522 OutPacket(aw, ThrottleOutPacketType.Task); 3608 OutPacket(aw, ThrottleOutPacketType.Task);
3523 } 3609 }
@@ -3530,7 +3616,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3530 3616
3531 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3617 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3532 // TODO: don't create new blocks if recycling an old packet 3618 // TODO: don't create new blocks if recycling an old packet
3533 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3619 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3534 avp.ObjectData.TextureEntry = textureEntry; 3620 avp.ObjectData.TextureEntry = textureEntry;
3535 3621
3536 AvatarAppearancePacket.VisualParamBlock avblock = null; 3622 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3543,7 +3629,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3543 3629
3544 avp.Sender.IsTrial = false; 3630 avp.Sender.IsTrial = false;
3545 avp.Sender.ID = agentID; 3631 avp.Sender.ID = agentID;
3546 //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); 3632 m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString());
3547 OutPacket(avp, ThrottleOutPacketType.Task); 3633 OutPacket(avp, ThrottleOutPacketType.Task);
3548 } 3634 }
3549 3635
@@ -3660,7 +3746,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3660 /// </summary> 3746 /// </summary>
3661 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3747 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3662 { 3748 {
3663 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3749 if (entity is SceneObjectPart)
3750 {
3751 SceneObjectPart e = (SceneObjectPart)entity;
3752 SceneObjectGroup g = e.ParentGroup;
3753 if (g.RootPart.Shape.State > 30) // HUD
3754 if (g.OwnerID != AgentId)
3755 return; // Don't send updates for other people's HUDs
3756 }
3757
3664 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3758 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3665 3759
3666 lock (m_entityUpdates.SyncRoot) 3760 lock (m_entityUpdates.SyncRoot)
@@ -3727,27 +3821,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3727 3821
3728 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3822 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3729 // condition where a kill can be processed before an out-of-date update for the same object. 3823 // condition where a kill can be processed before an out-of-date update for the same object.
3730 lock (m_killRecord) 3824 float avgTimeDilation = 1.0f;
3825 IEntityUpdate iupdate;
3826 Int32 timeinqueue; // this is just debugging code & can be dropped later
3827
3828 while (updatesThisCall < maxUpdates)
3731 { 3829 {
3732 float avgTimeDilation = 1.0f; 3830 lock (m_entityUpdates.SyncRoot)
3733 IEntityUpdate iupdate; 3831 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3734 Int32 timeinqueue; // this is just debugging code & can be dropped later 3832 break;
3833
3834 EntityUpdate update = (EntityUpdate)iupdate;
3835
3836 avgTimeDilation += update.TimeDilation;
3837 avgTimeDilation *= 0.5f;
3735 3838
3736 while (updatesThisCall < maxUpdates) 3839 if (update.Entity is SceneObjectPart)
3737 { 3840 {
3738 lock (m_entityUpdates.SyncRoot) 3841 SceneObjectPart part = (SceneObjectPart)update.Entity;
3739 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3740 break;
3741 3842
3742 EntityUpdate update = (EntityUpdate)iupdate; 3843 if (part.ParentGroup.IsDeleted)
3743 3844 continue;
3744 avgTimeDilation += update.TimeDilation;
3745 avgTimeDilation *= 0.5f;
3746 3845
3747 if (update.Entity is SceneObjectPart) 3846 if (part.ParentGroup.IsAttachment)
3847 { // Someone else's HUD, why are we getting these?
3848 if (part.ParentGroup.OwnerID != AgentId &&
3849 part.ParentGroup.RootPart.Shape.State > 30)
3850 continue;
3851 ScenePresence sp;
3852 // Owner is not in the sim, don't update it to
3853 // anyone
3854 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3855 continue;
3856
3857 List<SceneObjectGroup> atts = sp.GetAttachments();
3858 bool found = false;
3859 foreach (SceneObjectGroup att in atts)
3860 {
3861 if (att == part.ParentGroup)
3862 {
3863 found = true;
3864 break;
3865 }
3866 }
3867
3868 // It's an attachment of a valid avatar, but
3869 // doesn't seem to be attached, skip
3870 if (!found)
3871 continue;
3872
3873 // On vehicle crossing, the attachments are received
3874 // while the avatar is still a child. Don't send
3875 // updates here because the LocalId has not yet
3876 // been updated and the viewer will derender the
3877 // attachments until the avatar becomes root.
3878 if (sp.IsChildAgent)
3879 continue;
3880
3881 // If the object is an attachment we don't want it to be in the kill
3882 // record. Else attaching from inworld and subsequently dropping
3883 // it will no longer work.
3884// lock (m_killRecord)
3885// {
3886// m_killRecord.Remove(part.LocalId);
3887// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3888// }
3889 }
3890 else
3748 { 3891 {
3749 SceneObjectPart part = (SceneObjectPart)update.Entity;
3750
3751 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3892 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3752 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3893 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3753 // safety measure. 3894 // safety measure.
@@ -3758,241 +3899,177 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3758 // 3899 //
3759 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3900 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3760 // after the root prim has been deleted. 3901 // after the root prim has been deleted.
3761 if (m_killRecord.Contains(part.LocalId)) 3902 //
3762 { 3903 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3763 // m_log.WarnFormat( 3904// lock (m_killRecord)
3764 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3905// {
3765 // part.LocalId, Name); 3906// if (m_killRecord.Contains(part.LocalId))
3766 continue; 3907// continue;
3767 } 3908// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3768 3909// continue;
3769 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3910// }
3911 }
3912
3913 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3914 {
3915 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3916 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3770 { 3917 {
3771 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3918 part.Shape.LightEntry = false;
3772 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3773 {
3774 part.Shape.LightEntry = false;
3775 }
3776 } 3919 }
3777 } 3920 }
3778 3921 }
3779 #region UpdateFlags to packet type conversion 3922
3780 3923 ++updatesThisCall;
3781 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; 3924
3782 3925 #region UpdateFlags to packet type conversion
3783 bool canUseCompressed = true; 3926
3784 bool canUseImproved = true; 3927 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3785 3928
3786 // Compressed object updates only make sense for LL primitives 3929 bool canUseCompressed = true;
3787 if (!(update.Entity is SceneObjectPart)) 3930 bool canUseImproved = true;
3931
3932 // Compressed object updates only make sense for LL primitives
3933 if (!(update.Entity is SceneObjectPart))
3934 {
3935 canUseCompressed = false;
3936 }
3937
3938 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3939 {
3940 canUseCompressed = false;
3941 canUseImproved = false;
3942 }
3943 else
3944 {
3945 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3946 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3947 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3948 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3788 { 3949 {
3789 canUseCompressed = false; 3950 canUseCompressed = false;
3790 } 3951 }
3791 3952
3792 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 3953 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3954 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3955 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3956 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3957 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3958 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3959 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3960 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3961 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3962 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3963 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3964 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3965 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3966 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3793 { 3967 {
3794 canUseCompressed = false;
3795 canUseImproved = false; 3968 canUseImproved = false;
3796 } 3969 }
3797 else 3970 }
3798 {
3799 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3800 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3801 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3802 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3803 {
3804 canUseCompressed = false;
3805 }
3806
3807 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3808 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3809 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3810 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3811 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3812 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3813 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3814 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3815 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3816 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3817 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3818 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3819 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3820 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3821 {
3822 canUseImproved = false;
3823 }
3824 }
3825
3826 #endregion UpdateFlags to packet type conversion
3827
3828 #region Block Construction
3829
3830 // TODO: Remove this once we can build compressed updates
3831 canUseCompressed = false;
3832 3971
3833 if (!canUseImproved && !canUseCompressed) 3972 #endregion UpdateFlags to packet type conversion
3834 {
3835 ObjectUpdatePacket.ObjectDataBlock updateBlock;
3836 3973
3837 if (update.Entity is ScenePresence) 3974 #region Block Construction
3838 {
3839 updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
3840 }
3841 else
3842 {
3843 SceneObjectPart part = (SceneObjectPart)update.Entity;
3844 updateBlock = CreatePrimUpdateBlock(part, AgentId);
3845
3846 // If the part has become a private hud since the update was scheduled then we do not
3847 // want to send it to other avatars.
3848 if (part.ParentGroup.IsAttachment
3849 && part.ParentGroup.HasPrivateAttachmentPoint
3850 && part.ParentGroup.AttachedAvatar != AgentId)
3851 continue;
3852
3853 // If the part has since been deleted, then drop the update. In the case of attachments,
3854 // this is to avoid spurious updates to other viewers since post-processing of attachments
3855 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3856 // of the test above).
3857 //
3858 // Actual deletions (kills) happen in another method.
3859 if (part.ParentGroup.IsDeleted)
3860 continue;
3861 }
3862 3975
3863 objectUpdateBlocks.Value.Add(updateBlock); 3976 // TODO: Remove this once we can build compressed updates
3864 objectUpdates.Value.Add(update); 3977 canUseCompressed = false;
3865 }
3866 else if (!canUseImproved)
3867 {
3868 SceneObjectPart part = (SceneObjectPart)update.Entity;
3869 ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
3870 = CreateCompressedUpdateBlock(part, updateFlags);
3871
3872 // If the part has since been deleted, then drop the update. In the case of attachments,
3873 // this is to avoid spurious updates to other viewers since post-processing of attachments
3874 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3875 // of the test above).
3876 //
3877 // Actual deletions (kills) happen in another method.
3878 if (part.ParentGroup.IsDeleted)
3879 continue;
3880 3978
3881 compressedUpdateBlocks.Value.Add(compressedBlock); 3979 if (!canUseImproved && !canUseCompressed)
3882 compressedUpdates.Value.Add(update); 3980 {
3981 if (update.Entity is ScenePresence)
3982 {
3983 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3883 } 3984 }
3884 else 3985 else
3885 { 3986 {
3886 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3987 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3887 {
3888 // Self updates go into a special list
3889 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3890 terseAgentUpdates.Value.Add(update);
3891 }
3892 else
3893 {
3894 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
3895 = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
3896
3897 // Everything else goes here
3898 if (update.Entity is SceneObjectPart)
3899 {
3900 SceneObjectPart part = (SceneObjectPart)update.Entity;
3901
3902 // If the part has become a private hud since the update was scheduled then we do not
3903 // want to send it to other avatars.
3904 if (part.ParentGroup.IsAttachment
3905 && part.ParentGroup.HasPrivateAttachmentPoint
3906 && part.ParentGroup.AttachedAvatar != AgentId)
3907 continue;
3908
3909 // If the part has since been deleted, then drop the update. In the case of attachments,
3910 // this is to avoid spurious updates to other viewers since post-processing of attachments
3911 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3912 // of the test above).
3913 //
3914 // Actual deletions (kills) happen in another method.
3915 if (part.ParentGroup.IsDeleted)
3916 continue;
3917 }
3918
3919 terseUpdateBlocks.Value.Add(terseUpdateBlock);
3920 terseUpdates.Value.Add(update);
3921 }
3922 } 3988 }
3923
3924 ++updatesThisCall;
3925
3926 #endregion Block Construction
3927 } 3989 }
3928 3990 else if (!canUseImproved)
3929 #region Packet Sending
3930 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3931
3932 if (terseAgentUpdateBlocks.IsValueCreated)
3933 { 3991 {
3934 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 3992 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3993 }
3994 else
3995 {
3996 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3997 // Self updates go into a special list
3998 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3999 else
4000 // Everything else goes here
4001 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
4002 }
3935 4003
3936 ImprovedTerseObjectUpdatePacket packet 4004 #endregion Block Construction
3937 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 4005 }
3938 4006
3939 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4007 #region Packet Sending
3940 packet.RegionData.TimeDilation = timeDilation; 4008
3941 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4009 const float TIME_DILATION = 1.0f;
4010 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
4011
4012 if (terseAgentUpdateBlocks.IsValueCreated)
4013 {
4014 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3942 4015
3943 for (int i = 0; i < blocks.Count; i++) 4016 ImprovedTerseObjectUpdatePacket packet
3944 packet.ObjectData[i] = blocks[i]; 4017 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3945 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4018 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3946 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); }); 4019 packet.RegionData.TimeDilation = timeDilation;
3947 } 4020 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3948 4021
3949 if (objectUpdateBlocks.IsValueCreated) 4022 for (int i = 0; i < blocks.Count; i++)
3950 { 4023 packet.ObjectData[i] = blocks[i];
3951 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3952
3953 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3954 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3955 packet.RegionData.TimeDilation = timeDilation;
3956 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3957
3958 for (int i = 0; i < blocks.Count; i++)
3959 packet.ObjectData[i] = blocks[i];
3960 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3961 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3962 }
3963
3964 if (compressedUpdateBlocks.IsValueCreated)
3965 {
3966 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3967
3968 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3969 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3970 packet.RegionData.TimeDilation = timeDilation;
3971 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3972
3973 for (int i = 0; i < blocks.Count; i++)
3974 packet.ObjectData[i] = blocks[i];
3975 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3976 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3977 }
3978 4024
3979 if (terseUpdateBlocks.IsValueCreated) 4025 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3980 { 4026 }
3981 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3982
3983 ImprovedTerseObjectUpdatePacket packet
3984 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
3985 PacketType.ImprovedTerseObjectUpdate);
3986 4027
3987 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4028 if (objectUpdateBlocks.IsValueCreated)
3988 packet.RegionData.TimeDilation = timeDilation; 4029 {
3989 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4030 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3990 4031
3991 for (int i = 0; i < blocks.Count; i++) 4032 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3992 packet.ObjectData[i] = blocks[i]; 4033 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3993 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4034 packet.RegionData.TimeDilation = timeDilation;
3994 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 4035 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3995 } 4036
4037 for (int i = 0; i < blocks.Count; i++)
4038 packet.ObjectData[i] = blocks[i];
4039
4040 OutPacket(packet, ThrottleOutPacketType.Task, true);
4041 }
4042
4043 if (compressedUpdateBlocks.IsValueCreated)
4044 {
4045 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4046
4047 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4048 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4049 packet.RegionData.TimeDilation = timeDilation;
4050 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
4051
4052 for (int i = 0; i < blocks.Count; i++)
4053 packet.ObjectData[i] = blocks[i];
4054
4055 OutPacket(packet, ThrottleOutPacketType.Task, true);
4056 }
4057
4058 if (terseUpdateBlocks.IsValueCreated)
4059 {
4060 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4061
4062 ImprovedTerseObjectUpdatePacket packet
4063 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4064 PacketType.ImprovedTerseObjectUpdate);
4065 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4066 packet.RegionData.TimeDilation = timeDilation;
4067 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4068
4069 for (int i = 0; i < blocks.Count; i++)
4070 packet.ObjectData[i] = blocks[i];
4071
4072 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3996 } 4073 }
3997 4074
3998 #endregion Packet Sending 4075 #endregion Packet Sending
@@ -4285,11 +4362,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4285 4362
4286 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4363 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4287 // of the object rather than the properties when the packet was created 4364 // of the object rather than the properties when the packet was created
4288 OutPacket(packet, ThrottleOutPacketType.Task, true, 4365 // HACK : Remove intelligent resending until it's fixed in core
4289 delegate(OutgoingPacket oPacket) 4366 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4290 { 4367 // delegate(OutgoingPacket oPacket)
4291 ResendPropertyUpdates(updates, oPacket); 4368 // {
4292 }); 4369 // ResendPropertyUpdates(updates, oPacket);
4370 // });
4371 OutPacket(packet, ThrottleOutPacketType.Task, true);
4293 4372
4294 // pbcnt += blocks.Count; 4373 // pbcnt += blocks.Count;
4295 // ppcnt++; 4374 // ppcnt++;
@@ -4315,11 +4394,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4315 // of the object rather than the properties when the packet was created 4394 // of the object rather than the properties when the packet was created
4316 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4395 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4317 updates.Add(familyUpdates.Value[i]); 4396 updates.Add(familyUpdates.Value[i]);
4318 OutPacket(packet, ThrottleOutPacketType.Task, true, 4397 // HACK : Remove intelligent resending until it's fixed in core
4319 delegate(OutgoingPacket oPacket) 4398 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4320 { 4399 // delegate(OutgoingPacket oPacket)
4321 ResendPropertyUpdates(updates, oPacket); 4400 // {
4322 }); 4401 // ResendPropertyUpdates(updates, oPacket);
4402 // });
4403 OutPacket(packet, ThrottleOutPacketType.Task, true);
4323 4404
4324 // fpcnt++; 4405 // fpcnt++;
4325 // fbcnt++; 4406 // fbcnt++;
@@ -4691,7 +4772,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4691 4772
4692 if (landData.SimwideArea > 0) 4773 if (landData.SimwideArea > 0)
4693 { 4774 {
4694 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4775 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4776 // Never report more than sim total capacity
4777 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4778 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4695 updateMessage.SimWideMaxPrims = simulatorCapacity; 4779 updateMessage.SimWideMaxPrims = simulatorCapacity;
4696 } 4780 }
4697 else 4781 else
@@ -4820,14 +4904,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4820 4904
4821 if (notifyCount > 0) 4905 if (notifyCount > 0)
4822 { 4906 {
4823 if (notifyCount > 32) 4907// if (notifyCount > 32)
4824 { 4908// {
4825 m_log.InfoFormat( 4909// m_log.InfoFormat(
4826 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4910// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4827 + " - a developer might want to investigate whether this is a hard limit", 32); 4911// + " - a developer might want to investigate whether this is a hard limit", 32);
4828 4912//
4829 notifyCount = 32; 4913// notifyCount = 32;
4830 } 4914// }
4831 4915
4832 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4916 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4833 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4917 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4882,9 +4966,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4882 { 4966 {
4883 ScenePresence presence = (ScenePresence)entity; 4967 ScenePresence presence = (ScenePresence)entity;
4884 4968
4969 position = presence.OffsetPosition;
4970 rotation = presence.Rotation;
4971
4972 if (presence.ParentID != 0)
4973 {
4974 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4975 if (part != null && part != part.ParentGroup.RootPart)
4976 {
4977 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4978 rotation = part.RotationOffset * presence.Rotation;
4979 }
4980 }
4981
4885 attachPoint = 0; 4982 attachPoint = 0;
4886 collisionPlane = presence.CollisionPlane; 4983 collisionPlane = presence.CollisionPlane;
4887 position = presence.OffsetPosition;
4888 velocity = presence.Velocity; 4984 velocity = presence.Velocity;
4889 acceleration = Vector3.Zero; 4985 acceleration = Vector3.Zero;
4890 4986
@@ -4892,9 +4988,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4892 // in that direction, even though we don't model this on the server. Implementing this in the future 4988 // in that direction, even though we don't model this on the server. Implementing this in the future
4893 // may improve movement smoothness. 4989 // may improve movement smoothness.
4894// acceleration = new Vector3(1, 0, 0); 4990// acceleration = new Vector3(1, 0, 0);
4895 4991
4896 angularVelocity = Vector3.Zero; 4992 angularVelocity = Vector3.Zero;
4897 rotation = presence.Rotation;
4898 4993
4899 if (sendTexture) 4994 if (sendTexture)
4900 textureEntry = presence.Appearance.Texture.GetBytes(); 4995 textureEntry = presence.Appearance.Texture.GetBytes();
@@ -5001,13 +5096,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5001 5096
5002 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5097 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
5003 { 5098 {
5099 Vector3 offsetPosition = data.OffsetPosition;
5100 Quaternion rotation = data.Rotation;
5101 uint parentID = data.ParentID;
5102
5103 if (parentID != 0)
5104 {
5105 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5106 if (part != null && part != part.ParentGroup.RootPart)
5107 {
5108 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5109 rotation = part.RotationOffset * data.Rotation;
5110 parentID = part.ParentGroup.RootPart.LocalId;
5111 }
5112 }
5113
5004 byte[] objectData = new byte[76]; 5114 byte[] objectData = new byte[76];
5005 5115
5006 data.CollisionPlane.ToBytes(objectData, 0); 5116 data.CollisionPlane.ToBytes(objectData, 0);
5007 data.OffsetPosition.ToBytes(objectData, 16); 5117 offsetPosition.ToBytes(objectData, 16);
5008// data.Velocity.ToBytes(objectData, 28); 5118// data.Velocity.ToBytes(objectData, 28);
5009// data.Acceleration.ToBytes(objectData, 40); 5119// data.Acceleration.ToBytes(objectData, 40);
5010 data.Rotation.ToBytes(objectData, 52); 5120 rotation.ToBytes(objectData, 52);
5011 //data.AngularVelocity.ToBytes(objectData, 64); 5121 //data.AngularVelocity.ToBytes(objectData, 64);
5012 5122
5013 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5123 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -5021,14 +5131,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5021 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5131 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
5022 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5132 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
5023 update.ObjectData = objectData; 5133 update.ObjectData = objectData;
5024 update.ParentID = data.ParentID; 5134 update.ParentID = parentID;
5025 update.PathCurve = 16; 5135 update.PathCurve = 16;
5026 update.PathScaleX = 100; 5136 update.PathScaleX = 100;
5027 update.PathScaleY = 100; 5137 update.PathScaleY = 100;
5028 update.PCode = (byte)PCode.Avatar; 5138 update.PCode = (byte)PCode.Avatar;
5029 update.ProfileCurve = 1; 5139 update.ProfileCurve = 1;
5030 update.PSBlock = Utils.EmptyBytes; 5140 update.PSBlock = Utils.EmptyBytes;
5031 update.Scale = new Vector3(0.45f, 0.6f, 1.9f); 5141 update.Scale = data.Appearance.AvatarSize;
5142// update.Scale.Z -= 0.2f;
5143
5032 update.Text = Utils.EmptyBytes; 5144 update.Text = Utils.EmptyBytes;
5033 update.TextColor = new byte[4]; 5145 update.TextColor = new byte[4];
5034 5146
@@ -5039,10 +5151,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5039 update.TextureEntry = Utils.EmptyBytes; 5151 update.TextureEntry = Utils.EmptyBytes;
5040// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; 5152// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
5041 5153
5154/* all this flags seem related to prims and not avatars. This allow for wrong viewer side move of a avatar in prim edition mode (anv mantis 854)
5042 update.UpdateFlags = (uint)( 5155 update.UpdateFlags = (uint)(
5043 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | 5156 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
5044 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | 5157 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
5045 PrimFlags.ObjectOwnerModify); 5158 PrimFlags.ObjectOwnerModify);
5159*/
5160 update.UpdateFlags = 0;
5046 5161
5047 return update; 5162 return update;
5048 } 5163 }
@@ -5213,8 +5328,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5213 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs 5328 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs
5214 // for each AgentUpdate packet. 5329 // for each AgentUpdate packet.
5215 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false); 5330 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false);
5216 5331
5217 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false); 5332 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false);
5333 AddLocalPacketHandler(PacketType.VelocityInterpolateOff, HandleVelocityInterpolateOff, false);
5334 AddLocalPacketHandler(PacketType.VelocityInterpolateOn, HandleVelocityInterpolateOn, false);
5218 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); 5335 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false);
5219 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); 5336 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
5220 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false); 5337 AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false);
@@ -5366,6 +5483,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5366 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5483 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5367 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5484 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5368 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5485 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5486 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5369 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5487 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5370 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5488 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5371 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5489 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5432,6 +5550,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5432 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5550 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5433 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5551 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5434 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5552 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5553 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5435 5554
5436 AddGenericPacketHandler("autopilot", HandleAutopilot); 5555 AddGenericPacketHandler("autopilot", HandleAutopilot);
5437 } 5556 }
@@ -5470,6 +5589,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5470 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) || 5589 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) ||
5471 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) || 5590 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) ||
5472 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) || 5591 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) ||
5592 (x.ControlFlags != 0) ||
5473 (x.Far != m_lastAgentUpdateArgs.Far) || 5593 (x.Far != m_lastAgentUpdateArgs.Far) ||
5474 (x.Flags != m_lastAgentUpdateArgs.Flags) || 5594 (x.Flags != m_lastAgentUpdateArgs.Flags) ||
5475 (x.State != m_lastAgentUpdateArgs.State) || 5595 (x.State != m_lastAgentUpdateArgs.State) ||
@@ -5729,6 +5849,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5729 return true; 5849 return true;
5730 } 5850 }
5731 5851
5852 private bool HandleVelocityInterpolateOff(IClientAPI sender, Packet Pack)
5853 {
5854 VelocityInterpolateOffPacket p = (VelocityInterpolateOffPacket)Pack;
5855 if (p.AgentData.SessionID != SessionId ||
5856 p.AgentData.AgentID != AgentId)
5857 return true;
5858
5859 m_VelocityInterpolate = false;
5860 return true;
5861 }
5862
5863 private bool HandleVelocityInterpolateOn(IClientAPI sender, Packet Pack)
5864 {
5865 VelocityInterpolateOnPacket p = (VelocityInterpolateOnPacket)Pack;
5866 if (p.AgentData.SessionID != SessionId ||
5867 p.AgentData.AgentID != AgentId)
5868 return true;
5869
5870 m_VelocityInterpolate = true;
5871 return true;
5872 }
5873
5874
5732 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack) 5875 private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack)
5733 { 5876 {
5734 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack; 5877 AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack;
@@ -6149,17 +6292,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6149 // Temporarily protect ourselves from the mantis #951 failure. 6292 // Temporarily protect ourselves from the mantis #951 failure.
6150 // However, we could do this for several other handlers where a failure isn't terminal 6293 // However, we could do this for several other handlers where a failure isn't terminal
6151 // for the client session anyway, in order to protect ourselves against bad code in plugins 6294 // for the client session anyway, in order to protect ourselves against bad code in plugins
6295 Vector3 avSize = appear.AgentData.Size;
6152 try 6296 try
6153 { 6297 {
6154 byte[] visualparams = new byte[appear.VisualParam.Length]; 6298 byte[] visualparams = new byte[appear.VisualParam.Length];
6155 for (int i = 0; i < appear.VisualParam.Length; i++) 6299 for (int i = 0; i < appear.VisualParam.Length; i++)
6156 visualparams[i] = appear.VisualParam[i].ParamValue; 6300 visualparams[i] = appear.VisualParam[i].ParamValue;
6157 6301 //var b = appear.WearableData[0];
6302
6158 Primitive.TextureEntry te = null; 6303 Primitive.TextureEntry te = null;
6159 if (appear.ObjectData.TextureEntry.Length > 1) 6304 if (appear.ObjectData.TextureEntry.Length > 1)
6160 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); 6305 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
6306
6307 WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length];
6308 for (int i=0; i<appear.WearableData.Length;i++)
6309 cacheitems[i] = new WearableCacheItem(){CacheId = appear.WearableData[i].CacheID,TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex)};
6161 6310
6162 handlerSetAppearance(sender, te, visualparams); 6311
6312
6313 handlerSetAppearance(sender, te, visualparams,avSize, cacheitems);
6163 } 6314 }
6164 catch (Exception e) 6315 catch (Exception e)
6165 { 6316 {
@@ -6368,6 +6519,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6368 { 6519 {
6369 handlerCompleteMovementToRegion(sender, true); 6520 handlerCompleteMovementToRegion(sender, true);
6370 } 6521 }
6522 else
6523 m_log.Debug("HandleCompleteAgentMovement NULL handler");
6524
6371 handlerCompleteMovementToRegion = null; 6525 handlerCompleteMovementToRegion = null;
6372 6526
6373 return true; 6527 return true;
@@ -6385,7 +6539,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6385 return true; 6539 return true;
6386 } 6540 }
6387 #endregion 6541 #endregion
6388 6542/*
6389 StartAnim handlerStartAnim = null; 6543 StartAnim handlerStartAnim = null;
6390 StopAnim handlerStopAnim = null; 6544 StopAnim handlerStopAnim = null;
6391 6545
@@ -6409,6 +6563,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6409 } 6563 }
6410 } 6564 }
6411 return true; 6565 return true;
6566*/
6567 ChangeAnim handlerChangeAnim = null;
6568
6569 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6570 {
6571 handlerChangeAnim = OnChangeAnim;
6572 if (handlerChangeAnim != null)
6573 {
6574 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6575 }
6576 }
6577
6578 handlerChangeAnim = OnChangeAnim;
6579 if (handlerChangeAnim != null)
6580 {
6581 handlerChangeAnim(UUID.Zero, false, true);
6582 }
6583
6584 return true;
6412 } 6585 }
6413 6586
6414 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6587 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -6634,6 +6807,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6634 #endregion 6807 #endregion
6635 6808
6636 m_udpClient.SetThrottles(atpack.Throttle.Throttles); 6809 m_udpClient.SetThrottles(atpack.Throttle.Throttles);
6810 GenericCall2 handler = OnUpdateThrottles;
6811 if (handler != null)
6812 {
6813 handler();
6814 }
6637 return true; 6815 return true;
6638 } 6816 }
6639 6817
@@ -7035,10 +7213,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7035 // 46,47,48 are special positions within the packet 7213 // 46,47,48 are special positions within the packet
7036 // This may change so perhaps we need a better way 7214 // This may change so perhaps we need a better way
7037 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) 7215 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
7038 bool UsePhysics = (data[46] != 0) ? true : false; 7216 /*
7039 bool IsTemporary = (data[47] != 0) ? true : false; 7217 bool UsePhysics = (data[46] != 0) ? true : false;
7040 bool IsPhantom = (data[48] != 0) ? true : false; 7218 bool IsTemporary = (data[47] != 0) ? true : false;
7041 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this); 7219 bool IsPhantom = (data[48] != 0) ? true : false;
7220 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this);
7221 */
7222 bool UsePhysics = flags.AgentData.UsePhysics;
7223 bool IsPhantom = flags.AgentData.IsPhantom;
7224 bool IsTemporary = flags.AgentData.IsTemporary;
7225 ObjectFlagUpdatePacket.ExtraPhysicsBlock[] blocks = flags.ExtraPhysics;
7226 ExtraPhysicsData physdata = new ExtraPhysicsData();
7227
7228 if (blocks == null || blocks.Length == 0)
7229 {
7230 physdata.PhysShapeType = PhysShapeType.invalid;
7231 }
7232 else
7233 {
7234 ObjectFlagUpdatePacket.ExtraPhysicsBlock phsblock = blocks[0];
7235 physdata.PhysShapeType = (PhysShapeType)phsblock.PhysicsShapeType;
7236 physdata.Bounce = phsblock.Restitution;
7237 physdata.Density = phsblock.Density;
7238 physdata.Friction = phsblock.Friction;
7239 physdata.GravitationModifier = phsblock.GravityMultiplier;
7240 }
7241
7242 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
7042 } 7243 }
7043 return true; 7244 return true;
7044 } 7245 }
@@ -7621,6 +7822,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7621 // surrounding scene 7822 // surrounding scene
7622 if ((ImageType)block.Type == ImageType.Baked) 7823 if ((ImageType)block.Type == ImageType.Baked)
7623 args.Priority *= 2.0f; 7824 args.Priority *= 2.0f;
7825 int wearableout = 0;
7624 7826
7625 ImageManager.EnqueueReq(args); 7827 ImageManager.EnqueueReq(args);
7626 } 7828 }
@@ -8639,16 +8841,61 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8639 8841
8640 #region Parcel related packets 8842 #region Parcel related packets
8641 8843
8844 // acumulate several HandleRegionHandleRequest consecutive overlaping requests
8845 // to be done with minimal resources as possible
8846 // variables temporary here while in test
8847
8848 Queue<UUID> RegionHandleRequests = new Queue<UUID>();
8849 bool RegionHandleRequestsInService = false;
8850
8642 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack) 8851 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack)
8643 { 8852 {
8644 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; 8853 UUID currentUUID;
8645 8854
8646 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; 8855 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest;
8647 if (handlerRegionHandleRequest != null) 8856
8857 if (handlerRegionHandleRequest == null)
8858 return true;
8859
8860 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
8861
8862 lock (RegionHandleRequests)
8648 { 8863 {
8649 handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); 8864 if (RegionHandleRequestsInService)
8865 {
8866 // we are already busy doing a previus request
8867 // so enqueue it
8868 RegionHandleRequests.Enqueue(rhrPack.RequestBlock.RegionID);
8869 return true;
8870 }
8871
8872 // else do it
8873 currentUUID = rhrPack.RequestBlock.RegionID;
8874 RegionHandleRequestsInService = true;
8650 } 8875 }
8651 return true; 8876
8877 while (true)
8878 {
8879 handlerRegionHandleRequest(this, currentUUID);
8880
8881 lock (RegionHandleRequests)
8882 {
8883 // exit condition, nothing to do or closed
8884 // current code seems to assume we may loose the handler at anytime,
8885 // so keep checking it
8886 handlerRegionHandleRequest = OnRegionHandleRequest;
8887
8888 if (RegionHandleRequests.Count == 0 || !IsActive || handlerRegionHandleRequest == null)
8889 {
8890 RegionHandleRequests.Clear();
8891 RegionHandleRequestsInService = false;
8892 return true;
8893 }
8894 currentUUID = RegionHandleRequests.Dequeue();
8895 }
8896 }
8897
8898 return true; // actually unreached
8652 } 8899 }
8653 8900
8654 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack) 8901 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack)
@@ -9904,7 +10151,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9904 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 10151 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9905 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 10152 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9906 UpdateMuteListEntry.MuteData.MuteType, 10153 UpdateMuteListEntry.MuteData.MuteType,
9907 UpdateMuteListEntry.AgentData.AgentID); 10154 UpdateMuteListEntry.MuteData.MuteFlags);
9908 return true; 10155 return true;
9909 } 10156 }
9910 return false; 10157 return false;
@@ -9919,8 +10166,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9919 { 10166 {
9920 handlerRemoveMuteListEntry(this, 10167 handlerRemoveMuteListEntry(this,
9921 RemoveMuteListEntry.MuteData.MuteID, 10168 RemoveMuteListEntry.MuteData.MuteID,
9922 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 10169 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9923 RemoveMuteListEntry.AgentData.AgentID);
9924 return true; 10170 return true;
9925 } 10171 }
9926 return false; 10172 return false;
@@ -9964,10 +10210,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9964 return false; 10210 return false;
9965 } 10211 }
9966 10212
10213 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10214 {
10215 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10216 (ChangeInventoryItemFlagsPacket)packet;
10217 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10218 if (handlerChangeInventoryItemFlags != null)
10219 {
10220 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10221 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10222 return true;
10223 }
10224 return false;
10225 }
10226
9967 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10227 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9968 { 10228 {
9969 return true; 10229 return true;
9970 } 10230 }
10231
10232 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10233 {
10234 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10235
10236 #region Packet Session and User Check
10237 if (m_checkPackets)
10238 {
10239 if (packet.AgentData.SessionID != SessionId ||
10240 packet.AgentData.AgentID != AgentId)
10241 return true;
10242 }
10243 #endregion
10244 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10245 List<InventoryItemBase> items = new List<InventoryItemBase>();
10246 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10247 {
10248 InventoryItemBase b = new InventoryItemBase();
10249 b.ID = n.OldItemID;
10250 b.Folder = n.OldFolderID;
10251 items.Add(b);
10252 }
10253
10254 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10255 if (handlerMoveItemsAndLeaveCopy != null)
10256 {
10257 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10258 }
10259
10260 return true;
10261 }
9971 10262
9972 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10263 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9973 { 10264 {
@@ -10394,6 +10685,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10394 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10685 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10395 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10686 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10396 10687
10688 Scene scene = (Scene)m_scene;
10689 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10690 {
10691 ScenePresence p;
10692 if (scene.TryGetScenePresence(sender.AgentId, out p))
10693 {
10694 if (p.GodLevel >= 200)
10695 {
10696 groupProfileReply.GroupData.OpenEnrollment = true;
10697 groupProfileReply.GroupData.MembershipFee = 0;
10698 }
10699 }
10700 }
10701
10397 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10702 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10398 } 10703 }
10399 return true; 10704 return true;
@@ -10967,11 +11272,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10967 11272
10968 StartLure handlerStartLure = OnStartLure; 11273 StartLure handlerStartLure = OnStartLure;
10969 if (handlerStartLure != null) 11274 if (handlerStartLure != null)
10970 handlerStartLure(startLureRequest.Info.LureType, 11275 {
10971 Utils.BytesToString( 11276 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10972 startLureRequest.Info.Message), 11277 {
10973 startLureRequest.TargetData[0].TargetID, 11278 handlerStartLure(startLureRequest.Info.LureType,
10974 this); 11279 Utils.BytesToString(
11280 startLureRequest.Info.Message),
11281 startLureRequest.TargetData[i].TargetID,
11282 this);
11283 }
11284 }
10975 return true; 11285 return true;
10976 } 11286 }
10977 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11287 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -11085,10 +11395,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11085 } 11395 }
11086 #endregion 11396 #endregion
11087 11397
11088 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11398 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11089 if (handlerClassifiedGodDelete != null) 11399 if (handlerClassifiedGodDelete != null)
11090 handlerClassifiedGodDelete( 11400 handlerClassifiedGodDelete(
11091 classifiedGodDelete.Data.ClassifiedID, 11401 classifiedGodDelete.Data.ClassifiedID,
11402 classifiedGodDelete.Data.QueryID,
11092 this); 11403 this);
11093 return true; 11404 return true;
11094 } 11405 }
@@ -11401,6 +11712,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11401 11712
11402 if (cachedtex.AgentData.SessionID != SessionId) 11713 if (cachedtex.AgentData.SessionID != SessionId)
11403 return false; 11714 return false;
11715
11404 11716
11405 // TODO: don't create new blocks if recycling an old packet 11717 // TODO: don't create new blocks if recycling an old packet
11406 cachedresp.AgentData.AgentID = AgentId; 11718 cachedresp.AgentData.AgentID = AgentId;
@@ -11410,14 +11722,140 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11410 cachedresp.WearableData = 11722 cachedresp.WearableData =
11411 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length]; 11723 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
11412 11724
11413 for (int i = 0; i < cachedtex.WearableData.Length; i++) 11725 //IAvatarFactoryModule fac = m_scene.RequestModuleInterface<IAvatarFactoryModule>();
11726 // var item = fac.GetBakedTextureFaces(AgentId);
11727 //WearableCacheItem[] items = fac.GetCachedItems(AgentId);
11728
11729 IAssetService cache = m_scene.AssetService;
11730 IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
11731 //bakedTextureModule = null;
11732 int maxWearablesLoop = cachedtex.WearableData.Length;
11733 if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES)
11734 maxWearablesLoop = AvatarWearable.MAX_WEARABLES;
11735
11736 if (bakedTextureModule != null && cache != null)
11414 { 11737 {
11415 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); 11738 // We need to make sure the asset stored in the bake is available on this server also by it's assetid before we map it to a Cacheid
11416 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; 11739
11417 cachedresp.WearableData[i].TextureID = UUID.Zero; 11740 WearableCacheItem[] cacheItems = null;
11418 cachedresp.WearableData[i].HostName = new byte[0]; 11741 ScenePresence p = m_scene.GetScenePresence(AgentId);
11742 if (p.Appearance != null)
11743 if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty)
11744 {
11745 try
11746 {
11747 cacheItems = bakedTextureModule.Get(AgentId);
11748 p.Appearance.WearableCacheItems = cacheItems;
11749 p.Appearance.WearableCacheItemsDirty = false;
11750 }
11751
11752 /*
11753 * The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception!
11754 *
11755 catch (System.Net.Sockets.SocketException)
11756 {
11757 cacheItems = null;
11758 }
11759 catch (WebException)
11760 {
11761 cacheItems = null;
11762 }
11763 catch (InvalidOperationException)
11764 {
11765 cacheItems = null;
11766 } */
11767 catch (Exception)
11768 {
11769 cacheItems = null;
11770 }
11771
11772 }
11773 else if (p.Appearance.WearableCacheItems != null)
11774 {
11775 cacheItems = p.Appearance.WearableCacheItems;
11776 }
11777
11778 if (cache != null && cacheItems != null)
11779 {
11780 foreach (WearableCacheItem item in cacheItems)
11781 {
11782
11783 if (cache.GetCached(item.TextureID.ToString()) == null)
11784 {
11785 item.TextureAsset.Temporary = true;
11786 cache.Store(item.TextureAsset);
11787 }
11788
11789
11790 }
11791 }
11792
11793 if (cacheItems != null)
11794 {
11795
11796 for (int i = 0; i < maxWearablesLoop; i++)
11797 {
11798 WearableCacheItem item =
11799 WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems);
11800
11801 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11802 cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex;
11803 cachedresp.WearableData[i].HostName = new byte[0];
11804 if (item != null && cachedtex.WearableData[i].ID == item.CacheId)
11805 {
11806
11807 cachedresp.WearableData[i].TextureID = item.TextureID;
11808 }
11809 else
11810 {
11811 cachedresp.WearableData[i].TextureID = UUID.Zero;
11812 }
11813 }
11814 }
11815 else
11816 {
11817 for (int i = 0; i < maxWearablesLoop; i++)
11818 {
11819 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11820 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11821 cachedresp.WearableData[i].TextureID = UUID.Zero;
11822 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11823 cachedresp.WearableData[i].HostName = new byte[0];
11824 }
11825 }
11419 } 11826 }
11827 else
11828 {
11829 if (cache == null)
11830 {
11831 for (int i = 0; i < maxWearablesLoop; i++)
11832 {
11833 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11834 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11835 cachedresp.WearableData[i].TextureID = UUID.Zero;
11836 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11837 cachedresp.WearableData[i].HostName = new byte[0];
11838 }
11839 }
11840 else
11841 {
11842 for (int i = 0; i < maxWearablesLoop; i++)
11843 {
11844 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11845 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11420 11846
11847
11848
11849 if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null)
11850 cachedresp.WearableData[i].TextureID = UUID.Zero;
11851 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11852 else
11853 cachedresp.WearableData[i].TextureID = UUID.Zero;
11854 // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11855 cachedresp.WearableData[i].HostName = new byte[0];
11856 }
11857 }
11858 }
11421 cachedresp.Header.Zerocoded = true; 11859 cachedresp.Header.Zerocoded = true;
11422 OutPacket(cachedresp, ThrottleOutPacketType.Task); 11860 OutPacket(cachedresp, ThrottleOutPacketType.Task);
11423 11861
@@ -11454,209 +11892,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11454 } 11892 }
11455 else 11893 else
11456 { 11894 {
11457// m_log.DebugFormat( 11895 ClientChangeObject updatehandler = onClientChangeObject;
11458// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11459// i, block.Type, part.Name, part.LocalId);
11460 11896
11461// // Do this once since fetch parts creates a new array. 11897 if (updatehandler != null)
11462// SceneObjectPart[] parts = part.ParentGroup.Parts; 11898 {
11463// for (int j = 0; j < parts.Length; j++) 11899 ObjectChangeData udata = new ObjectChangeData();
11464// {
11465// part.StoreUndoState();
11466// parts[j].IgnoreUndoUpdate = true;
11467// }
11468 11900
11469 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11901 /*ubit from ll JIRA:
11902 * 0x01 position
11903 * 0x02 rotation
11904 * 0x04 scale
11905
11906 * 0x08 LINK_SET
11907 * 0x10 UNIFORM for scale
11908 */
11470 11909
11471 switch (block.Type) 11910 // translate to internal changes
11472 { 11911 // not all cases .. just the ones older code did
11473 case 1:
11474 Vector3 pos1 = new Vector3(block.Data, 0);
11475 11912
11476 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11913 switch (block.Type)
11477 if (handlerUpdatePrimSinglePosition != null) 11914 {
11478 { 11915 case 1: //change position sp
11479 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11916 udata.position = new Vector3(block.Data, 0);
11480 handlerUpdatePrimSinglePosition(localId, pos1, this);
11481 }
11482 break;
11483 11917
11484 case 2: 11918 udata.change = ObjectChangeType.primP;
11485 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11919 updatehandler(localId, udata, this);
11920 break;
11486 11921
11487 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11922 case 2: // rotation sp
11488 if (handlerUpdatePrimSingleRotation != null) 11923 udata.rotation = new Quaternion(block.Data, 0, true);
11489 {
11490 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11491 handlerUpdatePrimSingleRotation(localId, rot1, this);
11492 }
11493 break;
11494 11924
11495 case 3: 11925 udata.change = ObjectChangeType.primR;
11496 Vector3 rotPos = new Vector3(block.Data, 0); 11926 updatehandler(localId, udata, this);
11497 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11927 break;
11498 11928
11499 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11929 case 3: // position plus rotation
11500 if (handlerUpdatePrimSingleRotationPosition != null) 11930 udata.position = new Vector3(block.Data, 0);
11501 { 11931 udata.rotation = new Quaternion(block.Data, 12, true);
11502 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11503 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11504 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11505 }
11506 break;
11507 11932
11508 case 4: 11933 udata.change = ObjectChangeType.primPR;
11509 case 20: 11934 updatehandler(localId, udata, this);
11510 Vector3 scale4 = new Vector3(block.Data, 0); 11935 break;
11511 11936
11512 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11937 case 4: // scale sp
11513 if (handlerUpdatePrimScale != null) 11938 udata.scale = new Vector3(block.Data, 0);
11514 { 11939 udata.change = ObjectChangeType.primS;
11515 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11516 handlerUpdatePrimScale(localId, scale4, this);
11517 }
11518 break;
11519 11940
11520 case 5: 11941 updatehandler(localId, udata, this);
11521 Vector3 scale1 = new Vector3(block.Data, 12); 11942 break;
11522 Vector3 pos11 = new Vector3(block.Data, 0);
11523 11943
11524 handlerUpdatePrimScale = OnUpdatePrimScale; 11944 case 0x14: // uniform scale sp
11525 if (handlerUpdatePrimScale != null) 11945 udata.scale = new Vector3(block.Data, 0);
11526 {
11527 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11528 handlerUpdatePrimScale(localId, scale1, this);
11529 11946
11530 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11947 udata.change = ObjectChangeType.primUS;
11531 if (handlerUpdatePrimSinglePosition != null) 11948 updatehandler(localId, udata, this);
11532 { 11949 break;
11533 handlerUpdatePrimSinglePosition(localId, pos11, this);
11534 }
11535 }
11536 break;
11537 11950
11538 case 9: 11951 case 5: // scale and position sp
11539 Vector3 pos2 = new Vector3(block.Data, 0); 11952 udata.position = new Vector3(block.Data, 0);
11953 udata.scale = new Vector3(block.Data, 12);
11540 11954
11541 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11955 udata.change = ObjectChangeType.primPS;
11956 updatehandler(localId, udata, this);
11957 break;
11542 11958
11543 if (handlerUpdateVector != null) 11959 case 0x15: //uniform scale and position
11544 { 11960 udata.position = new Vector3(block.Data, 0);
11545 handlerUpdateVector(localId, pos2, this); 11961 udata.scale = new Vector3(block.Data, 12);
11546 }
11547 break;
11548 11962
11549 case 10: 11963 udata.change = ObjectChangeType.primPUS;
11550 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11964 updatehandler(localId, udata, this);
11965 break;
11551 11966
11552 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11967 // now group related (bit 4)
11553 if (handlerUpdatePrimRotation != null) 11968 case 9: //( 8 + 1 )group position
11554 { 11969 udata.position = new Vector3(block.Data, 0);
11555 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11556 handlerUpdatePrimRotation(localId, rot3, this);
11557 }
11558 break;
11559 11970
11560 case 11: 11971 udata.change = ObjectChangeType.groupP;
11561 Vector3 pos3 = new Vector3(block.Data, 0); 11972 updatehandler(localId, udata, this);
11562 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11973 break;
11563 11974
11564 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11975 case 0x0A: // (8 + 2) group rotation
11565 if (handlerUpdatePrimGroupRotation != null) 11976 udata.rotation = new Quaternion(block.Data, 0, true);
11566 {
11567 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11568 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11569 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11570 }
11571 break;
11572 case 12:
11573 case 28:
11574 Vector3 scale7 = new Vector3(block.Data, 0);
11575 11977
11576 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11978 udata.change = ObjectChangeType.groupR;
11577 if (handlerUpdatePrimGroupScale != null) 11979 updatehandler(localId, udata, this);
11578 { 11980 break;
11579 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11580 handlerUpdatePrimGroupScale(localId, scale7, this);
11581 }
11582 break;
11583 11981
11584 case 13: 11982 case 0x0B: //( 8 + 2 + 1) group rotation and position
11585 Vector3 scale2 = new Vector3(block.Data, 12); 11983 udata.position = new Vector3(block.Data, 0);
11586 Vector3 pos4 = new Vector3(block.Data, 0); 11984 udata.rotation = new Quaternion(block.Data, 12, true);
11587 11985
11588 handlerUpdatePrimScale = OnUpdatePrimScale; 11986 udata.change = ObjectChangeType.groupPR;
11589 if (handlerUpdatePrimScale != null) 11987 updatehandler(localId, udata, this);
11590 { 11988 break;
11591 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11592 handlerUpdatePrimScale(localId, scale2, this);
11593 11989
11594 // Change the position based on scale (for bug number 246) 11990 case 0x0C: // (8 + 4) group scale
11595 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11991 // only afects root prim and only sent by viewer editor object tab scaling
11596 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11992 // mouse edition only allows uniform scaling
11597 if (handlerUpdatePrimSinglePosition != null) 11993 // SL MAY CHANGE THIS in viewers
11598 {
11599 handlerUpdatePrimSinglePosition(localId, pos4, this);
11600 }
11601 }
11602 break;
11603 11994
11604 case 29: 11995 udata.scale = new Vector3(block.Data, 0);
11605 Vector3 scale5 = new Vector3(block.Data, 12);
11606 Vector3 pos5 = new Vector3(block.Data, 0);
11607 11996
11608 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11997 udata.change = ObjectChangeType.groupS;
11609 if (handlerUpdatePrimGroupScale != null) 11998 updatehandler(localId, udata, this);
11610 {
11611 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11612 part.StoreUndoState(true);
11613 part.IgnoreUndoUpdate = true;
11614 handlerUpdatePrimGroupScale(localId, scale5, this);
11615 handlerUpdateVector = OnUpdatePrimGroupPosition;
11616 11999
11617 if (handlerUpdateVector != null) 12000 break;
11618 {
11619 handlerUpdateVector(localId, pos5, this);
11620 }
11621 12001
11622 part.IgnoreUndoUpdate = false; 12002 case 0x0D: //(8 + 4 + 1) group scale and position
11623 } 12003 // exception as above
11624 12004
11625 break; 12005 udata.position = new Vector3(block.Data, 0);
12006 udata.scale = new Vector3(block.Data, 12);
11626 12007
11627 case 21: 12008 udata.change = ObjectChangeType.groupPS;
11628 Vector3 scale6 = new Vector3(block.Data, 12); 12009 updatehandler(localId, udata, this);
11629 Vector3 pos6 = new Vector3(block.Data, 0); 12010 break;
11630 12011
11631 handlerUpdatePrimScale = OnUpdatePrimScale; 12012 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11632 if (handlerUpdatePrimScale != null) 12013 udata.scale = new Vector3(block.Data, 0);
11633 {
11634 part.StoreUndoState(false);
11635 part.IgnoreUndoUpdate = true;
11636 12014
11637 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 12015 udata.change = ObjectChangeType.groupUS;
11638 handlerUpdatePrimScale(localId, scale6, this); 12016 updatehandler(localId, udata, this);
11639 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12017 break;
11640 if (handlerUpdatePrimSinglePosition != null)
11641 {
11642 handlerUpdatePrimSinglePosition(localId, pos6, this);
11643 }
11644 12018
11645 part.IgnoreUndoUpdate = false; 12019 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11646 } 12020 udata.position = new Vector3(block.Data, 0);
11647 break; 12021 udata.scale = new Vector3(block.Data, 12);
11648 12022
11649 default: 12023 udata.change = ObjectChangeType.groupPUS;
11650 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 12024 updatehandler(localId, udata, this);
11651 break; 12025 break;
12026
12027 default:
12028 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
12029 break;
12030 }
11652 } 12031 }
11653 12032
11654// for (int j = 0; j < parts.Length; j++)
11655// parts[j].IgnoreUndoUpdate = false;
11656 } 12033 }
11657 } 12034 }
11658 } 12035 }
11659
11660 return true; 12036 return true;
11661 } 12037 }
11662 12038
@@ -11717,9 +12093,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11717 public void SetChildAgentThrottle(byte[] throttles) 12093 public void SetChildAgentThrottle(byte[] throttles)
11718 { 12094 {
11719 m_udpClient.SetThrottles(throttles); 12095 m_udpClient.SetThrottles(throttles);
12096 GenericCall2 handler = OnUpdateThrottles;
12097 if (handler != null)
12098 {
12099 handler();
12100 }
11720 } 12101 }
11721 12102
11722 /// <summary> 12103 /// <summary>
12104 /// Sets the throttles from values supplied by the client
12105 /// </summary>
12106 /// <param name="throttles"></param>
12107 public void SetAgentThrottleSilent(int throttle, int setting)
12108 {
12109 m_udpClient.ForceThrottleSetting(throttle,setting);
12110 //m_udpClient.SetThrottles(throttles);
12111
12112 }
12113
12114
12115 /// <summary>
11723 /// Get the current throttles for this client as a packed byte array 12116 /// Get the current throttles for this client as a packed byte array
11724 /// </summary> 12117 /// </summary>
11725 /// <param name="multiplier">Unused</param> 12118 /// <param name="multiplier">Unused</param>
@@ -12106,7 +12499,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12106// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12499// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12107// requestID, taskID, (SourceType)sourceType, Name); 12500// requestID, taskID, (SourceType)sourceType, Name);
12108 12501
12502
12503 //Note, the bool returned from the below function is useless since it is always false.
12109 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12504 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12505
12110 } 12506 }
12111 12507
12112 /// <summary> 12508 /// <summary>
@@ -12172,7 +12568,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12172 /// <returns></returns> 12568 /// <returns></returns>
12173 private static int CalculateNumPackets(byte[] data) 12569 private static int CalculateNumPackets(byte[] data)
12174 { 12570 {
12175 const uint m_maxPacketSize = 600; 12571// const uint m_maxPacketSize = 600;
12572 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12176 int numPackets = 1; 12573 int numPackets = 1;
12177 12574
12178 if (data == null) 12575 if (data == null)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index 621e0fd..f1a1812 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
@@ -434,6 +435,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
434 if (category >= 0 && category < m_packetOutboxes.Length) 435 if (category >= 0 && category < m_packetOutboxes.Length)
435 { 436 {
436 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; 437 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
438
439 if (m_deliverPackets == false)
440 {
441 queue.Enqueue(packet);
442 return true;
443 }
444
437 TokenBucket bucket = m_throttleCategories[category]; 445 TokenBucket bucket = m_throttleCategories[category];
438 446
439 // Don't send this packet if there is already a packet waiting in the queue 447 // Don't send this packet if there is already a packet waiting in the queue
@@ -483,7 +491,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
483 /// <returns>True if any packets were sent, otherwise false</returns> 491 /// <returns>True if any packets were sent, otherwise false</returns>
484 public bool DequeueOutgoing() 492 public bool DequeueOutgoing()
485 { 493 {
486 OutgoingPacket packet; 494 if (m_deliverPackets == false) return false;
495
496 OutgoingPacket packet = null;
487 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 497 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
488 TokenBucket bucket; 498 TokenBucket bucket;
489 bool packetSent = false; 499 bool packetSent = false;
@@ -515,32 +525,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP
515 // No dequeued packet waiting to be sent, try to pull one off 525 // No dequeued packet waiting to be sent, try to pull one off
516 // this queue 526 // this queue
517 queue = m_packetOutboxes[i]; 527 queue = m_packetOutboxes[i];
518 if (queue.Dequeue(out packet)) 528 if (queue != null)
519 { 529 {
520 // A packet was pulled off the queue. See if we have 530 bool success = false;
521 // enough tokens in the bucket to send it out 531 try
522 if (bucket.RemoveTokens(packet.Buffer.DataLength))
523 { 532 {
524 // Send the packet 533 success = queue.Dequeue(out packet);
525 m_udpServer.SendPacketFinal(packet);
526 packetSent = true;
527 } 534 }
528 else 535 catch
529 { 536 {
530 // Save the dequeued packet for the next iteration 537 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
531 m_nextPackets[i] = packet;
532 } 538 }
533 539 if (success)
534 // If the queue is empty after this dequeue, fire the queue 540 {
535 // empty callback now so it has a chance to fill before we 541 // A packet was pulled off the queue. See if we have
536 // get back here 542 // enough tokens in the bucket to send it out
537 if (queue.Count == 0) 543 if (bucket.RemoveTokens(packet.Buffer.DataLength))
544 {
545 // Send the packet
546 m_udpServer.SendPacketFinal(packet);
547 packetSent = true;
548 }
549 else
550 {
551 // Save the dequeued packet for the next iteration
552 m_nextPackets[i] = packet;
553 }
554
555 // If the queue is empty after this dequeue, fire the queue
556 // empty callback now so it has a chance to fill before we
557 // get back here
558 if (queue.Count == 0)
559 emptyCategories |= CategoryToFlag(i);
560 }
561 else
562 {
563 // No packets in this queue. Fire the queue empty callback
564 // if it has not been called recently
538 emptyCategories |= CategoryToFlag(i); 565 emptyCategories |= CategoryToFlag(i);
566 }
539 } 567 }
540 else 568 else
541 { 569 {
542 // No packets in this queue. Fire the queue empty callback 570 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
543 // if it has not been called recently
544 emptyCategories |= CategoryToFlag(i); 571 emptyCategories |= CategoryToFlag(i);
545 } 572 }
546 } 573 }
@@ -649,6 +676,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
649 if (m_nextOnQueueEmpty == 0) 676 if (m_nextOnQueueEmpty == 0)
650 m_nextOnQueueEmpty = 1; 677 m_nextOnQueueEmpty = 1;
651 } 678 }
679 internal void ForceThrottleSetting(int throttle, int setting)
680 {
681 m_throttleCategories[throttle].RequestedDripRate = Math.Max(setting, LLUDPServer.MTU); ;
682 }
652 683
653 /// <summary> 684 /// <summary>
654 /// Converts a <seealso cref="ThrottleOutPacketType"/> integer to a 685 /// Converts a <seealso cref="ThrottleOutPacketType"/> integer to a
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index a7628d2..9a4abd4 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -126,7 +126,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
126 /// <summary>Handlers for incoming packets</summary> 126 /// <summary>Handlers for incoming packets</summary>
127 //PacketEventDictionary packetEvents = new PacketEventDictionary(); 127 //PacketEventDictionary packetEvents = new PacketEventDictionary();
128 /// <summary>Incoming packets that are awaiting handling</summary> 128 /// <summary>Incoming packets that are awaiting handling</summary>
129 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 129 //private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
130
131 private DoubleQueue<IncomingPacket> packetInbox = new DoubleQueue<IncomingPacket>();
130 132
131 /// <summary></summary> 133 /// <summary></summary>
132 //private UDPClientCollection m_clients = new UDPClientCollection(); 134 //private UDPClientCollection m_clients = new UDPClientCollection();
@@ -181,6 +183,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
181 /// <summary>Flag to signal when clients should send pings</summary> 183 /// <summary>Flag to signal when clients should send pings</summary>
182 protected bool m_sendPing; 184 protected bool m_sendPing;
183 185
186 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
184 private Pool<IncomingPacket> m_incomingPacketPool; 187 private Pool<IncomingPacket> m_incomingPacketPool;
185 188
186 /// <summary> 189 /// <summary>
@@ -1093,21 +1096,46 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1093 1096
1094 #region Packet to Client Mapping 1097 #region Packet to Client Mapping
1095 1098
1096 // UseCircuitCode handling 1099 // If there is already a client for this endpoint, don't process UseCircuitCode
1097 if (packet.Type == PacketType.UseCircuitCode) 1100 IClientAPI client = null;
1101 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1098 { 1102 {
1099 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1103 // UseCircuitCode handling
1100 // buffer. 1104 if (packet.Type == PacketType.UseCircuitCode)
1101 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1105 {
1106 // And if there is a UseCircuitCode pending, also drop it
1107 lock (m_pendingCache)
1108 {
1109 if (m_pendingCache.Contains(endPoint))
1110 return;
1102 1111
1103 Util.FireAndForget(HandleUseCircuitCode, array); 1112 m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60);
1113 }
1104 1114
1105 return; 1115 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1116 // buffer.
1117 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1118
1119 Util.FireAndForget(HandleUseCircuitCode, array);
1120
1121 return;
1122 }
1123 }
1124
1125 // If this is a pending connection, enqueue, don't process yet
1126 lock (m_pendingCache)
1127 {
1128 Queue<UDPPacketBuffer> queue;
1129 if (m_pendingCache.TryGetValue(endPoint, out queue))
1130 {
1131 //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type);
1132 queue.Enqueue(buffer);
1133 return;
1134 }
1106 } 1135 }
1107 1136
1108 // Determine which agent this packet came from 1137 // Determine which agent this packet came from
1109 IClientAPI client; 1138 if (client == null || !(client is LLClientView))
1110 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1111 { 1139 {
1112 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); 1140 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
1113 return; 1141 return;
@@ -1116,7 +1144,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1116 udpClient = ((LLClientView)client).UDPClient; 1144 udpClient = ((LLClientView)client).UDPClient;
1117 1145
1118 if (!udpClient.IsConnected) 1146 if (!udpClient.IsConnected)
1147 {
1148// m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName);
1119 return; 1149 return;
1150 }
1120 1151
1121 #endregion Packet to Client Mapping 1152 #endregion Packet to Client Mapping
1122 1153
@@ -1246,7 +1277,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1246 incomingPacket = new IncomingPacket((LLClientView)client, packet); 1277 incomingPacket = new IncomingPacket((LLClientView)client, packet);
1247 } 1278 }
1248 1279
1249 packetInbox.Enqueue(incomingPacket); 1280 if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
1281 incomingPacket.Packet.Type == PacketType.ChatFromViewer)
1282 packetInbox.EnqueueHigh(incomingPacket);
1283 else
1284 packetInbox.EnqueueLow(incomingPacket);
1250 } 1285 }
1251 1286
1252 #region BinaryStats 1287 #region BinaryStats
@@ -1366,6 +1401,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1366 // We only want to send initial data to new clients, not ones which are being converted from child to root. 1401 // We only want to send initial data to new clients, not ones which are being converted from child to root.
1367 if (client != null) 1402 if (client != null)
1368 client.SceneAgent.SendInitialDataToMe(); 1403 client.SceneAgent.SendInitialDataToMe();
1404
1405 // Now we know we can handle more data
1406 Thread.Sleep(200);
1407
1408 // Obtain the queue and remove it from the cache
1409 Queue<UDPPacketBuffer> queue = null;
1410
1411 lock (m_pendingCache)
1412 {
1413 if (!m_pendingCache.TryGetValue(endPoint, out queue))
1414 {
1415 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1416 return;
1417 }
1418 m_pendingCache.Remove(endPoint);
1419 }
1420
1421 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
1422
1423 // Reinject queued packets
1424 while(queue.Count > 0)
1425 {
1426 UDPPacketBuffer buf = queue.Dequeue();
1427 PacketReceived(buf);
1428 }
1429 queue = null;
1369 } 1430 }
1370 else 1431 else
1371 { 1432 {
@@ -1373,6 +1434,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1373 m_log.WarnFormat( 1434 m_log.WarnFormat(
1374 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1435 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
1375 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); 1436 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
1437 lock (m_pendingCache)
1438 m_pendingCache.Remove(endPoint);
1376 } 1439 }
1377 1440
1378 // m_log.DebugFormat( 1441 // m_log.DebugFormat(
@@ -1491,7 +1554,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1491 if (!client.SceneAgent.IsChildAgent) 1554 if (!client.SceneAgent.IsChildAgent)
1492 client.Kick("Simulator logged you out due to connection timeout"); 1555 client.Kick("Simulator logged you out due to connection timeout");
1493 1556
1494 client.CloseWithoutChecks(); 1557 client.CloseWithoutChecks(true);
1495 } 1558 }
1496 } 1559 }
1497 1560
@@ -1503,6 +1566,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1503 1566
1504 while (IsRunningInbound) 1567 while (IsRunningInbound)
1505 { 1568 {
1569 m_scene.ThreadAlive(1);
1506 try 1570 try
1507 { 1571 {
1508 IncomingPacket incomingPacket = null; 1572 IncomingPacket incomingPacket = null;
@@ -1550,6 +1614,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1550 1614
1551 while (base.IsRunningOutbound) 1615 while (base.IsRunningOutbound)
1552 { 1616 {
1617 m_scene.ThreadAlive(2);
1553 try 1618 try
1554 { 1619 {
1555 m_packetSent = false; 1620 m_packetSent = false;
@@ -1780,8 +1845,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1780 Packet packet = incomingPacket.Packet; 1845 Packet packet = incomingPacket.Packet;
1781 LLClientView client = incomingPacket.Client; 1846 LLClientView client = incomingPacket.Client;
1782 1847
1783 if (client.IsActive) 1848// if (client.IsActive)
1784 { 1849// {
1785 m_currentIncomingClient = client; 1850 m_currentIncomingClient = client;
1786 1851
1787 try 1852 try
@@ -1808,13 +1873,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1808 { 1873 {
1809 m_currentIncomingClient = null; 1874 m_currentIncomingClient = null;
1810 } 1875 }
1811 } 1876// }
1812 else 1877// else
1813 { 1878// {
1814 m_log.DebugFormat( 1879// m_log.DebugFormat(
1815 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 1880// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
1816 packet.Type, client.Name, m_scene.RegionInfo.RegionName); 1881// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
1817 } 1882// }
1818 1883
1819 IncomingPacketsProcessed++; 1884 IncomingPacketsProcessed++;
1820 } 1885 }
@@ -1826,8 +1891,116 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1826 if (!client.IsLoggingOut) 1891 if (!client.IsLoggingOut)
1827 { 1892 {
1828 client.IsLoggingOut = true; 1893 client.IsLoggingOut = true;
1829 client.Close(); 1894 client.Close(false, false);
1895 }
1896 }
1897 }
1898
1899 internal class DoubleQueue<T> where T:class
1900 {
1901 private Queue<T> m_lowQueue = new Queue<T>();
1902 private Queue<T> m_highQueue = new Queue<T>();
1903
1904 private object m_syncRoot = new object();
1905 private Semaphore m_s = new Semaphore(0, 1);
1906
1907 public DoubleQueue()
1908 {
1909 }
1910
1911 public virtual int Count
1912 {
1913 get { return m_highQueue.Count + m_lowQueue.Count; }
1914 }
1915
1916 public virtual void Enqueue(T data)
1917 {
1918 Enqueue(m_lowQueue, data);
1919 }
1920
1921 public virtual void EnqueueLow(T data)
1922 {
1923 Enqueue(m_lowQueue, data);
1924 }
1925
1926 public virtual void EnqueueHigh(T data)
1927 {
1928 Enqueue(m_highQueue, data);
1929 }
1930
1931 private void Enqueue(Queue<T> q, T data)
1932 {
1933 lock (m_syncRoot)
1934 {
1935 m_lowQueue.Enqueue(data);
1936 m_s.WaitOne(0);
1937 m_s.Release();
1938 }
1939 }
1940
1941 public virtual T Dequeue()
1942 {
1943 return Dequeue(Timeout.Infinite);
1944 }
1945
1946 public virtual T Dequeue(int tmo)
1947 {
1948 return Dequeue(TimeSpan.FromMilliseconds(tmo));
1949 }
1950
1951 public virtual T Dequeue(TimeSpan wait)
1952 {
1953 T res = null;
1954
1955 if (!Dequeue(wait, ref res))
1956 return null;
1957
1958 return res;
1959 }
1960
1961 public bool Dequeue(int timeout, ref T res)
1962 {
1963 return Dequeue(TimeSpan.FromMilliseconds(timeout), ref res);
1964 }
1965
1966 public bool Dequeue(TimeSpan wait, ref T res)
1967 {
1968 if (!m_s.WaitOne(wait))
1969 return false;
1970
1971 lock (m_syncRoot)
1972 {
1973 if (m_highQueue.Count > 0)
1974 res = m_highQueue.Dequeue();
1975 else
1976 res = m_lowQueue.Dequeue();
1977
1978 if (m_highQueue.Count == 0 && m_lowQueue.Count == 0)
1979 return true;
1980
1981 try
1982 {
1983 m_s.Release();
1984 }
1985 catch
1986 {
1987 }
1988
1989 return true;
1990 }
1991 }
1992
1993 public virtual void Clear()
1994 {
1995
1996 lock (m_syncRoot)
1997 {
1998 // Make sure sem count is 0
1999 m_s.WaitOne(0);
2000
2001 m_lowQueue.Clear();
2002 m_highQueue.Clear();
1830 } 2003 }
1831 } 2004 }
1832 } 2005 }
1833} \ No newline at end of file 2006}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index f143c32..7035e38 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -114,10 +114,6 @@ namespace OpenMetaverse
114 const int SIO_UDP_CONNRESET = -1744830452; 114 const int SIO_UDP_CONNRESET = -1744830452;
115 115
116 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort); 116 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort);
117
118 m_log.DebugFormat(
119 "[UDPBASE]: Binding UDP listener using internal IP address config {0}:{1}",
120 ipep.Address, ipep.Port);
121 117
122 m_udpSocket = new Socket( 118 m_udpSocket = new Socket(
123 AddressFamily.InterNetwork, 119 AddressFamily.InterNetwork,