Caps.cs 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959
  1. /*
  2. * Copyright (c) Contributors, 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 OpenSim 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 System;
  28. using System.Collections;
  29. using System.Collections.Generic;
  30. using System.IO;
  31. using libsecondlife;
  32. using OpenSim.Framework;
  33. using OpenSim.Framework.Communications.Cache;
  34. using OpenSim.Framework.Console;
  35. using OpenSim.Framework.Servers;
  36. namespace OpenSim.Region.Capabilities
  37. {
  38. public delegate void UpLoadedAsset(
  39. string assetName, string description, LLUUID assetID, LLUUID inventoryItem, LLUUID parentFolder,
  40. byte[] data, string inventoryType, string assetType);
  41. public delegate LLUUID UpdateItem(LLUUID itemID, byte[] data);
  42. public delegate void UpdateTaskScript(LLUUID itemID, LLUUID primID, bool isScriptRunning, byte[] data);
  43. public delegate void NewInventoryItem(LLUUID userID, InventoryItemBase item);
  44. public delegate LLUUID ItemUpdatedCallback(LLUUID userID, LLUUID itemID, byte[] data);
  45. public delegate void TaskScriptUpdatedCallback(LLUUID userID, LLUUID itemID, LLUUID primID,
  46. bool isScriptRunning, byte[] data);
  47. public delegate List<InventoryItemBase> FetchInventoryDescendentsCAPS(LLUUID agentID, LLUUID folderID, LLUUID ownerID,
  48. bool fetchFolders, bool fetchItems, int sortOrder);
  49. public class Caps
  50. {
  51. private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
  52. private string m_httpListenerHostName;
  53. private uint m_httpListenPort;
  54. /// <summary>
  55. /// This is the uuid portion of every CAPS path. It is used to make capability urls private to the requester.
  56. /// </summary>
  57. private string m_capsObjectPath;
  58. public string CapsObjectPath { get { return m_capsObjectPath; } }
  59. private static readonly string m_requestPath = "0000/";
  60. private static readonly string m_mapLayerPath = "0001/";
  61. private static readonly string m_newInventory = "0002/";
  62. //private static readonly string m_requestTexture = "0003/";
  63. private static readonly string m_notecardUpdatePath = "0004/";
  64. private static readonly string m_notecardTaskUpdatePath = "0005/";
  65. private static readonly string m_fetchInventoryPath = "0006/";
  66. private static readonly string m_parcelVoiceInfoRequestPath = "0007/";
  67. private static readonly string m_provisionVoiceAccountRequestPath = "0008/";
  68. //private string eventQueue = "0100/";
  69. private BaseHttpServer m_httpListener;
  70. private LLUUID m_agentID;
  71. private AssetCache m_assetCache;
  72. private int m_eventQueueCount = 1;
  73. private Queue<string> m_capsEventQueue = new Queue<string>();
  74. private bool m_dumpAssetsToFile;
  75. // These are callbacks which will be setup by the scene so that we can update scene data when we
  76. // receive capability calls
  77. public NewInventoryItem AddNewInventoryItem = null;
  78. public ItemUpdatedCallback ItemUpdatedCall = null;
  79. public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null;
  80. //
  81. public FetchInventoryDescendentsCAPS CAPSFetchInventoryDescendents = null;
  82. public Caps(AssetCache assetCache, BaseHttpServer httpServer, string httpListen, uint httpPort, string capsPath,
  83. LLUUID agent, bool dumpAssetsToFile)
  84. {
  85. m_assetCache = assetCache;
  86. m_capsObjectPath = capsPath;
  87. m_httpListener = httpServer;
  88. m_httpListenerHostName = httpListen;
  89. m_httpListenPort = httpPort;
  90. m_agentID = agent;
  91. m_dumpAssetsToFile = dumpAssetsToFile;
  92. }
  93. /// <summary>
  94. /// Register all CAPS http service handlers
  95. /// </summary>
  96. public void RegisterHandlers()
  97. {
  98. DeregisterHandlers();
  99. string capsBase = "/CAPS/" + m_capsObjectPath;
  100. try
  101. {
  102. m_httpListener.AddStreamHandler(
  103. new LLSDStreamhandler<LLSDMapRequest, LLSDMapLayerResponse>("POST", capsBase + m_mapLayerPath, GetMapLayer));
  104. m_httpListener.AddStreamHandler(
  105. new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>("POST",
  106. capsBase + m_newInventory,
  107. NewAgentInventoryRequest));
  108. // m_httpListener.AddStreamHandler(
  109. // new LLSDStreamhandler<LLSDFetchInventoryDescendents, LLSDInventoryDescendents>("POST",
  110. // capsBase + m_fetchInventory,
  111. // FetchInventory));
  112. AddLegacyCapsHandler(m_httpListener, m_requestPath, CapsRequest);
  113. //AddLegacyCapsHandler(m_httpListener, m_requestTexture , RequestTexture);
  114. AddLegacyCapsHandler(m_httpListener, m_parcelVoiceInfoRequestPath, ParcelVoiceInfoRequest);
  115. AddLegacyCapsHandler(m_httpListener, m_provisionVoiceAccountRequestPath, ProvisionVoiceAccountRequest);
  116. AddLegacyCapsHandler(m_httpListener, m_notecardUpdatePath, NoteCardAgentInventory);
  117. AddLegacyCapsHandler(m_httpListener, m_notecardTaskUpdatePath, ScriptTaskInventory);
  118. AddLegacyCapsHandler(m_httpListener, m_fetchInventoryPath, FetchInventoryRequest);
  119. }
  120. catch (Exception e)
  121. {
  122. m_log.Error("[CAPS]: " + e.ToString());
  123. }
  124. }
  125. /// <summary>
  126. /// Remove all CAPS service handlers.
  127. ///
  128. /// FIXME: Would be much nicer to remove and all paths to a single list. However, this is a little awkward
  129. /// than it could be as we set up some handlers differently (legacy and non-legacy)
  130. /// </summary>
  131. /// <param name="httpListener"></param>
  132. /// <param name="path"></param>
  133. /// <param name="restMethod"></param>
  134. public void DeregisterHandlers()
  135. {
  136. string capsBase = "/CAPS/" + m_capsObjectPath;
  137. m_httpListener.RemoveStreamHandler("POST", capsBase + m_mapLayerPath);
  138. m_httpListener.RemoveStreamHandler("POST", capsBase + m_newInventory);
  139. m_httpListener.RemoveStreamHandler("POST", capsBase + m_requestPath);
  140. m_httpListener.RemoveStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath);
  141. m_httpListener.RemoveStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath);
  142. m_httpListener.RemoveStreamHandler("POST", capsBase + m_notecardUpdatePath);
  143. m_httpListener.RemoveStreamHandler("POST", capsBase + m_notecardTaskUpdatePath);
  144. m_httpListener.RemoveStreamHandler("POST", capsBase + m_fetchInventoryPath);
  145. }
  146. //[Obsolete("Use BaseHttpServer.AddStreamHandler(new LLSDStreamHandler( LLSDMethod delegate )) instead.")]
  147. //Commented out the obsolete as at this time the first caps request can not use the new Caps method
  148. //as the sent type is a array and not a map and the deserialising doesn't deal properly with arrays.
  149. private void AddLegacyCapsHandler(BaseHttpServer httpListener, string path, RestMethod restMethod)
  150. {
  151. string capsBase = "/CAPS/" + m_capsObjectPath;
  152. httpListener.AddStreamHandler(new RestStreamHandler("POST", capsBase + path, restMethod));
  153. }
  154. /// <summary>
  155. /// Construct a client response detailing all the capabilities this server can provide.
  156. /// </summary>
  157. /// <param name="request"></param>
  158. /// <param name="path"></param>
  159. /// <param name="param"></param>
  160. /// <returns></returns>
  161. public string CapsRequest(string request, string path, string param)
  162. {
  163. //Console.WriteLine("caps request " + request);
  164. string result = LLSDHelpers.SerialiseLLSDReply(GetCapabilities());
  165. return result;
  166. }
  167. /// <summary>
  168. /// Return an LLSDCapsDetails listing all the capabilities this server can provide
  169. /// </summary>
  170. /// <returns></returns>
  171. protected LLSDCapsDetails GetCapabilities()
  172. {
  173. LLSDCapsDetails caps = new LLSDCapsDetails();
  174. string capsBaseUrl = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + "/CAPS/" +
  175. m_capsObjectPath;
  176. caps.MapLayer = capsBaseUrl + m_mapLayerPath;
  177. // caps.RequestTextureDownload = capsBaseUrl + m_requestTexture;
  178. caps.NewFileAgentInventory = capsBaseUrl + m_newInventory;
  179. caps.UpdateNotecardAgentInventory = capsBaseUrl + m_notecardUpdatePath;
  180. caps.UpdateScriptAgentInventory = capsBaseUrl + m_notecardUpdatePath;
  181. caps.UpdateScriptTaskInventory = capsBaseUrl + m_notecardTaskUpdatePath;
  182. caps.FetchInventoryDescendents = capsBaseUrl + m_fetchInventoryPath;
  183. caps.ParcelVoiceInfoRequest = capsBaseUrl + m_parcelVoiceInfoRequestPath;
  184. caps.ProvisionVoiceAccountRequest = capsBaseUrl + m_provisionVoiceAccountRequestPath;
  185. return caps;
  186. }
  187. public string FetchInventoryRequest(string request, string path, string param)
  188. {
  189. request = request.Replace("<llsd><map><key>folders</key><array>", "<llsd>");
  190. request = request.Replace("</map></array></map>", "</map>");
  191. //Console.WriteLine("inventory request " + request);
  192. Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Helpers.StringToField(request));
  193. LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
  194. LLSDHelpers.DeserialiseLLSDMap(hash, llsdRequest);
  195. LLSDInventoryDescendents reply = FetchInventory(llsdRequest);
  196. string response = LLSDHelpers.SerialiseLLSDReply(reply);
  197. return response;
  198. }
  199. private LLSDInventoryDescendents FetchInventory(LLSDFetchInventoryDescendents invFetch)
  200. {
  201. LLSDInventoryDescendents reply = new LLSDInventoryDescendents();
  202. LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents();
  203. contents.agent___id = m_agentID;
  204. contents.owner___id = invFetch.owner_id;
  205. contents.folder___id = invFetch.folder_id;
  206. contents.version = 1; //FixMe
  207. contents.descendents = 0;
  208. reply.folders.Array.Add(contents);
  209. List<InventoryItemBase> itemList = null;
  210. if (CAPSFetchInventoryDescendents != null)
  211. {
  212. itemList = CAPSFetchInventoryDescendents(m_agentID, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order);
  213. }
  214. if (itemList != null)
  215. {
  216. foreach (InventoryItemBase invItem in itemList)
  217. {
  218. contents.items.Array.Add(ConvertInventoryItem(invItem));
  219. }
  220. }
  221. contents.descendents = contents.items.Array.Count;
  222. return reply;
  223. }
  224. private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem)
  225. {
  226. LLSDInventoryItem llsdItem = new LLSDInventoryItem();
  227. llsdItem.asset_id = invItem.assetID;
  228. llsdItem.created_at = 1000;
  229. llsdItem.desc = invItem.inventoryDescription;
  230. llsdItem.flags = 0;
  231. llsdItem.item_id = invItem.inventoryID;
  232. llsdItem.name = invItem.inventoryName;
  233. llsdItem.parent_id = invItem.parentFolderID;
  234. llsdItem.type = Enum.GetName(typeof(AssetType), invItem.assetType).ToLower();
  235. llsdItem.inv_type = Enum.GetName(typeof(InventoryType), invItem.invType).ToLower();
  236. llsdItem.permissions = new LLSDPermissions();
  237. llsdItem.permissions.creator_id = invItem.creatorsID;
  238. llsdItem.permissions.base_mask = (int)invItem.inventoryBasePermissions;
  239. llsdItem.permissions.everyone_mask = (int)invItem.inventoryEveryOnePermissions;
  240. llsdItem.permissions.group_id = LLUUID.Zero;
  241. llsdItem.permissions.group_mask = 0;
  242. llsdItem.permissions.is_owner_group = false;
  243. llsdItem.permissions.next_owner_mask = (int)invItem.inventoryNextPermissions;
  244. llsdItem.permissions.owner_id = m_agentID; // FixMe
  245. llsdItem.permissions.owner_mask = (int)invItem.inventoryCurrentPermissions;
  246. llsdItem.sale_info = new LLSDSaleInfo();
  247. llsdItem.sale_info.sale_price = 10;
  248. llsdItem.sale_info.sale_type = "not";
  249. return llsdItem;
  250. }
  251. /// <summary>
  252. ///
  253. /// </summary>
  254. /// <param name="mapReq"></param>
  255. /// <returns></returns>
  256. public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq)
  257. {
  258. LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
  259. mapResponse.LayerData.Array.Add(GetLLSDMapLayerResponse());
  260. return mapResponse;
  261. }
  262. /// <summary>
  263. ///
  264. /// </summary>
  265. /// <returns></returns>
  266. protected LLSDMapLayer GetLLSDMapLayerResponse()
  267. {
  268. LLSDMapLayer mapLayer = new LLSDMapLayer();
  269. mapLayer.Right = 5000;
  270. mapLayer.Top = 5000;
  271. mapLayer.ImageID = new LLUUID("00000000-0000-1111-9999-000000000006");
  272. return mapLayer;
  273. }
  274. /// <summary>
  275. ///
  276. /// </summary>
  277. /// <param name="request"></param>
  278. /// <param name="path"></param>
  279. /// <param name="param"></param>
  280. /// <returns></returns>
  281. public string RequestTexture(string request, string path, string param)
  282. {
  283. Console.WriteLine("texture request " + request);
  284. // Needs implementing (added to remove compiler warning)
  285. return String.Empty;
  286. }
  287. #region EventQueue (Currently not enabled)
  288. /// <summary>
  289. ///
  290. /// </summary>
  291. /// <param name="request"></param>
  292. /// <param name="path"></param>
  293. /// <param name="param"></param>
  294. /// <returns></returns>
  295. public string ProcessEventQueue(string request, string path, string param)
  296. {
  297. string res = String.Empty;
  298. if (m_capsEventQueue.Count > 0)
  299. {
  300. lock (m_capsEventQueue)
  301. {
  302. string item = m_capsEventQueue.Dequeue();
  303. res = item;
  304. }
  305. }
  306. else
  307. {
  308. res = CreateEmptyEventResponse();
  309. }
  310. return res;
  311. }
  312. /// <summary>
  313. ///
  314. /// </summary>
  315. /// <param name="caps"></param>
  316. /// <param name="ipAddressPort"></param>
  317. /// <returns></returns>
  318. public string CreateEstablishAgentComms(string caps, string ipAddressPort)
  319. {
  320. LLSDCapEvent eventItem = new LLSDCapEvent();
  321. eventItem.id = m_eventQueueCount;
  322. //should be creating a EstablishAgentComms item, but there isn't a class for it yet
  323. eventItem.events.Array.Add(new LLSDEmpty());
  324. string res = LLSDHelpers.SerialiseLLSDReply(eventItem);
  325. m_eventQueueCount++;
  326. m_capsEventQueue.Enqueue(res);
  327. return res;
  328. }
  329. /// <summary>
  330. ///
  331. /// </summary>
  332. /// <returns></returns>
  333. public string CreateEmptyEventResponse()
  334. {
  335. LLSDCapEvent eventItem = new LLSDCapEvent();
  336. eventItem.id = m_eventQueueCount;
  337. eventItem.events.Array.Add(new LLSDEmpty());
  338. string res = LLSDHelpers.SerialiseLLSDReply(eventItem);
  339. m_eventQueueCount++;
  340. return res;
  341. }
  342. #endregion
  343. /// <summary>
  344. /// Called by the script task update handler. Provides a URL to which the client can upload a new asset.
  345. /// </summary>
  346. /// <param name="request"></param>
  347. /// <param name="path"></param>
  348. /// <param name="param"></param>
  349. /// <returns></returns>
  350. public string ScriptTaskInventory(string request, string path, string param)
  351. {
  352. try
  353. {
  354. // m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param);
  355. Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(Helpers.StringToField(request));
  356. LLSDTaskScriptUpdate llsdUpdateRequest = new LLSDTaskScriptUpdate();
  357. LLSDHelpers.DeserialiseLLSDMap(hash, llsdUpdateRequest);
  358. string capsBase = "/CAPS/" + m_capsObjectPath;
  359. string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
  360. TaskInventoryScriptUpdater uploader =
  361. new TaskInventoryScriptUpdater(
  362. llsdUpdateRequest.item_id,
  363. llsdUpdateRequest.task_id,
  364. llsdUpdateRequest.is_script_running,
  365. capsBase + uploaderPath,
  366. m_httpListener,
  367. m_dumpAssetsToFile);
  368. uploader.OnUpLoad += TaskScriptUpdated;
  369. m_httpListener.AddStreamHandler(
  370. new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
  371. string uploaderURL = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase +
  372. uploaderPath;
  373. LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
  374. uploadResponse.uploader = uploaderURL;
  375. uploadResponse.state = "upload";
  376. // m_log.InfoFormat("[CAPS]: " +
  377. // "ScriptTaskInventory response: {0}",
  378. // LLSDHelpers.SerialiseLLSDReply(uploadResponse)));
  379. return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
  380. }
  381. catch (Exception e)
  382. {
  383. m_log.Error("[CAPS]: " + e.ToString());
  384. }
  385. return null;
  386. }
  387. public string ParcelVoiceInfoRequest(string request, string path, string param)
  388. {
  389. try
  390. {
  391. m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param);
  392. //Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Helpers.StringToField(request));
  393. //LLSDTaskScriptUpdate llsdUpdateRequest = new LLSDTaskScriptUpdate();
  394. //LLSDHelpers.DeserialiseLLSDMap(hash, llsdUpdateRequest);
  395. //string capsBase = "/CAPS/" + m_capsObjectPath;
  396. //string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
  397. //TaskInventoryScriptUpdater uploader =
  398. //new TaskInventoryScriptUpdater(
  399. //llsdUpdateRequest.item_id,
  400. //llsdUpdateRequest.task_id,
  401. //llsdUpdateRequest.is_script_running,
  402. //capsBase + uploaderPath,
  403. //m_httpListener,
  404. //m_dumpAssetsToFile);
  405. //uploader.OnUpLoad += TaskScriptUpdated;
  406. //m_httpListener.AddStreamHandler(
  407. //new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
  408. //string uploaderURL = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase +
  409. //uploaderPath;
  410. //LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
  411. //uploadResponse.uploader = uploaderURL;
  412. //uploadResponse.state = "upload";
  413. // m_log.InfoFormat("[CAPS]: " +
  414. // "ScriptTaskInventory response: {0}",
  415. // LLSDHelpers.SerialiseLLSDReply(uploadResponse)));
  416. return LLSDHelpers.SerialiseLLSDReply("<llsd><map><key>parcel_local_id</key><integer>16</integer><key>region_name</key><string>Teravus Test</string><key>voice_credentials</key><map><key>channel_uri</key><string>sip:[email protected]\nsip:[email protected]</string></map></map></llsd>");
  417. }
  418. catch (Exception e)
  419. {
  420. m_log.Error("[CAPS]: " + e.ToString());
  421. }
  422. return null;
  423. }
  424. public string ProvisionVoiceAccountRequest(string request, string path, string param)
  425. {
  426. try
  427. {
  428. m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param);
  429. //Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Helpers.StringToField(request));
  430. //LLSDTaskScriptUpdate llsdUpdateRequest = new LLSDTaskScriptUpdate();
  431. //LLSDHelpers.DeserialiseLLSDMap(hash, llsdUpdateRequest);
  432. //string capsBase = "/CAPS/" + m_capsObjectPath;
  433. //string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
  434. //TaskInventoryScriptUpdater uploader =
  435. //new TaskInventoryScriptUpdater(
  436. //llsdUpdateRequest.item_id,
  437. //llsdUpdateRequest.task_id,
  438. //llsdUpdateRequest.is_script_running,
  439. //capsBase + uploaderPath,
  440. //m_httpListener,
  441. //m_dumpAssetsToFile);
  442. //uploader.OnUpLoad += TaskScriptUpdated;
  443. //m_httpListener.AddStreamHandler(
  444. //new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
  445. //string uploaderURL = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase +
  446. //uploaderPath;
  447. //LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
  448. //uploadResponse.uploader = uploaderURL;
  449. //uploadResponse.state = "upload";
  450. // m_log.InfoFormat("[CAPS]: " +
  451. // "ScriptTaskInventory response: {0}",
  452. // LLSDHelpers.SerialiseLLSDReply(uploadResponse)));
  453. return LLSDHelpers.SerialiseLLSDReply("<llsd><map><key>events</key><array><map><key>body</key><map><key>major_version</key><integer>1</integer><key>minor_version</key><integer>0</integer><key>region_name</key><string>Teravus Test</string></map><key>message</key><string>RequiredVoiceVersion</string></map></array><key>id</key><integer>152477222</integer></map></llsd>");
  454. }
  455. catch (Exception e)
  456. {
  457. m_log.Error("[CAPS]: " + e.ToString());
  458. }
  459. return null;
  460. }
  461. /// <summary>
  462. /// Called by the notecard update handler. Provides a URL to which the client can upload a new asset.
  463. /// </summary>
  464. /// <param name="request"></param>
  465. /// <param name="path"></param>
  466. /// <param name="param"></param>
  467. /// <returns></returns>
  468. public string NoteCardAgentInventory(string request, string path, string param)
  469. {
  470. //libsecondlife.StructuredData.LLSDMap hash = (libsecondlife.StructuredData.LLSDMap)libsecondlife.StructuredData.LLSDParser.DeserializeBinary(Helpers.StringToField(request));
  471. Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(Helpers.StringToField(request));
  472. LLSDItemUpdate llsdRequest = new LLSDItemUpdate();
  473. LLSDHelpers.DeserialiseLLSDMap(hash, llsdRequest);
  474. string capsBase = "/CAPS/" + m_capsObjectPath;
  475. string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
  476. ItemUpdater uploader =
  477. new ItemUpdater(llsdRequest.item_id, capsBase + uploaderPath, m_httpListener, m_dumpAssetsToFile);
  478. uploader.OnUpLoad += ItemUpdated;
  479. m_httpListener.AddStreamHandler(
  480. new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
  481. string uploaderURL = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase +
  482. uploaderPath;
  483. LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
  484. uploadResponse.uploader = uploaderURL;
  485. uploadResponse.state = "upload";
  486. // m_log.InfoFormat("[CAPS]: " +
  487. // "NoteCardAgentInventory response: {0}",
  488. // LLSDHelpers.SerialiseLLSDReply(uploadResponse)));
  489. return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
  490. }
  491. /// <summary>
  492. ///
  493. /// </summary>
  494. /// <param name="llsdRequest"></param>
  495. /// <returns></returns>
  496. public LLSDAssetUploadResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest)
  497. {
  498. //Console.WriteLine("asset upload request via CAPS" + llsdRequest.inventory_type +" , "+ llsdRequest.asset_type);
  499. string assetName = llsdRequest.name;
  500. string assetDes = llsdRequest.description;
  501. string capsBase = "/CAPS/" + m_capsObjectPath;
  502. LLUUID newAsset = LLUUID.Random();
  503. LLUUID newInvItem = LLUUID.Random();
  504. LLUUID parentFolder = llsdRequest.folder_id;
  505. string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
  506. AssetUploader uploader =
  507. new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
  508. llsdRequest.asset_type, capsBase + uploaderPath, m_httpListener, m_dumpAssetsToFile);
  509. m_httpListener.AddStreamHandler(
  510. new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
  511. string uploaderURL = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase +
  512. uploaderPath;
  513. LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
  514. uploadResponse.uploader = uploaderURL;
  515. uploadResponse.state = "upload";
  516. uploader.OnUpLoad += UploadCompleteHandler;
  517. return uploadResponse;
  518. }
  519. /// <summary>
  520. ///
  521. /// </summary>
  522. /// <param name="assetID"></param>
  523. /// <param name="inventoryItem"></param>
  524. /// <param name="data"></param>
  525. public void UploadCompleteHandler(string assetName, string assetDescription, LLUUID assetID,
  526. LLUUID inventoryItem, LLUUID parentFolder, byte[] data, string inventoryType,
  527. string assetType)
  528. {
  529. sbyte assType = 0;
  530. sbyte inType = 0;
  531. if (inventoryType == "sound")
  532. {
  533. inType = 1;
  534. assType = 1;
  535. }
  536. else if (inventoryType == "animation")
  537. {
  538. inType = 19;
  539. assType = 20;
  540. }
  541. AssetBase asset;
  542. asset = new AssetBase();
  543. asset.FullID = assetID;
  544. asset.Type = assType;
  545. asset.InvType = inType;
  546. asset.Name = assetName;
  547. asset.Data = data;
  548. m_assetCache.AddAsset(asset);
  549. InventoryItemBase item = new InventoryItemBase();
  550. item.avatarID = m_agentID;
  551. item.creatorsID = m_agentID;
  552. item.inventoryID = inventoryItem;
  553. item.assetID = asset.FullID;
  554. item.inventoryDescription = assetDescription;
  555. item.inventoryName = assetName;
  556. item.assetType = assType;
  557. item.invType = inType;
  558. item.parentFolderID = parentFolder;
  559. item.inventoryCurrentPermissions = 2147483647;
  560. item.inventoryNextPermissions = 2147483647;
  561. if (AddNewInventoryItem != null)
  562. {
  563. AddNewInventoryItem(m_agentID, item);
  564. }
  565. }
  566. /// <summary>
  567. /// Called when new asset data for an agent inventory item update has been uploaded.
  568. /// </summary>
  569. /// <param name="itemID">Item to update</param>
  570. /// <param name="data">New asset data</param>
  571. /// <returns></returns>
  572. public LLUUID ItemUpdated(LLUUID itemID, byte[] data)
  573. {
  574. if (ItemUpdatedCall != null)
  575. {
  576. return ItemUpdatedCall(m_agentID, itemID, data);
  577. }
  578. return LLUUID.Zero;
  579. }
  580. /// <summary>
  581. /// Called when new asset data for an agent inventory item update has been uploaded.
  582. /// </summary>
  583. /// <param name="itemID">Item to update</param>
  584. /// <param name="primID">Prim containing item to update</param>
  585. /// <param name="isScriptRunning">Signals whether the script to update is currently running</param>
  586. /// <param name="data">New asset data</param>
  587. public void TaskScriptUpdated(LLUUID itemID, LLUUID primID, bool isScriptRunning, byte[] data)
  588. {
  589. if (TaskScriptUpdatedCall != null)
  590. {
  591. TaskScriptUpdatedCall(m_agentID, itemID, primID, isScriptRunning, data);
  592. }
  593. }
  594. public class AssetUploader
  595. {
  596. public event UpLoadedAsset OnUpLoad;
  597. private UpLoadedAsset handlerUpLoad = null;
  598. private string uploaderPath = String.Empty;
  599. private LLUUID newAssetID;
  600. private LLUUID inventoryItemID;
  601. private LLUUID parentFolder;
  602. private BaseHttpServer httpListener;
  603. private bool m_dumpAssetsToFile;
  604. private string m_assetName = String.Empty;
  605. private string m_assetDes = String.Empty;
  606. private string m_invType = String.Empty;
  607. private string m_assetType = String.Empty;
  608. public AssetUploader(string assetName, string description, LLUUID assetID, LLUUID inventoryItem,
  609. LLUUID parentFolderID, string invType, string assetType, string path,
  610. BaseHttpServer httpServer, bool dumpAssetsToFile)
  611. {
  612. m_assetName = assetName;
  613. m_assetDes = description;
  614. newAssetID = assetID;
  615. inventoryItemID = inventoryItem;
  616. uploaderPath = path;
  617. httpListener = httpServer;
  618. parentFolder = parentFolderID;
  619. m_assetType = assetType;
  620. m_invType = invType;
  621. m_dumpAssetsToFile = dumpAssetsToFile;
  622. }
  623. /// <summary>
  624. ///
  625. /// </summary>
  626. /// <param name="data"></param>
  627. /// <param name="path"></param>
  628. /// <param name="param"></param>
  629. /// <returns></returns>
  630. public string uploaderCaps(byte[] data, string path, string param)
  631. {
  632. LLUUID inv = inventoryItemID;
  633. string res = String.Empty;
  634. LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
  635. uploadComplete.new_asset = newAssetID.ToString();
  636. uploadComplete.new_inventory_item = inv;
  637. uploadComplete.state = "complete";
  638. res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
  639. httpListener.RemoveStreamHandler("POST", uploaderPath);
  640. if (m_dumpAssetsToFile)
  641. {
  642. SaveAssetToFile(m_assetName + ".jp2", data);
  643. }
  644. handlerUpLoad = OnUpLoad;
  645. if (handlerUpLoad != null)
  646. {
  647. handlerUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType);
  648. }
  649. return res;
  650. }
  651. ///Left this in and commented in case there are unforseen issues
  652. //private void SaveAssetToFile(string filename, byte[] data)
  653. //{
  654. // FileStream fs = File.Create(filename);
  655. // BinaryWriter bw = new BinaryWriter(fs);
  656. // bw.Write(data);
  657. // bw.Close();
  658. // fs.Close();
  659. //}
  660. private void SaveAssetToFile(string filename, byte[] data)
  661. {
  662. string assetPath = "UserAssets";
  663. if (!Directory.Exists(assetPath))
  664. {
  665. Directory.CreateDirectory(assetPath);
  666. }
  667. FileStream fs = File.Create(Path.Combine(assetPath, Util.safeFileName(filename)));
  668. BinaryWriter bw = new BinaryWriter(fs);
  669. bw.Write(data);
  670. bw.Close();
  671. fs.Close();
  672. }
  673. }
  674. /// <summary>
  675. /// This class is a callback invoked when a client sends asset data to
  676. /// an agent inventory notecard update url
  677. /// </summary>
  678. public class ItemUpdater
  679. {
  680. public event UpdateItem OnUpLoad;
  681. private UpdateItem handlerUpdateItem = null;
  682. private string uploaderPath = String.Empty;
  683. private LLUUID inventoryItemID;
  684. private BaseHttpServer httpListener;
  685. private bool m_dumpAssetToFile;
  686. public ItemUpdater(LLUUID inventoryItem, string path, BaseHttpServer httpServer, bool dumpAssetToFile)
  687. {
  688. m_dumpAssetToFile = dumpAssetToFile;
  689. inventoryItemID = inventoryItem;
  690. uploaderPath = path;
  691. httpListener = httpServer;
  692. }
  693. /// <summary>
  694. ///
  695. /// </summary>
  696. /// <param name="data"></param>
  697. /// <param name="path"></param>
  698. /// <param name="param"></param>
  699. /// <returns></returns>
  700. public string uploaderCaps(byte[] data, string path, string param)
  701. {
  702. LLUUID inv = inventoryItemID;
  703. string res = String.Empty;
  704. LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
  705. LLUUID assetID = LLUUID.Zero;
  706. handlerUpdateItem = OnUpLoad;
  707. if (handlerUpdateItem != null)
  708. {
  709. assetID = handlerUpdateItem(inv, data);
  710. }
  711. uploadComplete.new_asset = assetID.ToString();
  712. uploadComplete.new_inventory_item = inv;
  713. uploadComplete.state = "complete";
  714. res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
  715. httpListener.RemoveStreamHandler("POST", uploaderPath);
  716. if (m_dumpAssetToFile)
  717. {
  718. SaveAssetToFile("updateditem" + Util.RandomClass.Next(1, 1000) + ".dat", data);
  719. }
  720. return res;
  721. }
  722. ///Left this in and commented in case there are unforseen issues
  723. //private void SaveAssetToFile(string filename, byte[] data)
  724. //{
  725. // FileStream fs = File.Create(filename);
  726. // BinaryWriter bw = new BinaryWriter(fs);
  727. // bw.Write(data);
  728. // bw.Close();
  729. // fs.Close();
  730. //}
  731. private void SaveAssetToFile(string filename, byte[] data)
  732. {
  733. string assetPath = "UserAssets";
  734. if (!Directory.Exists(assetPath))
  735. {
  736. Directory.CreateDirectory(assetPath);
  737. }
  738. FileStream fs = File.Create(Path.Combine(assetPath, filename));
  739. BinaryWriter bw = new BinaryWriter(fs);
  740. bw.Write(data);
  741. bw.Close();
  742. fs.Close();
  743. }
  744. }
  745. /// <summary>
  746. /// This class is a callback invoked when a client sends asset data to
  747. /// a task inventory script update url
  748. /// </summary>
  749. public class TaskInventoryScriptUpdater
  750. {
  751. public event UpdateTaskScript OnUpLoad;
  752. private UpdateTaskScript handlerUpdateTaskScript = null;
  753. private string uploaderPath = String.Empty;
  754. private LLUUID inventoryItemID;
  755. private LLUUID primID;
  756. private bool isScriptRunning;
  757. private BaseHttpServer httpListener;
  758. private bool m_dumpAssetToFile;
  759. public TaskInventoryScriptUpdater(LLUUID inventoryItemID, LLUUID primID, int isScriptRunning,
  760. string path, BaseHttpServer httpServer, bool dumpAssetToFile)
  761. {
  762. m_dumpAssetToFile = dumpAssetToFile;
  763. this.inventoryItemID = inventoryItemID;
  764. this.primID = primID;
  765. // This comes in over the packet as an integer, but actually appears to be treated as a bool
  766. this.isScriptRunning = (0 == isScriptRunning ? false : true);
  767. uploaderPath = path;
  768. httpListener = httpServer;
  769. }
  770. /// <summary>
  771. ///
  772. /// </summary>
  773. /// <param name="data"></param>
  774. /// <param name="path"></param>
  775. /// <param name="param"></param>
  776. /// <returns></returns>
  777. public string uploaderCaps(byte[] data, string path, string param)
  778. {
  779. try
  780. {
  781. // m_log.InfoFormat("[CAPS]: " +
  782. // "TaskInventoryScriptUpdater received data: {0}, path: {1}, param: {2}",
  783. // data, path, param));
  784. string res = String.Empty;
  785. LLSDTaskInventoryUploadComplete uploadComplete = new LLSDTaskInventoryUploadComplete();
  786. handlerUpdateTaskScript = OnUpLoad;
  787. if (handlerUpdateTaskScript != null)
  788. {
  789. handlerUpdateTaskScript(inventoryItemID, primID, isScriptRunning, data);
  790. }
  791. uploadComplete.item_id = inventoryItemID;
  792. uploadComplete.task_id = primID;
  793. uploadComplete.state = "complete";
  794. res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
  795. httpListener.RemoveStreamHandler("POST", uploaderPath);
  796. if (m_dumpAssetToFile)
  797. {
  798. SaveAssetToFile("updatedtaskscript" + Util.RandomClass.Next(1, 1000) + ".dat", data);
  799. }
  800. // m_log.InfoFormat("[CAPS]: TaskInventoryScriptUpdater.uploaderCaps res: {0}", res);
  801. return res;
  802. }
  803. catch (Exception e)
  804. {
  805. m_log.Error("[CAPS]: " + e.ToString());
  806. }
  807. // XXX Maybe this should be some meaningful error packet
  808. return null;
  809. }
  810. ///Left this in and commented in case there are unforseen issues
  811. //private void SaveAssetToFile(string filename, byte[] data)
  812. //{
  813. // FileStream fs = File.Create(filename);
  814. // BinaryWriter bw = new BinaryWriter(fs);
  815. // bw.Write(data);
  816. // bw.Close();
  817. // fs.Close();
  818. //}
  819. private void SaveAssetToFile(string filename, byte[] data)
  820. {
  821. string assetPath = "UserAssets";
  822. if (!Directory.Exists(assetPath))
  823. {
  824. Directory.CreateDirectory(assetPath);
  825. }
  826. FileStream fs = File.Create(Path.Combine(assetPath, filename));
  827. BinaryWriter bw = new BinaryWriter(fs);
  828. bw.Write(data);
  829. bw.Close();
  830. fs.Close();
  831. }
  832. }
  833. }
  834. }