clockwerk-opensim – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 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  
28 using System;
29 using System.Collections;
30 using System.Collections.Generic;
31 using System.IO;
32 using System.Reflection;
33 using System.Text;
34  
35 using OpenMetaverse;
36 using OpenMetaverse.StructuredData;
37 using Nini.Config;
38 using log4net;
39  
40 using OpenSim.Framework;
41 using OpenSim.Framework.Capabilities;
42 using OpenSim.Region.Framework;
43 using OpenSim.Region.Framework.Scenes;
44 using OpenSim.Region.Framework.Scenes.Serialization;
45 using OpenSim.Framework.Servers;
46 using OpenSim.Framework.Servers.HttpServer;
47 using OpenSim.Framework.Client;
48 using OpenSim.Services.Interfaces;
49  
50 using Caps = OpenSim.Framework.Capabilities.Caps;
51 using OSDArray = OpenMetaverse.StructuredData.OSDArray;
52 using OSDMap = OpenMetaverse.StructuredData.OSDMap;
53 using PermissionMask = OpenSim.Framework.PermissionMask;
54  
55 namespace OpenSim.Region.ClientStack.Linden
56 {
57 public delegate void UpLoadedAsset(
58 string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder,
59 byte[] data, string inventoryType, string assetType);
60  
61 public delegate UUID UpdateItem(UUID itemID, byte[] data);
62  
63 public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors);
64  
65 public delegate void NewInventoryItem(UUID userID, InventoryItemBase item);
66  
67 public delegate void NewAsset(AssetBase asset);
68  
69 public delegate UUID ItemUpdatedCallback(UUID userID, UUID itemID, byte[] data);
70  
71 public delegate ArrayList TaskScriptUpdatedCallback(UUID userID, UUID itemID, UUID primID,
72 bool isScriptRunning, byte[] data);
73  
74 public delegate InventoryCollection FetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID,
75 bool fetchFolders, bool fetchItems, int sortOrder, out int version);
76  
77 /// <summary>
78 /// XXX Probably not a particularly nice way of allow us to get the scene presence from the scene (chiefly so that
79 /// we can popup a message on the user's client if the inventory service has permanently failed). But I didn't want
80 /// to just pass the whole Scene into CAPS.
81 /// </summary>
82 public delegate IClientAPI GetClientDelegate(UUID agentID);
83  
84 public class BunchOfCaps
85 {
86 private static readonly ILog m_log =
87 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
88  
89 private Scene m_Scene;
90 private Caps m_HostCapsObj;
91  
92 private static readonly string m_requestPath = "0000/";
93 // private static readonly string m_mapLayerPath = "0001/";
94 private static readonly string m_newInventory = "0002/";
95 //private static readonly string m_requestTexture = "0003/";
96 private static readonly string m_notecardUpdatePath = "0004/";
97 private static readonly string m_notecardTaskUpdatePath = "0005/";
98 // private static readonly string m_fetchInventoryPath = "0006/";
99 private static readonly string m_copyFromNotecardPath = "0007/";
100 // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule.
101 private static readonly string m_getObjectPhysicsDataPath = "0101/";
102 /* 0102 - 0103 RESERVED */
103 private static readonly string m_UpdateAgentInformationPath = "0500/";
104  
105 // These are callbacks which will be setup by the scene so that we can update scene data when we
106 // receive capability calls
107 public NewInventoryItem AddNewInventoryItem = null;
108 public NewAsset AddNewAsset = null;
109 public ItemUpdatedCallback ItemUpdatedCall = null;
110 public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null;
111 public FetchInventoryDescendentsCAPS CAPSFetchInventoryDescendents = null;
112 public GetClientDelegate GetClient = null;
113  
114 private bool m_persistBakedTextures = false;
115 private IAssetService m_assetService;
116 private bool m_dumpAssetsToFile = false;
117 private string m_regionName;
118 private int m_levelUpload = 0;
119  
120 public BunchOfCaps(Scene scene, Caps caps)
121 {
122 m_Scene = scene;
123 m_HostCapsObj = caps;
124 IConfigSource config = m_Scene.Config;
125 if (config != null)
126 {
127 IConfig sconfig = config.Configs["Startup"];
128 if (sconfig != null)
129 {
130 m_levelUpload = sconfig.GetInt("LevelUpload", 0);
131 }
132  
133 IConfig appearanceConfig = config.Configs["Appearance"];
134 if (appearanceConfig != null)
135 {
136 m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
137 }
138 }
139  
140 m_assetService = m_Scene.AssetService;
141 m_regionName = m_Scene.RegionInfo.RegionName;
142  
143 RegisterHandlers();
144  
145 AddNewInventoryItem = m_Scene.AddUploadedInventoryItem;
146 ItemUpdatedCall = m_Scene.CapsUpdateInventoryItemAsset;
147 TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset;
148 GetClient = m_Scene.SceneGraph.GetControllingClient;
149 }
150  
151 /// <summary>
152 /// Register a bunch of CAPS http service handlers
153 /// </summary>
154 public void RegisterHandlers()
155 {
156 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
157  
158 RegisterRegionServiceHandlers(capsBase);
159 RegisterInventoryServiceHandlers(capsBase);
160 }
161  
162 public void RegisterRegionServiceHandlers(string capsBase)
163 {
164 try
165 {
166 // the root of all evil
167 m_HostCapsObj.RegisterHandler(
168 "SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest, "SEED", null));
169  
170 // m_log.DebugFormat(
171 // "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID);
172  
173 //m_capsHandlers["MapLayer"] =
174 // new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST",
175 // capsBase + m_mapLayerPath,
176 // GetMapLayer);
177 IRequestHandler req
178 = new RestStreamHandler(
179 "POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory, "UpdateScript", null);
180  
181 m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req);
182 m_HostCapsObj.RegisterHandler("UpdateScriptTask", req);
183 }
184 catch (Exception e)
185 {
186 m_log.Error("[CAPS]: " + e.ToString());
187 }
188 }
189  
190 public void RegisterInventoryServiceHandlers(string capsBase)
191 {
192 try
193 {
194 // I don't think this one works...
195 m_HostCapsObj.RegisterHandler(
196 "NewFileAgentInventory",
197 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>(
198 "POST",
199 capsBase + m_newInventory,
200 NewAgentInventoryRequest,
201 "NewFileAgentInventory",
202 null));
203  
204 IRequestHandler req
205 = new RestStreamHandler(
206 "POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory, "Update*", null);
207  
208 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req);
209 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req);
210 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
211  
212 IRequestHandler getObjectPhysicsDataHandler
213 = new RestStreamHandler(
214 "POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData, "GetObjectPhysicsData", null);
215 m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler);
216  
217 IRequestHandler UpdateAgentInformationHandler
218 = new RestStreamHandler(
219 "POST", capsBase + m_UpdateAgentInformationPath, UpdateAgentInformation, "UpdateAgentInformation", null);
220 m_HostCapsObj.RegisterHandler("UpdateAgentInformation", UpdateAgentInformationHandler);
221  
222 m_HostCapsObj.RegisterHandler(
223 "CopyInventoryFromNotecard",
224 new RestStreamHandler(
225 "POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard, "CopyInventoryFromNotecard", null));
226  
227 // As of RC 1.22.9 of the Linden client this is
228 // supported
229  
230 //m_capsHandlers["WebFetchInventoryDescendents"] =new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryDescendentsRequest);
231  
232 // justincc: I've disabled the CAPS service for now to fix problems with selecting textures, and
233 // subsequent inventory breakage, in the edit object pane (such as mantis 1085). This requires
234 // enhancements (probably filling out the folder part of the LLSD reply) to our CAPS service,
235 // but when I went on the Linden grid, the
236 // simulators I visited (version 1.21) were, surprisingly, no longer supplying this capability. Instead,
237 // the 1.19.1.4 client appeared to be happily flowing inventory data over UDP
238 //
239 // This is very probably just a temporary measure - once the CAPS service appears again on the Linden grid
240 // we will be
241 // able to get the data we need to implement the necessary part of the protocol to fix the issue above.
242 // m_capsHandlers["FetchInventoryDescendents"] =
243 // new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryRequest);
244  
245 // m_capsHandlers["FetchInventoryDescendents"] =
246 // new LLSDStreamhandler<LLSDFetchInventoryDescendents, LLSDInventoryDescendents>("POST",
247 // capsBase + m_fetchInventory,
248 // FetchInventory));
249 // m_capsHandlers["RequestTextureDownload"] = new RestStreamHandler("POST",
250 // capsBase + m_requestTexture,
251 // RequestTexture);
252 }
253 catch (Exception e)
254 {
255 m_log.Error("[CAPS]: " + e.ToString());
256 }
257 }
258  
259 /// <summary>
260 /// Construct a client response detailing all the capabilities this server can provide.
261 /// </summary>
262 /// <param name="request"></param>
263 /// <param name="path"></param>
264 /// <param name="param"></param>
265 /// <param name="httpRequest">HTTP request header object</param>
266 /// <param name="httpResponse">HTTP response header object</param>
267 /// <returns></returns>
268 public string SeedCapRequest(string request, string path, string param,
269 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
270 {
271 m_log.DebugFormat(
272 "[CAPS]: Received SEED caps request in {0} for agent {1}", m_regionName, m_HostCapsObj.AgentID);
273  
274 if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
275 {
276 m_log.WarnFormat(
277 "[CAPS]: Unauthorized CAPS client {0} from {1}",
278 m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint);
279  
280 return string.Empty;
281 }
282  
283 OSDArray capsRequested = (OSDArray)OSDParser.DeserializeLLSDXml(request);
284 List<string> validCaps = new List<string>();
285  
286 foreach (OSD c in capsRequested)
287 validCaps.Add(c.AsString());
288  
289 string result = LLSDHelpers.SerialiseLLSDReply(m_HostCapsObj.GetCapsDetails(true, validCaps));
290  
291 //m_log.DebugFormat("[CAPS] CapsRequest {0}", result);
292  
293 return result;
294 }
295  
296 /// <summary>
297 /// Called by the script task update handler. Provides a URL to which the client can upload a new asset.
298 /// </summary>
299 /// <param name="request"></param>
300 /// <param name="path"></param>
301 /// <param name="param"></param>
302 /// <param name="httpRequest">HTTP request header object</param>
303 /// <param name="httpResponse">HTTP response header object</param>
304 /// <returns></returns>
305 public string ScriptTaskInventory(string request, string path, string param,
306 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
307 {
308 try
309 {
310 // m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName);
311 //m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param);
312  
313 Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
314 LLSDTaskScriptUpdate llsdUpdateRequest = new LLSDTaskScriptUpdate();
315 LLSDHelpers.DeserialiseOSDMap(hash, llsdUpdateRequest);
316  
317 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
318 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
319  
320 TaskInventoryScriptUpdater uploader =
321 new TaskInventoryScriptUpdater(
322 llsdUpdateRequest.item_id,
323 llsdUpdateRequest.task_id,
324 llsdUpdateRequest.is_script_running,
325 capsBase + uploaderPath,
326 m_HostCapsObj.HttpListener,
327 m_dumpAssetsToFile);
328 uploader.OnUpLoad += TaskScriptUpdated;
329  
330 m_HostCapsObj.HttpListener.AddStreamHandler(
331 new BinaryStreamHandler(
332 "POST", capsBase + uploaderPath, uploader.uploaderCaps, "TaskInventoryScriptUpdater", null));
333  
334 string protocol = "http://";
335  
336 if (m_HostCapsObj.SSLCaps)
337 protocol = "https://";
338  
339 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase +
340 uploaderPath;
341  
342 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
343 uploadResponse.uploader = uploaderURL;
344 uploadResponse.state = "upload";
345  
346 // m_log.InfoFormat("[CAPS]: " +
347 // "ScriptTaskInventory response: {0}",
348 // LLSDHelpers.SerialiseLLSDReply(uploadResponse)));
349  
350 return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
351 }
352 catch (Exception e)
353 {
354 m_log.Error("[CAPS]: " + e.ToString());
355 }
356  
357 return null;
358 }
359  
360 /// <summary>
361 /// Called when new asset data for an agent inventory item update has been uploaded.
362 /// </summary>
363 /// <param name="itemID">Item to update</param>
364 /// <param name="primID">Prim containing item to update</param>
365 /// <param name="isScriptRunning">Signals whether the script to update is currently running</param>
366 /// <param name="data">New asset data</param>
367 public void TaskScriptUpdated(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors)
368 {
369 if (TaskScriptUpdatedCall != null)
370 {
371 ArrayList e = TaskScriptUpdatedCall(m_HostCapsObj.AgentID, itemID, primID, isScriptRunning, data);
372 foreach (Object item in e)
373 errors.Add(item);
374 }
375 }
376  
377 /// <summary>
378 /// Called when new asset data for an agent inventory item update has been uploaded.
379 /// </summary>
380 /// <param name="itemID">Item to update</param>
381 /// <param name="data">New asset data</param>
382 /// <returns></returns>
383 public UUID ItemUpdated(UUID itemID, byte[] data)
384 {
385 if (ItemUpdatedCall != null)
386 {
387 return ItemUpdatedCall(m_HostCapsObj.AgentID, itemID, data);
388 }
389  
390 return UUID.Zero;
391 }
392  
393 /// <summary>
394 ///
395 /// </summary>
396 /// <param name="llsdRequest"></param>
397 /// <returns></returns>
398 public LLSDAssetUploadResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest)
399 {
400 //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString());
401 //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type);
402  
403 if (llsdRequest.asset_type == "texture" ||
404 llsdRequest.asset_type == "animation" ||
405 llsdRequest.asset_type == "sound")
406 {
407 ScenePresence avatar = null;
408 IClientAPI client = null;
409 m_Scene.TryGetScenePresence(m_HostCapsObj.AgentID, out avatar);
410  
411 // check user level
412 if (avatar != null)
413 {
414 client = avatar.ControllingClient;
415  
416 if (avatar.UserLevel < m_levelUpload)
417 {
418 if (client != null)
419 client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
420  
421 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
422 errorResponse.uploader = "";
423 errorResponse.state = "error";
424 return errorResponse;
425 }
426 }
427  
428 // check funds
429 if (client != null)
430 {
431 IMoneyModule mm = m_Scene.RequestModuleInterface<IMoneyModule>();
432  
433 if (mm != null)
434 {
435 if (!mm.UploadCovered(client.AgentId, mm.UploadCharge))
436 {
437 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
438  
439 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
440 errorResponse.uploader = "";
441 errorResponse.state = "error";
442 return errorResponse;
443 }
444 }
445 }
446 }
447  
448 string assetName = llsdRequest.name;
449 string assetDes = llsdRequest.description;
450 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
451 UUID newAsset = UUID.Random();
452 UUID newInvItem = UUID.Random();
453 UUID parentFolder = llsdRequest.folder_id;
454 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
455  
456 AssetUploader uploader =
457 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
458 llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile);
459  
460 m_HostCapsObj.HttpListener.AddStreamHandler(
461 new BinaryStreamHandler(
462 "POST",
463 capsBase + uploaderPath,
464 uploader.uploaderCaps,
465 "NewAgentInventoryRequest",
466 m_HostCapsObj.AgentID.ToString()));
467  
468 string protocol = "http://";
469  
470 if (m_HostCapsObj.SSLCaps)
471 protocol = "https://";
472  
473 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase +
474 uploaderPath;
475  
476 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
477 uploadResponse.uploader = uploaderURL;
478 uploadResponse.state = "upload";
479 uploader.OnUpLoad += UploadCompleteHandler;
480 return uploadResponse;
481 }
482  
483 /// <summary>
484 /// Convert raw uploaded data into the appropriate asset and item.
485 /// </summary>
486 /// <param name="assetID"></param>
487 /// <param name="inventoryItem"></param>
488 /// <param name="data"></param>
489 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
490 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
491 string assetType)
492 {
493 m_log.DebugFormat(
494 "[BUNCH OF CAPS]: Uploaded asset {0} for inventory item {1}, inv type {2}, asset type {3}",
495 assetID, inventoryItem, inventoryType, assetType);
496  
497 sbyte assType = 0;
498 sbyte inType = 0;
499  
500 if (inventoryType == "sound")
501 {
502 inType = (sbyte)InventoryType.Sound;
503 assType = (sbyte)AssetType.Sound;
504 }
505 else if (inventoryType == "snapshot")
506 {
507 inType = (sbyte)InventoryType.Snapshot;
508 }
509 else if (inventoryType == "animation")
510 {
511 inType = (sbyte)InventoryType.Animation;
512 assType = (sbyte)AssetType.Animation;
513 }
514 else if (inventoryType == "wearable")
515 {
516 inType = (sbyte)InventoryType.Wearable;
517 switch (assetType)
518 {
519 case "bodypart":
520 assType = (sbyte)AssetType.Bodypart;
521 break;
522 case "clothing":
523 assType = (sbyte)AssetType.Clothing;
524 break;
525 }
526 }
527 else if (inventoryType == "object")
528 {
529 inType = (sbyte)InventoryType.Object;
530 assType = (sbyte)AssetType.Object;
531  
532 List<Vector3> positions = new List<Vector3>();
533 List<Quaternion> rotations = new List<Quaternion>();
534 OSDMap request = (OSDMap)OSDParser.DeserializeLLSDXml(data);
535 OSDArray instance_list = (OSDArray)request["instance_list"];
536 OSDArray mesh_list = (OSDArray)request["mesh_list"];
537 OSDArray texture_list = (OSDArray)request["texture_list"];
538 SceneObjectGroup grp = null;
539  
540 InventoryFolderBase textureUploadFolder = null;
541  
542 List<InventoryFolderBase> foldersToUpdate = new List<InventoryFolderBase>();
543 List<InventoryItemBase> itemsToUpdate = new List<InventoryItemBase>();
544 IClientInventory clientInv = null;
545  
546 if (texture_list.Count > 0)
547 {
548 ScenePresence avatar = null;
549 m_Scene.TryGetScenePresence(m_HostCapsObj.AgentID, out avatar);
550  
551 if (avatar != null)
552 {
553 IClientCore core = (IClientCore)avatar.ControllingClient;
554  
555 if (core.TryGet<IClientInventory>(out clientInv))
556 {
557 var systemTextureFolder = m_Scene.InventoryService.GetFolderForType(m_HostCapsObj.AgentID, AssetType.Texture);
558 textureUploadFolder = new InventoryFolderBase(UUID.Random(), assetName, m_HostCapsObj.AgentID, (short)AssetType.Unknown, systemTextureFolder.ID, 1);
559 if (m_Scene.InventoryService.AddFolder(textureUploadFolder))
560 {
561 foldersToUpdate.Add(textureUploadFolder);
562  
563 m_log.DebugFormat(
564 "[BUNCH OF CAPS]: Created new folder '{0}' ({1}) for textures uploaded with mesh object {2}",
565 textureUploadFolder.Name, textureUploadFolder.ID, assetName);
566 }
567 else
568 {
569 textureUploadFolder = null;
570 }
571 }
572 }
573 }
574  
575 List<UUID> textures = new List<UUID>();
576 for (int i = 0; i < texture_list.Count; i++)
577 {
578 AssetBase textureAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Texture, "");
579 textureAsset.Data = texture_list[i].AsBinary();
580 m_assetService.Store(textureAsset);
581 textures.Add(textureAsset.FullID);
582  
583 if (textureUploadFolder != null)
584 {
585 InventoryItemBase textureItem = new InventoryItemBase();
586 textureItem.Owner = m_HostCapsObj.AgentID;
587 textureItem.CreatorId = m_HostCapsObj.AgentID.ToString();
588 textureItem.CreatorData = String.Empty;
589 textureItem.ID = UUID.Random();
590 textureItem.AssetID = textureAsset.FullID;
591 textureItem.Description = assetDescription;
592 textureItem.Name = assetName + " - Texture " + (i + 1).ToString();
593 textureItem.AssetType = (int)AssetType.Texture;
594 textureItem.InvType = (int)InventoryType.Texture;
595 textureItem.Folder = textureUploadFolder.ID;
596 textureItem.CurrentPermissions
597 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Export);
598 textureItem.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
599 textureItem.EveryOnePermissions = 0;
600 textureItem.NextPermissions = (uint)PermissionMask.All;
601 textureItem.CreationDate = Util.UnixTimeSinceEpoch();
602 m_Scene.InventoryService.AddItem(textureItem);
603 itemsToUpdate.Add(textureItem);
604  
605 m_log.DebugFormat(
606 "[BUNCH OF CAPS]: Created new inventory item '{0}' ({1}) for texture uploaded with mesh object {2}",
607 textureItem.Name, textureItem.ID, assetName);
608 }
609 }
610  
611 if (clientInv != null && (foldersToUpdate.Count > 0 || itemsToUpdate.Count > 0))
612 {
613 clientInv.SendBulkUpdateInventory(foldersToUpdate.ToArray(), itemsToUpdate.ToArray());
614 }
615  
616 for (int i = 0; i < mesh_list.Count; i++)
617 {
618 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
619  
620 Primitive.TextureEntry textureEntry
621 = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE);
622 OSDMap inner_instance_list = (OSDMap)instance_list[i];
623  
624 OSDArray face_list = (OSDArray)inner_instance_list["face_list"];
625 for (uint face = 0; face < face_list.Count; face++)
626 {
627 OSDMap faceMap = (OSDMap)face_list[(int)face];
628 Primitive.TextureEntryFace f = pbs.Textures.CreateFace(face);
629 if(faceMap.ContainsKey("fullbright"))
630 f.Fullbright = faceMap["fullbright"].AsBoolean();
631 if (faceMap.ContainsKey ("diffuse_color"))
632 f.RGBA = faceMap["diffuse_color"].AsColor4();
633  
634 int textureNum = faceMap["image"].AsInteger();
635 float imagerot = faceMap["imagerot"].AsInteger();
636 float offsets = (float)faceMap["offsets"].AsReal();
637 float offsett = (float)faceMap["offsett"].AsReal();
638 float scales = (float)faceMap["scales"].AsReal();
639 float scalet = (float)faceMap["scalet"].AsReal();
640  
641 if(imagerot != 0)
642 f.Rotation = imagerot;
643  
644 if(offsets != 0)
645 f.OffsetU = offsets;
646  
647 if (offsett != 0)
648 f.OffsetV = offsett;
649  
650 if (scales != 0)
651 f.RepeatU = scales;
652  
653 if (scalet != 0)
654 f.RepeatV = scalet;
655  
656 if (textures.Count > textureNum)
657 f.TextureID = textures[textureNum];
658 else
659 f.TextureID = Primitive.TextureEntry.WHITE_TEXTURE;
660  
661 textureEntry.FaceTextures[face] = f;
662 }
663  
664 pbs.TextureEntry = textureEntry.GetBytes();
665  
666 AssetBase meshAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Mesh, "");
667 meshAsset.Data = mesh_list[i].AsBinary();
668 m_assetService.Store(meshAsset);
669  
670 pbs.SculptEntry = true;
671 pbs.SculptTexture = meshAsset.FullID;
672 pbs.SculptType = (byte)SculptType.Mesh;
673 pbs.SculptData = meshAsset.Data;
674  
675 Vector3 position = inner_instance_list["position"].AsVector3();
676 Vector3 scale = inner_instance_list["scale"].AsVector3();
677 Quaternion rotation = inner_instance_list["rotation"].AsQuaternion();
678  
679 // no longer used - begin ------------------------
680 // int physicsShapeType = inner_instance_list["physics_shape_type"].AsInteger();
681 // int material = inner_instance_list["material"].AsInteger();
682 // int mesh = inner_instance_list["mesh"].AsInteger();
683  
684 // OSDMap permissions = (OSDMap)inner_instance_list["permissions"];
685 // int base_mask = permissions["base_mask"].AsInteger();
686 // int everyone_mask = permissions["everyone_mask"].AsInteger();
687 // UUID creator_id = permissions["creator_id"].AsUUID();
688 // UUID group_id = permissions["group_id"].AsUUID();
689 // int group_mask = permissions["group_mask"].AsInteger();
690 // bool is_owner_group = permissions["is_owner_group"].AsBoolean();
691 // UUID last_owner_id = permissions["last_owner_id"].AsUUID();
692 // int next_owner_mask = permissions["next_owner_mask"].AsInteger();
693 // UUID owner_id = permissions["owner_id"].AsUUID();
694 // int owner_mask = permissions["owner_mask"].AsInteger();
695 // no longer used - end ------------------------
696  
697 UUID owner_id = m_HostCapsObj.AgentID;
698  
699 SceneObjectPart prim
700 = new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero);
701  
702 prim.Scale = scale;
703 //prim.OffsetPosition = position;
704 rotations.Add(rotation);
705 positions.Add(position);
706 prim.UUID = UUID.Random();
707 prim.CreatorID = owner_id;
708 prim.OwnerID = owner_id;
709 prim.GroupID = UUID.Zero;
710 prim.LastOwnerID = prim.OwnerID;
711 prim.CreationDate = Util.UnixTimeSinceEpoch();
712 prim.Name = assetName;
713 prim.Description = "";
714  
715 // prim.BaseMask = (uint)base_mask;
716 // prim.EveryoneMask = (uint)everyone_mask;
717 // prim.GroupMask = (uint)group_mask;
718 // prim.NextOwnerMask = (uint)next_owner_mask;
719 // prim.OwnerMask = (uint)owner_mask;
720  
721 if (grp == null)
722 grp = new SceneObjectGroup(prim);
723 else
724 grp.AddPart(prim);
725 }
726  
727 Vector3 rootPos = positions[0];
728  
729 if (grp.Parts.Length > 1)
730 {
731 // Fix first link number
732 grp.RootPart.LinkNum++;
733  
734 Quaternion rootRotConj = Quaternion.Conjugate(rotations[0]);
735 Quaternion tmprot;
736 Vector3 offset;
737  
738 // fix children rotations and positions
739 for (int i = 1; i < rotations.Count; i++)
740 {
741 tmprot = rotations[i];
742 tmprot = rootRotConj * tmprot;
743  
744 grp.Parts[i].RotationOffset = tmprot;
745  
746 offset = positions[i] - rootPos;
747  
748 offset *= rootRotConj;
749 grp.Parts[i].OffsetPosition = offset;
750 }
751  
752 grp.AbsolutePosition = rootPos;
753 grp.UpdateGroupRotationR(rotations[0]);
754 }
755 else
756 {
757 grp.AbsolutePosition = rootPos;
758 grp.UpdateGroupRotationR(rotations[0]);
759 }
760  
761 data = ASCIIEncoding.ASCII.GetBytes(SceneObjectSerializer.ToOriginalXmlFormat(grp));
762 }
763  
764 AssetBase asset;
765 asset = new AssetBase(assetID, assetName, assType, m_HostCapsObj.AgentID.ToString());
766 asset.Data = data;
767 if (AddNewAsset != null)
768 AddNewAsset(asset);
769 else if (m_assetService != null)
770 m_assetService.Store(asset);
771  
772 InventoryItemBase item = new InventoryItemBase();
773 item.Owner = m_HostCapsObj.AgentID;
774 item.CreatorId = m_HostCapsObj.AgentID.ToString();
775 item.CreatorData = String.Empty;
776 item.ID = inventoryItem;
777 item.AssetID = asset.FullID;
778 item.Description = assetDescription;
779 item.Name = assetName;
780 item.AssetType = assType;
781 item.InvType = inType;
782 item.Folder = parentFolder;
783  
784 // If we set PermissionMask.All then when we rez the item the next permissions will replace the current
785 // (owner) permissions. This becomes a problem if next permissions are changed.
786 item.CurrentPermissions
787 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Export);
788  
789 item.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
790 item.EveryOnePermissions = 0;
791 item.NextPermissions = (uint)PermissionMask.All;
792 item.CreationDate = Util.UnixTimeSinceEpoch();
793  
794 if (AddNewInventoryItem != null)
795 {
796 AddNewInventoryItem(m_HostCapsObj.AgentID, item);
797 }
798 }
799  
800 /// <summary>
801 ///
802 /// </summary>
803 /// <param name="mapReq"></param>
804 /// <returns></returns>
805 public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq)
806 {
807 m_log.Debug("[CAPS]: MapLayer Request in region: " + m_regionName);
808 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
809 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
810 return mapResponse;
811 }
812  
813 /// <summary>
814 ///
815 /// </summary>
816 /// <returns></returns>
817 protected static OSDMapLayer GetOSDMapLayerResponse()
818 {
819 OSDMapLayer mapLayer = new OSDMapLayer();
820 mapLayer.Right = 5000;
821 mapLayer.Top = 5000;
822 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006");
823  
824 return mapLayer;
825 }
826  
827 /// <summary>
828 ///
829 /// </summary>
830 /// <param name="request"></param>
831 /// <param name="path"></param>
832 /// <param name="param"></param>
833 /// <returns></returns>
834 public string RequestTexture(string request, string path, string param)
835 {
836 m_log.Debug("texture request " + request);
837 // Needs implementing (added to remove compiler warning)
838 return String.Empty;
839 }
840  
841  
842 /// <summary>
843 /// Called by the notecard update handler. Provides a URL to which the client can upload a new asset.
844 /// </summary>
845 /// <param name="request"></param>
846 /// <param name="path"></param>
847 /// <param name="param"></param>
848 /// <returns></returns>
849 public string NoteCardAgentInventory(string request, string path, string param,
850 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
851 {
852 //m_log.Debug("[CAPS]: NoteCardAgentInventory Request in region: " + m_regionName + "\n" + request);
853 //m_log.Debug("[CAPS]: NoteCardAgentInventory Request is: " + request);
854  
855 //OpenMetaverse.StructuredData.OSDMap hash = (OpenMetaverse.StructuredData.OSDMap)OpenMetaverse.StructuredData.LLSDParser.DeserializeBinary(Utils.StringToBytes(request));
856 Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
857 LLSDItemUpdate llsdRequest = new LLSDItemUpdate();
858 LLSDHelpers.DeserialiseOSDMap(hash, llsdRequest);
859  
860 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
861 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
862  
863 ItemUpdater uploader =
864 new ItemUpdater(llsdRequest.item_id, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile);
865 uploader.OnUpLoad += ItemUpdated;
866  
867 m_HostCapsObj.HttpListener.AddStreamHandler(
868 new BinaryStreamHandler(
869 "POST", capsBase + uploaderPath, uploader.uploaderCaps, "NoteCardAgentInventory", null));
870  
871 string protocol = "http://";
872  
873 if (m_HostCapsObj.SSLCaps)
874 protocol = "https://";
875  
876 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase +
877 uploaderPath;
878  
879 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
880 uploadResponse.uploader = uploaderURL;
881 uploadResponse.state = "upload";
882  
883 // m_log.InfoFormat("[CAPS]: " +
884 // "NoteCardAgentInventory response: {0}",
885 // LLSDHelpers.SerialiseLLSDReply(uploadResponse)));
886  
887 return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
888 }
889  
890 /// <summary>
891 /// Called by the CopyInventoryFromNotecard caps handler.
892 /// </summary>
893 /// <param name="request"></param>
894 /// <param name="path"></param>
895 /// <param name="param"></param>
896 public string CopyInventoryFromNotecard(string request, string path, string param,
897 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
898 {
899 Hashtable response = new Hashtable();
900 response["int_response_code"] = 404;
901 response["content_type"] = "text/plain";
902 response["keepalive"] = false;
903 response["str_response_string"] = "";
904  
905 try
906 {
907 OSDMap content = (OSDMap)OSDParser.DeserializeLLSDXml(request);
908 UUID objectID = content["object-id"].AsUUID();
909 UUID notecardID = content["notecard-id"].AsUUID();
910 UUID folderID = content["folder-id"].AsUUID();
911 UUID itemID = content["item-id"].AsUUID();
912  
913 // m_log.InfoFormat("[CAPS]: CopyInventoryFromNotecard, FolderID:{0}, ItemID:{1}, NotecardID:{2}, ObjectID:{3}", folderID, itemID, notecardID, objectID);
914  
915 if (objectID != UUID.Zero)
916 {
917 SceneObjectPart part = m_Scene.GetSceneObjectPart(objectID);
918 if (part != null)
919 {
920 // TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(notecardID);
921 if (!m_Scene.Permissions.CanCopyObjectInventory(notecardID, objectID, m_HostCapsObj.AgentID))
922 {
923 return LLSDHelpers.SerialiseLLSDReply(response);
924 }
925 }
926 }
927  
928 InventoryItemBase item = null;
929 InventoryItemBase copyItem = null;
930 IClientAPI client = null;
931  
932 m_Scene.TryGetClient(m_HostCapsObj.AgentID, out client);
933 item = m_Scene.InventoryService.GetItem(new InventoryItemBase(itemID));
934 if (item != null)
935 {
936 string message;
937 copyItem = m_Scene.GiveInventoryItem(m_HostCapsObj.AgentID, item.Owner, itemID, folderID, out message);
938 if (client != null)
939 {
940 if (copyItem != null)
941 {
942 m_log.InfoFormat("[CAPS]: CopyInventoryFromNotecard, ItemID:{0}, FolderID:{1}", copyItem.ID, copyItem.Folder);
943 client.SendBulkUpdateInventory(copyItem);
944 }
945 else
946 {
947 client.SendAgentAlertMessage(message, false);
948 }
949 }
950 }
951 else
952 {
953 m_log.ErrorFormat("[CAPS]: CopyInventoryFromNotecard - Failed to retrieve item {0} from notecard {1}", itemID, notecardID);
954 if (client != null)
955 client.SendAgentAlertMessage("Failed to retrieve item", false);
956 }
957 }
958 catch (Exception e)
959 {
960 m_log.ErrorFormat("[CAPS]: CopyInventoryFromNotecard : {0}", e.ToString());
961 }
962  
963 response["int_response_code"] = 200;
964 return LLSDHelpers.SerialiseLLSDReply(response);
965 }
966  
967 public string GetObjectPhysicsData(string request, string path,
968 string param, IOSHttpRequest httpRequest,
969 IOSHttpResponse httpResponse)
970 {
971 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
972 OSDMap resp = new OSDMap();
973 OSDArray object_ids = (OSDArray)req["object_ids"];
974  
975 for (int i = 0 ; i < object_ids.Count ; i++)
976 {
977 UUID uuid = object_ids[i].AsUUID();
978  
979 SceneObjectPart obj = m_Scene.GetSceneObjectPart(uuid);
980 if (obj != null)
981 {
982 OSDMap object_data = new OSDMap();
983  
984 object_data["PhysicsShapeType"] = obj.PhysicsShapeType;
985 object_data["Density"] = obj.Density;
986 object_data["Friction"] = obj.Friction;
987 object_data["Restitution"] = obj.Restitution;
988 object_data["GravityMultiplier"] = obj.GravityModifier;
989  
990 resp[uuid.ToString()] = object_data;
991 }
992 }
993  
994 string response = OSDParser.SerializeLLSDXmlString(resp);
995 return response;
996 }
997  
998 public string UpdateAgentInformation(string request, string path,
999 string param, IOSHttpRequest httpRequest,
1000 IOSHttpResponse httpResponse)
1001 {
1002 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
1003 OSDMap accessPrefs = (OSDMap)req["access_prefs"];
1004 string desiredMaturity = accessPrefs["max"];
1005  
1006 OSDMap resp = new OSDMap();
1007 OSDMap respAccessPrefs = new OSDMap();
1008 respAccessPrefs["max"] = desiredMaturity; // echoing the maturity back means success
1009 resp["access_prefs"] = respAccessPrefs;
1010  
1011 string response = OSDParser.SerializeLLSDXmlString(resp);
1012 return response;
1013 }
1014 }
1015  
1016 public class AssetUploader
1017 {
1018 public event UpLoadedAsset OnUpLoad;
1019 private UpLoadedAsset handlerUpLoad = null;
1020  
1021 private string uploaderPath = String.Empty;
1022 private UUID newAssetID;
1023 private UUID inventoryItemID;
1024 private UUID parentFolder;
1025 private IHttpServer httpListener;
1026 private bool m_dumpAssetsToFile;
1027 private string m_assetName = String.Empty;
1028 private string m_assetDes = String.Empty;
1029  
1030 private string m_invType = String.Empty;
1031 private string m_assetType = String.Empty;
1032  
1033 public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem,
1034 UUID parentFolderID, string invType, string assetType, string path,
1035 IHttpServer httpServer, bool dumpAssetsToFile)
1036 {
1037 m_assetName = assetName;
1038 m_assetDes = description;
1039 newAssetID = assetID;
1040 inventoryItemID = inventoryItem;
1041 uploaderPath = path;
1042 httpListener = httpServer;
1043 parentFolder = parentFolderID;
1044 m_assetType = assetType;
1045 m_invType = invType;
1046 m_dumpAssetsToFile = dumpAssetsToFile;
1047 }
1048  
1049 /// <summary>
1050 /// Handle raw asset upload data via the capability.
1051 /// </summary>
1052 /// <param name="data"></param>
1053 /// <param name="path"></param>
1054 /// <param name="param"></param>
1055 /// <returns></returns>
1056 public string uploaderCaps(byte[] data, string path, string param)
1057 {
1058 UUID inv = inventoryItemID;
1059 string res = String.Empty;
1060 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
1061 uploadComplete.new_asset = newAssetID.ToString();
1062 uploadComplete.new_inventory_item = inv;
1063 uploadComplete.state = "complete";
1064  
1065 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
1066  
1067 httpListener.RemoveStreamHandler("POST", uploaderPath);
1068  
1069 // TODO: probably make this a better set of extensions here
1070 string extension = ".jp2";
1071 if (m_invType != "image")
1072 {
1073 extension = ".dat";
1074 }
1075  
1076 if (m_dumpAssetsToFile)
1077 {
1078 SaveAssetToFile(m_assetName + extension, data);
1079 }
1080 handlerUpLoad = OnUpLoad;
1081 if (handlerUpLoad != null)
1082 {
1083 handlerUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType);
1084 }
1085  
1086 return res;
1087 }
1088  
1089 ///Left this in and commented in case there are unforseen issues
1090 //private void SaveAssetToFile(string filename, byte[] data)
1091 //{
1092 // FileStream fs = File.Create(filename);
1093 // BinaryWriter bw = new BinaryWriter(fs);
1094 // bw.Write(data);
1095 // bw.Close();
1096 // fs.Close();
1097 //}
1098  
1099 private static void SaveAssetToFile(string filename, byte[] data)
1100 {
1101 string assetPath = "UserAssets";
1102 if (!Directory.Exists(assetPath))
1103 {
1104 Directory.CreateDirectory(assetPath);
1105 }
1106 FileStream fs = File.Create(Path.Combine(assetPath, Util.safeFileName(filename)));
1107 BinaryWriter bw = new BinaryWriter(fs);
1108 bw.Write(data);
1109 bw.Close();
1110 fs.Close();
1111 }
1112 }
1113  
1114 /// <summary>
1115 /// This class is a callback invoked when a client sends asset data to
1116 /// an agent inventory notecard update url
1117 /// </summary>
1118 public class ItemUpdater
1119 {
1120 public event UpdateItem OnUpLoad;
1121  
1122 private UpdateItem handlerUpdateItem = null;
1123  
1124 private string uploaderPath = String.Empty;
1125 private UUID inventoryItemID;
1126 private IHttpServer httpListener;
1127 private bool m_dumpAssetToFile;
1128  
1129 public ItemUpdater(UUID inventoryItem, string path, IHttpServer httpServer, bool dumpAssetToFile)
1130 {
1131 m_dumpAssetToFile = dumpAssetToFile;
1132  
1133 inventoryItemID = inventoryItem;
1134 uploaderPath = path;
1135 httpListener = httpServer;
1136 }
1137  
1138 /// <summary>
1139 /// Handle raw uploaded asset data.
1140 /// </summary>
1141 /// <param name="data"></param>
1142 /// <param name="path"></param>
1143 /// <param name="param"></param>
1144 /// <returns></returns>
1145 public string uploaderCaps(byte[] data, string path, string param)
1146 {
1147 UUID inv = inventoryItemID;
1148 string res = String.Empty;
1149 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
1150 UUID assetID = UUID.Zero;
1151 handlerUpdateItem = OnUpLoad;
1152 if (handlerUpdateItem != null)
1153 {
1154 assetID = handlerUpdateItem(inv, data);
1155 }
1156  
1157 uploadComplete.new_asset = assetID.ToString();
1158 uploadComplete.new_inventory_item = inv;
1159 uploadComplete.state = "complete";
1160  
1161 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
1162  
1163 httpListener.RemoveStreamHandler("POST", uploaderPath);
1164  
1165 if (m_dumpAssetToFile)
1166 {
1167 SaveAssetToFile("updateditem" + Util.RandomClass.Next(1, 1000) + ".dat", data);
1168 }
1169  
1170 return res;
1171 }
1172  
1173 ///Left this in and commented in case there are unforseen issues
1174 //private void SaveAssetToFile(string filename, byte[] data)
1175 //{
1176 // FileStream fs = File.Create(filename);
1177 // BinaryWriter bw = new BinaryWriter(fs);
1178 // bw.Write(data);
1179 // bw.Close();
1180 // fs.Close();
1181 //}
1182  
1183 private static void SaveAssetToFile(string filename, byte[] data)
1184 {
1185 string assetPath = "UserAssets";
1186 if (!Directory.Exists(assetPath))
1187 {
1188 Directory.CreateDirectory(assetPath);
1189 }
1190 FileStream fs = File.Create(Path.Combine(assetPath, filename));
1191 BinaryWriter bw = new BinaryWriter(fs);
1192 bw.Write(data);
1193 bw.Close();
1194 fs.Close();
1195 }
1196 }
1197  
1198 /// <summary>
1199 /// This class is a callback invoked when a client sends asset data to
1200 /// a task inventory script update url
1201 /// </summary>
1202 public class TaskInventoryScriptUpdater
1203 {
1204 private static readonly ILog m_log =
1205 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
1206  
1207 public event UpdateTaskScript OnUpLoad;
1208  
1209 private UpdateTaskScript handlerUpdateTaskScript = null;
1210  
1211 private string uploaderPath = String.Empty;
1212 private UUID inventoryItemID;
1213 private UUID primID;
1214 private bool isScriptRunning;
1215 private IHttpServer httpListener;
1216 private bool m_dumpAssetToFile;
1217  
1218 public TaskInventoryScriptUpdater(UUID inventoryItemID, UUID primID, int isScriptRunning,
1219 string path, IHttpServer httpServer, bool dumpAssetToFile)
1220 {
1221 m_dumpAssetToFile = dumpAssetToFile;
1222  
1223 this.inventoryItemID = inventoryItemID;
1224 this.primID = primID;
1225  
1226 // This comes in over the packet as an integer, but actually appears to be treated as a bool
1227 this.isScriptRunning = (0 == isScriptRunning ? false : true);
1228  
1229 uploaderPath = path;
1230 httpListener = httpServer;
1231 }
1232  
1233 /// <summary>
1234 ///
1235 /// </summary>
1236 /// <param name="data"></param>
1237 /// <param name="path"></param>
1238 /// <param name="param"></param>
1239 /// <returns></returns>
1240 public string uploaderCaps(byte[] data, string path, string param)
1241 {
1242 try
1243 {
1244 // m_log.InfoFormat("[CAPS]: " +
1245 // "TaskInventoryScriptUpdater received data: {0}, path: {1}, param: {2}",
1246 // data, path, param));
1247  
1248 string res = String.Empty;
1249 LLSDTaskScriptUploadComplete uploadComplete = new LLSDTaskScriptUploadComplete();
1250  
1251 ArrayList errors = new ArrayList();
1252 handlerUpdateTaskScript = OnUpLoad;
1253 if (handlerUpdateTaskScript != null)
1254 {
1255 handlerUpdateTaskScript(inventoryItemID, primID, isScriptRunning, data, ref errors);
1256 }
1257  
1258 uploadComplete.new_asset = inventoryItemID;
1259 uploadComplete.compiled = errors.Count > 0 ? false : true;
1260 uploadComplete.state = "complete";
1261 uploadComplete.errors = new OpenSim.Framework.Capabilities.OSDArray();
1262 uploadComplete.errors.Array = errors;
1263  
1264 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
1265  
1266 httpListener.RemoveStreamHandler("POST", uploaderPath);
1267  
1268 if (m_dumpAssetToFile)
1269 {
1270 SaveAssetToFile("updatedtaskscript" + Util.RandomClass.Next(1, 1000) + ".dat", data);
1271 }
1272  
1273 // m_log.InfoFormat("[CAPS]: TaskInventoryScriptUpdater.uploaderCaps res: {0}", res);
1274  
1275 return res;
1276 }
1277 catch (Exception e)
1278 {
1279 m_log.Error("[CAPS]: " + e.ToString());
1280 }
1281  
1282 // XXX Maybe this should be some meaningful error packet
1283 return null;
1284 }
1285  
1286 ///Left this in and commented in case there are unforseen issues
1287 //private void SaveAssetToFile(string filename, byte[] data)
1288 //{
1289 // FileStream fs = File.Create(filename);
1290 // BinaryWriter bw = new BinaryWriter(fs);
1291 // bw.Write(data);
1292 // bw.Close();
1293 // fs.Close();
1294 //}
1295 private static void SaveAssetToFile(string filename, byte[] data)
1296 {
1297 string assetPath = "UserAssets";
1298 if (!Directory.Exists(assetPath))
1299 {
1300 Directory.CreateDirectory(assetPath);
1301 }
1302 FileStream fs = File.Create(Path.Combine(assetPath, filename));
1303 BinaryWriter bw = new BinaryWriter(fs);
1304 bw.Write(data);
1305 bw.Close();
1306 fs.Close();
1307 }
1308 }
1309 }