PageRenderTime 36ms CodeModel.GetById 29ms app.highlight 5ms RepoModel.GetById 0ms app.codeStats 1ms

/Aurora/Modules/Agent/AssetTransaction/AssetTransactionModule.cs

https://bitbucket.org/VirtualReality/software-testing
C# | 330 lines | 179 code | 47 blank | 104 comment | 23 complexity | 610fb25f4afec7b649724c68f5359fd9 MD5 | raw file
  1/*
  2 * Copyright (c) Contributors, http://aurora-sim.org/, http://opensimulator.org/
  3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4 *
  5 * Redistribution and use in source and binary forms, with or without
  6 * modification, are permitted provided that the following conditions are met:
  7 *     * Redistributions of source code must retain the above copyright
  8 *       notice, this list of conditions and the following disclaimer.
  9 *     * Redistributions in binary form must reproduce the above copyright
 10 *       notice, this list of conditions and the following disclaimer in the
 11 *       documentation and/or other materials provided with the distribution.
 12 *     * Neither the name of the Aurora-Sim Project nor the
 13 *       names of its contributors may be used to endorse or promote products
 14 *       derived from this software without specific prior written permission.
 15 *
 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 26 */
 27
 28using Aurora.Framework;
 29using Aurora.Framework.Modules;
 30using Aurora.Framework.PresenceInfo;
 31using Aurora.Framework.SceneInfo;
 32using Aurora.Framework.Services.ClassHelpers.Inventory;
 33using Nini.Config;
 34using OpenMetaverse;
 35using System;
 36using System.Collections.Generic;
 37
 38namespace Aurora.Modules.Agent.AssetTransaction
 39{
 40    public class AssetTransactionModule : INonSharedRegionModule, IAgentAssetTransactions
 41    {
 42//        private static readonly ILog MainConsole.Instance = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 43
 44        /// <summary>
 45        ///     Each agent has its own singleton collection of transactions
 46        /// </summary>
 47        private readonly Dictionary<UUID, AgentAssetTransactions> AgentTransactions =
 48            new Dictionary<UUID, AgentAssetTransactions>();
 49
 50        private readonly Dictionary<UUID, IScene> RegisteredScenes = new Dictionary<UUID, IScene>();
 51        private IScene m_scene;
 52
 53        //[Obsolete] //As long as this is being used to get objects that are not region specific, this is fine to use
 54        public IScene MyScene
 55        {
 56            get { return m_scene; }
 57        }
 58
 59        #region INonSharedRegionModule Members
 60
 61        public void Initialise(IConfigSource config)
 62        {
 63        }
 64
 65        public void AddRegion(IScene scene)
 66        {
 67            scene.RegisterModuleInterface<IAgentAssetTransactions>(this);
 68
 69            scene.EventManager.OnNewClient += NewClient;
 70            scene.EventManager.OnClosingClient += OnClosingClient;
 71            scene.EventManager.OnRemovePresence += OnRemovePresence;
 72
 73            m_scene = scene;
 74        }
 75
 76        public void RemoveRegion(IScene scene)
 77        {
 78            scene.UnregisterModuleInterface<IAgentAssetTransactions>(this);
 79
 80            scene.EventManager.OnNewClient -= NewClient;
 81            scene.EventManager.OnClosingClient -= OnClosingClient;
 82            scene.EventManager.OnRemovePresence -= OnRemovePresence;
 83
 84            m_scene = null;
 85        }
 86
 87        public void RegionLoaded(IScene scene)
 88        {
 89        }
 90
 91        public Type ReplaceableInterface
 92        {
 93            get { return null; }
 94        }
 95
 96        public void Close()
 97        {
 98        }
 99
100        public string Name
101        {
102            get { return "AgentTransactionModule"; }
103        }
104
105        #endregion
106
107        public void NewClient(IClientAPI client)
108        {
109            client.OnAssetUploadRequest += HandleUDPUploadRequest;
110            client.OnXferReceive += HandleXfer;
111        }
112
113        private void OnClosingClient(IClientAPI client)
114        {
115            client.OnAssetUploadRequest -= HandleUDPUploadRequest;
116            client.OnXferReceive -= HandleXfer;
117        }
118
119        private void OnRemovePresence(IScenePresence SP)
120        {
121            if (SP != null && !SP.IsChildAgent)
122                RemoveAgentAssetTransactions(SP.UUID);
123        }
124
125        #region AgentAssetTransactions
126
127        /// <summary>
128        ///     Remove the given agent asset transactions.  This should be called when a client is departing
129        ///     from a scene (and hence won't be making any more transactions here).
130        /// </summary>
131        /// <param name="userID"></param>
132        public void RemoveAgentAssetTransactions(UUID userID)
133        {
134            // MainConsole.Instance.DebugFormat("Removing agent asset transactions structure for agent {0}", userID);
135
136            lock (AgentTransactions)
137            {
138                AgentTransactions.Remove(userID);
139            }
140        }
141
142        /// <summary>
143        ///     Create an inventory item from data that has been received through a transaction.
144        ///     This is called when new clothing or body parts are created.  It may also be called in other
145        ///     situations.
146        /// </summary>
147        /// <param name="remoteClient"></param>
148        /// <param name="transactionID"></param>
149        /// <param name="folderID"></param>
150        /// <param name="callbackID"></param>
151        /// <param name="description"></param>
152        /// <param name="name"></param>
153        /// <param name="invType"></param>
154        /// <param name="type"></param>
155        /// <param name="wearableType"></param>
156        /// <param name="nextOwnerMask"></param>
157        public void HandleItemCreationFromTransaction(IClientAPI remoteClient, UUID transactionID, UUID folderID,
158                                                      uint callbackID, string description, string name, sbyte invType,
159                                                      sbyte type, byte wearableType, uint nextOwnerMask)
160        {
161            //            MainConsole.Instance.DebugFormat(
162            //                "[TRANSACTIONS MANAGER] Called HandleItemCreationFromTransaction with item {0}", name);
163
164            AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
165
166            IMonitorModule monitorModule = m_scene.RequestModuleInterface<IMonitorModule>();
167            if (monitorModule != null)
168            {
169                INetworkMonitor networkMonitor =
170                    (INetworkMonitor)
171                    monitorModule.GetMonitor(m_scene.RegionInfo.RegionID.ToString(), MonitorModuleHelper.NetworkMonitor);
172                networkMonitor.AddPendingUploads(1);
173            }
174
175            transactions.RequestCreateInventoryItem(
176                remoteClient, transactionID, folderID, callbackID, description,
177                name, invType, type, wearableType, nextOwnerMask);
178        }
179
180        /// <summary>
181        ///     Update an inventory item with data that has been received through a transaction.
182        ///     This is called when clothing or body parts are updated (for instance, with new textures or
183        ///     colours).  It may also be called in other situations.
184        /// </summary>
185        /// <param name="remoteClient"></param>
186        /// <param name="transactionID"></param>
187        /// <param name="item"></param>
188        public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, UUID transactionID,
189                                                    InventoryItemBase item)
190        {
191            //            MainConsole.Instance.DebugFormat(
192            //                "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}",
193            //                item.Name);
194
195            AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
196
197            IMonitorModule monitorModule = m_scene.RequestModuleInterface<IMonitorModule>();
198            if (monitorModule != null)
199            {
200                INetworkMonitor networkMonitor =
201                    (INetworkMonitor)
202                    monitorModule.GetMonitor(m_scene.RegionInfo.RegionID.ToString(), MonitorModuleHelper.NetworkMonitor);
203                networkMonitor.AddPendingUploads(1);
204            }
205
206            transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item);
207        }
208
209        /// <summary>
210        ///     Update a task inventory item with data that has been received through a transaction.
211        ///     This is currently called when, for instance, a notecard in a prim is saved.  The data is sent
212        ///     up through a single AssetUploadRequest.  A subsequent UpdateTaskInventory then references the transaction
213        ///     and comes through this method.
214        /// </summary>
215        /// <param name="remoteClient"></param>
216        /// <param name="part"></param>
217        /// <param name="transactionID"></param>
218        /// <param name="item"></param>
219        public void HandleTaskItemUpdateFromTransaction(
220            IClientAPI remoteClient, ISceneChildEntity part, UUID transactionID, TaskInventoryItem item)
221        {
222            //            MainConsole.Instance.DebugFormat(
223            //                "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0}",
224            //                item.Name);
225
226            AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
227
228            IMonitorModule monitorModule = m_scene.RequestModuleInterface<IMonitorModule>();
229            if (monitorModule != null)
230            {
231                INetworkMonitor networkMonitor =
232                    (INetworkMonitor)
233                    monitorModule.GetMonitor(m_scene.RegionInfo.RegionID.ToString(), MonitorModuleHelper.NetworkMonitor);
234                networkMonitor.AddPendingUploads(1);
235            }
236
237            transactions.RequestUpdateTaskInventoryItem(remoteClient, part, transactionID, item);
238        }
239
240        /// <summary>
241        ///     Get the collection of asset transactions for the given user.  If one does not already exist, it
242        ///     is created.
243        /// </summary>
244        /// <param name="userID"></param>
245        /// <returns></returns>
246        private AgentAssetTransactions GetUserTransactions(UUID userID)
247        {
248            lock (AgentTransactions)
249            {
250                if (!AgentTransactions.ContainsKey(userID))
251                {
252                    AgentAssetTransactions transactions = new AgentAssetTransactions(userID, m_scene, false);
253                    AgentTransactions.Add(userID, transactions);
254                }
255
256                return AgentTransactions[userID];
257            }
258        }
259
260        /// <summary>
261        ///     Request that a client (agent) begin an asset transfer.
262        /// </summary>
263        /// <param name="remoteClient"></param>
264        /// <param name="assetID"></param>
265        /// <param name="transaction"></param>
266        /// <param name="type"></param>
267        /// <param name="data"></param>
268        /// <param name="storeLocal"></param>
269        /// <param name="tempFile"></param>
270        public void HandleUDPUploadRequest(IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type,
271                                           byte[] data, bool storeLocal, bool tempFile)
272        {
273//            MainConsole.Instance.Debug("HandleUDPUploadRequest - assetID: " + assetID.ToString() + " transaction: " + transaction.ToString() + " type: " + type.ToString() + " storelocal: " + storeLocal + " tempFile: " + tempFile);
274
275            if (((AssetType) type == AssetType.Texture ||
276                 (AssetType) type == AssetType.Sound ||
277                 (AssetType) type == AssetType.TextureTGA ||
278                 (AssetType) type == AssetType.Animation) &&
279                tempFile == false)
280            {
281                IScene scene = remoteClient.Scene;
282                IMoneyModule mm = scene.RequestModuleInterface<IMoneyModule>();
283
284                if (mm != null)
285                {
286                    if (!mm.Charge(remoteClient, mm.UploadCharge))
287                    {
288                        remoteClient.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
289                        return;
290                    }
291                }
292            }
293
294            AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
295
296            AssetXferUploader uploader = transactions.RequestXferUploader(transaction);
297            if (uploader != null)
298            {
299                uploader.StartUpload(remoteClient, assetID, transaction, type, data, storeLocal, tempFile);
300            }
301        }
302
303        /// <summary>
304        ///     Handle asset transfer data packets received in response to the asset upload request in
305        ///     HandleUDPUploadRequest()
306        /// </summary>
307        /// <param name="remoteClient"></param>
308        /// <param name="xferID"></param>
309        /// <param name="packetID"></param>
310        /// <param name="data"></param>
311        public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data)
312        {
313            //MainConsole.Instance.Debug("xferID: " + xferID + "  packetID: " + packetID + "  data!");
314            AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
315
316            IMonitorModule monitorModule = m_scene.RequestModuleInterface<IMonitorModule>();
317            if (monitorModule != null)
318            {
319                INetworkMonitor networkMonitor =
320                    (INetworkMonitor)
321                    monitorModule.GetMonitor(m_scene.RegionInfo.RegionID.ToString(), MonitorModuleHelper.NetworkMonitor);
322                networkMonitor.AddPendingUploads(1);
323            }
324
325            transactions.HandleXfer(remoteClient, xferID, packetID, data);
326        }
327
328        #endregion
329    }
330}