clockwerk-opensim – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 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  
28 using System;
29 using System.Collections.Generic;
30 using System.Reflection;
31 using System.Threading;
32 using Timer = System.Timers.Timer;
33  
34 using log4net;
35 using Nini.Config;
36 using Mono.Addins;
37 using OpenMetaverse;
38  
39 using OpenSim.Region.Framework.Interfaces;
40 using OpenSim.Region.Framework.Scenes;
41 using OpenSim.Framework;
42 using OpenSim.Services.Interfaces;
43  
44 namespace 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 lock (m_avatars)
402 {
403 NPCAvatar av;
404 if (m_avatars.TryGetValue(agentID, out av))
405 {
406 /*
407 m_log.DebugFormat("[NPC MODULE]: Found {0} {1} to remove",
408 agentID, av.Name);
409 */
410  
411 scene.CloseAgent(agentID, false);
412  
413 m_avatars.Remove(agentID);
414  
415 /*
416 m_log.DebugFormat("[NPC MODULE]: Removed NPC {0} {1}",
417 agentID, av.Name);
418 */
419 return true;
420 }
421 }
422 /*
423 m_log.DebugFormat("[NPC MODULE]: Could not find {0} to remove",
424 agentID);
425 */
426 return false;
427 }
428  
429 public bool CheckPermissions(UUID npcID, UUID callerID)
430 {
431 lock (m_avatars)
432 {
433 NPCAvatar av;
434 if (m_avatars.TryGetValue(npcID, out av))
435 return CheckPermissions(av, callerID);
436 else
437 return false;
438 }
439 }
440  
441 /// <summary>
442 /// Check if the caller has permission to manipulate the given NPC.
443 /// </summary>
444 /// <param name="av"></param>
445 /// <param name="callerID"></param>
446 /// <returns>true if they do, false if they don't.</returns>
447 private bool CheckPermissions(NPCAvatar av, UUID callerID)
448 {
449 return callerID == UUID.Zero || av.OwnerID == UUID.Zero ||
450 av.OwnerID == callerID;
451 }
452 }
453 }