diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index eeb74d9320..c710723812 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -26,12 +26,14 @@ */ using System.Collections.Generic; +using System.Threading; using OpenMetaverse; using Nini.Config; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.CoreModules.Avatar.NPC; using OpenSim.Framework; +using Timer=System.Timers.Timer; namespace OpenSim.Region.OptionalModules.World.NPC { @@ -39,10 +41,25 @@ namespace OpenSim.Region.OptionalModules.World.NPC { // private const bool m_enabled = false; + private Mutex m_createMutex = new Mutex(false); + + private Timer m_timer = new Timer(500); + private Dictionary m_avatars = new Dictionary(); private Dictionary m_appearanceCache = new Dictionary(); + // Timer vars. + private bool p_inUse = false; + private readonly object p_lock = new object(); + // Private Temporary Variables. + private string p_firstname; + private string p_lastname; + private Vector3 p_position; + private Scene p_scene; + private UUID p_cloneAppearanceFrom; + private UUID p_returnUuid; + private AvatarAppearance GetAppearance(UUID target, Scene scene) { if (m_appearanceCache.ContainsKey(target)) @@ -57,29 +74,23 @@ namespace OpenSim.Region.OptionalModules.World.NPC public UUID CreateNPC(string firstname, string lastname,Vector3 position, Scene scene, UUID cloneAppearanceFrom) { - NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, scene); - npcAvatar.CircuitCode = (uint) Util.RandomClass.Next(0, int.MaxValue); + // Block. + m_createMutex.WaitOne(); - scene.ClientManager.Add(npcAvatar.CircuitCode, npcAvatar); - scene.AddNewClient(npcAvatar); - - ScenePresence sp; - if(scene.TryGetAvatar(npcAvatar.AgentId, out sp)) + // Copy Temp Variables for Timer to pick up. + lock (p_lock) { - AvatarAppearance x = GetAppearance(cloneAppearanceFrom, scene); - - List wearbyte = new List(); - for (int i = 0; i < x.VisualParams.Length; i++) - { - wearbyte.Add(x.VisualParams[i]); - } - - sp.SetAppearance(x.Texture.GetBytes(), wearbyte); + p_firstname = firstname; + p_lastname = lastname; + p_position = position; + p_scene = scene; + p_cloneAppearanceFrom = cloneAppearanceFrom; + p_inUse = true; } - m_avatars.Add(npcAvatar.AgentId, npcAvatar); + m_createMutex.ReleaseMutex(); - return npcAvatar.AgentId; + return p_returnUuid; } public void Autopilot(UUID agentID, Scene scene, Vector3 pos) @@ -116,6 +127,45 @@ namespace OpenSim.Region.OptionalModules.World.NPC public void Initialise(Scene scene, IConfigSource source) { scene.RegisterModuleInterface(this); + + m_timer.Elapsed += m_timer_Elapsed; + m_timer.Start(); + } + + void m_timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) + { + lock (p_lock) + { + if (p_inUse) + { + p_inUse = false; + + + NPCAvatar npcAvatar = new NPCAvatar(p_firstname, p_lastname, p_position, p_scene); + npcAvatar.CircuitCode = (uint) Util.RandomClass.Next(0, int.MaxValue); + + p_scene.ClientManager.Add(npcAvatar.CircuitCode, npcAvatar); + p_scene.AddNewClient(npcAvatar); + + ScenePresence sp; + if (p_scene.TryGetAvatar(npcAvatar.AgentId, out sp)) + { + AvatarAppearance x = GetAppearance(p_cloneAppearanceFrom, p_scene); + + List wearbyte = new List(); + for (int i = 0; i < x.VisualParams.Length; i++) + { + wearbyte.Add(x.VisualParams[i]); + } + + sp.SetAppearance(x.Texture.GetBytes(), wearbyte); + } + + m_avatars.Add(npcAvatar.AgentId, npcAvatar); + + p_returnUuid = npcAvatar.AgentId; + } + } } public void PostInitialise() diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index fcfa9fc482..61903498cc 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -31,6 +31,7 @@ using System.Collections.Generic; using System.Runtime.Remoting.Lifetime; using System.Text; using System.Net; +using System.Threading; using OpenMetaverse; using Nini.Config; using OpenSim; @@ -1766,6 +1767,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, LSL_Key cloneFrom) { CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); + //QueueUserWorkItem INPCModule module = World.RequestModuleInterface(); if (module != null)