opensim – Blame information for rev 1

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