aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs3
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs251
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs10
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs27
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs66
5 files changed, 232 insertions, 125 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
index e9e2dca..9dd6663 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
@@ -202,6 +202,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
202 m_stopPacket = TexturePacketCount(); 202 m_stopPacket = TexturePacketCount();
203 } 203 }
204 204
205 //Give them at least two packets, to play nice with some broken viewers (SL also behaves this way)
206 if (m_stopPacket == 1 && Layers[0].End > FIRST_PACKET_SIZE) m_stopPacket++;
207
205 m_currentPacket = StartPacket; 208 m_currentPacket = StartPacket;
206 } 209 }
207 } 210 }
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 4aa19d1..4c9011a 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -155,6 +155,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
155 public event RequestTaskInventory OnRequestTaskInventory; 155 public event RequestTaskInventory OnRequestTaskInventory;
156 public event UpdateInventoryItem OnUpdateInventoryItem; 156 public event UpdateInventoryItem OnUpdateInventoryItem;
157 public event CopyInventoryItem OnCopyInventoryItem; 157 public event CopyInventoryItem OnCopyInventoryItem;
158 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
158 public event MoveInventoryItem OnMoveInventoryItem; 159 public event MoveInventoryItem OnMoveInventoryItem;
159 public event RemoveInventoryItem OnRemoveInventoryItem; 160 public event RemoveInventoryItem OnRemoveInventoryItem;
160 public event RemoveInventoryFolder OnRemoveInventoryFolder; 161 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -335,11 +336,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
335// protected HashSet<uint> m_attachmentsSent; 336// protected HashSet<uint> m_attachmentsSent;
336 337
337 private int m_moneyBalance; 338 private int m_moneyBalance;
339 private bool m_deliverPackets = true;
338 private int m_animationSequenceNumber = 1; 340 private int m_animationSequenceNumber = 1;
339 private bool m_SendLogoutPacketWhenClosing = true; 341 private bool m_SendLogoutPacketWhenClosing = true;
340 private AgentUpdateArgs lastarg; 342 private AgentUpdateArgs lastarg;
341 private bool m_IsActive = true; 343 private bool m_IsActive = true;
342 private bool m_IsLoggingOut = false; 344 private bool m_IsLoggingOut = false;
345 private bool m_IsPresenceReady = false;
343 346
344 protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>(); 347 protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>();
345 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers 348 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
@@ -362,6 +365,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
362 365
363 private Timer m_propertiesPacketTimer; 366 private Timer m_propertiesPacketTimer;
364 private List<ObjectPropertiesPacket.ObjectDataBlock> m_propertiesBlocks = new List<ObjectPropertiesPacket.ObjectDataBlock>(); 367 private List<ObjectPropertiesPacket.ObjectDataBlock> m_propertiesBlocks = new List<ObjectPropertiesPacket.ObjectDataBlock>();
368 private List<Packet> m_pendingPackets;
365 369
366 #endregion Class Members 370 #endregion Class Members
367 371
@@ -377,6 +381,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
377 get { return m_startpos; } 381 get { return m_startpos; }
378 set { m_startpos = value; } 382 set { m_startpos = value; }
379 } 383 }
384 public bool DeliverPackets
385 {
386 get { return m_deliverPackets; }
387 set {
388 m_deliverPackets = value;
389 m_udpClient.m_deliverPackets = value;
390 }
391 }
380 public UUID AgentId { get { return m_agentId; } } 392 public UUID AgentId { get { return m_agentId; } }
381 public UUID ActiveGroupId { get { return m_activeGroupID; } } 393 public UUID ActiveGroupId { get { return m_activeGroupID; } }
382 public string ActiveGroupName { get { return m_activeGroupName; } } 394 public string ActiveGroupName { get { return m_activeGroupName; } }
@@ -406,6 +418,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
406 get { return m_IsActive; } 418 get { return m_IsActive; }
407 set { m_IsActive = value; } 419 set { m_IsActive = value; }
408 } 420 }
421
409 public bool IsLoggingOut 422 public bool IsLoggingOut
410 { 423 {
411 get { return m_IsLoggingOut; } 424 get { return m_IsLoggingOut; }
@@ -475,18 +488,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
475 488
476 #region Client Methods 489 #region Client Methods
477 490
491
478 /// <summary> 492 /// <summary>
479 /// Shut down the client view 493 /// Shut down the client view
480 /// </summary> 494 /// </summary>
481 public void Close() 495 public void Close()
482 { 496 {
497 Close(true);
498 }
499
500 /// <summary>
501 /// Shut down the client view
502 /// </summary>
503 public void Close(bool sendStop)
504 {
483 m_log.DebugFormat( 505 m_log.DebugFormat(
484 "[CLIENT]: Close has been called for {0} attached to scene {1}", 506 "[CLIENT]: Close has been called for {0} attached to scene {1}",
485 Name, m_scene.RegionInfo.RegionName); 507 Name, m_scene.RegionInfo.RegionName);
486 508
487 // Send the STOP packet 509 if (sendStop)
488 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); 510 {
489 OutPacket(disable, ThrottleOutPacketType.Unknown); 511 // Send the STOP packet
512 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
513 OutPacket(disable, ThrottleOutPacketType.Unknown);
514 }
490 515
491 IsActive = false; 516 IsActive = false;
492 517
@@ -766,7 +791,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
766 reply.ChatData.OwnerID = fromAgentID; 791 reply.ChatData.OwnerID = fromAgentID;
767 reply.ChatData.SourceID = fromAgentID; 792 reply.ChatData.SourceID = fromAgentID;
768 793
769 OutPacket(reply, ThrottleOutPacketType.Task); 794 OutPacket(reply, ThrottleOutPacketType.Unknown);
770 } 795 }
771 796
772 /// <summary> 797 /// <summary>
@@ -1052,6 +1077,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1052 public virtual void SendLayerData(float[] map) 1077 public virtual void SendLayerData(float[] map)
1053 { 1078 {
1054 Util.FireAndForget(DoSendLayerData, map); 1079 Util.FireAndForget(DoSendLayerData, map);
1080
1081 // Send it sync, and async. It's not that much data
1082 // and it improves user experience just so much!
1083 DoSendLayerData(map);
1055 } 1084 }
1056 1085
1057 /// <summary> 1086 /// <summary>
@@ -1064,16 +1093,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1064 1093
1065 try 1094 try
1066 { 1095 {
1067 //for (int y = 0; y < 16; y++) 1096 for (int y = 0; y < 16; y++)
1068 //{ 1097 {
1069 // for (int x = 0; x < 16; x++) 1098 for (int x = 0; x < 16; x+=4)
1070 // { 1099 {
1071 // SendLayerData(x, y, map); 1100 SendLayerPacket(x, y, map);
1072 // } 1101 }
1073 //} 1102 }
1074
1075 // Send LayerData in a spiral pattern. Fun!
1076 SendLayerTopRight(map, 0, 0, 15, 15);
1077 } 1103 }
1078 catch (Exception e) 1104 catch (Exception e)
1079 { 1105 {
@@ -1081,51 +1107,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1081 } 1107 }
1082 } 1108 }
1083 1109
1084 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1085 {
1086 // Row
1087 for (int i = x1; i <= x2; i++)
1088 SendLayerData(i, y1, map);
1089
1090 // Column
1091 for (int j = y1 + 1; j <= y2; j++)
1092 SendLayerData(x2, j, map);
1093
1094 if (x2 - x1 > 0)
1095 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1096 }
1097
1098 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1099 {
1100 // Row in reverse
1101 for (int i = x2; i >= x1; i--)
1102 SendLayerData(i, y2, map);
1103
1104 // Column in reverse
1105 for (int j = y2 - 1; j >= y1; j--)
1106 SendLayerData(x1, j, map);
1107
1108 if (x2 - x1 > 0)
1109 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1110 }
1111
1112 /// <summary> 1110 /// <summary>
1113 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1111 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1114 /// </summary> 1112 /// </summary>
1115 /// <param name="map">heightmap</param> 1113 /// <param name="map">heightmap</param>
1116 /// <param name="px">X coordinate for patches 0..12</param> 1114 /// <param name="px">X coordinate for patches 0..12</param>
1117 /// <param name="py">Y coordinate for patches 0..15</param> 1115 /// <param name="py">Y coordinate for patches 0..15</param>
1118 // private void SendLayerPacket(float[] map, int y, int x) 1116 private void SendLayerPacket(int x, int y, float[] map)
1119 // { 1117 {
1120 // int[] patches = new int[4]; 1118 int[] patches = new int[4];
1121 // patches[0] = x + 0 + y * 16; 1119 patches[0] = x + 0 + y * 16;
1122 // patches[1] = x + 1 + y * 16; 1120 patches[1] = x + 1 + y * 16;
1123 // patches[2] = x + 2 + y * 16; 1121 patches[2] = x + 2 + y * 16;
1124 // patches[3] = x + 3 + y * 16; 1122 patches[3] = x + 3 + y * 16;
1125 1123
1126 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1124 float[] heightmap = (map.Length == 65536) ?
1127 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1125 map :
1128 // } 1126 LLHeightFieldMoronize(map);
1127
1128 try
1129 {
1130 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1131 OutPacket(layerpack, ThrottleOutPacketType.Land);
1132 }
1133 catch
1134 {
1135 for (int px = x ; px < x + 4 ; px++)
1136 SendLayerData(px, y, map);
1137 }
1138 }
1129 1139
1130 /// <summary> 1140 /// <summary>
1131 /// Sends a specified patch to a client 1141 /// Sends a specified patch to a client
@@ -1145,7 +1155,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1145 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1155 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1146 layerpack.Header.Reliable = true; 1156 layerpack.Header.Reliable = true;
1147 1157
1148 OutPacket(layerpack, ThrottleOutPacketType.Land); 1158 OutPacket(layerpack, ThrottleOutPacketType.Task);
1149 } 1159 }
1150 catch (Exception e) 1160 catch (Exception e)
1151 { 1161 {
@@ -1506,35 +1516,46 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1506 OutPacket(pc, ThrottleOutPacketType.Unknown); 1516 OutPacket(pc, ThrottleOutPacketType.Unknown);
1507 } 1517 }
1508 1518
1509 public void SendKillObject(ulong regionHandle, uint localID) 1519 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1510 { 1520 {
1511// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1521// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle);
1512 1522
1513 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1523 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1514 // TODO: don't create new blocks if recycling an old packet 1524 // TODO: don't create new blocks if recycling an old packet
1515 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; 1525 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[localIDs.Count];
1516 kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); 1526 for (int i = 0 ; i < localIDs.Count ; i++ )
1517 kill.ObjectData[0].ID = localID; 1527 {
1528 kill.ObjectData[i] = new KillObjectPacket.ObjectDataBlock();
1529 kill.ObjectData[i].ID = localIDs[i];
1530 }
1518 kill.Header.Reliable = true; 1531 kill.Header.Reliable = true;
1519 kill.Header.Zerocoded = true; 1532 kill.Header.Zerocoded = true;
1520 1533
1521 if (m_scene.GetScenePresence(localID) == null) 1534 if (localIDs.Count == 1)
1522 { 1535 {
1523 lock (m_entityUpdates.SyncRoot) 1536 if (m_scene.GetScenePresence(localIDs[0]) != null)
1524 { 1537 {
1525 m_killRecord.Add(localID); 1538 OutPacket(kill, ThrottleOutPacketType.State);
1526 1539 return;
1527 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1528 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1529 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1530 // scene objects in a viewer until that viewer is relogged in.
1531 OutPacket(kill, ThrottleOutPacketType.Task);
1532 } 1540 }
1541 m_killRecord.Add(localIDs[0]);
1533 } 1542 }
1534 else 1543 else
1535 { 1544 {
1536 OutPacket(kill, ThrottleOutPacketType.State); 1545 lock (m_entityUpdates.SyncRoot)
1546 {
1547 foreach (uint localID in localIDs)
1548 m_killRecord.Add(localID);
1549 }
1537 } 1550 }
1551
1552 // The throttle queue used here must match that being used for
1553 // updates. Otherwise, there is a chance that a kill packet put
1554 // on a separate queue will be sent to the client before an
1555 // existing update packet on another queue. Receiving updates
1556 // after kills results in unowned and undeletable
1557 // scene objects in a viewer until that viewer is relogged in.
1558 OutPacket(kill, ThrottleOutPacketType.Task);
1538 } 1559 }
1539 1560
1540 /// <summary> 1561 /// <summary>
@@ -2240,6 +2261,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2240 OutPacket(sound, ThrottleOutPacketType.Task); 2261 OutPacket(sound, ThrottleOutPacketType.Task);
2241 } 2262 }
2242 2263
2264 public void SendTransferAbort(TransferRequestPacket transferRequest)
2265 {
2266 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2267 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2268 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2269 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2270 OutPacket(abort, ThrottleOutPacketType.Task);
2271 }
2272
2243 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2273 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2244 { 2274 {
2245 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2275 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -3541,6 +3571,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3541 /// </summary> 3571 /// </summary>
3542 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3572 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3543 { 3573 {
3574 if (entity is SceneObjectPart)
3575 {
3576 SceneObjectPart e = (SceneObjectPart)entity;
3577 SceneObjectGroup g = e.ParentGroup;
3578 if (g.RootPart.Shape.State > 30) // HUD
3579 if (g.OwnerID != AgentId)
3580 return; // Don't send updates for other people's HUDs
3581 }
3582
3544 double priority = m_prioritizer.GetUpdatePriority(this, entity); 3583 double priority = m_prioritizer.GetUpdatePriority(this, entity);
3545 3584
3546 lock (m_entityUpdates.SyncRoot) 3585 lock (m_entityUpdates.SyncRoot)
@@ -3561,23 +3600,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3561 EntityUpdate update; 3600 EntityUpdate update;
3562 while (updatesThisCall < maxUpdates && m_entityUpdates.TryDequeue(out update)) 3601 while (updatesThisCall < maxUpdates && m_entityUpdates.TryDequeue(out update))
3563 { 3602 {
3564 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3603 // If we have sent a kill packet for this object
3565 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3604 // drop any updates on the floor
3566 // safety measure.
3567 //
3568 // Receiving updates after kills results in undeleteable prims that persist until relog and
3569 // currently occurs because prims can be deleted before all queued updates are sent.
3570 if (m_killRecord.Contains(update.Entity.LocalId))
3571 {
3572// m_log.WarnFormat(
3573// "[CLIENT]: Preventing full update for prim with local id {0} after client for user {1} told it was deleted",
3574// update.Entity.LocalId, Name);
3575 continue;
3576 }
3577
3578 if (update.Entity is SceneObjectPart) 3605 if (update.Entity is SceneObjectPart)
3579 { 3606 {
3580 SceneObjectPart part = (SceneObjectPart)update.Entity; 3607 SceneObjectPart part = (SceneObjectPart)update.Entity;
3608 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3609 continue;
3581 3610
3582 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3611 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3583 { 3612 {
@@ -4011,6 +4040,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4011 { 4040 {
4012 m_propertiesPacketTimer.Stop(); 4041 m_propertiesPacketTimer.Stop();
4013 4042
4043 if (m_propertiesBlocks.Count == 0)
4044 return;
4045
4014 proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[m_propertiesBlocks.Count]; 4046 proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[m_propertiesBlocks.Count];
4015 4047
4016 int index = 0; 4048 int index = 0;
@@ -4917,6 +4949,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4917 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 4949 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
4918 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 4950 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
4919 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 4951 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
4952 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
4920 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 4953 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
4921 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 4954 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
4922 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 4955 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5016,6 +5049,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5016 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5049 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5017 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5050 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5018 (x.ControlFlags != lastarg.ControlFlags) || 5051 (x.ControlFlags != lastarg.ControlFlags) ||
5052 (x.ControlFlags != 0) ||
5019 (x.Far != lastarg.Far) || 5053 (x.Far != lastarg.Far) ||
5020 (x.Flags != lastarg.Flags) || 5054 (x.Flags != lastarg.Flags) ||
5021 (x.State != lastarg.State) || 5055 (x.State != lastarg.State) ||
@@ -5389,7 +5423,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5389 args.Channel = ch; 5423 args.Channel = ch;
5390 args.From = String.Empty; 5424 args.From = String.Empty;
5391 args.Message = Utils.BytesToString(msg); 5425 args.Message = Utils.BytesToString(msg);
5392 args.Type = ChatTypeEnum.Shout; 5426 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5393 args.Position = new Vector3(); 5427 args.Position = new Vector3();
5394 args.Scene = Scene; 5428 args.Scene = Scene;
5395 args.Sender = this; 5429 args.Sender = this;
@@ -9428,6 +9462,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9428 { 9462 {
9429 return true; 9463 return true;
9430 } 9464 }
9465
9466 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9467 {
9468 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9469
9470 #region Packet Session and User Check
9471 if (m_checkPackets)
9472 {
9473 if (packet.AgentData.SessionID != SessionId ||
9474 packet.AgentData.AgentID != AgentId)
9475 return true;
9476 }
9477 #endregion
9478 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9479 List<InventoryItemBase> items = new List<InventoryItemBase>();
9480 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9481 {
9482 InventoryItemBase b = new InventoryItemBase();
9483 b.ID = n.OldItemID;
9484 b.Folder = n.OldFolderID;
9485 items.Add(b);
9486 }
9487
9488 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9489 if (handlerMoveItemsAndLeaveCopy != null)
9490 {
9491 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9492 }
9493
9494 return true;
9495 }
9431 9496
9432 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9497 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9433 { 9498 {
@@ -10925,7 +10990,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10925 { 10990 {
10926 // It's a ghost! tell the client to delete it from view. 10991 // It's a ghost! tell the client to delete it from view.
10927 simClient.SendKillObject(Scene.RegionInfo.RegionHandle, 10992 simClient.SendKillObject(Scene.RegionInfo.RegionHandle,
10928 localId); 10993 new List<uint>() { localId });
10929 } 10994 }
10930 else 10995 else
10931 { 10996 {
@@ -11290,6 +11355,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11290 } 11355 }
11291 11356
11292 /// <summary> 11357 /// <summary>
11358 /// This processes packets which have accumulated while the presence was still in the process of initialising.
11359 /// </summary>
11360 public void ProcessPendingPackets()
11361 {
11362 m_IsPresenceReady = true;
11363 if (m_pendingPackets == null)
11364 return;
11365 foreach (Packet p in m_pendingPackets)
11366 {
11367 ProcessInPacket(p);
11368 }
11369 m_pendingPackets.Clear();
11370 }
11371
11372 /// <summary>
11293 /// Entryway from the client to the simulator. All UDP packets from the client will end up here 11373 /// Entryway from the client to the simulator. All UDP packets from the client will end up here
11294 /// </summary> 11374 /// </summary>
11295 /// <param name="Pack">OpenMetaverse.packet</param> 11375 /// <param name="Pack">OpenMetaverse.packet</param>
@@ -11552,7 +11632,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11552 11632
11553// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 11633// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11554 11634
11635
11636 //Note, the bool returned from the below function is useless since it is always false.
11555 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 11637 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
11638
11556 } 11639 }
11557 11640
11558 /// <summary> 11641 /// <summary>
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
index ca5a7bd..a4738ff 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
@@ -149,6 +149,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
149 149
150 private int m_defaultRTO = 3000; 150 private int m_defaultRTO = 3000;
151 private int m_maxRTO = 60000; 151 private int m_maxRTO = 60000;
152 public bool m_deliverPackets = true;
152 153
153 /// <summary> 154 /// <summary>
154 /// Default constructor 155 /// Default constructor
@@ -389,6 +390,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
389 if (category >= 0 && category < m_packetOutboxes.Length) 390 if (category >= 0 && category < m_packetOutboxes.Length)
390 { 391 {
391 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; 392 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
393
394 if (m_deliverPackets == false)
395 {
396 queue.Enqueue(packet);
397 return true;
398 }
399
392 TokenBucket bucket = m_throttleCategories[category]; 400 TokenBucket bucket = m_throttleCategories[category];
393 401
394 if (bucket.RemoveTokens(packet.Buffer.DataLength)) 402 if (bucket.RemoveTokens(packet.Buffer.DataLength))
@@ -425,6 +433,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
425 /// <returns>True if any packets were sent, otherwise false</returns> 433 /// <returns>True if any packets were sent, otherwise false</returns>
426 public bool DequeueOutgoing() 434 public bool DequeueOutgoing()
427 { 435 {
436 if (m_deliverPackets == false) return false;
437
428 OutgoingPacket packet; 438 OutgoingPacket packet;
429 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 439 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
430 TokenBucket bucket; 440 TokenBucket bucket;
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index 821f679..b8c692f 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -918,7 +918,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
918 client.DisableFacelights = m_disableFacelights; 918 client.DisableFacelights = m_disableFacelights;
919 919
920 // Start the IClientAPI 920 // Start the IClientAPI
921 client.Start(); 921 // Spin it off so that it doesn't clog up the LLUDPServer
922
923 //First, and very importantly:
924 //
925 //Set our DeliverPackets flag in the client to *false*
926 //this will prevent us from missing important messages
927 //before the modules are bound
928 client.DeliverPackets = false;
929 client.DisableFacelights = m_disableFacelights;
930
931 Util.FireAndForget(
932 delegate
933 {
934 try
935 {
936 client.Start();
937 }
938 finally
939 {
940 //Now, release the hounds. er, packets.
941 client.DeliverPackets = true;
942 }
943 }
944 );
922 } 945 }
923 else 946 else
924 { 947 {
@@ -934,7 +957,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
934 if (m_scene.TryGetClient(udpClient.AgentID, out client)) 957 if (m_scene.TryGetClient(udpClient.AgentID, out client))
935 { 958 {
936 client.IsLoggingOut = true; 959 client.IsLoggingOut = true;
937 client.Close(); 960 client.Close(false);
938 } 961 }
939 } 962 }
940 963
diff --git a/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs b/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs
index bdbd284..91e3d20 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs
@@ -133,7 +133,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
133 this.parent = parent; 133 this.parent = parent;
134 MaxBurst = maxBurst; 134 MaxBurst = maxBurst;
135 DripRate = dripRate; 135 DripRate = dripRate;
136 lastDrip = Environment.TickCount & Int32.MaxValue; 136 lastDrip = Environment.TickCount;
137 } 137 }
138 138
139 /// <summary> 139 /// <summary>
@@ -144,40 +144,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
144 /// the bucket, otherwise false</returns> 144 /// the bucket, otherwise false</returns>
145 public bool RemoveTokens(int amount) 145 public bool RemoveTokens(int amount)
146 { 146 {
147 bool dummy;
148 return RemoveTokens(amount, out dummy);
149 }
150
151 /// <summary>
152 /// Remove a given number of tokens from the bucket
153 /// </summary>
154 /// <param name="amount">Number of tokens to remove from the bucket</param>
155 /// <param name="dripSucceeded">True if tokens were added to the bucket
156 /// during this call, otherwise false</param>
157 /// <returns>True if the requested number of tokens were removed from
158 /// the bucket, otherwise false</returns>
159 public bool RemoveTokens(int amount, out bool dripSucceeded)
160 {
161 if (maxBurst == 0) 147 if (maxBurst == 0)
162 { 148 {
163 dripSucceeded = true;
164 return true; 149 return true;
165 } 150 }
166 151
167 dripSucceeded = Drip(); 152 if (amount > maxBurst)
168
169 if (content - amount >= 0)
170 { 153 {
171 if (parent != null && !parent.RemoveTokens(amount)) 154 throw new Exception("amount " + amount + " exceeds maxBurst " + maxBurst);
172 return false; 155 }
173 156
174 content -= amount; 157 Drip();
175 return true; 158
159 if (content < amount)
160 {
161 return false;
176 } 162 }
177 else 163
164 if (parent != null && !parent.RemoveTokens(amount))
178 { 165 {
179 return false; 166 return false;
180 } 167 }
168
169 content -= amount;
170 return true;
181 } 171 }
182 172
183 /// <summary> 173 /// <summary>
@@ -193,25 +183,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
193 content = maxBurst; 183 content = maxBurst;
194 return true; 184 return true;
195 } 185 }
196 else
197 {
198 int now = Environment.TickCount & Int32.MaxValue;
199 int deltaMS = now - lastDrip;
200 186
201 if (deltaMS <= 0) 187 int now = Environment.TickCount;
202 { 188 int deltaMS = now - lastDrip;
203 if (deltaMS < 0) 189 lastDrip = now;
204 lastDrip = now;
205 return false;
206 }
207 190
208 int dripAmount = deltaMS * tokensPerMS; 191 if (deltaMS <= 0)
209 192 {
210 content = Math.Min(content + dripAmount, maxBurst); 193 return false;
211 lastDrip = now; 194 }
212 195
213 return true; 196 long dripAmount = (long)deltaMS * (long)tokensPerMS + (long)content;
197 if (dripAmount > maxBurst)
198 {
199 dripAmount = maxBurst;
214 } 200 }
201 content = (int)dripAmount;
202 return true;
215 } 203 }
216 } 204 }
217} 205}