From dfe5e9d4ebb705d0c20d6260bae5d11659ac904d Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Mon, 7 Apr 2008 01:46:00 +0000 Subject: * EXPERIMENTAL ROUGH DRAFT: First rough implementation of avatar to avatar item giving * Now you can drag an object from your inventory and give it to another avatar * !!! Use at your own risk !!! Many things are unimplemented as of yet, including permissions (the person receiving your item can probably do absolutely everything with it) * Also, items for the receiving end up in their root folder rather than the objects folder --- .../Environment/Modules/InstantMessageModule.cs | 8 +- .../Region/Environment/Modules/InventoryModule.cs | 158 ++++++++++++++++++++- 2 files changed, 163 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/Environment/Modules') diff --git a/OpenSim/Region/Environment/Modules/InstantMessageModule.cs b/OpenSim/Region/Environment/Modules/InstantMessageModule.cs index 53d9fd9..6f7235e 100644 --- a/OpenSim/Region/Environment/Modules/InstantMessageModule.cs +++ b/OpenSim/Region/Environment/Modules/InstantMessageModule.cs @@ -70,13 +70,17 @@ namespace OpenSim.Region.Environment.Modules uint ParentEstateID, LLVector3 Position, LLUUID RegionID, byte[] binaryBucket) { - bool FriendDialog = ((dialog == (byte)38) || (dialog == (byte)39) || (dialog == (byte)40)); + bool dialogHandledElsewhere + = ((dialog == (byte)38) || (dialog == (byte)39) || (dialog == (byte)40) + || dialog == (byte)InstantMessageDialog.InventoryOffered + || dialog == (byte)InstantMessageDialog.InventoryAccepted + || dialog == (byte)InstantMessageDialog.InventoryDeclined); // IM dialogs need to be pre-processed and have their sessionID filled by the server // so the sim can match the transaction on the return packet. // Don't send a Friend Dialog IM with a LLUUID.Zero session. - if (!(FriendDialog && imSessionID == LLUUID.Zero)) + if (!(dialogHandledElsewhere && imSessionID == LLUUID.Zero)) { foreach (Scene scene in m_scenes) { diff --git a/OpenSim/Region/Environment/Modules/InventoryModule.cs b/OpenSim/Region/Environment/Modules/InventoryModule.cs index a0f3832..eadbb4f 100644 --- a/OpenSim/Region/Environment/Modules/InventoryModule.cs +++ b/OpenSim/Region/Environment/Modules/InventoryModule.cs @@ -25,7 +25,13 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; +using System.Collections.Generic; + +using libsecondlife; using Nini.Config; + +using OpenSim.Framework; using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Scenes; @@ -33,11 +39,22 @@ namespace OpenSim.Region.Environment.Modules { public class InventoryModule : IRegionModule { + private static readonly log4net.ILog m_log + = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + private Scene m_scene; + + /// + /// We need to keep track of the pending item offers between clients since the itemId offered only + /// occurs in the initial offer message, not the accept message. So this dictionary links + /// IM Session Ids to ItemIds + /// + private IDictionary m_pendingOffers = new Dictionary(); public void Initialise(Scene scene, IConfigSource config) - { + { m_scene = scene; + scene.EventManager.OnNewClient += OnNewClient; } public void PostInitialise() @@ -57,5 +74,144 @@ namespace OpenSim.Region.Environment.Modules { get { return false; } } + + private void OnNewClient(IClientAPI client) + { + // Inventory giving is conducted via instant message + client.OnInstantMessage += OnInstantMessage; + } + + private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID, + LLUUID fromAgentSession, LLUUID toAgentID, + LLUUID imSessionID, uint timestamp, string fromAgentName, + string message, byte dialog, bool fromGroup, byte offline, + uint ParentEstateID, LLVector3 Position, LLUUID RegionID, + byte[] binaryBucket) + { + if (dialog == (byte)InstantMessageDialog.InventoryOffered) + { + m_log.DebugFormat( + "[AGENT INVENTORY]: Routing inventory offering message from {0}, {1} to {2}", + client.AgentId, client.Name, toAgentID); + + if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence) + { + ScenePresence user = (ScenePresence)m_scene.Entities[toAgentID]; + + if (!user.IsChildAgent) + { + //byte[] rawId = new byte[16]; + + // First byte of the array is probably the item type + // Next 16 bytes are the UUID + //Array.Copy(binaryBucket, 1, rawId, 0, 16); + + //LLUUID itemId = new LLUUID(new Guid(rawId)); + LLUUID itemId = new LLUUID(binaryBucket, 1); + + m_log.DebugFormat( + "[AGENT INVENTORY]: ItemId for giving is {0}", itemId); + + m_pendingOffers[imSessionID] = itemId; + + user.ControllingClient.SendInstantMessage( + fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName, + dialog, timestamp, binaryBucket); + + return; + } + else + { + m_log.WarnFormat( + "[AGENT INVENTORY]: Agent {0} targeted for inventory give by {1}, {2} of {3} was a child agent!", + toAgentID, client.AgentId, client.Name, message); + } + } + else + { + m_log.WarnFormat( + "[AGENT INVENTORY]: Could not find agent {0} for user {1}, {2} to give {3}", + toAgentID, client.AgentId, client.Name, message); + } + } + else if (dialog == (byte)InstantMessageDialog.InventoryAccepted) + { + m_log.DebugFormat( + "[AGENT INVENTORY]: Routing inventory accepted message from {0}, {1} to {2}", + client.AgentId, client.Name, toAgentID); + + if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence) + { + ScenePresence user = (ScenePresence)m_scene.Entities[toAgentID]; + + if (!user.IsChildAgent) + { + user.ControllingClient.SendInstantMessage( + fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName, + dialog, timestamp, binaryBucket); + + if (m_pendingOffers.ContainsKey(imSessionID)) + { + m_log.DebugFormat( + "[AGENT INVENTORY]: Accepted item id {0}", m_pendingOffers[imSessionID]); + + // Since the message originates from the accepting client, the toAgentID is + // the agent giving the item. + m_scene.GiveInventoryItem(client, toAgentID, m_pendingOffers[imSessionID]); + + m_pendingOffers.Remove(imSessionID); + } + else + { + m_log.ErrorFormat( + "[AGENT INVENTORY]: Could not find an item associated with session id {0} to accept", + imSessionID); + } + + return; + } + else + { + m_log.WarnFormat( + "[AGENT INVENTORY]: Agent {0} targeted for inventory give by {1}, {2} of {3} was a child agent!", + toAgentID, client.AgentId, client.Name, message); + } + } + else + { + m_log.WarnFormat( + "[AGENT INVENTORY]: Could not find agent {0} for user {1}, {2} to give {3}", + toAgentID, client.AgentId, client.Name, message); + } + } + else if (dialog == (byte)InstantMessageDialog.InventoryDeclined) + { + if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence) + { + ScenePresence user = (ScenePresence)m_scene.Entities[toAgentID]; + + if (!user.IsChildAgent) + { + user.ControllingClient.SendInstantMessage( + fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName, + dialog, timestamp, binaryBucket); + + if (m_pendingOffers.ContainsKey(imSessionID)) + { + m_log.DebugFormat( + "[AGENT INVENTORY]: Declined item id {0}", m_pendingOffers[imSessionID]); + + m_pendingOffers.Remove(imSessionID); + } + else + { + m_log.ErrorFormat( + "[AGENT INVENTORY]: Could not find an item associated with session id {0} to decline", + imSessionID); + } + } + } + } + } } } -- cgit v1.1