aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/World/NPC
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
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')
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs1273
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs464
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs487
3 files changed, 2224 insertions, 0 deletions
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
new file mode 100644
index 0000000..fb644b7
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -0,0 +1,1273 @@
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.Net;
31using OpenMetaverse;
32using OpenMetaverse.Packets;
33using OpenSim.Framework;
34using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Region.CoreModules.World.Estate;
37using log4net;
38using System.Reflection;
39using System.Xml;
40
41namespace OpenSim.Region.OptionalModules.World.NPC
42{
43 public class NPCAvatar : IClientAPI, INPC
44 {
45 public bool SenseAsAgent { get; set; }
46
47 public delegate void ChatToNPC(
48 string message, byte type, Vector3 fromPos, string fromName,
49 UUID fromAgentID, UUID ownerID, byte source, byte audible);
50
51 /// <summary>
52 /// Fired when the NPC receives a chat message.
53 /// </summary>
54 public event ChatToNPC OnChatToNPC;
55
56 /// <summary>
57 /// Fired when the NPC receives an instant message.
58 /// </summary>
59 public event Action<GridInstantMessage> OnInstantMessageToNPC;
60
61 private readonly string m_firstname;
62 private readonly string m_lastname;
63 private readonly Vector3 m_startPos;
64 private readonly UUID m_uuid;
65 private readonly Scene m_scene;
66 private readonly UUID m_ownerID;
67
68 public NPCAvatar(
69 string firstname, string lastname, Vector3 position, UUID ownerID, bool senseAsAgent, Scene scene)
70 {
71 m_firstname = firstname;
72 m_lastname = lastname;
73 m_startPos = position;
74 m_uuid = UUID.Random();
75 m_scene = scene;
76 m_ownerID = ownerID;
77 SenseAsAgent = senseAsAgent;
78 }
79
80 public NPCAvatar(
81 string firstname, string lastname, UUID agentID, Vector3 position, UUID ownerID, bool senseAsAgent, Scene scene)
82 {
83 m_firstname = firstname;
84 m_lastname = lastname;
85 m_startPos = position;
86 m_uuid = agentID;
87 m_scene = scene;
88 m_ownerID = ownerID;
89 SenseAsAgent = senseAsAgent;
90 }
91
92 public IScene Scene
93 {
94 get { return m_scene; }
95 }
96
97 public UUID OwnerID
98 {
99 get { return m_ownerID; }
100 }
101
102 public ISceneAgent SceneAgent { get; set; }
103
104 public void Say(string message)
105 {
106 SendOnChatFromClient(0, message, ChatTypeEnum.Say);
107 }
108
109 public void Say(int channel, string message)
110 {
111 SendOnChatFromClient(channel, message, ChatTypeEnum.Say);
112 }
113
114 public void Shout(int channel, string message)
115 {
116 SendOnChatFromClient(channel, message, ChatTypeEnum.Shout);
117 }
118
119 public void Whisper(int channel, string message)
120 {
121 SendOnChatFromClient(channel, message, ChatTypeEnum.Whisper);
122 }
123
124 public void Broadcast(string message)
125 {
126 SendOnChatFromClient(0, message, ChatTypeEnum.Broadcast);
127 }
128
129 public void GiveMoney(UUID target, int amount)
130 {
131 OnMoneyTransferRequest(m_uuid, target, amount, 1, "Payment");
132 }
133
134 public bool Touch(UUID target)
135 {
136 SceneObjectPart part = m_scene.GetSceneObjectPart(target);
137 if (part == null)
138 return false;
139 bool objectTouchable = hasTouchEvents(part); // Only touch an object that is scripted to respond
140 if (!objectTouchable && !part.IsRoot)
141 objectTouchable = hasTouchEvents(part.ParentGroup.RootPart);
142 if (!objectTouchable)
143 return false;
144 // Set up the surface args as if the touch is from a client that does not support this
145 SurfaceTouchEventArgs surfaceArgs = new SurfaceTouchEventArgs();
146 surfaceArgs.FaceIndex = -1; // TOUCH_INVALID_FACE
147 surfaceArgs.Binormal = Vector3.Zero; // TOUCH_INVALID_VECTOR
148 surfaceArgs.Normal = Vector3.Zero; // TOUCH_INVALID_VECTOR
149 surfaceArgs.STCoord = new Vector3(-1.0f, -1.0f, 0.0f); // TOUCH_INVALID_TEXCOORD
150 surfaceArgs.UVCoord = surfaceArgs.STCoord; // TOUCH_INVALID_TEXCOORD
151 List<SurfaceTouchEventArgs> touchArgs = new List<SurfaceTouchEventArgs>();
152 touchArgs.Add(surfaceArgs);
153 Vector3 offset = part.OffsetPosition * -1.0f;
154 if (OnGrabObject == null)
155 return false;
156 OnGrabObject(part.LocalId, offset, this, touchArgs);
157 if (OnGrabUpdate != null)
158 OnGrabUpdate(part.UUID, offset, part.ParentGroup.RootPart.GroupPosition, this, touchArgs);
159 if (OnDeGrabObject != null)
160 OnDeGrabObject(part.LocalId, this, touchArgs);
161 return true;
162 }
163
164 private bool hasTouchEvents(SceneObjectPart part)
165 {
166 if ((part.ScriptEvents & scriptEvents.touch) != 0 ||
167 (part.ScriptEvents & scriptEvents.touch_start) != 0 ||
168 (part.ScriptEvents & scriptEvents.touch_end) != 0)
169 return true;
170 return false;
171 }
172
173 public void InstantMessage(UUID target, string message)
174 {
175 OnInstantMessage(this, new GridInstantMessage(m_scene,
176 m_uuid, m_firstname + " " + m_lastname,
177 target, 0, false, message,
178 UUID.Zero, false, Position, new byte[0], true));
179 }
180
181 public void SendAgentOffline(UUID[] agentIDs)
182 {
183
184 }
185
186 public void SendAgentOnline(UUID[] agentIDs)
187 {
188
189 }
190
191 public void SendSitResponse(UUID TargetID, Vector3 OffsetPos, Quaternion SitOrientation, bool autopilot,
192 Vector3 CameraAtOffset, Vector3 CameraEyeOffset, bool ForceMouseLook)
193 {
194
195 }
196
197 public void SendAdminResponse(UUID Token, uint AdminLevel)
198 {
199
200 }
201
202 public void SendGroupMembership(GroupMembershipData[] GroupMembership)
203 {
204
205 }
206
207 public Vector3 Position
208 {
209 get { return m_scene.Entities[m_uuid].AbsolutePosition; }
210 set { m_scene.Entities[m_uuid].AbsolutePosition = value; }
211 }
212
213 public bool SendLogoutPacketWhenClosing
214 {
215 set { }
216 }
217
218 #region Internal Functions
219
220 private void SendOnChatFromClient(int channel, string message, ChatTypeEnum chatType)
221 {
222 if (channel == 0)
223 {
224 message = message.Trim();
225 if (string.IsNullOrEmpty(message))
226 {
227 return;
228 }
229 }
230 OSChatMessage chatFromClient = new OSChatMessage();
231 chatFromClient.Channel = channel;
232 chatFromClient.From = Name;
233 chatFromClient.Message = message;
234 chatFromClient.Position = StartPos;
235 chatFromClient.Scene = m_scene;
236 chatFromClient.Sender = this;
237 chatFromClient.SenderUUID = AgentId;
238 chatFromClient.Type = chatType;
239
240 OnChatFromClient(this, chatFromClient);
241 }
242
243 #endregion
244
245 #region Event Definitions IGNORE
246
247// disable warning: public events constituting public API
248#pragma warning disable 67
249 public event Action<IClientAPI> OnLogout;
250 public event ObjectPermissions OnObjectPermissions;
251
252 public event MoneyTransferRequest OnMoneyTransferRequest;
253 public event ParcelBuy OnParcelBuy;
254 public event Action<IClientAPI> OnConnectionClosed;
255 public event GenericMessage OnGenericMessage;
256 public event ImprovedInstantMessage OnInstantMessage;
257 public event ChatMessage OnChatFromClient;
258 public event TextureRequest OnRequestTexture;
259 public event RezObject OnRezObject;
260 public event ModifyTerrain OnModifyTerrain;
261 public event SetAppearance OnSetAppearance;
262 public event AvatarNowWearing OnAvatarNowWearing;
263 public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
264 public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv;
265 public event UUIDNameRequest OnDetachAttachmentIntoInv;
266 public event ObjectAttach OnObjectAttach;
267 public event ObjectDeselect OnObjectDetach;
268 public event ObjectDrop OnObjectDrop;
269 public event StartAnim OnStartAnim;
270 public event StopAnim OnStopAnim;
271 public event LinkObjects OnLinkObjects;
272 public event DelinkObjects OnDelinkObjects;
273 public event RequestMapBlocks OnRequestMapBlocks;
274 public event RequestMapName OnMapNameRequest;
275 public event TeleportLocationRequest OnTeleportLocationRequest;
276 public event TeleportLandmarkRequest OnTeleportLandmarkRequest;
277 public event TeleportCancel OnTeleportCancel;
278 public event DisconnectUser OnDisconnectUser;
279 public event RequestAvatarProperties OnRequestAvatarProperties;
280 public event SetAlwaysRun OnSetAlwaysRun;
281
282 public event DeRezObject OnDeRezObject;
283 public event Action<IClientAPI> OnRegionHandShakeReply;
284 public event GenericCall1 OnRequestWearables;
285 public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
286 public event UpdateAgent OnPreAgentUpdate;
287 public event UpdateAgent OnAgentUpdate;
288 public event UpdateAgent OnAgentCameraUpdate;
289 public event AgentRequestSit OnAgentRequestSit;
290 public event AgentSit OnAgentSit;
291 public event AvatarPickerRequest OnAvatarPickerRequest;
292 public event Action<IClientAPI> OnRequestAvatarsData;
293 public event AddNewPrim OnAddPrim;
294 public event RequestGodlikePowers OnRequestGodlikePowers;
295 public event GodKickUser OnGodKickUser;
296 public event ObjectDuplicate OnObjectDuplicate;
297 public event GrabObject OnGrabObject;
298 public event DeGrabObject OnDeGrabObject;
299 public event MoveObject OnGrabUpdate;
300 public event SpinStart OnSpinStart;
301 public event SpinObject OnSpinUpdate;
302 public event SpinStop OnSpinStop;
303 public event ViewerEffectEventHandler OnViewerEffect;
304
305 public event FetchInventory OnAgentDataUpdateRequest;
306 public event TeleportLocationRequest OnSetStartLocationRequest;
307
308 public event UpdateShape OnUpdatePrimShape;
309 public event ObjectExtraParams OnUpdateExtraParams;
310 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
311 public event ObjectRequest OnObjectRequest;
312 public event ObjectSelect OnObjectSelect;
313 public event GenericCall7 OnObjectDescription;
314 public event GenericCall7 OnObjectName;
315 public event GenericCall7 OnObjectClickAction;
316 public event GenericCall7 OnObjectMaterial;
317 public event UpdatePrimFlags OnUpdatePrimFlags;
318 public event UpdatePrimTexture OnUpdatePrimTexture;
319 public event UpdateVector OnUpdatePrimGroupPosition;
320 public event UpdateVector OnUpdatePrimSinglePosition;
321 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
322 public event UpdatePrimSingleRotationPosition OnUpdatePrimSingleRotationPosition;
323 public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation;
324 public event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation;
325 public event UpdateVector OnUpdatePrimScale;
326 public event UpdateVector OnUpdatePrimGroupScale;
327 public event StatusChange OnChildAgentStatus;
328 public event GenericCall2 OnStopMovement;
329 public event Action<UUID> OnRemoveAvatar;
330
331 public event CreateNewInventoryItem OnCreateNewInventoryItem;
332 public event LinkInventoryItem OnLinkInventoryItem;
333 public event CreateInventoryFolder OnCreateNewInventoryFolder;
334 public event UpdateInventoryFolder OnUpdateInventoryFolder;
335 public event MoveInventoryFolder OnMoveInventoryFolder;
336 public event RemoveInventoryFolder OnRemoveInventoryFolder;
337 public event RemoveInventoryItem OnRemoveInventoryItem;
338 public event FetchInventoryDescendents OnFetchInventoryDescendents;
339 public event PurgeInventoryDescendents OnPurgeInventoryDescendents;
340 public event FetchInventory OnFetchInventory;
341 public event RequestTaskInventory OnRequestTaskInventory;
342 public event UpdateInventoryItem OnUpdateInventoryItem;
343 public event CopyInventoryItem OnCopyInventoryItem;
344 public event MoveInventoryItem OnMoveInventoryItem;
345 public event UDPAssetUploadRequest OnAssetUploadRequest;
346 public event XferReceive OnXferReceive;
347 public event RequestXfer OnRequestXfer;
348 public event AbortXfer OnAbortXfer;
349 public event ConfirmXfer OnConfirmXfer;
350 public event RezScript OnRezScript;
351 public event UpdateTaskInventory OnUpdateTaskInventory;
352 public event MoveTaskInventory OnMoveTaskItem;
353 public event RemoveTaskInventory OnRemoveTaskItem;
354 public event RequestAsset OnRequestAsset;
355
356 public event UUIDNameRequest OnNameFromUUIDRequest;
357 public event UUIDNameRequest OnUUIDGroupNameRequest;
358
359 public event ParcelPropertiesRequest OnParcelPropertiesRequest;
360 public event ParcelDivideRequest OnParcelDivideRequest;
361 public event ParcelJoinRequest OnParcelJoinRequest;
362 public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest;
363 public event ParcelAbandonRequest OnParcelAbandonRequest;
364 public event ParcelGodForceOwner OnParcelGodForceOwner;
365 public event ParcelReclaim OnParcelReclaim;
366 public event ParcelReturnObjectsRequest OnParcelReturnObjectsRequest;
367 public event ParcelAccessListRequest OnParcelAccessListRequest;
368 public event ParcelAccessListUpdateRequest OnParcelAccessListUpdateRequest;
369 public event ParcelSelectObjects OnParcelSelectObjects;
370 public event ParcelObjectOwnerRequest OnParcelObjectOwnerRequest;
371 public event ParcelDeedToGroup OnParcelDeedToGroup;
372 public event ObjectDeselect OnObjectDeselect;
373 public event RegionInfoRequest OnRegionInfoRequest;
374 public event EstateCovenantRequest OnEstateCovenantRequest;
375 public event RequestTerrain OnRequestTerrain;
376 public event RequestTerrain OnUploadTerrain;
377 public event ObjectDuplicateOnRay OnObjectDuplicateOnRay;
378
379 public event FriendActionDelegate OnApproveFriendRequest;
380 public event FriendActionDelegate OnDenyFriendRequest;
381 public event FriendshipTermination OnTerminateFriendship;
382 public event GrantUserFriendRights OnGrantUserRights;
383
384 public event EconomyDataRequest OnEconomyDataRequest;
385 public event MoneyBalanceRequest OnMoneyBalanceRequest;
386 public event UpdateAvatarProperties OnUpdateAvatarProperties;
387
388 public event ObjectIncludeInSearch OnObjectIncludeInSearch;
389 public event UUIDNameRequest OnTeleportHomeRequest;
390
391 public event ScriptAnswer OnScriptAnswer;
392 public event RequestPayPrice OnRequestPayPrice;
393 public event ObjectSaleInfo OnObjectSaleInfo;
394 public event ObjectBuy OnObjectBuy;
395 public event BuyObjectInventory OnBuyObjectInventory;
396 public event AgentSit OnUndo;
397 public event AgentSit OnRedo;
398 public event LandUndo OnLandUndo;
399
400 public event ForceReleaseControls OnForceReleaseControls;
401 public event GodLandStatRequest OnLandStatRequest;
402 public event RequestObjectPropertiesFamily OnObjectGroupRequest;
403
404 public event DetailedEstateDataRequest OnDetailedEstateDataRequest;
405 public event SetEstateFlagsRequest OnSetEstateFlagsRequest;
406 public event SetEstateTerrainBaseTexture OnSetEstateTerrainBaseTexture;
407 public event SetEstateTerrainDetailTexture OnSetEstateTerrainDetailTexture;
408 public event SetEstateTerrainTextureHeights OnSetEstateTerrainTextureHeights;
409 public event CommitEstateTerrainTextureRequest OnCommitEstateTerrainTextureRequest;
410 public event SetRegionTerrainSettings OnSetRegionTerrainSettings;
411 public event BakeTerrain OnBakeTerrain;
412 public event EstateRestartSimRequest OnEstateRestartSimRequest;
413 public event EstateChangeCovenantRequest OnEstateChangeCovenantRequest;
414 public event UpdateEstateAccessDeltaRequest OnUpdateEstateAccessDeltaRequest;
415 public event SimulatorBlueBoxMessageRequest OnSimulatorBlueBoxMessageRequest;
416 public event EstateBlueBoxMessageRequest OnEstateBlueBoxMessageRequest;
417 public event EstateDebugRegionRequest OnEstateDebugRegionRequest;
418 public event EstateTeleportOneUserHomeRequest OnEstateTeleportOneUserHomeRequest;
419 public event EstateTeleportAllUsersHomeRequest OnEstateTeleportAllUsersHomeRequest;
420 public event EstateChangeInfo OnEstateChangeInfo;
421 public event EstateManageTelehub OnEstateManageTelehub;
422 public event CachedTextureRequest OnCachedTextureRequest;
423 public event ScriptReset OnScriptReset;
424 public event GetScriptRunning OnGetScriptRunning;
425 public event SetScriptRunning OnSetScriptRunning;
426 public event Action<Vector3, bool, bool> OnAutoPilotGo;
427
428 public event TerrainUnacked OnUnackedTerrain;
429
430 public event RegionHandleRequest OnRegionHandleRequest;
431 public event ParcelInfoRequest OnParcelInfoRequest;
432
433 public event ActivateGesture OnActivateGesture;
434 public event DeactivateGesture OnDeactivateGesture;
435 public event ObjectOwner OnObjectOwner;
436
437 public event DirPlacesQuery OnDirPlacesQuery;
438 public event DirFindQuery OnDirFindQuery;
439 public event DirLandQuery OnDirLandQuery;
440 public event DirPopularQuery OnDirPopularQuery;
441 public event DirClassifiedQuery OnDirClassifiedQuery;
442 public event EventInfoRequest OnEventInfoRequest;
443 public event ParcelSetOtherCleanTime OnParcelSetOtherCleanTime;
444
445 public event MapItemRequest OnMapItemRequest;
446
447 public event OfferCallingCard OnOfferCallingCard;
448 public event AcceptCallingCard OnAcceptCallingCard;
449 public event DeclineCallingCard OnDeclineCallingCard;
450 public event SoundTrigger OnSoundTrigger;
451
452 public event StartLure OnStartLure;
453 public event TeleportLureRequest OnTeleportLureRequest;
454 public event NetworkStats OnNetworkStatsUpdate;
455
456 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
457 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
458 public event ClassifiedDelete OnClassifiedDelete;
459 public event ClassifiedDelete OnClassifiedGodDelete;
460
461 public event EventNotificationAddRequest OnEventNotificationAddRequest;
462 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
463 public event EventGodDelete OnEventGodDelete;
464
465 public event ParcelDwellRequest OnParcelDwellRequest;
466
467 public event UserInfoRequest OnUserInfoRequest;
468 public event UpdateUserInfo OnUpdateUserInfo;
469
470 public event RetrieveInstantMessages OnRetrieveInstantMessages;
471
472 public event PickDelete OnPickDelete;
473 public event PickGodDelete OnPickGodDelete;
474 public event PickInfoUpdate OnPickInfoUpdate;
475 public event AvatarNotesUpdate OnAvatarNotesUpdate;
476
477 public event MuteListRequest OnMuteListRequest;
478
479 public event AvatarInterestUpdate OnAvatarInterestUpdate;
480
481 public event PlacesQuery OnPlacesQuery;
482
483 public event FindAgentUpdate OnFindAgent;
484 public event TrackAgentUpdate OnTrackAgent;
485 public event NewUserReport OnUserReport;
486 public event SaveStateHandler OnSaveState;
487 public event GroupAccountSummaryRequest OnGroupAccountSummaryRequest;
488 public event GroupAccountDetailsRequest OnGroupAccountDetailsRequest;
489 public event GroupAccountTransactionsRequest OnGroupAccountTransactionsRequest;
490 public event FreezeUserUpdate OnParcelFreezeUser;
491 public event EjectUserUpdate OnParcelEjectUser;
492 public event ParcelBuyPass OnParcelBuyPass;
493 public event ParcelGodMark OnParcelGodMark;
494 public event GroupActiveProposalsRequest OnGroupActiveProposalsRequest;
495 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
496 public event SimWideDeletesDelegate OnSimWideDeletes;
497 public event SendPostcard OnSendPostcard;
498 public event MuteListEntryUpdate OnUpdateMuteListEntry;
499 public event MuteListEntryRemove OnRemoveMuteListEntry;
500 public event GodlikeMessage onGodlikeMessage;
501 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
502
503#pragma warning restore 67
504
505 #endregion
506
507 public void ActivateGesture(UUID assetId, UUID gestureId)
508 {
509 }
510 public void DeactivateGesture(UUID assetId, UUID gestureId)
511 {
512 }
513
514 #region Overrriden Methods IGNORE
515
516 public virtual Vector3 StartPos
517 {
518 get { return m_startPos; }
519 set { }
520 }
521
522 public virtual UUID AgentId
523 {
524 get { return m_uuid; }
525 }
526
527 public UUID SessionId
528 {
529 get { return UUID.Zero; }
530 }
531
532 public UUID SecureSessionId
533 {
534 get { return UUID.Zero; }
535 }
536
537 public virtual string FirstName
538 {
539 get { return m_firstname; }
540 }
541
542 public virtual string LastName
543 {
544 get { return m_lastname; }
545 }
546
547 public virtual String Name
548 {
549 get { return FirstName + " " + LastName; }
550 }
551
552 public bool IsActive
553 {
554 get { return true; }
555 set { }
556 }
557
558 public bool IsLoggingOut
559 {
560 get { return false; }
561 set { }
562 }
563 public UUID ActiveGroupId
564 {
565 get { return UUID.Zero; }
566 }
567
568 public string ActiveGroupName
569 {
570 get { return String.Empty; }
571 }
572
573 public ulong ActiveGroupPowers
574 {
575 get { return 0; }
576 }
577
578 public bool IsGroupMember(UUID groupID)
579 {
580 return false;
581 }
582
583 public ulong GetGroupPowers(UUID groupID)
584 {
585 return 0;
586 }
587
588 public virtual int NextAnimationSequenceNumber
589 {
590 get { return 1; }
591 }
592
593 public virtual void SendWearables(AvatarWearable[] wearables, int serial)
594 {
595 }
596
597 public virtual void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
598 {
599 }
600
601 public void SendCachedTextureResponse(ISceneEntity avatar, int serial, List<CachedTextureResponseArg> cachedTextures)
602 {
603
604 }
605
606 public virtual void Kick(string message)
607 {
608 }
609
610 public virtual void SendStartPingCheck(byte seq)
611 {
612 }
613
614 public virtual void SendAvatarPickerReply(AvatarPickerReplyAgentDataArgs AgentData, List<AvatarPickerReplyDataArgs> Data)
615 {
616 }
617
618 public virtual void SendAgentDataUpdate(UUID agentid, UUID activegroupid, string firstname, string lastname, ulong grouppowers, string groupname, string grouptitle)
619 {
620
621 }
622
623 public virtual void SendKillObject(List<uint> localID)
624 {
625 }
626
627 public virtual void SetChildAgentThrottle(byte[] throttle)
628 {
629 }
630 public byte[] GetThrottlesPacked(float multiplier)
631 {
632 return new byte[0];
633 }
634
635
636 public virtual void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs)
637 {
638 }
639
640 public virtual void SendChatMessage(
641 string message, byte type, Vector3 fromPos, string fromName,
642 UUID fromAgentID, UUID ownerID, byte source, byte audible)
643 {
644 ChatToNPC ctn = OnChatToNPC;
645
646 if (ctn != null)
647 ctn(message, type, fromPos, fromName, fromAgentID, ownerID, source, audible);
648 }
649
650 public void SendInstantMessage(GridInstantMessage im)
651 {
652 Action<GridInstantMessage> oimtn = OnInstantMessageToNPC;
653
654 if (oimtn != null)
655 oimtn(im);
656 }
657
658 public void SendGenericMessage(string method, UUID invoice, List<string> message)
659 {
660
661 }
662
663 public void SendGenericMessage(string method, UUID invoice, List<byte[]> message)
664 {
665
666 }
667
668 public virtual void SendLayerData(float[] map)
669 {
670 }
671
672 public virtual void SendLayerData(int px, int py, float[] map)
673 {
674 }
675 public virtual void SendLayerData(int px, int py, float[] map, bool track)
676 {
677 }
678
679 public virtual void SendWindData(Vector2[] windSpeeds) { }
680
681 public virtual void SendCloudData(float[] cloudCover) { }
682
683 public virtual void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
684 {
685 }
686
687 public virtual void InformClientOfNeighbour(ulong neighbourHandle, IPEndPoint neighbourExternalEndPoint)
688 {
689 }
690
691 public virtual AgentCircuitData RequestClientInfo()
692 {
693 return new AgentCircuitData();
694 }
695
696 public virtual void CrossRegion(ulong newRegionHandle, Vector3 pos, Vector3 lookAt,
697 IPEndPoint newRegionExternalEndPoint, string capsURL)
698 {
699 }
700
701 public virtual void SendMapBlock(List<MapBlockData> mapBlocks, uint flag)
702 {
703 }
704
705 public virtual void SendLocalTeleport(Vector3 position, Vector3 lookAt, uint flags)
706 {
707 }
708
709 public virtual void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint,
710 uint locationID, uint flags, string capsURL)
711 {
712 }
713
714 public virtual void SendTeleportFailed(string reason)
715 {
716 }
717
718 public virtual void SendTeleportStart(uint flags)
719 {
720 }
721
722 public virtual void SendTeleportProgress(uint flags, string message)
723 {
724 }
725
726 public virtual void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance, int transactionType, UUID sourceID, bool sourceIsGroup, UUID destID, bool destIsGroup, int amount, string item)
727 {
728 }
729
730 public virtual void SendPayPrice(UUID objectID, int[] payPrice)
731 {
732 }
733
734 public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
735 {
736 }
737
738 public virtual void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels)
739 {
740 }
741
742 public void SendAvatarDataImmediate(ISceneEntity avatar)
743 {
744 }
745
746 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
747 {
748 }
749
750 public void ReprioritizeUpdates()
751 {
752 }
753
754 public void FlushPrimUpdates()
755 {
756 }
757
758 public virtual void SendInventoryFolderDetails(UUID ownerID, UUID folderID,
759 List<InventoryItemBase> items,
760 List<InventoryFolderBase> folders,
761 int version,
762 bool fetchFolders,
763 bool fetchItems)
764 {
765 }
766
767 public virtual void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item)
768 {
769 }
770
771 public virtual void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackID)
772 {
773 }
774
775 public virtual void SendRemoveInventoryItem(UUID itemID)
776 {
777 }
778
779 public virtual void SendBulkUpdateInventory(InventoryNodeBase node)
780 {
781 }
782
783 public void SendTakeControls(int controls, bool passToAgent, bool TakeControls)
784 {
785 }
786
787 public virtual void SendTaskInventory(UUID taskID, short serial, byte[] fileName)
788 {
789 }
790
791 public virtual void SendXferPacket(ulong xferID, uint packet, byte[] data)
792 {
793 }
794 public virtual void SendAbortXferPacket(ulong xferID)
795 {
796
797 }
798
799 public virtual void SendEconomyData(float EnergyEfficiency, int ObjectCapacity, int ObjectCount, int PriceEnergyUnit,
800 int PriceGroupCreate, int PriceObjectClaim, float PriceObjectRent, float PriceObjectScaleFactor,
801 int PriceParcelClaim, float PriceParcelClaimFactor, int PriceParcelRent, int PricePublicObjectDecay,
802 int PricePublicObjectDelete, int PriceRentLight, int PriceUpload, int TeleportMinPrice, float TeleportPriceExponent)
803 {
804
805 }
806 public virtual void SendNameReply(UUID profileId, string firstname, string lastname)
807 {
808 }
809
810 public virtual void SendPreLoadSound(UUID objectID, UUID ownerID, UUID soundID)
811 {
812 }
813
814 public virtual void SendPlayAttachedSound(UUID soundID, UUID objectID, UUID ownerID, float gain,
815 byte flags)
816 {
817 }
818
819 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
820 {
821 }
822
823 public void SendAttachedSoundGainChange(UUID objectID, float gain)
824 {
825
826 }
827
828 public void SendAlertMessage(string message)
829 {
830 }
831
832 public void SendAgentAlertMessage(string message, bool modal)
833 {
834 }
835
836 public void SendSystemAlertMessage(string message)
837 {
838 }
839
840 public void SendLoadURL(string objectname, UUID objectID, UUID ownerID, bool groupOwned, string message,
841 string url)
842 {
843 }
844
845 public virtual void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args)
846 {
847 if (OnRegionHandShakeReply != null)
848 {
849 OnRegionHandShakeReply(this);
850 }
851 }
852
853 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)
854 {
855 }
856
857 public void SendConfirmXfer(ulong xferID, uint PacketID)
858 {
859 }
860
861 public void SendXferRequest(ulong XferID, short AssetType, UUID vFileID, byte FilePath, byte[] FileName)
862 {
863 }
864
865 public void SendInitiateDownload(string simFileName, string clientFileName)
866 {
867 }
868
869 public void SendImageFirstPart(ushort numParts, UUID ImageUUID, uint ImageSize, byte[] ImageData, byte imageCodec)
870 {
871 }
872
873 public void SendImageNotFound(UUID imageid)
874 {
875 }
876
877 public void SendImageNextPart(ushort partNumber, UUID imageUuid, byte[] imageData)
878 {
879 }
880
881 public void SendShutdownConnectionNotice()
882 {
883 }
884
885 public void SendSimStats(SimStats stats)
886 {
887 }
888
889 public void SendObjectPropertiesFamilyData(ISceneEntity Entity, uint RequestFlags)
890 {
891
892 }
893
894 public void SendObjectPropertiesReply(ISceneEntity entity)
895 {
896 }
897
898 public void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong time, uint dlen, uint ylen, float phase)
899 {
900 }
901
902 public void SendViewerEffect(ViewerEffectPacket.EffectBlock[] effectBlocks)
903 {
904 }
905
906 public void SendViewerTime(int phase)
907 {
908 }
909
910 public void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] charterMember,
911 string flAbout, uint flags, UUID flImageID, UUID imageID, string profileURL,
912 UUID partnerID)
913 {
914 }
915
916 public void SendAsset(AssetRequestToClient req)
917 {
918 }
919
920 public void SendTexture(AssetBase TextureAsset)
921 {
922 }
923
924 public int DebugPacketLevel { get; set; }
925
926 public void InPacket(object NewPack)
927 {
928 }
929
930 public void ProcessInPacket(Packet NewPack)
931 {
932 }
933
934 public void Close()
935 {
936 Close(false);
937 }
938
939 public void Close(bool force)
940 {
941 // Remove ourselves from the scene
942 m_scene.RemoveClient(AgentId, false);
943 }
944
945 public void Start()
946 {
947 // We never start the client, so always fail.
948 throw new NotImplementedException();
949 }
950
951 public void Stop()
952 {
953 }
954
955 private uint m_circuitCode;
956 private IPEndPoint m_remoteEndPoint;
957
958 public uint CircuitCode
959 {
960 get { return m_circuitCode; }
961 set
962 {
963 m_circuitCode = value;
964 m_remoteEndPoint = new IPEndPoint(IPAddress.Loopback, (ushort)m_circuitCode);
965 }
966 }
967
968 public IPEndPoint RemoteEndPoint
969 {
970 get { return m_remoteEndPoint; }
971 }
972
973 public void SendBlueBoxMessage(UUID FromAvatarID, String FromAvatarName, String Message)
974 {
975
976 }
977 public void SendLogoutPacket()
978 {
979 }
980
981 public void Terminate()
982 {
983 }
984
985 public ClientInfo GetClientInfo()
986 {
987 return null;
988 }
989
990 public void SetClientInfo(ClientInfo info)
991 {
992 }
993
994 public void SendScriptQuestion(UUID objectID, string taskName, string ownerName, UUID itemID, int question)
995 {
996 }
997 public void SendHealth(float health)
998 {
999 }
1000
1001 public void SendEstateList(UUID invoice, int code, UUID[] Data, uint estateID)
1002 {
1003 }
1004
1005 public void SendBannedUserList(UUID invoice, EstateBan[] banlist, uint estateID)
1006 {
1007 }
1008
1009 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
1010 {
1011 }
1012 public void SendEstateCovenantInformation(UUID covenant)
1013 {
1014 }
1015 public void SendTelehubInfo(UUID ObjectID, string ObjectName, Vector3 ObjectPos, Quaternion ObjectRot, List<Vector3> SpawnPoint)
1016 {
1017 }
1018 public void SendDetailedEstateData(UUID invoice, string estateName, uint estateID, uint parentEstate, uint estateFlags, uint sunPosition, UUID covenant, uint covenantChanged, string abuseEmail, UUID estateOwner)
1019 {
1020 }
1021
1022 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, ILandObject lo, float simObjectBonusFactor,int parcelObjectCapacity, int simObjectCapacity, uint regionFlags)
1023 {
1024 }
1025 public void SendLandAccessListData(List<LandAccessEntry> accessList, uint accessFlag, int localLandID)
1026 {
1027 }
1028 public void SendForceClientSelectObjects(List<uint> objectIDs)
1029 {
1030 }
1031 public void SendCameraConstraint(Vector4 ConstraintPlane)
1032 {
1033 }
1034 public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount)
1035 {
1036 }
1037 public void SendLandParcelOverlay(byte[] data, int sequence_id)
1038 {
1039 }
1040
1041 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
1042 {
1043 }
1044
1045 public void SendScriptRunningReply(UUID objectID, UUID itemID, bool running)
1046 {
1047 }
1048
1049 public void SendLandStatReply(uint reportType, uint requestFlags, uint resultCount, LandStatReportItem[] lsrpia)
1050 {
1051 }
1052 #endregion
1053
1054
1055 public void SendParcelMediaCommand(uint flags, ParcelMediaCommandEnum command, float time)
1056 {
1057 }
1058
1059 public void SendParcelMediaUpdate(string mediaUrl, UUID mediaTextureID,
1060 byte autoScale, string mediaType, string mediaDesc, int mediaWidth, int mediaHeight,
1061 byte mediaLoop)
1062 {
1063 }
1064
1065 public void SendSetFollowCamProperties (UUID objectID, SortedDictionary<int, float> parameters)
1066 {
1067 }
1068
1069 public void SendClearFollowCamProperties (UUID objectID)
1070 {
1071 }
1072
1073 public void SendRegionHandle (UUID regoinID, ulong handle)
1074 {
1075 }
1076
1077 public void SendParcelInfo (RegionInfo info, LandData land, UUID parcelID, uint x, uint y)
1078 {
1079 }
1080
1081 public void SetClientOption(string option, string value)
1082 {
1083 }
1084
1085 public string GetClientOption(string option)
1086 {
1087 return string.Empty;
1088 }
1089
1090 public void SendScriptTeleportRequest (string objName, string simName, Vector3 pos, Vector3 lookAt)
1091 {
1092 }
1093
1094 public void SendDirPlacesReply(UUID queryID, DirPlacesReplyData[] data)
1095 {
1096 }
1097
1098 public void SendDirPeopleReply(UUID queryID, DirPeopleReplyData[] data)
1099 {
1100 }
1101
1102 public void SendDirEventsReply(UUID queryID, DirEventsReplyData[] data)
1103 {
1104 }
1105
1106 public void SendDirGroupsReply(UUID queryID, DirGroupsReplyData[] data)
1107 {
1108 }
1109
1110 public void SendDirClassifiedReply(UUID queryID, DirClassifiedReplyData[] data)
1111 {
1112 }
1113
1114 public void SendDirLandReply(UUID queryID, DirLandReplyData[] data)
1115 {
1116 }
1117
1118 public void SendDirPopularReply(UUID queryID, DirPopularReplyData[] data)
1119 {
1120 }
1121
1122 public void SendMapItemReply(mapItemReply[] replies, uint mapitemtype, uint flags)
1123 {
1124 }
1125
1126 public void SendEventInfoReply (EventData info)
1127 {
1128 }
1129
1130 public void SendOfferCallingCard (UUID destID, UUID transactionID)
1131 {
1132 }
1133
1134 public void SendAcceptCallingCard (UUID transactionID)
1135 {
1136 }
1137
1138 public void SendDeclineCallingCard (UUID transactionID)
1139 {
1140 }
1141
1142 public void SendJoinGroupReply(UUID groupID, bool success)
1143 {
1144 }
1145
1146 public void SendEjectGroupMemberReply(UUID agentID, UUID groupID, bool success)
1147 {
1148 }
1149
1150 public void SendLeaveGroupReply(UUID groupID, bool success)
1151 {
1152 }
1153
1154 public void SendAvatarGroupsReply(UUID avatarID, GroupMembershipData[] data)
1155 {
1156 }
1157
1158 public void SendTerminateFriend(UUID exFriendID)
1159 {
1160 }
1161
1162 #region IClientAPI Members
1163
1164
1165 public bool AddGenericPacketHandler(string MethodName, GenericMessage handler)
1166 {
1167 //throw new NotImplementedException();
1168 return false;
1169 }
1170
1171 public void SendAvatarClassifiedReply(UUID targetID, UUID[] classifiedID, string[] name)
1172 {
1173 }
1174
1175 public void SendClassifiedInfoReply(UUID classifiedID, UUID creatorID, uint creationDate, uint expirationDate, uint category, string name, string description, UUID parcelID, uint parentEstate, UUID snapshotID, string simName, Vector3 globalPos, string parcelName, byte classifiedFlags, int price)
1176 {
1177 }
1178
1179 public void SendAgentDropGroup(UUID groupID)
1180 {
1181 }
1182
1183 public void SendAvatarNotesReply(UUID targetID, string text)
1184 {
1185 }
1186
1187 public void SendAvatarPicksReply(UUID targetID, Dictionary<UUID, string> picks)
1188 {
1189 }
1190
1191 public void SendAvatarClassifiedReply(UUID targetID, Dictionary<UUID, string> classifieds)
1192 {
1193 }
1194
1195 public void SendParcelDwellReply(int localID, UUID parcelID, float dwell)
1196 {
1197 }
1198
1199 public void SendUserInfoReply(bool imViaEmail, bool visible, string email)
1200 {
1201 }
1202
1203 public void SendCreateGroupReply(UUID groupID, bool success, string message)
1204 {
1205 }
1206
1207 public void RefreshGroupMembership()
1208 {
1209 }
1210
1211 public void SendUseCachedMuteList()
1212 {
1213 }
1214
1215 public void SendMuteListUpdate(string filename)
1216 {
1217 }
1218
1219 public void SendPickInfoReply(UUID pickID,UUID creatorID, bool topPick, UUID parcelID, string name, string desc, UUID snapshotID, string user, string originalName, string simName, Vector3 posGlobal, int sortOrder, bool enabled)
1220 {
1221 }
1222 #endregion
1223
1224 public void SendRebakeAvatarTextures(UUID textureID)
1225 {
1226 }
1227
1228 public void SendAvatarInterestsReply(UUID avatarID, uint wantMask, string wantText, uint skillsMask, string skillsText, string languages)
1229 {
1230 }
1231
1232 public void SendGroupAccountingDetails(IClientAPI sender,UUID groupID, UUID transactionID, UUID sessionID, int amt)
1233 {
1234 }
1235
1236 public void SendGroupAccountingSummary(IClientAPI sender,UUID groupID, uint moneyAmt, int totalTier, int usedTier)
1237 {
1238 }
1239
1240 public void SendGroupTransactionsSummaryDetails(IClientAPI sender,UUID groupID, UUID transactionID, UUID sessionID,int amt)
1241 {
1242 }
1243
1244 public void SendGroupVoteHistory(UUID groupID, UUID transactionID, GroupVoteHistory[] Votes)
1245 {
1246 }
1247
1248 public void SendGroupActiveProposals(UUID groupID, UUID transactionID, GroupActiveProposals[] Proposals)
1249 {
1250 }
1251
1252 public void SendChangeUserRights(UUID agentID, UUID friendID, int rights)
1253 {
1254 }
1255
1256 public void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId)
1257 {
1258 }
1259
1260 public void SendAgentTerseUpdate(ISceneEntity presence)
1261 {
1262 }
1263
1264 public void SendPlacesReply(UUID queryID, UUID transactionID, PlacesReplyData[] data)
1265 {
1266 }
1267
1268 public void SendPartPhysicsProprieties(ISceneEntity entity)
1269 {
1270 }
1271
1272 }
1273}
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}
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
new file mode 100644
index 0000000..0bebb58
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
@@ -0,0 +1,487 @@
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 log4net;
32using Nini.Config;
33using NUnit.Framework;
34using OpenMetaverse;
35using OpenSim.Framework;
36using OpenSim.Framework.Communications;
37using OpenSim.Region.CoreModules.Avatar.Attachments;
38using OpenSim.Region.CoreModules.Avatar.AvatarFactory;
39using OpenSim.Region.CoreModules.Framework.InventoryAccess;
40using OpenSim.Region.CoreModules.Framework.UserManagement;
41using OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar;
42using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes;
44using OpenSim.Services.AvatarService;
45using OpenSim.Tests.Common;
46
47namespace OpenSim.Region.OptionalModules.World.NPC.Tests
48{
49 [TestFixture]
50 public class NPCModuleTests : OpenSimTestCase
51 {
52 private TestScene m_scene;
53 private AvatarFactoryModule m_afMod;
54 private UserManagementModule m_umMod;
55 private AttachmentsModule m_attMod;
56 private NPCModule m_npcMod;
57
58 [TestFixtureSetUp]
59 public void FixtureInit()
60 {
61 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
62 Util.FireAndForgetMethod = FireAndForgetMethod.None;
63 }
64
65 [TestFixtureTearDown]
66 public void TearDown()
67 {
68 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
69 // threads. Possibly, later tests should be rewritten not to worry about such things.
70 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
71 }
72
73 public void SetUpScene()
74 {
75 SetUpScene(256, 256);
76 }
77
78 public void SetUpScene(uint sizeX, uint sizeY)
79 {
80 IConfigSource config = new IniConfigSource();
81 config.AddConfig("NPC");
82 config.Configs["NPC"].Set("Enabled", "true");
83 config.AddConfig("Modules");
84 config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
85
86 m_afMod = new AvatarFactoryModule();
87 m_umMod = new UserManagementModule();
88 m_attMod = new AttachmentsModule();
89 m_npcMod = new NPCModule();
90
91 m_scene = new SceneHelpers().SetupScene("test scene", UUID.Random(), 1000, 1000, sizeX, sizeY, config);
92 SceneHelpers.SetupSceneModules(m_scene, config, m_afMod, m_umMod, m_attMod, m_npcMod, new BasicInventoryAccessModule());
93 }
94
95 [Test]
96 public void TestCreate()
97 {
98 TestHelpers.InMethod();
99// log4net.Config.XmlConfigurator.Configure();
100
101 SetUpScene();
102
103 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
104// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
105
106 // 8 is the index of the first baked texture in AvatarAppearance
107 UUID originalFace8TextureId = TestHelpers.ParseTail(0x10);
108 Primitive.TextureEntry originalTe = new Primitive.TextureEntry(UUID.Zero);
109 Primitive.TextureEntryFace originalTef = originalTe.CreateFace(8);
110 originalTef.TextureID = originalFace8TextureId;
111
112 // We also need to add the texture to the asset service, otherwise the AvatarFactoryModule will tell
113 // ScenePresence.SendInitialData() to reset our entire appearance.
114 m_scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId));
115
116 m_afMod.SetAppearance(sp, originalTe, null, null);
117
118 UUID npcId = m_npcMod.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, sp.Appearance);
119
120 ScenePresence npc = m_scene.GetScenePresence(npcId);
121
122 Assert.That(npc, Is.Not.Null);
123 Assert.That(npc.Appearance.Texture.FaceTextures[8].TextureID, Is.EqualTo(originalFace8TextureId));
124 Assert.That(m_umMod.GetUserName(npc.UUID), Is.EqualTo(string.Format("{0} {1}", npc.Firstname, npc.Lastname)));
125
126 IClientAPI client;
127 Assert.That(m_scene.TryGetClient(npcId, out client), Is.True);
128
129 // Have to account for both SP and NPC.
130 Assert.That(m_scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(2));
131 }
132
133 [Test]
134 public void TestRemove()
135 {
136 TestHelpers.InMethod();
137// log4net.Config.XmlConfigurator.Configure();
138
139 SetUpScene();
140
141 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
142// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
143
144 Vector3 startPos = new Vector3(128, 128, 30);
145 UUID npcId = m_npcMod.CreateNPC("John", "Smith", startPos, UUID.Zero, true, m_scene, sp.Appearance);
146
147 m_npcMod.DeleteNPC(npcId, m_scene);
148
149 ScenePresence deletedNpc = m_scene.GetScenePresence(npcId);
150
151 Assert.That(deletedNpc, Is.Null);
152 IClientAPI client;
153 Assert.That(m_scene.TryGetClient(npcId, out client), Is.False);
154
155 // Have to account for SP still present.
156 Assert.That(m_scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(1));
157 }
158
159 [Test]
160 public void TestCreateWithAttachments()
161 {
162 TestHelpers.InMethod();
163// TestHelpers.EnableLogging();
164
165 SetUpScene();
166
167 UUID userId = TestHelpers.ParseTail(0x1);
168 UserAccountHelpers.CreateUserWithInventory(m_scene, userId);
169 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
170
171 UUID attItemId = TestHelpers.ParseTail(0x2);
172 UUID attAssetId = TestHelpers.ParseTail(0x3);
173 string attName = "att";
174
175 UserInventoryHelpers.CreateInventoryItem(m_scene, attName, attItemId, attAssetId, sp.UUID, InventoryType.Object);
176
177 m_attMod.RezSingleAttachmentFromInventory(sp, attItemId, (uint)AttachmentPoint.Chest);
178
179 UUID npcId = m_npcMod.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, sp.Appearance);
180
181 ScenePresence npc = m_scene.GetScenePresence(npcId);
182
183 // Check scene presence status
184 Assert.That(npc.HasAttachments(), Is.True);
185 List<SceneObjectGroup> attachments = npc.GetAttachments();
186 Assert.That(attachments.Count, Is.EqualTo(1));
187 SceneObjectGroup attSo = attachments[0];
188
189 // Just for now, we won't test the name since this is (wrongly) the asset part name rather than the item
190 // name. TODO: Do need to fix ultimately since the item may be renamed before being passed on to an NPC.
191// Assert.That(attSo.Name, Is.EqualTo(attName));
192
193 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
194 Assert.That(attSo.IsAttachment);
195 Assert.That(attSo.UsesPhysics, Is.False);
196 Assert.That(attSo.IsTemporary, Is.False);
197 Assert.That(attSo.OwnerID, Is.EqualTo(npc.UUID));
198 }
199
200 [Test]
201 public void TestCreateWithMultiAttachments()
202 {
203 TestHelpers.InMethod();
204// TestHelpers.EnableLogging();
205
206 SetUpScene();
207// m_attMod.DebugLevel = 1;
208
209 UUID userId = TestHelpers.ParseTail(0x1);
210 UserAccountHelpers.CreateUserWithInventory(m_scene, userId);
211 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
212
213 InventoryItemBase att1Item
214 = UserInventoryHelpers.CreateInventoryItem(
215 m_scene, "att1", TestHelpers.ParseTail(0x2), TestHelpers.ParseTail(0x3), sp.UUID, InventoryType.Object);
216 InventoryItemBase att2Item
217 = UserInventoryHelpers.CreateInventoryItem(
218 m_scene, "att2", TestHelpers.ParseTail(0x12), TestHelpers.ParseTail(0x13), sp.UUID, InventoryType.Object);
219
220 m_attMod.RezSingleAttachmentFromInventory(sp, att1Item.ID, (uint)AttachmentPoint.Chest);
221 m_attMod.RezSingleAttachmentFromInventory(sp, att2Item.ID, (uint)AttachmentPoint.Chest | 0x80);
222
223 UUID npcId = m_npcMod.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, sp.Appearance);
224
225 ScenePresence npc = m_scene.GetScenePresence(npcId);
226
227 // Check scene presence status
228 Assert.That(npc.HasAttachments(), Is.True);
229 List<SceneObjectGroup> attachments = npc.GetAttachments();
230 Assert.That(attachments.Count, Is.EqualTo(2));
231
232 // Just for now, we won't test the name since this is (wrongly) the asset part name rather than the item
233 // name. TODO: Do need to fix ultimately since the item may be renamed before being passed on to an NPC.
234// Assert.That(attSo.Name, Is.EqualTo(attName));
235
236 TestAttachedObject(attachments[0], AttachmentPoint.Chest, npc.UUID);
237 TestAttachedObject(attachments[1], AttachmentPoint.Chest, npc.UUID);
238
239 // Attached objects on the same point must have different FromItemIDs to be shown to other avatars, at least
240 // on Singularity 1.8.5. Otherwise, only one (the first ObjectUpdate sent) appears.
241 Assert.AreNotEqual(attachments[0].FromItemID, attachments[1].FromItemID);
242 }
243
244 private void TestAttachedObject(SceneObjectGroup attSo, AttachmentPoint attPoint, UUID ownerId)
245 {
246 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)attPoint));
247 Assert.That(attSo.IsAttachment);
248 Assert.That(attSo.UsesPhysics, Is.False);
249 Assert.That(attSo.IsTemporary, Is.False);
250 Assert.That(attSo.OwnerID, Is.EqualTo(ownerId));
251 }
252
253 [Test]
254 public void TestLoadAppearance()
255 {
256 TestHelpers.InMethod();
257// log4net.Config.XmlConfigurator.Configure();
258
259 SetUpScene();
260
261 UUID userId = TestHelpers.ParseTail(0x1);
262 UserAccountHelpers.CreateUserWithInventory(m_scene, userId);
263 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
264
265 UUID npcId = m_npcMod.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, sp.Appearance);
266
267 // Now add the attachment to the original avatar and use that to load a new appearance
268 // TODO: Could also run tests loading from a notecard though this isn't much different for our purposes here
269 UUID attItemId = TestHelpers.ParseTail(0x2);
270 UUID attAssetId = TestHelpers.ParseTail(0x3);
271 string attName = "att";
272
273 UserInventoryHelpers.CreateInventoryItem(m_scene, attName, attItemId, attAssetId, sp.UUID, InventoryType.Object);
274
275 m_attMod.RezSingleAttachmentFromInventory(sp, attItemId, (uint)AttachmentPoint.Chest);
276
277 m_npcMod.SetNPCAppearance(npcId, sp.Appearance, m_scene);
278
279 ScenePresence npc = m_scene.GetScenePresence(npcId);
280
281 // Check scene presence status
282 Assert.That(npc.HasAttachments(), Is.True);
283 List<SceneObjectGroup> attachments = npc.GetAttachments();
284 Assert.That(attachments.Count, Is.EqualTo(1));
285 SceneObjectGroup attSo = attachments[0];
286
287 // Just for now, we won't test the name since this is (wrongly) the asset part name rather than the item
288 // name. TODO: Do need to fix ultimately since the item may be renamed before being passed on to an NPC.
289// Assert.That(attSo.Name, Is.EqualTo(attName));
290
291 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
292 Assert.That(attSo.IsAttachment);
293 Assert.That(attSo.UsesPhysics, Is.False);
294 Assert.That(attSo.IsTemporary, Is.False);
295 Assert.That(attSo.OwnerID, Is.EqualTo(npc.UUID));
296 }
297
298 [Test]
299 public void TestMove()
300 {
301 TestHelpers.InMethod();
302// TestHelpers.EnableLogging();
303
304 SetUpScene();
305
306 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
307// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
308
309 Vector3 startPos = new Vector3(128, 128, 30);
310 UUID npcId = m_npcMod.CreateNPC("John", "Smith", startPos, UUID.Zero, true, m_scene, sp.Appearance);
311
312 ScenePresence npc = m_scene.GetScenePresence(npcId);
313 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
314
315 // For now, we'll make the scene presence fly to simplify this test, but this needs to change.
316 npc.Flying = true;
317
318 m_scene.Update(1);
319 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
320
321 Vector3 targetPos = startPos + new Vector3(0, 10, 0);
322 m_npcMod.MoveToTarget(npc.UUID, m_scene, targetPos, false, false, false);
323
324 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
325 //Assert.That(npc.Rotation, Is.EqualTo(new Quaternion(0, 0, 0.7071068f, 0.7071068f)));
326 Assert.That(
327 npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001));
328
329 m_scene.Update(1);
330
331 // We should really check the exact figure.
332 Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X));
333 Assert.That(npc.AbsolutePosition.Y, Is.GreaterThan(startPos.Y));
334 Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
335 Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.X));
336
337 m_scene.Update(10);
338
339 double distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos);
340 Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on first move");
341 Assert.That(npc.AbsolutePosition, Is.EqualTo(targetPos));
342 Assert.That(npc.AgentControlFlags, Is.EqualTo((uint)AgentManager.ControlFlags.NONE));
343
344 // Try a second movement
345 startPos = npc.AbsolutePosition;
346 targetPos = startPos + new Vector3(10, 0, 0);
347 m_npcMod.MoveToTarget(npc.UUID, m_scene, targetPos, false, false, false);
348
349 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
350// Assert.That(npc.Rotation, Is.EqualTo(new Quaternion(0, 0, 0, 1)));
351 Assert.That(
352 npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001));
353
354 m_scene.Update(1);
355
356 // We should really check the exact figure.
357 Assert.That(npc.AbsolutePosition.X, Is.GreaterThan(startPos.X));
358 Assert.That(npc.AbsolutePosition.X, Is.LessThan(targetPos.X));
359 Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y));
360 Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
361
362 m_scene.Update(10);
363
364 distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos);
365 Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on second move");
366 Assert.That(npc.AbsolutePosition, Is.EqualTo(targetPos));
367 }
368
369 [Test]
370 public void TestMoveInVarRegion()
371 {
372 TestHelpers.InMethod();
373// TestHelpers.EnableLogging();
374
375 SetUpScene(512, 512);
376
377 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
378// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
379
380 Vector3 startPos = new Vector3(128, 246, 30);
381 UUID npcId = m_npcMod.CreateNPC("John", "Smith", startPos, UUID.Zero, true, m_scene, sp.Appearance);
382
383 ScenePresence npc = m_scene.GetScenePresence(npcId);
384 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
385
386 // For now, we'll make the scene presence fly to simplify this test, but this needs to change.
387 npc.Flying = true;
388
389 m_scene.Update(1);
390 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
391
392 Vector3 targetPos = startPos + new Vector3(0, 20, 0);
393 m_npcMod.MoveToTarget(npc.UUID, m_scene, targetPos, false, false, false);
394
395 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
396 //Assert.That(npc.Rotation, Is.EqualTo(new Quaternion(0, 0, 0.7071068f, 0.7071068f)));
397 Assert.That(
398 npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001));
399
400 m_scene.Update(1);
401
402 // We should really check the exact figure.
403 Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X));
404 Assert.That(npc.AbsolutePosition.Y, Is.GreaterThan(startPos.Y));
405 Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
406 Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.X));
407
408 for (int i = 0; i < 20; i++)
409 {
410 m_scene.Update(1);
411// Console.WriteLine("pos: {0}", npc.AbsolutePosition);
412 }
413
414 double distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos);
415 Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on first move");
416 Assert.That(npc.AbsolutePosition, Is.EqualTo(targetPos));
417 Assert.That(npc.AgentControlFlags, Is.EqualTo((uint)AgentManager.ControlFlags.NONE));
418 }
419
420 [Test]
421 public void TestSitAndStandWithSitTarget()
422 {
423 TestHelpers.InMethod();
424// log4net.Config.XmlConfigurator.Configure();
425
426 SetUpScene();
427
428 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
429
430 Vector3 startPos = new Vector3(128, 128, 30);
431 UUID npcId = m_npcMod.CreateNPC("John", "Smith", startPos, UUID.Zero, true, m_scene, sp.Appearance);
432
433 ScenePresence npc = m_scene.GetScenePresence(npcId);
434 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart;
435
436 part.SitTargetPosition = new Vector3(0, 0, 1);
437 m_npcMod.Sit(npc.UUID, part.UUID, m_scene);
438
439 Assert.That(part.SitTargetAvatar, Is.EqualTo(npcId));
440 Assert.That(npc.ParentID, Is.EqualTo(part.LocalId));
441// Assert.That(
442// npc.AbsolutePosition,
443// Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT));
444
445 m_npcMod.Stand(npc.UUID, m_scene);
446
447 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
448 Assert.That(npc.ParentID, Is.EqualTo(0));
449 }
450
451 [Test]
452 public void TestSitAndStandWithNoSitTarget()
453 {
454 TestHelpers.InMethod();
455// TestHelpers.EnableLogging();
456
457 SetUpScene();
458
459 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
460
461 // FIXME: To get this to work for now, we are going to place the npc right next to the target so that
462 // the autopilot doesn't trigger
463 Vector3 startPos = new Vector3(1, 1, 1);
464
465 UUID npcId = m_npcMod.CreateNPC("John", "Smith", startPos, UUID.Zero, true, m_scene, sp.Appearance);
466
467 ScenePresence npc = m_scene.GetScenePresence(npcId);
468 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart;
469
470 m_npcMod.Sit(npc.UUID, part.UUID, m_scene);
471
472 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
473 Assert.That(npc.ParentID, Is.EqualTo(part.LocalId));
474
475 // We should really be using the NPC size but this would mean preserving the physics actor since it is
476 // removed on sit.
477 Assert.That(
478 npc.AbsolutePosition,
479 Is.EqualTo(part.AbsolutePosition + new Vector3(0, 0, sp.PhysicsActor.Size.Z / 2)));
480
481 m_npcMod.Stand(npc.UUID, m_scene);
482
483 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
484 Assert.That(npc.ParentID, Is.EqualTo(0));
485 }
486 }
487} \ No newline at end of file