diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index 408474178b..37cfe1d25f 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -700,6 +700,7 @@ namespace OpenSim
scene.LoadWorldMap();
scene.PhysicsScene = GetPhysicsScene(scene.RegionInfo.RegionName);
+ scene.PhysicsScene.RequestAssetMethod = scene.PhysicsRequestAsset;
scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
scene.PhysicsScene.SetWaterLevel((float) regionInfo.RegionSettings.WaterHeight);
diff --git a/OpenSim/Region/CoreModules/World/Tests/SOGSpamTest.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
similarity index 53%
rename from OpenSim/Region/CoreModules/World/Tests/SOGSpamTest.cs
rename to OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
index 53d775ea48..9787c8c173 100644
--- a/OpenSim/Region/CoreModules/World/Tests/SOGSpamTest.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
@@ -27,11 +27,49 @@
using System;
using System.Collections.Generic;
-using System.Text;
+using System.IO;
+using System.Reflection;
+using System.Threading;
+using log4net.Config;
+using NUnit.Framework;
+using OpenMetaverse;
+using OpenMetaverse.Assets;
+using OpenSim.Framework;
+using OpenSim.Region.CoreModules.Scripting.DynamicTexture;
+using OpenSim.Region.CoreModules.Scripting.VectorRender;
+using OpenSim.Region.Framework.Scenes;
+using OpenSim.Region.Framework.Scenes.Serialization;
+using OpenSim.Tests.Common;
+using OpenSim.Tests.Common.Mock;
-namespace OpenSim.Region.CoreModules.World.Tests
+namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
{
- class SOGSpamTest
+ [TestFixture]
+ public class VectorRenderModuleTests
{
+ [Test]
+ public void TestDraw()
+ {
+ TestHelpers.InMethod();
+
+ Scene scene = new SceneHelpers().SetupScene();
+ DynamicTextureModule dtm = new DynamicTextureModule();
+ VectorRenderModule vrm = new VectorRenderModule();
+ SceneHelpers.SetupSceneModules(scene, dtm, vrm);
+
+ SceneObjectGroup so = SceneHelpers.AddSceneObject(scene);
+ UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
+
+ dtm.AddDynamicTextureData(
+ scene.RegionInfo.RegionID,
+ so.UUID,
+ vrm.GetContentType(),
+ "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
+ "",
+ 0);
+
+
+ Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
+ }
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
index c061868ed6..d03911101d 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
@@ -98,16 +98,18 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
public void GetDrawStringSize(string text, string fontName, int fontSize,
out double xSize, out double ySize)
{
- Font myFont = new Font(fontName, fontSize);
- SizeF stringSize = new SizeF();
- lock (m_graph) {
- stringSize = m_graph.MeasureString(text, myFont);
- xSize = stringSize.Width;
- ySize = stringSize.Height;
+ using (Font myFont = new Font(fontName, fontSize))
+ {
+ SizeF stringSize = new SizeF();
+ lock (m_graph)
+ {
+ stringSize = m_graph.MeasureString(text, myFont);
+ xSize = stringSize.Width;
+ ySize = stringSize.Height;
+ }
}
}
-
#endregion
#region IRegionModule Members
@@ -121,6 +123,8 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
if (m_graph == null)
{
+ // We won't dispose of these explicitly since this module is only removed when the entire simulator
+ // is shut down.
Bitmap bitmap = new Bitmap(1024, 1024, PixelFormat.Format32bppArgb);
m_graph = Graphics.FromImage(bitmap);
}
@@ -299,53 +303,64 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
}
}
- Bitmap bitmap;
-
- if (alpha == 256)
- {
- bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
- }
- else
- {
- bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
- }
-
- Graphics graph = Graphics.FromImage(bitmap);
-
- // this is really just to save people filling the
- // background color in their scripts, only do when fully opaque
- if (alpha >= 255)
- {
- graph.FillRectangle(new SolidBrush(bgColor), 0, 0, width, height);
- }
-
- for (int w = 0; w < bitmap.Width; w++)
- {
- if (alpha <= 255)
- {
- for (int h = 0; h < bitmap.Height; h++)
- {
- bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h)));
- }
- }
- }
-
- GDIDraw(data, graph, altDataDelim);
-
- byte[] imageJ2000 = new byte[0];
+ Bitmap bitmap = null;
+ Graphics graph = null;
try
{
- imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, true);
- }
- catch (Exception e)
- {
- m_log.ErrorFormat(
- "[VECTORRENDERMODULE]: OpenJpeg Encode Failed. Exception {0}{1}",
- e.Message, e.StackTrace);
- }
+ if (alpha == 256)
+ bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
+ else
+ bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
- m_textureManager.ReturnData(id, imageJ2000);
+ graph = Graphics.FromImage(bitmap);
+
+ // this is really just to save people filling the
+ // background color in their scripts, only do when fully opaque
+ if (alpha >= 255)
+ {
+ using (SolidBrush bgFillBrush = new SolidBrush(bgColor))
+ {
+ graph.FillRectangle(bgFillBrush, 0, 0, width, height);
+ }
+ }
+
+ for (int w = 0; w < bitmap.Width; w++)
+ {
+ if (alpha <= 255)
+ {
+ for (int h = 0; h < bitmap.Height; h++)
+ {
+ bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h)));
+ }
+ }
+ }
+
+ GDIDraw(data, graph, altDataDelim);
+
+ byte[] imageJ2000 = new byte[0];
+
+ try
+ {
+ imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, true);
+ }
+ catch (Exception e)
+ {
+ m_log.ErrorFormat(
+ "[VECTORRENDERMODULE]: OpenJpeg Encode Failed. Exception {0}{1}",
+ e.Message, e.StackTrace);
+ }
+
+ m_textureManager.ReturnData(id, imageJ2000);
+ }
+ finally
+ {
+ if (graph != null)
+ graph.Dispose();
+
+ if (bitmap != null)
+ bitmap.Dispose();
+ }
}
private int parseIntParam(string strInt)
@@ -407,237 +422,284 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
{
Point startPoint = new Point(0, 0);
Point endPoint = new Point(0, 0);
- Pen drawPen = new Pen(Color.Black, 7);
- string fontName = m_fontName;
- float fontSize = 14;
- Font myFont = new Font(fontName, fontSize);
- SolidBrush myBrush = new SolidBrush(Color.Black);
-
- char[] lineDelimiter = {dataDelim};
- char[] partsDelimiter = {','};
- string[] lines = data.Split(lineDelimiter);
+ Pen drawPen = null;
+ Font myFont = null;
+ SolidBrush myBrush = null;
- foreach (string line in lines)
+ try
{
- string nextLine = line.Trim();
- //replace with switch, or even better, do some proper parsing
- if (nextLine.StartsWith("MoveTo"))
+ drawPen = new Pen(Color.Black, 7);
+ string fontName = m_fontName;
+ float fontSize = 14;
+ myFont = new Font(fontName, fontSize);
+ myBrush = new SolidBrush(Color.Black);
+
+ char[] lineDelimiter = {dataDelim};
+ char[] partsDelimiter = {','};
+ string[] lines = data.Split(lineDelimiter);
+
+ foreach (string line in lines)
{
- float x = 0;
- float y = 0;
- GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y);
- startPoint.X = (int) x;
- startPoint.Y = (int) y;
- }
- else if (nextLine.StartsWith("LineTo"))
- {
- float x = 0;
- float y = 0;
- GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y);
- endPoint.X = (int) x;
- endPoint.Y = (int) y;
- graph.DrawLine(drawPen, startPoint, endPoint);
- startPoint.X = endPoint.X;
- startPoint.Y = endPoint.Y;
- }
- else if (nextLine.StartsWith("Text"))
- {
- nextLine = nextLine.Remove(0, 4);
- nextLine = nextLine.Trim();
- graph.DrawString(nextLine, myFont, myBrush, startPoint);
- }
- else if (nextLine.StartsWith("Image"))
- {
- float x = 0;
- float y = 0;
- GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y);
- endPoint.X = (int) x;
- endPoint.Y = (int) y;
- Image image = ImageHttpRequest(nextLine);
- if (image != null)
+ string nextLine = line.Trim();
+ //replace with switch, or even better, do some proper parsing
+ if (nextLine.StartsWith("MoveTo"))
{
- graph.DrawImage(image, (float)startPoint.X, (float)startPoint.Y, x, y);
+ float x = 0;
+ float y = 0;
+ GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y);
+ startPoint.X = (int) x;
+ startPoint.Y = (int) y;
}
- else
+ else if (nextLine.StartsWith("LineTo"))
{
- graph.DrawString("URL couldn't be resolved or is", new Font(m_fontName,6),
- myBrush, startPoint);
- graph.DrawString("not an image. Please check URL.", new Font(m_fontName, 6),
- myBrush, new Point(startPoint.X, 12 + startPoint.Y));
+ float x = 0;
+ float y = 0;
+ GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y);
+ endPoint.X = (int) x;
+ endPoint.Y = (int) y;
+ graph.DrawLine(drawPen, startPoint, endPoint);
+ startPoint.X = endPoint.X;
+ startPoint.Y = endPoint.Y;
+ }
+ else if (nextLine.StartsWith("Text"))
+ {
+ nextLine = nextLine.Remove(0, 4);
+ nextLine = nextLine.Trim();
+ graph.DrawString(nextLine, myFont, myBrush, startPoint);
+ }
+ else if (nextLine.StartsWith("Image"))
+ {
+ float x = 0;
+ float y = 0;
+ GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y);
+ endPoint.X = (int) x;
+ endPoint.Y = (int) y;
+
+ using (Image image = ImageHttpRequest(nextLine))
+ {
+ if (image != null)
+ {
+ graph.DrawImage(image, (float)startPoint.X, (float)startPoint.Y, x, y);
+ }
+ else
+ {
+ using (Font errorFont = new Font(m_fontName,6))
+ {
+ graph.DrawString("URL couldn't be resolved or is", errorFont,
+ myBrush, startPoint);
+ graph.DrawString("not an image. Please check URL.", errorFont,
+ myBrush, new Point(startPoint.X, 12 + startPoint.Y));
+ }
+
+ graph.DrawRectangle(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
+ }
+ }
+
+ startPoint.X += endPoint.X;
+ startPoint.Y += endPoint.Y;
+ }
+ else if (nextLine.StartsWith("Rectangle"))
+ {
+ float x = 0;
+ float y = 0;
+ GetParams(partsDelimiter, ref nextLine, 9, ref x, ref y);
+ endPoint.X = (int) x;
+ endPoint.Y = (int) y;
graph.DrawRectangle(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
+ startPoint.X += endPoint.X;
+ startPoint.Y += endPoint.Y;
}
- startPoint.X += endPoint.X;
- startPoint.Y += endPoint.Y;
- }
- else if (nextLine.StartsWith("Rectangle"))
- {
- float x = 0;
- float y = 0;
- GetParams(partsDelimiter, ref nextLine, 9, ref x, ref y);
- endPoint.X = (int) x;
- endPoint.Y = (int) y;
- graph.DrawRectangle(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
- startPoint.X += endPoint.X;
- startPoint.Y += endPoint.Y;
- }
- else if (nextLine.StartsWith("FillRectangle"))
- {
- float x = 0;
- float y = 0;
- GetParams(partsDelimiter, ref nextLine, 13, ref x, ref y);
- endPoint.X = (int) x;
- endPoint.Y = (int) y;
- graph.FillRectangle(myBrush, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
- startPoint.X += endPoint.X;
- startPoint.Y += endPoint.Y;
- }
- else if (nextLine.StartsWith("FillPolygon"))
- {
- PointF[] points = null;
- GetParams(partsDelimiter, ref nextLine, 11, ref points);
- graph.FillPolygon(myBrush, points);
- }
- else if (nextLine.StartsWith("Polygon"))
- {
- PointF[] points = null;
- GetParams(partsDelimiter, ref nextLine, 7, ref points);
- graph.DrawPolygon(drawPen, points);
- }
- else if (nextLine.StartsWith("Ellipse"))
- {
- float x = 0;
- float y = 0;
- GetParams(partsDelimiter, ref nextLine, 7, ref x, ref y);
- endPoint.X = (int)x;
- endPoint.Y = (int)y;
- graph.DrawEllipse(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
- startPoint.X += endPoint.X;
- startPoint.Y += endPoint.Y;
- }
- else if (nextLine.StartsWith("FontSize"))
- {
- nextLine = nextLine.Remove(0, 8);
- nextLine = nextLine.Trim();
- fontSize = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture);
- myFont = new Font(fontName, fontSize);
- }
- else if (nextLine.StartsWith("FontProp"))
- {
- nextLine = nextLine.Remove(0, 8);
- nextLine = nextLine.Trim();
-
- string[] fprops = nextLine.Split(partsDelimiter);
- foreach (string prop in fprops)
+ else if (nextLine.StartsWith("FillRectangle"))
{
+ float x = 0;
+ float y = 0;
+ GetParams(partsDelimiter, ref nextLine, 13, ref x, ref y);
+ endPoint.X = (int) x;
+ endPoint.Y = (int) y;
+ graph.FillRectangle(myBrush, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
+ startPoint.X += endPoint.X;
+ startPoint.Y += endPoint.Y;
+ }
+ else if (nextLine.StartsWith("FillPolygon"))
+ {
+ PointF[] points = null;
+ GetParams(partsDelimiter, ref nextLine, 11, ref points);
+ graph.FillPolygon(myBrush, points);
+ }
+ else if (nextLine.StartsWith("Polygon"))
+ {
+ PointF[] points = null;
+ GetParams(partsDelimiter, ref nextLine, 7, ref points);
+ graph.DrawPolygon(drawPen, points);
+ }
+ else if (nextLine.StartsWith("Ellipse"))
+ {
+ float x = 0;
+ float y = 0;
+ GetParams(partsDelimiter, ref nextLine, 7, ref x, ref y);
+ endPoint.X = (int)x;
+ endPoint.Y = (int)y;
+ graph.DrawEllipse(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
+ startPoint.X += endPoint.X;
+ startPoint.Y += endPoint.Y;
+ }
+ else if (nextLine.StartsWith("FontSize"))
+ {
+ nextLine = nextLine.Remove(0, 8);
+ nextLine = nextLine.Trim();
+ fontSize = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture);
- switch (prop)
+ myFont.Dispose();
+ myFont = new Font(fontName, fontSize);
+ }
+ else if (nextLine.StartsWith("FontProp"))
+ {
+ nextLine = nextLine.Remove(0, 8);
+ nextLine = nextLine.Trim();
+
+ string[] fprops = nextLine.Split(partsDelimiter);
+ foreach (string prop in fprops)
{
- case "B":
- if (!(myFont.Bold))
- myFont = new Font(myFont, myFont.Style | FontStyle.Bold);
- break;
- case "I":
- if (!(myFont.Italic))
- myFont = new Font(myFont, myFont.Style | FontStyle.Italic);
- break;
- case "U":
- if (!(myFont.Underline))
- myFont = new Font(myFont, myFont.Style | FontStyle.Underline);
- break;
- case "S":
- if (!(myFont.Strikeout))
- myFont = new Font(myFont, myFont.Style | FontStyle.Strikeout);
- break;
- case "R":
- myFont = new Font(myFont, FontStyle.Regular);
- break;
+
+ switch (prop)
+ {
+ case "B":
+ if (!(myFont.Bold))
+ {
+ Font newFont = new Font(myFont, myFont.Style | FontStyle.Bold);
+ myFont.Dispose();
+ myFont = newFont;
+ }
+ break;
+ case "I":
+ if (!(myFont.Italic))
+ {
+ Font newFont = new Font(myFont, myFont.Style | FontStyle.Italic);
+ myFont.Dispose();
+ myFont = newFont;
+ }
+ break;
+ case "U":
+ if (!(myFont.Underline))
+ {
+ Font newFont = new Font(myFont, myFont.Style | FontStyle.Underline);
+ myFont.Dispose();
+ myFont = newFont;
+ }
+ break;
+ case "S":
+ if (!(myFont.Strikeout))
+ {
+ Font newFont = new Font(myFont, myFont.Style | FontStyle.Strikeout);
+ myFont.Dispose();
+ myFont = newFont;
+ }
+ break;
+ case "R":
+ Font newFont = new Font(myFont, FontStyle.Regular);
+ myFont.Dispose();
+ myFont = newFont;
+ break;
+ }
}
}
- }
- else if (nextLine.StartsWith("FontName"))
- {
- nextLine = nextLine.Remove(0, 8);
- fontName = nextLine.Trim();
- myFont = new Font(fontName, fontSize);
- }
- else if (nextLine.StartsWith("PenSize"))
- {
- nextLine = nextLine.Remove(0, 7);
- nextLine = nextLine.Trim();
- float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture);
- drawPen.Width = size;
- }
- else if (nextLine.StartsWith("PenCap"))
- {
- bool start = true, end = true;
- nextLine = nextLine.Remove(0, 6);
- nextLine = nextLine.Trim();
- string[] cap = nextLine.Split(partsDelimiter);
- if (cap[0].ToLower() == "start")
- end = false;
- else if (cap[0].ToLower() == "end")
- start = false;
- else if (cap[0].ToLower() != "both")
- return;
- string type = cap[1].ToLower();
-
- if (end)
+ else if (nextLine.StartsWith("FontName"))
{
- switch (type)
+ nextLine = nextLine.Remove(0, 8);
+ fontName = nextLine.Trim();
+ myFont.Dispose();
+ myFont = new Font(fontName, fontSize);
+ }
+ else if (nextLine.StartsWith("PenSize"))
+ {
+ nextLine = nextLine.Remove(0, 7);
+ nextLine = nextLine.Trim();
+ float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture);
+ drawPen.Width = size;
+ }
+ else if (nextLine.StartsWith("PenCap"))
+ {
+ bool start = true, end = true;
+ nextLine = nextLine.Remove(0, 6);
+ nextLine = nextLine.Trim();
+ string[] cap = nextLine.Split(partsDelimiter);
+ if (cap[0].ToLower() == "start")
+ end = false;
+ else if (cap[0].ToLower() == "end")
+ start = false;
+ else if (cap[0].ToLower() != "both")
+ return;
+ string type = cap[1].ToLower();
+
+ if (end)
{
- case "arrow":
- drawPen.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
- break;
- case "round":
- drawPen.EndCap = System.Drawing.Drawing2D.LineCap.RoundAnchor;
- break;
- case "diamond":
- drawPen.EndCap = System.Drawing.Drawing2D.LineCap.DiamondAnchor;
- break;
- case "flat":
- drawPen.EndCap = System.Drawing.Drawing2D.LineCap.Flat;
- break;
+ switch (type)
+ {
+ case "arrow":
+ drawPen.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
+ break;
+ case "round":
+ drawPen.EndCap = System.Drawing.Drawing2D.LineCap.RoundAnchor;
+ break;
+ case "diamond":
+ drawPen.EndCap = System.Drawing.Drawing2D.LineCap.DiamondAnchor;
+ break;
+ case "flat":
+ drawPen.EndCap = System.Drawing.Drawing2D.LineCap.Flat;
+ break;
+ }
+ }
+ if (start)
+ {
+ switch (type)
+ {
+ case "arrow":
+ drawPen.StartCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
+ break;
+ case "round":
+ drawPen.StartCap = System.Drawing.Drawing2D.LineCap.RoundAnchor;
+ break;
+ case "diamond":
+ drawPen.StartCap = System.Drawing.Drawing2D.LineCap.DiamondAnchor;
+ break;
+ case "flat":
+ drawPen.StartCap = System.Drawing.Drawing2D.LineCap.Flat;
+ break;
+ }
}
}
- if (start)
+ else if (nextLine.StartsWith("PenColour") || nextLine.StartsWith("PenColor"))
{
- switch (type)
+ nextLine = nextLine.Remove(0, 9);
+ nextLine = nextLine.Trim();
+ int hex = 0;
+
+ Color newColor;
+ if (Int32.TryParse(nextLine, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out hex))
{
- case "arrow":
- drawPen.StartCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
- break;
- case "round":
- drawPen.StartCap = System.Drawing.Drawing2D.LineCap.RoundAnchor;
- break;
- case "diamond":
- drawPen.StartCap = System.Drawing.Drawing2D.LineCap.DiamondAnchor;
- break;
- case "flat":
- drawPen.StartCap = System.Drawing.Drawing2D.LineCap.Flat;
- break;
+ newColor = Color.FromArgb(hex);
}
+ else
+ {
+ // this doesn't fail, it just returns black if nothing is found
+ newColor = Color.FromName(nextLine);
+ }
+
+ myBrush.Color = newColor;
+ drawPen.Color = newColor;
}
}
- else if (nextLine.StartsWith("PenColour") || nextLine.StartsWith("PenColor"))
- {
- nextLine = nextLine.Remove(0, 9);
- nextLine = nextLine.Trim();
- int hex = 0;
+ }
+ finally
+ {
+ if (drawPen != null)
+ drawPen.Dispose();
- Color newColor;
- if (Int32.TryParse(nextLine, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out hex))
- {
- newColor = Color.FromArgb(hex);
- }
- else
- {
- // this doesn't fail, it just returns black if nothing is found
- newColor = Color.FromName(nextLine);
- }
+ if (myFont != null)
+ myFont.Dispose();
- myBrush.Color = newColor;
- drawPen.Color = newColor;
- }
+ if (myBrush != null)
+ myBrush.Dispose();
}
}
@@ -691,7 +753,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
{
try
{
- WebRequest request = HttpWebRequest.Create(url);
+ WebRequest request = HttpWebRequest.Create(url);
//Ckrinke: Comment out for now as 'str' is unused. Bring it back into play later when it is used.
//Ckrinke Stream str = null;
HttpWebResponse response = (HttpWebResponse)(request).GetResponse();
@@ -702,7 +764,8 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
}
}
catch { }
+
return null;
}
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index 55110dcc86..a073cb9fb8 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -154,6 +154,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
protected void OnRequestCallbackTimeout(object source, ElapsedEventArgs args)
{
+ bool close = true;
+
try
{
lock (this)
@@ -161,7 +163,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver
// Take care of the possibilty that this thread started but was paused just outside the lock before
// the final request came in (assuming that such a thing is possible)
if (m_requestState == RequestState.Completed)
+ {
+ close = false;
return;
+ }
m_requestState = RequestState.Aborted;
}
@@ -208,7 +213,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
}
finally
{
- m_assetsArchiver.ForceClose();
+ if (close)
+ m_assetsArchiver.ForceClose();
}
}
@@ -242,11 +248,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
m_requestCallbackTimer.Stop();
- if (m_requestState == RequestState.Aborted)
+ if ((m_requestState == RequestState.Aborted) || (m_requestState == RequestState.Completed))
{
m_log.WarnFormat(
- "[ARCHIVER]: Received information about asset {0} after archive save abortion. Ignoring.",
- id);
+ "[ARCHIVER]: Received information about asset {0} while in state {1}. Ignoring.",
+ id, m_requestState);
return;
}
@@ -268,7 +274,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
m_notFoundAssetUuids.Add(new UUID(id));
}
- if (m_foundAssetUuids.Count + m_notFoundAssetUuids.Count == m_repliesRequired)
+ if (m_foundAssetUuids.Count + m_notFoundAssetUuids.Count >= m_repliesRequired)
{
m_requestState = RequestState.Completed;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index d18fffde04..7e31d60650 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -2131,7 +2131,8 @@ namespace OpenSim.Region.Framework.Scenes
if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
sourcePart.Inventory.RemoveInventoryItem(item.ItemID);
}
-
+
+ group.FromPartID = sourcePart.UUID;
AddNewSceneObject(group, true, pos, rot, vel);
// We can only call this after adding the scene object, since the scene object references the scene
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index eb4ba41d7b..c77457c764 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -5421,5 +5421,21 @@ namespace OpenSim.Region.Framework.Scenes
m_SpawnPoint = 1;
return m_SpawnPoint - 1;
}
+
+ // Wrappers to get physics modules retrieve assets. Has to be done this way
+ // because we can't assign the asset service to physics directly - at the
+ // time physics are instantiated it's not registered but it will be by
+ // the time the first prim exists.
+ public void PhysicsRequestAsset(UUID assetID, AssetReceivedDelegate callback)
+ {
+ AssetService.Get(assetID.ToString(), callback, PhysicsAssetReceived);
+ }
+
+ private void PhysicsAssetReceived(string id, Object sender, AssetBase asset)
+ {
+ AssetReceivedDelegate callback = (AssetReceivedDelegate)sender;
+
+ callback(asset);
+ }
}
}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 52469a2302..7b284aefaf 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -26,6 +26,7 @@
*/
using System;
+using System.ComponentModel;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
@@ -610,6 +611,14 @@ namespace OpenSim.Region.Framework.Scenes
///
public UUID FromItemID { get; set; }
+ ///
+ /// Refers to the SceneObjectPart.UUID property of the object that this object was rezzed from, if applicable.
+ ///
+ ///
+ /// If not applicable will be UUID.Zero
+ ///
+ public UUID FromPartID { get; set; }
+
///
/// The folder ID that this object was rezzed from, if applicable.
///
@@ -640,6 +649,7 @@ namespace OpenSim.Region.Framework.Scenes
/// The original SceneObjectPart will be used rather than a copy, preserving
/// its existing localID and UUID.
///
+ /// Root part for this scene object.
public SceneObjectGroup(SceneObjectPart part)
{
SetRootPart(part);
@@ -649,8 +659,8 @@ namespace OpenSim.Region.Framework.Scenes
/// Constructor. This object is added to the scene later via AttachToScene()
///
public SceneObjectGroup(UUID ownerID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape)
+ :this(new SceneObjectPart(ownerID, shape, pos, rot, Vector3.Zero))
{
- SetRootPart(new SceneObjectPart(ownerID, shape, pos, rot, Vector3.Zero));
}
///
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 4b2fedead8..4c87639f94 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -2467,7 +2467,7 @@ namespace OpenSim.Region.Framework.Scenes
///
/// Schedule a terse update for this prim. Terse updates only send position,
- /// rotation, velocity, rotational velocity and shape information.
+ /// rotation, velocity and rotational velocity information.
///
public void ScheduleTerseUpdate()
{
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
index 61aaf04bd2..d412cd1082 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
@@ -54,12 +54,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
private bool m_debugEnabled = false;
- public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome |
- GroupPowers.Accountable |
- GroupPowers.JoinChat |
- GroupPowers.AllowVoiceChat |
- GroupPowers.ReceiveNotices |
- GroupPowers.StartProposal |
+ public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome |
+ GroupPowers.Accountable |
+ GroupPowers.JoinChat |
+ GroupPowers.AllowVoiceChat |
+ GroupPowers.ReceiveNotices |
+ GroupPowers.StartProposal |
GroupPowers.VoteOnProposal;
private bool m_connectorEnabled = false;
@@ -201,8 +201,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
///
/// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role.
///
- public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID,
- int membershipFee, bool openEnrollment, bool allowPublish,
+ public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID,
+ int membershipFee, bool openEnrollment, bool allowPublish,
bool maturePublish, UUID founderID)
{
UUID GroupID = UUID.Random();
@@ -214,7 +214,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
param["Charter"] = charter;
param["ShowInList"] = showInList == true ? 1 : 0;
param["InsigniaID"] = insigniaID.ToString();
- param["MembershipFee"] = 0;
+ param["MembershipFee"] = membershipFee;
param["OpenEnrollment"] = openEnrollment == true ? 1 : 0;
param["AllowPublish"] = allowPublish == true ? 1 : 0;
param["MaturePublish"] = maturePublish == true ? 1 : 0;
@@ -285,8 +285,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
return UUID.Parse((string)respData["GroupID"]);
}
- public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList,
- UUID insigniaID, int membershipFee, bool openEnrollment,
+ public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList,
+ UUID insigniaID, int membershipFee, bool openEnrollment,
bool allowPublish, bool maturePublish)
{
Hashtable param = new Hashtable();
@@ -302,7 +302,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
XmlRpcCall(requestingAgentID, "groups.updateGroup", param);
}
- public void AddGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description,
+ public void AddGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description,
string title, ulong powers)
{
Hashtable param = new Hashtable();
@@ -325,7 +325,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
XmlRpcCall(requestingAgentID, "groups.removeRoleFromGroup", param);
}
- public void UpdateGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description,
+ public void UpdateGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description,
string title, ulong powers)
{
Hashtable param = new Hashtable();
@@ -580,7 +580,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
memberships.Add(HashTableToGroupMembershipData((Hashtable)membership));
}
}
-
+
return memberships;
}
@@ -800,9 +800,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID)
{
- // If we're tracking drops for this group,
+ // If we're tracking drops for this group,
// and we find them, well... then they've dropped
- return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)
+ return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)
&& m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID);
}
@@ -888,7 +888,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
return group;
}
-
+
private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData)
{
GroupMembershipData data = new GroupMembershipData();
@@ -921,7 +921,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
data.MembershipFee = int.Parse((string)respData["MembershipFee"]);
data.OpenEnrollment = ((string)respData["OpenEnrollment"] == "1");
data.ShowInList = ((string)respData["ShowInList"] == "1");
-
+
return data;
}
@@ -958,7 +958,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
m_memoryCache.TryGetValue(CacheKey, out resp);
}
}
-
+
if (resp == null)
{
if (m_debugEnabled)
@@ -967,7 +967,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
string UserService;
UUID SessionID;
GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID);
-
+
param.Add("RequestingAgentID", requestingAgentID.ToString());
param.Add("RequestingAgentUserService", UserService);
param.Add("RequestingSessionID", SessionID.ToString());
@@ -992,9 +992,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
catch (Exception e)
{
m_log.ErrorFormat(
- "[XMLRPC-GROUPS-CONNECTOR]: An error has occured while attempting to access the XmlRpcGroups server method {0} at {1}",
+ "[XMLRPC-GROUPS-CONNECTOR]: An error has occured while attempting to access the XmlRpcGroups server method {0} at {1}",
function, m_groupsServerURI);
-
+
m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0}{1}", e.Message, e.StackTrace);
foreach (string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine }, StringSplitOptions.None))
@@ -1061,9 +1061,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
}
}
}
-
+
///
- /// Group Request Tokens are an attempt to allow the groups service to authenticate
+ /// Group Request Tokens are an attempt to allow the groups service to authenticate
/// requests.
/// TODO: This broke after the big grid refactor, either find a better way, or discard this
///
@@ -1103,7 +1103,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
}
*/
}
-
+
}
}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index a4ab702f60..ebfd85b409 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -1331,13 +1331,15 @@ public sealed class BSPrim : PhysicsActor
base.RequestPhysicsterseUpdate();
}
+ /*
else
{
- // For debugging, we can also report the movement of children
+ // For debugging, we also report the movement of children
DetailLog("{0},UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,
entprop.Acceleration, entprop.RotationalVelocity);
}
+ */
}
// I've collided with something
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 28d5cb5b62..011033cefc 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -390,9 +390,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
// Simulate one timestep
public override float Simulate(float timeStep)
{
- int updatedEntityCount;
+ int updatedEntityCount = 0;
IntPtr updatedEntitiesPtr;
- int collidersCount;
+ int collidersCount = 0;
IntPtr collidersPtr;
LastSimulatedTimestep = timeStep;
@@ -411,8 +411,21 @@ public class BSScene : PhysicsScene, IPhysicsParameters
// step the physical world one interval
m_simulationStep++;
- int numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep,
- out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
+ int numSubSteps = 0;
+ try
+ {
+ numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep,
+ out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
+ DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", "0000000000", numSubSteps, updatedEntityCount, collidersCount);
+ }
+ catch (Exception e)
+ {
+ m_log.WarnFormat("{0},PhysicsStep Exception: substeps={1}, updates={2}, colliders={3}, e={4}", LogHeader, numSubSteps, updatedEntityCount, collidersCount, e);
+ DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", "0000000000", numSubSteps, updatedEntityCount, collidersCount);
+ // updatedEntityCount = 0;
+ collidersCount = 0;
+ }
+
// Don't have to use the pointers passed back since we know it is the same pinned memory we passed in
@@ -711,7 +724,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
return true;
}
- // The calls to the PhysicsActors can't directly call into the physics engine
+ // Calls to the PhysicsActors can't directly call into the physics engine
// because it might be busy. We delay changes to a known time.
// We rely on C#'s closure to save and restore the context for the delegate.
public void TaintedObject(TaintCallback callback)
@@ -1275,5 +1288,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
#endregion Runtime settable parameters
+ // Invoke the detailed logger and output something if it's enabled.
+ private void DetailLog(string msg, params Object[] args)
+ {
+ PhysicsLogging.Write(msg, args);
+ }
+
}
}
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index b32cd30bec..6a0558a35e 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -43,6 +43,9 @@ namespace OpenSim.Region.Physics.Manager
public delegate void JointDeactivated(PhysicsJoint joint);
public delegate void JointErrorMessage(PhysicsJoint joint, string message); // this refers to an "error message due to a problem", not "amount of joint constraint violation"
+ public delegate void RequestAssetDelegate(UUID assetID, AssetReceivedDelegate callback);
+ public delegate void AssetReceivedDelegate(AssetBase asset);
+
///
/// Contact result from a raycast.
///
@@ -73,6 +76,8 @@ namespace OpenSim.Region.Physics.Manager
get { return new NullPhysicsScene(); }
}
+ public RequestAssetDelegate RequestAssetMethod { private get; set; }
+
public virtual void TriggerPhysicsBasedRestart()
{
physicsCrash handler = OnPhysicsCrash;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 44de176609..bcd1a6f676 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -3314,5 +3314,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return Math.Max(a, b);
}
+
+ public LSL_Key osGetRezzingObject()
+ {
+ CheckThreatLevel(ThreatLevel.None, "osGetRezzingObject");
+ m_host.AddScriptLPS(1);
+
+ return new LSL_Key(m_host.ParentGroup.FromPartID.ToString());
+ }
}
}
\ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index f73a85e3e7..1f000a3e77 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -299,5 +299,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
///
///
LSL_Float osMax(double a, double b);
+
+ ///
+ /// Get the key of the object that rezzed this object.
+ ///
+ /// Rezzing object key or NULL_KEY if rezzed by agent or otherwise unknown.
+ LSL_Key osGetRezzingObject();
}
}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index 53daa13d49..94405d2b5d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -945,5 +945,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
{
return m_OSSL_Functions.osMax(a, b);
}
+
+ public LSL_Key osGetRezzingObject()
+ {
+ return m_OSSL_Functions.osGetRezzingObject();
+ }
}
}
diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs
index 137a9b0b18..b1f0f7e84d 100644
--- a/OpenSim/Services/AssetService/AssetService.cs
+++ b/OpenSim/Services/AssetService/AssetService.cs
@@ -191,7 +191,8 @@ namespace OpenSim.Services.AssetService
public virtual bool Delete(string id)
{
- m_log.DebugFormat("[ASSET SERVICE]: Deleting asset {0}", id);
+// m_log.DebugFormat("[ASSET SERVICE]: Deleting asset {0}", id);
+
UUID assetID;
if (!UUID.TryParse(id, out assetID))
return false;
diff --git a/OpenSim/Services/AssetService/XAssetService.cs b/OpenSim/Services/AssetService/XAssetService.cs
index 05eb125ebc..e62bcb556d 100644
--- a/OpenSim/Services/AssetService/XAssetService.cs
+++ b/OpenSim/Services/AssetService/XAssetService.cs
@@ -188,7 +188,8 @@ namespace OpenSim.Services.AssetService
public virtual bool Delete(string id)
{
- m_log.DebugFormat("[XASSET SERVICE]: Deleting asset {0}", id);
+// m_log.DebugFormat("[XASSET SERVICE]: Deleting asset {0}", id);
+
UUID assetID;
if (!UUID.TryParse(id, out assetID))
return false;
diff --git a/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs
index 701881e32f..66a336a0c6 100644
--- a/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs
+++ b/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs
@@ -47,6 +47,9 @@ namespace pCampBot
{
Dictionary objects = Bot.Objects;
+ if (objects.Count <= 0)
+ return;
+
Primitive prim = objects.ElementAt(Bot.Random.Next(0, objects.Count - 1)).Value;
// This appears to be a typical message sent when a viewer user clicks a clickable object
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini
index f92c55524e..ff5bdec32e 100644
--- a/bin/OpenSimDefaults.ini
+++ b/bin/OpenSimDefaults.ini
@@ -937,7 +937,7 @@
FixedTimeStep = .01667
MaxCollisionsPerFrame = 2048
- MaxUpdatesPerFrame = 8192
+ MaxUpdatesPerFrame = 2048
[RemoteAdmin]
enabled = false
diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll
index fd8f39ab7c..03e8f26a9b 100755
Binary files a/bin/lib32/BulletSim.dll and b/bin/lib32/BulletSim.dll differ
diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so
index 72847e7c6e..4e119c402f 100755
Binary files a/bin/lib32/libBulletSim.so and b/bin/lib32/libBulletSim.so differ
diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll
index 300e4be8eb..6e8d6b4427 100755
Binary files a/bin/lib64/BulletSim.dll and b/bin/lib64/BulletSim.dll differ
diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so
index 1acc0dd5ae..9363d1a4eb 100755
Binary files a/bin/lib64/libBulletSim.so and b/bin/lib64/libBulletSim.so differ
diff --git a/prebuild.xml b/prebuild.xml
index ea4ec250a4..6ed41a0ac7 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -2995,13 +2995,13 @@
-->
-
+