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.cs910
1 files changed, 763 insertions, 147 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index 8752404..8241e07 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Timers;
29using System.Collections; 30using System.Collections;
30using System.Collections.Generic; 31using System.Collections.Generic;
31using System.IO; 32using System.IO;
@@ -54,14 +55,16 @@ using PermissionMask = OpenSim.Framework.PermissionMask;
54namespace OpenSim.Region.ClientStack.Linden 55namespace OpenSim.Region.ClientStack.Linden
55{ 56{
56 public delegate void UpLoadedAsset( 57 public delegate void UpLoadedAsset(
57 string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder, 58 string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder,
58 byte[] data, string inventoryType, string assetType); 59 byte[] data, string inventoryType, string assetType,
60 int cost, UUID texturesFolder, int nreqtextures, int nreqmeshs, int nreqinstances,
61 bool IsAtestUpload, ref string error);
59 62
60 public delegate UUID UpdateItem(UUID itemID, byte[] data); 63 public delegate UUID UpdateItem(UUID itemID, byte[] data);
61 64
62 public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors); 65 public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors);
63 66
64 public delegate void NewInventoryItem(UUID userID, InventoryItemBase item); 67 public delegate void NewInventoryItem(UUID userID, InventoryItemBase item, uint cost);
65 68
66 public delegate void NewAsset(AssetBase asset); 69 public delegate void NewAsset(AssetBase asset);
67 70
@@ -87,6 +90,7 @@ namespace OpenSim.Region.ClientStack.Linden
87 90
88 private Scene m_Scene; 91 private Scene m_Scene;
89 private Caps m_HostCapsObj; 92 private Caps m_HostCapsObj;
93 private ModelCost m_ModelCost;
90 94
91 private static readonly string m_requestPath = "0000/"; 95 private static readonly string m_requestPath = "0000/";
92 // private static readonly string m_mapLayerPath = "0001/"; 96 // private static readonly string m_mapLayerPath = "0001/";
@@ -98,7 +102,8 @@ namespace OpenSim.Region.ClientStack.Linden
98 private static readonly string m_copyFromNotecardPath = "0007/"; 102 private static readonly string m_copyFromNotecardPath = "0007/";
99 // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule. 103 // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule.
100 private static readonly string m_getObjectPhysicsDataPath = "0101/"; 104 private static readonly string m_getObjectPhysicsDataPath = "0101/";
101 /* 0102 - 0103 RESERVED */ 105 private static readonly string m_getObjectCostPath = "0102/";
106 private static readonly string m_ResourceCostSelectedPath = "0103/";
102 private static readonly string m_UpdateAgentInformationPath = "0500/"; 107 private static readonly string m_UpdateAgentInformationPath = "0500/";
103 108
104 // These are callbacks which will be setup by the scene so that we can update scene data when we 109 // These are callbacks which will be setup by the scene so that we can update scene data when we
@@ -114,12 +119,50 @@ namespace OpenSim.Region.ClientStack.Linden
114 private IAssetService m_assetService; 119 private IAssetService m_assetService;
115 private bool m_dumpAssetsToFile = false; 120 private bool m_dumpAssetsToFile = false;
116 private string m_regionName; 121 private string m_regionName;
122
117 private int m_levelUpload = 0; 123 private int m_levelUpload = 0;
118 124
125 private bool m_enableFreeTestUpload = false; // allows "TEST-" prefix hack
126 private bool m_ForceFreeTestUpload = false; // forces all uploads to be test
127
128 private bool m_enableModelUploadTextureToInventory = false; // place uploaded textures also in inventory
129 // may not be visible till relog
130
131 private bool m_RestrictFreeTestUploadPerms = false; // reduces also the permitions. Needs a creator defined!!
132 private UUID m_testAssetsCreatorID = UUID.Zero;
133
134 private float m_PrimScaleMin = 0.001f;
135
136 private enum FileAgentInventoryState : int
137 {
138 idle = 0,
139 processRequest = 1,
140 waitUpload = 2,
141 processUpload = 3
142 }
143 private FileAgentInventoryState m_FileAgentInventoryState = FileAgentInventoryState.idle;
144
119 public BunchOfCaps(Scene scene, Caps caps) 145 public BunchOfCaps(Scene scene, Caps caps)
120 { 146 {
121 m_Scene = scene; 147 m_Scene = scene;
122 m_HostCapsObj = caps; 148 m_HostCapsObj = caps;
149
150 // create a model upload cost provider
151 m_ModelCost = new ModelCost();
152 // tell it about scene object limits
153 m_ModelCost.NonPhysicalPrimScaleMax = m_Scene.m_maxNonphys;
154 m_ModelCost.PhysicalPrimScaleMax = m_Scene.m_maxPhys;
155
156// m_ModelCost.ObjectLinkedPartsMax = ??
157// m_ModelCost.PrimScaleMin = ??
158
159 m_PrimScaleMin = m_ModelCost.PrimScaleMin;
160 float modelTextureUploadFactor = m_ModelCost.ModelTextureCostFactor;
161 float modelUploadFactor = m_ModelCost.ModelMeshCostFactor;
162 float modelMinUploadCostFactor = m_ModelCost.ModelMinCostFactor;
163 float modelPrimCreationCost = m_ModelCost.primCreationCost;
164 float modelMeshByteCost = m_ModelCost.bytecost;
165
123 IConfigSource config = m_Scene.Config; 166 IConfigSource config = m_Scene.Config;
124 if (config != null) 167 if (config != null)
125 { 168 {
@@ -134,6 +177,37 @@ namespace OpenSim.Region.ClientStack.Linden
134 { 177 {
135 m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures); 178 m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
136 } 179 }
180 // economy for model upload
181 IConfig EconomyConfig = config.Configs["Economy"];
182 if (EconomyConfig != null)
183 {
184 modelUploadFactor = EconomyConfig.GetFloat("MeshModelUploadCostFactor", modelUploadFactor);
185 modelTextureUploadFactor = EconomyConfig.GetFloat("MeshModelUploadTextureCostFactor", modelTextureUploadFactor);
186 modelMinUploadCostFactor = EconomyConfig.GetFloat("MeshModelMinCostFactor", modelMinUploadCostFactor);
187 // next 2 are normalized so final cost is afected by modelUploadFactor above and normal cost
188 modelPrimCreationCost = EconomyConfig.GetFloat("ModelPrimCreationCost", modelPrimCreationCost);
189 modelMeshByteCost = EconomyConfig.GetFloat("ModelMeshByteCost", modelMeshByteCost);
190
191 m_enableModelUploadTextureToInventory = EconomyConfig.GetBoolean("MeshModelAllowTextureToInventory", m_enableModelUploadTextureToInventory);
192
193 m_RestrictFreeTestUploadPerms = EconomyConfig.GetBoolean("m_RestrictFreeTestUploadPerms", m_RestrictFreeTestUploadPerms);
194 m_enableFreeTestUpload = EconomyConfig.GetBoolean("AllowFreeTestUpload", m_enableFreeTestUpload);
195 m_ForceFreeTestUpload = EconomyConfig.GetBoolean("ForceFreeTestUpload", m_ForceFreeTestUpload);
196 string testcreator = EconomyConfig.GetString("TestAssetsCreatorID", "");
197 if (testcreator != "")
198 {
199 UUID id;
200 UUID.TryParse(testcreator, out id);
201 if (id != null)
202 m_testAssetsCreatorID = id;
203 }
204
205 m_ModelCost.ModelMeshCostFactor = modelUploadFactor;
206 m_ModelCost.ModelTextureCostFactor = modelTextureUploadFactor;
207 m_ModelCost.ModelMinCostFactor = modelMinUploadCostFactor;
208 m_ModelCost.primCreationCost = modelPrimCreationCost;
209 m_ModelCost.bytecost = modelMeshByteCost;
210 }
137 } 211 }
138 212
139 m_assetService = m_Scene.AssetService; 213 m_assetService = m_Scene.AssetService;
@@ -145,6 +219,8 @@ namespace OpenSim.Region.ClientStack.Linden
145 ItemUpdatedCall = m_Scene.CapsUpdateInventoryItemAsset; 219 ItemUpdatedCall = m_Scene.CapsUpdateInventoryItemAsset;
146 TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset; 220 TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset;
147 GetClient = m_Scene.SceneGraph.GetControllingClient; 221 GetClient = m_Scene.SceneGraph.GetControllingClient;
222
223 m_FileAgentInventoryState = FileAgentInventoryState.idle;
148 } 224 }
149 225
150 /// <summary> 226 /// <summary>
@@ -190,7 +266,6 @@ namespace OpenSim.Region.ClientStack.Linden
190 { 266 {
191 try 267 try
192 { 268 {
193 // I don't think this one works...
194 m_HostCapsObj.RegisterHandler( 269 m_HostCapsObj.RegisterHandler(
195 "NewFileAgentInventory", 270 "NewFileAgentInventory",
196 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>( 271 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>(
@@ -209,6 +284,10 @@ namespace OpenSim.Region.ClientStack.Linden
209 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req); 284 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
210 IRequestHandler getObjectPhysicsDataHandler = new RestStreamHandler("POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData); 285 IRequestHandler getObjectPhysicsDataHandler = new RestStreamHandler("POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData);
211 m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler); 286 m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler);
287 IRequestHandler getObjectCostHandler = new RestStreamHandler("POST", capsBase + m_getObjectCostPath, GetObjectCost);
288 m_HostCapsObj.RegisterHandler("GetObjectCost", getObjectCostHandler);
289 IRequestHandler ResourceCostSelectedHandler = new RestStreamHandler("POST", capsBase + m_ResourceCostSelectedPath, ResourceCostSelected);
290 m_HostCapsObj.RegisterHandler("ResourceCostSelected", ResourceCostSelectedHandler);
212 IRequestHandler UpdateAgentInformationHandler = new RestStreamHandler("POST", capsBase + m_UpdateAgentInformationPath, UpdateAgentInformation); 291 IRequestHandler UpdateAgentInformationHandler = new RestStreamHandler("POST", capsBase + m_UpdateAgentInformationPath, UpdateAgentInformation);
213 m_HostCapsObj.RegisterHandler("UpdateAgentInformation", UpdateAgentInformationHandler); 292 m_HostCapsObj.RegisterHandler("UpdateAgentInformation", UpdateAgentInformationHandler);
214 293
@@ -264,6 +343,9 @@ namespace OpenSim.Region.ClientStack.Linden
264 m_log.DebugFormat( 343 m_log.DebugFormat(
265 "[CAPS]: Received SEED caps request in {0} for agent {1}", m_regionName, m_HostCapsObj.AgentID); 344 "[CAPS]: Received SEED caps request in {0} for agent {1}", m_regionName, m_HostCapsObj.AgentID);
266 345
346 if (!m_HostCapsObj.WaitForActivation())
347 return string.Empty;
348
267 if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint)) 349 if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
268 { 350 {
269 m_log.WarnFormat( 351 m_log.WarnFormat(
@@ -273,11 +355,22 @@ namespace OpenSim.Region.ClientStack.Linden
273 return string.Empty; 355 return string.Empty;
274 } 356 }
275 357
276 Hashtable caps = m_HostCapsObj.CapsHandlers.GetCapsDetails(true); 358 OSDArray capsRequested = (OSDArray)OSDParser.DeserializeLLSDXml(request);
359 List<string> validCaps = new List<string>();
360
361 foreach (OSD c in capsRequested)
362 validCaps.Add(c.AsString());
363
364 Hashtable caps = m_HostCapsObj.CapsHandlers.GetCapsDetails(true, validCaps);
277 365
278 // Add the external too 366 // Add the external too
279 foreach (KeyValuePair<string, string> kvp in m_HostCapsObj.ExternalCapsHandlers) 367 foreach (KeyValuePair<string, string> kvp in m_HostCapsObj.ExternalCapsHandlers)
368 {
369 if (!validCaps.Contains(kvp.Key))
370 continue;
371
280 caps[kvp.Key] = kvp.Value; 372 caps[kvp.Key] = kvp.Value;
373 }
281 374
282 string result = LLSDHelpers.SerialiseLLSDReply(caps); 375 string result = LLSDHelpers.SerialiseLLSDReply(caps);
283 376
@@ -393,62 +486,176 @@ namespace OpenSim.Region.ClientStack.Linden
393 //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString()); 486 //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString());
394 //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type); 487 //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type);
395 488
489 // start by getting the client
490 IClientAPI client = null;
491 m_Scene.TryGetClient(m_HostCapsObj.AgentID, out client);
492
493 // check current state so we only have one service at a time
494 lock (m_ModelCost)
495 {
496 switch (m_FileAgentInventoryState)
497 {
498 case FileAgentInventoryState.processRequest:
499 case FileAgentInventoryState.processUpload:
500 LLSDAssetUploadError resperror = new LLSDAssetUploadError();
501 resperror.message = "Uploader busy processing previus request";
502 resperror.identifier = UUID.Zero;
503
504 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
505 errorResponse.uploader = "";
506 errorResponse.state = "error";
507 errorResponse.error = resperror;
508 return errorResponse;
509 break;
510 case FileAgentInventoryState.waitUpload:
511 // todo stop current uploader server
512 break;
513 case FileAgentInventoryState.idle:
514 default:
515 break;
516 }
517
518 m_FileAgentInventoryState = FileAgentInventoryState.processRequest;
519 }
520
521 int cost = 0;
522 int nreqtextures = 0;
523 int nreqmeshs= 0;
524 int nreqinstances = 0;
525 bool IsAtestUpload = false;
526
527 string assetName = llsdRequest.name;
528
529 LLSDAssetUploadResponseData meshcostdata = new LLSDAssetUploadResponseData();
530
396 if (llsdRequest.asset_type == "texture" || 531 if (llsdRequest.asset_type == "texture" ||
397 llsdRequest.asset_type == "animation" || 532 llsdRequest.asset_type == "animation" ||
533 llsdRequest.asset_type == "mesh" ||
398 llsdRequest.asset_type == "sound") 534 llsdRequest.asset_type == "sound")
399 { 535 {
400 ScenePresence avatar = null; 536 ScenePresence avatar = null;
401 IClientAPI client = null;
402 m_Scene.TryGetScenePresence(m_HostCapsObj.AgentID, out avatar); 537 m_Scene.TryGetScenePresence(m_HostCapsObj.AgentID, out avatar);
403 538
404 // check user level 539 // check user level
405 if (avatar != null) 540 if (avatar != null)
406 { 541 {
407 client = avatar.ControllingClient;
408
409 if (avatar.UserLevel < m_levelUpload) 542 if (avatar.UserLevel < m_levelUpload)
410 { 543 {
411 if (client != null) 544 LLSDAssetUploadError resperror = new LLSDAssetUploadError();
412 client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false); 545 resperror.message = "Insufficient permissions to upload";
546 resperror.identifier = UUID.Zero;
413 547
414 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse(); 548 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
415 errorResponse.uploader = ""; 549 errorResponse.uploader = "";
416 errorResponse.state = "error"; 550 errorResponse.state = "error";
551 errorResponse.error = resperror;
552 lock (m_ModelCost)
553 m_FileAgentInventoryState = FileAgentInventoryState.idle;
417 return errorResponse; 554 return errorResponse;
418 } 555 }
419 } 556 }
420 557
421 // check funds 558 // check test upload and funds
422 if (client != null) 559 if (client != null)
423 { 560 {
424 IMoneyModule mm = m_Scene.RequestModuleInterface<IMoneyModule>(); 561 IMoneyModule mm = m_Scene.RequestModuleInterface<IMoneyModule>();
425 562
563 int baseCost = 0;
426 if (mm != null) 564 if (mm != null)
565 baseCost = mm.UploadCharge;
566
567 string warning = String.Empty;
568
569 if (llsdRequest.asset_type == "mesh")
427 { 570 {
428 if (!mm.UploadCovered(client.AgentId, mm.UploadCharge)) 571 string error;
572 int modelcost;
573
574 if (!m_ModelCost.MeshModelCost(llsdRequest.asset_resources, baseCost, out modelcost,
575 meshcostdata, out error, ref warning))
429 { 576 {
430 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); 577 LLSDAssetUploadError resperror = new LLSDAssetUploadError();
578 resperror.message = error;
579 resperror.identifier = UUID.Zero;
431 580
432 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse(); 581 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
433 errorResponse.uploader = ""; 582 errorResponse.uploader = "";
434 errorResponse.state = "error"; 583 errorResponse.state = "error";
584 errorResponse.error = resperror;
585
586 lock (m_ModelCost)
587 m_FileAgentInventoryState = FileAgentInventoryState.idle;
435 return errorResponse; 588 return errorResponse;
436 } 589 }
590 cost = modelcost;
591 }
592 else
593 {
594 cost = baseCost;
595 }
596
597 if (cost > 0 && mm != null)
598 {
599 // check for test upload
600
601 if (m_ForceFreeTestUpload) // all are test
602 {
603 if (!(assetName.Length > 5 && assetName.StartsWith("TEST-"))) // has normal name lets change it
604 assetName = "TEST-" + assetName;
605
606 IsAtestUpload = true;
607 }
608
609 else if (m_enableFreeTestUpload) // only if prefixed with "TEST-"
610 {
611
612 IsAtestUpload = (assetName.Length > 5 && assetName.StartsWith("TEST-"));
613 }
614
615
616 if(IsAtestUpload) // let user know, still showing cost estimation
617 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";
618
619 // check funds
620 else
621 {
622 if (!mm.UploadCovered(client.AgentId, (int)cost))
623 {
624 LLSDAssetUploadError resperror = new LLSDAssetUploadError();
625 resperror.message = "Insuficient funds";
626 resperror.identifier = UUID.Zero;
627
628 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
629 errorResponse.uploader = "";
630 errorResponse.state = "error";
631 errorResponse.error = resperror;
632 lock (m_ModelCost)
633 m_FileAgentInventoryState = FileAgentInventoryState.idle;
634 return errorResponse;
635 }
636 }
437 } 637 }
638
639 if (client != null && warning != String.Empty)
640 client.SendAgentAlertMessage(warning, true);
438 } 641 }
439 } 642 }
440 643
441 string assetName = llsdRequest.name;
442 string assetDes = llsdRequest.description; 644 string assetDes = llsdRequest.description;
443 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; 645 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
444 UUID newAsset = UUID.Random(); 646 UUID newAsset = UUID.Random();
445 UUID newInvItem = UUID.Random(); 647 UUID newInvItem = UUID.Random();
446 UUID parentFolder = llsdRequest.folder_id; 648 UUID parentFolder = llsdRequest.folder_id;
447 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); 649 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
650 UUID texturesFolder = UUID.Zero;
651
652 if(!IsAtestUpload && m_enableModelUploadTextureToInventory)
653 texturesFolder = llsdRequest.texture_folder_id;
448 654
449 AssetUploader uploader = 655 AssetUploader uploader =
450 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, 656 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
451 llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile); 657 llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile, cost,
658 texturesFolder, nreqtextures, nreqmeshs, nreqinstances, IsAtestUpload);
452 659
453 m_HostCapsObj.HttpListener.AddStreamHandler( 660 m_HostCapsObj.HttpListener.AddStreamHandler(
454 new BinaryStreamHandler( 661 new BinaryStreamHandler(
@@ -466,10 +673,22 @@ namespace OpenSim.Region.ClientStack.Linden
466 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase + 673 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase +
467 uploaderPath; 674 uploaderPath;
468 675
676
469 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); 677 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
470 uploadResponse.uploader = uploaderURL; 678 uploadResponse.uploader = uploaderURL;
471 uploadResponse.state = "upload"; 679 uploadResponse.state = "upload";
680 uploadResponse.upload_price = (int)cost;
681
682 if (llsdRequest.asset_type == "mesh")
683 {
684 uploadResponse.data = meshcostdata;
685 }
686
472 uploader.OnUpLoad += UploadCompleteHandler; 687 uploader.OnUpLoad += UploadCompleteHandler;
688
689 lock (m_ModelCost)
690 m_FileAgentInventoryState = FileAgentInventoryState.waitUpload;
691
473 return uploadResponse; 692 return uploadResponse;
474 } 693 }
475 694
@@ -481,8 +700,14 @@ namespace OpenSim.Region.ClientStack.Linden
481 /// <param name="data"></param> 700 /// <param name="data"></param>
482 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID, 701 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
483 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType, 702 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
484 string assetType) 703 string assetType, int cost,
704 UUID texturesFolder, int nreqtextures, int nreqmeshs, int nreqinstances,
705 bool IsAtestUpload, ref string error)
485 { 706 {
707
708 lock (m_ModelCost)
709 m_FileAgentInventoryState = FileAgentInventoryState.processUpload;
710
486 m_log.DebugFormat( 711 m_log.DebugFormat(
487 "[BUNCH OF CAPS]: Uploaded asset {0} for inventory item {1}, inv type {2}, asset type {3}", 712 "[BUNCH OF CAPS]: Uploaded asset {0} for inventory item {1}, inv type {2}, asset type {3}",
488 assetID, inventoryItem, inventoryType, assetType); 713 assetID, inventoryItem, inventoryType, assetType);
@@ -490,117 +715,247 @@ namespace OpenSim.Region.ClientStack.Linden
490 sbyte assType = 0; 715 sbyte assType = 0;
491 sbyte inType = 0; 716 sbyte inType = 0;
492 717
718 IClientAPI client = null;
719
720 UUID owner_id = m_HostCapsObj.AgentID;
721 UUID creatorID;
722
723 bool istest = IsAtestUpload && m_enableFreeTestUpload && (cost > 0);
724
725 bool restrictPerms = m_RestrictFreeTestUploadPerms && istest;
726
727 if (istest && m_testAssetsCreatorID != UUID.Zero)
728 creatorID = m_testAssetsCreatorID;
729 else
730 creatorID = owner_id;
731
732 string creatorIDstr = creatorID.ToString();
733
734 IMoneyModule mm = m_Scene.RequestModuleInterface<IMoneyModule>();
735 if (mm != null)
736 {
737 // make sure client still has enougth credit
738 if (!mm.UploadCovered(m_HostCapsObj.AgentID, (int)cost))
739 {
740 error = "Insufficient funds.";
741 return;
742 }
743 }
744
745 // strings to types
493 if (inventoryType == "sound") 746 if (inventoryType == "sound")
494 { 747 {
495 inType = 1; 748 inType = (sbyte)InventoryType.Sound;
496 assType = 1; 749 assType = (sbyte)AssetType.Sound;
497 } 750 }
498 else if (inventoryType == "animation") 751 else if (inventoryType == "animation")
499 { 752 {
500 inType = 19; 753 inType = (sbyte)InventoryType.Animation;
501 assType = 20; 754 assType = (sbyte)AssetType.Animation;
502 } 755 }
503 else if (inventoryType == "wearable") 756 else if (inventoryType == "wearable")
504 { 757 {
505 inType = 18; 758 inType = (sbyte)InventoryType.Wearable;
506 switch (assetType) 759 switch (assetType)
507 { 760 {
508 case "bodypart": 761 case "bodypart":
509 assType = 13; 762 assType = (sbyte)AssetType.Bodypart;
510 break; 763 break;
511 case "clothing": 764 case "clothing":
512 assType = 5; 765 assType = (sbyte)AssetType.Clothing;
513 break; 766 break;
514 } 767 }
515 } 768 }
516 else if (inventoryType == "object") 769 else if (inventoryType == "object")
517 { 770 {
518 inType = (sbyte)InventoryType.Object; 771 if (assetType == "mesh") // this code for now is for mesh models uploads only
519 assType = (sbyte)AssetType.Object;
520
521 List<Vector3> positions = new List<Vector3>();
522 List<Quaternion> rotations = new List<Quaternion>();
523 OSDMap request = (OSDMap)OSDParser.DeserializeLLSDXml(data);
524 OSDArray instance_list = (OSDArray)request["instance_list"];
525 OSDArray mesh_list = (OSDArray)request["mesh_list"];
526 OSDArray texture_list = (OSDArray)request["texture_list"];
527 SceneObjectGroup grp = null;
528
529 List<UUID> textures = new List<UUID>();
530 for (int i = 0; i < texture_list.Count; i++)
531 { 772 {
532 AssetBase textureAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Texture, ""); 773 inType = (sbyte)InventoryType.Object;
533 textureAsset.Data = texture_list[i].AsBinary(); 774 assType = (sbyte)AssetType.Object;
534 m_assetService.Store(textureAsset);
535 textures.Add(textureAsset.FullID);
536 }
537 775
538 for (int i = 0; i < mesh_list.Count; i++) 776 List<Vector3> positions = new List<Vector3>();
539 { 777 List<Quaternion> rotations = new List<Quaternion>();
540 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox(); 778 OSDMap request = (OSDMap)OSDParser.DeserializeLLSDXml(data);
541 779
542 Primitive.TextureEntry textureEntry 780 // compare and get updated information
543 = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE);
544 OSDMap inner_instance_list = (OSDMap)instance_list[i];
545 781
546 OSDArray face_list = (OSDArray)inner_instance_list["face_list"]; 782 bool mismatchError = true;
547 for (uint face = 0; face < face_list.Count; face++) 783
784 while (mismatchError)
548 { 785 {
549 OSDMap faceMap = (OSDMap)face_list[(int)face]; 786 mismatchError = false;
550 Primitive.TextureEntryFace f = pbs.Textures.CreateFace(face); 787 }
551 if(faceMap.ContainsKey("fullbright"))
552 f.Fullbright = faceMap["fullbright"].AsBoolean();
553 if (faceMap.ContainsKey ("diffuse_color"))
554 f.RGBA = faceMap["diffuse_color"].AsColor4();
555 788
556 int textureNum = faceMap["image"].AsInteger(); 789 if (mismatchError)
557 float imagerot = faceMap["imagerot"].AsInteger(); 790 {
558 float offsets = (float)faceMap["offsets"].AsReal(); 791 error = "Upload and fee estimation information don't match";
559 float offsett = (float)faceMap["offsett"].AsReal(); 792 lock (m_ModelCost)
560 float scales = (float)faceMap["scales"].AsReal(); 793 m_FileAgentInventoryState = FileAgentInventoryState.idle;
561 float scalet = (float)faceMap["scalet"].AsReal(); 794
795 return;
796 }
562 797
563 if(imagerot != 0) 798 OSDArray instance_list = (OSDArray)request["instance_list"];
564 f.Rotation = imagerot; 799 OSDArray mesh_list = (OSDArray)request["mesh_list"];
800 OSDArray texture_list = (OSDArray)request["texture_list"];
801 SceneObjectGroup grp = null;
565 802
566 if(offsets != 0) 803 // create and store texture assets
567 f.OffsetU = offsets; 804 bool doTextInv = (!istest && m_enableModelUploadTextureToInventory &&
805 texturesFolder != UUID.Zero);
568 806
569 if (offsett != 0)
570 f.OffsetV = offsett;
571 807
572 if (scales != 0) 808 List<UUID> textures = new List<UUID>();
573 f.RepeatU = scales;
574 809
575 if (scalet != 0) 810
576 f.RepeatV = scalet; 811 if (doTextInv)
812 m_Scene.TryGetClient(m_HostCapsObj.AgentID, out client);
577 813
578 if (textures.Count > textureNum) 814 if(client == null) // don't put textures in inventory if there is no client
579 f.TextureID = textures[textureNum]; 815 doTextInv = false;
580 else 816
581 f.TextureID = Primitive.TextureEntry.WHITE_TEXTURE; 817 for (int i = 0; i < texture_list.Count; i++)
818 {
819 AssetBase textureAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Texture, creatorIDstr);
820 textureAsset.Data = texture_list[i].AsBinary();
821 if (istest)
822 textureAsset.Local = true;
823 m_assetService.Store(textureAsset);
824 textures.Add(textureAsset.FullID);
825
826 if (doTextInv)
827 {
828 string name = assetName;
829 if (name.Length > 25)
830 name = name.Substring(0, 24);
831 name += "_Texture#" + i.ToString();
832 InventoryItemBase texitem = new InventoryItemBase();
833 texitem.Owner = m_HostCapsObj.AgentID;
834 texitem.CreatorId = creatorIDstr;
835 texitem.CreatorData = String.Empty;
836 texitem.ID = UUID.Random();
837 texitem.AssetID = textureAsset.FullID;
838 texitem.Description = "mesh model texture";
839 texitem.Name = name;
840 texitem.AssetType = (int)AssetType.Texture;
841 texitem.InvType = (int)InventoryType.Texture;
842 texitem.Folder = texturesFolder;
843
844 texitem.CurrentPermissions
845 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Export);
846
847 texitem.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
848 texitem.EveryOnePermissions = 0;
849 texitem.NextPermissions = (uint)PermissionMask.All;
850 texitem.CreationDate = Util.UnixTimeSinceEpoch();
851
852 m_Scene.AddInventoryItem(client, texitem);
853 texitem = null;
854 }
855 }
582 856
583 textureEntry.FaceTextures[face] = f; 857 // create and store meshs assets
858 List<UUID> meshAssets = new List<UUID>();
859 for (int i = 0; i < mesh_list.Count; i++)
860 {
861 AssetBase meshAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Mesh, creatorIDstr);
862 meshAsset.Data = mesh_list[i].AsBinary();
863 if (istest)
864 meshAsset.Local = true;
865 m_assetService.Store(meshAsset);
866 meshAssets.Add(meshAsset.FullID);
584 } 867 }
585 868
586 pbs.TextureEntry = textureEntry.GetBytes(); 869 int skipedMeshs = 0;
870 // build prims from instances
871 for (int i = 0; i < instance_list.Count; i++)
872 {
873 OSDMap inner_instance_list = (OSDMap)instance_list[i];
874
875 // skip prims that are 2 small
876 Vector3 scale = inner_instance_list["scale"].AsVector3();
877
878 if (scale.X < m_PrimScaleMin || scale.Y < m_PrimScaleMin || scale.Z < m_PrimScaleMin)
879 {
880 skipedMeshs++;
881 continue;
882 }
883
884 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
587 885
588 AssetBase meshAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Mesh, ""); 886 Primitive.TextureEntry textureEntry
589 meshAsset.Data = mesh_list[i].AsBinary(); 887 = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE);
590 m_assetService.Store(meshAsset);
591 888
592 pbs.SculptEntry = true;
593 pbs.SculptTexture = meshAsset.FullID;
594 pbs.SculptType = (byte)SculptType.Mesh;
595 pbs.SculptData = meshAsset.Data;
596 889
597 Vector3 position = inner_instance_list["position"].AsVector3(); 890 OSDArray face_list = (OSDArray)inner_instance_list["face_list"];
598 Vector3 scale = inner_instance_list["scale"].AsVector3(); 891 for (uint face = 0; face < face_list.Count; face++)
599 Quaternion rotation = inner_instance_list["rotation"].AsQuaternion(); 892 {
893 OSDMap faceMap = (OSDMap)face_list[(int)face];
894 Primitive.TextureEntryFace f = pbs.Textures.CreateFace(face);
895 if (faceMap.ContainsKey("fullbright"))
896 f.Fullbright = faceMap["fullbright"].AsBoolean();
897 if (faceMap.ContainsKey("diffuse_color"))
898 f.RGBA = faceMap["diffuse_color"].AsColor4();
899
900 int textureNum = faceMap["image"].AsInteger();
901 float imagerot = faceMap["imagerot"].AsInteger();
902 float offsets = (float)faceMap["offsets"].AsReal();
903 float offsett = (float)faceMap["offsett"].AsReal();
904 float scales = (float)faceMap["scales"].AsReal();
905 float scalet = (float)faceMap["scalet"].AsReal();
906
907 if (imagerot != 0)
908 f.Rotation = imagerot;
909
910 if (offsets != 0)
911 f.OffsetU = offsets;
912
913 if (offsett != 0)
914 f.OffsetV = offsett;
915
916 if (scales != 0)
917 f.RepeatU = scales;
918
919 if (scalet != 0)
920 f.RepeatV = scalet;
921
922 if (textures.Count > textureNum)
923 f.TextureID = textures[textureNum];
924 else
925 f.TextureID = Primitive.TextureEntry.WHITE_TEXTURE;
926
927 textureEntry.FaceTextures[face] = f;
928 }
929
930 pbs.TextureEntry = textureEntry.GetBytes();
931
932 bool hasmesh = false;
933 if (inner_instance_list.ContainsKey("mesh")) // seems to happen always but ...
934 {
935 int meshindx = inner_instance_list["mesh"].AsInteger();
936 if (meshAssets.Count > meshindx)
937 {
938 pbs.SculptEntry = true;
939 pbs.SculptType = (byte)SculptType.Mesh;
940 pbs.SculptTexture = meshAssets[meshindx]; // actual asset UUID after meshs suport introduction
941 // data will be requested from asset on rez (i hope)
942 hasmesh = true;
943 }
944 }
945
946 Vector3 position = inner_instance_list["position"].AsVector3();
947 Quaternion rotation = inner_instance_list["rotation"].AsQuaternion();
948
949 // for now viwers do send fixed defaults
950 // but this may change
951// int physicsShapeType = inner_instance_list["physics_shape_type"].AsInteger();
952 byte physicsShapeType = (byte)PhysShapeType.prim; // default for mesh is simple convex
953 if(hasmesh)
954 physicsShapeType = (byte) PhysShapeType.convex; // default for mesh is simple convex
955// int material = inner_instance_list["material"].AsInteger();
956 byte material = (byte)Material.Wood;
600 957
601// no longer used - begin ------------------------ 958// no longer used - begin ------------------------
602// int physicsShapeType = inner_instance_list["physics_shape_type"].AsInteger();
603// int material = inner_instance_list["material"].AsInteger();
604// int mesh = inner_instance_list["mesh"].AsInteger(); 959// int mesh = inner_instance_list["mesh"].AsInteger();
605 960
606// OSDMap permissions = (OSDMap)inner_instance_list["permissions"]; 961// OSDMap permissions = (OSDMap)inner_instance_list["permissions"];
@@ -615,24 +970,49 @@ namespace OpenSim.Region.ClientStack.Linden
615// UUID owner_id = permissions["owner_id"].AsUUID(); 970// UUID owner_id = permissions["owner_id"].AsUUID();
616// int owner_mask = permissions["owner_mask"].AsInteger(); 971// int owner_mask = permissions["owner_mask"].AsInteger();
617// no longer used - end ------------------------ 972// no longer used - end ------------------------
973
974
975 SceneObjectPart prim
976 = new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero);
977
978 prim.Scale = scale;
979 rotations.Add(rotation);
980 positions.Add(position);
981 prim.UUID = UUID.Random();
982 prim.CreatorID = creatorID;
983 prim.OwnerID = owner_id;
984 prim.GroupID = UUID.Zero;
985 prim.LastOwnerID = creatorID;
986 prim.CreationDate = Util.UnixTimeSinceEpoch();
987
988 if (grp == null)
989 prim.Name = assetName;
990 else
991 prim.Name = assetName + "#" + i.ToString();
618 992
619 UUID owner_id = m_HostCapsObj.AgentID; 993 prim.EveryoneMask = 0;
994 prim.GroupMask = 0;
995
996 if (restrictPerms)
997 {
998 prim.BaseMask = (uint)(PermissionMask.Move | PermissionMask.Modify);
999 prim.OwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify);
1000 prim.NextOwnerMask = 0;
1001 }
1002 else
1003 {
1004 prim.BaseMask = (uint)PermissionMask.All | (uint)PermissionMask.Export;
1005 prim.OwnerMask = (uint)PermissionMask.All | (uint)PermissionMask.Export;
1006 prim.NextOwnerMask = (uint)PermissionMask.Transfer;
1007 }
620 1008
621 SceneObjectPart prim 1009 if(istest)
622 = new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero); 1010 prim.Description = "For testing only. Other uses are prohibited";
1011 else
1012 prim.Description = "";
623 1013
624 prim.Scale = scale; 1014 prim.Material = material;
625 //prim.OffsetPosition = position; 1015 prim.PhysicsShapeType = physicsShapeType;
626 rotations.Add(rotation);
627 positions.Add(position);
628 prim.UUID = UUID.Random();
629 prim.CreatorID = owner_id;
630 prim.OwnerID = owner_id;
631 prim.GroupID = UUID.Zero;
632 prim.LastOwnerID = prim.OwnerID;
633 prim.CreationDate = Util.UnixTimeSinceEpoch();
634 prim.Name = assetName;
635 prim.Description = "";
636 1016
637// prim.BaseMask = (uint)base_mask; 1017// prim.BaseMask = (uint)base_mask;
638// prim.EveryoneMask = (uint)everyone_mask; 1018// prim.EveryoneMask = (uint)everyone_mask;
@@ -640,52 +1020,64 @@ namespace OpenSim.Region.ClientStack.Linden
640// prim.NextOwnerMask = (uint)next_owner_mask; 1020// prim.NextOwnerMask = (uint)next_owner_mask;
641// prim.OwnerMask = (uint)owner_mask; 1021// prim.OwnerMask = (uint)owner_mask;
642 1022
643 if (grp == null) 1023 if (grp == null)
644 grp = new SceneObjectGroup(prim); 1024 {
645 else 1025 grp = new SceneObjectGroup(prim);
646 grp.AddPart(prim); 1026 grp.LastOwnerID = creatorID;
647 } 1027 }
1028 else
1029 grp.AddPart(prim);
1030 }
648 1031
649 Vector3 rootPos = positions[0]; 1032 Vector3 rootPos = positions[0];
650 1033
651 if (grp.Parts.Length > 1) 1034 if (grp.Parts.Length > 1)
652 { 1035 {
653 // Fix first link number 1036 // Fix first link number
654 grp.RootPart.LinkNum++; 1037 grp.RootPart.LinkNum++;
655 1038
656 Quaternion rootRotConj = Quaternion.Conjugate(rotations[0]); 1039 Quaternion rootRotConj = Quaternion.Conjugate(rotations[0]);
657 Quaternion tmprot; 1040 Quaternion tmprot;
658 Vector3 offset; 1041 Vector3 offset;
659 1042
660 // fix children rotations and positions 1043 // fix children rotations and positions
661 for (int i = 1; i < rotations.Count; i++) 1044 for (int i = 1; i < rotations.Count; i++)
662 { 1045 {
663 tmprot = rotations[i]; 1046 tmprot = rotations[i];
664 tmprot = rootRotConj * tmprot; 1047 tmprot = rootRotConj * tmprot;
1048
1049 grp.Parts[i].RotationOffset = tmprot;
665 1050
666 grp.Parts[i].RotationOffset = tmprot; 1051 offset = positions[i] - rootPos;
667 1052
668 offset = positions[i] - rootPos; 1053 offset *= rootRotConj;
1054 grp.Parts[i].OffsetPosition = offset;
1055 }
669 1056
670 offset *= rootRotConj; 1057 grp.AbsolutePosition = rootPos;
671 grp.Parts[i].OffsetPosition = offset; 1058 grp.UpdateGroupRotationR(rotations[0]);
1059 }
1060 else
1061 {
1062 grp.AbsolutePosition = rootPos;
1063 grp.UpdateGroupRotationR(rotations[0]);
672 } 1064 }
673 1065
674 grp.AbsolutePosition = rootPos; 1066 data = ASCIIEncoding.ASCII.GetBytes(SceneObjectSerializer.ToOriginalXmlFormat(grp));
675 grp.UpdateGroupRotationR(rotations[0]);
676 } 1067 }
677 else 1068
1069 else // not a mesh model
678 { 1070 {
679 grp.AbsolutePosition = rootPos; 1071 m_log.ErrorFormat("[CAPS Asset Upload] got unsuported assetType for object upload");
680 grp.UpdateGroupRotationR(rotations[0]); 1072 return;
681 } 1073 }
682
683 data = ASCIIEncoding.ASCII.GetBytes(SceneObjectSerializer.ToOriginalXmlFormat(grp));
684 } 1074 }
685 1075
686 AssetBase asset; 1076 AssetBase asset;
687 asset = new AssetBase(assetID, assetName, assType, m_HostCapsObj.AgentID.ToString()); 1077 asset = new AssetBase(assetID, assetName, assType, creatorIDstr);
688 asset.Data = data; 1078 asset.Data = data;
1079 if (istest)
1080 asset.Local = true;
689 if (AddNewAsset != null) 1081 if (AddNewAsset != null)
690 AddNewAsset(asset); 1082 AddNewAsset(asset);
691 else if (m_assetService != null) 1083 else if (m_assetService != null)
@@ -693,11 +1085,17 @@ namespace OpenSim.Region.ClientStack.Linden
693 1085
694 InventoryItemBase item = new InventoryItemBase(); 1086 InventoryItemBase item = new InventoryItemBase();
695 item.Owner = m_HostCapsObj.AgentID; 1087 item.Owner = m_HostCapsObj.AgentID;
696 item.CreatorId = m_HostCapsObj.AgentID.ToString(); 1088 item.CreatorId = creatorIDstr;
697 item.CreatorData = String.Empty; 1089 item.CreatorData = String.Empty;
698 item.ID = inventoryItem; 1090 item.ID = inventoryItem;
699 item.AssetID = asset.FullID; 1091 item.AssetID = asset.FullID;
700 item.Description = assetDescription; 1092 if (istest)
1093 {
1094 item.Description = "For testing only. Other uses are prohibited";
1095 item.Flags = (uint) (InventoryItemFlags.SharedSingleReference);
1096 }
1097 else
1098 item.Description = assetDescription;
701 item.Name = assetName; 1099 item.Name = assetName;
702 item.AssetType = assType; 1100 item.AssetType = assType;
703 item.InvType = inType; 1101 item.InvType = inType;
@@ -705,18 +1103,56 @@ namespace OpenSim.Region.ClientStack.Linden
705 1103
706 // If we set PermissionMask.All then when we rez the item the next permissions will replace the current 1104 // If we set PermissionMask.All then when we rez the item the next permissions will replace the current
707 // (owner) permissions. This becomes a problem if next permissions are changed. 1105 // (owner) permissions. This becomes a problem if next permissions are changed.
708 item.CurrentPermissions
709 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Export);
710 1106
711 item.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export; 1107 if (restrictPerms)
712 item.EveryOnePermissions = 0; 1108 {
713 item.NextPermissions = (uint)PermissionMask.All; 1109 item.BasePermissions = (uint)(PermissionMask.Move | PermissionMask.Modify);
1110 item.CurrentPermissions = (uint)(PermissionMask.Move | PermissionMask.Modify);
1111 item.EveryOnePermissions = 0;
1112 item.NextPermissions = 0;
1113 }
1114 else
1115 {
1116 item.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
1117 item.CurrentPermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
1118 item.EveryOnePermissions = 0;
1119 item.NextPermissions = (uint)PermissionMask.Transfer;
1120 }
1121
714 item.CreationDate = Util.UnixTimeSinceEpoch(); 1122 item.CreationDate = Util.UnixTimeSinceEpoch();
715 1123
1124 m_Scene.TryGetClient(m_HostCapsObj.AgentID, out client);
1125
716 if (AddNewInventoryItem != null) 1126 if (AddNewInventoryItem != null)
717 { 1127 {
718 AddNewInventoryItem(m_HostCapsObj.AgentID, item); 1128 if (istest)
1129 {
1130 m_Scene.AddInventoryItem(client, item);
1131/*
1132 AddNewInventoryItem(m_HostCapsObj.AgentID, item, 0);
1133 if (client != null)
1134 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);
1135 */
1136 }
1137 else
1138 {
1139 AddNewInventoryItem(m_HostCapsObj.AgentID, item, (uint)cost);
1140// if (client != null)
1141// {
1142// // let users see anything.. i don't so far
1143// string str;
1144// if (cost > 0)
1145// // dont remember where is money unit name to put here
1146// str = "Upload complete. charged " + cost.ToString() + "$";
1147// else
1148// str = "Upload complete";
1149// client.SendAgentAlertMessage(str, true);
1150// }
1151 }
719 } 1152 }
1153
1154 lock (m_ModelCost)
1155 m_FileAgentInventoryState = FileAgentInventoryState.idle;
720 } 1156 }
721 1157
722 /// <summary> 1158 /// <summary>
@@ -909,6 +1345,120 @@ namespace OpenSim.Region.ClientStack.Linden
909 return response; 1345 return response;
910 } 1346 }
911 1347
1348 public string GetObjectCost(string request, string path,
1349 string param, IOSHttpRequest httpRequest,
1350 IOSHttpResponse httpResponse)
1351 {
1352 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
1353 OSDMap resp = new OSDMap();
1354
1355 OSDArray object_ids = (OSDArray)req["object_ids"];
1356
1357 for (int i = 0; i < object_ids.Count; i++)
1358 {
1359 UUID uuid = object_ids[i].AsUUID();
1360
1361 SceneObjectPart part = m_Scene.GetSceneObjectPart(uuid);
1362
1363 if (part != null)
1364 {
1365 SceneObjectGroup grp = part.ParentGroup;
1366 if (grp != null)
1367 {
1368 float linksetCost;
1369 float linksetPhysCost;
1370 float partCost;
1371 float partPhysCost;
1372
1373 grp.GetResourcesCosts(part, out linksetCost, out linksetPhysCost, out partCost, out partPhysCost);
1374
1375 OSDMap object_data = new OSDMap();
1376 object_data["linked_set_resource_cost"] = linksetCost;
1377 object_data["resource_cost"] = partCost;
1378 object_data["physics_cost"] = partPhysCost;
1379 object_data["linked_set_physics_cost"] = linksetPhysCost;
1380
1381 resp[uuid.ToString()] = object_data;
1382 }
1383 }
1384 }
1385
1386 string response = OSDParser.SerializeLLSDXmlString(resp);
1387 return response;
1388 }
1389
1390 public string ResourceCostSelected(string request, string path,
1391 string param, IOSHttpRequest httpRequest,
1392 IOSHttpResponse httpResponse)
1393 {
1394 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
1395 OSDMap resp = new OSDMap();
1396
1397
1398 float phys=0;
1399 float stream=0;
1400 float simul=0;
1401
1402 if (req.ContainsKey("selected_roots"))
1403 {
1404 OSDArray object_ids = (OSDArray)req["selected_roots"];
1405
1406 // should go by SOG suming costs for all parts
1407 // ll v3 works ok with several objects select we get the list and adds ok
1408 // FS calls per object so results are wrong guess fs bug
1409 for (int i = 0; i < object_ids.Count; i++)
1410 {
1411 UUID uuid = object_ids[i].AsUUID();
1412 float Physc;
1413 float simulc;
1414 float streamc;
1415
1416 SceneObjectGroup grp = m_Scene.GetGroupByPrim(uuid);
1417 if (grp != null)
1418 {
1419 grp.GetSelectedCosts(out Physc, out streamc, out simulc);
1420 phys += Physc;
1421 stream += streamc;
1422 simul += simulc;
1423 }
1424 }
1425 }
1426 else if (req.ContainsKey("selected_prims"))
1427 {
1428 OSDArray object_ids = (OSDArray)req["selected_prims"];
1429
1430 // don't see in use in any of the 2 viewers
1431 // guess it should be for edit linked but... nothing
1432 // should go to SOP per part
1433 for (int i = 0; i < object_ids.Count; i++)
1434 {
1435 UUID uuid = object_ids[i].AsUUID();
1436
1437 SceneObjectPart part = m_Scene.GetSceneObjectPart(uuid);
1438 if (part != null)
1439 {
1440 phys += part.PhysicsCost;
1441 stream += part.StreamingCost;
1442 simul += part.SimulationCost;
1443 }
1444 }
1445 }
1446
1447 if (simul != 0)
1448 {
1449 OSDMap object_data = new OSDMap();
1450
1451 object_data["physics"] = phys;
1452 object_data["streaming"] = stream;
1453 object_data["simulation"] = simul;
1454
1455 resp["selected"] = object_data;
1456 }
1457
1458 string response = OSDParser.SerializeLLSDXmlString(resp);
1459 return response;
1460 }
1461
912 public string UpdateAgentInformation(string request, string path, 1462 public string UpdateAgentInformation(string request, string path,
913 string param, IOSHttpRequest httpRequest, 1463 string param, IOSHttpRequest httpRequest,
914 IOSHttpResponse httpResponse) 1464 IOSHttpResponse httpResponse)
@@ -928,6 +1478,10 @@ namespace OpenSim.Region.ClientStack.Linden
928 1478
929 public class AssetUploader 1479 public class AssetUploader
930 { 1480 {
1481 private static readonly ILog m_log =
1482 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
1483
1484
931 public event UpLoadedAsset OnUpLoad; 1485 public event UpLoadedAsset OnUpLoad;
932 private UpLoadedAsset handlerUpLoad = null; 1486 private UpLoadedAsset handlerUpLoad = null;
933 1487
@@ -942,10 +1496,21 @@ namespace OpenSim.Region.ClientStack.Linden
942 1496
943 private string m_invType = String.Empty; 1497 private string m_invType = String.Empty;
944 private string m_assetType = String.Empty; 1498 private string m_assetType = String.Empty;
1499 private int m_cost;
1500 private string m_error = String.Empty;
1501
1502 private Timer m_timeoutTimer = new Timer();
1503 private UUID m_texturesFolder;
1504 private int m_nreqtextures;
1505 private int m_nreqmeshs;
1506 private int m_nreqinstances;
1507 private bool m_IsAtestUpload;
945 1508
946 public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem, 1509 public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem,
947 UUID parentFolderID, string invType, string assetType, string path, 1510 UUID parentFolderID, string invType, string assetType, string path,
948 IHttpServer httpServer, bool dumpAssetsToFile) 1511 IHttpServer httpServer, bool dumpAssetsToFile,
1512 int totalCost, UUID texturesFolder, int nreqtextures, int nreqmeshs, int nreqinstances,
1513 bool IsAtestUpload)
949 { 1514 {
950 m_assetName = assetName; 1515 m_assetName = assetName;
951 m_assetDes = description; 1516 m_assetDes = description;
@@ -957,6 +1522,18 @@ namespace OpenSim.Region.ClientStack.Linden
957 m_assetType = assetType; 1522 m_assetType = assetType;
958 m_invType = invType; 1523 m_invType = invType;
959 m_dumpAssetsToFile = dumpAssetsToFile; 1524 m_dumpAssetsToFile = dumpAssetsToFile;
1525 m_cost = totalCost;
1526
1527 m_texturesFolder = texturesFolder;
1528 m_nreqtextures = nreqtextures;
1529 m_nreqmeshs = nreqmeshs;
1530 m_nreqinstances = nreqinstances;
1531 m_IsAtestUpload = IsAtestUpload;
1532
1533 m_timeoutTimer.Elapsed += TimedOut;
1534 m_timeoutTimer.Interval = 120000;
1535 m_timeoutTimer.AutoReset = false;
1536 m_timeoutTimer.Start();
960 } 1537 }
961 1538
962 /// <summary> 1539 /// <summary>
@@ -971,12 +1548,14 @@ namespace OpenSim.Region.ClientStack.Linden
971 UUID inv = inventoryItemID; 1548 UUID inv = inventoryItemID;
972 string res = String.Empty; 1549 string res = String.Empty;
973 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); 1550 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
1551/*
974 uploadComplete.new_asset = newAssetID.ToString(); 1552 uploadComplete.new_asset = newAssetID.ToString();
975 uploadComplete.new_inventory_item = inv; 1553 uploadComplete.new_inventory_item = inv;
976 uploadComplete.state = "complete"; 1554 uploadComplete.state = "complete";
977 1555
978 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); 1556 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
979 1557*/
1558 m_timeoutTimer.Stop();
980 httpListener.RemoveStreamHandler("POST", uploaderPath); 1559 httpListener.RemoveStreamHandler("POST", uploaderPath);
981 1560
982 // TODO: probably make this a better set of extensions here 1561 // TODO: probably make this a better set of extensions here
@@ -993,12 +1572,49 @@ namespace OpenSim.Region.ClientStack.Linden
993 handlerUpLoad = OnUpLoad; 1572 handlerUpLoad = OnUpLoad;
994 if (handlerUpLoad != null) 1573 if (handlerUpLoad != null)
995 { 1574 {
996 handlerUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType); 1575 handlerUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType,
1576 m_cost, m_texturesFolder, m_nreqtextures, m_nreqmeshs, m_nreqinstances, m_IsAtestUpload, ref m_error);
997 } 1577 }
1578 if (m_IsAtestUpload)
1579 {
1580 LLSDAssetUploadError resperror = new LLSDAssetUploadError();
1581 resperror.message = "Upload SUCESSEFULL for testing purposes only. Other uses are prohibited. Item will not work after 48 hours or on other regions";
1582 resperror.identifier = inv;
998 1583
1584 uploadComplete.error = resperror;
1585 uploadComplete.state = "Upload4Testing";
1586 }
1587 else
1588 {
1589 if (m_error == String.Empty)
1590 {
1591 uploadComplete.new_asset = newAssetID.ToString();
1592 uploadComplete.new_inventory_item = inv;
1593 // if (m_texturesFolder != UUID.Zero)
1594 // uploadComplete.new_texture_folder_id = m_texturesFolder;
1595 uploadComplete.state = "complete";
1596 }
1597 else
1598 {
1599 LLSDAssetUploadError resperror = new LLSDAssetUploadError();
1600 resperror.message = m_error;
1601 resperror.identifier = inv;
1602
1603 uploadComplete.error = resperror;
1604 uploadComplete.state = "failed";
1605 }
1606 }
1607
1608 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
999 return res; 1609 return res;
1000 } 1610 }
1001 1611
1612 private void TimedOut(object sender, ElapsedEventArgs args)
1613 {
1614 m_log.InfoFormat("[CAPS]: Removing URL and handler for timed out mesh upload");
1615 httpListener.RemoveStreamHandler("POST", uploaderPath);
1616 }
1617
1002 ///Left this in and commented in case there are unforseen issues 1618 ///Left this in and commented in case there are unforseen issues
1003 //private void SaveAssetToFile(string filename, byte[] data) 1619 //private void SaveAssetToFile(string filename, byte[] data)
1004 //{ 1620 //{