diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs
index b65f82c5ed..cac8479142 100644
--- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs
@@ -42,7 +42,7 @@ namespace OpenSim.Region.Framework.Interfaces
///
/// The avatar appearance to use for the new NPC.
/// The UUID of the ScenePresence created.
- UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, AvatarAppearance appearance);
+ UUID CreateNPC(string firstname, string lastname, Vector3 position, UUID owner, Scene scene, AvatarAppearance appearance);
///
/// Check if the agent is an NPC.
@@ -117,6 +117,13 @@ namespace OpenSim.Region.Framework.Interfaces
/// The UUID of the NPC
///
/// True if the operation succeeded, false if there was no such agent or the agent was not an NPC
- bool DeleteNPC(UUID agentID, Scene scene);
+ bool DeleteNPC(UUID agentID, UUID CallerID, Scene scene);
+
+ ///
+ /// Get the owner of a NPC
+ ///
+ /// The UUID of the NPC
+ /// UUID of owner if the NPC exists, UUID.Zero if there was no such agent, the agent is unowned or the agent was not an NPC
+ UUID GetOwner(UUID agentID);
}
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index 6c7a683a03..b4181a474b 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -42,13 +42,15 @@ namespace OpenSim.Region.OptionalModules.World.NPC
private readonly Vector3 m_startPos;
private readonly UUID m_uuid = UUID.Random();
private readonly Scene m_scene;
+ private readonly UUID m_ownerID;
- public NPCAvatar(string firstname, string lastname, Vector3 position, Scene scene)
+ public NPCAvatar(string firstname, string lastname, Vector3 position, UUID ownerID, Scene scene)
{
m_firstname = firstname;
m_lastname = lastname;
m_startPos = position;
m_scene = scene;
+ m_ownerID = ownerID;
}
public IScene Scene
@@ -56,6 +58,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC
get { return m_scene; }
}
+ public UUID OwnerID
+ {
+ get { return m_ownerID; }
+ }
+
public ISceneAgent SceneAgent { get { throw new NotImplementedException(); } }
public void Say(string message)
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
index 56ff3675ac..e87441703a 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
@@ -91,9 +91,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC
}
public UUID CreateNPC(
- string firstname, string lastname, Vector3 position, Scene scene, AvatarAppearance appearance)
+ string firstname, string lastname, Vector3 position, UUID owner, Scene scene, AvatarAppearance appearance)
{
- NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, scene);
+ NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, owner, scene);
npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0, int.MaxValue);
m_log.DebugFormat(
@@ -234,12 +234,30 @@ namespace OpenSim.Region.OptionalModules.World.NPC
return false;
}
- public bool DeleteNPC(UUID agentID, Scene scene)
+ public UUID GetOwner(UUID agentID)
{
lock (m_avatars)
{
- if (m_avatars.ContainsKey(agentID))
+ NPCAvatar av;
+ if (m_avatars.TryGetValue(agentID, out av))
{
+ return av.OwnerID;
+ }
+ }
+
+ return UUID.Zero;
+ }
+
+ public bool DeleteNPC(UUID agentID, UUID callerID, Scene scene)
+ {
+ lock (m_avatars)
+ {
+ NPCAvatar av;
+ if (m_avatars.TryGetValue(agentID, out av))
+ {
+ if (av.OwnerID != UUID.Zero && callerID != UUID.Zero && av.OwnerID != callerID)
+ return false;
+
scene.RemoveClient(agentID, false);
m_avatars.Remove(agentID);
@@ -268,4 +286,4 @@ namespace OpenSim.Region.OptionalModules.World.NPC
get { return true; }
}
}
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
index 9c66b2567a..571d33d9ce 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
@@ -109,7 +109,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
afm.SetAppearance(sp, originalTe, null);
INPCModule npcModule = scene.RequestModuleInterface();
- UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, sp.Appearance);
+ UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, scene, sp.Appearance);
ScenePresence npc = scene.GetScenePresence(npcId);
@@ -137,7 +137,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
am.RezSingleAttachmentFromInventory(sp, attItemId, (uint)AttachmentPoint.Chest);
INPCModule npcModule = scene.RequestModuleInterface();
- UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, sp.Appearance);
+ UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, scene, sp.Appearance);
ScenePresence npc = scene.GetScenePresence(npcId);
@@ -169,7 +169,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
Vector3 startPos = new Vector3(128, 128, 30);
INPCModule npcModule = scene.RequestModuleInterface();
- UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, scene, sp.Appearance);
+ UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, UUID.Zero, scene, sp.Appearance);
ScenePresence npc = scene.GetScenePresence(npcId);
Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
@@ -240,7 +240,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
Vector3 startPos = new Vector3(128, 128, 30);
INPCModule npcModule = scene.RequestModuleInterface();
- UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, scene, sp.Appearance);
+ UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, UUID.Zero, scene, sp.Appearance);
ScenePresence npc = scene.GetScenePresence(npcId);
SceneObjectPart part = SceneHelpers.AddSceneObject(scene);
@@ -273,7 +273,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
Vector3 startPos = new Vector3(1, 1, 1);
INPCModule npcModule = scene.RequestModuleInterface();
- UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, scene, sp.Appearance);
+ UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, UUID.Zero, scene, sp.Appearance);
ScenePresence npc = scene.GetScenePresence(npcId);
SceneObjectPart part = SceneHelpers.AddSceneObject(scene);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 8cc6554f6e..120ae2c0fe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -2076,10 +2076,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return retVal;
}
+ public LSL_Key osNpcCreateOwned(string firstname, string lastname, LSL_Vector position, string notecard)
+ {
+ CheckThreatLevel(ThreatLevel.High, "osNpcCreateOwned");
+ return NpcCreate(firstname, lastname, position, notecard, true);
+ }
+
public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard)
{
- CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
+ CheckThreatLevel(ThreatLevel.High, "osNpcCreated");
+ return NpcCreate(firstname, lastname, position, notecard, false);
+ }
+ private LSL_Key NpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, bool owned)
+ {
INPCModule module = World.RequestModuleInterface();
if (module != null)
{
@@ -2108,9 +2118,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (appearance == null)
return new LSL_Key(UUID.Zero.ToString());
+ UUID ownerID = UUID.Zero;
+ if (owned)
+ ownerID = m_host.OwnerID;
UUID x = module.CreateNPC(firstname,
lastname,
new Vector3((float) position.x, (float) position.y, (float) position.z),
+ ownerID,
World,appearance);
return new LSL_Key(x.ToString());
@@ -2140,6 +2154,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene))
return new LSL_Key(UUID.Zero.ToString());
+ UUID ownerID = npcModule.GetOwner(npcId);
+ if (ownerID != UUID.Zero && ownerID != m_host.OwnerID)
+ return new LSL_Key(UUID.Zero.ToString());
+
return SaveAppearanceToNotecard(npcId, notecard);
}
@@ -2319,7 +2337,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
INPCModule module = World.RequestModuleInterface();
if (module != null)
{
- module.DeleteNPC(new UUID(npc.m_string), World);
+ module.DeleteNPC(new UUID(npc.m_string), m_host.OwnerID, World);
}
}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 91a7b87d95..ac1c1a98fb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -26,10 +26,13 @@
*/
using System;
+using System.Reflection;
using System.Collections.Generic;
using OpenMetaverse;
using OpenSim.Framework;
+using log4net;
+using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.ScriptEngine.Shared;
using OpenSim.Region.ScriptEngine.Shared.Api;
@@ -51,6 +54,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
private const int AGENT = 1;
private const int AGENT_BY_USERNAME = 0x10;
+ private const int NPC = 0x20;
private const int ACTIVE = 2;
private const int PASSIVE = 4;
private const int SCRIPTED = 8;
@@ -203,7 +207,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
List sensedEntities = new List();
// Is the sensor type is AGENT and not SCRIPTED then include agents
- if ((ts.type & (AGENT | AGENT_BY_USERNAME)) != 0 && (ts.type & SCRIPTED) == 0)
+ if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
{
sensedEntities.AddRange(doAgentSensor(ts));
}
@@ -415,6 +419,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
private List doAgentSensor(SenseRepeatClass ts)
{
+ INPCModule npcModule = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface();
+
List sensedEntities = new List();
// If nobody about quit fast
@@ -446,7 +452,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
Action senseEntity = new Action(delegate(ScenePresence presence)
{
- if (presence.PresenceType == PresenceType.Npc)
+ if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
+ return;
+ if ((ts.type & AGENT) == 0 && presence.PresenceType == PresenceType.User)
return;
if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0)
@@ -460,6 +468,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
toRegionPos = presence.AbsolutePosition;
dis = Math.Abs(Util.GetDistanceTo(toRegionPos, fromRegionPos));
+ if (presence.PresenceType == PresenceType.Npc && npcModule != null)
+ {
+ UUID npcOwner = npcModule.GetOwner(presence.UUID);
+ if (npcOwner != UUID.Zero && npcOwner != SensePoint.OwnerID)
+ return;
+ }
+
// are they in range
if (dis <= ts.range)
{
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index a49feb0278..a815c5bc32 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -172,6 +172,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules);
key osNpcCreate(string user, string name, vector position, string notecard);
+ key osNpcCreateOwned(string user, string name, vector position, string notecard);
LSL_Key osNpcSaveAppearance(key npc, string notecard);
void osNpcLoadAppearance(key npc, string notecard);
vector osNpcGetPos(key npc);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 0ad3f782b6..3c258d8b96 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -52,6 +52,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public const int AGENT = 1;
public const int AGENT_BY_LEGACY_NAME = 1;
public const int AGENT_BY_USERNAME = 0x10;
+ public const int NPC = 0x20;
public const int ACTIVE = 2;
public const int PASSIVE = 4;
public const int SCRIPTED = 8;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index 0d7d5ea87f..6572def1d1 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -488,6 +488,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
return m_OSSL_Functions.osNpcCreate(user, name, position, cloneFrom);
}
+ public key osNpcCreateOwned(string user, string name, vector position, key cloneFrom)
+ {
+ return m_OSSL_Functions.osNpcCreateOwned(user, name, position, cloneFrom);
+ }
+
public key osNpcSaveAppearance(key npc, string notecard)
{
return m_OSSL_Functions.osNpcSaveAppearance(npc, notecard);
@@ -818,4 +823,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
return m_OSSL_Functions.osUnixTimeToTimestamp(time);
}
}
-}
\ No newline at end of file
+}