From 6942eaed5b3d8065ebf01dc465e905ca456c0fa4 Mon Sep 17 00:00:00 2001 From: Charles Krinke Date: Mon, 29 Jun 2009 21:47:47 +0000 Subject: Thank you kindly, Snowdrop, for a patch that solves: The current API for MRM is quite sparse, this patch supplies basic support for accessing the task inventory of object. --- .../Scripting/Minimodule/Interfaces/IAvatar.cs | 8 +- .../Minimodule/Interfaces/IInventoryItem.cs | 16 ++ .../Scripting/Minimodule/Interfaces/IObject.cs | 4 + .../Scripting/Minimodule/InventoryItem.cs | 72 ++++++++ .../Minimodule/Object/IObjectInventory.cs | 17 ++ .../Scripting/Minimodule/SOPObject.cs | 7 +- .../Scripting/Minimodule/SOPObjectInventory.cs | 190 +++++++++++++++++++++ .../Scripting/Minimodule/SPAvatar.cs | 8 + 8 files changed, 320 insertions(+), 2 deletions(-) create mode 100644 OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IInventoryItem.cs create mode 100644 OpenSim/Region/OptionalModules/Scripting/Minimodule/InventoryItem.cs create mode 100644 OpenSim/Region/OptionalModules/Scripting/Minimodule/Object/IObjectInventory.cs create mode 100644 OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObjectInventory.cs (limited to 'OpenSim') diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IAvatar.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IAvatar.cs index 51ba36c..3345988 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IAvatar.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IAvatar.cs @@ -50,6 +50,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule //// /// Array of worn attachments, empty but not null, if no attachments are worn /// - IAvatarAttachment[] Attachments { get; } + + IAvatarAttachment[] Attachments { get; } + + /// + /// Request to open an url clientside + /// + void LoadUrl(IObject sender, string message, string url); } } diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IInventoryItem.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IInventoryItem.cs new file mode 100644 index 0000000..7490dda --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IInventoryItem.cs @@ -0,0 +1,16 @@ +using System; +using OpenMetaverse; + +namespace OpenSim.Region.OptionalModules.Scripting.Minimodule +{ + + /// + /// This implements the methods needed to operate on individual inventory items. + /// + public interface IInventoryItem + { + int Type { get; } + UUID AssetID { get; } + T RetreiveAsset() where T : OpenMetaverse.Asset, new(); + } +} diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IObject.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IObject.cs index dd9cc29..1be3b71 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IObject.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IObject.cs @@ -179,6 +179,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule /// The message to send to the user void Say(string msg); + //// + /// Grants access to the objects inventory + /// + IObjectInventory Inventory { get; } } public enum PhysicsMaterial diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/InventoryItem.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/InventoryItem.cs new file mode 100644 index 0000000..512a120 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/InventoryItem.cs @@ -0,0 +1,72 @@ + +using System; +using System.Text; + +using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; +//using OpenSim.Services.AssetService; +using OpenMetaverse; + +namespace OpenSim.Region.OptionalModules.Scripting.Minimodule +{ + + + public class InventoryItem : IInventoryItem + { + TaskInventoryItem m_privateItem; + Scene m_rootSceene; + + public InventoryItem(Scene rootScene, TaskInventoryItem internalItem) + { + m_rootSceene = rootScene; + m_privateItem = internalItem; + } + + // Marked internal, to prevent scripts from accessing the internal type + internal TaskInventoryItem ToTaskInventoryItem() + { + return m_privateItem; + } + + /// + /// This will attempt to convert from an IInventoryItem to an InventoryItem object + /// + /// + /// In order for this to work the object which implements IInventoryItem must inherit from InventoryItem, otherwise + /// an exception is thrown. + /// + /// + /// The interface to upcast + /// + /// + /// The object backing the interface implementation + /// + internal static InventoryItem FromInterface(IInventoryItem i) + { + if(typeof(InventoryItem).IsAssignableFrom(i.GetType())) + { + return (InventoryItem)i; + } + else + { + throw new ApplicationException("[MRM] There is no legal conversion from IInventoryItem to InventoryItem"); + } + } + + public int Type { get { return m_privateItem.Type; } } + public UUID AssetID { get { return m_privateItem.AssetID; } } + + public T RetreiveAsset() where T : OpenMetaverse.Asset, new() + { + AssetBase a = m_rootSceene.AssetService.Get(AssetID.ToString()); + T result = new T(); + + if((sbyte)result.AssetType != a.Type) + throw new ApplicationException("[MRM] The supplied asset class does not match the found asset"); + + result.AssetData = a.Data; + result.Decode(); + return result; + } + } +} diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Object/IObjectInventory.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Object/IObjectInventory.cs new file mode 100644 index 0000000..98ac13d --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Object/IObjectInventory.cs @@ -0,0 +1,17 @@ + +using System; +using System.Collections.Generic; + +using OpenMetaverse; + +namespace OpenSim.Region.OptionalModules.Scripting.Minimodule.Object +{ + + /// + /// This implements the methods neccesary to operate on the inventory of an object + /// + public interface IObjectInventory : IDictionary + { + IInventoryItem this[string name] { get; } + } +} diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs index a40a0d9..689c70e1d 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs @@ -301,7 +301,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule get { return this; } } - #region Public Functions + public IObjectInventory Inventory + { + get { return new SOPObjectInventory(m_rootScene, GetSOP().TaskInventory); } + } + + #region Public Functions public void Say(string msg) { diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObjectInventory.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObjectInventory.cs new file mode 100644 index 0000000..19740bd --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObjectInventory.cs @@ -0,0 +1,190 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; +using OpenMetaverse; + +namespace OpenSim.Region.OptionalModules.Scripting.Minimodule.Object +{ + + + public class SOPObjectInventory : IObjectInventory + { + TaskInventoryDictionary m_privateInventory; /// OpenSim's task inventory + Dictionary m_publicInventory; /// MRM's inventory + Scene m_rootScene; + + public SOPObjectInventory(Scene rootScene, TaskInventoryDictionary taskInventory) + { + m_rootScene = rootScene; + m_privateInventory = taskInventory; + m_publicInventory = new Dictionary(); + } + + /// + /// Fully populate the public dictionary with the contents of the private dictionary + /// + /// + /// This will only convert those items which hasn't already been converted. ensuring that + /// no items are converted twice, and that any references already in use are maintained. + /// + private void SynchronizeDictionaries() + { + foreach(TaskInventoryItem privateItem in m_privateInventory.Values) + if(!m_publicInventory.ContainsKey(privateItem.ItemID)) + m_publicInventory.Add(privateItem.ItemID, new InventoryItem(m_rootScene, privateItem)); + } + + #region IDictionary implementation + public void Add (UUID key, IInventoryItem value) + { + m_publicInventory.Add(key, value); + m_privateInventory.Add(key, InventoryItem.FromInterface(value).ToTaskInventoryItem()); + } + + public bool ContainsKey (UUID key) + { + return m_privateInventory.ContainsKey(key); + } + + public bool Remove (UUID key) + { + m_publicInventory.Remove(key); + return m_privateInventory.Remove(key); + } + + public bool TryGetValue (UUID key, out IInventoryItem value) + { + value = null; + + bool result = false; + if(!m_publicInventory.TryGetValue(key, out value)) + { + // wasn't found in the public inventory + TaskInventoryItem privateItem; + + result = m_privateInventory.TryGetValue(key, out privateItem); + if(result) + { + value = new InventoryItem(m_rootScene, privateItem); + m_publicInventory.Add(key, value); // add item, so we don't convert again + } + } else + return true; + + return result; + } + + public ICollection Keys { + get { + return m_privateInventory.Keys; + } + } + + public ICollection Values { + get { + SynchronizeDictionaries(); + return m_publicInventory.Values; + } + } + #endregion + + #region IEnumerable> implementation + public IEnumerator> GetEnumerator () + { + SynchronizeDictionaries(); + return m_publicInventory.GetEnumerator(); + } + + #endregion + + #region IEnumerable implementation + IEnumerator IEnumerable.GetEnumerator () + { + SynchronizeDictionaries(); + return m_publicInventory.GetEnumerator(); + } + + #endregion + + #region ICollection> implementation + public void Add (KeyValuePair item) + { + Add(item.Key, item.Value); + } + + public void Clear () + { + m_publicInventory.Clear(); + m_privateInventory.Clear(); + } + + public bool Contains (KeyValuePair item) + { + return m_privateInventory.ContainsKey(item.Key); + } + + public void CopyTo (KeyValuePair[] array, int arrayIndex) + { + throw new NotImplementedException(); + } + + public bool Remove (KeyValuePair item) + { + return Remove(item.Key); + } + + public int Count { + get { + return m_privateInventory.Count; + } + } + + public bool IsReadOnly { + get { + return false; + } + } + #endregion + + #region Explicit implementations + IInventoryItem System.Collections.Generic.IDictionary.this[UUID key] + { + get { + IInventoryItem result; + if(TryGetValue(key, out result)) + return result; + else + throw new KeyNotFoundException("[MRM] The requrested item ID could not be found"); + } + set { + m_publicInventory[key] = value; + m_privateInventory[key] = InventoryItem.FromInterface(value).ToTaskInventoryItem(); + } + } + + void System.Collections.Generic.ICollection>.CopyTo(System.Collections.Generic.KeyValuePair[] array, int offset) + { + throw new NotImplementedException(); + } + #endregion + + public IInventoryItem this[string name] + { + get { + foreach(TaskInventoryItem i in m_privateInventory.Values) + if(i.Name == name) + { + if(!m_publicInventory.ContainsKey(i.ItemID)) + m_publicInventory.Add(i.ItemID, new InventoryItem(m_rootScene, i)); + + return m_publicInventory[i.ItemID]; + } + throw new KeyNotFoundException(); + } + } + + } +} diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs index 6fd36bf..a71d1e5 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs @@ -32,6 +32,7 @@ using System.Collections.Generic; using OpenMetaverse; using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Interfaces; using log4net; @@ -90,6 +91,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule return attachments.ToArray(); } } + + public void LoadUrl(IObject sender, string message, string url) + { + IDialogModule dm = m_rootScene.RequestModuleInterface(); + if(dm != null) + dm.SendUrlToUser(GetSP().UUID, sender.Name, sender.GlobalID, GetSP().UUID, false, message, url); + } #endregion } } -- cgit v1.1