diff --git a/OpenMetaverse.GUI/LocalChat.cs b/OpenMetaverse.GUI/LocalChat.cs index 20cf4628..57378e07 100644 --- a/OpenMetaverse.GUI/LocalChat.cs +++ b/OpenMetaverse.GUI/LocalChat.cs @@ -157,17 +157,17 @@ namespace OpenMetaverse.GUI private void InitializeClient(GridClient client) { _Client = client; - _Client.Self.OnChat += new AgentManager.ChatCallback(Self_OnChat); + _Client.Self.ChatFromSimulator += new EventHandler(Self_ChatFromSimulator); } - void Self_OnChat(string message, ChatAudibleLevel audible, ChatType type, ChatSourceType sourceType, string fromName, UUID id, UUID ownerid, Vector3 position) + void Self_ChatFromSimulator(object sender, ChatEventArgs e) { - if (audible == ChatAudibleLevel.Fully && type != ChatType.StartTyping && type != ChatType.StopTyping) + if (e.AudibleLevel == ChatAudibleLevel.Fully && e.Type != ChatType.StartTyping && e.Type != ChatType.StopTyping) { Color color; - if (sourceType == ChatSourceType.Agent) color = Color.FromKnownColor(KnownColor.ControlText); + if (e.SourceType == ChatSourceType.Agent) color = Color.FromKnownColor(KnownColor.ControlText); else color = Color.FromKnownColor(KnownColor.GrayText); - LogChat(fromName, type, message, color); + LogChat(e.FromName, e.Type, e.Message, color); } } diff --git a/OpenMetaverse.GUI/MessageBar.cs b/OpenMetaverse.GUI/MessageBar.cs index 3bf2093d..1bdab886 100644 --- a/OpenMetaverse.GUI/MessageBar.cs +++ b/OpenMetaverse.GUI/MessageBar.cs @@ -208,7 +208,26 @@ namespace OpenMetaverse.GUI private void InitializeClient(GridClient client) { _Client = client; - _Client.Self.OnInstantMessage += new AgentManager.InstantMessageCallback(Self_OnInstantMessage); + _Client.Self.IM += Self_IM; + } + + void Self_IM(object sender, InstantMessageEventArgs e) + { + if (e.IM.Dialog == InstantMessageDialog.MessageFromAgent) + { + lock (_Sessions) + { + if (_Sessions.ContainsKey(e.IM.FromAgentID)) + { + _Sessions[e.IM.FromAgentID].IMSessionID = e.IM.IMSessionID; + _Sessions[e.IM.FromAgentID].Window.LogText(e.IM.FromAgentName + ": " + e.IM.Message, Color.FromKnownColor(KnownColor.ControlText)); + } + else + { + CreateSession(e.IM.FromAgentName, e.IM.FromAgentID, e.IM.IMSessionID, false); + } + } + } } void button_OnMessageNeedsSending(UUID targetID, string message) @@ -231,26 +250,7 @@ namespace OpenMetaverse.GUI if (this.InvokeRequired) this.BeginInvoke((MethodInvoker)delegate { button.Window.Show(); button.Window.Activate(); }); else { button.Window.Show(); button.Window.Activate(); } } - - void Self_OnInstantMessage(InstantMessage im, Simulator simulator) - { - if (im.Dialog == InstantMessageDialog.MessageFromAgent) - { - lock (_Sessions) - { - if (_Sessions.ContainsKey(im.FromAgentID)) - { - _Sessions[im.FromAgentID].IMSessionID = im.IMSessionID; - _Sessions[im.FromAgentID].Window.LogText(im.FromAgentName + ": " + im.Message, Color.FromKnownColor(KnownColor.ControlText)); - } - else - { - CreateSession(im.FromAgentName, im.FromAgentID, im.IMSessionID, false); - } - } - } - } - + void button_Disposed(object sender, EventArgs e) { MessageBarButton button = (MessageBarButton)sender; diff --git a/OpenMetaverse.GUI/StatusOutput.cs b/OpenMetaverse.GUI/StatusOutput.cs index 048b08aa..9f8b50b7 100644 --- a/OpenMetaverse.GUI/StatusOutput.cs +++ b/OpenMetaverse.GUI/StatusOutput.cs @@ -86,16 +86,21 @@ namespace OpenMetaverse.GUI _Client.Network.OnCurrentSimChanged += new NetworkManager.CurrentSimChangedCallback(Network_OnCurrentSimChanged); _Client.Network.OnDisconnected += new NetworkManager.DisconnectedCallback(Network_OnDisconnected); _Client.Network.OnLogin += new NetworkManager.LoginCallback(Network_OnLogin); - _Client.Self.OnAlertMessage += new AgentManager.AlertMessageCallback(Self_OnAlertMessage); - _Client.Self.OnMoneyBalanceReplyReceived += new AgentManager.MoneyBalanceReplyCallback(Self_OnMoneyBalanceReplyReceived); + _Client.Self.AlertMessage += Self_AlertMessage; + _Client.Self.MoneyBalanceReply += Self_MoneyBalanceReply; } - void Self_OnMoneyBalanceReplyReceived(UUID transactionID, bool transactionSuccess, int balance, int metersCredit, int metersCommitted, string description) + void Self_AlertMessage(object sender, AlertMessageEventArgs e) { - if (description != String.Empty) LogText(description, Color.Green); - LogText("Balance: L$" + balance, Color.Green); + LogText(e.Message, Color.Gray); } + void Self_MoneyBalanceReply(object sender, MoneyBalanceReplyEventArgs e) + { + if (e.Description != String.Empty) LogText(e.Description, Color.Green); + LogText("Balance: L$" + e.Balance, Color.Green); + } + void Network_OnCurrentSimChanged(Simulator PreviousSimulator) { if (Client.Network.CurrentSim != null) @@ -114,11 +119,5 @@ namespace OpenMetaverse.GUI if (login == LoginStatus.Failed) LogText("Login failed: " + message, Color.Red); else if (login != LoginStatus.Success) LogText(message, Color.Black); } - - void Self_OnAlertMessage(string message) - { - LogText(message, Color.Gray); - } - } } diff --git a/OpenMetaverse/AgentManager.cs b/OpenMetaverse/AgentManager.cs index c00d610a..35c13f61 100644 --- a/OpenMetaverse/AgentManager.cs +++ b/OpenMetaverse/AgentManager.cs @@ -26,16 +26,16 @@ using System; using System.Net; -using System.Collections.Generic; -using System.Threading; using System.Text; +using System.Threading; using System.Reflection; +using System.Collections.Generic; using OpenMetaverse.StructuredData; using OpenMetaverse.Http; +using OpenMetaverse.Assets; using OpenMetaverse.Packets; using OpenMetaverse.Interfaces; using OpenMetaverse.Messages.Linden; -using OpenMetaverse.Assets; namespace OpenMetaverse { @@ -211,7 +211,7 @@ namespace OpenMetaverse StartTyping = 4, /// Event message when an Avatar has stopped typing StopTyping = 5, - /// Unknown + /// Send the message to the debug channel Debug = 6, /// Event message when an object uses llOwnerSay OwnerSay = 8, @@ -495,7 +495,7 @@ namespace OpenMetaverse Right = 8, /// Up (E or PgUp) Up = 16, - /// Down (C or PgDown + /// Down (C or PgDown) Down = 32, /// Rotate left (A or left arrow) RotateLeft = 256, @@ -667,18 +667,11 @@ namespace OpenMetaverse /// Context specific packed data public byte[] BinaryBucket; - //Print the contents of a message + /// Print the struct data as a string + /// A string containing the field name, and field value public override string ToString() { - string result = ""; - Type imType = this.GetType(); - FieldInfo[] fields = imType.GetFields(); - foreach (FieldInfo field in fields) - { - result += (field.Name + " = " + field.GetValue(this) + " "); - } - return result; - + return Helpers.StructToString(this); } } @@ -689,128 +682,241 @@ namespace OpenMetaverse /// public partial class AgentManager { - #region Callbacks + #region Event Delegates - /// - /// Triggered on incoming chat messages - /// - /// Text of chat message - /// Audible level of this chat message - /// Type of chat (whisper, shout, status, etc.) - /// Source of the chat message - /// Name of the sending object - /// Key of source - /// Key of the sender - /// Senders position - public delegate void ChatCallback(string message, ChatAudibleLevel audible, ChatType type, - ChatSourceType sourceType, string fromName, UUID id, UUID ownerid, Vector3 position); + /// The event subscribers. null if no subcribers + private EventHandler m_Chat; - /// - /// Triggered when a script pops up a dialog box - /// - /// The dialog box message - /// Name of the object that sent the dialog - /// Image to be displayed in the dialog - /// ID of the object that sent the dialog - /// First name of the object owner - /// Last name of the object owner - /// Chat channel that the object is communicating on - /// List of button labels - public delegate void ScriptDialogCallback(string message, string objectName, UUID imageID, - UUID objectID, string firstName, string lastName, int chatChannel, List buttons); + /// Raises the ChatFromSimulator event + /// A ChatEventArgs object containing the + /// data returned from the data server + protected virtual void OnChat(ChatEventArgs e) + { + EventHandler handler = m_Chat; + if (handler != null) + handler(this, e); + } - /// - /// Triggered when a script asks for permissions - /// - /// Simulator object this request comes from - /// Task ID of the script requesting permissions - /// ID of the object containing the script - /// Name of the object containing the script - /// Name of the object's owner - /// Bitwise value representing the requested permissions - public delegate void ScriptQuestionCallback(Simulator simulator, UUID taskID, UUID itemID, string objectName, string objectOwner, ScriptPermission questions); + /// Thread sync lock object + private readonly object m_ChatLock = new object(); - /// - /// Triggered when a script displays a URL via llLoadURL - /// - /// Name of the scripted object - /// ID of the scripted object - /// ID of the object's owner - /// Whether or not ownerID is a group - /// Message displayed along with URL - /// Offered URL - public delegate void LoadURLCallback(string objectName, UUID objectID, UUID ownerID, bool ownerIsGroup, string message, string URL); + /// Raised when a scripted object or agent within range sends a public message + public event EventHandler ChatFromSimulator + { + add { lock (m_ChatLock) { m_Chat += value; } } + remove { lock (m_ChatLock) { m_Chat -= value; } } + } + + /// The event subscribers. null if no subcribers + private EventHandler m_ScriptDialog; - /// - /// Triggered when the L$ account balance for this avatar changes - /// - /// The new account balance - public delegate void BalanceCallback(int balance); + /// Raises the ScriptDialog event + /// A SctriptDialogEventArgs object containing the + /// data returned from the data server + protected virtual void OnScriptDialog(ScriptDialogEventArgs e) + { + EventHandler handler = m_ScriptDialog; + if (handler != null) + handler(this, e); + } - /// - /// Triggered on Money Balance Reply - /// - /// ID provided in Request Money Balance, or auto-generated by system events - /// Was the transaction successful - /// Current balance - /// Land use credits you have - /// Tier committed to group(s) - /// Description of the transaction - public delegate void MoneyBalanceReplyCallback(UUID transactionID, bool transactionSuccess, int balance, int metersCredit, int metersCommitted, string description); + /// Thread sync lock object + private readonly object m_ScriptDialogLock = new object(); + /// Raised when a scripted object sends a dialog box containing possible + /// options an agent can respond to + public event EventHandler ScriptDialog + { + add { lock (m_ScriptDialogLock) { m_ScriptDialog += value; } } + remove { lock (m_ScriptDialogLock) { m_ScriptDialog -= value; } } + } + + /// The event subscribers. null if no subcribers + private EventHandler m_ScriptQuestion; + /// Raises the ScriptQuestion event + /// A ScriptQuestionEventArgs object containing the + /// data returned from the data server + protected virtual void OnScriptQuestion(ScriptQuestionEventArgs e) + { + EventHandler handler = m_ScriptQuestion; + if (handler != null) + handler(this, e); + } + + /// Thread sync lock object + private readonly object m_ScriptQuestionLock = new object(); + /// Raised when an object requests a change in the permissions an agent has permitted + public event EventHandler ScriptQuestion + { + add { lock (m_ScriptQuestionLock) { m_ScriptQuestion += value; } } + remove { lock (m_ScriptQuestionLock) { m_ScriptQuestion -= value; } } + } + + /// The event subscribers. null if no subcribers + private EventHandler m_LoadURL; + + /// Raises the LoadURL event + /// A LoadUrlEventArgs object containing the + /// data returned from the data server + protected virtual void OnLoadURL(LoadUrlEventArgs e) + { + EventHandler handler = m_LoadURL; + if (handler != null) + handler(this, e); + } + + /// Thread sync lock object + private readonly object m_LoadUrlLock = new object(); + /// Raised when a script requests an agent open the specified URL + public event EventHandler LoadURL + { + add { lock (m_LoadUrlLock) { m_LoadURL += value; } } + remove { lock (m_LoadUrlLock) { m_LoadURL -= value; } } + } + + /// The event subscribers. null if no subcribers + public EventHandler m_Balance; + + /// Raises the MoneyBalance event + /// A BalanceEventArgs object containing the + /// data returned from the data server + protected virtual void OnBalance(BalanceEventArgs e) + { + EventHandler handler = m_Balance; + if (handler != null) + handler(this, e); + } + + /// Thread sync lock object + private readonly object m_BalanceLock = new object(); + + /// Raised when an agents currency balance is updated + public event EventHandler MoneyBalance + { + add { lock (m_BalanceLock) { m_Balance += value; } } + remove { lock (m_BalanceLock) { m_Balance -= value; } } + } + + /// The event subscribers. null if no subcribers + public EventHandler m_MoneyBalance; + + /// Raises the MoneyBalanceReply event + /// A MoneyBalanceReplyEventArgs object containing the + /// data returned from the data server + protected virtual void OnMoneyBalanceReply(MoneyBalanceReplyEventArgs e) + { + EventHandler handler = m_MoneyBalance; + if (handler != null) + handler(this, e); + } + + /// Thread sync lock object + private readonly object m_MoneyBalanceReplyLock = new object(); + + /// Raised when a transaction occurs involving currency such as a land purchase + public event EventHandler MoneyBalanceReply + { + add { lock (m_MoneyBalanceReplyLock) { m_MoneyBalance += value; } } + remove { lock (m_MoneyBalanceReplyLock) { m_MoneyBalance -= value; } } + } /// /// Triggered on incoming instant messages /// /// Instant message data structure /// Simulator where this IM was received from - public delegate void InstantMessageCallback(InstantMessage im, Simulator simulator); + //public delegate void InstantMessageCallback(InstantMessage im, Simulator simulator); - /// - /// Triggered for any status updates of a teleport (progress, failed, succeeded) - /// - /// A message about the current teleport status - /// The current status of the teleport - /// Various flags describing the teleport - public delegate void TeleportCallback(string message, TeleportStatus status, TeleportFlags flags); + /// The event subscribers. null if no subcribers + private EventHandler m_InstantMessage; - /// - /// Reply to a request to join a group, informs whether it was successful or not - /// - /// The group we attempted to join - /// Whether we joined the group or not - public delegate void JoinGroupCallback(UUID groupID, bool success); + /// Raises the IM event + /// A InstantMessageEventArgs object containing the + /// data returned from the data server + protected virtual void OnInstantMessage(InstantMessageEventArgs e) + { + EventHandler handler = m_InstantMessage; + if (handler != null) + handler(this, e); + } - /// - /// Reply to a request to leave a group, informs whether it was successful or not - /// - /// The group we attempted to leave - /// Whether we left the group or not - public delegate void LeaveGroupCallback(UUID groupID, bool success); + /// Thread sync lock object + private readonly object m_InstantMessageLock = new object(); + /// Raised when an ImprovedInstantMessage packet is recieved from the simulator, this is used for everything from + /// private messaging to friendship offers. The Dialog field defines what type of message has arrived + public event EventHandler IM + { + add { lock (m_InstantMessageLock) { m_InstantMessage += value; } } + remove { lock (m_InstantMessageLock) { m_InstantMessage -= value; } } + } + + /// The event subscribers. null if no subcribers + private EventHandler m_Teleport; - /// - /// Informs the avatar that it is no longer a member of a group - /// - /// The group Key we are no longer a member of - public delegate void GroupDroppedCallback(UUID groupID); + /// Raises the TeleportProgress event + /// A TeleportEventArgs object containing the + /// data returned from the data server + protected virtual void OnTeleport(TeleportEventArgs e) + { + EventHandler handler = m_Teleport; + if (handler != null) + handler(this, e); + } - /// - /// Reply to an AgentData request - /// - /// First name of Avatar - /// Last name of Avatar - /// Key of Group Avatar has active - /// Avatars Active Title - /// Powers Avatar has in group - /// Name of the Group - public delegate void AgentDataCallback(string firstName, string lastName, UUID activeGroupID, - string groupTitle, GroupPowers groupPowers, string groupName); + /// Thread sync lock object + private readonly object m_TeleportLock = new object(); + /// 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 + public event EventHandler TeleportProgress + { + add { lock (m_TeleportLock) { m_Teleport += value; } } + remove { lock (m_TeleportLock) { m_Teleport += value; } } + } + + /// The event subscribers. null if no subcribers + private EventHandler m_AgentData; - /// - /// Triggered when the current agent animations change - /// - /// A convenience reference to the - /// SignaledAnimations collection - public delegate void AnimationsChangedCallback(InternalDictionary agentAnimations); + /// Raises the AgentDataReply event + /// A AgentDataReplyEventArgs object containing the + /// data returned from the data server + protected virtual void OnAgentData(AgentDataReplyEventArgs e) + { + EventHandler handler = m_AgentData; + if (handler != null) + handler(this, e); + } + + /// Thread sync lock object + private readonly object m_AgentDataLock = new object(); + + /// Raised when a simulator sends agent specific information for our avatar. + public event EventHandler AgentDataReply + { + add { lock (m_AgentDataLock) { m_AgentData += value; } } + remove { lock (m_AgentDataLock) { m_AgentData -= value; } } + } + + /// The event subscribers. null if no subcribers + private EventHandler m_AnimationsChanged; + + /// Raises the AnimationsChanged event + /// A AnimationsChangedEventArgs object containing the + /// data returned from the data server + protected virtual void OnAnimationsChanged(AnimationsChangedEventArgs e) + { + EventHandler handler = m_AnimationsChanged; + if (handler != null) + handler(this, e); + } + + /// Thread sync lock object + private readonly object m_AnimationsChangedLock = new object(); + + /// Raised when our agents animation playlist changes + public event EventHandler AnimationsChanged + { + add { lock (m_AnimationsChangedLock) { m_AnimationsChanged += value; } } + remove { lock (m_AnimationsChangedLock) { m_AnimationsChanged -= value; } } + } /// /// Triggered when an object or avatar forcefully collides with our @@ -821,16 +927,61 @@ namespace OpenMetaverse /// Victim ID, should be our own AgentID /// Velocity or total force of the collision /// Time the collision occurred - public delegate void MeanCollisionCallback(MeanCollisionType type, UUID perp, UUID victim, - float magnitude, DateTime time); + //public delegate void MeanCollisionCallback(MeanCollisionType type, UUID perp, UUID victim, + // float magnitude, DateTime time); + + /// The event subscribers. null if no subcribers + private EventHandler m_MeanCollision; + + /// Raises the MeanCollision event + /// A MeanCollisionEventArgs object containing the + /// data returned from the data server + protected virtual void OnMeanCollision(MeanCollisionEventArgs e) + { + EventHandler handler = m_MeanCollision; + if (handler != null) + handler(this, e); + } + + /// Thread sync lock object + private readonly object m_MeanCollisionLock = new object(); + + /// Raised when an object or avatar forcefully collides with our agent + public event EventHandler MeanCollision + { + add { lock (m_MeanCollisionLock) { m_MeanCollision += value; } } + remove { lock (m_MeanCollisionLock) { m_MeanCollision -= value; } } + } /// /// Triggered when the agent physically moves in to a neighboring region /// /// Simulator agent was previously occupying /// Simulator agent is now currently occupying - public delegate void RegionCrossedCallback(Simulator oldSim, Simulator newSim); + //public delegate void RegionCrossedCallback(Simulator oldSim, Simulator newSim); + /// The event subscribers. null if no subcribers + private EventHandler m_RegionCrossed; + + /// Raises the RegionCrossed event + /// A RegionCrossedEventArgs object containing the + /// data returned from the data server + protected virtual void OnRegionCrossed(RegionCrossedEventArgs e) + { + EventHandler handler = m_RegionCrossed; + if (handler != null) + handler(this, e); + } + + /// Thread sync lock object + private readonly object m_RegionCrossedLock = new object(); + + /// Raised when our agent crosses a region border into another region + public event EventHandler RegionCrossed + { + add { lock (m_RegionCrossedLock) { m_RegionCrossed += value; } } + remove { lock (m_RegionCrossedLock) { m_RegionCrossed -= value; } } + } /// /// Fired when group chat session confirmed joined /// Key of Session (groups UUID) @@ -838,17 +989,86 @@ namespace OpenMetaverse /// A string representation of the session name /// if session start successful, /// otherwise - public delegate void GroupChatJoinedCallback(UUID groupChatSessionID, string sessionName, UUID tmpSessionID, bool success); + //public delegate void GroupChatJoinedCallback(UUID groupChatSessionID, string sessionName, UUID tmpSessionID, bool success);GroupChatJoinedEventArgs + /// The event subscribers. null if no subcribers + private EventHandler m_GroupChatJoined; + + /// Raises the GroupChatJoined event + /// A GroupChatJoinedEventArgs object containing the + /// data returned from the data server + protected virtual void OnGroupChatJoined(GroupChatJoinedEventArgs e) + { + EventHandler handler = m_GroupChatJoined; + if (handler != null) + handler(this, e); + } + + /// Thread sync lock object + private readonly object m_GroupChatJoinedLock = new object(); + + /// Raised when our agent succeeds or fails to join a group chat session + public event EventHandler GroupChatJoined + { + add { lock (m_GroupChatJoinedLock) { m_GroupChatJoined += value; } } + remove { lock (m_GroupChatJoinedLock) { m_GroupChatJoined -= value; } } + } /// Fired when agent group chat session terminated /// Key of Session (groups UUID) - public delegate void GroupChatLeftCallback(UUID groupchatSessionID); + //public delegate void GroupChatLeftCallback(UUID groupchatSessionID); + /// The event subscribers. null if no subcribers + private EventHandler m_GroupChatLeft; + + /// Raises the GroupChatLeft event + /// A GroupChatLeftEventArgs object containing the + /// data returned from the data server + protected virtual void OnGroupChatLeft(GroupChatLeftEventArgs e) + { + EventHandler handler = m_GroupChatLeft; + if (handler != null) + handler(this, e); + } + + /// Thread sync lock object + private readonly object m_GroupChatLeftLock = new object(); + + /// Raised when our agent exits a group chat session + public event EventHandler GroupChatLeft + { + add { lock (m_GroupChatLeftLock) { m_GroupChatLeft += value; } } + remove { lock (m_GroupChatLeftLock) { m_GroupChatLeft -= value; } } + } /// /// Fired when alert message received from simulator /// /// the message sent from the grid to our avatar. - public delegate void AlertMessageCallback(string message); + //public delegate void AlertMessageCallback(string message); + + /// The event subscribers. null if no subcribers + private EventHandler m_AlertMessage; + + /// Raises the AlertMessage event + /// A AlertMessageEventArgs object containing the + /// data returned from the data server + protected virtual void OnAlertMessage(AlertMessageEventArgs e) + { + EventHandler handler = m_AlertMessage; + if (handler != null) + handler(this, e); + } + + /// Thread sync lock object + private readonly object m_AlertMessageLock = new object(); + + /// 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 + public event EventHandler AlertMessage + { + add { lock (m_AlertMessageLock) { m_AlertMessage += value; } } + remove { lock (m_AlertMessageLock) { m_AlertMessage -= value; } } + } + /// /// Fired when a script wants to give or release controls. @@ -856,14 +1076,60 @@ namespace OpenMetaverse /// Control to give or take /// true of passing control to agent /// true of taking control from agent - public delegate void ScriptControlCallback(ScriptControlChange controls, bool pass, bool take); + //public delegate void ScriptControlCallback(ScriptControlChange controls, bool pass, bool take); ScriptControlEventArgs + + /// The event subscribers. null if no subcribers + private EventHandler m_ScriptControl; + + /// Raises the ScriptControlChange event + /// A ScriptControlEventArgs object containing the + /// data returned from the data server + protected virtual void OnScriptControlChange(ScriptControlEventArgs e) + { + EventHandler handler = m_ScriptControl; + if (handler != null) + handler(this, e); + } + + /// Thread sync lock object + private readonly object m_ScriptControlLock = new object(); + + /// Raised when a script attempts to take or release specified controls for our agent + public event EventHandler ScriptControlChange + { + add { lock (m_ScriptControlLock) { m_ScriptControl += value; } } + remove { lock (m_ScriptControlLock) { m_ScriptControl -= value; } } + } /// /// Fired when camera tries to view beyond its view limits /// /// representing plane where constraints were hit - public delegate void CameraConstraintCallback(Vector4 collidePlane); + //public delegate void CameraConstraintCallback(Vector4 collidePlane); + /// The event subscribers. null if no subcribers + private EventHandler m_CameraConstraint; + + /// Raises the CameraConstraint event + /// A CameraConstraintEventArgs object containing the + /// data returned from the data server + protected virtual void OnCameraConstraint(CameraConstraintEventArgs e) + { + EventHandler handler = m_CameraConstraint; + if (handler != null) + handler(this, e); + } + + /// Thread sync lock object + private readonly object m_CameraConstraintLock = new object(); + + /// Raised when the simulator detects our agent is trying to view something + /// beyond its limits + public event EventHandler CameraConstraint + { + add { lock (m_CameraConstraintLock) { m_CameraConstraint += value; } } + remove { lock (m_CameraConstraintLock) { m_CameraConstraint -= value; } } + } /// /// Fired when script sensor reply is received /// @@ -878,108 +1144,133 @@ namespace OpenMetaverse /// Objects Type /// representing the velocity of object /// TODO: this should probably be a struct, and there should be an enum added for type - public delegate void ScriptSensorReplyCallback(UUID requestorID, UUID groupID, string name, - UUID objectID, UUID ownerID, Vector3 position, float range, Quaternion rotation, - ScriptSensorTypeFlags type, Vector3 velocity); + //public delegate void ScriptSensorReplyCallback(UUID requestorID, UUID groupID, string name, + // UUID objectID, UUID ownerID, Vector3 position, float range, Quaternion rotation, + // ScriptSensorTypeFlags type, Vector3 velocity); - /// - /// Fired in response to a RequestSit() - /// - /// ID of primitive avatar will be sitting on - /// true of avatar autopiloted there - /// Camera offset when avatar is seated - /// Camera eye offset when avatar is seated - /// true of sitting on this object will force mouselook - /// position avatar will be in when seated - /// rotation avatar will be in when seated - public delegate void AvatarSitResponseCallback(UUID objectID, bool autoPilot, Vector3 cameraAtOffset, - Vector3 cameraEyeOffset, bool forceMouselook, Vector3 sitPosition, Quaternion sitRotation); + /// The event subscribers. null if no subcribers + public EventHandler m_ScriptSensorReply; + /// Raises the ScriptSensorReply event + /// A ScriptSensorReplyEventArgs object containing the + /// data returned from the data server + protected virtual void OnScriptSensorReply(ScriptSensorReplyEventArgs e) + { + EventHandler handler = m_ScriptSensorReply; + if (handler != null) + handler(this, e); + } + + /// Thread sync lock object + private readonly object m_ScriptSensorReplyLock = new object(); + + /// Raised when a script sensor reply is received from a simulator + public event EventHandler ScriptSensorReply + { + add { lock (m_ScriptSensorReplyLock) { m_ScriptSensorReply += value; } } + remove { lock (m_ScriptSensorReplyLock) { m_ScriptSensorReply -= value; } } + } + + /// The event subscribers. null if no subcribers + private EventHandler m_AvatarSitResponse; + + /// Raises the AvatarSitResponse event + /// A AvatarSitResponseEventArgs object containing the + /// data returned from the data server + protected virtual void OnAvatarSitResponse(AvatarSitResponseEventArgs e) + { + EventHandler handler = m_AvatarSitResponse; + if (handler != null) + handler(this, e); + } + + /// Thread sync lock object + private readonly object m_AvatarSitResponseLock = new object(); + + /// Raised in response to a request + public event EventHandler AvatarSitResponse + { + add { lock (m_AvatarSitResponseLock) { m_AvatarSitResponse += value; } } + remove { lock (m_AvatarSitResponseLock) { m_AvatarSitResponse -= value; } } + } /// /// Fired when a new member joins a Group chat session /// /// the ID of the session /// the ID of the avatar that joined - public delegate void ChatSessionMemberAddedCallback(UUID sessionID, UUID agent_key); + //public delegate void ChatSessionMemberAddedCallback(UUID sessionID, UUID agent_key); + + /// The event subscribers. null if no subcribers + private EventHandler m_ChatSessionMemberAdded; + + /// Raises the ChatSessionMemberAdded event + /// A ChatSessionMemberAddedEventArgs object containing the + /// data returned from the data server + protected virtual void OnChatSessionMemberAdded(ChatSessionMemberAddedEventArgs e) + { + EventHandler handler = m_ChatSessionMemberAdded; + if (handler != null) + handler(this, e); + } + + /// Thread sync lock object + private readonly object m_ChatSessionMemberAddedLock = new object(); + + /// Raised when an avatar enters a group chat session we are participating in + public event EventHandler ChatSessionMemberAdded + { + add { lock (m_ChatSessionMemberAddedLock) { m_ChatSessionMemberAdded += value; } } + remove { lock (m_ChatSessionMemberAddedLock) { m_ChatSessionMemberAdded -= value; } } + } /// /// Fired when a member of a Group chat leaves the session /// /// the ID of the session /// the ID of the avatar that joined - public delegate void ChatSessionMemberLeftCallback(UUID sessionID, UUID agent_key); + //public delegate void ChatSessionMemberLeftCallback(UUID sessionID, UUID agent_key); + /// The event subscribers. null if no subcribers + private EventHandler m_ChatSessionMemberLeft; + + /// Raises the ChatSessionMemberLeft event + /// A ChatSessionMemberLeftEventArgs object containing the + /// data returned from the data server + protected virtual void OnChatSessionMemberLeft(ChatSessionMemberLeftEventArgs e) + { + EventHandler handler = m_ChatSessionMemberLeft; + if (handler != null) + handler(this, e); + } + + /// Thread sync lock object + private readonly object m_ChatSessionMemberLeftLock = new object(); + + /// Raised when an agent exits a group chat session we are participating in + public event EventHandler ChatSessionMemberLeft + { + add { lock (m_ChatSessionMemberLeftLock) { m_ChatSessionMemberLeft += value; } } + remove { lock (m_ChatSessionMemberLeftLock) { m_ChatSessionMemberLeft -= value; } } + } #endregion Callbacks #region Events - /// Fired when a is received from the simulator, Contains - /// Any Whisper, Shout, or Say within range of avatar - public event ChatCallback OnChat; - /// Fired when a is received, use - /// to respond to dialog - public event ScriptDialogCallback OnScriptDialog; - /// Fired when a is received in response to a - /// scripted object requesting permissions, Use to reply - public event ScriptQuestionCallback OnScriptQuestion; - /// Fired when a is received, contains a URL pasted in Chat - public event LoadURLCallback OnLoadURL; - /// Fired when a or a ChatterBoxInvitation is received - public event InstantMessageCallback OnInstantMessage; - /// Fired when a is received, occurs when a - /// or is called - public event TeleportCallback OnTeleport; - /// Fired when a indicating the agents - /// balance has changed by spending, sending, or receiving L$, Contains the Avatars new balance - public event BalanceCallback OnBalanceUpdated; - /// Fired when a is received, contains L$ balance and additional - /// details of the transaction - public event MoneyBalanceReplyCallback OnMoneyBalanceReplyReceived; - /// Fired when a is received, caused by changing the - /// Agents active group with - public event AgentDataCallback OnAgentDataUpdated; - /// Fired when a is received, will contain a Dictionary - /// of animations currently being played - public event AnimationsChangedCallback OnAnimationsChanged; - /// Callback for an object or avatar forcefully colliding - /// with the agent - public event MeanCollisionCallback OnMeanCollision; - /// Callback for the agent moving in to a neighboring sim - public event RegionCrossedCallback OnRegionCrossed; - /// Callback for when agent is confirmed joined group chat session. - public event GroupChatJoinedCallback OnGroupChatJoin; - /// Callback for when agent is confirmed to have left group chat session. - public event GroupChatLeftCallback OnGroupChatLeft; - /// Alert messages sent to client from simulator - public event AlertMessageCallback OnAlertMessage; - /// Fired when a script wants to take or release control of your avatar. - public event ScriptControlCallback OnScriptControlChange; - /// Fired when our avatar camera reaches the maximum possible point - public event CameraConstraintCallback OnCameraConstraint; - /// Fired when a script sensor reply is received - public event ScriptSensorReplyCallback OnScriptSensorReply; - /// Fired in response to a sit request - public event AvatarSitResponseCallback OnAvatarSitResponse; - /// Fired when a new member joins an active ChatterBoxSession session - public event ChatSessionMemberAddedCallback OnChatSessionMemberAdded; - /// Fired when a member of an active ChatterBoxSession leaves the session - public event ChatSessionMemberLeftCallback OnChatSessionMemberLeft; - #endregion Events /// Reference to the GridClient instance - public readonly GridClient Client; + private readonly GridClient Client; /// Used for movement and camera tracking public readonly AgentMovement Movement; /// Currently playing animations for the agent. Can be used to /// check the current movement status such as walking, hovering, aiming, - /// etc. by checking for system animations in the Animations class + /// etc. by checking against system animations found in the Animations class public InternalDictionary SignaledAnimations = new InternalDictionary(); /// Dictionary containing current Group Chat sessions and members public InternalDictionary> GroupChatSessions = new InternalDictionary>(); #region Properties - /// Your (client) avatars + /// Your (client) avatars /// "client", "agent", and "avatar" all represent the same thing public UUID AgentID { get { return id; } } /// Temporary assigned to this session, used for @@ -1157,18 +1448,18 @@ namespace OpenMetaverse public AgentManager(GridClient client) { Client = client; + Movement = new AgentMovement(Client); - NetworkManager.PacketCallback callback; + Client.Network.OnDisconnected += new NetworkManager.DisconnectedCallback(Network_OnDisconnected); - // Teleport callbacks - callback = new NetworkManager.PacketCallback(TeleportHandler); - Client.Network.RegisterCallback(PacketType.TeleportStart, callback); - Client.Network.RegisterCallback(PacketType.TeleportProgress, callback); - Client.Network.RegisterCallback(PacketType.TeleportFailed, callback); - Client.Network.RegisterCallback(PacketType.TeleportCancel, callback); - Client.Network.RegisterCallback(PacketType.TeleportLocal, callback); + // 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); // these come in via the EventQueue Client.Network.RegisterEventCallback("TeleportFailed", new Caps.EventQueueCallback(TeleportFailedEventHandler)); Client.Network.RegisterEventCallback("TeleportFinish", new Caps.EventQueueCallback(TeleportFinishEventHandler)); @@ -1500,17 +1791,17 @@ namespace OpenMetaverse throw new Exception("ChatSessionRequest capability is not currently available"); } - } + } - /// - /// Start a friends conference - /// - /// List of UUIDs to start a conference with - /// the temportary session ID returned in the callback> - public void StartIMConference(List participants,UUID tmp_session_id) - { - if (Client.Network.CurrentSim == null || Client.Network.CurrentSim.Caps == null) - throw new Exception("ChatSessionRequest capability is not currently available"); + /// + /// Start a friends conference + /// + /// List of UUIDs to start a conference with + /// the temportary session ID returned in the callback> + public void StartIMConference(List participants, UUID tmp_session_id) + { + if (Client.Network.CurrentSim == null || Client.Network.CurrentSim.Caps == null) + throw new Exception("ChatSessionRequest capability is not currently available"); Uri url = Client.Network.CurrentSim.Caps.CapabilityURI("ChatSessionRequest"); @@ -1926,7 +2217,7 @@ namespace OpenMetaverse grab.AgentData.AgentID = Client.Self.AgentID; grab.AgentData.SessionID = Client.Self.SessionID; - + grab.ObjectData.LocalID = objectLocalID; grab.ObjectData.GrabOffset = grabOffset; @@ -2018,7 +2309,7 @@ namespace OpenMetaverse degrab.AgentData.SessionID = Client.Self.SessionID; degrab.ObjectData.LocalID = objectLocalID; - + degrab.SurfaceInfo = new ObjectDeGrabPacket.SurfaceInfoBlock[1]; degrab.SurfaceInfo[0] = new ObjectDeGrabPacket.SurfaceInfoBlock(); degrab.SurfaceInfo[0].UVCoord = uvCoord; @@ -2133,7 +2424,7 @@ namespace OpenMetaverse } /// - /// Give Money to destionation Object or Avatar + /// Give Money to destination Object or Avatar /// /// UUID of the Target Object/Avatar /// Amount in L$ @@ -2852,7 +3143,7 @@ namespace OpenMetaverse /// Name of the classified /// Long description of the classified /// if true, auto renew classified after expiration - public void UpdateClassifiedInfo(UUID classifiedID, DirectoryManager.ClassifiedCategories category, + public void UpdateClassifiedInfo(UUID classifiedID, DirectoryManager.ClassifiedCategories category, UUID snapshotID, int price, Vector3d position, string name, string desc, bool autoRenew) { ClassifiedInfoUpdatePacket classified = new ClassifiedInfoUpdatePacket(); @@ -2917,13 +3208,13 @@ namespace OpenMetaverse /// /// Incoming ImprovedInstantMessagePacket /// Unused - private void InstantMessageHandler(Packet packet, Simulator simulator) + protected void InstantMessageHandler(Packet packet, Simulator simulator) { if (packet.Type == PacketType.ImprovedInstantMessage) { ImprovedInstantMessagePacket im = (ImprovedInstantMessagePacket)packet; - if (OnInstantMessage != null) + if (m_InstantMessage != null) { InstantMessage message; message.FromAgentID = im.AgentData.AgentID; @@ -2940,8 +3231,7 @@ namespace OpenMetaverse message.Offline = (InstantMessageOnline)im.MessageBlock.Offline; message.BinaryBucket = im.MessageBlock.BinaryBucket; - try { OnInstantMessage(message, simulator); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnInstantMessage(new InstantMessageEventArgs(message, simulator)); } } } @@ -2952,21 +3242,20 @@ namespace OpenMetaverse /// /// Incoming ChatFromSimulatorPacket /// Unused - private void ChatHandler(Packet packet, Simulator simulator) + protected void ChatHandler(Packet packet, Simulator simulator) { - if (OnChat != null) + if (m_Chat != null) { ChatFromSimulatorPacket chat = (ChatFromSimulatorPacket)packet; - OnChat(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 - ); + OnChat(new ChatEventArgs(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)); } } @@ -2975,9 +3264,9 @@ namespace OpenMetaverse /// /// Incoming ScriptDialog packet /// Unused - private void ScriptDialogHandler(Packet packet, Simulator simulator) + protected void ScriptDialogHandler(Packet packet, Simulator simulator) { - if (OnScriptDialog != null) + if (m_ScriptDialog != null) { ScriptDialogPacket dialog = (ScriptDialogPacket)packet; List buttons = new List(); @@ -2987,14 +3276,14 @@ namespace OpenMetaverse buttons.Add(Utils.BytesToString(button.ButtonLabel)); } - OnScriptDialog(Utils.BytesToString(dialog.Data.Message), + 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); + buttons)); } } @@ -3003,22 +3292,18 @@ namespace OpenMetaverse /// /// Incoming ScriptDialog packet /// Unused - private void ScriptQuestionHandler(Packet packet, Simulator simulator) + protected void ScriptQuestionHandler(Packet packet, Simulator simulator) { - if (OnScriptQuestion != null) + if (m_ScriptQuestion != null) { ScriptQuestionPacket question = (ScriptQuestionPacket)packet; - try - { - OnScriptQuestion(simulator, + OnScriptQuestion(new ScriptQuestionEventArgs(simulator, question.Data.TaskID, question.Data.ItemID, Utils.BytesToString(question.Data.ObjectName), Utils.BytesToString(question.Data.ObjectOwner), - (ScriptPermission)question.Data.Questions); - } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + (ScriptPermission)question.Data.Questions)); } } @@ -3029,18 +3314,14 @@ namespace OpenMetaverse /// private void ScriptControlChangeHandler(Packet packet, Simulator simulator) { - if (OnScriptControlChange != null) + if (m_ScriptControl != null) { ScriptControlChangePacket change = (ScriptControlChangePacket)packet; for (int i = 0; i < change.Data.Length; i++) { - try - { - OnScriptControlChange((ScriptControlChange)change.Data[i].Controls, + OnScriptControlChange(new ScriptControlEventArgs((ScriptControlChange)change.Data[i].Controls, change.Data[i].PassToAgent, - change.Data[i].TakeControls); - } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + change.Data[i].TakeControls)); } } } @@ -3050,23 +3331,19 @@ namespace OpenMetaverse /// /// /// - private void LoadURLHandler(Packet packet, Simulator simulator) + protected void LoadURLHandler(Packet packet, Simulator simulator) { LoadURLPacket loadURL = (LoadURLPacket)packet; - if (OnLoadURL != null) + if (m_LoadURL != null) { - try - { - OnLoadURL( - Utils.BytesToString(loadURL.Data.ObjectName), - loadURL.Data.ObjectID, - loadURL.Data.OwnerID, - loadURL.Data.OwnerIsGroup, - Utils.BytesToString(loadURL.Data.Message), - Utils.BytesToString(loadURL.Data.URL) - ); - } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + 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) + )); } } @@ -3107,13 +3384,12 @@ namespace OpenMetaverse activeGroup = p.AgentData.ActiveGroupID; activeGroupPowers = (GroupPowers)p.AgentData.GroupPowers; - if (OnAgentDataUpdated != null) + if (m_AgentData != null) { string groupTitle = Utils.BytesToString(p.AgentData.GroupTitle); string groupName = Utils.BytesToString(p.AgentData.GroupName); - try { OnAgentDataUpdated(firstName, lastName, activeGroup, groupTitle, (GroupPowers)p.AgentData.GroupPowers, groupName); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnAgentData(new AgentDataReplyEventArgs(firstName, lastName, activeGroup, groupTitle, activeGroupPowers, groupName)); } } else @@ -3128,30 +3404,27 @@ namespace OpenMetaverse /// /// Incoming MoneyBalanceReplyPacket /// Unused - private void BalanceHandler(Packet packet, Simulator simulator) + protected void BalanceHandler(Packet packet, Simulator simulator) { if (packet.Type == PacketType.MoneyBalanceReply) { - MoneyBalanceReplyPacket mbrp = (MoneyBalanceReplyPacket)packet; - balance = mbrp.MoneyData.MoneyBalance; + MoneyBalanceReplyPacket reply = (MoneyBalanceReplyPacket)packet; + this.balance = reply.MoneyData.MoneyBalance; - if (OnMoneyBalanceReplyReceived != null) + if (m_MoneyBalance != null) { - try - { - OnMoneyBalanceReplyReceived(mbrp.MoneyData.TransactionID, - mbrp.MoneyData.TransactionSuccess, mbrp.MoneyData.MoneyBalance, - mbrp.MoneyData.SquareMetersCredit, mbrp.MoneyData.SquareMetersCommitted, - Utils.BytesToString(mbrp.MoneyData.Description)); - } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnMoneyBalanceReply(new MoneyBalanceReplyEventArgs(reply.MoneyData.TransactionID, + reply.MoneyData.TransactionSuccess, + reply.MoneyData.MoneyBalance, + reply.MoneyData.SquareMetersCredit, + reply.MoneyData.SquareMetersCommitted, + Utils.BytesToString(reply.MoneyData.Description))); } } - if (OnBalanceUpdated != null) + if (m_Balance != null) { - try { OnBalanceUpdated(balance); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnBalance(new BalanceEventArgs(balance)); } } @@ -3161,7 +3434,7 @@ namespace OpenMetaverse if (Client.Settings.MULTIPLE_SIMS) { - + IPEndPoint endPoint = new IPEndPoint(msg.Address, msg.Port); Simulator sim = Client.Network.FindSimulator(endPoint); @@ -3190,12 +3463,12 @@ namespace OpenMetaverse /// The simulator originating the event message public void TeleportFailedEventHandler(string messageKey, IMessage message, Simulator simulator) { - TeleportFailedMessage msg = (TeleportFailedMessage) message; + TeleportFailedMessage msg = (TeleportFailedMessage)message; TeleportFailedPacket failedPacket = new TeleportFailedPacket(); failedPacket.Info.AgentID = msg.AgentID; failedPacket.Info.Reason = Utils.StringToBytes(msg.Reason); - + TeleportHandler(failedPacket, simulator); } @@ -3319,10 +3592,9 @@ namespace OpenMetaverse Logger.DebugLog("TeleportLocal received, Flags: " + flags.ToString(), Client); } - if (OnTeleport != null) + if (m_Teleport != null) { - try { OnTeleport(teleportMessage, teleportStat, flags); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnTeleport(new TeleportEventArgs(teleportMessage, teleportStat, flags)); } if (finished) teleportEvent.Set(); @@ -3333,7 +3605,7 @@ namespace OpenMetaverse /// /// /// - private void AvatarAnimationHandler(Packet packet, Simulator sim) + protected void AvatarAnimationHandler(Packet packet, Simulator sim) { AvatarAnimationPacket animation = (AvatarAnimationPacket)packet; @@ -3380,18 +3652,18 @@ namespace OpenMetaverse } } } - - if (OnAnimationsChanged != null) - { - try { OnAnimationsChanged(SignaledAnimations); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } - } } + + if (m_AnimationsChanged != null) + { + OnAnimationsChanged(new AnimationsChangedEventArgs(this.SignaledAnimations)); + } + } - private void MeanCollisionAlertHandler(Packet packet, Simulator sim) + protected void MeanCollisionAlertHandler(Packet packet, Simulator sim) { - if (OnMeanCollision != null) + if (m_MeanCollision != null) { MeanCollisionAlertPacket collision = (MeanCollisionAlertPacket)packet; @@ -3402,8 +3674,7 @@ namespace OpenMetaverse DateTime time = Utils.UnixTimeToDateTime(block.Time); MeanCollisionType type = (MeanCollisionType)block.Type; - try { OnMeanCollision(type, block.Perp, block.Victim, block.Mag, time); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnMeanCollision(new MeanCollisionEventArgs(type, block.Perp, block.Victim, block.Mag, time)); } } } @@ -3431,8 +3702,6 @@ namespace OpenMetaverse fullName = null; } - - /// /// 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. @@ -3442,7 +3711,7 @@ namespace OpenMetaverse /// The which originated the packet private void CrossedRegionEventHandler(string capsKey, IMessage message, Simulator simulator) { - CrossedRegionMessage crossed = (CrossedRegionMessage) message; + CrossedRegionMessage crossed = (CrossedRegionMessage)message; IPEndPoint endPoint = new IPEndPoint(crossed.IP, crossed.Port); @@ -3455,10 +3724,9 @@ namespace OpenMetaverse { Logger.Log("Finished crossing over in to region " + newSim.ToString(), Helpers.LogLevel.Info, Client); - if (OnRegionCrossed != null) + if (m_RegionCrossed != null) { - try { OnRegionCrossed(oldSim, newSim); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnRegionCrossed(new RegionCrossedEventArgs(oldSim, newSim)); } } else @@ -3475,7 +3743,7 @@ namespace OpenMetaverse /// simulators /// /// This packet is now being sent via the EventQueue - private void CrossedRegionHandler(Packet packet, Simulator sim) + protected void CrossedRegionHandler(Packet packet, Simulator sim) { CrossedRegionPacket crossing = (CrossedRegionPacket)packet; string seedCap = Utils.BytesToString(crossing.RegionData.SeedCapability); @@ -3490,10 +3758,9 @@ namespace OpenMetaverse { Logger.Log("Finished crossing over in to region " + newSim.ToString(), Helpers.LogLevel.Info, Client); - if (OnRegionCrossed != null) + if (m_RegionCrossed != null) { - try { OnRegionCrossed(oldSim, newSim); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnRegionCrossed(new RegionCrossedEventArgs(oldSim, newSim)); } } else @@ -3511,11 +3778,11 @@ namespace OpenMetaverse /// The capability Key /// IMessage object containing decoded data from OSD /// - private void ChatterBoxSessionEventReplyEventHandler(string capsKey, IMessage message, Simulator simulator) + protected void ChatterBoxSessionEventReplyEventHandler(string capsKey, IMessage message, Simulator simulator) { ChatterboxSessionEventReplyMessage msg = (ChatterboxSessionEventReplyMessage)message; - - if(!msg.Success) + + if (!msg.Success) { Logger.Log("Attempt to send group chat to non-existant session for group " + msg.SessionID, Helpers.LogLevel.Info, Client); @@ -3528,14 +3795,13 @@ namespace OpenMetaverse /// /// IMessage object containing decoded data from OSD /// - private void ChatterBoxSessionStartReplyEventHandler(string capsKey, IMessage message, Simulator simulator) + protected void ChatterBoxSessionStartReplyEventHandler(string capsKey, IMessage message, Simulator simulator) { - if (OnGroupChatJoin != null) + if (m_GroupChatJoined != null) { ChatterBoxSessionStartReplyMessage msg = (ChatterBoxSessionStartReplyMessage)message; - try { OnGroupChatJoin(msg.SessionID, msg.SessionName, msg.TempSessionID, msg.Success); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnGroupChatJoined(new GroupChatJoinedEventArgs(msg.SessionID, msg.SessionName, msg.TempSessionID, msg.Success)); } } @@ -3576,10 +3842,9 @@ namespace OpenMetaverse lock (GroupChatSessions.Dictionary) GroupChatSessions[msg.SessionID].Add(fndMbr); - if (OnChatSessionMemberAdded != null) + if (m_ChatSessionMemberAdded != null) { - try { OnChatSessionMemberAdded(msg.SessionID, fndMbr.AvatarKey); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnChatSessionMemberAdded(new ChatSessionMemberAddedEventArgs(msg.SessionID, fndMbr.AvatarKey)); } } } @@ -3589,16 +3854,14 @@ namespace OpenMetaverse lock (GroupChatSessions.Dictionary) GroupChatSessions[msg.SessionID].Remove(fndMbr); - if (OnChatSessionMemberLeft != null) + if (m_ChatSessionMemberLeft != null) { - try { OnChatSessionMemberLeft(msg.SessionID, msg.Updates[i].AgentID); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnChatSessionMemberLeft(new ChatSessionMemberLeftEventArgs(msg.SessionID, msg.Updates[i].AgentID)); } if (msg.Updates[i].AgentID == Client.Self.AgentID) { - try { OnGroupChatLeft(msg.SessionID); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnGroupChatLeft(new GroupChatLeftEventArgs(msg.SessionID)); } } } @@ -3609,7 +3872,7 @@ namespace OpenMetaverse return m.AvatarKey == msg.Updates[i].AgentID; }); - + update_member.MuteText = msg.Updates[i].MuteText; update_member.MuteVoice = msg.Updates[i].MuteVoice; @@ -3638,7 +3901,7 @@ namespace OpenMetaverse /// Originating Simulator private void ChatterBoxInvitationEventHandler(string capsKey, IMessage message, Simulator simulator) { - if (OnInstantMessage != null) + if (m_InstantMessage != null) { ChatterBoxInvitationMessage msg = (ChatterBoxInvitationMessage)message; @@ -3658,8 +3921,7 @@ namespace OpenMetaverse im.Offline = msg.Offline; im.BinaryBucket = msg.BinaryBucket; - try { OnInstantMessage(im, simulator); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnInstantMessage(new InstantMessageEventArgs(im, simulator)); } } @@ -3703,13 +3965,11 @@ namespace OpenMetaverse /// not used private void AlertMessageHandler(Packet packet, Simulator simulator) { - AlertMessagePacket alert = (AlertMessagePacket)packet; - string message = Utils.BytesToString(alert.AlertData.Message); - - if (OnAlertMessage != null) + if (m_AlertMessage != null) { - try { OnAlertMessage(message); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + AlertMessagePacket alert = (AlertMessagePacket)packet; + + OnAlertMessage(new AlertMessageEventArgs(Utils.BytesToString(alert.AlertData.Message))); } } @@ -3720,12 +3980,10 @@ namespace OpenMetaverse /// private void CameraConstraintHandler(Packet packet, Simulator simulator) { - if (OnCameraConstraint != null) + if (m_CameraConstraint != null) { CameraConstraintPacket camera = (CameraConstraintPacket)packet; - - try { OnCameraConstraint(camera.CameraCollidePlane.Plane); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnCameraConstraint(new CameraConstraintEventArgs(camera.CameraCollidePlane.Plane)); } } @@ -3734,9 +3992,9 @@ namespace OpenMetaverse /// /// /// - private void ScriptSensorReplyHandler(Packet packet, Simulator simulator) + protected void ScriptSensorReplyHandler(Packet packet, Simulator simulator) { - if (OnScriptSensorReply != null) + if (m_ScriptSensorReply != null) { ScriptSensorReplyPacket reply = (ScriptSensorReplyPacket)packet; @@ -3745,12 +4003,8 @@ namespace OpenMetaverse ScriptSensorReplyPacket.SensedDataBlock block = reply.SensedData[i]; ScriptSensorReplyPacket.RequesterBlock requestor = reply.Requester; - try - { - OnScriptSensorReply(requestor.SourceID, block.GroupID, Utils.BytesToString(block.Name), - block.ObjectID, block.OwnerID, block.Position, block.Range, block.Rotation, (ScriptSensorTypeFlags)block.Type, block.Velocity); - } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + 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)); } } @@ -3763,20 +4017,724 @@ namespace OpenMetaverse /// private void AvatarSitResponseHandler(Packet packet, Simulator simulator) { - if (OnAvatarSitResponse != null) + if (m_AvatarSitResponse != null) { AvatarSitResponsePacket sit = (AvatarSitResponsePacket)packet; - try - { - OnAvatarSitResponse(sit.SitObject.ID, sit.SitTransform.AutoPilot, sit.SitTransform.CameraAtOffset, + OnAvatarSitResponse(new AvatarSitResponseEventArgs(sit.SitObject.ID, sit.SitTransform.AutoPilot, sit.SitTransform.CameraAtOffset, sit.SitTransform.CameraEyeOffset, sit.SitTransform.ForceMouselook, sit.SitTransform.SitPosition, - sit.SitTransform.SitRotation); - } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + sit.SitTransform.SitRotation)); } } #endregion Packet Handlers } + + #region Event Argument Classes + + /// + /// + /// + public class ChatEventArgs : EventArgs + { + private readonly string m_Message; + private readonly ChatAudibleLevel m_AudibleLevel; + private readonly ChatType m_Type; + private readonly ChatSourceType m_SourceType; + private readonly string m_FromName; + private readonly UUID m_SourceID; + private readonly UUID m_OwnerID; + private readonly Vector3 m_Position; + + /// Get the message sent + public string Message { get { return m_Message; } } + /// Get the audible level of the message + public ChatAudibleLevel AudibleLevel { get { return m_AudibleLevel; } } + /// Get the type of message sent: whisper, shout, etc + public ChatType Type { get { return m_Type; } } + /// Get the source type of the message sender + public ChatSourceType SourceType { get { return m_SourceType; } } + /// Get the name of the agent or object sending the message + public string FromName { get { return m_FromName; } } + /// Get the ID of the agent or object sending the message + public UUID SourceID { get { return m_SourceID; } } + /// Get the ID of the object owner, or the agent ID sending the message + public UUID OwnerID { get { return m_OwnerID; } } + /// Get the position of the agent or object sending the message + public Vector3 Position { get { return m_Position; } } + + /// + /// Construct a new instance of the ChatEventArgs object + /// + /// The message sent + /// The audible level of the message + /// The type of message sent: whisper, shout, etc + /// The source type of the message sender + /// The name of the agent or object sending the message + /// The ID of the agent or object sending the message + /// The ID of the object owner, or the agent ID sending the message + /// The position of the agent or object sending the message + public ChatEventArgs(string message, ChatAudibleLevel audible, ChatType type, + ChatSourceType sourceType, string fromName, UUID sourceId, UUID ownerid, Vector3 position) + { + this.m_Message = message; + this.m_AudibleLevel = audible; + this.m_Type = type; + this.m_SourceType = sourceType; + this.m_FromName = fromName; + this.m_SourceID = sourceId; + this.m_Position = position; + this.m_OwnerID = ownerid; + } + } + + /// Contains the data sent when a primitive opens a dialog with this agent + public class ScriptDialogEventArgs : EventArgs + { + private readonly string m_Message; + private readonly string m_ObjectName; + private readonly UUID m_ImageID; + private readonly UUID m_ObjectID; + private readonly string m_FirstName; + private readonly string m_LastName; + private readonly int m_Channel; + private readonly List m_ButtonLabels; + + /// Get the dialog message + public string Message { get { return m_Message; } } + /// Get the name of the object that sent the dialog request + public string ObjectName { get { return m_ObjectName; } } + /// Get the ID of the image to be displayed + public UUID ImageID { get { return m_ImageID; } } + /// Get the ID of the primitive sending the dialog + public UUID ObjectID { get { return m_ObjectID; } } + /// Get the first name of the senders owner + public string FirstName { get { return m_FirstName; } } + /// Get the last name of the senders owner + public string LastName { get { return m_LastName; } } + /// Get the communication channel the dialog was sent on, responses + /// should also send responses on this same channel + public int Channel { get { return m_Channel; } } + /// Get the string labels containing the options presented in this dialog + public List ButtonLabels { get { return m_ButtonLabels; } } + + /// + /// Construct a new instance of the ScriptDialogEventArgs + /// + /// The dialog message + /// The name of the object that sent the dialog request + /// The ID of the image to be displayed + /// The ID of the primitive sending the dialog + /// The first name of the senders owner + /// The last name of the senders owner + /// The communication channel the dialog was sent on + /// The string labels containing the options presented in this dialog + public ScriptDialogEventArgs(string message, string objectName, UUID imageID, + UUID objectID, string firstName, string lastName, int chatChannel, List buttons) + { + this.m_Message = message; + this.m_ObjectName = objectName; + this.m_ImageID = imageID; + this.m_ObjectID = objectID; + this.m_FirstName = firstName; + this.m_LastName = lastName; + this.m_Channel = chatChannel; + this.m_ButtonLabels = buttons; + } + } + + /// Contains the data sent when a primitive requests debit or other permissions + /// requesting a YES or NO answer + public class ScriptQuestionEventArgs : EventArgs + { + private readonly Simulator m_Simulator; + private readonly UUID m_TaskID; + private readonly UUID m_ItemID; + private readonly string m_ObjectName; + private readonly string m_ObjectOwnerName; + private readonly ScriptPermission m_Questions; + + /// Get the simulator containing the object sending the request + public Simulator Simulator { get { return m_Simulator; } } + /// Get the ID of the script making the request + public UUID TaskID { get { return m_TaskID; } } + /// Get the ID of the primitive containing the script making the request + public UUID ItemID { get { return m_ItemID; } } + /// Get the name of the primitive making the request + public string ObjectName { get { return m_ObjectName; } } + /// Get the name of the owner of the object making the request + public string ObjectOwnerName { get { return m_ObjectOwnerName; } } + /// Get the permissions being requested + public ScriptPermission Questions { get { return m_Questions; } } + + /// + /// Construct a new instance of the ScriptQuestionEventArgs + /// + /// The simulator containing the object sending the request + /// The ID of the script making the request + /// The ID of the primitive containing the script making the request + /// The name of the primitive making the request + /// The name of the owner of the object making the request + /// The permissions being requested + public ScriptQuestionEventArgs(Simulator simulator, UUID taskID, UUID itemID, string objectName, string objectOwner, ScriptPermission questions) + { + this.m_Simulator = simulator; + this.m_TaskID = taskID; + this.m_ItemID = itemID; + this.m_ObjectName = objectName; + this.m_ObjectOwnerName = objectOwner; + this.m_Questions = questions; + } + + } + + /// Contains the data sent when a primitive sends a request + /// to an agent to open the specified URL + public class LoadUrlEventArgs : EventArgs + { + private readonly string m_ObjectName; + private readonly UUID m_ObjectID; + private readonly UUID m_OwnerID; + private readonly bool m_OwnerIsGroup; + private readonly string m_Message; + private readonly string m_URL; + + /// Get the name of the object sending the request + public string ObjectName { get { return m_ObjectName; } } + /// Get the ID of the object sending the request + public UUID ObjectID { get { return m_ObjectID; } } + /// Get the ID of the owner of the object sending the request + public UUID OwnerID { get { return m_OwnerID; } } + /// True if the object is owned by a group + public bool OwnerIsGroup { get { return m_OwnerIsGroup; } } + /// Get the message sent with the request + public string Message { get { return m_Message; } } + /// Get the URL the object sent + public string URL { get { return m_URL; } } + + /// + /// Construct a new instance of the LoadUrlEventArgs + /// + /// The name of the object sending the request + /// The ID of the object sending the request + /// The ID of the owner of the object sending the request + /// True if the object is owned by a group + /// The message sent with the request + /// The URL the object sent + public LoadUrlEventArgs(string objectName, UUID objectID, UUID ownerID, bool ownerIsGroup, string message, string URL) + { + this.m_ObjectName = objectName; + this.m_ObjectID = objectID; + this.m_OwnerID = ownerID; + this.m_OwnerIsGroup = ownerIsGroup; + this.m_Message = message; + this.m_URL = URL; + } + } + + /// The date received from an ImprovedInstantMessage + public class InstantMessageEventArgs : EventArgs + { + private readonly InstantMessage m_IM; + private readonly Simulator m_Simulator; + + /// Get the InstantMessage object + public InstantMessage IM { get { return m_IM; } } + /// Get the simulator where the InstantMessage origniated + public Simulator Simulator { get { return m_Simulator; } } + + /// + /// Construct a new instance of the InstantMessageEventArgs object + /// + /// the InstantMessage object + /// the simulator where the InstantMessage origniated + public InstantMessageEventArgs(InstantMessage im, Simulator simulator) + { + this.m_IM = im; + this.m_Simulator = simulator; + } + } + + /// Contains the currency balance + public class BalanceEventArgs : EventArgs + { + private readonly int m_Balance; + + /// + /// Get the currenct balance + /// + public int Balance { get { return m_Balance; } } + + /// + /// Construct a new BalanceEventArgs object + /// + /// The currenct balance + public BalanceEventArgs(int balance) + { + this.m_Balance = balance; + } + } + + /// Contains the transaction summary when an item is purchased, + /// money is given, or land is purchased + public class MoneyBalanceReplyEventArgs : EventArgs + { + private readonly UUID m_TransactionID; + private readonly bool m_Success; + private readonly int m_Balance; + private readonly int m_MetersCredit; + private readonly int m_MetersCommitted; + private readonly string m_Description; + + /// Get the ID of the transaction + public UUID TransactionID { get { return m_TransactionID; } } + /// True of the transaction was successful + public bool Success { get { return m_Success; } } + /// Get the remaining currency balance + public int Balance { get { return m_Balance; } } + /// Get the meters credited + public int MetersCredit { get { return m_MetersCredit; } } + /// Get the meters comitted + public int MetersCommitted { get { return m_MetersCommitted; } } + /// Get the description of the transaction + public string Description { get { return m_Description; } } + + /// + /// Construct a new instance of the MoneyBalanceReplyEventArgs object + /// + /// The ID of the transaction + /// True of the transaction was successful + /// The current currency balance + /// The meters credited + /// The meters comitted + /// A brief description of the transaction + public MoneyBalanceReplyEventArgs(UUID transactionID, bool transactionSuccess, int balance, int metersCredit, int metersCommitted, string description) + { + this.m_TransactionID = transactionID; + this.m_Success = transactionSuccess; + this.m_Balance = balance; + this.m_MetersCredit = metersCredit; + this.m_MetersCommitted = metersCommitted; + this.m_Description = description; + } + } + + // string message, TeleportStatus status, TeleportFlags flags + public class TeleportEventArgs : EventArgs + { + private readonly string m_Message; + private readonly TeleportStatus m_Status; + private readonly TeleportFlags m_Flags; + + public string Message { get { return m_Message; } } + public TeleportStatus Status { get { return m_Status; } } + public TeleportFlags Flags { get { return m_Flags; } } + + public TeleportEventArgs(string message, TeleportStatus status, TeleportFlags flags) + { + this.m_Message = message; + this.m_Status = status; + this.m_Flags = flags; + } + } + + /// Data sent from the simulator containing information about your agent and active group information + public class AgentDataReplyEventArgs : EventArgs + { + private readonly string m_FirstName; + private readonly string m_LastName; + private readonly UUID m_ActiveGroupID; + private readonly string m_GroupTitle; + private readonly GroupPowers m_GroupPowers; + private readonly string m_GroupName; + + /// Get the agents first name + public string FirstName { get { return m_FirstName; } } + /// Get the agents last name + public string LastName { get { return m_LastName; } } + /// Get the active group ID of your agent + public UUID ActiveGroupID { get { return m_ActiveGroupID; } } + /// Get the active groups title of your agent + public string GroupTitle { get { return m_GroupTitle; } } + /// Get the combined group powers of your agent + public GroupPowers GroupPowers { get { return m_GroupPowers; } } + /// Get the active group name of your agent + public string GroupName { get { return m_GroupName; } } + + /// + /// Construct a new instance of the AgentDataReplyEventArgs object + /// + /// The agents first name + /// The agents last name + /// The agents active group ID + /// The group title of the agents active group + /// The combined group powers the agent has in the active group + /// The name of the group the agent has currently active + public AgentDataReplyEventArgs(string firstName, string lastName, UUID activeGroupID, + string groupTitle, GroupPowers groupPowers, string groupName) + { + this.m_FirstName = firstName; + this.m_LastName = lastName; + this.m_ActiveGroupID = activeGroupID; + this.m_GroupTitle = groupTitle; + this.m_GroupPowers = groupPowers; + this.m_GroupName = groupName; + } + } + + /// Data sent by the simulator to indicate the active/changed animations + /// applied to your agent + public class AnimationsChangedEventArgs : EventArgs + { + private readonly InternalDictionary m_Animations; + + /// Get the dictionary that contains the changed animations + public InternalDictionary Animations { get { return m_Animations; } } + + /// + /// Construct a new instance of the AnimationsChangedEventArgs class + /// + /// The dictionary that contains the changed animations + public AnimationsChangedEventArgs(InternalDictionary agentAnimations) + { + this.m_Animations = agentAnimations; + } + + } + + /// + /// Data sent from a simulator indicating a collision with your agent + /// + public class MeanCollisionEventArgs : EventArgs + { + private readonly MeanCollisionType m_Type; + private readonly UUID m_Aggressor; + private readonly UUID m_Victim; + private readonly float m_Magnitude; + private readonly DateTime m_Time; + + /// Get the Type of collision + public MeanCollisionType Type { get { return m_Type; } } + /// Get the ID of the agent or object that collided with your agent + public UUID Aggressor { get { return m_Aggressor; } } + /// Get the ID of the agent that was attacked + public UUID Victim { get { return m_Victim; } } + /// A value indicating the strength of the collision + public float Magnitude { get { return m_Magnitude; } } + /// Get the time the collision occurred + public DateTime Time { get { return m_Time; } } + + /// + /// Construct a new instance of the MeanCollisionEventArgs class + /// + /// The type of collision that occurred + /// The ID of the agent or object that perpetrated the agression + /// The ID of the Victim + /// The strength of the collision + /// The Time the collision occurred + public MeanCollisionEventArgs(MeanCollisionType type, UUID perp, UUID victim, + float magnitude, DateTime time) + { + this.m_Type = type; + this.m_Aggressor = perp; + this.m_Victim = victim; + this.m_Magnitude = magnitude; + this.m_Time = time; + } + } + + /// Data sent to your agent when it crosses region boundaries + public class RegionCrossedEventArgs : EventArgs + { + private readonly Simulator m_OldSimulator; + private readonly Simulator m_NewSimulator; + + /// Get the simulator your agent just left + public Simulator OldSimulator { get { return m_OldSimulator; } } + /// Get the simulator your agent is now in + public Simulator NewSimulator { get { return m_NewSimulator; } } + + /// + /// Construct a new instance of the RegionCrossedEventArgs class + /// + /// The simulator your agent just left + /// The simulator your agent is now in + public RegionCrossedEventArgs(Simulator oldSim, Simulator newSim) + { + this.m_OldSimulator = oldSim; + this.m_NewSimulator = newSim; + } + } + + /// Data sent from the simulator when your agent joins a group chat session + public class GroupChatJoinedEventArgs : EventArgs + { + private readonly UUID m_SessionID; + private readonly string m_SessionName; + private readonly UUID m_TmpSessionID; + private readonly bool m_Success; + + /// Get the ID of the group chat session + public UUID SessionID { get { return m_SessionID; } } + /// Get the name of the session + public string SessionName { get { return m_SessionName; } } + /// Get the temporary session ID used for establishing new sessions + public UUID TmpSessionID { get { return m_TmpSessionID; } } + /// True if your agent successfully joined the session + public bool Success { get { return m_Success; } } + + /// + /// Construct a new instance of the GroupChatJoinedEventArgs class + /// + /// The ID of the session + /// The name of the session + /// A temporary session id used for establishing new sessions + /// True of your agent successfully joined the session + public GroupChatJoinedEventArgs(UUID groupChatSessionID, string sessionName, UUID tmpSessionID, bool success) + { + this.m_SessionID = groupChatSessionID; + this.m_SessionName = sessionName; + this.m_TmpSessionID = tmpSessionID; + this.m_Success = success; + } + } + + /// The session information when your agent exits a group chat session + public class GroupChatLeftEventArgs : EventArgs + { + private readonly UUID m_SessionID; + + /// Get the ID of the session your agent left + public UUID SessionID { get { return m_SessionID; } } + + /// + /// Construct a new instance of the GroupChatLeftEventArgs class + /// + /// The ID of the session your agent left + public GroupChatLeftEventArgs(UUID chatSessionID) + { + this.m_SessionID = chatSessionID; + } + } + + /// Data sent by the simulator containing urgent messages + public class AlertMessageEventArgs : EventArgs + { + private readonly string m_Message; + + /// Get the alert message + public string Message { get { return m_Message; } } + + /// + /// Construct a new instance of the AlertMessageEventArgs class + /// + /// The alert message + public AlertMessageEventArgs(string message) + { + this.m_Message = message; + } + } + + /// Data sent by a script requesting to take or release specified controls to your agent + public class ScriptControlEventArgs : EventArgs + { + private readonly ScriptControlChange m_Controls; + private readonly bool m_Pass; + private readonly bool m_Take; + + /// Get the controls the script is attempting to take or release to the agent + public ScriptControlChange Controls { get { return m_Controls; } } + /// True if the script is passing controls back to the agent + public bool Pass { get { return m_Pass; } } + /// True if the script is requesting controls be released to the script + public bool Take { get { return m_Take; } } + + /// + /// Construct a new instance of the ScriptControlEventArgs class + /// + /// The controls the script is attempting to take or release to the agent + /// True if the script is passing controls back to the agent + /// True if the script is requesting controls be released to the script + public ScriptControlEventArgs(ScriptControlChange controls, bool pass, bool take) + { + m_Controls = controls; + m_Pass = pass; + m_Take = take; + } + } + + /// + /// Data sent from the simulator to an agent to indicate its view limits + /// + public class CameraConstraintEventArgs : EventArgs + { + private readonly Vector4 m_CollidePlane; + + /// Get the collision plane + public Vector4 CollidePlane { get { return m_CollidePlane; } } + + /// + /// Construct a new instance of the CameraConstraintEventArgs class + /// + /// The collision plane + public CameraConstraintEventArgs(Vector4 collidePlane) + { + m_CollidePlane = collidePlane; + } + } + + /// + /// Data containing script sensor requests which allow an agent to know the specific details + /// of a primitive sending script sensor requests + /// + public class ScriptSensorReplyEventArgs : EventArgs + { + private readonly UUID m_RequestorID; + private readonly UUID m_GroupID; + private readonly string m_Name; + private readonly UUID m_ObjectID; + private readonly UUID m_OwnerID; + private readonly Vector3 m_Position; + private readonly float m_Range; + private readonly Quaternion m_Rotation; + private readonly ScriptSensorTypeFlags m_Type; + private readonly Vector3 m_Velocity; + + /// Get the ID of the primitive sending the sensor + public UUID RequestorID { get { return m_RequestorID; } } + /// Get the ID of the group associated with the primitive + public UUID GroupID { get { return m_GroupID; } } + /// Get the name of the primitive sending the sensor + public string Name { get { return m_Name; } } + /// Get the ID of the primitive sending the sensor + public UUID ObjectID { get { return m_ObjectID; } } + /// Get the ID of the owner of the primitive sending the sensor + public UUID OwnerID { get { return m_OwnerID; } } + /// Get the position of the primitive sending the sensor + public Vector3 Position { get { return m_Position; } } + /// Get the range the primitive specified to scan + public float Range { get { return m_Range; } } + /// Get the rotation of the primitive sending the sensor + public Quaternion Rotation { get { return m_Rotation; } } + /// Get the type of sensor the primitive sent + public ScriptSensorTypeFlags Type { get { return m_Type; } } + /// Get the velocity of the primitive sending the sensor + public Vector3 Velocity { get { return m_Velocity; } } + + /// + /// Construct a new instance of the ScriptSensorReplyEventArgs + /// + /// The ID of the primitive sending the sensor + /// The ID of the group associated with the primitive + /// The name of the primitive sending the sensor + /// The ID of the primitive sending the sensor + /// The ID of the owner of the primitive sending the sensor + /// The position of the primitive sending the sensor + /// The range the primitive specified to scan + /// The rotation of the primitive sending the sensor + /// The type of sensor the primitive sent + /// The velocity of the primitive sending the sensor + public ScriptSensorReplyEventArgs(UUID requestorID, UUID groupID, string name, + UUID objectID, UUID ownerID, Vector3 position, float range, Quaternion rotation, + ScriptSensorTypeFlags type, Vector3 velocity) + { + this.m_RequestorID = requestorID; + this.m_GroupID = groupID; + this.m_Name = name; + this.m_ObjectID = objectID; + this.m_OwnerID = ownerID; + this.m_Position = position; + this.m_Range = range; + this.m_Rotation = rotation; + this.m_Type = type; + this.m_Velocity = velocity; + } + } + + /// Contains the response data returned from the simulator in response to a + public class AvatarSitResponseEventArgs : EventArgs + { + private readonly UUID m_ObjectID; + private readonly bool m_Autopilot; + private readonly Vector3 m_CameraAtOffset; + private readonly Vector3 m_CameraEyeOffset; + private readonly bool m_ForceMouselook; + private readonly Vector3 m_SitPosition; + private readonly Quaternion m_SitRotation; + + /// Get the ID of the primitive the agent will be sitting on + public UUID ObjectID { get { return m_ObjectID; } } + /// True if the simulator Autopilot functions were involved + public bool Autopilot { get { return m_Autopilot; } } + /// Get the camera offset of the agent when seated + public Vector3 CameraAtOffset { get { return m_CameraAtOffset; } } + /// Get the camera eye offset of the agent when seated + public Vector3 CameraEyeOffset { get { return m_CameraEyeOffset; } } + /// True of the agent will be in mouselook mode when seated + public bool ForceMouselook { get { return m_ForceMouselook; } } + /// Get the position of the agent when seated + public Vector3 SitPosition { get { return m_SitPosition; } } + /// Get the rotation of the agent when seated + public Quaternion SitRotation { get { return m_SitRotation; } } + + /// Construct a new instance of the AvatarSitResponseEventArgs object + public AvatarSitResponseEventArgs(UUID objectID, bool autoPilot, Vector3 cameraAtOffset, + Vector3 cameraEyeOffset, bool forceMouselook, Vector3 sitPosition, Quaternion sitRotation) + { + this.m_ObjectID = objectID; + this.m_Autopilot = autoPilot; + this.m_CameraAtOffset = cameraAtOffset; + this.m_CameraEyeOffset = cameraEyeOffset; + this.m_ForceMouselook = forceMouselook; + this.m_SitPosition = sitPosition; + this.m_SitRotation = sitRotation; + } + } + + /// Data sent when an agent joins a chat session your agent is currently participating in + public class ChatSessionMemberAddedEventArgs : EventArgs + { + private readonly UUID m_SessionID; + private readonly UUID m_AgentID; + + /// Get the ID of the chat session + public UUID SessionID { get { return m_SessionID; } } + /// Get the ID of the agent that joined + public UUID AgentID { get { return m_AgentID; } } + + /// + /// Construct a new instance of the ChatSessionMemberAddedEventArgs object + /// + /// The ID of the chat session + /// The ID of the agent joining + public ChatSessionMemberAddedEventArgs(UUID sessionID, UUID agentID) + { + this.m_SessionID = sessionID; + this.m_AgentID = agentID; + } + } + + /// Data sent when an agent exits a chat session your agent is currently participating in + public class ChatSessionMemberLeftEventArgs : EventArgs + { + private readonly UUID m_SessionID; + private readonly UUID m_AgentID; + + /// Get the ID of the chat session + public UUID SessionID { get { return m_SessionID; } } + /// Get the ID of the agent that left + public UUID AgentID { get { return m_AgentID; } } + + /// + /// Construct a new instance of the ChatSessionMemberLeftEventArgs object + /// + /// The ID of the chat session + /// The ID of the Agent that left + public ChatSessionMemberLeftEventArgs(UUID sessionID, UUID agentID) + { + this.m_SessionID = sessionID; + this.m_AgentID = agentID; + } + } + #endregion } diff --git a/OpenMetaverse/DirectoryManager.cs b/OpenMetaverse/DirectoryManager.cs index d4ef889b..77509eb1 100644 --- a/OpenMetaverse/DirectoryManager.cs +++ b/OpenMetaverse/DirectoryManager.cs @@ -209,11 +209,16 @@ namespace OpenMetaverse [Flags] public enum ClassifiedFlags : byte { + /// None = 1 << 0, + /// Mature = 1 << 1, + /// Enabled = 1 << 2, // HasPrice = 1 << 3, // Deprecated + /// UpdateTime = 1 << 4, + /// AutoRenew = 1 << 5 } @@ -447,7 +452,6 @@ namespace OpenMetaverse } } - /// /// The details of an "Event" /// diff --git a/OpenMetaverse/FriendsManager.cs b/OpenMetaverse/FriendsManager.cs index eb144dbd..596cd76e 100644 --- a/OpenMetaverse/FriendsManager.cs +++ b/OpenMetaverse/FriendsManager.cs @@ -327,8 +327,8 @@ namespace OpenMetaverse Client = client; Client.Network.OnConnected += new NetworkManager.ConnectedCallback(Network_OnConnect); - Client.Avatars.OnAvatarNames += new AvatarManager.AvatarNamesCallback(Avatars_OnAvatarNames); - Client.Self.OnInstantMessage += new AgentManager.InstantMessageCallback(MainAvatar_InstantMessage); + Client.Avatars.OnAvatarNames += new AvatarManager.AvatarNamesCallback(Avatars_OnAvatarNames); + Client.Self.IM += Self_IM; Client.Network.RegisterCallback(PacketType.OnlineNotification, OnlineNotificationHandler); Client.Network.RegisterCallback(PacketType.OfflineNotification, OfflineNotificationHandler); @@ -339,6 +339,8 @@ namespace OpenMetaverse Client.Network.RegisterLoginResponseCallback(new NetworkManager.LoginResponseCallback(Network_OnLoginResponse), new string[] { "buddy-list" }); } + + #region Public Methods /// @@ -734,46 +736,41 @@ namespace OpenMetaverse #endregion - /// - /// Handles relevant messages from the server encapsulated in instant messages. - /// - /// InstantMessage object containing encapsalated instant message - /// Originating Simulator - private void MainAvatar_InstantMessage(InstantMessage im, Simulator simulator) + void Self_IM(object sender, InstantMessageEventArgs e) { - if (im.Dialog == InstantMessageDialog.FriendshipOffered) + if (e.IM.Dialog == InstantMessageDialog.FriendshipOffered) { if (OnFriendshipOffered != null) { - if (FriendRequests.ContainsKey(im.FromAgentID)) - FriendRequests[im.FromAgentID] = im.IMSessionID; + if (FriendRequests.ContainsKey(e.IM.FromAgentID)) + FriendRequests[e.IM.FromAgentID] = e.IM.IMSessionID; else - FriendRequests.Add(im.FromAgentID, im.IMSessionID); + FriendRequests.Add(e.IM.FromAgentID, e.IM.IMSessionID); - try { OnFriendshipOffered(im.FromAgentID, im.FromAgentName, im.IMSessionID); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + try { OnFriendshipOffered(e.IM.FromAgentID, e.IM.FromAgentName, e.IM.IMSessionID); } + catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Error, Client, ex); } } } - else if (im.Dialog == InstantMessageDialog.FriendshipAccepted) + else if (e.IM.Dialog == InstantMessageDialog.FriendshipAccepted) { - FriendInfo friend = new FriendInfo(im.FromAgentID, FriendRights.CanSeeOnline, + FriendInfo friend = new FriendInfo(e.IM.FromAgentID, FriendRights.CanSeeOnline, FriendRights.CanSeeOnline); - friend.Name = im.FromAgentName; + friend.Name = e.IM.FromAgentName; lock (FriendList.Dictionary) FriendList[friend.UUID] = friend; if (OnFriendshipResponse != null) { - try { OnFriendshipResponse(im.FromAgentID, im.FromAgentName, true); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + try { OnFriendshipResponse(e.IM.FromAgentID, e.IM.FromAgentName, true); } + catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Error, Client, ex); } } - RequestOnlineNotification(im.FromAgentID); + RequestOnlineNotification(e.IM.FromAgentID); } - else if (im.Dialog == InstantMessageDialog.FriendshipDeclined) + else if (e.IM.Dialog == InstantMessageDialog.FriendshipDeclined) { if (OnFriendshipResponse != null) { - try { OnFriendshipResponse(im.FromAgentID, im.FromAgentName, false); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + try { OnFriendshipResponse(e.IM.FromAgentID, e.IM.FromAgentName, false); } + catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Error, Client, ex); } } } } diff --git a/OpenMetaverse/InventoryManager.cs b/OpenMetaverse/InventoryManager.cs index 762e2675..be420e06 100644 --- a/OpenMetaverse/InventoryManager.cs +++ b/OpenMetaverse/InventoryManager.cs @@ -1069,8 +1069,8 @@ namespace OpenMetaverse _Client.Network.RegisterCallback(PacketType.ReplyTaskInventory, new NetworkManager.PacketCallback(ReplyTaskInventoryHandler)); _Client.Network.RegisterEventCallback("ScriptRunningReply", new Caps.EventQueueCallback(ScriptRunningReplyMessageHandler)); - // Watch for inventory given to us through instant message - _Client.Self.OnInstantMessage += new AgentManager.InstantMessageCallback(Self_OnInstantMessage); + // Watch for inventory given to us through instant message + _Client.Self.IM += Self_IM; // Register extra parameters with login and parse the inventory data that comes back _Client.Network.RegisterLoginResponseCallback( @@ -1080,6 +1080,7 @@ namespace OpenMetaverse "inventory-lib-owner", "inventory-skel-lib"}); } + #region Fetch /// @@ -3242,6 +3243,113 @@ namespace OpenMetaverse #region Callbacks + void Self_IM(object sender, InstantMessageEventArgs e) + { + // TODO: MainAvatar.InstantMessageDialog.GroupNotice can also be an inventory offer, should we + // handle it here? + + if (OnObjectOffered != null && + (e.IM.Dialog == InstantMessageDialog.InventoryOffered + || e.IM.Dialog == InstantMessageDialog.TaskInventoryOffered)) + { + AssetType type = AssetType.Unknown; + UUID objectID = UUID.Zero; + bool fromTask = false; + + if (e.IM.Dialog == InstantMessageDialog.InventoryOffered) + { + if (e.IM.BinaryBucket.Length == 17) + { + type = (AssetType)e.IM.BinaryBucket[0]; + objectID = new UUID(e.IM.BinaryBucket, 1); + fromTask = false; + } + else + { + Logger.Log("Malformed inventory offer from agent", Helpers.LogLevel.Warning, _Client); + return; + } + } + else if (e.IM.Dialog == InstantMessageDialog.TaskInventoryOffered) + { + if (e.IM.BinaryBucket.Length == 1) + { + type = (AssetType)e.IM.BinaryBucket[0]; + fromTask = true; + } + else + { + Logger.Log("Malformed inventory offer from object", Helpers.LogLevel.Warning, _Client); + return; + } + } + + // Find the folder where this is going to go + UUID destinationFolderID = FindFolderForType(type); + + // Fire the callback + try + { + ImprovedInstantMessagePacket imp = new ImprovedInstantMessagePacket(); + imp.AgentData.AgentID = _Client.Self.AgentID; + imp.AgentData.SessionID = _Client.Self.SessionID; + imp.MessageBlock.FromGroup = false; + imp.MessageBlock.ToAgentID = e.IM.FromAgentID; + imp.MessageBlock.Offline = 0; + imp.MessageBlock.ID = e.IM.IMSessionID; + imp.MessageBlock.Timestamp = 0; + imp.MessageBlock.FromAgentName = Utils.StringToBytes(_Client.Self.Name); + imp.MessageBlock.Message = Utils.EmptyBytes; + imp.MessageBlock.ParentEstateID = 0; + imp.MessageBlock.RegionID = UUID.Zero; + imp.MessageBlock.Position = _Client.Self.SimPosition; + + if (OnObjectOffered(e.IM, type, objectID, fromTask)) + { + // Accept the inventory offer + switch (e.IM.Dialog) + { + case InstantMessageDialog.InventoryOffered: + imp.MessageBlock.Dialog = (byte)InstantMessageDialog.InventoryAccepted; + break; + case InstantMessageDialog.TaskInventoryOffered: + imp.MessageBlock.Dialog = (byte)InstantMessageDialog.TaskInventoryAccepted; + break; + case InstantMessageDialog.GroupNotice: + imp.MessageBlock.Dialog = (byte)InstantMessageDialog.GroupNoticeInventoryAccepted; + break; + } + + imp.MessageBlock.BinaryBucket = destinationFolderID.GetBytes(); + } + else + { + // Decline the inventory offer + switch (e.IM.Dialog) + { + case InstantMessageDialog.InventoryOffered: + imp.MessageBlock.Dialog = (byte)InstantMessageDialog.InventoryDeclined; + break; + case InstantMessageDialog.TaskInventoryOffered: + imp.MessageBlock.Dialog = (byte)InstantMessageDialog.TaskInventoryDeclined; + break; + case InstantMessageDialog.GroupNotice: + imp.MessageBlock.Dialog = (byte)InstantMessageDialog.GroupNoticeInventoryDeclined; + break; + } + + imp.MessageBlock.BinaryBucket = Utils.EmptyBytes; + } + + _Client.Network.SendPacket(imp, e.Simulator); + } + catch (Exception ex) + { + Logger.Log(ex.Message, Helpers.LogLevel.Error, _Client, ex); + } + } + } + private void CreateItemFromAssetResponse(CapsClient client, OSD result, Exception error) { object[] args = (object[])client.UserData; @@ -3732,113 +3840,7 @@ namespace OpenMetaverse } } - private void Self_OnInstantMessage(InstantMessage im, Simulator simulator) - { - // TODO: MainAvatar.InstantMessageDialog.GroupNotice can also be an inventory offer, should we - // handle it here? - - if (OnObjectOffered != null && - (im.Dialog == InstantMessageDialog.InventoryOffered - || im.Dialog == InstantMessageDialog.TaskInventoryOffered)) - { - AssetType type = AssetType.Unknown; - UUID objectID = UUID.Zero; - bool fromTask = false; - - if (im.Dialog == InstantMessageDialog.InventoryOffered) - { - if (im.BinaryBucket.Length == 17) - { - type = (AssetType)im.BinaryBucket[0]; - objectID = new UUID(im.BinaryBucket, 1); - fromTask = false; - } - else - { - Logger.Log("Malformed inventory offer from agent", Helpers.LogLevel.Warning, _Client); - return; - } - } - else if (im.Dialog == InstantMessageDialog.TaskInventoryOffered) - { - if (im.BinaryBucket.Length == 1) - { - type = (AssetType)im.BinaryBucket[0]; - fromTask = true; - } - else - { - Logger.Log("Malformed inventory offer from object", Helpers.LogLevel.Warning, _Client); - return; - } - } - - // Find the folder where this is going to go - UUID destinationFolderID = FindFolderForType(type); - - // Fire the callback - try - { - ImprovedInstantMessagePacket imp = new ImprovedInstantMessagePacket(); - imp.AgentData.AgentID = _Client.Self.AgentID; - imp.AgentData.SessionID = _Client.Self.SessionID; - imp.MessageBlock.FromGroup = false; - imp.MessageBlock.ToAgentID = im.FromAgentID; - imp.MessageBlock.Offline = 0; - imp.MessageBlock.ID = im.IMSessionID; - imp.MessageBlock.Timestamp = 0; - imp.MessageBlock.FromAgentName = Utils.StringToBytes(_Client.Self.Name); - imp.MessageBlock.Message = Utils.EmptyBytes; - imp.MessageBlock.ParentEstateID = 0; - imp.MessageBlock.RegionID = UUID.Zero; - imp.MessageBlock.Position = _Client.Self.SimPosition; - - if (OnObjectOffered(im, type, objectID, fromTask)) - { - // Accept the inventory offer - switch (im.Dialog) - { - case InstantMessageDialog.InventoryOffered: - imp.MessageBlock.Dialog = (byte)InstantMessageDialog.InventoryAccepted; - break; - case InstantMessageDialog.TaskInventoryOffered: - imp.MessageBlock.Dialog = (byte)InstantMessageDialog.TaskInventoryAccepted; - break; - case InstantMessageDialog.GroupNotice: - imp.MessageBlock.Dialog = (byte)InstantMessageDialog.GroupNoticeInventoryAccepted; - break; - } - - imp.MessageBlock.BinaryBucket = destinationFolderID.GetBytes(); - } - else - { - // Decline the inventory offer - switch (im.Dialog) - { - case InstantMessageDialog.InventoryOffered: - imp.MessageBlock.Dialog = (byte)InstantMessageDialog.InventoryDeclined; - break; - case InstantMessageDialog.TaskInventoryOffered: - imp.MessageBlock.Dialog = (byte)InstantMessageDialog.TaskInventoryDeclined; - break; - case InstantMessageDialog.GroupNotice: - imp.MessageBlock.Dialog = (byte)InstantMessageDialog.GroupNoticeInventoryDeclined; - break; - } - - imp.MessageBlock.BinaryBucket = Utils.EmptyBytes; - } - - _Client.Network.SendPacket(imp, simulator); - } - catch (Exception e) - { - Logger.Log(e.Message, Helpers.LogLevel.Error, _Client, e); - } - } - } - + private void Network_OnLoginResponse(bool loginSuccess, bool redirect, string message, string reason, LoginResponseData replyData) { if (loginSuccess) diff --git a/Programs/examples/Dashboard/Dashboard.cs b/Programs/examples/Dashboard/Dashboard.cs index acef11a9..55678575 100644 --- a/Programs/examples/Dashboard/Dashboard.cs +++ b/Programs/examples/Dashboard/Dashboard.cs @@ -64,7 +64,7 @@ namespace Dashboard Client.Settings.USE_ASSET_CACHE = true; Client.Network.OnDisconnected += new NetworkManager.DisconnectedCallback(Network_OnDisconnected); - Client.Self.OnInstantMessage += new AgentManager.InstantMessageCallback(Self_OnInstantMessage); + Client.Self.IM += Self_IM; //define the client object for each GUI element avatarList1.Client = Client; @@ -78,6 +78,19 @@ namespace Dashboard statusOutput1.Client = Client; } + void Self_IM(object sender, InstantMessageEventArgs e) + { + if (e.IM.Dialog == InstantMessageDialog.RequestTeleport) + { + this.BeginInvoke((MethodInvoker)delegate + { + DialogResult result = MessageBox.Show(this, e.IM.FromAgentName + " has offered you a teleport request:" + Environment.NewLine + e.IM.Message, this.Text, MessageBoxButtons.YesNo); + if (result == DialogResult.Yes) + Client.Self.TeleportLureRespond(e.IM.FromAgentID, true); + }); + } + } + void Dashboard_FormClosing(object sender, FormClosingEventArgs e) { ShuttingDown = true; @@ -103,20 +116,6 @@ namespace Dashboard void Network_OnDisconnected(NetworkManager.DisconnectType reason, string message) { InitializeClient(!ShuttingDown); - } - - void Self_OnInstantMessage(InstantMessage im, Simulator simulator) - { - if (im.Dialog == InstantMessageDialog.RequestTeleport) - { - this.BeginInvoke((MethodInvoker)delegate - { - DialogResult result = MessageBox.Show(this, im.FromAgentName + " has offered you a teleport request:" + Environment.NewLine + im.Message, this.Text, MessageBoxButtons.YesNo); - if (result == DialogResult.Yes) - Client.Self.TeleportLureRespond(im.FromAgentID, true); - }); - } - } - + } } } \ No newline at end of file diff --git a/Programs/examples/IRCGateway/Program.cs b/Programs/examples/IRCGateway/Program.cs index 6f0d730f..e7ebc8a3 100644 --- a/Programs/examples/IRCGateway/Program.cs +++ b/Programs/examples/IRCGateway/Program.cs @@ -22,9 +22,8 @@ namespace IRCGateway { _Client = new GridClient(); _Client.Network.OnLogin += new NetworkManager.LoginCallback(Network_OnLogin); - _Client.Self.OnChat += new AgentManager.ChatCallback(Self_OnChat); - _Client.Self.OnInstantMessage += new AgentManager.InstantMessageCallback(Self_OnInstantMessage); - + _Client.Self.ChatFromSimulator += new EventHandler(Self_ChatFromSimulator); + _Client.Self.IM += Self_IM; _ClientLogin = _Client.Network.DefaultLoginParams(args[0], args[1], args[2], "", "IRCGateway"); _AutoJoinChannel = args[6]; @@ -39,6 +38,27 @@ namespace IRCGateway } } + static void Self_IM(object sender, InstantMessageEventArgs e) + { + if (e.IM.Dialog == InstantMessageDialog.RequestTeleport) + { + if (e.IM.FromAgentID == _MasterID) + { + _Client.Self.TeleportLureRespond(e.IM.FromAgentID, true); + } + } + } + + static void Self_ChatFromSimulator(object sender, ChatEventArgs e) + { + if (e.FromName != _Client.Self.Name && e.Type == ChatType.Normal && e.AudibleLevel == ChatAudibleLevel.Fully) + { + string str = "<" + e.FromName + "> " + e.Message; + _IRC.SendMessage(_AutoJoinChannel, str); + Console.WriteLine("[SL->IRC] " + str); + } + } + static void _IRC_OnConnected() { _IRC.JoinChannel(_AutoJoinChannel); @@ -54,32 +74,10 @@ namespace IRCGateway Console.WriteLine("[IRC->SL] " + str); } } - - static void Self_OnInstantMessage(InstantMessage im, Simulator simulator) - { - if (im.Dialog == InstantMessageDialog.RequestTeleport) - { - if (im.FromAgentID == _MasterID) - { - _Client.Self.TeleportLureRespond(im.FromAgentID, true); - } - } - } - + static void Network_OnLogin(LoginStatus login, string message) { _IRC.SendMessage(_AutoJoinChannel, message); } - - static void Self_OnChat(string message, ChatAudibleLevel audible, ChatType type, ChatSourceType sourceType, string fromName, UUID id, UUID ownerid, Vector3 position) - { - if (fromName != _Client.Self.Name && type == ChatType.Normal && audible == ChatAudibleLevel.Fully) - { - string str = "<" + fromName + "> " + message; - _IRC.SendMessage(_AutoJoinChannel, str); - Console.WriteLine("[SL->IRC] " + str); - } - } - } } diff --git a/Programs/examples/TestClient/Commands/Appearance/WearCommand.cs b/Programs/examples/TestClient/Commands/Appearance/WearCommand.cs index ce7ba1ea..e19d2420 100644 --- a/Programs/examples/TestClient/Commands/Appearance/WearCommand.cs +++ b/Programs/examples/TestClient/Commands/Appearance/WearCommand.cs @@ -19,6 +19,7 @@ namespace OpenMetaverse.TestClient return "Usage: wear [outfit name] eg: 'wear /My Outfit/Dance Party"; string target = String.Empty; + bool bake = true; for (int ct = 0; ct < args.Length; ct++) diff --git a/Programs/examples/TestClient/Commands/Communication/EchoMasterCommand.cs b/Programs/examples/TestClient/Commands/Communication/EchoMasterCommand.cs index 683c7c66..89b619ce 100644 --- a/Programs/examples/TestClient/Commands/Communication/EchoMasterCommand.cs +++ b/Programs/examples/TestClient/Commands/Communication/EchoMasterCommand.cs @@ -20,22 +20,21 @@ namespace OpenMetaverse.TestClient if (!Active) { Active = true; - Client.Self.OnChat += new AgentManager.ChatCallback(Self_OnChat); + Client.Self.ChatFromSimulator += Self_ChatFromSimulator; return "Echoing is now on."; } else { Active = false; - Client.Self.OnChat -= new AgentManager.ChatCallback(Self_OnChat); + Client.Self.ChatFromSimulator -= Self_ChatFromSimulator; return "Echoing is now off."; } } - void Self_OnChat(string message, ChatAudibleLevel audible, ChatType type, - ChatSourceType sourcetype, string fromName, UUID id, UUID ownerid, Vector3 position) - { - if (message.Length > 0 && (Client.MasterKey == id || (Client.MasterName == fromName && !Client.AllowObjectMaster))) - Client.Self.Chat(message, 0, ChatType.Normal); - } + void Self_ChatFromSimulator(object sender, ChatEventArgs e) + { + if (e.Message.Length > 0 && (Client.MasterKey == e.SourceID || (Client.MasterName == e.FromName && !Client.AllowObjectMaster))) + Client.Self.Chat(e.Message, 0, ChatType.Normal); + } } } diff --git a/Programs/examples/TestClient/Commands/Communication/IMGroupCommand.cs b/Programs/examples/TestClient/Commands/Communication/IMGroupCommand.cs index 624a6da2..9c7719f1 100644 --- a/Programs/examples/TestClient/Commands/Communication/IMGroupCommand.cs +++ b/Programs/examples/TestClient/Commands/Communication/IMGroupCommand.cs @@ -30,10 +30,16 @@ namespace OpenMetaverse.TestClient string message = String.Empty; for (int ct = 1; ct < args.Length; ct++) message += args[ct] + " "; - message = message.TrimEnd(); - if (message.Length > 1023) message = message.Remove(1023); - Client.Self.OnGroupChatJoin += new AgentManager.GroupChatJoinedCallback(Self_OnGroupChatJoin); + message = message.TrimEnd(); + if (message.Length > 1023) + { + message = message.Remove(1023); + Console.WriteLine("Message truncated at 1024 characters"); + } + + Client.Self.GroupChatJoined += Self_GroupChatJoined; + if (!Client.Self.GroupChatSessions.ContainsKey(ToGroupID)) { WaitForSessionStart.Reset(); @@ -52,8 +58,8 @@ namespace OpenMetaverse.TestClient { return "Timeout waiting for group session start"; } - - Client.Self.OnGroupChatJoin -= new AgentManager.GroupChatJoinedCallback(Self_OnGroupChatJoin); + + Client.Self.GroupChatJoined -= Self_GroupChatJoined; return "Instant Messaged group " + ToGroupID.ToString() + " with message: " + message; } else @@ -62,11 +68,11 @@ namespace OpenMetaverse.TestClient } } - void Self_OnGroupChatJoin(UUID groupChatSessionID, string sessionName, UUID tmpSessionID, bool success) + void Self_GroupChatJoined(object sender, GroupChatJoinedEventArgs e) { - if (success) + if (e.Success) { - Console.WriteLine("Joined {0} Group Chat Success!", sessionName); + Console.WriteLine("Joined {0} Group Chat Success!", e.SessionName); WaitForSessionStart.Set(); } else @@ -74,5 +80,7 @@ namespace OpenMetaverse.TestClient Console.WriteLine("Join Group Chat failed :("); } } + + } } diff --git a/Programs/examples/TestClient/Commands/Directory/SearchClassifiedsCommand.cs b/Programs/examples/TestClient/Commands/Directory/SearchClassifiedsCommand.cs index 4916856a..23944575 100644 --- a/Programs/examples/TestClient/Commands/Directory/SearchClassifiedsCommand.cs +++ b/Programs/examples/TestClient/Commands/Directory/SearchClassifiedsCommand.cs @@ -6,8 +6,7 @@ namespace OpenMetaverse.TestClient.Commands { class SearchClassifiedsCommand : Command { - System.Threading.AutoResetEvent waitQuery = new System.Threading.AutoResetEvent(false); - int resultCount; + System.Threading.AutoResetEvent waitQuery = new System.Threading.AutoResetEvent(false); public SearchClassifiedsCommand(TestClient testClient) { diff --git a/Programs/examples/TestClient/Commands/Directory/SearchPlacesCommand.cs b/Programs/examples/TestClient/Commands/Directory/SearchPlacesCommand.cs index 84b83858..b9409035 100644 --- a/Programs/examples/TestClient/Commands/Directory/SearchPlacesCommand.cs +++ b/Programs/examples/TestClient/Commands/Directory/SearchPlacesCommand.cs @@ -7,7 +7,6 @@ namespace OpenMetaverse.TestClient.Commands class SearchPlacesCommand : Command { System.Threading.AutoResetEvent waitQuery = new System.Threading.AutoResetEvent(false); - int resultCount; public SearchPlacesCommand(TestClient testClient) { diff --git a/Programs/examples/TestClient/Commands/Inventory/BalanceCommand.cs b/Programs/examples/TestClient/Commands/Inventory/BalanceCommand.cs index 763bee6c..969ffe47 100644 --- a/Programs/examples/TestClient/Commands/Inventory/BalanceCommand.cs +++ b/Programs/examples/TestClient/Commands/Inventory/BalanceCommand.cs @@ -17,17 +17,17 @@ namespace OpenMetaverse.TestClient public override string Execute(string[] args, UUID fromAgentID) { System.Threading.AutoResetEvent waitBalance = new System.Threading.AutoResetEvent(false); - AgentManager.BalanceCallback del = delegate(int balance) { waitBalance.Set(); }; - Client.Self.OnBalanceUpdated += del; + + EventHandler del = delegate(object sender, BalanceEventArgs e) { waitBalance.Set(); }; + Client.Self.MoneyBalance += del; Client.Self.RequestBalance(); String result = "Timeout waiting for balance reply"; if (waitBalance.WaitOne(10000, false)) { result = Client.ToString() + " has L$: " + Client.Self.Balance; - } - Client.Self.OnBalanceUpdated -= del; - return result; - + } + Client.Self.MoneyBalance -= del; + return result; } } } diff --git a/Programs/examples/TestClient/TestClient.cs b/Programs/examples/TestClient/TestClient.cs index f72387f6..7003f830 100644 --- a/Programs/examples/TestClient/TestClient.cs +++ b/Programs/examples/TestClient/TestClient.cs @@ -52,7 +52,7 @@ namespace OpenMetaverse.TestClient Network.RegisterCallback(PacketType.AgentDataUpdate, new NetworkManager.PacketCallback(AgentDataUpdateHandler)); Network.OnLogin += new NetworkManager.LoginCallback(LoginHandler); - Self.OnInstantMessage += new AgentManager.InstantMessageCallback(Self_OnInstantMessage); + Self.IM += Self_IM; Groups.OnGroupMembers += new GroupManager.GroupMembersCallback(GroupMembersHandler); Inventory.OnObjectOffered += new InventoryManager.ObjectOfferedCallback(Inventory_OnInventoryObjectReceived); @@ -64,6 +64,37 @@ namespace OpenMetaverse.TestClient updateTimer.Start(); } + void Self_IM(object sender, InstantMessageEventArgs e) + { + bool groupIM = e.IM.GroupIM && GroupMembers != null && GroupMembers.ContainsKey(e.IM.FromAgentID) ? true : false; + + if (e.IM.FromAgentID == MasterKey || (GroupCommands && groupIM)) + { + // Received an IM from someone that is authenticated + Console.WriteLine("<{0} ({1})> {2}: {3} (@{4}:{5})", e.IM.GroupIM ? "GroupIM" : "IM", e.IM.Dialog, e.IM.FromAgentName, e.IM.Message, + e.IM.RegionID, e.IM.Position); + + if (e.IM.Dialog == InstantMessageDialog.RequestTeleport) + { + Console.WriteLine("Accepting teleport lure."); + Self.TeleportLureRespond(e.IM.FromAgentID, true); + } + else if ( + e.IM.Dialog == InstantMessageDialog.MessageFromAgent || + e.IM.Dialog == InstantMessageDialog.MessageFromObject) + { + ClientManager.Instance.DoCommandAll(e.IM.Message, e.IM.FromAgentID); + } + } + else + { + // Received an IM from someone that is not the bot's master, ignore + Console.WriteLine("<{0} ({1})> {2} (not master): {3} (@{4}:{5})", e.IM.GroupIM ? "GroupIM" : "IM", e.IM.Dialog, e.IM.FromAgentName, e.IM.Message, + e.IM.RegionID, e.IM.Position); + return; + } + } + /// /// Initialize everything that needs to be initialized once we're logged in. /// @@ -186,37 +217,7 @@ namespace OpenMetaverse.TestClient Logger.Log("[AlertMessage] " + Utils.BytesToString(message.AlertData.Message), Helpers.LogLevel.Info, this); } - - private void Self_OnInstantMessage(InstantMessage im, Simulator simulator) - { - bool groupIM = im.GroupIM && GroupMembers != null && GroupMembers.ContainsKey(im.FromAgentID) ? true : false; - - if (im.FromAgentID == MasterKey || (GroupCommands && groupIM)) - { - // Received an IM from someone that is authenticated - Console.WriteLine("<{0} ({1})> {2}: {3} (@{4}:{5})", im.GroupIM ? "GroupIM" : "IM", im.Dialog, im.FromAgentName, im.Message, im.RegionID, im.Position); - - if (im.Dialog == InstantMessageDialog.RequestTeleport) - { - Console.WriteLine("Accepting teleport lure."); - Self.TeleportLureRespond(im.FromAgentID, true); - } - else if ( - im.Dialog == InstantMessageDialog.MessageFromAgent || - im.Dialog == InstantMessageDialog.MessageFromObject) - { - ClientManager.Instance.DoCommandAll(im.Message, im.FromAgentID); - } - } - else - { - // Received an IM from someone that is not the bot's master, ignore - Console.WriteLine("<{0} ({1})> {2} (not master): {3} (@{4}:{5})", im.GroupIM ? "GroupIM" : "IM", im.Dialog, im.FromAgentName, im.Message, - im.RegionID, im.Position); - return; - } - } - + private bool Inventory_OnInventoryObjectReceived(InstantMessage offer, AssetType type, UUID objectID, bool fromTask) {