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