diff --git a/LibreMetaverse/AgentManager.cs b/LibreMetaverse/AgentManager.cs
index 2c77e8cc..7fa93c2b 100644
--- a/LibreMetaverse/AgentManager.cs
+++ b/LibreMetaverse/AgentManager.cs
@@ -1253,6 +1253,8 @@ namespace OpenMetaverse
}
#endregion Callbacks
+ private const string AGENT_PROFILE_CAP = "AgentProfile";
+
/// Reference to the GridClient instance
private readonly GridClient Client;
/// Used for movement and camera tracking
@@ -1269,7 +1271,7 @@ namespace OpenMetaverse
#region Properties
- /// Your (client) avatars
+ /// Your (client) avatar's
/// "client", "agent", and "avatar" all represent the same thing
public UUID AgentID { get; private set; }
@@ -1491,6 +1493,7 @@ namespace OpenMetaverse
private readonly ManualResetEvent teleportEvent = new ManualResetEvent(false);
private uint heightWidthGenCounter;
private readonly Dictionary gestureCache = new Dictionary();
+
#endregion Private Members
///
@@ -3430,14 +3433,36 @@ namespace OpenMetaverse
#endregion Teleporting
- #region Misc
+ #region Profile
///
/// Update agent profile
///
- /// struct containing updated
+ /// struct containing updated
/// profile information
+ ///
+ /// The behavior between LLUDP and Http Capability differs. See each method's remarks
+ ///
+ ///
+ ///
public void UpdateProfile(Avatar.AvatarProperties profile)
+ {
+ if (Client.Network.CurrentSim.Caps.CapabilityURI(AGENT_PROFILE_CAP) != null)
+ {
+ UpdateProfileHttp(profile);
+ }
+ else
+ {
+ UpdateProfileUdp(profile);
+ }
+ }
+
+ ///
+ /// Update agent profile via simulator LLUDP
+ ///
+ /// struct containing updated
+ /// profile information
+ public void UpdateProfileUdp(Avatar.AvatarProperties profile)
{
AvatarPropertiesUpdatePacket apup = new AvatarPropertiesUpdatePacket
{
@@ -3461,10 +3486,51 @@ namespace OpenMetaverse
Client.Network.SendPacket(apup);
}
+ ///
+ /// Update agent profile
+ ///
+ /// struct containing updated
+ /// profile information
+ ///
+ ///
+ /// Only updates about text fields, profile url, and allow_publish.
+ /// Does not update image UUID, etc. like the legacy LLUDP request.
+ ///
+ public async void UpdateProfileHttp(Avatar.AvatarProperties profile, CancellationToken cancellationToken = default)
+ {
+ var payload = new OSDMap
+ {
+ ["sl_about_text"] = profile.AboutText,
+ ["fl_about_text"] = profile.FirstLifeText,
+ ["profile_url"] = profile.ProfileURL,
+ ["allow_publish"] = profile.AllowPublish,
+ // This next pair may or may not do anything! It would be nice if it did.
+ ["sl_image_id"] = profile.ProfileImage,
+ ["fl_image_id"] = profile.FirstLifeImage
+ };
+
+ var capability = Client.Network.CurrentSim.Caps.CapabilityURI(AGENT_PROFILE_CAP);
+ var uri = new Uri($"{capability}/{AgentID}");
+ await Client.HttpCapsClient.PutRequestAsync(uri, OSDFormat.Xml, payload, cancellationToken,
+ (response, data, error) =>
+ {
+ if (error != null)
+ {
+ Logger.Log($"AgentProfile update failed: {error.Message}", Helpers.LogLevel.Warning);
+ return;
+ }
+
+ if (response.IsSuccessStatusCode)
+ {
+ Logger.Log("AgentProfile update succeeded.", Helpers.LogLevel.Debug);
+ }
+ });
+ }
+
///
/// Update agent's profile interests
///
- /// selection of interests from struct
+ /// selection of interests from struct
public void UpdateInterests(Avatar.Interests interests)
{
AvatarInterestsUpdatePacket aiup = new AvatarInterestsUpdatePacket
@@ -3492,7 +3558,21 @@ namespace OpenMetaverse
///
/// target avatar for notes
/// notes to store
+ ///
+ ///
public void UpdateProfileNotes(UUID target, string notes)
+ {
+ if (Client.Network.CurrentSim.Caps.CapabilityURI(AGENT_PROFILE_CAP) != null)
+ {
+ UpdateProfileNotesHttp(target, notes);
+ }
+ else
+ {
+ UpdateProfileNotesUdp(target, notes);
+ }
+ }
+
+ private void UpdateProfileNotesUdp(UUID target, string notes)
{
AvatarNotesUpdatePacket anup = new AvatarNotesUpdatePacket
{
@@ -3511,32 +3591,36 @@ namespace OpenMetaverse
}
///
- /// Set the height and the width of the client window. This is used
- /// by the server to build a virtual camera frustum for our avatar
+ /// Update agent's private notes for target avatar using HTTP capability system
///
- /// New height of the viewer window
- /// New width of the viewer window
- public void SetHeightWidth(ushort height, ushort width)
+ /// target avatar for notes
+ /// notes to store
+ ///
+ public async void UpdateProfileNotesHttp(UUID target, string notes, CancellationToken cancellationToken = default)
{
- AgentHeightWidthPacket heightwidth = new AgentHeightWidthPacket
- {
- AgentData =
- {
- AgentID = Client.Self.AgentID,
- SessionID = Client.Self.SessionID,
- CircuitCode = Client.Network.CircuitCode
- },
- HeightWidthBlock =
- {
- Height = height,
- Width = width,
- GenCounter = heightWidthGenCounter++
- }
- };
+ var payload = new OSDMap { ["notes"] = notes };
- Client.Network.SendPacket(heightwidth);
+ var capability = Client.Network.CurrentSim.Caps.CapabilityURI(AGENT_PROFILE_CAP);
+ var uri = new Uri($"{capability}/{target}");
+ await Client.HttpCapsClient.PutRequestAsync(uri, OSDFormat.Xml, payload, cancellationToken,
+ (response, data, error) =>
+ {
+ if (error != null)
+ {
+ Logger.Log($"AgentProfile notes update failed: {error.Message}", Helpers.LogLevel.Warning);
+ }
+
+ if (response.IsSuccessStatusCode)
+ {
+ Logger.Log("AgentProfile notes update succeeded.", Helpers.LogLevel.Debug);
+ }
+ });
}
+ #endregion Profile
+
+ #region Mute List
+
///
/// Request the list of muted objects and avatars for this agent
///
@@ -3644,10 +3728,41 @@ namespace OpenMetaverse
}
}
+ #endregion Mute List
+
+ #region Misc
+
+ ///
+ /// Set the height and the width of the client window. This is used
+ /// by the server to build a virtual camera frustum for our avatar
+ ///
+ /// New height of the viewer window
+ /// New width of the viewer window
+ public void SetHeightWidth(ushort height, ushort width)
+ {
+ AgentHeightWidthPacket heightwidth = new AgentHeightWidthPacket
+ {
+ AgentData =
+ {
+ AgentID = Client.Self.AgentID,
+ SessionID = Client.Self.SessionID,
+ CircuitCode = Client.Network.CircuitCode
+ },
+ HeightWidthBlock =
+ {
+ Height = height,
+ Width = width,
+ GenCounter = heightWidthGenCounter++
+ }
+ };
+
+ Client.Network.SendPacket(heightwidth);
+ }
+
///
/// Sets home location to agents current position
///
- /// will fire an AlertMessage () with
+ /// will fire an AlertMessage () with
/// success or failure message
public void SetHome()
{
@@ -3673,7 +3788,7 @@ namespace OpenMetaverse
/// Move an agent in to a simulator. This packet is the last packet
/// needed to complete the transition in to a new simulator
///
- /// Object
+ /// Object
public void CompleteAgentMovement(Simulator simulator)
{
CompleteAgentMovementPacket move = new CompleteAgentMovementPacket
@@ -3693,10 +3808,10 @@ namespace OpenMetaverse
///
/// Reply to script permissions request
///
- /// Object
+ /// Object
/// of the itemID requesting permissions
/// of the taskID requesting permissions
- /// list of permissions to allow
+ /// list of permissions to allow
public void ScriptQuestionReply(Simulator simulator, UUID itemID, UUID taskID, ScriptPermission permissions)
{
ScriptAnswerYesPacket yes = new ScriptAnswerYesPacket