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.cs169
-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, 174 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 0aec01a..a9f9d60 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -334,11 +334,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
334// protected HashSet<uint> m_attachmentsSent; 334// protected HashSet<uint> m_attachmentsSent;
335 335
336 private int m_moneyBalance; 336 private int m_moneyBalance;
337 private bool m_deliverPackets = true;
337 private int m_animationSequenceNumber = 1; 338 private int m_animationSequenceNumber = 1;
338 private bool m_SendLogoutPacketWhenClosing = true; 339 private bool m_SendLogoutPacketWhenClosing = true;
339 private AgentUpdateArgs lastarg; 340 private AgentUpdateArgs lastarg;
340 private bool m_IsActive = true; 341 private bool m_IsActive = true;
341 private bool m_IsLoggingOut = false; 342 private bool m_IsLoggingOut = false;
343 private bool m_IsPresenceReady = false;
342 344
343 protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>(); 345 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 346 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
@@ -361,6 +363,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
361 363
362 private Timer m_propertiesPacketTimer; 364 private Timer m_propertiesPacketTimer;
363 private List<ObjectPropertiesPacket.ObjectDataBlock> m_propertiesBlocks = new List<ObjectPropertiesPacket.ObjectDataBlock>(); 365 private List<ObjectPropertiesPacket.ObjectDataBlock> m_propertiesBlocks = new List<ObjectPropertiesPacket.ObjectDataBlock>();
366 private List<Packet> m_pendingPackets;
364 367
365 #endregion Class Members 368 #endregion Class Members
366 369
@@ -376,6 +379,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
376 get { return m_startpos; } 379 get { return m_startpos; }
377 set { m_startpos = value; } 380 set { m_startpos = value; }
378 } 381 }
382 public bool DeliverPackets
383 {
384 get { return m_deliverPackets; }
385 set {
386 m_deliverPackets = value;
387 m_udpClient.m_deliverPackets = value;
388 }
389 }
379 public UUID AgentId { get { return m_agentId; } } 390 public UUID AgentId { get { return m_agentId; } }
380 public UUID ActiveGroupId { get { return m_activeGroupID; } } 391 public UUID ActiveGroupId { get { return m_activeGroupID; } }
381 public string ActiveGroupName { get { return m_activeGroupName; } } 392 public string ActiveGroupName { get { return m_activeGroupName; } }
@@ -401,6 +412,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
401 get { return m_IsActive; } 412 get { return m_IsActive; }
402 set { m_IsActive = value; } 413 set { m_IsActive = value; }
403 } 414 }
415
404 public bool IsLoggingOut 416 public bool IsLoggingOut
405 { 417 {
406 get { return m_IsLoggingOut; } 418 get { return m_IsLoggingOut; }
@@ -464,18 +476,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
464 476
465 #region Client Methods 477 #region Client Methods
466 478
479
467 /// <summary> 480 /// <summary>
468 /// Shut down the client view 481 /// Shut down the client view
469 /// </summary> 482 /// </summary>
470 public void Close() 483 public void Close()
471 { 484 {
485 Close(true);
486 }
487
488 /// <summary>
489 /// Shut down the client view
490 /// </summary>
491 public void Close(bool sendStop)
492 {
472 m_log.DebugFormat( 493 m_log.DebugFormat(
473 "[CLIENT]: Close has been called for {0} attached to scene {1}", 494 "[CLIENT]: Close has been called for {0} attached to scene {1}",
474 Name, m_scene.RegionInfo.RegionName); 495 Name, m_scene.RegionInfo.RegionName);
475 496
476 // Send the STOP packet 497 if (sendStop)
477 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); 498 {
478 OutPacket(disable, ThrottleOutPacketType.Unknown); 499 // Send the STOP packet
500 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
501 OutPacket(disable, ThrottleOutPacketType.Unknown);
502 }
479 503
480 IsActive = false; 504 IsActive = false;
481 505
@@ -1041,6 +1065,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1041 public virtual void SendLayerData(float[] map) 1065 public virtual void SendLayerData(float[] map)
1042 { 1066 {
1043 Util.FireAndForget(DoSendLayerData, map); 1067 Util.FireAndForget(DoSendLayerData, map);
1068
1069 // Send it sync, and async. It's not that much data
1070 // and it improves user experience just so much!
1071 DoSendLayerData(map);
1044 } 1072 }
1045 1073
1046 /// <summary> 1074 /// <summary>
@@ -1053,16 +1081,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1053 1081
1054 try 1082 try
1055 { 1083 {
1056 //for (int y = 0; y < 16; y++) 1084 for (int y = 0; y < 16; y++)
1057 //{ 1085 {
1058 // for (int x = 0; x < 16; x++) 1086 for (int x = 0; x < 16; x+=4)
1059 // { 1087 {
1060 // SendLayerData(x, y, map); 1088 SendLayerPacket(x, y, map);
1061 // } 1089 }
1062 //} 1090 }
1063
1064 // Send LayerData in a spiral pattern. Fun!
1065 SendLayerTopRight(map, 0, 0, 15, 15);
1066 } 1091 }
1067 catch (Exception e) 1092 catch (Exception e)
1068 { 1093 {
@@ -1070,51 +1095,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1070 } 1095 }
1071 } 1096 }
1072 1097
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> 1098 /// <summary>
1102 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1099 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1103 /// </summary> 1100 /// </summary>
1104 /// <param name="map">heightmap</param> 1101 /// <param name="map">heightmap</param>
1105 /// <param name="px">X coordinate for patches 0..12</param> 1102 /// <param name="px">X coordinate for patches 0..12</param>
1106 /// <param name="py">Y coordinate for patches 0..15</param> 1103 /// <param name="py">Y coordinate for patches 0..15</param>
1107 // private void SendLayerPacket(float[] map, int y, int x) 1104 private void SendLayerPacket(int x, int y, float[] map)
1108 // { 1105 {
1109 // int[] patches = new int[4]; 1106 int[] patches = new int[4];
1110 // patches[0] = x + 0 + y * 16; 1107 patches[0] = x + 0 + y * 16;
1111 // patches[1] = x + 1 + y * 16; 1108 patches[1] = x + 1 + y * 16;
1112 // patches[2] = x + 2 + y * 16; 1109 patches[2] = x + 2 + y * 16;
1113 // patches[3] = x + 3 + y * 16; 1110 patches[3] = x + 3 + y * 16;
1114 1111
1115 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1112 float[] heightmap = (map.Length == 65536) ?
1116 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1113 map :
1117 // } 1114 LLHeightFieldMoronize(map);
1115
1116 try
1117 {
1118 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1119 OutPacket(layerpack, ThrottleOutPacketType.Land);
1120 }
1121 catch
1122 {
1123 for (int px = x ; px < x + 4 ; px++)
1124 SendLayerData(px, y, map);
1125 }
1126 }
1118 1127
1119 /// <summary> 1128 /// <summary>
1120 /// Sends a specified patch to a client 1129 /// Sends a specified patch to a client
@@ -1134,7 +1143,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1134 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1143 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1135 layerpack.Header.Reliable = true; 1144 layerpack.Header.Reliable = true;
1136 1145
1137 OutPacket(layerpack, ThrottleOutPacketType.Land); 1146 OutPacket(layerpack, ThrottleOutPacketType.Task);
1138 } 1147 }
1139 catch (Exception e) 1148 catch (Exception e)
1140 { 1149 {
@@ -2206,6 +2215,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2206 OutPacket(sound, ThrottleOutPacketType.Task); 2215 OutPacket(sound, ThrottleOutPacketType.Task);
2207 } 2216 }
2208 2217
2218 public void SendTransferAbort(TransferRequestPacket transferRequest)
2219 {
2220 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2221 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2222 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2223 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2224 OutPacket(abort, ThrottleOutPacketType.Task);
2225 }
2226
2209 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2227 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2210 { 2228 {
2211 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2229 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -3909,6 +3927,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3909 { 3927 {
3910 m_propertiesPacketTimer.Stop(); 3928 m_propertiesPacketTimer.Stop();
3911 3929
3930 if (m_propertiesBlocks.Count == 0)
3931 return;
3932
3912 proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[m_propertiesBlocks.Count]; 3933 proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[m_propertiesBlocks.Count];
3913 3934
3914 int index = 0; 3935 int index = 0;
@@ -4900,6 +4921,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4900 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 4921 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
4901 (x.CameraUpAxis != lastarg.CameraUpAxis) || 4922 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
4902 (x.ControlFlags != lastarg.ControlFlags) || 4923 (x.ControlFlags != lastarg.ControlFlags) ||
4924 (x.ControlFlags != 0) ||
4903 (x.Far != lastarg.Far) || 4925 (x.Far != lastarg.Far) ||
4904 (x.Flags != lastarg.Flags) || 4926 (x.Flags != lastarg.Flags) ||
4905 (x.State != lastarg.State) || 4927 (x.State != lastarg.State) ||
@@ -5271,7 +5293,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5271 args.Channel = ch; 5293 args.Channel = ch;
5272 args.From = String.Empty; 5294 args.From = String.Empty;
5273 args.Message = Utils.BytesToString(msg); 5295 args.Message = Utils.BytesToString(msg);
5274 args.Type = ChatTypeEnum.Shout; 5296 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5275 args.Position = new Vector3(); 5297 args.Position = new Vector3();
5276 args.Scene = Scene; 5298 args.Scene = Scene;
5277 args.Sender = this; 5299 args.Sender = this;
@@ -11152,18 +11174,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11152 } 11174 }
11153 11175
11154 /// <summary> 11176 /// <summary>
11177 /// This processes packets which have accumulated while the presence was still in the process of initialising.
11178 /// </summary>
11179 public void ProcessPendingPackets()
11180 {
11181 m_IsPresenceReady = true;
11182 if (m_pendingPackets == null)
11183 return;
11184 foreach (Packet p in m_pendingPackets)
11185 {
11186 ProcessInPacket(p);
11187 }
11188 m_pendingPackets.Clear();
11189 }
11190
11191 /// <summary>
11155 /// Entryway from the client to the simulator. All UDP packets from the client will end up here 11192 /// Entryway from the client to the simulator. All UDP packets from the client will end up here
11156 /// </summary> 11193 /// </summary>
11157 /// <param name="Pack">OpenMetaverse.packet</param> 11194 /// <param name="Pack">OpenMetaverse.packet</param>
11158 public void ProcessInPacket(Packet Pack) 11195 public void ProcessInPacket(Packet Pack)
11159 { 11196 {
11160 if (m_debugPacketLevel >= 255) 11197 if (!m_IsPresenceReady)
11161 m_log.DebugFormat("[CLIENT]: Packet IN {0}", Pack.Type); 11198 {
11199 if (m_pendingPackets == null)
11200 {
11201 m_pendingPackets = new List<Packet>();
11202 }
11203 m_pendingPackets.Add(Pack);
11204 }
11205 else
11206 {
11207 if (m_debugPacketLevel >= 255)
11208 m_log.DebugFormat("[CLIENT]: Packet IN {0}", Pack.Type);
11162 11209
11163 if (!ProcessPacketMethod(Pack)) 11210 if (!ProcessPacketMethod(Pack))
11164 m_log.Warn("[CLIENT]: unhandled packet " + Pack.Type); 11211 m_log.Warn("[CLIENT]: unhandled packet " + Pack.Type);
11165 11212
11166 PacketPool.Instance.ReturnPacket(Pack); 11213 PacketPool.Instance.ReturnPacket(Pack);
11214 }
11167 } 11215 }
11168 11216
11169 private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket) 11217 private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket)
@@ -11400,7 +11448,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11400 11448
11401// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 11449// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11402 11450
11451
11452 //Note, the bool returned from the below function is useless since it is always false.
11403 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 11453 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
11454
11404 } 11455 }
11405 11456
11406 /// <summary> 11457 /// <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}