opensim-development – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 eva 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,
182 true);
183 acd.Appearance = npcAppearance;
184  
185 /*
186 for (int i = 0;
187 i < acd.Appearance.Texture.FaceTextures.Length; i++)
188 {
189 m_log.DebugFormat(
190 "[NPC MODULE]: NPC avatar {0} has texture id {1} : {2}",
191 acd.AgentID, i,
192 acd.Appearance.Texture.FaceTextures[i]);
193 }
194 */
195  
196 lock (m_avatars)
197 {
198 scene.AuthenticateHandler.AddNewCircuit(npcAvatar.CircuitCode,
199 acd);
200 scene.AddNewAgent(npcAvatar, PresenceType.Npc);
201  
202 ScenePresence sp;
203 if (scene.TryGetScenePresence(npcAvatar.AgentId, out sp))
204 {
205 /*
206 m_log.DebugFormat(
207 "[NPC MODULE]: Successfully retrieved scene presence for NPC {0} {1}",
208 sp.Name, sp.UUID);
209 */
210  
211 sp.CompleteMovement(npcAvatar, false);
212 m_avatars.Add(npcAvatar.AgentId, npcAvatar);
213 m_log.DebugFormat("[NPC MODULE]: Created NPC {0} {1}", npcAvatar.AgentId, sp.Name);
214  
215 return npcAvatar.AgentId;
216 }
217 else
218 {
219 m_log.WarnFormat(
220 "[NPC MODULE]: Could not find scene presence for NPC {0} {1}",
221 sp.Name, sp.UUID);
222  
223 return UUID.Zero;
224 }
225 }
226 }
227  
228 public bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos,
229 bool noFly, bool landAtTarget, bool running)
230 {
231 lock (m_avatars)
232 {
233 if (m_avatars.ContainsKey(agentID))
234 {
235 ScenePresence sp;
236 if (scene.TryGetScenePresence(agentID, out sp))
237 {
238 // m_log.DebugFormat(
239 // "[NPC MODULE]: Moving {0} to {1} in {2}, noFly {3}, landAtTarget {4}",
240 // sp.Name, pos, scene.RegionInfo.RegionName,
241 // noFly, landAtTarget);
242  
243 sp.MoveToTarget(pos, noFly, landAtTarget);
244 sp.SetAlwaysRun = running;
245  
246 return true;
247 }
248 }
249 }
250  
251 return false;
252 }
253  
254 public bool StopMoveToTarget(UUID agentID, Scene scene)
255 {
256 lock (m_avatars)
257 {
258 if (m_avatars.ContainsKey(agentID))
259 {
260 ScenePresence sp;
261 if (scene.TryGetScenePresence(agentID, out sp))
262 {
263 sp.Velocity = Vector3.Zero;
264 sp.ResetMoveToTarget();
265  
266 return true;
267 }
268 }
269 }
270  
271 return false;
272 }
273  
274 public bool Say(UUID agentID, Scene scene, string text)
275 {
276 return Say(agentID, scene, text, 0);
277 }
278  
279 public bool Say(UUID agentID, Scene scene, string text, int channel)
280 {
281 lock (m_avatars)
282 {
283 if (m_avatars.ContainsKey(agentID))
284 {
285 m_avatars[agentID].Say(channel, text);
286  
287 return true;
288 }
289 }
290  
291 return false;
292 }
293  
294 public bool Shout(UUID agentID, Scene scene, string text, int channel)
295 {
296 lock (m_avatars)
297 {
298 if (m_avatars.ContainsKey(agentID))
299 {
300 m_avatars[agentID].Shout(channel, text);
301  
302 return true;
303 }
304 }
305  
306 return false;
307 }
308  
309 public bool Sit(UUID agentID, UUID partID, Scene scene)
310 {
311 lock (m_avatars)
312 {
313 if (m_avatars.ContainsKey(agentID))
314 {
315 ScenePresence sp;
316 if (scene.TryGetScenePresence(agentID, out sp))
317 {
318 sp.HandleAgentRequestSit(m_avatars[agentID], agentID, partID, Vector3.Zero);
319  
320 return true;
321 }
322 }
323 }
324  
325 return false;
326 }
327  
328 public bool Whisper(UUID agentID, Scene scene, string text,
329 int channel)
330 {
331 lock (m_avatars)
332 {
333 if (m_avatars.ContainsKey(agentID))
334 {
335 m_avatars[agentID].Whisper(channel, text);
336  
337 return true;
338 }
339 }
340  
341 return false;
342 }
343  
344 public bool Stand(UUID agentID, Scene scene)
345 {
346 lock (m_avatars)
347 {
348 if (m_avatars.ContainsKey(agentID))
349 {
350 ScenePresence sp;
351 if (scene.TryGetScenePresence(agentID, out sp))
352 {
353 sp.StandUp();
354  
355 return true;
356 }
357 }
358 }
359  
360 return false;
361 }
362  
363 public bool Touch(UUID agentID, UUID objectID)
364 {
365 lock (m_avatars)
366 {
367 if (m_avatars.ContainsKey(agentID))
368 return m_avatars[agentID].Touch(objectID);
369  
370 return false;
371 }
372 }
373  
374 public UUID GetOwner(UUID agentID)
375 {
376 lock (m_avatars)
377 {
378 NPCAvatar av;
379 if (m_avatars.TryGetValue(agentID, out av))
380 return av.OwnerID;
381 }
382  
383 return UUID.Zero;
384 }
385  
386 public INPC GetNPC(UUID agentID, Scene scene)
387 {
388 lock (m_avatars)
389 {
390 if (m_avatars.ContainsKey(agentID))
391 return m_avatars[agentID];
392 else
393 return null;
394 }
395 }
396  
397 public bool DeleteNPC(UUID agentID, Scene scene)
398 {
399 lock (m_avatars)
400 {
401 NPCAvatar av;
402 if (m_avatars.TryGetValue(agentID, out av))
403 {
404 /*
405 m_log.DebugFormat("[NPC MODULE]: Found {0} {1} to remove",
406 agentID, av.Name);
407 */
408  
409 scene.CloseAgent(agentID, false);
410  
411 m_avatars.Remove(agentID);
412  
413 /*
414 m_log.DebugFormat("[NPC MODULE]: Removed NPC {0} {1}",
415 agentID, av.Name);
416 */
417 return true;
418 }
419 }
420 /*
421 m_log.DebugFormat("[NPC MODULE]: Could not find {0} to remove",
422 agentID);
423 */
424 return false;
425 }
426  
427 public bool CheckPermissions(UUID npcID, UUID callerID)
428 {
429 lock (m_avatars)
430 {
431 NPCAvatar av;
432 if (m_avatars.TryGetValue(npcID, out av))
433 return CheckPermissions(av, callerID);
434 else
435 return false;
436 }
437 }
438  
439 /// <summary>
440 /// Check if the caller has permission to manipulate the given NPC.
441 /// </summary>
442 /// <param name="av"></param>
443 /// <param name="callerID"></param>
444 /// <returns>true if they do, false if they don't.</returns>
445 private bool CheckPermissions(NPCAvatar av, UUID callerID)
446 {
447 return callerID == UUID.Zero || av.OwnerID == UUID.Zero ||
448 av.OwnerID == callerID;
449 }
450 }
451 }