diff options
Diffstat (limited to 'OpenSim/Region')
19 files changed, 505 insertions, 365 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index cd438d6..910fb76 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -395,6 +395,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
395 | public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); } | 395 | public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); } |
396 | 396 | ||
397 | /// <summary> | 397 | /// <summary> |
398 | /// Entity update queues | ||
399 | /// </summary> | ||
400 | public PriorityQueue EntityUpdateQueue { get { return m_entityUpdates; } } | ||
401 | |||
402 | /// <summary> | ||
398 | /// First name of the agent/avatar represented by the client | 403 | /// First name of the agent/avatar represented by the client |
399 | /// </summary> | 404 | /// </summary> |
400 | public string FirstName { get { return m_firstName; } } | 405 | public string FirstName { get { return m_firstName; } } |
@@ -3625,7 +3630,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3625 | // Remove the update packet from the list of packets waiting for acknowledgement | 3630 | // Remove the update packet from the list of packets waiting for acknowledgement |
3626 | // because we are requeuing the list of updates. They will be resent in new packets | 3631 | // because we are requeuing the list of updates. They will be resent in new packets |
3627 | // with the most recent state and priority. | 3632 | // with the most recent state and priority. |
3628 | m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber, 0, true); | 3633 | m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber); |
3634 | |||
3635 | // Count this as a resent packet since we are going to requeue all of the updates contained in it | ||
3636 | Interlocked.Increment(ref m_udpClient.PacketsResent); | ||
3637 | |||
3629 | foreach (EntityUpdate update in updates) | 3638 | foreach (EntityUpdate update in updates) |
3630 | ResendPrimUpdate(update); | 3639 | ResendPrimUpdate(update); |
3631 | } | 3640 | } |
@@ -4092,7 +4101,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4092 | // Remove the update packet from the list of packets waiting for acknowledgement | 4101 | // Remove the update packet from the list of packets waiting for acknowledgement |
4093 | // because we are requeuing the list of updates. They will be resent in new packets | 4102 | // because we are requeuing the list of updates. They will be resent in new packets |
4094 | // with the most recent state. | 4103 | // with the most recent state. |
4095 | m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber, 0, true); | 4104 | m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber); |
4105 | |||
4106 | // Count this as a resent packet since we are going to requeue all of the updates contained in it | ||
4107 | Interlocked.Increment(ref m_udpClient.PacketsResent); | ||
4108 | |||
4096 | foreach (ObjectPropertyUpdate update in updates) | 4109 | foreach (ObjectPropertyUpdate update in updates) |
4097 | ResendPropertyUpdate(update); | 4110 | ResendPropertyUpdate(update); |
4098 | } | 4111 | } |
@@ -4897,7 +4910,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4897 | data.RelativePosition.ToBytes(objectData, 0); | 4910 | data.RelativePosition.ToBytes(objectData, 0); |
4898 | data.Velocity.ToBytes(objectData, 12); | 4911 | data.Velocity.ToBytes(objectData, 12); |
4899 | data.Acceleration.ToBytes(objectData, 24); | 4912 | data.Acceleration.ToBytes(objectData, 24); |
4900 | data.RotationOffset.ToBytes(objectData, 36); | 4913 | try |
4914 | { | ||
4915 | data.RotationOffset.ToBytes(objectData, 36); | ||
4916 | } | ||
4917 | catch (Exception e) | ||
4918 | { | ||
4919 | m_log.Warn("[LLClientView]: exception converting quaternion to bytes, using Quaternion.Identity. Exception: " + e.ToString()); | ||
4920 | OpenMetaverse.Quaternion.Identity.ToBytes(objectData, 36); | ||
4921 | } | ||
4901 | data.AngularVelocity.ToBytes(objectData, 48); | 4922 | data.AngularVelocity.ToBytes(objectData, 48); |
4902 | 4923 | ||
4903 | ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); | 4924 | ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); |
@@ -11513,7 +11534,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11513 | /// <returns></returns> | 11534 | /// <returns></returns> |
11514 | public byte[] GetThrottlesPacked(float multiplier) | 11535 | public byte[] GetThrottlesPacked(float multiplier) |
11515 | { | 11536 | { |
11516 | return m_udpClient.GetThrottlesPacked(); | 11537 | return m_udpClient.GetThrottlesPacked(multiplier); |
11517 | } | 11538 | } |
11518 | 11539 | ||
11519 | /// <summary> | 11540 | /// <summary> |
@@ -11706,7 +11727,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11706 | 11727 | ||
11707 | info.userEP = m_userEndPoint; | 11728 | info.userEP = m_userEndPoint; |
11708 | info.proxyEP = null; | 11729 | info.proxyEP = null; |
11709 | info.agentcircuit = new sAgentCircuitData(RequestClientInfo()); | 11730 | info.agentcircuit = RequestClientInfo(); |
11710 | 11731 | ||
11711 | return info; | 11732 | return info; |
11712 | } | 11733 | } |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index e54d326..95a8e23 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | |||
@@ -182,9 +182,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
182 | m_maxRTO = maxRTO; | 182 | m_maxRTO = maxRTO; |
183 | 183 | ||
184 | // Create a token bucket throttle for this client that has the scene token bucket as a parent | 184 | // Create a token bucket throttle for this client that has the scene token bucket as a parent |
185 | m_throttleClient = new AdaptiveTokenBucket(parentThrottle, rates.TotalLimit); | 185 | m_throttleClient = new AdaptiveTokenBucket(parentThrottle, rates.Total, rates.AdaptiveThrottlesEnabled); |
186 | // Create a token bucket throttle for the total categary with the client bucket as a throttle | 186 | // Create a token bucket throttle for the total categary with the client bucket as a throttle |
187 | m_throttleCategory = new TokenBucket(m_throttleClient, rates.TotalLimit); | 187 | m_throttleCategory = new TokenBucket(m_throttleClient, 0); |
188 | // Create an array of token buckets for this clients different throttle categories | 188 | // Create an array of token buckets for this clients different throttle categories |
189 | m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; | 189 | m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; |
190 | 190 | ||
@@ -195,7 +195,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
195 | // Initialize the packet outboxes, where packets sit while they are waiting for tokens | 195 | // Initialize the packet outboxes, where packets sit while they are waiting for tokens |
196 | m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); | 196 | m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); |
197 | // Initialize the token buckets that control the throttling for each category | 197 | // Initialize the token buckets that control the throttling for each category |
198 | m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetLimit(type)); | 198 | m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetRate(type)); |
199 | } | 199 | } |
200 | 200 | ||
201 | // Default the retransmission timeout to three seconds | 201 | // Default the retransmission timeout to three seconds |
@@ -229,26 +229,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
229 | /// <returns>Information about the client connection</returns> | 229 | /// <returns>Information about the client connection</returns> |
230 | public ClientInfo GetClientInfo() | 230 | public ClientInfo GetClientInfo() |
231 | { | 231 | { |
232 | ///<mic> | ||
233 | TokenBucket tb; | ||
234 | |||
235 | tb = m_throttleClient.Parent; | ||
236 | m_log.WarnFormat("[TOKENS] {3}: Actual={0},Request={1},TotalRequest={2}",tb.DripRate,tb.RequestedDripRate,tb.TotalDripRequest,"ROOT"); | ||
237 | |||
238 | tb = m_throttleClient; | ||
239 | m_log.WarnFormat("[TOKENS] {3}: Actual={0},Request={1},TotalRequest={2}",tb.DripRate,tb.RequestedDripRate,tb.TotalDripRequest," CLIENT"); | ||
240 | |||
241 | tb = m_throttleCategory; | ||
242 | m_log.WarnFormat("[TOKENS] {3}: Actual={0},Request={1},TotalRequest={2}",tb.DripRate,tb.RequestedDripRate,tb.TotalDripRequest," CATEGORY"); | ||
243 | |||
244 | for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) | ||
245 | { | ||
246 | tb = m_throttleCategories[i]; | ||
247 | m_log.WarnFormat("[TOKENS] {4} <{0}:{1}>: Actual={2},Requested={3}",AgentID,i,tb.DripRate,tb.RequestedDripRate," BUCKET"); | ||
248 | } | ||
249 | |||
250 | ///</mic> | ||
251 | |||
252 | // TODO: This data structure is wrong in so many ways. Locking and copying the entire lists | 232 | // TODO: This data structure is wrong in so many ways. Locking and copying the entire lists |
253 | // of pending and needed ACKs for every client every time some method wants information about | 233 | // of pending and needed ACKs for every client every time some method wants information about |
254 | // this connection is a recipe for poor performance | 234 | // this connection is a recipe for poor performance |
@@ -260,12 +240,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
260 | info.landThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Land].DripRate; | 240 | info.landThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Land].DripRate; |
261 | info.windThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate; | 241 | info.windThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate; |
262 | info.cloudThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate; | 242 | info.cloudThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate; |
263 | // info.taskThrottle = m_throttleCategories[(int)ThrottleOutPacketType.State].DripRate + m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; | ||
264 | info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; | 243 | info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; |
265 | info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; | 244 | info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; |
266 | info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; | 245 | info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; |
267 | info.totalThrottle = info.resendThrottle + info.landThrottle + info.windThrottle + info.cloudThrottle + | 246 | info.totalThrottle = (int)m_throttleCategory.DripRate; |
268 | info.taskThrottle + info.assetThrottle + info.textureThrottle; | ||
269 | 247 | ||
270 | return info; | 248 | return info; |
271 | } | 249 | } |
@@ -352,8 +330,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
352 | int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); | 330 | int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); |
353 | // State is a subcategory of task that we allocate a percentage to | 331 | // State is a subcategory of task that we allocate a percentage to |
354 | int state = 0; | 332 | int state = 0; |
355 | // int state = (int)((float)task * STATE_TASK_PERCENTAGE); | ||
356 | // task -= state; | ||
357 | 333 | ||
358 | // Make sure none of the throttles are set below our packet MTU, | 334 | // Make sure none of the throttles are set below our packet MTU, |
359 | // otherwise a throttle could become permanently clogged | 335 | // otherwise a throttle could become permanently clogged |
@@ -364,19 +340,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
364 | task = Math.Max(task, LLUDPServer.MTU); | 340 | task = Math.Max(task, LLUDPServer.MTU); |
365 | texture = Math.Max(texture, LLUDPServer.MTU); | 341 | texture = Math.Max(texture, LLUDPServer.MTU); |
366 | asset = Math.Max(asset, LLUDPServer.MTU); | 342 | asset = Math.Max(asset, LLUDPServer.MTU); |
367 | state = Math.Max(state, LLUDPServer.MTU); | ||
368 | 343 | ||
369 | int total = resend + land + wind + cloud + task + texture + asset + state; | 344 | //int total = resend + land + wind + cloud + task + texture + asset; |
370 | 345 | //m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, Total={8}", | |
371 | //m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, State={8}, Total={9}", | 346 | // AgentID, resend, land, wind, cloud, task, texture, asset, total); |
372 | // AgentID, resend, land, wind, cloud, task, texture, asset, state, total); | ||
373 | 347 | ||
374 | // Update the token buckets with new throttle values | 348 | // Update the token buckets with new throttle values |
375 | TokenBucket bucket; | 349 | TokenBucket bucket; |
376 | 350 | ||
377 | bucket = m_throttleCategory; | ||
378 | bucket.RequestedDripRate = total; | ||
379 | |||
380 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend]; | 351 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend]; |
381 | bucket.RequestedDripRate = resend; | 352 | bucket.RequestedDripRate = resend; |
382 | 353 | ||
@@ -405,22 +376,38 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
405 | m_packedThrottles = null; | 376 | m_packedThrottles = null; |
406 | } | 377 | } |
407 | 378 | ||
408 | public byte[] GetThrottlesPacked() | 379 | public byte[] GetThrottlesPacked(float multiplier) |
409 | { | 380 | { |
410 | byte[] data = m_packedThrottles; | 381 | byte[] data = m_packedThrottles; |
411 | 382 | ||
412 | if (data == null) | 383 | if (data == null) |
413 | { | 384 | { |
385 | float rate; | ||
386 | |||
414 | data = new byte[7 * 4]; | 387 | data = new byte[7 * 4]; |
415 | int i = 0; | 388 | int i = 0; |
416 | 389 | ||
417 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Resend].RequestedDripRate), 0, data, i, 4); i += 4; | 390 | // multiply by 8 to convert bytes back to bits |
418 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Land].RequestedDripRate), 0, data, i, 4); i += 4; | 391 | rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Resend].RequestedDripRate * 8 * multiplier; |
419 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Wind].RequestedDripRate), 0, data, i, 4); i += 4; | 392 | Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; |
420 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].RequestedDripRate), 0, data, i, 4); i += 4; | 393 | |
421 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Task].RequestedDripRate), 0, data, i, 4); i += 4; | 394 | rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Land].RequestedDripRate * 8 * multiplier; |
422 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Texture].RequestedDripRate), 0, data, i, 4); i += 4; | 395 | Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; |
423 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Asset].RequestedDripRate), 0, data, i, 4); i += 4; | 396 | |
397 | rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Wind].RequestedDripRate * 8 * multiplier; | ||
398 | Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; | ||
399 | |||
400 | rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].RequestedDripRate * 8 * multiplier; | ||
401 | Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; | ||
402 | |||
403 | rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Task].RequestedDripRate * 8 * multiplier; | ||
404 | Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; | ||
405 | |||
406 | rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Texture].RequestedDripRate * 8 * multiplier; | ||
407 | Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; | ||
408 | |||
409 | rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Asset].RequestedDripRate * 8 * multiplier; | ||
410 | Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; | ||
424 | 411 | ||
425 | m_packedThrottles = data; | 412 | m_packedThrottles = data; |
426 | } | 413 | } |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index a1a58e5..ab6674d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | |||
@@ -672,7 +672,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
672 | if (packet.Header.AppendedAcks && packet.Header.AckList != null) | 672 | if (packet.Header.AppendedAcks && packet.Header.AckList != null) |
673 | { | 673 | { |
674 | for (int i = 0; i < packet.Header.AckList.Length; i++) | 674 | for (int i = 0; i < packet.Header.AckList.Length; i++) |
675 | udpClient.NeedAcks.Remove(packet.Header.AckList[i], now, packet.Header.Resent); | 675 | udpClient.NeedAcks.Acknowledge(packet.Header.AckList[i], now, packet.Header.Resent); |
676 | } | 676 | } |
677 | 677 | ||
678 | // Handle PacketAck packets | 678 | // Handle PacketAck packets |
@@ -681,7 +681,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
681 | PacketAckPacket ackPacket = (PacketAckPacket)packet; | 681 | PacketAckPacket ackPacket = (PacketAckPacket)packet; |
682 | 682 | ||
683 | for (int i = 0; i < ackPacket.Packets.Length; i++) | 683 | for (int i = 0; i < ackPacket.Packets.Length; i++) |
684 | udpClient.NeedAcks.Remove(ackPacket.Packets[i].ID, now, packet.Header.Resent); | 684 | udpClient.NeedAcks.Acknowledge(ackPacket.Packets[i].ID, now, packet.Header.Resent); |
685 | 685 | ||
686 | // We don't need to do anything else with PacketAck packets | 686 | // We don't need to do anything else with PacketAck packets |
687 | return; | 687 | return; |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs b/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs index aaf6e26..c9aac0b 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs | |||
@@ -52,30 +52,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
52 | public int Texture; | 52 | public int Texture; |
53 | /// <summary>Drip rate for asset packets</summary> | 53 | /// <summary>Drip rate for asset packets</summary> |
54 | public int Asset; | 54 | public int Asset; |
55 | /// <summary>Drip rate for state packets</summary> | 55 | |
56 | public int State; | ||
57 | /// <summary>Drip rate for the parent token bucket</summary> | 56 | /// <summary>Drip rate for the parent token bucket</summary> |
58 | public int Total; | 57 | public int Total; |
59 | 58 | ||
60 | /// <summary>Maximum burst rate for resent packets</summary> | 59 | /// <summary>Flag used to enable adaptive throttles</summary> |
61 | public int ResendLimit; | 60 | public bool AdaptiveThrottlesEnabled; |
62 | /// <summary>Maximum burst rate for land packets</summary> | 61 | |
63 | public int LandLimit; | ||
64 | /// <summary>Maximum burst rate for wind packets</summary> | ||
65 | public int WindLimit; | ||
66 | /// <summary>Maximum burst rate for cloud packets</summary> | ||
67 | public int CloudLimit; | ||
68 | /// <summary>Maximum burst rate for task (state and transaction) packets</summary> | ||
69 | public int TaskLimit; | ||
70 | /// <summary>Maximum burst rate for texture packets</summary> | ||
71 | public int TextureLimit; | ||
72 | /// <summary>Maximum burst rate for asset packets</summary> | ||
73 | public int AssetLimit; | ||
74 | /// <summary>Maximum burst rate for state packets</summary> | ||
75 | public int StateLimit; | ||
76 | /// <summary>Burst rate for the parent token bucket</summary> | ||
77 | public int TotalLimit; | ||
78 | |||
79 | /// <summary> | 62 | /// <summary> |
80 | /// Default constructor | 63 | /// Default constructor |
81 | /// </summary> | 64 | /// </summary> |
@@ -86,26 +69,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
86 | { | 69 | { |
87 | IConfig throttleConfig = config.Configs["ClientStack.LindenUDP"]; | 70 | IConfig throttleConfig = config.Configs["ClientStack.LindenUDP"]; |
88 | 71 | ||
89 | Resend = throttleConfig.GetInt("resend_default", 12500); | 72 | Resend = throttleConfig.GetInt("resend_default", 6625); |
90 | Land = throttleConfig.GetInt("land_default", 1000); | 73 | Land = throttleConfig.GetInt("land_default", 9125); |
91 | Wind = throttleConfig.GetInt("wind_default", 1000); | 74 | Wind = throttleConfig.GetInt("wind_default", 1750); |
92 | Cloud = throttleConfig.GetInt("cloud_default", 1000); | 75 | Cloud = throttleConfig.GetInt("cloud_default", 1750); |
93 | Task = throttleConfig.GetInt("task_default", 1000); | 76 | Task = throttleConfig.GetInt("task_default", 18500); |
94 | Texture = throttleConfig.GetInt("texture_default", 1000); | 77 | Texture = throttleConfig.GetInt("texture_default", 18500); |
95 | Asset = throttleConfig.GetInt("asset_default", 1000); | 78 | Asset = throttleConfig.GetInt("asset_default", 10500); |
96 | State = throttleConfig.GetInt("state_default", 1000); | ||
97 | |||
98 | ResendLimit = throttleConfig.GetInt("resend_limit", 18750); | ||
99 | LandLimit = throttleConfig.GetInt("land_limit", 29750); | ||
100 | WindLimit = throttleConfig.GetInt("wind_limit", 18750); | ||
101 | CloudLimit = throttleConfig.GetInt("cloud_limit", 18750); | ||
102 | TaskLimit = throttleConfig.GetInt("task_limit", 18750); | ||
103 | TextureLimit = throttleConfig.GetInt("texture_limit", 55750); | ||
104 | AssetLimit = throttleConfig.GetInt("asset_limit", 27500); | ||
105 | StateLimit = throttleConfig.GetInt("state_limit", 37000); | ||
106 | 79 | ||
107 | Total = throttleConfig.GetInt("client_throttle_max_bps", 0); | 80 | Total = throttleConfig.GetInt("client_throttle_max_bps", 0); |
108 | TotalLimit = Total; | 81 | |
82 | AdaptiveThrottlesEnabled = throttleConfig.GetBoolean("enable_adaptive_throttles", false); | ||
109 | } | 83 | } |
110 | catch (Exception) { } | 84 | catch (Exception) { } |
111 | } | 85 | } |
@@ -128,34 +102,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
128 | return Texture; | 102 | return Texture; |
129 | case ThrottleOutPacketType.Asset: | 103 | case ThrottleOutPacketType.Asset: |
130 | return Asset; | 104 | return Asset; |
131 | case ThrottleOutPacketType.State: | ||
132 | return State; | ||
133 | case ThrottleOutPacketType.Unknown: | ||
134 | default: | ||
135 | return 0; | ||
136 | } | ||
137 | } | ||
138 | |||
139 | public int GetLimit(ThrottleOutPacketType type) | ||
140 | { | ||
141 | switch (type) | ||
142 | { | ||
143 | case ThrottleOutPacketType.Resend: | ||
144 | return ResendLimit; | ||
145 | case ThrottleOutPacketType.Land: | ||
146 | return LandLimit; | ||
147 | case ThrottleOutPacketType.Wind: | ||
148 | return WindLimit; | ||
149 | case ThrottleOutPacketType.Cloud: | ||
150 | return CloudLimit; | ||
151 | case ThrottleOutPacketType.Task: | ||
152 | return TaskLimit; | ||
153 | case ThrottleOutPacketType.Texture: | ||
154 | return TextureLimit; | ||
155 | case ThrottleOutPacketType.Asset: | ||
156 | return AssetLimit; | ||
157 | case ThrottleOutPacketType.State: | ||
158 | return StateLimit; | ||
159 | case ThrottleOutPacketType.Unknown: | 105 | case ThrottleOutPacketType.Unknown: |
160 | default: | 106 | default: |
161 | return 0; | 107 | return 0; |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs b/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs index 4ee6d3a..29fd1a4 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs | |||
@@ -29,6 +29,8 @@ using System; | |||
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using OpenSim.Framework; | ||
33 | |||
32 | using log4net; | 34 | using log4net; |
33 | 35 | ||
34 | namespace OpenSim.Region.ClientStack.LindenUDP | 36 | namespace OpenSim.Region.ClientStack.LindenUDP |
@@ -177,7 +179,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
177 | RequestedDripRate = dripRate; | 179 | RequestedDripRate = dripRate; |
178 | // TotalDripRequest = dripRate; // this will be overwritten when a child node registers | 180 | // TotalDripRequest = dripRate; // this will be overwritten when a child node registers |
179 | // MaxBurst = (Int64)((double)dripRate * m_quantumsPerBurst); | 181 | // MaxBurst = (Int64)((double)dripRate * m_quantumsPerBurst); |
180 | m_lastDrip = Environment.TickCount & Int32.MaxValue; | 182 | m_lastDrip = Util.EnvironmentTickCount(); |
181 | } | 183 | } |
182 | 184 | ||
183 | #endregion Constructor | 185 | #endregion Constructor |
@@ -211,12 +213,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
211 | /// </summary> | 213 | /// </summary> |
212 | public void RegisterRequest(TokenBucket child, Int64 request) | 214 | public void RegisterRequest(TokenBucket child, Int64 request) |
213 | { | 215 | { |
214 | m_children[child] = request; | 216 | lock (m_children) |
215 | // m_totalDripRequest = m_children.Values.Sum(); | 217 | { |
218 | m_children[child] = request; | ||
219 | // m_totalDripRequest = m_children.Values.Sum(); | ||
216 | 220 | ||
217 | m_totalDripRequest = 0; | 221 | m_totalDripRequest = 0; |
218 | foreach (KeyValuePair<TokenBucket, Int64> cref in m_children) | 222 | foreach (KeyValuePair<TokenBucket, Int64> cref in m_children) |
219 | m_totalDripRequest += cref.Value; | 223 | m_totalDripRequest += cref.Value; |
224 | } | ||
220 | 225 | ||
221 | // Pass the new values up to the parent | 226 | // Pass the new values up to the parent |
222 | if (m_parent != null) | 227 | if (m_parent != null) |
@@ -229,12 +234,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
229 | /// </summary> | 234 | /// </summary> |
230 | public void UnregisterRequest(TokenBucket child) | 235 | public void UnregisterRequest(TokenBucket child) |
231 | { | 236 | { |
232 | m_children.Remove(child); | 237 | lock (m_children) |
233 | // m_totalDripRequest = m_children.Values.Sum(); | 238 | { |
239 | m_children.Remove(child); | ||
240 | // m_totalDripRequest = m_children.Values.Sum(); | ||
234 | 241 | ||
235 | m_totalDripRequest = 0; | 242 | m_totalDripRequest = 0; |
236 | foreach (KeyValuePair<TokenBucket, Int64> cref in m_children) | 243 | foreach (KeyValuePair<TokenBucket, Int64> cref in m_children) |
237 | m_totalDripRequest += cref.Value; | 244 | m_totalDripRequest += cref.Value; |
245 | } | ||
246 | |||
238 | 247 | ||
239 | // Pass the new values up to the parent | 248 | // Pass the new values up to the parent |
240 | if (m_parent != null) | 249 | if (m_parent != null) |
@@ -297,10 +306,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
297 | 306 | ||
298 | // Determine the interval over which we are adding tokens, never add | 307 | // Determine the interval over which we are adding tokens, never add |
299 | // more than a single quantum of tokens | 308 | // more than a single quantum of tokens |
300 | Int32 now = Environment.TickCount & Int32.MaxValue; | 309 | Int32 deltaMS = Math.Min(Util.EnvironmentTickCountSubtract(m_lastDrip), m_ticksPerQuantum); |
301 | Int32 deltaMS = Math.Min(now - m_lastDrip, m_ticksPerQuantum); | 310 | m_lastDrip = Util.EnvironmentTickCount(); |
302 | |||
303 | m_lastDrip = now; | ||
304 | 311 | ||
305 | // This can be 0 in the very unusual case that the timer wrapped | 312 | // This can be 0 in the very unusual case that the timer wrapped |
306 | // It can be 0 if we try add tokens at a sub-tick rate | 313 | // It can be 0 if we try add tokens at a sub-tick rate |
@@ -315,10 +322,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
315 | { | 322 | { |
316 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 323 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
317 | 324 | ||
318 | // <summary> | 325 | /// <summary> |
319 | // The minimum rate for flow control. | 326 | /// The minimum rate for flow control. Minimum drip rate is one |
320 | // </summary> | 327 | /// packet per second. Open the throttle to 15 packets per second |
321 | protected const Int64 m_minimumFlow = m_minimumDripRate * 10; | 328 | /// or about 160kbps. |
329 | /// </summary> | ||
330 | protected const Int64 m_minimumFlow = m_minimumDripRate * 15; | ||
322 | 331 | ||
323 | // <summary> | 332 | // <summary> |
324 | // The maximum rate for flow control. Drip rate can never be | 333 | // The maximum rate for flow control. Drip rate can never be |
@@ -331,6 +340,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
331 | set { m_maxDripRate = (value == 0 ? 0 : Math.Max(value,m_minimumFlow)); } | 340 | set { m_maxDripRate = (value == 0 ? 0 : Math.Max(value,m_minimumFlow)); } |
332 | } | 341 | } |
333 | 342 | ||
343 | private bool m_enabled = false; | ||
344 | |||
334 | // <summary> | 345 | // <summary> |
335 | // | 346 | // |
336 | // </summary> | 347 | // </summary> |
@@ -348,9 +359,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
348 | // <summary> | 359 | // <summary> |
349 | // | 360 | // |
350 | // </summary> | 361 | // </summary> |
351 | public AdaptiveTokenBucket(TokenBucket parent, Int64 maxDripRate) : base(parent,m_minimumFlow) | 362 | public AdaptiveTokenBucket(TokenBucket parent, Int64 maxDripRate, bool enabled) : base(parent,maxDripRate) |
352 | { | 363 | { |
353 | MaxDripRate = maxDripRate; | 364 | m_enabled = enabled; |
365 | |||
366 | if (m_enabled) | ||
367 | { | ||
368 | // m_log.DebugFormat("[TOKENBUCKET] Adaptive throttle enabled"); | ||
369 | MaxDripRate = maxDripRate; | ||
370 | AdjustedDripRate = m_minimumFlow; | ||
371 | } | ||
354 | } | 372 | } |
355 | 373 | ||
356 | // <summary> | 374 | // <summary> |
@@ -359,7 +377,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
359 | public void ExpirePackets(Int32 count) | 377 | public void ExpirePackets(Int32 count) |
360 | { | 378 | { |
361 | // m_log.WarnFormat("[ADAPTIVEBUCKET] drop {0} by {1} expired packets",AdjustedDripRate,count); | 379 | // m_log.WarnFormat("[ADAPTIVEBUCKET] drop {0} by {1} expired packets",AdjustedDripRate,count); |
362 | AdjustedDripRate = (Int64) (AdjustedDripRate / Math.Pow(2,count)); | 380 | if (m_enabled) |
381 | AdjustedDripRate = (Int64) (AdjustedDripRate / Math.Pow(2,count)); | ||
363 | } | 382 | } |
364 | 383 | ||
365 | // <summary> | 384 | // <summary> |
@@ -367,7 +386,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
367 | // </summary> | 386 | // </summary> |
368 | public void AcknowledgePackets(Int32 count) | 387 | public void AcknowledgePackets(Int32 count) |
369 | { | 388 | { |
370 | AdjustedDripRate = AdjustedDripRate + count; | 389 | if (m_enabled) |
390 | AdjustedDripRate = AdjustedDripRate + count; | ||
371 | } | 391 | } |
372 | } | 392 | } |
373 | } | 393 | } |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs index b170964..793aefe 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs | |||
@@ -65,7 +65,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
65 | /// <summary>Holds packets that need to be added to the unacknowledged list</summary> | 65 | /// <summary>Holds packets that need to be added to the unacknowledged list</summary> |
66 | private LocklessQueue<OutgoingPacket> m_pendingAdds = new LocklessQueue<OutgoingPacket>(); | 66 | private LocklessQueue<OutgoingPacket> m_pendingAdds = new LocklessQueue<OutgoingPacket>(); |
67 | /// <summary>Holds information about pending acknowledgements</summary> | 67 | /// <summary>Holds information about pending acknowledgements</summary> |
68 | private LocklessQueue<PendingAck> m_pendingRemoves = new LocklessQueue<PendingAck>(); | 68 | private LocklessQueue<PendingAck> m_pendingAcknowledgements = new LocklessQueue<PendingAck>(); |
69 | /// <summary>Holds information about pending removals</summary> | ||
70 | private LocklessQueue<uint> m_pendingRemoves = new LocklessQueue<uint>(); | ||
69 | 71 | ||
70 | /// <summary> | 72 | /// <summary> |
71 | /// Add an unacked packet to the collection | 73 | /// Add an unacked packet to the collection |
@@ -83,15 +85,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
83 | 85 | ||
84 | /// <summary> | 86 | /// <summary> |
85 | /// Marks a packet as acknowledged | 87 | /// Marks a packet as acknowledged |
88 | /// This method is used when an acknowledgement is received from the network for a previously | ||
89 | /// sent packet. Effects of removal this way are to update unacked byte count, adjust RTT | ||
90 | /// and increase throttle to the coresponding client. | ||
86 | /// </summary> | 91 | /// </summary> |
87 | /// <param name="sequenceNumber">Sequence number of the packet to | 92 | /// <param name="sequenceNumber">Sequence number of the packet to |
88 | /// acknowledge</param> | 93 | /// acknowledge</param> |
89 | /// <param name="currentTime">Current value of Environment.TickCount</param> | 94 | /// <param name="currentTime">Current value of Environment.TickCount</param> |
90 | /// <remarks>This does not immediately acknowledge the packet, it only | 95 | /// <remarks>This does not immediately acknowledge the packet, it only |
91 | /// queues the ack so it can be handled in a thread-safe way later</remarks> | 96 | /// queues the ack so it can be handled in a thread-safe way later</remarks> |
92 | public void Remove(uint sequenceNumber, int currentTime, bool fromResend) | 97 | public void Acknowledge(uint sequenceNumber, int currentTime, bool fromResend) |
93 | { | 98 | { |
94 | m_pendingRemoves.Enqueue(new PendingAck(sequenceNumber, currentTime, fromResend)); | 99 | m_pendingAcknowledgements.Enqueue(new PendingAck(sequenceNumber, currentTime, fromResend)); |
100 | } | ||
101 | |||
102 | /// <summary> | ||
103 | /// Marks a packet as no longer needing acknowledgement without a received acknowledgement. | ||
104 | /// This method is called when a packet expires and we no longer need an acknowledgement. | ||
105 | /// When some reliable packet types expire, they are handled in a way other than simply | ||
106 | /// resending them. The only effect of removal this way is to update unacked byte count. | ||
107 | /// </summary> | ||
108 | /// <param name="sequenceNumber">Sequence number of the packet to | ||
109 | /// acknowledge</param> | ||
110 | /// <remarks>The does not immediately remove the packet, it only queues the removal | ||
111 | /// so it can be handled in a thread safe way later</remarks> | ||
112 | public void Remove(uint sequenceNumber) | ||
113 | { | ||
114 | m_pendingRemoves.Enqueue(sequenceNumber); | ||
95 | } | 115 | } |
96 | 116 | ||
97 | /// <summary> | 117 | /// <summary> |
@@ -151,15 +171,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
151 | m_packets[pendingAdd.SequenceNumber] = pendingAdd; | 171 | m_packets[pendingAdd.SequenceNumber] = pendingAdd; |
152 | 172 | ||
153 | // Process all the pending removes, including updating statistics and round-trip times | 173 | // Process all the pending removes, including updating statistics and round-trip times |
154 | PendingAck pendingRemove; | 174 | PendingAck pendingAcknowledgement; |
155 | OutgoingPacket ackedPacket; | 175 | while (m_pendingAcknowledgements.TryDequeue(out pendingAcknowledgement)) |
156 | while (m_pendingRemoves.TryDequeue(out pendingRemove)) | ||
157 | { | 176 | { |
158 | if (m_packets.TryGetValue(pendingRemove.SequenceNumber, out ackedPacket)) | 177 | OutgoingPacket ackedPacket; |
178 | if (m_packets.TryGetValue(pendingAcknowledgement.SequenceNumber, out ackedPacket)) | ||
159 | { | 179 | { |
160 | if (ackedPacket != null) | 180 | if (ackedPacket != null) |
161 | { | 181 | { |
162 | m_packets.Remove(pendingRemove.SequenceNumber); | 182 | m_packets.Remove(pendingAcknowledgement.SequenceNumber); |
163 | 183 | ||
164 | // As with other network applications, assume that an acknowledged packet is an | 184 | // As with other network applications, assume that an acknowledged packet is an |
165 | // indication that the network can handle a little more load, speed up the transmission | 185 | // indication that the network can handle a little more load, speed up the transmission |
@@ -168,16 +188,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
168 | // Update stats | 188 | // Update stats |
169 | Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength); | 189 | Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength); |
170 | 190 | ||
171 | if (!pendingRemove.FromResend) | 191 | if (!pendingAcknowledgement.FromResend) |
172 | { | 192 | { |
173 | // Calculate the round-trip time for this packet and its ACK | 193 | // Calculate the round-trip time for this packet and its ACK |
174 | int rtt = pendingRemove.RemoveTime - ackedPacket.TickCount; | 194 | int rtt = pendingAcknowledgement.RemoveTime - ackedPacket.TickCount; |
175 | if (rtt > 0) | 195 | if (rtt > 0) |
176 | ackedPacket.Client.UpdateRoundTrip(rtt); | 196 | ackedPacket.Client.UpdateRoundTrip(rtt); |
177 | } | 197 | } |
178 | } | 198 | } |
179 | } | 199 | } |
180 | } | 200 | } |
201 | |||
202 | uint pendingRemove; | ||
203 | while(m_pendingRemoves.TryDequeue(out pendingRemove)) | ||
204 | { | ||
205 | OutgoingPacket removedPacket; | ||
206 | if (m_packets.TryGetValue(pendingRemove, out removedPacket)) | ||
207 | { | ||
208 | if (removedPacket != null) | ||
209 | { | ||
210 | m_packets.Remove(pendingRemove); | ||
211 | |||
212 | // Update stats | ||
213 | Interlocked.Add(ref removedPacket.Client.UnackedBytes, -removedPacket.Buffer.DataLength); | ||
214 | } | ||
215 | } | ||
216 | } | ||
181 | } | 217 | } |
182 | } | 218 | } |
183 | } \ No newline at end of file | 219 | } |
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs index 4255c79..ff4ec4c 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs | |||
@@ -41,8 +41,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
41 | /// </summary> | 41 | /// </summary> |
42 | public class AgentAssetTransactions | 42 | public class AgentAssetTransactions |
43 | { | 43 | { |
44 | // private static readonly ILog m_log = LogManager.GetLogger( | 44 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
45 | // MethodBase.GetCurrentMethod().DeclaringType); | ||
46 | 45 | ||
47 | // Fields | 46 | // Fields |
48 | private bool m_dumpAssetsToFile; | 47 | private bool m_dumpAssetsToFile; |
@@ -149,6 +148,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
149 | 148 | ||
150 | if (asset != null) | 149 | if (asset != null) |
151 | { | 150 | { |
151 | // m_log.DebugFormat( | ||
152 | // "[AGENT ASSETS TRANSACTIONS]: Updating item {0} in {1} for transaction {2}", | ||
153 | // item.Name, part.Name, transactionID); | ||
154 | |||
152 | asset.FullID = UUID.Random(); | 155 | asset.FullID = UUID.Random(); |
153 | asset.Name = item.Name; | 156 | asset.Name = item.Name; |
154 | asset.Description = item.Description; | 157 | asset.Description = item.Description; |
@@ -156,8 +159,6 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
156 | item.AssetID = asset.FullID; | 159 | item.AssetID = asset.FullID; |
157 | 160 | ||
158 | m_Scene.AssetService.Store(asset); | 161 | m_Scene.AssetService.Store(asset); |
159 | |||
160 | part.Inventory.UpdateInventoryItem(item); | ||
161 | } | 162 | } |
162 | } | 163 | } |
163 | } | 164 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index dc33dbb..47476a9 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -571,14 +571,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
571 | /// <param name="sp"></param> | 571 | /// <param name="sp"></param> |
572 | /// <param name="so"></param> | 572 | /// <param name="so"></param> |
573 | /// <param name="attachmentpoint"></param> | 573 | /// <param name="attachmentpoint"></param> |
574 | /// <param name="AttachOffset"></param> | 574 | /// <param name="attachOffset"></param> |
575 | /// <param name="silent"></param> | 575 | /// <param name="silent"></param> |
576 | protected void AttachToAgent(ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 AttachOffset, bool silent) | 576 | protected void AttachToAgent(ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) |
577 | { | 577 | { |
578 | // don't attach attachments to child agents | ||
579 | if (avatar.IsChildAgent) return; | ||
580 | 578 | ||
581 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1}", Name, avatar.Name); | 579 | m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", Name, avatar.Name, |
580 | attachmentpoint, attachOffset, so.RootPart.AttachedPos); | ||
582 | 581 | ||
583 | so.DetachFromBackup(); | 582 | so.DetachFromBackup(); |
584 | 583 | ||
@@ -599,8 +598,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
599 | so.RootPart.PhysActor = null; | 598 | so.RootPart.PhysActor = null; |
600 | } | 599 | } |
601 | 600 | ||
602 | so.AbsolutePosition = AttachOffset; | 601 | so.AbsolutePosition = attachOffset; |
603 | so.RootPart.AttachedPos = AttachOffset; | 602 | so.RootPart.AttachedPos = attachOffset; |
604 | so.RootPart.IsAttachment = true; | 603 | so.RootPart.IsAttachment = true; |
605 | 604 | ||
606 | so.RootPart.SetParentLocalId(avatar.LocalId); | 605 | so.RootPart.SetParentLocalId(avatar.LocalId); |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 138556f..e2bdee0 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -286,11 +286,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
286 | } | 286 | } |
287 | 287 | ||
288 | string reason; | 288 | string reason; |
289 | if (!m_aScene.SimulationService.QueryAccess(finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out reason)) | 289 | string version; |
290 | if (!m_aScene.SimulationService.QueryAccess(finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) | ||
290 | { | 291 | { |
291 | sp.ControllingClient.SendTeleportFailed("Teleport failed: " + reason); | 292 | sp.ControllingClient.SendTeleportFailed("Teleport failed: " + reason); |
292 | return; | 293 | return; |
293 | } | 294 | } |
295 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); | ||
294 | 296 | ||
295 | sp.ControllingClient.SendTeleportStart(teleportFlags); | 297 | sp.ControllingClient.SendTeleportStart(teleportFlags); |
296 | 298 | ||
@@ -372,20 +374,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
372 | capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); | 374 | capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); |
373 | } | 375 | } |
374 | 376 | ||
375 | // Expect avatar crossing is a heavy-duty function at the destination. | ||
376 | // That is where MakeRoot is called, which fetches appearance and inventory. | ||
377 | // Plus triggers OnMakeRoot, which spawns a series of asynchronous updates. | ||
378 | //m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, | ||
379 | // position, false); | ||
380 | |||
381 | //{ | ||
382 | // avatar.ControllingClient.SendTeleportFailed("Problem with destination."); | ||
383 | // // We should close that agent we just created over at destination... | ||
384 | // List<ulong> lst = new List<ulong>(); | ||
385 | // lst.Add(reg.RegionHandle); | ||
386 | // SendCloseChildAgentAsync(avatar.UUID, lst); | ||
387 | // return; | ||
388 | //} | ||
389 | 377 | ||
390 | SetInTransit(sp.UUID); | 378 | SetInTransit(sp.UUID); |
391 | 379 | ||
@@ -427,7 +415,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
427 | 415 | ||
428 | // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which | 416 | // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which |
429 | // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation | 417 | // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation |
430 | // that the client contacted the destination before we send the attachments and close things here. | 418 | // that the client contacted the destination before we close things here. |
431 | if (!WaitForCallback(sp.UUID)) | 419 | if (!WaitForCallback(sp.UUID)) |
432 | { | 420 | { |
433 | m_log.WarnFormat( | 421 | m_log.WarnFormat( |
@@ -438,14 +426,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
438 | return; | 426 | return; |
439 | } | 427 | } |
440 | 428 | ||
441 | // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it | 429 | // For backwards compatibility |
442 | CrossAttachmentsIntoNewRegion(finalDestination, sp, true); | 430 | if (version == "Unknown" || version == string.Empty) |
431 | { | ||
432 | // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it | ||
433 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old simulator, sending attachments one by one..."); | ||
434 | CrossAttachmentsIntoNewRegion(finalDestination, sp, true); | ||
435 | } | ||
436 | |||
437 | // May need to logout or other cleanup | ||
438 | AgentHasMovedAway(sp, logout); | ||
443 | 439 | ||
444 | // Well, this is it. The agent is over there. | 440 | // Well, this is it. The agent is over there. |
445 | KillEntity(sp.Scene, sp.LocalId); | 441 | KillEntity(sp.Scene, sp.LocalId); |
446 | 442 | ||
447 | // May need to logout or other cleanup | ||
448 | AgentHasMovedAway(sp.ControllingClient.SessionId, logout); | ||
449 | 443 | ||
450 | // Now let's make it officially a child agent | 444 | // Now let's make it officially a child agent |
451 | sp.MakeChildAgent(); | 445 | sp.MakeChildAgent(); |
@@ -486,7 +480,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
486 | 480 | ||
487 | // Fail. Reset it back | 481 | // Fail. Reset it back |
488 | sp.IsChildAgent = false; | 482 | sp.IsChildAgent = false; |
489 | 483 | ReInstantiateScripts(sp); | |
490 | ResetFromTransit(sp.UUID); | 484 | ResetFromTransit(sp.UUID); |
491 | 485 | ||
492 | EnableChildAgents(sp); | 486 | EnableChildAgents(sp); |
@@ -514,8 +508,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
514 | 508 | ||
515 | } | 509 | } |
516 | 510 | ||
517 | protected virtual void AgentHasMovedAway(UUID sessionID, bool logout) | 511 | protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout) |
518 | { | 512 | { |
513 | foreach (SceneObjectGroup sop in sp.Attachments) | ||
514 | { | ||
515 | sop.Scene.DeleteSceneObject(sop, true); | ||
516 | } | ||
517 | sp.Attachments.Clear(); | ||
519 | } | 518 | } |
520 | 519 | ||
521 | protected void KillEntity(Scene scene, uint localID) | 520 | protected void KillEntity(Scene scene, uint localID) |
@@ -803,7 +802,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
803 | GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); | 802 | GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); |
804 | 803 | ||
805 | string reason; | 804 | string reason; |
806 | if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out reason)) | 805 | string version; |
806 | if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason)) | ||
807 | { | 807 | { |
808 | agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); | 808 | agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); |
809 | if (r == null) | 809 | if (r == null) |
@@ -823,7 +823,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
823 | agent.InTransit(); | 823 | agent.InTransit(); |
824 | 824 | ||
825 | CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; | 825 | CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; |
826 | d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, CrossAgentToNewRegionCompleted, d); | 826 | d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); |
827 | 827 | ||
828 | return true; | 828 | return true; |
829 | } | 829 | } |
@@ -880,17 +880,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
880 | icon.EndInvoke(iar); | 880 | icon.EndInvoke(iar); |
881 | } | 881 | } |
882 | 882 | ||
883 | public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying); | 883 | public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); |
884 | 884 | ||
885 | /// <summary> | 885 | /// <summary> |
886 | /// This Closes child agents on neighbouring regions | 886 | /// This Closes child agents on neighbouring regions |
887 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. | 887 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. |
888 | /// </summary> | 888 | /// </summary> |
889 | protected ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying) | 889 | protected ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version) |
890 | { | 890 | { |
891 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); | 891 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); |
892 | 892 | ||
893 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3}", agent.Firstname, agent.Lastname, neighbourx, neighboury); | 893 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", agent.Firstname, agent.Lastname, neighbourx, neighboury, version); |
894 | 894 | ||
895 | Scene m_scene = agent.Scene; | 895 | Scene m_scene = agent.Scene; |
896 | 896 | ||
@@ -953,6 +953,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
953 | if (!WaitForCallback(agent.UUID)) | 953 | if (!WaitForCallback(agent.UUID)) |
954 | { | 954 | { |
955 | m_log.Debug("[ENTITY TRANSFER MODULE]: Callback never came in crossing agent"); | 955 | m_log.Debug("[ENTITY TRANSFER MODULE]: Callback never came in crossing agent"); |
956 | ReInstantiateScripts(agent); | ||
956 | ResetFromTransit(agent.UUID); | 957 | ResetFromTransit(agent.UUID); |
957 | 958 | ||
958 | // Yikes! We should just have a ref to scene here. | 959 | // Yikes! We should just have a ref to scene here. |
@@ -968,7 +969,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
968 | agent.SendOtherAgentsAvatarDataToMe(); | 969 | agent.SendOtherAgentsAvatarDataToMe(); |
969 | agent.SendOtherAgentsAppearanceToMe(); | 970 | agent.SendOtherAgentsAppearanceToMe(); |
970 | 971 | ||
971 | CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); | 972 | // Backwards compatibility |
973 | if (version == "Unknown" || version == string.Empty) | ||
974 | { | ||
975 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old neighbor, passing attachments one by one..."); | ||
976 | CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); | ||
977 | } | ||
978 | |||
979 | AgentHasMovedAway(agent, false); | ||
972 | 980 | ||
973 | // the user may change their profile information in other region, | 981 | // the user may change their profile information in other region, |
974 | // so the userinfo in UserProfileCache is not reliable any more, delete it | 982 | // so the userinfo in UserProfileCache is not reliable any more, delete it |
@@ -1775,7 +1783,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1775 | return false; | 1783 | return false; |
1776 | } | 1784 | } |
1777 | 1785 | ||
1778 | 1786 | protected void ReInstantiateScripts(ScenePresence sp) | |
1787 | { | ||
1788 | sp.Attachments.ForEach(delegate(SceneObjectGroup sog) | ||
1789 | { | ||
1790 | sog.CreateScriptInstances(0, false, sp.Scene.DefaultScriptEngine, 0); | ||
1791 | sog.ResumeScripts(); | ||
1792 | }); | ||
1793 | } | ||
1779 | #endregion | 1794 | #endregion |
1780 | 1795 | ||
1781 | } | 1796 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 5a80100..1ccbcfd 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs | |||
@@ -142,11 +142,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
142 | return false; | 142 | return false; |
143 | } | 143 | } |
144 | 144 | ||
145 | protected override void AgentHasMovedAway(UUID sessionID, bool logout) | 145 | protected override void AgentHasMovedAway(ScenePresence sp, bool logout) |
146 | { | 146 | { |
147 | base.AgentHasMovedAway(sp, logout); | ||
147 | if (logout) | 148 | if (logout) |
148 | // Log them out of this grid | 149 | // Log them out of this grid |
149 | m_aScene.PresenceService.LogoutAgent(sessionID); | 150 | m_aScene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId); |
150 | } | 151 | } |
151 | 152 | ||
152 | protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) | 153 | protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index 41dbffb..9714c36 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs | |||
@@ -41,6 +41,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
41 | public class LocalSimulationConnectorModule : ISharedRegionModule, ISimulationService | 41 | public class LocalSimulationConnectorModule : ISharedRegionModule, ISimulationService |
42 | { | 42 | { |
43 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 43 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
44 | // Version of this service | ||
45 | private const string m_Version = "SIMULATION/0.1"; | ||
46 | |||
44 | private List<Scene> m_sceneList = new List<Scene>(); | 47 | private List<Scene> m_sceneList = new List<Scene>(); |
45 | 48 | ||
46 | private IEntityTransferModule m_AgentTransferModule; | 49 | private IEntityTransferModule m_AgentTransferModule; |
@@ -257,9 +260,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
257 | return false; | 260 | return false; |
258 | } | 261 | } |
259 | 262 | ||
260 | public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string reason) | 263 | public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason) |
261 | { | 264 | { |
262 | reason = "Communications failure"; | 265 | reason = "Communications failure"; |
266 | version = m_Version; | ||
263 | if (destination == null) | 267 | if (destination == null) |
264 | return false; | 268 | return false; |
265 | 269 | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs index 97833f3..5564067 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs | |||
@@ -229,19 +229,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
229 | 229 | ||
230 | } | 230 | } |
231 | 231 | ||
232 | public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string reason) | 232 | public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason) |
233 | { | 233 | { |
234 | reason = "Communications failure"; | 234 | reason = "Communications failure"; |
235 | version = "Unknown"; | ||
235 | if (destination == null) | 236 | if (destination == null) |
236 | return false; | 237 | return false; |
237 | 238 | ||
238 | // Try local first | 239 | // Try local first |
239 | if (m_localBackend.QueryAccess(destination, id, position, out reason)) | 240 | if (m_localBackend.QueryAccess(destination, id, position, out version, out reason)) |
240 | return true; | 241 | return true; |
241 | 242 | ||
242 | // else do the remote thing | 243 | // else do the remote thing |
243 | if (!m_localBackend.IsLocalRegion(destination.RegionHandle)) | 244 | if (!m_localBackend.IsLocalRegion(destination.RegionHandle)) |
244 | return m_remoteConnector.QueryAccess(destination, id, position, out reason); | 245 | return m_remoteConnector.QueryAccess(destination, id, position, out version, out reason); |
245 | 246 | ||
246 | return false; | 247 | return false; |
247 | 248 | ||
diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index 17b2da1..0f35894 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs | |||
@@ -88,7 +88,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
88 | 88 | ||
89 | // If this is an update for our own avatar give it the highest priority | 89 | // If this is an update for our own avatar give it the highest priority |
90 | if (client.AgentId == entity.UUID) | 90 | if (client.AgentId == entity.UUID) |
91 | return PriorityQueue.ImmediateQueue; | 91 | return 0; |
92 | 92 | ||
93 | uint priority; | 93 | uint priority; |
94 | 94 | ||
@@ -119,16 +119,40 @@ namespace OpenSim.Region.Framework.Scenes | |||
119 | 119 | ||
120 | private uint GetPriorityByTime(IClientAPI client, ISceneEntity entity) | 120 | private uint GetPriorityByTime(IClientAPI client, ISceneEntity entity) |
121 | { | 121 | { |
122 | return 1; | 122 | // And anything attached to this avatar gets top priority as well |
123 | if (entity is SceneObjectPart) | ||
124 | { | ||
125 | SceneObjectPart sop = (SceneObjectPart)entity; | ||
126 | if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.RootPart.AttachedAvatar) | ||
127 | return 1; | ||
128 | } | ||
129 | |||
130 | return PriorityQueue.NumberOfImmediateQueues; // first queue past the immediate queues | ||
123 | } | 131 | } |
124 | 132 | ||
125 | private uint GetPriorityByDistance(IClientAPI client, ISceneEntity entity) | 133 | private uint GetPriorityByDistance(IClientAPI client, ISceneEntity entity) |
126 | { | 134 | { |
135 | // And anything attached to this avatar gets top priority as well | ||
136 | if (entity is SceneObjectPart) | ||
137 | { | ||
138 | SceneObjectPart sop = (SceneObjectPart)entity; | ||
139 | if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.RootPart.AttachedAvatar) | ||
140 | return 1; | ||
141 | } | ||
142 | |||
127 | return ComputeDistancePriority(client,entity,false); | 143 | return ComputeDistancePriority(client,entity,false); |
128 | } | 144 | } |
129 | 145 | ||
130 | private uint GetPriorityByFrontBack(IClientAPI client, ISceneEntity entity) | 146 | private uint GetPriorityByFrontBack(IClientAPI client, ISceneEntity entity) |
131 | { | 147 | { |
148 | // And anything attached to this avatar gets top priority as well | ||
149 | if (entity is SceneObjectPart) | ||
150 | { | ||
151 | SceneObjectPart sop = (SceneObjectPart)entity; | ||
152 | if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.RootPart.AttachedAvatar) | ||
153 | return 1; | ||
154 | } | ||
155 | |||
132 | return ComputeDistancePriority(client,entity,true); | 156 | return ComputeDistancePriority(client,entity,true); |
133 | } | 157 | } |
134 | 158 | ||
@@ -143,18 +167,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
143 | { | 167 | { |
144 | if (!presence.IsChildAgent) | 168 | if (!presence.IsChildAgent) |
145 | { | 169 | { |
170 | // All avatars other than our own go into pqueue 1 | ||
171 | if (entity is ScenePresence) | ||
172 | return 1; | ||
173 | |||
146 | if (entity is SceneObjectPart) | 174 | if (entity is SceneObjectPart) |
147 | { | 175 | { |
176 | // Attachments are high priority, | ||
177 | if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment) | ||
178 | return 1; | ||
179 | |||
148 | // Non physical prims are lower priority than physical prims | 180 | // Non physical prims are lower priority than physical prims |
149 | PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor; | 181 | PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor; |
150 | if (physActor == null || !physActor.IsPhysical) | 182 | if (physActor == null || !physActor.IsPhysical) |
151 | pqueue++; | 183 | pqueue++; |
152 | |||
153 | // Attachments are high priority, | ||
154 | // MIC: shouldn't these already be in the highest priority queue already | ||
155 | // since their root position is same as the avatars? | ||
156 | if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment) | ||
157 | pqueue = 1; | ||
158 | } | 184 | } |
159 | } | 185 | } |
160 | } | 186 | } |
@@ -205,8 +231,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
205 | 231 | ||
206 | // And convert the distance to a priority queue, this computation gives queues | 232 | // And convert the distance to a priority queue, this computation gives queues |
207 | // at 10, 20, 40, 80, 160, 320, 640, and 1280m | 233 | // at 10, 20, 40, 80, 160, 320, 640, and 1280m |
208 | uint pqueue = 1; | 234 | uint pqueue = PriorityQueue.NumberOfImmediateQueues; |
209 | for (int i = 0; i < 8; i++) | 235 | uint queues = PriorityQueue.NumberOfQueues - PriorityQueue.NumberOfImmediateQueues; |
236 | |||
237 | for (int i = 0; i < queues - 1; i++) | ||
210 | { | 238 | { |
211 | if (distance < 10 * Math.Pow(2.0,i)) | 239 | if (distance < 10 * Math.Pow(2.0,i)) |
212 | break; | 240 | break; |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index f41c6b9..5b7a297 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | |||
@@ -1449,6 +1449,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
1449 | } | 1449 | } |
1450 | else // Updating existing item with new perms etc | 1450 | else // Updating existing item with new perms etc |
1451 | { | 1451 | { |
1452 | // m_log.DebugFormat( | ||
1453 | // "[PRIM INVENTORY]: Updating item {0} in {1} for UpdateTaskInventory()", | ||
1454 | // currentItem.Name, part.Name); | ||
1455 | |||
1452 | IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>(); | 1456 | IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>(); |
1453 | if (agentTransactions != null) | 1457 | if (agentTransactions != null) |
1454 | { | 1458 | { |
@@ -2089,6 +2093,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2089 | if (rot != null) | 2093 | if (rot != null) |
2090 | group.UpdateGroupRotationR((Quaternion)rot); | 2094 | group.UpdateGroupRotationR((Quaternion)rot); |
2091 | 2095 | ||
2096 | // TODO: This needs to be refactored with the similar code in | ||
2097 | // SceneGraph.AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, Vector3 pos, Quaternion rot, Vector3 vel) | ||
2098 | // possibly by allowing this method to take a null rotation. | ||
2099 | if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical && vel != Vector3.Zero) | ||
2100 | group.RootPart.ApplyImpulse((vel * group.GetMass()), false); | ||
2101 | |||
2092 | // We can only call this after adding the scene object, since the scene object references the scene | 2102 | // We can only call this after adding the scene object, since the scene object references the scene |
2093 | // to find out if scripts should be activated at all. | 2103 | // to find out if scripts should be activated at all. |
2094 | group.CreateScriptInstances(param, true, DefaultScriptEngine, 3); | 2104 | group.CreateScriptInstances(param, true, DefaultScriptEngine, 3); |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 4d619c3..1d06889 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -1255,7 +1255,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1255 | 1255 | ||
1256 | // Increment the frame counter | 1256 | // Increment the frame counter |
1257 | ++Frame; | 1257 | ++Frame; |
1258 | |||
1259 | try | 1258 | try |
1260 | { | 1259 | { |
1261 | // Check if any objects have reached their targets | 1260 | // Check if any objects have reached their targets |
@@ -2383,7 +2382,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2383 | /// <returns></returns> | 2382 | /// <returns></returns> |
2384 | public bool IncomingCreateObject(ISceneObject sog) | 2383 | public bool IncomingCreateObject(ISceneObject sog) |
2385 | { | 2384 | { |
2386 | //m_log.Debug(" >>> IncomingCreateObject(sog) <<< " + ((SceneObjectGroup)sog).AbsolutePosition + " deleted? " + ((SceneObjectGroup)sog).IsDeleted); | 2385 | //m_log.DebugFormat(" >>> IncomingCreateObject(sog) <<< {0} deleted? {1} isAttach? {2}", ((SceneObjectGroup)sog).AbsolutePosition, |
2386 | // ((SceneObjectGroup)sog).IsDeleted, ((SceneObjectGroup)sog).RootPart.IsAttachment); | ||
2387 | |||
2387 | SceneObjectGroup newObject; | 2388 | SceneObjectGroup newObject; |
2388 | try | 2389 | try |
2389 | { | 2390 | { |
@@ -2401,9 +2402,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2401 | return false; | 2402 | return false; |
2402 | } | 2403 | } |
2403 | 2404 | ||
2404 | newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); | 2405 | // For attachments, we need to wait until the agent is root |
2405 | 2406 | // before we restart the scripts, or else some functions won't work. | |
2406 | newObject.ResumeScripts(); | 2407 | if (!newObject.IsAttachment) |
2408 | { | ||
2409 | newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); | ||
2410 | newObject.ResumeScripts(); | ||
2411 | } | ||
2407 | 2412 | ||
2408 | // Do this as late as possible so that listeners have full access to the incoming object | 2413 | // Do this as late as possible so that listeners have full access to the incoming object |
2409 | EventManager.TriggerOnIncomingSceneObject(newObject); | 2414 | EventManager.TriggerOnIncomingSceneObject(newObject); |
@@ -2540,17 +2545,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2540 | ScenePresence sp = GetScenePresence(sog.OwnerID); | 2545 | ScenePresence sp = GetScenePresence(sog.OwnerID); |
2541 | 2546 | ||
2542 | if (sp != null) | 2547 | if (sp != null) |
2543 | { | 2548 | return sp.GetStateSource(); |
2544 | AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(sp.UUID); | ||
2545 | |||
2546 | if (aCircuit != null && (aCircuit.teleportFlags != (uint)TeleportFlags.Default)) | ||
2547 | { | ||
2548 | // This will get your attention | ||
2549 | //m_log.Error("[XXX] Triggering CHANGED_TELEPORT"); | ||
2550 | 2549 | ||
2551 | return 5; // StateSource.Teleporting | ||
2552 | } | ||
2553 | } | ||
2554 | return 2; // StateSource.PrimCrossing | 2550 | return 2; // StateSource.PrimCrossing |
2555 | } | 2551 | } |
2556 | 2552 | ||
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 3e0241c..56680df 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | |||
@@ -884,6 +884,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
884 | 884 | ||
885 | if (m_items.ContainsKey(item.ItemID)) | 885 | if (m_items.ContainsKey(item.ItemID)) |
886 | { | 886 | { |
887 | // m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); | ||
888 | |||
887 | item.ParentID = m_part.UUID; | 889 | item.ParentID = m_part.UUID; |
888 | item.ParentPartID = m_part.UUID; | 890 | item.ParentPartID = m_part.UUID; |
889 | 891 | ||
@@ -899,6 +901,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
899 | m_inventorySerial++; | 901 | m_inventorySerial++; |
900 | if (fireScriptEvents) | 902 | if (fireScriptEvents) |
901 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 903 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
904 | |||
902 | if (considerChanged) | 905 | if (considerChanged) |
903 | { | 906 | { |
904 | HasInventoryChanged = true; | 907 | HasInventoryChanged = true; |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 9e48447..cdf8366 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -924,6 +924,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
924 | 924 | ||
925 | //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); | 925 | //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); |
926 | 926 | ||
927 | bool wasChild = m_isChildAgent; | ||
928 | m_isChildAgent = false; | ||
929 | |||
927 | IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); | 930 | IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); |
928 | if (gm != null) | 931 | if (gm != null) |
929 | m_grouptitle = gm.GetGroupTitle(m_uuid); | 932 | m_grouptitle = gm.GetGroupTitle(m_uuid); |
@@ -1069,14 +1072,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1069 | // Animator.SendAnimPack(); | 1072 | // Animator.SendAnimPack(); |
1070 | 1073 | ||
1071 | m_scene.SwapRootAgentCount(false); | 1074 | m_scene.SwapRootAgentCount(false); |
1072 | 1075 | ||
1073 | //CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(m_uuid); | 1076 | // The initial login scene presence is already root when it gets here |
1074 | //if (userInfo != null) | 1077 | // and it has already rezzed the attachments and started their scripts. |
1075 | // userInfo.FetchInventory(); | 1078 | // We do the following only for non-login agents, because their scripts |
1076 | //else | 1079 | // haven't started yet. |
1077 | // m_log.ErrorFormat("[SCENE]: Could not find user info for {0} when making it a root agent", m_uuid); | 1080 | if (wasChild) |
1078 | 1081 | { | |
1079 | m_isChildAgent = false; | 1082 | m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); |
1083 | // Resume scripts | ||
1084 | Attachments.ForEach(delegate(SceneObjectGroup sog) | ||
1085 | { | ||
1086 | sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); | ||
1087 | sog.ResumeScripts(); | ||
1088 | }); | ||
1089 | } | ||
1080 | 1090 | ||
1081 | // send the animations of the other presences to me | 1091 | // send the animations of the other presences to me |
1082 | m_scene.ForEachScenePresence(delegate(ScenePresence presence) | 1092 | m_scene.ForEachScenePresence(delegate(ScenePresence presence) |
@@ -1088,6 +1098,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
1088 | m_scene.EventManager.TriggerOnMakeRootAgent(this); | 1098 | m_scene.EventManager.TriggerOnMakeRootAgent(this); |
1089 | } | 1099 | } |
1090 | 1100 | ||
1101 | public int GetStateSource() | ||
1102 | { | ||
1103 | AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(UUID); | ||
1104 | |||
1105 | if (aCircuit != null && (aCircuit.teleportFlags != (uint)TeleportFlags.Default)) | ||
1106 | { | ||
1107 | // This will get your attention | ||
1108 | //m_log.Error("[XXX] Triggering CHANGED_TELEPORT"); | ||
1109 | |||
1110 | return 5; // StateSource.Teleporting | ||
1111 | } | ||
1112 | return 2; // StateSource.PrimCrossing | ||
1113 | } | ||
1114 | |||
1091 | /// <summary> | 1115 | /// <summary> |
1092 | /// This turns a root agent into a child agent | 1116 | /// This turns a root agent into a child agent |
1093 | /// when an agent departs this region for a neighbor, this gets called. | 1117 | /// when an agent departs this region for a neighbor, this gets called. |
@@ -1288,7 +1312,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1288 | AbsolutePosition = pos; | 1312 | AbsolutePosition = pos; |
1289 | } | 1313 | } |
1290 | 1314 | ||
1291 | m_isChildAgent = false; | ||
1292 | bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); | 1315 | bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); |
1293 | MakeRootAgent(AbsolutePosition, m_flying); | 1316 | MakeRootAgent(AbsolutePosition, m_flying); |
1294 | 1317 | ||
@@ -2757,12 +2780,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
2757 | 2780 | ||
2758 | #region Update Client(s) | 2781 | #region Update Client(s) |
2759 | 2782 | ||
2783 | |||
2760 | /// <summary> | 2784 | /// <summary> |
2761 | /// Sends a location update to the client connected to this scenePresence | 2785 | /// Sends a location update to the client connected to this scenePresence |
2762 | /// </summary> | 2786 | /// </summary> |
2763 | /// <param name="remoteClient"></param> | 2787 | /// <param name="remoteClient"></param> |
2764 | public void SendTerseUpdateToClient(IClientAPI remoteClient) | 2788 | public void SendTerseUpdateToClient(IClientAPI remoteClient) |
2765 | { | 2789 | { |
2790 | |||
2766 | // If the client is inactive, it's getting its updates from another | 2791 | // If the client is inactive, it's getting its updates from another |
2767 | // server. | 2792 | // server. |
2768 | if (remoteClient.IsActive) | 2793 | if (remoteClient.IsActive) |
@@ -2775,8 +2800,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2775 | //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); | 2800 | //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); |
2776 | 2801 | ||
2777 | remoteClient.SendPrimUpdate( | 2802 | remoteClient.SendPrimUpdate( |
2778 | this, | 2803 | this, |
2779 | PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | 2804 | PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity |
2780 | | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); | 2805 | | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); |
2781 | 2806 | ||
2782 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); | 2807 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); |
@@ -2784,16 +2809,31 @@ namespace OpenSim.Region.Framework.Scenes | |||
2784 | } | 2809 | } |
2785 | } | 2810 | } |
2786 | 2811 | ||
2812 | |||
2813 | // vars to support reduced update frequency when velocity is unchanged | ||
2814 | private Vector3 lastVelocitySentToAllClients = Vector3.Zero; | ||
2815 | private int lastTerseUpdateToAllClientsTick = Util.EnvironmentTickCount(); | ||
2816 | |||
2787 | /// <summary> | 2817 | /// <summary> |
2788 | /// Send a location/velocity/accelleration update to all agents in scene | 2818 | /// Send a location/velocity/accelleration update to all agents in scene |
2789 | /// </summary> | 2819 | /// </summary> |
2790 | public void SendTerseUpdateToAllClients() | 2820 | public void SendTerseUpdateToAllClients() |
2791 | { | 2821 | { |
2792 | m_perfMonMS = Util.EnvironmentTickCount(); | 2822 | int currentTick = Util.EnvironmentTickCount(); |
2793 | |||
2794 | m_scene.ForEachClient(SendTerseUpdateToClient); | ||
2795 | 2823 | ||
2796 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); | 2824 | // decrease update frequency when avatar is moving but velocity is not changing |
2825 | if (m_velocity.Length() < 0.01f | ||
2826 | || Vector3.Distance(lastVelocitySentToAllClients, m_velocity) > 0.01f | ||
2827 | || currentTick - lastTerseUpdateToAllClientsTick > 1500) | ||
2828 | { | ||
2829 | m_perfMonMS = currentTick; | ||
2830 | lastVelocitySentToAllClients = m_velocity; | ||
2831 | lastTerseUpdateToAllClientsTick = currentTick; | ||
2832 | |||
2833 | m_scene.ForEachClient(SendTerseUpdateToClient); | ||
2834 | |||
2835 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); | ||
2836 | } | ||
2797 | } | 2837 | } |
2798 | 2838 | ||
2799 | public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs) | 2839 | public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs) |
@@ -3049,18 +3089,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
3049 | cadu.GroupAccess = 0; | 3089 | cadu.GroupAccess = 0; |
3050 | cadu.Position = AbsolutePosition; | 3090 | cadu.Position = AbsolutePosition; |
3051 | cadu.regionHandle = m_rootRegionHandle; | 3091 | cadu.regionHandle = m_rootRegionHandle; |
3092 | |||
3093 | // Throttles | ||
3052 | float multiplier = 1; | 3094 | float multiplier = 1; |
3053 | int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); | 3095 | int childRegions = m_knownChildRegions.Count; |
3054 | if (innacurateNeighbors != 0) | 3096 | if (childRegions != 0) |
3055 | { | 3097 | multiplier = 1f / childRegions; |
3056 | multiplier = 1f / (float)innacurateNeighbors; | 3098 | |
3057 | } | 3099 | // Minimum throttle for a child region is 1/4 of the root region throttle |
3058 | if (multiplier <= 0f) | 3100 | if (multiplier <= 0.25f) |
3059 | { | ||
3060 | multiplier = 0.25f; | 3101 | multiplier = 0.25f; |
3061 | } | ||
3062 | 3102 | ||
3063 | //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString()); | ||
3064 | cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier); | 3103 | cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier); |
3065 | cadu.Velocity = Velocity; | 3104 | cadu.Velocity = Velocity; |
3066 | 3105 | ||
@@ -3456,16 +3495,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
3456 | 3495 | ||
3457 | // Throttles | 3496 | // Throttles |
3458 | float multiplier = 1; | 3497 | float multiplier = 1; |
3459 | int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); | 3498 | int childRegions = m_knownChildRegions.Count; |
3460 | if (innacurateNeighbors != 0) | 3499 | if (childRegions != 0) |
3461 | { | 3500 | multiplier = 1f / childRegions; |
3462 | multiplier = 1f / innacurateNeighbors; | 3501 | |
3463 | } | 3502 | // Minimum throttle for a child region is 1/4 of the root region throttle |
3464 | if (multiplier <= 0f) | 3503 | if (multiplier <= 0.25f) |
3465 | { | ||
3466 | multiplier = 0.25f; | 3504 | multiplier = 0.25f; |
3467 | } | 3505 | |
3468 | //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString()); | ||
3469 | cAgent.Throttles = ControllingClient.GetThrottlesPacked(multiplier); | 3506 | cAgent.Throttles = ControllingClient.GetThrottlesPacked(multiplier); |
3470 | 3507 | ||
3471 | cAgent.HeadRotation = m_headrotation; | 3508 | cAgent.HeadRotation = m_headrotation; |
@@ -3481,54 +3518,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
3481 | 3518 | ||
3482 | cAgent.Appearance = new AvatarAppearance(m_appearance); | 3519 | cAgent.Appearance = new AvatarAppearance(m_appearance); |
3483 | 3520 | ||
3484 | /* | ||
3485 | try | ||
3486 | { | ||
3487 | // We might not pass the Wearables in all cases... | ||
3488 | // They're only needed so that persistent changes to the appearance | ||
3489 | // are preserved in the new region where the user is moving to. | ||
3490 | // But in Hypergrid we might not let this happen. | ||
3491 | int i = 0; | ||
3492 | UUID[] wears = new UUID[m_appearance.Wearables.Length * 2]; | ||
3493 | foreach (AvatarWearable aw in m_appearance.Wearables) | ||
3494 | { | ||
3495 | if (aw != null) | ||
3496 | { | ||
3497 | wears[i++] = aw.ItemID; | ||
3498 | wears[i++] = aw.AssetID; | ||
3499 | } | ||
3500 | else | ||
3501 | { | ||
3502 | wears[i++] = UUID.Zero; | ||
3503 | wears[i++] = UUID.Zero; | ||
3504 | } | ||
3505 | } | ||
3506 | cAgent.Wearables = wears; | ||
3507 | |||
3508 | cAgent.VisualParams = m_appearance.VisualParams; | ||
3509 | |||
3510 | if (m_appearance.Texture != null) | ||
3511 | cAgent.AgentTextures = m_appearance.Texture.GetBytes(); | ||
3512 | } | ||
3513 | catch (Exception e) | ||
3514 | { | ||
3515 | m_log.Warn("[SCENE PRESENCE]: exception in CopyTo " + e.Message); | ||
3516 | } | ||
3517 | |||
3518 | //Attachments | ||
3519 | List<int> attPoints = m_appearance.GetAttachedPoints(); | ||
3520 | if (attPoints != null) | ||
3521 | { | ||
3522 | //m_log.DebugFormat("[SCENE PRESENCE]: attachments {0}", attPoints.Count); | ||
3523 | int i = 0; | ||
3524 | AvatarAttachment[] attachs = new AvatarAttachment[attPoints.Count]; | ||
3525 | foreach (int point in attPoints) | ||
3526 | { | ||
3527 | attachs[i++] = new AvatarAttachment(point, m_appearance.GetAttachedItem(point), m_appearance.GetAttachedAsset(point)); | ||
3528 | } | ||
3529 | cAgent.Attachments = attachs; | ||
3530 | } | ||
3531 | */ | ||
3532 | lock (scriptedcontrols) | 3521 | lock (scriptedcontrols) |
3533 | { | 3522 | { |
3534 | ControllerData[] controls = new ControllerData[scriptedcontrols.Count]; | 3523 | ControllerData[] controls = new ControllerData[scriptedcontrols.Count]; |
@@ -3548,9 +3537,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
3548 | } | 3537 | } |
3549 | catch { } | 3538 | catch { } |
3550 | 3539 | ||
3551 | // cAgent.GroupID = ?? | 3540 | // Attachment objects |
3552 | // Groups??? | 3541 | if (m_attachments != null && m_attachments.Count > 0) |
3553 | 3542 | { | |
3543 | cAgent.AttachmentObjects = new List<ISceneObject>(); | ||
3544 | cAgent.AttachmentObjectStates = new List<string>(); | ||
3545 | IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>(); | ||
3546 | foreach (SceneObjectGroup sog in m_attachments) | ||
3547 | { | ||
3548 | // We need to make a copy and pass that copy | ||
3549 | // because of transfers withn the same sim | ||
3550 | ISceneObject clone = sog.CloneForNewScene(); | ||
3551 | // Attachment module assumes that GroupPosition holds the offsets...! | ||
3552 | ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; | ||
3553 | ((SceneObjectGroup)clone).RootPart.IsAttachment = false; | ||
3554 | cAgent.AttachmentObjects.Add(clone); | ||
3555 | cAgent.AttachmentObjectStates.Add(sog.GetStateSnapshot()); | ||
3556 | // Let's remove the scripts of the original object here | ||
3557 | sog.RemoveScriptInstances(true); | ||
3558 | } | ||
3559 | } | ||
3554 | } | 3560 | } |
3555 | 3561 | ||
3556 | public void CopyFrom(AgentData cAgent) | 3562 | public void CopyFrom(AgentData cAgent) |
@@ -3592,50 +3598,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
3592 | AddToPhysicalScene(isFlying); | 3598 | AddToPhysicalScene(isFlying); |
3593 | } | 3599 | } |
3594 | 3600 | ||
3595 | /* | ||
3596 | uint i = 0; | ||
3597 | try | ||
3598 | { | ||
3599 | if (cAgent.Wearables == null) | ||
3600 | cAgent.Wearables = new UUID[0]; | ||
3601 | AvatarWearable[] wears = new AvatarWearable[cAgent.Wearables.Length / 2]; | ||
3602 | for (uint n = 0; n < cAgent.Wearables.Length; n += 2) | ||
3603 | { | ||
3604 | UUID itemId = cAgent.Wearables[n]; | ||
3605 | UUID assetId = cAgent.Wearables[n + 1]; | ||
3606 | wears[i++] = new AvatarWearable(itemId, assetId); | ||
3607 | } | ||
3608 | // m_appearance.Wearables = wears; | ||
3609 | Primitive.TextureEntry textures = null; | ||
3610 | if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1) | ||
3611 | textures = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length); | ||
3612 | |||
3613 | byte[] visuals = null; | ||
3614 | |||
3615 | if ((cAgent.VisualParams != null) && (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT)) | ||
3616 | visuals = (byte[])cAgent.VisualParams.Clone(); | ||
3617 | |||
3618 | m_appearance = new AvatarAppearance(cAgent.AgentID,wears,textures,visuals); | ||
3619 | } | ||
3620 | catch (Exception e) | ||
3621 | { | ||
3622 | m_log.Warn("[SCENE PRESENCE]: exception in CopyFrom " + e.Message); | ||
3623 | } | ||
3624 | |||
3625 | // Attachments | ||
3626 | try | ||
3627 | { | ||
3628 | if (cAgent.Attachments != null) | ||
3629 | { | ||
3630 | m_appearance.ClearAttachments(); | ||
3631 | foreach (AvatarAttachment att in cAgent.Attachments) | ||
3632 | { | ||
3633 | m_appearance.SetAttachment(att.AttachPoint, att.ItemID, att.AssetID); | ||
3634 | } | ||
3635 | } | ||
3636 | } | ||
3637 | catch { } | ||
3638 | */ | ||
3639 | try | 3601 | try |
3640 | { | 3602 | { |
3641 | lock (scriptedcontrols) | 3603 | lock (scriptedcontrols) |
@@ -3665,8 +3627,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
3665 | } | 3627 | } |
3666 | catch { } | 3628 | catch { } |
3667 | 3629 | ||
3668 | //cAgent.GroupID = ?? | 3630 | if (cAgent.AttachmentObjects != null && cAgent.AttachmentObjects.Count > 0) |
3669 | //Groups??? | 3631 | { |
3632 | m_attachments = new List<SceneObjectGroup>(); | ||
3633 | int i = 0; | ||
3634 | foreach (ISceneObject so in cAgent.AttachmentObjects) | ||
3635 | { | ||
3636 | ((SceneObjectGroup)so).LocalId = 0; | ||
3637 | ((SceneObjectGroup)so).RootPart.UpdateFlag = 0; | ||
3638 | so.SetState(cAgent.AttachmentObjectStates[i++], m_scene); | ||
3639 | m_scene.IncomingCreateObject(so); | ||
3640 | } | ||
3641 | } | ||
3670 | } | 3642 | } |
3671 | 3643 | ||
3672 | public bool CopyAgent(out IAgentData agent) | 3644 | public bool CopyAgent(out IAgentData agent) |
diff --git a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs index 6a24cc1..db17d8f 100644 --- a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs | |||
@@ -82,6 +82,14 @@ namespace OpenSim.Region.CoreModules.UDP.Linden | |||
82 | m_scenes[scene.RegionInfo.RegionID] = scene; | 82 | m_scenes[scene.RegionInfo.RegionID] = scene; |
83 | 83 | ||
84 | scene.AddCommand( | 84 | scene.AddCommand( |
85 | this, "show pqueues", | ||
86 | "show pqueues [full]", | ||
87 | "Show priority queue data for each client", | ||
88 | "Without the 'full' option, only root agents are shown." | ||
89 | + " With the 'full' option child agents are also shown.", | ||
90 | ShowPQueuesReport); | ||
91 | |||
92 | scene.AddCommand( | ||
85 | this, "show queues", | 93 | this, "show queues", |
86 | "show queues [full]", | 94 | "show queues [full]", |
87 | "Show queue data for each client", | 95 | "Show queue data for each client", |
@@ -119,6 +127,11 @@ namespace OpenSim.Region.CoreModules.UDP.Linden | |||
119 | // m_log.DebugFormat("[LINDEN UDP INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); | 127 | // m_log.DebugFormat("[LINDEN UDP INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); |
120 | } | 128 | } |
121 | 129 | ||
130 | protected void ShowPQueuesReport(string module, string[] cmd) | ||
131 | { | ||
132 | MainConsole.Instance.Output(GetPQueuesReport(cmd)); | ||
133 | } | ||
134 | |||
122 | protected void ShowQueuesReport(string module, string[] cmd) | 135 | protected void ShowQueuesReport(string module, string[] cmd) |
123 | { | 136 | { |
124 | MainConsole.Instance.Output(GetQueuesReport(cmd)); | 137 | MainConsole.Instance.Output(GetQueuesReport(cmd)); |
@@ -155,6 +168,80 @@ namespace OpenSim.Region.CoreModules.UDP.Linden | |||
155 | ""); | 168 | ""); |
156 | } | 169 | } |
157 | 170 | ||
171 | |||
172 | /// <summary> | ||
173 | /// Generate UDP Queue data report for each client | ||
174 | /// </summary> | ||
175 | /// <param name="showParams"></param> | ||
176 | /// <returns></returns> | ||
177 | protected string GetPQueuesReport(string[] showParams) | ||
178 | { | ||
179 | bool showChildren = false; | ||
180 | string pname = ""; | ||
181 | |||
182 | if (showParams.Length > 2 && showParams[2] == "full") | ||
183 | showChildren = true; | ||
184 | else if (showParams.Length > 3) | ||
185 | pname = showParams[2] + " " + showParams[3]; | ||
186 | |||
187 | StringBuilder report = new StringBuilder(); | ||
188 | |||
189 | int columnPadding = 2; | ||
190 | int maxNameLength = 18; | ||
191 | int maxRegionNameLength = 14; | ||
192 | int maxTypeLength = 4; | ||
193 | int totalInfoFieldsLength = maxNameLength + columnPadding + maxRegionNameLength + columnPadding + maxTypeLength + columnPadding; | ||
194 | |||
195 | report.Append(GetColumnEntry("User", maxNameLength, columnPadding)); | ||
196 | report.Append(GetColumnEntry("Region", maxRegionNameLength, columnPadding)); | ||
197 | report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding)); | ||
198 | |||
199 | report.AppendFormat( | ||
200 | "{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7} {10,7} {11,7}\n", | ||
201 | "Pri 0", | ||
202 | "Pri 1", | ||
203 | "Pri 2", | ||
204 | "Pri 3", | ||
205 | "Pri 4", | ||
206 | "Pri 5", | ||
207 | "Pri 6", | ||
208 | "Pri 7", | ||
209 | "Pri 8", | ||
210 | "Pri 9", | ||
211 | "Pri 10", | ||
212 | "Pri 11"); | ||
213 | |||
214 | lock (m_scenes) | ||
215 | { | ||
216 | foreach (Scene scene in m_scenes.Values) | ||
217 | { | ||
218 | scene.ForEachClient( | ||
219 | delegate(IClientAPI client) | ||
220 | { | ||
221 | if (client is LLClientView) | ||
222 | { | ||
223 | bool isChild = scene.PresenceChildStatus(client.AgentId); | ||
224 | if (isChild && !showChildren) | ||
225 | return; | ||
226 | |||
227 | string name = client.Name; | ||
228 | if (pname != "" && name != pname) | ||
229 | return; | ||
230 | |||
231 | string regionName = scene.RegionInfo.RegionName; | ||
232 | |||
233 | report.Append(GetColumnEntry(name, maxNameLength, columnPadding)); | ||
234 | report.Append(GetColumnEntry(regionName, maxRegionNameLength, columnPadding)); | ||
235 | report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding)); | ||
236 | report.AppendLine(((LLClientView)client).EntityUpdateQueue.ToString()); | ||
237 | } | ||
238 | }); | ||
239 | } | ||
240 | } | ||
241 | |||
242 | return report.ToString(); | ||
243 | } | ||
244 | |||
158 | /// <summary> | 245 | /// <summary> |
159 | /// Generate UDP Queue data report for each client | 246 | /// Generate UDP Queue data report for each client |
160 | /// </summary> | 247 | /// </summary> |
@@ -163,10 +250,13 @@ namespace OpenSim.Region.CoreModules.UDP.Linden | |||
163 | protected string GetQueuesReport(string[] showParams) | 250 | protected string GetQueuesReport(string[] showParams) |
164 | { | 251 | { |
165 | bool showChildren = false; | 252 | bool showChildren = false; |
253 | string pname = ""; | ||
166 | 254 | ||
167 | if (showParams.Length > 2 && showParams[2] == "full") | 255 | if (showParams.Length > 2 && showParams[2] == "full") |
168 | showChildren = true; | 256 | showChildren = true; |
169 | 257 | else if (showParams.Length > 3) | |
258 | pname = showParams[2] + " " + showParams[3]; | ||
259 | |||
170 | StringBuilder report = new StringBuilder(); | 260 | StringBuilder report = new StringBuilder(); |
171 | 261 | ||
172 | int columnPadding = 2; | 262 | int columnPadding = 2; |
@@ -224,6 +314,9 @@ namespace OpenSim.Region.CoreModules.UDP.Linden | |||
224 | return; | 314 | return; |
225 | 315 | ||
226 | string name = client.Name; | 316 | string name = client.Name; |
317 | if (pname != "" && name != pname) | ||
318 | return; | ||
319 | |||
227 | string regionName = scene.RegionInfo.RegionName; | 320 | string regionName = scene.RegionInfo.RegionName; |
228 | 321 | ||
229 | report.Append(GetColumnEntry(name, maxNameLength, columnPadding)); | 322 | report.Append(GetColumnEntry(name, maxNameLength, columnPadding)); |
@@ -249,10 +342,13 @@ namespace OpenSim.Region.CoreModules.UDP.Linden | |||
249 | protected string GetThrottlesReport(string[] showParams) | 342 | protected string GetThrottlesReport(string[] showParams) |
250 | { | 343 | { |
251 | bool showChildren = false; | 344 | bool showChildren = false; |
345 | string pname = ""; | ||
252 | 346 | ||
253 | if (showParams.Length > 2 && showParams[2] == "full") | 347 | if (showParams.Length > 2 && showParams[2] == "full") |
254 | showChildren = true; | 348 | showChildren = true; |
255 | 349 | else if (showParams.Length > 3) | |
350 | pname = showParams[2] + " " + showParams[3]; | ||
351 | |||
256 | StringBuilder report = new StringBuilder(); | 352 | StringBuilder report = new StringBuilder(); |
257 | 353 | ||
258 | int columnPadding = 2; | 354 | int columnPadding = 2; |
@@ -302,7 +398,7 @@ namespace OpenSim.Region.CoreModules.UDP.Linden | |||
302 | if (client is LLClientView) | 398 | if (client is LLClientView) |
303 | { | 399 | { |
304 | LLClientView llClient = client as LLClientView; | 400 | LLClientView llClient = client as LLClientView; |
305 | 401 | ||
306 | if (firstClient) | 402 | if (firstClient) |
307 | { | 403 | { |
308 | report.AppendLine(GetServerThrottlesReport(llClient.UDPServer)); | 404 | report.AppendLine(GetServerThrottlesReport(llClient.UDPServer)); |
@@ -314,6 +410,9 @@ namespace OpenSim.Region.CoreModules.UDP.Linden | |||
314 | return; | 410 | return; |
315 | 411 | ||
316 | string name = client.Name; | 412 | string name = client.Name; |
413 | if (pname != "" && name != pname) | ||
414 | return; | ||
415 | |||
317 | string regionName = scene.RegionInfo.RegionName; | 416 | string regionName = scene.RegionInfo.RegionName; |
318 | 417 | ||
319 | LLUDPClient llUdpClient = llClient.UDPClient; | 418 | LLUDPClient llUdpClient = llClient.UDPClient; |
@@ -352,7 +451,7 @@ namespace OpenSim.Region.CoreModules.UDP.Linden | |||
352 | int maxRegionNameLength = 14; | 451 | int maxRegionNameLength = 14; |
353 | int maxTypeLength = 4; | 452 | int maxTypeLength = 4; |
354 | 453 | ||
355 | string name = "SERVER AGENT LIMITS"; | 454 | string name = "SERVER AGENT RATES"; |
356 | 455 | ||
357 | report.Append(GetColumnEntry(name, maxNameLength, columnPadding)); | 456 | report.Append(GetColumnEntry(name, maxNameLength, columnPadding)); |
358 | report.Append(GetColumnEntry("-", maxRegionNameLength, columnPadding)); | 457 | report.Append(GetColumnEntry("-", maxRegionNameLength, columnPadding)); |
@@ -362,13 +461,13 @@ namespace OpenSim.Region.CoreModules.UDP.Linden | |||
362 | report.AppendFormat( | 461 | report.AppendFormat( |
363 | "{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}", | 462 | "{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}", |
364 | (throttleRates.Total * 8) / 1000, | 463 | (throttleRates.Total * 8) / 1000, |
365 | (throttleRates.ResendLimit * 8) / 1000, | 464 | (throttleRates.Resend * 8) / 1000, |
366 | (throttleRates.LandLimit * 8) / 1000, | 465 | (throttleRates.Land * 8) / 1000, |
367 | (throttleRates.WindLimit * 8) / 1000, | 466 | (throttleRates.Wind * 8) / 1000, |
368 | (throttleRates.CloudLimit * 8) / 1000, | 467 | (throttleRates.Cloud * 8) / 1000, |
369 | (throttleRates.TaskLimit * 8) / 1000, | 468 | (throttleRates.Task * 8) / 1000, |
370 | (throttleRates.TextureLimit * 8) / 1000, | 469 | (throttleRates.Texture * 8) / 1000, |
371 | (throttleRates.AssetLimit * 8) / 1000); | 470 | (throttleRates.Asset * 8) / 1000); |
372 | 471 | ||
373 | return report.ToString(); | 472 | return report.ToString(); |
374 | } | 473 | } |
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 64774d8..f89b824 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs | |||
@@ -88,7 +88,8 @@ namespace OpenSim.Region.Physics.Meshing | |||
88 | 88 | ||
89 | decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache"); | 89 | decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache"); |
90 | cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps); | 90 | cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps); |
91 | useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); | 91 | if(mesh_config != null) |
92 | useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); | ||
92 | 93 | ||
93 | try | 94 | try |
94 | { | 95 | { |