BunchOfCaps.cs 111 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649
  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 OpenSimulator 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.Timers;
  29. using System.Collections;
  30. using System.Collections.Generic;
  31. using System.Collections.Specialized;
  32. using System.IO;
  33. using System.Net;
  34. using System.Threading;
  35. using System.Reflection;
  36. using System.Text;
  37. using OpenMetaverse;
  38. using OpenMetaverse.StructuredData;
  39. using Nini.Config;
  40. using log4net;
  41. using OpenSim.Framework;
  42. using OpenSim.Framework.Capabilities;
  43. using OpenSim.Region.Framework.Interfaces;
  44. using OpenSim.Region.Framework.Scenes;
  45. using OpenSim.Region.Framework.Scenes.Serialization;
  46. using OpenSim.Framework.Servers.HttpServer;
  47. using OpenSim.Services.Interfaces;
  48. using Caps = OpenSim.Framework.Capabilities.Caps;
  49. using OSDArray = OpenMetaverse.StructuredData.OSDArray;
  50. using OSDMap = OpenMetaverse.StructuredData.OSDMap;
  51. using PermissionMask = OpenSim.Framework.PermissionMask;
  52. using Timer = System.Threading.Timer;
  53. namespace OpenSim.Region.ClientStack.Linden
  54. {
  55. public delegate void UpLoadedAsset(
  56. string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder,
  57. byte[] data, string inventoryType, string assetType,
  58. int cost, UUID texturesFolder, int nreqtextures, int nreqmeshs, int nreqinstances,
  59. bool IsAtestUpload, ref string error, ref int nextOwnerMask, ref int groupMask, ref int everyoneMask, int[] meshesSides);
  60. public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors);
  61. public delegate void NewInventoryItem(UUID userID, InventoryItemBase item, uint cost);
  62. public delegate void NewAsset(AssetBase asset);
  63. public delegate ArrayList TaskScriptUpdatedCallback(UUID userID, UUID itemID, UUID primID,
  64. bool isScriptRunning, byte[] data);
  65. /// <summary>
  66. /// XXX Probably not a particularly nice way of allow us to get the scene presence from the scene (chiefly so that
  67. /// we can popup a message on the user's client if the inventory service has permanently failed). But I didn't want
  68. /// to just pass the whole Scene into CAPS.
  69. /// </summary>
  70. public delegate IClientAPI GetClientDelegate(UUID agentID);
  71. public partial class BunchOfCaps
  72. {
  73. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  74. private Scene m_Scene;
  75. private UUID m_AgentID;
  76. private UUID m_scopeID;
  77. private Caps m_HostCapsObj;
  78. private ModelCost m_ModelCost;
  79. private BunchOfCapsConfigOptions ConfigOptions;
  80. // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule.
  81. // These are callbacks which will be setup by the scene so that we can update scene data when we
  82. // receive capability calls
  83. public NewInventoryItem AddNewInventoryItem = null;
  84. public NewAsset AddNewAsset = null;
  85. public ItemUpdatedCallback ItemUpdatedCall = null;
  86. public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null;
  87. public GetClientDelegate GetClient = null;
  88. private IAssetService m_assetService;
  89. private bool m_dumpAssetsToFile = false;
  90. private string m_regionName;
  91. private IUserManagement m_UserManager;
  92. private IUserAccountService m_userAccountService;
  93. private IMoneyModule m_moneyModule;
  94. private enum FileAgentInventoryState : int
  95. {
  96. idle = 0,
  97. processRequest = 1,
  98. waitUpload = 2,
  99. processUpload = 3
  100. }
  101. private FileAgentInventoryState m_FileAgentInventoryState = FileAgentInventoryState.idle;
  102. public BunchOfCaps(Scene scene, UUID agentID, Caps caps, BunchOfCapsConfigOptions configOptions)
  103. {
  104. m_Scene = scene;
  105. m_AgentID = agentID;
  106. m_HostCapsObj = caps;
  107. ConfigOptions = configOptions;
  108. //cache model upload cost provider
  109. m_ModelCost = configOptions.ModelCost;
  110. m_assetService = m_Scene.AssetService;
  111. m_regionName = m_Scene.RegionInfo.RegionName;
  112. m_UserManager = m_Scene.RequestModuleInterface<IUserManagement>();
  113. m_userAccountService = m_Scene.RequestModuleInterface<IUserAccountService>();
  114. m_moneyModule = m_Scene.RequestModuleInterface<IMoneyModule>();
  115. if (m_UserManager is null)
  116. m_log.Error("[CAPS]: GetDisplayNames disabled because user management component not found");
  117. UserAccount account = m_userAccountService?.GetUserAccount(m_Scene.RegionInfo.ScopeID, m_AgentID);
  118. if (account is null) // Hypergrid?
  119. m_scopeID = m_Scene.RegionInfo.ScopeID;
  120. else
  121. m_scopeID = account.ScopeID;
  122. AddNewInventoryItem = m_Scene.AddUploadedInventoryItem;
  123. ItemUpdatedCall = m_Scene.CapsUpdateItemAsset;
  124. TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset;
  125. GetClient = m_Scene.SceneGraph.GetControllingClient;
  126. RegisterHandlers();
  127. m_FileAgentInventoryState = FileAgentInventoryState.idle;
  128. }
  129. public string GetNewCapPath()
  130. {
  131. return "/" + UUID.Random();
  132. }
  133. /// <summary>
  134. /// Register a bunch of CAPS http service handlers
  135. /// </summary>
  136. public void RegisterHandlers()
  137. {
  138. // this path is also defined elsewhere so keeping it
  139. string seedcapsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath + "0000";
  140. m_HostCapsObj.RegisterSimpleHandler("SEED", new SimpleStreamHandler(seedcapsBase, SeedCapRequest));
  141. // m_log.DebugFormat(
  142. // "[CAPS]: Registered seed capability {0} for {1}", seedcapsBase, m_HostCapsObj.AgentID);
  143. RegisterRegionServiceHandlers();
  144. RegisterInventoryServiceHandlers();
  145. RegisterOtherHandlers();
  146. }
  147. public void RegisterRegionServiceHandlers()
  148. {
  149. try
  150. {
  151. m_HostCapsObj.RegisterSimpleHandler("GetObjectPhysicsData",
  152. new SimpleOSDMapHandler("POST", GetNewCapPath(), GetObjectPhysicsData));
  153. m_HostCapsObj.RegisterSimpleHandler("GetObjectCost",
  154. new SimpleOSDMapHandler("POST", GetNewCapPath(), GetObjectCost));
  155. m_HostCapsObj.RegisterSimpleHandler("ResourceCostSelected",
  156. new SimpleOSDMapHandler("POST", GetNewCapPath(), ResourceCostSelected));
  157. if(ConfigOptions.AllowCapHomeLocation)
  158. {
  159. m_HostCapsObj.RegisterSimpleHandler("HomeLocation",
  160. new SimpleStreamHandler(GetNewCapPath(), HomeLocation));
  161. }
  162. if (ConfigOptions.AllowCapGroupMemberData)
  163. {
  164. m_HostCapsObj.RegisterSimpleHandler("GroupMemberData",
  165. new SimpleStreamHandler(GetNewCapPath(), GroupMemberData));
  166. }
  167. if (ConfigOptions.AllowCapLandResources)
  168. {
  169. m_HostCapsObj.RegisterSimpleHandler("LandResources",
  170. new SimpleOSDMapHandler("POST", GetNewCapPath(), LandResources));
  171. }
  172. if (ConfigOptions.AllowCapAttachmentResources)
  173. {
  174. m_HostCapsObj.RegisterSimpleHandler("AttachmentResources",
  175. new SimpleStreamHandler(GetNewCapPath(), AttachmentResources));
  176. }
  177. m_HostCapsObj.RegisterSimpleHandler("DispatchRegionInfo",
  178. new SimpleOSDMapHandler("POST", GetNewCapPath(), DispatchRegionInfo), true);
  179. }
  180. catch (Exception e)
  181. {
  182. m_log.Error("[CAPS]: Error " + e.Message);
  183. }
  184. }
  185. public void RegisterInventoryServiceHandlers()
  186. {
  187. try
  188. {
  189. m_HostCapsObj.RegisterHandler("NewFileAgentInventory",
  190. new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>(
  191. "POST", GetNewCapPath(), NewAgentInventoryRequest, "NewFileAgentInventory", null));
  192. SimpleOSDMapHandler oreq;
  193. if (ItemUpdatedCall is not null)
  194. {
  195. // first sets the http handler, others only register the cap, using it
  196. oreq = new SimpleOSDMapHandler("POST", GetNewCapPath(), UpdateNotecardItemAsset);
  197. m_HostCapsObj.RegisterSimpleHandler("UpdateNotecardAgentInventory", oreq, true);
  198. m_HostCapsObj.RegisterSimpleHandler("UpdateNotecardTaskInventory", oreq, false); // a object inv
  199. oreq = new SimpleOSDMapHandler("POST", GetNewCapPath(), UpdateAnimSetItemAsset);
  200. m_HostCapsObj.RegisterSimpleHandler("UpdateAnimSetAgentInventory", oreq, true);
  201. //m_HostCapsObj.RegisterSimpleHandler("UpdateAnimSetTaskInventory", oreq, false);
  202. oreq = new SimpleOSDMapHandler("POST", GetNewCapPath(), UpdateScriptItemAsset);
  203. m_HostCapsObj.RegisterSimpleHandler("UpdateScriptAgent", oreq, true);
  204. m_HostCapsObj.RegisterSimpleHandler("UpdateScriptAgentInventory", oreq, false); //legacy
  205. oreq = new SimpleOSDMapHandler("POST", GetNewCapPath(), UpdateSettingsItemAsset);
  206. m_HostCapsObj.RegisterSimpleHandler("UpdateSettingsAgentInventory", oreq, true);
  207. m_HostCapsObj.RegisterSimpleHandler("UpdateSettingsTaskInventory", oreq, false); // a object inv
  208. oreq = new SimpleOSDMapHandler("POST", GetNewCapPath(), UpdateMaterialItemAsset);
  209. m_HostCapsObj.RegisterSimpleHandler("UpdateMaterialAgentInventory", oreq, true);
  210. m_HostCapsObj.RegisterSimpleHandler("UpdateMaterialTaskInventory", oreq, false); // a object inv
  211. oreq = new SimpleOSDMapHandler("POST", GetNewCapPath(), UpdateGestureItemAsset);
  212. m_HostCapsObj.RegisterSimpleHandler("UpdateGestureAgentInventory", oreq, true);
  213. m_HostCapsObj.RegisterSimpleHandler("UpdateGestureTaskInventory", oreq, false);
  214. }
  215. if (TaskScriptUpdatedCall is not null)
  216. {
  217. oreq = new SimpleOSDMapHandler("POST", GetNewCapPath(), UpdateScriptTaskInventory);
  218. m_HostCapsObj.RegisterSimpleHandler("UpdateScriptTask", oreq, true);
  219. m_HostCapsObj.RegisterSimpleHandler("UpdateScriptTaskInventory", oreq, true); //legacy
  220. }
  221. m_HostCapsObj.RegisterSimpleHandler("UpdateAgentInformation",
  222. new SimpleStreamHandler(GetNewCapPath(), UpdateAgentInformation));
  223. m_HostCapsObj.RegisterSimpleHandler("CopyInventoryFromNotecard",
  224. new SimpleOSDMapHandler("POST", GetNewCapPath(), CopyInventoryFromNotecard));
  225. m_HostCapsObj.RegisterSimpleHandler("CreateInventoryCategory",
  226. new SimpleStreamHandler(GetNewCapPath(), CreateInventoryCategory));
  227. }
  228. catch (Exception e)
  229. {
  230. m_log.Error("[CAPS]: " + e.ToString());
  231. }
  232. }
  233. public void RegisterOtherHandlers()
  234. {
  235. try
  236. {
  237. if (m_UserManager is not null)
  238. {
  239. m_HostCapsObj.RegisterSimpleHandler("GetDisplayNames",
  240. new SimpleStreamHandler(GetNewCapPath(), GetDisplayNames));
  241. }
  242. }
  243. catch (Exception e)
  244. {
  245. m_log.Error("[CAPS]: Error " + e.Message);
  246. }
  247. }
  248. /// <summary>
  249. /// Construct a client response detailing all the capabilities this server can provide.
  250. /// </summary>
  251. /// <param name="request"></param>
  252. /// <param name="path"></param>
  253. /// <param name="param"></param>
  254. /// <param name="httpRequest">HTTP request header object</param>
  255. /// <param name="httpResponse">HTTP response header object</param>
  256. /// <returns></returns>
  257. public void SeedCapRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
  258. {
  259. m_log.Debug(
  260. $"[CAPS]: Received SEED caps request in {m_regionName} for agent {m_HostCapsObj.AgentID}");
  261. if(httpRequest.HttpMethod != "POST" || httpRequest.ContentType != "application/llsd+xml")
  262. {
  263. httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
  264. return;
  265. }
  266. if (!m_HostCapsObj.WaitForActivation())
  267. {
  268. httpResponse.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
  269. httpResponse.AddHeader("Retry-After", "30");
  270. return;
  271. }
  272. if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
  273. {
  274. m_log.WarnFormat(
  275. $"[CAPS]: Unauthorized CAPS client {m_HostCapsObj.AgentID} from {httpRequest.RemoteIPEndPoint}");
  276. httpResponse.StatusCode = (int)HttpStatusCode.Forbidden;
  277. return;
  278. }
  279. OSDArray capsRequested;
  280. try
  281. {
  282. capsRequested = (OSDArray)OSDParser.DeserializeLLSDXml(httpRequest.InputStream);
  283. }
  284. catch
  285. {
  286. httpResponse.StatusCode = (int)HttpStatusCode.BadRequest;
  287. return;
  288. }
  289. HashSet<string> validCaps = new();
  290. foreach (OSD c in capsRequested)
  291. {
  292. string cstr = c.AsString();
  293. if (string.IsNullOrEmpty(cstr))
  294. continue;
  295. switch (cstr)
  296. {
  297. case "SEED":
  298. continue;
  299. case "ViewerBenefits": // this may need a proper cap but not currently
  300. m_HostCapsObj.Flags |= Caps.CapsFlags.ViewerBenefits;
  301. continue;
  302. case "ObjectAnimation":
  303. m_HostCapsObj.Flags |= Caps.CapsFlags.ObjectAnim;
  304. break;
  305. case "EnvironmentSettings":
  306. m_HostCapsObj.Flags |= Caps.CapsFlags.WLEnv;
  307. break;
  308. case "ExtEnvironment":
  309. m_HostCapsObj.Flags |= Caps.CapsFlags.AdvEnv;
  310. break;
  311. case "ModifyMaterialParams": // will not work if a viewer has no edit features
  312. m_HostCapsObj.Flags |= Caps.CapsFlags.PBR;
  313. break;
  314. default:
  315. break;
  316. }
  317. validCaps.Add(cstr);
  318. }
  319. osUTF8 sb = LLSDxmlEncode2.Start();
  320. LLSDxmlEncode2.AddMap(sb);
  321. m_HostCapsObj.GetCapsDetailsLLSDxml(validCaps, sb);
  322. LLSDxmlEncode2.AddEndMap(sb);
  323. httpResponse.RawBuffer = LLSDxmlEncode2.EndToBytes(sb);
  324. httpResponse.StatusCode = (int)HttpStatusCode.OK;
  325. m_HostCapsObj.Flags |= Caps.CapsFlags.SentSeeds;
  326. }
  327. /// <summary>
  328. ///
  329. /// </summary>
  330. /// <param name="llsdRequest"></param>
  331. /// <returns></returns>
  332. public LLSDAssetUploadResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest)
  333. {
  334. //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString());
  335. //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type);
  336. // start by getting the client
  337. IClientAPI client = null;
  338. m_Scene.TryGetClient(m_HostCapsObj.AgentID, out client);
  339. // check current state so we only have one service at a time
  340. lock (m_ModelCost)
  341. {
  342. switch (m_FileAgentInventoryState)
  343. {
  344. case FileAgentInventoryState.processRequest:
  345. case FileAgentInventoryState.processUpload:
  346. LLSDAssetUploadError resperror = new LLSDAssetUploadError();
  347. resperror.message = "Uploader busy processing previous request";
  348. resperror.identifier = UUID.Zero;
  349. LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
  350. errorResponse.uploader = "";
  351. errorResponse.state = "error";
  352. errorResponse.error = resperror;
  353. return errorResponse;
  354. case FileAgentInventoryState.waitUpload:
  355. // todo stop current uploader server
  356. break;
  357. case FileAgentInventoryState.idle:
  358. default:
  359. break;
  360. }
  361. m_FileAgentInventoryState = FileAgentInventoryState.processRequest;
  362. }
  363. int cost = 0;
  364. int nreqtextures = 0;
  365. int nreqmeshs= 0;
  366. int nreqinstances = 0;
  367. bool IsAtestUpload = false;
  368. int[] meshesSides = null;
  369. string assetName = llsdRequest.name;
  370. LLSDAssetUploadResponseData meshcostdata = new LLSDAssetUploadResponseData();
  371. if (llsdRequest.asset_type == "texture" ||
  372. llsdRequest.asset_type == "animation" ||
  373. llsdRequest.asset_type == "animatn" || // this is the asset name actually used by viewers
  374. llsdRequest.asset_type == "mesh" ||
  375. llsdRequest.asset_type == "sound")
  376. {
  377. ScenePresence avatar = null;
  378. m_Scene.TryGetScenePresence(m_HostCapsObj.AgentID, out avatar);
  379. // check user level
  380. if (avatar is not null)
  381. {
  382. if (avatar.GodController.UserLevel < ConfigOptions.levelUpload)
  383. {
  384. LLSDAssetUploadError resperror = new LLSDAssetUploadError();
  385. resperror.message = "Insufficient permissions to upload";
  386. resperror.identifier = UUID.Zero;
  387. LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
  388. errorResponse.uploader = "";
  389. errorResponse.state = "error";
  390. errorResponse.error = resperror;
  391. lock (m_ModelCost)
  392. m_FileAgentInventoryState = FileAgentInventoryState.idle;
  393. return errorResponse;
  394. }
  395. }
  396. // check test upload and funds
  397. if (client is not null)
  398. {
  399. IMoneyModule mm = m_Scene.RequestModuleInterface<IMoneyModule>();
  400. int baseCost = 0;
  401. if (mm is not null)
  402. baseCost = mm.UploadCharge;
  403. string warning = String.Empty;
  404. if (llsdRequest.asset_type == "mesh")
  405. {
  406. string error;
  407. int modelcost;
  408. if (!m_ModelCost.MeshModelCost(llsdRequest.asset_resources, baseCost, out modelcost,
  409. meshcostdata, out error, ref warning, out meshesSides))
  410. {
  411. LLSDAssetUploadError resperror = new LLSDAssetUploadError();
  412. resperror.message = error;
  413. resperror.identifier = UUID.Zero;
  414. LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
  415. errorResponse.uploader = "";
  416. errorResponse.state = "error";
  417. errorResponse.error = resperror;
  418. lock (m_ModelCost)
  419. m_FileAgentInventoryState = FileAgentInventoryState.idle;
  420. return errorResponse;
  421. }
  422. cost = modelcost;
  423. }
  424. else
  425. {
  426. cost = baseCost;
  427. }
  428. if (cost > 0 && mm != null)
  429. {
  430. // check for test upload
  431. if (ConfigOptions.ForceFreeTestUpload) // all are test
  432. {
  433. if (!(assetName.Length > 5 && assetName.StartsWith("TEST-"))) // has normal name lets change it
  434. assetName = "TEST-" + assetName;
  435. IsAtestUpload = true;
  436. }
  437. else if (ConfigOptions.enableFreeTestUpload) // only if prefixed with "TEST-"
  438. {
  439. IsAtestUpload = (assetName.Length > 5 && assetName.StartsWith("TEST-"));
  440. }
  441. if(IsAtestUpload) // let user know, still showing cost estimation
  442. warning += "Upload will have no cost, for testing purposes only. Other uses are prohibited. Items will be local to region only, Inventory entry will be lost on logout";
  443. // check funds
  444. else
  445. {
  446. if (!mm.UploadCovered(client.AgentId, (int)cost))
  447. {
  448. LLSDAssetUploadError resperror = new LLSDAssetUploadError();
  449. resperror.message = "Insuficient funds";
  450. resperror.identifier = UUID.Zero;
  451. LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
  452. errorResponse.uploader = "";
  453. errorResponse.state = "error";
  454. errorResponse.error = resperror;
  455. lock (m_ModelCost)
  456. m_FileAgentInventoryState = FileAgentInventoryState.idle;
  457. return errorResponse;
  458. }
  459. }
  460. }
  461. else if (ConfigOptions.enableFreeTestUpload) // only if prefixed with "TEST-"
  462. {
  463. IsAtestUpload = (assetName.Length > 5 && assetName.StartsWith("TEST-"));
  464. if(IsAtestUpload)
  465. warning += "Upload for testing purposes only. Items will be local to region only, Inventory entry will be lost on logout";
  466. }
  467. if (client != null && warning != String.Empty)
  468. client.SendAgentAlertMessage(warning, true);
  469. }
  470. }
  471. string assetDes = llsdRequest.description;
  472. UUID newAsset = UUID.Random();
  473. UUID newInvItem = UUID.Random();
  474. UUID parentFolder = llsdRequest.folder_id;
  475. string uploaderPath = GetNewCapPath();
  476. UUID texturesFolder = UUID.Zero;
  477. if(!IsAtestUpload && ConfigOptions.enableModelUploadTextureToInventory)
  478. texturesFolder = llsdRequest.texture_folder_id;
  479. AssetUploader uploader =
  480. new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
  481. llsdRequest.asset_type, uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile, cost,
  482. texturesFolder, nreqtextures, nreqmeshs, nreqinstances, IsAtestUpload,
  483. llsdRequest.next_owner_mask, llsdRequest.group_mask, llsdRequest.everyone_mask, meshesSides);
  484. m_HostCapsObj.HttpListener.AddStreamHandler(
  485. new BinaryStreamHandler(
  486. "POST",
  487. uploaderPath,
  488. uploader.uploaderCaps,
  489. "NewAgentInventoryRequest",
  490. m_HostCapsObj.AgentID.ToString()));
  491. string protocol = "http://";
  492. if (m_HostCapsObj.SSLCaps)
  493. protocol = "https://";
  494. string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + uploaderPath;
  495. LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
  496. uploadResponse.uploader = uploaderURL;
  497. uploadResponse.state = "upload";
  498. uploadResponse.upload_price = (int)cost;
  499. if (llsdRequest.asset_type == "mesh")
  500. {
  501. uploadResponse.data = meshcostdata;
  502. }
  503. uploader.OnUpLoad += UploadCompleteHandler;
  504. lock (m_ModelCost)
  505. m_FileAgentInventoryState = FileAgentInventoryState.waitUpload;
  506. return uploadResponse;
  507. }
  508. /// <summary>
  509. /// Convert raw uploaded data into the appropriate asset and item.
  510. /// </summary>
  511. /// <param name="assetID"></param>
  512. /// <param name="inventoryItem"></param>
  513. /// <param name="data"></param>
  514. public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
  515. UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
  516. string assetType, int cost,
  517. UUID texturesFolder, int nreqtextures, int nreqmeshs, int nreqinstances,
  518. bool IsAtestUpload, ref string error,
  519. ref int nextOwnerMask, ref int groupMask, ref int everyoneMask, int[] meshesSides)
  520. {
  521. lock (m_ModelCost)
  522. m_FileAgentInventoryState = FileAgentInventoryState.processUpload;
  523. m_log.DebugFormat(
  524. "[BUNCH OF CAPS]: Uploaded asset {0} for inventory item {1}, inv type {2}, asset type {3}",
  525. assetID, inventoryItem, inventoryType, assetType);
  526. sbyte assType = 0;
  527. sbyte inType = 0;
  528. IClientAPI client = null;
  529. UUID owner_id = m_HostCapsObj.AgentID;
  530. UUID creatorID;
  531. bool istest = IsAtestUpload && ConfigOptions.enableFreeTestUpload;
  532. bool restrictPerms = ConfigOptions.RestrictFreeTestUploadPerms && istest;
  533. if (istest && ConfigOptions.testAssetsCreatorID.IsNotZero())
  534. creatorID = ConfigOptions.testAssetsCreatorID;
  535. else
  536. creatorID = owner_id;
  537. string creatorIDstr = creatorID.ToString();
  538. IMoneyModule mm = m_Scene.RequestModuleInterface<IMoneyModule>();
  539. if (mm != null)
  540. {
  541. // make sure client still has enougth credit
  542. if (!mm.UploadCovered(m_HostCapsObj.AgentID, (int)cost))
  543. {
  544. error = "Insufficient funds.";
  545. return;
  546. }
  547. }
  548. // strings to types
  549. if (inventoryType == "sound")
  550. {
  551. inType = (sbyte)InventoryType.Sound;
  552. assType = (sbyte)AssetType.Sound;
  553. }
  554. else if (inventoryType == "snapshot")
  555. {
  556. inType = (sbyte)InventoryType.Snapshot;
  557. }
  558. else if (inventoryType == "animation")
  559. {
  560. inType = (sbyte)InventoryType.Animation;
  561. assType = (sbyte)AssetType.Animation;
  562. }
  563. else if (inventoryType == "animset")
  564. {
  565. inType = (sbyte)CustomInventoryType.AnimationSet;
  566. assType = (sbyte)CustomAssetType.AnimationSet;
  567. m_log.Debug("got animset upload request");
  568. }
  569. else if (inventoryType == "wearable")
  570. {
  571. inType = (sbyte)InventoryType.Wearable;
  572. switch (assetType)
  573. {
  574. case "bodypart":
  575. assType = (sbyte)AssetType.Bodypart;
  576. break;
  577. case "clothing":
  578. assType = (sbyte)AssetType.Clothing;
  579. break;
  580. }
  581. }
  582. else if (inventoryType == "object")
  583. {
  584. if (assetType == "mesh") // this code for now is for mesh models uploads only
  585. {
  586. inType = (sbyte)InventoryType.Object;
  587. assType = (sbyte)AssetType.Object;
  588. List<Vector3> positions = new List<Vector3>();
  589. List<Quaternion> rotations = new List<Quaternion>();
  590. OSDMap request = (OSDMap)OSDParser.DeserializeLLSDXml(data);
  591. // compare and get updated information
  592. /* does nothing still we do need something to avoid special viewer to upload something diferent from the cost estimation
  593. bool mismatchError = true;
  594. while (mismatchError)
  595. {
  596. mismatchError = false;
  597. }
  598. if (mismatchError)
  599. {
  600. error = "Upload and fee estimation information don't match";
  601. lock (m_ModelCost)
  602. m_FileAgentInventoryState = FileAgentInventoryState.idle;
  603. return;
  604. }
  605. */
  606. OSDArray instance_list = (OSDArray)request["instance_list"];
  607. OSDArray mesh_list = (OSDArray)request["mesh_list"];
  608. OSDArray texture_list = (OSDArray)request["texture_list"];
  609. SceneObjectGroup grp = null;
  610. // create and store texture assets
  611. bool doTextInv = (!istest && ConfigOptions.enableModelUploadTextureToInventory &&
  612. texturesFolder != UUID.Zero);
  613. List<UUID> textures = new List<UUID>();
  614. // if (doTextInv)
  615. m_Scene.TryGetClient(m_HostCapsObj.AgentID, out client);
  616. if(client == null) // don't put textures in inventory if there is no client
  617. doTextInv = false;
  618. for (int i = 0; i < texture_list.Count; i++)
  619. {
  620. AssetBase textureAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Texture, creatorIDstr);
  621. textureAsset.Data = texture_list[i].AsBinary();
  622. if (istest)
  623. textureAsset.Local = true;
  624. m_assetService.Store(textureAsset);
  625. textures.Add(textureAsset.FullID);
  626. if (doTextInv)
  627. {
  628. string name = assetName;
  629. if (name.Length > 25)
  630. name = name.Substring(0, 24);
  631. name += "_Texture#" + i.ToString();
  632. InventoryItemBase texitem = new InventoryItemBase();
  633. texitem.Owner = m_HostCapsObj.AgentID;
  634. texitem.CreatorId = creatorIDstr;
  635. texitem.CreatorData = String.Empty;
  636. texitem.ID = UUID.Random();
  637. texitem.AssetID = textureAsset.FullID;
  638. texitem.Description = "mesh model texture";
  639. texitem.Name = name;
  640. texitem.AssetType = (int)AssetType.Texture;
  641. texitem.InvType = (int)InventoryType.Texture;
  642. texitem.Folder = texturesFolder;
  643. texitem.CurrentPermissions
  644. = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Export);
  645. texitem.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
  646. texitem.EveryOnePermissions = 0;
  647. texitem.NextPermissions = (uint)PermissionMask.All;
  648. texitem.CreationDate = Util.UnixTimeSinceEpoch();
  649. m_Scene.AddInventoryItem(client, texitem);
  650. texitem = null;
  651. }
  652. }
  653. // create and store meshs assets
  654. List<UUID> meshAssets = new List<UUID>();
  655. List<bool> meshAvatarSkeletons = new List<bool>();
  656. List<bool> meshAvatarColliders = new List<bool>();
  657. bool curAvSkeleton;
  658. bool curAvCollider;
  659. for (int i = 0; i < mesh_list.Count; i++)
  660. {
  661. curAvSkeleton = false;
  662. curAvCollider = false;
  663. // we do need to parse the mesh now
  664. OSD osd = OSDParser.DeserializeLLSDBinary(mesh_list[i]);
  665. if (osd is OSDMap)
  666. {
  667. OSDMap mosd = (OSDMap)osd;
  668. if (mosd.ContainsKey("skeleton"))
  669. {
  670. OSDMap skeleton = (OSDMap)mosd["skeleton"];
  671. int sksize = skeleton["size"].AsInteger();
  672. if (sksize > 0)
  673. curAvSkeleton = true;
  674. }
  675. }
  676. AssetBase meshAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Mesh, creatorIDstr);
  677. meshAsset.Data = mesh_list[i].AsBinary();
  678. if (istest)
  679. meshAsset.Local = true;
  680. m_assetService.Store(meshAsset);
  681. meshAssets.Add(meshAsset.FullID);
  682. meshAvatarSkeletons.Add(curAvSkeleton);
  683. meshAvatarColliders.Add(curAvCollider);
  684. // test code
  685. if (curAvSkeleton && client != null)
  686. {
  687. string name = assetName;
  688. if (name.Length > 25)
  689. name = name.Substring(0, 24);
  690. name += "_Mesh#" + i.ToString();
  691. InventoryItemBase meshitem = new InventoryItemBase();
  692. meshitem.Owner = m_HostCapsObj.AgentID;
  693. meshitem.CreatorId = creatorIDstr;
  694. meshitem.CreatorData = String.Empty;
  695. meshitem.ID = UUID.Random();
  696. meshitem.AssetID = meshAsset.FullID;
  697. meshitem.Description = "mesh ";
  698. meshitem.Name = name;
  699. meshitem.AssetType = (int)AssetType.Mesh;
  700. meshitem.InvType = (int)InventoryType.Mesh;
  701. // meshitem.Folder = UUID.Zero; // send to default
  702. meshitem.Folder = parentFolder; // dont let it go to folder Meshes that viewers dont show
  703. // If we set PermissionMask.All then when we rez the item the next permissions will replace the current
  704. // (owner) permissions. This becomes a problem if next permissions are changed.
  705. meshitem.CurrentPermissions
  706. = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
  707. meshitem.BasePermissions = (uint)PermissionMask.All;
  708. meshitem.EveryOnePermissions = 0;
  709. meshitem.NextPermissions = (uint)PermissionMask.All;
  710. meshitem.CreationDate = Util.UnixTimeSinceEpoch();
  711. m_Scene.AddInventoryItem(client, meshitem);
  712. meshitem = null;
  713. }
  714. }
  715. int skipedMeshs = 0;
  716. float primScaleMin = m_ModelCost.PrimScaleMin;
  717. // build prims from instances
  718. for (int i = 0; i < instance_list.Count; i++)
  719. {
  720. OSDMap inner_instance_list = (OSDMap)instance_list[i];
  721. // skip prims that are 2 small
  722. Vector3 scale = inner_instance_list["scale"].AsVector3();
  723. if (scale.X < primScaleMin || scale.Y < primScaleMin || scale.Z < primScaleMin)
  724. {
  725. skipedMeshs++;
  726. continue;
  727. }
  728. OSDArray face_list = (OSDArray)inner_instance_list["face_list"];
  729. PrimitiveBaseShape pbs = null;
  730. if (inner_instance_list.ContainsKey("mesh")) // seems to happen always but ...
  731. {
  732. int meshindx = inner_instance_list["mesh"].AsInteger();
  733. if (meshAssets.Count > meshindx)
  734. {
  735. if(meshesSides != null && meshesSides.Length > meshindx)
  736. pbs = PrimitiveBaseShape.CreateMesh(meshesSides[i], meshAssets[meshindx]);
  737. else
  738. pbs = PrimitiveBaseShape.CreateMesh(face_list.Count, meshAssets[meshindx]);
  739. }
  740. }
  741. if(pbs == null) // fallback
  742. pbs = PrimitiveBaseShape.CreateBox();
  743. Primitive.TextureEntry textureEntry
  744. = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE);
  745. for (uint face = 0; face < face_list.Count; face++)
  746. {
  747. OSDMap faceMap = (OSDMap)face_list[(int)face];
  748. Primitive.TextureEntryFace f = textureEntry.CreateFace(face); //clone the default
  749. if (faceMap.ContainsKey("fullbright"))
  750. f.Fullbright = faceMap["fullbright"].AsBoolean();
  751. if (faceMap.ContainsKey("diffuse_color"))
  752. f.RGBA = faceMap["diffuse_color"].AsColor4();
  753. int textureNum = faceMap["image"].AsInteger();
  754. float imagerot = faceMap["imagerot"].AsInteger();
  755. float offsets = (float)faceMap["offsets"].AsReal();
  756. float offsett = (float)faceMap["offsett"].AsReal();
  757. float scales = (float)faceMap["scales"].AsReal();
  758. float scalet = (float)faceMap["scalet"].AsReal();
  759. if (imagerot != 0)
  760. f.Rotation = imagerot;
  761. if (offsets != 0)
  762. f.OffsetU = offsets;
  763. if (offsett != 0)
  764. f.OffsetV = offsett;
  765. if (scales != 0)
  766. f.RepeatU = scales;
  767. if (scalet != 0)
  768. f.RepeatV = scalet;
  769. if (textures.Count > textureNum)
  770. f.TextureID = textures[textureNum];
  771. textureEntry.FaceTextures[face] = f;
  772. }
  773. if(face_list.Count > 0)
  774. {
  775. int last = face_list.Count - 1;
  776. // we do need a better te compacting code
  777. textureEntry.DefaultTexture = textureEntry.FaceTextures[last];
  778. textureEntry.FaceTextures[last] = null;
  779. pbs.TextureEntry = textureEntry.GetBytes(last);
  780. }
  781. Vector3 position = inner_instance_list["position"].AsVector3();
  782. Quaternion rotation = inner_instance_list["rotation"].AsQuaternion();
  783. byte physicsShapeType = (byte)PhysShapeType.convex; // default is simple convex
  784. if (inner_instance_list.ContainsKey("physics_shape_type"))
  785. physicsShapeType = (byte)inner_instance_list["physics_shape_type"].AsInteger();
  786. byte material = (byte)Material.Wood;
  787. if (inner_instance_list.ContainsKey("material"))
  788. material = (byte)inner_instance_list["material"].AsInteger();
  789. SceneObjectPart prim
  790. = new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero);
  791. prim.Scale = scale;
  792. rotations.Add(rotation);
  793. positions.Add(position);
  794. prim.UUID = UUID.Random();
  795. prim.CreatorID = creatorID;
  796. prim.OwnerID = owner_id;
  797. prim.GroupID = UUID.Zero;
  798. prim.LastOwnerID = creatorID;
  799. prim.RezzerID = creatorID;
  800. prim.CreationDate = Util.UnixTimeSinceEpoch();
  801. if (grp == null)
  802. prim.Name = assetName;
  803. else
  804. prim.Name = assetName + "#" + i.ToString();
  805. prim.EveryoneMask = 0;
  806. prim.GroupMask = 0;
  807. if (restrictPerms)
  808. {
  809. prim.BaseMask = (uint)(PermissionMask.Move | PermissionMask.Modify);
  810. prim.OwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify);
  811. prim.NextOwnerMask = 0;
  812. }
  813. else
  814. {
  815. prim.BaseMask = (uint)PermissionMask.All | (uint)PermissionMask.Export;
  816. prim.OwnerMask = (uint)PermissionMask.All | (uint)PermissionMask.Export;
  817. prim.GroupMask = prim.BaseMask & (uint)groupMask;
  818. prim.EveryoneMask = prim.BaseMask & (uint)everyoneMask;
  819. prim.NextOwnerMask = prim.BaseMask & (uint)nextOwnerMask;
  820. // If the viewer gives us bogus permissions, revert to the SL
  821. // default of transfer only.
  822. if ((prim.NextOwnerMask & (uint)PermissionMask.All) == 0)
  823. prim.NextOwnerMask = (uint)PermissionMask.Transfer;
  824. }
  825. if(istest)
  826. prim.Description = "For testing only. Other uses are prohibited";
  827. else
  828. prim.Description = "";
  829. prim.Material = material;
  830. prim.PhysicsShapeType = physicsShapeType;
  831. // prim.BaseMask = (uint)base_mask;
  832. // prim.EveryoneMask = (uint)everyone_mask;
  833. // prim.GroupMask = (uint)group_mask;
  834. // prim.NextOwnerMask = (uint)next_owner_mask;
  835. // prim.OwnerMask = (uint)owner_mask;
  836. if (grp == null)
  837. {
  838. grp = new SceneObjectGroup(prim);
  839. grp.LastOwnerID = creatorID;
  840. grp.RezzerID = creatorID;
  841. }
  842. else
  843. grp.AddPart(prim);
  844. }
  845. Vector3 rootPos = positions[0];
  846. if (grp.Parts.Length > 1)
  847. {
  848. // Fix first link number
  849. grp.RootPart.LinkNum++;
  850. Quaternion rootRotConj = Quaternion.Conjugate(rotations[0]);
  851. Quaternion tmprot;
  852. Vector3 offset;
  853. // fix children rotations and positions
  854. for (int i = 1; i < rotations.Count; i++)
  855. {
  856. tmprot = rotations[i];
  857. tmprot = rootRotConj * tmprot;
  858. grp.Parts[i].RotationOffset = tmprot;
  859. offset = positions[i] - rootPos;
  860. offset *= rootRotConj;
  861. grp.Parts[i].OffsetPosition = offset;
  862. }
  863. grp.AbsolutePosition = rootPos;
  864. grp.UpdateGroupRotationR(rotations[0]);
  865. }
  866. else
  867. {
  868. grp.AbsolutePosition = rootPos;
  869. grp.UpdateGroupRotationR(rotations[0]);
  870. }
  871. data = ASCIIEncoding.ASCII.GetBytes(SceneObjectSerializer.ToOriginalXmlFormat(grp));
  872. }
  873. else // not a mesh model
  874. {
  875. m_log.ErrorFormat("[CAPS Asset Upload] got unsuported assetType for object upload");
  876. return;
  877. }
  878. }
  879. AssetBase asset;
  880. asset = new AssetBase(assetID, assetName, assType, creatorIDstr);
  881. asset.Data = data;
  882. if (istest)
  883. asset.Local = true;
  884. if (AddNewAsset != null)
  885. AddNewAsset(asset);
  886. else if (m_assetService != null)
  887. m_assetService.Store(asset);
  888. InventoryItemBase item = new InventoryItemBase();
  889. item.Owner = m_HostCapsObj.AgentID;
  890. item.CreatorId = creatorIDstr;
  891. item.CreatorData = String.Empty;
  892. item.ID = inventoryItem;
  893. item.AssetID = asset.FullID;
  894. if (istest)
  895. {
  896. item.Description = "For testing only. Other uses are prohibited";
  897. item.Flags = (uint) (InventoryItemFlags.SharedSingleReference);
  898. }
  899. else
  900. item.Description = assetDescription;
  901. item.Name = assetName;
  902. item.AssetType = assType;
  903. item.InvType = inType;
  904. item.Folder = parentFolder;
  905. // If we set PermissionMask.All then when we rez the item the next permissions will replace the current
  906. // (owner) permissions. This becomes a problem if next permissions are changed.
  907. if (inType == (sbyte)CustomInventoryType.AnimationSet)
  908. {
  909. AnimationSet.setCreateItemPermitions(item);
  910. }
  911. else if (restrictPerms)
  912. {
  913. item.BasePermissions = (uint)(PermissionMask.Move | PermissionMask.Modify);
  914. item.CurrentPermissions = (uint)(PermissionMask.Move | PermissionMask.Modify);
  915. item.GroupPermissions = 0;
  916. item.EveryOnePermissions = 0;
  917. item.NextPermissions = 0;
  918. }
  919. else
  920. {
  921. item.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
  922. item.CurrentPermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
  923. item.GroupPermissions = item.BasePermissions & (uint)groupMask;
  924. item.EveryOnePermissions = item.BasePermissions & (uint)everyoneMask;
  925. item.NextPermissions = item.BasePermissions & (uint)nextOwnerMask;
  926. if ((item.NextPermissions & (uint)PermissionMask.All) == 0)
  927. item.NextPermissions = (uint)PermissionMask.Transfer;
  928. }
  929. item.CreationDate = Util.UnixTimeSinceEpoch();
  930. everyoneMask = (int)item.EveryOnePermissions;
  931. groupMask = (int)item.GroupPermissions;
  932. nextOwnerMask = (int)item.NextPermissions;
  933. m_Scene.TryGetClient(m_HostCapsObj.AgentID, out client);
  934. if (AddNewInventoryItem != null)
  935. {
  936. if (istest)
  937. {
  938. m_Scene.AddInventoryItem(client, item);
  939. /*
  940. AddNewInventoryItem(m_HostCapsObj.AgentID, item, 0);
  941. if (client != null)
  942. client.SendAgentAlertMessage("Upload will have no cost, for personal test purposes only. Other uses are forbiden. Items may not work on a another region" , true);
  943. */
  944. }
  945. else
  946. {
  947. AddNewInventoryItem(m_HostCapsObj.AgentID, item, (uint)cost);
  948. // if (client != null)
  949. // {
  950. // // let users see anything.. i don't so far
  951. // string str;
  952. // if (cost > 0)
  953. // // dont remember where is money unit name to put here
  954. // str = "Upload complete. charged " + cost.ToString() + "$";
  955. // else
  956. // str = "Upload complete";
  957. // client.SendAgentAlertMessage(str, true);
  958. // }
  959. }
  960. }
  961. lock (m_ModelCost)
  962. m_FileAgentInventoryState = FileAgentInventoryState.idle;
  963. }
  964. public void CreateInventoryCategory(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
  965. {
  966. if(httpRequest.HttpMethod != "POST")
  967. {
  968. httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
  969. return;
  970. }
  971. if (m_Scene.InventoryService == null)
  972. {
  973. httpResponse.StatusCode = (int)HttpStatusCode.NotImplemented;
  974. return;
  975. }
  976. ScenePresence sp = m_Scene.GetScenePresence(m_AgentID);
  977. if (sp == null || sp.IsDeleted)
  978. {
  979. httpResponse.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
  980. httpResponse.AddHeader("Retry-After", "60");
  981. return;
  982. }
  983. OSDMap req;
  984. OSD tmp;
  985. try
  986. {
  987. req = (OSDMap)OSDParser.DeserializeLLSDXml(httpRequest.InputStream);
  988. }
  989. catch
  990. {
  991. httpResponse.StatusCode = (int)HttpStatusCode.BadRequest;
  992. return;
  993. }
  994. try
  995. {
  996. while (true) // kinda goto
  997. {
  998. if (!req.TryGetValue("folder_id", out tmp) || !(tmp is OSDUUID))
  999. break;
  1000. UUID folderID = tmp.AsUUID();
  1001. if(folderID == UUID.Zero)
  1002. break;
  1003. if (!req.TryGetValue("parent_id", out tmp) || !(tmp is OSDUUID))
  1004. break;
  1005. UUID parentID = tmp.AsUUID();
  1006. if (!req.TryGetValue("name", out tmp) || !(tmp is OSDString))
  1007. break;
  1008. string folderName = tmp.AsString();
  1009. if(string.IsNullOrEmpty(folderName))
  1010. break;
  1011. if(folderName.Length > 63)
  1012. folderName = folderName.Substring(0, 63);
  1013. if (!req.TryGetValue("type", out tmp) || !(tmp is OSDInteger))
  1014. break;
  1015. int folderType = tmp.AsInteger();
  1016. InventoryFolderBase folder = new InventoryFolderBase(folderID, folderName, m_AgentID, (short)folderType, parentID, 1);
  1017. if (!m_Scene.InventoryService.AddFolder(folder))
  1018. break;
  1019. // costly double check plus possible service changes
  1020. folder = m_Scene.InventoryService.GetFolder(m_AgentID, folderID);
  1021. if (folder == null)
  1022. break;
  1023. osUTF8 sb = LLSDxmlEncode2.Start();
  1024. LLSDxmlEncode2.AddMap(sb);
  1025. LLSDxmlEncode2.AddElem("folder_id", folder.ID, sb);
  1026. LLSDxmlEncode2.AddElem("name", folder.Name, sb);
  1027. LLSDxmlEncode2.AddElem("parent_id", folder.ParentID, sb);
  1028. LLSDxmlEncode2.AddElem("type", folder.Type, sb);
  1029. LLSDxmlEncode2.AddEndMap(sb);
  1030. httpResponse.RawBuffer = LLSDxmlEncode2.EndToNBBytes(sb);
  1031. httpResponse.StatusCode = (int)HttpStatusCode.OK;
  1032. return;
  1033. }
  1034. }
  1035. catch { }
  1036. m_log.Debug("[CAPS]: CreateInventoryCategory failed to process request");
  1037. httpResponse.StatusCode = (int)HttpStatusCode.BadRequest;
  1038. }
  1039. /// <summary>
  1040. /// Called by the CopyInventoryFromNotecard caps handler.
  1041. /// </summary>
  1042. /// <param name="request"></param>
  1043. /// <param name="path"></param>
  1044. /// <param name="param"></param>
  1045. public void CopyInventoryFromNotecard(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap content)
  1046. {
  1047. InventoryItemBase copyItem = null;
  1048. IClientAPI client = null;
  1049. httpResponse.StatusCode = (int)HttpStatusCode.OK;
  1050. try
  1051. {
  1052. UUID objectID = content["object-id"].AsUUID();
  1053. UUID notecardID = content["notecard-id"].AsUUID();
  1054. UUID folderID = content["folder-id"].AsUUID();
  1055. UUID itemID = content["item-id"].AsUUID();
  1056. // m_log.InfoFormat("[CAPS]: CopyInventoryFromNotecard, FolderID:{0}, ItemID:{1}, NotecardID:{2}, ObjectID:{3}", folderID, itemID, notecardID, objectID);
  1057. UUID noteAssetID = UUID.Zero;
  1058. UUID agentID = m_HostCapsObj.AgentID;
  1059. m_Scene.TryGetClient(agentID, out client);
  1060. if (!objectID.IsZero())
  1061. {
  1062. SceneObjectPart part = m_Scene.GetSceneObjectPart(objectID);
  1063. if(part == null)
  1064. throw new Exception("failed to find object with notecard item" + notecardID.ToString());
  1065. TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(notecardID);
  1066. if (taskItem == null || taskItem.AssetID.IsZero())
  1067. throw new Exception("Failed to find notecard item" + notecardID.ToString());
  1068. if (!m_Scene.Permissions.CanCopyObjectInventory(notecardID, objectID, agentID))
  1069. throw new Exception("No permission to copy notecard from object");
  1070. noteAssetID = taskItem.AssetID;
  1071. }
  1072. else
  1073. {
  1074. // we may have the item around...
  1075. InventoryItemBase localitem = m_Scene.InventoryService.GetItem(agentID, itemID);
  1076. if (localitem != null)
  1077. {
  1078. string message;
  1079. copyItem = m_Scene.GiveInventoryItem(agentID, localitem.Owner, itemID, folderID, out message);
  1080. if (copyItem == null)
  1081. throw new Exception("Failed to find notecard item" + notecardID.ToString());
  1082. m_log.InfoFormat("[CAPS]: CopyInventoryFromNotecard, ItemID:{0}, FolderID:{1}", copyItem.ID, copyItem.Folder);
  1083. if (client != null)
  1084. client.SendBulkUpdateInventory(copyItem);
  1085. return;
  1086. }
  1087. if (!notecardID.IsZero())
  1088. {
  1089. InventoryItemBase noteItem = m_Scene.InventoryService.GetItem(agentID, notecardID);
  1090. if (noteItem == null || noteItem.AssetID.IsZero())
  1091. throw new Exception("Failed to find notecard item" + notecardID.ToString());
  1092. noteAssetID = noteItem.AssetID;
  1093. }
  1094. }
  1095. AssetBase noteAsset = m_Scene.AssetService.Get(noteAssetID.ToString());
  1096. if (noteAsset == null || noteAsset.Type != (sbyte)AssetType.Notecard)
  1097. throw new Exception("Failed to find the notecard asset" + notecardID.ToString());
  1098. InventoryItemBase item = SLUtil.GetEmbeddedItem(noteAsset.Data, itemID);
  1099. if(item == null)
  1100. throw new Exception("Failed to find the notecard item" + notecardID.ToString());
  1101. if (!m_Scene.Permissions.CanTransferUserInventory(itemID, item.Owner, agentID))
  1102. throw new Exception("Notecard item permissions check fail" + notecardID.ToString());
  1103. if (!m_Scene.Permissions.BypassPermissions())
  1104. {
  1105. if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
  1106. throw new Exception("Notecard item permissions check fail" + notecardID.ToString());
  1107. }
  1108. // check if we do have the item asset
  1109. noteAsset = m_Scene.AssetService.Get(item.AssetID.ToString());
  1110. if (noteAsset == null)
  1111. throw new Exception("Failed to find the notecard " + notecardID.ToString() +" item asset");
  1112. // find where to put it
  1113. InventoryFolderBase folder = null;
  1114. if (!folderID.IsZero())
  1115. folder = m_Scene.InventoryService.GetFolder(agentID, folderID);
  1116. if (folder == null && Enum.IsDefined(typeof(FolderType), (sbyte)item.AssetType))
  1117. folder = m_Scene.InventoryService.GetFolderForType(agentID, (FolderType)item.AssetType);
  1118. if (folder == null)
  1119. folder = m_Scene.InventoryService.GetRootFolder(agentID);
  1120. if (folder == null)
  1121. throw new Exception("Failed to find a folder for the notecard item" + notecardID.ToString());
  1122. item.Folder = folder.ID;
  1123. // do change owner permissions (c&p from scene inventory code)
  1124. if (m_Scene.Permissions.PropagatePermissions() && item.Owner != agentID)
  1125. {
  1126. uint permsMask = ~((uint)PermissionMask.Copy |
  1127. (uint)PermissionMask.Transfer |
  1128. (uint)PermissionMask.Modify |
  1129. (uint)PermissionMask.Export);
  1130. uint nextPerms = permsMask | (item.NextPermissions &
  1131. ((uint)PermissionMask.Copy |
  1132. (uint)PermissionMask.Transfer |
  1133. (uint)PermissionMask.Modify));
  1134. if (nextPerms == permsMask)
  1135. nextPerms |= (uint)PermissionMask.Transfer;
  1136. uint basePerms = item.BasePermissions | (uint)PermissionMask.Move;
  1137. uint ownerPerms = item.CurrentPermissions;
  1138. uint foldedPerms = (item.CurrentPermissions & (uint)PermissionMask.FoldedMask) << (int)PermissionMask.FoldingShift;
  1139. if (foldedPerms != 0 && item.InvType == (int)InventoryType.Object)
  1140. {
  1141. foldedPerms |= permsMask;
  1142. bool isRootMod = (item.CurrentPermissions &
  1143. (uint)PermissionMask.Modify) != 0 ?
  1144. true : false;
  1145. ownerPerms &= foldedPerms;
  1146. basePerms &= foldedPerms;
  1147. if (isRootMod)
  1148. {
  1149. ownerPerms |= (uint)PermissionMask.Modify;
  1150. basePerms |= (uint)PermissionMask.Modify;
  1151. }
  1152. }
  1153. ownerPerms &= nextPerms;
  1154. basePerms &= nextPerms;
  1155. basePerms &= ~(uint)PermissionMask.FoldedMask;
  1156. basePerms |= ((basePerms >> 13) & 7) | (((basePerms & (uint)PermissionMask.Export) != 0) ? (uint)PermissionMask.FoldedExport : 0);
  1157. item.BasePermissions = basePerms;
  1158. item.CurrentPermissions = ownerPerms;
  1159. item.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
  1160. item.Flags &= ~(uint)(InventoryItemFlags.ObjectOverwriteBase | InventoryItemFlags.ObjectOverwriteOwner | InventoryItemFlags.ObjectOverwriteGroup | InventoryItemFlags.ObjectOverwriteEveryone | InventoryItemFlags.ObjectOverwriteNextOwner);
  1161. item.NextPermissions = item.NextPermissions;
  1162. item.EveryOnePermissions = item.EveryOnePermissions & nextPerms;
  1163. }
  1164. else
  1165. {
  1166. //??
  1167. item.EveryOnePermissions &= item.NextPermissions;
  1168. }
  1169. item.GroupPermissions = 0; // we killed the group
  1170. item.Owner = agentID;
  1171. if (!m_Scene.InventoryService.AddItem(item))
  1172. throw new Exception("Failed create the notecard item" + notecardID.ToString());
  1173. m_log.InfoFormat("[CAPS]: CopyInventoryFromNotecard, ItemID:{0} FolderID:{1}", item.ID, item.Folder);
  1174. if (client != null)
  1175. client.SendBulkUpdateInventory(item);
  1176. return;
  1177. }
  1178. catch (Exception e)
  1179. {
  1180. m_log.ErrorFormat("[CAPS]: CopyInventoryFromNotecard : {0}", e.Message);
  1181. copyItem = null;
  1182. }
  1183. if(copyItem == null)
  1184. {
  1185. if (client != null)
  1186. client.SendAlertMessage("Failed to retrieve item");
  1187. httpResponse.StatusCode = (int)HttpStatusCode.BadRequest;
  1188. }
  1189. }
  1190. public void GetObjectPhysicsData(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap req)
  1191. {
  1192. OSDArray object_ids;
  1193. try
  1194. {
  1195. object_ids = (OSDArray)req["object_ids"];
  1196. }
  1197. catch
  1198. {
  1199. httpResponse.StatusCode = (int)HttpStatusCode.BadRequest;
  1200. return;
  1201. }
  1202. osUTF8 lsl = LLSDxmlEncode2.Start();
  1203. if(object_ids.Count == 0)
  1204. LLSDxmlEncode2.AddEmptyMap(lsl);
  1205. else
  1206. {
  1207. LLSDxmlEncode2.AddMap(lsl);
  1208. for (int i = 0 ; i < object_ids.Count ; i++)
  1209. {
  1210. UUID uuid = object_ids[i].AsUUID();
  1211. SceneObjectPart obj = m_Scene.GetSceneObjectPart(uuid);
  1212. if (obj != null)
  1213. {
  1214. LLSDxmlEncode2.AddMap(uuid.ToString(),lsl);
  1215. LLSDxmlEncode2.AddElem("PhysicsShapeType", obj.PhysicsShapeType, lsl);
  1216. LLSDxmlEncode2.AddElem("Density", obj.Density, lsl);
  1217. LLSDxmlEncode2.AddElem("Friction", obj.Friction, lsl);
  1218. LLSDxmlEncode2.AddElem("Restitution", obj.Restitution, lsl);
  1219. LLSDxmlEncode2.AddElem("GravityMultiplier", obj.GravityModifier, lsl);
  1220. LLSDxmlEncode2.AddEndMap(lsl);
  1221. }
  1222. LLSDxmlEncode2.AddEndMap(lsl);
  1223. }
  1224. }
  1225. httpResponse.RawBuffer = LLSDxmlEncode2.EndToNBBytes(lsl);
  1226. httpResponse.StatusCode = (int)HttpStatusCode.OK;
  1227. }
  1228. public void GetObjectCost(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap req)
  1229. {
  1230. OSDArray object_ids;
  1231. try
  1232. {
  1233. object_ids = (OSDArray)req["object_ids"];
  1234. }
  1235. catch
  1236. {
  1237. httpResponse.StatusCode = (int)HttpStatusCode.BadRequest;
  1238. return;
  1239. }
  1240. osUTF8 lsl = LLSDxmlEncode2.Start(512);
  1241. if(object_ids.Count == 0)
  1242. LLSDxmlEncode2.AddEmptyMap(lsl);
  1243. else
  1244. {
  1245. bool haveone = false;
  1246. LLSDxmlEncode2.AddMap(lsl);
  1247. for (int i = 0; i < object_ids.Count; i++)
  1248. {
  1249. UUID uuid = object_ids[i].AsUUID();
  1250. SceneObjectPart part = m_Scene.GetSceneObjectPart(uuid);
  1251. SceneObjectGroup grp = null;
  1252. if (part != null)
  1253. grp = part.ParentGroup;
  1254. if (grp != null)
  1255. {
  1256. haveone = true;
  1257. grp.GetResourcesCosts(part, out float linksetCost, out float linksetPhysCost, out float partCost, out float partPhysCost);
  1258. LLSDxmlEncode2.AddMap(uuid.ToString(), lsl);
  1259. LLSDxmlEncode2.AddElem("linked_set_resource_cost", linksetCost, lsl);
  1260. LLSDxmlEncode2.AddElem("resource_cost", partCost, lsl);
  1261. LLSDxmlEncode2.AddElem("physics_cost", partPhysCost, lsl);
  1262. LLSDxmlEncode2.AddElem("linked_set_physics_cost", linksetPhysCost, lsl);
  1263. LLSDxmlEncode2.AddElem("resource_limiting_type", "legacy", lsl);
  1264. LLSDxmlEncode2.AddEndMap(lsl);
  1265. }
  1266. }
  1267. if(!haveone)
  1268. {
  1269. LLSDxmlEncode2.AddMap(UUID.Zero.ToString(), lsl);
  1270. LLSDxmlEncode2.AddElem("linked_set_resource_cost", 0, lsl);
  1271. LLSDxmlEncode2.AddElem("resource_cost", 0, lsl);
  1272. LLSDxmlEncode2.AddElem("physics_cost", 0, lsl);
  1273. LLSDxmlEncode2.AddElem("linked_set_physics_cost", 0, lsl);
  1274. LLSDxmlEncode2.AddElem("resource_limiting_type", "legacy", lsl);
  1275. LLSDxmlEncode2.AddEndMap(lsl);
  1276. }
  1277. LLSDxmlEncode2.AddEndMap(lsl);
  1278. }
  1279. httpResponse.RawBuffer = LLSDxmlEncode2.EndToNBBytes(lsl);
  1280. httpResponse.StatusCode = (int)HttpStatusCode.OK;
  1281. }
  1282. public struct AttachmentScriptInfo
  1283. {
  1284. public UUID id;
  1285. public string name;
  1286. public Vector3 pos;
  1287. public int memory;
  1288. public int urls;
  1289. };
  1290. public void AttachmentResources(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
  1291. {
  1292. if(m_Scene.TryGetScenePresence(m_AgentID, out ScenePresence sp) && !sp.IsChildAgent && !sp.IsDeleted && !sp.IsInTransit)
  1293. {
  1294. int totalmem = 0;
  1295. int totalurls = 0;
  1296. List<SceneObjectGroup> atts = sp.GetAttachments();
  1297. Dictionary<byte, List<AttachmentScriptInfo>> perAttPoints = null;
  1298. if (atts.Count > 0)
  1299. {
  1300. IUrlModule urlModule = m_Scene.RequestModuleInterface<IUrlModule>();
  1301. perAttPoints = new Dictionary<byte, List<AttachmentScriptInfo>>();
  1302. foreach (SceneObjectGroup so in atts)
  1303. {
  1304. byte attp = so.GetAttachmentPoint();
  1305. if(!so.ScriptsMemory(out int mem))
  1306. continue;
  1307. int urls_used = 0;
  1308. totalmem += mem;
  1309. if (urlModule != null)
  1310. {
  1311. urls_used = urlModule.GetUrlCount(so.UUID);
  1312. totalurls += urls_used;
  1313. }
  1314. AttachmentScriptInfo info = new AttachmentScriptInfo()
  1315. {
  1316. id = so.UUID,
  1317. name = so.Name,
  1318. memory = mem,
  1319. urls = urls_used,
  1320. pos = so.AbsolutePosition
  1321. };
  1322. if(perAttPoints.TryGetValue(attp, out List<AttachmentScriptInfo> la))
  1323. la.Add(info);
  1324. else
  1325. perAttPoints[attp] = new List<AttachmentScriptInfo>(){ info };
  1326. }
  1327. }
  1328. osUTF8 sb = LLSDxmlEncode2.Start();
  1329. LLSDxmlEncode2.AddMap(sb);
  1330. if (atts.Count > 0)
  1331. {
  1332. LLSDxmlEncode2.AddArray("attachments", sb);
  1333. foreach (KeyValuePair<byte, List<AttachmentScriptInfo>> kvp in perAttPoints)
  1334. {
  1335. LLSDxmlEncode2.AddMap(sb);
  1336. LLSDxmlEncode2.AddElem("location", SLUtil.GetAttachmentName(kvp.Key), sb);
  1337. LLSDxmlEncode2.AddArray("objects", sb);
  1338. foreach(AttachmentScriptInfo asi in kvp.Value)
  1339. {
  1340. LLSDxmlEncode2.AddMap(sb);
  1341. LLSDxmlEncode2.AddElem("id", asi.id, sb);
  1342. LLSDxmlEncode2.AddElem("is_group_owned", (int)0, sb);
  1343. LLSDxmlEncode2.AddElem("location", asi.pos, sb);
  1344. LLSDxmlEncode2.AddElem("name", asi.name, sb);
  1345. LLSDxmlEncode2.AddElem("owner_id", m_AgentID, sb);
  1346. LLSDxmlEncode2.AddMap("resources", sb);
  1347. if (asi.memory > 0)
  1348. LLSDxmlEncode2.AddElem("memory", asi.memory, sb);
  1349. if (asi.urls > 0)
  1350. LLSDxmlEncode2.AddElem("urls", asi.urls, sb);
  1351. LLSDxmlEncode2.AddEndMap(sb);
  1352. LLSDxmlEncode2.AddEndMap(sb);
  1353. }
  1354. LLSDxmlEncode2.AddEndArray(sb);
  1355. LLSDxmlEncode2.AddEndMap(sb);
  1356. }
  1357. LLSDxmlEncode2.AddEndArray(sb); //attachments
  1358. }
  1359. else
  1360. LLSDxmlEncode2.AddEmptyArray("attachments", sb);
  1361. LLSDxmlEncode2.AddMap("summary", sb);
  1362. LLSDxmlEncode2.AddArray("available", sb);
  1363. int maxurls = totalurls <= 38? 38: totalurls; // we don't limit this
  1364. LLSDxmlEncode2.AddMap(sb);
  1365. LLSDxmlEncode2.AddElem("amount", maxurls, sb);
  1366. LLSDxmlEncode2.AddElem("type", "urls", sb);
  1367. LLSDxmlEncode2.AddEndMap(sb);
  1368. LLSDxmlEncode2.AddMap(sb);
  1369. LLSDxmlEncode2.AddElem("amount", (int)-1, sb);
  1370. LLSDxmlEncode2.AddElem("type", "memory", sb);
  1371. LLSDxmlEncode2.AddEndMap(sb);
  1372. LLSDxmlEncode2.AddEndArray(sb); //available
  1373. LLSDxmlEncode2.AddArray("used", sb);
  1374. LLSDxmlEncode2.AddMap(sb);
  1375. LLSDxmlEncode2.AddElem("amount",totalurls, sb);
  1376. LLSDxmlEncode2.AddElem("type", "urls", sb);
  1377. LLSDxmlEncode2.AddEndMap(sb);
  1378. LLSDxmlEncode2.AddMap(sb);
  1379. LLSDxmlEncode2.AddElem("amount", totalmem, sb);
  1380. LLSDxmlEncode2.AddElem("type", "memory", sb);
  1381. LLSDxmlEncode2.AddEndMap(sb);
  1382. LLSDxmlEncode2.AddEndArray(sb); //used
  1383. LLSDxmlEncode2.AddEndMap(sb); // summary
  1384. LLSDxmlEncode2.AddEndMap(sb);
  1385. httpResponse.RawBuffer = LLSDxmlEncode2.EndToNBBytes(sb);
  1386. httpResponse.StatusCode = (int)HttpStatusCode.OK;
  1387. return;
  1388. }
  1389. httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
  1390. }
  1391. public class ScriptInfoForParcel
  1392. {
  1393. public UUID id;
  1394. public UUID owner;
  1395. public string name;
  1396. public int memory;
  1397. public int urls;
  1398. public bool groupOwned;
  1399. public Vector3 pos;
  1400. };
  1401. public class ParcelScriptInfo
  1402. {
  1403. public UUID id;
  1404. public string name;
  1405. public int localID;
  1406. public List<ScriptInfoForParcel> objects;
  1407. };
  1408. public void LandResources(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap req)
  1409. {
  1410. if (!m_Scene.TryGetScenePresence(m_AgentID, out ScenePresence sp))
  1411. {
  1412. httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
  1413. return;
  1414. }
  1415. UUID parcelOwner;
  1416. LandData landdata = null;
  1417. ulong myHandler = m_Scene.RegionInfo.RegionHandle;
  1418. if (req.TryGetValue("parcel_id", out OSD tmp) && tmp is OSDUUID)
  1419. {
  1420. UUID parcelID = tmp.AsUUID();
  1421. if (Util.ParseFakeParcelID(parcelID, out ulong regionHandle, out uint x, out uint y) && regionHandle == myHandler)
  1422. {
  1423. ILandObject land = m_Scene.LandChannel.GetLandObjectClippedXY(x, y);
  1424. if (land != null)
  1425. landdata = land.LandData;
  1426. land = null;
  1427. }
  1428. }
  1429. if(landdata == null)
  1430. {
  1431. httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
  1432. return;
  1433. }
  1434. parcelOwner = landdata.OwnerID;
  1435. int showType = 0;
  1436. if (sp.IsGod || m_Scene.Permissions.IsEstateManager(m_AgentID))
  1437. showType = 1;
  1438. else
  1439. {
  1440. if (parcelOwner == m_AgentID)
  1441. showType = 2;
  1442. else if (!landdata.GroupID.IsZero())
  1443. {
  1444. ulong powers = sp.ControllingClient.GetGroupPowers(landdata.GroupID);
  1445. if ((powers & (ulong)(GroupPowers.ReturnGroupOwned | GroupPowers.ReturnGroupSet | GroupPowers.ReturnNonGroup)) != 0)
  1446. showType = 2;
  1447. }
  1448. }
  1449. landdata = null;
  1450. int totalmem = 0;
  1451. int totalurls = 0;
  1452. bool ownerparcels = showType != 1;
  1453. bool showdetail = showType != 0;
  1454. List<ParcelScriptInfo> parcelsInfo = null;
  1455. IUrlModule urlModule = m_Scene.RequestModuleInterface<IUrlModule>();
  1456. List<ILandObject> allParcels = m_Scene.LandChannel.AllParcels();
  1457. if (showdetail)
  1458. parcelsInfo = new List<ParcelScriptInfo>(allParcels.Count);
  1459. for (int p = 0; p < allParcels.Count; ++p)
  1460. {
  1461. ILandObject parcel = allParcels[p];
  1462. landdata = parcel.LandData;
  1463. if (landdata == null)
  1464. continue;
  1465. if(ownerparcels && landdata.OwnerID != parcelOwner)
  1466. continue;
  1467. ParcelScriptInfo pi = null;
  1468. if (showdetail)
  1469. {
  1470. pi = new ParcelScriptInfo
  1471. {
  1472. name = landdata.Name,
  1473. localID = landdata.LocalID,
  1474. id = landdata.FakeID,
  1475. objects = new List<ScriptInfoForParcel>()
  1476. };
  1477. }
  1478. ISceneObject[] isops = parcel.GetSceneObjectGroups();
  1479. for(int i = 0; i < isops.Length; ++i)
  1480. {
  1481. SceneObjectGroup so = isops[i] as SceneObjectGroup;
  1482. if(so == null || so.IsDeleted || so.inTransit || so.IsAttachment)
  1483. continue;
  1484. if(!so.ScriptsMemory(out int mem))
  1485. continue;
  1486. int urls_used = 0;
  1487. totalmem += mem;
  1488. if (urlModule != null)
  1489. {
  1490. urls_used = urlModule.GetUrlCount(so.UUID);
  1491. totalurls += urls_used;
  1492. }
  1493. if (showdetail)
  1494. {
  1495. ScriptInfoForParcel sip = new ScriptInfoForParcel()
  1496. {
  1497. id = so.UUID,
  1498. owner = so.OwnerID,
  1499. name = so.Name,
  1500. memory = mem,
  1501. urls = urls_used,
  1502. groupOwned = (so.OwnerID == so.GroupID),
  1503. pos = so.AbsolutePosition
  1504. };
  1505. pi.objects.Add(sip);
  1506. }
  1507. }
  1508. if (showdetail)
  1509. parcelsInfo.Add(pi);
  1510. }
  1511. landdata = null;
  1512. osUTF8 lsl = LLSDxmlEncode2.Start();
  1513. LLSDxmlEncode2.AddMap(lsl);
  1514. string baseurl = m_HostCapsObj.SSLCaps ? "https://" : "http://";
  1515. baseurl += m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString();
  1516. string SRSPath = GetNewCapPath();
  1517. ScriptResourceSummary srs =
  1518. new ScriptResourceSummary(m_Scene, m_AgentID, m_HostCapsObj.HttpListener, SRSPath, httpRequest.RemoteIPEndPoint.Address,
  1519. totalmem, totalurls);
  1520. m_HostCapsObj.HttpListener.AddSimpleStreamHandler(new SimpleStreamHandler(SRSPath, srs.ScriptResourceSummaryCap));
  1521. string SRSURL = baseurl + SRSPath;
  1522. LLSDxmlEncode2.AddElem("ScriptResourceSummary", SRSURL, lsl);
  1523. if(showdetail)
  1524. {
  1525. string SRDPath = GetNewCapPath();
  1526. string SRDURL = baseurl + SRDPath;
  1527. ScriptResourceDetails srd =
  1528. new ScriptResourceDetails(m_Scene, m_AgentID, m_HostCapsObj.HttpListener, SRDPath, httpRequest.RemoteIPEndPoint.Address,
  1529. parcelsInfo);
  1530. m_HostCapsObj.HttpListener.AddSimpleStreamHandler(new SimpleStreamHandler(SRDPath, srd.ScriptResourceDetailsCap));
  1531. LLSDxmlEncode2.AddElem("ScriptResourceDetails", SRDURL, lsl);
  1532. }
  1533. LLSDxmlEncode2.AddEndMap(lsl);
  1534. httpResponse.RawBuffer = LLSDxmlEncode2.EndToNBBytes(lsl);
  1535. httpResponse.StatusCode = (int)HttpStatusCode.OK;
  1536. return;
  1537. }
  1538. public void ResourceCostSelected(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap req)
  1539. {
  1540. float phys=0;
  1541. float stream=0;
  1542. float simul=0;
  1543. if (req.ContainsKey("selected_roots"))
  1544. {
  1545. OSDArray object_ids = (OSDArray)req["selected_roots"];
  1546. // should go by SOG suming costs for all parts
  1547. // ll v3 works ok with several objects select we get the list and adds ok
  1548. // FS calls per object so results are wrong guess fs bug
  1549. for (int i = 0; i < object_ids.Count; i++)
  1550. {
  1551. UUID uuid = object_ids[i].AsUUID();
  1552. float Physc;
  1553. float simulc;
  1554. float streamc;
  1555. SceneObjectGroup grp = m_Scene.GetGroupByPrim(uuid);
  1556. if (grp != null)
  1557. {
  1558. grp.GetSelectedCosts(out Physc, out streamc, out simulc);
  1559. phys += Physc;
  1560. stream += streamc;
  1561. simul += simulc;
  1562. }
  1563. }
  1564. }
  1565. else if (req.ContainsKey("selected_prims"))
  1566. {
  1567. OSDArray object_ids = (OSDArray)req["selected_prims"];
  1568. // don't see in use in any of the 2 viewers
  1569. // guess it should be for edit linked but... nothing
  1570. // should go to SOP per part
  1571. for (int i = 0; i < object_ids.Count; i++)
  1572. {
  1573. UUID uuid = object_ids[i].AsUUID();
  1574. SceneObjectPart part = m_Scene.GetSceneObjectPart(uuid);
  1575. if (part != null)
  1576. {
  1577. phys += part.PhysicsCost;
  1578. stream += part.StreamingCost;
  1579. simul += part.SimulationCost;
  1580. }
  1581. }
  1582. }
  1583. osUTF8 lsl = LLSDxmlEncode2.Start();
  1584. LLSDxmlEncode2.AddMap(lsl);
  1585. LLSDxmlEncode2.AddMap("selected", lsl);
  1586. LLSDxmlEncode2.AddElem("physics", phys, lsl);
  1587. LLSDxmlEncode2.AddElem("streaming", stream, lsl);
  1588. LLSDxmlEncode2.AddElem("simulation", simul, lsl);
  1589. LLSDxmlEncode2.AddEndMap(lsl);
  1590. LLSDxmlEncode2.AddEndMap(lsl);
  1591. // resp["transaction_id"] = "undef";
  1592. httpResponse.RawBuffer = LLSDxmlEncode2.EndToNBBytes(lsl);
  1593. httpResponse.StatusCode = (int)HttpStatusCode.OK;
  1594. }
  1595. public void UpdateAgentInformation(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
  1596. {
  1597. if (httpRequest.HttpMethod != "POST")
  1598. {
  1599. httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
  1600. return;
  1601. }
  1602. // this is wrong now ignores request and sends same result for all
  1603. // we don't store and worse don't use that to filter contents
  1604. // OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
  1605. OSDMap resp = new OSDMap();
  1606. OSDMap accessPrefs = new OSDMap();
  1607. accessPrefs["max"] = "A";
  1608. resp["access_prefs"] = accessPrefs;
  1609. httpResponse.RawBuffer = OSDParser.SerializeLLSDXmlBytes(resp);
  1610. httpResponse.StatusCode = (int)HttpStatusCode.OK;
  1611. }
  1612. public bool OSDMapTOVector3(OSDMap map, out Vector3 v)
  1613. {
  1614. v = Vector3.Zero;
  1615. if(!map.ContainsKey("X"))
  1616. return false;
  1617. if(!map.ContainsKey("Y"))
  1618. return false;
  1619. if(!map.ContainsKey("Z"))
  1620. return false;
  1621. v.X = (float)map["X"].AsReal();
  1622. v.Y = (float)map["Y"].AsReal();
  1623. v.Z = (float)map["Z"].AsReal();
  1624. return true;
  1625. }
  1626. public void HomeLocation(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
  1627. {
  1628. if (httpRequest.HttpMethod != "POST")
  1629. {
  1630. httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
  1631. return;
  1632. }
  1633. bool fail = true;
  1634. string message = "Set Home request failed";
  1635. //int locationID = 1;
  1636. Vector3 pos = Vector3.Zero;
  1637. Vector3 lookAt = Vector3.Zero;
  1638. IClientAPI client = null;
  1639. ScenePresence sp;
  1640. while(true)
  1641. {
  1642. if(m_Scene.GridUserService == null)
  1643. break;
  1644. if(m_Scene.UserManagementModule == null)
  1645. break;
  1646. m_Scene.TryGetScenePresence(m_AgentID, out sp);
  1647. if(sp == null || sp.IsChildAgent || sp.IsDeleted)
  1648. break;
  1649. if(sp.IsInTransit && !sp.IsInLocalTransit)
  1650. break;
  1651. client = sp.ControllingClient;
  1652. if(!m_Scene.UserManagementModule.IsLocalGridUser(m_AgentID))
  1653. break;
  1654. OSDMap req;
  1655. try
  1656. {
  1657. req = (OSDMap)OSDParser.DeserializeLLSDXml(httpRequest.InputStream);
  1658. }
  1659. catch
  1660. {
  1661. httpResponse.StatusCode = (int)HttpStatusCode.BadRequest;
  1662. return;
  1663. }
  1664. OSD tmp;
  1665. if (!req.TryGetValue("HomeLocation", out tmp) || !(tmp is OSDMap))
  1666. break;
  1667. OSDMap HLocation = (OSDMap)tmp;
  1668. if(!HLocation.TryGetValue("LocationPos", out tmp) || !(tmp is OSDMap))
  1669. break;
  1670. if (!OSDMapTOVector3((OSDMap)tmp, out pos))
  1671. break;
  1672. if (!HLocation.TryGetValue("LocationLookAt", out tmp) || !(tmp is OSDMap))
  1673. break;
  1674. if (!OSDMapTOVector3((OSDMap)tmp, out lookAt))
  1675. break;
  1676. //locationID = HLocation["LocationId"].AsInteger();
  1677. ILandObject land = m_Scene.LandChannel.GetLandObject(pos);
  1678. if(land == null)
  1679. break;
  1680. ulong gpowers = client.GetGroupPowers(land.LandData.GroupID);
  1681. SceneObjectGroup telehub = null;
  1682. if (!m_Scene.RegionInfo.RegionSettings.TelehubObject.IsZero())
  1683. // Does the telehub exist in the scene?
  1684. telehub = m_Scene.GetSceneObjectGroup(m_Scene.RegionInfo.RegionSettings.TelehubObject);
  1685. if (!m_Scene.Permissions.IsAdministrator(m_AgentID) && // (a) gods and land managers can set home
  1686. !m_Scene.Permissions.IsGod(m_AgentID) &&
  1687. m_AgentID != land.LandData.OwnerID && // (b) land owners can set home
  1688. // (c) members of the land-associated group in roles that can set home
  1689. ((gpowers & (ulong)GroupPowers.AllowSetHome) != (ulong)GroupPowers.AllowSetHome) &&
  1690. // (d) parcels with telehubs can be the home of anyone
  1691. (telehub == null || !land.ContainsPoint((int)telehub.AbsolutePosition.X, (int)telehub.AbsolutePosition.Y)))
  1692. {
  1693. message = "You are not allowed to set your home location in this parcel.";
  1694. break;
  1695. }
  1696. string userId;
  1697. UUID test;
  1698. if (!m_Scene.UserManagementModule.GetUserUUI(m_AgentID, out userId))
  1699. {
  1700. message = "Set Home request failed. (User Lookup)";
  1701. break;
  1702. }
  1703. if (!UUID.TryParse(userId, out test))
  1704. {
  1705. message = "Set Home request failed. (HG visitor)";
  1706. break;
  1707. }
  1708. if (m_Scene.GridUserService.SetHome(userId, land.RegionUUID, pos, lookAt))
  1709. fail = false;
  1710. break;
  1711. }
  1712. OSDMap resp = new OSDMap();
  1713. if(fail)
  1714. {
  1715. if(client != null)
  1716. client.SendAlertMessage(message);
  1717. resp["success"] = "false";
  1718. }
  1719. else
  1720. {
  1721. // so its http but still needs a udp reply to inform user? crap :p
  1722. if(client != null)
  1723. client.SendAlertMessage("Home position set.","HomePositionSet");
  1724. resp["success"] = "true";
  1725. OSDMap homeloc = new OSDMap();
  1726. OSDMap homelocpos = new OSDMap();
  1727. // for some odd reason viewers send pos as reals but read as integer
  1728. homelocpos["X"] = new OSDReal(pos.X);
  1729. homelocpos["Y"] = new OSDReal(pos.Y);
  1730. homelocpos["Z"] = new OSDReal(pos.Z);
  1731. homeloc["LocationPos"] = homelocpos;
  1732. resp["HomeLocation"] = homeloc;
  1733. }
  1734. httpResponse.RawBuffer = Util.UTF8NBGetbytes(OSDParser.SerializeLLSDXmlString(resp));
  1735. httpResponse.StatusCode = (int)HttpStatusCode.OK;
  1736. }
  1737. private static int CompareRolesByMembersDesc(GroupRolesData x, GroupRolesData y)
  1738. {
  1739. return -(x.Members.CompareTo(y.Members));
  1740. }
  1741. public void GroupMemberData(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
  1742. {
  1743. if (httpRequest.HttpMethod != "POST")
  1744. {
  1745. httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
  1746. return;
  1747. }
  1748. OSDMap resp = new OSDMap();
  1749. bool fail = true;
  1750. IClientAPI client = null;
  1751. ScenePresence sp;
  1752. IGroupsModule m_GroupsModule;
  1753. UUID groupID = UUID.Zero;
  1754. while(true)
  1755. {
  1756. m_GroupsModule = m_Scene.RequestModuleInterface<IGroupsModule>();
  1757. if(m_GroupsModule == null)
  1758. break;
  1759. m_Scene.TryGetScenePresence(m_AgentID, out sp);
  1760. if(sp == null || sp.IsChildAgent || sp.IsDeleted)
  1761. break;
  1762. if(sp.IsInTransit && !sp.IsInLocalTransit)
  1763. break;
  1764. client = sp.ControllingClient;
  1765. OSDMap req;
  1766. try
  1767. {
  1768. req = (OSDMap)OSDParser.DeserializeLLSDXml(httpRequest.InputStream);
  1769. }
  1770. catch
  1771. {
  1772. httpResponse.StatusCode = (int)HttpStatusCode.BadRequest;
  1773. return;
  1774. }
  1775. OSD tmp;
  1776. if(!req.TryGetValue("group_id", out tmp) || !(tmp is OSDUUID))
  1777. break;
  1778. groupID = tmp.AsUUID();
  1779. if(groupID.IsZero())
  1780. break;
  1781. List<GroupRolesData> roles = m_GroupsModule.GroupRoleDataRequest(client, groupID);
  1782. if(roles == null || roles.Count == 0)
  1783. break;
  1784. List<GroupMembersData> members = m_GroupsModule.GroupMembersRequest(client, groupID);
  1785. if(members == null || members.Count == 0)
  1786. break;
  1787. int memberCount = members.Count;
  1788. Dictionary<string,int> titles = new Dictionary<string,int>();
  1789. int i = 0;
  1790. ulong defaultPowers = 0;
  1791. // build titles array and index
  1792. roles.Sort(CompareRolesByMembersDesc);
  1793. OSDArray osdtitles = new OSDArray();
  1794. foreach(GroupRolesData grd in roles)
  1795. {
  1796. if(grd.Title == null)
  1797. continue;
  1798. string title = grd.Title;
  1799. if(i==0)
  1800. defaultPowers = grd.Powers;
  1801. if(!titles.ContainsKey(title))
  1802. {
  1803. titles[title] = i++;
  1804. osdtitles.Add(new OSDString(title));
  1805. }
  1806. }
  1807. if(titles.Count == 0)
  1808. break;
  1809. OSDMap osdmembers = new OSDMap();
  1810. foreach(GroupMembersData gmd in members)
  1811. {
  1812. OSDMap m = new OSDMap();
  1813. if(gmd.OnlineStatus != null && gmd.OnlineStatus != "")
  1814. m["last_login"] = new OSDString(gmd.OnlineStatus);
  1815. if(gmd.AgentPowers != defaultPowers)
  1816. m["powers"] = new OSDString((gmd.AgentPowers).ToString("X"));
  1817. if(gmd.Title != null && titles.ContainsKey(gmd.Title) && titles[gmd.Title] != 0)
  1818. m["title"] = new OSDInteger(titles[gmd.Title]);
  1819. if(gmd.IsOwner)
  1820. m["owner"] = new OSDString("true");
  1821. if(gmd.Contribution != 0)
  1822. m["donated_square_meters"] = new OSDInteger(gmd.Contribution);
  1823. osdmembers[(gmd.AgentID).ToString()] = m;
  1824. }
  1825. OSDMap osddefaults = new OSDMap();
  1826. osddefaults["default_powers"] = new OSDString(defaultPowers.ToString("X"));
  1827. resp["group_id"] = new OSDUUID(groupID);
  1828. resp["agent_id"] = new OSDUUID(m_AgentID);
  1829. resp["member_count"] = new OSDInteger(memberCount);
  1830. resp["defaults"] = osddefaults;
  1831. resp["titles"] = osdtitles;
  1832. resp["members"] = osdmembers;
  1833. fail = false;
  1834. break;
  1835. }
  1836. if(fail)
  1837. {
  1838. resp["group_id"] = new OSDUUID(groupID);
  1839. resp["agent_id"] = new OSDUUID(m_AgentID);
  1840. resp["member_count"] = new OSDInteger(0);
  1841. resp["defaults"] = new OSDMap();
  1842. resp["titles"] = new OSDArray();
  1843. resp["members"] = new OSDMap();
  1844. }
  1845. httpResponse.RawBuffer = Util.UTF8NBGetbytes(OSDParser.SerializeLLSDXmlString(resp));
  1846. httpResponse.StatusCode = (int)HttpStatusCode.OK;
  1847. }
  1848. public void GetDisplayNames(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
  1849. {
  1850. if (httpRequest.HttpMethod != "GET")
  1851. {
  1852. httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
  1853. return;
  1854. }
  1855. ScenePresence sp = m_Scene.GetScenePresence(m_AgentID);
  1856. if(sp == null || sp.IsDeleted)
  1857. {
  1858. httpResponse.StatusCode = (int)HttpStatusCode.Gone;
  1859. return;
  1860. }
  1861. if(sp.IsInTransit && !sp.IsInLocalTransit)
  1862. {
  1863. httpResponse.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
  1864. httpResponse.AddHeader("Retry-After","30");
  1865. return;
  1866. }
  1867. // Full content request
  1868. NameValueCollection query = httpRequest.QueryString;
  1869. string[] ids = query.GetValues("ids");
  1870. osUTF8 lsl;
  1871. if(ids.Length == 0)
  1872. {
  1873. lsl = LLSDxmlEncode2.Start();
  1874. LLSDxmlEncode2.AddMap(lsl);
  1875. LLSDxmlEncode2.AddEmptyArray("agents", lsl);
  1876. }
  1877. else
  1878. {
  1879. List<UserData> names = m_UserManager.GetKnownUsers(ids, m_scopeID);
  1880. lsl = LLSDxmlEncode2.Start(names.Count * 256 + 256);
  1881. LLSDxmlEncode2.AddMap(lsl);
  1882. if (names.Count == 0)
  1883. LLSDxmlEncode2.AddEmptyArray("agents", lsl);
  1884. else
  1885. {
  1886. LLSDxmlEncode2.AddArray("agents", lsl);
  1887. foreach (UserData ud in names)
  1888. {
  1889. // dont tell about unknown users, we can't send them back on Bad either
  1890. if (string.IsNullOrEmpty(ud.FirstName) || ud.FirstName.Equals("Unkown"))
  1891. continue;
  1892. string fullname = ud.FirstName + " " + ud.LastName;
  1893. LLSDxmlEncode2.AddMap(lsl);
  1894. LLSDxmlEncode2.AddElem("username", fullname, lsl);
  1895. LLSDxmlEncode2.AddElem("display_name", fullname, lsl);
  1896. LLSDxmlEncode2.AddElem("display_name_next_update", DateTime.UtcNow.AddDays(8), lsl);
  1897. LLSDxmlEncode2.AddElem("display_name_expires", DateTime.UtcNow.AddMonths(1), lsl);
  1898. LLSDxmlEncode2.AddElem("legacy_first_name", ud.FirstName, lsl);
  1899. LLSDxmlEncode2.AddElem("legacy_last_name", ud.LastName, lsl);
  1900. LLSDxmlEncode2.AddElem("id", ud.Id, lsl);
  1901. LLSDxmlEncode2.AddElem("is_display_name_default", true, lsl);
  1902. LLSDxmlEncode2.AddEndMap(lsl);
  1903. }
  1904. LLSDxmlEncode2.AddEndArray(lsl);
  1905. }
  1906. }
  1907. LLSDxmlEncode2.AddEndMap(lsl);
  1908. httpResponse.RawBuffer = LLSDxmlEncode2.EndToNBBytes(lsl);
  1909. httpResponse.ContentType = "application/llsd+xml";
  1910. httpResponse.StatusCode = (int)HttpStatusCode.OK;
  1911. }
  1912. public class AssetUploader
  1913. {
  1914. private static readonly ILog m_log =
  1915. LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  1916. public event UpLoadedAsset OnUpLoad;
  1917. private UpLoadedAsset handlerUpLoad = null;
  1918. private string uploaderPath = String.Empty;
  1919. private UUID newAssetID;
  1920. private UUID inventoryItemID;
  1921. private UUID parentFolder;
  1922. private IHttpServer httpListener;
  1923. private bool m_dumpAssetsToFile;
  1924. private string m_assetName = String.Empty;
  1925. private string m_assetDes = String.Empty;
  1926. private string m_invType = String.Empty;
  1927. private string m_assetType = String.Empty;
  1928. private int m_cost;
  1929. private string m_error = String.Empty;
  1930. private System.Timers.Timer m_timeoutTimer;
  1931. private UUID m_texturesFolder;
  1932. private int m_nreqtextures;
  1933. private int m_nreqmeshs;
  1934. private int m_nreqinstances;
  1935. private bool m_IsAtestUpload;
  1936. private int m_nextOwnerMask;
  1937. private int m_groupMask;
  1938. private int m_everyoneMask;
  1939. private int[] m_meshesSides;
  1940. public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem,
  1941. UUID parentFolderID, string invType, string assetType, string path,
  1942. IHttpServer httpServer, bool dumpAssetsToFile,
  1943. int totalCost, UUID texturesFolder, int nreqtextures, int nreqmeshs, int nreqinstances,
  1944. bool IsAtestUpload, int nextOwnerMask, int groupMask, int everyoneMask, int[] meshesSides)
  1945. {
  1946. m_assetName = assetName;
  1947. m_assetDes = description;
  1948. newAssetID = assetID;
  1949. inventoryItemID = inventoryItem;
  1950. uploaderPath = path;
  1951. httpListener = httpServer;
  1952. parentFolder = parentFolderID;
  1953. m_assetType = assetType;
  1954. m_invType = invType;
  1955. m_dumpAssetsToFile = dumpAssetsToFile;
  1956. m_cost = totalCost;
  1957. m_texturesFolder = texturesFolder;
  1958. m_nreqtextures = nreqtextures;
  1959. m_nreqmeshs = nreqmeshs;
  1960. m_nreqinstances = nreqinstances;
  1961. m_IsAtestUpload = IsAtestUpload;
  1962. m_timeoutTimer = new System.Timers.Timer();
  1963. m_timeoutTimer.Elapsed += TimedOut;
  1964. m_timeoutTimer.Interval = 120000;
  1965. m_timeoutTimer.AutoReset = false;
  1966. m_timeoutTimer.Start();
  1967. m_nextOwnerMask = nextOwnerMask;
  1968. m_groupMask = groupMask;
  1969. m_everyoneMask = everyoneMask;
  1970. m_meshesSides = meshesSides;
  1971. }
  1972. /// <summary>
  1973. /// Handle raw asset upload data via the capability.
  1974. /// </summary>
  1975. /// <param name="data"></param>
  1976. /// <param name="path"></param>
  1977. /// <param name="param"></param>
  1978. /// <returns></returns>
  1979. public string uploaderCaps(byte[] data, string path, string param)
  1980. {
  1981. UUID inv = inventoryItemID;
  1982. string res = String.Empty;
  1983. LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
  1984. /*
  1985. uploadComplete.new_asset = newAssetID.ToString();
  1986. uploadComplete.new_inventory_item = inv;
  1987. uploadComplete.state = "complete";
  1988. res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
  1989. */
  1990. m_timeoutTimer.Stop();
  1991. httpListener.RemoveStreamHandler("POST", uploaderPath);
  1992. // TODO: probably make this a better set of extensions here
  1993. string extension = ".jp2";
  1994. if (m_invType != "image")
  1995. {
  1996. extension = ".dat";
  1997. }
  1998. if (m_dumpAssetsToFile)
  1999. {
  2000. SaveAssetToFile(m_assetName + extension, data);
  2001. }
  2002. handlerUpLoad = OnUpLoad;
  2003. if (handlerUpLoad != null)
  2004. {
  2005. handlerUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType,
  2006. m_cost, m_texturesFolder, m_nreqtextures, m_nreqmeshs, m_nreqinstances, m_IsAtestUpload,
  2007. ref m_error, ref m_nextOwnerMask, ref m_groupMask, ref m_everyoneMask, m_meshesSides);
  2008. }
  2009. uploadComplete.new_next_owner_mask = m_nextOwnerMask;
  2010. uploadComplete.new_group_mask = m_groupMask;
  2011. uploadComplete.new_everyone_mask = m_everyoneMask;
  2012. if (m_error == String.Empty)
  2013. {
  2014. uploadComplete.new_asset = newAssetID.ToString();
  2015. uploadComplete.new_inventory_item = inv;
  2016. // if (m_texturesFolder != UUID.Zero)
  2017. // uploadComplete.new_texture_folder_id = m_texturesFolder;
  2018. if (m_IsAtestUpload)
  2019. {
  2020. LLSDAssetUploadError resperror = new LLSDAssetUploadError();
  2021. resperror.message = "Upload SUCCESSFUL for testing purposes only. Other uses are prohibited. Item will not work after 48 hours or on other regions";
  2022. resperror.identifier = inv;
  2023. uploadComplete.error = resperror;
  2024. }
  2025. uploadComplete.state = "complete";
  2026. }
  2027. else
  2028. {
  2029. LLSDAssetUploadError resperror = new LLSDAssetUploadError();
  2030. resperror.message = m_error;
  2031. resperror.identifier = inv;
  2032. uploadComplete.error = resperror;
  2033. uploadComplete.state = "failed";
  2034. }
  2035. res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
  2036. return res;
  2037. }
  2038. private void TimedOut(object sender, ElapsedEventArgs args)
  2039. {
  2040. m_log.InfoFormat("[CAPS]: Removing URL and handler for timed out mesh upload");
  2041. httpListener.RemoveStreamHandler("POST", uploaderPath);
  2042. }
  2043. private static void SaveAssetToFile(string filename, byte[] data)
  2044. {
  2045. string assetPath = "UserAssets";
  2046. if (!Directory.Exists(assetPath))
  2047. {
  2048. Directory.CreateDirectory(assetPath);
  2049. }
  2050. FileStream fs = File.Create(Path.Combine(assetPath, Util.SafeFileName(filename)));
  2051. BinaryWriter bw = new BinaryWriter(fs);
  2052. bw.Write(data);
  2053. bw.Close();
  2054. fs.Close();
  2055. }
  2056. }
  2057. public class ExpiringCapBase
  2058. {
  2059. protected IHttpServer m_httpListener;
  2060. protected string m_mypath;
  2061. protected Timer m_timeoutTimer;
  2062. public ExpiringCapBase(IHttpServer httpServer, string path)
  2063. {
  2064. m_httpListener = httpServer;
  2065. m_mypath = path;
  2066. }
  2067. public virtual void Start(int timeout)
  2068. {
  2069. m_timeoutTimer = new Timer(Timedout, null, timeout, Timeout.Infinite);
  2070. }
  2071. public virtual void Stop()
  2072. {
  2073. m_httpListener.RemoveSimpleStreamHandler(m_mypath);
  2074. m_timeoutTimer.Dispose();
  2075. m_timeoutTimer = null;
  2076. }
  2077. public virtual void Timedout(object state)
  2078. {
  2079. Stop();
  2080. m_log.InfoFormat("[CAPS]: Removing URL and handler for timed out service");
  2081. }
  2082. }
  2083. public class ScriptResourceSummary : ExpiringCapBase
  2084. {
  2085. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  2086. private Scene m_scene;
  2087. private UUID m_agentID;
  2088. private int m_memory;
  2089. private int m_urls;
  2090. private IPAddress m_address;
  2091. public ScriptResourceSummary(Scene scene, UUID agentID, IHttpServer httpServer, string path, IPAddress address,
  2092. int memory, int urls) : base(httpServer, path)
  2093. {
  2094. m_address = address;
  2095. m_scene = scene;
  2096. m_agentID = agentID;
  2097. m_memory = memory;
  2098. m_urls = urls;
  2099. Start(30000);
  2100. }
  2101. /// <summary>
  2102. /// Handle raw asset upload data via the capability.
  2103. /// </summary>
  2104. /// <param name="data"></param>
  2105. /// <param name="path"></param>
  2106. /// <param name="param"></param>
  2107. /// <returns></returns>
  2108. public void ScriptResourceSummaryCap(IOSHttpRequest request, IOSHttpResponse response)
  2109. {
  2110. Stop();
  2111. if (!request.RemoteIPEndPoint.Address.Equals(m_address))
  2112. {
  2113. response.StatusCode = (int)HttpStatusCode.Unauthorized;
  2114. return;
  2115. }
  2116. if (m_scene.ShuttingDown || !m_scene.TryGetScenePresence(m_agentID, out ScenePresence sp) || sp.IsChildAgent || sp.IsInTransit)
  2117. {
  2118. response.StatusCode = (int)HttpStatusCode.Unauthorized;
  2119. return;
  2120. }
  2121. osUTF8 sb = LLSDxmlEncode2.Start();
  2122. LLSDxmlEncode2.AddMap(sb);
  2123. LLSDxmlEncode2.AddMap("summary", sb);
  2124. LLSDxmlEncode2.AddArray("available", sb);
  2125. int maxurls = m_urls + 5000; // we don't limit this
  2126. LLSDxmlEncode2.AddMap(sb);
  2127. LLSDxmlEncode2.AddElem("amount", maxurls, sb);
  2128. LLSDxmlEncode2.AddElem("type", "urls", sb);
  2129. LLSDxmlEncode2.AddEndMap(sb);
  2130. LLSDxmlEncode2.AddMap(sb);
  2131. LLSDxmlEncode2.AddElem("amount", (int)-1, sb);
  2132. LLSDxmlEncode2.AddElem("type", "memory", sb);
  2133. LLSDxmlEncode2.AddEndMap(sb);
  2134. LLSDxmlEncode2.AddEndArray(sb); //available
  2135. LLSDxmlEncode2.AddArray("used", sb);
  2136. LLSDxmlEncode2.AddMap(sb);
  2137. LLSDxmlEncode2.AddElem("amount", m_urls, sb);
  2138. LLSDxmlEncode2.AddElem("type", "urls", sb);
  2139. LLSDxmlEncode2.AddEndMap(sb);
  2140. LLSDxmlEncode2.AddMap(sb);
  2141. LLSDxmlEncode2.AddElem("amount", m_memory, sb);
  2142. LLSDxmlEncode2.AddElem("type", "memory", sb);
  2143. LLSDxmlEncode2.AddEndMap(sb);
  2144. LLSDxmlEncode2.AddEndArray(sb); //used
  2145. LLSDxmlEncode2.AddEndMap(sb); // summary
  2146. LLSDxmlEncode2.AddEndMap(sb);
  2147. response.RawBuffer = LLSDxmlEncode2.EndToNBBytes(sb);
  2148. response.StatusCode = (int)HttpStatusCode.OK;
  2149. }
  2150. }
  2151. public class ScriptResourceDetails : ExpiringCapBase
  2152. {
  2153. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  2154. private Scene m_scene;
  2155. private UUID m_agentID;
  2156. private List<ParcelScriptInfo> m_parcelsInfo;
  2157. private IPAddress m_address;
  2158. public ScriptResourceDetails(Scene scene, UUID agentID, IHttpServer httpServer, string path, IPAddress address,
  2159. List<ParcelScriptInfo> parcelsInfo) :base(httpServer, path)
  2160. {
  2161. m_address = address;
  2162. m_scene = scene;
  2163. m_agentID = agentID;
  2164. m_parcelsInfo = parcelsInfo;
  2165. Start(30000);
  2166. }
  2167. /// <summary>
  2168. /// Handle raw asset upload data via the capability.
  2169. /// </summary>
  2170. /// <param name="data"></param>
  2171. /// <param name="path"></param>
  2172. /// <param name="param"></param>
  2173. /// <returns></returns>
  2174. public void ScriptResourceDetailsCap(IOSHttpRequest request, IOSHttpResponse response)
  2175. {
  2176. Stop();
  2177. if (!request.RemoteIPEndPoint.Address.Equals(m_address))
  2178. {
  2179. response.StatusCode = (int)HttpStatusCode.Unauthorized;
  2180. return;
  2181. }
  2182. if (m_scene.ShuttingDown || !m_scene.TryGetScenePresence(m_agentID, out ScenePresence sp) || sp.IsChildAgent || sp.IsInTransit)
  2183. {
  2184. response.StatusCode = (int)HttpStatusCode.Unauthorized;
  2185. return;
  2186. }
  2187. osUTF8 sb = LLSDxmlEncode2.Start();
  2188. LLSDxmlEncode2.AddMap(sb);
  2189. if (m_parcelsInfo.Count > 0)
  2190. {
  2191. LLSDxmlEncode2.AddArray("parcels", sb);
  2192. foreach (ParcelScriptInfo ps in m_parcelsInfo)
  2193. {
  2194. LLSDxmlEncode2.AddMap(sb);
  2195. LLSDxmlEncode2.AddElem("name", ps.name, sb);
  2196. LLSDxmlEncode2.AddElem("id", ps.id, sb);
  2197. LLSDxmlEncode2.AddElem("local_id", ps.localID, sb);
  2198. if(ps.objects.Count > 0)
  2199. {
  2200. LLSDxmlEncode2.AddArray("objects", sb);
  2201. foreach (ScriptInfoForParcel sip in ps.objects)
  2202. {
  2203. LLSDxmlEncode2.AddMap(sb);
  2204. LLSDxmlEncode2.AddElem("id", sip.id, sb);
  2205. LLSDxmlEncode2.AddElem("is_group_owned", sip.groupOwned, sb);
  2206. LLSDxmlEncode2.AddElem("location", sip.pos, sb);
  2207. LLSDxmlEncode2.AddElem("name", sip.name, sb);
  2208. LLSDxmlEncode2.AddElem("owner_id", sip.owner, sb);
  2209. LLSDxmlEncode2.AddMap("resources", sb);
  2210. LLSDxmlEncode2.AddElem("memory", sip.memory, sb);
  2211. LLSDxmlEncode2.AddElem("urls", sip.urls, sb);
  2212. LLSDxmlEncode2.AddEndMap(sb);
  2213. LLSDxmlEncode2.AddEndMap(sb);
  2214. }
  2215. LLSDxmlEncode2.AddEndArray(sb);
  2216. }
  2217. else
  2218. LLSDxmlEncode2.AddEmptyArray("objects", sb);
  2219. LLSDxmlEncode2.AddEndMap(sb);
  2220. }
  2221. LLSDxmlEncode2.AddEndArray(sb); //parcels
  2222. }
  2223. else
  2224. LLSDxmlEncode2.AddEmptyArray("parcels", sb);
  2225. LLSDxmlEncode2.AddEndMap(sb);
  2226. response.RawBuffer = LLSDxmlEncode2.EndToNBBytes(sb);
  2227. response.StatusCode = (int)HttpStatusCode.OK;
  2228. }
  2229. }
  2230. }
  2231. }