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.cs220
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs10
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs26
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs66
5 files changed, 225 insertions, 100 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 7bf7511..af2dd85 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -154,6 +154,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
154 public event RequestTaskInventory OnRequestTaskInventory; 154 public event RequestTaskInventory OnRequestTaskInventory;
155 public event UpdateInventoryItem OnUpdateInventoryItem; 155 public event UpdateInventoryItem OnUpdateInventoryItem;
156 public event CopyInventoryItem OnCopyInventoryItem; 156 public event CopyInventoryItem OnCopyInventoryItem;
157 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
157 public event MoveInventoryItem OnMoveInventoryItem; 158 public event MoveInventoryItem OnMoveInventoryItem;
158 public event RemoveInventoryItem OnRemoveInventoryItem; 159 public event RemoveInventoryItem OnRemoveInventoryItem;
159 public event RemoveInventoryFolder OnRemoveInventoryFolder; 160 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -334,11 +335,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
334// protected HashSet<uint> m_attachmentsSent; 335// protected HashSet<uint> m_attachmentsSent;
335 336
336 private int m_moneyBalance; 337 private int m_moneyBalance;
338 private bool m_deliverPackets = true;
337 private int m_animationSequenceNumber = 1; 339 private int m_animationSequenceNumber = 1;
338 private bool m_SendLogoutPacketWhenClosing = true; 340 private bool m_SendLogoutPacketWhenClosing = true;
339 private AgentUpdateArgs lastarg; 341 private AgentUpdateArgs lastarg;
340 private bool m_IsActive = true; 342 private bool m_IsActive = true;
341 private bool m_IsLoggingOut = false; 343 private bool m_IsLoggingOut = false;
344 private bool m_IsPresenceReady = false;
342 345
343 protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>(); 346 protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>();
344 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers 347 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
@@ -361,6 +364,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
361 364
362 private Timer m_propertiesPacketTimer; 365 private Timer m_propertiesPacketTimer;
363 private List<ObjectPropertiesPacket.ObjectDataBlock> m_propertiesBlocks = new List<ObjectPropertiesPacket.ObjectDataBlock>(); 366 private List<ObjectPropertiesPacket.ObjectDataBlock> m_propertiesBlocks = new List<ObjectPropertiesPacket.ObjectDataBlock>();
367 private List<Packet> m_pendingPackets;
364 368
365 #endregion Class Members 369 #endregion Class Members
366 370
@@ -376,6 +380,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
376 get { return m_startpos; } 380 get { return m_startpos; }
377 set { m_startpos = value; } 381 set { m_startpos = value; }
378 } 382 }
383 public bool DeliverPackets
384 {
385 get { return m_deliverPackets; }
386 set {
387 m_deliverPackets = value;
388 m_udpClient.m_deliverPackets = value;
389 }
390 }
379 public UUID AgentId { get { return m_agentId; } } 391 public UUID AgentId { get { return m_agentId; } }
380 public UUID ActiveGroupId { get { return m_activeGroupID; } } 392 public UUID ActiveGroupId { get { return m_activeGroupID; } }
381 public string ActiveGroupName { get { return m_activeGroupName; } } 393 public string ActiveGroupName { get { return m_activeGroupName; } }
@@ -401,6 +413,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
401 get { return m_IsActive; } 413 get { return m_IsActive; }
402 set { m_IsActive = value; } 414 set { m_IsActive = value; }
403 } 415 }
416
404 public bool IsLoggingOut 417 public bool IsLoggingOut
405 { 418 {
406 get { return m_IsLoggingOut; } 419 get { return m_IsLoggingOut; }
@@ -464,18 +477,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
464 477
465 #region Client Methods 478 #region Client Methods
466 479
480
467 /// <summary> 481 /// <summary>
468 /// Shut down the client view 482 /// Shut down the client view
469 /// </summary> 483 /// </summary>
470 public void Close() 484 public void Close()
471 { 485 {
486 Close(true);
487 }
488
489 /// <summary>
490 /// Shut down the client view
491 /// </summary>
492 public void Close(bool sendStop)
493 {
472 m_log.DebugFormat( 494 m_log.DebugFormat(
473 "[CLIENT]: Close has been called for {0} attached to scene {1}", 495 "[CLIENT]: Close has been called for {0} attached to scene {1}",
474 Name, m_scene.RegionInfo.RegionName); 496 Name, m_scene.RegionInfo.RegionName);
475 497
476 // Send the STOP packet 498 if (sendStop)
477 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); 499 {
478 OutPacket(disable, ThrottleOutPacketType.Unknown); 500 // Send the STOP packet
501 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
502 OutPacket(disable, ThrottleOutPacketType.Unknown);
503 }
479 504
480 IsActive = false; 505 IsActive = false;
481 506
@@ -1041,6 +1066,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1041 public virtual void SendLayerData(float[] map) 1066 public virtual void SendLayerData(float[] map)
1042 { 1067 {
1043 Util.FireAndForget(DoSendLayerData, map); 1068 Util.FireAndForget(DoSendLayerData, map);
1069
1070 // Send it sync, and async. It's not that much data
1071 // and it improves user experience just so much!
1072 DoSendLayerData(map);
1044 } 1073 }
1045 1074
1046 /// <summary> 1075 /// <summary>
@@ -1053,16 +1082,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1053 1082
1054 try 1083 try
1055 { 1084 {
1056 //for (int y = 0; y < 16; y++) 1085 for (int y = 0; y < 16; y++)
1057 //{ 1086 {
1058 // for (int x = 0; x < 16; x++) 1087 for (int x = 0; x < 16; x+=4)
1059 // { 1088 {
1060 // SendLayerData(x, y, map); 1089 SendLayerPacket(x, y, map);
1061 // } 1090 }
1062 //} 1091 }
1063
1064 // Send LayerData in a spiral pattern. Fun!
1065 SendLayerTopRight(map, 0, 0, 15, 15);
1066 } 1092 }
1067 catch (Exception e) 1093 catch (Exception e)
1068 { 1094 {
@@ -1070,51 +1096,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1070 } 1096 }
1071 } 1097 }
1072 1098
1073 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1074 {
1075 // Row
1076 for (int i = x1; i <= x2; i++)
1077 SendLayerData(i, y1, map);
1078
1079 // Column
1080 for (int j = y1 + 1; j <= y2; j++)
1081 SendLayerData(x2, j, map);
1082
1083 if (x2 - x1 > 0)
1084 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1085 }
1086
1087 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1088 {
1089 // Row in reverse
1090 for (int i = x2; i >= x1; i--)
1091 SendLayerData(i, y2, map);
1092
1093 // Column in reverse
1094 for (int j = y2 - 1; j >= y1; j--)
1095 SendLayerData(x1, j, map);
1096
1097 if (x2 - x1 > 0)
1098 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1099 }
1100
1101 /// <summary> 1099 /// <summary>
1102 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1100 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1103 /// </summary> 1101 /// </summary>
1104 /// <param name="map">heightmap</param> 1102 /// <param name="map">heightmap</param>
1105 /// <param name="px">X coordinate for patches 0..12</param> 1103 /// <param name="px">X coordinate for patches 0..12</param>
1106 /// <param name="py">Y coordinate for patches 0..15</param> 1104 /// <param name="py">Y coordinate for patches 0..15</param>
1107 // private void SendLayerPacket(float[] map, int y, int x) 1105 private void SendLayerPacket(int x, int y, float[] map)
1108 // { 1106 {
1109 // int[] patches = new int[4]; 1107 int[] patches = new int[4];
1110 // patches[0] = x + 0 + y * 16; 1108 patches[0] = x + 0 + y * 16;
1111 // patches[1] = x + 1 + y * 16; 1109 patches[1] = x + 1 + y * 16;
1112 // patches[2] = x + 2 + y * 16; 1110 patches[2] = x + 2 + y * 16;
1113 // patches[3] = x + 3 + y * 16; 1111 patches[3] = x + 3 + y * 16;
1114 1112
1115 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1113 float[] heightmap = (map.Length == 65536) ?
1116 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1114 map :
1117 // } 1115 LLHeightFieldMoronize(map);
1116
1117 try
1118 {
1119 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1120 OutPacket(layerpack, ThrottleOutPacketType.Land);
1121 }
1122 catch
1123 {
1124 for (int px = x ; px < x + 4 ; px++)
1125 SendLayerData(px, y, map);
1126 }
1127 }
1118 1128
1119 /// <summary> 1129 /// <summary>
1120 /// Sends a specified patch to a client 1130 /// Sends a specified patch to a client
@@ -1134,7 +1144,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1134 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1144 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1135 layerpack.Header.Reliable = true; 1145 layerpack.Header.Reliable = true;
1136 1146
1137 OutPacket(layerpack, ThrottleOutPacketType.Land); 1147 OutPacket(layerpack, ThrottleOutPacketType.Task);
1138 } 1148 }
1139 catch (Exception e) 1149 catch (Exception e)
1140 { 1150 {
@@ -2206,6 +2216,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2206 OutPacket(sound, ThrottleOutPacketType.Task); 2216 OutPacket(sound, ThrottleOutPacketType.Task);
2207 } 2217 }
2208 2218
2219 public void SendTransferAbort(TransferRequestPacket transferRequest)
2220 {
2221 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2222 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2223 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2224 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2225 OutPacket(abort, ThrottleOutPacketType.Task);
2226 }
2227
2209 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2228 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2210 { 2229 {
2211 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2230 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -3467,6 +3486,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3467 /// </summary> 3486 /// </summary>
3468 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3487 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3469 { 3488 {
3489 if (entity is SceneObjectPart)
3490 {
3491 SceneObjectPart e = (SceneObjectPart)entity;
3492 SceneObjectGroup g = e.ParentGroup;
3493 if (g.RootPart.Shape.State > 30) // HUD
3494 if (g.OwnerID != AgentId)
3495 return; // Don't send updates for other people's HUDs
3496 }
3497
3470 double priority = m_prioritizer.GetUpdatePriority(this, entity); 3498 double priority = m_prioritizer.GetUpdatePriority(this, entity);
3471 3499
3472 lock (m_entityUpdates.SyncRoot) 3500 lock (m_entityUpdates.SyncRoot)
@@ -3487,6 +3515,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3487 EntityUpdate update; 3515 EntityUpdate update;
3488 while (updatesThisCall < maxUpdates && m_entityUpdates.TryDequeue(out update)) 3516 while (updatesThisCall < maxUpdates && m_entityUpdates.TryDequeue(out update))
3489 { 3517 {
3518 // If we have sent a kill packet for this object
3519 // drop any updates on the floor
3520 if (update.Entity is SceneObjectPart)
3521 {
3522 SceneObjectPart part = (SceneObjectPart)update.Entity;
3523 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3524 continue;
3525 }
3526
3490 ++updatesThisCall; 3527 ++updatesThisCall;
3491 3528
3492 #region UpdateFlags to packet type conversion 3529 #region UpdateFlags to packet type conversion
@@ -3909,6 +3946,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3909 { 3946 {
3910 m_propertiesPacketTimer.Stop(); 3947 m_propertiesPacketTimer.Stop();
3911 3948
3949 if (m_propertiesBlocks.Count == 0)
3950 return;
3951
3912 proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[m_propertiesBlocks.Count]; 3952 proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[m_propertiesBlocks.Count];
3913 3953
3914 int index = 0; 3954 int index = 0;
@@ -4800,6 +4840,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4800 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 4840 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
4801 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 4841 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
4802 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 4842 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
4843 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
4803 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 4844 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
4804 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 4845 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
4805 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 4846 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -4899,6 +4940,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4899 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 4940 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
4900 (x.CameraUpAxis != lastarg.CameraUpAxis) || 4941 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
4901 (x.ControlFlags != lastarg.ControlFlags) || 4942 (x.ControlFlags != lastarg.ControlFlags) ||
4943 (x.ControlFlags != 0) ||
4902 (x.Far != lastarg.Far) || 4944 (x.Far != lastarg.Far) ||
4903 (x.Flags != lastarg.Flags) || 4945 (x.Flags != lastarg.Flags) ||
4904 (x.State != lastarg.State) || 4946 (x.State != lastarg.State) ||
@@ -5270,7 +5312,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5270 args.Channel = ch; 5312 args.Channel = ch;
5271 args.From = String.Empty; 5313 args.From = String.Empty;
5272 args.Message = Utils.BytesToString(msg); 5314 args.Message = Utils.BytesToString(msg);
5273 args.Type = ChatTypeEnum.Shout; 5315 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5274 args.Position = new Vector3(); 5316 args.Position = new Vector3();
5275 args.Scene = Scene; 5317 args.Scene = Scene;
5276 args.Sender = this; 5318 args.Sender = this;
@@ -9308,6 +9350,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9308 { 9350 {
9309 return true; 9351 return true;
9310 } 9352 }
9353
9354 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9355 {
9356 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9357
9358 #region Packet Session and User Check
9359 if (m_checkPackets)
9360 {
9361 if (packet.AgentData.SessionID != SessionId ||
9362 packet.AgentData.AgentID != AgentId)
9363 return true;
9364 }
9365 #endregion
9366 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9367 List<InventoryItemBase> items = new List<InventoryItemBase>();
9368 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9369 {
9370 InventoryItemBase b = new InventoryItemBase();
9371 b.ID = n.OldItemID;
9372 b.Folder = n.OldFolderID;
9373 items.Add(b);
9374 }
9375
9376 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9377 if (handlerMoveItemsAndLeaveCopy != null)
9378 {
9379 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9380 }
9381
9382 return true;
9383 }
9311 9384
9312 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9385 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9313 { 9386 {
@@ -11151,18 +11224,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11151 } 11224 }
11152 11225
11153 /// <summary> 11226 /// <summary>
11227 /// This processes packets which have accumulated while the presence was still in the process of initialising.
11228 /// </summary>
11229 public void ProcessPendingPackets()
11230 {
11231 m_IsPresenceReady = true;
11232 if (m_pendingPackets == null)
11233 return;
11234 foreach (Packet p in m_pendingPackets)
11235 {
11236 ProcessInPacket(p);
11237 }
11238 m_pendingPackets.Clear();
11239 }
11240
11241 /// <summary>
11154 /// Entryway from the client to the simulator. All UDP packets from the client will end up here 11242 /// Entryway from the client to the simulator. All UDP packets from the client will end up here
11155 /// </summary> 11243 /// </summary>
11156 /// <param name="Pack">OpenMetaverse.packet</param> 11244 /// <param name="Pack">OpenMetaverse.packet</param>
11157 public void ProcessInPacket(Packet Pack) 11245 public void ProcessInPacket(Packet Pack)
11158 { 11246 {
11159 if (m_debugPacketLevel >= 255) 11247 if (!m_IsPresenceReady)
11160 m_log.DebugFormat("[CLIENT]: Packet IN {0}", Pack.Type); 11248 {
11249 if (m_pendingPackets == null)
11250 {
11251 m_pendingPackets = new List<Packet>();
11252 }
11253 m_pendingPackets.Add(Pack);
11254 }
11255 else
11256 {
11257 if (m_debugPacketLevel >= 255)
11258 m_log.DebugFormat("[CLIENT]: Packet IN {0}", Pack.Type);
11161 11259
11162 if (!ProcessPacketMethod(Pack)) 11260 if (!ProcessPacketMethod(Pack))
11163 m_log.Warn("[CLIENT]: unhandled packet " + Pack.Type); 11261 m_log.Warn("[CLIENT]: unhandled packet " + Pack.Type);
11164 11262
11165 PacketPool.Instance.ReturnPacket(Pack); 11263 PacketPool.Instance.ReturnPacket(Pack);
11264 }
11166 } 11265 }
11167 11266
11168 private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket) 11267 private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket)
@@ -11399,7 +11498,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11399 11498
11400// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 11499// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11401 11500
11501
11502 //Note, the bool returned from the below function is useless since it is always false.
11402 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 11503 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
11504
11403 } 11505 }
11404 11506
11405 /// <summary> 11507 /// <summary>
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
index 6232c48..eebbfa5 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))
@@ -419,6 +427,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
419 /// <returns>True if any packets were sent, otherwise false</returns> 427 /// <returns>True if any packets were sent, otherwise false</returns>
420 public bool DequeueOutgoing() 428 public bool DequeueOutgoing()
421 { 429 {
430 if (m_deliverPackets == false) return false;
431
422 OutgoingPacket packet; 432 OutgoingPacket packet;
423 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 433 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
424 TokenBucket bucket; 434 TokenBucket bucket;
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index 1b81105..3b63bcd 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -899,7 +899,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
899 client.OnLogout += LogoutHandler; 899 client.OnLogout += LogoutHandler;
900 900
901 // Start the IClientAPI 901 // Start the IClientAPI
902 client.Start(); 902 // Spin it off so that it doesn't clog up the LLUDPServer
903
904 //First, and very importantly:
905 //
906 //Set our DeliverPackets flag in the client to *false*
907 //this will prevent us from missing important messages
908 //before the modules are bound
909 client.DeliverPackets = false;
910
911 Util.FireAndForget(
912 delegate
913 {
914 try
915 {
916 client.Start();
917 }
918 finally
919 {
920 //Now, release the hounds. er, packets.
921 client.DeliverPackets = true;
922 }
923 }
924 );
903 } 925 }
904 else 926 else
905 { 927 {
@@ -915,7 +937,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
915 if (m_scene.TryGetClient(udpClient.AgentID, out client)) 937 if (m_scene.TryGetClient(udpClient.AgentID, out client))
916 { 938 {
917 client.IsLoggingOut = true; 939 client.IsLoggingOut = true;
918 client.Close(); 940 client.Close(false);
919 } 941 }
920 } 942 }
921 943
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}