diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
index c275d87c34..6437d0b7b0 100644
--- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
+++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
@@ -68,7 +68,7 @@ namespace OpenSim.Capabilities.Handlers
ret["content_type"] = "text/plain";
ret["keepalive"] = false;
ret["reusecontext"] = false;
-
+ ret["int_bytes"] = 0;
string textureStr = (string)request["texture_id"];
string format = (string)request["format"];
@@ -237,6 +237,7 @@ namespace OpenSim.Capabilities.Handlers
{
response["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
response["bin_response_data"] = texture.Data;
+ response["int_bytes"] = texture.Data.Length;
}
else
{
@@ -246,6 +247,7 @@ namespace OpenSim.Capabilities.Handlers
byte[] d = new byte[len];
Array.Copy(texture.Data, start, d, 0, len);
response["bin_response_data"] = d;
+ response["int_bytes"] = len;
}
// response.Body.Write(texture.Data, start, len);
}
@@ -266,6 +268,8 @@ namespace OpenSim.Capabilities.Handlers
response["content_type"] = "image/" + format;
response["bin_response_data"] = texture.Data;
+ response["int_bytes"] = texture.Data.Length;
+
// response.Body.Write(texture.Data, 0, texture.Data.Length);
}
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index a1df6378e8..1c6685aec6 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -1053,7 +1053,7 @@ namespace OpenSim.Framework
event MuteListEntryRemove OnRemoveMuteListEntry;
event GodlikeMessage onGodlikeMessage;
event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
-
+ event GenericCall2 OnUpdateThrottles;
///
/// Set the debug level at which packet output should be printed to console.
///
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
index 24a019016f..d1ec4aa5aa 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
@@ -58,6 +58,13 @@ namespace OpenSim.Region.ClientStack.Linden
public Hashtable request;
}
+ public class aPollResponse
+ {
+ public Hashtable response;
+ public int bytes;
+ }
+
+
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene;
@@ -72,6 +79,8 @@ namespace OpenSim.Region.ClientStack.Linden
private static OpenMetaverse.BlockingQueue m_queue =
new OpenMetaverse.BlockingQueue();
+ private Dictionary m_pollservices = new Dictionary();
+
#region ISharedRegionModule Members
public void Initialise(IConfigSource source)
@@ -88,6 +97,7 @@ namespace OpenSim.Region.ClientStack.Linden
{
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
+ m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate;
m_scene = null;
}
@@ -98,6 +108,7 @@ namespace OpenSim.Region.ClientStack.Linden
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
+ m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate;
if (m_workerThreads == null)
{
@@ -115,6 +126,56 @@ namespace OpenSim.Region.ClientStack.Linden
}
}
}
+ private int ExtractImageThrottle(byte[] pthrottles)
+ {
+
+ byte[] adjData;
+ int pos = 0;
+
+ if (!BitConverter.IsLittleEndian)
+ {
+ byte[] newData = new byte[7 * 4];
+ Buffer.BlockCopy(pthrottles, 0, newData, 0, 7 * 4);
+
+ for (int i = 0; i < 7; i++)
+ Array.Reverse(newData, i * 4, 4);
+
+ adjData = newData;
+ }
+ else
+ {
+ adjData = pthrottles;
+ }
+
+ // 0.125f converts from bits to bytes
+ //int resend = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
+ //pos += 4;
+ // int land = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
+ //pos += 4;
+ // int wind = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
+ // pos += 4;
+ // int cloud = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
+ // pos += 4;
+ // int task = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
+ // pos += 4;
+ pos = pos + 20;
+ int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); //pos += 4;
+ //int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
+ return texture;
+ }
+
+ // Now we know when the throttle is changed by the client in the case of a root agent or by a neighbor region in the case of a child agent.
+ public void ThrottleUpdate(ScenePresence p)
+ {
+ byte[] throttles = p.ControllingClient.GetThrottlesPacked(1);
+ UUID user = p.UUID;
+ int imagethrottle = ExtractImageThrottle(throttles);
+ PollServiceTextureEventArgs args;
+ if (m_pollservices.TryGetValue(user,out args))
+ {
+ args.UpdateThrottle(imagethrottle);
+ }
+ }
public void PostInitialise()
{
@@ -142,20 +203,25 @@ namespace OpenSim.Region.ClientStack.Linden
{
private List requests =
new List();
- private Dictionary responses =
- new Dictionary();
+ private Dictionary responses =
+ new Dictionary();
private Scene m_scene;
-
+ private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000,10000);
public PollServiceTextureEventArgs(UUID pId, Scene scene) :
base(null, null, null, null, pId, int.MaxValue)
{
m_scene = scene;
-
+ // x is request id, y is userid
HasEvents = (x, y) =>
{
lock (responses)
- return responses.ContainsKey(x);
+ {
+ bool ret = m_throttler.hasEvents(x, responses);
+ m_throttler.ProcessTime();
+ return ret;
+
+ }
};
GetEvents = (x, y) =>
{
@@ -163,7 +229,7 @@ namespace OpenSim.Region.ClientStack.Linden
{
try
{
- return responses[x];
+ return responses[x].response;
}
finally
{
@@ -171,14 +237,14 @@ namespace OpenSim.Region.ClientStack.Linden
}
}
};
-
+ // x is request id, y is request data hashtable
Request = (x, y) =>
{
aPollRequest reqinfo = new aPollRequest();
reqinfo.thepoll = this;
reqinfo.reqID = x;
reqinfo.request = y;
-
+
m_queue.Enqueue(reqinfo);
};
@@ -220,16 +286,29 @@ namespace OpenSim.Region.ClientStack.Linden
response["content_type"] = "text/plain";
response["keepalive"] = false;
response["reusecontext"] = false;
-
+
lock (responses)
- responses[requestID] = response;
+ responses[requestID] = new aPollResponse() {bytes = 0, response = response};
return;
}
-
+
response = m_getTextureHandler.Handle(requestinfo.request);
lock (responses)
- responses[requestID] = response;
+ {
+ responses[requestID] = new aPollResponse()
+ {
+ bytes = (int) response["int_bytes"],
+ response = response
+ };
+
+ }
+ m_throttler.ProcessTime();
+ }
+
+ internal void UpdateThrottle(int pimagethrottle)
+ {
+ m_throttler.ThrottleBytes = pimagethrottle;
}
}
@@ -254,19 +333,23 @@ namespace OpenSim.Region.ClientStack.Linden
protocol = "https";
}
caps.RegisterHandler("GetTexture", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
-
+ m_pollservices.Add(agentID, args);
m_capsDict[agentID] = capUrl;
}
private void DeregisterCaps(UUID agentID, Caps caps)
{
string capUrl;
-
+ PollServiceTextureEventArgs args;
if (m_capsDict.TryGetValue(agentID, out capUrl))
{
MainServer.Instance.RemoveHTTPHandler("", capUrl);
m_capsDict.Remove(agentID);
}
+ if (m_pollservices.TryGetValue(agentID, out args))
+ {
+ m_pollservices.Remove(agentID);
+ }
}
private void DoTextureRequests()
@@ -279,4 +362,79 @@ namespace OpenSim.Region.ClientStack.Linden
}
}
}
+
+ internal sealed class CapsDataThrottler
+ {
+
+ private volatile int currenttime = 0;
+ private volatile int lastTimeElapsed = 0;
+ private volatile int BytesSent = 0;
+ private int oversizedImages = 0;
+ public CapsDataThrottler(int pBytes, int max, int min)
+ {
+ ThrottleBytes = pBytes;
+ lastTimeElapsed = Util.EnvironmentTickCount();
+ }
+ public bool hasEvents(UUID key, Dictionary responses)
+ {
+ PassTime();
+ // Note, this is called IN LOCK
+ bool haskey = responses.ContainsKey(key);
+ if (!haskey)
+ {
+ return false;
+ }
+ GetTextureModule.aPollResponse response;
+ if (responses.TryGetValue(key,out response))
+ {
+
+ // Normal
+ if (BytesSent + response.bytes <= ThrottleBytes)
+ {
+ BytesSent += response.bytes;
+ //TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + 1000, unlockyn = false };
+ //m_actions.Add(timeBasedAction);
+ return true;
+ }
+ // Big textures
+ else if (response.bytes > ThrottleBytes && oversizedImages <= ((ThrottleBytes%50000) + 1))
+ {
+ Interlocked.Increment(ref oversizedImages);
+ BytesSent += response.bytes;
+ //TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + (((response.bytes % ThrottleBytes)+1)*1000) , unlockyn = false };
+ //m_actions.Add(timeBasedAction);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ return haskey;
+ }
+ public void ProcessTime()
+ {
+ PassTime();
+ }
+
+
+ private void PassTime()
+ {
+ currenttime = Util.EnvironmentTickCount();
+ int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed);
+ //processTimeBasedActions(responses);
+ if (Util.EnvironmentTickCountSubtract(currenttime, timeElapsed) >= 1000)
+ {
+ lastTimeElapsed = Util.EnvironmentTickCount();
+ BytesSent -= ThrottleBytes;
+ if (BytesSent < 0) BytesSent = 0;
+ if (BytesSent < ThrottleBytes)
+ {
+ oversizedImages = 0;
+ }
+ }
+ }
+ public int ThrottleBytes;
+ }
}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 81167ece84..5551f510ba 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -296,6 +296,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public event MuteListEntryRemove OnRemoveMuteListEntry;
public event GodlikeMessage onGodlikeMessage;
public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
+ public event GenericCall2 OnUpdateThrottles;
#endregion Events
@@ -6753,6 +6754,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#endregion
m_udpClient.SetThrottles(atpack.Throttle.Throttles);
+ GenericCall2 handler = OnUpdateThrottles;
+ if (handler != null)
+ {
+ handler();
+ }
return true;
}
@@ -11906,6 +11912,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void SetChildAgentThrottle(byte[] throttles)
{
m_udpClient.SetThrottles(throttles);
+ GenericCall2 handler = OnUpdateThrottles;
+ if (handler != null)
+ {
+ handler();
+ }
}
///
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
index f6dd5af2d3..0aa46931fb 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
@@ -136,18 +136,27 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
if (XferID == xferID)
{
- if (m_asset.Data.Length > 1)
+ lock (this)
{
- byte[] destinationArray = new byte[m_asset.Data.Length + data.Length];
- Array.Copy(m_asset.Data, 0, destinationArray, 0, m_asset.Data.Length);
- Array.Copy(data, 0, destinationArray, m_asset.Data.Length, data.Length);
- m_asset.Data = destinationArray;
- }
- else
- {
- byte[] buffer2 = new byte[data.Length - 4];
- Array.Copy(data, 4, buffer2, 0, data.Length - 4);
- m_asset.Data = buffer2;
+ int assetLength = m_asset.Data.Length;
+ int dataLength = data.Length;
+
+ if (m_asset.Data.Length > 1)
+ {
+ byte[] destinationArray = new byte[assetLength + dataLength];
+ Array.Copy(m_asset.Data, 0, destinationArray, 0, assetLength);
+ Array.Copy(data, 0, destinationArray, assetLength, dataLength);
+ m_asset.Data = destinationArray;
+ }
+ else
+ {
+ if (dataLength > 4)
+ {
+ byte[] buffer2 = new byte[dataLength - 4];
+ Array.Copy(data, 4, buffer2, 0, dataLength - 4);
+ m_asset.Data = buffer2;
+ }
+ }
}
ourClient.SendConfirmXfer(xferID, packetID);
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 8691b91d3f..5b1c9f4a1c 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -816,6 +816,10 @@ namespace OpenSim.Region.Framework.Scenes
public event ParcelPrimCountTainted OnParcelPrimCountTainted;
public event GetScriptRunning OnGetScriptRunning;
+ public delegate void ThrottleUpdate(ScenePresence scenePresence);
+
+ public event ThrottleUpdate OnThrottleUpdate;
+
///
/// RegisterCapsEvent is called by Scene after the Caps object
/// has been instantiated and before it is return to the
@@ -3130,5 +3134,14 @@ namespace OpenSim.Region.Framework.Scenes
}
}
}
+
+ public void TriggerThrottleUpdate(ScenePresence scenePresence)
+ {
+ ThrottleUpdate handler = OnThrottleUpdate;
+ if (handler != null)
+ {
+ handler(scenePresence);
+ }
+ }
}
}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 74d2629489..b9f9c86cd1 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -112,7 +112,7 @@ namespace OpenSim.Region.Framework.Scenes
private long timeLastChanged = 0;
private long m_maxPersistTime = 0;
private long m_minPersistTime = 0;
- private Random m_rand;
+// private Random m_rand;
private List m_linkedAvatars = new List();
///
@@ -130,6 +130,7 @@ namespace OpenSim.Region.Framework.Scenes
{
if (value)
{
+
if (m_isBackedUp)
{
m_scene.SceneGraph.FireChangeBackup(this);
@@ -139,19 +140,21 @@ namespace OpenSim.Region.Framework.Scenes
timeFirstChanged = DateTime.Now.Ticks;
if (m_rootPart != null && m_rootPart.UUID != null && m_scene != null)
{
+/*
if (m_rand == null)
{
byte[] val = new byte[16];
m_rootPart.UUID.ToBytes(val, 0);
m_rand = new Random(BitConverter.ToInt32(val, 0));
}
-
+ */
if (m_scene.GetRootAgentCount() == 0)
{
//If the region is empty, this change has been made by an automated process
//and thus we delay the persist time by a random amount between 1.5 and 2.5.
- float factor = 1.5f + (float)(m_rand.NextDouble());
+// float factor = 1.5f + (float)(m_rand.NextDouble());
+ float factor = 2.0f;
m_maxPersistTime = (long)((float)m_scene.m_persistAfter * factor);
m_minPersistTime = (long)((float)m_scene.m_dontPersistBefore * factor);
}
@@ -159,8 +162,10 @@ namespace OpenSim.Region.Framework.Scenes
{
//If the region is not empty, we want to obey the minimum and maximum persist times
//but add a random factor so we stagger the object persistance a little
- m_maxPersistTime = (long)((float)m_scene.m_persistAfter * (1.0d - (m_rand.NextDouble() / 5.0d))); //Multiply by 1.0-1.5
- m_minPersistTime = (long)((float)m_scene.m_dontPersistBefore * (1.0d + (m_rand.NextDouble() / 2.0d))); //Multiply by 0.8-1.0
+// m_maxPersistTime = (long)((float)m_scene.m_persistAfter * (1.0d - (m_rand.NextDouble() / 5.0d))); //Multiply by 1.0-1.5
+// m_minPersistTime = (long)((float)m_scene.m_dontPersistBefore * (1.0d + (m_rand.NextDouble() / 2.0d))); //Multiply by 0.8-1.0
+ m_maxPersistTime = m_scene.m_persistAfter;
+ m_minPersistTime = m_scene.m_dontPersistBefore;
}
}
}
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 2c18397301..25a53b4142 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -794,6 +794,7 @@ namespace OpenSim.Region.Framework.Scenes
ControllingClient.OnChangeAnim += avnHandleChangeAnim;
ControllingClient.OnForceReleaseControls += HandleForceReleaseControls;
ControllingClient.OnAutoPilotGo += MoveToTarget;
+ ControllingClient.OnUpdateThrottles += RaiseUpdateThrottles;
// ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
// ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
@@ -3174,6 +3175,10 @@ namespace OpenSim.Region.Framework.Scenes
}
private static Vector3 marker = new Vector3(-1f, -1f, -1f);
+ private void RaiseUpdateThrottles()
+ {
+ m_scene.EventManager.TriggerThrottleUpdate(this);
+ }
///
/// This updates important decision making data about a child agent
/// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index c363fd33be..254eeb4d89 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -873,6 +873,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
public event MuteListEntryRemove OnRemoveMuteListEntry;
public event GodlikeMessage onGodlikeMessage;
public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
+ public event GenericCall2 OnUpdateThrottles;
#pragma warning restore 67
diff --git a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs
index 59ff9b8a19..39cabb52b6 100644
--- a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs
+++ b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs
@@ -121,34 +121,40 @@ namespace OpenSim.Region.OptionalModules
private bool CanObjectEnter(UUID objectID, bool enteringRegion, Vector3 newPoint, Scene scene)
{
- if ((newPoint.X > 257f || newPoint.X < -1f || newPoint.Y > 257f || newPoint.Y < -1f))
+ if (newPoint.X < -1f || newPoint.X > (float)(Constants.RegionSize + 1) ||
+ newPoint.Y < -1f || newPoint.Y > (float)(Constants.RegionSize + 1))
return true;
SceneObjectPart obj = scene.GetSceneObjectPart(objectID);
- Vector3 oldPoint = obj.GroupPosition;
- int objectCount = obj.ParentGroup.PrimCount;
- ILandObject oldParcel = scene.LandChannel.GetLandObject(oldPoint.X, oldPoint.Y);
+
+ if (obj == null)
+ return false;
+
+ // Prim counts are determined by the location of the root prim. if we're
+ // moving a child prim, just let it pass
+ if (!obj.IsRoot)
+ {
+ return true;
+ }
+
ILandObject newParcel = scene.LandChannel.GetLandObject(newPoint.X, newPoint.Y);
if (newParcel == null)
return true;
- int usedPrims = newParcel.PrimCounts.Total;
- int simulatorCapacity = newParcel.GetSimulatorMaxPrimCount();
+ Vector3 oldPoint = obj.GroupPosition;
+ ILandObject oldParcel = scene.LandChannel.GetLandObject(oldPoint.X, oldPoint.Y);
// The prim hasn't crossed a region boundry so we don't need to worry
// about prim counts here
- if(oldParcel.Equals(newParcel))
+ if(oldParcel != null && oldParcel.Equals(newParcel))
{
return true;
}
- // Prim counts are determined by the location of the root prim. if we're
- // moving a child prim, just let it pass
- if(!obj.IsRoot)
- {
- return true;
- }
+ int objectCount = obj.ParentGroup.PrimCount;
+ int usedPrims = newParcel.PrimCounts.Total;
+ int simulatorCapacity = newParcel.GetSimulatorMaxPrimCount();
// TODO: Add Special Case here for temporary prims
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index 5471afaf8f..3a03101751 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -473,7 +473,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
public event MuteListEntryRemove OnRemoveMuteListEntry;
public event GodlikeMessage onGodlikeMessage;
public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
-
+ public event GenericCall2 OnUpdateThrottles;
#pragma warning restore 67
#endregion
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index 76e42d4417..dc247a9fa2 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
@@ -1403,8 +1403,8 @@ namespace OpenSim.Region.Physics.OdePlugin
if (vertexCount == 0 || indexCount == 0)
{
- m_log.WarnFormat("[PHYSICS]: Invalid mesh data on OdePrim {0}, mesh {1}",
- Name, _pbs.SculptEntry ? _pbs.SculptTexture.ToString() : "primMesh");
+ m_log.WarnFormat("[PHYSICS]: Invalid mesh data on OdePrim {0}, mesh {1} at {2}",
+ Name, _pbs.SculptEntry ? _pbs.SculptTexture.ToString() : "primMesh",_position.ToString());
m_hasOBB = false;
m_OBBOffset = Vector3.Zero;
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs
index ebdfb4f95e..5ad3c9f635 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -320,7 +320,7 @@ namespace OpenSim.Tests.Common.Mock
public event MuteListEntryRemove OnRemoveMuteListEntry;
public event GodlikeMessage onGodlikeMessage;
public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
-
+ public event GenericCall2 OnUpdateThrottles;
#pragma warning restore 67
///