2007-03-09 20:26:07 +00:00
/ *
2022-08-27 20:36:50 -05:00
* Copyright ( c ) 2006 - 2016 , openmetaverse . co
2022-01-02 09:04:28 -06:00
* Copyright ( c ) 2019 - 2022 , Sjofn LLC
2007-03-09 20:26:07 +00:00
* All rights reserved .
*
2009-04-13 09:32:25 +00:00
* - Redistribution and use in source and binary forms , with or without
2007-03-09 20:26:07 +00:00
* modification , are permitted provided that the following conditions are met :
*
* - Redistributions of source code must retain the above copyright notice , this
* list of conditions and the following disclaimer .
2015-11-06 19:00:05 +01:00
* - Neither the name of the openmetaverse . co nor the names
2007-03-09 20:26:07 +00:00
* of its contributors may be used to endorse or promote products derived from
* this software without specific prior written permission .
*
2009-04-13 09:32:25 +00:00
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR
* CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS
* INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN
* CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE )
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE
2007-03-09 20:26:07 +00:00
* POSSIBILITY OF SUCH DAMAGE .
* /
using System ;
using System.Net ;
2011-03-05 23:48:49 +00:00
using System.Text.RegularExpressions ;
2009-10-16 02:53:53 +00:00
using System.Threading ;
using System.Collections.Generic ;
2022-10-10 16:22:33 -05:00
using System.Globalization ;
2017-06-04 12:43:14 -05:00
using System.Linq ;
2008-07-21 21:12:59 +00:00
using OpenMetaverse.StructuredData ;
2009-10-16 02:53:53 +00:00
using OpenMetaverse.Assets ;
2008-07-21 21:12:59 +00:00
using OpenMetaverse.Packets ;
2009-04-13 09:32:25 +00:00
using OpenMetaverse.Interfaces ;
using OpenMetaverse.Messages.Linden ;
2022-11-03 14:19:56 -05:00
using System.Net.Http ;
using System.Threading.Tasks ;
2007-03-09 20:26:07 +00:00
2008-07-21 21:12:59 +00:00
namespace OpenMetaverse
2007-03-09 20:26:07 +00:00
{
2008-09-09 04:58:58 +00:00
#region Enums
/// <summary>
2008-03-14 07:11:13 +00:00
/// Permission request flags, asked when a script wants to control an Avatar
2007-08-22 18:16:38 +00:00
/// </summary>
[Flags]
public enum ScriptPermission : int
{
2008-09-09 04:58:58 +00:00
/// <summary>Placeholder for empty values, shouldn't ever see this</summary>
None = 0 ,
/// <summary>Script wants ability to take money from you</summary>
Debit = 1 < < 1 ,
/// <summary>Script wants to take camera controls for you</summary>
TakeControls = 1 < < 2 ,
/// <summary>Script wants to remap avatars controls</summary>
RemapControls = 1 < < 3 ,
/// <summary>Script wants to trigger avatar animations</summary>
2008-03-14 07:11:13 +00:00
/// <remarks>This function is not implemented on the grid</remarks>
2008-09-09 04:58:58 +00:00
TriggerAnimation = 1 < < 4 ,
/// <summary>Script wants to attach or detach the prim or primset to your avatar</summary>
Attach = 1 < < 5 ,
/// <summary>Script wants permission to release ownership</summary>
2008-03-14 07:11:13 +00:00
/// <remarks>This function is not implemented on the grid
/// The concept of "public" objects does not exist anymore.</remarks>
2008-09-09 04:58:58 +00:00
ReleaseOwnership = 1 < < 6 ,
/// <summary>Script wants ability to link/delink with other prims</summary>
ChangeLinks = 1 < < 7 ,
/// <summary>Script wants permission to change joints</summary>
2008-03-14 07:11:13 +00:00
/// <remarks>This function is not implemented on the grid</remarks>
2008-09-09 04:58:58 +00:00
ChangeJoints = 1 < < 8 ,
/// <summary>Script wants permissions to change permissions</summary>
2008-03-14 07:11:13 +00:00
/// <remarks>This function is not implemented on the grid</remarks>
2008-09-09 04:58:58 +00:00
ChangePermissions = 1 < < 9 ,
/// <summary>Script wants to track avatars camera position and rotation </summary>
TrackCamera = 1 < < 10 ,
/// <summary>Script wants to control your camera</summary>
2012-09-18 01:36:01 +02:00
ControlCamera = 1 < < 11 ,
2012-07-31 21:46:18 +02:00
/// <summary>Script wants the ability to teleport you</summary>
Teleport = 1 < < 12
2007-08-22 18:16:38 +00:00
}
2008-09-09 04:58:58 +00:00
2007-08-22 18:16:38 +00:00
/// <summary>
2008-09-09 04:58:58 +00:00
/// Special commands used in Instant Messages
/// </summary>
public enum InstantMessageDialog : byte
{
/// <summary>Indicates a regular IM from another agent</summary>
MessageFromAgent = 0 ,
/// <summary>Simple notification box with an OK button</summary>
MessageBox = 1 ,
// <summary>Used to show a countdown notification with an OK
// button, deprecated now</summary>
2008-07-21 18:56:11 +00:00
//[Obsolete]
//MessageBoxCountdown = 2,
2008-09-09 04:58:58 +00:00
/// <summary>You've been invited to join a group.</summary>
GroupInvitation = 3 ,
/// <summary>Inventory offer</summary>
InventoryOffered = 4 ,
/// <summary>Accepted inventory offer</summary>
InventoryAccepted = 5 ,
/// <summary>Declined inventory offer</summary>
InventoryDeclined = 6 ,
/// <summary>Group vote</summary>
GroupVote = 7 ,
// <summary>A message to everyone in the agent's group, no longer
// used</summary>
2008-07-21 18:56:11 +00:00
//[Obsolete]
//DeprecatedGroupMessage = 8,
2008-09-09 04:58:58 +00:00
/// <summary>An object is offering its inventory</summary>
TaskInventoryOffered = 9 ,
/// <summary>Accept an inventory offer from an object</summary>
TaskInventoryAccepted = 10 ,
/// <summary>Decline an inventory offer from an object</summary>
TaskInventoryDeclined = 11 ,
/// <summary>Unknown</summary>
NewUserDefault = 12 ,
/// <summary>Start a session, or add users to a session</summary>
SessionAdd = 13 ,
/// <summary>Start a session, but don't prune offline users</summary>
SessionOfflineAdd = 14 ,
/// <summary>Start a session with your group</summary>
SessionGroupStart = 15 ,
/// <summary>Start a session without a calling card (finder or objects)</summary>
SessionCardlessStart = 16 ,
/// <summary>Send a message to a session</summary>
SessionSend = 17 ,
/// <summary>Leave a session</summary>
SessionDrop = 18 ,
/// <summary>Indicates that the IM is from an object</summary>
MessageFromObject = 19 ,
/// <summary>Sent an IM to a busy user, this is the auto response</summary>
BusyAutoResponse = 20 ,
/// <summary>Shows the message in the console and chat history</summary>
ConsoleAndChatHistory = 21 ,
/// <summary>Send a teleport lure</summary>
RequestTeleport = 22 ,
2022-11-06 21:21:53 -06:00
/// <summary>Response sent to the agent who initiated a teleport invitation</summary>
2008-09-09 04:58:58 +00:00
AcceptTeleport = 23 ,
2022-11-06 21:21:53 -06:00
/// <summary>Response sent to the agent who initiated a teleport invitation</summary>
2008-09-09 04:58:58 +00:00
DenyTeleport = 24 ,
2022-11-06 21:21:53 -06:00
/// <summary>Forceful admin teleport</summary>
2008-09-09 04:58:58 +00:00
GodLikeRequestTeleport = 25 ,
2013-01-25 13:41:21 +01:00
/// <summary>Request a teleport lure</summary>
RequestLure = 26 ,
2008-09-09 04:58:58 +00:00
// <summary>Notification of a new group election, this is
// deprecated</summary>
2008-07-21 18:56:11 +00:00
//[Obsolete]
//DeprecatedGroupElection = 27,
2008-09-09 04:58:58 +00:00
/// <summary>IM to tell the user to go to an URL</summary>
GotoUrl = 28 ,
/// <summary>IM for help</summary>
Session911Start = 29 ,
/// <summary>IM sent automatically on call for help, sends a lure
/// to each Helper reached</summary>
Lure911 = 30 ,
/// <summary>Like an IM but won't go to email</summary>
FromTaskAsAlert = 31 ,
/// <summary>IM from a group officer to all group members</summary>
GroupNotice = 32 ,
/// <summary>Unknown</summary>
GroupNoticeInventoryAccepted = 33 ,
/// <summary>Unknown</summary>
GroupNoticeInventoryDeclined = 34 ,
/// <summary>Accept a group invitation</summary>
GroupInvitationAccept = 35 ,
/// <summary>Decline a group invitation</summary>
GroupInvitationDecline = 36 ,
/// <summary>Unknown</summary>
GroupNoticeRequested = 37 ,
/// <summary>An avatar is offering you friendship</summary>
FriendshipOffered = 38 ,
/// <summary>An avatar has accepted your friendship offer</summary>
FriendshipAccepted = 39 ,
/// <summary>An avatar has declined your friendship offer</summary>
FriendshipDeclined = 40 ,
/// <summary>Indicates that a user has started typing</summary>
StartTyping = 41 ,
/// <summary>Indicates that a user has stopped typing</summary>
StopTyping = 42
}
/// <summary>
/// Flag in Instant Messages, whether the IM should be delivered to
/// offline avatars as well
/// </summary>
public enum InstantMessageOnline
{
/// <summary>Only deliver to online avatars</summary>
Online = 0 ,
/// <summary>If the avatar is offline the message will be held until
/// they login next, and possibly forwarded to their e-mail account</summary>
Offline = 1
2007-08-22 18:16:38 +00:00
}
2008-09-09 04:58:58 +00:00
/// <summary>
/// Conversion type to denote Chat Packet types in an easier-to-understand format
/// </summary>
public enum ChatType : byte
{
/// <summary>Whisper (5m radius)</summary>
Whisper = 0 ,
/// <summary>Normal chat (10/20m radius), what the official viewer typically sends</summary>
Normal = 1 ,
/// <summary>Shouting! (100m radius)</summary>
Shout = 2 ,
// <summary>Say chat (10/20m radius) - The official viewer will
// print "[4:15] You say, hey" instead of "[4:15] You: hey"</summary>
2008-07-21 18:56:11 +00:00
//[Obsolete]
//Say = 3,
2008-09-09 04:58:58 +00:00
/// <summary>Event message when an Avatar has begun to type</summary>
StartTyping = 4 ,
/// <summary>Event message when an Avatar has stopped typing</summary>
StopTyping = 5 ,
2009-10-16 02:53:53 +00:00
/// <summary>Send the message to the debug channel</summary>
2008-09-09 04:58:58 +00:00
Debug = 6 ,
2008-06-02 17:12:14 +00:00
/// <summary>Event message when an object uses llOwnerSay</summary>
2009-03-02 22:49:25 +00:00
OwnerSay = 8 ,
2015-03-30 15:46:41 +02:00
/// <summary>Event message when an object uses llRegionSayTo</summary>
RegionSayTo = 9 ,
2009-03-02 22:49:25 +00:00
/// <summary>Special value to support llRegionSay, never sent to the client</summary>
2016-11-27 22:05:54 -06:00
RegionSay = byte . MaxValue ,
2008-09-09 04:58:58 +00:00
}
/// <summary>
/// Identifies the source of a chat message
/// </summary>
public enum ChatSourceType : byte
{
/// <summary>Chat from the grid or simulator</summary>
System = 0 ,
/// <summary>Chat from another avatar</summary>
Agent = 1 ,
/// <summary>Chat from an object</summary>
Object = 2
}
/// <summary>
///
/// </summary>
public enum ChatAudibleLevel : sbyte
{
/// <summary></summary>
Not = - 1 ,
/// <summary></summary>
Barely = 0 ,
/// <summary></summary>
Fully = 1
}
/// <summary>
/// Effect type used in ViewerEffect packets
/// </summary>
public enum EffectType : byte
{
/// <summary></summary>
Text = 0 ,
/// <summary></summary>
Icon ,
/// <summary></summary>
Connector ,
/// <summary></summary>
FlexibleObject ,
/// <summary></summary>
AnimalControls ,
/// <summary></summary>
AnimationObject ,
/// <summary></summary>
Cloth ,
/// <summary>Project a beam from a source to a destination, such as
/// the one used when editing an object</summary>
Beam ,
/// <summary></summary>
Glow ,
/// <summary></summary>
Point ,
/// <summary></summary>
Trail ,
/// <summary>Create a swirl of particles around an object</summary>
Sphere ,
/// <summary></summary>
Spiral ,
/// <summary></summary>
Edit ,
/// <summary>Cause an avatar to look at an object</summary>
LookAt ,
/// <summary>Cause an avatar to point at an object</summary>
PointAt
}
/// <summary>
/// The action an avatar is doing when looking at something, used in
/// ViewerEffect packets for the LookAt effect
/// </summary>
public enum LookAtType : byte
{
/// <summary></summary>
None ,
/// <summary></summary>
Idle ,
/// <summary></summary>
AutoListen ,
/// <summary></summary>
FreeLook ,
/// <summary></summary>
Respond ,
/// <summary></summary>
Hover ,
/// <summary>Deprecated</summary>
2007-09-05 01:21:36 +00:00
[Obsolete]
2008-09-09 04:58:58 +00:00
Conversation ,
/// <summary></summary>
Select ,
/// <summary></summary>
Focus ,
/// <summary></summary>
Mouselook ,
/// <summary></summary>
Clear
}
/// <summary>
/// The action an avatar is doing when pointing at something, used in
/// ViewerEffect packets for the PointAt effect
/// </summary>
public enum PointAtType : byte
{
/// <summary></summary>
None ,
/// <summary></summary>
Select ,
/// <summary></summary>
Grab ,
/// <summary></summary>
Clear
2007-08-22 18:16:38 +00:00
}
2008-03-14 07:11:13 +00:00
/// <summary>
/// Money transaction types
/// </summary>
2007-09-05 01:21:36 +00:00
public enum MoneyTransactionType : int
{
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
None = 0 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
FailSimulatorTimeout = 1 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
FailDataserverTimeout = 2 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
ObjectClaim = 1000 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
LandClaim = 1001 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
GroupCreate = 1002 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
ObjectPublicClaim = 1003 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
GroupJoin = 1004 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
TeleportCharge = 1100 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
UploadCharge = 1101 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
LandAuction = 1102 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
ClassifiedCharge = 1103 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
ObjectTax = 2000 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
LandTax = 2001 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
LightTax = 2002 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
ParcelDirFee = 2003 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
GroupTax = 2004 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
ClassifiedRenew = 2005 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
GiveInventory = 3000 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
ObjectSale = 5000 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
Gift = 5001 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
LandSale = 5002 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
ReferBonus = 5003 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
InventorySale = 5004 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
RefundPurchase = 5005 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
LandPassSale = 5006 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
DwellBonus = 5007 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
PayObject = 5008 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
ObjectPays = 5009 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
GroupLandDeed = 6001 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
GroupObjectDeed = 6002 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
GroupLiability = 6003 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
GroupDividend = 6004 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
GroupMembershipDues = 6005 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
ObjectRelease = 8000 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
LandRelease = 8001 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
ObjectDelete = 8002 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
ObjectPublicDecay = 8003 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
ObjectPublicDelete = 8004 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
LindenAdjustment = 9000 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
LindenGrant = 9001 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
LindenPenalty = 9002 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
EventFee = 9003 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
EventPrize = 9004 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
StipendBasic = 10000 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
StipendDeveloper = 10001 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
StipendAlways = 10002 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
StipendDaily = 10003 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
StipendRating = 10004 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
StipendDelta = 10005
}
2008-03-14 07:11:13 +00:00
/// <summary>
///
/// </summary>
2007-09-05 01:21:36 +00:00
[Flags]
public enum TransactionFlags : byte
{
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
None = 0 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
SourceGroup = 1 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
DestGroup = 2 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
OwnerGroup = 4 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
SimultaneousContribution = 8 ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-09-05 01:21:36 +00:00
ContributionRemoval = 16
}
2008-03-14 07:11:13 +00:00
/// <summary>
///
/// </summary>
2007-11-30 03:55:08 +00:00
public enum MeanCollisionType : byte
{
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-11-30 03:55:08 +00:00
None ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-11-30 03:55:08 +00:00
Bump ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-11-30 03:55:08 +00:00
LLPushObject ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-11-30 03:55:08 +00:00
SelectedObjectCollide ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-11-30 03:55:08 +00:00
ScriptedObjectCollide ,
2008-03-14 07:11:13 +00:00
/// <summary></summary>
2007-11-30 03:55:08 +00:00
PhysicalObjectCollide
}
2008-04-04 21:08:38 +00:00
/// <summary>
/// Flags sent when a script takes or releases a control
/// </summary>
/// <remarks>NOTE: (need to verify) These might be a subset of the ControlFlags enum in Movement,</remarks>
[Flags]
public enum ScriptControlChange : uint
{
/// <summary>No Flags set</summary>
None = 0 ,
/// <summary>Forward (W or up Arrow)</summary>
Forward = 1 ,
/// <summary>Back (S or down arrow)</summary>
Back = 2 ,
/// <summary>Move left (shift+A or left arrow)</summary>
Left = 4 ,
/// <summary>Move right (shift+D or right arrow)</summary>
Right = 8 ,
/// <summary>Up (E or PgUp)</summary>
Up = 16 ,
2009-10-16 02:53:53 +00:00
/// <summary>Down (C or PgDown)</summary>
2008-04-04 21:08:38 +00:00
Down = 32 ,
/// <summary>Rotate left (A or left arrow)</summary>
RotateLeft = 256 ,
/// <summary>Rotate right (D or right arrow)</summary>
RotateRight = 512 ,
/// <summary>Left Mouse Button</summary>
LeftButton = 268435456 ,
/// <summary>Left Mouse button in MouseLook</summary>
MouseLookLeftButton = 1073741824
}
2009-02-03 18:14:11 +00:00
/// <summary>
/// Currently only used to hide your group title
/// </summary>
[Flags]
public enum AgentFlags : byte
{
/// <summary>No flags set</summary>
None = 0 ,
/// <summary>Hide your group title</summary>
HideTitle = 0x01 ,
}
/// <summary>
/// Action state of the avatar, which can currently be typing and
/// editing
/// </summary>
[Flags]
public enum AgentState : byte
{
/// <summary></summary>
None = 0x00 ,
/// <summary></summary>
Typing = 0x04 ,
/// <summary></summary>
Editing = 0x10
}
/// <summary>
/// Current teleport status
/// </summary>
public enum TeleportStatus
{
/// <summary>Unknown status</summary>
None ,
/// <summary>Teleport initialized</summary>
Start ,
/// <summary>Teleport in progress</summary>
Progress ,
/// <summary>Teleport failed</summary>
Failed ,
/// <summary>Teleport completed</summary>
Finished ,
/// <summary>Teleport cancelled</summary>
Cancelled
}
/// <summary>
///
/// </summary>
[Flags]
public enum TeleportFlags : uint
{
/// <summary>No flags set, or teleport failed</summary>
Default = 0 ,
/// <summary>Set when newbie leaves help island for first time</summary>
SetHomeToTarget = 1 < < 0 ,
/// <summary></summary>
SetLastToTarget = 1 < < 1 ,
/// <summary>Via Lure</summary>
ViaLure = 1 < < 2 ,
/// <summary>Via Landmark</summary>
ViaLandmark = 1 < < 3 ,
/// <summary>Via Location</summary>
ViaLocation = 1 < < 4 ,
/// <summary>Via Home</summary>
ViaHome = 1 < < 5 ,
/// <summary>Via Telehub</summary>
ViaTelehub = 1 < < 6 ,
/// <summary>Via Login</summary>
ViaLogin = 1 < < 7 ,
/// <summary>Linden Summoned</summary>
ViaGodlikeLure = 1 < < 8 ,
/// <summary>Linden Forced me</summary>
Godlike = 1 < < 9 ,
/// <summary></summary>
NineOneOne = 1 < < 10 ,
/// <summary>Agent Teleported Home via Script</summary>
DisableCancel = 1 < < 11 ,
/// <summary></summary>
ViaRegionID = 1 < < 12 ,
/// <summary></summary>
IsFlying = 1 < < 13 ,
/// <summary></summary>
ResetHome = 1 < < 14 ,
/// <summary>forced to new location for example when avatar is banned or ejected</summary>
ForceRedirect = 1 < < 15 ,
/// <summary>Teleport Finished via a Lure</summary>
FinishedViaLure = 1 < < 26 ,
/// <summary>Finished, Sim Changed</summary>
FinishedViaNewSim = 1 < < 28 ,
/// <summary>Finished, Same Sim</summary>
FinishedViaSameSim = 1 < < 29
}
/// <summary>
///
/// </summary>
[Flags]
public enum TeleportLureFlags
{
/// <summary></summary>
NormalLure = 0 ,
/// <summary></summary>
GodlikeLure = 1 ,
/// <summary></summary>
GodlikePursuit = 2
}
/// <summary>
///
/// </summary>
[Flags]
public enum ScriptSensorTypeFlags
{
/// <summary></summary>
Agent = 1 ,
/// <summary></summary>
Active = 2 ,
/// <summary></summary>
Passive = 4 ,
/// <summary></summary>
Scripted = 8 ,
}
2011-03-05 23:48:49 +00:00
/// <summary>
/// Type of mute entry
/// </summary>
public enum MuteType
{
/// <summary>Object muted by name</summary>
ByName = 0 ,
2022-11-11 10:16:31 -06:00
/// <summary>Muted resident</summary>
2011-03-05 23:48:49 +00:00
Resident = 1 ,
/// <summary>Object muted by UUID</summary>
Object = 2 ,
/// <summary>Muted group</summary>
Group = 3 ,
/// <summary>Muted external entry</summary>
External = 4
}
/// <summary>
/// Flags of mute entry
/// </summary>
[Flags]
public enum MuteFlags : int
{
/// <summary>No exceptions</summary>
Default = 0x0 ,
/// <summary>Don't mute text chat</summary>
TextChat = 0x1 ,
/// <summary>Don't mute voice chat</summary>
VoiceChat = 0x2 ,
/// <summary>Don't mute particles</summary>
Particles = 0x4 ,
/// <summary>Don't mute sounds</summary>
ObjectSounds = 0x8 ,
/// <summary>Don't mute</summary>
All = 0xf
}
2007-08-22 18:16:38 +00:00
#endregion Enums
2008-09-09 04:58:58 +00:00
2007-08-22 18:16:38 +00:00
#region Structs
2008-09-09 04:58:58 +00:00
/// <summary>
/// Instant Message
/// </summary>
public struct InstantMessage
{
/// <summary>Key of sender</summary>
public UUID FromAgentID ;
/// <summary>Name of sender</summary>
2007-08-22 18:16:38 +00:00
public string FromAgentName ;
/// <summary>Key of destination avatar</summary>
2008-07-25 05:15:05 +00:00
public UUID ToAgentID ;
2007-08-22 18:16:38 +00:00
/// <summary>ID of originating estate</summary>
public uint ParentEstateID ;
/// <summary>Key of originating region</summary>
2008-07-25 05:15:05 +00:00
public UUID RegionID ;
2007-08-22 18:16:38 +00:00
/// <summary>Coordinates in originating region</summary>
2008-07-25 05:15:05 +00:00
public Vector3 Position ;
2007-08-22 18:16:38 +00:00
/// <summary>Instant message type</summary>
public InstantMessageDialog Dialog ;
/// <summary>Group IM session toggle</summary>
public bool GroupIM ;
2008-04-08 03:59:46 +00:00
/// <summary>Key of IM session, for Group Messages, the groups UUID</summary>
2008-07-25 05:15:05 +00:00
public UUID IMSessionID ;
2007-08-22 18:16:38 +00:00
/// <summary>Timestamp of the instant message</summary>
public DateTime Timestamp ;
/// <summary>Instant message text</summary>
public string Message ;
/// <summary>Whether this message is held for offline avatars</summary>
public InstantMessageOnline Offline ;
/// <summary>Context specific packed data</summary>
public byte [ ] BinaryBucket ;
2009-04-09 01:17:40 +00:00
2009-10-16 02:53:53 +00:00
/// <summary>Print the struct data as a string</summary>
/// <returns>A string containing the field name, and field value</returns>
2008-09-09 04:58:58 +00:00
public override string ToString ( )
{
2009-10-16 02:53:53 +00:00
return Helpers . StructToString ( this ) ;
2008-09-09 04:58:58 +00:00
}
}
2011-03-05 23:48:49 +00:00
/// <summary>Represents muted object or resident</summary>
public class MuteEntry
{
/// <summary>Type of the mute entry</summary>
public MuteType Type ;
/// <summary>UUID of the mute etnry</summary>
public UUID ID ;
/// <summary>Mute entry name</summary>
public string Name ;
/// <summary>Mute flags</summary>
public MuteFlags Flags ;
}
2011-05-11 10:11:11 +00:00
/// <summary>Transaction detail sent with MoneyBalanceReply message</summary>
public class TransactionInfo
{
/// <summary>Type of the transaction</summary>
public int TransactionType ; // FIXME: this should be an enum
/// <summary>UUID of the transaction source</summary>
public UUID SourceID ;
/// <summary>Is the transaction source a group</summary>
public bool IsSourceGroup ;
/// <summary>UUID of the transaction destination</summary>
public UUID DestID ;
/// <summary>Is transaction destination a group</summary>
public bool IsDestGroup ;
/// <summary>Transaction amount</summary>
public int Amount ;
/// <summary>Transaction description</summary>
public string ItemDescription ;
}
2008-09-09 04:58:58 +00:00
#endregion Structs
2007-03-09 20:26:07 +00:00
/// <summary>
2007-11-06 09:26:10 +00:00
/// Manager class for our own avatar
2007-03-09 20:26:07 +00:00
/// </summary>
2007-11-06 09:26:10 +00:00
public partial class AgentManager
2007-03-09 20:26:07 +00:00
{
2010-03-31 11:47:52 +00:00
#region Delegates
/// <summary>
/// Called once attachment resource usage information has been collected
/// </summary>
/// <param name="success">Indicates if operation was successfull</param>
/// <param name="info">Attachment resource usage information</param>
public delegate void AttachmentResourcesCallback ( bool success , AttachmentResourcesMessage info ) ;
#endregion Delegates
2009-10-16 02:53:53 +00:00
#region Event Delegates
2008-07-28 22:23:48 +00:00
2022-11-06 21:21:53 -06:00
/// <summary>The event subscribers. null if no subscribers</summary>
2009-10-16 02:53:53 +00:00
private EventHandler < ChatEventArgs > m_Chat ;
2007-03-09 20:26:07 +00:00
2009-10-16 02:53:53 +00:00
/// <summary>Raises the ChatFromSimulator event</summary>
/// <param name="e">A ChatEventArgs object containing the
/// data returned from the data server</param>
protected virtual void OnChat ( ChatEventArgs e )
{
EventHandler < ChatEventArgs > handler = m_Chat ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-16 02:53:53 +00:00
}
2007-03-09 20:26:07 +00:00
2009-10-16 02:53:53 +00:00
/// <summary>Thread sync lock object</summary>
private readonly object m_ChatLock = new object ( ) ;
2007-03-20 22:30:39 +00:00
2009-10-16 02:53:53 +00:00
/// <summary>Raised when a scripted object or agent within range sends a public message</summary>
public event EventHandler < ChatEventArgs > ChatFromSimulator
{
add { lock ( m_ChatLock ) { m_Chat + = value ; } }
remove { lock ( m_ChatLock ) { m_Chat - = value ; } }
}
2010-03-31 11:47:52 +00:00
2022-11-06 21:21:53 -06:00
/// <summary>The event subscribers. null if no subscribers</summary>
2009-10-16 02:53:53 +00:00
private EventHandler < ScriptDialogEventArgs > m_ScriptDialog ;
/// <summary>Raises the ScriptDialog event</summary>
2022-11-11 10:16:31 -06:00
/// <param name="e">A ScriptDialogEventArgs object containing the
2009-10-16 02:53:53 +00:00
/// data returned from the data server</param>
protected virtual void OnScriptDialog ( ScriptDialogEventArgs e )
{
EventHandler < ScriptDialogEventArgs > handler = m_ScriptDialog ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-16 02:53:53 +00:00
}
2008-01-20 23:08:13 +00:00
2009-10-16 02:53:53 +00:00
/// <summary>Thread sync lock object</summary>
private readonly object m_ScriptDialogLock = new object ( ) ;
/// <summary>Raised when a scripted object sends a dialog box containing possible
/// options an agent can respond to</summary>
public event EventHandler < ScriptDialogEventArgs > ScriptDialog
{
add { lock ( m_ScriptDialogLock ) { m_ScriptDialog + = value ; } }
remove { lock ( m_ScriptDialogLock ) { m_ScriptDialog - = value ; } }
}
2010-03-31 11:47:52 +00:00
2022-11-06 21:21:53 -06:00
/// <summary>The event subscribers. null if no subscribers</summary>
2009-10-16 02:53:53 +00:00
private EventHandler < ScriptQuestionEventArgs > m_ScriptQuestion ;
/// <summary>Raises the ScriptQuestion event</summary>
/// <param name="e">A ScriptQuestionEventArgs object containing the
/// data returned from the data server</param>
protected virtual void OnScriptQuestion ( ScriptQuestionEventArgs e )
{
EventHandler < ScriptQuestionEventArgs > handler = m_ScriptQuestion ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-16 02:53:53 +00:00
}
2007-03-09 20:26:07 +00:00
2009-10-16 02:53:53 +00:00
/// <summary>Thread sync lock object</summary>
private readonly object m_ScriptQuestionLock = new object ( ) ;
/// <summary>Raised when an object requests a change in the permissions an agent has permitted</summary>
public event EventHandler < ScriptQuestionEventArgs > ScriptQuestion
{
add { lock ( m_ScriptQuestionLock ) { m_ScriptQuestion + = value ; } }
remove { lock ( m_ScriptQuestionLock ) { m_ScriptQuestion - = value ; } }
2010-03-31 11:47:52 +00:00
}
2009-10-16 02:53:53 +00:00
2022-11-06 21:21:53 -06:00
/// <summary>The event subscribers. null if no subscribers</summary>
2009-10-16 02:53:53 +00:00
private EventHandler < LoadUrlEventArgs > m_LoadURL ;
/// <summary>Raises the LoadURL event</summary>
/// <param name="e">A LoadUrlEventArgs object containing the
/// data returned from the data server</param>
protected virtual void OnLoadURL ( LoadUrlEventArgs e )
{
EventHandler < LoadUrlEventArgs > handler = m_LoadURL ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-16 02:53:53 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_LoadUrlLock = new object ( ) ;
/// <summary>Raised when a script requests an agent open the specified URL</summary>
public event EventHandler < LoadUrlEventArgs > LoadURL
{
add { lock ( m_LoadUrlLock ) { m_LoadURL + = value ; } }
remove { lock ( m_LoadUrlLock ) { m_LoadURL - = value ; } }
}
2010-03-31 11:47:52 +00:00
2022-11-06 21:21:53 -06:00
/// <summary>The event subscribers. null if no subscribers</summary>
2009-10-23 05:08:11 +00:00
private EventHandler < BalanceEventArgs > m_Balance ;
2009-10-16 02:53:53 +00:00
/// <summary>Raises the MoneyBalance event</summary>
/// <param name="e">A BalanceEventArgs object containing the
/// data returned from the data server</param>
protected virtual void OnBalance ( BalanceEventArgs e )
{
EventHandler < BalanceEventArgs > handler = m_Balance ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-16 02:53:53 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_BalanceLock = new object ( ) ;
/// <summary>Raised when an agents currency balance is updated</summary>
public event EventHandler < BalanceEventArgs > MoneyBalance
{
add { lock ( m_BalanceLock ) { m_Balance + = value ; } }
remove { lock ( m_BalanceLock ) { m_Balance - = value ; } }
}
2010-03-31 11:47:52 +00:00
2022-11-06 21:21:53 -06:00
/// <summary>The event subscribers. null if no subscribers</summary>
2009-10-23 05:08:11 +00:00
private EventHandler < MoneyBalanceReplyEventArgs > m_MoneyBalance ;
2009-10-16 02:53:53 +00:00
/// <summary>Raises the MoneyBalanceReply event</summary>
/// <param name="e">A MoneyBalanceReplyEventArgs object containing the
/// data returned from the data server</param>
protected virtual void OnMoneyBalanceReply ( MoneyBalanceReplyEventArgs e )
{
EventHandler < MoneyBalanceReplyEventArgs > handler = m_MoneyBalance ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-16 02:53:53 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_MoneyBalanceReplyLock = new object ( ) ;
2007-03-09 20:26:07 +00:00
2009-10-16 02:53:53 +00:00
/// <summary>Raised when a transaction occurs involving currency such as a land purchase</summary>
public event EventHandler < MoneyBalanceReplyEventArgs > MoneyBalanceReply
{
add { lock ( m_MoneyBalanceReplyLock ) { m_MoneyBalance + = value ; } }
remove { lock ( m_MoneyBalanceReplyLock ) { m_MoneyBalance - = value ; } }
}
2010-03-31 11:47:52 +00:00
2022-11-06 21:21:53 -06:00
/// <summary>The event subscribers. null if no subscribers</summary>
2009-10-16 02:53:53 +00:00
private EventHandler < InstantMessageEventArgs > m_InstantMessage ;
2007-03-09 20:26:07 +00:00
2009-10-16 02:53:53 +00:00
/// <summary>Raises the IM event</summary>
/// <param name="e">A InstantMessageEventArgs object containing the
/// data returned from the data server</param>
protected virtual void OnInstantMessage ( InstantMessageEventArgs e )
{
EventHandler < InstantMessageEventArgs > handler = m_InstantMessage ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-16 02:53:53 +00:00
}
2007-03-09 20:26:07 +00:00
2009-10-16 02:53:53 +00:00
/// <summary>Thread sync lock object</summary>
private readonly object m_InstantMessageLock = new object ( ) ;
2023-01-27 21:05:14 -06:00
/// <summary>Raised when an ImprovedInstantMessage packet is received from the simulator, this is used for everything from
2009-10-16 02:53:53 +00:00
/// private messaging to friendship offers. The Dialog field defines what type of message has arrived</summary>
public event EventHandler < InstantMessageEventArgs > IM
{
add { lock ( m_InstantMessageLock ) { m_InstantMessage + = value ; } }
remove { lock ( m_InstantMessageLock ) { m_InstantMessage - = value ; } }
}
2010-03-31 11:47:52 +00:00
2022-11-06 21:21:53 -06:00
/// <summary>The event subscribers. null if no subscribers</summary>
2009-10-16 02:53:53 +00:00
private EventHandler < TeleportEventArgs > m_Teleport ;
/// <summary>Raises the TeleportProgress event</summary>
/// <param name="e">A TeleportEventArgs object containing the
/// data returned from the data server</param>
protected virtual void OnTeleport ( TeleportEventArgs e )
{
EventHandler < TeleportEventArgs > handler = m_Teleport ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-16 02:53:53 +00:00
}
2007-03-09 20:26:07 +00:00
2009-10-16 02:53:53 +00:00
/// <summary>Thread sync lock object</summary>
private readonly object m_TeleportLock = new object ( ) ;
/// <summary>Raised when an agent has requested a teleport to another location, or when responding to a lure. Raised multiple times
/// for each teleport indicating the progress of the request</summary>
public event EventHandler < TeleportEventArgs > TeleportProgress
{
add { lock ( m_TeleportLock ) { m_Teleport + = value ; } }
remove { lock ( m_TeleportLock ) { m_Teleport + = value ; } }
}
2010-03-31 11:47:52 +00:00
2022-11-06 21:21:53 -06:00
/// <summary>The event subscribers. null if no subscribers</summary>
2009-10-16 02:53:53 +00:00
private EventHandler < AgentDataReplyEventArgs > m_AgentData ;
/// <summary>Raises the AgentDataReply event</summary>
/// <param name="e">A AgentDataReplyEventArgs object containing the
/// data returned from the data server</param>
protected virtual void OnAgentData ( AgentDataReplyEventArgs e )
{
EventHandler < AgentDataReplyEventArgs > handler = m_AgentData ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-16 02:53:53 +00:00
}
2007-03-09 20:26:07 +00:00
2009-10-16 02:53:53 +00:00
/// <summary>Thread sync lock object</summary>
private readonly object m_AgentDataLock = new object ( ) ;
2007-04-27 23:47:45 +00:00
2009-10-16 02:53:53 +00:00
/// <summary>Raised when a simulator sends agent specific information for our avatar.</summary>
public event EventHandler < AgentDataReplyEventArgs > AgentDataReply
{
add { lock ( m_AgentDataLock ) { m_AgentData + = value ; } }
remove { lock ( m_AgentDataLock ) { m_AgentData - = value ; } }
}
2022-11-06 21:21:53 -06:00
/// <summary>The event subscribers. null if no subscribers</summary>
2009-10-16 02:53:53 +00:00
private EventHandler < AnimationsChangedEventArgs > m_AnimationsChanged ;
/// <summary>Raises the AnimationsChanged event</summary>
/// <param name="e">A AnimationsChangedEventArgs object containing the
/// data returned from the data server</param>
protected virtual void OnAnimationsChanged ( AnimationsChangedEventArgs e )
{
EventHandler < AnimationsChangedEventArgs > handler = m_AnimationsChanged ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-16 02:53:53 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_AnimationsChangedLock = new object ( ) ;
/// <summary>Raised when our agents animation playlist changes</summary>
public event EventHandler < AnimationsChangedEventArgs > AnimationsChanged
{
add { lock ( m_AnimationsChangedLock ) { m_AnimationsChanged + = value ; } }
remove { lock ( m_AnimationsChangedLock ) { m_AnimationsChanged - = value ; } }
2010-03-31 11:47:52 +00:00
}
2009-10-16 02:53:53 +00:00
2022-11-06 21:21:53 -06:00
/// <summary>The event subscribers. null if no subscribers</summary>
2009-10-16 02:53:53 +00:00
private EventHandler < MeanCollisionEventArgs > m_MeanCollision ;
/// <summary>Raises the MeanCollision event</summary>
/// <param name="e">A MeanCollisionEventArgs object containing the
/// data returned from the data server</param>
protected virtual void OnMeanCollision ( MeanCollisionEventArgs e )
{
EventHandler < MeanCollisionEventArgs > handler = m_MeanCollision ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-16 02:53:53 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_MeanCollisionLock = new object ( ) ;
/// <summary>Raised when an object or avatar forcefully collides with our agent</summary>
public event EventHandler < MeanCollisionEventArgs > MeanCollision
{
add { lock ( m_MeanCollisionLock ) { m_MeanCollision + = value ; } }
remove { lock ( m_MeanCollisionLock ) { m_MeanCollision - = value ; } }
2010-03-31 11:47:52 +00:00
}
2009-10-16 02:53:53 +00:00
2022-11-06 21:21:53 -06:00
/// <summary>The event subscribers. null if no subscribers</summary>
2009-10-16 02:53:53 +00:00
private EventHandler < RegionCrossedEventArgs > m_RegionCrossed ;
2007-12-29 22:34:11 +00:00
2009-10-16 02:53:53 +00:00
/// <summary>Raises the RegionCrossed event</summary>
/// <param name="e">A RegionCrossedEventArgs object containing the
/// data returned from the data server</param>
protected virtual void OnRegionCrossed ( RegionCrossedEventArgs e )
{
EventHandler < RegionCrossedEventArgs > handler = m_RegionCrossed ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-16 02:53:53 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_RegionCrossedLock = new object ( ) ;
/// <summary>Raised when our agent crosses a region border into another region</summary>
public event EventHandler < RegionCrossedEventArgs > RegionCrossed
{
add { lock ( m_RegionCrossedLock ) { m_RegionCrossed + = value ; } }
remove { lock ( m_RegionCrossedLock ) { m_RegionCrossed - = value ; } }
}
2010-03-31 11:47:52 +00:00
2022-11-06 21:21:53 -06:00
/// <summary>The event subscribers. null if no subscribers</summary>
2009-10-16 02:53:53 +00:00
private EventHandler < GroupChatJoinedEventArgs > m_GroupChatJoined ;
/// <summary>Raises the GroupChatJoined event</summary>
/// <param name="e">A GroupChatJoinedEventArgs object containing the
/// data returned from the data server</param>
protected virtual void OnGroupChatJoined ( GroupChatJoinedEventArgs e )
{
EventHandler < GroupChatJoinedEventArgs > handler = m_GroupChatJoined ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-16 02:53:53 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_GroupChatJoinedLock = new object ( ) ;
/// <summary>Raised when our agent succeeds or fails to join a group chat session</summary>
public event EventHandler < GroupChatJoinedEventArgs > GroupChatJoined
{
add { lock ( m_GroupChatJoinedLock ) { m_GroupChatJoined + = value ; } }
remove { lock ( m_GroupChatJoinedLock ) { m_GroupChatJoined - = value ; } }
2010-03-31 11:47:52 +00:00
}
2008-01-05 23:06:19 +00:00
2021-09-09 17:49:06 -05:00
/// <summary>The event subscribers. null if no subscribers</summary>
2009-10-16 02:53:53 +00:00
private EventHandler < AlertMessageEventArgs > m_AlertMessage ;
/// <summary>Raises the AlertMessage event</summary>
/// <param name="e">A AlertMessageEventArgs object containing the
/// data returned from the data server</param>
protected virtual void OnAlertMessage ( AlertMessageEventArgs e )
{
EventHandler < AlertMessageEventArgs > handler = m_AlertMessage ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-16 02:53:53 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_AlertMessageLock = new object ( ) ;
/// <summary>Raised when a simulator sends an urgent message usually indication the recent failure of
/// another action we have attempted to take such as an attempt to enter a parcel where we are denied access</summary>
public event EventHandler < AlertMessageEventArgs > AlertMessage
{
add { lock ( m_AlertMessageLock ) { m_AlertMessage + = value ; } }
remove { lock ( m_AlertMessageLock ) { m_AlertMessage - = value ; } }
2010-03-31 11:47:52 +00:00
}
2009-10-16 02:53:53 +00:00
2022-11-06 21:21:53 -06:00
/// <summary>The event subscribers. null if no subscribers</summary>
2009-10-16 02:53:53 +00:00
private EventHandler < ScriptControlEventArgs > m_ScriptControl ;
/// <summary>Raises the ScriptControlChange event</summary>
/// <param name="e">A ScriptControlEventArgs object containing the
/// data returned from the data server</param>
protected virtual void OnScriptControlChange ( ScriptControlEventArgs e )
{
EventHandler < ScriptControlEventArgs > handler = m_ScriptControl ;
2016-09-25 19:52:04 -05:00
handler ? . Invoke ( this , e ) ;
2009-10-16 02:53:53 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_ScriptControlLock = new object ( ) ;
/// <summary>Raised when a script attempts to take or release specified controls for our agent</summary>
public event EventHandler < ScriptControlEventArgs > ScriptControlChange
{
add { lock ( m_ScriptControlLock ) { m_ScriptControl + = value ; } }
remove { lock ( m_ScriptControlLock ) { m_ScriptControl - = value ; } }
}
2010-03-31 11:47:52 +00:00
2022-11-06 21:21:53 -06:00
/// <summary>The event subscribers. null if no subscribers</summary>
2009-10-16 02:53:53 +00:00
private EventHandler < CameraConstraintEventArgs > m_CameraConstraint ;
/// <summary>Raises the CameraConstraint event</summary>
/// <param name="e">A CameraConstraintEventArgs object containing the
/// data returned from the data server</param>
protected virtual void OnCameraConstraint ( CameraConstraintEventArgs e )
{
EventHandler < CameraConstraintEventArgs > handler = m_CameraConstraint ;
2023-01-27 21:07:39 -06:00
handler ? . Invoke ( this , e ) ;
2009-10-16 02:53:53 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_CameraConstraintLock = new object ( ) ;
/// <summary>Raised when the simulator detects our agent is trying to view something
/// beyond its limits</summary>
public event EventHandler < CameraConstraintEventArgs > CameraConstraint
{
add { lock ( m_CameraConstraintLock ) { m_CameraConstraint + = value ; } }
remove { lock ( m_CameraConstraintLock ) { m_CameraConstraint - = value ; } }
}
2010-03-31 11:47:52 +00:00
2022-11-06 21:21:53 -06:00
/// <summary>The event subscribers. null if no subscribers</summary>
2009-10-23 05:08:11 +00:00
private EventHandler < ScriptSensorReplyEventArgs > m_ScriptSensorReply ;
2009-10-16 02:53:53 +00:00
/// <summary>Raises the ScriptSensorReply event</summary>
/// <param name="e">A ScriptSensorReplyEventArgs object containing the
/// data returned from the data server</param>
protected virtual void OnScriptSensorReply ( ScriptSensorReplyEventArgs e )
{
EventHandler < ScriptSensorReplyEventArgs > handler = m_ScriptSensorReply ;
2023-01-27 21:07:39 -06:00
handler ? . Invoke ( this , e ) ;
2009-10-16 02:53:53 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_ScriptSensorReplyLock = new object ( ) ;
/// <summary>Raised when a script sensor reply is received from a simulator</summary>
public event EventHandler < ScriptSensorReplyEventArgs > ScriptSensorReply
{
add { lock ( m_ScriptSensorReplyLock ) { m_ScriptSensorReply + = value ; } }
remove { lock ( m_ScriptSensorReplyLock ) { m_ScriptSensorReply - = value ; } }
2010-03-31 11:47:52 +00:00
}
2009-10-16 02:53:53 +00:00
2022-11-06 21:21:53 -06:00
/// <summary>The event subscribers. null if no subscribers</summary>
2009-10-16 02:53:53 +00:00
private EventHandler < AvatarSitResponseEventArgs > m_AvatarSitResponse ;
/// <summary>Raises the AvatarSitResponse event</summary>
/// <param name="e">A AvatarSitResponseEventArgs object containing the
/// data returned from the data server</param>
protected virtual void OnAvatarSitResponse ( AvatarSitResponseEventArgs e )
{
EventHandler < AvatarSitResponseEventArgs > handler = m_AvatarSitResponse ;
2023-01-27 21:07:39 -06:00
handler ? . Invoke ( this , e ) ;
2009-10-16 02:53:53 +00:00
}
2008-04-07 22:09:40 +00:00
2009-10-16 02:53:53 +00:00
/// <summary>Thread sync lock object</summary>
private readonly object m_AvatarSitResponseLock = new object ( ) ;
/// <summary>Raised in response to a <see cref="RequestSit"/> request</summary>
public event EventHandler < AvatarSitResponseEventArgs > AvatarSitResponse
{
add { lock ( m_AvatarSitResponseLock ) { m_AvatarSitResponse + = value ; } }
remove { lock ( m_AvatarSitResponseLock ) { m_AvatarSitResponse - = value ; } }
2010-03-31 11:47:52 +00:00
}
2009-10-16 02:53:53 +00:00
2022-11-06 21:21:53 -06:00
/// <summary>The event subscribers. null if no subscribers</summary>
2009-10-16 02:53:53 +00:00
private EventHandler < ChatSessionMemberAddedEventArgs > m_ChatSessionMemberAdded ;
/// <summary>Raises the ChatSessionMemberAdded event</summary>
/// <param name="e">A ChatSessionMemberAddedEventArgs object containing the
/// data returned from the data server</param>
protected virtual void OnChatSessionMemberAdded ( ChatSessionMemberAddedEventArgs e )
{
EventHandler < ChatSessionMemberAddedEventArgs > handler = m_ChatSessionMemberAdded ;
2016-11-27 22:05:54 -06:00
handler ? . Invoke ( this , e ) ;
2009-10-16 02:53:53 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_ChatSessionMemberAddedLock = new object ( ) ;
/// <summary>Raised when an avatar enters a group chat session we are participating in</summary>
public event EventHandler < ChatSessionMemberAddedEventArgs > ChatSessionMemberAdded
{
add { lock ( m_ChatSessionMemberAddedLock ) { m_ChatSessionMemberAdded + = value ; } }
remove { lock ( m_ChatSessionMemberAddedLock ) { m_ChatSessionMemberAdded - = value ; } }
2010-03-31 11:47:52 +00:00
}
2008-09-09 04:58:58 +00:00
2022-11-06 21:21:53 -06:00
/// <summary>The event subscribers. null if no subscribers</summary>
2009-10-16 02:53:53 +00:00
private EventHandler < ChatSessionMemberLeftEventArgs > m_ChatSessionMemberLeft ;
/// <summary>Raises the ChatSessionMemberLeft event</summary>
/// <param name="e">A ChatSessionMemberLeftEventArgs object containing the
/// data returned from the data server</param>
protected virtual void OnChatSessionMemberLeft ( ChatSessionMemberLeftEventArgs e )
{
EventHandler < ChatSessionMemberLeftEventArgs > handler = m_ChatSessionMemberLeft ;
2016-11-27 22:05:54 -06:00
handler ? . Invoke ( this , e ) ;
2009-10-16 02:53:53 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_ChatSessionMemberLeftLock = new object ( ) ;
/// <summary>Raised when an agent exits a group chat session we are participating in</summary>
public event EventHandler < ChatSessionMemberLeftEventArgs > ChatSessionMemberLeft
{
add { lock ( m_ChatSessionMemberLeftLock ) { m_ChatSessionMemberLeft + = value ; } }
remove { lock ( m_ChatSessionMemberLeftLock ) { m_ChatSessionMemberLeft - = value ; } }
}
2008-07-28 08:28:16 +00:00
2022-11-14 18:48:49 -06:00
/// <summary>The event subscribers, null if no subscribers</summary>
2010-11-20 13:46:21 +00:00
private EventHandler < SetDisplayNameReplyEventArgs > m_SetDisplayNameReply ;
///<summary>Raises the SetDisplayNameReply Event</summary>
/// <param name="e">A SetDisplayNameReplyEventArgs object containing
/// the data sent from the simulator</param>
protected virtual void OnSetDisplayNameReply ( SetDisplayNameReplyEventArgs e )
{
EventHandler < SetDisplayNameReplyEventArgs > handler = m_SetDisplayNameReply ;
2016-11-27 22:05:54 -06:00
handler ? . Invoke ( this , e ) ;
2010-11-20 13:46:21 +00:00
}
2008-04-09 19:22:17 +00:00
2010-11-20 13:46:21 +00:00
/// <summary>Thread sync lock object</summary>
private readonly object m_SetDisplayNameReplyLock = new object ( ) ;
/// <summary>Raised when the simulator sends us data containing
/// the details of display name change</summary>
public event EventHandler < SetDisplayNameReplyEventArgs > SetDisplayNameReply
{
add { lock ( m_SetDisplayNameReplyLock ) { m_SetDisplayNameReply + = value ; } }
remove { lock ( m_SetDisplayNameReplyLock ) { m_SetDisplayNameReply - = value ; } }
}
2011-03-05 23:48:49 +00:00
2022-11-06 21:21:53 -06:00
/// <summary>The event subscribers. null if no subscribers</summary>
2011-03-05 23:48:49 +00:00
private EventHandler < EventArgs > m_MuteListUpdated ;
/// <summary>Raises the MuteListUpdated event</summary>
/// <param name="e">A EventArgs object containing the
/// data returned from the data server</param>
protected virtual void OnMuteListUpdated ( EventArgs e )
{
EventHandler < EventArgs > handler = m_MuteListUpdated ;
2016-11-27 22:05:54 -06:00
handler ? . Invoke ( this , e ) ;
2011-03-05 23:48:49 +00:00
}
/// <summary>Thread sync lock object</summary>
private readonly object m_MuteListUpdatedLock = new object ( ) ;
/// <summary>Raised when a scripted object or agent within range sends a public message</summary>
public event EventHandler < EventArgs > MuteListUpdated
{
add { lock ( m_MuteListUpdatedLock ) { m_MuteListUpdated + = value ; } }
remove { lock ( m_MuteListUpdatedLock ) { m_MuteListUpdated - = value ; } }
}
2010-11-20 13:46:21 +00:00
#endregion Callbacks
2007-03-09 20:26:07 +00:00
2009-04-29 18:33:46 +00:00
/// <summary>Reference to the GridClient instance</summary>
2009-10-16 02:53:53 +00:00
private readonly GridClient Client ;
2007-11-06 09:26:10 +00:00
/// <summary>Used for movement and camera tracking</summary>
public readonly AgentMovement Movement ;
2007-11-30 03:55:08 +00:00
/// <summary>Currently playing animations for the agent. Can be used to
/// check the current movement status such as walking, hovering, aiming,
2009-10-16 02:53:53 +00:00
/// etc. by checking against system animations found in the Animations class</summary>
2008-07-25 05:15:05 +00:00
public InternalDictionary < UUID , int > SignaledAnimations = new InternalDictionary < UUID , int > ( ) ;
2009-04-29 18:33:46 +00:00
/// <summary>Dictionary containing current Group Chat sessions and members</summary>
2008-09-09 04:58:58 +00:00
public InternalDictionary < UUID , List < ChatSessionMember > > GroupChatSessions = new InternalDictionary < UUID , List < ChatSessionMember > > ( ) ;
2022-11-11 10:16:31 -06:00
/// <summary>Dictionary containing mute list keyed on mute name and key</summary>
2011-03-05 23:48:49 +00:00
public InternalDictionary < string , MuteEntry > MuteList = new InternalDictionary < string , MuteEntry > ( ) ;
2017-07-08 16:10:45 -04:00
public InternalDictionary < UUID , UUID > ActiveGestures { get ; } = new InternalDictionary < UUID , UUID > ( ) ;
2007-08-10 20:16:19 +00:00
2007-11-06 09:26:10 +00:00
#region Properties
2007-08-10 20:16:19 +00:00
2009-10-16 02:53:53 +00:00
/// <summary>Your (client) avatars <see cref="UUID"/></summary>
2008-03-14 07:11:13 +00:00
/// <remarks>"client", "agent", and "avatar" all represent the same thing</remarks>
2021-12-09 14:21:48 -06:00
public UUID AgentID { get ; private set ; }
2016-11-27 22:05:54 -06:00
2008-07-28 08:28:16 +00:00
/// <summary>Temporary <seealso cref="UUID"/> assigned to this session, used for
2007-11-06 09:26:10 +00:00
/// verifying our identity in packets</summary>
2021-12-09 14:21:48 -06:00
public UUID SessionID { get ; private set ; }
2016-11-27 22:05:54 -06:00
2008-07-28 08:28:16 +00:00
/// <summary>Shared secret <seealso cref="UUID"/> that is never sent over the wire</summary>
2021-12-09 14:21:48 -06:00
public UUID SecureSessionID { get ; private set ; }
2016-11-27 22:05:54 -06:00
2007-03-09 20:26:07 +00:00
/// <summary>Your (client) avatar ID, local to the current region/sim</summary>
2016-11-27 22:05:54 -06:00
public uint LocalID = > localID ;
2007-04-02 04:37:15 +00:00
/// <summary>Where the avatar started at login. Can be "last", "home"
2008-07-21 21:12:59 +00:00
/// or a login <seealso cref="T:OpenMetaverse.URI"/></summary>
2021-12-09 14:21:48 -06:00
public string StartLocation { get ; private set ; } = string . Empty ;
2016-11-27 22:05:54 -06:00
2014-03-05 00:19:15 +01:00
/// <summary>The access level of this agent, usually M, PG or A</summary>
2021-12-09 14:21:48 -06:00
public string AgentAccess { get ; private set ; } = string . Empty ;
2016-11-27 22:05:54 -06:00
2008-07-28 08:28:16 +00:00
/// <summary>The CollisionPlane of Agent</summary>
2016-11-27 22:05:54 -06:00
public Vector4 CollisionPlane = > collisionPlane ;
2008-07-28 08:28:16 +00:00
/// <summary>An <seealso cref="Vector3"/> representing the velocity of our agent</summary>
2016-11-27 22:05:54 -06:00
public Vector3 Velocity = > velocity ;
2008-07-28 08:28:16 +00:00
/// <summary>An <seealso cref="Vector3"/> representing the acceleration of our agent</summary>
2016-11-27 22:05:54 -06:00
public Vector3 Acceleration = > acceleration ;
2008-07-28 08:28:16 +00:00
/// <summary>A <seealso cref="Vector3"/> which specifies the angular speed, and axis about which an Avatar is rotating.</summary>
2016-11-27 22:05:54 -06:00
public Vector3 AngularVelocity = > angularVelocity ;
2021-12-06 14:52:03 -06:00
/// <summary>Region handle for 'home' region</summary>
public ulong HomeRegionHandle = > home . RegionHandle ;
2007-03-09 20:26:07 +00:00
/// <summary>Position avatar client will goto when login to 'home' or during
/// teleport request to 'home' region.</summary>
2021-12-06 14:52:03 -06:00
public Vector3 HomePosition = > home . Position ;
2016-11-27 22:05:54 -06:00
2007-03-09 20:26:07 +00:00
/// <summary>LookAt point saved/restored with HomePosition</summary>
2021-12-06 14:52:03 -06:00
public Vector3 HomeLookAt = > home . LookAt ;
2016-11-27 22:05:54 -06:00
2007-08-10 20:16:19 +00:00
/// <summary>Avatar First Name (i.e. Philip)</summary>
2021-12-09 14:21:48 -06:00
public string FirstName { get ; private set ; } = string . Empty ;
2016-11-27 22:05:54 -06:00
2007-08-10 20:16:19 +00:00
/// <summary>Avatar Last Name (i.e. Linden)</summary>
2021-12-09 14:21:48 -06:00
public string LastName { get ; private set ; } = string . Empty ;
2016-11-27 22:05:54 -06:00
2013-09-16 15:30:17 +02:00
/// <summary>LookAt point received with the login response message</summary>
2021-12-09 14:21:48 -06:00
public Vector3 LookAt { get ; private set ; }
2016-11-27 22:05:54 -06:00
2007-08-29 08:55:53 +00:00
/// <summary>Avatar Full Name (i.e. Philip Linden)</summary>
public string Name
{
get
{
// This is a fairly common request, so assume the name doesn't
// change mid-session and cache the result
2008-05-06 23:57:26 +00:00
if ( fullName = = null | | fullName . Length < 2 )
2021-12-09 14:21:48 -06:00
fullName = $"{FirstName} {LastName}" ;
2007-08-29 08:55:53 +00:00
return fullName ;
}
}
2007-03-09 20:26:07 +00:00
/// <summary>Gets the health of the agent</summary>
2021-12-09 14:21:48 -06:00
public float Health { get ; private set ; }
2016-11-27 22:05:54 -06:00
2007-03-09 20:26:07 +00:00
/// <summary>Gets the current balance of the agent</summary>
2021-12-09 14:21:48 -06:00
public int Balance { get ; private set ; }
2016-11-27 22:05:54 -06:00
2008-03-14 07:11:13 +00:00
/// <summary>Gets the local ID of the prim the agent is sitting on,
2007-03-09 20:26:07 +00:00
/// zero if the avatar is not currently sitting</summary>
2016-11-27 22:05:54 -06:00
public uint SittingOn = > sittingOn ;
2008-07-28 08:28:16 +00:00
/// <summary>Gets the <seealso cref="UUID"/> of the agents active group.</summary>
2021-12-09 14:21:48 -06:00
public UUID ActiveGroup { get ; private set ; }
2016-11-27 22:05:54 -06:00
2008-09-14 08:12:51 +00:00
/// <summary>Gets the Agents powers in the currently active group</summary>
2021-12-09 14:21:48 -06:00
public GroupPowers ActiveGroupPowers { get ; private set ; }
2016-11-27 22:05:54 -06:00
2007-04-15 07:37:53 +00:00
/// <summary>Current status message for teleporting</summary>
2021-12-09 14:21:48 -06:00
public string TeleportMessage { get ; private set ; } = string . Empty ;
2016-11-27 22:05:54 -06:00
2007-11-06 09:26:10 +00:00
/// <summary>Current position of the agent as a relative offset from
/// the simulator, or the parent object if we are sitting on something</summary>
2022-11-06 21:21:53 -06:00
public Vector3 RelativePosition { get = > relativePosition ;
set = > relativePosition = value ;
}
2007-11-06 09:26:10 +00:00
/// <summary>Current rotation of the agent as a relative rotation from
/// the simulator, or the parent object if we are sitting on something</summary>
2022-11-06 21:21:53 -06:00
public Quaternion RelativeRotation { get = > relativeRotation ;
set = > relativeRotation = value ;
}
2008-03-14 07:11:13 +00:00
/// <summary>Current position of the agent in the simulator</summary>
2008-07-25 05:15:05 +00:00
public Vector3 SimPosition
2007-11-06 09:26:10 +00:00
{
get
{
2010-06-29 13:36:52 +00:00
// simple case, agent not seated
if ( sittingOn = = 0 )
2007-11-06 09:26:10 +00:00
{
2010-06-29 13:36:52 +00:00
return relativePosition ;
}
2022-11-11 10:16:31 -06:00
// a bit more complicated, agent sitting on a prim
2016-11-27 22:05:54 -06:00
Primitive p ;
2010-06-29 13:36:52 +00:00
Vector3 fullPosition = relativePosition ;
2010-07-25 20:32:43 +00:00
if ( Client . Network . CurrentSim . ObjectsPrimitives . TryGetValue ( sittingOn , out p ) )
{
2011-08-11 12:46:03 +00:00
fullPosition = p . Position + relativePosition * p . Rotation ;
2010-07-25 20:32:43 +00:00
}
2010-06-29 13:36:52 +00:00
2022-11-11 10:16:31 -06:00
// go up the hierarchy trying to find the root prim
2010-06-29 13:36:52 +00:00
while ( p ! = null & & p . ParentID ! = 0 )
{
Avatar av ;
if ( Client . Network . CurrentSim . ObjectsAvatars . TryGetValue ( p . ParentID , out av ) )
2007-11-06 09:26:10 +00:00
{
2010-06-29 13:36:52 +00:00
p = av ;
fullPosition + = p . Position ;
2007-11-06 09:26:10 +00:00
}
else
{
2010-06-29 13:36:52 +00:00
if ( Client . Network . CurrentSim . ObjectsPrimitives . TryGetValue ( p . ParentID , out p ) )
{
fullPosition + = p . Position ;
}
2007-11-06 09:26:10 +00:00
}
}
2010-06-29 13:36:52 +00:00
if ( p ! = null ) // we found the root prim
2007-11-06 09:26:10 +00:00
{
2010-06-29 13:36:52 +00:00
return fullPosition ;
2007-11-06 09:26:10 +00:00
}
2010-06-29 13:36:52 +00:00
2022-11-11 10:16:31 -06:00
// Didn't find the seat's root prim, try returning coarse location
2010-06-29 13:36:52 +00:00
if ( Client . Network . CurrentSim . avatarPositions . TryGetValue ( AgentID , out fullPosition ) )
{
return fullPosition ;
}
2022-11-11 10:16:31 -06:00
Logger . Log ( "Failed to determine agent sim position" , Helpers . LogLevel . Warning , Client ) ;
2010-06-29 13:36:52 +00:00
return relativePosition ;
2007-11-06 09:26:10 +00:00
}
}
2008-03-14 07:11:13 +00:00
/// <summary>
2008-07-28 08:28:16 +00:00
/// A <seealso cref="Quaternion"/> representing the agents current rotation
2008-03-14 07:11:13 +00:00
/// </summary>
2008-07-25 05:15:05 +00:00
public Quaternion SimRotation
2007-11-06 09:26:10 +00:00
{
get
{
if ( sittingOn ! = 0 )
{
Primitive parent ;
2008-01-03 21:55:49 +00:00
if ( Client . Network . CurrentSim ! = null & & Client . Network . CurrentSim . ObjectsPrimitives . TryGetValue ( sittingOn , out parent ) )
2007-11-06 09:26:10 +00:00
{
return relativeRotation * parent . Rotation ;
}
2016-11-27 22:05:54 -06:00
Logger . Log (
$"Currently sitting on object {sittingOn} which is not tracked, SimRotation will be inaccurate" ,
Helpers . LogLevel . Warning , Client ) ;
2007-11-06 09:26:10 +00:00
return relativeRotation ;
}
2016-11-27 22:05:54 -06:00
return relativeRotation ;
2007-11-06 09:26:10 +00:00
}
}
2007-08-23 17:41:57 +00:00
/// <summary>Returns the global grid position of the avatar</summary>
2008-07-25 05:15:05 +00:00
public Vector3d GlobalPosition
2007-08-23 17:41:57 +00:00
{
get
{
if ( Client . Network . CurrentSim ! = null )
{
uint globalX , globalY ;
2008-10-06 22:34:38 +00:00
Utils . LongToUInts ( Client . Network . CurrentSim . Handle , out globalX , out globalY ) ;
2008-07-25 05:15:05 +00:00
Vector3 pos = SimPosition ;
2007-11-06 09:26:10 +00:00
2008-07-25 05:15:05 +00:00
return new Vector3d (
2016-11-27 22:05:54 -06:00
globalX + pos . X ,
globalY + pos . Y ,
pos . Z ) ;
2007-08-23 17:41:57 +00:00
}
2016-11-27 22:05:54 -06:00
return Vector3d . Zero ;
2007-08-23 17:41:57 +00:00
}
}
2007-03-09 20:26:07 +00:00
2013-02-16 07:05:16 +01:00
/// <summary>Various abilities and preferences sent by the grid</summary>
public AgentStateUpdateMessage AgentStateStatus ;
2007-11-06 09:26:10 +00:00
#endregion Properties
2007-03-09 20:26:07 +00:00
2007-11-06 09:26:10 +00:00
internal uint localID ;
2008-07-25 05:15:05 +00:00
internal Vector3 relativePosition ;
internal Quaternion relativeRotation = Quaternion . Identity ;
internal Vector4 collisionPlane ;
internal Vector3 velocity ;
internal Vector3 acceleration ;
internal Vector3 angularVelocity ;
2007-11-06 09:26:10 +00:00
internal uint sittingOn ;
internal int lastInterpolation ;
#region Private Members
2021-12-06 14:52:03 -06:00
private HomeInfo home ;
2007-08-29 08:55:53 +00:00
private string fullName ;
2007-11-06 09:26:10 +00:00
private TeleportStatus teleportStat = TeleportStatus . None ;
private ManualResetEvent teleportEvent = new ManualResetEvent ( false ) ;
private uint heightWidthGenCounter ;
2009-07-12 16:44:07 +00:00
private Dictionary < UUID , AssetGesture > gestureCache = new Dictionary < UUID , AssetGesture > ( ) ;
2007-11-06 09:26:10 +00:00
#endregion Private Members
2007-03-09 20:26:07 +00:00
/// <summary>
/// Constructor, setup callbacks for packets related to our avatar
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="client">A reference to the <seealso cref="T:OpenMetaverse.GridClient"/> Class</param>
public AgentManager ( GridClient client )
2007-03-09 20:26:07 +00:00
{
Client = client ;
2009-10-16 02:53:53 +00:00
2007-11-06 09:26:10 +00:00
Movement = new AgentMovement ( Client ) ;
2010-03-31 11:47:52 +00:00
2009-10-28 08:01:52 +00:00
Client . Network . Disconnected + = Network_OnDisconnected ;
2007-08-29 08:55:53 +00:00
2009-10-16 02:53:53 +00:00
// Teleport callbacks
Client . Network . RegisterCallback ( PacketType . TeleportStart , TeleportHandler ) ;
Client . Network . RegisterCallback ( PacketType . TeleportProgress , TeleportHandler ) ;
Client . Network . RegisterCallback ( PacketType . TeleportFailed , TeleportHandler ) ;
Client . Network . RegisterCallback ( PacketType . TeleportCancel , TeleportHandler ) ;
Client . Network . RegisterCallback ( PacketType . TeleportLocal , TeleportHandler ) ;
2009-04-29 18:33:46 +00:00
// these come in via the EventQueue
Client . Network . RegisterEventCallback ( "TeleportFailed" , new Caps . EventQueueCallback ( TeleportFailedEventHandler ) ) ;
Client . Network . RegisterEventCallback ( "TeleportFinish" , new Caps . EventQueueCallback ( TeleportFinishEventHandler ) ) ;
2007-03-09 20:26:07 +00:00
2007-11-29 01:28:41 +00:00
// Instant message callback
2009-10-28 08:01:52 +00:00
Client . Network . RegisterCallback ( PacketType . ImprovedInstantMessage , InstantMessageHandler ) ;
2007-03-09 20:26:07 +00:00
// Chat callback
2009-10-28 08:01:52 +00:00
Client . Network . RegisterCallback ( PacketType . ChatFromSimulator , ChatHandler ) ;
2007-03-09 20:26:07 +00:00
// Script dialog callback
2009-10-28 08:01:52 +00:00
Client . Network . RegisterCallback ( PacketType . ScriptDialog , ScriptDialogHandler ) ;
2007-03-20 22:30:39 +00:00
// Script question callback
2009-10-28 08:01:52 +00:00
Client . Network . RegisterCallback ( PacketType . ScriptQuestion , ScriptQuestionHandler ) ;
2008-01-20 23:08:13 +00:00
// Script URL callback
2009-10-28 08:01:52 +00:00
Client . Network . RegisterCallback ( PacketType . LoadURL , LoadURLHandler ) ;
2007-03-09 20:26:07 +00:00
// Movement complete callback
2009-10-28 08:01:52 +00:00
Client . Network . RegisterCallback ( PacketType . AgentMovementComplete , MovementCompleteHandler ) ;
2007-03-09 20:26:07 +00:00
// Health callback
2009-10-28 08:01:52 +00:00
Client . Network . RegisterCallback ( PacketType . HealthMessage , HealthHandler ) ;
2007-11-06 09:26:10 +00:00
// Money callback
2009-10-28 08:01:52 +00:00
Client . Network . RegisterCallback ( PacketType . MoneyBalanceReply , MoneyBalanceReplyHandler ) ;
2008-09-09 04:58:58 +00:00
//Agent update callback
2009-10-28 08:01:52 +00:00
Client . Network . RegisterCallback ( PacketType . AgentDataUpdate , AgentDataUpdateHandler ) ;
2007-11-29 01:28:41 +00:00
// Animation callback
2010-08-12 22:37:27 +00:00
Client . Network . RegisterCallback ( PacketType . AvatarAnimation , AvatarAnimationHandler , false ) ;
2007-11-30 03:55:08 +00:00
// Object colliding into our agent callback
2009-10-28 08:01:52 +00:00
Client . Network . RegisterCallback ( PacketType . MeanCollisionAlert , MeanCollisionAlertHandler ) ;
2007-12-29 22:34:11 +00:00
// Region Crossing
2009-10-28 08:01:52 +00:00
Client . Network . RegisterCallback ( PacketType . CrossedRegion , CrossedRegionHandler ) ;
2016-11-27 22:05:54 -06:00
Client . Network . RegisterEventCallback ( "CrossedRegion" , CrossedRegionEventHandler ) ;
2008-09-09 04:58:58 +00:00
// CAPS callbacks
2016-11-27 22:05:54 -06:00
Client . Network . RegisterEventCallback ( "EstablishAgentCommunication" , EstablishAgentCommunicationEventHandler ) ;
Client . Network . RegisterEventCallback ( "SetDisplayNameReply" , SetDisplayNameReplyEventHandler ) ;
Client . Network . RegisterEventCallback ( "AgentStateUpdate" , AgentStateUpdateEventHandler ) ;
2008-01-05 23:06:19 +00:00
// Incoming Group Chat
2016-11-27 22:05:54 -06:00
Client . Network . RegisterEventCallback ( "ChatterBoxInvitation" , ChatterBoxInvitationEventHandler ) ;
2008-01-05 23:06:19 +00:00
// Outgoing Group Chat Reply
2016-11-27 22:05:54 -06:00
Client . Network . RegisterEventCallback ( "ChatterBoxSessionEventReply" , ChatterBoxSessionEventReplyEventHandler ) ;
Client . Network . RegisterEventCallback ( "ChatterBoxSessionStartReply" , ChatterBoxSessionStartReplyEventHandler ) ;
Client . Network . RegisterEventCallback ( "ChatterBoxSessionAgentListUpdates" , ChatterBoxSessionAgentListUpdatesEventHandler ) ;
2007-11-06 09:26:10 +00:00
// Login
2016-11-27 22:05:54 -06:00
Client . Network . RegisterLoginResponseCallback ( Network_OnLoginResponse ) ;
2008-02-19 08:46:16 +00:00
// Alert Messages
2009-10-28 08:01:52 +00:00
Client . Network . RegisterCallback ( PacketType . AlertMessage , AlertMessageHandler ) ;
2021-09-09 17:49:06 -05:00
Client . Network . RegisterCallback ( PacketType . AgentAlertMessage , AgentAlertMessageHandler ) ;
2008-04-04 21:08:38 +00:00
// script control change messages, ie: when an in-world LSL script wants to take control of your agent.
2009-10-28 08:01:52 +00:00
Client . Network . RegisterCallback ( PacketType . ScriptControlChange , ScriptControlChangeHandler ) ;
2008-04-05 00:01:49 +00:00
// Camera Constraint (probably needs to move to AgentManagerCamera TODO:
2009-10-28 08:01:52 +00:00
Client . Network . RegisterCallback ( PacketType . CameraConstraint , CameraConstraintHandler ) ;
Client . Network . RegisterCallback ( PacketType . ScriptSensorReply , ScriptSensorReplyHandler ) ;
Client . Network . RegisterCallback ( PacketType . AvatarSitResponse , AvatarSitResponseHandler ) ;
2011-03-05 23:48:49 +00:00
// Process mute list update message
Client . Network . RegisterCallback ( PacketType . MuteListUpdate , MuteListUpdateHander ) ;
2007-11-06 09:26:10 +00:00
}
#region Chat and instant messages
2020-03-09 04:25:52 +00:00
protected int message_chunk_group_id = 0 ; // a int that starts at 1 goes upto 500 (then back to 1)
2007-11-06 09:26:10 +00:00
/// <summary>
2009-04-29 18:33:46 +00:00
/// Send a text message from the Agent to the Simulator
2007-11-06 09:26:10 +00:00
/// </summary>
2009-04-29 18:33:46 +00:00
/// <param name="message">A <see cref="string"/> containing the message</param>
/// <param name="channel">The channel to send the message on, 0 is the public channel. Channels above 0
/// can be used however only scripts listening on the specified channel will see the message</param>
/// <param name="type">Denotes the type of message being sent, shout, whisper, etc.</param>
2020-03-09 04:25:52 +00:00
/// <param name="allow_split_message">Enables large messages to be split into chunks of 900 with [CHUNKGROUPID|CHUNKID|TOTALCHUNKS] at the start</param>
/// <param name="hide_chunk_grouping">Hides [CHUNKGROUPID|CHUNKID|TOTALCHUNKS] at the start of chunked messages</param>
public void Chat ( string message , int channel , ChatType type , bool allow_split_message = true , bool hide_chunk_grouping = true )
2007-11-06 09:26:10 +00:00
{
2020-03-09 04:25:52 +00:00
if ( ( message . Length > 900 ) & & ( allow_split_message = = true ) )
2016-11-27 22:05:54 -06:00
{
2020-03-09 04:25:52 +00:00
int group_id = message_chunk_group_id ;
message_chunk_group_id + + ;
2021-12-21 17:53:13 -06:00
if ( message_chunk_group_id > 500 ) { message_chunk_group_id = 1 ; }
2020-03-09 04:25:52 +00:00
string [ ] chunks = message . SplitBy ( 900 ) . ToArray ( ) ;
int chunkid = 1 ;
2021-12-21 17:53:13 -06:00
foreach ( string chunk in chunks )
2016-11-27 22:05:54 -06:00
{
2020-03-09 04:25:52 +00:00
string chunk_grouping = "" ;
if ( hide_chunk_grouping = = false )
{
2021-12-21 17:53:13 -06:00
chunk_grouping = $"[{group_id}|{chunkid}|{chunks.Length}]" ;
2020-03-09 04:25:52 +00:00
}
2021-12-21 17:53:13 -06:00
Chat ( $"{chunk_grouping}{chunk}" , channel , type , false ) ;
2020-03-09 04:25:52 +00:00
chunkid + + ;
2016-11-27 22:05:54 -06:00
}
2020-03-09 04:25:52 +00:00
}
else if ( ( message . Length > 0 ) & & ( message . Length < 1000 ) )
{
ChatFromViewerPacket chat = new ChatFromViewerPacket
{
AgentData =
{
2021-12-09 14:21:48 -06:00
AgentID = AgentID ,
2020-03-09 04:25:52 +00:00
SessionID = Client . Self . SessionID
} ,
ChatData =
{
Channel = channel ,
Message = Utils . StringToBytes ( message ) ,
Type = ( byte ) type
}
} ;
Client . Network . SendPacket ( chat ) ;
}
2007-11-06 09:26:10 +00:00
}
2009-04-29 18:33:46 +00:00
/// <summary>
/// Request any instant messages sent while the client was offline to be resent.
/// </summary>
2007-11-06 09:26:10 +00:00
public void RetrieveInstantMessages ( )
2021-09-22 15:04:43 -05:00
{
Uri offlineMsgsCap = Client . Network . CurrentSim . Caps . CapabilityURI ( "ReadOfflineMsgs" ) ;
if ( offlineMsgsCap = = null
| | Client . Network . CurrentSim . Caps . CapabilityURI ( "AcceptFriendship" ) = = null
| | Client . Network . CurrentSim . Caps . CapabilityURI ( "AcceptGroupInvite" ) = = null )
{
// fallback to lludp
RetrieveInstantMessagesLegacy ( ) ;
return ;
}
2022-11-04 07:13:09 -05:00
Task req = Client . HttpCapsClient . GetRequestAsync ( offlineMsgsCap , CancellationToken . None , OfflineMessageHandlerCallback ) ;
2021-09-22 15:04:43 -05:00
}
/// <summary>
/// Request offline instant messages via the legacy LLUDP packet
/// </summary>
private void RetrieveInstantMessagesLegacy ( )
2007-11-06 09:26:10 +00:00
{
2016-11-27 22:05:54 -06:00
RetrieveInstantMessagesPacket p = new RetrieveInstantMessagesPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
}
} ;
2007-11-06 09:26:10 +00:00
Client . Network . SendPacket ( p ) ;
2007-03-09 20:26:07 +00:00
}
/// <summary>
2009-04-29 18:33:46 +00:00
/// Send an Instant Message to another Avatar
2007-03-09 20:26:07 +00:00
/// </summary>
2009-04-29 18:33:46 +00:00
/// <param name="target">The recipients <see cref="UUID"/></param>
/// <param name="message">A <see cref="string"/> containing the message to send</param>
2008-07-25 05:15:05 +00:00
public void InstantMessage ( UUID target , string message )
2007-03-09 20:26:07 +00:00
{
2008-01-08 09:36:20 +00:00
InstantMessage ( Name , target , message , AgentID . Equals ( target ) ? AgentID : target ^ AgentID ,
2016-11-27 22:05:54 -06:00
InstantMessageDialog . MessageFromAgent , InstantMessageOnline . Offline , SimPosition ,
2009-03-06 01:32:02 +00:00
UUID . Zero , Utils . EmptyBytes ) ;
2007-03-09 20:26:07 +00:00
}
/// <summary>
2009-04-29 18:33:46 +00:00
/// Send an Instant Message to an existing group chat or conference chat
2007-03-09 20:26:07 +00:00
/// </summary>
2009-04-29 18:33:46 +00:00
/// <param name="target">The recipients <see cref="UUID"/></param>
/// <param name="message">A <see cref="string"/> containing the message to send</param>
2007-03-09 20:26:07 +00:00
/// <param name="imSessionID">IM session ID (to differentiate between IM windows)</param>
2008-07-25 05:15:05 +00:00
public void InstantMessage ( UUID target , string message , UUID imSessionID )
2007-03-09 20:26:07 +00:00
{
2007-08-29 08:55:53 +00:00
InstantMessage ( Name , target , message , imSessionID ,
2016-11-27 22:05:54 -06:00
InstantMessageDialog . MessageFromAgent , InstantMessageOnline . Offline , SimPosition ,
2009-03-06 01:32:02 +00:00
UUID . Zero , Utils . EmptyBytes ) ;
2007-03-09 20:26:07 +00:00
}
/// <summary>
/// Send an Instant Message
/// </summary>
/// <param name="fromName">The name this IM will show up as being from</param>
/// <param name="target">Key of Avatar</param>
/// <param name="message">Text message being sent</param>
/// <param name="imSessionID">IM session ID (to differentiate between IM windows)</param>
2008-01-09 00:52:59 +00:00
/// <param name="conferenceIDs">IDs of sessions for a conference</param>
2008-09-09 04:58:58 +00:00
public void InstantMessage ( string fromName , UUID target , string message , UUID imSessionID ,
2008-07-25 05:15:05 +00:00
UUID [ ] conferenceIDs )
2008-09-09 04:58:58 +00:00
{
2007-03-09 20:26:07 +00:00
byte [ ] binaryBucket ;
if ( conferenceIDs ! = null & & conferenceIDs . Length > 0 )
{
binaryBucket = new byte [ 16 * conferenceIDs . Length ] ;
for ( int i = 0 ; i < conferenceIDs . Length ; + + i )
2007-12-25 02:37:35 +00:00
Buffer . BlockCopy ( conferenceIDs [ i ] . GetBytes ( ) , 0 , binaryBucket , i * 16 , 16 ) ;
2007-03-09 20:26:07 +00:00
}
else
{
2009-03-06 01:32:02 +00:00
binaryBucket = Utils . EmptyBytes ;
2007-03-09 20:26:07 +00:00
}
2008-09-09 04:58:58 +00:00
InstantMessage ( fromName , target , message , imSessionID , InstantMessageDialog . MessageFromAgent ,
2008-07-25 05:15:05 +00:00
InstantMessageOnline . Offline , Vector3 . Zero , UUID . Zero , binaryBucket ) ;
2008-09-09 04:58:58 +00:00
}
2007-03-09 20:26:07 +00:00
/// <summary>
/// Send an Instant Message
/// </summary>
/// <param name="fromName">The name this IM will show up as being from</param>
/// <param name="target">Key of Avatar</param>
/// <param name="message">Text message being sent</param>
/// <param name="imSessionID">IM session ID (to differentiate between IM windows)</param>
/// <param name="dialog">Type of instant message to send</param>
/// <param name="offline">Whether to IM offline avatars as well</param>
2008-01-08 06:41:29 +00:00
/// <param name="position">Senders Position</param>
/// <param name="regionID">RegionID Sender is In</param>
2007-03-09 20:26:07 +00:00
/// <param name="binaryBucket">Packed binary data that is specific to
/// the dialog type</param>
2008-09-09 04:58:58 +00:00
public void InstantMessage ( string fromName , UUID target , string message , UUID imSessionID ,
InstantMessageDialog dialog , InstantMessageOnline offline , Vector3 position , UUID regionID ,
2007-03-09 20:26:07 +00:00
byte [ ] binaryBucket )
{
2008-07-25 05:15:05 +00:00
if ( target ! = UUID . Zero )
2007-12-21 05:31:13 +00:00
{
ImprovedInstantMessagePacket im = new ImprovedInstantMessagePacket ( ) ;
2008-01-08 06:43:34 +00:00
2008-07-25 05:15:05 +00:00
if ( imSessionID . Equals ( UUID . Zero ) | | imSessionID . Equals ( AgentID ) )
2008-01-08 09:36:20 +00:00
imSessionID = AgentID . Equals ( target ) ? AgentID : target ^ AgentID ;
2007-03-09 20:26:07 +00:00
2007-12-21 05:31:13 +00:00
im . AgentData . AgentID = Client . Self . AgentID ;
im . AgentData . SessionID = Client . Self . SessionID ;
2007-03-09 20:26:07 +00:00
2007-12-21 05:31:13 +00:00
im . MessageBlock . Dialog = ( byte ) dialog ;
2008-08-12 22:38:02 +00:00
im . MessageBlock . FromAgentName = Utils . StringToBytes ( fromName ) ;
2007-12-21 05:31:13 +00:00
im . MessageBlock . FromGroup = false ;
im . MessageBlock . ID = imSessionID ;
2008-08-12 22:38:02 +00:00
im . MessageBlock . Message = Utils . StringToBytes ( message ) ;
2007-12-21 05:31:13 +00:00
im . MessageBlock . Offline = ( byte ) offline ;
im . MessageBlock . ToAgentID = target ;
2007-03-09 20:26:07 +00:00
2016-11-27 22:05:54 -06:00
im . MessageBlock . BinaryBucket = binaryBucket ? ? Utils . EmptyBytes ;
2007-03-09 20:26:07 +00:00
2007-12-21 05:31:13 +00:00
// These fields are mandatory, even if we don't have valid values for them
2008-07-25 05:15:05 +00:00
im . MessageBlock . Position = Vector3 . Zero ;
2007-12-21 05:31:13 +00:00
//TODO: Allow region id to be correctly set by caller or fetched from Client.*
im . MessageBlock . RegionID = regionID ;
2007-03-09 20:26:07 +00:00
2007-12-21 05:31:13 +00:00
// Send the message
Client . Network . SendPacket ( im ) ;
}
else
{
2016-11-27 22:05:54 -06:00
Logger . Log ( $"Suppressing instant message \" { message } \ " to UUID.Zero" ,
2008-05-06 23:57:26 +00:00
Helpers . LogLevel . Error , Client ) ;
2007-12-21 05:31:13 +00:00
}
2007-03-09 20:26:07 +00:00
}
/// <summary>
/// Send an Instant Message to a group
/// </summary>
2008-07-28 08:28:16 +00:00
/// <param name="groupID"><seealso cref="UUID"/> of the group to send message to</param>
2007-03-09 20:26:07 +00:00
/// <param name="message">Text Message being sent.</param>
2008-07-28 08:28:16 +00:00
public void InstantMessageGroup ( UUID groupID , string message )
2007-03-09 20:26:07 +00:00
{
2008-07-28 08:28:16 +00:00
InstantMessageGroup ( Name , groupID , message ) ;
2007-03-09 20:26:07 +00:00
}
/// <summary>
2009-04-29 18:33:46 +00:00
/// Send an Instant Message to a group the agent is a member of
2007-03-09 20:26:07 +00:00
/// </summary>
/// <param name="fromName">The name this IM will show up as being from</param>
2008-07-28 08:28:16 +00:00
/// <param name="groupID"><seealso cref="UUID"/> of the group to send message to</param>
2007-03-09 20:26:07 +00:00
/// <param name="message">Text message being sent</param>
2008-07-28 08:28:16 +00:00
public void InstantMessageGroup ( string fromName , UUID groupID , string message )
2008-01-05 23:06:19 +00:00
{
lock ( GroupChatSessions . Dictionary )
2022-10-22 19:52:21 -05:00
{
2008-07-28 08:28:16 +00:00
if ( GroupChatSessions . ContainsKey ( groupID ) )
2008-01-05 23:06:19 +00:00
{
2016-11-27 22:05:54 -06:00
ImprovedInstantMessagePacket im = new ImprovedInstantMessagePacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
MessageBlock =
{
Dialog = ( byte ) InstantMessageDialog . SessionSend ,
FromAgentName = Utils . StringToBytes ( fromName ) ,
FromGroup = false ,
Message = Utils . StringToBytes ( message ) ,
Offline = 0 ,
ID = groupID ,
ToAgentID = groupID ,
Position = Vector3 . Zero ,
RegionID = UUID . Zero ,
BinaryBucket = Utils . StringToBytes ( "\0" )
}
} ;
2008-09-09 04:58:58 +00:00
2008-01-05 23:06:19 +00:00
Client . Network . SendPacket ( im ) ;
}
else
2008-05-06 23:57:26 +00:00
{
2008-09-09 04:58:58 +00:00
Logger . Log ( "No Active group chat session appears to exist, use RequestJoinGroupChat() to join one" ,
2008-05-06 23:57:26 +00:00
Helpers . LogLevel . Error , Client ) ;
2008-01-05 23:06:19 +00:00
}
2022-10-22 19:52:21 -05:00
}
2008-01-05 23:06:19 +00:00
}
/// <summary>
/// Send a request to join a group chat session
/// </summary>
2008-07-28 08:28:16 +00:00
/// <param name="groupID"><seealso cref="UUID"/> of Group to leave</param>
public void RequestJoinGroupChat ( UUID groupID )
2008-01-05 23:06:19 +00:00
{
2016-11-27 22:05:54 -06:00
ImprovedInstantMessagePacket im = new ImprovedInstantMessagePacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
MessageBlock =
{
Dialog = ( byte ) InstantMessageDialog . SessionGroupStart ,
FromAgentName = Utils . StringToBytes ( Client . Self . Name ) ,
FromGroup = false ,
Message = Utils . EmptyBytes ,
ParentEstateID = 0 ,
Offline = 0 ,
ID = groupID ,
ToAgentID = groupID ,
BinaryBucket = Utils . EmptyBytes ,
Position = Client . Self . SimPosition ,
RegionID = UUID . Zero
}
} ;
2008-01-05 23:06:19 +00:00
Client . Network . SendPacket ( im ) ;
}
2009-04-29 18:33:46 +00:00
2008-01-05 23:06:19 +00:00
/// <summary>
2009-04-29 18:33:46 +00:00
/// Exit a group chat session. This will stop further Group chat messages
/// from being sent until session is rejoined.
2008-01-05 23:06:19 +00:00
/// </summary>
2009-04-29 18:33:46 +00:00
/// <param name="groupID"><seealso cref="UUID"/> of Group chat session to leave</param>
2008-07-28 08:28:16 +00:00
public void RequestLeaveGroupChat ( UUID groupID )
2007-03-09 20:26:07 +00:00
{
2016-11-27 22:05:54 -06:00
ImprovedInstantMessagePacket im = new ImprovedInstantMessagePacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
MessageBlock =
{
Dialog = ( byte ) InstantMessageDialog . SessionDrop ,
FromAgentName = Utils . StringToBytes ( Client . Self . Name ) ,
FromGroup = false ,
Message = Utils . EmptyBytes ,
Offline = 0 ,
ID = groupID ,
ToAgentID = groupID ,
BinaryBucket = Utils . EmptyBytes ,
Position = Vector3 . Zero ,
RegionID = UUID . Zero
}
} ;
2007-03-09 20:26:07 +00:00
Client . Network . SendPacket ( im ) ;
2010-04-29 00:07:31 +00:00
lock ( GroupChatSessions . Dictionary )
2022-10-22 19:52:21 -05:00
{
2010-04-29 00:07:31 +00:00
if ( GroupChatSessions . ContainsKey ( groupID ) )
GroupChatSessions . Remove ( groupID ) ;
2022-10-22 19:52:21 -05:00
}
2007-03-09 20:26:07 +00:00
}
2008-01-12 03:10:39 +00:00
/// <summary>
/// Reply to script dialog questions.
/// </summary>
/// <param name="channel">Channel initial request came on</param>
/// <param name="buttonIndex">Index of button you're "clicking"</param>
/// <param name="buttonlabel">Label of button you're "clicking"</param>
2008-07-28 08:28:16 +00:00
/// <param name="objectID"><seealso cref="UUID"/> of Object that sent the dialog request</param>
/// <seealso cref="OnScriptDialog"/>
2008-07-25 05:15:05 +00:00
public void ReplyToScriptDialog ( int channel , int buttonIndex , string buttonlabel , UUID objectID )
2008-01-12 03:10:39 +00:00
{
2016-11-27 22:05:54 -06:00
ScriptDialogReplyPacket reply = new ScriptDialogReplyPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
Data =
{
ButtonIndex = buttonIndex ,
ButtonLabel = Utils . StringToBytes ( buttonlabel ) ,
ChatChannel = channel ,
ObjectID = objectID
}
} ;
2008-01-12 03:10:39 +00:00
Client . Network . SendPacket ( reply ) ;
}
2009-03-02 11:53:26 +00:00
/// <summary>
/// Accept invite for to a chatterbox session
/// </summary>
/// <param name="session_id"><seealso cref="UUID"/> of session to accept invite to</param>
public void ChatterBoxAcceptInvite ( UUID session_id )
{
if ( Client . Network . CurrentSim = = null | | Client . Network . CurrentSim . Caps = = null )
2019-08-11 10:08:35 -05:00
{
2009-03-02 11:53:26 +00:00
throw new Exception ( "ChatSessionRequest capability is not currently available" ) ;
2019-08-11 10:08:35 -05:00
}
2009-03-02 11:53:26 +00:00
2022-11-03 14:19:56 -05:00
Uri cap = Client . Network . CurrentSim . Caps . CapabilityURI ( "ChatSessionRequest" ) ;
if ( cap ! = null )
2009-03-02 11:53:26 +00:00
{
2019-08-11 10:08:35 -05:00
ChatSessionAcceptInvitation acceptInvite = new ChatSessionAcceptInvitation { SessionID = session_id } ;
2010-05-06 13:43:00 +00:00
2022-11-03 14:19:56 -05:00
Task req = Client . HttpCapsClient . PostRequestAsync ( cap , OSDFormat . Xml , acceptInvite . Serialize ( ) ,
2022-11-04 07:13:09 -05:00
CancellationToken . None , null ) ;
2022-11-03 14:19:56 -05:00
req . ContinueWith ( t = >
2022-10-22 19:52:21 -05:00
{
2022-11-03 14:19:56 -05:00
lock ( GroupChatSessions . Dictionary )
{
if ( ! GroupChatSessions . ContainsKey ( session_id ) )
GroupChatSessions . Add ( session_id , new List < ChatSessionMember > ( ) ) ;
}
} ) ;
2009-03-02 11:53:26 +00:00
}
else
{
throw new Exception ( "ChatSessionRequest capability is not currently available" ) ;
}
2009-10-16 02:53:53 +00:00
}
2009-03-02 11:53:26 +00:00
2009-10-16 02:53:53 +00:00
/// <summary>
/// Start a friends conference
/// </summary>
/// <param name="participants"><seealso cref="UUID"/> List of UUIDs to start a conference with</param>
2017-01-02 11:20:36 +00:00
/// <param name="tmp_session_id">the temporary session ID returned in the <see cref="OnJoinedGroupChat"/> callback></param>
2009-10-16 02:53:53 +00:00
public void StartIMConference ( List < UUID > participants , UUID tmp_session_id )
{
if ( Client . Network . CurrentSim = = null | | Client . Network . CurrentSim . Caps = = null )
2019-08-11 10:08:35 -05:00
{
2009-10-16 02:53:53 +00:00
throw new Exception ( "ChatSessionRequest capability is not currently available" ) ;
2019-08-11 10:08:35 -05:00
}
2022-11-03 14:19:56 -05:00
Uri cap = Client . Network . CurrentSim . Caps . CapabilityURI ( "ChatSessionRequest" ) ;
if ( cap ! = null )
2009-03-02 11:53:26 +00:00
{
2016-11-27 22:05:54 -06:00
ChatSessionRequestStartConference startConference = new ChatSessionRequestStartConference
{
AgentsBlock = new UUID [ participants . Count ]
} ;
2009-03-02 11:53:26 +00:00
2022-11-03 14:19:56 -05:00
for ( var i = 0 ; i < participants . Count ; i + + )
2019-08-11 10:08:35 -05:00
{
2009-04-29 18:33:46 +00:00
startConference . AgentsBlock [ i ] = participants [ i ] ;
2019-08-11 10:08:35 -05:00
}
2009-03-02 11:53:26 +00:00
2009-04-29 18:33:46 +00:00
startConference . SessionID = tmp_session_id ;
2022-11-04 07:13:09 -05:00
Task req = Client . HttpCapsClient . PostRequestAsync ( cap , OSDFormat . Xml , startConference . Serialize ( ) ,
CancellationToken . None , null ) ;
2009-03-02 11:53:26 +00:00
}
else
{
throw new Exception ( "ChatSessionRequest capability is not currently available" ) ;
}
}
2007-11-06 09:26:10 +00:00
#endregion Chat and instant messages
#region Viewer Effects
2007-03-09 20:26:07 +00:00
/// <summary>
2008-03-14 07:11:13 +00:00
/// Start a particle stream between an agent and an object
2007-03-09 20:26:07 +00:00
/// </summary>
2008-07-28 08:28:16 +00:00
/// <param name="sourceAvatar"><seealso cref="UUID"/> Key of the source agent</param>
/// <param name="targetObject"><seealso cref="UUID"/> Key of the target object</param>
2007-03-09 20:26:07 +00:00
/// <param name="globalOffset"></param>
2008-05-08 16:58:09 +00:00
/// <param name="type">The type from the <seealso cref="T:PointAtType"/> enum</param>
2008-07-28 08:28:16 +00:00
/// <param name="effectID">A unique <seealso cref="UUID"/> for this effect</param>
2008-07-25 05:15:05 +00:00
public void PointAtEffect ( UUID sourceAvatar , UUID targetObject , Vector3d globalOffset , PointAtType type ,
UUID effectID )
2007-03-09 20:26:07 +00:00
{
2016-11-27 22:05:54 -06:00
ViewerEffectPacket effect = new ViewerEffectPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
Effect = new ViewerEffectPacket . EffectBlock [ 1 ]
} ;
2008-09-09 04:58:58 +00:00
2007-03-09 20:26:07 +00:00
2016-11-27 22:05:54 -06:00
effect . Effect [ 0 ] = new ViewerEffectPacket . EffectBlock
{
AgentID = Client . Self . AgentID ,
Color = new byte [ 4 ] ,
Duration = ( type = = PointAtType . Clear ) ? 0.0f : Single . MaxValue / 4.0f ,
ID = effectID ,
Type = ( byte ) EffectType . PointAt
} ;
2007-03-09 20:26:07 +00:00
byte [ ] typeData = new byte [ 57 ] ;
2008-07-25 05:15:05 +00:00
if ( sourceAvatar ! = UUID . Zero )
2007-04-15 07:37:53 +00:00
Buffer . BlockCopy ( sourceAvatar . GetBytes ( ) , 0 , typeData , 0 , 16 ) ;
2008-07-25 05:15:05 +00:00
if ( targetObject ! = UUID . Zero )
2007-04-15 07:37:53 +00:00
Buffer . BlockCopy ( targetObject . GetBytes ( ) , 0 , typeData , 16 , 16 ) ;
Buffer . BlockCopy ( globalOffset . GetBytes ( ) , 0 , typeData , 32 , 24 ) ;
2007-03-09 20:26:07 +00:00
typeData [ 56 ] = ( byte ) type ;
effect . Effect [ 0 ] . TypeData = typeData ;
Client . Network . SendPacket ( effect ) ;
}
/// <summary>
2008-03-14 07:11:13 +00:00
/// Start a particle stream between an agent and an object
2007-03-09 20:26:07 +00:00
/// </summary>
2008-07-28 08:28:16 +00:00
/// <param name="sourceAvatar"><seealso cref="UUID"/> Key of the source agent</param>
/// <param name="targetObject"><seealso cref="UUID"/> Key of the target object</param>
/// <param name="globalOffset">A <seealso cref="Vector3d"/> representing the beams offset from the source</param>
2008-05-01 10:48:09 +00:00
/// <param name="type">A <seealso cref="T:PointAtType"/> which sets the avatars lookat animation</param>
2008-07-28 08:28:16 +00:00
/// <param name="effectID"><seealso cref="UUID"/> of the Effect</param>
2008-07-25 05:15:05 +00:00
public void LookAtEffect ( UUID sourceAvatar , UUID targetObject , Vector3d globalOffset , LookAtType type ,
UUID effectID )
2007-03-09 20:26:07 +00:00
{
2016-11-27 22:05:54 -06:00
ViewerEffectPacket effect = new ViewerEffectPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
}
} ;
2007-03-09 20:26:07 +00:00
float duration ;
switch ( type )
{
2007-04-23 06:39:37 +00:00
case LookAtType . Clear :
2009-11-08 12:58:59 +00:00
duration = 2.0f ;
2007-03-09 20:26:07 +00:00
break ;
2007-04-23 06:39:37 +00:00
case LookAtType . Hover :
2007-03-09 20:26:07 +00:00
duration = 1.0f ;
break ;
2007-04-23 06:39:37 +00:00
case LookAtType . FreeLook :
2007-03-09 20:26:07 +00:00
duration = 2.0f ;
break ;
2007-04-23 06:39:37 +00:00
case LookAtType . Idle :
2007-03-09 20:26:07 +00:00
duration = 3.0f ;
break ;
2007-04-23 06:39:37 +00:00
case LookAtType . AutoListen :
case LookAtType . Respond :
2007-03-09 20:26:07 +00:00
duration = 4.0f ;
break ;
2007-04-23 06:39:37 +00:00
case LookAtType . None :
case LookAtType . Select :
case LookAtType . Focus :
case LookAtType . Mouselook :
2007-03-09 20:26:07 +00:00
duration = Single . MaxValue / 2.0f ;
break ;
default :
duration = 0.0f ;
break ;
}
effect . Effect = new ViewerEffectPacket . EffectBlock [ 1 ] ;
2016-11-27 22:05:54 -06:00
effect . Effect [ 0 ] = new ViewerEffectPacket . EffectBlock
{
AgentID = Client . Self . AgentID ,
Color = new byte [ 4 ] ,
Duration = duration ,
ID = effectID ,
Type = ( byte ) EffectType . LookAt
} ;
2007-03-09 20:26:07 +00:00
byte [ ] typeData = new byte [ 57 ] ;
2009-11-08 12:58:59 +00:00
Buffer . BlockCopy ( sourceAvatar . GetBytes ( ) , 0 , typeData , 0 , 16 ) ;
Buffer . BlockCopy ( targetObject . GetBytes ( ) , 0 , typeData , 16 , 16 ) ;
Buffer . BlockCopy ( globalOffset . GetBytes ( ) , 0 , typeData , 32 , 24 ) ;
2007-03-09 20:26:07 +00:00
typeData [ 56 ] = ( byte ) type ;
effect . Effect [ 0 ] . TypeData = typeData ;
Client . Network . SendPacket ( effect ) ;
}
/// <summary>
2009-07-24 08:25:28 +00:00
/// Create a particle beam between an avatar and an primitive
/// </summary>
/// <param name="sourceAvatar">The ID of source avatar</param>
/// <param name="targetObject">The ID of the target primitive</param>
/// <param name="globalOffset">global offset</param>
/// <param name="color">A <see cref="Color4"/> object containing the combined red, green, blue and alpha
/// color values of particle beam</param>
/// <param name="duration">a float representing the duration the parcicle beam will last</param>
/// <param name="effectID">A Unique ID for the beam</param>
/// <seealso cref="ViewerEffectPacket"/>
2008-09-09 04:58:58 +00:00
public void BeamEffect ( UUID sourceAvatar , UUID targetObject , Vector3d globalOffset , Color4 color ,
2008-07-25 05:15:05 +00:00
float duration , UUID effectID )
2007-03-09 20:26:07 +00:00
{
2016-11-27 22:05:54 -06:00
ViewerEffectPacket effect = new ViewerEffectPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
Effect = new ViewerEffectPacket . EffectBlock [ 1 ]
} ;
2007-03-09 20:26:07 +00:00
2016-11-27 22:05:54 -06:00
effect . Effect [ 0 ] = new ViewerEffectPacket . EffectBlock
{
AgentID = Client . Self . AgentID ,
Color = color . GetBytes ( ) ,
Duration = duration ,
ID = effectID ,
Type = ( byte ) EffectType . Beam
} ;
2007-03-09 20:26:07 +00:00
byte [ ] typeData = new byte [ 56 ] ;
2007-11-06 09:26:10 +00:00
Buffer . BlockCopy ( sourceAvatar . GetBytes ( ) , 0 , typeData , 0 , 16 ) ;
Buffer . BlockCopy ( targetObject . GetBytes ( ) , 0 , typeData , 16 , 16 ) ;
2007-04-15 07:37:53 +00:00
Buffer . BlockCopy ( globalOffset . GetBytes ( ) , 0 , typeData , 32 , 24 ) ;
2007-03-09 20:26:07 +00:00
effect . Effect [ 0 ] . TypeData = typeData ;
Client . Network . SendPacket ( effect ) ;
}
2009-06-03 16:19:51 +00:00
/// <summary>
2009-07-24 08:25:28 +00:00
/// Create a particle swirl around a target position using a <seealso cref="ViewerEffectPacket"/> packet
2009-06-03 16:19:51 +00:00
/// </summary>
2009-07-24 08:25:28 +00:00
/// <param name="globalOffset">global offset</param>
/// <param name="color">A <see cref="Color4"/> object containing the combined red, green, blue and alpha
/// color values of particle beam</param>
/// <param name="duration">a float representing the duration the parcicle beam will last</param>
/// <param name="effectID">A Unique ID for the beam</param>
2009-06-03 16:19:51 +00:00
public void SphereEffect ( Vector3d globalOffset , Color4 color , float duration , UUID effectID )
{
2016-11-27 22:05:54 -06:00
ViewerEffectPacket effect = new ViewerEffectPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
Effect = new ViewerEffectPacket . EffectBlock [ 1 ]
} ;
2009-06-03 16:19:51 +00:00
2016-11-27 22:05:54 -06:00
effect . Effect [ 0 ] = new ViewerEffectPacket . EffectBlock
{
AgentID = Client . Self . AgentID ,
Color = color . GetBytes ( ) ,
Duration = duration ,
ID = effectID ,
Type = ( byte ) EffectType . Sphere
} ;
2009-06-03 16:19:51 +00:00
byte [ ] typeData = new byte [ 56 ] ;
Buffer . BlockCopy ( UUID . Zero . GetBytes ( ) , 0 , typeData , 0 , 16 ) ;
Buffer . BlockCopy ( UUID . Zero . GetBytes ( ) , 0 , typeData , 16 , 16 ) ;
Buffer . BlockCopy ( globalOffset . GetBytes ( ) , 0 , typeData , 32 , 24 ) ;
effect . Effect [ 0 ] . TypeData = typeData ;
Client . Network . SendPacket ( effect ) ;
}
2007-11-06 09:26:10 +00:00
#endregion Viewer Effects
2007-04-13 20:02:21 +00:00
2007-11-06 09:26:10 +00:00
#region Movement Actions
2007-03-09 20:26:07 +00:00
/// <summary>
/// Sends a request to sit on the specified object
/// </summary>
2008-07-28 08:28:16 +00:00
/// <param name="targetID"><seealso cref="UUID"/> of the object to sit on</param>
2007-03-09 20:26:07 +00:00
/// <param name="offset">Sit at offset</param>
2008-07-25 05:15:05 +00:00
public void RequestSit ( UUID targetID , Vector3 offset )
2007-03-09 20:26:07 +00:00
{
2016-11-27 22:05:54 -06:00
AgentRequestSitPacket requestSit = new AgentRequestSitPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
TargetObject =
{
TargetID = targetID ,
Offset = offset
}
} ;
2007-03-09 20:26:07 +00:00
Client . Network . SendPacket ( requestSit ) ;
}
2007-11-29 01:28:41 +00:00
/// <summary>
2008-07-28 08:28:16 +00:00
/// Follows a call to <seealso cref="RequestSit"/> to actually sit on the object
2007-03-09 20:26:07 +00:00
/// </summary>
public void Sit ( )
{
2016-11-27 22:05:54 -06:00
AgentSitPacket sit = new AgentSitPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
}
} ;
2007-03-09 20:26:07 +00:00
Client . Network . SendPacket ( sit ) ;
}
2007-11-29 01:28:41 +00:00
/// <summary>Stands up from sitting on a prim or the ground</summary>
2008-05-01 10:48:09 +00:00
/// <returns>true of AgentUpdate was sent</returns>
2007-11-29 01:28:41 +00:00
public bool Stand ( )
2007-08-10 02:24:35 +00:00
{
2007-08-10 04:06:55 +00:00
if ( Client . Settings . SEND_AGENT_UPDATES )
{
2008-10-15 23:57:38 +00:00
Movement . SitOnGround = false ;
2007-11-29 01:28:41 +00:00
Movement . StandUp = true ;
Movement . SendUpdate ( ) ;
2008-05-26 02:22:30 +00:00
Movement . StandUp = false ;
Movement . SendUpdate ( ) ;
2007-08-10 07:42:23 +00:00
return true ;
2007-08-10 04:06:55 +00:00
}
else
{
2008-05-06 23:57:26 +00:00
Logger . Log ( "Attempted to Stand() but agent updates are disabled" , Helpers . LogLevel . Warning , Client ) ;
2007-08-10 04:06:55 +00:00
return false ;
}
}
/// <summary>
2007-11-29 01:28:41 +00:00
/// Does a "ground sit" at the avatar's current position
2007-08-10 04:06:55 +00:00
/// </summary>
2007-11-29 01:28:41 +00:00
public void SitOnGround ( )
2007-08-10 04:06:55 +00:00
{
2007-11-29 01:28:41 +00:00
Movement . SitOnGround = true ;
Movement . SendUpdate ( true ) ;
2007-08-10 04:06:55 +00:00
}
/// <summary>
2007-11-29 01:28:41 +00:00
/// Starts or stops flying
2007-08-10 04:06:55 +00:00
/// </summary>
2007-11-29 01:28:41 +00:00
/// <param name="start">True to start flying, false to stop flying</param>
public void Fly ( bool start )
2007-08-10 04:06:55 +00:00
{
2016-11-27 22:05:54 -06:00
Movement . Fly = start ;
2007-11-29 01:28:41 +00:00
Movement . SendUpdate ( true ) ;
2007-08-10 04:06:55 +00:00
}
/// <summary>
2007-11-29 01:28:41 +00:00
/// Starts or stops crouching
2007-08-10 04:06:55 +00:00
/// </summary>
2008-11-05 23:12:09 +00:00
/// <param name="crouching">True to start crouching, false to stop crouching</param>
2008-10-28 18:27:19 +00:00
public void Crouch ( bool crouching )
2007-08-10 04:06:55 +00:00
{
2008-10-28 18:27:19 +00:00
Movement . UpNeg = crouching ;
2007-11-29 01:28:41 +00:00
Movement . SendUpdate ( true ) ;
2007-08-10 04:06:55 +00:00
}
/// <summary>
2007-11-29 01:28:41 +00:00
/// Starts a jump (begin holding the jump key)
2007-08-10 04:06:55 +00:00
/// </summary>
2008-10-28 18:27:19 +00:00
public void Jump ( bool jumping )
2007-08-10 04:06:55 +00:00
{
2008-10-28 18:27:19 +00:00
Movement . UpPos = jumping ;
Movement . FastUp = jumping ;
2007-11-29 01:28:41 +00:00
Movement . SendUpdate ( true ) ;
2007-08-10 02:24:35 +00:00
}
2007-11-06 09:26:10 +00:00
/// <summary>
/// Use the autopilot sim function to move the avatar to a new
/// position. Uses double precision to get precise movements
/// </summary>
/// <remarks>The z value is currently not handled properly by the simulator</remarks>
/// <param name="globalX">Global X coordinate to move to</param>
/// <param name="globalY">Global Y coordinate to move to</param>
/// <param name="z">Z coordinate to move to</param>
public void AutoPilot ( double globalX , double globalY , double z )
{
GenericMessagePacket autopilot = new GenericMessagePacket ( ) ;
autopilot . AgentData . AgentID = Client . Self . AgentID ;
autopilot . AgentData . SessionID = Client . Self . SessionID ;
2008-07-25 05:15:05 +00:00
autopilot . AgentData . TransactionID = UUID . Zero ;
autopilot . MethodData . Invoice = UUID . Zero ;
2008-08-12 22:38:02 +00:00
autopilot . MethodData . Method = Utils . StringToBytes ( "autopilot" ) ;
2007-11-06 09:26:10 +00:00
autopilot . ParamList = new GenericMessagePacket . ParamListBlock [ 3 ] ;
2016-11-27 22:05:54 -06:00
autopilot . ParamList [ 0 ] = new GenericMessagePacket . ParamListBlock
{
2022-10-10 16:22:33 -05:00
Parameter = Utils . StringToBytes ( globalX . ToString ( CultureInfo . InvariantCulture ) )
2016-11-27 22:05:54 -06:00
} ;
autopilot . ParamList [ 1 ] = new GenericMessagePacket . ParamListBlock
{
2022-10-10 16:22:33 -05:00
Parameter = Utils . StringToBytes ( globalY . ToString ( CultureInfo . InvariantCulture ) )
2016-11-27 22:05:54 -06:00
} ;
autopilot . ParamList [ 2 ] = new GenericMessagePacket . ParamListBlock
{
2022-10-10 16:22:33 -05:00
Parameter = Utils . StringToBytes ( z . ToString ( CultureInfo . InvariantCulture ) )
2016-11-27 22:05:54 -06:00
} ;
2007-11-06 09:26:10 +00:00
Client . Network . SendPacket ( autopilot ) ;
}
/// <summary>
/// Use the autopilot sim function to move the avatar to a new position
/// </summary>
/// <remarks>The z value is currently not handled properly by the simulator</remarks>
/// <param name="globalX">Integer value for the global X coordinate to move to</param>
/// <param name="globalY">Integer value for the global Y coordinate to move to</param>
/// <param name="z">Floating-point value for the Z coordinate to move to</param>
public void AutoPilot ( ulong globalX , ulong globalY , float z )
{
2016-11-27 22:05:54 -06:00
GenericMessagePacket autopilot = new GenericMessagePacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID ,
TransactionID = UUID . Zero
} ,
MethodData =
{
Invoice = UUID . Zero ,
Method = Utils . StringToBytes ( "autopilot" )
} ,
ParamList = new GenericMessagePacket . ParamListBlock [ 3 ]
} ;
2007-11-06 09:26:10 +00:00
2016-11-27 22:05:54 -06:00
autopilot . ParamList [ 0 ] = new GenericMessagePacket . ParamListBlock
{
Parameter = Utils . StringToBytes ( globalX . ToString ( ) )
} ;
autopilot . ParamList [ 1 ] = new GenericMessagePacket . ParamListBlock
{
Parameter = Utils . StringToBytes ( globalY . ToString ( ) )
} ;
autopilot . ParamList [ 2 ] = new GenericMessagePacket . ParamListBlock
{
2022-10-10 16:22:33 -05:00
Parameter = Utils . StringToBytes ( z . ToString ( CultureInfo . InvariantCulture ) )
2016-11-27 22:05:54 -06:00
} ;
2007-11-06 09:26:10 +00:00
Client . Network . SendPacket ( autopilot ) ;
}
/// <summary>
/// Use the autopilot sim function to move the avatar to a new position
/// </summary>
/// <remarks>The z value is currently not handled properly by the simulator</remarks>
/// <param name="localX">Integer value for the local X coordinate to move to</param>
/// <param name="localY">Integer value for the local Y coordinate to move to</param>
/// <param name="z">Floating-point value for the Z coordinate to move to</param>
public void AutoPilotLocal ( int localX , int localY , float z )
{
uint x , y ;
2008-10-06 22:34:38 +00:00
Utils . LongToUInts ( Client . Network . CurrentSim . Handle , out x , out y ) ;
2007-11-06 09:26:10 +00:00
AutoPilot ( ( ulong ) ( x + localX ) , ( ulong ) ( y + localY ) , z ) ;
}
2008-05-01 10:48:09 +00:00
/// <summary>Macro to cancel autopilot sim function</summary>
2007-11-06 09:26:10 +00:00
/// <remarks>Not certain if this is how it is really done</remarks>
2008-05-01 10:48:09 +00:00
/// <returns>true if control flags were set and AgentUpdate was sent to the simulator</returns>
2007-11-06 09:26:10 +00:00
public bool AutoPilotCancel ( )
{
if ( Client . Settings . SEND_AGENT_UPDATES )
{
Movement . AtPos = true ;
Movement . SendUpdate ( ) ;
Movement . AtPos = false ;
Movement . SendUpdate ( ) ;
return true ;
}
else
{
2008-05-06 23:57:26 +00:00
Logger . Log ( "Attempted to AutoPilotCancel() but agent updates are disabled" , Helpers . LogLevel . Warning , Client ) ;
2007-11-06 09:26:10 +00:00
return false ;
}
}
#endregion Movement actions
#region Touch and grab
2019-10-08 19:08:50 -05:00
public static readonly Vector3 TOUCH_INVALID_TEXCOORD = new Vector3 ( - 1.0f , - 1.0f , 0.0f ) ;
public static readonly Vector3 TOUCH_INVALID_VECTOR = Vector3 . Zero ;
2019-10-08 16:02:43 -05:00
2007-11-06 09:26:10 +00:00
/// <summary>
/// Grabs an object
/// </summary>
2008-05-01 10:48:09 +00:00
/// <param name="objectLocalID">an unsigned integer of the objects ID within the simulator</param>
2009-11-03 05:32:49 +00:00
/// <seealso cref="Simulator.ObjectsPrimitives"/>
2007-11-06 09:26:10 +00:00
public void Grab ( uint objectLocalID )
2009-05-30 23:14:31 +00:00
{
2019-10-08 16:02:43 -05:00
Grab ( objectLocalID , Vector3 . Zero , TOUCH_INVALID_TEXCOORD , TOUCH_INVALID_TEXCOORD ,
2019-10-08 19:08:50 -05:00
0 , TOUCH_INVALID_VECTOR , TOUCH_INVALID_VECTOR , TOUCH_INVALID_VECTOR ) ;
2009-05-30 23:14:31 +00:00
}
/// <summary>
/// Overload: Grab a simulated object
/// </summary>
/// <param name="objectLocalID">an unsigned integer of the objects ID within the simulator</param>
/// <param name="grabOffset"></param>
2009-11-03 05:32:49 +00:00
/// <param name="uvCoord">The texture coordinates to grab</param>
/// <param name="stCoord">The surface coordinates to grab</param>
/// <param name="faceIndex">The face of the position to grab</param>
/// <param name="position">The region coordinates of the position to grab</param>
2019-10-08 16:02:43 -05:00
/// <param name="normal">The surface normal of the position to grab (A normal is a vector perpendicular to the surface)</param>
/// <param name="binormal">The surface bi-normal of the position to grab (A bi-normal is a vector tangent to the surface
2009-11-03 05:32:49 +00:00
/// pointing along the U direction of the tangent space</param>
2019-10-08 16:02:43 -05:00
public void Grab ( uint objectLocalID , Vector3 grabOffset , Vector3 uvCoord , Vector3 stCoord ,
int faceIndex , Vector3 position , Vector3 normal , Vector3 binormal )
2007-11-06 09:26:10 +00:00
{
2016-11-27 22:05:54 -06:00
ObjectGrabPacket grab = new ObjectGrabPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
ObjectData =
{
LocalID = objectLocalID ,
GrabOffset = grabOffset
} ,
SurfaceInfo = new ObjectGrabPacket . SurfaceInfoBlock [ 1 ]
} ;
2009-05-30 23:14:31 +00:00
2016-11-27 22:05:54 -06:00
grab . SurfaceInfo [ 0 ] = new ObjectGrabPacket . SurfaceInfoBlock
{
UVCoord = uvCoord ,
STCoord = stCoord ,
FaceIndex = faceIndex ,
Position = position ,
Normal = normal ,
Binormal = binormal
} ;
2009-05-30 23:14:31 +00:00
2007-11-06 09:26:10 +00:00
Client . Network . SendPacket ( grab ) ;
}
/// <summary>
2009-05-30 23:14:31 +00:00
/// Drag an object
2007-11-06 09:26:10 +00:00
/// </summary>
2008-07-28 08:28:16 +00:00
/// <param name="objectID"><seealso cref="UUID"/> of the object to drag</param>
2007-11-06 09:26:10 +00:00
/// <param name="grabPosition">Drag target in region coordinates</param>
2008-07-25 05:15:05 +00:00
public void GrabUpdate ( UUID objectID , Vector3 grabPosition )
2009-05-30 23:14:31 +00:00
{
2019-10-08 16:02:43 -05:00
GrabUpdate ( objectID , grabPosition , Vector3 . Zero , Vector3 . Zero , Vector3 . Zero ,
0 , Vector3 . Zero , Vector3 . Zero , Vector3 . Zero ) ;
2009-05-30 23:14:31 +00:00
}
/// <summary>
/// Overload: Drag an object
/// </summary>
/// <param name="objectID"><seealso cref="UUID"/> of the object to drag</param>
/// <param name="grabPosition">Drag target in region coordinates</param>
/// <param name="grabOffset"></param>
2009-11-03 05:32:49 +00:00
/// <param name="uvCoord">The texture coordinates to grab</param>
/// <param name="stCoord">The surface coordinates to grab</param>
/// <param name="faceIndex">The face of the position to grab</param>
/// <param name="position">The region coordinates of the position to grab</param>
2019-10-08 16:02:43 -05:00
/// <param name="normal">The surface normal of the position to grab (A normal is a vector perpendicular to the surface)</param>
/// <param name="binormal">The surface bi-normal of the position to grab (A bi-normal is a vector tangent to the surface
2009-11-03 05:32:49 +00:00
/// pointing along the U direction of the tangent space</param>
2019-10-08 16:02:43 -05:00
public void GrabUpdate ( UUID objectID , Vector3 grabPosition , Vector3 grabOffset , Vector3 uvCoord , Vector3 stCoord ,
int faceIndex , Vector3 position , Vector3 normal , Vector3 binormal )
2007-11-06 09:26:10 +00:00
{
2016-11-27 22:05:54 -06:00
ObjectGrabUpdatePacket grab = new ObjectGrabUpdatePacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
ObjectData =
{
ObjectID = objectID ,
GrabOffsetInitial = grabOffset ,
GrabPosition = grabPosition ,
TimeSinceLast = 0
} ,
SurfaceInfo = new ObjectGrabUpdatePacket . SurfaceInfoBlock [ 1 ]
} ;
2009-05-30 23:14:31 +00:00
2016-11-27 22:05:54 -06:00
grab . SurfaceInfo [ 0 ] = new ObjectGrabUpdatePacket . SurfaceInfoBlock
{
UVCoord = uvCoord ,
STCoord = stCoord ,
FaceIndex = faceIndex ,
Position = position ,
Normal = normal ,
Binormal = binormal
} ;
2009-05-30 23:14:31 +00:00
2007-11-06 09:26:10 +00:00
Client . Network . SendPacket ( grab ) ;
}
/// <summary>
2009-05-30 23:14:31 +00:00
/// Release a grabbed object
2007-11-06 09:26:10 +00:00
/// </summary>
2008-07-28 08:28:16 +00:00
/// <param name="objectLocalID">The Objects Simulator Local ID</param>
2009-11-03 05:32:49 +00:00
/// <seealso cref="Simulator.ObjectsPrimitives"/>
2021-12-29 12:15:50 -06:00
/// <seealso cref="AgentManager.Grab"/>
/// <seealso cref="AgentManager.GrabUpdate"/>
2007-11-06 09:26:10 +00:00
public void DeGrab ( uint objectLocalID )
2009-05-30 23:14:31 +00:00
{
2019-10-08 16:02:43 -05:00
DeGrab ( objectLocalID , TOUCH_INVALID_TEXCOORD , TOUCH_INVALID_TEXCOORD ,
2019-10-08 19:08:50 -05:00
0 , TOUCH_INVALID_VECTOR , TOUCH_INVALID_VECTOR , TOUCH_INVALID_VECTOR ) ;
2009-05-30 23:14:31 +00:00
}
/// <summary>
/// Release a grabbed object
/// </summary>
/// <param name="objectLocalID">The Objects Simulator Local ID</param>
2009-11-03 05:32:49 +00:00
/// <param name="uvCoord">The texture coordinates to grab</param>
/// <param name="stCoord">The surface coordinates to grab</param>
/// <param name="faceIndex">The face of the position to grab</param>
/// <param name="position">The region coordinates of the position to grab</param>
2019-10-08 16:02:43 -05:00
/// <param name="normal">The surface normal of the position to grab (A normal is a vector perpendicular to the surface)</param>
/// <param name="binormal">The surface bi-normal of the position to grab (A bi-normal is a vector tangent to the surface
2009-11-03 05:32:49 +00:00
/// pointing along the U direction of the tangent space</param>
2019-10-08 16:02:43 -05:00
public void DeGrab ( uint objectLocalID , Vector3 uvCoord , Vector3 stCoord ,
int faceIndex , Vector3 position , Vector3 normal , Vector3 binormal )
2007-11-06 09:26:10 +00:00
{
2016-11-27 22:05:54 -06:00
ObjectDeGrabPacket degrab = new ObjectDeGrabPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
ObjectData = { LocalID = objectLocalID } ,
SurfaceInfo = new ObjectDeGrabPacket . SurfaceInfoBlock [ 1 ]
} ;
2009-05-30 23:14:31 +00:00
2009-10-16 02:53:53 +00:00
2016-11-27 22:05:54 -06:00
degrab . SurfaceInfo [ 0 ] = new ObjectDeGrabPacket . SurfaceInfoBlock
{
UVCoord = uvCoord ,
STCoord = stCoord ,
FaceIndex = faceIndex ,
Position = position ,
Normal = normal ,
Binormal = binormal
} ;
2009-05-30 23:14:31 +00:00
2007-11-06 09:26:10 +00:00
Client . Network . SendPacket ( degrab ) ;
}
/// <summary>
/// Touches an object
/// </summary>
2008-05-01 10:48:09 +00:00
/// <param name="objectLocalID">an unsigned integer of the objects ID within the simulator</param>
2009-11-03 05:32:49 +00:00
/// <seealso cref="Simulator.ObjectsPrimitives"/>
2007-11-06 09:26:10 +00:00
public void Touch ( uint objectLocalID )
{
Client . Self . Grab ( objectLocalID ) ;
Client . Self . DeGrab ( objectLocalID ) ;
}
#endregion Touch and grab
#region Money
/// <summary>
/// Request the current L$ balance
/// </summary>
public void RequestBalance ( )
{
2016-11-27 22:05:54 -06:00
MoneyBalanceRequestPacket money = new MoneyBalanceRequestPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
MoneyData = { TransactionID = UUID . Zero }
} ;
2007-11-06 09:26:10 +00:00
Client . Network . SendPacket ( money ) ;
}
2007-03-09 20:26:07 +00:00
/// <summary>
/// Give Money to destination Avatar
/// </summary>
/// <param name="target">UUID of the Target Avatar</param>
/// <param name="amount">Amount in L$</param>
2008-07-25 05:15:05 +00:00
public void GiveAvatarMoney ( UUID target , int amount )
2007-03-09 20:26:07 +00:00
{
2016-11-27 22:05:54 -06:00
GiveMoney ( target , amount , string . Empty , MoneyTransactionType . Gift , TransactionFlags . None ) ;
2007-09-05 01:21:36 +00:00
}
/// <summary>
/// Give Money to destination Avatar
/// </summary>
/// <param name="target">UUID of the Target Avatar</param>
/// <param name="amount">Amount in L$</param>
/// <param name="description">Description that will show up in the
/// recipients transaction history</param>
2008-07-25 05:15:05 +00:00
public void GiveAvatarMoney ( UUID target , int amount , string description )
2007-09-05 01:21:36 +00:00
{
GiveMoney ( target , amount , description , MoneyTransactionType . Gift , TransactionFlags . None ) ;
}
/// <summary>
2008-03-15 09:16:38 +00:00
/// Give L$ to an object
2007-09-05 01:21:36 +00:00
/// </summary>
2008-07-28 08:28:16 +00:00
/// <param name="target">object <seealso cref="UUID"/> to give money to</param>
2008-03-15 09:16:38 +00:00
/// <param name="amount">amount of L$ to give</param>
/// <param name="objectName">name of object</param>
2008-07-25 05:15:05 +00:00
public void GiveObjectMoney ( UUID target , int amount , string objectName )
2007-09-05 01:21:36 +00:00
{
GiveMoney ( target , amount , objectName , MoneyTransactionType . PayObject , TransactionFlags . None ) ;
}
/// <summary>
2008-03-15 09:16:38 +00:00
/// Give L$ to a group
2007-09-05 01:21:36 +00:00
/// </summary>
2008-07-28 08:28:16 +00:00
/// <param name="target">group <seealso cref="UUID"/> to give money to</param>
2008-03-15 09:16:38 +00:00
/// <param name="amount">amount of L$ to give</param>
2008-07-25 05:15:05 +00:00
public void GiveGroupMoney ( UUID target , int amount )
2007-09-05 01:21:36 +00:00
{
2016-11-27 22:05:54 -06:00
GiveMoney ( target , amount , string . Empty , MoneyTransactionType . Gift , TransactionFlags . DestGroup ) ;
2007-09-05 01:21:36 +00:00
}
/// <summary>
2008-03-15 09:16:38 +00:00
/// Give L$ to a group
2007-09-05 01:21:36 +00:00
/// </summary>
2008-07-28 08:28:16 +00:00
/// <param name="target">group <seealso cref="UUID"/> to give money to</param>
2008-03-15 09:16:38 +00:00
/// <param name="amount">amount of L$ to give</param>
/// <param name="description">description of transaction</param>
2008-07-25 05:15:05 +00:00
public void GiveGroupMoney ( UUID target , int amount , string description )
2007-09-05 01:21:36 +00:00
{
GiveMoney ( target , amount , description , MoneyTransactionType . Gift , TransactionFlags . DestGroup ) ;
}
/// <summary>
2008-03-15 09:16:38 +00:00
/// Pay texture/animation upload fee
2007-09-05 01:21:36 +00:00
/// </summary>
public void PayUploadFee ( )
{
2016-11-27 22:05:54 -06:00
GiveMoney ( UUID . Zero , Client . Settings . UPLOAD_COST , string . Empty , MoneyTransactionType . UploadCharge ,
2007-09-05 01:21:36 +00:00
TransactionFlags . None ) ;
}
/// <summary>
2008-03-15 09:16:38 +00:00
/// Pay texture/animation upload fee
2007-09-05 01:21:36 +00:00
/// </summary>
2008-03-15 09:16:38 +00:00
/// <param name="description">description of the transaction</param>
2007-09-05 01:21:36 +00:00
public void PayUploadFee ( string description )
{
2008-09-09 04:58:58 +00:00
GiveMoney ( UUID . Zero , Client . Settings . UPLOAD_COST , description , MoneyTransactionType . UploadCharge ,
2007-09-05 01:21:36 +00:00
TransactionFlags . None ) ;
2007-03-09 20:26:07 +00:00
}
/// <summary>
2009-10-16 02:53:53 +00:00
/// Give Money to destination Object or Avatar
2007-03-09 20:26:07 +00:00
/// </summary>
/// <param name="target">UUID of the Target Object/Avatar</param>
/// <param name="amount">Amount in L$</param>
/// <param name="description">Reason (Optional normally)</param>
2007-09-05 01:21:36 +00:00
/// <param name="type">The type of transaction</param>
/// <param name="flags">Transaction flags, mostly for identifying group
/// transactions</param>
2008-07-25 05:15:05 +00:00
public void GiveMoney ( UUID target , int amount , string description , MoneyTransactionType type , TransactionFlags flags )
2007-03-09 20:26:07 +00:00
{
2016-11-27 22:05:54 -06:00
MoneyTransferRequestPacket money = new MoneyTransferRequestPacket
{
AgentData =
{
2021-12-09 14:21:48 -06:00
AgentID = AgentID ,
2016-11-27 22:05:54 -06:00
SessionID = Client . Self . SessionID
} ,
MoneyData =
{
Description = Utils . StringToBytes ( description ) ,
DestID = target ,
2021-12-09 14:21:48 -06:00
SourceID = AgentID ,
2016-11-27 22:05:54 -06:00
TransactionType = ( int ) type ,
AggregatePermInventory = 0 ,
AggregatePermNextOwner = 0 ,
Flags = ( byte ) flags ,
Amount = amount
}
} ;
// This is weird, apparently always set to zero though
// This is weird, apparently always set to zero though
2007-03-09 20:26:07 +00:00
Client . Network . SendPacket ( money ) ;
}
2007-11-06 09:26:10 +00:00
#endregion Money
2009-07-12 15:41:22 +00:00
#region Gestures
/// <summary>
/// Plays a gesture
/// </summary>
2009-07-16 08:25:44 +00:00
/// <param name="gestureID">Asset <seealso cref="UUID"/> of the gesture</param>
2009-07-12 15:41:22 +00:00
public void PlayGesture ( UUID gestureID )
{
2019-10-20 23:56:44 -05:00
ThreadPool . QueueUserWorkItem ( ( _ ) = >
2016-11-27 22:05:54 -06:00
{
// First fetch the guesture
AssetGesture gesture = null ;
2009-07-12 15:41:22 +00:00
2016-11-27 22:05:54 -06:00
if ( gestureCache . ContainsKey ( gestureID ) )
{
gesture = gestureCache [ gestureID ] ;
}
else
{
AutoResetEvent gotAsset = new AutoResetEvent ( false ) ;
2009-07-19 03:38:27 +00:00
2016-11-27 22:05:54 -06:00
Client . Assets . RequestAsset ( gestureID , AssetType . Gesture , true ,
delegate ( AssetDownload transfer , Asset asset )
{
if ( transfer . Success )
{
gesture = ( AssetGesture ) asset ;
}
2009-07-19 03:38:27 +00:00
2016-11-27 22:05:54 -06:00
gotAsset . Set ( ) ;
}
) ;
2009-07-19 03:38:27 +00:00
2016-11-27 22:05:54 -06:00
gotAsset . WaitOne ( 30 * 1000 , false ) ;
2009-07-12 15:41:22 +00:00
2016-11-27 22:05:54 -06:00
if ( gesture ! = null & & gesture . Decode ( ) )
{
lock ( gestureCache )
2009-07-12 16:44:07 +00:00
{
2016-11-27 22:05:54 -06:00
if ( ! gestureCache . ContainsKey ( gestureID ) )
2009-07-12 16:44:07 +00:00
{
2016-11-27 22:05:54 -06:00
gestureCache [ gestureID ] = gesture ;
2009-07-12 16:44:07 +00:00
}
}
}
2016-11-27 22:05:54 -06:00
}
2009-07-12 15:41:22 +00:00
2016-11-27 22:05:54 -06:00
// We got it, now we play it
if ( gesture = = null ) return ;
foreach ( GestureStep step in gesture . Sequence )
{
switch ( step . GestureStepType )
2009-07-12 15:41:22 +00:00
{
2016-11-27 22:05:54 -06:00
case GestureStepType . Chat :
string text = ( ( GestureStepChat ) step ) . Text ;
int channel = 0 ;
Match m ;
if (
( m =
Regex . Match ( text , @"^/(?<channel>-?[0-9]+)\s*(?<text>.*)" ,
RegexOptions . CultureInvariant ) ) . Success )
2009-07-12 15:41:22 +00:00
{
2016-11-27 22:05:54 -06:00
if ( int . TryParse ( m . Groups [ "channel" ] . Value , out channel ) )
{
text = m . Groups [ "text" ] . Value ;
}
}
2015-07-21 22:37:19 -04:00
2016-11-27 22:05:54 -06:00
Chat ( text , channel , ChatType . Normal ) ;
break ;
2009-07-12 15:41:22 +00:00
2016-11-27 22:05:54 -06:00
case GestureStepType . Animation :
GestureStepAnimation anim = ( GestureStepAnimation ) step ;
2009-07-12 15:41:22 +00:00
2016-11-27 22:05:54 -06:00
if ( anim . AnimationStart )
{
if ( SignaledAnimations . ContainsKey ( anim . ID ) )
{
AnimationStop ( anim . ID , true ) ;
}
AnimationStart ( anim . ID , true ) ;
}
else
{
AnimationStop ( anim . ID , true ) ;
}
break ;
2009-07-12 15:41:22 +00:00
2016-11-27 22:05:54 -06:00
case GestureStepType . Sound :
Client . Sound . PlaySound ( ( ( GestureStepSound ) step ) . ID ) ;
break ;
2009-07-12 15:41:22 +00:00
2016-11-27 22:05:54 -06:00
case GestureStepType . Wait :
GestureStepWait wait = ( GestureStepWait ) step ;
if ( wait . WaitForTime )
{
Thread . Sleep ( ( int ) ( 1000f * wait . WaitTime ) ) ;
2009-07-12 15:41:22 +00:00
}
2016-11-27 22:05:54 -06:00
if ( wait . WaitForAnimation )
{
// TODO: implement waiting for all animations to end that were triggered
// during playing of this guesture sequence
}
break ;
2009-07-12 15:41:22 +00:00
}
2016-11-27 22:05:54 -06:00
}
2019-10-20 23:56:44 -05:00
} ) ;
2009-07-12 15:41:22 +00:00
}
2009-07-12 21:07:49 +00:00
/// <summary>
/// Mark gesture active
/// </summary>
/// <param name="invID">Inventory <seealso cref="UUID"/> of the gesture</param>
/// <param name="assetID">Asset <seealso cref="UUID"/> of the gesture</param>
public void ActivateGesture ( UUID invID , UUID assetID )
{
2016-11-27 22:05:54 -06:00
ActivateGesturesPacket packet = new ActivateGesturesPacket
{
AgentData =
{
AgentID = AgentID ,
SessionID = SessionID ,
Flags = 0x00
}
} ;
2009-07-12 21:07:49 +00:00
2016-11-27 22:05:54 -06:00
ActivateGesturesPacket . DataBlock block = new ActivateGesturesPacket . DataBlock
{
ItemID = invID ,
AssetID = assetID ,
GestureFlags = 0x00
} ;
2009-07-12 21:07:49 +00:00
2016-11-27 22:05:54 -06:00
packet . Data = new ActivateGesturesPacket . DataBlock [ 1 ] ;
packet . Data [ 0 ] = block ;
2009-07-12 21:07:49 +00:00
2016-11-27 22:05:54 -06:00
Client . Network . SendPacket ( packet ) ;
2017-07-08 16:10:45 -04:00
ActiveGestures [ invID ] = assetID ;
2009-07-12 21:07:49 +00:00
}
/// <summary>
/// Mark gesture inactive
/// </summary>
/// <param name="invID">Inventory <seealso cref="UUID"/> of the gesture</param>
public void DeactivateGesture ( UUID invID )
{
2016-11-27 22:05:54 -06:00
DeactivateGesturesPacket p = new DeactivateGesturesPacket
{
AgentData =
{
AgentID = AgentID ,
SessionID = SessionID ,
Flags = 0x00
}
} ;
2009-07-12 21:07:49 +00:00
2016-11-27 22:05:54 -06:00
DeactivateGesturesPacket . DataBlock b = new DeactivateGesturesPacket . DataBlock
{
ItemID = invID ,
GestureFlags = 0x00
} ;
2009-07-12 21:07:49 +00:00
p . Data = new DeactivateGesturesPacket . DataBlock [ 1 ] ;
p . Data [ 0 ] = b ;
Client . Network . SendPacket ( p ) ;
2017-07-08 16:10:45 -04:00
ActiveGestures . Remove ( invID ) ;
2009-07-12 21:07:49 +00:00
}
2009-07-12 15:41:22 +00:00
#endregion
2007-11-06 09:26:10 +00:00
#region Animations
2007-03-09 20:26:07 +00:00
/// <summary>
/// Send an AgentAnimation packet that toggles a single animation on
/// </summary>
2008-07-28 08:28:16 +00:00
/// <param name="animation">The <seealso cref="UUID"/> of the animation to start playing</param>
2008-01-03 21:14:01 +00:00
/// <param name="reliable">Whether to ensure delivery of this packet or not</param>
2008-07-25 05:15:05 +00:00
public void AnimationStart ( UUID animation , bool reliable )
2007-03-09 20:26:07 +00:00
{
2016-11-27 22:05:54 -06:00
var animations = new Dictionary < UUID , bool > { [ animation ] = true } ;
2007-03-09 20:26:07 +00:00
2008-01-03 21:14:01 +00:00
Animate ( animations , reliable ) ;
2007-03-09 20:26:07 +00:00
}
/// <summary>
/// Send an AgentAnimation packet that toggles a single animation off
/// </summary>
2008-07-28 08:28:16 +00:00
/// <param name="animation">The <seealso cref="UUID"/> of a
2008-03-15 09:16:38 +00:00
/// currently playing animation to stop playing</param>
2008-01-03 21:14:01 +00:00
/// <param name="reliable">Whether to ensure delivery of this packet or not</param>
2008-07-25 05:15:05 +00:00
public void AnimationStop ( UUID animation , bool reliable )
2007-03-09 20:26:07 +00:00
{
2016-11-27 22:05:54 -06:00
var animations = new Dictionary < UUID , bool > { [ animation ] = false } ;
2007-03-09 20:26:07 +00:00
2008-01-03 21:14:01 +00:00
Animate ( animations , reliable ) ;
2007-03-09 20:26:07 +00:00
}
/// <summary>
/// Send an AgentAnimation packet that will toggle animations on or off
/// </summary>
2008-07-28 08:28:16 +00:00
/// <param name="animations">A list of animation <seealso cref="UUID"/>s, and whether to
2007-03-09 20:26:07 +00:00
/// turn that animation on or off</param>
2008-01-03 21:14:01 +00:00
/// <param name="reliable">Whether to ensure delivery of this packet or not</param>
2008-07-25 05:15:05 +00:00
public void Animate ( Dictionary < UUID , bool > animations , bool reliable )
2007-03-09 20:26:07 +00:00
{
2016-11-27 22:05:54 -06:00
AgentAnimationPacket animate = new AgentAnimationPacket
{
Header = { Reliable = reliable } ,
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
AnimationList = new AgentAnimationPacket . AnimationListBlock [ animations . Count ]
} ;
2007-03-09 20:26:07 +00:00
int i = 0 ;
2016-11-27 22:05:54 -06:00
foreach ( var animation in animations )
2007-03-09 20:26:07 +00:00
{
2016-11-27 22:05:54 -06:00
animate . AnimationList [ i ] = new AgentAnimationPacket . AnimationListBlock
{
AnimID = animation . Key ,
StartAnim = animation . Value
} ;
2007-03-09 20:26:07 +00:00
i + + ;
}
2009-06-16 19:16:38 +00:00
// TODO: Implement support for this
2022-04-19 18:22:05 -05:00
animate . PhysicalAvatarEventList = Array . Empty < AgentAnimationPacket . PhysicalAvatarEventListBlock > ( ) ;
2009-06-16 19:16:38 +00:00
2007-03-09 20:26:07 +00:00
Client . Network . SendPacket ( animate ) ;
}
2007-11-06 09:26:10 +00:00
#endregion Animations
2007-03-09 20:26:07 +00:00
2007-11-06 09:26:10 +00:00
#region Teleporting
2007-03-09 20:26:07 +00:00
/// <summary>
2008-03-15 09:16:38 +00:00
/// Teleports agent to their stored home location
2007-03-09 20:26:07 +00:00
/// </summary>
2008-05-01 10:48:09 +00:00
/// <returns>true on successful teleport to home location</returns>
2007-11-06 09:26:10 +00:00
public bool GoHome ( )
2007-03-09 20:26:07 +00:00
{
2008-07-25 05:15:05 +00:00
return Teleport ( UUID . Zero ) ;
2007-07-27 21:30:55 +00:00
}
2008-09-09 04:58:58 +00:00
/// <summary>
/// Teleport agent to a landmark
/// </summary>
/// <param name="landmark"><seealso cref="UUID"/> of the landmark to teleport agent to</param>
/// <returns>true on success, false on failure</returns>
public bool Teleport ( UUID landmark )
{
teleportStat = TeleportStatus . None ;
2007-11-06 09:26:10 +00:00
teleportEvent . Reset ( ) ;
2016-11-27 22:05:54 -06:00
TeleportLandmarkRequestPacket p = new TeleportLandmarkRequestPacket
{
Info = new TeleportLandmarkRequestPacket . InfoBlock
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID ,
LandmarkID = landmark
}
} ;
2008-09-09 04:58:58 +00:00
Client . Network . SendPacket ( p ) ;
2007-05-21 05:52:28 +00:00
2007-11-06 09:26:10 +00:00
teleportEvent . WaitOne ( Client . Settings . TELEPORT_TIMEOUT , false ) ;
2007-05-21 05:52:28 +00:00
2007-11-06 09:26:10 +00:00
if ( teleportStat = = TeleportStatus . None | |
teleportStat = = TeleportStatus . Start | |
teleportStat = = TeleportStatus . Progress )
2007-05-21 05:52:28 +00:00
{
2021-12-09 14:21:48 -06:00
TeleportMessage = "Teleport timed out." ;
2007-11-06 09:26:10 +00:00
teleportStat = TeleportStatus . Failed ;
2007-05-21 05:52:28 +00:00
}
2007-11-06 09:26:10 +00:00
return ( teleportStat = = TeleportStatus . Finished ) ;
2008-09-09 04:58:58 +00:00
}
2007-11-06 09:26:10 +00:00
2007-03-09 20:26:07 +00:00
/// <summary>
/// Attempt to look up a simulator name and teleport to the discovered
/// destination
/// </summary>
/// <param name="simName">Region name to look up</param>
/// <param name="position">Position to teleport to</param>
/// <returns>True if the lookup and teleport were successful, otherwise
/// false</returns>
2008-07-25 05:15:05 +00:00
public bool Teleport ( string simName , Vector3 position )
2007-03-09 20:26:07 +00:00
{
2008-07-25 05:15:05 +00:00
return Teleport ( simName , position , new Vector3 ( 0 , 1.0f , 0 ) ) ;
2007-03-09 20:26:07 +00:00
}
/// <summary>
/// Attempt to look up a simulator name and teleport to the discovered
/// destination
/// </summary>
/// <param name="simName">Region name to look up</param>
/// <param name="position">Position to teleport to</param>
/// <param name="lookAt">Target to look at</param>
/// <returns>True if the lookup and teleport were successful, otherwise
/// false</returns>
2008-07-25 05:15:05 +00:00
public bool Teleport ( string simName , Vector3 position , Vector3 lookAt )
2007-03-09 20:26:07 +00:00
{
2022-11-06 21:21:53 -06:00
if ( Client . Network . CurrentSim = = null ) { return false ; }
2009-03-11 00:09:47 +00:00
2007-11-06 09:26:10 +00:00
teleportStat = TeleportStatus . None ;
2007-03-09 20:26:07 +00:00
2009-06-27 22:13:22 +00:00
if ( simName ! = Client . Network . CurrentSim . Name )
2007-03-09 20:26:07 +00:00
{
// Teleporting to a foreign sim
2022-11-06 21:21:53 -06:00
if ( Client . Grid . GetGridRegion ( simName , GridLayerType . Objects , out var region ) )
2007-03-09 20:26:07 +00:00
{
return Teleport ( region . RegionHandle , position , lookAt ) ;
}
else
{
2022-11-06 21:21:53 -06:00
TeleportMessage = $"Unable to resolve simulator named: {simName}" ;
2007-11-06 09:26:10 +00:00
teleportStat = TeleportStatus . Failed ;
2007-03-09 20:26:07 +00:00
return false ;
}
}
else
{
// Teleporting to the sim we're already in
return Teleport ( Client . Network . CurrentSim . Handle , position , lookAt ) ;
}
}
/// <summary>
2008-03-15 09:16:38 +00:00
/// Teleport agent to another region
2007-03-09 20:26:07 +00:00
/// </summary>
2008-03-15 09:16:38 +00:00
/// <param name="regionHandle">handle of region to teleport agent to</param>
2008-07-28 08:28:16 +00:00
/// <param name="position"><seealso cref="Vector3"/> position in destination sim to teleport to</param>
2008-03-15 09:16:38 +00:00
/// <returns>true on success, false on failure</returns>
/// <remarks>This call is blocking</remarks>
2008-07-25 05:15:05 +00:00
public bool Teleport ( ulong regionHandle , Vector3 position )
2007-03-09 20:26:07 +00:00
{
2008-07-25 05:15:05 +00:00
return Teleport ( regionHandle , position , new Vector3 ( 0.0f , 1.0f , 0.0f ) ) ;
2007-03-09 20:26:07 +00:00
}
/// <summary>
2008-03-15 09:16:38 +00:00
/// Teleport agent to another region
2007-03-09 20:26:07 +00:00
/// </summary>
2008-03-15 09:16:38 +00:00
/// <param name="regionHandle">handle of region to teleport agent to</param>
2008-07-28 08:28:16 +00:00
/// <param name="position"><seealso cref="Vector3"/> position in destination sim to teleport to</param>
/// <param name="lookAt"><seealso cref="Vector3"/> direction in destination sim agent will look at</param>
2008-03-15 09:16:38 +00:00
/// <returns>true on success, false on failure</returns>
/// <remarks>This call is blocking</remarks>
2008-07-25 05:15:05 +00:00
public bool Teleport ( ulong regionHandle , Vector3 position , Vector3 lookAt )
2007-03-09 20:26:07 +00:00
{
2008-10-11 00:17:21 +00:00
if ( Client . Network . CurrentSim = = null | |
Client . Network . CurrentSim . Caps = = null | |
! Client . Network . CurrentSim . Caps . IsEventQueueRunning )
{
// Wait a bit to see if the event queue comes online
AutoResetEvent queueEvent = new AutoResetEvent ( false ) ;
2009-10-28 08:01:52 +00:00
EventHandler < EventQueueRunningEventArgs > queueCallback =
delegate ( object sender , EventQueueRunningEventArgs e )
2008-10-11 00:17:21 +00:00
{
2009-10-28 08:01:52 +00:00
if ( e . Simulator = = Client . Network . CurrentSim )
2008-10-11 00:17:21 +00:00
queueEvent . Set ( ) ;
} ;
2010-03-31 11:47:52 +00:00
2009-10-28 08:01:52 +00:00
Client . Network . EventQueueRunning + = queueCallback ;
2008-10-11 00:17:21 +00:00
queueEvent . WaitOne ( 10 * 1000 , false ) ;
2009-10-28 08:01:52 +00:00
Client . Network . EventQueueRunning - = queueCallback ;
2008-10-11 00:17:21 +00:00
}
2007-11-06 09:26:10 +00:00
teleportStat = TeleportStatus . None ;
teleportEvent . Reset ( ) ;
2007-03-09 20:26:07 +00:00
RequestTeleport ( regionHandle , position , lookAt ) ;
2007-11-06 09:26:10 +00:00
teleportEvent . WaitOne ( Client . Settings . TELEPORT_TIMEOUT , false ) ;
2007-03-09 20:26:07 +00:00
2007-11-06 09:26:10 +00:00
if ( teleportStat = = TeleportStatus . None | |
teleportStat = = TeleportStatus . Start | |
teleportStat = = TeleportStatus . Progress )
2007-03-09 20:26:07 +00:00
{
2021-12-09 14:21:48 -06:00
TeleportMessage = "Teleport timed out." ;
2007-11-06 09:26:10 +00:00
teleportStat = TeleportStatus . Failed ;
2007-03-09 20:26:07 +00:00
}
2007-11-06 09:26:10 +00:00
return ( teleportStat = = TeleportStatus . Finished ) ;
2007-03-09 20:26:07 +00:00
}
/// <summary>
2008-03-15 09:16:38 +00:00
/// Request teleport to a another simulator
2007-03-09 20:26:07 +00:00
/// </summary>
2008-03-15 09:16:38 +00:00
/// <param name="regionHandle">handle of region to teleport agent to</param>
2008-07-28 08:28:16 +00:00
/// <param name="position"><seealso cref="Vector3"/> position in destination sim to teleport to</param>
2008-07-25 05:15:05 +00:00
public void RequestTeleport ( ulong regionHandle , Vector3 position )
2007-03-09 20:26:07 +00:00
{
2008-07-25 05:15:05 +00:00
RequestTeleport ( regionHandle , position , new Vector3 ( 0.0f , 1.0f , 0.0f ) ) ;
2007-03-09 20:26:07 +00:00
}
/// <summary>
2022-11-06 21:21:53 -06:00
/// Request teleport to another region
2007-03-09 20:26:07 +00:00
/// </summary>
2008-03-15 09:16:38 +00:00
/// <param name="regionHandle">handle of region to teleport agent to</param>
2008-07-28 08:28:16 +00:00
/// <param name="position"><seealso cref="Vector3"/> position in destination sim to teleport to</param>
/// <param name="lookAt"><seealso cref="Vector3"/> direction in destination sim agent will look at</param>
2008-07-25 05:15:05 +00:00
public void RequestTeleport ( ulong regionHandle , Vector3 position , Vector3 lookAt )
2007-03-09 20:26:07 +00:00
{
2022-12-31 14:19:13 -06:00
if ( Client . Network ? . CurrentSim ? . Caps ! = null & &
2022-11-20 00:46:46 -06:00
Client . Network . CurrentSim . Caps . IsEventQueueRunning )
2007-04-15 07:37:53 +00:00
{
2022-11-06 21:21:53 -06:00
TeleportLocationRequestPacket teleport = new TeleportLocationRequestPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
Info =
{
LookAt = lookAt ,
Position = position ,
RegionHandle = regionHandle
}
} ;
2007-03-09 20:26:07 +00:00
2022-11-06 21:21:53 -06:00
Logger . Log ( $"Requesting teleport to region handle {regionHandle}" , Helpers . LogLevel . Info , Client ) ;
2007-03-09 20:26:07 +00:00
2007-04-15 07:37:53 +00:00
Client . Network . SendPacket ( teleport ) ;
}
else
{
2021-12-09 14:21:48 -06:00
TeleportMessage = "CAPS event queue is not running" ;
2007-11-06 09:26:10 +00:00
teleportEvent . Set ( ) ;
teleportStat = TeleportStatus . Failed ;
2007-04-15 07:37:53 +00:00
}
2007-03-09 20:26:07 +00:00
}
2008-04-06 01:57:08 +00:00
/// <summary>
/// Teleport agent to a landmark
/// </summary>
2008-07-28 08:28:16 +00:00
/// <param name="landmark"><seealso cref="UUID"/> of the landmark to teleport agent to</param>
2008-07-25 05:15:05 +00:00
public void RequestTeleport ( UUID landmark )
2008-04-06 01:57:08 +00:00
{
2016-11-27 22:05:54 -06:00
TeleportLandmarkRequestPacket p = new TeleportLandmarkRequestPacket
{
Info = new TeleportLandmarkRequestPacket . InfoBlock
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID ,
LandmarkID = landmark
}
} ;
2008-04-06 01:57:08 +00:00
Client . Network . SendPacket ( p ) ;
}
2008-03-15 09:16:38 +00:00
/// <summary>
/// Send a teleport lure to another avatar with default "Join me in ..." invitation message
/// </summary>
2008-07-28 08:28:16 +00:00
/// <param name="targetID">target avatars <seealso cref="UUID"/> to lure</param>
2008-07-25 05:15:05 +00:00
public void SendTeleportLure ( UUID targetID )
2007-05-04 07:10:40 +00:00
{
2022-11-06 21:21:53 -06:00
SendTeleportLure ( targetID , $"Join me in {Client.Network.CurrentSim.Name}!" ) ;
2007-05-04 07:10:40 +00:00
}
2008-03-15 09:16:38 +00:00
/// <summary>
/// Send a teleport lure to another avatar with custom invitation message
/// </summary>
2008-07-28 08:28:16 +00:00
/// <param name="targetID">target avatars <seealso cref="UUID"/> to lure</param>
2008-03-15 09:16:38 +00:00
/// <param name="message">custom message to send with invitation</param>
2008-07-25 05:15:05 +00:00
public void SendTeleportLure ( UUID targetID , string message )
2007-05-04 07:10:40 +00:00
{
2016-11-27 22:05:54 -06:00
StartLurePacket p = new StartLurePacket
{
AgentData =
{
2021-12-09 14:21:48 -06:00
AgentID = Client . Self . AgentID ,
2016-11-27 22:05:54 -06:00
SessionID = Client . Self . SessionID
} ,
Info =
{
LureType = 0 ,
Message = Utils . StringToBytes ( message )
} ,
TargetData = new [ ] { new StartLurePacket . TargetDataBlock ( ) }
} ;
2007-05-04 07:10:40 +00:00
p . TargetData [ 0 ] . TargetID = targetID ;
Client . Network . SendPacket ( p ) ;
}
2007-03-09 20:26:07 +00:00
/// <summary>
/// Respond to a teleport lure by either accepting it and initiating
/// the teleport, or denying it
/// </summary>
2008-07-28 08:28:16 +00:00
/// <param name="requesterID"><seealso cref="UUID"/> of the avatar sending the lure</param>
2010-10-21 13:30:55 +00:00
/// <param name="sessionID">IM session <seealso cref="UUID"/> of the incoming lure request</param>
2008-03-15 09:16:38 +00:00
/// <param name="accept">true to accept the lure, false to decline it</param>
2010-10-21 13:30:55 +00:00
public void TeleportLureRespond ( UUID requesterID , UUID sessionID , bool accept )
2007-03-09 20:26:07 +00:00
{
if ( accept )
{
2016-11-27 22:05:54 -06:00
TeleportLureRequestPacket lure = new TeleportLureRequestPacket
{
Info =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID ,
LureID = sessionID ,
TeleportFlags = ( uint ) TeleportFlags . ViaLure
}
} ;
2007-03-09 20:26:07 +00:00
Client . Network . SendPacket ( lure ) ;
}
2010-10-21 13:30:55 +00:00
else
{
2016-11-27 22:05:54 -06:00
InstantMessage ( Name , requesterID , string . Empty , sessionID , InstantMessageDialog . DenyTeleport ,
InstantMessageOnline . Offline , SimPosition , UUID . Zero , Utils . EmptyBytes ) ;
2010-10-21 13:30:55 +00:00
}
2007-03-09 20:26:07 +00:00
}
2020-05-10 16:54:03 -05:00
/// <summary>
/// Request a teleport lure from another agent
/// </summary>
/// <param name="targetID"><seealso cref="UUID"/> of the avatar lure is being requested from</param>
/// <param name="sessionID">IM session <seealso cref="UUID"/></param>
/// <param name="message">message to send with request</param>
public void SendTeleportLureRequest ( UUID targetID , UUID sessionID , string message )
2021-09-09 17:49:06 -05:00
{
2020-12-01 05:49:36 +00:00
if ( targetID ! = AgentID )
2021-09-09 17:49:06 -05:00
{
2020-12-01 05:49:36 +00:00
InstantMessage ( Name , targetID , message , sessionID , InstantMessageDialog . RequestLure ,
2021-09-09 17:49:06 -05:00
InstantMessageOnline . Online , SimPosition , UUID . Zero , Utils . EmptyBytes ) ;
2020-12-01 05:49:36 +00:00
}
}
public void SendTeleportLureRequest ( UUID targetID , string message )
{
SendTeleportLureRequest ( targetID , targetID , message ) ;
2021-09-09 17:49:06 -05:00
}
2020-12-01 05:49:36 +00:00
public void SendTeleportLureRequest ( UUID targetID )
2020-05-10 16:54:03 -05:00
{
2020-12-01 05:49:36 +00:00
SendTeleportLureRequest ( targetID , "Hi there I would like to teleport to you" ) ;
2020-05-10 16:54:03 -05:00
}
2007-11-06 09:26:10 +00:00
#endregion Teleporting
2007-09-11 03:00:13 +00:00
2007-11-06 09:26:10 +00:00
#region Misc
2007-03-09 20:26:07 +00:00
/// <summary>
2008-03-15 09:16:38 +00:00
/// Update agent profile
2007-05-21 19:57:37 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="profile"><seealso cref="OpenMetaverse.Avatar.AvatarProperties"/> struct containing updated
2008-03-15 09:16:38 +00:00
/// profile information</param>
2007-11-06 09:26:10 +00:00
public void UpdateProfile ( Avatar . AvatarProperties profile )
2007-05-21 19:57:37 +00:00
{
2016-11-27 22:05:54 -06:00
AvatarPropertiesUpdatePacket apup = new AvatarPropertiesUpdatePacket
{
AgentData =
{
2021-12-09 14:21:48 -06:00
AgentID = AgentID ,
SessionID = SessionID
2016-11-27 22:05:54 -06:00
} ,
PropertiesData =
{
AboutText = Utils . StringToBytes ( profile . AboutText ) ,
AllowPublish = profile . AllowPublish ,
FLAboutText = Utils . StringToBytes ( profile . FirstLifeText ) ,
FLImageID = profile . FirstLifeImage ,
ImageID = profile . ProfileImage ,
MaturePublish = profile . MaturePublish ,
ProfileURL = Utils . StringToBytes ( profile . ProfileURL )
}
} ;
2007-09-03 08:03:07 +00:00
2007-11-06 09:26:10 +00:00
Client . Network . SendPacket ( apup ) ;
2007-05-21 19:57:37 +00:00
}
2007-09-03 08:03:07 +00:00
/// <summary>
2021-09-17 09:53:34 -05:00
/// Update agent's profile interests
2007-09-03 08:03:07 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="interests">selection of interests from <seealso cref="T:OpenMetaverse.Avatar.Interests"/> struct</param>
2007-11-06 09:26:10 +00:00
public void UpdateInterests ( Avatar . Interests interests )
2007-09-03 08:03:07 +00:00
{
2016-11-27 22:05:54 -06:00
AvatarInterestsUpdatePacket aiup = new AvatarInterestsUpdatePacket
{
AgentData =
{
2021-12-09 14:21:48 -06:00
AgentID = AgentID ,
SessionID = SessionID
2016-11-27 22:05:54 -06:00
} ,
PropertiesData =
{
LanguagesText = Utils . StringToBytes ( interests . LanguagesText ) ,
SkillsMask = interests . SkillsMask ,
SkillsText = Utils . StringToBytes ( interests . SkillsText ) ,
WantToMask = interests . WantToMask ,
WantToText = Utils . StringToBytes ( interests . WantToText )
}
} ;
2007-09-03 08:03:07 +00:00
2007-11-06 09:26:10 +00:00
Client . Network . SendPacket ( aiup ) ;
2007-09-03 08:03:07 +00:00
}
2022-08-27 20:36:50 -05:00
/// <summary>
/// Update agent's private notes for target avatar
/// </summary>
/// <param name="target">target avatar for notes</param>
2021-09-17 09:53:34 -05:00
/// <param name="notes">notes to store</param>
2022-08-27 20:36:50 -05:00
public void UpdateProfileNotes ( UUID target , string notes )
{
AvatarNotesUpdatePacket anup = new AvatarNotesUpdatePacket
{
AgentData =
{
AgentID = AgentID ,
SessionID = SessionID
} ,
Data =
{
TargetID = target ,
Notes = Utils . StringToBytes ( notes )
}
} ;
Client . Network . SendPacket ( anup ) ;
2021-09-17 09:53:34 -05:00
}
2007-03-09 20:26:07 +00:00
/// <summary>
2007-11-06 09:26:10 +00:00
/// Set the height and the width of the client window. This is used
/// by the server to build a virtual camera frustum for our avatar
2007-03-09 20:26:07 +00:00
/// </summary>
2007-11-06 09:26:10 +00:00
/// <param name="height">New height of the viewer window</param>
/// <param name="width">New width of the viewer window</param>
public void SetHeightWidth ( ushort height , ushort width )
2007-03-09 20:26:07 +00:00
{
2016-11-27 22:05:54 -06:00
AgentHeightWidthPacket heightwidth = new AgentHeightWidthPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID ,
CircuitCode = Client . Network . CircuitCode
} ,
HeightWidthBlock =
{
Height = height ,
Width = width ,
GenCounter = heightWidthGenCounter + +
}
} ;
2007-03-09 20:26:07 +00:00
2007-11-06 09:26:10 +00:00
Client . Network . SendPacket ( heightwidth ) ;
2007-03-09 20:26:07 +00:00
}
/// <summary>
2008-03-15 09:16:38 +00:00
/// Request the list of muted objects and avatars for this agent
2007-03-09 20:26:07 +00:00
/// </summary>
2007-11-06 09:26:10 +00:00
public void RequestMuteList ( )
2007-03-09 20:26:07 +00:00
{
2016-11-27 22:05:54 -06:00
MuteListRequestPacket mute = new MuteListRequestPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
MuteData = { MuteCRC = 0 }
} ;
2007-03-09 20:26:07 +00:00
2007-11-06 09:26:10 +00:00
Client . Network . SendPacket ( mute ) ;
2007-03-09 20:26:07 +00:00
}
2011-03-05 23:48:49 +00:00
/// <summary>
/// Mute an object, resident, etc.
/// </summary>
/// <param name="type">Mute type</param>
/// <param name="id">Mute UUID</param>
/// <param name="name">Mute name</param>
public void UpdateMuteListEntry ( MuteType type , UUID id , string name )
{
UpdateMuteListEntry ( type , id , name , MuteFlags . Default ) ;
}
/// <summary>
/// Mute an object, resident, etc.
/// </summary>
/// <param name="type">Mute type</param>
/// <param name="id">Mute UUID</param>
/// <param name="name">Mute name</param>
/// <param name="flags">Mute flags</param>
public void UpdateMuteListEntry ( MuteType type , UUID id , string name , MuteFlags flags )
{
2016-11-27 22:05:54 -06:00
UpdateMuteListEntryPacket p = new UpdateMuteListEntryPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
MuteData =
{
MuteType = ( int ) type ,
MuteID = id ,
MuteName = Utils . StringToBytes ( name ) ,
MuteFlags = ( uint ) flags
}
} ;
2011-03-05 23:48:49 +00:00
Client . Network . SendPacket ( p ) ;
2016-11-27 22:05:54 -06:00
MuteEntry me = new MuteEntry
{
Type = type ,
ID = id ,
Name = name ,
Flags = flags
} ;
2011-03-05 23:48:49 +00:00
lock ( MuteList . Dictionary )
{
2016-11-27 22:05:54 -06:00
MuteList [ $"{me.ID}|{me.Name}" ] = me ;
2011-03-05 23:48:49 +00:00
}
OnMuteListUpdated ( EventArgs . Empty ) ;
}
/// <summary>
/// Unmute an object, resident, etc.
/// </summary>
/// <param name="id">Mute UUID</param>
/// <param name="name">Mute name</param>
public void RemoveMuteListEntry ( UUID id , string name )
{
2016-11-27 22:05:54 -06:00
RemoveMuteListEntryPacket p = new RemoveMuteListEntryPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
MuteData =
{
MuteID = id ,
MuteName = Utils . StringToBytes ( name )
}
} ;
2011-03-05 23:48:49 +00:00
Client . Network . SendPacket ( p ) ;
2016-11-27 22:05:54 -06:00
string listKey = $"{id}|{name}" ;
2011-03-05 23:48:49 +00:00
if ( MuteList . ContainsKey ( listKey ) )
{
lock ( MuteList . Dictionary )
{
MuteList . Remove ( listKey ) ;
}
OnMuteListUpdated ( EventArgs . Empty ) ;
}
}
2007-03-09 20:26:07 +00:00
/// <summary>
2008-03-15 09:16:38 +00:00
/// Sets home location to agents current position
/// </summary>
2008-07-21 21:12:59 +00:00
/// <remarks>will fire an AlertMessage (<seealso cref="E:OpenMetaverse.AgentManager.OnAlertMessage"/>) with
2008-03-15 09:16:38 +00:00
/// success or failure message</remarks>
2007-11-06 09:26:10 +00:00
public void SetHome ( )
2007-03-09 20:26:07 +00:00
{
2016-11-27 22:05:54 -06:00
SetStartLocationRequestPacket s = new SetStartLocationRequestPacket
{
AgentData = new SetStartLocationRequestPacket . AgentDataBlock
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
}
} ;
s . StartLocationData = new SetStartLocationRequestPacket . StartLocationDataBlock
{
LocationPos = Client . Self . SimPosition ,
LocationID = 1 ,
SimName = Utils . StringToBytes ( String . Empty ) ,
LocationLookAt = Movement . Camera . AtAxis
} ;
2007-11-06 09:26:10 +00:00
Client . Network . SendPacket ( s ) ;
2007-03-09 20:26:07 +00:00
}
/// <summary>
/// Move an agent in to a simulator. This packet is the last packet
/// needed to complete the transition in to a new simulator
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator"><seealso cref="T:OpenMetaverse.Simulator"/> Object</param>
2007-03-09 20:26:07 +00:00
public void CompleteAgentMovement ( Simulator simulator )
{
2016-11-27 22:05:54 -06:00
CompleteAgentMovementPacket move = new CompleteAgentMovementPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID ,
CircuitCode = Client . Network . CircuitCode
}
} ;
2007-03-09 20:26:07 +00:00
Client . Network . SendPacket ( move , simulator ) ;
}
2007-03-21 16:14:06 +00:00
/// <summary>
2008-01-12 03:10:39 +00:00
/// Reply to script permissions request
2007-03-21 16:14:06 +00:00
/// </summary>
2008-07-21 21:12:59 +00:00
/// <param name="simulator"><seealso cref="T:OpenMetaverse.Simulator"/> Object</param>
2008-07-28 08:28:16 +00:00
/// <param name="itemID"><seealso cref="UUID"/> of the itemID requesting permissions</param>
/// <param name="taskID"><seealso cref="UUID"/> of the taskID requesting permissions</param>
2008-07-21 21:12:59 +00:00
/// <param name="permissions"><seealso cref="OpenMetaverse.ScriptPermission"/> list of permissions to allow</param>
2008-07-25 05:15:05 +00:00
public void ScriptQuestionReply ( Simulator simulator , UUID itemID , UUID taskID , ScriptPermission permissions )
2007-03-21 16:14:06 +00:00
{
2016-11-27 22:05:54 -06:00
ScriptAnswerYesPacket yes = new ScriptAnswerYesPacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
Data =
{
ItemID = itemID ,
TaskID = taskID ,
Questions = ( int ) permissions
}
} ;
2007-03-21 16:14:06 +00:00
Client . Network . SendPacket ( yes , simulator ) ;
}
2008-02-28 21:24:42 +00:00
/// <summary>
/// Respond to a group invitation by either accepting or denying it
/// </summary>
/// <param name="groupID">UUID of the group (sent in the AgentID field of the invite message)</param>
/// <param name="imSessionID">IM Session ID from the group invitation message</param>
/// <param name="accept">Accept the group invitation or deny it</param>
2008-07-25 05:15:05 +00:00
public void GroupInviteRespond ( UUID groupID , UUID imSessionID , bool accept )
2008-02-28 21:24:42 +00:00
{
2016-11-27 22:05:54 -06:00
InstantMessage ( Name , groupID , string . Empty , imSessionID ,
2008-02-28 21:24:42 +00:00
accept ? InstantMessageDialog . GroupInvitationAccept : InstantMessageDialog . GroupInvitationDecline ,
2009-03-06 01:32:02 +00:00
InstantMessageOnline . Offline , Vector3 . Zero , UUID . Zero , Utils . EmptyBytes ) ;
2008-04-07 22:09:40 +00:00
}
2008-02-28 21:24:42 +00:00
2008-04-07 22:09:40 +00:00
/// <summary>
/// Requests script detection of objects and avatars
/// </summary>
/// <param name="name">name of the object/avatar to search for</param>
/// <param name="searchID">UUID of the object or avatar to search for</param>
/// <param name="type">Type of search from ScriptSensorTypeFlags</param>
/// <param name="range">range of scan (96 max?)</param>
/// <param name="arc">the arc in radians to search within</param>
/// <param name="requestID">an user generated ID to correlate replies with</param>
/// <param name="sim">Simulator to perform search in</param>
2008-07-25 05:15:05 +00:00
public void RequestScriptSensor ( string name , UUID searchID , ScriptSensorTypeFlags type , float range , float arc , UUID requestID , Simulator sim )
2008-04-07 22:09:40 +00:00
{
2016-11-27 22:05:54 -06:00
ScriptSensorRequestPacket request = new ScriptSensorRequestPacket
{
Requester =
{
Arc = arc ,
Range = range ,
RegionHandle = sim . Handle ,
RequestID = requestID ,
SearchDir = Quaternion . Identity ,
SearchID = searchID ,
SearchName = Utils . StringToBytes ( name ) ,
SearchPos = Vector3 . Zero ,
SearchRegions = 0 ,
SourceID = Client . Self . AgentID ,
Type = ( int ) type
}
} ;
// TODO: this needs to be tested
// TODO: ?
2008-04-07 22:09:40 +00:00
Client . Network . SendPacket ( request , sim ) ;
}
2008-11-09 23:52:35 +00:00
/// <summary>
2008-11-09 23:59:48 +00:00
/// Create or update profile pick
/// </summary>
/// <param name="pickID">UUID of the pick to update, or random UUID to create a new pick</param>
/// <param name="topPick">Is this a top pick? (typically false)</param>
/// <param name="parcelID">UUID of the parcel (UUID.Zero for the current parcel)</param>
/// <param name="name">Name of the pick</param>
/// <param name="globalPosition">Global position of the pick landmark</param>
/// <param name="textureID">UUID of the image displayed with the pick</param>
/// <param name="description">Long description of the pick</param>
public void PickInfoUpdate ( UUID pickID , bool topPick , UUID parcelID , string name , Vector3d globalPosition , UUID textureID , string description )
{
2016-11-27 22:05:54 -06:00
PickInfoUpdatePacket pick = new PickInfoUpdatePacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
Data =
{
PickID = pickID ,
Desc = Utils . StringToBytes ( description ) ,
CreatorID = Client . Self . AgentID ,
TopPick = topPick ,
ParcelID = parcelID ,
Name = Utils . StringToBytes ( name ) ,
SnapshotID = textureID ,
PosGlobal = globalPosition ,
SortOrder = 0 ,
Enabled = false
}
} ;
2008-11-09 23:59:48 +00:00
Client . Network . SendPacket ( pick ) ;
2008-11-09 23:52:35 +00:00
}
/// <summary>
/// Delete profile pick
/// </summary>
2008-11-09 23:59:48 +00:00
/// <param name="pickID">UUID of the pick to delete</param>
public void PickDelete ( UUID pickID )
2008-11-09 23:52:35 +00:00
{
2016-11-27 22:05:54 -06:00
PickDeletePacket delete = new PickDeletePacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
2021-12-09 14:21:48 -06:00
SessionID = Client . Self . SessionID
2016-11-27 22:05:54 -06:00
} ,
Data = { PickID = pickID }
} ;
2008-11-09 23:59:48 +00:00
2008-11-09 23:52:35 +00:00
Client . Network . SendPacket ( delete ) ;
}
2009-05-14 19:35:57 +00:00
/// <summary>
/// Create or update profile Classified
/// </summary>
/// <param name="classifiedID">UUID of the classified to update, or random UUID to create a new classified</param>
2019-10-08 16:02:43 -05:00
/// <param name="category">Defines what category the classified is in</param>
2009-05-14 19:35:57 +00:00
/// <param name="snapshotID">UUID of the image displayed with the classified</param>
/// <param name="price">Price that the classified will cost to place for a week</param>
/// <param name="position">Global position of the classified landmark</param>
/// <param name="name">Name of the classified</param>
/// <param name="desc">Long description of the classified</param>
/// <param name="autoRenew">if true, auto renew classified after expiration</param>
2009-10-16 02:53:53 +00:00
public void UpdateClassifiedInfo ( UUID classifiedID , DirectoryManager . ClassifiedCategories category ,
2009-05-14 19:35:57 +00:00
UUID snapshotID , int price , Vector3d position , string name , string desc , bool autoRenew )
{
2016-11-27 22:05:54 -06:00
ClassifiedInfoUpdatePacket classified = new ClassifiedInfoUpdatePacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
Data =
{
ClassifiedID = classifiedID ,
Category = ( uint ) category ,
ParcelID = UUID . Zero ,
ParentEstate = 0 ,
SnapshotID = snapshotID ,
PosGlobal = position ,
ClassifiedFlags = autoRenew ? ( byte ) 32 : ( byte ) 0 ,
PriceForListing = price ,
Name = Utils . StringToBytes ( name ) ,
Desc = Utils . StringToBytes ( desc )
}
} ;
2009-05-14 19:35:57 +00:00
Client . Network . SendPacket ( classified ) ;
}
2009-07-24 08:25:28 +00:00
/// <summary>
/// Create or update profile Classified
/// </summary>
/// <param name="classifiedID">UUID of the classified to update, or random UUID to create a new classified</param>
2019-10-08 16:02:43 -05:00
/// <param name="category">Defines what category the classified is in</param>
2009-07-24 08:25:28 +00:00
/// <param name="snapshotID">UUID of the image displayed with the classified</param>
/// <param name="price">Price that the classified will cost to place for a week</param>
/// <param name="name">Name of the classified</param>
/// <param name="desc">Long description of the classified</param>
/// <param name="autoRenew">if true, auto renew classified after expiration</param>
2009-05-14 19:35:57 +00:00
public void UpdateClassifiedInfo ( UUID classifiedID , DirectoryManager . ClassifiedCategories category , UUID snapshotID , int price , string name , string desc , bool autoRenew )
{
UpdateClassifiedInfo ( classifiedID , category , snapshotID , price , Client . Self . GlobalPosition , name , desc , autoRenew ) ;
}
/// <summary>
/// Delete a classified ad
/// </summary>
/// <param name="classifiedID">The classified ads ID</param>
2022-11-03 14:19:56 -05:00
public void DeleteClassified ( UUID classifiedID )
2009-05-14 19:35:57 +00:00
{
2016-11-27 22:05:54 -06:00
ClassifiedDeletePacket classified = new ClassifiedDeletePacket
{
AgentData =
{
AgentID = Client . Self . AgentID ,
SessionID = Client . Self . SessionID
} ,
Data = { ClassifiedID = classifiedID }
} ;
2009-05-14 19:35:57 +00:00
Client . Network . SendPacket ( classified ) ;
}
2010-03-31 11:47:52 +00:00
/// <summary>
2019-08-11 10:08:35 -05:00
/// Fetches resource usage by agents attachments
2010-03-31 11:47:52 +00:00
/// </summary>
/// <param name="callback">Called when the requested information is collected</param>
public void GetAttachmentResources ( AttachmentResourcesCallback callback )
{
try
{
2022-11-03 14:19:56 -05:00
Uri cap = Client . Network . CurrentSim . Caps . CapabilityURI ( "AttachmentResources" ) ;
2022-11-04 07:13:09 -05:00
Task req = Client . HttpCapsClient . GetRequestAsync ( cap , CancellationToken . None ,
( response , data , error ) = >
2010-03-31 11:47:52 +00:00
{
2022-11-03 14:19:56 -05:00
if ( error ! = null )
{
callback ( false , null ) ;
}
2010-03-31 11:47:52 +00:00
try
{
2022-11-03 14:19:56 -05:00
OSD result = OSDParser . Deserialize ( data ) ;
2010-03-31 11:47:52 +00:00
AttachmentResourcesMessage info = AttachmentResourcesMessage . FromOSD ( result ) ;
callback ( true , info ) ;
}
catch ( Exception ex )
{
Logger . Log ( "Failed fetching AttachmentResources" , Helpers . LogLevel . Error , Client , ex ) ;
callback ( false , null ) ;
}
2022-11-04 07:13:09 -05:00
} ) ;
2010-03-31 11:47:52 +00:00
}
catch ( Exception ex )
{
Logger . Log ( "Failed fetching AttachmentResources" , Helpers . LogLevel . Error , Client , ex ) ;
callback ( false , null ) ;
}
}
2010-11-20 13:46:21 +00:00
/// <summary>
2019-10-08 16:02:43 -05:00
/// Initiates request to set a new display name
2010-11-20 13:46:21 +00:00
/// </summary>
/// <param name="oldName">Previous display name</param>
/// <param name="newName">Desired new display name</param>
public void SetDisplayName ( string oldName , string newName )
{
2019-08-11 10:08:35 -05:00
if ( Client . Network . CurrentSim = = null | | Client . Network . CurrentSim . Caps = = null )
{
2022-11-03 14:19:56 -05:00
Logger . Log ( "Not connected to simulator to set display name." ,
2019-08-11 10:08:35 -05:00
Helpers . LogLevel . Warning , Client ) ;
return ;
}
2010-11-20 13:46:21 +00:00
2022-11-03 14:19:56 -05:00
Uri cap = Client . Network . CurrentSim . Caps . CapabilityURI ( "SetDisplayName" ) ;
if ( cap = = null )
2010-11-20 13:46:21 +00:00
{
2022-11-03 14:19:56 -05:00
Logger . Log ( "Unable to obtain capability to set display name." ,
2019-08-11 10:08:35 -05:00
Helpers . LogLevel . Warning , Client ) ;
2010-11-20 13:46:21 +00:00
return ;
}
2016-11-27 22:05:54 -06:00
SetDisplayNameMessage msg = new SetDisplayNameMessage
{
OldDisplayName = oldName ,
NewDisplayName = newName
} ;
2010-11-20 13:46:21 +00:00
2022-11-04 07:13:09 -05:00
Task req = Client . HttpCapsClient . PostRequestAsync ( cap , OSDFormat . Xml , msg . Serialize ( ) ,
CancellationToken . None , null ) ;
2010-11-20 13:46:21 +00:00
}
2011-06-04 22:28:45 +00:00
/// <summary>
/// Tells the sim what UI language is used, and if it's ok to share that with scripts
/// </summary>
/// <param name="language">Two letter language code</param>
/// <param name="isPublic">Share language info with scripts</param>
public void UpdateAgentLanguage ( string language , bool isPublic )
{
try
{
2016-11-27 22:05:54 -06:00
UpdateAgentLanguageMessage msg = new UpdateAgentLanguageMessage
{
Language = language ,
LanguagePublic = isPublic
} ;
2011-06-04 22:28:45 +00:00
2022-11-03 14:19:56 -05:00
Uri cap = Client . Network . CurrentSim . Caps . CapabilityURI ( "UpdateAgentLanguage" ) ;
2022-11-04 07:13:09 -05:00
Task req = Client . HttpCapsClient . PostRequestAsync ( cap , OSDFormat . Xml , msg . Serialize ( ) ,
CancellationToken . None , null ) ;
2011-06-04 22:28:45 +00:00
}
catch ( Exception ex )
{
2019-08-11 10:08:35 -05:00
Logger . Log ( "Failed to update agent language" , Helpers . LogLevel . Error , Client , ex ) ;
2011-06-04 22:28:45 +00:00
}
}
2014-03-05 00:19:15 +01:00
public delegate void AgentAccessCallback ( AgentAccessEventArgs e ) ;
/// <summary>
/// Sets agents maturity access level
/// </summary>
/// <param name="access">PG, M or A</param>
public void SetAgentAccess ( string access )
{
SetAgentAccess ( access , null ) ;
}
/// <summary>
/// Sets agents maturity access level
/// </summary>
/// <param name="access">PG, M or A</param>
/// <param name="callback">Callback function</param>
public void SetAgentAccess ( string access , AgentAccessCallback callback )
{
2022-11-03 14:19:56 -05:00
if ( Client = = null | | ! Client . Network . Connected | | Client . Network . CurrentSim . Caps = = null ) { return ; }
2014-03-05 00:19:15 +01:00
2022-11-04 07:13:09 -05:00
OSDMap payload = new OSDMap
2022-08-27 20:36:50 -05:00
{
["access_prefs"] = new OSDMap { [ "max" ] = access }
2021-09-24 14:05:12 -05:00
} ;
2022-11-03 14:19:56 -05:00
Uri cap = Client . Network . CurrentSim . Caps . CapabilityURI ( "UpdateAgentInformation" ) ;
if ( cap = = null ) { return ; }
2022-11-04 07:13:09 -05:00
Task req = Client . HttpCapsClient . PostRequestAsync ( cap , OSDFormat . Xml , payload , CancellationToken . None ,
( response , data , error ) = >
2022-11-03 14:19:56 -05:00
{
bool success = true ;
OSD result = OSDParser . Deserialize ( data ) ;
if ( error = = null & & result is OSDMap osdMap )
{
var map = osdMap [ "access_prefs" ] ;
AgentAccess = ( ( OSDMap ) map ) [ "max" ] ;
Logger . Log ( $"Max maturity access set to {AgentAccess}" , Helpers . LogLevel . Info , Client ) ;
}
else if ( error = = null )
{
Logger . Log ( $"Max maturity unchanged at {AgentAccess}" , Helpers . LogLevel . Info , Client ) ;
}
else
{
Logger . Log ( "Failed setting max maturity access." , Helpers . LogLevel . Warning , Client ) ;
success = false ;
}
2014-03-05 00:19:15 +01:00
2022-11-03 14:19:56 -05:00
if ( callback ! = null )
{
try { callback ( new AgentAccessEventArgs ( success , AgentAccess ) ) ; }
catch { } // *TODO: So gross
}
2022-11-04 07:13:09 -05:00
} ) ;
2014-03-05 00:19:15 +01:00
}
2017-07-18 23:56:19 -04:00
2017-07-19 00:34:18 -04:00
/// <summary>
/// Sets agents hover height.
/// </summary>
/// <param name="hoverHeight">Hover height [-2.0, 2.0]</param>
public void SetHoverHeight ( double hoverHeight )
2017-07-18 23:56:19 -04:00
{
2022-11-03 14:19:56 -05:00
if ( Client = = null | | ! Client . Network . Connected | | Client . Network . CurrentSim . Caps = = null ) { return ; }
var postData = new OSDMap { [ "hover_height" ] = hoverHeight } ;
2017-07-18 23:56:19 -04:00
2022-11-03 14:19:56 -05:00
Uri cap = Client . Network . CurrentSim . Caps . CapabilityURI ( "AgentPreferences" ) ;
if ( cap = = null ) { return ; }
2017-07-18 23:56:19 -04:00
2022-11-04 07:13:09 -05:00
Task req = Client . HttpCapsClient . PostRequestAsync ( cap , OSDFormat . Xml , postData , CancellationToken . None ,
( response , data , error ) = >
2017-07-18 23:56:19 -04:00
{
2022-11-03 14:19:56 -05:00
OSD result = OSDParser . Deserialize ( data ) ;
2017-07-18 23:56:19 -04:00
2022-11-03 14:19:56 -05:00
if ( error ! = null )
2017-07-18 23:56:19 -04:00
{
2017-07-19 00:34:18 -04:00
Logger . Log ( $"Failed to set hover height: {error}." , Helpers . LogLevel . Warning , Client ) ;
2017-07-18 23:56:19 -04:00
}
2022-11-03 14:19:56 -05:00
else if ( ! ( result is OSDMap resultMap ) )
2017-07-18 23:56:19 -04:00
{
2022-11-03 14:19:56 -05:00
Logger . Log ( $"Failed to set hover height: Expected {nameof(OSDMap)} response, but got {result.Type}" ,
Helpers . LogLevel . Warning , Client ) ;
2017-07-18 23:56:19 -04:00
}
else
{
var confirmedHeight = resultMap [ "hover_height" ] ;
2022-11-03 14:19:56 -05:00
Logger . Log ( $"Hover height set to {confirmedHeight}" , Helpers . LogLevel . Debug , Client ) ;
2017-07-18 23:56:19 -04:00
}
2022-11-04 07:13:09 -05:00
} ) ;
2017-07-18 23:56:19 -04:00
}
2007-11-06 09:26:10 +00:00
#endregion Misc
2007-04-13 20:02:21 +00:00
#region Packet Handlers
2007-03-09 20:26:07 +00:00
/// <summary>
/// Take an incoming ImprovedInstantMessage packet, auto-parse, and if
/// OnInstantMessage is defined call that with the appropriate arguments
/// </summary>
2009-10-28 08:01:52 +00:00
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void InstantMessageHandler ( object sender , PacketReceivedEventArgs e )
2007-03-09 20:26:07 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
2021-09-23 19:47:07 -05:00
Simulator simulator = e . Simulator ;
2009-10-28 08:01:52 +00:00
2016-11-27 22:05:54 -06:00
if ( packet . Type ! = PacketType . ImprovedInstantMessage ) return ;
2007-03-09 20:26:07 +00:00
2016-11-27 22:05:54 -06:00
ImprovedInstantMessagePacket im = ( ImprovedInstantMessagePacket ) packet ;
if ( m_InstantMessage ! = null )
{
InstantMessage message ;
message . FromAgentID = im . AgentData . AgentID ;
message . FromAgentName = Utils . BytesToString ( im . MessageBlock . FromAgentName ) ;
message . ToAgentID = im . MessageBlock . ToAgentID ;
message . ParentEstateID = im . MessageBlock . ParentEstateID ;
message . RegionID = im . MessageBlock . RegionID ;
message . Position = im . MessageBlock . Position ;
message . Dialog = ( InstantMessageDialog ) im . MessageBlock . Dialog ;
message . GroupIM = im . MessageBlock . FromGroup ;
message . IMSessionID = im . MessageBlock . ID ;
message . Timestamp = new DateTime ( im . MessageBlock . Timestamp ) ;
message . Message = Utils . BytesToString ( im . MessageBlock . Message ) ;
message . Offline = ( InstantMessageOnline ) im . MessageBlock . Offline ;
message . BinaryBucket = im . MessageBlock . BinaryBucket ;
2021-09-23 19:47:07 -05:00
OnInstantMessage ( new InstantMessageEventArgs ( message , simulator ) ) ;
2021-09-22 15:04:43 -05:00
}
}
2022-11-03 14:19:56 -05:00
protected void OfflineMessageHandlerCallback ( HttpResponseMessage response , byte [ ] data , Exception error )
2021-09-22 15:04:43 -05:00
{
if ( error ! = null ) {
Logger . Log ( $"Failed to retrieve offline messages from the simulator: {error.Message}" ,
Helpers . LogLevel . Warning ) ;
2021-09-22 20:35:05 -05:00
RetrieveInstantMessagesLegacy ( ) ;
2022-11-03 14:19:56 -05:00
return ;
2021-09-22 15:04:43 -05:00
}
2022-11-03 14:19:56 -05:00
if ( m_InstantMessage = = null ) { return ; } // don't bother if we don't have any listeners
2021-09-22 15:04:43 -05:00
2022-11-03 14:19:56 -05:00
OSD result = OSDParser . Deserialize ( data ) ;
if ( ! ( result is OSDMap respMap ) | | respMap . Count = = 0 | | respMap . ContainsKey ( "messages" ) )
2022-08-27 20:36:50 -05:00
{
2022-11-03 14:19:56 -05:00
Logger . Log ( "Failed to retrieve offline messages because the capability returned invalid shiz." ,
2022-08-27 20:36:50 -05:00
Helpers . LogLevel . Warning ) ;
RetrieveInstantMessagesLegacy ( ) ;
return ;
2021-09-22 15:04:43 -05:00
}
if ( respMap [ "messages" ] is OSDArray msgArray )
{
foreach ( var osd in msgArray )
{
var msg = ( OSDMap ) osd ;
InstantMessage message ;
message . FromAgentID = msg [ "from_agent_id" ] . AsUUID ( ) ;
message . FromAgentName = msg [ "from_agent_name" ] . AsString ( ) ;
message . ToAgentID = msg [ "to_agent_id" ] . AsUUID ( ) ;
message . RegionID = msg [ "region_id" ] . AsUUID ( ) ;
message . Dialog = ( InstantMessageDialog ) msg [ "dialog" ] . AsInteger ( ) ;
message . IMSessionID = msg [ "transaction-id" ] . AsUUID ( ) ;
message . Timestamp = new DateTime ( msg [ "timestamp" ] . AsInteger ( ) ) ;
message . Message = msg [ "message" ] . AsString ( ) ;
message . Offline = msg . ContainsKey ( "offline" )
? ( InstantMessageOnline ) msg [ "offline" ] . AsInteger ( )
: InstantMessageOnline . Offline ;
message . ParentEstateID = msg . ContainsKey ( "parent_estate_id" )
? msg [ "parent_estate_id" ] . AsUInteger ( ) : 1 ;
2022-08-27 20:36:50 -05:00
message . Position = msg . ContainsKey ( "position" )
? msg [ "position" ] . AsVector3 ( )
2021-09-22 15:04:43 -05:00
: new Vector3 ( msg [ "local_x" ] , msg [ "local_y" ] , msg [ "local_z" ] ) ;
message . BinaryBucket = msg . ContainsKey ( "binary_bucket" )
? msg [ "binary_bucket" ] . AsBinary ( ) : new byte [ ] { 0 } ;
2021-12-09 13:53:36 -06:00
message . GroupIM = msg . ContainsKey ( "from_group" ) & & msg [ "from_group" ] . AsBoolean ( ) ;
2021-09-22 15:04:43 -05:00
2021-09-23 19:47:07 -05:00
OnInstantMessage ( new InstantMessageEventArgs ( message , null ) ) ;
2022-11-03 14:19:56 -05:00
}
2007-03-09 20:26:07 +00:00
}
}
/// <summary>
/// Take an incoming Chat packet, auto-parse, and if OnChat is defined call
/// that with the appropriate arguments.
/// </summary>
2009-10-28 08:01:52 +00:00
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void ChatHandler ( object sender , PacketReceivedEventArgs e )
2007-03-09 20:26:07 +00:00
{
2016-11-27 22:05:54 -06:00
if ( m_Chat = = null ) return ;
Packet packet = e . Packet ;
2010-03-31 11:47:52 +00:00
2016-11-27 22:05:54 -06:00
ChatFromSimulatorPacket chat = ( ChatFromSimulatorPacket ) packet ;
2007-03-09 20:26:07 +00:00
2016-11-27 22:05:54 -06:00
OnChat ( new ChatEventArgs ( e . Simulator , Utils . BytesToString ( chat . ChatData . Message ) ,
( ChatAudibleLevel ) chat . ChatData . Audible ,
( ChatType ) chat . ChatData . ChatType ,
( ChatSourceType ) chat . ChatData . SourceType ,
Utils . BytesToString ( chat . ChatData . FromName ) ,
chat . ChatData . SourceID ,
chat . ChatData . OwnerID ,
chat . ChatData . Position ) ) ;
2007-03-09 20:26:07 +00:00
}
/// <summary>
2007-08-29 08:55:53 +00:00
/// Used for parsing llDialogs
2007-03-09 20:26:07 +00:00
/// </summary>
2009-10-28 08:01:52 +00:00
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void ScriptDialogHandler ( object sender , PacketReceivedEventArgs e )
2007-03-09 20:26:07 +00:00
{
2016-11-27 22:05:54 -06:00
if ( m_ScriptDialog = = null ) return ;
Packet packet = e . Packet ;
2007-03-09 20:26:07 +00:00
2016-11-27 22:05:54 -06:00
ScriptDialogPacket dialog = ( ScriptDialogPacket ) packet ;
2017-06-04 12:43:14 -05:00
List < string > buttons = dialog . Buttons . Select ( button = > Utils . BytesToString ( button . ButtonLabel ) ) . ToList ( ) ;
2011-05-11 09:52:37 +00:00
2016-11-27 22:05:54 -06:00
UUID ownerID = UUID . Zero ;
2011-05-11 09:52:37 +00:00
2016-11-27 22:05:54 -06:00
if ( dialog . OwnerData ! = null & & dialog . OwnerData . Length > 0 )
{
ownerID = dialog . OwnerData [ 0 ] . OwnerID ;
2007-03-09 20:26:07 +00:00
}
2016-11-27 22:05:54 -06:00
OnScriptDialog ( new ScriptDialogEventArgs ( Utils . BytesToString ( dialog . Data . Message ) ,
Utils . BytesToString ( dialog . Data . ObjectName ) ,
dialog . Data . ImageID ,
dialog . Data . ObjectID ,
Utils . BytesToString ( dialog . Data . FirstName ) ,
Utils . BytesToString ( dialog . Data . LastName ) ,
dialog . Data . ChatChannel ,
buttons ,
ownerID ) ) ;
2007-03-09 20:26:07 +00:00
}
2007-03-20 22:30:39 +00:00
/// <summary>
/// Used for parsing llRequestPermissions dialogs
/// </summary>
2009-10-28 08:01:52 +00:00
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void ScriptQuestionHandler ( object sender , PacketReceivedEventArgs e )
2007-03-20 22:30:39 +00:00
{
2016-11-27 22:05:54 -06:00
if ( m_ScriptQuestion = = null ) return ;
Packet packet = e . Packet ;
Simulator simulator = e . Simulator ;
2009-10-28 08:01:52 +00:00
2016-11-27 22:05:54 -06:00
ScriptQuestionPacket question = ( ScriptQuestionPacket ) packet ;
2007-03-20 22:30:39 +00:00
2016-11-27 22:05:54 -06:00
OnScriptQuestion ( new ScriptQuestionEventArgs ( simulator ,
question . Data . TaskID ,
question . Data . ItemID ,
Utils . BytesToString ( question . Data . ObjectName ) ,
Utils . BytesToString ( question . Data . ObjectOwner ) ,
( ScriptPermission ) question . Data . Questions ) ) ;
2007-03-20 22:30:39 +00:00
}
2008-04-04 21:08:38 +00:00
/// <summary>
/// Handles Script Control changes when Script with permissions releases or takes a control
/// </summary>
2009-10-28 08:01:52 +00:00
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
private void ScriptControlChangeHandler ( object sender , PacketReceivedEventArgs e )
2008-04-04 21:08:38 +00:00
{
2016-11-27 22:05:54 -06:00
if ( m_ScriptControl = = null ) return ;
Packet packet = e . Packet ;
2010-03-31 11:47:52 +00:00
2016-11-27 22:05:54 -06:00
ScriptControlChangePacket change = ( ScriptControlChangePacket ) packet ;
2017-06-04 12:43:14 -05:00
foreach ( ScriptControlChangePacket . DataBlock data in change . Data )
2016-11-27 22:05:54 -06:00
{
2017-06-04 12:43:14 -05:00
OnScriptControlChange ( new ScriptControlEventArgs ( ( ScriptControlChange ) data . Controls ,
data . PassToAgent ,
data . TakeControls ) ) ;
2008-04-04 21:08:38 +00:00
}
}
2008-01-20 23:08:13 +00:00
/// <summary>
/// Used for parsing llLoadURL Dialogs
/// </summary>
2009-10-28 08:01:52 +00:00
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void LoadURLHandler ( object sender , PacketReceivedEventArgs e )
2008-01-20 23:08:13 +00:00
{
2016-11-27 22:05:54 -06:00
if ( m_LoadURL = = null ) return ;
Packet packet = e . Packet ;
2010-03-31 11:47:52 +00:00
2016-11-27 22:05:54 -06:00
LoadURLPacket loadURL = ( LoadURLPacket ) packet ;
2010-03-31 11:47:52 +00:00
2016-11-27 22:05:54 -06:00
OnLoadURL ( new LoadUrlEventArgs (
Utils . BytesToString ( loadURL . Data . ObjectName ) ,
loadURL . Data . ObjectID ,
loadURL . Data . OwnerID ,
loadURL . Data . OwnerIsGroup ,
Utils . BytesToString ( loadURL . Data . Message ) ,
Utils . BytesToString ( loadURL . Data . URL )
) ) ;
2008-01-20 23:08:13 +00:00
}
2007-03-09 20:26:07 +00:00
/// <summary>
/// Update client's Position, LookAt and region handle from incoming packet
/// </summary>
2009-10-28 08:01:52 +00:00
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
2008-05-01 10:48:09 +00:00
/// <remarks>This occurs when after an avatar moves into a new sim</remarks>
2009-10-28 08:01:52 +00:00
private void MovementCompleteHandler ( object sender , PacketReceivedEventArgs e )
2007-03-09 20:26:07 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
Simulator simulator = e . Simulator ;
2007-03-09 20:26:07 +00:00
AgentMovementCompletePacket movement = ( AgentMovementCompletePacket ) packet ;
2007-11-21 23:50:05 +00:00
relativePosition = movement . Data . Position ;
Movement . Camera . LookDirection ( movement . Data . LookAt ) ;
2007-03-09 20:26:07 +00:00
simulator . Handle = movement . Data . RegionHandle ;
2008-08-12 22:38:02 +00:00
simulator . SimVersion = Utils . BytesToString ( movement . SimData . ChannelVersion ) ;
2011-05-23 23:04:50 +00:00
simulator . AgentMovementComplete = true ;
2007-03-09 20:26:07 +00:00
}
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void HealthHandler ( object sender , PacketReceivedEventArgs e )
2007-03-09 20:26:07 +00:00
{
2010-03-31 11:47:52 +00:00
Packet packet = e . Packet ;
2021-12-09 14:21:48 -06:00
Health = ( ( HealthMessagePacket ) packet ) . HealthData . Health ;
2007-03-09 20:26:07 +00:00
}
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void AgentDataUpdateHandler ( object sender , PacketReceivedEventArgs e )
2007-03-09 20:26:07 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
Simulator simulator = e . Simulator ;
2007-03-09 20:26:07 +00:00
AgentDataUpdatePacket p = ( AgentDataUpdatePacket ) packet ;
2007-08-10 20:16:19 +00:00
2007-11-06 09:26:10 +00:00
if ( p . AgentData . AgentID = = simulator . Client . Self . AgentID )
2007-08-10 20:16:19 +00:00
{
2021-12-09 14:21:48 -06:00
FirstName = Utils . BytesToString ( p . AgentData . FirstName ) ;
LastName = Utils . BytesToString ( p . AgentData . LastName ) ;
ActiveGroup = p . AgentData . ActiveGroupID ;
ActiveGroupPowers = ( GroupPowers ) p . AgentData . GroupPowers ;
2007-08-10 20:16:19 +00:00
2016-11-27 22:05:54 -06:00
if ( m_AgentData = = null ) return ;
2007-08-10 20:16:19 +00:00
2016-11-27 22:05:54 -06:00
string groupTitle = Utils . BytesToString ( p . AgentData . GroupTitle ) ;
string groupName = Utils . BytesToString ( p . AgentData . GroupName ) ;
2021-12-09 14:21:48 -06:00
OnAgentData ( new AgentDataReplyEventArgs ( FirstName , LastName , ActiveGroup , groupTitle , ActiveGroupPowers , groupName ) ) ;
2007-03-09 20:26:07 +00:00
}
2007-08-10 20:16:19 +00:00
else
2007-03-09 20:26:07 +00:00
{
2022-04-23 10:38:11 -05:00
Logger . Log ( "Got an AgentDataUpdate packet for avatar " + p . AgentData . AgentID +
" instead of " + Client . Self . AgentID + ", this shouldn't happen" , Helpers . LogLevel . Error , Client ) ;
2007-03-09 20:26:07 +00:00
}
}
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void MoneyBalanceReplyHandler ( object sender , PacketReceivedEventArgs e )
2007-03-09 20:26:07 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
2010-03-31 11:47:52 +00:00
2007-07-13 14:49:36 +00:00
if ( packet . Type = = PacketType . MoneyBalanceReply )
2007-07-11 16:17:06 +00:00
{
2009-10-16 02:53:53 +00:00
MoneyBalanceReplyPacket reply = ( MoneyBalanceReplyPacket ) packet ;
2021-12-09 14:21:48 -06:00
this . Balance = reply . MoneyData . MoneyBalance ;
2007-07-13 14:49:36 +00:00
2009-10-16 02:53:53 +00:00
if ( m_MoneyBalance ! = null )
2007-07-13 14:49:36 +00:00
{
2016-11-27 22:05:54 -06:00
TransactionInfo transactionInfo = new TransactionInfo
{
TransactionType = reply . TransactionInfo . TransactionType ,
SourceID = reply . TransactionInfo . SourceID ,
IsSourceGroup = reply . TransactionInfo . IsSourceGroup ,
DestID = reply . TransactionInfo . DestID ,
IsDestGroup = reply . TransactionInfo . IsDestGroup ,
Amount = reply . TransactionInfo . Amount ,
ItemDescription = Utils . BytesToString ( reply . TransactionInfo . ItemDescription )
} ;
2011-05-11 10:11:11 +00:00
2009-10-16 02:53:53 +00:00
OnMoneyBalanceReply ( new MoneyBalanceReplyEventArgs ( reply . MoneyData . TransactionID ,
reply . MoneyData . TransactionSuccess ,
reply . MoneyData . MoneyBalance ,
reply . MoneyData . SquareMetersCredit ,
reply . MoneyData . SquareMetersCommitted ,
2011-05-11 10:11:11 +00:00
Utils . BytesToString ( reply . MoneyData . Description ) ,
transactionInfo ) ) ;
2007-07-13 14:49:36 +00:00
}
2007-03-09 20:26:07 +00:00
}
2009-10-16 02:53:53 +00:00
if ( m_Balance ! = null )
2007-03-09 20:26:07 +00:00
{
2021-12-09 14:21:48 -06:00
OnBalance ( new BalanceEventArgs ( Balance ) ) ;
2007-03-09 20:26:07 +00:00
}
}
2010-11-20 13:46:21 +00:00
/// <summary>
/// EQ Message fired with the result of SetDisplayName request
/// </summary>
/// <param name="capsKey">The message key</param>
/// <param name="message">the IMessage object containing the deserialized data sent from the simulator</param>
/// <param name="simulator">The <see cref="Simulator"/> which originated the packet</param>
protected void SetDisplayNameReplyEventHandler ( string capsKey , IMessage message , Simulator simulator )
{
2016-11-27 22:05:54 -06:00
if ( m_SetDisplayNameReply = = null ) return ;
SetDisplayNameReplyMessage msg = ( SetDisplayNameReplyMessage ) message ;
OnSetDisplayNameReply ( new SetDisplayNameReplyEventArgs ( msg . Status , msg . Reason , msg . DisplayName ) ) ;
2010-11-20 13:46:21 +00:00
}
2013-02-16 07:05:16 +01:00
protected void AgentStateUpdateEventHandler ( string capsKey , IMessage message , Simulator simulator )
{
2019-10-08 16:02:43 -05:00
if ( message is AgentStateUpdateMessage updateMessage )
2013-02-16 07:05:16 +01:00
{
2019-10-08 16:02:43 -05:00
AgentStateStatus = updateMessage ;
2013-02-16 07:05:16 +01:00
}
}
2009-10-28 08:01:52 +00:00
protected void EstablishAgentCommunicationEventHandler ( string capsKey , IMessage message , Simulator simulator )
2007-08-04 14:31:31 +00:00
{
2009-04-13 09:32:25 +00:00
EstablishAgentCommunicationMessage msg = ( EstablishAgentCommunicationMessage ) message ;
2007-11-21 23:50:05 +00:00
2022-11-06 21:21:53 -06:00
if ( ! Client . Settings . MULTIPLE_SIMS ) { return ; }
2016-11-27 22:05:54 -06:00
IPEndPoint endPoint = new IPEndPoint ( msg . Address , msg . Port ) ;
Simulator sim = Client . Network . FindSimulator ( endPoint ) ;
2007-08-02 01:09:53 +00:00
2016-11-27 22:05:54 -06:00
if ( sim = = null )
{
Logger . Log ( $"Got EstablishAgentCommunication for unknown sim {msg.Address}:{msg.Port}" ,
Helpers . LogLevel . Error , Client ) ;
2007-08-03 07:07:49 +00:00
2016-11-27 22:05:54 -06:00
// FIXME: Should we use this opportunity to connect to the simulator?
}
else
{
2022-11-03 14:47:34 -05:00
Logger . Log ( $"Got EstablishAgentCommunication for {sim}" ,
2016-11-27 22:05:54 -06:00
Helpers . LogLevel . Info , Client ) ;
2007-08-02 01:09:53 +00:00
2022-11-03 14:47:34 -05:00
sim . SetSeedCaps ( msg . SeedCapability ) ;
2007-03-09 20:26:07 +00:00
}
2007-08-02 01:09:53 +00:00
}
2007-03-09 20:26:07 +00:00
2009-04-29 06:05:31 +00:00
/// <summary>
/// Process TeleportFailed message sent via EventQueue, informs agent its last teleport has failed and why.
/// </summary>
/// <param name="messageKey">The Message Key</param>
2022-11-06 21:21:53 -06:00
/// <param name="message">An IMessage object Deserialized from the received message event</param>
2009-04-29 18:33:46 +00:00
/// <param name="simulator">The simulator originating the event message</param>
2009-04-29 06:05:31 +00:00
public void TeleportFailedEventHandler ( string messageKey , IMessage message , Simulator simulator )
{
2009-10-16 02:53:53 +00:00
TeleportFailedMessage msg = ( TeleportFailedMessage ) message ;
2009-04-29 06:05:31 +00:00
2016-11-27 22:05:54 -06:00
TeleportFailedPacket failedPacket = new TeleportFailedPacket
{
Info =
{
AgentID = msg . AgentID ,
Reason = Utils . StringToBytes ( msg . Reason )
}
} ;
2009-10-16 02:53:53 +00:00
2009-10-28 08:01:52 +00:00
TeleportHandler ( this , new PacketReceivedEventArgs ( failedPacket , simulator ) ) ;
2009-04-29 06:05:31 +00:00
}
2008-10-24 18:42:46 +00:00
/// <summary>
/// Process TeleportFinish from Event Queue and pass it onto our TeleportHandler
/// </summary>
2009-04-20 07:50:25 +00:00
/// <param name="capsKey">The message system key for this event</param>
/// <param name="message">IMessage object containing decoded data from OSD</param>
2009-04-29 18:33:46 +00:00
/// <param name="simulator">The simulator originating the event message</param>
2009-04-13 09:32:25 +00:00
private void TeleportFinishEventHandler ( string capsKey , IMessage message , Simulator simulator )
2008-10-24 18:42:46 +00:00
{
2009-04-13 09:32:25 +00:00
TeleportFinishMessage msg = ( TeleportFinishMessage ) message ;
2008-10-24 18:42:46 +00:00
2016-11-27 22:05:54 -06:00
TeleportFinishPacket p = new TeleportFinishPacket
{
Info =
{
AgentID = msg . AgentID ,
LocationID = ( uint ) msg . LocationID ,
RegionHandle = msg . RegionHandle ,
SeedCapability = Utils . StringToBytes ( msg . SeedCapability . ToString ( ) ) ,
SimAccess = ( byte ) msg . SimAccess ,
SimIP = Utils . IPToUInt ( msg . IP ) ,
SimPort = ( ushort ) msg . Port ,
TeleportFlags = ( uint ) msg . Flags
}
} ;
// FIXME: Check This
2009-04-13 09:32:25 +00:00
// pass the packet onto the teleport handler
2009-10-28 08:01:52 +00:00
TeleportHandler ( this , new PacketReceivedEventArgs ( p , simulator ) ) ;
2008-10-24 18:42:46 +00:00
}
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void TeleportHandler ( object sender , PacketReceivedEventArgs e )
2007-03-09 20:26:07 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
Simulator simulator = e . Simulator ;
2010-03-31 11:47:52 +00:00
2007-03-09 20:26:07 +00:00
bool finished = false ;
TeleportFlags flags = TeleportFlags . Default ;
2008-09-09 04:58:58 +00:00
2007-03-09 20:26:07 +00:00
if ( packet . Type = = PacketType . TeleportStart )
{
TeleportStartPacket start = ( TeleportStartPacket ) packet ;
2021-12-09 14:21:48 -06:00
TeleportMessage = "Teleport started" ;
2007-03-09 20:26:07 +00:00
flags = ( TeleportFlags ) start . Info . TeleportFlags ;
2007-11-06 09:26:10 +00:00
teleportStat = TeleportStatus . Start ;
2007-03-09 20:26:07 +00:00
2016-11-27 22:05:54 -06:00
Logger . DebugLog ( $"TeleportStart received, Flags: {flags}" , Client ) ;
2007-03-09 20:26:07 +00:00
}
else if ( packet . Type = = PacketType . TeleportProgress )
{
TeleportProgressPacket progress = ( TeleportProgressPacket ) packet ;
2021-12-09 14:21:48 -06:00
TeleportMessage = Utils . BytesToString ( progress . Info . Message ) ;
2007-03-09 20:26:07 +00:00
flags = ( TeleportFlags ) progress . Info . TeleportFlags ;
2007-11-06 09:26:10 +00:00
teleportStat = TeleportStatus . Progress ;
2007-03-09 20:26:07 +00:00
2021-12-09 14:21:48 -06:00
Logger . DebugLog ( $"TeleportProgress received, Message: {TeleportMessage}, Flags: {flags}" , Client ) ;
2007-03-09 20:26:07 +00:00
}
else if ( packet . Type = = PacketType . TeleportFailed )
{
TeleportFailedPacket failed = ( TeleportFailedPacket ) packet ;
2021-12-09 14:21:48 -06:00
TeleportMessage = Utils . BytesToString ( failed . Info . Reason ) ;
2007-11-06 09:26:10 +00:00
teleportStat = TeleportStatus . Failed ;
2007-03-09 20:26:07 +00:00
finished = true ;
2021-12-09 14:21:48 -06:00
Logger . DebugLog ( $"TeleportFailed received, Reason: {TeleportMessage}" , Client ) ;
2007-03-09 20:26:07 +00:00
}
else if ( packet . Type = = PacketType . TeleportFinish )
{
TeleportFinishPacket finish = ( TeleportFinishPacket ) packet ;
flags = ( TeleportFlags ) finish . Info . TeleportFlags ;
2022-11-03 14:47:34 -05:00
Uri seedcaps = new Uri ( Utils . BytesToString ( finish . Info . SeedCapability ) ) ;
2007-03-09 20:26:07 +00:00
finished = true ;
2016-11-27 22:05:54 -06:00
Logger . DebugLog ( $"TeleportFinish received, Flags: {flags}" , Client ) ;
2007-03-09 20:26:07 +00:00
// Connect to the new sim
2011-05-23 23:04:50 +00:00
Client . Network . CurrentSim . AgentMovementComplete = false ; // we're not there anymore
2007-07-13 14:49:36 +00:00
Simulator newSimulator = Client . Network . Connect ( new IPAddress ( finish . Info . SimIP ) ,
finish . Info . SimPort , finish . Info . RegionHandle , true , seedcaps ) ;
2007-03-09 20:26:07 +00:00
2007-03-21 15:24:51 +00:00
if ( newSimulator ! = null )
2007-03-09 20:26:07 +00:00
{
2021-12-09 14:21:48 -06:00
TeleportMessage = "Teleport finished" ;
2007-11-06 09:26:10 +00:00
teleportStat = TeleportStatus . Finished ;
2007-03-09 20:26:07 +00:00
2016-11-27 22:05:54 -06:00
Logger . Log ( $"Moved to new sim {newSimulator}" , Helpers . LogLevel . Info , Client ) ;
2007-03-09 20:26:07 +00:00
}
else
{
2021-12-09 14:21:48 -06:00
TeleportMessage = "Failed to connect to the new sim after a teleport" ;
2007-11-06 09:26:10 +00:00
teleportStat = TeleportStatus . Failed ;
2007-03-09 20:26:07 +00:00
2007-07-13 14:49:36 +00:00
// We're going to get disconnected now
2021-12-09 14:21:48 -06:00
Logger . Log ( TeleportMessage , Helpers . LogLevel . Error , Client ) ;
2007-03-09 20:26:07 +00:00
}
}
else if ( packet . Type = = PacketType . TeleportCancel )
{
//TeleportCancelPacket cancel = (TeleportCancelPacket)packet;
2021-12-09 14:21:48 -06:00
TeleportMessage = "Cancelled" ;
2007-11-06 09:26:10 +00:00
teleportStat = TeleportStatus . Cancelled ;
2007-03-09 20:26:07 +00:00
finished = true ;
2016-11-27 22:05:54 -06:00
Logger . DebugLog ( $"TeleportCancel received from {simulator}" , Client ) ;
2007-03-09 20:26:07 +00:00
}
else if ( packet . Type = = PacketType . TeleportLocal )
{
TeleportLocalPacket local = ( TeleportLocalPacket ) packet ;
2021-12-09 14:21:48 -06:00
TeleportMessage = "Teleport finished" ;
2007-03-09 20:26:07 +00:00
flags = ( TeleportFlags ) local . Info . TeleportFlags ;
2007-11-06 09:26:10 +00:00
teleportStat = TeleportStatus . Finished ;
relativePosition = local . Info . Position ;
2007-11-21 23:50:05 +00:00
Movement . Camera . LookDirection ( local . Info . LookAt ) ;
2007-03-09 20:26:07 +00:00
// This field is apparently not used for anything
//local.Info.LocationID;
finished = true ;
2016-11-27 22:05:54 -06:00
Logger . DebugLog ( $"TeleportLocal received, Flags: {flags}" , Client ) ;
2007-03-09 20:26:07 +00:00
}
2009-10-16 02:53:53 +00:00
if ( m_Teleport ! = null )
2007-03-09 20:26:07 +00:00
{
2021-12-09 14:21:48 -06:00
OnTeleport ( new TeleportEventArgs ( TeleportMessage , teleportStat , flags ) ) ;
2007-03-09 20:26:07 +00:00
}
2022-11-11 10:16:31 -06:00
if ( finished ) { teleportEvent . Set ( ) ; }
2007-11-06 09:26:10 +00:00
}
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void AvatarAnimationHandler ( object sender , PacketReceivedEventArgs e )
2007-11-29 01:28:41 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
2007-11-29 01:28:41 +00:00
AvatarAnimationPacket animation = ( AvatarAnimationPacket ) packet ;
if ( animation . Sender . ID = = Client . Self . AgentID )
{
lock ( SignaledAnimations . Dictionary )
{
// Reset the signaled animation list
SignaledAnimations . Dictionary . Clear ( ) ;
for ( int i = 0 ; i < animation . AnimationList . Length ; i + + )
{
2008-07-25 05:15:05 +00:00
UUID animID = animation . AnimationList [ i ] . AnimID ;
2007-11-29 01:28:41 +00:00
int sequenceID = animation . AnimationList [ i ] . AnimSequenceID ;
// Add this animation to the list of currently signaled animations
SignaledAnimations . Dictionary [ animID ] = sequenceID ;
if ( i < animation . AnimationSourceList . Length )
{
// FIXME: The server tells us which objects triggered our animations,
// we should store this info
//animation.AnimationSourceList[i].ObjectID
}
if ( i < animation . PhysicalAvatarEventList . Length )
{
// FIXME: What is this?
}
2016-11-27 22:05:54 -06:00
if ( ! Client . Settings . SEND_AGENT_UPDATES ) continue ;
// We have to manually tell the server to stop playing some animations
if ( animID = = Animations . STANDUP | |
animID = = Animations . PRE_JUMP | |
animID = = Animations . LAND | |
animID = = Animations . MEDIUM_LAND )
2007-11-29 01:28:41 +00:00
{
2016-11-27 22:05:54 -06:00
Movement . FinishAnim = true ;
Movement . SendUpdate ( true ) ;
Movement . FinishAnim = false ;
2007-11-29 01:28:41 +00:00
}
}
}
2009-10-16 02:53:53 +00:00
}
2007-11-29 01:28:41 +00:00
2009-10-16 02:53:53 +00:00
if ( m_AnimationsChanged ! = null )
{
2019-10-20 21:22:13 -05:00
ThreadPool . QueueUserWorkItem ( delegate ( object o )
2010-08-12 22:37:27 +00:00
{ OnAnimationsChanged ( new AnimationsChangedEventArgs ( this . SignaledAnimations ) ) ; } ) ;
2007-11-29 01:28:41 +00:00
}
2009-10-16 02:53:53 +00:00
2007-11-29 01:28:41 +00:00
}
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void MeanCollisionAlertHandler ( object sender , PacketReceivedEventArgs e )
2007-11-30 03:55:08 +00:00
{
2016-11-27 22:05:54 -06:00
if ( m_MeanCollision = = null ) return ;
Packet packet = e . Packet ;
MeanCollisionAlertPacket collision = ( MeanCollisionAlertPacket ) packet ;
2007-11-30 03:55:08 +00:00
2016-11-27 22:05:54 -06:00
foreach ( MeanCollisionAlertPacket . MeanCollisionBlock block in collision . MeanCollision )
{
DateTime time = Utils . UnixTimeToDateTime ( block . Time ) ;
MeanCollisionType type = ( MeanCollisionType ) block . Type ;
2007-11-30 03:55:08 +00:00
2016-11-27 22:05:54 -06:00
OnMeanCollision ( new MeanCollisionEventArgs ( type , block . Perp , block . Victim , block . Mag , time ) ) ;
2007-11-30 03:55:08 +00:00
}
}
2007-11-06 09:26:10 +00:00
private void Network_OnLoginResponse ( bool loginSuccess , bool redirect , string message , string reason ,
2007-12-21 02:25:36 +00:00
LoginResponseData reply )
2007-11-06 09:26:10 +00:00
{
2021-12-09 14:21:48 -06:00
AgentID = reply . AgentID ;
SessionID = reply . SessionID ;
SecureSessionID = reply . SecureSessionID ;
FirstName = reply . FirstName ;
LastName = reply . LastName ;
StartLocation = reply . StartLocation ;
AgentAccess = reply . AgentAccess ;
2009-04-08 21:02:58 +00:00
Movement . Camera . LookDirection ( reply . LookAt ) ;
2021-12-06 14:52:03 -06:00
home = reply . Home ;
2021-12-09 14:21:48 -06:00
LookAt = reply . LookAt ;
2017-07-08 16:10:45 -04:00
2019-06-30 10:41:00 -05:00
if ( reply . Gestures ! = null )
2017-07-08 16:10:45 -04:00
{
2019-06-30 10:41:00 -05:00
foreach ( var gesture in reply . Gestures )
{
ActiveGestures . Add ( gesture . Key , gesture . Value ) ;
}
2017-07-08 16:10:45 -04:00
}
2007-03-09 20:26:07 +00:00
}
2007-03-30 13:00:56 +00:00
2009-10-28 08:01:52 +00:00
private void Network_OnDisconnected ( object sender , DisconnectedEventArgs e )
2007-08-29 08:55:53 +00:00
{
// Null out the cached fullName since it can change after logging
// in again (with a different account name or different login
2008-07-21 21:12:59 +00:00
// server but using the same GridClient object
2007-08-29 08:55:53 +00:00
fullName = null ;
}
2009-04-29 06:05:31 +00:00
/// <summary>
/// Crossed region handler for message that comes across the EventQueue. Sent to an agent
/// when the agent crosses a sim border into a new region.
/// </summary>
/// <param name="capsKey">The message key</param>
/// <param name="message">the IMessage object containing the deserialized data sent from the simulator</param>
2009-04-29 18:33:46 +00:00
/// <param name="simulator">The <see cref="Simulator"/> which originated the packet</param>
private void CrossedRegionEventHandler ( string capsKey , IMessage message , Simulator simulator )
2009-04-29 06:05:31 +00:00
{
2009-10-16 02:53:53 +00:00
CrossedRegionMessage crossed = ( CrossedRegionMessage ) message ;
2009-04-29 06:05:31 +00:00
IPEndPoint endPoint = new IPEndPoint ( crossed . IP , crossed . Port ) ;
2016-11-27 22:05:54 -06:00
Logger . DebugLog ( $"Crossed in to new region area, attempting to connect to {endPoint}" , Client ) ;
2009-04-29 06:05:31 +00:00
Simulator oldSim = Client . Network . CurrentSim ;
2022-11-03 14:47:34 -05:00
Simulator newSim = Client . Network . Connect ( endPoint , crossed . RegionHandle , true , crossed . SeedCapability ) ;
2009-04-29 06:05:31 +00:00
if ( newSim ! = null )
{
2016-11-27 22:05:54 -06:00
Logger . Log ( $"Finished crossing over in to region {newSim}" , Helpers . LogLevel . Info , Client ) ;
2011-05-23 23:04:50 +00:00
oldSim . AgentMovementComplete = false ; // We're no longer there
2009-10-16 02:53:53 +00:00
if ( m_RegionCrossed ! = null )
2009-04-29 06:05:31 +00:00
{
2010-03-31 11:47:52 +00:00
OnRegionCrossed ( new RegionCrossedEventArgs ( oldSim , newSim ) ) ;
2009-04-29 06:05:31 +00:00
}
}
else
{
// The old simulator will (poorly) handle our movement still, so the connection isn't
// completely shot yet
2016-11-27 22:05:54 -06:00
Logger . Log ( $"Failed to connect to new region {endPoint} after crossing over" ,
2009-04-29 06:05:31 +00:00
Helpers . LogLevel . Warning , Client ) ;
}
}
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
2009-04-29 18:33:46 +00:00
/// <remarks>This packet is now being sent via the EventQueue</remarks>
2009-10-28 08:01:52 +00:00
protected void CrossedRegionHandler ( object sender , PacketReceivedEventArgs e )
2007-12-29 22:34:11 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
2007-12-29 22:34:11 +00:00
CrossedRegionPacket crossing = ( CrossedRegionPacket ) packet ;
2022-11-03 14:47:34 -05:00
Uri seedCap = new Uri ( Utils . BytesToString ( crossing . RegionData . SeedCapability ) ) ;
2007-12-29 22:34:11 +00:00
IPEndPoint endPoint = new IPEndPoint ( crossing . RegionData . SimIP , crossing . RegionData . SimPort ) ;
2016-11-27 22:05:54 -06:00
Logger . DebugLog ( $"Crossed in to new region area, attempting to connect to {endPoint}" , Client ) ;
2007-12-29 22:34:11 +00:00
Simulator oldSim = Client . Network . CurrentSim ;
Simulator newSim = Client . Network . Connect ( endPoint , crossing . RegionData . RegionHandle , true , seedCap ) ;
if ( newSim ! = null )
{
2016-11-27 22:05:54 -06:00
Logger . Log ( $"Finished crossing over in to region {newSim}" , Helpers . LogLevel . Info , Client ) ;
2007-12-29 22:34:11 +00:00
2009-10-16 02:53:53 +00:00
if ( m_RegionCrossed ! = null )
2007-12-29 22:34:11 +00:00
{
2009-10-16 02:53:53 +00:00
OnRegionCrossed ( new RegionCrossedEventArgs ( oldSim , newSim ) ) ;
2007-12-29 22:34:11 +00:00
}
}
else
{
// The old simulator will (poorly) handle our movement still, so the connection isn't
// completely shot yet
2016-11-27 22:05:54 -06:00
Logger . Log ( $"Failed to connect to new region {endPoint} after crossing over" ,
2008-05-06 23:57:26 +00:00
Helpers . LogLevel . Warning , Client ) ;
2007-12-29 22:34:11 +00:00
}
}
2008-01-05 23:06:19 +00:00
/// <summary>
/// Group Chat event handler
/// </summary>
2008-04-22 22:09:58 +00:00
/// <param name="capsKey">The capability Key</param>
2009-04-20 07:50:25 +00:00
/// <param name="message">IMessage object containing decoded data from OSD</param>
2008-01-05 23:06:19 +00:00
/// <param name="simulator"></param>
2009-10-16 02:53:53 +00:00
protected void ChatterBoxSessionEventReplyEventHandler ( string capsKey , IMessage message , Simulator simulator )
2008-01-05 23:06:19 +00:00
{
2009-04-13 09:32:25 +00:00
ChatterboxSessionEventReplyMessage msg = ( ChatterboxSessionEventReplyMessage ) message ;
2009-10-16 02:53:53 +00:00
2016-11-27 22:05:54 -06:00
if ( msg . Success ) return ;
RequestJoinGroupChat ( msg . SessionID ) ;
Logger . Log ( $"Attempt to send group chat to non-existant session for group {msg.SessionID}" ,
Helpers . LogLevel . Info , Client ) ;
2008-01-05 23:06:19 +00:00
}
/// <summary>
/// Response from request to join a group chat
/// </summary>
/// <param name="capsKey"></param>
2009-04-20 07:50:25 +00:00
/// <param name="message">IMessage object containing decoded data from OSD</param>
2008-01-05 23:06:19 +00:00
/// <param name="simulator"></param>
2009-10-16 02:53:53 +00:00
protected void ChatterBoxSessionStartReplyEventHandler ( string capsKey , IMessage message , Simulator simulator )
2008-01-05 23:06:19 +00:00
{
2010-05-01 17:05:24 +00:00
ChatterBoxSessionStartReplyMessage msg = ( ChatterBoxSessionStartReplyMessage ) message ;
2009-04-13 09:32:25 +00:00
2010-05-06 13:43:00 +00:00
if ( msg . Success )
{
lock ( GroupChatSessions . Dictionary )
2022-10-22 19:52:21 -05:00
{
2010-05-06 13:43:00 +00:00
if ( ! GroupChatSessions . ContainsKey ( msg . SessionID ) )
GroupChatSessions . Add ( msg . SessionID , new List < ChatSessionMember > ( ) ) ;
2022-10-22 19:52:21 -05:00
}
2010-05-06 13:43:00 +00:00
}
2010-05-01 17:05:24 +00:00
OnGroupChatJoined ( new GroupChatJoinedEventArgs ( msg . SessionID , msg . SessionName , msg . TempSessionID , msg . Success ) ) ;
2008-01-05 23:06:19 +00:00
}
/// <summary>
/// Someone joined or left group chat
/// </summary>
/// <param name="capsKey"></param>
2009-04-20 07:50:25 +00:00
/// <param name="message">IMessage object containing decoded data from OSD</param>
2008-01-05 23:06:19 +00:00
/// <param name="simulator"></param>
2009-04-29 18:33:46 +00:00
private void ChatterBoxSessionAgentListUpdatesEventHandler ( string capsKey , IMessage message , Simulator simulator )
2008-01-05 23:06:19 +00:00
{
2009-04-13 09:32:25 +00:00
ChatterBoxSessionAgentListUpdatesMessage msg = ( ChatterBoxSessionAgentListUpdatesMessage ) message ;
2008-01-05 23:06:19 +00:00
2009-06-11 04:04:44 +00:00
lock ( GroupChatSessions . Dictionary )
2022-10-22 19:52:21 -05:00
{
2009-04-13 09:32:25 +00:00
if ( ! GroupChatSessions . ContainsKey ( msg . SessionID ) )
GroupChatSessions . Add ( msg . SessionID , new List < ChatSessionMember > ( ) ) ;
2022-10-22 19:52:21 -05:00
}
2008-09-09 04:58:58 +00:00
2016-11-27 22:05:54 -06:00
foreach ( ChatterBoxSessionAgentListUpdatesMessage . AgentUpdatesBlock t in msg . Updates )
2008-09-09 04:58:58 +00:00
{
2009-04-13 09:32:25 +00:00
ChatSessionMember fndMbr ;
lock ( GroupChatSessions . Dictionary )
2008-01-05 23:06:19 +00:00
{
2016-11-27 22:05:54 -06:00
fndMbr = GroupChatSessions [ msg . SessionID ] . Find ( member = > member . AvatarKey = = t . AgentID ) ;
2009-04-13 09:32:25 +00:00
}
2008-09-09 04:58:58 +00:00
2016-11-27 22:05:54 -06:00
if ( t . Transition ! = null )
2009-04-13 09:32:25 +00:00
{
2016-11-27 22:05:54 -06:00
if ( t . Transition . Equals ( "ENTER" ) )
2008-09-09 04:58:58 +00:00
{
2008-09-13 00:10:47 +00:00
if ( fndMbr . AvatarKey = = UUID . Zero )
2008-09-09 04:58:58 +00:00
{
2016-11-27 22:05:54 -06:00
fndMbr = new ChatSessionMember { AvatarKey = t . AgentID } ;
2008-09-09 04:58:58 +00:00
lock ( GroupChatSessions . Dictionary )
2009-06-11 04:04:44 +00:00
GroupChatSessions [ msg . SessionID ] . Add ( fndMbr ) ;
2008-09-09 04:58:58 +00:00
2009-10-16 02:53:53 +00:00
if ( m_ChatSessionMemberAdded ! = null )
2008-09-09 04:58:58 +00:00
{
2009-10-16 02:53:53 +00:00
OnChatSessionMemberAdded ( new ChatSessionMemberAddedEventArgs ( msg . SessionID , fndMbr . AvatarKey ) ) ;
2008-09-09 04:58:58 +00:00
}
}
}
2016-11-27 22:05:54 -06:00
else if ( t . Transition . Equals ( "LEAVE" ) )
2008-09-09 04:58:58 +00:00
{
2008-10-09 16:48:44 +00:00
if ( fndMbr . AvatarKey ! = UUID . Zero )
2022-10-22 19:52:21 -05:00
{
2008-09-09 04:58:58 +00:00
lock ( GroupChatSessions . Dictionary )
2009-06-11 04:04:44 +00:00
GroupChatSessions [ msg . SessionID ] . Remove ( fndMbr ) ;
2022-10-22 19:52:21 -05:00
}
2008-09-09 04:58:58 +00:00
2009-10-16 02:53:53 +00:00
if ( m_ChatSessionMemberLeft ! = null )
2008-09-09 04:58:58 +00:00
{
2016-11-27 22:05:54 -06:00
OnChatSessionMemberLeft ( new ChatSessionMemberLeftEventArgs ( msg . SessionID , t . AgentID ) ) ;
2008-09-09 04:58:58 +00:00
}
2008-01-05 23:06:19 +00:00
}
}
2008-09-09 04:58:58 +00:00
2009-04-13 09:32:25 +00:00
// handle updates
2016-11-27 22:05:54 -06:00
ChatSessionMember update_member = GroupChatSessions . Dictionary [ msg . SessionID ] . Find (
m = > m . AvatarKey = = t . AgentID ) ;
2008-01-05 23:06:19 +00:00
2009-10-16 02:53:53 +00:00
2016-11-27 22:05:54 -06:00
update_member . MuteText = t . MuteText ;
update_member . MuteVoice = t . MuteVoice ;
2008-09-09 04:58:58 +00:00
2016-11-27 22:05:54 -06:00
update_member . CanVoiceChat = t . CanVoiceChat ;
update_member . IsModerator = t . IsModerator ;
2008-09-09 04:58:58 +00:00
2009-04-14 06:11:21 +00:00
// replace existing member record
lock ( GroupChatSessions . Dictionary )
{
2016-11-27 22:05:54 -06:00
int found = GroupChatSessions . Dictionary [ msg . SessionID ] . FindIndex ( m = > m . AvatarKey = = t . AgentID ) ;
2008-09-09 04:58:58 +00:00
2009-04-14 06:11:21 +00:00
if ( found > = 0 )
GroupChatSessions . Dictionary [ msg . SessionID ] [ found ] = update_member ;
}
2008-01-05 23:06:19 +00:00
}
}
/// <summary>
2009-04-29 18:33:46 +00:00
/// Handle a group chat Invitation
2008-01-05 23:06:19 +00:00
/// </summary>
2008-03-06 05:57:16 +00:00
/// <param name="capsKey">Caps Key</param>
2009-04-20 07:50:25 +00:00
/// <param name="message">IMessage object containing decoded data from OSD</param>
2008-03-06 05:57:16 +00:00
/// <param name="simulator">Originating Simulator</param>
2009-04-29 18:33:46 +00:00
private void ChatterBoxInvitationEventHandler ( string capsKey , IMessage message , Simulator simulator )
2008-09-09 04:58:58 +00:00
{
2016-11-27 22:05:54 -06:00
if ( m_InstantMessage = = null ) return ;
ChatterBoxInvitationMessage msg = ( ChatterBoxInvitationMessage ) message ;
//TODO: do something about invitations to voice group chat/friends conference
//Skip for now
if ( msg . Voice ) return ;
InstantMessage im = new InstantMessage
2008-09-09 04:58:58 +00:00
{
2016-11-27 22:05:54 -06:00
FromAgentID = msg . FromAgentID ,
FromAgentName = msg . FromAgentName ,
ToAgentID = msg . ToAgentID ,
ParentEstateID = msg . ParentEstateID ,
RegionID = msg . RegionID ,
Position = msg . Position ,
Dialog = msg . Dialog ,
GroupIM = msg . GroupIM ,
IMSessionID = msg . IMSessionID ,
Timestamp = msg . Timestamp ,
Message = msg . Message ,
Offline = msg . Offline ,
BinaryBucket = msg . BinaryBucket
} ;
try
{
ChatterBoxAcceptInvite ( msg . IMSessionID ) ;
2008-09-09 04:58:58 +00:00
}
2016-11-27 22:05:54 -06:00
catch ( Exception ex )
{
Logger . Log ( "Failed joining IM:" , Helpers . LogLevel . Warning , Client , ex ) ;
}
2021-09-23 19:47:07 -05:00
OnInstantMessage ( new InstantMessageEventArgs ( im , simulator ) ) ;
2008-09-09 04:58:58 +00:00
}
2008-01-05 23:06:19 +00:00
2008-09-09 04:58:58 +00:00
/// <summary>
/// Moderate a chat session
/// </summary>
/// <param name="sessionID">the <see cref="UUID"/> of the session to moderate, for group chats this will be the groups UUID</param>
/// <param name="memberID">the <see cref="UUID"/> of the avatar to moderate</param>
2009-04-20 07:50:25 +00:00
/// <param name="key">Either "voice" to moderate users voice, or "text" to moderate users text session</param>
2009-04-13 09:32:25 +00:00
/// <param name="moderate">true to moderate (silence user), false to allow avatar to speak</param>
public void ModerateChatSessions ( UUID sessionID , UUID memberID , string key , bool moderate )
2008-09-09 04:58:58 +00:00
{
if ( Client . Network . CurrentSim = = null | | Client . Network . CurrentSim . Caps = = null )
throw new Exception ( "ChatSessionRequest capability is not currently available" ) ;
2022-11-03 14:19:56 -05:00
Uri cap = Client . Network . CurrentSim . Caps . CapabilityURI ( "ChatSessionRequest" ) ;
2009-04-13 09:32:25 +00:00
2022-11-03 14:19:56 -05:00
if ( cap = = null )
2008-09-09 04:58:58 +00:00
{
throw new Exception ( "ChatSessionRequest capability is not currently available" ) ;
}
2022-11-03 14:19:56 -05:00
2022-11-04 07:13:09 -05:00
ChatSessionRequestMuteUpdate payload = new ChatSessionRequestMuteUpdate
2022-11-03 14:19:56 -05:00
{
RequestKey = key ,
RequestValue = moderate ,
SessionID = sessionID ,
AgentID = memberID
} ;
2022-11-04 07:13:09 -05:00
Task req = Client . HttpCapsClient . PostRequestAsync ( cap , OSDFormat . Xml , payload . Serialize ( ) , CancellationToken . None , null ) ;
2008-01-05 23:06:19 +00:00
}
2008-02-19 08:46:16 +00:00
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void AlertMessageHandler ( object sender , PacketReceivedEventArgs e )
2008-02-19 08:46:16 +00:00
{
2016-11-27 22:05:54 -06:00
if ( m_AlertMessage = = null ) return ;
Packet packet = e . Packet ;
2010-03-31 11:47:52 +00:00
2016-11-27 22:05:54 -06:00
AlertMessagePacket alert = ( AlertMessagePacket ) packet ;
2009-10-16 02:53:53 +00:00
2021-09-11 09:21:35 -05:00
string message = Utils . BytesToString ( alert . AlertData . Message ) ;
2022-08-27 20:36:50 -05:00
if ( alert . AlertInfo . Length > 0 )
{
string notificationid = Utils . BytesToString ( alert . AlertInfo [ 0 ] . Message ) ;
OSDMap extra = ( alert . AlertInfo [ 0 ] . ExtraParams ! = null & & alert . AlertInfo [ 0 ] . ExtraParams . Length > 0 )
? OSDParser . Deserialize ( alert . AlertInfo [ 0 ] . ExtraParams ) as OSDMap
: null ;
OnAlertMessage ( new AlertMessageEventArgs ( message , notificationid , extra ) ) ;
}
else
{
OnAlertMessage ( new AlertMessageEventArgs ( message , null , null ) ) ;
2021-09-11 09:21:35 -05:00
}
2008-02-19 08:46:16 +00:00
}
2008-04-05 00:01:49 +00:00
2021-09-09 17:49:06 -05:00
protected void AgentAlertMessageHandler ( object sender , PacketReceivedEventArgs e )
{
if ( m_AlertMessage = = null ) return ;
Packet packet = e . Packet ;
AgentAlertMessagePacket alert = ( AgentAlertMessagePacket ) packet ;
// HACK: Agent alerts support modal and Generic Alerts do not, but it's all the same for
// my simplified ass right now.
2021-09-11 09:21:35 -05:00
OnAlertMessage ( new AlertMessageEventArgs ( Utils . BytesToString ( alert . AlertData . Message ) , null , null ) ) ;
2021-09-09 17:49:06 -05:00
}
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void CameraConstraintHandler ( object sender , PacketReceivedEventArgs e )
2008-04-05 00:01:49 +00:00
{
2016-11-27 22:05:54 -06:00
if ( m_CameraConstraint = = null ) return ;
Packet packet = e . Packet ;
2010-03-31 11:47:52 +00:00
2016-11-27 22:05:54 -06:00
CameraConstraintPacket camera = ( CameraConstraintPacket ) packet ;
OnCameraConstraint ( new CameraConstraintEventArgs ( camera . CameraCollidePlane . Plane ) ) ;
2008-04-05 00:01:49 +00:00
}
2008-04-07 22:09:40 +00:00
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void ScriptSensorReplyHandler ( object sender , PacketReceivedEventArgs e )
2008-04-07 22:09:40 +00:00
{
2016-11-27 22:05:54 -06:00
if ( m_ScriptSensorReply = = null ) return ;
Packet packet = e . Packet ;
2010-03-31 11:47:52 +00:00
2016-11-27 22:05:54 -06:00
ScriptSensorReplyPacket reply = ( ScriptSensorReplyPacket ) packet ;
2008-04-07 22:09:40 +00:00
2016-11-27 22:05:54 -06:00
foreach ( ScriptSensorReplyPacket . SensedDataBlock block in reply . SensedData )
{
ScriptSensorReplyPacket . RequesterBlock requestor = reply . Requester ;
2008-09-09 04:58:58 +00:00
2016-11-27 22:05:54 -06:00
OnScriptSensorReply ( new ScriptSensorReplyEventArgs ( requestor . SourceID , block . GroupID , Utils . BytesToString ( block . Name ) ,
block . ObjectID , block . OwnerID , block . Position , block . Range , block . Rotation , ( ScriptSensorTypeFlags ) block . Type , block . Velocity ) ) ;
2008-04-07 22:09:40 +00:00
}
}
2009-10-28 08:01:52 +00:00
/// <summary>Process an incoming packet and raise the appropriate events</summary>
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
protected void AvatarSitResponseHandler ( object sender , PacketReceivedEventArgs e )
2008-04-07 22:09:40 +00:00
{
2016-11-27 22:05:54 -06:00
if ( m_AvatarSitResponse = = null ) return ;
Packet packet = e . Packet ;
2010-03-31 11:47:52 +00:00
2016-11-27 22:05:54 -06:00
AvatarSitResponsePacket sit = ( AvatarSitResponsePacket ) packet ;
2008-04-07 22:09:40 +00:00
2016-11-27 22:05:54 -06:00
OnAvatarSitResponse ( new AvatarSitResponseEventArgs ( sit . SitObject . ID , sit . SitTransform . AutoPilot , sit . SitTransform . CameraAtOffset ,
sit . SitTransform . CameraEyeOffset , sit . SitTransform . ForceMouselook , sit . SitTransform . SitPosition ,
sit . SitTransform . SitRotation ) ) ;
2008-04-07 22:09:40 +00:00
}
2011-03-05 23:48:49 +00:00
protected void MuteListUpdateHander ( object sender , PacketReceivedEventArgs e )
{
MuteListUpdatePacket packet = ( MuteListUpdatePacket ) e . Packet ;
if ( packet . MuteData . AgentID ! = Client . Self . AgentID )
{
return ;
}
2019-10-20 21:22:13 -05:00
ThreadPool . QueueUserWorkItem ( sync = >
2011-03-05 23:48:49 +00:00
{
using ( AutoResetEvent gotMuteList = new AutoResetEvent ( false ) )
{
string fileName = Utils . BytesToString ( packet . MuteData . Filename ) ;
string muteList = string . Empty ;
ulong xferID = 0 ;
byte [ ] assetData = null ;
EventHandler < XferReceivedEventArgs > xferCallback = ( object xsender , XferReceivedEventArgs xe ) = >
{
2016-11-27 22:05:54 -06:00
if ( xe . Xfer . XferID ! = xferID ) return ;
assetData = xe . Xfer . AssetData ;
gotMuteList . Set ( ) ;
2011-03-05 23:48:49 +00:00
} ;
Client . Assets . XferReceived + = xferCallback ;
xferID = Client . Assets . RequestAssetXfer ( fileName , true , false , UUID . Zero , AssetType . Unknown , true ) ;
if ( gotMuteList . WaitOne ( 60 * 1000 , false ) )
{
muteList = Utils . BytesToString ( assetData ) ;
lock ( MuteList . Dictionary )
{
MuteList . Dictionary . Clear ( ) ;
foreach ( var line in muteList . Split ( '\n' ) )
{
if ( line . Trim ( ) = = string . Empty ) continue ;
try
{
Match m ;
if ( ( m = Regex . Match ( line , @"(?<MyteType>\d+)\s+(?<Key>[a-zA-Z0-9-]+)\s+(?<Name>[^|]+)|(?<Flags>.+)" , RegexOptions . CultureInvariant ) ) . Success )
{
2016-11-27 22:05:54 -06:00
MuteEntry me = new MuteEntry
{
Type = ( MuteType ) int . Parse ( m . Groups [ "MyteType" ] . Value ) ,
ID = new UUID ( m . Groups [ "Key" ] . Value ) ,
Name = m . Groups [ "Name" ] . Value
} ;
2011-03-05 23:48:49 +00:00
int flags = 0 ;
int . TryParse ( m . Groups [ "Flags" ] . Value , out flags ) ;
me . Flags = ( MuteFlags ) flags ;
2016-11-27 22:05:54 -06:00
MuteList [ $"{me.ID}|{me.Name}" ] = me ;
2011-03-05 23:48:49 +00:00
}
else
{
throw new ArgumentException ( "Invalid mutelist entry line" ) ;
}
}
catch ( Exception ex )
{
Logger . Log ( "Failed to parse the mute list line: " + line , Helpers . LogLevel . Warning , Client , ex ) ;
}
}
}
OnMuteListUpdated ( EventArgs . Empty ) ;
}
else
{
Logger . Log ( "Timed out waiting for mute list download" , Helpers . LogLevel . Warning , Client ) ;
}
Client . Assets . XferReceived - = xferCallback ;
}
} ) ;
}
2007-08-29 08:55:53 +00:00
#endregion Packet Handlers
}
2009-10-16 02:53:53 +00:00
#region Event Argument Classes
2014-03-05 00:19:15 +01:00
/// <summary>
/// Class for sending info on the success of the opration
/// of setting the maturity access level
/// </summary>
public class AgentAccessEventArgs : EventArgs
{
/// <summary>
/// New maturity accesss level returned from the sim
/// </summary>
2016-11-27 22:05:54 -06:00
public string NewLevel { get ; }
2014-03-05 00:19:15 +01:00
/// <summary>
/// True if setting the new maturity access level has succedded
/// </summary>
2016-11-27 22:05:54 -06:00
public bool Success { get ; }
2014-03-05 00:19:15 +01:00
/// <summary>
/// Creates new instance of the EventArgs class
/// </summary>
/// <param name="success">Has setting new maturty access level succeeded</param>
/// <param name="newLevel">New maturity access level as returned by the simulator</param>
public AgentAccessEventArgs ( bool success , string newLevel )
{
2016-11-27 22:05:54 -06:00
NewLevel = newLevel ;
Success = success ;
2014-03-05 00:19:15 +01:00
}
}
2010-03-31 11:47:52 +00:00
2009-10-16 02:53:53 +00:00
/// <summary>
///
/// </summary>
public class ChatEventArgs : EventArgs
{
2009-11-02 02:25:34 +00:00
/// <summary>Get the simulator sending the message</summary>
2016-11-27 22:05:54 -06:00
public Simulator Simulator { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the message sent</summary>
2016-11-27 22:05:54 -06:00
public string Message { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the audible level of the message</summary>
2016-11-27 22:05:54 -06:00
public ChatAudibleLevel AudibleLevel { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the type of message sent: whisper, shout, etc</summary>
2016-11-27 22:05:54 -06:00
public ChatType Type { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the source type of the message sender</summary>
2016-11-27 22:05:54 -06:00
public ChatSourceType SourceType { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the name of the agent or object sending the message</summary>
2016-11-27 22:05:54 -06:00
public string FromName { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the ID of the agent or object sending the message</summary>
2016-11-27 22:05:54 -06:00
public UUID SourceID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the ID of the object owner, or the agent ID sending the message</summary>
2016-11-27 22:05:54 -06:00
public UUID OwnerID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the position of the agent or object sending the message</summary>
2016-11-27 22:05:54 -06:00
public Vector3 Position { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>
/// Construct a new instance of the ChatEventArgs object
/// </summary>
2009-11-29 21:59:38 +00:00
/// <param name="simulator">Sim from which the message originates</param>
2009-10-16 02:53:53 +00:00
/// <param name="message">The message sent</param>
/// <param name="audible">The audible level of the message</param>
/// <param name="type">The type of message sent: whisper, shout, etc</param>
/// <param name="sourceType">The source type of the message sender</param>
/// <param name="fromName">The name of the agent or object sending the message</param>
/// <param name="sourceId">The ID of the agent or object sending the message</param>
/// <param name="ownerid">The ID of the object owner, or the agent ID sending the message</param>
/// <param name="position">The position of the agent or object sending the message</param>
2009-11-02 02:25:34 +00:00
public ChatEventArgs ( Simulator simulator , string message , ChatAudibleLevel audible , ChatType type ,
2009-10-16 02:53:53 +00:00
ChatSourceType sourceType , string fromName , UUID sourceId , UUID ownerid , Vector3 position )
{
2016-11-27 22:05:54 -06:00
Simulator = simulator ;
Message = message ;
AudibleLevel = audible ;
Type = type ;
SourceType = sourceType ;
FromName = fromName ;
SourceID = sourceId ;
Position = position ;
OwnerID = ownerid ;
2009-10-16 02:53:53 +00:00
}
}
/// <summary>Contains the data sent when a primitive opens a dialog with this agent</summary>
public class ScriptDialogEventArgs : EventArgs
{
/// <summary>Get the dialog message</summary>
2016-11-27 22:05:54 -06:00
public string Message { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the name of the object that sent the dialog request</summary>
2016-11-27 22:05:54 -06:00
public string ObjectName { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the ID of the image to be displayed</summary>
2016-11-27 22:05:54 -06:00
public UUID ImageID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the ID of the primitive sending the dialog</summary>
2016-11-27 22:05:54 -06:00
public UUID ObjectID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the first name of the senders owner</summary>
2016-11-27 22:05:54 -06:00
public string FirstName { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the last name of the senders owner</summary>
2016-11-27 22:05:54 -06:00
public string LastName { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the communication channel the dialog was sent on, responses
/// should also send responses on this same channel</summary>
2016-11-27 22:05:54 -06:00
public int Channel { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the string labels containing the options presented in this dialog</summary>
2016-11-27 22:05:54 -06:00
public List < string > ButtonLabels { get ; }
2011-05-11 09:52:37 +00:00
/// <summary>UUID of the scritped object owner</summary>
2016-11-27 22:05:54 -06:00
public UUID OwnerID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>
/// Construct a new instance of the ScriptDialogEventArgs
/// </summary>
/// <param name="message">The dialog message</param>
/// <param name="objectName">The name of the object that sent the dialog request</param>
/// <param name="imageID">The ID of the image to be displayed</param>
/// <param name="objectID">The ID of the primitive sending the dialog</param>
/// <param name="firstName">The first name of the senders owner</param>
/// <param name="lastName">The last name of the senders owner</param>
/// <param name="chatChannel">The communication channel the dialog was sent on</param>
/// <param name="buttons">The string labels containing the options presented in this dialog</param>
2011-05-11 09:52:37 +00:00
/// <param name="ownerID">UUID of the scritped object owner</param>
2009-10-16 02:53:53 +00:00
public ScriptDialogEventArgs ( string message , string objectName , UUID imageID ,
2011-05-11 09:52:37 +00:00
UUID objectID , string firstName , string lastName , int chatChannel , List < string > buttons , UUID ownerID )
2009-10-16 02:53:53 +00:00
{
2016-11-27 22:05:54 -06:00
Message = message ;
ObjectName = objectName ;
ImageID = imageID ;
ObjectID = objectID ;
FirstName = firstName ;
LastName = lastName ;
Channel = chatChannel ;
ButtonLabels = buttons ;
OwnerID = ownerID ;
2009-10-16 02:53:53 +00:00
}
}
/// <summary>Contains the data sent when a primitive requests debit or other permissions
/// requesting a YES or NO answer</summary>
public class ScriptQuestionEventArgs : EventArgs
{
/// <summary>Get the simulator containing the object sending the request</summary>
2016-11-27 22:05:54 -06:00
public Simulator Simulator { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the ID of the script making the request</summary>
2016-11-27 22:05:54 -06:00
public UUID TaskID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the ID of the primitive containing the script making the request</summary>
2016-11-27 22:05:54 -06:00
public UUID ItemID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the name of the primitive making the request</summary>
2016-11-27 22:05:54 -06:00
public string ObjectName { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the name of the owner of the object making the request</summary>
2016-11-27 22:05:54 -06:00
public string ObjectOwnerName { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the permissions being requested</summary>
2016-11-27 22:05:54 -06:00
public ScriptPermission Questions { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>
/// Construct a new instance of the ScriptQuestionEventArgs
/// </summary>
/// <param name="simulator">The simulator containing the object sending the request</param>
/// <param name="taskID">The ID of the script making the request</param>
/// <param name="itemID">The ID of the primitive containing the script making the request</param>
/// <param name="objectName">The name of the primitive making the request</param>
/// <param name="objectOwner">The name of the owner of the object making the request</param>
/// <param name="questions">The permissions being requested</param>
public ScriptQuestionEventArgs ( Simulator simulator , UUID taskID , UUID itemID , string objectName , string objectOwner , ScriptPermission questions )
{
2016-11-27 22:05:54 -06:00
Simulator = simulator ;
TaskID = taskID ;
ItemID = itemID ;
ObjectName = objectName ;
ObjectOwnerName = objectOwner ;
Questions = questions ;
2009-10-16 02:53:53 +00:00
}
}
/// <summary>Contains the data sent when a primitive sends a request
/// to an agent to open the specified URL</summary>
public class LoadUrlEventArgs : EventArgs
{
/// <summary>Get the name of the object sending the request</summary>
2016-11-27 22:05:54 -06:00
public string ObjectName { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the ID of the object sending the request</summary>
2016-11-27 22:05:54 -06:00
public UUID ObjectID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the ID of the owner of the object sending the request</summary>
2016-11-27 22:05:54 -06:00
public UUID OwnerID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>True if the object is owned by a group</summary>
2016-11-27 22:05:54 -06:00
public bool OwnerIsGroup { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the message sent with the request</summary>
2016-11-27 22:05:54 -06:00
public string Message { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the URL the object sent</summary>
2016-11-27 22:05:54 -06:00
public string URL { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>
/// Construct a new instance of the LoadUrlEventArgs
/// </summary>
/// <param name="objectName">The name of the object sending the request</param>
/// <param name="objectID">The ID of the object sending the request</param>
/// <param name="ownerID">The ID of the owner of the object sending the request</param>
/// <param name="ownerIsGroup">True if the object is owned by a group</param>
/// <param name="message">The message sent with the request</param>
2016-11-30 23:12:10 -06:00
/// <param name="url">The URL the object sent</param>
public LoadUrlEventArgs ( string objectName , UUID objectID , UUID ownerID , bool ownerIsGroup , string message , string url )
2009-10-16 02:53:53 +00:00
{
2016-11-27 22:05:54 -06:00
ObjectName = objectName ;
ObjectID = objectID ;
OwnerID = ownerID ;
OwnerIsGroup = ownerIsGroup ;
Message = message ;
2016-11-30 23:12:10 -06:00
URL = url ;
2009-10-16 02:53:53 +00:00
}
}
/// <summary>The date received from an ImprovedInstantMessage</summary>
public class InstantMessageEventArgs : EventArgs
{
/// <summary>Get the InstantMessage object</summary>
2016-11-27 22:05:54 -06:00
public InstantMessage IM { get ; }
2022-11-06 21:21:53 -06:00
/// <summary>Get the simulator where the InstantMessage originated</summary>
2021-09-23 19:47:07 -05:00
public Simulator Simulator { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>
/// Construct a new instance of the InstantMessageEventArgs object
/// </summary>
/// <param name="im">the InstantMessage object</param>
2022-11-06 21:21:53 -06:00
/// <param name="simulator">the simulator where the InstantMessage originated</param>
2021-09-23 19:47:07 -05:00
public InstantMessageEventArgs ( InstantMessage im , Simulator simulator )
2009-10-16 02:53:53 +00:00
{
2016-11-27 22:05:54 -06:00
IM = im ;
2021-09-23 19:47:07 -05:00
Simulator = simulator ;
2009-10-16 02:53:53 +00:00
}
}
/// <summary>Contains the currency balance</summary>
public class BalanceEventArgs : EventArgs
{
/// <summary>
2022-11-06 21:21:53 -06:00
/// Get current balance
2009-10-16 02:53:53 +00:00
/// </summary>
2016-11-27 22:05:54 -06:00
public int Balance { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>
/// Construct a new BalanceEventArgs object
/// </summary>
2022-11-06 21:21:53 -06:00
/// <param name="balance">The current balance</param>
2009-10-16 02:53:53 +00:00
public BalanceEventArgs ( int balance )
{
2016-11-27 22:05:54 -06:00
Balance = balance ;
2009-10-16 02:53:53 +00:00
}
}
2022-11-06 21:21:53 -06:00
/// <summary>Contains the transaction summary when an item is purchased,
2009-10-16 02:53:53 +00:00
/// money is given, or land is purchased</summary>
public class MoneyBalanceReplyEventArgs : EventArgs
{
/// <summary>Get the ID of the transaction</summary>
2016-11-27 22:05:54 -06:00
public UUID TransactionID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>True of the transaction was successful</summary>
2016-11-27 22:05:54 -06:00
public bool Success { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the remaining currency balance</summary>
2016-11-27 22:05:54 -06:00
public int Balance { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the meters credited</summary>
2016-11-27 22:05:54 -06:00
public int MetersCredit { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the meters comitted</summary>
2016-11-27 22:05:54 -06:00
public int MetersCommitted { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the description of the transaction</summary>
2016-11-27 22:05:54 -06:00
public string Description { get ; }
2011-05-11 10:11:11 +00:00
/// <summary>Detailed transaction information</summary>
2016-11-27 22:05:54 -06:00
public TransactionInfo TransactionInfo { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>
/// Construct a new instance of the MoneyBalanceReplyEventArgs object
/// </summary>
/// <param name="transactionID">The ID of the transaction</param>
/// <param name="transactionSuccess">True of the transaction was successful</param>
/// <param name="balance">The current currency balance</param>
/// <param name="metersCredit">The meters credited</param>
2022-11-06 21:21:53 -06:00
/// <param name="metersCommitted">The meters committed</param>
2009-10-16 02:53:53 +00:00
/// <param name="description">A brief description of the transaction</param>
2012-11-17 14:23:04 +01:00
/// <param name="transactionInfo">Transaction info</param>
2011-05-11 10:11:11 +00:00
public MoneyBalanceReplyEventArgs ( UUID transactionID , bool transactionSuccess , int balance , int metersCredit , int metersCommitted , string description , TransactionInfo transactionInfo )
2009-10-16 02:53:53 +00:00
{
2016-11-27 22:05:54 -06:00
TransactionID = transactionID ;
Success = transactionSuccess ;
Balance = balance ;
MetersCredit = metersCredit ;
MetersCommitted = metersCommitted ;
Description = description ;
TransactionInfo = transactionInfo ;
2009-10-16 02:53:53 +00:00
}
}
// string message, TeleportStatus status, TeleportFlags flags
public class TeleportEventArgs : EventArgs
{
2016-11-27 22:05:54 -06:00
public string Message { get ; }
public TeleportStatus Status { get ; }
public TeleportFlags Flags { get ; }
2009-10-16 02:53:53 +00:00
public TeleportEventArgs ( string message , TeleportStatus status , TeleportFlags flags )
{
2016-11-27 22:05:54 -06:00
Message = message ;
Status = status ;
Flags = flags ;
2009-10-16 02:53:53 +00:00
}
}
/// <summary>Data sent from the simulator containing information about your agent and active group information</summary>
public class AgentDataReplyEventArgs : EventArgs
{
/// <summary>Get the agents first name</summary>
2016-11-27 22:05:54 -06:00
public string FirstName { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the agents last name</summary>
2016-11-27 22:05:54 -06:00
public string LastName { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the active group ID of your agent</summary>
2016-11-27 22:05:54 -06:00
public UUID ActiveGroupID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the active groups title of your agent</summary>
2016-11-27 22:05:54 -06:00
public string GroupTitle { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the combined group powers of your agent</summary>
2016-11-27 22:05:54 -06:00
public GroupPowers GroupPowers { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the active group name of your agent</summary>
2016-11-27 22:05:54 -06:00
public string GroupName { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>
/// Construct a new instance of the AgentDataReplyEventArgs object
/// </summary>
/// <param name="firstName">The agents first name</param>
/// <param name="lastName">The agents last name</param>
/// <param name="activeGroupID">The agents active group ID</param>
/// <param name="groupTitle">The group title of the agents active group</param>
/// <param name="groupPowers">The combined group powers the agent has in the active group</param>
/// <param name="groupName">The name of the group the agent has currently active</param>
public AgentDataReplyEventArgs ( string firstName , string lastName , UUID activeGroupID ,
string groupTitle , GroupPowers groupPowers , string groupName )
{
2016-11-27 22:05:54 -06:00
FirstName = firstName ;
LastName = lastName ;
ActiveGroupID = activeGroupID ;
GroupTitle = groupTitle ;
GroupPowers = groupPowers ;
GroupName = groupName ;
2009-10-16 02:53:53 +00:00
}
}
2010-03-31 11:47:52 +00:00
2009-10-16 02:53:53 +00:00
/// <summary>Data sent by the simulator to indicate the active/changed animations
/// applied to your agent</summary>
public class AnimationsChangedEventArgs : EventArgs
{
/// <summary>Get the dictionary that contains the changed animations</summary>
2016-11-27 22:05:54 -06:00
public InternalDictionary < UUID , int > Animations { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>
/// Construct a new instance of the AnimationsChangedEventArgs class
/// </summary>
/// <param name="agentAnimations">The dictionary that contains the changed animations</param>
public AnimationsChangedEventArgs ( InternalDictionary < UUID , int > agentAnimations )
{
2016-11-27 22:05:54 -06:00
Animations = agentAnimations ;
2009-10-16 02:53:53 +00:00
}
}
/// <summary>
/// Data sent from a simulator indicating a collision with your agent
/// </summary>
public class MeanCollisionEventArgs : EventArgs
{
/// <summary>Get the Type of collision</summary>
2016-11-27 22:05:54 -06:00
public MeanCollisionType Type { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the ID of the agent or object that collided with your agent</summary>
2016-11-27 22:05:54 -06:00
public UUID Aggressor { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the ID of the agent that was attacked</summary>
2016-11-27 22:05:54 -06:00
public UUID Victim { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>A value indicating the strength of the collision</summary>
2016-11-27 22:05:54 -06:00
public float Magnitude { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the time the collision occurred</summary>
2016-11-27 22:05:54 -06:00
public DateTime Time { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>
/// Construct a new instance of the MeanCollisionEventArgs class
/// </summary>
/// <param name="type">The type of collision that occurred</param>
/// <param name="perp">The ID of the agent or object that perpetrated the agression</param>
/// <param name="victim">The ID of the Victim</param>
/// <param name="magnitude">The strength of the collision</param>
/// <param name="time">The Time the collision occurred</param>
public MeanCollisionEventArgs ( MeanCollisionType type , UUID perp , UUID victim ,
float magnitude , DateTime time )
{
2016-11-27 22:05:54 -06:00
Type = type ;
Aggressor = perp ;
Victim = victim ;
Magnitude = magnitude ;
Time = time ;
2009-10-16 02:53:53 +00:00
}
}
/// <summary>Data sent to your agent when it crosses region boundaries</summary>
public class RegionCrossedEventArgs : EventArgs
{
/// <summary>Get the simulator your agent just left</summary>
2016-11-27 22:05:54 -06:00
public Simulator OldSimulator { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the simulator your agent is now in</summary>
2016-11-27 22:05:54 -06:00
public Simulator NewSimulator { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>
/// Construct a new instance of the RegionCrossedEventArgs class
/// </summary>
/// <param name="oldSim">The simulator your agent just left</param>
/// <param name="newSim">The simulator your agent is now in</param>
public RegionCrossedEventArgs ( Simulator oldSim , Simulator newSim )
{
2016-11-27 22:05:54 -06:00
OldSimulator = oldSim ;
NewSimulator = newSim ;
2009-10-16 02:53:53 +00:00
}
}
/// <summary>Data sent from the simulator when your agent joins a group chat session</summary>
public class GroupChatJoinedEventArgs : EventArgs
{
/// <summary>Get the ID of the group chat session</summary>
2016-11-27 22:05:54 -06:00
public UUID SessionID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the name of the session</summary>
2016-11-27 22:05:54 -06:00
public string SessionName { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the temporary session ID used for establishing new sessions</summary>
2016-11-27 22:05:54 -06:00
public UUID TmpSessionID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>True if your agent successfully joined the session</summary>
2016-11-27 22:05:54 -06:00
public bool Success { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>
/// Construct a new instance of the GroupChatJoinedEventArgs class
/// </summary>
/// <param name="groupChatSessionID">The ID of the session</param>
/// <param name="sessionName">The name of the session</param>
/// <param name="tmpSessionID">A temporary session id used for establishing new sessions</param>
/// <param name="success">True of your agent successfully joined the session</param>
public GroupChatJoinedEventArgs ( UUID groupChatSessionID , string sessionName , UUID tmpSessionID , bool success )
{
2016-11-27 22:05:54 -06:00
SessionID = groupChatSessionID ;
SessionName = sessionName ;
TmpSessionID = tmpSessionID ;
Success = success ;
2009-10-16 02:53:53 +00:00
}
}
2010-03-31 11:47:52 +00:00
2009-10-16 02:53:53 +00:00
/// <summary>Data sent by the simulator containing urgent messages</summary>
public class AlertMessageEventArgs : EventArgs
{
2016-11-27 22:05:54 -06:00
public string Message { get ; }
2021-09-11 09:21:35 -05:00
public string NotificationId { get ; }
2021-09-14 10:01:41 -05:00
public OSDMap ExtraParams { get ; }
2021-09-11 09:21:35 -05:00
2022-08-27 20:36:50 -05:00
/// <summary>
/// Construct a new instance of the AlertMessageEventArgs class
/// </summary>
/// <param name="message">user readable message</param>
/// <param name="notificationid">notification id for alert, may be null</param>
2021-09-11 09:21:35 -05:00
/// <param name="extraparams">any extra params in OSD format, may be null</param>
2022-08-27 20:36:50 -05:00
public AlertMessageEventArgs ( string message , string notificationid , OSDMap extraparams )
{
Message = message ;
NotificationId = notificationid ;
ExtraParams = extraparams ;
2009-10-16 02:53:53 +00:00
}
}
/// <summary>Data sent by a script requesting to take or release specified controls to your agent</summary>
public class ScriptControlEventArgs : EventArgs
{
/// <summary>Get the controls the script is attempting to take or release to the agent</summary>
2016-11-27 22:05:54 -06:00
public ScriptControlChange Controls { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>True if the script is passing controls back to the agent</summary>
2016-11-27 22:05:54 -06:00
public bool Pass { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>True if the script is requesting controls be released to the script</summary>
2016-11-27 22:05:54 -06:00
public bool Take { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>
/// Construct a new instance of the ScriptControlEventArgs class
/// </summary>
/// <param name="controls">The controls the script is attempting to take or release to the agent</param>
/// <param name="pass">True if the script is passing controls back to the agent</param>
/// <param name="take">True if the script is requesting controls be released to the script</param>
public ScriptControlEventArgs ( ScriptControlChange controls , bool pass , bool take )
{
2016-11-27 22:05:54 -06:00
Controls = controls ;
Pass = pass ;
Take = take ;
2009-10-16 02:53:53 +00:00
}
}
/// <summary>
/// Data sent from the simulator to an agent to indicate its view limits
/// </summary>
public class CameraConstraintEventArgs : EventArgs
{
/// <summary>Get the collision plane</summary>
2016-11-27 22:05:54 -06:00
public Vector4 CollidePlane { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>
/// Construct a new instance of the CameraConstraintEventArgs class
/// </summary>
/// <param name="collidePlane">The collision plane</param>
public CameraConstraintEventArgs ( Vector4 collidePlane )
{
2016-11-27 22:05:54 -06:00
CollidePlane = collidePlane ;
2009-10-16 02:53:53 +00:00
}
}
2010-03-31 11:47:52 +00:00
2009-10-16 02:53:53 +00:00
/// <summary>
/// Data containing script sensor requests which allow an agent to know the specific details
/// of a primitive sending script sensor requests
/// </summary>
public class ScriptSensorReplyEventArgs : EventArgs
{
/// <summary>Get the ID of the primitive sending the sensor</summary>
2016-11-27 22:05:54 -06:00
public UUID RequestorID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the ID of the group associated with the primitive</summary>
2016-11-27 22:05:54 -06:00
public UUID GroupID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the name of the primitive sending the sensor</summary>
2016-11-27 22:05:54 -06:00
public string Name { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the ID of the primitive sending the sensor</summary>
2016-11-27 22:05:54 -06:00
public UUID ObjectID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the ID of the owner of the primitive sending the sensor</summary>
2016-11-27 22:05:54 -06:00
public UUID OwnerID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the position of the primitive sending the sensor</summary>
2016-11-27 22:05:54 -06:00
public Vector3 Position { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the range the primitive specified to scan</summary>
2016-11-27 22:05:54 -06:00
public float Range { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the rotation of the primitive sending the sensor</summary>
2016-11-27 22:05:54 -06:00
public Quaternion Rotation { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the type of sensor the primitive sent</summary>
2016-11-27 22:05:54 -06:00
public ScriptSensorTypeFlags Type { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the velocity of the primitive sending the sensor</summary>
2016-11-27 22:05:54 -06:00
public Vector3 Velocity { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>
/// Construct a new instance of the ScriptSensorReplyEventArgs
/// </summary>
/// <param name="requestorID">The ID of the primitive sending the sensor</param>
/// <param name="groupID">The ID of the group associated with the primitive</param>
/// <param name="name">The name of the primitive sending the sensor</param>
/// <param name="objectID">The ID of the primitive sending the sensor</param>
/// <param name="ownerID">The ID of the owner of the primitive sending the sensor</param>
/// <param name="position">The position of the primitive sending the sensor</param>
/// <param name="range">The range the primitive specified to scan</param>
/// <param name="rotation">The rotation of the primitive sending the sensor</param>
/// <param name="type">The type of sensor the primitive sent</param>
/// <param name="velocity">The velocity of the primitive sending the sensor</param>
public ScriptSensorReplyEventArgs ( UUID requestorID , UUID groupID , string name ,
UUID objectID , UUID ownerID , Vector3 position , float range , Quaternion rotation ,
ScriptSensorTypeFlags type , Vector3 velocity )
{
2016-11-27 22:05:54 -06:00
RequestorID = requestorID ;
GroupID = groupID ;
Name = name ;
ObjectID = objectID ;
OwnerID = ownerID ;
Position = position ;
Range = range ;
Rotation = rotation ;
Type = type ;
Velocity = velocity ;
2009-10-16 02:53:53 +00:00
}
}
2010-03-31 11:47:52 +00:00
2009-10-16 02:53:53 +00:00
/// <summary>Contains the response data returned from the simulator in response to a <see cref="RequestSit"/></summary>
public class AvatarSitResponseEventArgs : EventArgs
2010-03-31 11:47:52 +00:00
{
2009-10-16 02:53:53 +00:00
/// <summary>Get the ID of the primitive the agent will be sitting on</summary>
2016-11-27 22:05:54 -06:00
public UUID ObjectID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>True if the simulator Autopilot functions were involved</summary>
2016-11-27 22:05:54 -06:00
public bool Autopilot { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the camera offset of the agent when seated</summary>
2016-11-27 22:05:54 -06:00
public Vector3 CameraAtOffset { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the camera eye offset of the agent when seated</summary>
2016-11-27 22:05:54 -06:00
public Vector3 CameraEyeOffset { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>True of the agent will be in mouselook mode when seated</summary>
2016-11-27 22:05:54 -06:00
public bool ForceMouselook { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the position of the agent when seated</summary>
2016-11-27 22:05:54 -06:00
public Vector3 SitPosition { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the rotation of the agent when seated</summary>
2016-11-27 22:05:54 -06:00
public Quaternion SitRotation { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Construct a new instance of the AvatarSitResponseEventArgs object</summary>
public AvatarSitResponseEventArgs ( UUID objectID , bool autoPilot , Vector3 cameraAtOffset ,
Vector3 cameraEyeOffset , bool forceMouselook , Vector3 sitPosition , Quaternion sitRotation )
{
2016-11-27 22:05:54 -06:00
ObjectID = objectID ;
Autopilot = autoPilot ;
CameraAtOffset = cameraAtOffset ;
CameraEyeOffset = cameraEyeOffset ;
ForceMouselook = forceMouselook ;
SitPosition = sitPosition ;
SitRotation = sitRotation ;
2009-10-16 02:53:53 +00:00
}
}
/// <summary>Data sent when an agent joins a chat session your agent is currently participating in</summary>
public class ChatSessionMemberAddedEventArgs : EventArgs
{
/// <summary>Get the ID of the chat session</summary>
2016-11-27 22:05:54 -06:00
public UUID SessionID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the ID of the agent that joined</summary>
2016-11-27 22:05:54 -06:00
public UUID AgentID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>
/// Construct a new instance of the ChatSessionMemberAddedEventArgs object
/// </summary>
/// <param name="sessionID">The ID of the chat session</param>
/// <param name="agentID">The ID of the agent joining</param>
public ChatSessionMemberAddedEventArgs ( UUID sessionID , UUID agentID )
{
2016-11-27 22:05:54 -06:00
SessionID = sessionID ;
AgentID = agentID ;
2009-10-16 02:53:53 +00:00
}
}
/// <summary>Data sent when an agent exits a chat session your agent is currently participating in</summary>
public class ChatSessionMemberLeftEventArgs : EventArgs
{
/// <summary>Get the ID of the chat session</summary>
2016-11-27 22:05:54 -06:00
public UUID SessionID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>Get the ID of the agent that left</summary>
2016-11-27 22:05:54 -06:00
public UUID AgentID { get ; }
2009-10-16 02:53:53 +00:00
/// <summary>
/// Construct a new instance of the ChatSessionMemberLeftEventArgs object
/// </summary>
/// <param name="sessionID">The ID of the chat session</param>
/// <param name="agentID">The ID of the Agent that left</param>
public ChatSessionMemberLeftEventArgs ( UUID sessionID , UUID agentID )
{
2016-11-27 22:05:54 -06:00
SessionID = sessionID ;
AgentID = agentID ;
2009-10-16 02:53:53 +00:00
}
}
2010-11-20 13:46:21 +00:00
/// <summary>Event arguments with the result of setting display name operation</summary>
public class SetDisplayNameReplyEventArgs : EventArgs
{
/// <summary>Status code, 200 indicates settign display name was successful</summary>
2016-11-27 22:05:54 -06:00
public int Status { get ; }
2010-11-20 13:46:21 +00:00
/// <summary>Textual description of the status</summary>
2016-11-27 22:05:54 -06:00
public string Reason { get ; }
2010-11-20 13:46:21 +00:00
/// <summary>Details of the newly set display name</summary>
2016-11-27 22:05:54 -06:00
public AgentDisplayName DisplayName { get ; }
2010-11-20 13:46:21 +00:00
/// <summary>Default constructor</summary>
public SetDisplayNameReplyEventArgs ( int status , string reason , AgentDisplayName displayName )
{
2016-11-27 22:05:54 -06:00
Status = status ;
Reason = reason ;
DisplayName = displayName ;
2010-11-20 13:46:21 +00:00
}
}
2009-10-16 02:53:53 +00:00
#endregion
2007-03-09 20:26:07 +00:00
}