diff --git a/OpenSim/Framework/Cache.cs b/OpenSim/Framework/Cache.cs
index 79e20fc88e..31cab4a021 100644
--- a/OpenSim/Framework/Cache.cs
+++ b/OpenSim/Framework/Cache.cs
@@ -199,7 +199,14 @@ namespace OpenSim.Framework
//
public class Cache
{
+ ///
+ /// Must only be accessed under lock.
+ ///
private List m_Index = new List();
+
+ ///
+ /// Must only be accessed under m_Index lock.
+ ///
private Dictionary m_Lookup =
new Dictionary();
@@ -320,19 +327,19 @@ namespace OpenSim.Framework
{
if (m_Lookup.ContainsKey(index))
item = m_Lookup[index];
- }
- if (item == null)
- {
+ if (item == null)
+ {
+ Expire(true);
+ return null;
+ }
+
+ item.hits++;
+ item.lastUsed = DateTime.Now;
+
Expire(true);
- return null;
}
- item.hits++;
- item.lastUsed = DateTime.Now;
-
- Expire(true);
-
return item;
}
@@ -385,7 +392,10 @@ namespace OpenSim.Framework
//
public Object Find(Predicate d)
{
- CacheItemBase item = m_Index.Find(d);
+ CacheItemBase item;
+
+ lock (m_Index)
+ item = m_Index.Find(d);
if (item == null)
return null;
@@ -419,12 +429,12 @@ namespace OpenSim.Framework
public virtual void Store(string index, Object data, Type container,
Object[] parameters)
{
- Expire(false);
-
CacheItemBase item;
lock (m_Index)
{
+ Expire(false);
+
if (m_Index.Contains(new CacheItemBase(index)))
{
if ((m_Flags & CacheFlags.AllowUpdate) != 0)
@@ -450,9 +460,17 @@ namespace OpenSim.Framework
m_Index.Add(item);
m_Lookup[index] = item;
}
+
item.Store(data);
}
+ ///
+ /// Expire items as appropriate.
+ ///
+ ///
+ /// Callers must lock m_Index.
+ ///
+ ///
protected virtual void Expire(bool getting)
{
if (getting && (m_Strategy == CacheStrategy.Aggressive))
@@ -475,12 +493,10 @@ namespace OpenSim.Framework
switch (m_Strategy)
{
- case CacheStrategy.Aggressive:
- if (Count < Size)
- return;
+ case CacheStrategy.Aggressive:
+ if (Count < Size)
+ return;
- lock (m_Index)
- {
m_Index.Sort(new SortLRU());
m_Index.Reverse();
@@ -490,7 +506,7 @@ namespace OpenSim.Framework
ExpireDelegate doExpire = OnExpire;
- if (doExpire != null)
+ if (doExpire != null)
{
List candidates =
m_Index.GetRange(target, Count - target);
@@ -513,27 +529,34 @@ namespace OpenSim.Framework
foreach (CacheItemBase item in m_Index)
m_Lookup[item.uuid] = item;
}
- }
- break;
- default:
- break;
+
+ break;
+
+ default:
+ break;
}
}
public void Invalidate(string uuid)
{
- if (!m_Lookup.ContainsKey(uuid))
- return;
+ lock (m_Index)
+ {
+ if (!m_Lookup.ContainsKey(uuid))
+ return;
- CacheItemBase item = m_Lookup[uuid];
- m_Lookup.Remove(uuid);
- m_Index.Remove(item);
+ CacheItemBase item = m_Lookup[uuid];
+ m_Lookup.Remove(uuid);
+ m_Index.Remove(item);
+ }
}
public void Clear()
{
- m_Index.Clear();
- m_Lookup.Clear();
+ lock (m_Index)
+ {
+ m_Index.Clear();
+ m_Lookup.Clear();
+ }
}
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 6be2bd7501..91f36a5dff 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -1046,8 +1046,21 @@ namespace OpenSim.Framework
void InPacket(object NewPack);
void ProcessInPacket(Packet NewPack);
+
+ ///
+ /// Close this client
+ ///
void Close();
- void Close(bool sendStop);
+
+ ///
+ /// Close this client
+ ///
+ ///
+ /// 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.
+ ///
+ void Close(bool sendStop, bool force);
+
void Kick(string message);
///
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index 6255515c32..9c7598a776 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -35,6 +35,7 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Timers;
using log4net;
+using NDesk.Options;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
@@ -310,8 +311,11 @@ namespace OpenSim
"Change the scale of a named prim", HandleEditScale);
m_console.Commands.AddCommand("Users", false, "kick user",
- "kick user [message]",
- "Kick a user off the simulator", KickUserCommand);
+ "kick user [--force] [message]",
+ "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",
"show users [full]",
@@ -416,6 +420,7 @@ namespace OpenSim
{
RunCommandScript(m_shutdownCommandsFile);
}
+
base.ShutdownSpecific();
}
@@ -453,11 +458,17 @@ namespace OpenSim
/// name of avatar to kick
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 mainParams = options.Parse(cmdparams);
+
+ if (mainParams.Count < 4)
return;
string alert = null;
- if (cmdparams.Length > 4)
+ if (mainParams.Count > 4)
alert = String.Format("\n{0}\n", String.Join(" ", cmdparams, 4, cmdparams.Length - 4));
IList agents = SceneManager.GetCurrentSceneAvatars();
@@ -466,8 +477,8 @@ namespace OpenSim
{
RegionInfo regionInfo = presence.Scene.RegionInfo;
- if (presence.Firstname.ToLower().Contains(cmdparams[2].ToLower()) &&
- presence.Lastname.ToLower().Contains(cmdparams[3].ToLower()))
+ if (presence.Firstname.ToLower().Contains(mainParams[2].ToLower()) &&
+ presence.Lastname.ToLower().Contains(mainParams[3].ToLower()))
{
MainConsole.Instance.Output(
String.Format(
@@ -480,7 +491,7 @@ namespace OpenSim
else
presence.ControllingClient.Kick("\nYou have been logged out by an administrator.\n");
- presence.Scene.IncomingCloseAgent(presence.UUID);
+ presence.Scene.IncomingCloseAgent(presence.UUID, force);
}
}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
index cd70410680..d604cf6f51 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
@@ -94,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
UUID spId = TestHelpers.ParseTail(0x1);
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
Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0));
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index ddd8f18e11..2dcc9cb3c9 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -509,19 +509,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
///
public void Close()
{
- Close(true);
+ Close(true, false);
}
- ///
- /// Shut down the client view
- ///
- public void Close(bool sendStop)
+ public void Close(bool sendStop, bool force)
{
// 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.
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;
IsActive = false;
@@ -12140,7 +12139,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
Kick(reason);
Thread.Sleep(1000);
- Close();
+ Disconnect();
}
public void Disconnect()
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 7042c9a228..fb73e1d975 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -1515,7 +1515,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (!client.IsLoggingOut)
{
client.IsLoggingOut = true;
- client.Close(false);
+ client.Close(false, false);
}
}
}
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index d9a619d15b..48f3a23e90 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -461,7 +461,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
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.
Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null);
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 560f807167..c248f956a3 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -644,7 +644,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// an agent cannot teleport back to this region if it has teleported away.
Thread.Sleep(2000);
- sp.Scene.IncomingCloseAgent(sp.UUID);
+ sp.Scene.IncomingCloseAgent(sp.UUID, false);
}
else
{
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
index 8b2f2f84e9..05eaaeceb0 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
@@ -308,36 +308,44 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
try
{
- if (alpha == 256)
- bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
- else
- bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
-
- 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)
+ // XXX: 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.
+ lock (this)
{
- using (SolidBrush bgFillBrush = new SolidBrush(bgColor))
- {
- graph.FillRectangle(bgFillBrush, 0, 0, width, height);
- }
- }
+ if (alpha == 256)
+ bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
+ else
+ bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
- for (int w = 0; w < bitmap.Width; w++)
- {
- if (alpha <= 255)
+ 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)
{
- 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];
try
@@ -355,11 +363,19 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
}
finally
{
- if (graph != null)
- graph.Dispose();
-
- if (bitmap != null)
- bitmap.Dispose();
+ // XXX: 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.
+ lock (this)
+ {
+ if (graph != null)
+ graph.Dispose();
+
+ if (bitmap != null)
+ bitmap.Dispose();
+ }
}
}
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
index 6eb99ea710..8ed1833aca 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
@@ -313,7 +313,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
if (m_scenes.ContainsKey(destination.RegionID))
{
- Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id); });
+// m_log.DebugFormat(
+// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
+// s.RegionInfo.RegionName, destination.RegionHandle);
+
+ Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id, false); });
return true;
}
//m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent");
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index 619550c1c5..142567bff1 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -97,6 +97,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver
}
}
+ ///
+ /// Used to cache lookups for valid groups.
+ ///
+ private IDictionary m_validGroupUuids = new Dictionary();
+
+ private IGroupsModule m_groupsModule;
+
public ArchiveReadRequest(Scene scene, string loadPath, bool merge, bool skipAssets, Guid requestId)
{
m_scene = scene;
@@ -120,6 +127,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
// Zero can never be a valid user id
m_validUserUuids[UUID.Zero] = false;
+
+ m_groupsModule = m_scene.RequestModuleInterface();
}
public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge, bool skipAssets, Guid requestId)
@@ -132,6 +141,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
// Zero can never be a valid user id
m_validUserUuids[UUID.Zero] = false;
+
+ m_groupsModule = m_scene.RequestModuleInterface();
}
///
@@ -302,6 +313,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
if (!ResolveUserUuid(part.LastOwnerID))
part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
+ if (!ResolveGroupUuid(part.GroupID))
+ part.GroupID = UUID.Zero;
+
// And zap any troublesome sit target information
// part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
// part.SitTargetPosition = new Vector3(0, 0, 0);
@@ -335,13 +349,18 @@ namespace OpenSim.Region.CoreModules.World.Archiver
{
kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
}
+
if (kvp.Value.CreatorData == null || kvp.Value.CreatorData == string.Empty)
{
if (!ResolveUserUuid(kvp.Value.CreatorID))
kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
}
+
if (UserManager != null)
UserManager.AddUser(kvp.Value.CreatorID, kvp.Value.CreatorData);
+
+ if (!ResolveGroupUuid(kvp.Value.GroupID))
+ kvp.Value.GroupID = UUID.Zero;
}
part.TaskInventory.LockItemsForRead(false);
}
@@ -382,9 +401,27 @@ namespace OpenSim.Region.CoreModules.World.Archiver
foreach (string serialisedParcel in serialisedParcels)
{
LandData parcel = LandDataSerializer.Deserialize(serialisedParcel);
+
+ // Validate User and Group UUID's
+
if (!ResolveUserUuid(parcel.OwnerID))
parcel.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
-
+
+ if (!ResolveGroupUuid(parcel.GroupID))
+ {
+ parcel.GroupID = UUID.Zero;
+ parcel.IsGroupOwned = false;
+ }
+
+ List accessList = new List();
+ foreach (LandAccessEntry entry in parcel.ParcelAccessList)
+ {
+ if (ResolveUserUuid(entry.AgentID))
+ accessList.Add(entry);
+ // else, drop this access rule
+ }
+ parcel.ParcelAccessList = accessList;
+
// m_log.DebugFormat(
// "[ARCHIVER]: Adding parcel {0}, local id {1}, area {2}",
// parcel.Name, parcel.LocalID, parcel.Area);
@@ -419,6 +456,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver
}
///
+ /// Look up the given group id to check whether it's one that is valid for this grid.
+ ///
+ ///
+ ///
+ private bool ResolveGroupUuid(UUID uuid)
+ {
+ if (uuid == UUID.Zero)
+ return true; // this means the object has no group
+
+ if (!m_validGroupUuids.ContainsKey(uuid))
+ {
+ bool exists;
+
+ if (m_groupsModule == null)
+ exists = false;
+ else
+ exists = (m_groupsModule.GetGroupRecord(uuid) != null);
+
+ m_validGroupUuids.Add(uuid, exists);
+ }
+
+ return m_validGroupUuids[uuid];
+ }
+
/// Load an asset
///
///
diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
index 14c1a3947e..a2f09507ef 100644
--- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
+++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
@@ -85,13 +85,15 @@ namespace OpenSim.Region.CoreModules.World.Sound
dis = 0;
}
+ float thisSpGain;
+
// Scale by distance
if (radius == 0)
- gain = (float)((double)gain * ((100.0 - dis) / 100.0));
+ thisSpGain = (float)((double)gain * ((100.0 - dis) / 100.0));
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);
});
}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 0883913f8d..249946008b 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -4340,15 +4340,18 @@ namespace OpenSim.Region.Framework.Scenes
/// Tell a single agent to disconnect from the region.
///
///
- ///
- public bool IncomingCloseAgent(UUID agentID, bool childOnly)
+ ///
+ /// 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.
+ ///
+ public bool IncomingCloseAgent(UUID agentID, bool force)
{
//m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
if (presence != null)
{
- presence.ControllingClient.Close();
+ presence.ControllingClient.Close(true, force);
return true;
}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 593e1d3afd..af06250899 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -3560,23 +3560,32 @@ namespace OpenSim.Region.Framework.Scenes
}
///
- /// Set the color of prim faces
+ /// Set the color & alpha of prim faces
///
- ///
///
- public void SetFaceColor(Vector3 color, int face)
+ ///
+ ///
+ public void SetFaceColorAlpha(int face, Vector3 color, double ?alpha)
{
+ Vector3 clippedColor = Util.Clip(color, 0.0f, 1.0f);
+ float clippedAlpha = alpha.HasValue ?
+ Util.Clip((float)alpha.Value, 0.0f, 1.0f) : 0;
+
// The only way to get a deep copy/ If we don't do this, we can
- // mever detect color changes further down.
+ // never detect color changes further down.
Byte[] buf = Shape.Textures.GetBytes();
Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length);
Color4 texcolor;
if (face >= 0 && face < GetNumberOfSides())
{
texcolor = tex.CreateFace((uint)face).RGBA;
- texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f);
- texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f);
- texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f);
+ texcolor.R = clippedColor.X;
+ texcolor.G = clippedColor.Y;
+ texcolor.B = clippedColor.Z;
+ if (alpha.HasValue)
+ {
+ texcolor.A = clippedAlpha;
+ }
tex.FaceTextures[face].RGBA = texcolor;
UpdateTextureEntry(tex.GetBytes());
return;
@@ -3588,15 +3597,23 @@ namespace OpenSim.Region.Framework.Scenes
if (tex.FaceTextures[i] != null)
{
texcolor = tex.FaceTextures[i].RGBA;
- texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f);
- texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f);
- texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f);
+ texcolor.R = clippedColor.X;
+ texcolor.G = clippedColor.Y;
+ texcolor.B = clippedColor.Z;
+ if (alpha.HasValue)
+ {
+ texcolor.A = clippedAlpha;
+ }
tex.FaceTextures[i].RGBA = texcolor;
}
texcolor = tex.DefaultTexture.RGBA;
- texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f);
- texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f);
- texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f);
+ texcolor.R = clippedColor.X;
+ texcolor.G = clippedColor.Y;
+ texcolor.B = clippedColor.Z;
+ if (alpha.HasValue)
+ {
+ texcolor.A = clippedAlpha;
+ }
tex.DefaultTexture.RGBA = texcolor;
}
UpdateTextureEntry(tex.GetBytes());
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
index 5758869e7a..5faf131caf 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
@@ -141,7 +141,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
TestScene scene = new SceneHelpers().SetupScene();
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.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null);
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 3b83e58933..1660c45d30 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -890,10 +890,10 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
public void Close()
{
- Close(true);
+ Close(true, false);
}
- public void Close(bool sendStop)
+ public void Close(bool sendStop, bool force)
{
Disconnect();
}
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index d00a6c0516..625342e257 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -905,11 +905,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC
public void Close()
{
- Close(true);
+ Close(true, false);
}
- public void Close(bool sendStop)
+ public void Close(bool sendStop, bool force)
{
+ // Remove ourselves from the scene
+ m_scene.RemoveClient(AgentId, false);
}
public void Start()
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 434638d822..0c7f49b126 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -1490,11 +1490,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
scale.y = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.y));
scale.z = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.z));
}
-
- // Next we clamp the scale to the non-physical min/max
- scale.x = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.x));
- scale.y = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.y));
- scale.z = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.z));
+ else
+ {
+ // If not physical, then we clamp the scale to the non-physical min/max
+ scale.x = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.x));
+ scale.y = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.y));
+ scale.z = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.z));
+ }
Vector3 tmp = part.Scale;
tmp.X = (float)scale.x;
@@ -1568,7 +1570,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (face == ScriptBaseClass.ALL_SIDES)
face = SceneObjectPart.ALL_SIDES;
- m_host.SetFaceColor(color, face);
+ m_host.SetFaceColorAlpha(face, color, null);
}
public void SetTexGen(SceneObjectPart part, int face,int style)
@@ -3900,7 +3902,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
try
{
foreach (SceneObjectPart part in parts)
- part.SetFaceColor(color, face);
+ part.SetFaceColorAlpha(face, color, null);
}
finally
{
@@ -8243,8 +8245,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
LSL_Vector color=rules.GetVector3Item(idx++);
double alpha=(double)rules.GetLSLFloatItem(idx++);
- part.SetFaceColor(color, face);
- SetAlpha(part, alpha, face);
+ part.SetFaceColorAlpha(face, color, alpha);
break;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 37766fbbb7..04c3184219 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -2925,7 +2925,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
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");
m_host.AddScriptLPS(1);
@@ -2939,7 +2939,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
sp.ControllingClient.Kick(alert);
// ...and close on our side
- sp.Scene.IncomingCloseAgent(sp.UUID);
+ sp.Scene.IncomingCloseAgent(sp.UUID, false);
}
});
}
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
index 17a0d69838..03be2abf07 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
@@ -546,6 +546,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
"OpenSim.Region.ScriptEngine.Shared.dll"));
parameters.ReferencedAssemblies.Add(Path.Combine(rootPath,
"OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll"));
+ parameters.ReferencedAssemblies.Add(Path.Combine(rootPath,
+ "OpenMetaverseTypes.dll"));
if (lang == enumCompileType.yp)
{
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs
index 6add1305a8..4e3bc6738a 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -935,12 +935,12 @@ namespace OpenSim.Tests.Common.Mock
Close();
}
- public void Close(bool c)
+ public void Close()
{
- Close();
+ Close(true, false);
}
- public void Close()
+ public void Close(bool sendStop, bool force)
{
// Fire the callback for this connection closing
// This is necesary to get the presence detector to notice that a client has logged out.
diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll
index cc55f00919..ce0dd9d636 100755
Binary files a/bin/lib32/BulletSim.dll and b/bin/lib32/BulletSim.dll differ
diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so
index 26ad52ba23..d2d65408af 100755
Binary files a/bin/lib32/libBulletSim.so and b/bin/lib32/libBulletSim.so differ
diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll
index 94dae95849..67d3f1c397 100755
Binary files a/bin/lib64/BulletSim.dll and b/bin/lib64/BulletSim.dll differ
diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so
index 52e9960274..9a5c1712f3 100755
Binary files a/bin/lib64/libBulletSim.so and b/bin/lib64/libBulletSim.so differ
diff --git a/prebuild.xml b/prebuild.xml
index 09336b3594..f85550a3f1 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -1880,6 +1880,7 @@
+