Merge branch 'careminster' into avination

avinationmerge
Melanie 2012-08-03 16:48:06 +01:00
commit eb4c092cac
20 changed files with 465 additions and 305 deletions

View File

@ -27,11 +27,49 @@
using System; using System;
using System.Collections.Generic; 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));
}
} }
} }

View File

@ -98,16 +98,18 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
public void GetDrawStringSize(string text, string fontName, int fontSize, public void GetDrawStringSize(string text, string fontName, int fontSize,
out double xSize, out double ySize) out double xSize, out double ySize)
{ {
Font myFont = new Font(fontName, fontSize); using (Font myFont = new Font(fontName, fontSize))
SizeF stringSize = new SizeF(); {
lock (m_graph) { SizeF stringSize = new SizeF();
stringSize = m_graph.MeasureString(text, myFont); lock (m_graph)
xSize = stringSize.Width; {
ySize = stringSize.Height; stringSize = m_graph.MeasureString(text, myFont);
xSize = stringSize.Width;
ySize = stringSize.Height;
}
} }
} }
#endregion #endregion
#region IRegionModule Members #region IRegionModule Members
@ -121,6 +123,8 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
if (m_graph == null) 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); Bitmap bitmap = new Bitmap(1024, 1024, PixelFormat.Format32bppArgb);
m_graph = Graphics.FromImage(bitmap); m_graph = Graphics.FromImage(bitmap);
} }
@ -299,53 +303,64 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
} }
} }
Bitmap bitmap; Bitmap bitmap = null;
Graphics graph = null;
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];
try try
{ {
imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, true); if (alpha == 256)
} bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
catch (Exception e) else
{ bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
m_log.ErrorFormat(
"[VECTORRENDERMODULE]: OpenJpeg Encode Failed. Exception {0}{1}",
e.Message, e.StackTrace);
}
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) private int parseIntParam(string strInt)
@ -407,237 +422,284 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
{ {
Point startPoint = new Point(0, 0); Point startPoint = new Point(0, 0);
Point endPoint = new Point(0, 0); Point endPoint = new Point(0, 0);
Pen drawPen = new Pen(Color.Black, 7); Pen drawPen = null;
string fontName = m_fontName; Font myFont = null;
float fontSize = 14; SolidBrush myBrush = null;
Font myFont = new Font(fontName, fontSize);
SolidBrush myBrush = new SolidBrush(Color.Black);
char[] lineDelimiter = {dataDelim};
char[] partsDelimiter = {','};
string[] lines = data.Split(lineDelimiter);
foreach (string line in lines) try
{ {
string nextLine = line.Trim(); drawPen = new Pen(Color.Black, 7);
//replace with switch, or even better, do some proper parsing string fontName = m_fontName;
if (nextLine.StartsWith("MoveTo")) 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; string nextLine = line.Trim();
float y = 0; //replace with switch, or even better, do some proper parsing
GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y); if (nextLine.StartsWith("MoveTo"))
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)
{ {
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), float x = 0;
myBrush, startPoint); float y = 0;
graph.DrawString("not an image. Please check URL.", new Font(m_fontName, 6), GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y);
myBrush, new Point(startPoint.X, 12 + startPoint.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); graph.DrawRectangle(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
startPoint.X += endPoint.X;
startPoint.Y += endPoint.Y;
} }
startPoint.X += endPoint.X; else if (nextLine.StartsWith("FillRectangle"))
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)
{ {
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)) switch (prop)
myFont = new Font(myFont, myFont.Style | FontStyle.Bold); {
break; case "B":
case "I": if (!(myFont.Bold))
if (!(myFont.Italic)) {
myFont = new Font(myFont, myFont.Style | FontStyle.Italic); Font newFont = new Font(myFont, myFont.Style | FontStyle.Bold);
break; myFont.Dispose();
case "U": myFont = newFont;
if (!(myFont.Underline)) }
myFont = new Font(myFont, myFont.Style | FontStyle.Underline); break;
break; case "I":
case "S": if (!(myFont.Italic))
if (!(myFont.Strikeout)) {
myFont = new Font(myFont, myFont.Style | FontStyle.Strikeout); Font newFont = new Font(myFont, myFont.Style | FontStyle.Italic);
break; myFont.Dispose();
case "R": myFont = newFont;
myFont = new Font(myFont, FontStyle.Regular); }
break; 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"))
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)
{ {
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": switch (type)
drawPen.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor; {
break; case "arrow":
case "round": drawPen.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
drawPen.EndCap = System.Drawing.Drawing2D.LineCap.RoundAnchor; break;
break; case "round":
case "diamond": drawPen.EndCap = System.Drawing.Drawing2D.LineCap.RoundAnchor;
drawPen.EndCap = System.Drawing.Drawing2D.LineCap.DiamondAnchor; break;
break; case "diamond":
case "flat": drawPen.EndCap = System.Drawing.Drawing2D.LineCap.DiamondAnchor;
drawPen.EndCap = System.Drawing.Drawing2D.LineCap.Flat; break;
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": newColor = Color.FromArgb(hex);
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;
} }
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")) }
{ finally
nextLine = nextLine.Remove(0, 9); {
nextLine = nextLine.Trim(); if (drawPen != null)
int hex = 0; drawPen.Dispose();
Color newColor; if (myFont != null)
if (Int32.TryParse(nextLine, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out hex)) myFont.Dispose();
{
newColor = Color.FromArgb(hex);
}
else
{
// this doesn't fail, it just returns black if nothing is found
newColor = Color.FromName(nextLine);
}
myBrush.Color = newColor; if (myBrush != null)
drawPen.Color = newColor; myBrush.Dispose();
}
} }
} }
@ -691,7 +753,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
{ {
try 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: Comment out for now as 'str' is unused. Bring it back into play later when it is used.
//Ckrinke Stream str = null; //Ckrinke Stream str = null;
HttpWebResponse response = (HttpWebResponse)(request).GetResponse(); HttpWebResponse response = (HttpWebResponse)(request).GetResponse();
@ -702,7 +764,8 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
} }
} }
catch { } catch { }
return null; return null;
} }
} }
} }

View File

@ -154,6 +154,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
protected void OnRequestCallbackTimeout(object source, ElapsedEventArgs args) protected void OnRequestCallbackTimeout(object source, ElapsedEventArgs args)
{ {
bool close = true;
try try
{ {
lock (this) 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 // 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) // the final request came in (assuming that such a thing is possible)
if (m_requestState == RequestState.Completed) if (m_requestState == RequestState.Completed)
{
close = false;
return; return;
}
m_requestState = RequestState.Aborted; m_requestState = RequestState.Aborted;
} }
@ -208,7 +213,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
} }
finally finally
{ {
m_assetsArchiver.ForceClose(); if (close)
m_assetsArchiver.ForceClose();
} }
} }
@ -242,11 +248,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
m_requestCallbackTimer.Stop(); m_requestCallbackTimer.Stop();
if (m_requestState == RequestState.Aborted) if ((m_requestState == RequestState.Aborted) || (m_requestState == RequestState.Completed))
{ {
m_log.WarnFormat( m_log.WarnFormat(
"[ARCHIVER]: Received information about asset {0} after archive save abortion. Ignoring.", "[ARCHIVER]: Received information about asset {0} while in state {1}. Ignoring.",
id); id, m_requestState);
return; return;
} }
@ -264,7 +270,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
m_notFoundAssetUuids.Add(new UUID(id)); 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; m_requestState = RequestState.Completed;

View File

@ -2283,7 +2283,8 @@ namespace OpenSim.Region.Framework.Scenes
if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
sourcePart.Inventory.RemoveInventoryItem(item.ItemID); sourcePart.Inventory.RemoveInventoryItem(item.ItemID);
} }
group.FromPartID = sourcePart.UUID;
AddNewSceneObject(group, true, pos, rot, vel); AddNewSceneObject(group, true, pos, rot, vel);
// We can only call this after adding the scene object, since the scene object references the scene // We can only call this after adding the scene object, since the scene object references the scene

View File

@ -26,6 +26,7 @@
*/ */
using System; using System;
using System.ComponentModel;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
@ -910,6 +911,14 @@ namespace OpenSim.Region.Framework.Scenes
/// </remarks> /// </remarks>
public UUID FromItemID { get; set; } public UUID FromItemID { get; set; }
/// <summary>
/// Refers to the SceneObjectPart.UUID property of the object that this object was rezzed from, if applicable.
/// </summary>
/// <remarks>
/// If not applicable will be UUID.Zero
/// </remarks>
public UUID FromPartID { get; set; }
/// <summary> /// <summary>
/// The folder ID that this object was rezzed from, if applicable. /// The folder ID that this object was rezzed from, if applicable.
/// </summary> /// </summary>
@ -941,6 +950,7 @@ namespace OpenSim.Region.Framework.Scenes
/// The original SceneObjectPart will be used rather than a copy, preserving /// The original SceneObjectPart will be used rather than a copy, preserving
/// its existing localID and UUID. /// its existing localID and UUID.
/// </summary> /// </summary>
/// <param name='part'>Root part for this scene object.</param>
public SceneObjectGroup(SceneObjectPart part) public SceneObjectGroup(SceneObjectPart part)
{ {
SetRootPart(part); SetRootPart(part);

View File

@ -3081,7 +3081,7 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary> /// <summary>
/// Schedule a terse update for this prim. Terse updates only send position, /// 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.
/// </summary> /// </summary>
public void ScheduleTerseUpdate() public void ScheduleTerseUpdate()
{ {

View File

@ -54,12 +54,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
private bool m_debugEnabled = false; private bool m_debugEnabled = false;
public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome |
GroupPowers.Accountable | GroupPowers.Accountable |
GroupPowers.JoinChat | GroupPowers.JoinChat |
GroupPowers.AllowVoiceChat | GroupPowers.AllowVoiceChat |
GroupPowers.ReceiveNotices | GroupPowers.ReceiveNotices |
GroupPowers.StartProposal | GroupPowers.StartProposal |
GroupPowers.VoteOnProposal; GroupPowers.VoteOnProposal;
private bool m_connectorEnabled = false; private bool m_connectorEnabled = false;
@ -201,8 +201,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
/// <summary> /// <summary>
/// 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. /// 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.
/// </summary> /// </summary>
public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID, public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID,
int membershipFee, bool openEnrollment, bool allowPublish, int membershipFee, bool openEnrollment, bool allowPublish,
bool maturePublish, UUID founderID) bool maturePublish, UUID founderID)
{ {
UUID GroupID = UUID.Random(); UUID GroupID = UUID.Random();
@ -214,7 +214,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
param["Charter"] = charter; param["Charter"] = charter;
param["ShowInList"] = showInList == true ? 1 : 0; param["ShowInList"] = showInList == true ? 1 : 0;
param["InsigniaID"] = insigniaID.ToString(); param["InsigniaID"] = insigniaID.ToString();
param["MembershipFee"] = 0; param["MembershipFee"] = membershipFee;
param["OpenEnrollment"] = openEnrollment == true ? 1 : 0; param["OpenEnrollment"] = openEnrollment == true ? 1 : 0;
param["AllowPublish"] = allowPublish == true ? 1 : 0; param["AllowPublish"] = allowPublish == true ? 1 : 0;
param["MaturePublish"] = maturePublish == 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"]); return UUID.Parse((string)respData["GroupID"]);
} }
public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList, public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList,
UUID insigniaID, int membershipFee, bool openEnrollment, UUID insigniaID, int membershipFee, bool openEnrollment,
bool allowPublish, bool maturePublish) bool allowPublish, bool maturePublish)
{ {
Hashtable param = new Hashtable(); Hashtable param = new Hashtable();
@ -302,7 +302,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
XmlRpcCall(requestingAgentID, "groups.updateGroup", param); 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) string title, ulong powers)
{ {
Hashtable param = new Hashtable(); Hashtable param = new Hashtable();
@ -325,7 +325,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
XmlRpcCall(requestingAgentID, "groups.removeRoleFromGroup", param); 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) string title, ulong powers)
{ {
Hashtable param = new Hashtable(); Hashtable param = new Hashtable();
@ -580,7 +580,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
memberships.Add(HashTableToGroupMembershipData((Hashtable)membership)); memberships.Add(HashTableToGroupMembershipData((Hashtable)membership));
} }
} }
return memberships; return memberships;
} }
@ -800,9 +800,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID) 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 // and we find them, well... then they've dropped
return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID) return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)
&& m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID); && m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID);
} }
@ -888,7 +888,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
return group; return group;
} }
private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData) private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData)
{ {
GroupMembershipData data = new GroupMembershipData(); GroupMembershipData data = new GroupMembershipData();
@ -921,7 +921,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
data.MembershipFee = int.Parse((string)respData["MembershipFee"]); data.MembershipFee = int.Parse((string)respData["MembershipFee"]);
data.OpenEnrollment = ((string)respData["OpenEnrollment"] == "1"); data.OpenEnrollment = ((string)respData["OpenEnrollment"] == "1");
data.ShowInList = ((string)respData["ShowInList"] == "1"); data.ShowInList = ((string)respData["ShowInList"] == "1");
return data; return data;
} }
@ -958,7 +958,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
m_memoryCache.TryGetValue(CacheKey, out resp); m_memoryCache.TryGetValue(CacheKey, out resp);
} }
} }
if (resp == null) if (resp == null)
{ {
if (m_debugEnabled) if (m_debugEnabled)
@ -967,7 +967,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
string UserService; string UserService;
UUID SessionID; UUID SessionID;
GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID); GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID);
param.Add("RequestingAgentID", requestingAgentID.ToString()); param.Add("RequestingAgentID", requestingAgentID.ToString());
param.Add("RequestingAgentUserService", UserService); param.Add("RequestingAgentUserService", UserService);
param.Add("RequestingSessionID", SessionID.ToString()); param.Add("RequestingSessionID", SessionID.ToString());
@ -992,9 +992,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat( 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); function, m_groupsServerURI);
m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0}{1}", e.Message, e.StackTrace); 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)) foreach (string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine }, StringSplitOptions.None))
@ -1061,9 +1061,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
} }
} }
} }
/// <summary> /// <summary>
/// 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. /// requests.
/// TODO: This broke after the big grid refactor, either find a better way, or discard this /// TODO: This broke after the big grid refactor, either find a better way, or discard this
/// </summary> /// </summary>
@ -1103,7 +1103,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
} }
*/ */
} }
} }
} }

View File

@ -1331,13 +1331,15 @@ public sealed class BSPrim : PhysicsActor
base.RequestPhysicsterseUpdate(); base.RequestPhysicsterseUpdate();
} }
/*
else 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}", DetailLog("{0},UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,
entprop.Acceleration, entprop.RotationalVelocity); entprop.Acceleration, entprop.RotationalVelocity);
} }
*/
} }
// I've collided with something // I've collided with something

View File

@ -390,9 +390,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
// Simulate one timestep // Simulate one timestep
public override float Simulate(float timeStep) public override float Simulate(float timeStep)
{ {
int updatedEntityCount; int updatedEntityCount = 0;
IntPtr updatedEntitiesPtr; IntPtr updatedEntitiesPtr;
int collidersCount; int collidersCount = 0;
IntPtr collidersPtr; IntPtr collidersPtr;
LastSimulatedTimestep = timeStep; LastSimulatedTimestep = timeStep;
@ -411,8 +411,21 @@ public class BSScene : PhysicsScene, IPhysicsParameters
// step the physical world one interval // step the physical world one interval
m_simulationStep++; m_simulationStep++;
int numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep, int numSubSteps = 0;
out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); 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 // 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; 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. // 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. // We rely on C#'s closure to save and restore the context for the delegate.
public void TaintedObject(TaintCallback callback) public void TaintedObject(TaintCallback callback)
@ -1275,5 +1288,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
#endregion Runtime settable parameters #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);
}
} }
} }

View File

@ -3362,5 +3362,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return Math.Max(a, b); 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());
}
} }
} }

View File

@ -299,5 +299,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
/// <param name="b"></param> /// <param name="b"></param>
/// <returns></returns> /// <returns></returns>
LSL_Float osMax(double a, double b); LSL_Float osMax(double a, double b);
/// <summary>
/// Get the key of the object that rezzed this object.
/// </summary>
/// <returns>Rezzing object key or NULL_KEY if rezzed by agent or otherwise unknown.</returns>
LSL_Key osGetRezzingObject();
} }
} }

View File

@ -945,5 +945,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
{ {
return m_OSSL_Functions.osMax(a, b); return m_OSSL_Functions.osMax(a, b);
} }
public LSL_Key osGetRezzingObject()
{
return m_OSSL_Functions.osGetRezzingObject();
}
} }
} }

View File

@ -194,7 +194,8 @@ namespace OpenSim.Services.AssetService
public virtual bool Delete(string id) 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; UUID assetID;
if (!UUID.TryParse(id, out assetID)) if (!UUID.TryParse(id, out assetID))
return false; return false;

View File

@ -188,7 +188,8 @@ namespace OpenSim.Services.AssetService
public virtual bool Delete(string id) 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; UUID assetID;
if (!UUID.TryParse(id, out assetID)) if (!UUID.TryParse(id, out assetID))
return false; return false;

View File

@ -937,7 +937,7 @@
FixedTimeStep = .01667 FixedTimeStep = .01667
MaxCollisionsPerFrame = 2048 MaxCollisionsPerFrame = 2048
MaxUpdatesPerFrame = 8192 MaxUpdatesPerFrame = 2048
[RemoteAdmin] [RemoteAdmin]
enabled = false enabled = false

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -3077,13 +3077,13 @@
--> -->
<Files> <Files>
<!-- SADLY the way this works means you need to keep adding these paths --> <!-- SADLY the way this works means you need to keep adding these paths -->
<Match path="Agent/TextureSender/Tests" pattern="*.cs" recurse="true"/>
<Match path="Asset/Tests" pattern="*.cs" recurse="true"/> <Match path="Asset/Tests" pattern="*.cs" recurse="true"/>
<Match path="Avatar/Attachments/Tests" pattern="*.cs" recurse="true"/> <Match path="Avatar/Attachments/Tests" pattern="*.cs" recurse="true"/>
<Match path="Avatar/AvatarFactory/Tests" pattern="*.cs" recurse="true"/> <Match path="Avatar/AvatarFactory/Tests" pattern="*.cs" recurse="true"/>
<Match path="Avatar/Friends/Tests" pattern="*.cs" recurse="true"/> <Match path="Avatar/Friends/Tests" pattern="*.cs" recurse="true"/>
<Match path="Avatar/Inventory/Archiver/Tests" pattern="*.cs" recurse="true"/> <Match path="Avatar/Inventory/Archiver/Tests" pattern="*.cs" recurse="true"/>
<Match path="Framework/InventoryAccess/Tests" pattern="*.cs" recurse="true"/> <Match path="Framework/InventoryAccess/Tests" pattern="*.cs" recurse="true"/>
<Match path="Scripting/VectorRender/Tests" pattern="*.cs" recurse="true"/>
<Match path="World/Archiver/Tests" pattern="*.cs" recurse="true"/> <Match path="World/Archiver/Tests" pattern="*.cs" recurse="true"/>
<Match buildAction="EmbeddedResource" path="World/Archiver/Tests/Resources" pattern="*"/> <Match buildAction="EmbeddedResource" path="World/Archiver/Tests/Resources" pattern="*"/>
<Match path="World/Land/Tests" pattern="*.cs" recurse="true"/> <Match path="World/Land/Tests" pattern="*.cs" recurse="true"/>