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 84055cceba..5f4f937811 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 bb0ba3d556..c1a700a853 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2067,10 +2067,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) { @@ -2099,11 +2109,14 @@ 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), - World, - appearance); + ownerID, + World,appearance); return new LSL_Key(x.ToString()); } @@ -2132,6 +2145,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); } @@ -2311,7 +2328,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 3eeb23d63e..7d7813dd68 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)); } @@ -413,6 +417,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 @@ -441,6 +447,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins Action senseEntity = new Action(delegate(ScenePresence presence) { + 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) return; @@ -452,6 +463,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 f5ee73366a..1380ed4ee1 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 fd08373574..b58cf570f0 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 +}