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