diff --git a/OpenMetaverse/AgentManager.cs b/OpenMetaverse/AgentManager.cs
index d5c1e09e..d5acaa1c 100644
--- a/OpenMetaverse/AgentManager.cs
+++ b/OpenMetaverse/AgentManager.cs
@@ -682,6 +682,15 @@ namespace OpenMetaverse
///
public partial class AgentManager
{
+ #region Delegates
+ ///
+ /// Called once attachment resource usage information has been collected
+ ///
+ /// Indicates if operation was successfull
+ /// Attachment resource usage information
+ public delegate void AttachmentResourcesCallback(bool success, AttachmentResourcesMessage info);
+ #endregion Delegates
+
#region Event Delegates
/// The event subscribers. null if no subcribers
@@ -706,7 +715,7 @@ namespace OpenMetaverse
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;
@@ -729,7 +738,7 @@ namespace OpenMetaverse
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;
@@ -750,7 +759,7 @@ namespace OpenMetaverse
{
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;
@@ -773,7 +782,7 @@ namespace OpenMetaverse
add { lock (m_LoadUrlLock) { m_LoadURL += value; } }
remove { lock (m_LoadUrlLock) { m_LoadURL -= value; } }
}
-
+
/// The event subscribers. null if no subcribers
private EventHandler m_Balance;
@@ -796,7 +805,7 @@ namespace OpenMetaverse
add { lock (m_BalanceLock) { m_Balance += value; } }
remove { lock (m_BalanceLock) { m_Balance -= value; } }
}
-
+
/// The event subscribers. null if no subcribers
private EventHandler m_MoneyBalance;
@@ -819,7 +828,7 @@ namespace OpenMetaverse
add { lock (m_MoneyBalanceReplyLock) { m_MoneyBalance += value; } }
remove { lock (m_MoneyBalanceReplyLock) { m_MoneyBalance -= value; } }
}
-
+
/// The event subscribers. null if no subcribers
private EventHandler m_InstantMessage;
@@ -842,7 +851,7 @@ namespace OpenMetaverse
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;
@@ -865,7 +874,7 @@ namespace OpenMetaverse
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;
@@ -910,7 +919,7 @@ namespace OpenMetaverse
{
add { lock (m_AnimationsChangedLock) { m_AnimationsChanged += value; } }
remove { lock (m_AnimationsChangedLock) { m_AnimationsChanged -= value; } }
- }
+ }
/// The event subscribers. null if no subcribers
private EventHandler m_MeanCollision;
@@ -933,7 +942,7 @@ namespace OpenMetaverse
{
add { lock (m_MeanCollisionLock) { m_MeanCollision += value; } }
remove { lock (m_MeanCollisionLock) { m_MeanCollision -= value; } }
- }
+ }
/// The event subscribers. null if no subcribers
private EventHandler m_RegionCrossed;
@@ -957,7 +966,7 @@ namespace OpenMetaverse
add { lock (m_RegionCrossedLock) { m_RegionCrossed += value; } }
remove { lock (m_RegionCrossedLock) { m_RegionCrossed -= value; } }
}
-
+
/// The event subscribers. null if no subcribers
private EventHandler m_GroupChatJoined;
@@ -979,7 +988,7 @@ namespace OpenMetaverse
{
add { lock (m_GroupChatJoinedLock) { m_GroupChatJoined += value; } }
remove { lock (m_GroupChatJoinedLock) { m_GroupChatJoined -= value; } }
- }
+ }
/// The event subscribers. null if no subcribers
private EventHandler m_GroupChatLeft;
@@ -1002,7 +1011,7 @@ namespace OpenMetaverse
{
add { lock (m_GroupChatLeftLock) { m_GroupChatLeft += value; } }
remove { lock (m_GroupChatLeftLock) { m_GroupChatLeft -= value; } }
- }
+ }
/// The event subscribers. null if no subcribers
private EventHandler m_AlertMessage;
@@ -1026,7 +1035,7 @@ namespace OpenMetaverse
{
add { lock (m_AlertMessageLock) { m_AlertMessage += value; } }
remove { lock (m_AlertMessageLock) { m_AlertMessage -= value; } }
- }
+ }
/// The event subscribers. null if no subcribers
private EventHandler m_ScriptControl;
@@ -1050,7 +1059,7 @@ namespace OpenMetaverse
add { lock (m_ScriptControlLock) { m_ScriptControl += value; } }
remove { lock (m_ScriptControlLock) { m_ScriptControl -= value; } }
}
-
+
/// The event subscribers. null if no subcribers
private EventHandler m_CameraConstraint;
@@ -1074,7 +1083,7 @@ namespace OpenMetaverse
add { lock (m_CameraConstraintLock) { m_CameraConstraint += value; } }
remove { lock (m_CameraConstraintLock) { m_CameraConstraint -= value; } }
}
-
+
/// The event subscribers. null if no subcribers
private EventHandler m_ScriptSensorReply;
@@ -1096,7 +1105,7 @@ namespace OpenMetaverse
{
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;
@@ -1119,7 +1128,7 @@ namespace OpenMetaverse
{
add { lock (m_AvatarSitResponseLock) { m_AvatarSitResponse += value; } }
remove { lock (m_AvatarSitResponseLock) { m_AvatarSitResponse -= value; } }
- }
+ }
/// The event subscribers. null if no subcribers
private EventHandler m_ChatSessionMemberAdded;
@@ -1142,7 +1151,7 @@ namespace OpenMetaverse
{
add { lock (m_ChatSessionMemberAddedLock) { m_ChatSessionMemberAdded += value; } }
remove { lock (m_ChatSessionMemberAddedLock) { m_ChatSessionMemberAdded -= value; } }
- }
+ }
/// The event subscribers. null if no subcribers
private EventHandler m_ChatSessionMemberLeft;
@@ -1365,7 +1374,7 @@ namespace OpenMetaverse
Client = client;
Movement = new AgentMovement(Client);
-
+
Client.Network.Disconnected += Network_OnDisconnected;
// Teleport callbacks
@@ -2705,7 +2714,7 @@ namespace OpenMetaverse
if (e.Simulator == Client.Network.CurrentSim)
queueEvent.Set();
};
-
+
Client.Network.EventQueueRunning += queueCallback;
queueEvent.WaitOne(10 * 1000, false);
Client.Network.EventQueueRunning -= queueCallback;
@@ -3114,6 +3123,46 @@ namespace OpenMetaverse
classified.Data.ClassifiedID = classifiedID;
Client.Network.SendPacket(classified);
}
+
+ ///
+ /// Fetches resource usage by agents attachmetns
+ ///
+ /// Called when the requested information is collected
+ public void GetAttachmentResources(AttachmentResourcesCallback callback)
+ {
+ try
+ {
+ Uri url = Client.Network.CurrentSim.Caps.CapabilityURI("AttachmentResources");
+ CapsClient request = new CapsClient(url);
+
+ request.OnComplete += delegate(CapsClient client, OSD result, Exception error)
+ {
+ try
+ {
+ if (result == null || error != null)
+ {
+ callback(false, null);
+ }
+ AttachmentResourcesMessage info = AttachmentResourcesMessage.FromOSD(result);
+ callback(true, info);
+
+ }
+ catch (Exception ex)
+ {
+ Logger.Log("Failed fetching AttachmentResources", Helpers.LogLevel.Error, Client, ex);
+ callback(false, null);
+ }
+ };
+
+ request.BeginGetResponse(Client.Settings.CAPS_TIMEOUT);
+ }
+ catch (Exception ex)
+ {
+ Logger.Log("Failed fetching AttachmentResources", Helpers.LogLevel.Error, Client, ex);
+ callback(false, null);
+ }
+ }
+
#endregion Misc
#region Packet Handlers
@@ -3166,7 +3215,7 @@ namespace OpenMetaverse
if (m_Chat != null)
{
Packet packet = e.Packet;
-
+
ChatFromSimulatorPacket chat = (ChatFromSimulatorPacket)packet;
OnChat(new ChatEventArgs(e.Simulator, Utils.BytesToString(chat.ChatData.Message),
@@ -3190,7 +3239,7 @@ namespace OpenMetaverse
if (m_ScriptDialog != null)
{
Packet packet = e.Packet;
-
+
ScriptDialogPacket dialog = (ScriptDialogPacket)packet;
List buttons = new List();
@@ -3243,13 +3292,13 @@ namespace OpenMetaverse
if (m_ScriptControl != null)
{
Packet packet = e.Packet;
-
+
ScriptControlChangePacket change = (ScriptControlChangePacket)packet;
for (int i = 0; i < change.Data.Length; i++)
{
OnScriptControlChange(new ScriptControlEventArgs((ScriptControlChange)change.Data[i].Controls,
change.Data[i].PassToAgent,
- change.Data[i].TakeControls));
+ change.Data[i].TakeControls));
}
}
}
@@ -3261,13 +3310,13 @@ namespace OpenMetaverse
/// The EventArgs object containing the packet data
protected void LoadURLHandler(object sender, PacketReceivedEventArgs e)
{
-
+
if (m_LoadURL != null)
{
Packet packet = e.Packet;
LoadURLPacket loadURL = (LoadURLPacket)packet;
-
+
OnLoadURL(new LoadUrlEventArgs(
Utils.BytesToString(loadURL.Data.ObjectName),
loadURL.Data.ObjectID,
@@ -3303,7 +3352,7 @@ namespace OpenMetaverse
/// The EventArgs object containing the packet data
protected void HealthHandler(object sender, PacketReceivedEventArgs e)
{
- Packet packet = e.Packet;
+ Packet packet = e.Packet;
health = ((HealthMessagePacket)packet).HealthData.Health;
}
@@ -3345,7 +3394,7 @@ namespace OpenMetaverse
protected void MoneyBalanceReplyHandler(object sender, PacketReceivedEventArgs e)
{
Packet packet = e.Packet;
-
+
if (packet.Type == PacketType.MoneyBalanceReply)
{
MoneyBalanceReplyPacket reply = (MoneyBalanceReplyPacket)packet;
@@ -3443,7 +3492,7 @@ namespace OpenMetaverse
{
Packet packet = e.Packet;
Simulator simulator = e.Simulator;
-
+
bool finished = false;
TeleportFlags flags = TeleportFlags.Default;
@@ -3670,7 +3719,7 @@ namespace OpenMetaverse
if (m_RegionCrossed != null)
{
- OnRegionCrossed(new RegionCrossedEventArgs(oldSim, newSim));
+ OnRegionCrossed(new RegionCrossedEventArgs(oldSim, newSim));
}
}
else
@@ -3745,7 +3794,7 @@ namespace OpenMetaverse
{
ChatterBoxSessionStartReplyMessage msg = (ChatterBoxSessionStartReplyMessage)message;
- OnGroupChatJoined(new GroupChatJoinedEventArgs(msg.SessionID, msg.SessionName, msg.TempSessionID, msg.Success));
+ OnGroupChatJoined(new GroupChatJoinedEventArgs(msg.SessionID, msg.SessionName, msg.TempSessionID, msg.Success));
}
}
@@ -3805,7 +3854,7 @@ namespace OpenMetaverse
if (msg.Updates[i].AgentID == Client.Self.AgentID)
{
- OnGroupChatLeft(new GroupChatLeftEventArgs(msg.SessionID));
+ OnGroupChatLeft(new GroupChatLeftEventArgs(msg.SessionID));
}
}
}
@@ -3914,10 +3963,10 @@ namespace OpenMetaverse
if (m_AlertMessage != null)
{
Packet packet = e.Packet;
-
+
AlertMessagePacket alert = (AlertMessagePacket)packet;
- OnAlertMessage(new AlertMessageEventArgs(Utils.BytesToString(alert.AlertData.Message)));
+ OnAlertMessage(new AlertMessageEventArgs(Utils.BytesToString(alert.AlertData.Message)));
}
}
@@ -3929,7 +3978,7 @@ namespace OpenMetaverse
if (m_CameraConstraint != null)
{
Packet packet = e.Packet;
-
+
CameraConstraintPacket camera = (CameraConstraintPacket)packet;
OnCameraConstraint(new CameraConstraintEventArgs(camera.CameraCollidePlane.Plane));
}
@@ -3943,7 +3992,7 @@ namespace OpenMetaverse
if (m_ScriptSensorReply != null)
{
Packet packet = e.Packet;
-
+
ScriptSensorReplyPacket reply = (ScriptSensorReplyPacket)packet;
for (int i = 0; i < reply.SensedData.Length; i++)
@@ -3952,7 +4001,7 @@ namespace OpenMetaverse
ScriptSensorReplyPacket.RequesterBlock requestor = reply.Requester;
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));
+ block.ObjectID, block.OwnerID, block.Position, block.Range, block.Rotation, (ScriptSensorTypeFlags)block.Type, block.Velocity));
}
}
@@ -3966,12 +4015,12 @@ namespace OpenMetaverse
if (m_AvatarSitResponse != null)
{
Packet packet = e.Packet;
-
+
AvatarSitResponsePacket sit = (AvatarSitResponsePacket)packet;
OnAvatarSitResponse(new AvatarSitResponseEventArgs(sit.SitObject.ID, sit.SitTransform.AutoPilot, sit.SitTransform.CameraAtOffset,
sit.SitTransform.CameraEyeOffset, sit.SitTransform.ForceMouselook, sit.SitTransform.SitPosition,
- sit.SitTransform.SitRotation));
+ sit.SitTransform.SitRotation));
}
}
@@ -3979,7 +4028,7 @@ namespace OpenMetaverse
}
#region Event Argument Classes
-
+
///
///
///
@@ -4334,7 +4383,7 @@ namespace OpenMetaverse
this.m_GroupName = groupName;
}
}
-
+
/// Data sent by the simulator to indicate the active/changed animations
/// applied to your agent
public class AnimationsChangedEventArgs : EventArgs
@@ -4415,7 +4464,7 @@ namespace OpenMetaverse
public RegionCrossedEventArgs(Simulator oldSim, Simulator newSim)
{
this.m_OldSimulator = oldSim;
- this.m_NewSimulator = newSim;
+ this.m_NewSimulator = newSim;
}
}
@@ -4451,7 +4500,7 @@ namespace OpenMetaverse
this.m_Success = success;
}
}
-
+
/// The session information when your agent exits a group chat session
public class GroupChatLeftEventArgs : EventArgs
{
@@ -4535,7 +4584,7 @@ namespace OpenMetaverse
m_CollidePlane = collidePlane;
}
}
-
+
///
/// Data containing script sensor requests which allow an agent to know the specific details
/// of a primitive sending script sensor requests
@@ -4603,10 +4652,10 @@ namespace OpenMetaverse
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;
diff --git a/OpenMetaverse/Messages/LindenMessages.cs b/OpenMetaverse/Messages/LindenMessages.cs
index 6fbb747e..aae4034f 100644
--- a/OpenMetaverse/Messages/LindenMessages.cs
+++ b/OpenMetaverse/Messages/LindenMessages.cs
@@ -3976,4 +3976,333 @@ namespace OpenMetaverse.Messages.Linden
}
}
#endregion Object Media Messages
+
+ #region Resource usage
+ /// Details about object resource usage
+ public class ObjectResourcesDetail
+ {
+ /// Object UUID
+ public UUID ID;
+ /// Object name
+ public string Name;
+ /// Indicates if object is group owned
+ public bool GroupOwned;
+ /// Locatio of the object
+ public Vector3d Location;
+ /// Object owner
+ public UUID OwnerID;
+ /// Resource usage, keys are resource names, values are resource usage for that specific resource
+ public Dictionary Resources;
+
+ ///
+ /// Deserializes object from OSD
+ ///
+ /// An containing the data
+ public virtual void Deserialize(OSDMap obj)
+ {
+ ID = obj["id"].AsUUID();
+ Name = obj["name"].AsString();
+ Location = obj["location"].AsVector3d();
+ GroupOwned = obj["is_group_owned"].AsBoolean();
+ OwnerID = obj["owner_id"].AsUUID();
+ OSDMap resources = (OSDMap)obj["resources"];
+ Resources = new Dictionary(resources.Keys.Count);
+ foreach (KeyValuePair kvp in resources)
+ {
+ Resources.Add(kvp.Key, kvp.Value.AsInteger());
+ }
+ }
+
+ ///
+ /// Makes an instance based on deserialized data
+ ///
+ /// serialized data
+ /// Instance containg deserialized data
+ public static ObjectResourcesDetail FromOSD(OSD osd)
+ {
+ ObjectResourcesDetail res = new ObjectResourcesDetail();
+ res.Deserialize((OSDMap)osd);
+ return res;
+ }
+ }
+
+ /// Details about parcel resource usage
+ public class ParcelResourcesDetail
+ {
+ /// Parcel UUID
+ public UUID ID;
+ /// Parcel local ID
+ public int LocalID;
+ /// Parcel name
+ public string Name;
+ /// Indicates if parcel is group owned
+ public bool GroupOwned;
+ /// Parcel owner
+ public UUID OwnerID;
+ /// Array of containing per object resource usage
+ public ObjectResourcesDetail[] Objects;
+
+ ///
+ /// Deserializes object from OSD
+ ///
+ /// An containing the data
+ public virtual void Deserialize(OSDMap map)
+ {
+ ID = map["id"].AsUUID();
+ LocalID = map["local_id"].AsInteger();
+ Name = map["name"].AsString();
+ GroupOwned = map["is_group_owned"].AsBoolean();
+ OwnerID = map["owner_id"].AsUUID();
+
+ OSDArray objectsOSD = (OSDArray)map["objects"];
+ Objects = new ObjectResourcesDetail[objectsOSD.Count];
+
+ for (int i = 0; i < objectsOSD.Count; i++)
+ {
+ Objects[i] = ObjectResourcesDetail.FromOSD(objectsOSD[i]);
+ }
+ }
+
+ ///
+ /// Makes an instance based on deserialized data
+ ///
+ /// serialized data
+ /// Instance containg deserialized data
+ public static ParcelResourcesDetail FromOSD(OSD osd)
+ {
+ ParcelResourcesDetail res = new ParcelResourcesDetail();
+ res.Deserialize((OSDMap)osd);
+ return res;
+ }
+ }
+
+ /// Resource usage base class, both agent and parcel resource
+ /// usage contains summary information
+ public abstract class BaseResourcesInfo : IMessage
+ {
+ /// Summary of available resources, keys are resource names,
+ /// values are resource usage for that specific resource
+ public Dictionary SummaryAvailable;
+ /// Summary resource usage, keys are resource names,
+ /// values are resource usage for that specific resource
+ public Dictionary SummaryUsed;
+
+ ///
+ /// Serializes object
+ ///
+ /// serialized data
+ public virtual OSDMap Serialize()
+ {
+ throw new NotImplementedException();
+ }
+
+ ///
+ /// Deserializes object from OSD
+ ///
+ /// An containing the data
+ public virtual void Deserialize(OSDMap map)
+ {
+ SummaryAvailable = new Dictionary();
+ SummaryUsed = new Dictionary();
+
+ OSDMap summary = (OSDMap)map["summary"];
+ OSDArray available = (OSDArray)summary["available"];
+ OSDArray used = (OSDArray)summary["used"];
+
+ for (int i = 0; i < available.Count; i++)
+ {
+ OSDMap limit = (OSDMap)available[i];
+ SummaryAvailable.Add(limit["type"].AsString(), limit["amount"].AsInteger());
+ }
+
+ for (int i = 0; i < used.Count; i++)
+ {
+ OSDMap limit = (OSDMap)used[i];
+ SummaryUsed.Add(limit["type"].AsString(), limit["amount"].AsInteger());
+ }
+ }
+ }
+
+ /// Agent resource usage
+ public class AttachmentResourcesMessage : BaseResourcesInfo
+ {
+ /// Per attachment point object resource usage
+ public Dictionary Attachments;
+
+ ///
+ /// Deserializes object from OSD
+ ///
+ /// An containing the data
+ public override void Deserialize(OSDMap osd)
+ {
+ base.Deserialize(osd);
+ OSDArray attachments = (OSDArray)((OSDMap)osd)["attachments"];
+ Attachments = new Dictionary();
+
+ for (int i = 0; i < attachments.Count; i++)
+ {
+ OSDMap attachment = (OSDMap)attachments[i];
+ AttachmentPoint pt = Utils.StringToAttachmentPoint(attachment["location"].AsString());
+
+ OSDArray objectsOSD = (OSDArray)attachment["objects"];
+ ObjectResourcesDetail[] objects = new ObjectResourcesDetail[objectsOSD.Count];
+
+ for (int j = 0; j < objects.Length; j++)
+ {
+ objects[j] = ObjectResourcesDetail.FromOSD(objectsOSD[j]);
+ }
+
+ Attachments.Add(pt, objects);
+ }
+ }
+
+ ///
+ /// Makes an instance based on deserialized data
+ ///
+ /// serialized data
+ /// Instance containg deserialized data
+ public static AttachmentResourcesMessage FromOSD(OSD osd)
+ {
+ AttachmentResourcesMessage res = new AttachmentResourcesMessage();
+ res.Deserialize((OSDMap)osd);
+ return res;
+ }
+
+ ///
+ /// Detects which class handles deserialization of this message
+ ///
+ /// An containing the data
+ /// Object capable of decoding this message
+ public static IMessage GetMessageHandler(OSDMap map)
+ {
+ if (map == null)
+ {
+ return null;
+ }
+ else
+ {
+ return new AttachmentResourcesMessage();
+ }
+ }
+ }
+
+ /// Request message for parcel resource usage
+ public class LandResourcesRequest : IMessage
+ {
+ /// UUID of the parel to request resource usage info
+ public UUID ParcelID;
+
+ ///
+ /// Serializes object
+ ///
+ /// serialized data
+ public OSDMap Serialize()
+ {
+ OSDMap map = new OSDMap(1);
+ map["parcel_id"] = OSD.FromUUID(ParcelID);
+ return map;
+ }
+
+ ///
+ /// Deserializes object from OSD
+ ///
+ /// An containing the data
+ public void Deserialize(OSDMap map)
+ {
+ ParcelID = map["parcel_id"].AsUUID();
+ }
+ }
+
+ /// Response message for parcel resource usage
+ public class LandResourcesMessage : IMessage
+ {
+ /// URL where parcel resource usage details can be retrieved
+ public Uri ScriptResourceDetails;
+ /// URL where parcel resource usage summary can be retrieved
+ public Uri ScriptResourceSummary;
+
+ ///
+ /// Serializes object
+ ///
+ /// serialized data
+ public OSDMap Serialize()
+ {
+ OSDMap map = new OSDMap(1);
+ if (ScriptResourceSummary != null)
+ {
+ map["ScriptResourceSummary"] = OSD.FromString(ScriptResourceSummary.ToString());
+ }
+
+ if (ScriptResourceDetails != null)
+ {
+ map["ScriptResourceDetails"] = OSD.FromString(ScriptResourceDetails.ToString());
+ }
+ return map;
+ }
+
+ ///
+ /// Deserializes object from OSD
+ ///
+ /// An containing the data
+ public void Deserialize(OSDMap map)
+ {
+ if (map.ContainsKey("ScriptResourceSummary"))
+ {
+ ScriptResourceSummary = new Uri(map["ScriptResourceSummary"].AsString());
+ }
+ if (map.ContainsKey("ScriptResourceDetails"))
+ {
+ ScriptResourceDetails = new Uri(map["ScriptResourceDetails"].AsString());
+ }
+ }
+
+ ///
+ /// Detects which class handles deserialization of this message
+ ///
+ /// An containing the data
+ /// Object capable of decoding this message
+ public static IMessage GetMessageHandler(OSDMap map)
+ {
+ if (map.ContainsKey("parcel_id"))
+ {
+ return new LandResourcesRequest();
+ }
+ else if (map.ContainsKey("ScriptResourceSummary"))
+ {
+ return new LandResourcesMessage();
+ }
+ return null;
+ }
+ }
+
+ /// Parcel resource usage
+ public class LandResourcesInfo : BaseResourcesInfo
+ {
+ /// Array of containing per percal resource usage
+ public ParcelResourcesDetail[] Parcels;
+
+ ///
+ /// Deserializes object from OSD
+ ///
+ /// An containing the data
+ public override void Deserialize(OSDMap map)
+ {
+ if (map.ContainsKey("summary"))
+ {
+ base.Deserialize(map);
+ }
+ else if (map.ContainsKey("parcels"))
+ {
+ OSDArray parcelsOSD = (OSDArray)map["parcels"];
+ Parcels = new ParcelResourcesDetail[parcelsOSD.Count];
+
+ for (int i = 0; i < parcelsOSD.Count; i++)
+ {
+ Parcels[i] = ParcelResourcesDetail.FromOSD(parcelsOSD[i]);
+ }
+ }
+ }
+ }
+
+ #endregion Resource usage
}
diff --git a/OpenMetaverse/Messages/MessageEventDecoder.cs b/OpenMetaverse/Messages/MessageEventDecoder.cs
index 7dfdb38e..2534919c 100644
--- a/OpenMetaverse/Messages/MessageEventDecoder.cs
+++ b/OpenMetaverse/Messages/MessageEventDecoder.cs
@@ -90,6 +90,8 @@ namespace OpenMetaverse.Messages
case "RegionInfo": message = new RegionInfoMessage(); break;
case "ObjectMediaNavigate": message = new ObjectMediaNavigateMessage(); break;
case "ObjectMedia": message = new ObjectMediaMessage(); break;
+ case "AttachmentResources": message = AttachmentResourcesMessage.GetMessageHandler(map); break;
+ case "LandResources": message = LandResourcesMessage.GetMessageHandler(map); break;
//case "ProductInfoRequest": message = new ProductInfoRequestMessage(); break;
// Capabilities TODO:
diff --git a/OpenMetaverse/ParcelManager.cs b/OpenMetaverse/ParcelManager.cs
index 9a22a447..f7ebc689 100644
--- a/OpenMetaverse/ParcelManager.cs
+++ b/OpenMetaverse/ParcelManager.cs
@@ -775,6 +775,12 @@ namespace OpenMetaverse
#endregion Structs
#region Delegates
+ ///
+ /// Called once parcel resource usage information has been collected
+ ///
+ /// Indicates if operation was successfull
+ /// Parcel resource usage information
+ public delegate void LandResourcesCallback(bool success, LandResourcesInfo info);
/// The event subscribers. null if no subcribers
private EventHandler m_DwellReply;
@@ -1599,6 +1605,64 @@ namespace OpenMetaverse
return UUID.Zero;
}
+
+ ///
+ /// Retrieves information on resources used by the parcel
+ ///
+ /// UUID of the parcel
+ /// Should per object resource usage be requested
+ /// Callback invoked when the request is complete
+ public void GetParcelResouces(UUID parcelID, bool getDetails, LandResourcesCallback callback)
+ {
+ try
+ {
+ Uri url = Client.Network.CurrentSim.Caps.CapabilityURI("LandResources");
+ CapsClient request = new CapsClient(url);
+
+ request.OnComplete += delegate(CapsClient client, OSD result, Exception error)
+ {
+ try
+ {
+ if (result == null || error != null)
+ {
+ callback(false, null);
+ }
+ LandResourcesMessage response = new LandResourcesMessage();
+ response.Deserialize((OSDMap)result);
+
+ CapsClient summaryRequest = new CapsClient(response.ScriptResourceSummary);
+ OSD summaryResponse = summaryRequest.GetResponse(Client.Settings.CAPS_TIMEOUT);
+
+ LandResourcesInfo res = new LandResourcesInfo();
+ res.Deserialize((OSDMap)summaryResponse);
+
+ if (response.ScriptResourceDetails != null && getDetails)
+ {
+ CapsClient detailRequest = new CapsClient(response.ScriptResourceDetails);
+ OSD detailResponse = detailRequest.GetResponse(Client.Settings.CAPS_TIMEOUT);
+ res.Deserialize((OSDMap)detailResponse);
+ }
+ callback(true, res);
+ }
+ catch (Exception ex)
+ {
+ Logger.Log("Failed fetching land resources", Helpers.LogLevel.Error, Client, ex);
+ callback(false, null);
+ }
+ };
+
+ LandResourcesRequest param = new LandResourcesRequest();
+ param.ParcelID = parcelID;
+ request.BeginGetResponse(param.Serialize(), OSDFormat.Xml, Client.Settings.CAPS_TIMEOUT);
+
+ }
+ catch (Exception ex)
+ {
+ Logger.Log("Failed fetching land resources:", Helpers.LogLevel.Error, Client, ex);
+ callback(false, null);
+ }
+ }
+
#endregion Public Methods
#region Packet Handlers