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.cs1475
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs69
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs219
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs4
5 files changed, 1185 insertions, 585 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
index afbe56b..3995620 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
@@ -234,6 +234,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
234 m_stopPacket = TexturePacketCount(); 234 m_stopPacket = TexturePacketCount();
235 } 235 }
236 236
237 //Give them at least two packets, to play nice with some broken viewers (SL also behaves this way)
238 if (m_stopPacket == 1 && m_layers[0].End > FIRST_PACKET_SIZE) m_stopPacket++;
239
237 m_currentPacket = StartPacket; 240 m_currentPacket = StartPacket;
238 } 241 }
239 } 242 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 504df40..465d76d 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.State : 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.State : 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.State : 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,24 +3587,25 @@ 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.State);
3523 } 3609 }
3524 3610
3525 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) 3611 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
@@ -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,8 +3629,8 @@ 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.State);
3548 } 3634 }
3549 3635
3550 public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) 3636 public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs)
@@ -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)
@@ -6633,6 +6806,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6633 #endregion 6806 #endregion
6634 6807
6635 m_udpClient.SetThrottles(atpack.Throttle.Throttles); 6808 m_udpClient.SetThrottles(atpack.Throttle.Throttles);
6809 GenericCall2 handler = OnUpdateThrottles;
6810 if (handler != null)
6811 {
6812 handler();
6813 }
6636 return true; 6814 return true;
6637 } 6815 }
6638 6816
@@ -7034,10 +7212,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7034 // 46,47,48 are special positions within the packet 7212 // 46,47,48 are special positions within the packet
7035 // This may change so perhaps we need a better way 7213 // This may change so perhaps we need a better way
7036 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) 7214 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
7037 bool UsePhysics = (data[46] != 0) ? true : false; 7215 /*
7038 bool IsTemporary = (data[47] != 0) ? true : false; 7216 bool UsePhysics = (data[46] != 0) ? true : false;
7039 bool IsPhantom = (data[48] != 0) ? true : false; 7217 bool IsTemporary = (data[47] != 0) ? true : false;
7040 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this); 7218 bool IsPhantom = (data[48] != 0) ? true : false;
7219 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this);
7220 */
7221 bool UsePhysics = flags.AgentData.UsePhysics;
7222 bool IsPhantom = flags.AgentData.IsPhantom;
7223 bool IsTemporary = flags.AgentData.IsTemporary;
7224 ObjectFlagUpdatePacket.ExtraPhysicsBlock[] blocks = flags.ExtraPhysics;
7225 ExtraPhysicsData physdata = new ExtraPhysicsData();
7226
7227 if (blocks == null || blocks.Length == 0)
7228 {
7229 physdata.PhysShapeType = PhysShapeType.invalid;
7230 }
7231 else
7232 {
7233 ObjectFlagUpdatePacket.ExtraPhysicsBlock phsblock = blocks[0];
7234 physdata.PhysShapeType = (PhysShapeType)phsblock.PhysicsShapeType;
7235 physdata.Bounce = phsblock.Restitution;
7236 physdata.Density = phsblock.Density;
7237 physdata.Friction = phsblock.Friction;
7238 physdata.GravitationModifier = phsblock.GravityMultiplier;
7239 }
7240
7241 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
7041 } 7242 }
7042 return true; 7243 return true;
7043 } 7244 }
@@ -7620,6 +7821,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7620 // surrounding scene 7821 // surrounding scene
7621 if ((ImageType)block.Type == ImageType.Baked) 7822 if ((ImageType)block.Type == ImageType.Baked)
7622 args.Priority *= 2.0f; 7823 args.Priority *= 2.0f;
7824 int wearableout = 0;
7623 7825
7624 ImageManager.EnqueueReq(args); 7826 ImageManager.EnqueueReq(args);
7625 } 7827 }
@@ -8638,16 +8840,61 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8638 8840
8639 #region Parcel related packets 8841 #region Parcel related packets
8640 8842
8843 // acumulate several HandleRegionHandleRequest consecutive overlaping requests
8844 // to be done with minimal resources as possible
8845 // variables temporary here while in test
8846
8847 Queue<UUID> RegionHandleRequests = new Queue<UUID>();
8848 bool RegionHandleRequestsInService = false;
8849
8641 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack) 8850 private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack)
8642 { 8851 {
8643 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; 8852 UUID currentUUID;
8644 8853
8645 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; 8854 RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest;
8646 if (handlerRegionHandleRequest != null) 8855
8856 if (handlerRegionHandleRequest == null)
8857 return true;
8858
8859 RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
8860
8861 lock (RegionHandleRequests)
8647 { 8862 {
8648 handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); 8863 if (RegionHandleRequestsInService)
8864 {
8865 // we are already busy doing a previus request
8866 // so enqueue it
8867 RegionHandleRequests.Enqueue(rhrPack.RequestBlock.RegionID);
8868 return true;
8869 }
8870
8871 // else do it
8872 currentUUID = rhrPack.RequestBlock.RegionID;
8873 RegionHandleRequestsInService = true;
8649 } 8874 }
8650 return true; 8875
8876 while (true)
8877 {
8878 handlerRegionHandleRequest(this, currentUUID);
8879
8880 lock (RegionHandleRequests)
8881 {
8882 // exit condition, nothing to do or closed
8883 // current code seems to assume we may loose the handler at anytime,
8884 // so keep checking it
8885 handlerRegionHandleRequest = OnRegionHandleRequest;
8886
8887 if (RegionHandleRequests.Count == 0 || !IsActive || handlerRegionHandleRequest == null)
8888 {
8889 RegionHandleRequests.Clear();
8890 RegionHandleRequestsInService = false;
8891 return true;
8892 }
8893 currentUUID = RegionHandleRequests.Dequeue();
8894 }
8895 }
8896
8897 return true; // actually unreached
8651 } 8898 }
8652 8899
8653 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack) 8900 private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack)
@@ -9903,7 +10150,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9903 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 10150 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9904 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 10151 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9905 UpdateMuteListEntry.MuteData.MuteType, 10152 UpdateMuteListEntry.MuteData.MuteType,
9906 UpdateMuteListEntry.AgentData.AgentID); 10153 UpdateMuteListEntry.MuteData.MuteFlags);
9907 return true; 10154 return true;
9908 } 10155 }
9909 return false; 10156 return false;
@@ -9918,8 +10165,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9918 { 10165 {
9919 handlerRemoveMuteListEntry(this, 10166 handlerRemoveMuteListEntry(this,
9920 RemoveMuteListEntry.MuteData.MuteID, 10167 RemoveMuteListEntry.MuteData.MuteID,
9921 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 10168 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9922 RemoveMuteListEntry.AgentData.AgentID);
9923 return true; 10169 return true;
9924 } 10170 }
9925 return false; 10171 return false;
@@ -9963,10 +10209,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9963 return false; 10209 return false;
9964 } 10210 }
9965 10211
10212 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10213 {
10214 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10215 (ChangeInventoryItemFlagsPacket)packet;
10216 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10217 if (handlerChangeInventoryItemFlags != null)
10218 {
10219 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10220 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10221 return true;
10222 }
10223 return false;
10224 }
10225
9966 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10226 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9967 { 10227 {
9968 return true; 10228 return true;
9969 } 10229 }
10230
10231 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10232 {
10233 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10234
10235 #region Packet Session and User Check
10236 if (m_checkPackets)
10237 {
10238 if (packet.AgentData.SessionID != SessionId ||
10239 packet.AgentData.AgentID != AgentId)
10240 return true;
10241 }
10242 #endregion
10243 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10244 List<InventoryItemBase> items = new List<InventoryItemBase>();
10245 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10246 {
10247 InventoryItemBase b = new InventoryItemBase();
10248 b.ID = n.OldItemID;
10249 b.Folder = n.OldFolderID;
10250 items.Add(b);
10251 }
10252
10253 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10254 if (handlerMoveItemsAndLeaveCopy != null)
10255 {
10256 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10257 }
10258
10259 return true;
10260 }
9970 10261
9971 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10262 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9972 { 10263 {
@@ -10393,6 +10684,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10393 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10684 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10394 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10685 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10395 10686
10687 Scene scene = (Scene)m_scene;
10688 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10689 {
10690 ScenePresence p;
10691 if (scene.TryGetScenePresence(sender.AgentId, out p))
10692 {
10693 if (p.GodLevel >= 200)
10694 {
10695 groupProfileReply.GroupData.OpenEnrollment = true;
10696 groupProfileReply.GroupData.MembershipFee = 0;
10697 }
10698 }
10699 }
10700
10396 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10701 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10397 } 10702 }
10398 return true; 10703 return true;
@@ -10966,11 +11271,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10966 11271
10967 StartLure handlerStartLure = OnStartLure; 11272 StartLure handlerStartLure = OnStartLure;
10968 if (handlerStartLure != null) 11273 if (handlerStartLure != null)
10969 handlerStartLure(startLureRequest.Info.LureType, 11274 {
10970 Utils.BytesToString( 11275 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10971 startLureRequest.Info.Message), 11276 {
10972 startLureRequest.TargetData[0].TargetID, 11277 handlerStartLure(startLureRequest.Info.LureType,
10973 this); 11278 Utils.BytesToString(
11279 startLureRequest.Info.Message),
11280 startLureRequest.TargetData[i].TargetID,
11281 this);
11282 }
11283 }
10974 return true; 11284 return true;
10975 } 11285 }
10976 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11286 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -11084,10 +11394,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11084 } 11394 }
11085 #endregion 11395 #endregion
11086 11396
11087 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11397 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11088 if (handlerClassifiedGodDelete != null) 11398 if (handlerClassifiedGodDelete != null)
11089 handlerClassifiedGodDelete( 11399 handlerClassifiedGodDelete(
11090 classifiedGodDelete.Data.ClassifiedID, 11400 classifiedGodDelete.Data.ClassifiedID,
11401 classifiedGodDelete.Data.QueryID,
11091 this); 11402 this);
11092 return true; 11403 return true;
11093 } 11404 }
@@ -11400,6 +11711,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11400 11711
11401 if (cachedtex.AgentData.SessionID != SessionId) 11712 if (cachedtex.AgentData.SessionID != SessionId)
11402 return false; 11713 return false;
11714
11403 11715
11404 // TODO: don't create new blocks if recycling an old packet 11716 // TODO: don't create new blocks if recycling an old packet
11405 cachedresp.AgentData.AgentID = AgentId; 11717 cachedresp.AgentData.AgentID = AgentId;
@@ -11409,14 +11721,140 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11409 cachedresp.WearableData = 11721 cachedresp.WearableData =
11410 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length]; 11722 new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
11411 11723
11412 for (int i = 0; i < cachedtex.WearableData.Length; i++) 11724 //IAvatarFactoryModule fac = m_scene.RequestModuleInterface<IAvatarFactoryModule>();
11725 // var item = fac.GetBakedTextureFaces(AgentId);
11726 //WearableCacheItem[] items = fac.GetCachedItems(AgentId);
11727
11728 IAssetService cache = m_scene.AssetService;
11729 IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
11730 //bakedTextureModule = null;
11731 int maxWearablesLoop = cachedtex.WearableData.Length;
11732 if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES)
11733 maxWearablesLoop = AvatarWearable.MAX_WEARABLES;
11734
11735 if (bakedTextureModule != null && cache != null)
11413 { 11736 {
11414 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); 11737 // 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
11415 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; 11738
11416 cachedresp.WearableData[i].TextureID = UUID.Zero; 11739 WearableCacheItem[] cacheItems = null;
11417 cachedresp.WearableData[i].HostName = new byte[0]; 11740 ScenePresence p = m_scene.GetScenePresence(AgentId);
11741 if (p.Appearance != null)
11742 if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty)
11743 {
11744 try
11745 {
11746 cacheItems = bakedTextureModule.Get(AgentId);
11747 p.Appearance.WearableCacheItems = cacheItems;
11748 p.Appearance.WearableCacheItemsDirty = false;
11749 }
11750
11751 /*
11752 * The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception!
11753 *
11754 catch (System.Net.Sockets.SocketException)
11755 {
11756 cacheItems = null;
11757 }
11758 catch (WebException)
11759 {
11760 cacheItems = null;
11761 }
11762 catch (InvalidOperationException)
11763 {
11764 cacheItems = null;
11765 } */
11766 catch (Exception)
11767 {
11768 cacheItems = null;
11769 }
11770
11771 }
11772 else if (p.Appearance.WearableCacheItems != null)
11773 {
11774 cacheItems = p.Appearance.WearableCacheItems;
11775 }
11776
11777 if (cache != null && cacheItems != null)
11778 {
11779 foreach (WearableCacheItem item in cacheItems)
11780 {
11781
11782 if (cache.GetCached(item.TextureID.ToString()) == null)
11783 {
11784 item.TextureAsset.Temporary = true;
11785 cache.Store(item.TextureAsset);
11786 }
11787
11788
11789 }
11790 }
11791
11792 if (cacheItems != null)
11793 {
11794
11795 for (int i = 0; i < maxWearablesLoop; i++)
11796 {
11797 WearableCacheItem item =
11798 WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems);
11799
11800 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11801 cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex;
11802 cachedresp.WearableData[i].HostName = new byte[0];
11803 if (item != null && cachedtex.WearableData[i].ID == item.CacheId)
11804 {
11805
11806 cachedresp.WearableData[i].TextureID = item.TextureID;
11807 }
11808 else
11809 {
11810 cachedresp.WearableData[i].TextureID = UUID.Zero;
11811 }
11812 }
11813 }
11814 else
11815 {
11816 for (int i = 0; i < maxWearablesLoop; i++)
11817 {
11818 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11819 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11820 cachedresp.WearableData[i].TextureID = UUID.Zero;
11821 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11822 cachedresp.WearableData[i].HostName = new byte[0];
11823 }
11824 }
11418 } 11825 }
11826 else
11827 {
11828 if (cache == null)
11829 {
11830 for (int i = 0; i < maxWearablesLoop; i++)
11831 {
11832 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11833 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11834 cachedresp.WearableData[i].TextureID = UUID.Zero;
11835 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11836 cachedresp.WearableData[i].HostName = new byte[0];
11837 }
11838 }
11839 else
11840 {
11841 for (int i = 0; i < maxWearablesLoop; i++)
11842 {
11843 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
11844 cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
11419 11845
11846
11847
11848 if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null)
11849 cachedresp.WearableData[i].TextureID = UUID.Zero;
11850 //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11851 else
11852 cachedresp.WearableData[i].TextureID = UUID.Zero;
11853 // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
11854 cachedresp.WearableData[i].HostName = new byte[0];
11855 }
11856 }
11857 }
11420 cachedresp.Header.Zerocoded = true; 11858 cachedresp.Header.Zerocoded = true;
11421 OutPacket(cachedresp, ThrottleOutPacketType.Task); 11859 OutPacket(cachedresp, ThrottleOutPacketType.Task);
11422 11860
@@ -11453,209 +11891,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11453 } 11891 }
11454 else 11892 else
11455 { 11893 {
11456// m_log.DebugFormat( 11894 ClientChangeObject updatehandler = onClientChangeObject;
11457// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11458// i, block.Type, part.Name, part.LocalId);
11459 11895
11460// // Do this once since fetch parts creates a new array. 11896 if (updatehandler != null)
11461// SceneObjectPart[] parts = part.ParentGroup.Parts; 11897 {
11462// for (int j = 0; j < parts.Length; j++) 11898 ObjectChangeData udata = new ObjectChangeData();
11463// {
11464// part.StoreUndoState();
11465// parts[j].IgnoreUndoUpdate = true;
11466// }
11467 11899
11468 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11900 /*ubit from ll JIRA:
11901 * 0x01 position
11902 * 0x02 rotation
11903 * 0x04 scale
11904
11905 * 0x08 LINK_SET
11906 * 0x10 UNIFORM for scale
11907 */
11469 11908
11470 switch (block.Type) 11909 // translate to internal changes
11471 { 11910 // not all cases .. just the ones older code did
11472 case 1:
11473 Vector3 pos1 = new Vector3(block.Data, 0);
11474 11911
11475 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11912 switch (block.Type)
11476 if (handlerUpdatePrimSinglePosition != null) 11913 {
11477 { 11914 case 1: //change position sp
11478 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11915 udata.position = new Vector3(block.Data, 0);
11479 handlerUpdatePrimSinglePosition(localId, pos1, this);
11480 }
11481 break;
11482 11916
11483 case 2: 11917 udata.change = ObjectChangeType.primP;
11484 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11918 updatehandler(localId, udata, this);
11919 break;
11485 11920
11486 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11921 case 2: // rotation sp
11487 if (handlerUpdatePrimSingleRotation != null) 11922 udata.rotation = new Quaternion(block.Data, 0, true);
11488 {
11489 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11490 handlerUpdatePrimSingleRotation(localId, rot1, this);
11491 }
11492 break;
11493 11923
11494 case 3: 11924 udata.change = ObjectChangeType.primR;
11495 Vector3 rotPos = new Vector3(block.Data, 0); 11925 updatehandler(localId, udata, this);
11496 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11926 break;
11497 11927
11498 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11928 case 3: // position plus rotation
11499 if (handlerUpdatePrimSingleRotationPosition != null) 11929 udata.position = new Vector3(block.Data, 0);
11500 { 11930 udata.rotation = new Quaternion(block.Data, 12, true);
11501 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11502 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11503 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11504 }
11505 break;
11506 11931
11507 case 4: 11932 udata.change = ObjectChangeType.primPR;
11508 case 20: 11933 updatehandler(localId, udata, this);
11509 Vector3 scale4 = new Vector3(block.Data, 0); 11934 break;
11510 11935
11511 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11936 case 4: // scale sp
11512 if (handlerUpdatePrimScale != null) 11937 udata.scale = new Vector3(block.Data, 0);
11513 { 11938 udata.change = ObjectChangeType.primS;
11514 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11515 handlerUpdatePrimScale(localId, scale4, this);
11516 }
11517 break;
11518 11939
11519 case 5: 11940 updatehandler(localId, udata, this);
11520 Vector3 scale1 = new Vector3(block.Data, 12); 11941 break;
11521 Vector3 pos11 = new Vector3(block.Data, 0);
11522 11942
11523 handlerUpdatePrimScale = OnUpdatePrimScale; 11943 case 0x14: // uniform scale sp
11524 if (handlerUpdatePrimScale != null) 11944 udata.scale = new Vector3(block.Data, 0);
11525 {
11526 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11527 handlerUpdatePrimScale(localId, scale1, this);
11528 11945
11529 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11946 udata.change = ObjectChangeType.primUS;
11530 if (handlerUpdatePrimSinglePosition != null) 11947 updatehandler(localId, udata, this);
11531 { 11948 break;
11532 handlerUpdatePrimSinglePosition(localId, pos11, this);
11533 }
11534 }
11535 break;
11536 11949
11537 case 9: 11950 case 5: // scale and position sp
11538 Vector3 pos2 = new Vector3(block.Data, 0); 11951 udata.position = new Vector3(block.Data, 0);
11952 udata.scale = new Vector3(block.Data, 12);
11539 11953
11540 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11954 udata.change = ObjectChangeType.primPS;
11955 updatehandler(localId, udata, this);
11956 break;
11541 11957
11542 if (handlerUpdateVector != null) 11958 case 0x15: //uniform scale and position
11543 { 11959 udata.position = new Vector3(block.Data, 0);
11544 handlerUpdateVector(localId, pos2, this); 11960 udata.scale = new Vector3(block.Data, 12);
11545 }
11546 break;
11547 11961
11548 case 10: 11962 udata.change = ObjectChangeType.primPUS;
11549 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11963 updatehandler(localId, udata, this);
11964 break;
11550 11965
11551 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11966 // now group related (bit 4)
11552 if (handlerUpdatePrimRotation != null) 11967 case 9: //( 8 + 1 )group position
11553 { 11968 udata.position = new Vector3(block.Data, 0);
11554 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11555 handlerUpdatePrimRotation(localId, rot3, this);
11556 }
11557 break;
11558 11969
11559 case 11: 11970 udata.change = ObjectChangeType.groupP;
11560 Vector3 pos3 = new Vector3(block.Data, 0); 11971 updatehandler(localId, udata, this);
11561 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11972 break;
11562 11973
11563 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11974 case 0x0A: // (8 + 2) group rotation
11564 if (handlerUpdatePrimGroupRotation != null) 11975 udata.rotation = new Quaternion(block.Data, 0, true);
11565 {
11566 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11567 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11568 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11569 }
11570 break;
11571 case 12:
11572 case 28:
11573 Vector3 scale7 = new Vector3(block.Data, 0);
11574 11976
11575 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11977 udata.change = ObjectChangeType.groupR;
11576 if (handlerUpdatePrimGroupScale != null) 11978 updatehandler(localId, udata, this);
11577 { 11979 break;
11578 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11579 handlerUpdatePrimGroupScale(localId, scale7, this);
11580 }
11581 break;
11582 11980
11583 case 13: 11981 case 0x0B: //( 8 + 2 + 1) group rotation and position
11584 Vector3 scale2 = new Vector3(block.Data, 12); 11982 udata.position = new Vector3(block.Data, 0);
11585 Vector3 pos4 = new Vector3(block.Data, 0); 11983 udata.rotation = new Quaternion(block.Data, 12, true);
11586 11984
11587 handlerUpdatePrimScale = OnUpdatePrimScale; 11985 udata.change = ObjectChangeType.groupPR;
11588 if (handlerUpdatePrimScale != null) 11986 updatehandler(localId, udata, this);
11589 { 11987 break;
11590 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11591 handlerUpdatePrimScale(localId, scale2, this);
11592 11988
11593 // Change the position based on scale (for bug number 246) 11989 case 0x0C: // (8 + 4) group scale
11594 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11990 // only afects root prim and only sent by viewer editor object tab scaling
11595 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11991 // mouse edition only allows uniform scaling
11596 if (handlerUpdatePrimSinglePosition != null) 11992 // SL MAY CHANGE THIS in viewers
11597 {
11598 handlerUpdatePrimSinglePosition(localId, pos4, this);
11599 }
11600 }
11601 break;
11602 11993
11603 case 29: 11994 udata.scale = new Vector3(block.Data, 0);
11604 Vector3 scale5 = new Vector3(block.Data, 12);
11605 Vector3 pos5 = new Vector3(block.Data, 0);
11606 11995
11607 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11996 udata.change = ObjectChangeType.groupS;
11608 if (handlerUpdatePrimGroupScale != null) 11997 updatehandler(localId, udata, this);
11609 {
11610 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11611 part.StoreUndoState(true);
11612 part.IgnoreUndoUpdate = true;
11613 handlerUpdatePrimGroupScale(localId, scale5, this);
11614 handlerUpdateVector = OnUpdatePrimGroupPosition;
11615 11998
11616 if (handlerUpdateVector != null) 11999 break;
11617 {
11618 handlerUpdateVector(localId, pos5, this);
11619 }
11620 12000
11621 part.IgnoreUndoUpdate = false; 12001 case 0x0D: //(8 + 4 + 1) group scale and position
11622 } 12002 // exception as above
11623 12003
11624 break; 12004 udata.position = new Vector3(block.Data, 0);
12005 udata.scale = new Vector3(block.Data, 12);
11625 12006
11626 case 21: 12007 udata.change = ObjectChangeType.groupPS;
11627 Vector3 scale6 = new Vector3(block.Data, 12); 12008 updatehandler(localId, udata, this);
11628 Vector3 pos6 = new Vector3(block.Data, 0); 12009 break;
11629 12010
11630 handlerUpdatePrimScale = OnUpdatePrimScale; 12011 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11631 if (handlerUpdatePrimScale != null) 12012 udata.scale = new Vector3(block.Data, 0);
11632 {
11633 part.StoreUndoState(false);
11634 part.IgnoreUndoUpdate = true;
11635 12013
11636 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 12014 udata.change = ObjectChangeType.groupUS;
11637 handlerUpdatePrimScale(localId, scale6, this); 12015 updatehandler(localId, udata, this);
11638 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 12016 break;
11639 if (handlerUpdatePrimSinglePosition != null)
11640 {
11641 handlerUpdatePrimSinglePosition(localId, pos6, this);
11642 }
11643 12017
11644 part.IgnoreUndoUpdate = false; 12018 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11645 } 12019 udata.position = new Vector3(block.Data, 0);
11646 break; 12020 udata.scale = new Vector3(block.Data, 12);
11647 12021
11648 default: 12022 udata.change = ObjectChangeType.groupPUS;
11649 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 12023 updatehandler(localId, udata, this);
11650 break; 12024 break;
12025
12026 default:
12027 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
12028 break;
12029 }
11651 } 12030 }
11652 12031
11653// for (int j = 0; j < parts.Length; j++)
11654// parts[j].IgnoreUndoUpdate = false;
11655 } 12032 }
11656 } 12033 }
11657 } 12034 }
11658
11659 return true; 12035 return true;
11660 } 12036 }
11661 12037
@@ -11716,9 +12092,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11716 public void SetChildAgentThrottle(byte[] throttles) 12092 public void SetChildAgentThrottle(byte[] throttles)
11717 { 12093 {
11718 m_udpClient.SetThrottles(throttles); 12094 m_udpClient.SetThrottles(throttles);
12095 GenericCall2 handler = OnUpdateThrottles;
12096 if (handler != null)
12097 {
12098 handler();
12099 }
11719 } 12100 }
11720 12101
11721 /// <summary> 12102 /// <summary>
12103 /// Sets the throttles from values supplied by the client
12104 /// </summary>
12105 /// <param name="throttles"></param>
12106 public void SetAgentThrottleSilent(int throttle, int setting)
12107 {
12108 m_udpClient.ForceThrottleSetting(throttle,setting);
12109 //m_udpClient.SetThrottles(throttles);
12110
12111 }
12112
12113
12114 /// <summary>
11722 /// Get the current throttles for this client as a packed byte array 12115 /// Get the current throttles for this client as a packed byte array
11723 /// </summary> 12116 /// </summary>
11724 /// <param name="multiplier">Unused</param> 12117 /// <param name="multiplier">Unused</param>
@@ -12105,7 +12498,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12105// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12498// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12106// requestID, taskID, (SourceType)sourceType, Name); 12499// requestID, taskID, (SourceType)sourceType, Name);
12107 12500
12501
12502 //Note, the bool returned from the below function is useless since it is always false.
12108 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12503 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12504
12109 } 12505 }
12110 12506
12111 /// <summary> 12507 /// <summary>
@@ -12171,7 +12567,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12171 /// <returns></returns> 12567 /// <returns></returns>
12172 private static int CalculateNumPackets(byte[] data) 12568 private static int CalculateNumPackets(byte[] data)
12173 { 12569 {
12174 const uint m_maxPacketSize = 600; 12570// const uint m_maxPacketSize = 600;
12571 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12175 int numPackets = 1; 12572 int numPackets = 1;
12176 12573
12177 if (data == null) 12574 if (data == null)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index 8963756..f675377 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -158,6 +158,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
158 158
159 private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC 159 private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC
160 private int m_maxRTO = 60000; 160 private int m_maxRTO = 60000;
161 public bool m_deliverPackets = true;
161 162
162 /// <summary> 163 /// <summary>
163 /// Default constructor 164 /// Default constructor
@@ -440,6 +441,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
440 if (category >= 0 && category < m_packetOutboxes.Length) 441 if (category >= 0 && category < m_packetOutboxes.Length)
441 { 442 {
442 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; 443 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
444
445 if (m_deliverPackets == false)
446 {
447 queue.Enqueue(packet);
448 return true;
449 }
450
443 TokenBucket bucket = m_throttleCategories[category]; 451 TokenBucket bucket = m_throttleCategories[category];
444 452
445 // Don't send this packet if there is already a packet waiting in the queue 453 // Don't send this packet if there is already a packet waiting in the queue
@@ -489,7 +497,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
489 /// <returns>True if any packets were sent, otherwise false</returns> 497 /// <returns>True if any packets were sent, otherwise false</returns>
490 public bool DequeueOutgoing() 498 public bool DequeueOutgoing()
491 { 499 {
492 OutgoingPacket packet; 500 if (m_deliverPackets == false) return false;
501
502 OutgoingPacket packet = null;
493 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 503 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
494 TokenBucket bucket; 504 TokenBucket bucket;
495 bool packetSent = false; 505 bool packetSent = false;
@@ -521,32 +531,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP
521 // No dequeued packet waiting to be sent, try to pull one off 531 // No dequeued packet waiting to be sent, try to pull one off
522 // this queue 532 // this queue
523 queue = m_packetOutboxes[i]; 533 queue = m_packetOutboxes[i];
524 if (queue.Dequeue(out packet)) 534 if (queue != null)
525 { 535 {
526 // A packet was pulled off the queue. See if we have 536 bool success = false;
527 // enough tokens in the bucket to send it out 537 try
528 if (bucket.RemoveTokens(packet.Buffer.DataLength))
529 { 538 {
530 // Send the packet 539 success = queue.Dequeue(out packet);
531 m_udpServer.SendPacketFinal(packet);
532 packetSent = true;
533 } 540 }
534 else 541 catch
535 { 542 {
536 // Save the dequeued packet for the next iteration 543 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
537 m_nextPackets[i] = packet;
538 } 544 }
539 545 if (success)
540 // If the queue is empty after this dequeue, fire the queue 546 {
541 // empty callback now so it has a chance to fill before we 547 // A packet was pulled off the queue. See if we have
542 // get back here 548 // enough tokens in the bucket to send it out
543 if (queue.Count == 0) 549 if (bucket.RemoveTokens(packet.Buffer.DataLength))
550 {
551 // Send the packet
552 m_udpServer.SendPacketFinal(packet);
553 packetSent = true;
554 }
555 else
556 {
557 // Save the dequeued packet for the next iteration
558 m_nextPackets[i] = packet;
559 }
560
561 // If the queue is empty after this dequeue, fire the queue
562 // empty callback now so it has a chance to fill before we
563 // get back here
564 if (queue.Count == 0)
565 emptyCategories |= CategoryToFlag(i);
566 }
567 else
568 {
569 // No packets in this queue. Fire the queue empty callback
570 // if it has not been called recently
544 emptyCategories |= CategoryToFlag(i); 571 emptyCategories |= CategoryToFlag(i);
572 }
545 } 573 }
546 else 574 else
547 { 575 {
548 // No packets in this queue. Fire the queue empty callback 576 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
549 // if it has not been called recently
550 emptyCategories |= CategoryToFlag(i); 577 emptyCategories |= CategoryToFlag(i);
551 } 578 }
552 } 579 }
@@ -655,6 +682,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
655 if (m_nextOnQueueEmpty == 0) 682 if (m_nextOnQueueEmpty == 0)
656 m_nextOnQueueEmpty = 1; 683 m_nextOnQueueEmpty = 1;
657 } 684 }
685 internal void ForceThrottleSetting(int throttle, int setting)
686 {
687 m_throttleCategories[throttle].RequestedDripRate = Math.Max(setting, LLUDPServer.MTU); ;
688 }
658 689
659 /// <summary> 690 /// <summary>
660 /// Converts a <seealso cref="ThrottleOutPacketType"/> integer to a 691 /// Converts a <seealso cref="ThrottleOutPacketType"/> integer to a
@@ -704,4 +735,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP
704 } 735 }
705 } 736 }
706 } 737 }
707} \ No newline at end of file 738}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index a7628d2..9a4abd4 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -126,7 +126,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
126 /// <summary>Handlers for incoming packets</summary> 126 /// <summary>Handlers for incoming packets</summary>
127 //PacketEventDictionary packetEvents = new PacketEventDictionary(); 127 //PacketEventDictionary packetEvents = new PacketEventDictionary();
128 /// <summary>Incoming packets that are awaiting handling</summary> 128 /// <summary>Incoming packets that are awaiting handling</summary>
129 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 129 //private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
130
131 private DoubleQueue<IncomingPacket> packetInbox = new DoubleQueue<IncomingPacket>();
130 132
131 /// <summary></summary> 133 /// <summary></summary>
132 //private UDPClientCollection m_clients = new UDPClientCollection(); 134 //private UDPClientCollection m_clients = new UDPClientCollection();
@@ -181,6 +183,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
181 /// <summary>Flag to signal when clients should send pings</summary> 183 /// <summary>Flag to signal when clients should send pings</summary>
182 protected bool m_sendPing; 184 protected bool m_sendPing;
183 185
186 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
184 private Pool<IncomingPacket> m_incomingPacketPool; 187 private Pool<IncomingPacket> m_incomingPacketPool;
185 188
186 /// <summary> 189 /// <summary>
@@ -1093,21 +1096,46 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1093 1096
1094 #region Packet to Client Mapping 1097 #region Packet to Client Mapping
1095 1098
1096 // UseCircuitCode handling 1099 // If there is already a client for this endpoint, don't process UseCircuitCode
1097 if (packet.Type == PacketType.UseCircuitCode) 1100 IClientAPI client = null;
1101 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1098 { 1102 {
1099 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1103 // UseCircuitCode handling
1100 // buffer. 1104 if (packet.Type == PacketType.UseCircuitCode)
1101 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1105 {
1106 // And if there is a UseCircuitCode pending, also drop it
1107 lock (m_pendingCache)
1108 {
1109 if (m_pendingCache.Contains(endPoint))
1110 return;
1102 1111
1103 Util.FireAndForget(HandleUseCircuitCode, array); 1112 m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60);
1113 }
1104 1114
1105 return; 1115 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1116 // buffer.
1117 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1118
1119 Util.FireAndForget(HandleUseCircuitCode, array);
1120
1121 return;
1122 }
1123 }
1124
1125 // If this is a pending connection, enqueue, don't process yet
1126 lock (m_pendingCache)
1127 {
1128 Queue<UDPPacketBuffer> queue;
1129 if (m_pendingCache.TryGetValue(endPoint, out queue))
1130 {
1131 //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type);
1132 queue.Enqueue(buffer);
1133 return;
1134 }
1106 } 1135 }
1107 1136
1108 // Determine which agent this packet came from 1137 // Determine which agent this packet came from
1109 IClientAPI client; 1138 if (client == null || !(client is LLClientView))
1110 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1111 { 1139 {
1112 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); 1140 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
1113 return; 1141 return;
@@ -1116,7 +1144,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1116 udpClient = ((LLClientView)client).UDPClient; 1144 udpClient = ((LLClientView)client).UDPClient;
1117 1145
1118 if (!udpClient.IsConnected) 1146 if (!udpClient.IsConnected)
1147 {
1148// m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName);
1119 return; 1149 return;
1150 }
1120 1151
1121 #endregion Packet to Client Mapping 1152 #endregion Packet to Client Mapping
1122 1153
@@ -1246,7 +1277,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1246 incomingPacket = new IncomingPacket((LLClientView)client, packet); 1277 incomingPacket = new IncomingPacket((LLClientView)client, packet);
1247 } 1278 }
1248 1279
1249 packetInbox.Enqueue(incomingPacket); 1280 if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
1281 incomingPacket.Packet.Type == PacketType.ChatFromViewer)
1282 packetInbox.EnqueueHigh(incomingPacket);
1283 else
1284 packetInbox.EnqueueLow(incomingPacket);
1250 } 1285 }
1251 1286
1252 #region BinaryStats 1287 #region BinaryStats
@@ -1366,6 +1401,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1366 // We only want to send initial data to new clients, not ones which are being converted from child to root. 1401 // We only want to send initial data to new clients, not ones which are being converted from child to root.
1367 if (client != null) 1402 if (client != null)
1368 client.SceneAgent.SendInitialDataToMe(); 1403 client.SceneAgent.SendInitialDataToMe();
1404
1405 // Now we know we can handle more data
1406 Thread.Sleep(200);
1407
1408 // Obtain the queue and remove it from the cache
1409 Queue<UDPPacketBuffer> queue = null;
1410
1411 lock (m_pendingCache)
1412 {
1413 if (!m_pendingCache.TryGetValue(endPoint, out queue))
1414 {
1415 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1416 return;
1417 }
1418 m_pendingCache.Remove(endPoint);
1419 }
1420
1421 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
1422
1423 // Reinject queued packets
1424 while(queue.Count > 0)
1425 {
1426 UDPPacketBuffer buf = queue.Dequeue();
1427 PacketReceived(buf);
1428 }
1429 queue = null;
1369 } 1430 }
1370 else 1431 else
1371 { 1432 {
@@ -1373,6 +1434,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1373 m_log.WarnFormat( 1434 m_log.WarnFormat(
1374 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1435 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
1375 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); 1436 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
1437 lock (m_pendingCache)
1438 m_pendingCache.Remove(endPoint);
1376 } 1439 }
1377 1440
1378 // m_log.DebugFormat( 1441 // m_log.DebugFormat(
@@ -1491,7 +1554,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1491 if (!client.SceneAgent.IsChildAgent) 1554 if (!client.SceneAgent.IsChildAgent)
1492 client.Kick("Simulator logged you out due to connection timeout"); 1555 client.Kick("Simulator logged you out due to connection timeout");
1493 1556
1494 client.CloseWithoutChecks(); 1557 client.CloseWithoutChecks(true);
1495 } 1558 }
1496 } 1559 }
1497 1560
@@ -1503,6 +1566,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1503 1566
1504 while (IsRunningInbound) 1567 while (IsRunningInbound)
1505 { 1568 {
1569 m_scene.ThreadAlive(1);
1506 try 1570 try
1507 { 1571 {
1508 IncomingPacket incomingPacket = null; 1572 IncomingPacket incomingPacket = null;
@@ -1550,6 +1614,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1550 1614
1551 while (base.IsRunningOutbound) 1615 while (base.IsRunningOutbound)
1552 { 1616 {
1617 m_scene.ThreadAlive(2);
1553 try 1618 try
1554 { 1619 {
1555 m_packetSent = false; 1620 m_packetSent = false;
@@ -1780,8 +1845,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1780 Packet packet = incomingPacket.Packet; 1845 Packet packet = incomingPacket.Packet;
1781 LLClientView client = incomingPacket.Client; 1846 LLClientView client = incomingPacket.Client;
1782 1847
1783 if (client.IsActive) 1848// if (client.IsActive)
1784 { 1849// {
1785 m_currentIncomingClient = client; 1850 m_currentIncomingClient = client;
1786 1851
1787 try 1852 try
@@ -1808,13 +1873,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1808 { 1873 {
1809 m_currentIncomingClient = null; 1874 m_currentIncomingClient = null;
1810 } 1875 }
1811 } 1876// }
1812 else 1877// else
1813 { 1878// {
1814 m_log.DebugFormat( 1879// m_log.DebugFormat(
1815 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 1880// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
1816 packet.Type, client.Name, m_scene.RegionInfo.RegionName); 1881// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
1817 } 1882// }
1818 1883
1819 IncomingPacketsProcessed++; 1884 IncomingPacketsProcessed++;
1820 } 1885 }
@@ -1826,8 +1891,116 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1826 if (!client.IsLoggingOut) 1891 if (!client.IsLoggingOut)
1827 { 1892 {
1828 client.IsLoggingOut = true; 1893 client.IsLoggingOut = true;
1829 client.Close(); 1894 client.Close(false, false);
1895 }
1896 }
1897 }
1898
1899 internal class DoubleQueue<T> where T:class
1900 {
1901 private Queue<T> m_lowQueue = new Queue<T>();
1902 private Queue<T> m_highQueue = new Queue<T>();
1903
1904 private object m_syncRoot = new object();
1905 private Semaphore m_s = new Semaphore(0, 1);
1906
1907 public DoubleQueue()
1908 {
1909 }
1910
1911 public virtual int Count
1912 {
1913 get { return m_highQueue.Count + m_lowQueue.Count; }
1914 }
1915
1916 public virtual void Enqueue(T data)
1917 {
1918 Enqueue(m_lowQueue, data);
1919 }
1920
1921 public virtual void EnqueueLow(T data)
1922 {
1923 Enqueue(m_lowQueue, data);
1924 }
1925
1926 public virtual void EnqueueHigh(T data)
1927 {
1928 Enqueue(m_highQueue, data);
1929 }
1930
1931 private void Enqueue(Queue<T> q, T data)
1932 {
1933 lock (m_syncRoot)
1934 {
1935 m_lowQueue.Enqueue(data);
1936 m_s.WaitOne(0);
1937 m_s.Release();
1938 }
1939 }
1940
1941 public virtual T Dequeue()
1942 {
1943 return Dequeue(Timeout.Infinite);
1944 }
1945
1946 public virtual T Dequeue(int tmo)
1947 {
1948 return Dequeue(TimeSpan.FromMilliseconds(tmo));
1949 }
1950
1951 public virtual T Dequeue(TimeSpan wait)
1952 {
1953 T res = null;
1954
1955 if (!Dequeue(wait, ref res))
1956 return null;
1957
1958 return res;
1959 }
1960
1961 public bool Dequeue(int timeout, ref T res)
1962 {
1963 return Dequeue(TimeSpan.FromMilliseconds(timeout), ref res);
1964 }
1965
1966 public bool Dequeue(TimeSpan wait, ref T res)
1967 {
1968 if (!m_s.WaitOne(wait))
1969 return false;
1970
1971 lock (m_syncRoot)
1972 {
1973 if (m_highQueue.Count > 0)
1974 res = m_highQueue.Dequeue();
1975 else
1976 res = m_lowQueue.Dequeue();
1977
1978 if (m_highQueue.Count == 0 && m_lowQueue.Count == 0)
1979 return true;
1980
1981 try
1982 {
1983 m_s.Release();
1984 }
1985 catch
1986 {
1987 }
1988
1989 return true;
1990 }
1991 }
1992
1993 public virtual void Clear()
1994 {
1995
1996 lock (m_syncRoot)
1997 {
1998 // Make sure sem count is 0
1999 m_s.WaitOne(0);
2000
2001 m_lowQueue.Clear();
2002 m_highQueue.Clear();
1830 } 2003 }
1831 } 2004 }
1832 } 2005 }
1833} \ No newline at end of file 2006}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index f143c32..7035e38 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -114,10 +114,6 @@ namespace OpenMetaverse
114 const int SIO_UDP_CONNRESET = -1744830452; 114 const int SIO_UDP_CONNRESET = -1744830452;
115 115
116 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort); 116 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort);
117
118 m_log.DebugFormat(
119 "[UDPBASE]: Binding UDP listener using internal IP address config {0}:{1}",
120 ipep.Address, ipep.Port);
121 117
122 m_udpSocket = new Socket( 118 m_udpSocket = new Socket(
123 AddressFamily.InterNetwork, 119 AddressFamily.InterNetwork,