Compare commits

...

23 Commits

Author SHA1 Message Date
Justin Clark-Casey (justincc)
d80eda202f Extend "Restarting scripts in attachments" debug log message to show actual name of user and the region they are in 2012-08-24 22:57:18 +01:00
Justin Clark-Casey (justincc)
3edfa585ec If a connecting scene presence is replacing an existing scene presence then bypass close checks. 2012-08-24 22:43:14 +01:00
Justin Clark-Casey (justincc)
fa13a6a8da Bump version number to 0.7.4-rc2 2012-08-24 22:07:58 +01:00
Justin Clark-Casey (justincc)
9d5e7c89d9 Pass the "attachToBackup" bool given to SceneGraph.AddNewSceneObject() down into the 3-parameter AddNewSceneObject() method instead of always hardcoding true.
This doesn't affect any core OpenSimulator code since all callers were passing true anyway
But it allows region modules to create objects that are never persisted.
2012-08-24 21:53:57 +01:00
SignpostMarv
590bf0bcc0 adding sqlite journal files to .gitignore 2012-08-24 21:53:46 +01:00
Justin Clark-Casey (justincc)
b199a2dea3 If a script state save fails for some reason on shutdown/region removal, get xengine to spit out some useful information and continue to save other script states 2012-08-24 21:53:22 +01:00
Justin Clark-Casey (justincc)
f1d4b8d83e Add an [HGAssetService] section to SQLiteStandalone.ini with the same connection string as [AssetService].
This is necessary because commit 8131a24 (Tue Mar 27 10:08:13 2012) started passing the config section name rather than hardcoding "AssetService"
This meant that the HG external-facing asset service tried to read ConnectionString from [HGAssetService] rather than [AssetService].
On SQLite, not finding this meant that it fell back to [DatabaseService], which is set for OpenSim.db rather than Asset.db.
Therefore, all external asset requests returned null.
Solution taken here is to create an [HGAssetService] section with the same ConnectionString as [AssetService].
This bug does not affect normal MySQL/MSSQL config since they use the [DatabaseService] connection string anyway.
Addresses http://opensimulator.org/mantis/view.php?id=6200, many thanks to DanBanner for identifying the exact problem commit which was very helpful.
This was a regression from OpenSimulator 0.7.3.1 which did not contain this bug.
2012-08-24 21:53:12 +01:00
Justin Clark-Casey (justincc)
0088661356 Lock disposal of separate gdi+ objects under different threads since this prevents malloc heap corruption seen under Ubuntu 10.04.1 and 11.04 - probably a libcairo issue
In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously,
the native malloc heap can become corrupted, possibly due to a double free().  This may be due to
bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX.  These problems were
seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1.  They go away if disposal is perfomed
under lock.
2012-08-24 21:53:01 +01:00
Justin Clark-Casey (justincc)
1a7e3cabc0 Fix bug in SoundModule.PlayAttachedSound() where every sound update to an avatar would base its gain calculation on the previous avatar's gain, instead of the original input gain
This is similar to commit d89faa which fixed the same kind of bug in TriggerSound()
2012-08-24 21:52:51 +01:00
Justin Clark-Casey (justincc)
132d701b3e Tighten up OpenSim.Framework.Cache locking to avoid race conditions.
This is to resolve a reported issue in http://opensimulator.org/mantis/view.php?id=6232
Here, the land management module is using OpenSim.Framework.Cache (the only code to currently do so apart from the non-default CoreAssetCache).
2012-08-24 21:52:30 +01:00
Justin Clark-Casey (justincc)
3b97241716 Add --force flag to "kick user" console command to allow bypassing of recent race condition checks.
This is to allow a second attempt to remove an avatar even if "show connections" shows them as already inactive (i.e. close has already been attempted once).
You should only attempt --force if a normal kick fails.
This is partly for diagnostics as we have seen some connections occasionally remain on lbsa plaza even if they are registered as inactive.
This is not a permanent solution and may not work anyway - the ultimate solution is to stop this problem from happening in the first place.
2012-08-24 21:52:21 +01:00
Melanie
f82d090df3 Fix llDialog responses so that they can be heard throughout the region. This now conforms to the behaviour in SL. 2012-08-24 21:52:12 +01:00
Justin Clark-Casey (justincc)
7399d3e953 When reporting a thread timeout, create a copy of the info rather than passing the original ThreadWatchdogInfo structure.
This is to avoid the possibility of misleading reporting if a watchdog update outraces an alarm.
Should address any remaining issues from http://opensimulator.org/mantis/view.php?id=6012
2012-08-24 21:51:03 +01:00
Justin Clark-Casey (justincc)
cab546ecee Add information to ThreadStackSize about possibly increasing if suffering StackOverflowExceptions during script conversion/compilation (e.g. on Windows 64-bit) 2012-08-24 21:50:49 +01:00
Justin Clark-Casey (justincc)
7dc1c7d841 minor: Make xengine debug message on script load a scripting loading message instead.
This is more useful if compilation fails due to an uncatchable exception since we know what was being compiled.
2012-08-24 21:50:40 +01:00
Robert Adams
fbff51f387 Correct an exception report in SceneObjectPart so it outputs the stack. 2012-08-24 21:50:03 +01:00
SignpostMarv
b714fb0c39 Implementing PRIM_LINK_TARGET in a non-recursive fashion 2012-08-24 21:49:44 +01:00
Justin Clark-Casey (justincc)
f37038013d Don't enable the thread watchdog until all regions are ready.
This is to avoid false positives when the machine is under heavy load whilst starting up.
2012-08-24 21:49:36 +01:00
SignpostMarv
5e98e2b7c7 adding ATTACH_*_PEC constants 2012-08-24 21:49:27 +01:00
Justin Clark-Casey (justincc)
35f8f3ff79 minor: Add Gryc Ueusp to CREDITS for commit 884edac amongst others, by request. 2012-08-24 21:48:59 +01:00
Justin Clark-Casey (justincc)
7ec8e7e025 Prevent race conditions when one thread removes an NPC SP before another thread has retreived it after checking whether the NPC exists. 2012-08-24 21:48:48 +01:00
Melanie
c6efebdd8c Release http-in URLs when llResetScript is called 2012-08-24 21:48:15 +01:00
Justin Clark-Casey (justincc)
760047abc5 Flip version to 0.7.4-rc1 2012-08-03 23:58:34 +01:00
31 changed files with 406 additions and 194 deletions

1
.gitignore vendored
View File

@@ -26,6 +26,7 @@
bin/Debug/*.dll bin/Debug/*.dll
bin/*.dll.mdb bin/*.dll.mdb
bin/*.db bin/*.db
bin/*.db-journal
bin/addin-db-* bin/addin-db-*
bin/*.dll bin/*.dll
bin/OpenSim.vshost.exe.config bin/OpenSim.vshost.exe.config

View File

@@ -91,6 +91,7 @@ what it is today.
* Fly-Man * Fly-Man
* Flyte Xevious * Flyte Xevious
* Garmin Kawaguichi * Garmin Kawaguichi
* Gryc Ueusp
* Imaze Rhiano * Imaze Rhiano
* Intimidated * Intimidated
* Jeremy Bongio (IBM) * Jeremy Bongio (IBM)

View File

@@ -199,7 +199,14 @@ namespace OpenSim.Framework
// //
public class Cache public class Cache
{ {
/// <summary>
/// Must only be accessed under lock.
/// </summary>
private List<CacheItemBase> m_Index = new List<CacheItemBase>(); private List<CacheItemBase> m_Index = new List<CacheItemBase>();
/// <summary>
/// Must only be accessed under m_Index lock.
/// </summary>
private Dictionary<string, CacheItemBase> m_Lookup = private Dictionary<string, CacheItemBase> m_Lookup =
new Dictionary<string, CacheItemBase>(); new Dictionary<string, CacheItemBase>();
@@ -320,19 +327,19 @@ namespace OpenSim.Framework
{ {
if (m_Lookup.ContainsKey(index)) if (m_Lookup.ContainsKey(index))
item = m_Lookup[index]; item = m_Lookup[index];
}
if (item == null) if (item == null)
{ {
Expire(true);
return null;
}
item.hits++;
item.lastUsed = DateTime.Now;
Expire(true); Expire(true);
return null;
} }
item.hits++;
item.lastUsed = DateTime.Now;
Expire(true);
return item; return item;
} }
@@ -385,7 +392,10 @@ namespace OpenSim.Framework
// //
public Object Find(Predicate<CacheItemBase> d) public Object Find(Predicate<CacheItemBase> d)
{ {
CacheItemBase item = m_Index.Find(d); CacheItemBase item;
lock (m_Index)
item = m_Index.Find(d);
if (item == null) if (item == null)
return null; return null;
@@ -419,12 +429,12 @@ namespace OpenSim.Framework
public virtual void Store(string index, Object data, Type container, public virtual void Store(string index, Object data, Type container,
Object[] parameters) Object[] parameters)
{ {
Expire(false);
CacheItemBase item; CacheItemBase item;
lock (m_Index) lock (m_Index)
{ {
Expire(false);
if (m_Index.Contains(new CacheItemBase(index))) if (m_Index.Contains(new CacheItemBase(index)))
{ {
if ((m_Flags & CacheFlags.AllowUpdate) != 0) if ((m_Flags & CacheFlags.AllowUpdate) != 0)
@@ -450,9 +460,17 @@ namespace OpenSim.Framework
m_Index.Add(item); m_Index.Add(item);
m_Lookup[index] = item; m_Lookup[index] = item;
} }
item.Store(data); item.Store(data);
} }
/// <summary>
/// Expire items as appropriate.
/// </summary>
/// <remarks>
/// Callers must lock m_Index.
/// </remarks>
/// <param name='getting'></param>
protected virtual void Expire(bool getting) protected virtual void Expire(bool getting)
{ {
if (getting && (m_Strategy == CacheStrategy.Aggressive)) if (getting && (m_Strategy == CacheStrategy.Aggressive))
@@ -475,12 +493,10 @@ namespace OpenSim.Framework
switch (m_Strategy) switch (m_Strategy)
{ {
case CacheStrategy.Aggressive: case CacheStrategy.Aggressive:
if (Count < Size) if (Count < Size)
return; return;
lock (m_Index)
{
m_Index.Sort(new SortLRU()); m_Index.Sort(new SortLRU());
m_Index.Reverse(); m_Index.Reverse();
@@ -490,7 +506,7 @@ namespace OpenSim.Framework
ExpireDelegate doExpire = OnExpire; ExpireDelegate doExpire = OnExpire;
if (doExpire != null) if (doExpire != null)
{ {
List<CacheItemBase> candidates = List<CacheItemBase> candidates =
m_Index.GetRange(target, Count - target); m_Index.GetRange(target, Count - target);
@@ -513,27 +529,34 @@ namespace OpenSim.Framework
foreach (CacheItemBase item in m_Index) foreach (CacheItemBase item in m_Index)
m_Lookup[item.uuid] = item; m_Lookup[item.uuid] = item;
} }
}
break; break;
default:
break; default:
break;
} }
} }
public void Invalidate(string uuid) public void Invalidate(string uuid)
{ {
if (!m_Lookup.ContainsKey(uuid)) lock (m_Index)
return; {
if (!m_Lookup.ContainsKey(uuid))
return;
CacheItemBase item = m_Lookup[uuid]; CacheItemBase item = m_Lookup[uuid];
m_Lookup.Remove(uuid); m_Lookup.Remove(uuid);
m_Index.Remove(item); m_Index.Remove(item);
}
} }
public void Clear() public void Clear()
{ {
m_Index.Clear(); lock (m_Index)
m_Lookup.Clear(); {
m_Index.Clear();
m_Lookup.Clear();
}
} }
} }
} }

View File

@@ -1033,7 +1033,21 @@ namespace OpenSim.Framework
void InPacket(object NewPack); void InPacket(object NewPack);
void ProcessInPacket(Packet NewPack); void ProcessInPacket(Packet NewPack);
/// <summary>
/// Close this client
/// </summary>
void Close(); void Close();
/// <summary>
/// Close this client
/// </summary>
/// <param name='force'>
/// If true, attempts the close without checking active status. You do not want to try this except as a last
/// ditch attempt where Active == false but the ScenePresence still exists.
/// </param>
void Close(bool force);
void Kick(string message); void Kick(string message);
/// <summary> /// <summary>

View File

@@ -89,6 +89,17 @@ namespace OpenSim.Framework.Monitoring
FirstTick = Environment.TickCount & Int32.MaxValue; FirstTick = Environment.TickCount & Int32.MaxValue;
LastTick = FirstTick; LastTick = FirstTick;
} }
public ThreadWatchdogInfo(ThreadWatchdogInfo previousTwi)
{
Thread = previousTwi.Thread;
FirstTick = previousTwi.FirstTick;
LastTick = previousTwi.LastTick;
Timeout = previousTwi.Timeout;
IsTimedOut = previousTwi.IsTimedOut;
AlarmIfTimeout = previousTwi.AlarmIfTimeout;
AlarmMethod = previousTwi.AlarmMethod;
}
} }
/// <summary> /// <summary>
@@ -97,6 +108,32 @@ namespace OpenSim.Framework.Monitoring
/// /summary> /// /summary>
public static event Action<ThreadWatchdogInfo> OnWatchdogTimeout; public static event Action<ThreadWatchdogInfo> OnWatchdogTimeout;
/// <summary>
/// Is this watchdog active?
/// </summary>
public static bool Enabled
{
get { return m_enabled; }
set
{
// m_log.DebugFormat("[MEMORY WATCHDOG]: Setting MemoryWatchdog.Enabled to {0}", value);
if (value == m_enabled)
return;
m_enabled = value;
if (m_enabled)
{
// Set now so we don't get alerted on the first run
LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue;
}
m_watchdogTimer.Enabled = m_enabled;
}
}
private static bool m_enabled;
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private static Dictionary<int, ThreadWatchdogInfo> m_threads; private static Dictionary<int, ThreadWatchdogInfo> m_threads;
private static System.Timers.Timer m_watchdogTimer; private static System.Timers.Timer m_watchdogTimer;
@@ -115,11 +152,6 @@ namespace OpenSim.Framework.Monitoring
m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS); m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS);
m_watchdogTimer.AutoReset = false; m_watchdogTimer.AutoReset = false;
m_watchdogTimer.Elapsed += WatchdogTimerElapsed; m_watchdogTimer.Elapsed += WatchdogTimerElapsed;
// Set now so we don't get alerted on the first run
LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue;
m_watchdogTimer.Start();
} }
/// <summary> /// <summary>
@@ -314,7 +346,9 @@ namespace OpenSim.Framework.Monitoring
if (callbackInfos == null) if (callbackInfos == null)
callbackInfos = new List<ThreadWatchdogInfo>(); callbackInfos = new List<ThreadWatchdogInfo>();
callbackInfos.Add(threadInfo); // Send a copy of the watchdog info to prevent race conditions where the watchdog
// thread updates the monitoring info after an alarm has been sent out.
callbackInfos.Add(new ThreadWatchdogInfo(threadInfo));
} }
} }
} }

View File

@@ -30,7 +30,7 @@ namespace OpenSim
public class VersionInfo public class VersionInfo
{ {
private const string VERSION_NUMBER = "0.7.4"; private const string VERSION_NUMBER = "0.7.4";
private const Flavour VERSION_FLAVOUR = Flavour.Dev; private const Flavour VERSION_FLAVOUR = Flavour.RC2;
public enum Flavour public enum Flavour
{ {

View File

@@ -35,6 +35,7 @@ using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Timers; using System.Timers;
using log4net; using log4net;
using NDesk.Options;
using Nini.Config; using Nini.Config;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
@@ -310,8 +311,11 @@ namespace OpenSim
"Change the scale of a named prim", HandleEditScale); "Change the scale of a named prim", HandleEditScale);
m_console.Commands.AddCommand("Users", false, "kick user", m_console.Commands.AddCommand("Users", false, "kick user",
"kick user <first> <last> [message]", "kick user <first> <last> [--force] [message]",
"Kick a user off the simulator", KickUserCommand); "Kick a user off the simulator",
"The --force option will kick the user without any checks to see whether it's already in the process of closing\n"
+ "Only use this option if you are sure the avatar is inactive and a normal kick user operation does not removed them",
KickUserCommand);
m_console.Commands.AddCommand("Users", false, "show users", m_console.Commands.AddCommand("Users", false, "show users",
"show users [full]", "show users [full]",
@@ -453,11 +457,17 @@ namespace OpenSim
/// <param name="cmdparams">name of avatar to kick</param> /// <param name="cmdparams">name of avatar to kick</param>
private void KickUserCommand(string module, string[] cmdparams) private void KickUserCommand(string module, string[] cmdparams)
{ {
if (cmdparams.Length < 4) bool force = false;
OptionSet options = new OptionSet().Add("f|force", delegate (string v) { force = v != null; });
List<string> mainParams = options.Parse(cmdparams);
if (mainParams.Count < 4)
return; return;
string alert = null; string alert = null;
if (cmdparams.Length > 4) if (mainParams.Count > 4)
alert = String.Format("\n{0}\n", String.Join(" ", cmdparams, 4, cmdparams.Length - 4)); alert = String.Format("\n{0}\n", String.Join(" ", cmdparams, 4, cmdparams.Length - 4));
IList agents = SceneManager.GetCurrentSceneAvatars(); IList agents = SceneManager.GetCurrentSceneAvatars();
@@ -466,8 +476,8 @@ namespace OpenSim
{ {
RegionInfo regionInfo = presence.Scene.RegionInfo; RegionInfo regionInfo = presence.Scene.RegionInfo;
if (presence.Firstname.ToLower().Contains(cmdparams[2].ToLower()) && if (presence.Firstname.ToLower().Contains(mainParams[2].ToLower()) &&
presence.Lastname.ToLower().Contains(cmdparams[3].ToLower())) presence.Lastname.ToLower().Contains(mainParams[3].ToLower()))
{ {
MainConsole.Instance.Output( MainConsole.Instance.Output(
String.Format( String.Format(
@@ -480,7 +490,7 @@ namespace OpenSim
else else
presence.ControllingClient.Kick("\nThe OpenSim manager kicked you out.\n"); presence.ControllingClient.Kick("\nThe OpenSim manager kicked you out.\n");
presence.Scene.IncomingCloseAgent(presence.UUID); presence.Scene.IncomingCloseAgent(presence.UUID, force);
} }
} }

View File

@@ -305,8 +305,13 @@ namespace OpenSim
m_httpServerPort = m_networkServersInfo.HttpListenerPort; m_httpServerPort = m_networkServersInfo.HttpListenerPort;
SceneManager.OnRestartSim += handleRestartRegion; SceneManager.OnRestartSim += handleRestartRegion;
// Only start the memory watchdog once all regions are ready // Only enable the watchdogs when all regions are ready. Otherwise we get false positives when cpu is
SceneManager.OnRegionsReadyStatusChange += sm => MemoryWatchdog.Enabled = sm.AllRegionsReady; // heavily used during initial startup.
//
// FIXME: It's also possible that region ready status should be flipped during an OAR load since this
// also makes heavy use of the CPU.
SceneManager.OnRegionsReadyStatusChange
+= sm => { MemoryWatchdog.Enabled = sm.AllRegionsReady; Watchdog.Enabled = sm.AllRegionsReady; };
} }
/// <summary> /// <summary>

View File

@@ -94,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
UUID spId = TestHelpers.ParseTail(0x1); UUID spId = TestHelpers.ParseTail(0x1);
SceneHelpers.AddScenePresence(m_scene, spId); SceneHelpers.AddScenePresence(m_scene, spId);
m_scene.IncomingCloseAgent(spId); m_scene.IncomingCloseAgent(spId, false);
// TODO: Add more assertions for the other aspects of event queues // TODO: Add more assertions for the other aspects of event queues
Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0)); Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0));

View File

@@ -487,16 +487,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region Client Methods #region Client Methods
/// <summary>
/// Close down the client view
/// </summary>
public void Close() public void Close()
{
Close(false);
}
public void Close(bool force)
{ {
// We lock here to prevent race conditions between two threads calling close simultaneously (e.g. // We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
// a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
lock (CloseSyncLock) lock (CloseSyncLock)
{ {
if (!IsActive) // We still perform a force close inside the sync lock since this is intended to attempt close where
// there is some unidentified connection problem, not where we have issues due to deadlock
if (!IsActive && !force)
return; return;
IsActive = false; IsActive = false;
@@ -5810,7 +5814,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
args.Channel = ch; args.Channel = ch;
args.From = String.Empty; args.From = String.Empty;
args.Message = Utils.BytesToString(msg); args.Message = Utils.BytesToString(msg);
args.Type = ChatTypeEnum.Shout; args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
args.Position = new Vector3(); args.Position = new Vector3();
args.Scene = Scene; args.Scene = Scene;
args.Sender = this; args.Sender = this;
@@ -11989,7 +11993,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
Kick(reason); Kick(reason);
Thread.Sleep(1000); Thread.Sleep(1000);
Close(); Disconnect();
} }
public void Disconnect() public void Disconnect()

View File

@@ -461,7 +461,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
SceneObjectGroup rezzedAtt = presence.GetAttachments()[0]; SceneObjectGroup rezzedAtt = presence.GetAttachments()[0];
scene.IncomingCloseAgent(presence.UUID); scene.IncomingCloseAgent(presence.UUID, false);
// Check that we can't retrieve this attachment from the scene. // Check that we can't retrieve this attachment from the scene.
Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null); Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null);
@@ -641,4 +641,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
// Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects"); // Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects");
// } // }
} }
} }

View File

@@ -644,7 +644,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// an agent cannot teleport back to this region if it has teleported away. // an agent cannot teleport back to this region if it has teleported away.
Thread.Sleep(2000); Thread.Sleep(2000);
sp.Scene.IncomingCloseAgent(sp.UUID); sp.Scene.IncomingCloseAgent(sp.UUID, false);
} }
else else
{ {

View File

@@ -308,36 +308,44 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
try try
{ {
if (alpha == 256) // XXX: In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously,
bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb); // the native malloc heap can become corrupted, possibly due to a double free(). This may be due to
else // bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX. These problems were
bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb); // seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1. They go away if disposal is perfomed
// under lock.
graph = Graphics.FromImage(bitmap); lock (this)
// 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)) if (alpha == 256)
{ bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
graph.FillRectangle(bgFillBrush, 0, 0, width, height); else
} bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
}
for (int w = 0; w < bitmap.Width; w++) graph = Graphics.FromImage(bitmap);
{
if (alpha <= 255) // this is really just to save people filling the
// background color in their scripts, only do when fully opaque
if (alpha >= 255)
{ {
for (int h = 0; h < bitmap.Height; h++) using (SolidBrush bgFillBrush = new SolidBrush(bgColor))
{ {
bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h))); 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);
} }
GDIDraw(data, graph, altDataDelim);
byte[] imageJ2000 = new byte[0]; byte[] imageJ2000 = new byte[0];
try try
@@ -355,11 +363,19 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
} }
finally finally
{ {
if (graph != null) // XXX: In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously,
graph.Dispose(); // the native malloc heap can become corrupted, possibly due to a double free(). This may be due to
// bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX. These problems were
if (bitmap != null) // seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1. They go away if disposal is perfomed
bitmap.Dispose(); // under lock.
lock (this)
{
if (graph != null)
graph.Dispose();
if (bitmap != null)
bitmap.Dispose();
}
} }
} }

View File

@@ -312,7 +312,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
// s.RegionInfo.RegionName, destination.RegionHandle); // s.RegionInfo.RegionName, destination.RegionHandle);
Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id); }); Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id, false); });
return true; return true;
} }

View File

@@ -85,13 +85,15 @@ namespace OpenSim.Region.CoreModules.World.Sound
dis = 0; dis = 0;
} }
float thisSpGain;
// Scale by distance // Scale by distance
if (radius == 0) if (radius == 0)
gain = (float)((double)gain * ((100.0 - dis) / 100.0)); thisSpGain = (float)((double)gain * ((100.0 - dis) / 100.0));
else else
gain = (float)((double)gain * ((radius - dis) / radius)); thisSpGain = (float)((double)gain * ((radius - dis) / radius));
sp.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, (float)gain, flags); sp.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, thisSpGain, flags);
}); });
} }

View File

@@ -3529,7 +3529,7 @@ namespace OpenSim.Region.Framework.Scenes
"[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
sp.Name, sp.UUID, RegionInfo.RegionName); sp.Name, sp.UUID, RegionInfo.RegionName);
sp.ControllingClient.Close(); sp.ControllingClient.Close(true);
sp = null; sp = null;
} }
@@ -4083,16 +4083,19 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary> /// <summary>
/// Tell a single agent to disconnect from the region. /// Tell a single agent to disconnect from the region.
/// </summary> /// </summary>
/// <param name="regionHandle"></param>
/// <param name="agentID"></param> /// <param name="agentID"></param>
public bool IncomingCloseAgent(UUID agentID) /// <param name="force">
/// Force the agent to close even if it might be in the middle of some other operation. You do not want to
/// force unless you are absolutely sure that the agent is dead and a normal close is not working.
/// </param>
public bool IncomingCloseAgent(UUID agentID, bool force)
{ {
//m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
if (presence != null) if (presence != null)
{ {
presence.ControllingClient.Close(); presence.ControllingClient.Close(force);
return true; return true;
} }

View File

@@ -300,7 +300,7 @@ namespace OpenSim.Region.Framework.Scenes
public bool AddNewSceneObject( public bool AddNewSceneObject(
SceneObjectGroup sceneObject, bool attachToBackup, Vector3? pos, Quaternion? rot, Vector3 vel) SceneObjectGroup sceneObject, bool attachToBackup, Vector3? pos, Quaternion? rot, Vector3 vel)
{ {
AddNewSceneObject(sceneObject, true, false); AddNewSceneObject(sceneObject, attachToBackup, false);
if (pos != null) if (pos != null)
sceneObject.AbsolutePosition = (Vector3)pos; sceneObject.AbsolutePosition = (Vector3)pos;

View File

@@ -733,7 +733,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
catch (Exception e) catch (Exception e)
{ {
m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message); m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e);
} }
} }

View File

@@ -891,7 +891,9 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (wasChild && HasAttachments()) if (wasChild && HasAttachments())
{ {
m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); m_log.DebugFormat(
"[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
// Resume scripts // Resume scripts
foreach (SceneObjectGroup sog in m_attachments) foreach (SceneObjectGroup sog in m_attachments)
{ {

View File

@@ -141,7 +141,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
TestScene scene = new SceneHelpers().SetupScene(); TestScene scene = new SceneHelpers().SetupScene();
ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
scene.IncomingCloseAgent(sp.UUID); scene.IncomingCloseAgent(sp.UUID, false);
Assert.That(scene.GetScenePresence(sp.UUID), Is.Null); Assert.That(scene.GetScenePresence(sp.UUID), Is.Null);
Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null); Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null);

View File

@@ -885,6 +885,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
} }
public void Close() public void Close()
{
Close(false);
}
public void Close(bool force)
{ {
Disconnect(); Disconnect();
} }

View File

@@ -900,6 +900,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC
} }
public void Close() public void Close()
{
Close(false);
}
public void Close(bool force)
{ {
// Remove ourselves from the scene // Remove ourselves from the scene
m_scene.RemoveClient(AgentId, false); m_scene.RemoveClient(AgentId, false);

View File

@@ -176,16 +176,17 @@ namespace OpenSim.Region.OptionalModules.World.NPC
if (m_avatars.ContainsKey(agentID)) if (m_avatars.ContainsKey(agentID))
{ {
ScenePresence sp; ScenePresence sp;
scene.TryGetScenePresence(agentID, out sp); if (scene.TryGetScenePresence(agentID, out sp))
{
m_log.DebugFormat(
"[NPC MODULE]: Moving {0} to {1} in {2}, noFly {3}, landAtTarget {4}",
sp.Name, pos, scene.RegionInfo.RegionName, noFly, landAtTarget);
m_log.DebugFormat( sp.MoveToTarget(pos, noFly, landAtTarget);
"[NPC MODULE]: Moving {0} to {1} in {2}, noFly {3}, landAtTarget {4}", sp.SetAlwaysRun = running;
sp.Name, pos, scene.RegionInfo.RegionName, noFly, landAtTarget);
return true;
sp.MoveToTarget(pos, noFly, landAtTarget); }
sp.SetAlwaysRun = running;
return true;
} }
} }
@@ -199,12 +200,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC
if (m_avatars.ContainsKey(agentID)) if (m_avatars.ContainsKey(agentID))
{ {
ScenePresence sp; ScenePresence sp;
scene.TryGetScenePresence(agentID, out sp); if (scene.TryGetScenePresence(agentID, out sp))
{
sp.Velocity = Vector3.Zero;
sp.ResetMoveToTarget();
sp.Velocity = Vector3.Zero; return true;
sp.ResetMoveToTarget(); }
return true;
} }
} }
@@ -222,9 +224,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{ {
if (m_avatars.ContainsKey(agentID)) if (m_avatars.ContainsKey(agentID))
{ {
ScenePresence sp;
scene.TryGetScenePresence(agentID, out sp);
m_avatars[agentID].Say(channel, text); m_avatars[agentID].Say(channel, text);
return true; return true;
@@ -240,9 +239,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{ {
if (m_avatars.ContainsKey(agentID)) if (m_avatars.ContainsKey(agentID))
{ {
ScenePresence sp;
scene.TryGetScenePresence(agentID, out sp);
m_avatars[agentID].Shout(channel, text); m_avatars[agentID].Shout(channel, text);
return true; return true;
@@ -259,11 +255,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC
if (m_avatars.ContainsKey(agentID)) if (m_avatars.ContainsKey(agentID))
{ {
ScenePresence sp; ScenePresence sp;
scene.TryGetScenePresence(agentID, out sp); if (scene.TryGetScenePresence(agentID, out sp))
sp.HandleAgentRequestSit(m_avatars[agentID], agentID, partID, Vector3.Zero); {
// sp.HandleAgentSit(m_avatars[agentID], agentID); sp.HandleAgentRequestSit(m_avatars[agentID], agentID, partID, Vector3.Zero);
// sp.HandleAgentSit(m_avatars[agentID], agentID);
return true;
return true;
}
} }
} }
@@ -276,9 +274,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{ {
if (m_avatars.ContainsKey(agentID)) if (m_avatars.ContainsKey(agentID))
{ {
ScenePresence sp;
scene.TryGetScenePresence(agentID, out sp);
m_avatars[agentID].Whisper(channel, text); m_avatars[agentID].Whisper(channel, text);
return true; return true;
@@ -295,10 +290,12 @@ namespace OpenSim.Region.OptionalModules.World.NPC
if (m_avatars.ContainsKey(agentID)) if (m_avatars.ContainsKey(agentID))
{ {
ScenePresence sp; ScenePresence sp;
scene.TryGetScenePresence(agentID, out sp); if (scene.TryGetScenePresence(agentID, out sp))
sp.StandUp(); {
sp.StandUp();
return true; return true;
}
} }
} }
@@ -311,6 +308,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{ {
if (m_avatars.ContainsKey(agentID)) if (m_avatars.ContainsKey(agentID))
return m_avatars[agentID].Touch(objectID); return m_avatars[agentID].Touch(objectID);
return false; return false;
} }
} }
@@ -321,9 +319,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{ {
NPCAvatar av; NPCAvatar av;
if (m_avatars.TryGetValue(agentID, out av)) if (m_avatars.TryGetValue(agentID, out av))
{
return av.OwnerID; return av.OwnerID;
}
} }
return UUID.Zero; return UUID.Zero;

View File

@@ -183,6 +183,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public void llResetScript() public void llResetScript()
{ {
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
// We need to tell the URL module, if we hav one, to release
// the allocated URLs
if (m_UrlModule != null)
m_UrlModule.ScriptRemoved(m_item.ItemID);
m_ScriptEngine.ApiResetScript(m_item.ItemID); m_ScriptEngine.ApiResetScript(m_item.ItemID);
} }
@@ -237,33 +243,38 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
} }
public List<SceneObjectPart> GetLinkParts(int linkType) public List<SceneObjectPart> GetLinkParts(int linkType)
{
return GetLinkParts(m_host, linkType);
}
private List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
{ {
List<SceneObjectPart> ret = new List<SceneObjectPart>(); List<SceneObjectPart> ret = new List<SceneObjectPart>();
ret.Add(m_host); ret.Add(part);
switch (linkType) switch (linkType)
{ {
case ScriptBaseClass.LINK_SET: case ScriptBaseClass.LINK_SET:
return new List<SceneObjectPart>(m_host.ParentGroup.Parts); return new List<SceneObjectPart>(part.ParentGroup.Parts);
case ScriptBaseClass.LINK_ROOT: case ScriptBaseClass.LINK_ROOT:
ret = new List<SceneObjectPart>(); ret = new List<SceneObjectPart>();
ret.Add(m_host.ParentGroup.RootPart); ret.Add(part.ParentGroup.RootPart);
return ret; return ret;
case ScriptBaseClass.LINK_ALL_OTHERS: case ScriptBaseClass.LINK_ALL_OTHERS:
ret = new List<SceneObjectPart>(m_host.ParentGroup.Parts); ret = new List<SceneObjectPart>(part.ParentGroup.Parts);
if (ret.Contains(m_host)) if (ret.Contains(part))
ret.Remove(m_host); ret.Remove(part);
return ret; return ret;
case ScriptBaseClass.LINK_ALL_CHILDREN: case ScriptBaseClass.LINK_ALL_CHILDREN:
ret = new List<SceneObjectPart>(m_host.ParentGroup.Parts); ret = new List<SceneObjectPart>(part.ParentGroup.Parts);
if (ret.Contains(m_host.ParentGroup.RootPart)) if (ret.Contains(part.ParentGroup.RootPart))
ret.Remove(m_host.ParentGroup.RootPart); ret.Remove(part.ParentGroup.RootPart);
return ret; return ret;
case ScriptBaseClass.LINK_THIS: case ScriptBaseClass.LINK_THIS:
@@ -273,7 +284,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (linkType < 0) if (linkType < 0)
return new List<SceneObjectPart>(); return new List<SceneObjectPart>();
SceneObjectPart target = m_host.ParentGroup.GetLinkNumPart(linkType); SceneObjectPart target = part.ParentGroup.GetLinkNumPart(linkType);
if (target == null) if (target == null)
return new List<SceneObjectPart>(); return new List<SceneObjectPart>();
ret = new List<SceneObjectPart>(); ret = new List<SceneObjectPart>();
@@ -7178,7 +7189,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public void llSetPrimitiveParams(LSL_List rules) public void llSetPrimitiveParams(LSL_List rules)
{ {
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
SetPrimParams(m_host, rules);
setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules);
ScriptSleep(200); ScriptSleep(200);
} }
@@ -7203,11 +7215,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{ {
List<SceneObjectPart> parts = GetLinkParts(linknumber); List<SceneObjectPart> parts = GetLinkParts(linknumber);
LSL_List remaining = null;
foreach (SceneObjectPart part in parts) foreach (SceneObjectPart part in parts)
SetPrimParams(part, rules); remaining = SetPrimParams(part, rules);
while(remaining != null && remaining.Length > 2)
{
linknumber = remaining.GetLSLIntegerItem(0);
rules = remaining.GetSublist(1,-1);
parts = GetLinkParts(linknumber);
foreach (SceneObjectPart part in parts)
remaining = SetPrimParams(part, rules);
}
} }
protected void SetPrimParams(SceneObjectPart part, LSL_List rules) protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules)
{ {
int idx = 0; int idx = 0;
@@ -7230,7 +7254,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_POSITION: case (int)ScriptBaseClass.PRIM_POSITION:
case (int)ScriptBaseClass.PRIM_POS_LOCAL: case (int)ScriptBaseClass.PRIM_POS_LOCAL:
if (remain < 1) if (remain < 1)
return; return null;
v=rules.GetVector3Item(idx++); v=rules.GetVector3Item(idx++);
positionChanged = true; positionChanged = true;
@@ -7239,7 +7263,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
break; break;
case (int)ScriptBaseClass.PRIM_SIZE: case (int)ScriptBaseClass.PRIM_SIZE:
if (remain < 1) if (remain < 1)
return; return null;
v=rules.GetVector3Item(idx++); v=rules.GetVector3Item(idx++);
SetScale(part, v); SetScale(part, v);
@@ -7247,7 +7271,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
break; break;
case (int)ScriptBaseClass.PRIM_ROTATION: case (int)ScriptBaseClass.PRIM_ROTATION:
if (remain < 1) if (remain < 1)
return; return null;
LSL_Rotation q = rules.GetQuaternionItem(idx++); LSL_Rotation q = rules.GetQuaternionItem(idx++);
// try to let this work as in SL... // try to let this work as in SL...
@@ -7267,7 +7291,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TYPE: case (int)ScriptBaseClass.PRIM_TYPE:
if (remain < 3) if (remain < 3)
return; return null;
code = (int)rules.GetLSLIntegerItem(idx++); code = (int)rules.GetLSLIntegerItem(idx++);
@@ -7286,7 +7310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{ {
case (int)ScriptBaseClass.PRIM_TYPE_BOX: case (int)ScriptBaseClass.PRIM_TYPE_BOX:
if (remain < 6) if (remain < 6)
return; return null;
face = (int)rules.GetLSLIntegerItem(idx++); face = (int)rules.GetLSLIntegerItem(idx++);
v = rules.GetVector3Item(idx++); // cut v = rules.GetVector3Item(idx++); // cut
@@ -7301,7 +7325,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER: case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
if (remain < 6) if (remain < 6)
return; return null;
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
v = rules.GetVector3Item(idx++); // cut v = rules.GetVector3Item(idx++); // cut
@@ -7315,7 +7339,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TYPE_PRISM: case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
if (remain < 6) if (remain < 6)
return; return null;
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
v = rules.GetVector3Item(idx++); //cut v = rules.GetVector3Item(idx++); //cut
@@ -7329,7 +7353,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TYPE_SPHERE: case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
if (remain < 5) if (remain < 5)
return; return null;
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
v = rules.GetVector3Item(idx++); // cut v = rules.GetVector3Item(idx++); // cut
@@ -7342,7 +7366,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TYPE_TORUS: case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
if (remain < 11) if (remain < 11)
return; return null;
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
v = rules.GetVector3Item(idx++); //cut v = rules.GetVector3Item(idx++); //cut
@@ -7361,7 +7385,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TYPE_TUBE: case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
if (remain < 11) if (remain < 11)
return; return null;
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
v = rules.GetVector3Item(idx++); //cut v = rules.GetVector3Item(idx++); //cut
@@ -7380,7 +7404,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TYPE_RING: case (int)ScriptBaseClass.PRIM_TYPE_RING:
if (remain < 11) if (remain < 11)
return; return null;
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
v = rules.GetVector3Item(idx++); //cut v = rules.GetVector3Item(idx++); //cut
@@ -7399,7 +7423,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TYPE_SCULPT: case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
if (remain < 2) if (remain < 2)
return; return null;
string map = rules.Data[idx++].ToString(); string map = rules.Data[idx++].ToString();
face = (int)rules.GetLSLIntegerItem(idx++); // type face = (int)rules.GetLSLIntegerItem(idx++); // type
@@ -7411,7 +7435,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TEXTURE: case (int)ScriptBaseClass.PRIM_TEXTURE:
if (remain < 5) if (remain < 5)
return; return null;
face=(int)rules.GetLSLIntegerItem(idx++); face=(int)rules.GetLSLIntegerItem(idx++);
string tex=rules.Data[idx++].ToString(); string tex=rules.Data[idx++].ToString();
@@ -7428,7 +7452,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_COLOR: case (int)ScriptBaseClass.PRIM_COLOR:
if (remain < 3) if (remain < 3)
return; return null;
face=(int)rules.GetLSLIntegerItem(idx++); face=(int)rules.GetLSLIntegerItem(idx++);
LSL_Vector color=rules.GetVector3Item(idx++); LSL_Vector color=rules.GetVector3Item(idx++);
@@ -7441,7 +7465,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_FLEXIBLE: case (int)ScriptBaseClass.PRIM_FLEXIBLE:
if (remain < 7) if (remain < 7)
return; return null;
bool flexi = rules.GetLSLIntegerItem(idx++); bool flexi = rules.GetLSLIntegerItem(idx++);
int softness = rules.GetLSLIntegerItem(idx++); int softness = rules.GetLSLIntegerItem(idx++);
@@ -7457,7 +7481,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_POINT_LIGHT: case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
if (remain < 5) if (remain < 5)
return; return null;
bool light = rules.GetLSLIntegerItem(idx++); bool light = rules.GetLSLIntegerItem(idx++);
LSL_Vector lightcolor = rules.GetVector3Item(idx++); LSL_Vector lightcolor = rules.GetVector3Item(idx++);
float intensity = (float)rules.GetLSLFloatItem(idx++); float intensity = (float)rules.GetLSLFloatItem(idx++);
@@ -7470,7 +7494,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_GLOW: case (int)ScriptBaseClass.PRIM_GLOW:
if (remain < 2) if (remain < 2)
return; return null;
face = rules.GetLSLIntegerItem(idx++); face = rules.GetLSLIntegerItem(idx++);
float glow = (float)rules.GetLSLFloatItem(idx++); float glow = (float)rules.GetLSLFloatItem(idx++);
@@ -7480,7 +7504,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_BUMP_SHINY: case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
if (remain < 3) if (remain < 3)
return; return null;
face = (int)rules.GetLSLIntegerItem(idx++); face = (int)rules.GetLSLIntegerItem(idx++);
int shiny = (int)rules.GetLSLIntegerItem(idx++); int shiny = (int)rules.GetLSLIntegerItem(idx++);
Bumpiness bump = (Bumpiness)(int)rules.GetLSLIntegerItem(idx++); Bumpiness bump = (Bumpiness)(int)rules.GetLSLIntegerItem(idx++);
@@ -7491,7 +7515,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_FULLBRIGHT: case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
if (remain < 2) if (remain < 2)
return; return null;
face = rules.GetLSLIntegerItem(idx++); face = rules.GetLSLIntegerItem(idx++);
bool st = rules.GetLSLIntegerItem(idx++); bool st = rules.GetLSLIntegerItem(idx++);
SetFullBright(part, face , st); SetFullBright(part, face , st);
@@ -7499,17 +7523,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_MATERIAL: case (int)ScriptBaseClass.PRIM_MATERIAL:
if (remain < 1) if (remain < 1)
return; return null;
int mat = rules.GetLSLIntegerItem(idx++); int mat = rules.GetLSLIntegerItem(idx++);
if (mat < 0 || mat > 7) if (mat < 0 || mat > 7)
return; return null;
part.Material = Convert.ToByte(mat); part.Material = Convert.ToByte(mat);
break; break;
case (int)ScriptBaseClass.PRIM_PHANTOM: case (int)ScriptBaseClass.PRIM_PHANTOM:
if (remain < 1) if (remain < 1)
return; return null;
string ph = rules.Data[idx++].ToString(); string ph = rules.Data[idx++].ToString();
m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1"));
@@ -7518,7 +7542,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_PHYSICS: case (int)ScriptBaseClass.PRIM_PHYSICS:
if (remain < 1) if (remain < 1)
return; return null;
string phy = rules.Data[idx++].ToString(); string phy = rules.Data[idx++].ToString();
bool physics; bool physics;
@@ -7532,7 +7556,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
if (remain < 1) if (remain < 1)
return; return null;
string temp = rules.Data[idx++].ToString(); string temp = rules.Data[idx++].ToString();
m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1"));
@@ -7541,7 +7565,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TEXGEN: case (int)ScriptBaseClass.PRIM_TEXGEN:
if (remain < 2) if (remain < 2)
return; return null;
//face,type //face,type
face = rules.GetLSLIntegerItem(idx++); face = rules.GetLSLIntegerItem(idx++);
int style = rules.GetLSLIntegerItem(idx++); int style = rules.GetLSLIntegerItem(idx++);
@@ -7549,7 +7573,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
break; break;
case (int)ScriptBaseClass.PRIM_TEXT: case (int)ScriptBaseClass.PRIM_TEXT:
if (remain < 3) if (remain < 3)
return; return null;
string primText = rules.GetLSLStringItem(idx++); string primText = rules.GetLSLStringItem(idx++);
LSL_Vector primTextColor = rules.GetVector3Item(idx++); LSL_Vector primTextColor = rules.GetVector3Item(idx++);
LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++); LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++);
@@ -7561,25 +7585,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
break; break;
case (int)ScriptBaseClass.PRIM_NAME: case (int)ScriptBaseClass.PRIM_NAME:
if (remain < 1) if (remain < 1)
return; return null;
string primName = rules.GetLSLStringItem(idx++); string primName = rules.GetLSLStringItem(idx++);
part.Name = primName; part.Name = primName;
break; break;
case (int)ScriptBaseClass.PRIM_DESC: case (int)ScriptBaseClass.PRIM_DESC:
if (remain < 1) if (remain < 1)
return; return null;
string primDesc = rules.GetLSLStringItem(idx++); string primDesc = rules.GetLSLStringItem(idx++);
part.Description = primDesc; part.Description = primDesc;
break; break;
case (int)ScriptBaseClass.PRIM_ROT_LOCAL: case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
if (remain < 1) if (remain < 1)
return; return null;
LSL_Rotation lr = rules.GetQuaternionItem(idx++); LSL_Rotation lr = rules.GetQuaternionItem(idx++);
SetRot(part, Rot2Quaternion(lr)); SetRot(part, Rot2Quaternion(lr));
break; break;
case (int)ScriptBaseClass.PRIM_OMEGA: case (int)ScriptBaseClass.PRIM_OMEGA:
if (remain < 3) if (remain < 3)
return; return null;
LSL_Vector axis = rules.GetVector3Item(idx++); LSL_Vector axis = rules.GetVector3Item(idx++);
LSL_Float spinrate = rules.GetLSLFloatItem(idx++); LSL_Float spinrate = rules.GetLSLFloatItem(idx++);
LSL_Float gain = rules.GetLSLFloatItem(idx++); LSL_Float gain = rules.GetLSLFloatItem(idx++);
@@ -7587,12 +7611,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
break; break;
case (int)ScriptBaseClass.PRIM_LINK_TARGET: case (int)ScriptBaseClass.PRIM_LINK_TARGET:
if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
return; return null;
LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
LSL_List new_rules = rules.GetSublist(idx, -1);
setLinkPrimParams((int)new_linknumber, new_rules);
return; return rules.GetSublist(idx, -1);
} }
} }
} }
@@ -7614,6 +7635,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
} }
} }
} }
return null;
} }
public LSL_String llStringToBase64(string str) public LSL_String llStringToBase64(string str)
@@ -10686,7 +10708,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (obj.OwnerID != m_host.OwnerID) if (obj.OwnerID != m_host.OwnerID)
return; return;
SetPrimParams(obj, rules); LSL_List remaining = SetPrimParams(obj, rules);
while (remaining != null && remaining.Length > 2)
{
LSL_Integer newLink = remaining.GetLSLIntegerItem(0);
LSL_List newrules = remaining.GetSublist(1, -1);
foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){
remaining = SetPrimParams(part, newrules);
}
}
} }
public LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules) public LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules)

View File

@@ -2434,8 +2434,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (!npcModule.CheckPermissions(npcId, m_host.OwnerID)) if (!npcModule.CheckPermissions(npcId, m_host.OwnerID))
return new LSL_Vector(0, 0, 0); return new LSL_Vector(0, 0, 0);
Vector3 pos = World.GetScenePresence(npcId).AbsolutePosition; ScenePresence sp = World.GetScenePresence(npcId);
return new LSL_Vector(pos.X, pos.Y, pos.Z);
if (sp != null)
{
Vector3 pos = sp.AbsolutePosition;
return new LSL_Vector(pos.X, pos.Y, pos.Z);
}
} }
return new LSL_Vector(0, 0, 0); return new LSL_Vector(0, 0, 0);
@@ -2503,9 +2508,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W); return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W);
ScenePresence sp = World.GetScenePresence(npcId); ScenePresence sp = World.GetScenePresence(npcId);
Quaternion rot = sp.Rotation;
return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W); if (sp != null)
{
Quaternion rot = sp.Rotation;
return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
}
} }
return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W); return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W);
@@ -2527,7 +2535,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return; return;
ScenePresence sp = World.GetScenePresence(npcId); ScenePresence sp = World.GetScenePresence(npcId);
sp.Rotation = LSL_Api.Rot2Quaternion(rotation);
if (sp != null)
sp.Rotation = LSL_Api.Rot2Quaternion(rotation);
} }
} }
@@ -2689,6 +2699,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{ {
CheckThreatLevel(ThreatLevel.High, "osNpcTouch"); CheckThreatLevel(ThreatLevel.High, "osNpcTouch");
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
INPCModule module = World.RequestModuleInterface<INPCModule>(); INPCModule module = World.RequestModuleInterface<INPCModule>();
int linkNum = link_num.value; int linkNum = link_num.value;
if (module != null || (linkNum < 0 && linkNum != ScriptBaseClass.LINK_THIS)) if (module != null || (linkNum < 0 && linkNum != ScriptBaseClass.LINK_THIS))
@@ -2696,12 +2707,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
UUID npcId; UUID npcId;
if (!UUID.TryParse(npcLSL_Key, out npcId) || !module.CheckPermissions(npcId, m_host.OwnerID)) if (!UUID.TryParse(npcLSL_Key, out npcId) || !module.CheckPermissions(npcId, m_host.OwnerID))
return; return;
SceneObjectPart part = null; SceneObjectPart part = null;
UUID objectId; UUID objectId;
if (UUID.TryParse(LSL_String.ToString(object_key), out objectId)) if (UUID.TryParse(LSL_String.ToString(object_key), out objectId))
part = World.GetSceneObjectPart(objectId); part = World.GetSceneObjectPart(objectId);
if (part == null) if (part == null)
return; return;
if (linkNum != ScriptBaseClass.LINK_THIS) if (linkNum != ScriptBaseClass.LINK_THIS)
{ {
if (linkNum == 0 || linkNum == ScriptBaseClass.LINK_ROOT) if (linkNum == 0 || linkNum == ScriptBaseClass.LINK_ROOT)
@@ -2716,6 +2730,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return; return;
} }
} }
module.Touch(npcId, part.UUID); module.Touch(npcId, part.UUID);
} }
} }
@@ -2866,7 +2881,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
avatar.SpeedModifier = (float)SpeedModifier; avatar.SpeedModifier = (float)SpeedModifier;
} }
public void osKickAvatar(string FirstName,string SurName,string alert) public void osKickAvatar(string FirstName, string SurName, string alert)
{ {
CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar");
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
@@ -2880,7 +2895,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
sp.ControllingClient.Kick(alert); sp.ControllingClient.Kick(alert);
// ...and close on our side // ...and close on our side
sp.Scene.IncomingCloseAgent(sp.UUID); sp.Scene.IncomingCloseAgent(sp.UUID, false);
} }
}); });
} }

View File

@@ -226,6 +226,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public const int ATTACH_BELLY = 28; public const int ATTACH_BELLY = 28;
public const int ATTACH_RPEC = 29; public const int ATTACH_RPEC = 29;
public const int ATTACH_LPEC = 30; public const int ATTACH_LPEC = 30;
public const int ATTACH_LEFT_PEC = 29; // Same value as ATTACH_RPEC, see https://jira.secondlife.com/browse/SVC-580
public const int ATTACH_RIGHT_PEC = 30; // Same value as ATTACH_LPEC, see https://jira.secondlife.com/browse/SVC-580
public const int ATTACH_HUD_CENTER_2 = 31; public const int ATTACH_HUD_CENTER_2 = 31;
public const int ATTACH_HUD_TOP_RIGHT = 32; public const int ATTACH_HUD_TOP_RIGHT = 32;
public const int ATTACH_HUD_TOP_CENTER = 33; public const int ATTACH_HUD_TOP_CENTER = 33;

View File

@@ -589,7 +589,19 @@ namespace OpenSim.Region.ScriptEngine.XEngine
if (m_Assemblies.ContainsKey(instance.AssetID)) if (m_Assemblies.ContainsKey(instance.AssetID))
{ {
string assembly = m_Assemblies[instance.AssetID]; string assembly = m_Assemblies[instance.AssetID];
instance.SaveState(assembly);
try
{
instance.SaveState(assembly);
}
catch (Exception e)
{
m_log.Error(
string.Format(
"[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
, e);
}
} }
// Clear the event queue and abort the instance thread // Clear the event queue and abort the instance thread
@@ -707,7 +719,18 @@ namespace OpenSim.Region.ScriptEngine.XEngine
assembly = m_Assemblies[i.AssetID]; assembly = m_Assemblies[i.AssetID];
} }
i.SaveState(assembly); try
{
i.SaveState(assembly);
}
catch (Exception e)
{
m_log.Error(
string.Format(
"[XEngine]: Failed to save state of script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
i.PrimName, i.ScriptName, i.ItemID, i.ObjectID, World.Name)
, e);
}
} }
instances.Clear(); instances.Clear();
@@ -982,10 +1005,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
return false; return false;
} }
UUID assetID = item.AssetID; m_log.DebugFormat(
"[XEngine] Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
//m_log.DebugFormat("[XEngine] Compiling script {0} ({1} on object {2})", UUID assetID = item.AssetID;
// item.Name, itemID.ToString(), part.ParentGroup.RootPart.Name);
ScenePresence presence = m_Scene.GetScenePresence(item.OwnerID); ScenePresence presence = m_Scene.GetScenePresence(item.OwnerID);
@@ -1164,10 +1189,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
stateSource, m_MaxScriptQueue); stateSource, m_MaxScriptQueue);
// if (DebugLevel >= 1) // if (DebugLevel >= 1)
m_log.DebugFormat( // m_log.DebugFormat(
"[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", // "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, // part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); // part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
if (presence != null) if (presence != null)
{ {

View File

@@ -933,6 +933,11 @@ namespace OpenSim.Tests.Common.Mock
} }
public void Close() public void Close()
{
Close(false);
}
public void Close(bool force)
{ {
// Fire the callback for this connection closing // Fire the callback for this connection closing
// This is necesary to get the presence detector to notice that a client has logged out. // This is necesary to get the presence detector to notice that a client has logged out.

View File

@@ -675,7 +675,9 @@
;; Maximum number of events to queue for a script (excluding timers) ;; Maximum number of events to queue for a script (excluding timers)
; MaxScriptEventQueue = 300 ; MaxScriptEventQueue = 300
;; Stack size per thread created ;; Stack size per script engine thread in bytes.
;; If you are experiencing StackOverflowExceptions you may want to increase this (e.g. double it).
;; The trade-off may be increased memory usage by the script engine.
; ThreadStackSize = 262144 ; ThreadStackSize = 262144
;# {DeleteScriptsOnStartup} {} {Delete previously compiled script DLLs on startup?} (true false) true ;# {DeleteScriptsOnStartup} {} {Delete previously compiled script DLLs on startup?} (true false) true

View File

@@ -7,6 +7,16 @@
[AssetService] [AssetService]
ConnectionString = "URI=file:Asset.db,version=3" ConnectionString = "URI=file:Asset.db,version=3"
; The HGAssetService section controls the connection given to the AssetService in a Hypergrid configuration.
; This has to be separate from [AssetService] because the Hypergrid facing connector uses [HGAssetService] for its config data instead.
; However, the internal asset service will still use the [AssetService] section.
; Therefore, you will almost certainly want the ConnectionString in [HGAssetService] to be the same as in [AssetService]
; so that they both access the same database.
; This issue does not apply to normal MySQL/MSSQL configurations, since by default they use the settings in [DatabaseService] and
; do not have separate connection strings for different services.
[HGAssetService]
ConnectionString = "URI=file:Asset.db,version=3"
[InventoryService] [InventoryService]
;ConnectionString = "URI=file:inventory.db,version=3" ;ConnectionString = "URI=file:inventory.db,version=3"
; if you have a legacy inventory store use the connection string below ; if you have a legacy inventory store use the connection string below

View File

@@ -1760,6 +1760,7 @@
<Reference name="System.Core"/> <Reference name="System.Core"/>
<Reference name="System.Xml"/> <Reference name="System.Xml"/>
<Reference name="Mono.Addins" path="../../../bin/"/> <Reference name="Mono.Addins" path="../../../bin/"/>
<Reference name="NDesk.Options" path="../../../bin/"/>
<Reference name="OpenMetaverseTypes" path="../../../bin/"/> <Reference name="OpenMetaverseTypes" path="../../../bin/"/>
<Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/> <Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
<Reference name="OpenMetaverse" path="../../../bin/"/> <Reference name="OpenMetaverse" path="../../../bin/"/>