aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/Caps
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs978
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs703
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs490
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs22
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs410
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs427
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs18
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs297
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs9
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs20
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs184
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs12
12 files changed, 2765 insertions, 805 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index 774202e..4e6d196 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;
@@ -55,14 +56,16 @@ using PermissionMask = OpenSim.Framework.PermissionMask;
55namespace OpenSim.Region.ClientStack.Linden 56namespace OpenSim.Region.ClientStack.Linden
56{ 57{
57 public delegate void UpLoadedAsset( 58 public delegate void UpLoadedAsset(
58 string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder, 59 string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder,
59 byte[] data, string inventoryType, string assetType); 60 byte[] data, string inventoryType, string assetType,
61 int cost, UUID texturesFolder, int nreqtextures, int nreqmeshs, int nreqinstances,
62 bool IsAtestUpload, ref string error);
60 63
61 public delegate UUID UpdateItem(UUID itemID, byte[] data); 64 public delegate UUID UpdateItem(UUID itemID, byte[] data);
62 65
63 public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors); 66 public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors);
64 67
65 public delegate void NewInventoryItem(UUID userID, InventoryItemBase item); 68 public delegate void NewInventoryItem(UUID userID, InventoryItemBase item, uint cost);
66 69
67 public delegate void NewAsset(AssetBase asset); 70 public delegate void NewAsset(AssetBase asset);
68 71
@@ -88,6 +91,7 @@ namespace OpenSim.Region.ClientStack.Linden
88 91
89 private Scene m_Scene; 92 private Scene m_Scene;
90 private Caps m_HostCapsObj; 93 private Caps m_HostCapsObj;
94 private ModelCost m_ModelCost;
91 95
92 private static readonly string m_requestPath = "0000/"; 96 private static readonly string m_requestPath = "0000/";
93 // private static readonly string m_mapLayerPath = "0001/"; 97 // private static readonly string m_mapLayerPath = "0001/";
@@ -99,8 +103,10 @@ namespace OpenSim.Region.ClientStack.Linden
99 private static readonly string m_copyFromNotecardPath = "0007/"; 103 private static readonly string m_copyFromNotecardPath = "0007/";
100 // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule. 104 // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule.
101 private static readonly string m_getObjectPhysicsDataPath = "0101/"; 105 private static readonly string m_getObjectPhysicsDataPath = "0101/";
102 /* 0102 - 0103 RESERVED */ 106 private static readonly string m_getObjectCostPath = "0102/";
107 private static readonly string m_ResourceCostSelectedPath = "0103/";
103 private static readonly string m_UpdateAgentInformationPath = "0500/"; 108 private static readonly string m_UpdateAgentInformationPath = "0500/";
109 private static readonly string m_animSetTaskUpdatePath = "0260/";
104 110
105 // These are callbacks which will be setup by the scene so that we can update scene data when we 111 // These are callbacks which will be setup by the scene so that we can update scene data when we
106 // receive capability calls 112 // receive capability calls
@@ -115,12 +121,50 @@ namespace OpenSim.Region.ClientStack.Linden
115 private IAssetService m_assetService; 121 private IAssetService m_assetService;
116 private bool m_dumpAssetsToFile = false; 122 private bool m_dumpAssetsToFile = false;
117 private string m_regionName; 123 private string m_regionName;
124
118 private int m_levelUpload = 0; 125 private int m_levelUpload = 0;
119 126
127 private bool m_enableFreeTestUpload = false; // allows "TEST-" prefix hack
128 private bool m_ForceFreeTestUpload = false; // forces all uploads to be test
129
130 private bool m_enableModelUploadTextureToInventory = false; // place uploaded textures also in inventory
131 // may not be visible till relog
132
133 private bool m_RestrictFreeTestUploadPerms = false; // reduces also the permitions. Needs a creator defined!!
134 private UUID m_testAssetsCreatorID = UUID.Zero;
135
136 private float m_PrimScaleMin = 0.001f;
137
138 private enum FileAgentInventoryState : int
139 {
140 idle = 0,
141 processRequest = 1,
142 waitUpload = 2,
143 processUpload = 3
144 }
145 private FileAgentInventoryState m_FileAgentInventoryState = FileAgentInventoryState.idle;
146
120 public BunchOfCaps(Scene scene, Caps caps) 147 public BunchOfCaps(Scene scene, Caps caps)
121 { 148 {
122 m_Scene = scene; 149 m_Scene = scene;
123 m_HostCapsObj = caps; 150 m_HostCapsObj = caps;
151
152 // create a model upload cost provider
153 m_ModelCost = new ModelCost();
154 // tell it about scene object limits
155 m_ModelCost.NonPhysicalPrimScaleMax = m_Scene.m_maxNonphys;
156 m_ModelCost.PhysicalPrimScaleMax = m_Scene.m_maxPhys;
157
158// m_ModelCost.ObjectLinkedPartsMax = ??
159// m_ModelCost.PrimScaleMin = ??
160
161 m_PrimScaleMin = m_ModelCost.PrimScaleMin;
162 float modelTextureUploadFactor = m_ModelCost.ModelTextureCostFactor;
163 float modelUploadFactor = m_ModelCost.ModelMeshCostFactor;
164 float modelMinUploadCostFactor = m_ModelCost.ModelMinCostFactor;
165 float modelPrimCreationCost = m_ModelCost.primCreationCost;
166 float modelMeshByteCost = m_ModelCost.bytecost;
167
124 IConfigSource config = m_Scene.Config; 168 IConfigSource config = m_Scene.Config;
125 if (config != null) 169 if (config != null)
126 { 170 {
@@ -135,6 +179,37 @@ namespace OpenSim.Region.ClientStack.Linden
135 { 179 {
136 m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures); 180 m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
137 } 181 }
182 // economy for model upload
183 IConfig EconomyConfig = config.Configs["Economy"];
184 if (EconomyConfig != null)
185 {
186 modelUploadFactor = EconomyConfig.GetFloat("MeshModelUploadCostFactor", modelUploadFactor);
187 modelTextureUploadFactor = EconomyConfig.GetFloat("MeshModelUploadTextureCostFactor", modelTextureUploadFactor);
188 modelMinUploadCostFactor = EconomyConfig.GetFloat("MeshModelMinCostFactor", modelMinUploadCostFactor);
189 // next 2 are normalized so final cost is afected by modelUploadFactor above and normal cost
190 modelPrimCreationCost = EconomyConfig.GetFloat("ModelPrimCreationCost", modelPrimCreationCost);
191 modelMeshByteCost = EconomyConfig.GetFloat("ModelMeshByteCost", modelMeshByteCost);
192
193 m_enableModelUploadTextureToInventory = EconomyConfig.GetBoolean("MeshModelAllowTextureToInventory", m_enableModelUploadTextureToInventory);
194
195 m_RestrictFreeTestUploadPerms = EconomyConfig.GetBoolean("m_RestrictFreeTestUploadPerms", m_RestrictFreeTestUploadPerms);
196 m_enableFreeTestUpload = EconomyConfig.GetBoolean("AllowFreeTestUpload", m_enableFreeTestUpload);
197 m_ForceFreeTestUpload = EconomyConfig.GetBoolean("ForceFreeTestUpload", m_ForceFreeTestUpload);
198 string testcreator = EconomyConfig.GetString("TestAssetsCreatorID", "");
199 if (testcreator != "")
200 {
201 UUID id;
202 UUID.TryParse(testcreator, out id);
203 if (id != null)
204 m_testAssetsCreatorID = id;
205 }
206
207 m_ModelCost.ModelMeshCostFactor = modelUploadFactor;
208 m_ModelCost.ModelTextureCostFactor = modelTextureUploadFactor;
209 m_ModelCost.ModelMinCostFactor = modelMinUploadCostFactor;
210 m_ModelCost.primCreationCost = modelPrimCreationCost;
211 m_ModelCost.bytecost = modelMeshByteCost;
212 }
138 } 213 }
139 214
140 m_assetService = m_Scene.AssetService; 215 m_assetService = m_Scene.AssetService;
@@ -146,6 +221,8 @@ namespace OpenSim.Region.ClientStack.Linden
146 ItemUpdatedCall = m_Scene.CapsUpdateInventoryItemAsset; 221 ItemUpdatedCall = m_Scene.CapsUpdateInventoryItemAsset;
147 TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset; 222 TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset;
148 GetClient = m_Scene.SceneGraph.GetControllingClient; 223 GetClient = m_Scene.SceneGraph.GetControllingClient;
224
225 m_FileAgentInventoryState = FileAgentInventoryState.idle;
149 } 226 }
150 227
151 /// <summary> 228 /// <summary>
@@ -173,13 +250,31 @@ namespace OpenSim.Region.ClientStack.Linden
173 //m_capsHandlers["MapLayer"] = 250 //m_capsHandlers["MapLayer"] =
174 // new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST", 251 // new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST",
175 // capsBase + m_mapLayerPath, 252 // capsBase + m_mapLayerPath,
176 // GetMapLayer); 253 // GetMapLayer);
254
255 IRequestHandler getObjectPhysicsDataHandler
256 = new RestStreamHandler(
257 "POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData, "GetObjectPhysicsData", null);
258 m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler);
259
260 IRequestHandler getObjectCostHandler = new RestStreamHandler("POST", capsBase + m_getObjectCostPath, GetObjectCost);
261 m_HostCapsObj.RegisterHandler("GetObjectCost", getObjectCostHandler);
262 IRequestHandler ResourceCostSelectedHandler = new RestStreamHandler("POST", capsBase + m_ResourceCostSelectedPath, ResourceCostSelected);
263 m_HostCapsObj.RegisterHandler("ResourceCostSelected", ResourceCostSelectedHandler);
264
265
177 IRequestHandler req 266 IRequestHandler req
178 = new RestStreamHandler( 267 = new RestStreamHandler(
179 "POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory, "UpdateScript", null); 268 "POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory, "UpdateScript", null);
180 269
181 m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req); 270 m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req);
182 m_HostCapsObj.RegisterHandler("UpdateScriptTask", req); 271 m_HostCapsObj.RegisterHandler("UpdateScriptTask", req);
272
273// IRequestHandler animSetRequestHandler
274// = new RestStreamHandler(
275// "POST", capsBase + m_animSetTaskUpdatePath, AnimSetTaskInventory, "UpdateScript", null);
276
277// m_HostCapsObj.RegisterHandler("UpdateAnimSetTaskInventory", animSetRequestHandler);
183 } 278 }
184 catch (Exception e) 279 catch (Exception e)
185 { 280 {
@@ -191,7 +286,6 @@ namespace OpenSim.Region.ClientStack.Linden
191 { 286 {
192 try 287 try
193 { 288 {
194 // I don't think this one works...
195 m_HostCapsObj.RegisterHandler( 289 m_HostCapsObj.RegisterHandler(
196 "NewFileAgentInventory", 290 "NewFileAgentInventory",
197 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>( 291 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>(
@@ -206,13 +300,11 @@ namespace OpenSim.Region.ClientStack.Linden
206 "POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory, "Update*", null); 300 "POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory, "Update*", null);
207 301
208 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req); 302 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req);
303 m_HostCapsObj.RegisterHandler("UpdateAnimSetAgentInventory", req);
209 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req); 304 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req);
210 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req); 305 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
211 306
212 IRequestHandler getObjectPhysicsDataHandler 307
213 = new RestStreamHandler(
214 "POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData, "GetObjectPhysicsData", null);
215 m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler);
216 308
217 IRequestHandler UpdateAgentInformationHandler 309 IRequestHandler UpdateAgentInformationHandler
218 = new RestStreamHandler( 310 = new RestStreamHandler(
@@ -271,6 +363,9 @@ namespace OpenSim.Region.ClientStack.Linden
271// m_log.DebugFormat( 363// m_log.DebugFormat(
272// "[CAPS]: Received SEED caps request in {0} for agent {1}", m_regionName, m_HostCapsObj.AgentID); 364// "[CAPS]: Received SEED caps request in {0} for agent {1}", m_regionName, m_HostCapsObj.AgentID);
273 365
366 if (!m_HostCapsObj.WaitForActivation())
367 return string.Empty;
368
274 if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint)) 369 if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
275 { 370 {
276 m_log.WarnFormat( 371 m_log.WarnFormat(
@@ -400,62 +495,178 @@ namespace OpenSim.Region.ClientStack.Linden
400 //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString()); 495 //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString());
401 //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type); 496 //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type);
402 497
498 // start by getting the client
499 IClientAPI client = null;
500 m_Scene.TryGetClient(m_HostCapsObj.AgentID, out client);
501
502 // check current state so we only have one service at a time
503 lock (m_ModelCost)
504 {
505 switch (m_FileAgentInventoryState)
506 {
507 case FileAgentInventoryState.processRequest:
508 case FileAgentInventoryState.processUpload:
509 LLSDAssetUploadError resperror = new LLSDAssetUploadError();
510 resperror.message = "Uploader busy processing previus request";
511 resperror.identifier = UUID.Zero;
512
513 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
514 errorResponse.uploader = "";
515 errorResponse.state = "error";
516 errorResponse.error = resperror;
517 return errorResponse;
518 break;
519 case FileAgentInventoryState.waitUpload:
520 // todo stop current uploader server
521 break;
522 case FileAgentInventoryState.idle:
523 default:
524 break;
525 }
526
527 m_FileAgentInventoryState = FileAgentInventoryState.processRequest;
528 }
529
530 int cost = 0;
531 int nreqtextures = 0;
532 int nreqmeshs= 0;
533 int nreqinstances = 0;
534 bool IsAtestUpload = false;
535
536 string assetName = llsdRequest.name;
537
538 LLSDAssetUploadResponseData meshcostdata = new LLSDAssetUploadResponseData();
539
403 if (llsdRequest.asset_type == "texture" || 540 if (llsdRequest.asset_type == "texture" ||
404 llsdRequest.asset_type == "animation" || 541 llsdRequest.asset_type == "animation" ||
542 llsdRequest.asset_type == "animatn" || // this is the asset name actually used by viewers
543 llsdRequest.asset_type == "mesh" ||
405 llsdRequest.asset_type == "sound") 544 llsdRequest.asset_type == "sound")
406 { 545 {
407 ScenePresence avatar = null; 546 ScenePresence avatar = null;
408 IClientAPI client = null;
409 m_Scene.TryGetScenePresence(m_HostCapsObj.AgentID, out avatar); 547 m_Scene.TryGetScenePresence(m_HostCapsObj.AgentID, out avatar);
410 548
411 // check user level 549 // check user level
412 if (avatar != null) 550 if (avatar != null)
413 { 551 {
414 client = avatar.ControllingClient;
415
416 if (avatar.UserLevel < m_levelUpload) 552 if (avatar.UserLevel < m_levelUpload)
417 { 553 {
418 if (client != null) 554 LLSDAssetUploadError resperror = new LLSDAssetUploadError();
419 client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false); 555 resperror.message = "Insufficient permissions to upload";
556 resperror.identifier = UUID.Zero;
420 557
421 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse(); 558 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
422 errorResponse.uploader = ""; 559 errorResponse.uploader = "";
423 errorResponse.state = "error"; 560 errorResponse.state = "error";
561 errorResponse.error = resperror;
562 lock (m_ModelCost)
563 m_FileAgentInventoryState = FileAgentInventoryState.idle;
424 return errorResponse; 564 return errorResponse;
425 } 565 }
426 } 566 }
427 567
428 // check funds 568 // check test upload and funds
429 if (client != null) 569 if (client != null)
430 { 570 {
431 IMoneyModule mm = m_Scene.RequestModuleInterface<IMoneyModule>(); 571 IMoneyModule mm = m_Scene.RequestModuleInterface<IMoneyModule>();
432 572
573 int baseCost = 0;
433 if (mm != null) 574 if (mm != null)
575 baseCost = mm.UploadCharge;
576
577 string warning = String.Empty;
578
579 if (llsdRequest.asset_type == "mesh")
434 { 580 {
435 if (!mm.UploadCovered(client.AgentId, mm.UploadCharge)) 581 string error;
582 int modelcost;
583
584
585 if (!m_ModelCost.MeshModelCost(llsdRequest.asset_resources, baseCost, out modelcost,
586 meshcostdata, out error, ref warning))
436 { 587 {
437 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); 588 LLSDAssetUploadError resperror = new LLSDAssetUploadError();
589 resperror.message = error;
590 resperror.identifier = UUID.Zero;
438 591
439 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse(); 592 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
440 errorResponse.uploader = ""; 593 errorResponse.uploader = "";
441 errorResponse.state = "error"; 594 errorResponse.state = "error";
595 errorResponse.error = resperror;
596
597 lock (m_ModelCost)
598 m_FileAgentInventoryState = FileAgentInventoryState.idle;
442 return errorResponse; 599 return errorResponse;
443 } 600 }
601 cost = modelcost;
444 } 602 }
603 else
604 {
605 cost = baseCost;
606 }
607
608 if (cost > 0 && mm != null)
609 {
610 // check for test upload
611
612 if (m_ForceFreeTestUpload) // all are test
613 {
614 if (!(assetName.Length > 5 && assetName.StartsWith("TEST-"))) // has normal name lets change it
615 assetName = "TEST-" + assetName;
616
617 IsAtestUpload = true;
618 }
619
620 else if (m_enableFreeTestUpload) // only if prefixed with "TEST-"
621 {
622
623 IsAtestUpload = (assetName.Length > 5 && assetName.StartsWith("TEST-"));
624 }
625
626
627 if(IsAtestUpload) // let user know, still showing cost estimation
628 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";
629
630 // check funds
631 else
632 {
633 if (!mm.UploadCovered(client.AgentId, (int)cost))
634 {
635 LLSDAssetUploadError resperror = new LLSDAssetUploadError();
636 resperror.message = "Insuficient funds";
637 resperror.identifier = UUID.Zero;
638
639 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
640 errorResponse.uploader = "";
641 errorResponse.state = "error";
642 errorResponse.error = resperror;
643 lock (m_ModelCost)
644 m_FileAgentInventoryState = FileAgentInventoryState.idle;
645 return errorResponse;
646 }
647 }
648 }
649
650 if (client != null && warning != String.Empty)
651 client.SendAgentAlertMessage(warning, true);
445 } 652 }
446 } 653 }
447 654
448 string assetName = llsdRequest.name;
449 string assetDes = llsdRequest.description; 655 string assetDes = llsdRequest.description;
450 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; 656 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
451 UUID newAsset = UUID.Random(); 657 UUID newAsset = UUID.Random();
452 UUID newInvItem = UUID.Random(); 658 UUID newInvItem = UUID.Random();
453 UUID parentFolder = llsdRequest.folder_id; 659 UUID parentFolder = llsdRequest.folder_id;
454 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); 660 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
661 UUID texturesFolder = UUID.Zero;
662
663 if(!IsAtestUpload && m_enableModelUploadTextureToInventory)
664 texturesFolder = llsdRequest.texture_folder_id;
455 665
456 AssetUploader uploader = 666 AssetUploader uploader =
457 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, 667 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
458 llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile); 668 llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile, cost,
669 texturesFolder, nreqtextures, nreqmeshs, nreqinstances, IsAtestUpload);
459 670
460 m_HostCapsObj.HttpListener.AddStreamHandler( 671 m_HostCapsObj.HttpListener.AddStreamHandler(
461 new BinaryStreamHandler( 672 new BinaryStreamHandler(
@@ -473,10 +684,22 @@ namespace OpenSim.Region.ClientStack.Linden
473 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase + 684 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase +
474 uploaderPath; 685 uploaderPath;
475 686
687
476 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); 688 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
477 uploadResponse.uploader = uploaderURL; 689 uploadResponse.uploader = uploaderURL;
478 uploadResponse.state = "upload"; 690 uploadResponse.state = "upload";
691 uploadResponse.upload_price = (int)cost;
692
693 if (llsdRequest.asset_type == "mesh")
694 {
695 uploadResponse.data = meshcostdata;
696 }
697
479 uploader.OnUpLoad += UploadCompleteHandler; 698 uploader.OnUpLoad += UploadCompleteHandler;
699
700 lock (m_ModelCost)
701 m_FileAgentInventoryState = FileAgentInventoryState.waitUpload;
702
480 return uploadResponse; 703 return uploadResponse;
481 } 704 }
482 705
@@ -488,8 +711,14 @@ namespace OpenSim.Region.ClientStack.Linden
488 /// <param name="data"></param> 711 /// <param name="data"></param>
489 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID, 712 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
490 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType, 713 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
491 string assetType) 714 string assetType, int cost,
715 UUID texturesFolder, int nreqtextures, int nreqmeshs, int nreqinstances,
716 bool IsAtestUpload, ref string error)
492 { 717 {
718
719 lock (m_ModelCost)
720 m_FileAgentInventoryState = FileAgentInventoryState.processUpload;
721
493 m_log.DebugFormat( 722 m_log.DebugFormat(
494 "[BUNCH OF CAPS]: Uploaded asset {0} for inventory item {1}, inv type {2}, asset type {3}", 723 "[BUNCH OF CAPS]: Uploaded asset {0} for inventory item {1}, inv type {2}, asset type {3}",
495 assetID, inventoryItem, inventoryType, assetType); 724 assetID, inventoryItem, inventoryType, assetType);
@@ -497,6 +726,34 @@ namespace OpenSim.Region.ClientStack.Linden
497 sbyte assType = 0; 726 sbyte assType = 0;
498 sbyte inType = 0; 727 sbyte inType = 0;
499 728
729 IClientAPI client = null;
730
731 UUID owner_id = m_HostCapsObj.AgentID;
732 UUID creatorID;
733
734 bool istest = IsAtestUpload && m_enableFreeTestUpload && (cost > 0);
735
736 bool restrictPerms = m_RestrictFreeTestUploadPerms && istest;
737
738 if (istest && m_testAssetsCreatorID != UUID.Zero)
739 creatorID = m_testAssetsCreatorID;
740 else
741 creatorID = owner_id;
742
743 string creatorIDstr = creatorID.ToString();
744
745 IMoneyModule mm = m_Scene.RequestModuleInterface<IMoneyModule>();
746 if (mm != null)
747 {
748 // make sure client still has enougth credit
749 if (!mm.UploadCovered(m_HostCapsObj.AgentID, (int)cost))
750 {
751 error = "Insufficient funds.";
752 return;
753 }
754 }
755
756 // strings to types
500 if (inventoryType == "sound") 757 if (inventoryType == "sound")
501 { 758 {
502 inType = (sbyte)InventoryType.Sound; 759 inType = (sbyte)InventoryType.Sound;
@@ -511,6 +768,12 @@ namespace OpenSim.Region.ClientStack.Linden
511 inType = (sbyte)InventoryType.Animation; 768 inType = (sbyte)InventoryType.Animation;
512 assType = (sbyte)AssetType.Animation; 769 assType = (sbyte)AssetType.Animation;
513 } 770 }
771 else if (inventoryType == "animset")
772 {
773 inType = (sbyte)CustomInventoryType.AnimationSet;
774 assType = (sbyte)CustomAssetType.AnimationSet;
775 m_log.Debug("got animset upload request");
776 }
514 else if (inventoryType == "wearable") 777 else if (inventoryType == "wearable")
515 { 778 {
516 inType = (sbyte)InventoryType.Wearable; 779 inType = (sbyte)InventoryType.Wearable;
@@ -526,6 +789,7 @@ namespace OpenSim.Region.ClientStack.Linden
526 } 789 }
527 else if (inventoryType == "object") 790 else if (inventoryType == "object")
528 { 791 {
792<<<<<<< HEAD
529 inType = (sbyte)InventoryType.Object; 793 inType = (sbyte)InventoryType.Object;
530 assType = (sbyte)AssetType.Object; 794 assType = (sbyte)AssetType.Object;
531 795
@@ -612,73 +876,255 @@ namespace OpenSim.Region.ClientStack.Linden
612 { 876 {
613 clientInv.SendBulkUpdateInventory(foldersToUpdate.ToArray(), itemsToUpdate.ToArray()); 877 clientInv.SendBulkUpdateInventory(foldersToUpdate.ToArray(), itemsToUpdate.ToArray());
614 } 878 }
615 879=======
616 for (int i = 0; i < mesh_list.Count; i++) 880 if (assetType == "mesh") // this code for now is for mesh models uploads only
617 { 881 {
618 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox(); 882 inType = (sbyte)InventoryType.Object;
883 assType = (sbyte)AssetType.Object;
884>>>>>>> avn/ubitvar
619 885
620 Primitive.TextureEntry textureEntry 886 List<Vector3> positions = new List<Vector3>();
621 = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE); 887 List<Quaternion> rotations = new List<Quaternion>();
622 OSDMap inner_instance_list = (OSDMap)instance_list[i]; 888 OSDMap request = (OSDMap)OSDParser.DeserializeLLSDXml(data);
889
890 // compare and get updated information
891/* does nothing still we do need something to avoid special viewer to upload something diferent from the cost estimation
892 bool mismatchError = true;
893
894 while (mismatchError)
895 {
896 mismatchError = false;
897 }
623 898
624 OSDArray face_list = (OSDArray)inner_instance_list["face_list"]; 899 if (mismatchError)
625 for (uint face = 0; face < face_list.Count; face++)
626 { 900 {
627 OSDMap faceMap = (OSDMap)face_list[(int)face]; 901 error = "Upload and fee estimation information don't match";
628 Primitive.TextureEntryFace f = pbs.Textures.CreateFace(face); 902 lock (m_ModelCost)
629 if(faceMap.ContainsKey("fullbright")) 903 m_FileAgentInventoryState = FileAgentInventoryState.idle;
630 f.Fullbright = faceMap["fullbright"].AsBoolean();
631 if (faceMap.ContainsKey ("diffuse_color"))
632 f.RGBA = faceMap["diffuse_color"].AsColor4();
633 904
634 int textureNum = faceMap["image"].AsInteger(); 905 return;
635 float imagerot = faceMap["imagerot"].AsInteger(); 906 }
636 float offsets = (float)faceMap["offsets"].AsReal(); 907*/
637 float offsett = (float)faceMap["offsett"].AsReal(); 908 OSDArray instance_list = (OSDArray)request["instance_list"];
638 float scales = (float)faceMap["scales"].AsReal(); 909 OSDArray mesh_list = (OSDArray)request["mesh_list"];
639 float scalet = (float)faceMap["scalet"].AsReal(); 910 OSDArray texture_list = (OSDArray)request["texture_list"];
911 SceneObjectGroup grp = null;
640 912
641 if(imagerot != 0) 913 // create and store texture assets
642 f.Rotation = imagerot; 914 bool doTextInv = (!istest && m_enableModelUploadTextureToInventory &&
915 texturesFolder != UUID.Zero);
643 916
644 if(offsets != 0)
645 f.OffsetU = offsets;
646 917
647 if (offsett != 0) 918 List<UUID> textures = new List<UUID>();
648 f.OffsetV = offsett;
649 919
650 if (scales != 0) 920
651 f.RepeatU = scales; 921// if (doTextInv)
922 m_Scene.TryGetClient(m_HostCapsObj.AgentID, out client);
652 923
653 if (scalet != 0) 924 if(client == null) // don't put textures in inventory if there is no client
654 f.RepeatV = scalet; 925 doTextInv = false;
655 926
656 if (textures.Count > textureNum) 927 for (int i = 0; i < texture_list.Count; i++)
657 f.TextureID = textures[textureNum]; 928 {
658 else 929 AssetBase textureAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Texture, creatorIDstr);
659 f.TextureID = Primitive.TextureEntry.WHITE_TEXTURE; 930 textureAsset.Data = texture_list[i].AsBinary();
931 if (istest)
932 textureAsset.Local = true;
933 m_assetService.Store(textureAsset);
934 textures.Add(textureAsset.FullID);
935
936 if (doTextInv)
937 {
938 string name = assetName;
939 if (name.Length > 25)
940 name = name.Substring(0, 24);
941 name += "_Texture#" + i.ToString();
942 InventoryItemBase texitem = new InventoryItemBase();
943 texitem.Owner = m_HostCapsObj.AgentID;
944 texitem.CreatorId = creatorIDstr;
945 texitem.CreatorData = String.Empty;
946 texitem.ID = UUID.Random();
947 texitem.AssetID = textureAsset.FullID;
948 texitem.Description = "mesh model texture";
949 texitem.Name = name;
950 texitem.AssetType = (int)AssetType.Texture;
951 texitem.InvType = (int)InventoryType.Texture;
952 texitem.Folder = texturesFolder;
953
954 texitem.CurrentPermissions
955 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Export);
956
957 texitem.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
958 texitem.EveryOnePermissions = 0;
959 texitem.NextPermissions = (uint)PermissionMask.All;
960 texitem.CreationDate = Util.UnixTimeSinceEpoch();
961
962 m_Scene.AddInventoryItem(client, texitem);
963 texitem = null;
964 }
965 }
966
967 // create and store meshs assets
968 List<UUID> meshAssets = new List<UUID>();
969 List<bool> meshAvatarSkeletons = new List<bool>();
970 List<bool> meshAvatarColliders = new List<bool>();
971
972 bool curAvSkeleton;
973 bool curAvCollider;
974 for (int i = 0; i < mesh_list.Count; i++)
975 {
976 curAvSkeleton = false;
977 curAvCollider = false;
660 978
661 textureEntry.FaceTextures[face] = f; 979 // we do need to parse the mesh now
980 OSD osd = OSDParser.DeserializeLLSDBinary(mesh_list[i]);
981 if (osd is OSDMap)
982 {
983 OSDMap mosd = (OSDMap)osd;
984 if (mosd.ContainsKey("skeleton"))
985 {
986 OSDMap skeleton = (OSDMap)mosd["skeleton"];
987 int sksize = skeleton["size"].AsInteger();
988 if (sksize > 0)
989 curAvSkeleton = true;
990 }
991 }
992
993 AssetBase meshAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Mesh, creatorIDstr);
994 meshAsset.Data = mesh_list[i].AsBinary();
995 if (istest)
996 meshAsset.Local = true;
997 m_assetService.Store(meshAsset);
998 meshAssets.Add(meshAsset.FullID);
999 meshAvatarSkeletons.Add(curAvSkeleton);
1000 meshAvatarColliders.Add(curAvCollider);
1001
1002 // test code
1003 if (curAvSkeleton && client != null)
1004 {
1005 string name = assetName;
1006 if (name.Length > 25)
1007 name = name.Substring(0, 24);
1008 name += "_Mesh#" + i.ToString();
1009 InventoryItemBase meshitem = new InventoryItemBase();
1010 meshitem.Owner = m_HostCapsObj.AgentID;
1011 meshitem.CreatorId = creatorIDstr;
1012 meshitem.CreatorData = String.Empty;
1013 meshitem.ID = UUID.Random();
1014 meshitem.AssetID = meshAsset.FullID;
1015 meshitem.Description = "mesh ";
1016 meshitem.Name = name;
1017 meshitem.AssetType = (int)AssetType.Mesh;
1018 meshitem.InvType = (int)InventoryType.Mesh;
1019 // meshitem.Folder = UUID.Zero; // send to default
1020
1021 meshitem.Folder = parentFolder; // dont let it go to folder Meshes that viewers dont show
1022
1023 // If we set PermissionMask.All then when we rez the item the next permissions will replace the current
1024 // (owner) permissions. This becomes a problem if next permissions are changed.
1025 meshitem.CurrentPermissions
1026 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
1027
1028 meshitem.BasePermissions = (uint)PermissionMask.All;
1029 meshitem.EveryOnePermissions = 0;
1030 meshitem.NextPermissions = (uint)PermissionMask.All;
1031 meshitem.CreationDate = Util.UnixTimeSinceEpoch();
1032
1033 m_Scene.AddInventoryItem(client, meshitem);
1034 meshitem = null;
1035 }
662 } 1036 }
663 1037
664 pbs.TextureEntry = textureEntry.GetBytes(); 1038 int skipedMeshs = 0;
1039 // build prims from instances
1040 for (int i = 0; i < instance_list.Count; i++)
1041 {
1042 OSDMap inner_instance_list = (OSDMap)instance_list[i];
665 1043
666 AssetBase meshAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Mesh, ""); 1044 // skip prims that are 2 small
667 meshAsset.Data = mesh_list[i].AsBinary(); 1045 Vector3 scale = inner_instance_list["scale"].AsVector3();
668 m_assetService.Store(meshAsset);
669 1046
670 pbs.SculptEntry = true; 1047 if (scale.X < m_PrimScaleMin || scale.Y < m_PrimScaleMin || scale.Z < m_PrimScaleMin)
671 pbs.SculptTexture = meshAsset.FullID; 1048 {
672 pbs.SculptType = (byte)SculptType.Mesh; 1049 skipedMeshs++;
673 pbs.SculptData = meshAsset.Data; 1050 continue;
1051 }
1052
1053 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
1054
1055 Primitive.TextureEntry textureEntry
1056 = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE);
1057
1058
1059 OSDArray face_list = (OSDArray)inner_instance_list["face_list"];
1060 for (uint face = 0; face < face_list.Count; face++)
1061 {
1062 OSDMap faceMap = (OSDMap)face_list[(int)face];
1063 Primitive.TextureEntryFace f = pbs.Textures.CreateFace(face);
1064 if (faceMap.ContainsKey("fullbright"))
1065 f.Fullbright = faceMap["fullbright"].AsBoolean();
1066 if (faceMap.ContainsKey("diffuse_color"))
1067 f.RGBA = faceMap["diffuse_color"].AsColor4();
1068
1069 int textureNum = faceMap["image"].AsInteger();
1070 float imagerot = faceMap["imagerot"].AsInteger();
1071 float offsets = (float)faceMap["offsets"].AsReal();
1072 float offsett = (float)faceMap["offsett"].AsReal();
1073 float scales = (float)faceMap["scales"].AsReal();
1074 float scalet = (float)faceMap["scalet"].AsReal();
1075
1076 if (imagerot != 0)
1077 f.Rotation = imagerot;
1078
1079 if (offsets != 0)
1080 f.OffsetU = offsets;
674 1081
675 Vector3 position = inner_instance_list["position"].AsVector3(); 1082 if (offsett != 0)
676 Vector3 scale = inner_instance_list["scale"].AsVector3(); 1083 f.OffsetV = offsett;
677 Quaternion rotation = inner_instance_list["rotation"].AsQuaternion(); 1084
1085 if (scales != 0)
1086 f.RepeatU = scales;
1087
1088 if (scalet != 0)
1089 f.RepeatV = scalet;
1090
1091 if (textures.Count > textureNum)
1092 f.TextureID = textures[textureNum];
1093 else
1094 f.TextureID = Primitive.TextureEntry.WHITE_TEXTURE;
1095
1096 textureEntry.FaceTextures[face] = f;
1097 }
1098
1099 pbs.TextureEntry = textureEntry.GetBytes();
1100
1101 bool hasmesh = false;
1102 if (inner_instance_list.ContainsKey("mesh")) // seems to happen always but ...
1103 {
1104 int meshindx = inner_instance_list["mesh"].AsInteger();
1105 if (meshAssets.Count > meshindx)
1106 {
1107 pbs.SculptEntry = true;
1108 pbs.SculptType = (byte)SculptType.Mesh;
1109 pbs.SculptTexture = meshAssets[meshindx]; // actual asset UUID after meshs suport introduction
1110 // data will be requested from asset on rez (i hope)
1111 hasmesh = true;
1112 }
1113 }
1114
1115 Vector3 position = inner_instance_list["position"].AsVector3();
1116 Quaternion rotation = inner_instance_list["rotation"].AsQuaternion();
1117
1118 // for now viwers do send fixed defaults
1119 // but this may change
1120// int physicsShapeType = inner_instance_list["physics_shape_type"].AsInteger();
1121 byte physicsShapeType = (byte)PhysShapeType.prim; // default for mesh is simple convex
1122 if(hasmesh)
1123 physicsShapeType = (byte) PhysShapeType.convex; // default for mesh is simple convex
1124// int material = inner_instance_list["material"].AsInteger();
1125 byte material = (byte)Material.Wood;
678 1126
679// no longer used - begin ------------------------ 1127// no longer used - begin ------------------------
680// int physicsShapeType = inner_instance_list["physics_shape_type"].AsInteger();
681// int material = inner_instance_list["material"].AsInteger();
682// int mesh = inner_instance_list["mesh"].AsInteger(); 1128// int mesh = inner_instance_list["mesh"].AsInteger();
683 1129
684// OSDMap permissions = (OSDMap)inner_instance_list["permissions"]; 1130// OSDMap permissions = (OSDMap)inner_instance_list["permissions"];
@@ -693,24 +1139,49 @@ namespace OpenSim.Region.ClientStack.Linden
693// UUID owner_id = permissions["owner_id"].AsUUID(); 1139// UUID owner_id = permissions["owner_id"].AsUUID();
694// int owner_mask = permissions["owner_mask"].AsInteger(); 1140// int owner_mask = permissions["owner_mask"].AsInteger();
695// no longer used - end ------------------------ 1141// no longer used - end ------------------------
1142
1143
1144 SceneObjectPart prim
1145 = new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero);
1146
1147 prim.Scale = scale;
1148 rotations.Add(rotation);
1149 positions.Add(position);
1150 prim.UUID = UUID.Random();
1151 prim.CreatorID = creatorID;
1152 prim.OwnerID = owner_id;
1153 prim.GroupID = UUID.Zero;
1154 prim.LastOwnerID = creatorID;
1155 prim.CreationDate = Util.UnixTimeSinceEpoch();
1156
1157 if (grp == null)
1158 prim.Name = assetName;
1159 else
1160 prim.Name = assetName + "#" + i.ToString();
696 1161
697 UUID owner_id = m_HostCapsObj.AgentID; 1162 prim.EveryoneMask = 0;
1163 prim.GroupMask = 0;
1164
1165 if (restrictPerms)
1166 {
1167 prim.BaseMask = (uint)(PermissionMask.Move | PermissionMask.Modify);
1168 prim.OwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify);
1169 prim.NextOwnerMask = 0;
1170 }
1171 else
1172 {
1173 prim.BaseMask = (uint)PermissionMask.All | (uint)PermissionMask.Export;
1174 prim.OwnerMask = (uint)PermissionMask.All | (uint)PermissionMask.Export;
1175 prim.NextOwnerMask = (uint)PermissionMask.Transfer;
1176 }
698 1177
699 SceneObjectPart prim 1178 if(istest)
700 = new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero); 1179 prim.Description = "For testing only. Other uses are prohibited";
1180 else
1181 prim.Description = "";
701 1182
702 prim.Scale = scale; 1183 prim.Material = material;
703 //prim.OffsetPosition = position; 1184 prim.PhysicsShapeType = physicsShapeType;
704 rotations.Add(rotation);
705 positions.Add(position);
706 prim.UUID = UUID.Random();
707 prim.CreatorID = owner_id;
708 prim.OwnerID = owner_id;
709 prim.GroupID = UUID.Zero;
710 prim.LastOwnerID = prim.OwnerID;
711 prim.CreationDate = Util.UnixTimeSinceEpoch();
712 prim.Name = assetName;
713 prim.Description = "";
714 1185
715// prim.BaseMask = (uint)base_mask; 1186// prim.BaseMask = (uint)base_mask;
716// prim.EveryoneMask = (uint)everyone_mask; 1187// prim.EveryoneMask = (uint)everyone_mask;
@@ -718,52 +1189,64 @@ namespace OpenSim.Region.ClientStack.Linden
718// prim.NextOwnerMask = (uint)next_owner_mask; 1189// prim.NextOwnerMask = (uint)next_owner_mask;
719// prim.OwnerMask = (uint)owner_mask; 1190// prim.OwnerMask = (uint)owner_mask;
720 1191
721 if (grp == null) 1192 if (grp == null)
722 grp = new SceneObjectGroup(prim); 1193 {
723 else 1194 grp = new SceneObjectGroup(prim);
724 grp.AddPart(prim); 1195 grp.LastOwnerID = creatorID;
725 } 1196 }
1197 else
1198 grp.AddPart(prim);
1199 }
726 1200
727 Vector3 rootPos = positions[0]; 1201 Vector3 rootPos = positions[0];
728 1202
729 if (grp.Parts.Length > 1) 1203 if (grp.Parts.Length > 1)
730 { 1204 {
731 // Fix first link number 1205 // Fix first link number
732 grp.RootPart.LinkNum++; 1206 grp.RootPart.LinkNum++;
733 1207
734 Quaternion rootRotConj = Quaternion.Conjugate(rotations[0]); 1208 Quaternion rootRotConj = Quaternion.Conjugate(rotations[0]);
735 Quaternion tmprot; 1209 Quaternion tmprot;
736 Vector3 offset; 1210 Vector3 offset;
737 1211
738 // fix children rotations and positions 1212 // fix children rotations and positions
739 for (int i = 1; i < rotations.Count; i++) 1213 for (int i = 1; i < rotations.Count; i++)
740 { 1214 {
741 tmprot = rotations[i]; 1215 tmprot = rotations[i];
742 tmprot = rootRotConj * tmprot; 1216 tmprot = rootRotConj * tmprot;
1217
1218 grp.Parts[i].RotationOffset = tmprot;
743 1219
744 grp.Parts[i].RotationOffset = tmprot; 1220 offset = positions[i] - rootPos;
745 1221
746 offset = positions[i] - rootPos; 1222 offset *= rootRotConj;
1223 grp.Parts[i].OffsetPosition = offset;
1224 }
747 1225
748 offset *= rootRotConj; 1226 grp.AbsolutePosition = rootPos;
749 grp.Parts[i].OffsetPosition = offset; 1227 grp.UpdateGroupRotationR(rotations[0]);
1228 }
1229 else
1230 {
1231 grp.AbsolutePosition = rootPos;
1232 grp.UpdateGroupRotationR(rotations[0]);
750 } 1233 }
751 1234
752 grp.AbsolutePosition = rootPos; 1235 data = ASCIIEncoding.ASCII.GetBytes(SceneObjectSerializer.ToOriginalXmlFormat(grp));
753 grp.UpdateGroupRotationR(rotations[0]);
754 } 1236 }
755 else 1237
1238 else // not a mesh model
756 { 1239 {
757 grp.AbsolutePosition = rootPos; 1240 m_log.ErrorFormat("[CAPS Asset Upload] got unsuported assetType for object upload");
758 grp.UpdateGroupRotationR(rotations[0]); 1241 return;
759 } 1242 }
760
761 data = ASCIIEncoding.ASCII.GetBytes(SceneObjectSerializer.ToOriginalXmlFormat(grp));
762 } 1243 }
763 1244
764 AssetBase asset; 1245 AssetBase asset;
765 asset = new AssetBase(assetID, assetName, assType, m_HostCapsObj.AgentID.ToString()); 1246 asset = new AssetBase(assetID, assetName, assType, creatorIDstr);
766 asset.Data = data; 1247 asset.Data = data;
1248 if (istest)
1249 asset.Local = true;
767 if (AddNewAsset != null) 1250 if (AddNewAsset != null)
768 AddNewAsset(asset); 1251 AddNewAsset(asset);
769 else if (m_assetService != null) 1252 else if (m_assetService != null)
@@ -771,11 +1254,17 @@ namespace OpenSim.Region.ClientStack.Linden
771 1254
772 InventoryItemBase item = new InventoryItemBase(); 1255 InventoryItemBase item = new InventoryItemBase();
773 item.Owner = m_HostCapsObj.AgentID; 1256 item.Owner = m_HostCapsObj.AgentID;
774 item.CreatorId = m_HostCapsObj.AgentID.ToString(); 1257 item.CreatorId = creatorIDstr;
775 item.CreatorData = String.Empty; 1258 item.CreatorData = String.Empty;
776 item.ID = inventoryItem; 1259 item.ID = inventoryItem;
777 item.AssetID = asset.FullID; 1260 item.AssetID = asset.FullID;
778 item.Description = assetDescription; 1261 if (istest)
1262 {
1263 item.Description = "For testing only. Other uses are prohibited";
1264 item.Flags = (uint) (InventoryItemFlags.SharedSingleReference);
1265 }
1266 else
1267 item.Description = assetDescription;
779 item.Name = assetName; 1268 item.Name = assetName;
780 item.AssetType = assType; 1269 item.AssetType = assType;
781 item.InvType = inType; 1270 item.InvType = inType;
@@ -783,18 +1272,61 @@ namespace OpenSim.Region.ClientStack.Linden
783 1272
784 // If we set PermissionMask.All then when we rez the item the next permissions will replace the current 1273 // If we set PermissionMask.All then when we rez the item the next permissions will replace the current
785 // (owner) permissions. This becomes a problem if next permissions are changed. 1274 // (owner) permissions. This becomes a problem if next permissions are changed.
786 item.CurrentPermissions
787 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Export);
788 1275
789 item.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export; 1276 if (inType == (sbyte)CustomInventoryType.AnimationSet)
790 item.EveryOnePermissions = 0; 1277 {
791 item.NextPermissions = (uint)PermissionMask.All; 1278 AnimationSet.setCreateItemPermitions(item);
1279 }
1280
1281 else if (restrictPerms)
1282 {
1283 item.BasePermissions = (uint)(PermissionMask.Move | PermissionMask.Modify);
1284 item.CurrentPermissions = (uint)(PermissionMask.Move | PermissionMask.Modify);
1285 item.EveryOnePermissions = 0;
1286 item.NextPermissions = 0;
1287 }
1288 else
1289 {
1290 item.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
1291 item.CurrentPermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
1292 item.EveryOnePermissions = 0;
1293 item.NextPermissions = (uint)PermissionMask.Transfer;
1294 }
1295
792 item.CreationDate = Util.UnixTimeSinceEpoch(); 1296 item.CreationDate = Util.UnixTimeSinceEpoch();
793 1297
1298 m_Scene.TryGetClient(m_HostCapsObj.AgentID, out client);
1299
794 if (AddNewInventoryItem != null) 1300 if (AddNewInventoryItem != null)
795 { 1301 {
796 AddNewInventoryItem(m_HostCapsObj.AgentID, item); 1302 if (istest)
1303 {
1304 m_Scene.AddInventoryItem(client, item);
1305/*
1306 AddNewInventoryItem(m_HostCapsObj.AgentID, item, 0);
1307 if (client != null)
1308 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);
1309 */
1310 }
1311 else
1312 {
1313 AddNewInventoryItem(m_HostCapsObj.AgentID, item, (uint)cost);
1314// if (client != null)
1315// {
1316// // let users see anything.. i don't so far
1317// string str;
1318// if (cost > 0)
1319// // dont remember where is money unit name to put here
1320// str = "Upload complete. charged " + cost.ToString() + "$";
1321// else
1322// str = "Upload complete";
1323// client.SendAgentAlertMessage(str, true);
1324// }
1325 }
797 } 1326 }
1327
1328 lock (m_ModelCost)
1329 m_FileAgentInventoryState = FileAgentInventoryState.idle;
798 } 1330 }
799 1331
800 /// <summary> 1332 /// <summary>
@@ -995,6 +1527,131 @@ namespace OpenSim.Region.ClientStack.Linden
995 return response; 1527 return response;
996 } 1528 }
997 1529
1530 public string GetObjectCost(string request, string path,
1531 string param, IOSHttpRequest httpRequest,
1532 IOSHttpResponse httpResponse)
1533 {
1534 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
1535 OSDMap resp = new OSDMap();
1536
1537 OSDArray object_ids = (OSDArray)req["object_ids"];
1538
1539 for (int i = 0; i < object_ids.Count; i++)
1540 {
1541 UUID uuid = object_ids[i].AsUUID();
1542
1543 SceneObjectPart part = m_Scene.GetSceneObjectPart(uuid);
1544
1545 if (part != null)
1546 {
1547 SceneObjectGroup grp = part.ParentGroup;
1548 if (grp != null)
1549 {
1550 float linksetCost;
1551 float linksetPhysCost;
1552 float partCost;
1553 float partPhysCost;
1554
1555 grp.GetResourcesCosts(part, out linksetCost, out linksetPhysCost, out partCost, out partPhysCost);
1556
1557 OSDMap object_data = new OSDMap();
1558 object_data["linked_set_resource_cost"] = linksetCost;
1559 object_data["resource_cost"] = partCost;
1560 object_data["physics_cost"] = partPhysCost;
1561 object_data["linked_set_physics_cost"] = linksetPhysCost;
1562
1563 resp[uuid.ToString()] = object_data;
1564 }
1565 else
1566 {
1567 OSDMap object_data = new OSDMap();
1568 object_data["linked_set_resource_cost"] = 0;
1569 object_data["resource_cost"] = 0;
1570 object_data["physics_cost"] = 0;
1571 object_data["linked_set_physics_cost"] = 0;
1572
1573 resp[uuid.ToString()] = object_data;
1574 }
1575
1576 }
1577 }
1578
1579 string response = OSDParser.SerializeLLSDXmlString(resp);
1580 return response;
1581 }
1582
1583 public string ResourceCostSelected(string request, string path,
1584 string param, IOSHttpRequest httpRequest,
1585 IOSHttpResponse httpResponse)
1586 {
1587 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
1588 OSDMap resp = new OSDMap();
1589
1590
1591 float phys=0;
1592 float stream=0;
1593 float simul=0;
1594
1595 if (req.ContainsKey("selected_roots"))
1596 {
1597 OSDArray object_ids = (OSDArray)req["selected_roots"];
1598
1599 // should go by SOG suming costs for all parts
1600 // ll v3 works ok with several objects select we get the list and adds ok
1601 // FS calls per object so results are wrong guess fs bug
1602 for (int i = 0; i < object_ids.Count; i++)
1603 {
1604 UUID uuid = object_ids[i].AsUUID();
1605 float Physc;
1606 float simulc;
1607 float streamc;
1608
1609 SceneObjectGroup grp = m_Scene.GetGroupByPrim(uuid);
1610 if (grp != null)
1611 {
1612 grp.GetSelectedCosts(out Physc, out streamc, out simulc);
1613 phys += Physc;
1614 stream += streamc;
1615 simul += simulc;
1616 }
1617 }
1618 }
1619 else if (req.ContainsKey("selected_prims"))
1620 {
1621 OSDArray object_ids = (OSDArray)req["selected_prims"];
1622
1623 // don't see in use in any of the 2 viewers
1624 // guess it should be for edit linked but... nothing
1625 // should go to SOP per part
1626 for (int i = 0; i < object_ids.Count; i++)
1627 {
1628 UUID uuid = object_ids[i].AsUUID();
1629
1630 SceneObjectPart part = m_Scene.GetSceneObjectPart(uuid);
1631 if (part != null)
1632 {
1633 phys += part.PhysicsCost;
1634 stream += part.StreamingCost;
1635 simul += part.SimulationCost;
1636 }
1637 }
1638 }
1639
1640 // if (simul != 0)
1641 {
1642 OSDMap object_data = new OSDMap();
1643
1644 object_data["physics"] = phys;
1645 object_data["streaming"] = stream;
1646 object_data["simulation"] = simul;
1647
1648 resp["selected"] = object_data;
1649 }
1650
1651 string response = OSDParser.SerializeLLSDXmlString(resp);
1652 return response;
1653 }
1654
998 public string UpdateAgentInformation(string request, string path, 1655 public string UpdateAgentInformation(string request, string path,
999 string param, IOSHttpRequest httpRequest, 1656 string param, IOSHttpRequest httpRequest,
1000 IOSHttpResponse httpResponse) 1657 IOSHttpResponse httpResponse)
@@ -1015,6 +1672,10 @@ namespace OpenSim.Region.ClientStack.Linden
1015 1672
1016 public class AssetUploader 1673 public class AssetUploader
1017 { 1674 {
1675 private static readonly ILog m_log =
1676 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
1677
1678
1018 public event UpLoadedAsset OnUpLoad; 1679 public event UpLoadedAsset OnUpLoad;
1019 private UpLoadedAsset handlerUpLoad = null; 1680 private UpLoadedAsset handlerUpLoad = null;
1020 1681
@@ -1029,10 +1690,21 @@ namespace OpenSim.Region.ClientStack.Linden
1029 1690
1030 private string m_invType = String.Empty; 1691 private string m_invType = String.Empty;
1031 private string m_assetType = String.Empty; 1692 private string m_assetType = String.Empty;
1032 1693 private int m_cost;
1694 private string m_error = String.Empty;
1695
1696 private Timer m_timeoutTimer = new Timer();
1697 private UUID m_texturesFolder;
1698 private int m_nreqtextures;
1699 private int m_nreqmeshs;
1700 private int m_nreqinstances;
1701 private bool m_IsAtestUpload;
1702
1033 public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem, 1703 public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem,
1034 UUID parentFolderID, string invType, string assetType, string path, 1704 UUID parentFolderID, string invType, string assetType, string path,
1035 IHttpServer httpServer, bool dumpAssetsToFile) 1705 IHttpServer httpServer, bool dumpAssetsToFile,
1706 int totalCost, UUID texturesFolder, int nreqtextures, int nreqmeshs, int nreqinstances,
1707 bool IsAtestUpload)
1036 { 1708 {
1037 m_assetName = assetName; 1709 m_assetName = assetName;
1038 m_assetDes = description; 1710 m_assetDes = description;
@@ -1044,6 +1716,18 @@ namespace OpenSim.Region.ClientStack.Linden
1044 m_assetType = assetType; 1716 m_assetType = assetType;
1045 m_invType = invType; 1717 m_invType = invType;
1046 m_dumpAssetsToFile = dumpAssetsToFile; 1718 m_dumpAssetsToFile = dumpAssetsToFile;
1719 m_cost = totalCost;
1720
1721 m_texturesFolder = texturesFolder;
1722 m_nreqtextures = nreqtextures;
1723 m_nreqmeshs = nreqmeshs;
1724 m_nreqinstances = nreqinstances;
1725 m_IsAtestUpload = IsAtestUpload;
1726
1727 m_timeoutTimer.Elapsed += TimedOut;
1728 m_timeoutTimer.Interval = 120000;
1729 m_timeoutTimer.AutoReset = false;
1730 m_timeoutTimer.Start();
1047 } 1731 }
1048 1732
1049 /// <summary> 1733 /// <summary>
@@ -1058,12 +1742,14 @@ namespace OpenSim.Region.ClientStack.Linden
1058 UUID inv = inventoryItemID; 1742 UUID inv = inventoryItemID;
1059 string res = String.Empty; 1743 string res = String.Empty;
1060 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); 1744 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
1745/*
1061 uploadComplete.new_asset = newAssetID.ToString(); 1746 uploadComplete.new_asset = newAssetID.ToString();
1062 uploadComplete.new_inventory_item = inv; 1747 uploadComplete.new_inventory_item = inv;
1063 uploadComplete.state = "complete"; 1748 uploadComplete.state = "complete";
1064 1749
1065 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); 1750 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
1066 1751*/
1752 m_timeoutTimer.Stop();
1067 httpListener.RemoveStreamHandler("POST", uploaderPath); 1753 httpListener.RemoveStreamHandler("POST", uploaderPath);
1068 1754
1069 // TODO: probably make this a better set of extensions here 1755 // TODO: probably make this a better set of extensions here
@@ -1080,12 +1766,50 @@ namespace OpenSim.Region.ClientStack.Linden
1080 handlerUpLoad = OnUpLoad; 1766 handlerUpLoad = OnUpLoad;
1081 if (handlerUpLoad != null) 1767 if (handlerUpLoad != null)
1082 { 1768 {
1083 handlerUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType); 1769 handlerUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType,
1770 m_cost, m_texturesFolder, m_nreqtextures, m_nreqmeshs, m_nreqinstances, m_IsAtestUpload,
1771 ref m_error);
1084 } 1772 }
1773 if (m_IsAtestUpload)
1774 {
1775 LLSDAssetUploadError resperror = new LLSDAssetUploadError();
1776 resperror.message = "Upload SUCESSEFULL for testing purposes only. Other uses are prohibited. Item will not work after 48 hours or on other regions";
1777 resperror.identifier = inv;
1778
1779 uploadComplete.error = resperror;
1780 uploadComplete.state = "Upload4Testing";
1781 }
1782 else
1783 {
1784 if (m_error == String.Empty)
1785 {
1786 uploadComplete.new_asset = newAssetID.ToString();
1787 uploadComplete.new_inventory_item = inv;
1788 // if (m_texturesFolder != UUID.Zero)
1789 // uploadComplete.new_texture_folder_id = m_texturesFolder;
1790 uploadComplete.state = "complete";
1791 }
1792 else
1793 {
1794 LLSDAssetUploadError resperror = new LLSDAssetUploadError();
1795 resperror.message = m_error;
1796 resperror.identifier = inv;
1085 1797
1798 uploadComplete.error = resperror;
1799 uploadComplete.state = "failed";
1800 }
1801 }
1802
1803 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
1086 return res; 1804 return res;
1087 } 1805 }
1088 1806
1807 private void TimedOut(object sender, ElapsedEventArgs args)
1808 {
1809 m_log.InfoFormat("[CAPS]: Removing URL and handler for timed out mesh upload");
1810 httpListener.RemoveStreamHandler("POST", uploaderPath);
1811 }
1812
1089 ///Left this in and commented in case there are unforseen issues 1813 ///Left this in and commented in case there are unforseen issues
1090 //private void SaveAssetToFile(string filename, byte[] data) 1814 //private void SaveAssetToFile(string filename, byte[] data)
1091 //{ 1815 //{
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs
new file mode 100644
index 0000000..546bcd9
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs
@@ -0,0 +1,703 @@
1// Proprietary code of Avination Virtual Limited
2// (c) 2012 Melanie Thielker, Leal Duarte
3//
4
5using System;
6using System.IO;
7using System.Collections;
8using System.Collections.Generic;
9using System.Text;
10
11using OpenMetaverse;
12using OpenMetaverse.StructuredData;
13
14using OpenSim.Framework;
15using OpenSim.Region.Framework;
16using OpenSim.Region.Framework.Scenes;
17using OpenSim.Framework.Capabilities;
18
19using ComponentAce.Compression.Libs.zlib;
20
21using OSDArray = OpenMetaverse.StructuredData.OSDArray;
22using OSDMap = OpenMetaverse.StructuredData.OSDMap;
23
24namespace OpenSim.Region.ClientStack.Linden
25{
26 public struct ModelPrimLimits
27 {
28
29 }
30
31 public class ModelCost
32 {
33
34 // upload fee defaults
35 // fees are normalized to 1.0
36 // this parameters scale them to basic cost ( so 1.0 translates to 10 )
37
38 public float ModelMeshCostFactor = 0.0f; // scale total cost relative to basic (excluding textures)
39 public float ModelTextureCostFactor = 1.0f; // scale textures fee to basic.
40 public float ModelMinCostFactor = 0.0f; // 0.5f; // minimum total model free excluding textures
41
42 // itens costs in normalized values
43 // ie will be multiplied by basicCost and factors above
44 public float primCreationCost = 0.002f; // extra cost for each prim creation overhead
45 // weigthed size to normalized cost
46 public float bytecost = 1e-5f;
47
48 // mesh upload fees based on compressed data sizes
49 // several data sections are counted more that once
50 // to promote user optimization
51 // following parameters control how many extra times they are added
52 // to global size.
53 // LOD meshs
54 const float medSizeWth = 1f; // 2x
55 const float lowSizeWth = 1.5f; // 2.5x
56 const float lowestSizeWth = 2f; // 3x
57 // favor potencially physical optimized meshs versus automatic decomposition
58 const float physMeshSizeWth = 6f; // counts 7x
59 const float physHullSizeWth = 8f; // counts 9x
60
61 // stream cost area factors
62 // more or less like SL
63 const float highLodFactor = 17.36f;
64 const float midLodFactor = 277.78f;
65 const float lowLodFactor = 1111.11f;
66
67 // physics cost is below, identical to SL, assuming shape type convex
68 // server cost is below identical to SL assuming non scripted non physical object
69
70 // internal
71 const int bytesPerCoord = 6; // 3 coords, 2 bytes per each
72
73 // control prims dimensions
74 public float PrimScaleMin = 0.001f;
75 public float NonPhysicalPrimScaleMax = 256f;
76 public float PhysicalPrimScaleMax = 10f;
77 public int ObjectLinkedPartsMax = 512;
78
79 // storage for a single mesh asset cost parameters
80 private class ameshCostParam
81 {
82 // LOD sizes for size dependent streaming cost
83 public int highLODSize;
84 public int medLODSize;
85 public int lowLODSize;
86 public int lowestLODSize;
87 // normalized fee based on compressed data sizes
88 public float costFee;
89 // physics cost
90 public float physicsCost;
91 }
92
93 // calculates a mesh model costs
94 // returns false on error, with a reason on parameter error
95 // resources input LLSD request
96 // basicCost input region assets upload cost
97 // totalcost returns model total upload fee
98 // meshcostdata returns detailed costs for viewer
99 // avatarSkeleton if mesh includes a avatar skeleton
100 // useAvatarCollider if we should use physics mesh for avatar
101 public bool MeshModelCost(LLSDAssetResource resources, int basicCost, out int totalcost,
102 LLSDAssetUploadResponseData meshcostdata, out string error, ref string warning)
103 {
104 totalcost = 0;
105 error = string.Empty;
106
107 bool avatarSkeleton = false;
108
109 if (resources == null ||
110 resources.instance_list == null ||
111 resources.instance_list.Array.Count == 0)
112 {
113 error = "missing model information.";
114 return false;
115 }
116
117 int numberInstances = resources.instance_list.Array.Count;
118
119 if( numberInstances > ObjectLinkedPartsMax )
120 {
121 error = "Model whould have more than " + ObjectLinkedPartsMax.ToString() + " linked prims";
122 return false;
123 }
124
125 meshcostdata.model_streaming_cost = 0.0;
126 meshcostdata.simulation_cost = 0.0;
127 meshcostdata.physics_cost = 0.0;
128 meshcostdata.resource_cost = 0.0;
129
130 meshcostdata.upload_price_breakdown.mesh_instance = 0;
131 meshcostdata.upload_price_breakdown.mesh_physics = 0;
132 meshcostdata.upload_price_breakdown.mesh_streaming = 0;
133 meshcostdata.upload_price_breakdown.model = 0;
134
135 int itmp;
136
137 // textures cost
138 if (resources.texture_list != null && resources.texture_list.Array.Count > 0)
139 {
140 float textures_cost = (float)(resources.texture_list.Array.Count * basicCost);
141 textures_cost *= ModelTextureCostFactor;
142
143 itmp = (int)(textures_cost + 0.5f); // round
144 meshcostdata.upload_price_breakdown.texture = itmp;
145 totalcost += itmp;
146 }
147
148 // meshs assets cost
149 float meshsfee = 0;
150 int numberMeshs = 0;
151 bool haveMeshs = false;
152
153 bool curskeleton;
154 bool curAvatarPhys;
155
156 List<ameshCostParam> meshsCosts = new List<ameshCostParam>();
157
158 if (resources.mesh_list != null && resources.mesh_list.Array.Count > 0)
159 {
160 numberMeshs = resources.mesh_list.Array.Count;
161
162 for (int i = 0; i < numberMeshs; i++)
163 {
164 ameshCostParam curCost = new ameshCostParam();
165 byte[] data = (byte[])resources.mesh_list.Array[i];
166
167 if (!MeshCost(data, curCost,out curskeleton, out curAvatarPhys, out error))
168 {
169 return false;
170 }
171
172 if (curskeleton)
173 {
174 if (avatarSkeleton)
175 {
176 error = "model can only contain a avatar skeleton";
177 return false;
178 }
179 avatarSkeleton = true;
180 }
181 meshsCosts.Add(curCost);
182 meshsfee += curCost.costFee;
183 }
184 haveMeshs = true;
185 }
186
187 // instances (prims) cost
188
189
190 int mesh;
191 int skipedSmall = 0;
192 for (int i = 0; i < numberInstances; i++)
193 {
194 Hashtable inst = (Hashtable)resources.instance_list.Array[i];
195
196 ArrayList ascale = (ArrayList)inst["scale"];
197 Vector3 scale;
198 double tmp;
199 tmp = (double)ascale[0];
200 scale.X = (float)tmp;
201 tmp = (double)ascale[1];
202 scale.Y = (float)tmp;
203 tmp = (double)ascale[2];
204 scale.Z = (float)tmp;
205
206 if (scale.X < PrimScaleMin || scale.Y < PrimScaleMin || scale.Z < PrimScaleMin)
207 {
208 skipedSmall++;
209 continue;
210 }
211
212 if (scale.X > NonPhysicalPrimScaleMax || scale.Y > NonPhysicalPrimScaleMax || scale.Z > NonPhysicalPrimScaleMax)
213 {
214 error = "Model contains parts with sides larger than " + NonPhysicalPrimScaleMax.ToString() + "m. Please ajust scale";
215 return false;
216 }
217
218 if (haveMeshs && inst.ContainsKey("mesh"))
219 {
220 mesh = (int)inst["mesh"];
221
222 if (mesh >= numberMeshs)
223 {
224 error = "Incoerent model information.";
225 return false;
226 }
227
228 // streamming cost
229
230 float sqdiam = scale.LengthSquared();
231
232 ameshCostParam curCost = meshsCosts[mesh];
233 float mesh_streaming = streamingCost(curCost, sqdiam);
234
235 meshcostdata.model_streaming_cost += mesh_streaming;
236 meshcostdata.physics_cost += curCost.physicsCost;
237 }
238 else // instance as no mesh ??
239 {
240 // to do later if needed
241 meshcostdata.model_streaming_cost += 0.5f;
242 meshcostdata.physics_cost += 1.0f;
243 }
244
245 // assume unscripted and static prim server cost
246 meshcostdata.simulation_cost += 0.5f;
247 // charge for prims creation
248 meshsfee += primCreationCost;
249 }
250
251 if (skipedSmall > 0)
252 {
253 if (skipedSmall > numberInstances / 2)
254 {
255 error = "Model contains too many prims smaller than " + PrimScaleMin.ToString() +
256 "m minimum allowed size. Please check scalling";
257 return false;
258 }
259 else
260 warning += skipedSmall.ToString() + " of the requested " +numberInstances.ToString() +
261 " model prims will not upload because they are smaller than " + PrimScaleMin.ToString() +
262 "m minimum allowed size. Please check scalling ";
263 }
264
265 if (meshcostdata.physics_cost <= meshcostdata.model_streaming_cost)
266 meshcostdata.resource_cost = meshcostdata.model_streaming_cost;
267 else
268 meshcostdata.resource_cost = meshcostdata.physics_cost;
269
270 if (meshcostdata.resource_cost < meshcostdata.simulation_cost)
271 meshcostdata.resource_cost = meshcostdata.simulation_cost;
272
273 // scale cost
274 // at this point a cost of 1.0 whould mean basic cost
275 meshsfee *= ModelMeshCostFactor;
276
277 if (meshsfee < ModelMinCostFactor)
278 meshsfee = ModelMinCostFactor;
279
280 // actually scale it to basic cost
281 meshsfee *= (float)basicCost;
282
283 meshsfee += 0.5f; // rounding
284
285 totalcost += (int)meshsfee;
286
287 // breakdown prices
288 // don't seem to be in use so removed code for now
289
290 return true;
291 }
292
293 // single mesh asset cost
294 private bool MeshCost(byte[] data, ameshCostParam cost,out bool skeleton, out bool avatarPhys, out string error)
295 {
296 cost.highLODSize = 0;
297 cost.medLODSize = 0;
298 cost.lowLODSize = 0;
299 cost.lowestLODSize = 0;
300 cost.physicsCost = 0.0f;
301 cost.costFee = 0.0f;
302
303 error = string.Empty;
304
305 skeleton = false;
306 avatarPhys = false;
307
308 if (data == null || data.Length == 0)
309 {
310 error = "Missing model information.";
311 return false;
312 }
313
314 OSD meshOsd = null;
315 int start = 0;
316
317 error = "Invalid model data";
318
319 using (MemoryStream ms = new MemoryStream(data))
320 {
321 try
322 {
323 OSD osd = OSDParser.DeserializeLLSDBinary(ms);
324 if (osd is OSDMap)
325 meshOsd = (OSDMap)osd;
326 else
327 return false;
328 }
329 catch (Exception e)
330 {
331 return false;
332 }
333 start = (int)ms.Position;
334 }
335
336 OSDMap map = (OSDMap)meshOsd;
337 OSDMap tmpmap;
338
339 int highlod_size = 0;
340 int medlod_size = 0;
341 int lowlod_size = 0;
342 int lowestlod_size = 0;
343 int skin_size = 0;
344
345 int hulls_size = 0;
346 int phys_nhulls;
347 int phys_hullsvertices = 0;
348
349 int physmesh_size = 0;
350 int phys_ntriangles = 0;
351
352 int submesh_offset = -1;
353
354 if (map.ContainsKey("skeleton"))
355 {
356 tmpmap = (OSDMap)map["skeleton"];
357 if (tmpmap.ContainsKey("offset") && tmpmap.ContainsKey("size"))
358 {
359 int sksize = tmpmap["size"].AsInteger();
360 if(sksize > 0)
361 skeleton = true;
362 }
363 }
364
365 if (map.ContainsKey("physics_convex"))
366 {
367 tmpmap = (OSDMap)map["physics_convex"];
368 if (tmpmap.ContainsKey("offset"))
369 submesh_offset = tmpmap["offset"].AsInteger() + start;
370 if (tmpmap.ContainsKey("size"))
371 hulls_size = tmpmap["size"].AsInteger();
372 }
373
374 if (submesh_offset < 0 || hulls_size == 0)
375 {
376 error = "Missing physics_convex block";
377 return false;
378 }
379
380 if (!hulls(data, submesh_offset, hulls_size, out phys_hullsvertices, out phys_nhulls))
381 {
382 error = "Bad physics_convex block";
383 return false;
384 }
385
386 submesh_offset = -1;
387
388 // only look for LOD meshs sizes
389
390 if (map.ContainsKey("high_lod"))
391 {
392 tmpmap = (OSDMap)map["high_lod"];
393 // see at least if there is a offset for this one
394 if (tmpmap.ContainsKey("offset"))
395 submesh_offset = tmpmap["offset"].AsInteger() + start;
396 if (tmpmap.ContainsKey("size"))
397 highlod_size = tmpmap["size"].AsInteger();
398 }
399
400 if (submesh_offset < 0 || highlod_size <= 0)
401 {
402 error = "Missing high_lod block";
403 return false;
404 }
405
406 bool haveprev = true;
407
408 if (map.ContainsKey("medium_lod"))
409 {
410 tmpmap = (OSDMap)map["medium_lod"];
411 if (tmpmap.ContainsKey("size"))
412 medlod_size = tmpmap["size"].AsInteger();
413 else
414 haveprev = false;
415 }
416
417 if (haveprev && map.ContainsKey("low_lod"))
418 {
419 tmpmap = (OSDMap)map["low_lod"];
420 if (tmpmap.ContainsKey("size"))
421 lowlod_size = tmpmap["size"].AsInteger();
422 else
423 haveprev = false;
424 }
425
426 if (haveprev && map.ContainsKey("lowest_lod"))
427 {
428 tmpmap = (OSDMap)map["lowest_lod"];
429 if (tmpmap.ContainsKey("size"))
430 lowestlod_size = tmpmap["size"].AsInteger();
431 }
432
433 if (map.ContainsKey("skin"))
434 {
435 tmpmap = (OSDMap)map["skin"];
436 if (tmpmap.ContainsKey("size"))
437 skin_size = tmpmap["size"].AsInteger();
438 }
439
440 cost.highLODSize = highlod_size;
441 cost.medLODSize = medlod_size;
442 cost.lowLODSize = lowlod_size;
443 cost.lowestLODSize = lowestlod_size;
444
445 submesh_offset = -1;
446
447 tmpmap = null;
448 if(map.ContainsKey("physics_mesh"))
449 tmpmap = (OSDMap)map["physics_mesh"];
450 else if (map.ContainsKey("physics_shape")) // old naming
451 tmpmap = (OSDMap)map["physics_shape"];
452
453 if(tmpmap != null)
454 {
455 if (tmpmap.ContainsKey("offset"))
456 submesh_offset = tmpmap["offset"].AsInteger() + start;
457 if (tmpmap.ContainsKey("size"))
458 physmesh_size = tmpmap["size"].AsInteger();
459
460 if (submesh_offset >= 0 || physmesh_size > 0)
461 {
462
463 if (!submesh(data, submesh_offset, physmesh_size, out phys_ntriangles))
464 {
465 error = "Model data parsing error";
466 return false;
467 }
468 }
469 }
470
471 // upload is done in convex shape type so only one hull
472 phys_hullsvertices++;
473 cost.physicsCost = 0.04f * phys_hullsvertices;
474
475 float sfee;
476
477 sfee = data.Length; // start with total compressed data size
478
479 // penalize lod meshs that should be more builder optimized
480 sfee += medSizeWth * medlod_size;
481 sfee += lowSizeWth * lowlod_size;
482 sfee += lowestSizeWth * lowlod_size;
483
484 // physics
485 // favor potencial optimized meshs versus automatic decomposition
486 if (physmesh_size != 0)
487 sfee += physMeshSizeWth * (physmesh_size + hulls_size / 4); // reduce cost of mandatory convex hull
488 else
489 sfee += physHullSizeWth * hulls_size;
490
491 // bytes to money
492 sfee *= bytecost;
493
494 cost.costFee = sfee;
495 return true;
496 }
497
498 // parses a LOD or physics mesh component
499 private bool submesh(byte[] data, int offset, int size, out int ntriangles)
500 {
501 ntriangles = 0;
502
503 OSD decodedMeshOsd = new OSD();
504 byte[] meshBytes = new byte[size];
505 System.Buffer.BlockCopy(data, offset, meshBytes, 0, size);
506 try
507 {
508 using (MemoryStream inMs = new MemoryStream(meshBytes))
509 {
510 using (MemoryStream outMs = new MemoryStream())
511 {
512 using (ZOutputStream zOut = new ZOutputStream(outMs))
513 {
514 byte[] readBuffer = new byte[4096];
515 int readLen = 0;
516 while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
517 {
518 zOut.Write(readBuffer, 0, readLen);
519 }
520 zOut.Flush();
521 outMs.Seek(0, SeekOrigin.Begin);
522
523 byte[] decompressedBuf = outMs.GetBuffer();
524 decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
525 }
526 }
527 }
528 }
529 catch (Exception e)
530 {
531 return false;
532 }
533
534 OSDArray decodedMeshOsdArray = null;
535 if ((!decodedMeshOsd is OSDArray))
536 return false;
537
538 byte[] dummy;
539
540 decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
541 foreach (OSD subMeshOsd in decodedMeshOsdArray)
542 {
543 if (subMeshOsd is OSDMap)
544 {
545 OSDMap subtmpmap = (OSDMap)subMeshOsd;
546 if (subtmpmap.ContainsKey("NoGeometry") && ((OSDBoolean)subtmpmap["NoGeometry"]))
547 continue;
548
549 if (!subtmpmap.ContainsKey("Position"))
550 return false;
551
552 if (subtmpmap.ContainsKey("TriangleList"))
553 {
554 dummy = subtmpmap["TriangleList"].AsBinary();
555 ntriangles += dummy.Length / bytesPerCoord;
556 }
557 else
558 return false;
559 }
560 }
561
562 return true;
563 }
564
565 // parses convex hulls component
566 private bool hulls(byte[] data, int offset, int size, out int nvertices, out int nhulls)
567 {
568 nvertices = 0;
569 nhulls = 1;
570
571 OSD decodedMeshOsd = new OSD();
572 byte[] meshBytes = new byte[size];
573 System.Buffer.BlockCopy(data, offset, meshBytes, 0, size);
574 try
575 {
576 using (MemoryStream inMs = new MemoryStream(meshBytes))
577 {
578 using (MemoryStream outMs = new MemoryStream())
579 {
580 using (ZOutputStream zOut = new ZOutputStream(outMs))
581 {
582 byte[] readBuffer = new byte[4096];
583 int readLen = 0;
584 while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
585 {
586 zOut.Write(readBuffer, 0, readLen);
587 }
588 zOut.Flush();
589 outMs.Seek(0, SeekOrigin.Begin);
590
591 byte[] decompressedBuf = outMs.GetBuffer();
592 decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
593 }
594 }
595 }
596 }
597 catch (Exception e)
598 {
599 return false;
600 }
601
602 OSDMap cmap = (OSDMap)decodedMeshOsd;
603 if (cmap == null)
604 return false;
605
606 byte[] dummy;
607
608 // must have one of this
609 if (cmap.ContainsKey("BoundingVerts"))
610 {
611 dummy = cmap["BoundingVerts"].AsBinary();
612 nvertices = dummy.Length / bytesPerCoord;
613 }
614 else
615 return false;
616
617/* upload is done with convex shape type
618 if (cmap.ContainsKey("HullList"))
619 {
620 dummy = cmap["HullList"].AsBinary();
621 nhulls += dummy.Length;
622 }
623
624
625 if (cmap.ContainsKey("Positions"))
626 {
627 dummy = cmap["Positions"].AsBinary();
628 nvertices = dummy.Length / bytesPerCoord;
629 }
630 */
631
632 return true;
633 }
634
635 // returns streaming cost from on mesh LODs sizes in curCost and square of prim size length
636 private float streamingCost(ameshCostParam curCost, float sqdiam)
637 {
638 // compute efective areas
639 float ma = 262144f;
640
641 float mh = sqdiam * highLodFactor;
642 if (mh > ma)
643 mh = ma;
644 float mm = sqdiam * midLodFactor;
645 if (mm > ma)
646 mm = ma;
647
648 float ml = sqdiam * lowLodFactor;
649 if (ml > ma)
650 ml = ma;
651
652 float mlst = ma;
653
654 mlst -= ml;
655 ml -= mm;
656 mm -= mh;
657
658 if (mlst < 1.0f)
659 mlst = 1.0f;
660 if (ml < 1.0f)
661 ml = 1.0f;
662 if (mm < 1.0f)
663 mm = 1.0f;
664 if (mh < 1.0f)
665 mh = 1.0f;
666
667 ma = mlst + ml + mm + mh;
668
669 // get LODs compressed sizes
670 // giving 384 bytes bonus
671 int lst = curCost.lowestLODSize - 384;
672 int l = curCost.lowLODSize - 384;
673 int m = curCost.medLODSize - 384;
674 int h = curCost.highLODSize - 384;
675
676 // use previus higher LOD size on missing ones
677 if (m <= 0)
678 m = h;
679 if (l <= 0)
680 l = m;
681 if (lst <= 0)
682 lst = l;
683
684 // force minumum sizes
685 if (lst < 16)
686 lst = 16;
687 if (l < 16)
688 l = 16;
689 if (m < 16)
690 m = 16;
691 if (h < 16)
692 h = 16;
693
694 // compute cost weighted by relative effective areas
695 float cost = (float)lst * mlst + (float)l * ml + (float)m * mm + (float)h * mh;
696 cost /= ma;
697
698 cost *= 0.004f; // overall tunning parameter
699
700 return cost;
701 }
702 }
703}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index 9b9f6a7..5fb028c 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -78,7 +78,6 @@ namespace OpenSim.Region.ClientStack.Linden
78 private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>(); 78 private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
79 79
80 private Dictionary<UUID, Queue<OSD>> queues = new Dictionary<UUID, Queue<OSD>>(); 80 private Dictionary<UUID, Queue<OSD>> queues = new Dictionary<UUID, Queue<OSD>>();
81 private Dictionary<UUID, UUID> m_QueueUUIDAvatarMapping = new Dictionary<UUID, UUID>();
82 private Dictionary<UUID, UUID> m_AvatarQueueUUIDMapping = new Dictionary<UUID, UUID>(); 81 private Dictionary<UUID, UUID> m_AvatarQueueUUIDMapping = new Dictionary<UUID, UUID>();
83 82
84 #region INonSharedRegionModule methods 83 #region INonSharedRegionModule methods
@@ -178,6 +177,7 @@ namespace OpenSim.Region.ClientStack.Linden
178 } 177 }
179 178
180 /// <summary> 179 /// <summary>
180<<<<<<< HEAD
181 /// Always returns a valid queue 181 /// Always returns a valid queue
182 /// </summary> 182 /// </summary>
183 /// <param name="agentId"></param> 183 /// <param name="agentId"></param>
@@ -201,6 +201,8 @@ namespace OpenSim.Region.ClientStack.Linden
201 } 201 }
202 202
203 /// <summary> 203 /// <summary>
204=======
205>>>>>>> avn/ubitvar
204 /// May return a null queue 206 /// May return a null queue
205 /// </summary> 207 /// </summary>
206 /// <param name="agentId"></param> 208 /// <param name="agentId"></param>
@@ -263,28 +265,13 @@ namespace OpenSim.Region.ClientStack.Linden
263 lock (queues) 265 lock (queues)
264 queues.Remove(agentID); 266 queues.Remove(agentID);
265 267
266 List<UUID> removeitems = new List<UUID>();
267 lock (m_AvatarQueueUUIDMapping) 268 lock (m_AvatarQueueUUIDMapping)
268 m_AvatarQueueUUIDMapping.Remove(agentID); 269 m_AvatarQueueUUIDMapping.Remove(agentID);
269 270
270 UUID searchval = UUID.Zero; 271 lock (m_ids)
271
272 removeitems.Clear();
273
274 lock (m_QueueUUIDAvatarMapping)
275 { 272 {
276 foreach (UUID ky in m_QueueUUIDAvatarMapping.Keys) 273 if (!m_ids.ContainsKey(agentID))
277 { 274 m_ids.Remove(agentID);
278 searchval = m_QueueUUIDAvatarMapping[ky];
279
280 if (searchval == agentID)
281 {
282 removeitems.Add(ky);
283 }
284 }
285
286 foreach (UUID ky in removeitems)
287 m_QueueUUIDAvatarMapping.Remove(ky);
288 } 275 }
289 276
290 // m_log.DebugFormat("[EVENTQUEUE]: Deleted queues for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName); 277 // m_log.DebugFormat("[EVENTQUEUE]: Deleted queues for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
@@ -303,61 +290,107 @@ namespace OpenSim.Region.ClientStack.Linden
303 public void OnRegisterCaps(UUID agentID, Caps caps) 290 public void OnRegisterCaps(UUID agentID, Caps caps)
304 { 291 {
305 // Register an event queue for the client 292 // Register an event queue for the client
293<<<<<<< HEAD
306 294
307 if (DebugLevel > 0) 295 if (DebugLevel > 0)
308 m_log.DebugFormat( 296 m_log.DebugFormat(
309 "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}", 297 "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
310 agentID, caps, m_scene.RegionInfo.RegionName); 298 agentID, caps, m_scene.RegionInfo.RegionName);
311 299=======
312 // Let's instantiate a Queue for this agent right now 300 m_log.DebugFormat(
313 TryGetQueue(agentID); 301 "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
302 agentID, caps, m_scene.RegionInfo.RegionName);
303>>>>>>> avn/ubitvar
314 304
315 UUID eventQueueGetUUID; 305 UUID eventQueueGetUUID;
306 Queue<OSD> queue;
307 Random rnd = new Random(Environment.TickCount);
308 int nrnd = rnd.Next(30000000);
309 if (nrnd < 0)
310 nrnd = -nrnd;
316 311
317 lock (m_AvatarQueueUUIDMapping) 312 lock (queues)
318 { 313 {
319 // Reuse open queues. The client does! 314 if (queues.ContainsKey(agentID))
320 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID)) 315 queue = queues[agentID];
316 else
317 queue = null;
318
319 if (queue == null)
321 { 320 {
322 //m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); 321 queue = new Queue<OSD>();
323 eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; 322 queues[agentID] = queue;
323
324 // push markers to handle old responses still waiting
325 // this will cost at most viewer getting two forced noevents
326 // even being a new queue better be safe
327 queue.Enqueue(null);
328 queue.Enqueue(null); // one should be enough
329
330 lock (m_AvatarQueueUUIDMapping)
331 {
332 eventQueueGetUUID = UUID.Random();
333 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
334 {
335 // oops this should not happen ?
336 m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID without a queue");
337 eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
338 }
339 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
340 }
341 lock (m_ids)
342 {
343 if (!m_ids.ContainsKey(agentID))
344 m_ids.Add(agentID, nrnd);
345 else
346 m_ids[agentID] = nrnd;
347 }
324 } 348 }
325 else 349 else
326 { 350 {
327 eventQueueGetUUID = UUID.Random(); 351 // push markers to handle old responses still waiting
328 //m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!"); 352 // this will cost at most viewer getting two forced noevents
353 // even being a new queue better be safe
354 queue.Enqueue(null);
355 queue.Enqueue(null); // one should be enough
356
357 // reuse or not to reuse TODO FIX
358 lock (m_AvatarQueueUUIDMapping)
359 {
360 // Reuse open queues. The client does!
361 // Its reuse caps path not queues those are been reused already
362 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
363 {
364 m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
365 eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
366 }
367 else
368 {
369 eventQueueGetUUID = UUID.Random();
370 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
371 m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
372 }
373 }
374 lock (m_ids)
375 {
376 // change to negative numbers so they are changed at end of sending first marker
377 // old data on a queue may be sent on a response for a new caps
378 // but at least will be sent with coerent IDs
379 if (!m_ids.ContainsKey(agentID))
380 m_ids.Add(agentID, -nrnd); // should not happen
381 else
382 m_ids[agentID] = -m_ids[agentID];
383 }
329 } 384 }
330 } 385 }
331 386
332 lock (m_QueueUUIDAvatarMapping)
333 {
334 if (!m_QueueUUIDAvatarMapping.ContainsKey(eventQueueGetUUID))
335 m_QueueUUIDAvatarMapping.Add(eventQueueGetUUID, agentID);
336 }
337
338 lock (m_AvatarQueueUUIDMapping)
339 {
340 if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID))
341 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
342 }
343
344 caps.RegisterPollHandler( 387 caps.RegisterPollHandler(
345 "EventQueueGet", 388 "EventQueueGet",
346 new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS)); 389 new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS));
347
348 Random rnd = new Random(Environment.TickCount);
349 lock (m_ids)
350 {
351 if (!m_ids.ContainsKey(agentID))
352 m_ids.Add(agentID, rnd.Next(30000000));
353 }
354 } 390 }
355 391
356 public bool HasEvents(UUID requestID, UUID agentID) 392 public bool HasEvents(UUID requestID, UUID agentID)
357 { 393 {
358 // Don't use this, because of race conditions at agent closing time
359 //Queue<OSD> queue = TryGetQueue(agentID);
360
361 Queue<OSD> queue = GetQueue(agentID); 394 Queue<OSD> queue = GetQueue(agentID);
362 if (queue != null) 395 if (queue != null)
363 lock (queue) 396 lock (queue)
@@ -366,7 +399,8 @@ namespace OpenSim.Region.ClientStack.Linden
366 return queue.Count > 0; 399 return queue.Count > 0;
367 } 400 }
368 401
369 return false; 402 //m_log.WarnFormat("POLLED FOR EVENTS BY {0} unknown agent", agentID);
403 return true;
370 } 404 }
371 405
372 /// <summary> 406 /// <summary>
@@ -395,55 +429,65 @@ namespace OpenSim.Region.ClientStack.Linden
395 return NoEvents(requestID, pAgentId); 429 return NoEvents(requestID, pAgentId);
396 } 430 }
397 431
398 OSD element; 432 OSD element = null;;
433 OSDArray array = new OSDArray();
434 int thisID = 0;
435 bool negativeID = false;
436
399 lock (queue) 437 lock (queue)
400 { 438 {
401 if (queue.Count == 0) 439 if (queue.Count == 0)
402 return NoEvents(requestID, pAgentId); 440 return NoEvents(requestID, pAgentId);
403 element = queue.Dequeue(); // 15s timeout
404 }
405
406 int thisID = 0;
407 lock (m_ids)
408 thisID = m_ids[pAgentId];
409
410 OSDArray array = new OSDArray();
411 if (element == null) // didn't have an event in 15s
412 {
413 // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
414 array.Add(EventQueueHelper.KeepAliveEvent());
415 //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", pAgentId, m_scene.RegionInfo.RegionName);
416 }
417 else
418 {
419 if (DebugLevel > 0)
420 LogOutboundDebugMessage(element, pAgentId);
421 441
422 array.Add(element); 442 lock (m_ids)
443 thisID = m_ids[pAgentId];
423 444
424 lock (queue) 445 if (thisID < 0)
425 { 446 {
426 while (queue.Count > 0) 447 negativeID = true;
427 { 448 thisID = -thisID;
428 element = queue.Dequeue(); 449 }
450
451 while (queue.Count > 0)
452 {
453 element = queue.Dequeue();
454 // add elements until a marker is found
455 // so they get into a response
456 if (element == null)
457 break;
458 if (DebugLevel > 0)
459 LogOutboundDebugMessage(element, pAgentId);
460 array.Add(element);
461 thisID++;
462 }
463 }
429 464
430 if (DebugLevel > 0) 465 OSDMap events = null;
431 LogOutboundDebugMessage(element, pAgentId);
432 466
433 array.Add(element); 467 if (array.Count > 0)
434 thisID++; 468 {
435 } 469 events = new OSDMap();
436 } 470 events.Add("events", array);
471 events.Add("id", new OSDInteger(thisID));
437 } 472 }
438 473
439 OSDMap events = new OSDMap(); 474 if (negativeID && element == null)
440 events.Add("events", array); 475 {
476 Random rnd = new Random(Environment.TickCount);
477 thisID = rnd.Next(30000000);
478 if (thisID < 0)
479 thisID = -thisID;
480 }
441 481
442 events.Add("id", new OSDInteger(thisID));
443 lock (m_ids) 482 lock (m_ids)
444 { 483 {
445 m_ids[pAgentId] = thisID + 1; 484 m_ids[pAgentId] = thisID + 1;
446 } 485 }
486
487 // if there where no elements before a marker send a NoEvents
488 if (array.Count == 0)
489 return NoEvents(requestID, pAgentId);
490
447 Hashtable responsedata = new Hashtable(); 491 Hashtable responsedata = new Hashtable();
448 responsedata["int_response_code"] = 200; 492 responsedata["int_response_code"] = 200;
449 responsedata["content_type"] = "application/xml"; 493 responsedata["content_type"] = "application/xml";
@@ -461,260 +505,12 @@ namespace OpenSim.Region.ClientStack.Linden
461 responsedata["content_type"] = "text/plain"; 505 responsedata["content_type"] = "text/plain";
462 responsedata["keepalive"] = false; 506 responsedata["keepalive"] = false;
463 responsedata["reusecontext"] = false; 507 responsedata["reusecontext"] = false;
464 responsedata["str_response_string"] = "Upstream error: "; 508 responsedata["str_response_string"] = "<llsd></llsd>";
465 responsedata["error_status_text"] = "Upstream error:"; 509 responsedata["error_status_text"] = "<llsd></llsd>";
466 responsedata["http_protocol_version"] = "HTTP/1.0"; 510 responsedata["http_protocol_version"] = "HTTP/1.0";
467 return responsedata; 511 return responsedata;
468 } 512 }
469 513
470// public Hashtable ProcessQueue(Hashtable request, UUID agentID, Caps caps)
471// {
472// // TODO: this has to be redone to not busy-wait (and block the thread),
473// // TODO: as soon as we have a non-blocking way to handle HTTP-requests.
474//
475//// if (m_log.IsDebugEnabled)
476//// {
477//// String debug = "[EVENTQUEUE]: Got request for agent {0} in region {1} from thread {2}: [ ";
478//// foreach (object key in request.Keys)
479//// {
480//// debug += key.ToString() + "=" + request[key].ToString() + " ";
481//// }
482//// m_log.DebugFormat(debug + " ]", agentID, m_scene.RegionInfo.RegionName, System.Threading.Thread.CurrentThread.Name);
483//// }
484//
485// Queue<OSD> queue = TryGetQueue(agentID);
486// OSD element;
487//
488// lock (queue)
489// element = queue.Dequeue(); // 15s timeout
490//
491// Hashtable responsedata = new Hashtable();
492//
493// int thisID = 0;
494// lock (m_ids)
495// thisID = m_ids[agentID];
496//
497// if (element == null)
498// {
499// //m_log.ErrorFormat("[EVENTQUEUE]: Nothing to process in " + m_scene.RegionInfo.RegionName);
500// if (thisID == -1) // close-request
501// {
502// m_log.ErrorFormat("[EVENTQUEUE]: 404 in " + m_scene.RegionInfo.RegionName);
503// responsedata["int_response_code"] = 404; //501; //410; //404;
504// responsedata["content_type"] = "text/plain";
505// responsedata["keepalive"] = false;
506// responsedata["str_response_string"] = "Closed EQG";
507// return responsedata;
508// }
509// responsedata["int_response_code"] = 502;
510// responsedata["content_type"] = "text/plain";
511// responsedata["keepalive"] = false;
512// responsedata["str_response_string"] = "Upstream error: ";
513// responsedata["error_status_text"] = "Upstream error:";
514// responsedata["http_protocol_version"] = "HTTP/1.0";
515// return responsedata;
516// }
517//
518// OSDArray array = new OSDArray();
519// if (element == null) // didn't have an event in 15s
520// {
521// // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
522// array.Add(EventQueueHelper.KeepAliveEvent());
523// //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
524// }
525// else
526// {
527// array.Add(element);
528//
529// if (element is OSDMap)
530// {
531// OSDMap ev = (OSDMap)element;
532// m_log.DebugFormat(
533// "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
534// ev["message"], m_scene.GetScenePresence(agentID).Name);
535// }
536//
537// lock (queue)
538// {
539// while (queue.Count > 0)
540// {
541// element = queue.Dequeue();
542//
543// if (element is OSDMap)
544// {
545// OSDMap ev = (OSDMap)element;
546// m_log.DebugFormat(
547// "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
548// ev["message"], m_scene.GetScenePresence(agentID).Name);
549// }
550//
551// array.Add(element);
552// thisID++;
553// }
554// }
555// }
556//
557// OSDMap events = new OSDMap();
558// events.Add("events", array);
559//
560// events.Add("id", new OSDInteger(thisID));
561// lock (m_ids)
562// {
563// m_ids[agentID] = thisID + 1;
564// }
565//
566// responsedata["int_response_code"] = 200;
567// responsedata["content_type"] = "application/xml";
568// responsedata["keepalive"] = false;
569// responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
570//
571// m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
572//
573// return responsedata;
574// }
575
576// public Hashtable EventQueuePath2(Hashtable request)
577// {
578// string capuuid = (string)request["uri"]; //path.Replace("/CAPS/EQG/","");
579// // pull off the last "/" in the path.
580// Hashtable responsedata = new Hashtable();
581// capuuid = capuuid.Substring(0, capuuid.Length - 1);
582// capuuid = capuuid.Replace("/CAPS/EQG/", "");
583// UUID AvatarID = UUID.Zero;
584// UUID capUUID = UUID.Zero;
585//
586// // parse the path and search for the avatar with it registered
587// if (UUID.TryParse(capuuid, out capUUID))
588// {
589// lock (m_QueueUUIDAvatarMapping)
590// {
591// if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
592// {
593// AvatarID = m_QueueUUIDAvatarMapping[capUUID];
594// }
595// }
596//
597// if (AvatarID != UUID.Zero)
598// {
599// return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsForUser(AvatarID));
600// }
601// else
602// {
603// responsedata["int_response_code"] = 404;
604// responsedata["content_type"] = "text/plain";
605// responsedata["keepalive"] = false;
606// responsedata["str_response_string"] = "Not Found";
607// responsedata["error_status_text"] = "Not Found";
608// responsedata["http_protocol_version"] = "HTTP/1.0";
609// return responsedata;
610// // return 404
611// }
612// }
613// else
614// {
615// responsedata["int_response_code"] = 404;
616// responsedata["content_type"] = "text/plain";
617// responsedata["keepalive"] = false;
618// responsedata["str_response_string"] = "Not Found";
619// responsedata["error_status_text"] = "Not Found";
620// responsedata["http_protocol_version"] = "HTTP/1.0";
621// return responsedata;
622// // return 404
623// }
624// }
625
626 public OSD EventQueueFallBack(string path, OSD request, string endpoint)
627 {
628 // This is a fallback element to keep the client from loosing EventQueueGet
629 // Why does CAPS fail sometimes!?
630 m_log.Warn("[EVENTQUEUE]: In the Fallback handler! We lost the Queue in the rest handler!");
631 string capuuid = path.Replace("/CAPS/EQG/","");
632 capuuid = capuuid.Substring(0, capuuid.Length - 1);
633
634// UUID AvatarID = UUID.Zero;
635 UUID capUUID = UUID.Zero;
636 if (UUID.TryParse(capuuid, out capUUID))
637 {
638/* Don't remove this yet code cleaners!
639 * Still testing this!
640 *
641 lock (m_QueueUUIDAvatarMapping)
642 {
643 if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
644 {
645 AvatarID = m_QueueUUIDAvatarMapping[capUUID];
646 }
647 }
648
649
650 if (AvatarID != UUID.Zero)
651 {
652 // Repair the CAP!
653 //OpenSim.Framework.Capabilities.Caps caps = m_scene.GetCapsHandlerForUser(AvatarID);
654 //string capsBase = "/CAPS/EQG/";
655 //caps.RegisterHandler("EventQueueGet",
656 //new RestHTTPHandler("POST", capsBase + capUUID.ToString() + "/",
657 //delegate(Hashtable m_dhttpMethod)
658 //{
659 // return ProcessQueue(m_dhttpMethod, AvatarID, caps);
660 //}));
661 // start new ID sequence.
662 Random rnd = new Random(System.Environment.TickCount);
663 lock (m_ids)
664 {
665 if (!m_ids.ContainsKey(AvatarID))
666 m_ids.Add(AvatarID, rnd.Next(30000000));
667 }
668
669
670 int thisID = 0;
671 lock (m_ids)
672 thisID = m_ids[AvatarID];
673
674 BlockingLLSDQueue queue = GetQueue(AvatarID);
675 OSDArray array = new OSDArray();
676 LLSD element = queue.Dequeue(15000); // 15s timeout
677 if (element == null)
678 {
679
680 array.Add(EventQueueHelper.KeepAliveEvent());
681 }
682 else
683 {
684 array.Add(element);
685 while (queue.Count() > 0)
686 {
687 array.Add(queue.Dequeue(1));
688 thisID++;
689 }
690 }
691 OSDMap events = new OSDMap();
692 events.Add("events", array);
693
694 events.Add("id", new LLSDInteger(thisID));
695
696 lock (m_ids)
697 {
698 m_ids[AvatarID] = thisID + 1;
699 }
700
701 return events;
702 }
703 else
704 {
705 return new LLSD();
706 }
707*
708*/
709 }
710 else
711 {
712 //return new LLSD();
713 }
714
715 return new OSDString("shutdown404!");
716 }
717
718 public void DisableSimulator(ulong handle, UUID avatarID) 514 public void DisableSimulator(ulong handle, UUID avatarID)
719 { 515 {
720 OSD item = EventQueueHelper.DisableSimulator(handle); 516 OSD item = EventQueueHelper.DisableSimulator(handle);
@@ -723,9 +519,14 @@ namespace OpenSim.Region.ClientStack.Linden
723 519
724 public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY) 520 public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY)
725 { 521 {
522<<<<<<< HEAD
726 if (DebugLevel > 0) 523 if (DebugLevel > 0)
727 m_log.DebugFormat("{0} EnableSimulator. handle={1}, endPoint={2}, avatarID={3}", 524 m_log.DebugFormat("{0} EnableSimulator. handle={1}, endPoint={2}, avatarID={3}",
728 LogHeader, handle, endPoint, avatarID, regionSizeX, regionSizeY); 525 LogHeader, handle, endPoint, avatarID, regionSizeX, regionSizeY);
526=======
527 m_log.DebugFormat("{0} EnableSimulator. handle={1}, avatarID={2}, regionSize={3},{4}>",
528 LogHeader, handle, avatarID, regionSizeX, regionSizeY);
529>>>>>>> avn/ubitvar
729 530
730 OSD item = EventQueueHelper.EnableSimulator(handle, endPoint, regionSizeX, regionSizeY); 531 OSD item = EventQueueHelper.EnableSimulator(handle, endPoint, regionSizeX, regionSizeY);
731 Enqueue(item, avatarID); 532 Enqueue(item, avatarID);
@@ -734,10 +535,15 @@ namespace OpenSim.Region.ClientStack.Linden
734 public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath, 535 public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath,
735 ulong regionHandle, int regionSizeX, int regionSizeY) 536 ulong regionHandle, int regionSizeX, int regionSizeY)
736 { 537 {
538<<<<<<< HEAD
737 if (DebugLevel > 0) 539 if (DebugLevel > 0)
738 m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, endPoint={2}, avatarID={3}", 540 m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, endPoint={2}, avatarID={3}",
739 LogHeader, regionHandle, endPoint, avatarID, regionSizeX, regionSizeY); 541 LogHeader, regionHandle, endPoint, avatarID, regionSizeX, regionSizeY);
740 542
543=======
544 m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, avatarID={2}, regionSize={3},{4}>",
545 LogHeader, regionHandle, avatarID, regionSizeX, regionSizeY);
546>>>>>>> avn/ubitvar
741 OSD item = EventQueueHelper.EstablishAgentCommunication(avatarID, endPoint.ToString(), capsPath, regionHandle, regionSizeX, regionSizeY); 547 OSD item = EventQueueHelper.EstablishAgentCommunication(avatarID, endPoint.ToString(), capsPath, regionHandle, regionSizeX, regionSizeY);
742 Enqueue(item, avatarID); 548 Enqueue(item, avatarID);
743 } 549 }
@@ -747,9 +553,14 @@ namespace OpenSim.Region.ClientStack.Linden
747 uint locationID, uint flags, string capsURL, 553 uint locationID, uint flags, string capsURL,
748 UUID avatarID, int regionSizeX, int regionSizeY) 554 UUID avatarID, int regionSizeX, int regionSizeY)
749 { 555 {
556<<<<<<< HEAD
750 if (DebugLevel > 0) 557 if (DebugLevel > 0)
751 m_log.DebugFormat("{0} TeleportFinishEvent. handle={1}, endPoint={2}, avatarID={3}", 558 m_log.DebugFormat("{0} TeleportFinishEvent. handle={1}, endPoint={2}, avatarID={3}",
752 LogHeader, regionHandle, regionExternalEndPoint, avatarID, regionSizeX, regionSizeY); 559 LogHeader, regionHandle, regionExternalEndPoint, avatarID, regionSizeX, regionSizeY);
560=======
561 m_log.DebugFormat("{0} TeleportFinishEvent. handle={1}, avatarID={2}, regionSize={3},{4}>",
562 LogHeader, regionHandle, avatarID, regionSizeX, regionSizeY);
563>>>>>>> avn/ubitvar
753 564
754 OSD item = EventQueueHelper.TeleportFinishEvent(regionHandle, simAccess, regionExternalEndPoint, 565 OSD item = EventQueueHelper.TeleportFinishEvent(regionHandle, simAccess, regionExternalEndPoint,
755 locationID, flags, capsURL, avatarID, regionSizeX, regionSizeY); 566 locationID, flags, capsURL, avatarID, regionSizeX, regionSizeY);
@@ -760,9 +571,14 @@ namespace OpenSim.Region.ClientStack.Linden
760 IPEndPoint newRegionExternalEndPoint, 571 IPEndPoint newRegionExternalEndPoint,
761 string capsURL, UUID avatarID, UUID sessionID, int regionSizeX, int regionSizeY) 572 string capsURL, UUID avatarID, UUID sessionID, int regionSizeX, int regionSizeY)
762 { 573 {
574<<<<<<< HEAD
763 if (DebugLevel > 0) 575 if (DebugLevel > 0)
764 m_log.DebugFormat("{0} CrossRegion. handle={1}, avatarID={2}, regionSize={3},{4}>", 576 m_log.DebugFormat("{0} CrossRegion. handle={1}, avatarID={2}, regionSize={3},{4}>",
765 LogHeader, handle, avatarID, regionSizeX, regionSizeY); 577 LogHeader, handle, avatarID, regionSizeX, regionSizeY);
578=======
579 m_log.DebugFormat("{0} CrossRegion. handle={1}, avatarID={2}, regionSize={3},{4}>",
580 LogHeader, handle, avatarID, regionSizeX, regionSizeY);
581>>>>>>> avn/ubitvar
766 582
767 OSD item = EventQueueHelper.CrossRegion(handle, pos, lookAt, newRegionExternalEndPoint, 583 OSD item = EventQueueHelper.CrossRegion(handle, pos, lookAt, newRegionExternalEndPoint,
768 capsURL, avatarID, sessionID, regionSizeX, regionSizeY); 584 capsURL, avatarID, sessionID, regionSizeX, regionSizeY);
@@ -827,4 +643,4 @@ namespace OpenSim.Region.ClientStack.Linden
827 Enqueue(item, avatarID); 643 Enqueue(item, avatarID);
828 } 644 }
829 } 645 }
830} \ No newline at end of file 646}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
index 384af74..8b7e4c1 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
@@ -77,8 +77,13 @@ namespace OpenSim.Region.ClientStack.Linden
77 llsdSimInfo.Add("Handle", new OSDBinary(ulongToByteArray(handle))); 77 llsdSimInfo.Add("Handle", new OSDBinary(ulongToByteArray(handle)));
78 llsdSimInfo.Add("IP", new OSDBinary(endPoint.Address.GetAddressBytes())); 78 llsdSimInfo.Add("IP", new OSDBinary(endPoint.Address.GetAddressBytes()));
79 llsdSimInfo.Add("Port", new OSDInteger(endPoint.Port)); 79 llsdSimInfo.Add("Port", new OSDInteger(endPoint.Port));
80<<<<<<< HEAD
80 llsdSimInfo.Add("RegionSizeX", OSD.FromUInteger((uint) regionSizeX)); 81 llsdSimInfo.Add("RegionSizeX", OSD.FromUInteger((uint) regionSizeX));
81 llsdSimInfo.Add("RegionSizeY", OSD.FromUInteger((uint) regionSizeY)); 82 llsdSimInfo.Add("RegionSizeY", OSD.FromUInteger((uint) regionSizeY));
83=======
84 llsdSimInfo.Add("RegionSizeX", OSD.FromUInteger((uint)regionSizeX));
85 llsdSimInfo.Add("RegionSizeY", OSD.FromUInteger((uint)regionSizeY));
86>>>>>>> avn/ubitvar
82 87
83 OSDArray arr = new OSDArray(1); 88 OSDArray arr = new OSDArray(1);
84 arr.Add(llsdSimInfo); 89 arr.Add(llsdSimInfo);
@@ -157,6 +162,12 @@ namespace OpenSim.Region.ClientStack.Linden
157 uint locationID, uint flags, string capsURL, UUID agentID, 162 uint locationID, uint flags, string capsURL, UUID agentID,
158 int regionSizeX, int regionSizeY) 163 int regionSizeX, int regionSizeY)
159 { 164 {
165 // not sure why flags get overwritten here
166 if ((flags & (uint)TeleportFlags.IsFlying) != 0)
167 flags = (uint)TeleportFlags.ViaLocation | (uint)TeleportFlags.IsFlying;
168 else
169 flags = (uint)TeleportFlags.ViaLocation;
170
160 OSDMap info = new OSDMap(); 171 OSDMap info = new OSDMap();
161 info.Add("AgentID", OSD.FromUUID(agentID)); 172 info.Add("AgentID", OSD.FromUUID(agentID));
162 info.Add("LocationID", OSD.FromInteger(4)); // TODO what is this? 173 info.Add("LocationID", OSD.FromInteger(4)); // TODO what is this?
@@ -165,7 +176,12 @@ namespace OpenSim.Region.ClientStack.Linden
165 info.Add("SimAccess", OSD.FromInteger(simAccess)); 176 info.Add("SimAccess", OSD.FromInteger(simAccess));
166 info.Add("SimIP", OSD.FromBinary(regionExternalEndPoint.Address.GetAddressBytes())); 177 info.Add("SimIP", OSD.FromBinary(regionExternalEndPoint.Address.GetAddressBytes()));
167 info.Add("SimPort", OSD.FromInteger(regionExternalEndPoint.Port)); 178 info.Add("SimPort", OSD.FromInteger(regionExternalEndPoint.Port));
179<<<<<<< HEAD
168 info.Add("TeleportFlags", OSD.FromULong(1L << 4)); // AgentManager.TeleportFlags.ViaLocation 180 info.Add("TeleportFlags", OSD.FromULong(1L << 4)); // AgentManager.TeleportFlags.ViaLocation
181=======
182// info.Add("TeleportFlags", OSD.FromULong(1L << 4)); // AgentManager.TeleportFlags.ViaLocation
183 info.Add("TeleportFlags", OSD.FromUInteger(flags));
184>>>>>>> avn/ubitvar
169 info.Add("RegionSizeX", OSD.FromUInteger((uint)regionSizeX)); 185 info.Add("RegionSizeX", OSD.FromUInteger((uint)regionSizeX));
170 info.Add("RegionSizeY", OSD.FromUInteger((uint)regionSizeY)); 186 info.Add("RegionSizeY", OSD.FromUInteger((uint)regionSizeY));
171 187
@@ -204,8 +220,8 @@ namespace OpenSim.Region.ClientStack.Linden
204 {"sim-ip-and-port", new OSDString(simIpAndPort)}, 220 {"sim-ip-and-port", new OSDString(simIpAndPort)},
205 {"seed-capability", new OSDString(seedcap)}, 221 {"seed-capability", new OSDString(seedcap)},
206 {"region-handle", OSD.FromULong(regionHandle)}, 222 {"region-handle", OSD.FromULong(regionHandle)},
207 {"region-size-x", OSD.FromInteger(regionSizeX)}, 223 {"region-size-x", OSD.FromUInteger((uint)regionSizeX)},
208 {"region-size-y", OSD.FromInteger(regionSizeY)} 224 {"region-size-y", OSD.FromUInteger((uint)regionSizeY)}
209 }; 225 };
210 226
211 return BuildEvent("EstablishAgentCommunication", body); 227 return BuildEvent("EstablishAgentCommunication", body);
@@ -412,7 +428,7 @@ namespace OpenSim.Region.ClientStack.Linden
412 public static OSD partPhysicsProperties(uint localID, byte physhapetype, 428 public static OSD partPhysicsProperties(uint localID, byte physhapetype,
413 float density, float friction, float bounce, float gravmod) 429 float density, float friction, float bounce, float gravmod)
414 { 430 {
415 431
416 OSDMap physinfo = new OSDMap(6); 432 OSDMap physinfo = new OSDMap(6);
417 physinfo["LocalID"] = localID; 433 physinfo["LocalID"] = localID;
418 physinfo["Density"] = density; 434 physinfo["Density"] = density;
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
index f57d857..91efe8a 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
@@ -27,11 +27,14 @@
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic;
30using System.Collections.Specialized; 31using System.Collections.Specialized;
31using System.Reflection; 32using System.Reflection;
32using System.IO; 33using System.IO;
34using System.Threading;
33using System.Web; 35using System.Web;
34using Mono.Addins; 36using Mono.Addins;
37using OpenSim.Framework.Monitoring;
35using log4net; 38using log4net;
36using Nini.Config; 39using Nini.Config;
37using OpenMetaverse; 40using OpenMetaverse;
@@ -57,12 +60,51 @@ namespace OpenSim.Region.ClientStack.Linden
57 private IAssetService m_AssetService; 60 private IAssetService m_AssetService;
58 private bool m_Enabled = true; 61 private bool m_Enabled = true;
59 private string m_URL; 62 private string m_URL;
63<<<<<<< HEAD
60 private string m_URL2; 64 private string m_URL2;
61 private string m_RedirectURL = null; 65 private string m_RedirectURL = null;
62 private string m_RedirectURL2 = null; 66 private string m_RedirectURL2 = null;
67=======
68
69 struct aPollRequest
70 {
71 public PollServiceMeshEventArgs thepoll;
72 public UUID reqID;
73 public Hashtable request;
74 }
75
76 public class aPollResponse
77 {
78 public Hashtable response;
79 public int bytes;
80 public int lod;
81 }
82
83
84 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
85
86 private static GetMeshHandler m_getMeshHandler;
87
88 private IAssetService m_assetService = null;
89
90 private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
91 private static Thread[] m_workerThreads = null;
92
93 private static OpenMetaverse.BlockingQueue<aPollRequest> m_queue =
94 new OpenMetaverse.BlockingQueue<aPollRequest>();
95
96 private Dictionary<UUID, PollServiceMeshEventArgs> m_pollservices = new Dictionary<UUID, PollServiceMeshEventArgs>();
97>>>>>>> avn/ubitvar
63 98
64 #region Region Module interfaceBase Members 99 #region Region Module interfaceBase Members
65 100
101 ~GetMeshModule()
102 {
103 foreach (Thread t in m_workerThreads)
104 Watchdog.AbortThread(t.ManagedThreadId);
105
106 }
107
66 public Type ReplaceableInterface 108 public Type ReplaceableInterface
67 { 109 {
68 get { return null; } 110 get { return null; }
@@ -87,8 +129,12 @@ namespace OpenSim.Region.ClientStack.Linden
87 if (m_URL2 != string.Empty) 129 if (m_URL2 != string.Empty)
88 { 130 {
89 m_Enabled = true; 131 m_Enabled = true;
132<<<<<<< HEAD
90 m_RedirectURL2 = config.GetString("GetMesh2RedirectURL"); 133 m_RedirectURL2 = config.GetString("GetMesh2RedirectURL");
91 } 134 }
135=======
136
137>>>>>>> avn/ubitvar
92 } 138 }
93 139
94 public void AddRegion(Scene pScene) 140 public void AddRegion(Scene pScene)
@@ -97,6 +143,8 @@ namespace OpenSim.Region.ClientStack.Linden
97 return; 143 return;
98 144
99 m_scene = pScene; 145 m_scene = pScene;
146
147 m_assetService = pScene.AssetService;
100 } 148 }
101 149
102 public void RemoveRegion(Scene scene) 150 public void RemoveRegion(Scene scene)
@@ -105,6 +153,9 @@ namespace OpenSim.Region.ClientStack.Linden
105 return; 153 return;
106 154
107 m_scene.EventManager.OnRegisterCaps -= RegisterCaps; 155 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
156 m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
157 m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate;
158
108 m_scene = null; 159 m_scene = null;
109 } 160 }
110 161
@@ -115,6 +166,27 @@ namespace OpenSim.Region.ClientStack.Linden
115 166
116 m_AssetService = m_scene.RequestModuleInterface<IAssetService>(); 167 m_AssetService = m_scene.RequestModuleInterface<IAssetService>();
117 m_scene.EventManager.OnRegisterCaps += RegisterCaps; 168 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
169 // We'll reuse the same handler for all requests.
170 m_getMeshHandler = new GetMeshHandler(m_assetService);
171 m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
172 m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate;
173
174 if (m_workerThreads == null)
175 {
176 m_workerThreads = new Thread[2];
177
178 for (uint i = 0; i < 2; i++)
179 {
180 m_workerThreads[i] = Watchdog.StartThread(DoMeshRequests,
181 String.Format("MeshWorkerThread{0}", i),
182 ThreadPriority.Normal,
183 false,
184 false,
185 null,
186 int.MaxValue);
187 }
188 }
189
118 } 190 }
119 191
120 192
@@ -124,9 +196,147 @@ namespace OpenSim.Region.ClientStack.Linden
124 196
125 #endregion 197 #endregion
126 198
199 private void DoMeshRequests()
200 {
201 while (true)
202 {
203 aPollRequest poolreq = m_queue.Dequeue();
204
205 poolreq.thepoll.Process(poolreq);
206 }
207 }
208
209 // Now we know when the throttle is changed by the client in the case of a root agent or by a neighbor region in the case of a child agent.
210 public void ThrottleUpdate(ScenePresence p)
211 {
212 UUID user = p.UUID;
213 int imagethrottle = p.ControllingClient.GetAgentThrottleSilent((int)ThrottleOutPacketType.Asset);
214 PollServiceMeshEventArgs args;
215 if (m_pollservices.TryGetValue(user, out args))
216 {
217 args.UpdateThrottle(imagethrottle, p);
218 }
219 }
220
221 private class PollServiceMeshEventArgs : PollServiceEventArgs
222 {
223 private List<Hashtable> requests =
224 new List<Hashtable>();
225 private Dictionary<UUID, aPollResponse> responses =
226 new Dictionary<UUID, aPollResponse>();
227
228 private Scene m_scene;
229 private MeshCapsDataThrottler m_throttler;
230 public PollServiceMeshEventArgs(string uri, UUID pId, Scene scene) :
231 base(null, uri, null, null, null, pId, int.MaxValue)
232 {
233 m_scene = scene;
234 m_throttler = new MeshCapsDataThrottler(100000, 1400000, 10000, scene, pId);
235 // x is request id, y is userid
236 HasEvents = (x, y) =>
237 {
238 lock (responses)
239 {
240 bool ret = m_throttler.hasEvents(x, responses);
241 m_throttler.ProcessTime();
242 return ret;
243
244 }
245 };
246 GetEvents = (x, y) =>
247 {
248 lock (responses)
249 {
250 try
251 {
252 return responses[x].response;
253 }
254 finally
255 {
256 m_throttler.ProcessTime();
257 responses.Remove(x);
258 }
259 }
260 };
261 // x is request id, y is request data hashtable
262 Request = (x, y) =>
263 {
264 aPollRequest reqinfo = new aPollRequest();
265 reqinfo.thepoll = this;
266 reqinfo.reqID = x;
267 reqinfo.request = y;
268
269 m_queue.Enqueue(reqinfo);
270 };
271
272 // this should never happen except possible on shutdown
273 NoEvents = (x, y) =>
274 {
275 /*
276 lock (requests)
277 {
278 Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString());
279 requests.Remove(request);
280 }
281 */
282 Hashtable response = new Hashtable();
283
284 response["int_response_code"] = 500;
285 response["str_response_string"] = "Script timeout";
286 response["content_type"] = "text/plain";
287 response["keepalive"] = false;
288 response["reusecontext"] = false;
289
290 return response;
291 };
292 }
293
294 public void Process(aPollRequest requestinfo)
295 {
296 Hashtable response;
297
298 UUID requestID = requestinfo.reqID;
299
300 // If the avatar is gone, don't bother to get the texture
301 if (m_scene.GetScenePresence(Id) == null)
302 {
303 response = new Hashtable();
304
305 response["int_response_code"] = 500;
306 response["str_response_string"] = "Script timeout";
307 response["content_type"] = "text/plain";
308 response["keepalive"] = false;
309 response["reusecontext"] = false;
310
311 lock (responses)
312 responses[requestID] = new aPollResponse() { bytes = 0, response = response, lod = 0 };
313
314 return;
315 }
316
317 response = m_getMeshHandler.Handle(requestinfo.request);
318 lock (responses)
319 {
320 responses[requestID] = new aPollResponse()
321 {
322 bytes = (int)response["int_bytes"],
323 lod = (int)response["int_lod"],
324 response = response
325 };
326
327 }
328 m_throttler.ProcessTime();
329 }
330
331 internal void UpdateThrottle(int pimagethrottle, ScenePresence p)
332 {
333 m_throttler.UpdateThrottle(pimagethrottle, p);
334 }
335 }
127 336
128 public void RegisterCaps(UUID agentID, Caps caps) 337 public void RegisterCaps(UUID agentID, Caps caps)
129 { 338 {
339<<<<<<< HEAD
130 UUID capID = UUID.Random(); 340 UUID capID = UUID.Random();
131 bool getMeshRegistered = false; 341 bool getMeshRegistered = false;
132 342
@@ -140,6 +350,35 @@ namespace OpenSim.Region.ClientStack.Linden
140 caps.RegisterHandler( 350 caps.RegisterHandler(
141 "GetMesh", 351 "GetMesh",
142 new GetMeshHandler("/CAPS/" + capID + "/", m_AssetService, "GetMesh", agentID.ToString(), m_RedirectURL)); 352 new GetMeshHandler("/CAPS/" + capID + "/", m_AssetService, "GetMesh", agentID.ToString(), m_RedirectURL));
353=======
354// UUID capID = UUID.Random();
355 if (m_URL == "localhost")
356 {
357 string capUrl = "/CAPS/" + UUID.Random() + "/";
358
359 // Register this as a poll service
360 PollServiceMeshEventArgs args = new PollServiceMeshEventArgs(capUrl, agentID, m_scene);
361
362 args.Type = PollServiceEventArgs.EventType.Mesh;
363 MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
364
365 string hostName = m_scene.RegionInfo.ExternalHostName;
366 uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
367 string protocol = "http";
368
369 if (MainServer.Instance.UseSSL)
370 {
371 hostName = MainServer.Instance.SSLCommonName;
372 port = MainServer.Instance.SSLPort;
373 protocol = "https";
374 }
375 caps.RegisterHandler("GetMesh", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
376 m_pollservices[agentID] = args;
377 m_capsDict[agentID] = capUrl;
378
379
380
381>>>>>>> avn/ubitvar
143 } 382 }
144 else 383 else
145 { 384 {
@@ -164,6 +403,177 @@ namespace OpenSim.Region.ClientStack.Linden
164 caps.RegisterHandler("GetMesh2", m_URL2); 403 caps.RegisterHandler("GetMesh2", m_URL2);
165 } 404 }
166 } 405 }
406 private void DeregisterCaps(UUID agentID, Caps caps)
407 {
408 string capUrl;
409 PollServiceMeshEventArgs args;
410 if (m_capsDict.TryGetValue(agentID, out capUrl))
411 {
412 MainServer.Instance.RemoveHTTPHandler("", capUrl);
413 m_capsDict.Remove(agentID);
414 }
415 if (m_pollservices.TryGetValue(agentID, out args))
416 {
417 m_pollservices.Remove(agentID);
418 }
419 }
420
421 internal sealed class MeshCapsDataThrottler
422 {
423
424 private volatile int currenttime = 0;
425 private volatile int lastTimeElapsed = 0;
426 private volatile int BytesSent = 0;
427 private int Lod3 = 0;
428 private int Lod2 = 0;
429 private int Lod1 = 0;
430 private int UserSetThrottle = 0;
431 private int UDPSetThrottle = 0;
432 private int CapSetThrottle = 0;
433 private float CapThrottleDistributon = 0.30f;
434 private readonly Scene m_scene;
435 private ThrottleOutPacketType Throttle;
436 private readonly UUID User;
437
438 public MeshCapsDataThrottler(int pBytes, int max, int min, Scene pScene, UUID puser)
439 {
440 ThrottleBytes = pBytes;
441 lastTimeElapsed = Util.EnvironmentTickCount();
442 Throttle = ThrottleOutPacketType.Asset;
443 m_scene = pScene;
444 User = puser;
445 }
446
447
448 public bool hasEvents(UUID key, Dictionary<UUID, aPollResponse> responses)
449 {
450 const float ThirtyPercent = 0.30f;
451 const float FivePercent = 0.05f;
452 PassTime();
453 // Note, this is called IN LOCK
454 bool haskey = responses.ContainsKey(key);
455
456 if (responses.Count > 2)
457 {
458 SplitThrottle(ThirtyPercent);
459 }
460 else
461 {
462 SplitThrottle(FivePercent);
463 }
464
465 if (!haskey)
466 {
467 return false;
468 }
469 aPollResponse response;
470 if (responses.TryGetValue(key, out response))
471 {
472 float LOD3Over = (((ThrottleBytes*CapThrottleDistributon)%50000) + 1);
473 float LOD2Over = (((ThrottleBytes*CapThrottleDistributon)%10000) + 1);
474 // Normal
475 if (BytesSent + response.bytes <= ThrottleBytes)
476 {
477 BytesSent += response.bytes;
478
479 return true;
480 }
481 // Lod3 Over Throttle protection to keep things processing even when the throttle bandwidth is set too little.
482 else if (response.bytes > ThrottleBytes && Lod3 <= ((LOD3Over < 1)? 1: LOD3Over) )
483 {
484 Interlocked.Increment(ref Lod3);
485 BytesSent += response.bytes;
486
487 return true;
488 }
489 // Lod2 Over Throttle protection to keep things processing even when the throttle bandwidth is set too little.
490 else if (response.bytes > ThrottleBytes && Lod2 <= ((LOD2Over < 1) ? 1 : LOD2Over))
491 {
492 Interlocked.Increment(ref Lod2);
493 BytesSent += response.bytes;
494
495 return true;
496 }
497 else
498 {
499 return false;
500 }
501 }
502
503 return haskey;
504 }
505 public void SubtractBytes(int bytes,int lod)
506 {
507 BytesSent -= bytes;
508 }
509 private void SplitThrottle(float percentMultiplier)
510 {
511
512 if (CapThrottleDistributon != percentMultiplier) // don't switch it if it's already set at the % multipler
513 {
514 CapThrottleDistributon = percentMultiplier;
515 ScenePresence p;
516 if (m_scene.TryGetScenePresence(User, out p)) // If we don't get a user they're not here anymore.
517 {
518// AlterThrottle(UserSetThrottle, p);
519 UpdateThrottle(UserSetThrottle, p);
520 }
521 }
522 }
523
524 public void ProcessTime()
525 {
526 PassTime();
527 }
528
529
530 private void PassTime()
531 {
532 currenttime = Util.EnvironmentTickCount();
533 int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed);
534 //processTimeBasedActions(responses);
535 if (currenttime - timeElapsed >= 1000)
536 {
537 lastTimeElapsed = Util.EnvironmentTickCount();
538 BytesSent -= ThrottleBytes;
539 if (BytesSent < 0) BytesSent = 0;
540 if (BytesSent < ThrottleBytes)
541 {
542 Lod3 = 0;
543 Lod2 = 0;
544 Lod1 = 0;
545 }
546 }
547 }
548 private void AlterThrottle(int setting, ScenePresence p)
549 {
550 p.ControllingClient.SetAgentThrottleSilent((int)Throttle,setting);
551 }
552
553 public int ThrottleBytes
554 {
555 get { return CapSetThrottle; }
556 set { CapSetThrottle = value; }
557 }
558
559 internal void UpdateThrottle(int pimagethrottle, ScenePresence p)
560 {
561 // Client set throttle !
562 UserSetThrottle = pimagethrottle;
563 CapSetThrottle = (int)(pimagethrottle*CapThrottleDistributon);
564// UDPSetThrottle = (int) (pimagethrottle*(100 - CapThrottleDistributon));
565
566 float udp = 1.0f - CapThrottleDistributon;
567 if(udp < 0.7f)
568 udp = 0.7f;
569 UDPSetThrottle = (int) ((float)pimagethrottle * udp);
570 if (CapSetThrottle < 4068)
571 CapSetThrottle = 4068; // at least two discovery mesh
572 p.ControllingClient.SetAgentThrottleSilent((int) Throttle, UDPSetThrottle);
573 ProcessTime();
574
575 }
576 }
167 577
168 } 578 }
169} 579}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
index bb932f2..b9396b7 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
@@ -27,18 +27,13 @@
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Specialized; 30using System.Collections.Generic;
31using System.Drawing;
32using System.Drawing.Imaging;
33using System.Reflection; 31using System.Reflection;
34using System.IO; 32using System.Threading;
35using System.Web;
36using log4net; 33using log4net;
37using Nini.Config; 34using Nini.Config;
38using Mono.Addins; 35using Mono.Addins;
39using OpenMetaverse; 36using OpenMetaverse;
40using OpenMetaverse.StructuredData;
41using OpenMetaverse.Imaging;
42using OpenSim.Framework; 37using OpenSim.Framework;
43using OpenSim.Framework.Servers; 38using OpenSim.Framework.Servers;
44using OpenSim.Framework.Servers.HttpServer; 39using OpenSim.Framework.Servers.HttpServer;
@@ -47,6 +42,7 @@ using OpenSim.Region.Framework.Scenes;
47using OpenSim.Services.Interfaces; 42using OpenSim.Services.Interfaces;
48using Caps = OpenSim.Framework.Capabilities.Caps; 43using Caps = OpenSim.Framework.Capabilities.Caps;
49using OpenSim.Capabilities.Handlers; 44using OpenSim.Capabilities.Handlers;
45using OpenSim.Framework.Monitoring;
50 46
51namespace OpenSim.Region.ClientStack.Linden 47namespace OpenSim.Region.ClientStack.Linden
52{ 48{
@@ -54,16 +50,44 @@ namespace OpenSim.Region.ClientStack.Linden
54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GetTextureModule")] 50 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GetTextureModule")]
55 public class GetTextureModule : INonSharedRegionModule 51 public class GetTextureModule : INonSharedRegionModule
56 { 52 {
57// private static readonly ILog m_log = 53
58// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 struct aPollRequest
59 55 {
56 public PollServiceTextureEventArgs thepoll;
57 public UUID reqID;
58 public Hashtable request;
59 public bool send503;
60 }
61
62 public class aPollResponse
63 {
64 public Hashtable response;
65 public int bytes;
66 }
67
68
69 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
70
60 private Scene m_scene; 71 private Scene m_scene;
61 private IAssetService m_assetService;
62 72
63 private bool m_Enabled = false; 73 private static GetTextureHandler m_getTextureHandler;
74
75 private IAssetService m_assetService = null;
76
77 private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
78 private static Thread[] m_workerThreads = null;
79
80 private string m_Url = "localhost";
81
82 private static OpenMetaverse.BlockingQueue<aPollRequest> m_queue =
83 new OpenMetaverse.BlockingQueue<aPollRequest>();
64 84
85<<<<<<< HEAD
65 // TODO: Change this to a config option 86 // TODO: Change this to a config option
66 private string m_RedirectURL = null; 87 private string m_RedirectURL = null;
88=======
89 private Dictionary<UUID,PollServiceTextureEventArgs> m_pollservices = new Dictionary<UUID,PollServiceTextureEventArgs>();
90>>>>>>> avn/ubitvar
67 91
68 private string m_URL; 92 private string m_URL;
69 93
@@ -72,6 +96,7 @@ namespace OpenSim.Region.ClientStack.Linden
72 public void Initialise(IConfigSource source) 96 public void Initialise(IConfigSource source)
73 { 97 {
74 IConfig config = source.Configs["ClientStack.LindenCaps"]; 98 IConfig config = source.Configs["ClientStack.LindenCaps"];
99<<<<<<< HEAD
75 if (config == null) 100 if (config == null)
76 return; 101 return;
77 102
@@ -82,32 +107,100 @@ namespace OpenSim.Region.ClientStack.Linden
82 m_Enabled = true; 107 m_Enabled = true;
83 m_RedirectURL = config.GetString("GetTextureRedirectURL"); 108 m_RedirectURL = config.GetString("GetTextureRedirectURL");
84 } 109 }
110=======
111 if (config != null)
112 m_Url = config.GetString("Cap_GetTexture", "localhost");
113>>>>>>> avn/ubitvar
85 } 114 }
86 115
87 public void AddRegion(Scene s) 116 public void AddRegion(Scene s)
88 { 117 {
89 if (!m_Enabled)
90 return;
91
92 m_scene = s; 118 m_scene = s;
119 m_assetService = s.AssetService;
93 } 120 }
94 121
95 public void RemoveRegion(Scene s) 122 public void RemoveRegion(Scene s)
96 { 123 {
97 if (!m_Enabled)
98 return;
99
100 m_scene.EventManager.OnRegisterCaps -= RegisterCaps; 124 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
125 m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
126 m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate;
101 m_scene = null; 127 m_scene = null;
102 } 128 }
103 129
104 public void RegionLoaded(Scene s) 130 public void RegionLoaded(Scene s)
105 { 131 {
106 if (!m_Enabled) 132 // We'll reuse the same handler for all requests.
107 return; 133 m_getTextureHandler = new GetTextureHandler(m_assetService);
108 134
109 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
110 m_scene.EventManager.OnRegisterCaps += RegisterCaps; 135 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
136 m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
137 m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate;
138
139 if (m_workerThreads == null)
140 {
141 m_workerThreads = new Thread[2];
142
143 for (uint i = 0; i < 2; i++)
144 {
145 m_workerThreads[i] = Watchdog.StartThread(DoTextureRequests,
146 String.Format("TextureWorkerThread{0}", i),
147 ThreadPriority.Normal,
148 false,
149 false,
150 null,
151 int.MaxValue);
152 }
153 }
154 }
155 private int ExtractImageThrottle(byte[] pthrottles)
156 {
157
158 byte[] adjData;
159 int pos = 0;
160
161 if (!BitConverter.IsLittleEndian)
162 {
163 byte[] newData = new byte[7 * 4];
164 Buffer.BlockCopy(pthrottles, 0, newData, 0, 7 * 4);
165
166 for (int i = 0; i < 7; i++)
167 Array.Reverse(newData, i * 4, 4);
168
169 adjData = newData;
170 }
171 else
172 {
173 adjData = pthrottles;
174 }
175
176 // 0.125f converts from bits to bytes
177 //int resend = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
178 //pos += 4;
179 // int land = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
180 //pos += 4;
181 // int wind = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
182 // pos += 4;
183 // int cloud = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
184 // pos += 4;
185 // int task = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
186 // pos += 4;
187 pos = pos + 20;
188 int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); //pos += 4;
189 //int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
190 return texture;
191 }
192
193 // Now we know when the throttle is changed by the client in the case of a root agent or by a neighbor region in the case of a child agent.
194 public void ThrottleUpdate(ScenePresence p)
195 {
196 byte[] throttles = p.ControllingClient.GetThrottlesPacked(1);
197 UUID user = p.UUID;
198 int imagethrottle = ExtractImageThrottle(throttles);
199 PollServiceTextureEventArgs args;
200 if (m_pollservices.TryGetValue(user,out args))
201 {
202 args.UpdateThrottle(imagethrottle);
203 }
111 } 204 }
112 205
113 public void PostInitialise() 206 public void PostInitialise()
@@ -125,28 +218,306 @@ namespace OpenSim.Region.ClientStack.Linden
125 218
126 #endregion 219 #endregion
127 220
128 public void RegisterCaps(UUID agentID, Caps caps) 221 ~GetTextureModule()
129 { 222 {
130 UUID capID = UUID.Random(); 223 foreach (Thread t in m_workerThreads)
224 Watchdog.AbortThread(t.ManagedThreadId);
131 225
132 //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); 226 }
133 if (m_URL == "localhost") 227
228 private class PollServiceTextureEventArgs : PollServiceEventArgs
229 {
230 private List<Hashtable> requests =
231 new List<Hashtable>();
232 private Dictionary<UUID, aPollResponse> responses =
233 new Dictionary<UUID, aPollResponse>();
234
235 private Scene m_scene;
236 private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000,10000);
237 public PollServiceTextureEventArgs(UUID pId, Scene scene) :
238 base(null, "", null, null, null, pId, int.MaxValue)
134 { 239 {
240<<<<<<< HEAD
135// m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); 241// m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
136 caps.RegisterHandler( 242 caps.RegisterHandler(
137 "GetTexture", 243 "GetTexture",
138 new GetTextureHandler("/CAPS/" + capID + "/", m_assetService, "GetTexture", agentID.ToString(), m_RedirectURL)); 244 new GetTextureHandler("/CAPS/" + capID + "/", m_assetService, "GetTexture", agentID.ToString(), m_RedirectURL));
245=======
246 m_scene = scene;
247 // x is request id, y is userid
248 HasEvents = (x, y) =>
249 {
250 lock (responses)
251 {
252 bool ret = m_throttler.hasEvents(x, responses);
253 m_throttler.ProcessTime();
254 return ret;
255
256 }
257 };
258 GetEvents = (x, y) =>
259 {
260 lock (responses)
261 {
262 try
263 {
264 return responses[x].response;
265 }
266 finally
267 {
268 responses.Remove(x);
269 }
270 }
271 };
272 // x is request id, y is request data hashtable
273 Request = (x, y) =>
274 {
275 aPollRequest reqinfo = new aPollRequest();
276 reqinfo.thepoll = this;
277 reqinfo.reqID = x;
278 reqinfo.request = y;
279 reqinfo.send503 = false;
280
281 lock (responses)
282 {
283 if (responses.Count > 0)
284 {
285 if (m_queue.Count >= 4)
286 {
287 // Never allow more than 4 fetches to wait
288 reqinfo.send503 = true;
289 }
290 }
291 }
292 m_queue.Enqueue(reqinfo);
293 };
294
295 // this should never happen except possible on shutdown
296 NoEvents = (x, y) =>
297 {
298/*
299 lock (requests)
300 {
301 Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString());
302 requests.Remove(request);
303 }
304*/
305 Hashtable response = new Hashtable();
306
307 response["int_response_code"] = 500;
308 response["str_response_string"] = "Script timeout";
309 response["content_type"] = "text/plain";
310 response["keepalive"] = false;
311 response["reusecontext"] = false;
312
313 return response;
314 };
315>>>>>>> avn/ubitvar
139 } 316 }
140 else 317
318 public void Process(aPollRequest requestinfo)
141 { 319 {
142// m_log.DebugFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); 320 Hashtable response;
321
322 UUID requestID = requestinfo.reqID;
323
324 if (requestinfo.send503)
325 {
326 response = new Hashtable();
327
328
329 response["int_response_code"] = 503;
330 response["str_response_string"] = "Throttled";
331 response["content_type"] = "text/plain";
332 response["keepalive"] = false;
333 response["reusecontext"] = false;
334
335 Hashtable headers = new Hashtable();
336 headers["Retry-After"] = 30;
337 response["headers"] = headers;
338
339 lock (responses)
340 responses[requestID] = new aPollResponse() {bytes = 0, response = response};
341
342 return;
343 }
344
345 // If the avatar is gone, don't bother to get the texture
346 if (m_scene.GetScenePresence(Id) == null)
347 {
348 response = new Hashtable();
349
350 response["int_response_code"] = 500;
351 response["str_response_string"] = "Script timeout";
352 response["content_type"] = "text/plain";
353 response["keepalive"] = false;
354 response["reusecontext"] = false;
355
356 lock (responses)
357 responses[requestID] = new aPollResponse() {bytes = 0, response = response};
358
359 return;
360 }
361
362 response = m_getTextureHandler.Handle(requestinfo.request);
363 lock (responses)
364 {
365 responses[requestID] = new aPollResponse()
366 {
367 bytes = (int) response["int_bytes"],
368 response = response
369 };
370
371 }
372 m_throttler.ProcessTime();
373 }
374
375 internal void UpdateThrottle(int pimagethrottle)
376 {
377 m_throttler.ThrottleBytes = pimagethrottle;
378 }
379 }
380
381 private void RegisterCaps(UUID agentID, Caps caps)
382 {
383 if (m_Url == "localhost")
384 {
385 string capUrl = "/CAPS/" + UUID.Random() + "/";
386
387 // Register this as a poll service
388 PollServiceTextureEventArgs args = new PollServiceTextureEventArgs(agentID, m_scene);
389
390 args.Type = PollServiceEventArgs.EventType.Texture;
391 MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
392
393 string hostName = m_scene.RegionInfo.ExternalHostName;
394 uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
395 string protocol = "http";
396
397 if (MainServer.Instance.UseSSL)
398 {
399 hostName = MainServer.Instance.SSLCommonName;
400 port = MainServer.Instance.SSLPort;
401 protocol = "https";
402 }
143 IExternalCapsModule handler = m_scene.RequestModuleInterface<IExternalCapsModule>(); 403 IExternalCapsModule handler = m_scene.RequestModuleInterface<IExternalCapsModule>();
144 if (handler != null) 404 if (handler != null)
405<<<<<<< HEAD
145 handler.RegisterExternalUserCapsHandler(agentID,caps,"GetTexture", m_URL); 406 handler.RegisterExternalUserCapsHandler(agentID,caps,"GetTexture", m_URL);
407=======
408 handler.RegisterExternalUserCapsHandler(agentID, caps, "GetTexture", capUrl);
409>>>>>>> avn/ubitvar
146 else 410 else
147 caps.RegisterHandler("GetTexture", m_URL); 411 caps.RegisterHandler("GetTexture", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
412 m_pollservices[agentID] = args;
413 m_capsDict[agentID] = capUrl;
414 }
415 else
416 {
417 caps.RegisterHandler("GetTexture", m_Url);
148 } 418 }
149 } 419 }
150 420
421 private void DeregisterCaps(UUID agentID, Caps caps)
422 {
423 PollServiceTextureEventArgs args;
424
425 MainServer.Instance.RemoveHTTPHandler("", m_URL);
426 m_capsDict.Remove(agentID);
427
428 if (m_pollservices.TryGetValue(agentID, out args))
429 {
430 m_pollservices.Remove(agentID);
431 }
432 }
433
434 private void DoTextureRequests()
435 {
436 while (true)
437 {
438 aPollRequest poolreq = m_queue.Dequeue();
439
440 poolreq.thepoll.Process(poolreq);
441 }
442 }
443 internal sealed class CapsDataThrottler
444 {
445
446 private volatile int currenttime = 0;
447 private volatile int lastTimeElapsed = 0;
448 private volatile int BytesSent = 0;
449 private int oversizedImages = 0;
450 public CapsDataThrottler(int pBytes, int max, int min)
451 {
452 ThrottleBytes = pBytes;
453 lastTimeElapsed = Util.EnvironmentTickCount();
454 }
455 public bool hasEvents(UUID key, Dictionary<UUID, GetTextureModule.aPollResponse> responses)
456 {
457 PassTime();
458 // Note, this is called IN LOCK
459 bool haskey = responses.ContainsKey(key);
460 if (!haskey)
461 {
462 return false;
463 }
464 GetTextureModule.aPollResponse response;
465 if (responses.TryGetValue(key, out response))
466 {
467 // This is any error response
468 if (response.bytes == 0)
469 return true;
470
471 // Normal
472 if (BytesSent + response.bytes <= ThrottleBytes)
473 {
474 BytesSent += response.bytes;
475 //TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + 1000, unlockyn = false };
476 //m_actions.Add(timeBasedAction);
477 return true;
478 }
479 // Big textures
480 else if (response.bytes > ThrottleBytes && oversizedImages <= ((ThrottleBytes % 50000) + 1))
481 {
482 Interlocked.Increment(ref oversizedImages);
483 BytesSent += response.bytes;
484 //TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + (((response.bytes % ThrottleBytes)+1)*1000) , unlockyn = false };
485 //m_actions.Add(timeBasedAction);
486 return true;
487 }
488 else
489 {
490 return false;
491 }
492 }
493
494 return haskey;
495 }
496
497 public void ProcessTime()
498 {
499 PassTime();
500 }
501
502 private void PassTime()
503 {
504 currenttime = Util.EnvironmentTickCount();
505 int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed);
506 //processTimeBasedActions(responses);
507 if (Util.EnvironmentTickCountSubtract(currenttime, timeElapsed) >= 1000)
508 {
509 lastTimeElapsed = Util.EnvironmentTickCount();
510 BytesSent -= ThrottleBytes;
511 if (BytesSent < 0) BytesSent = 0;
512 if (BytesSent < ThrottleBytes)
513 {
514 oversizedImages = 0;
515 }
516 }
517 }
518 public int ThrottleBytes;
519 }
151 } 520 }
521
522
152} 523}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
index 45d33cd..1b68603 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
@@ -129,15 +129,15 @@ namespace OpenSim.Region.ClientStack.Linden
129// m_log.DebugFormat("[MESH UPLOAD FLAG MODULE]: MeshUploadFlag request"); 129// m_log.DebugFormat("[MESH UPLOAD FLAG MODULE]: MeshUploadFlag request");
130 130
131 OSDMap data = new OSDMap(); 131 OSDMap data = new OSDMap();
132 ScenePresence sp = m_scene.GetScenePresence(agentID); 132// ScenePresence sp = m_scene.GetScenePresence(m_agentID);
133 data["username"] = sp.Firstname + "." + sp.Lastname; 133// data["username"] = sp.Firstname + "." + sp.Lastname;
134 data["display_name_next_update"] = new OSDDate(DateTime.Now); 134// data["display_name_next_update"] = new OSDDate(DateTime.Now);
135 data["legacy_first_name"] = sp.Firstname; 135// data["legacy_first_name"] = sp.Firstname;
136 data["mesh_upload_status"] = "valid"; 136 data["mesh_upload_status"] = "valid";
137 data["display_name"] = sp.Firstname + " " + sp.Lastname; 137// data["display_name"] = sp.Firstname + " " + sp.Lastname;
138 data["legacy_last_name"] = sp.Lastname; 138// data["legacy_last_name"] = sp.Lastname;
139 data["id"] = agentID; 139// data["id"] = m_agentID;
140 data["is_display_name_default"] = true; 140// data["is_display_name_default"] = true;
141 141
142 //Send back data 142 //Send back data
143 Hashtable responsedata = new Hashtable(); 143 Hashtable responsedata = new Hashtable();
@@ -148,4 +148,4 @@ namespace OpenSim.Region.ClientStack.Linden
148 return responsedata; 148 return responsedata;
149 } 149 }
150 } 150 }
151} \ No newline at end of file 151}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
deleted file mode 100644
index f69a0bb..0000000
--- a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
+++ /dev/null
@@ -1,297 +0,0 @@
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.Collections;
30using System.Collections.Specialized;
31using System.Reflection;
32using System.IO;
33using System.Web;
34using Mono.Addins;
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39using OpenSim.Framework;
40using OpenSim.Framework.Servers;
41using OpenSim.Framework.Servers.HttpServer;
42using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes;
44using OpenSim.Services.Interfaces;
45using Caps = OpenSim.Framework.Capabilities.Caps;
46using OpenSim.Framework.Capabilities;
47using PermissionMask = OpenSim.Framework.PermissionMask;
48
49namespace OpenSim.Region.ClientStack.Linden
50{
51 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "NewFileAgentInventoryVariablePriceModule")]
52 public class NewFileAgentInventoryVariablePriceModule : INonSharedRegionModule
53 {
54// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55
56 private Scene m_scene;
57// private IAssetService m_assetService;
58 private bool m_dumpAssetsToFile = false;
59 private bool m_enabled = true;
60 private int m_levelUpload = 0;
61
62 #region Region Module interfaceBase Members
63
64
65 public Type ReplaceableInterface
66 {
67 get { return null; }
68 }
69
70 public void Initialise(IConfigSource source)
71 {
72 IConfig meshConfig = source.Configs["Mesh"];
73 if (meshConfig == null)
74 return;
75
76 m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true);
77 m_levelUpload = meshConfig.GetInt("LevelUpload", 0);
78 }
79
80 public void AddRegion(Scene pScene)
81 {
82 m_scene = pScene;
83 }
84
85 public void RemoveRegion(Scene scene)
86 {
87
88 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
89 m_scene = null;
90 }
91
92 public void RegionLoaded(Scene scene)
93 {
94
95// m_assetService = m_scene.RequestModuleInterface<IAssetService>();
96 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
97 }
98
99 #endregion
100
101
102 #region Region Module interface
103
104
105
106 public void Close() { }
107
108 public string Name { get { return "NewFileAgentInventoryVariablePriceModule"; } }
109
110
111 public void RegisterCaps(UUID agentID, Caps caps)
112 {
113 if(!m_enabled)
114 return;
115
116 UUID capID = UUID.Random();
117
118// m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID);
119 caps.RegisterHandler(
120 "NewFileAgentInventoryVariablePrice",
121 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>(
122 "POST",
123 "/CAPS/" + capID.ToString(),
124 req => NewAgentInventoryRequest(req, agentID),
125 "NewFileAgentInventoryVariablePrice",
126 agentID.ToString()));
127 }
128
129 #endregion
130
131 public LLSDNewFileAngentInventoryVariablePriceReplyResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest, UUID agentID)
132 {
133 //TODO: The Mesh uploader uploads many types of content. If you're going to implement a Money based limit
134 // you need to be aware of this
135
136 //if (llsdRequest.asset_type == "texture" ||
137 // llsdRequest.asset_type == "animation" ||
138 // llsdRequest.asset_type == "sound")
139 // {
140 // check user level
141
142 ScenePresence avatar = null;
143 IClientAPI client = null;
144 m_scene.TryGetScenePresence(agentID, out avatar);
145
146 if (avatar != null)
147 {
148 client = avatar.ControllingClient;
149
150 if (avatar.UserLevel < m_levelUpload)
151 {
152 if (client != null)
153 client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
154
155 LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
156 errorResponse.rsvp = "";
157 errorResponse.state = "error";
158 return errorResponse;
159 }
160 }
161
162 // check funds
163 IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
164
165 if (mm != null)
166 {
167 if (!mm.UploadCovered(agentID, mm.UploadCharge))
168 {
169 if (client != null)
170 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
171
172 LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
173 errorResponse.rsvp = "";
174 errorResponse.state = "error";
175 return errorResponse;
176 }
177 }
178
179 // }
180
181 string assetName = llsdRequest.name;
182 string assetDes = llsdRequest.description;
183 string capsBase = "/CAPS/NewFileAgentInventoryVariablePrice/";
184 UUID newAsset = UUID.Random();
185 UUID newInvItem = UUID.Random();
186 UUID parentFolder = llsdRequest.folder_id;
187 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000") + "/";
188
189 AssetUploader uploader =
190 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
191 llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile);
192
193 MainServer.Instance.AddStreamHandler(
194 new BinaryStreamHandler(
195 "POST",
196 capsBase + uploaderPath,
197 uploader.uploaderCaps,
198 "NewFileAgentInventoryVariablePrice",
199 agentID.ToString()));
200
201 string protocol = "http://";
202
203 if (MainServer.Instance.UseSSL)
204 protocol = "https://";
205
206 string uploaderURL = protocol + m_scene.RegionInfo.ExternalHostName + ":" + MainServer.Instance.Port.ToString() + capsBase +
207 uploaderPath;
208
209
210 LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
211
212 uploadResponse.rsvp = uploaderURL;
213 uploadResponse.state = "upload";
214 uploadResponse.resource_cost = 0;
215 uploadResponse.upload_price = 0;
216
217 uploader.OnUpLoad += //UploadCompleteHandler;
218
219 delegate(
220 string passetName, string passetDescription, UUID passetID,
221 UUID pinventoryItem, UUID pparentFolder, byte[] pdata, string pinventoryType,
222 string passetType)
223 {
224 UploadCompleteHandler(passetName, passetDescription, passetID,
225 pinventoryItem, pparentFolder, pdata, pinventoryType,
226 passetType,agentID);
227 };
228
229 return uploadResponse;
230 }
231
232 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
233 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
234 string assetType,UUID AgentID)
235 {
236// m_log.DebugFormat(
237// "[NEW FILE AGENT INVENTORY VARIABLE PRICE MODULE]: Upload complete for {0}", inventoryItem);
238
239 sbyte assType = 0;
240 sbyte inType = 0;
241
242 if (inventoryType == "sound")
243 {
244 inType = 1;
245 assType = 1;
246 }
247 else if (inventoryType == "animation")
248 {
249 inType = 19;
250 assType = 20;
251 }
252 else if (inventoryType == "wearable")
253 {
254 inType = 18;
255 switch (assetType)
256 {
257 case "bodypart":
258 assType = 13;
259 break;
260 case "clothing":
261 assType = 5;
262 break;
263 }
264 }
265 else if (inventoryType == "mesh")
266 {
267 inType = (sbyte)InventoryType.Mesh;
268 assType = (sbyte)AssetType.Mesh;
269 }
270
271 AssetBase asset;
272 asset = new AssetBase(assetID, assetName, assType, AgentID.ToString());
273 asset.Data = data;
274
275 if (m_scene.AssetService != null)
276 m_scene.AssetService.Store(asset);
277
278 InventoryItemBase item = new InventoryItemBase();
279 item.Owner = AgentID;
280 item.CreatorId = AgentID.ToString();
281 item.ID = inventoryItem;
282 item.AssetID = asset.FullID;
283 item.Description = assetDescription;
284 item.Name = assetName;
285 item.AssetType = assType;
286 item.InvType = inType;
287 item.Folder = parentFolder;
288 item.CurrentPermissions
289 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
290 item.BasePermissions = (uint)PermissionMask.All;
291 item.EveryOnePermissions = 0;
292 item.NextPermissions = (uint)PermissionMask.All;
293 item.CreationDate = Util.UnixTimeSinceEpoch();
294 m_scene.AddInventoryItem(item);
295 }
296 }
297}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
index a133a69..5196368 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
@@ -64,6 +64,8 @@ namespace OpenSim.Region.ClientStack.Linden
64 private Commands m_commands = new Commands(); 64 private Commands m_commands = new Commands();
65 public ICommands Commands { get { return m_commands; } } 65 public ICommands Commands { get { return m_commands; } }
66 66
67 public event ConsoleMessage OnConsoleMessage;
68
67 public void Initialise(IConfigSource source) 69 public void Initialise(IConfigSource source)
68 { 70 {
69 m_commands.AddCommand( "Help", false, "help", "help [<item>]", "Display help on a particular command or on a list of commands in a category", Help); 71 m_commands.AddCommand( "Help", false, "help", "help [<item>]", "Display help on a particular command or on a list of commands in a category", Help);
@@ -102,7 +104,7 @@ namespace OpenSim.Region.ClientStack.Linden
102 104
103 public void RegisterCaps(UUID agentID, Caps caps) 105 public void RegisterCaps(UUID agentID, Caps caps)
104 { 106 {
105 if (!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(agentID)) 107 if (!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(agentID) && !m_scene.Permissions.IsGod(agentID))
106 return; 108 return;
107 109
108 UUID capID = UUID.Random(); 110 UUID capID = UUID.Random();
@@ -118,6 +120,11 @@ namespace OpenSim.Region.ClientStack.Linden
118 OSD osd = OSD.FromString(message); 120 OSD osd = OSD.FromString(message);
119 121
120 m_eventQueue.Enqueue(EventQueueHelper.BuildEvent("SimConsoleResponse", osd), agentID); 122 m_eventQueue.Enqueue(EventQueueHelper.BuildEvent("SimConsoleResponse", osd), agentID);
123
124 ConsoleMessage handlerConsoleMessage = OnConsoleMessage;
125
126 if (handlerConsoleMessage != null)
127 handlerConsoleMessage( agentID, message);
121 } 128 }
122 129
123 public bool RunCommand(string command, UUID invokerID) 130 public bool RunCommand(string command, UUID invokerID)
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
index e258bcb..54542c9 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
@@ -155,8 +155,13 @@ namespace OpenSim.Region.ClientStack.Linden
155 m_features["MeshRezEnabled"] = true; 155 m_features["MeshRezEnabled"] = true;
156 m_features["MeshUploadEnabled"] = true; 156 m_features["MeshUploadEnabled"] = true;
157 m_features["MeshXferEnabled"] = true; 157 m_features["MeshXferEnabled"] = true;
158
158 m_features["PhysicsMaterialsEnabled"] = true; 159 m_features["PhysicsMaterialsEnabled"] = true;
160<<<<<<< HEAD
159 161
162=======
163
164>>>>>>> avn/ubitvar
160 OSDMap typesMap = new OSDMap(); 165 OSDMap typesMap = new OSDMap();
161 typesMap["convex"] = true; 166 typesMap["convex"] = true;
162 typesMap["none"] = true; 167 typesMap["none"] = true;
@@ -164,6 +169,7 @@ namespace OpenSim.Region.ClientStack.Linden
164 m_features["PhysicsShapeTypes"] = typesMap; 169 m_features["PhysicsShapeTypes"] = typesMap;
165 170
166 // Extra information for viewers that want to use it 171 // Extra information for viewers that want to use it
172<<<<<<< HEAD
167 // TODO: Take these out of here into their respective modules, like map-server-url 173 // TODO: Take these out of here into their respective modules, like map-server-url
168 OSDMap extrasMap; 174 OSDMap extrasMap;
169 if(m_features.ContainsKey("OpenSimExtras")) 175 if(m_features.ContainsKey("OpenSimExtras"))
@@ -173,6 +179,15 @@ namespace OpenSim.Region.ClientStack.Linden
173 else 179 else
174 extrasMap = new OSDMap(); 180 extrasMap = new OSDMap();
175 181
182=======
183
184 OSDMap extrasMap = new OSDMap();
185
186 extrasMap["AvatarSkeleton"] = true;
187 extrasMap["AnimationSet"] = true;
188
189 // TODO: Take these out of here into their respective modules, like map-server-url
190>>>>>>> avn/ubitvar
176 if (m_SearchURL != string.Empty) 191 if (m_SearchURL != string.Empty)
177 extrasMap["search-server-url"] = m_SearchURL; 192 extrasMap["search-server-url"] = m_SearchURL;
178 if (!string.IsNullOrEmpty(m_DestinationGuideURL)) 193 if (!string.IsNullOrEmpty(m_DestinationGuideURL))
@@ -184,8 +199,13 @@ namespace OpenSim.Region.ClientStack.Linden
184 if (m_GridName != string.Empty) 199 if (m_GridName != string.Empty)
185 extrasMap["GridName"] = m_GridName; 200 extrasMap["GridName"] = m_GridName;
186 201
202<<<<<<< HEAD
187 if (extrasMap.Count > 0) 203 if (extrasMap.Count > 0)
188 m_features["OpenSimExtras"] = extrasMap; 204 m_features["OpenSimExtras"] = extrasMap;
205=======
206 m_features["OpenSimExtras"] = extrasMap;
207
208>>>>>>> avn/ubitvar
189 } 209 }
190 } 210 }
191 211
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs
index 8cdebcd..c27d101 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs
@@ -67,6 +67,8 @@ namespace OpenSim.Region.ClientStack.Linden
67 67
68 private IBakedTextureModule m_BakedTextureModule; 68 private IBakedTextureModule m_BakedTextureModule;
69 69
70 private IBakedTextureModule m_BakedTextureModule;
71
70 public void Initialise(IConfigSource source) 72 public void Initialise(IConfigSource source)
71 { 73 {
72 IConfig appearanceConfig = source.Configs["Appearance"]; 74 IConfig appearanceConfig = source.Configs["Appearance"];
@@ -89,7 +91,11 @@ namespace OpenSim.Region.ClientStack.Linden
89 s.EventManager.OnRemovePresence -= DeRegisterPresence; 91 s.EventManager.OnRemovePresence -= DeRegisterPresence;
90 m_BakedTextureModule = null; 92 m_BakedTextureModule = null;
91 m_scene = null; 93 m_scene = null;
94<<<<<<< HEAD
92 } 95 }
96=======
97 }
98>>>>>>> avn/ubitvar
93 99
94 100
95 101
@@ -103,6 +109,7 @@ namespace OpenSim.Region.ClientStack.Linden
103 109
104 private void DeRegisterPresence(UUID agentId) 110 private void DeRegisterPresence(UUID agentId)
105 { 111 {
112<<<<<<< HEAD
106 ScenePresence presence = null; 113 ScenePresence presence = null;
107 if (m_scene.TryGetScenePresence(agentId, out presence)) 114 if (m_scene.TryGetScenePresence(agentId, out presence))
108 { 115 {
@@ -261,8 +268,162 @@ namespace OpenSim.Region.ClientStack.Linden
261 } 268 }
262 } 269 }
263 } 270 }
271=======
272// ScenePresence presence = null;
273// if (m_scene.TryGetScenePresence(agentId, out presence))
274 {
275// presence.ControllingClient.OnSetAppearance -= CaptureAppearanceSettings;
276 }
277
278>>>>>>> avn/ubitvar
279 }
280
281 private void RegisterNewPresence(ScenePresence presence)
282 {
283// presence.ControllingClient.OnSetAppearance += CaptureAppearanceSettings;
264 } 284 }
265 285
286/* not in use. work done in AvatarFactoryModule ValidateBakedTextureCache() and UpdateBakedTextureCache()
287 private void CaptureAppearanceSettings(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems)
288 {
289 // if cacheItems.Length > 0 viewer is giving us current textures information.
290 // baked ones should had been uploaded and in assets cache as local itens
291
292
293 if (cacheItems.Length == 0)
294 return; // no textures information, nothing to do
295
296 ScenePresence p = null;
297 if (!m_scene.TryGetScenePresence(remoteClient.AgentId, out p))
298 return; // what are we doing if there is no presence to cache for?
299
300 if (p.IsDeleted)
301 return; // does this really work?
302
303 int maxCacheitemsLoop = cacheItems.Length;
304 if (maxCacheitemsLoop > 20)
305 {
306 maxCacheitemsLoop = AvatarWearable.MAX_WEARABLES;
307 m_log.WarnFormat("[CACHEDBAKES]: Too Many Cache items Provided {0}, the max is {1}. Truncating!", cacheItems.Length, AvatarWearable.MAX_WEARABLES);
308 }
309
310 m_BakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
311
312
313 // some nice debug
314 m_log.Debug("[Cacheitems]: " + cacheItems.Length);
315 for (int iter = 0; iter < maxCacheitemsLoop; iter++)
316 {
317 m_log.Debug("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" +
318 cacheItems[iter].TextureID);
319 }
320
321 // p.Appearance.WearableCacheItems is in memory primary cashID to textures mapper
322
323 WearableCacheItem[] existingitems = p.Appearance.WearableCacheItems;
324
325 if (existingitems == null)
326 {
327 if (m_BakedTextureModule != null)
328 {
329 WearableCacheItem[] savedcache = null;
330 try
331 {
332 if (p.Appearance.WearableCacheItemsDirty)
333 {
334 savedcache = m_BakedTextureModule.Get(p.UUID);
335 p.Appearance.WearableCacheItems = savedcache;
336 p.Appearance.WearableCacheItemsDirty = false;
337 }
338 }
339
340 catch (Exception)
341 {
342 // The service logs a sufficient error message.
343 }
344
345
346 if (savedcache != null)
347 existingitems = savedcache;
348 }
349 }
350
351 // Existing items null means it's a fully new appearance
352 if (existingitems == null)
353 {
354 for (int i = 0; i < maxCacheitemsLoop; i++)
355 {
356 if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex)
357 {
358 Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex];
359 if (face == null)
360 {
361 textureEntry.CreateFace(cacheItems[i].TextureIndex);
362 textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID =
363 AppearanceManager.DEFAULT_AVATAR_TEXTURE;
364 continue;
365 }
366 cacheItems[i].TextureID = face.TextureID;
367 if (m_scene.AssetService != null)
368 cacheItems[i].TextureAsset =
369 m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString());
370 }
371 else
372 {
373 m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length);
374 }
375 }
376 }
377 else
378 {
379 for (int i = 0; i < maxCacheitemsLoop; i++)
380 {
381 if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex)
382 {
383 Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex];
384 if (face == null)
385 {
386 textureEntry.CreateFace(cacheItems[i].TextureIndex);
387 textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID =
388 AppearanceManager.DEFAULT_AVATAR_TEXTURE;
389 continue;
390 }
391 cacheItems[i].TextureID =
392 face.TextureID;
393 }
394 else
395 {
396 m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length);
397 }
398 }
399
400 for (int i = 0; i < maxCacheitemsLoop; i++)
401 {
402 if (cacheItems[i].TextureAsset == null)
403 {
404 cacheItems[i].TextureAsset =
405 m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString());
406 }
407 }
408 }
409 p.Appearance.WearableCacheItems = cacheItems;
410
411 if (m_BakedTextureModule != null)
412 {
413 m_BakedTextureModule.Store(remoteClient.AgentId, cacheItems);
414 p.Appearance.WearableCacheItemsDirty = true;
415
416 }
417 else
418 p.Appearance.WearableCacheItemsDirty = false;
419
420 for (int iter = 0; iter < maxCacheitemsLoop; iter++)
421 {
422 m_log.Debug("[CacheitemsLeaving] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" +
423 cacheItems[iter].TextureID);
424 }
425 }
426 */
266 public void PostInitialise() 427 public void PostInitialise()
267 { 428 {
268 } 429 }
@@ -283,6 +444,7 @@ namespace OpenSim.Region.ClientStack.Linden
283 UploadBakedTextureHandler avatarhandler = new UploadBakedTextureHandler( 444 UploadBakedTextureHandler avatarhandler = new UploadBakedTextureHandler(
284 caps, m_scene.AssetService, m_persistBakedTextures); 445 caps, m_scene.AssetService, m_persistBakedTextures);
285 446
447<<<<<<< HEAD
286 448
287 449
288 caps.RegisterHandler( 450 caps.RegisterHandler(
@@ -297,6 +459,28 @@ namespace OpenSim.Region.ClientStack.Linden
297 459
298 460
299 461
462=======
463 //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture));
464 if (m_URL == "localhost")
465 {
466 UploadBakedTextureHandler avatarhandler = new UploadBakedTextureHandler(
467 caps, m_scene.AssetService, m_persistBakedTextures);
468
469 caps.RegisterHandler(
470 "UploadBakedTexture",
471 new RestStreamHandler(
472 "POST",
473 "/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
474 avatarhandler.UploadBakedTexture,
475 "UploadBakedTexture",
476 agentID.ToString()));
477
478 }
479 else
480 {
481 caps.RegisterHandler("UploadBakedTexture", m_URL);
482 }
483>>>>>>> avn/ubitvar
300 } 484 }
301 } 485 }
302} 486}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
index 025ffea..92f8c51 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
@@ -34,9 +34,7 @@ using log4net;
34using Nini.Config; 34using Nini.Config;
35using Mono.Addins; 35using Mono.Addins;
36using OpenMetaverse; 36using OpenMetaverse;
37using OpenMetaverse.StructuredData;
38using OpenSim.Framework; 37using OpenSim.Framework;
39using OpenSim.Framework.Monitoring;
40using OpenSim.Framework.Servers; 38using OpenSim.Framework.Servers;
41using OpenSim.Framework.Servers.HttpServer; 39using OpenSim.Framework.Servers.HttpServer;
42using OpenSim.Region.Framework.Interfaces; 40using OpenSim.Region.Framework.Interfaces;
@@ -45,6 +43,9 @@ using OpenSim.Framework.Capabilities;
45using OpenSim.Services.Interfaces; 43using OpenSim.Services.Interfaces;
46using Caps = OpenSim.Framework.Capabilities.Caps; 44using Caps = OpenSim.Framework.Capabilities.Caps;
47using OpenSim.Capabilities.Handlers; 45using OpenSim.Capabilities.Handlers;
46using OpenSim.Framework.Monitoring;
47using OpenMetaverse;
48using OpenMetaverse.StructuredData;
48 49
49namespace OpenSim.Region.ClientStack.Linden 50namespace OpenSim.Region.ClientStack.Linden
50{ 51{
@@ -63,7 +64,11 @@ namespace OpenSim.Region.ClientStack.Linden
63 public List<UUID> folders; 64 public List<UUID> folders;
64 } 65 }
65 66
67<<<<<<< HEAD
66 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 68 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
69=======
70 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
71>>>>>>> avn/ubitvar
67 72
68 /// <summary> 73 /// <summary>
69 /// Control whether requests will be processed asynchronously. 74 /// Control whether requests will be processed asynchronously.
@@ -312,7 +317,8 @@ namespace OpenSim.Region.ClientStack.Linden
312 { 317 {
313 if (!reqinfo.folders.Contains(folderID)) 318 if (!reqinfo.folders.Contains(folderID))
314 { 319 {
315 //TODO: Port COF handling from Avination 320 if (sp.COF != UUID.Zero && sp.COF == folderID)
321 highPriority = true;
316 reqinfo.folders.Add(folderID); 322 reqinfo.folders.Add(folderID);
317 } 323 }
318 } 324 }