diff options
Diffstat (limited to 'OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs')
-rw-r--r-- | OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | 138 |
1 files changed, 111 insertions, 27 deletions
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index a3cefc9..b3bfe07 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | |||
@@ -26,73 +26,157 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
29 | using System.Threading; | ||
29 | using OpenMetaverse; | 30 | using OpenMetaverse; |
30 | using Nini.Config; | 31 | using Nini.Config; |
31 | using OpenSim.Region.Framework.Interfaces; | 32 | using OpenSim.Region.Framework.Interfaces; |
32 | using OpenSim.Region.Framework.Scenes; | 33 | using OpenSim.Region.Framework.Scenes; |
34 | using OpenSim.Region.CoreModules.Avatar.NPC; | ||
33 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
36 | using Timer=System.Timers.Timer; | ||
34 | 37 | ||
35 | namespace OpenSim.Region.OptionalModules.World.NPC | 38 | namespace OpenSim.Region.OptionalModules.World.NPC |
36 | { | 39 | { |
37 | public interface INPCModule | ||
38 | { | ||
39 | UUID CreateNPC(string firstname, string lastname,Vector3 position, Scene scene, UUID cloneAppearanceFrom); | ||
40 | void Autopilot(UUID agentID, Scene scene, Vector3 pos); | ||
41 | void Say(UUID agentID, Scene scene, string text); | ||
42 | void DeleteNPC(UUID agentID, Scene scene); | ||
43 | } | ||
44 | |||
45 | public class NPCModule : IRegionModule, INPCModule | 40 | public class NPCModule : IRegionModule, INPCModule |
46 | { | 41 | { |
47 | // private const bool m_enabled = false; | 42 | // private const bool m_enabled = false; |
48 | 43 | ||
44 | private Mutex m_createMutex = new Mutex(false); | ||
45 | |||
46 | private Timer m_timer = new Timer(500); | ||
47 | |||
49 | private Dictionary<UUID,NPCAvatar> m_avatars = new Dictionary<UUID, NPCAvatar>(); | 48 | private Dictionary<UUID,NPCAvatar> m_avatars = new Dictionary<UUID, NPCAvatar>(); |
50 | 49 | ||
50 | private Dictionary<UUID,AvatarAppearance> m_appearanceCache = new Dictionary<UUID, AvatarAppearance>(); | ||
51 | |||
52 | // Timer vars. | ||
53 | private bool p_inUse = false; | ||
54 | private readonly object p_lock = new object(); | ||
55 | // Private Temporary Variables. | ||
56 | private string p_firstname; | ||
57 | private string p_lastname; | ||
58 | private Vector3 p_position; | ||
59 | private Scene p_scene; | ||
60 | private UUID p_cloneAppearanceFrom; | ||
61 | private UUID p_returnUuid; | ||
62 | |||
63 | private AvatarAppearance GetAppearance(UUID target, Scene scene) | ||
64 | { | ||
65 | if (m_appearanceCache.ContainsKey(target)) | ||
66 | return m_appearanceCache[target]; | ||
67 | |||
68 | AvatarAppearance x = scene.CommsManager.AvatarService.GetUserAppearance(target); | ||
69 | |||
70 | m_appearanceCache.Add(target, x); | ||
71 | |||
72 | return x; | ||
73 | } | ||
74 | |||
51 | public UUID CreateNPC(string firstname, string lastname,Vector3 position, Scene scene, UUID cloneAppearanceFrom) | 75 | public UUID CreateNPC(string firstname, string lastname,Vector3 position, Scene scene, UUID cloneAppearanceFrom) |
52 | { | 76 | { |
53 | NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, scene); | 77 | // Block. |
54 | scene.AddNewClient(npcAvatar); | 78 | m_createMutex.WaitOne(); |
55 | 79 | ||
56 | ScenePresence sp; | 80 | // Copy Temp Variables for Timer to pick up. |
57 | if(scene.TryGetAvatar(npcAvatar.AgentId, out sp)) | 81 | lock (p_lock) |
58 | { | 82 | { |
59 | AvatarAppearance x = scene.CommsManager.AvatarService.GetUserAppearance(cloneAppearanceFrom); | 83 | p_firstname = firstname; |
60 | 84 | p_lastname = lastname; | |
61 | List<byte> wearbyte = new List<byte>(); | 85 | p_position = position; |
62 | for (int i = 0; i < x.VisualParams.Length; i++) | 86 | p_scene = scene; |
63 | { | 87 | p_cloneAppearanceFrom = cloneAppearanceFrom; |
64 | wearbyte.Add(x.VisualParams[i]); | 88 | p_inUse = true; |
65 | } | 89 | p_returnUuid = UUID.Zero; |
90 | } | ||
66 | 91 | ||
67 | sp.SetAppearance(x.Texture.GetBytes(), wearbyte); | 92 | while (p_returnUuid == UUID.Zero) |
93 | { | ||
94 | Thread.Sleep(250); | ||
68 | } | 95 | } |
69 | 96 | ||
70 | m_avatars.Add(npcAvatar.AgentId, npcAvatar); | 97 | m_createMutex.ReleaseMutex(); |
71 | 98 | ||
72 | return npcAvatar.AgentId; | 99 | return p_returnUuid; |
73 | } | 100 | } |
74 | 101 | ||
75 | public void Autopilot(UUID agentID, Scene scene, Vector3 pos) | 102 | public void Autopilot(UUID agentID, Scene scene, Vector3 pos) |
76 | { | 103 | { |
77 | ScenePresence sp; | 104 | lock (m_avatars) |
78 | scene.TryGetAvatar(agentID, out sp); | 105 | { |
79 | sp.DoAutoPilot(0,pos,m_avatars[agentID]); | 106 | if (m_avatars.ContainsKey(agentID)) |
107 | { | ||
108 | ScenePresence sp; | ||
109 | scene.TryGetAvatar(agentID, out sp); | ||
110 | sp.DoAutoPilot(0, pos, m_avatars[agentID]); | ||
111 | } | ||
112 | } | ||
80 | } | 113 | } |
81 | 114 | ||
82 | public void Say(UUID agentID, Scene scene, string text) | 115 | public void Say(UUID agentID, Scene scene, string text) |
83 | { | 116 | { |
84 | m_avatars[agentID].Say(text); | 117 | lock (m_avatars) |
118 | { | ||
119 | if (m_avatars.ContainsKey(agentID)) | ||
120 | { | ||
121 | m_avatars[agentID].Say(text); | ||
122 | } | ||
123 | } | ||
85 | } | 124 | } |
86 | 125 | ||
87 | public void DeleteNPC(UUID agentID, Scene scene) | 126 | public void DeleteNPC(UUID agentID, Scene scene) |
88 | { | 127 | { |
89 | scene.RemoveClient(agentID); | 128 | lock (m_avatars) |
129 | { | ||
130 | if (m_avatars.ContainsKey(agentID)) | ||
131 | { | ||
132 | scene.RemoveClient(agentID); | ||
133 | m_avatars.Remove(agentID); | ||
134 | } | ||
135 | } | ||
90 | } | 136 | } |
91 | 137 | ||
92 | 138 | ||
93 | public void Initialise(Scene scene, IConfigSource source) | 139 | public void Initialise(Scene scene, IConfigSource source) |
94 | { | 140 | { |
95 | scene.RegisterModuleInterface<INPCModule>(this); | 141 | scene.RegisterModuleInterface<INPCModule>(this); |
142 | |||
143 | m_timer.Elapsed += m_timer_Elapsed; | ||
144 | m_timer.Start(); | ||
145 | } | ||
146 | |||
147 | void m_timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) | ||
148 | { | ||
149 | lock (p_lock) | ||
150 | { | ||
151 | if (p_inUse) | ||
152 | { | ||
153 | p_inUse = false; | ||
154 | |||
155 | NPCAvatar npcAvatar = new NPCAvatar(p_firstname, p_lastname, p_position, p_scene); | ||
156 | npcAvatar.CircuitCode = (uint) Util.RandomClass.Next(0, int.MaxValue); | ||
157 | |||
158 | p_scene.ClientManager.Add(npcAvatar.CircuitCode, npcAvatar); | ||
159 | p_scene.AddNewClient(npcAvatar); | ||
160 | |||
161 | ScenePresence sp; | ||
162 | if (p_scene.TryGetAvatar(npcAvatar.AgentId, out sp)) | ||
163 | { | ||
164 | AvatarAppearance x = GetAppearance(p_cloneAppearanceFrom, p_scene); | ||
165 | |||
166 | List<byte> wearbyte = new List<byte>(); | ||
167 | for (int i = 0; i < x.VisualParams.Length; i++) | ||
168 | { | ||
169 | wearbyte.Add(x.VisualParams[i]); | ||
170 | } | ||
171 | |||
172 | sp.SetAppearance(x.Texture.GetBytes(), wearbyte); | ||
173 | } | ||
174 | |||
175 | m_avatars.Add(npcAvatar.AgentId, npcAvatar); | ||
176 | |||
177 | p_returnUuid = npcAvatar.AgentId; | ||
178 | } | ||
179 | } | ||
96 | } | 180 | } |
97 | 181 | ||
98 | public void PostInitialise() | 182 | public void PostInitialise() |