aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
diff options
context:
space:
mode:
authorUbitUmarov2015-09-01 11:43:07 +0100
committerUbitUmarov2015-09-01 11:43:07 +0100
commitfb78b182520fc9bb0f971afd0322029c70278ea6 (patch)
treeb4e30d383938fdeef8c92d1d1c2f44bb61d329bd /OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
parentlixo (diff)
parentMantis #7713: fixed bug introduced by 1st MOSES patch. (diff)
downloadopensim-SC_OLD-fb78b182520fc9bb0f971afd0322029c70278ea6.zip
opensim-SC_OLD-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.gz
opensim-SC_OLD-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.bz2
opensim-SC_OLD-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.xz
Merge remote-tracking branch 'os/master'
Diffstat (limited to 'OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs')
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs464
1 files changed, 464 insertions, 0 deletions
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
new file mode 100644
index 0000000..9232db9
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
@@ -0,0 +1,464 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Threading;
32using Timer = System.Timers.Timer;
33
34using log4net;
35using Nini.Config;
36using Mono.Addins;
37using OpenMetaverse;
38
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Framework;
42using OpenSim.Services.Interfaces;
43
44namespace OpenSim.Region.OptionalModules.World.NPC
45{
46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "NPCModule")]
47 public class NPCModule : INPCModule, ISharedRegionModule
48 {
49 private static readonly ILog m_log = LogManager.GetLogger(
50 MethodBase.GetCurrentMethod().DeclaringType);
51
52 private Dictionary<UUID, NPCAvatar> m_avatars =
53 new Dictionary<UUID, NPCAvatar>();
54
55 public bool Enabled { get; private set; }
56
57 public void Initialise(IConfigSource source)
58 {
59 IConfig config = source.Configs["NPC"];
60
61 Enabled = (config != null && config.GetBoolean("Enabled", false));
62 }
63
64 public void AddRegion(Scene scene)
65 {
66 if (Enabled)
67 scene.RegisterModuleInterface<INPCModule>(this);
68 }
69
70 public void RegionLoaded(Scene scene)
71 {
72 }
73
74 public void PostInitialise()
75 {
76 }
77
78 public void RemoveRegion(Scene scene)
79 {
80 scene.UnregisterModuleInterface<INPCModule>(this);
81 }
82
83 public void Close()
84 {
85 }
86
87 public string Name
88 {
89 get { return "NPCModule"; }
90 }
91
92 public Type ReplaceableInterface { get { return null; } }
93
94 public bool IsNPC(UUID agentId, Scene scene)
95 {
96 // FIXME: This implementation could not just use the
97 // ScenePresence.PresenceType (and callers could inspect that
98 // directly).
99 ScenePresence sp = scene.GetScenePresence(agentId);
100 if (sp == null || sp.IsChildAgent)
101 return false;
102
103 lock (m_avatars)
104 return m_avatars.ContainsKey(agentId);
105 }
106
107 public bool SetNPCAppearance(UUID agentId,
108 AvatarAppearance appearance, Scene scene)
109 {
110 ScenePresence npc = scene.GetScenePresence(agentId);
111 if (npc == null || npc.IsChildAgent)
112 return false;
113
114 lock (m_avatars)
115 if (!m_avatars.ContainsKey(agentId))
116 return false;
117
118 // Delete existing npc attachments
119 if(scene.AttachmentsModule != null)
120 scene.AttachmentsModule.DeleteAttachmentsFromScene(npc, false);
121
122 // XXX: We can't just use IAvatarFactoryModule.SetAppearance() yet
123 // since it doesn't transfer attachments
124 AvatarAppearance npcAppearance = new AvatarAppearance(appearance,
125 true);
126 npc.Appearance = npcAppearance;
127
128 // Rez needed npc attachments
129 if (scene.AttachmentsModule != null)
130 scene.AttachmentsModule.RezAttachments(npc);
131
132 IAvatarFactoryModule module =
133 scene.RequestModuleInterface<IAvatarFactoryModule>();
134 module.SendAppearance(npc.UUID);
135
136 return true;
137 }
138
139 public UUID CreateNPC(string firstname, string lastname,
140 Vector3 position, UUID owner, bool senseAsAgent, Scene scene,
141 AvatarAppearance appearance)
142 {
143 return CreateNPC(firstname, lastname, position, UUID.Zero, owner, senseAsAgent, scene, appearance);
144 }
145
146 public UUID CreateNPC(string firstname, string lastname,
147 Vector3 position, UUID agentID, UUID owner, bool senseAsAgent, Scene scene,
148 AvatarAppearance appearance)
149 {
150 NPCAvatar npcAvatar = null;
151
152 try
153 {
154 if (agentID == UUID.Zero)
155 npcAvatar = new NPCAvatar(firstname, lastname, position,
156 owner, senseAsAgent, scene);
157 else
158 npcAvatar = new NPCAvatar(firstname, lastname, agentID, position,
159 owner, senseAsAgent, scene);
160 }
161 catch (Exception e)
162 {
163 m_log.Info("[NPC MODULE]: exception creating NPC avatar: " + e.ToString());
164 return UUID.Zero;
165 }
166
167 npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0,
168 int.MaxValue);
169
170 m_log.DebugFormat(
171 "[NPC MODULE]: Creating NPC {0} {1} {2}, owner={3}, senseAsAgent={4} at {5} in {6}",
172 firstname, lastname, npcAvatar.AgentId, owner,
173 senseAsAgent, position, scene.RegionInfo.RegionName);
174
175 AgentCircuitData acd = new AgentCircuitData();
176 acd.AgentID = npcAvatar.AgentId;
177 acd.firstname = firstname;
178 acd.lastname = lastname;
179 acd.ServiceURLs = new Dictionary<string, object>();
180
181 AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true);
182 acd.Appearance = npcAppearance;
183
184 /*
185 for (int i = 0;
186 i < acd.Appearance.Texture.FaceTextures.Length; i++)
187 {
188 m_log.DebugFormat(
189 "[NPC MODULE]: NPC avatar {0} has texture id {1} : {2}",
190 acd.AgentID, i,
191 acd.Appearance.Texture.FaceTextures[i]);
192 }
193 */
194
195 lock (m_avatars)
196 {
197 scene.AuthenticateHandler.AddNewCircuit(npcAvatar.CircuitCode,
198 acd);
199 scene.AddNewAgent(npcAvatar, PresenceType.Npc);
200
201 ScenePresence sp;
202 if (scene.TryGetScenePresence(npcAvatar.AgentId, out sp))
203 {
204 /*
205 m_log.DebugFormat(
206 "[NPC MODULE]: Successfully retrieved scene presence for NPC {0} {1}",
207 sp.Name, sp.UUID);
208 */
209
210 sp.CompleteMovement(npcAvatar, false);
211 m_avatars.Add(npcAvatar.AgentId, npcAvatar);
212 m_log.DebugFormat("[NPC MODULE]: Created NPC {0} {1}", npcAvatar.AgentId, sp.Name);
213
214 return npcAvatar.AgentId;
215 }
216 else
217 {
218 m_log.WarnFormat(
219 "[NPC MODULE]: Could not find scene presence for NPC {0} {1}",
220 sp.Name, sp.UUID);
221
222 return UUID.Zero;
223 }
224 }
225 }
226
227 public bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos,
228 bool noFly, bool landAtTarget, bool running)
229 {
230 lock (m_avatars)
231 {
232 if (m_avatars.ContainsKey(agentID))
233 {
234 ScenePresence sp;
235 if (scene.TryGetScenePresence(agentID, out sp))
236 {
237 if (sp.IsSatOnObject || sp.SitGround)
238 return false;
239
240// m_log.DebugFormat(
241// "[NPC MODULE]: Moving {0} to {1} in {2}, noFly {3}, landAtTarget {4}",
242// sp.Name, pos, scene.RegionInfo.RegionName,
243// noFly, landAtTarget);
244
245 sp.MoveToTarget(pos, noFly, landAtTarget);
246 sp.SetAlwaysRun = running;
247
248 return true;
249 }
250 }
251 }
252
253 return false;
254 }
255
256 public bool StopMoveToTarget(UUID agentID, Scene scene)
257 {
258 lock (m_avatars)
259 {
260 if (m_avatars.ContainsKey(agentID))
261 {
262 ScenePresence sp;
263 if (scene.TryGetScenePresence(agentID, out sp))
264 {
265 sp.Velocity = Vector3.Zero;
266 sp.ResetMoveToTarget();
267
268 return true;
269 }
270 }
271 }
272
273 return false;
274 }
275
276 public bool Say(UUID agentID, Scene scene, string text)
277 {
278 return Say(agentID, scene, text, 0);
279 }
280
281 public bool Say(UUID agentID, Scene scene, string text, int channel)
282 {
283 lock (m_avatars)
284 {
285 if (m_avatars.ContainsKey(agentID))
286 {
287 m_avatars[agentID].Say(channel, text);
288
289 return true;
290 }
291 }
292
293 return false;
294 }
295
296 public bool Shout(UUID agentID, Scene scene, string text, int channel)
297 {
298 lock (m_avatars)
299 {
300 if (m_avatars.ContainsKey(agentID))
301 {
302 m_avatars[agentID].Shout(channel, text);
303
304 return true;
305 }
306 }
307
308 return false;
309 }
310
311 public bool Sit(UUID agentID, UUID partID, Scene scene)
312 {
313 lock (m_avatars)
314 {
315 if (m_avatars.ContainsKey(agentID))
316 {
317 ScenePresence sp;
318 if (scene.TryGetScenePresence(agentID, out sp))
319 {
320 sp.HandleAgentRequestSit(m_avatars[agentID], agentID, partID, Vector3.Zero);
321
322 return true;
323 }
324 }
325 }
326
327 return false;
328 }
329
330 public bool Whisper(UUID agentID, Scene scene, string text,
331 int channel)
332 {
333 lock (m_avatars)
334 {
335 if (m_avatars.ContainsKey(agentID))
336 {
337 m_avatars[agentID].Whisper(channel, text);
338
339 return true;
340 }
341 }
342
343 return false;
344 }
345
346 public bool Stand(UUID agentID, Scene scene)
347 {
348 lock (m_avatars)
349 {
350 if (m_avatars.ContainsKey(agentID))
351 {
352 ScenePresence sp;
353 if (scene.TryGetScenePresence(agentID, out sp))
354 {
355 sp.StandUp();
356
357 return true;
358 }
359 }
360 }
361
362 return false;
363 }
364
365 public bool Touch(UUID agentID, UUID objectID)
366 {
367 lock (m_avatars)
368 {
369 if (m_avatars.ContainsKey(agentID))
370 return m_avatars[agentID].Touch(objectID);
371
372 return false;
373 }
374 }
375
376 public UUID GetOwner(UUID agentID)
377 {
378 lock (m_avatars)
379 {
380 NPCAvatar av;
381 if (m_avatars.TryGetValue(agentID, out av))
382 return av.OwnerID;
383 }
384
385 return UUID.Zero;
386 }
387
388 public INPC GetNPC(UUID agentID, Scene scene)
389 {
390 lock (m_avatars)
391 {
392 if (m_avatars.ContainsKey(agentID))
393 return m_avatars[agentID];
394 else
395 return null;
396 }
397 }
398
399 public bool DeleteNPC(UUID agentID, Scene scene)
400 {
401 bool doRemove = false;
402 NPCAvatar av;
403 lock (m_avatars)
404 {
405 if (m_avatars.TryGetValue(agentID, out av))
406 {
407 /*
408 m_log.DebugFormat("[NPC MODULE]: Found {0} {1} to remove",
409 agentID, av.Name);
410 */
411 doRemove = true;
412 }
413 }
414
415 if (doRemove)
416 {
417 scene.CloseAgent(agentID, false);
418 lock (m_avatars)
419 {
420 m_avatars.Remove(agentID);
421 }
422 m_log.DebugFormat("[NPC MODULE]: Removed NPC {0} {1}",
423 agentID, av.Name);
424 return true;
425 }
426 /*
427 m_log.DebugFormat("[NPC MODULE]: Could not find {0} to remove",
428 agentID);
429 */
430 return false;
431 }
432
433 public bool CheckPermissions(UUID npcID, UUID callerID)
434 {
435 lock (m_avatars)
436 {
437 NPCAvatar av;
438 if (m_avatars.TryGetValue(npcID, out av))
439 return CheckPermissions(av, callerID);
440 else
441 return false;
442 }
443 }
444
445 /// <summary>
446 /// Check if the caller has permission to manipulate the given NPC.
447 /// </summary>
448 /// <remarks>
449 /// A caller has permission if
450 /// * The caller UUID given is UUID.Zero.
451 /// * The avatar is unowned (owner is UUID.Zero).
452 /// * The avatar is owned and the owner and callerID match.
453 /// * The avatar is owned and the callerID matches its agentID.
454 /// </remarks>
455 /// <param name="av"></param>
456 /// <param name="callerID"></param>
457 /// <returns>true if they do, false if they don't.</returns>
458 private bool CheckPermissions(NPCAvatar av, UUID callerID)
459 {
460 return callerID == UUID.Zero || av.OwnerID == UUID.Zero ||
461 av.OwnerID == callerID || av.AgentId == callerID;
462 }
463 }
464}