diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 4ab719d728..0b8b95b7c1 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -3514,6 +3514,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
EntityUpdate update;
while (updatesThisCall < maxUpdates && m_entityUpdates.TryDequeue(out update))
{
+ // If we have sent a kill packet for this object
+ // drop any updates on the floor
+ if (update.Entity is SceneObjectPart)
+ {
+ SceneObjectPart part = (SceneObjectPart)update.Entity;
+ if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
+ continue;
+ }
+
++updatesThisCall;
#region UpdateFlags to packet type conversion
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index a0fabffcda..ba84b88381 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -3044,6 +3044,15 @@ namespace OpenSim.Region.Framework.Scenes
UUID ownerID = _ownerID;
UUID objectID = UUID;
UUID parentID = GetRootPartUUID();
+
+ if (ParentGroup.IsAttachment && ParentGroup.RootPart.Shape.State > 30)
+ {
+ // Use the avatar as the parent for HUDs, since the prims
+ // are not sent to other avatars
+ objectID = _ownerID;
+ parentID = _ownerID;
+ }
+
UUID soundID = UUID.Zero;
Vector3 position = AbsolutePosition; // region local
ulong regionHandle = m_parentGroup.Scene.RegionInfo.RegionHandle;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index d61715ec35..236458c091 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -69,6 +69,14 @@ using System.Reflection;
namespace OpenSim.Region.ScriptEngine.Shared.Api
{
+ // MUST be a ref type
+ public class UserInfoCacheEntry
+ {
+ public int time;
+ public UserAccount account;
+ public PresenceInfo pinfo;
+ }
+
///
/// Contains all LSL ll-functions. This class will be in Default AppDomain.
///
@@ -93,6 +101,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
protected int m_scriptConsoleChannel = 0;
protected bool m_scriptConsoleChannelEnabled = false;
protected IUrlModule m_UrlModule = null;
+ protected Dictionary m_userInfoCache =
+ new Dictionary();
public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
{
@@ -1173,12 +1183,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public virtual void llDie()
{
m_host.AddScriptLPS(1);
- if (!m_host.IsAttachment)
- {
- //Enforce a sleep here to avoid ghost prims
- llSleep(0.2d);
- throw new SelfDeleteException();
- }
+ if (!m_host.IsAttachment) throw new SelfDeleteException();
}
public LSL_Float llGround(LSL_Vector offset)
@@ -4249,16 +4254,50 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.AddScriptLPS(1);
UUID uuid = (UUID)id;
-
- UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
- if (account == null)
- return UUID.Zero.ToString();
-
-
PresenceInfo pinfo = null;
- PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
- if (pinfos != null && pinfos.Length > 0)
- pinfo = pinfos[0];
+ UserAccount account;
+
+ UserInfoCacheEntry ce;
+ if (!m_userInfoCache.TryGetValue(uuid, out ce))
+ {
+ account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
+ if (account == null)
+ {
+ m_userInfoCache[uuid] = null; // Cache negative
+ return UUID.Zero.ToString();
+ }
+
+
+ PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
+ if (pinfos != null && pinfos.Length > 0)
+ pinfo = pinfos[0];
+
+ ce = new UserInfoCacheEntry();
+ ce.time = Util.EnvironmentTickCount();
+ ce.account = account;
+ ce.pinfo = pinfo;
+ m_userInfoCache[uuid] = ce;
+ }
+ else
+ {
+ if (ce == null)
+ return UUID.Zero.ToString();
+
+ account = ce.account;
+ pinfo = ce.pinfo;
+ }
+
+ if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
+ {
+ PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
+ if (pinfos != null && pinfos.Length > 0)
+ pinfo = pinfos[0];
+ else
+ pinfo = null;
+
+ ce.time = Util.EnvironmentTickCount();
+ ce.pinfo = pinfo;
+ }
string reply = String.Empty;