diff --git a/OpenMetaverse/AgentManager.cs b/OpenMetaverse/AgentManager.cs
index fac590d6..afacbccc 100644
--- a/OpenMetaverse/AgentManager.cs
+++ b/OpenMetaverse/AgentManager.cs
@@ -36,295 +36,295 @@ using OpenMetaverse.Packets;
namespace OpenMetaverse
{
- #region Enums
-
- ///
+ #region Enums
+
+ ///
/// Permission request flags, asked when a script wants to control an Avatar
///
[Flags]
public enum ScriptPermission : int
{
- /// Placeholder for empty values, shouldn't ever see this
- None = 0,
- /// Script wants ability to take money from you
- Debit = 1 << 1,
- /// Script wants to take camera controls for you
- TakeControls = 1 << 2,
- /// Script wants to remap avatars controls
- RemapControls = 1 << 3,
- /// Script wants to trigger avatar animations
+ /// Placeholder for empty values, shouldn't ever see this
+ None = 0,
+ /// Script wants ability to take money from you
+ Debit = 1 << 1,
+ /// Script wants to take camera controls for you
+ TakeControls = 1 << 2,
+ /// Script wants to remap avatars controls
+ RemapControls = 1 << 3,
+ /// Script wants to trigger avatar animations
/// This function is not implemented on the grid
- TriggerAnimation = 1 << 4,
- /// Script wants to attach or detach the prim or primset to your avatar
- Attach = 1 << 5,
- /// Script wants permission to release ownership
+ TriggerAnimation = 1 << 4,
+ /// Script wants to attach or detach the prim or primset to your avatar
+ Attach = 1 << 5,
+ /// Script wants permission to release ownership
/// This function is not implemented on the grid
/// The concept of "public" objects does not exist anymore.
- ReleaseOwnership = 1 << 6,
- /// Script wants ability to link/delink with other prims
- ChangeLinks = 1 << 7,
- /// Script wants permission to change joints
+ ReleaseOwnership = 1 << 6,
+ /// Script wants ability to link/delink with other prims
+ ChangeLinks = 1 << 7,
+ /// Script wants permission to change joints
/// This function is not implemented on the grid
- ChangeJoints = 1 << 8,
- /// Script wants permissions to change permissions
+ ChangeJoints = 1 << 8,
+ /// Script wants permissions to change permissions
/// This function is not implemented on the grid
- ChangePermissions = 1 << 9,
- /// Script wants to track avatars camera position and rotation
- TrackCamera = 1 << 10,
- /// Script wants to control your camera
- ControlCamera = 1 << 11
+ ChangePermissions = 1 << 9,
+ /// Script wants to track avatars camera position and rotation
+ TrackCamera = 1 << 10,
+ /// Script wants to control your camera
+ ControlCamera = 1 << 11
}
-
+
///
- /// Special commands used in Instant Messages
- ///
- public enum InstantMessageDialog : byte
- {
- /// Indicates a regular IM from another agent
- MessageFromAgent = 0,
- /// Simple notification box with an OK button
- MessageBox = 1,
- // Used to show a countdown notification with an OK
- // button, deprecated now
+ /// Special commands used in Instant Messages
+ ///
+ public enum InstantMessageDialog : byte
+ {
+ /// Indicates a regular IM from another agent
+ MessageFromAgent = 0,
+ /// Simple notification box with an OK button
+ MessageBox = 1,
+ // Used to show a countdown notification with an OK
+ // button, deprecated now
//[Obsolete]
//MessageBoxCountdown = 2,
- /// You've been invited to join a group.
- GroupInvitation = 3,
- /// Inventory offer
- InventoryOffered = 4,
- /// Accepted inventory offer
- InventoryAccepted = 5,
- /// Declined inventory offer
- InventoryDeclined = 6,
- /// Group vote
- GroupVote = 7,
- // A message to everyone in the agent's group, no longer
- // used
+ /// You've been invited to join a group.
+ GroupInvitation = 3,
+ /// Inventory offer
+ InventoryOffered = 4,
+ /// Accepted inventory offer
+ InventoryAccepted = 5,
+ /// Declined inventory offer
+ InventoryDeclined = 6,
+ /// Group vote
+ GroupVote = 7,
+ // A message to everyone in the agent's group, no longer
+ // used
//[Obsolete]
//DeprecatedGroupMessage = 8,
- /// An object is offering its inventory
- TaskInventoryOffered = 9,
- /// Accept an inventory offer from an object
- TaskInventoryAccepted = 10,
- /// Decline an inventory offer from an object
- TaskInventoryDeclined = 11,
- /// Unknown
- NewUserDefault = 12,
- /// Start a session, or add users to a session
- SessionAdd = 13,
- /// Start a session, but don't prune offline users
- SessionOfflineAdd = 14,
- /// Start a session with your group
- SessionGroupStart = 15,
- /// Start a session without a calling card (finder or objects)
- SessionCardlessStart = 16,
- /// Send a message to a session
- SessionSend = 17,
- /// Leave a session
- SessionDrop = 18,
- /// Indicates that the IM is from an object
- MessageFromObject = 19,
- /// Sent an IM to a busy user, this is the auto response
- BusyAutoResponse = 20,
- /// Shows the message in the console and chat history
- ConsoleAndChatHistory = 21,
- /// Send a teleport lure
- RequestTeleport = 22,
- /// Response sent to the agent which inititiated a teleport invitation
- AcceptTeleport = 23,
- /// Response sent to the agent which inititiated a teleport invitation
- DenyTeleport = 24,
- /// Only useful if you have Linden permissions
- GodLikeRequestTeleport = 25,
- /// A placeholder type for future expansion, currently not
- /// used
- CurrentlyUnused = 26,
- // Notification of a new group election, this is
- // deprecated
+ /// An object is offering its inventory
+ TaskInventoryOffered = 9,
+ /// Accept an inventory offer from an object
+ TaskInventoryAccepted = 10,
+ /// Decline an inventory offer from an object
+ TaskInventoryDeclined = 11,
+ /// Unknown
+ NewUserDefault = 12,
+ /// Start a session, or add users to a session
+ SessionAdd = 13,
+ /// Start a session, but don't prune offline users
+ SessionOfflineAdd = 14,
+ /// Start a session with your group
+ SessionGroupStart = 15,
+ /// Start a session without a calling card (finder or objects)
+ SessionCardlessStart = 16,
+ /// Send a message to a session
+ SessionSend = 17,
+ /// Leave a session
+ SessionDrop = 18,
+ /// Indicates that the IM is from an object
+ MessageFromObject = 19,
+ /// Sent an IM to a busy user, this is the auto response
+ BusyAutoResponse = 20,
+ /// Shows the message in the console and chat history
+ ConsoleAndChatHistory = 21,
+ /// Send a teleport lure
+ RequestTeleport = 22,
+ /// Response sent to the agent which inititiated a teleport invitation
+ AcceptTeleport = 23,
+ /// Response sent to the agent which inititiated a teleport invitation
+ DenyTeleport = 24,
+ /// Only useful if you have Linden permissions
+ GodLikeRequestTeleport = 25,
+ /// A placeholder type for future expansion, currently not
+ /// used
+ CurrentlyUnused = 26,
+ // Notification of a new group election, this is
+ // deprecated
//[Obsolete]
//DeprecatedGroupElection = 27,
- /// IM to tell the user to go to an URL
- GotoUrl = 28,
- /// IM for help
- Session911Start = 29,
- /// IM sent automatically on call for help, sends a lure
- /// to each Helper reached
- Lure911 = 30,
- /// Like an IM but won't go to email
- FromTaskAsAlert = 31,
- /// IM from a group officer to all group members
- GroupNotice = 32,
- /// Unknown
- GroupNoticeInventoryAccepted = 33,
- /// Unknown
- GroupNoticeInventoryDeclined = 34,
- /// Accept a group invitation
- GroupInvitationAccept = 35,
- /// Decline a group invitation
- GroupInvitationDecline = 36,
- /// Unknown
- GroupNoticeRequested = 37,
- /// An avatar is offering you friendship
- FriendshipOffered = 38,
- /// An avatar has accepted your friendship offer
- FriendshipAccepted = 39,
- /// An avatar has declined your friendship offer
- FriendshipDeclined = 40,
- /// Indicates that a user has started typing
- StartTyping = 41,
- /// Indicates that a user has stopped typing
- StopTyping = 42
+ /// IM to tell the user to go to an URL
+ GotoUrl = 28,
+ /// IM for help
+ Session911Start = 29,
+ /// IM sent automatically on call for help, sends a lure
+ /// to each Helper reached
+ Lure911 = 30,
+ /// Like an IM but won't go to email
+ FromTaskAsAlert = 31,
+ /// IM from a group officer to all group members
+ GroupNotice = 32,
+ /// Unknown
+ GroupNoticeInventoryAccepted = 33,
+ /// Unknown
+ GroupNoticeInventoryDeclined = 34,
+ /// Accept a group invitation
+ GroupInvitationAccept = 35,
+ /// Decline a group invitation
+ GroupInvitationDecline = 36,
+ /// Unknown
+ GroupNoticeRequested = 37,
+ /// An avatar is offering you friendship
+ FriendshipOffered = 38,
+ /// An avatar has accepted your friendship offer
+ FriendshipAccepted = 39,
+ /// An avatar has declined your friendship offer
+ FriendshipDeclined = 40,
+ /// Indicates that a user has started typing
+ StartTyping = 41,
+ /// Indicates that a user has stopped typing
+ StopTyping = 42
}
- ///
- /// Flag in Instant Messages, whether the IM should be delivered to
- /// offline avatars as well
- ///
- public enum InstantMessageOnline
- {
- /// Only deliver to online avatars
- Online = 0,
- /// If the avatar is offline the message will be held until
- /// they login next, and possibly forwarded to their e-mail account
- Offline = 1
- }
+ ///
+ /// Flag in Instant Messages, whether the IM should be delivered to
+ /// offline avatars as well
+ ///
+ public enum InstantMessageOnline
+ {
+ /// Only deliver to online avatars
+ Online = 0,
+ /// If the avatar is offline the message will be held until
+ /// they login next, and possibly forwarded to their e-mail account
+ Offline = 1
+ }
- ///
- /// Conversion type to denote Chat Packet types in an easier-to-understand format
- ///
- public enum ChatType : byte
- {
- /// Whisper (5m radius)
- Whisper = 0,
- /// Normal chat (10/20m radius), what the official viewer typically sends
- Normal = 1,
- /// Shouting! (100m radius)
- Shout = 2,
- // Say chat (10/20m radius) - The official viewer will
- // print "[4:15] You say, hey" instead of "[4:15] You: hey"
+ ///
+ /// Conversion type to denote Chat Packet types in an easier-to-understand format
+ ///
+ public enum ChatType : byte
+ {
+ /// Whisper (5m radius)
+ Whisper = 0,
+ /// Normal chat (10/20m radius), what the official viewer typically sends
+ Normal = 1,
+ /// Shouting! (100m radius)
+ Shout = 2,
+ // Say chat (10/20m radius) - The official viewer will
+ // print "[4:15] You say, hey" instead of "[4:15] You: hey"
//[Obsolete]
//Say = 3,
- /// Event message when an Avatar has begun to type
- StartTyping = 4,
- /// Event message when an Avatar has stopped typing
- StopTyping = 5,
- /// Unknown
- Debug = 6,
+ /// Event message when an Avatar has begun to type
+ StartTyping = 4,
+ /// Event message when an Avatar has stopped typing
+ StopTyping = 5,
+ /// Unknown
+ Debug = 6,
/// Event message when an object uses llOwnerSay
- OwnerSay = 8
- }
+ OwnerSay = 8
+ }
- ///
- /// Identifies the source of a chat message
- ///
- public enum ChatSourceType : byte
- {
- /// Chat from the grid or simulator
- System = 0,
- /// Chat from another avatar
- Agent = 1,
- /// Chat from an object
- Object = 2
- }
+ ///
+ /// Identifies the source of a chat message
+ ///
+ public enum ChatSourceType : byte
+ {
+ /// Chat from the grid or simulator
+ System = 0,
+ /// Chat from another avatar
+ Agent = 1,
+ /// Chat from an object
+ Object = 2
+ }
- ///
- ///
- ///
- public enum ChatAudibleLevel : sbyte
- {
- ///
- Not = -1,
- ///
- Barely = 0,
- ///
- Fully = 1
- }
+ ///
+ ///
+ ///
+ public enum ChatAudibleLevel : sbyte
+ {
+ ///
+ Not = -1,
+ ///
+ Barely = 0,
+ ///
+ Fully = 1
+ }
- ///
- /// Effect type used in ViewerEffect packets
- ///
- public enum EffectType : byte
- {
- ///
- Text = 0,
- ///
- Icon,
- ///
- Connector,
- ///
- FlexibleObject,
- ///
- AnimalControls,
- ///
- AnimationObject,
- ///
- Cloth,
- /// Project a beam from a source to a destination, such as
- /// the one used when editing an object
- Beam,
- ///
- Glow,
- ///
- Point,
- ///
- Trail,
- /// Create a swirl of particles around an object
- Sphere,
- ///
- Spiral,
- ///
- Edit,
- /// Cause an avatar to look at an object
- LookAt,
- /// Cause an avatar to point at an object
- PointAt
- }
+ ///
+ /// Effect type used in ViewerEffect packets
+ ///
+ public enum EffectType : byte
+ {
+ ///
+ Text = 0,
+ ///
+ Icon,
+ ///
+ Connector,
+ ///
+ FlexibleObject,
+ ///
+ AnimalControls,
+ ///
+ AnimationObject,
+ ///
+ Cloth,
+ /// Project a beam from a source to a destination, such as
+ /// the one used when editing an object
+ Beam,
+ ///
+ Glow,
+ ///
+ Point,
+ ///
+ Trail,
+ /// Create a swirl of particles around an object
+ Sphere,
+ ///
+ Spiral,
+ ///
+ Edit,
+ /// Cause an avatar to look at an object
+ LookAt,
+ /// Cause an avatar to point at an object
+ PointAt
+ }
- ///
- /// The action an avatar is doing when looking at something, used in
- /// ViewerEffect packets for the LookAt effect
- ///
- public enum LookAtType : byte
- {
- ///
- None,
- ///
- Idle,
- ///
- AutoListen,
- ///
- FreeLook,
- ///
- Respond,
- ///
- Hover,
- /// Deprecated
+ ///
+ /// The action an avatar is doing when looking at something, used in
+ /// ViewerEffect packets for the LookAt effect
+ ///
+ public enum LookAtType : byte
+ {
+ ///
+ None,
+ ///
+ Idle,
+ ///
+ AutoListen,
+ ///
+ FreeLook,
+ ///
+ Respond,
+ ///
+ Hover,
+ /// Deprecated
[Obsolete]
- Conversation,
- ///
- Select,
- ///
- Focus,
- ///
- Mouselook,
- ///
- Clear
- }
+ Conversation,
+ ///
+ Select,
+ ///
+ Focus,
+ ///
+ Mouselook,
+ ///
+ Clear
+ }
- ///
- /// The action an avatar is doing when pointing at something, used in
- /// ViewerEffect packets for the PointAt effect
- ///
- public enum PointAtType : byte
- {
- ///
- None,
- ///
- Select,
- ///
- Grab,
- ///
- Clear
+ ///
+ /// The action an avatar is doing when pointing at something, used in
+ /// ViewerEffect packets for the PointAt effect
+ ///
+ public enum PointAtType : byte
+ {
+ ///
+ None,
+ ///
+ Select,
+ ///
+ Grab,
+ ///
+ Clear
}
///
@@ -502,17 +502,17 @@ namespace OpenMetaverse
MouseLookLeftButton = 1073741824
}
#endregion Enums
-
+
#region Structs
-
- ///
- /// Instant Message
- ///
- public struct InstantMessage
- {
- /// Key of sender
- public UUID FromAgentID;
- /// Name of sender
+
+ ///
+ /// Instant Message
+ ///
+ public struct InstantMessage
+ {
+ /// Key of sender
+ public UUID FromAgentID;
+ /// Name of sender
public string FromAgentName;
/// Key of destination avatar
public UUID ToAgentID;
@@ -536,21 +536,23 @@ namespace OpenMetaverse
public InstantMessageOnline Offline;
/// Context specific packed data
public byte[] BinaryBucket;
- //Print the contents of a message
- 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;
+ //Print the contents of a message
+ 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;
+
+ }
+ }
+
+ #endregion Structs
- }
- }
-
- #endregion Structs
-
///
/// Manager class for our own avatar
///
@@ -611,39 +613,39 @@ namespace OpenMetaverse
public enum TeleportFlags : uint
{
/// No flags set, or teleport failed
- Default = 0,
+ Default = 0,
/// Set when newbie leaves help island for first time
SetHomeToTarget = 1 << 0,
///
SetLastToTarget = 1 << 1,
/// Via Lure
- ViaLure = 1 << 2,
+ ViaLure = 1 << 2,
/// Via Landmark
- ViaLandmark = 1 << 3,
+ ViaLandmark = 1 << 3,
/// Via Location
- ViaLocation = 1 << 4,
+ ViaLocation = 1 << 4,
/// Via Home
- ViaHome = 1 << 5,
+ ViaHome = 1 << 5,
/// Via Telehub
- ViaTelehub = 1 << 6,
+ ViaTelehub = 1 << 6,
/// Via Login
- ViaLogin = 1 << 7,
+ ViaLogin = 1 << 7,
/// Linden Summoned
- ViaGodlikeLure = 1 << 8,
+ ViaGodlikeLure = 1 << 8,
/// Linden Forced me
- Godlike = 1 << 9,
+ Godlike = 1 << 9,
///
- NineOneOne = 1 << 10,
+ NineOneOne = 1 << 10,
/// Agent Teleported Home via Script
- DisableCancel = 1 << 11,
+ DisableCancel = 1 << 11,
///
- ViaRegionID = 1 << 12,
+ ViaRegionID = 1 << 12,
///
- IsFlying = 1 << 13,
+ IsFlying = 1 << 13,
///
- ResetHome = 1 << 14,
+ ResetHome = 1 << 14,
/// forced to new location for example when avatar is banned or ejected
- ForceRedirect = 1 << 15,
+ ForceRedirect = 1 << 15,
/// Teleport Finished via a Lure
FinishedViaLure = 1 << 26,
/// Finished, Sim Changed
@@ -697,7 +699,7 @@ namespace OpenMetaverse
/// Key of source
/// Key of the sender
/// Senders position
- public delegate void ChatCallback(string message, ChatAudibleLevel audible, ChatType type,
+ public delegate void ChatCallback(string message, ChatAudibleLevel audible, ChatType type,
ChatSourceType sourceType, string fromName, UUID id, UUID ownerid, Vector3 position);
///
@@ -734,7 +736,7 @@ namespace OpenMetaverse
/// 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);
+ public delegate void LoadURLCallback(string objectName, UUID objectID, UUID ownerID, bool ownerIsGroup, string message, string URL);
///
/// Triggered when the L$ account balance for this avatar changes
@@ -797,7 +799,7 @@ namespace OpenMetaverse
/// Avatars Active Title
/// Powers Avatar has in group
/// Name of the Group
- public delegate void AgentDataCallback(string firstName, string lastName, UUID activeGroupID,
+ public delegate void AgentDataCallback(string firstName, string lastName, UUID activeGroupID,
string groupTitle, GroupPowers groupPowers, string groupName);
///
@@ -832,17 +834,17 @@ namespace OpenMetaverse
/// Temporary session Key
/// if session start successful,
/// otherwise
- public delegate void GroupChatJoined(UUID groupChatSessionID, UUID tmpSessionID, bool success);
+ public delegate void GroupChatJoinedCallback(UUID groupChatSessionID, string sessionName, UUID tmpSessionID, bool success);
/// Fired when agent group chat session terminated
/// Key of Session (groups UUID)
- public delegate void GroupChatLeft(UUID groupchatSessionID);
+ public delegate void GroupChatLeftCallback(UUID groupchatSessionID);
///
/// Fired when alert message received from simulator
///
/// the message sent from the grid to our avatar.
- public delegate void AlertMessage(string message);
+ public delegate void AlertMessageCallback(string message);
///
/// Fired when a script wants to give or release controls.
@@ -889,6 +891,19 @@ namespace OpenMetaverse
public delegate void AvatarSitResponseCallback(UUID objectID, bool autoPilot, Vector3 cameraAtOffset,
Vector3 cameraEyeOffset, bool forceMouselook, Vector3 sitPosition, Quaternion sitRotation);
+ ///
+ /// 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);
+ ///
+ /// 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);
+
#endregion Callbacks
#region Events
@@ -927,11 +942,11 @@ namespace OpenMetaverse
/// 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 GroupChatJoined OnGroupChatJoin;
+ public event GroupChatJoinedCallback OnGroupChatJoin;
/// Callback for when agent is confirmed to have left group chat session.
- public event GroupChatLeft OnGroupChatLeft;
+ public event GroupChatLeftCallback OnGroupChatLeft;
/// Alert messages sent to client from simulator
- public event AlertMessage OnAlertMessage;
+ 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
@@ -940,6 +955,10 @@ namespace OpenMetaverse
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
@@ -954,7 +973,7 @@ namespace OpenMetaverse
///
/// Dictionary containing current Group Chat sessions and members
///
- public InternalDictionary> GroupChatSessions = new InternalDictionary>();
+ public InternalDictionary> GroupChatSessions = new InternalDictionary>();
#region Properties
@@ -1027,7 +1046,7 @@ namespace OpenMetaverse
if (sittingOn != 0)
{
Primitive parent;
- if(Client.Network.CurrentSim != null && Client.Network.CurrentSim.ObjectsPrimitives.TryGetValue(sittingOn, out parent))
+ if (Client.Network.CurrentSim != null && Client.Network.CurrentSim.ObjectsPrimitives.TryGetValue(sittingOn, out parent))
{
return parent.Position + relativePosition;
}
@@ -1122,7 +1141,7 @@ namespace OpenMetaverse
private uint heightWidthGenCounter;
private float health;
private int balance;
- private UUID activeGroup;
+ private UUID activeGroup;
#endregion Private Members
///
@@ -1162,15 +1181,15 @@ namespace OpenMetaverse
Client.Network.RegisterCallback(PacketType.HealthMessage, new NetworkManager.PacketCallback(HealthHandler));
// Money callback
Client.Network.RegisterCallback(PacketType.MoneyBalanceReply, new NetworkManager.PacketCallback(BalanceHandler));
- //Agent update callback
- Client.Network.RegisterCallback(PacketType.AgentDataUpdate, new NetworkManager.PacketCallback(AgentDataUpdateHandler));
+ //Agent update callback
+ Client.Network.RegisterCallback(PacketType.AgentDataUpdate, new NetworkManager.PacketCallback(AgentDataUpdateHandler));
// Animation callback
Client.Network.RegisterCallback(PacketType.AvatarAnimation, new NetworkManager.PacketCallback(AvatarAnimationHandler));
// Object colliding into our agent callback
Client.Network.RegisterCallback(PacketType.MeanCollisionAlert, new NetworkManager.PacketCallback(MeanCollisionAlertHandler));
// Region Crossing
Client.Network.RegisterCallback(PacketType.CrossedRegion, new NetworkManager.PacketCallback(CrossedRegionHandler));
- // CAPS callbacks
+ // CAPS callbacks
Client.Network.RegisterEventCallback("EstablishAgentCommunication", new Caps.EventQueueCallback(EstablishAgentCommunicationEventHandler));
// Incoming Group Chat
Client.Network.RegisterEventCallback("ChatterBoxInvitation", new Caps.EventQueueCallback(ChatterBoxInvitationHandler));
@@ -1254,9 +1273,9 @@ namespace OpenMetaverse
/// Text message being sent
/// IM session ID (to differentiate between IM windows)
/// IDs of sessions for a conference
- public void InstantMessage(string fromName, UUID target, string message, UUID imSessionID,
+ public void InstantMessage(string fromName, UUID target, string message, UUID imSessionID,
UUID[] conferenceIDs)
- {
+ {
byte[] binaryBucket;
if (conferenceIDs != null && conferenceIDs.Length > 0)
@@ -1270,9 +1289,9 @@ namespace OpenMetaverse
binaryBucket = new byte[0];
}
- InstantMessage(fromName, target, message, imSessionID, InstantMessageDialog.MessageFromAgent,
+ InstantMessage(fromName, target, message, imSessionID, InstantMessageDialog.MessageFromAgent,
InstantMessageOnline.Offline, Vector3.Zero, UUID.Zero, binaryBucket);
- }
+ }
///
/// Send an Instant Message
@@ -1287,8 +1306,8 @@ namespace OpenMetaverse
/// RegionID Sender is In
/// Packed binary data that is specific to
/// the dialog type
- public void InstantMessage(string fromName, UUID target, string message, UUID imSessionID,
- InstantMessageDialog dialog, InstantMessageOnline offline, Vector3 position, UUID regionID,
+ public void InstantMessage(string fromName, UUID target, string message, UUID imSessionID,
+ InstantMessageDialog dialog, InstantMessageOnline offline, Vector3 position, UUID regionID,
byte[] binaryBucket)
{
if (target != UUID.Zero)
@@ -1365,12 +1384,12 @@ namespace OpenMetaverse
im.MessageBlock.Position = Vector3.Zero;
im.MessageBlock.RegionID = UUID.Zero;
im.MessageBlock.BinaryBucket = Utils.StringToBytes("\0");
-
+
Client.Network.SendPacket(im);
}
else
{
- Logger.Log("No Active group chat session appears to exist, use RequestJoinGroupChat() to join one",
+ Logger.Log("No Active group chat session appears to exist, use RequestJoinGroupChat() to join one",
Helpers.LogLevel.Error, Client);
}
}
@@ -1389,11 +1408,12 @@ namespace OpenMetaverse
im.MessageBlock.FromAgentName = Utils.StringToBytes(Client.Self.Name);
im.MessageBlock.FromGroup = false;
im.MessageBlock.Message = new byte[0];
+ im.MessageBlock.ParentEstateID = 0;
im.MessageBlock.Offline = 0;
im.MessageBlock.ID = groupID;
im.MessageBlock.ToAgentID = groupID;
im.MessageBlock.BinaryBucket = new byte[0];
- im.MessageBlock.Position = Vector3.Zero;
+ im.MessageBlock.Position = Client.Self.SimPosition;
im.MessageBlock.RegionID = UUID.Zero;
Client.Network.SendPacket(im);
@@ -1462,7 +1482,7 @@ namespace OpenMetaverse
UUID effectID)
{
ViewerEffectPacket effect = new ViewerEffectPacket();
-
+
effect.AgentData.AgentID = Client.Self.AgentID;
effect.AgentData.SessionID = Client.Self.SessionID;
@@ -1563,7 +1583,7 @@ namespace OpenMetaverse
/// Color values of beam
/// a float representing the duration the beam will last
/// of the Effect
- public void BeamEffect(UUID sourceAvatar, UUID targetObject, Vector3d globalOffset, Color4 color,
+ public void BeamEffect(UUID sourceAvatar, UUID targetObject, Vector3d globalOffset, Color4 color,
float duration, UUID effectID)
{
ViewerEffectPacket effect = new ViewerEffectPacket();
@@ -1913,7 +1933,7 @@ namespace OpenMetaverse
///
public void PayUploadFee()
{
- GiveMoney(UUID.Zero, Client.Settings.UPLOAD_COST, String.Empty, MoneyTransactionType.UploadCharge,
+ GiveMoney(UUID.Zero, Client.Settings.UPLOAD_COST, String.Empty, MoneyTransactionType.UploadCharge,
TransactionFlags.None);
}
@@ -1923,7 +1943,7 @@ namespace OpenMetaverse
/// description of the transaction
public void PayUploadFee(string description)
{
- GiveMoney(UUID.Zero, Client.Settings.UPLOAD_COST, description, MoneyTransactionType.UploadCharge,
+ GiveMoney(UUID.Zero, Client.Settings.UPLOAD_COST, description, MoneyTransactionType.UploadCharge,
TransactionFlags.None);
}
@@ -2025,21 +2045,21 @@ namespace OpenMetaverse
return Teleport(UUID.Zero);
}
- ///
- /// Teleport agent to a landmark
- ///
- /// of the landmark to teleport agent to
- /// true on success, false on failure
- public bool Teleport(UUID landmark)
- {
- teleportStat = TeleportStatus.None;
+ ///
+ /// Teleport agent to a landmark
+ ///
+ /// of the landmark to teleport agent to
+ /// true on success, false on failure
+ public bool Teleport(UUID landmark)
+ {
+ teleportStat = TeleportStatus.None;
teleportEvent.Reset();
- TeleportLandmarkRequestPacket p = new TeleportLandmarkRequestPacket();
- p.Info = new TeleportLandmarkRequestPacket.InfoBlock();
- p.Info.AgentID = Client.Self.AgentID;
- p.Info.SessionID = Client.Self.SessionID;
- p.Info.LandmarkID = landmark;
- Client.Network.SendPacket(p);
+ TeleportLandmarkRequestPacket p = new TeleportLandmarkRequestPacket();
+ p.Info = new TeleportLandmarkRequestPacket.InfoBlock();
+ p.Info.AgentID = Client.Self.AgentID;
+ p.Info.SessionID = Client.Self.SessionID;
+ p.Info.LandmarkID = landmark;
+ Client.Network.SendPacket(p);
teleportEvent.WaitOne(Client.Settings.TELEPORT_TIMEOUT, false);
@@ -2052,7 +2072,7 @@ namespace OpenMetaverse
}
return (teleportStat == TeleportStatus.Finished);
- }
+ }
///
/// Attempt to look up a simulator name and teleport to the discovered
@@ -2233,7 +2253,7 @@ namespace OpenMetaverse
/// true to accept the lure, false to decline it
public void TeleportLureRespond(UUID requesterID, bool accept)
{
- InstantMessage(Name, requesterID, String.Empty, UUID.Random(),
+ InstantMessage(Name, requesterID, String.Empty, UUID.Random(),
accept ? InstantMessageDialog.AcceptTeleport : InstantMessageDialog.DenyTeleport,
InstantMessageOnline.Offline, this.SimPosition, UUID.Zero, new byte[0]);
@@ -2437,23 +2457,23 @@ namespace OpenMetaverse
if (OnInstantMessage != null)
{
- InstantMessage message;
- message.FromAgentID = im.AgentData.AgentID;
- message.FromAgentName = Utils.BytesToString(im.MessageBlock.FromAgentName);
- message.ToAgentID = im.MessageBlock.ToAgentID;
- message.ParentEstateID = im.MessageBlock.ParentEstateID;
- message.RegionID = im.MessageBlock.RegionID;
- message.Position = im.MessageBlock.Position;
- message.Dialog = (InstantMessageDialog)im.MessageBlock.Dialog;
- message.GroupIM = im.MessageBlock.FromGroup;
- message.IMSessionID = im.MessageBlock.ID;
- message.Timestamp = new DateTime(im.MessageBlock.Timestamp);
- message.Message = Utils.BytesToString(im.MessageBlock.Message);
- message.Offline = (InstantMessageOnline)im.MessageBlock.Offline;
- message.BinaryBucket = im.MessageBlock.BinaryBucket;
+ InstantMessage message;
+ message.FromAgentID = im.AgentData.AgentID;
+ message.FromAgentName = Utils.BytesToString(im.MessageBlock.FromAgentName);
+ message.ToAgentID = im.MessageBlock.ToAgentID;
+ message.ParentEstateID = im.MessageBlock.ParentEstateID;
+ message.RegionID = im.MessageBlock.RegionID;
+ message.Position = im.MessageBlock.Position;
+ message.Dialog = (InstantMessageDialog)im.MessageBlock.Dialog;
+ message.GroupIM = im.MessageBlock.FromGroup;
+ message.IMSessionID = im.MessageBlock.ID;
+ message.Timestamp = new DateTime(im.MessageBlock.Timestamp);
+ message.Message = Utils.BytesToString(im.MessageBlock.Message);
+ message.Offline = (InstantMessageOnline)im.MessageBlock.Offline;
+ message.BinaryBucket = im.MessageBlock.BinaryBucket;
- try { OnInstantMessage(message, simulator); }
- catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); }
+ try { OnInstantMessage(message, simulator); }
+ catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); }
}
}
}
@@ -2567,7 +2587,8 @@ namespace OpenMetaverse
LoadURLPacket loadURL = (LoadURLPacket)packet;
if (OnLoadURL != null)
{
- try {
+ try
+ {
OnLoadURL(
Utils.BytesToString(loadURL.Data.ObjectName),
loadURL.Data.ObjectID,
@@ -2647,10 +2668,13 @@ namespace OpenMetaverse
if (OnMoneyBalanceReplyReceived != null)
{
- try { OnMoneyBalanceReplyReceived(mbrp.MoneyData.TransactionID,
- mbrp.MoneyData.TransactionSuccess, mbrp.MoneyData.MoneyBalance,
- mbrp.MoneyData.SquareMetersCredit, mbrp.MoneyData.SquareMetersCommitted,
- Utils.BytesToString(mbrp.MoneyData.Description)); }
+ 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); }
}
}
@@ -2700,7 +2724,7 @@ namespace OpenMetaverse
{
bool finished = false;
TeleportFlags flags = TeleportFlags.Default;
-
+
if (packet.Type == PacketType.TeleportStart)
{
TeleportStartPacket start = (TeleportStartPacket)packet;
@@ -2962,27 +2986,25 @@ namespace OpenMetaverse
LLSDMap map = (LLSDMap)llsd;
UUID sessionID = map["session_id"].AsUUID();
UUID tmpSessionID = map["temp_session_id"].AsUUID();
+
+ string sessionName = String.Empty;
+
bool success = map["success"].AsBoolean();
if (success)
{
- LLSDArray agentlist = (LLSDArray)map["agents"];
- List agents = new List();
- foreach (LLSD id in agentlist)
- agents.Add(id.AsUUID());
-
- lock (GroupChatSessions.Dictionary)
- {
- if (GroupChatSessions.ContainsKey(sessionID))
- GroupChatSessions.Dictionary[sessionID] = agents;
- else
- GroupChatSessions.Add(sessionID, agents);
- }
+ LLSDMap sessionInfo = (LLSDMap)map["session_info"];
+ sessionName = sessionInfo["session_name"].AsString();
+
+ /* Parameters we do not currently use for anything */
+ // sessionInfo["type"].AsInteger();
+ // sessionInfo["voice_enabled"}.AsBoolean();
+ // sessionInfo["moderated_mode"] -> ["voice"].AsBoolean()
}
if (OnGroupChatJoin != null)
{
- try { OnGroupChatJoin(sessionID, tmpSessionID, success); }
+ try { OnGroupChatJoin(sessionID, sessionName, tmpSessionID, success); }
catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); }
}
}
@@ -2995,40 +3017,171 @@ namespace OpenMetaverse
///
private void ChatterBoxSessionAgentListReplyHandler(string capsKey, LLSD llsd, Simulator simulator)
{
+ // parse the LLSD
LLSDMap map = (LLSDMap)llsd;
- UUID sessionID = map["session_id"].AsUUID();
- LLSDMap update = (LLSDMap)map["updates"];
- string errormsg = map["error"].AsString();
-
- //if (errormsg.Equals("already in session"))
- // return;
- foreach (KeyValuePair kvp in update)
+ // verify sessions exists, if not add it
+ UUID sessionID;
+ if (map.ContainsKey("session_id"))
{
- if (kvp.Value.Equals("ENTER"))
+ sessionID = map["session_id"].AsUUID();
+ lock (GroupChatSessions)
+ if (!GroupChatSessions.ContainsKey(sessionID))
+ GroupChatSessions.Add(sessionID, new List());
+ }
+ else
+ {
+ return;
+ }
+
+
+ //string errormsg = map["error"].AsString();
+ LLSDMap updates = (LLSDMap)map["updates"];
+
+ // Handle any agent data updates
+ LLSDMap agent_updates = (LLSDMap)map["agent_updates"];
+
+ foreach (KeyValuePair kvp in agent_updates)
+ {
+ UUID agent_key = kvp.Key;
+ LLSDMap record = (LLSDMap)kvp.Value;
+
+ // handle joins/parts first
+ if (record.ContainsKey("transition"))
{
+ // find existing record if any
+ ChatSessionMember fndMbr;
lock (GroupChatSessions.Dictionary)
{
- if (!GroupChatSessions.Dictionary[sessionID].Contains((UUID)kvp.Key))
- GroupChatSessions.Dictionary[sessionID].Add((UUID)kvp.Key);
+ fndMbr = GroupChatSessions[sessionID].Find(delegate(ChatSessionMember member)
+ {
+ return member.AvatarKey == agent_key;
+ });
+ }
+
+ // handle joins
+ if (record["transition"].AsString().Equals("ENTER"))
+ {
+ if (fndMbr.AvatarKey == null)
+ {
+ fndMbr = new ChatSessionMember();
+ fndMbr.AvatarKey = agent_key;
+
+ lock (GroupChatSessions.Dictionary)
+ GroupChatSessions[sessionID].Add(fndMbr);
+
+ if (OnChatSessionMemberAdded != null)
+ {
+ try { OnChatSessionMemberAdded(sessionID, agent_key); }
+ catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); }
+ }
+ }
+
+ }
+ // handle parts
+ else if (record["transition"].AsString().Equals("LEAVE"))
+ {
+ if (fndMbr.AvatarKey != null)
+ lock (GroupChatSessions.Dictionary)
+ GroupChatSessions[sessionID].Remove(fndMbr);
+
+ if (OnChatSessionMemberLeft != null)
+ {
+ try { OnChatSessionMemberLeft(sessionID, agent_key); }
+ catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); }
+ }
+ // no need to process anything else in this record
+ continue;
+ }
+ // this should only fire if LL adds a new transition but doesn't tell anyone
+ else
+ {
+ Logger.Log("Unknown transition action " + record["transition"], Helpers.LogLevel.Warning, Client);
}
}
- else if (kvp.Value.Equals("LEAVE"))
- {
- lock (GroupChatSessions.Dictionary)
- {
- if (GroupChatSessions.Dictionary[sessionID].Contains((UUID)kvp.Key))
- GroupChatSessions.Dictionary[sessionID].Remove((UUID)kvp.Key);
- // we left session, remove from dictionary
- if (kvp.Key.Equals(Client.Self.id) && OnGroupChatLeft != null)
+
+ // Handle any updates
+
+ // search for member to update
+ ChatSessionMember update_member = GroupChatSessions.Dictionary[sessionID].Find(delegate(ChatSessionMember m)
+ {
+ return m.AvatarKey == agent_key;
+ });
+
+ LLSDMap record_info = (LLSDMap)record["info"];
+
+ lock (GroupChatSessions.Dictionary)
+ {
+
+ if (record_info.ContainsKey("mutes"))
+ {
+ LLSDMap mutes = (LLSDMap)record_info["mutes"];
+ foreach (KeyValuePair muteEntry in mutes)
{
- GroupChatSessions.Dictionary.Remove(sessionID);
- OnGroupChatLeft(sessionID);
+ if (muteEntry.Key == "text")
+ {
+ update_member.MuteText = muteEntry.Value.AsBoolean();
+ }
+ else if (muteEntry.Key == "voice")
+ {
+ update_member.MuteVoice = muteEntry.Value.AsBoolean();
+ }
}
}
+
+ if (record_info.ContainsKey("can_voice_chat"))
+ {
+ update_member.CanVoiceChat = record_info["can_voice_chat"].AsBoolean();
+ }
+
+ if (record_info.ContainsKey("is_moderator"))
+ {
+ update_member.IsModerator = record_info["is_moderator"].AsBoolean();
+ }
}
+
+ // replace existing member record
+ lock (GroupChatSessions.Dictionary)
+ {
+ int found = GroupChatSessions.Dictionary[sessionID].FindIndex(delegate(ChatSessionMember m)
+ {
+ return m.AvatarKey == agent_key;
+ });
+
+ if (found >= 0)
+ GroupChatSessions.Dictionary[sessionID][found] = update_member;
+ }
+
}
+
+
+ //foreach (KeyValuePair kvp in updates)
+ //{
+ // if (kvp.Value.Equals("ENTER"))
+ // {
+ // lock (GroupChatSessions.Dictionary)
+ // {
+ // if (!GroupChatSessions.Dictionary[sessionID].Contains((UUID)kvp.Key))
+ // GroupChatSessions.Dictionary[sessionID].Add((UUID)kvp.Key);
+ // }
+ // }
+ // else if (kvp.Value.Equals("LEAVE"))
+ // {
+ // lock (GroupChatSessions.Dictionary)
+ // {
+ // if (GroupChatSessions.Dictionary[sessionID].Contains((UUID)kvp.Key))
+ // GroupChatSessions.Dictionary[sessionID].Remove((UUID)kvp.Key);
+
+ // // we left session, remove from dictionary
+ // if (kvp.Key.Equals(Client.Self.id) && OnGroupChatLeft != null)
+ // {
+ // GroupChatSessions.Dictionary.Remove(sessionID);
+ // OnGroupChatLeft(sessionID);
+ // }
+ // }
+ // }
+ //}
}
///
@@ -3038,34 +3191,75 @@ namespace OpenMetaverse
/// LLSD Map containing invitation
/// Originating Simulator
private void ChatterBoxInvitationHandler(string capsKey, LLSD llsd, Simulator simulator)
- {
- if (OnInstantMessage != null)
- {
- LLSDMap map = (LLSDMap)llsd;
- LLSDMap im = (LLSDMap)map["instantmessage"];
- LLSDMap agent = (LLSDMap)im["agent_params"];
- LLSDMap msg = (LLSDMap)im["message_params"];
- LLSDMap msgdata = (LLSDMap)msg["data"];
+ {
+ if (OnInstantMessage != null)
+ {
+ LLSDMap map = (LLSDMap)llsd;
+ LLSDMap im = (LLSDMap)map["instantmessage"];
+ LLSDMap agent = (LLSDMap)im["agent_params"];
+ LLSDMap msg = (LLSDMap)im["message_params"];
+ LLSDMap msgdata = (LLSDMap)msg["data"];
- InstantMessage message = new InstantMessage();
-
- message.FromAgentID = map["from_id"].AsUUID();
- message.FromAgentName = map["from_name"].AsString();
- message.ToAgentID = msg["to_id"].AsString();
- message.ParentEstateID = (uint)msg["parent_estate_id"].AsInteger();
- message.RegionID = msg["region_id"].AsUUID();
- message.Position = ((LLSDArray)msg["position"]).AsVector3();
- message.Dialog = (InstantMessageDialog)msgdata["type"].AsInteger();
- message.GroupIM = true;
- message.IMSessionID = map["session_id"].AsUUID();
- message.Timestamp = new DateTime(msgdata["timestamp"].AsInteger());
- message.Message = msg["message"].AsString();
- message.Offline = (InstantMessageOnline)msg["offline"].AsInteger();
- message.BinaryBucket = msg["binary_bucket"].AsBinary();
+ InstantMessage message = new InstantMessage();
- try { OnInstantMessage(message, simulator); }
- catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); }
- }
+ message.FromAgentID = map["from_id"].AsUUID();
+ message.FromAgentName = map["from_name"].AsString();
+ message.ToAgentID = msg["to_id"].AsString();
+ message.ParentEstateID = (uint)msg["parent_estate_id"].AsInteger();
+ message.RegionID = msg["region_id"].AsUUID();
+ message.Position = ((LLSDArray)msg["position"]).AsVector3();
+ message.Dialog = (InstantMessageDialog)msgdata["type"].AsInteger();
+ message.GroupIM = true;
+ message.IMSessionID = map["session_id"].AsUUID();
+ message.Timestamp = new DateTime(msgdata["timestamp"].AsInteger());
+ message.Message = msg["message"].AsString();
+ message.Offline = (InstantMessageOnline)msg["offline"].AsInteger();
+ message.BinaryBucket = msg["binary_bucket"].AsBinary();
+
+ try { OnInstantMessage(message, simulator); }
+ catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); }
+ }
+ }
+
+
+ ///
+ /// Moderate a chat session
+ ///
+ /// the of the session to moderate, for group chats this will be the groups UUID
+ /// the of the avatar to moderate
+ /// true to moderate (silence user), false to allow avatar to speak
+ public void ModerateChatSessions(UUID sessionID, UUID memberID, bool moderateText)
+ {
+ 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");
+
+ if (url != null)
+ {
+ LLSDMap req = new LLSDMap();
+ req.Add("method", LLSD.FromString("mute update"));
+
+ LLSDMap mute_info = new LLSDMap();
+ mute_info.Add("text", LLSD.FromBoolean(moderateText));
+
+ LLSDMap parameters = new LLSDMap();
+ parameters["agent_id"] = LLSD.FromUUID(memberID);
+ parameters["mute_info"] = mute_info;
+
+ req["params"] = parameters;
+
+ req.Add("session-id", LLSD.FromUUID(sessionID));
+
+ byte[] postData = StructuredData.LLSDParser.SerializeXmlBytes(req);
+
+ CapsClient request = new CapsClient(url);
+ request.StartRequest(postData);
+ }
+ else
+ {
+ throw new Exception("ChatSessionRequest capability is not currently available");
+ }
}
///
@@ -3116,13 +3310,16 @@ 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); }
+
+ 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); }
}
}
-
+
}
///
diff --git a/OpenMetaverse/AvatarManager.cs b/OpenMetaverse/AvatarManager.cs
index 37bca1c1..3c598563 100644
--- a/OpenMetaverse/AvatarManager.cs
+++ b/OpenMetaverse/AvatarManager.cs
@@ -239,6 +239,7 @@ namespace OpenMetaverse
/// The avatar key to retrieve a name for
public void RequestAvatarName(UUID id)
{
+ Console.WriteLine("AvatarManager requesting UUID for {0}", id);
UUIDNameRequestPacket request = new UUIDNameRequestPacket();
request.UUIDNameBlock = new UUIDNameRequestPacket.UUIDNameBlockBlock[1];
request.UUIDNameBlock[0] = new UUIDNameRequestPacket.UUIDNameBlockBlock();
@@ -253,16 +254,25 @@ namespace OpenMetaverse
/// The avatar keys to retrieve names for
public void RequestAvatarNames(List ids)
{
- UUIDNameRequestPacket request = new UUIDNameRequestPacket();
- request.UUIDNameBlock = new UUIDNameRequestPacket.UUIDNameBlockBlock[ids.Count];
-
- for (int i = 0; i < ids.Count; i++)
+ Console.WriteLine("AvatarManager requesting UUIDs count {0}", ids.Count);
+ if (ids.Count > 0)
{
- request.UUIDNameBlock[i] = new UUIDNameRequestPacket.UUIDNameBlockBlock();
- request.UUIDNameBlock[i].ID = ids[i];
+ UUIDNameRequestPacket request = new UUIDNameRequestPacket();
+ request.UUIDNameBlock = new UUIDNameRequestPacket.UUIDNameBlockBlock[ids.Count];
+
+ for (int i = 0; i < ids.Count; i++)
+ {
+ request.UUIDNameBlock[i] = new UUIDNameRequestPacket.UUIDNameBlockBlock();
+ request.UUIDNameBlock[i].ID = ids[i];
+ }
+
+ Client.Network.SendPacket(request);
+ }
+ else
+ {
+ // not sending request, no ids!
}
- Client.Network.SendPacket(request);
}
///
diff --git a/OpenMetaverse/GroupManager.cs b/OpenMetaverse/GroupManager.cs
index e2f9e72b..1381138f 100644
--- a/OpenMetaverse/GroupManager.cs
+++ b/OpenMetaverse/GroupManager.cs
@@ -239,6 +239,24 @@ namespace OpenMetaverse
}
}
+ ///
+ /// Struct representing a member of a group chat session and their settings
+ ///
+ public struct ChatSessionMember
+ {
+ public UUID AvatarKey;
+ public bool CanVoiceChat;
+ public bool IsModerator;
+ public bool MuteText;
+ public bool MuteVoice;
+
+ public override string ToString()
+ {
+ return String.Format("Avatar={0} CanVoiceChat={1} IsModerator={2} MuteText={3} MuteVoice={4}",
+ AvatarKey, CanVoiceChat, IsModerator, MuteText, MuteVoice);
+ }
+ }
+
#endregion Structs
#region Enums
@@ -260,100 +278,102 @@ namespace OpenMetaverse
/// Group role powers flags
///
[Flags]
- public enum GroupRolePowers : long
+ public enum GroupPowers : long
{
+ ///
None = 0,
+ /// Can send invitations to groups default role
Invite = 1 << 1,
+ /// Can eject members from group
Eject = 1 << 2,
+ /// Can toggle 'Open Enrollment' and change 'Signup fee'
ChangeOptions = 1 << 3,
+ /// Can create new roles
CreateRole = 1 << 4,
+ /// Can delete existing roles
DeleteRole = 1 << 5,
+ /// Can change Role names, titles and descriptions
RoleProperties = 1 << 6,
+ /// Can assign other members to assigners role
AssignMemberLimited = 1 << 7,
+ /// Can assign other members to any role
AssignMember = 1 << 8,
+ /// Can remove members from roles
RemoveMember = 1 << 9,
+ /// Can assign and remove abilities in roles
ChangeActions = 1 << 10,
+ /// Can change group Charter, Insignia, 'Publish on the web' and which
+ /// members are publicly visible in group member listings
ChangeIdentity = 1 << 11,
+ /// Can buy land or deed land to group
LandDeed = 1 << 12,
+ /// Can abandon group owned land to Governor Linden on mainland, or Estate owner for
+ /// private estates
LandRelease = 1 << 13,
+ /// Can set land for-sale information on group owned parcels
LandSetSale = 1 << 14,
- LandDevideJoin = 1 << 15,
+ /// Can subdivide and join parcels
+ LandDivideJoin = 1 << 15,
+ /// Can join group chat sessions
+ JoinChat = 1 << 16,
+ /// Can toggle "Show in Find Places" and set search category
FindPlaces = 1 << 17,
+ /// Can change parcel name, description, and 'Publish on web' settings
LandChangeIdentity = 1 << 18,
+ /// Can set the landing point and teleport routing on group land
SetLandingPoint = 1 << 19,
+ /// Can change music and media settings
ChangeMedia = 1 << 20,
+ /// Can toggle 'Edit Terrain' option in Land settings
LandEdit = 1 << 21,
+ /// Can toggle various About Land > Options settings
LandOptions = 1 << 22,
+ /// Can always terraform land, even if parcel settings have it turned off
AllowEditLand = 1 << 23,
+ /// Can always fly while over group owned land
AllowFly = 1 << 24,
+ /// Can always rez objects on group owned land
AllowRez = 1 << 25,
+ /// Can always create landmarks for group owned parcels
AllowLandmark = 1 << 26,
+ /// Can use voice chat in Group Chat sessions
+ AllowVoiceChat = 1 << 27,
+ /// Can set home location on any group owned parcel
AllowSetHome = 1 << 28,
+ /// Can modify public access settings for group owned parcels
LandManageAllowed = 1 << 29,
+ /// Can manager parcel ban lists on group owned land
LandManageBanned = 1 << 30,
+ /// Can manage pass list sales information
LandManagePasses = 1 << 31,
+ /// Can eject and freeze other avatars on group owned land
LandEjectAndFreeze = 1 << 32,
- ReturnGroupOwned = 1 << 48,
+ /// Can return objects set to group
ReturnGroupSet = 1 << 33,
+ /// Can return non-group owned/set objects
ReturnNonGroup = 1 << 34,
+ /// Can landscape using Linden plants
LandGardening = 1 << 35,
+ /// Can deed objects to group
DeedObject = 1 << 36,
+ /// Can moderate group chat sessions
+ ModerateChat = 1 << 37,
+ /// Can move group owned objects
ObjectManipulate = 1 << 38,
+ /// Can set group owned objects for-sale
ObjectSetForSale = 1 << 39,
+ /// Pay group liabilities and receive group dividends
Accountable = 1 << 40,
+ /// Can send group notices
SendNotices = 1 << 42,
+ /// Can receive group notices
ReceiveNotices = 1 << 43,
+ /// Can create group proposals
StartProposal = 1 << 44,
- VoteOnProposal = 1 << 45
- }
-
- [Flags]
- public enum GroupPowers : ulong
- {
- MemberInvite = 2,
- MemberEject = 4,
- MemberOptions = 8,
- MemberVisibleInDir = 140737488355328,
- RoleCreate = 16,
- RoleDelete = 32,
- RoleProperties = 64,
- RoleAssignMemberLimited = 128,
- RoleAssignMember = 256,
- RoleRemoveMember = 512,
- RoleChangeActions = 1024,
- GroupChangeIdentity = 2048,
- LandDeed = 4096,
- LandRelease = 8192,
- LandSetSaleInfo = 16384,
- LandDivideJoin = 32768,
- LandFindPlaces = 131072,
- LandChangeIdentity = 262144,
- LandSetLandingPoint = 524288,
- LandChangeMedia = 1048576,
- LandEdit = 2097152,
- LandOptions = 4194304,
- LandAllowEditLand = 8388608,
- LandAllowFly = 16777216,
- LandAllowCreate = 33554432,
- LandAllowLandmark = 67108864,
- LandAllowSetHome = 268435456,
- LandManageAllowed = 536870912,
- LandManageBanned = 1073741824,
- LandManagePasses = 2147483648,
- LandAdmin = 4294967296,
- LandReturnGroupOwned = 281474976710656,
- LandReturnGroupSet = 8589934592,
- LandReturnNonGroup = 17179869184,
- LandReturn = LandReturnGroupOwned | LandReturnGroupSet | LandReturnNonGroup,
- LandGardening = 34359738368,
- ObjectDeed = 68719476736,
- ObjectManipulate = 274877906944,
- ObjectSetSale = 549755813888,
- AccountingAccountable = 1099511627776,
- NoticesSend = 4398046511104,
- NoticesReceive = 8796093022208,
- ProposalStart = 17592186044416,
- ProposalVote = 35184372088832
+ /// Can vote on group proposals
+ VoteOnProposal = 1 << 45,
+ /// Can return group owned objects
+ ReturnGroupOwned = 1 << 48
}
#endregion Enums
diff --git a/Programs/examples/TestClient/Commands/Communication/IMGroupCommand.cs b/Programs/examples/TestClient/Commands/Communication/IMGroupCommand.cs
index 58ae71a7..624a6da2 100644
--- a/Programs/examples/TestClient/Commands/Communication/IMGroupCommand.cs
+++ b/Programs/examples/TestClient/Commands/Communication/IMGroupCommand.cs
@@ -33,7 +33,7 @@ namespace OpenMetaverse.TestClient
message = message.TrimEnd();
if (message.Length > 1023) message = message.Remove(1023);
- Client.Self.OnGroupChatJoin += new AgentManager.GroupChatJoined(Self_OnGroupChatJoin);
+ Client.Self.OnGroupChatJoin += new AgentManager.GroupChatJoinedCallback(Self_OnGroupChatJoin);
if (!Client.Self.GroupChatSessions.ContainsKey(ToGroupID))
{
WaitForSessionStart.Reset();
@@ -44,7 +44,7 @@ namespace OpenMetaverse.TestClient
WaitForSessionStart.Set();
}
- if (WaitForSessionStart.WaitOne(10000, false))
+ if (WaitForSessionStart.WaitOne(20000, false))
{
Client.Self.InstantMessageGroup(ToGroupID, message);
}
@@ -53,7 +53,7 @@ namespace OpenMetaverse.TestClient
return "Timeout waiting for group session start";
}
- Client.Self.OnGroupChatJoin -= new AgentManager.GroupChatJoined(Self_OnGroupChatJoin);
+ Client.Self.OnGroupChatJoin -= new AgentManager.GroupChatJoinedCallback(Self_OnGroupChatJoin);
return "Instant Messaged group " + ToGroupID.ToString() + " with message: " + message;
}
else
@@ -62,11 +62,11 @@ namespace OpenMetaverse.TestClient
}
}
- void Self_OnGroupChatJoin(UUID groupChatSessionID, UUID tmpSessionID, bool success)
+ void Self_OnGroupChatJoin(UUID groupChatSessionID, string sessionName, UUID tmpSessionID, bool success)
{
if (success)
{
- Console.WriteLine("Join Group Chat Success!");
+ Console.WriteLine("Joined {0} Group Chat Success!", sessionName);
WaitForSessionStart.Set();
}
else