/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. using Aurora.Framework;
  28. using Aurora.Framework.Modules;
  29. using Aurora.Framework.PresenceInfo;
  30. using Aurora.Framework.SceneInfo;
  31. using Aurora.Framework.Services.ClassHelpers.Inventory;
  32. using Nini.Config;
  33. using OpenMetaverse;
  34. using System;
  35. using System.Collections.Generic;
  36. namespace Aurora.Modules.Agent.AssetTransaction
  37. {
  38. public class AssetTransactionModule : INonSharedRegionModule, IAgentAssetTransactions
  39. {
  40. // private static readonly ILog MainConsole.Instance = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  41. /// <summary>
  42. /// Each agent has its own singleton collection of transactions
  43. /// </summary>
  44. private readonly Dictionary<UUID, AgentAssetTransactions> AgentTransactions =
  45. new Dictionary<UUID, AgentAssetTransactions>();
  46. private readonly Dictionary<UUID, IScene> RegisteredScenes = new Dictionary<UUID, IScene>();
  47. private IScene m_scene;
  48. //[Obsolete] //As long as this is being used to get objects that are not region specific, this is fine to use
  49. public IScene MyScene
  50. {
  51. get { return m_scene; }
  52. }
  53. #region INonSharedRegionModule Members
  54. public void Initialise(IConfigSource config)
  55. {
  56. }
  57. public void AddRegion(IScene scene)
  58. {
  59. scene.RegisterModuleInterface<IAgentAssetTransactions>(this);
  60. scene.EventManager.OnNewClient += NewClient;
  61. scene.EventManager.OnClosingClient += OnClosingClient;
  62. scene.EventManager.OnRemovePresence += OnRemovePresence;
  63. m_scene = scene;
  64. }
  65. public void RemoveRegion(IScene scene)
  66. {
  67. scene.UnregisterModuleInterface<IAgentAssetTransactions>(this);
  68. scene.EventManager.OnNewClient -= NewClient;
  69. scene.EventManager.OnClosingClient -= OnClosingClient;
  70. scene.EventManager.OnRemovePresence -= OnRemovePresence;
  71. m_scene = null;
  72. }
  73. public void RegionLoaded(IScene scene)
  74. {
  75. }
  76. public Type ReplaceableInterface
  77. {
  78. get { return null; }
  79. }
  80. public void Close()
  81. {
  82. }
  83. public string Name
  84. {
  85. get { return "AgentTransactionModule"; }
  86. }
  87. #endregion
  88. public void NewClient(IClientAPI client)
  89. {
  90. client.OnAssetUploadRequest += HandleUDPUploadRequest;
  91. client.OnXferReceive += HandleXfer;
  92. }
  93. private void OnClosingClient(IClientAPI client)
  94. {
  95. client.OnAssetUploadRequest -= HandleUDPUploadRequest;
  96. client.OnXferReceive -= HandleXfer;
  97. }
  98. private void OnRemovePresence(IScenePresence SP)
  99. {
  100. if (SP != null && !SP.IsChildAgent)
  101. RemoveAgentAssetTransactions(SP.UUID);
  102. }
  103. #region AgentAssetTransactions
  104. /// <summary>
  105. /// Remove the given agent asset transactions. This should be called when a client is departing
  106. /// from a scene (and hence won't be making any more transactions here).
  107. /// </summary>
  108. /// <param name="userID"></param>
  109. public void RemoveAgentAssetTransactions(UUID userID)
  110. {
  111. // MainConsole.Instance.DebugFormat("Removing agent asset transactions structure for agent {0}", userID);
  112. lock (AgentTransactions)
  113. {
  114. AgentTransactions.Remove(userID);
  115. }
  116. }
  117. /// <summary>
  118. /// Create an inventory item from data that has been received through a transaction.
  119. /// This is called when new clothing or body parts are created. It may also be called in other
  120. /// situations.
  121. /// </summary>
  122. /// <param name="remoteClient"></param>
  123. /// <param name="transactionID"></param>
  124. /// <param name="folderID"></param>
  125. /// <param name="callbackID"></param>
  126. /// <param name="description"></param>
  127. /// <param name="name"></param>
  128. /// <param name="invType"></param>
  129. /// <param name="type"></param>
  130. /// <param name="wearableType"></param>
  131. /// <param name="nextOwnerMask"></param>
  132. public void HandleItemCreationFromTransaction(IClientAPI remoteClient, UUID transactionID, UUID folderID,
  133. uint callbackID, string description, string name, sbyte invType,
  134. sbyte type, byte wearableType, uint nextOwnerMask)
  135. {
  136. // MainConsole.Instance.DebugFormat(
  137. // "[TRANSACTIONS MANAGER] Called HandleItemCreationFromTransaction with item {0}", name);
  138. AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
  139. IMonitorModule monitorModule = m_scene.RequestModuleInterface<IMonitorModule>();
  140. if (monitorModule != null)
  141. {
  142. INetworkMonitor networkMonitor =
  143. (INetworkMonitor)
  144. monitorModule.GetMonitor(m_scene.RegionInfo.RegionID.ToString(), MonitorModuleHelper.NetworkMonitor);
  145. networkMonitor.AddPendingUploads(1);
  146. }
  147. transactions.RequestCreateInventoryItem(
  148. remoteClient, transactionID, folderID, callbackID, description,
  149. name, invType, type, wearableType, nextOwnerMask);
  150. }
  151. /// <summary>
  152. /// Update an inventory item with data that has been received through a transaction.
  153. /// This is called when clothing or body parts are updated (for instance, with new textures or
  154. /// colours). It may also be called in other situations.
  155. /// </summary>
  156. /// <param name="remoteClient"></param>
  157. /// <param name="transactionID"></param>
  158. /// <param name="item"></param>
  159. public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, UUID transactionID,
  160. InventoryItemBase item)
  161. {
  162. // MainConsole.Instance.DebugFormat(
  163. // "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}",
  164. // item.Name);
  165. AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
  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. transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item);
  175. }
  176. /// <summary>
  177. /// Update a task inventory item with data that has been received through a transaction.
  178. /// This is currently called when, for instance, a notecard in a prim is saved. The data is sent
  179. /// up through a single AssetUploadRequest. A subsequent UpdateTaskInventory then references the transaction
  180. /// and comes through this method.
  181. /// </summary>
  182. /// <param name="remoteClient"></param>
  183. /// <param name="part"></param>
  184. /// <param name="transactionID"></param>
  185. /// <param name="item"></param>
  186. public void HandleTaskItemUpdateFromTransaction(
  187. IClientAPI remoteClient, ISceneChildEntity part, UUID transactionID, TaskInventoryItem item)
  188. {
  189. // MainConsole.Instance.DebugFormat(
  190. // "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0}",
  191. // item.Name);
  192. AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
  193. IMonitorModule monitorModule = m_scene.RequestModuleInterface<IMonitorModule>();
  194. if (monitorModule != null)
  195. {
  196. INetworkMonitor networkMonitor =
  197. (INetworkMonitor)
  198. monitorModule.GetMonitor(m_scene.RegionInfo.RegionID.ToString(), MonitorModuleHelper.NetworkMonitor);
  199. networkMonitor.AddPendingUploads(1);
  200. }
  201. transactions.RequestUpdateTaskInventoryItem(remoteClient, part, transactionID, item);
  202. }
  203. /// <summary>
  204. /// Get the collection of asset transactions for the given user. If one does not already exist, it
  205. /// is created.
  206. /// </summary>
  207. /// <param name="userID"></param>
  208. /// <returns></returns>
  209. private AgentAssetTransactions GetUserTransactions(UUID userID)
  210. {
  211. lock (AgentTransactions)
  212. {
  213. if (!AgentTransactions.ContainsKey(userID))
  214. {
  215. AgentAssetTransactions transactions = new AgentAssetTransactions(userID, m_scene, false);
  216. AgentTransactions.Add(userID, transactions);
  217. }
  218. return AgentTransactions[userID];
  219. }
  220. }
  221. /// <summary>
  222. /// Request that a client (agent) begin an asset transfer.
  223. /// </summary>
  224. /// <param name="remoteClient"></param>
  225. /// <param name="assetID"></param>
  226. /// <param name="transaction"></param>
  227. /// <param name="type"></param>
  228. /// <param name="data"></param>
  229. /// <param name="storeLocal"></param>
  230. /// <param name="tempFile"></param>
  231. public void HandleUDPUploadRequest(IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type,
  232. byte[] data, bool storeLocal, bool tempFile)
  233. {
  234. // MainConsole.Instance.Debug("HandleUDPUploadRequest - assetID: " + assetID.ToString() + " transaction: " + transaction.ToString() + " type: " + type.ToString() + " storelocal: " + storeLocal + " tempFile: " + tempFile);
  235. if (((AssetType) type == AssetType.Texture ||
  236. (AssetType) type == AssetType.Sound ||
  237. (AssetType) type == AssetType.TextureTGA ||
  238. (AssetType) type == AssetType.Animation) &&
  239. tempFile == false)
  240. {
  241. IScene scene = remoteClient.Scene;
  242. IMoneyModule mm = scene.RequestModuleInterface<IMoneyModule>();
  243. if (mm != null)
  244. {
  245. if (!mm.Charge(remoteClient, mm.UploadCharge))
  246. {
  247. remoteClient.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
  248. return;
  249. }
  250. }
  251. }
  252. AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
  253. AssetXferUploader uploader = transactions.RequestXferUploader(transaction);
  254. if (uploader != null)
  255. {
  256. uploader.StartUpload(remoteClient, assetID, transaction, type, data, storeLocal, tempFile);
  257. }
  258. }
  259. /// <summary>
  260. /// Handle asset transfer data packets received in response to the asset upload request in
  261. /// HandleUDPUploadRequest()
  262. /// </summary>
  263. /// <param name="remoteClient"></param>
  264. /// <param name="xferID"></param>
  265. /// <param name="packetID"></param>
  266. /// <param name="data"></param>
  267. public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data)
  268. {
  269. //MainConsole.Instance.Debug("xferID: " + xferID + " packetID: " + packetID + " data!");
  270. AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
  271. IMonitorModule monitorModule = m_scene.RequestModuleInterface<IMonitorModule>();
  272. if (monitorModule != null)
  273. {
  274. INetworkMonitor networkMonitor =
  275. (INetworkMonitor)
  276. monitorModule.GetMonitor(m_scene.RegionInfo.RegionID.ToString(), MonitorModuleHelper.NetworkMonitor);
  277. networkMonitor.AddPendingUploads(1);
  278. }
  279. transactions.HandleXfer(remoteClient, xferID, packetID, data);
  280. }
  281. #endregion
  282. }
  283. }