From 5317b1053f2b8fd81f71c0b95c79aaa03efb47e4 Mon Sep 17 00:00:00 2001
From: UbitUmarov
Date: Wed, 19 Sep 2012 03:53:51 +0100
Subject:  be more tolerant to small prims, skipping them, only failing if they
 are  more than half of total. Add a state control to NewFileAgentInventory 
 to avoid more than one at a time per client. ( Incomplete and possible not
 that good)

---
 .../Linden/Caps/BunchOfCaps/BunchOfCaps.cs         | 81 ++++++++++++++++++----
 .../Linden/Caps/BunchOfCaps/MeshCost.cs            | 17 +++--
 2 files changed, 82 insertions(+), 16 deletions(-)

diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index 0fb6c99..d66076d 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -117,6 +117,17 @@ namespace OpenSim.Region.ClientStack.Linden
         private bool m_dumpAssetsToFile = false;
         private string m_regionName;
         private int m_levelUpload = 0;
+        private float m_PrimScaleMin = 0.001f;
+
+        private enum FileAgentInventoryState : int
+        {
+            idle = 0,
+            processRequest = 1,
+            waitUpload = 2,
+            processUpload = 3
+        }
+        private FileAgentInventoryState m_FileAgentInventoryState = FileAgentInventoryState.idle;
+        
 //        private bool m_addNewTextures = false;
 //        private bool m_addNewMeshes = false;
 
@@ -132,6 +143,7 @@ namespace OpenSim.Region.ClientStack.Linden
             m_ModelCost.PhysicalPrimScaleMax = m_Scene.m_maxPhys;
 //            m_ModelCost.PrimScaleMin = ??
 //            m_ModelCost.ObjectLinkedPartsMax = ??
+//            m_PrimScaleMin = ??
 
             IConfigSource config = m_Scene.Config;
             if (config != null)
@@ -158,6 +170,8 @@ namespace OpenSim.Region.ClientStack.Linden
             ItemUpdatedCall = m_Scene.CapsUpdateInventoryItemAsset;
             TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset;
             GetClient = m_Scene.SceneGraph.GetControllingClient;
+
+            m_FileAgentInventoryState = FileAgentInventoryState.idle;
         }
 
         /// <summary>
@@ -224,9 +238,7 @@ namespace OpenSim.Region.ClientStack.Linden
                 IRequestHandler getObjectCostHandler = new RestStreamHandler("POST", capsBase + m_getObjectCostPath, GetObjectCost);
                 m_HostCapsObj.RegisterHandler("GetObjectCost", getObjectCostHandler);
                 IRequestHandler ResourceCostSelectedHandler = new RestStreamHandler("POST", capsBase + m_ResourceCostSelectedPath, ResourceCostSelected);
-                m_HostCapsObj.RegisterHandler("ResourceCostSelected", ResourceCostSelectedHandler);
-           
-
+                m_HostCapsObj.RegisterHandler("ResourceCostSelected", ResourceCostSelectedHandler);       
 
                 m_HostCapsObj.RegisterHandler(
                     "CopyInventoryFromNotecard",
@@ -439,6 +451,35 @@ namespace OpenSim.Region.ClientStack.Linden
             //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString());
             //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type);
 
+            // start by getting the client
+            IClientAPI client = null;
+            m_Scene.TryGetClient(m_HostCapsObj.AgentID, out client);
+
+            // check current state so we only have one service at a time
+            lock (m_ModelCost)
+            {
+                switch (m_FileAgentInventoryState)
+                {
+                    case FileAgentInventoryState.processRequest:
+                    case FileAgentInventoryState.processUpload:
+                        if (client != null)
+                            client.SendAgentAlertMessage("Unable to upload asset. Processing previus request", false);
+                        LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
+                        errorResponse.uploader = "";
+                        errorResponse.state = "error";
+                        return errorResponse;
+                        break;
+                    case FileAgentInventoryState.waitUpload:
+                        // todo stop current uploader server
+                        break;
+                    case FileAgentInventoryState.idle:
+                    default:
+                        break;
+                }
+
+                m_FileAgentInventoryState = FileAgentInventoryState.processRequest;
+            }
+
             uint cost = 0;
             LLSDAssetUploadResponseData meshcostdata = new LLSDAssetUploadResponseData();
 
@@ -447,15 +488,12 @@ namespace OpenSim.Region.ClientStack.Linden
                 llsdRequest.asset_type == "mesh" ||
                 llsdRequest.asset_type == "sound")
             {
-                ScenePresence avatar = null;
-                IClientAPI client = null;
+                ScenePresence avatar = null;              
                 m_Scene.TryGetScenePresence(m_HostCapsObj.AgentID, out avatar);
 
                 // check user level
                 if (avatar != null)
                 {
-                    client = avatar.ControllingClient;
-
                     if (avatar.UserLevel < m_levelUpload)
                     {
                         if (client != null)
@@ -464,6 +502,8 @@ namespace OpenSim.Region.ClientStack.Linden
                         LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
                         errorResponse.uploader = "";
                         errorResponse.state = "error";
+                        lock (m_ModelCost)
+                            m_FileAgentInventoryState = FileAgentInventoryState.idle;
                         return errorResponse;
                     }
                 }
@@ -490,6 +530,8 @@ namespace OpenSim.Region.ClientStack.Linden
                             LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
                             errorResponse.uploader = "";
                             errorResponse.state = "error";
+                            lock (m_ModelCost)
+                                m_FileAgentInventoryState = FileAgentInventoryState.idle;
                             return errorResponse;
                         }
                         cost = (uint)modelcost;
@@ -509,6 +551,8 @@ namespace OpenSim.Region.ClientStack.Linden
                             LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
                             errorResponse.uploader = "";
                             errorResponse.state = "error";
+                            lock (m_ModelCost)
+                                m_FileAgentInventoryState = FileAgentInventoryState.idle;
                             return errorResponse;
                         }
                     }
@@ -555,8 +599,11 @@ namespace OpenSim.Region.ClientStack.Linden
             }
 
             uploader.OnUpLoad += UploadCompleteHandler;
-            return uploadResponse;
 
+            lock (m_ModelCost)
+                m_FileAgentInventoryState = FileAgentInventoryState.waitUpload;
+
+            return uploadResponse;
         }
 
         /// <summary>
@@ -569,6 +616,9 @@ namespace OpenSim.Region.ClientStack.Linden
                                           UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
                                           string assetType, uint cost)
         {
+            lock (m_ModelCost)
+                m_FileAgentInventoryState = FileAgentInventoryState.processUpload;
+
             m_log.DebugFormat(
                 "[BUNCH OF CAPS]: Uploaded asset {0} for inventory item {1}, inv type {2}, asset type {3}",
                 assetID, inventoryItem, inventoryType, assetType);
@@ -730,12 +780,19 @@ namespace OpenSim.Region.ClientStack.Linden
                     // build prims from instances
                     for (int i = 0; i < instance_list.Count; i++)
                     {
+                        OSDMap inner_instance_list = (OSDMap)instance_list[i];
+
+                        // skip prims that are 2 small
+                        Vector3 scale = inner_instance_list["scale"].AsVector3();
+                        
+                        if (scale.X < m_PrimScaleMin || scale.Y < m_PrimScaleMin || scale.Z < m_PrimScaleMin)
+                            continue;
+
                         PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
 
                         Primitive.TextureEntry textureEntry
                             = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE);
 
-                        OSDMap inner_instance_list = (OSDMap)instance_list[i];
 
                         OSDArray face_list = (OSDArray)inner_instance_list["face_list"];
                         for (uint face = 0; face < face_list.Count; face++)
@@ -789,7 +846,6 @@ namespace OpenSim.Region.ClientStack.Linden
                         }
 
                         Vector3 position = inner_instance_list["position"].AsVector3();
-                        Vector3 scale = inner_instance_list["scale"].AsVector3();
                         Quaternion rotation = inner_instance_list["rotation"].AsQuaternion();
 
 // no longer used - begin ------------------------
@@ -903,6 +959,8 @@ namespace OpenSim.Region.ClientStack.Linden
             {
                 AddNewInventoryItem(m_HostCapsObj.AgentID, item, cost);
             }
+            lock (m_ModelCost)
+                m_FileAgentInventoryState = FileAgentInventoryState.idle;
         }
 
         /// <summary>
@@ -1270,8 +1328,8 @@ namespace OpenSim.Region.ClientStack.Linden
 
             res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
 
-            httpListener.RemoveStreamHandler("POST", uploaderPath);
             m_timeoutTimer.Stop();
+            httpListener.RemoveStreamHandler("POST", uploaderPath);
 
             // TODO: probably make this a better set of extensions here
             string extension = ".jp2";
@@ -1289,7 +1347,6 @@ namespace OpenSim.Region.ClientStack.Linden
             {
                 handlerUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType);
             }
-
             return res;
         }
 
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs
index 62f1d06..ece40ac 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs
@@ -73,7 +73,7 @@ namespace OpenSim.Region.ClientStack.Linden
         const int bytesPerCoord = 6; // 3 coords, 2 bytes per each
 
         // control prims dimensions
-        public float PrimScaleMin = 0.01f;
+        public float PrimScaleMin = 0.001f;
         public float NonPhysicalPrimScaleMax = 256f;
         public float PhysicalPrimScaleMax = 10f;
         public int ObjectLinkedPartsMax = 512;
@@ -171,6 +171,7 @@ namespace OpenSim.Region.ClientStack.Linden
             
 
             int mesh;
+            int skipedSmall = 0;
             for (int i = 0; i < numberInstances; i++)
             {
                 Hashtable inst = (Hashtable)resources.instance_list.Array[i];
@@ -187,8 +188,10 @@ namespace OpenSim.Region.ClientStack.Linden
 
                 if (scale.X < PrimScaleMin || scale.Y < PrimScaleMin || scale.Z < PrimScaleMin)
                 {
-                    error = " upload fail: Model contains parts with a dimension lower than 0.01. Please adjust scaling";
-                    return false;
+//                    error = " upload fail: Model contains parts with a dimension lower than 0.001. Please adjust scaling";
+//                    return false;
+                    skipedSmall++;
+                    continue;
                 }
 
                 if (scale.X > NonPhysicalPrimScaleMax || scale.Y > NonPhysicalPrimScaleMax || scale.Z > NonPhysicalPrimScaleMax)
@@ -229,7 +232,13 @@ namespace OpenSim.Region.ClientStack.Linden
                 // charge for prims creation
                 meshsfee += primCreationCost;
             }
-            
+
+            if (skipedSmall >0 && skipedSmall > numberInstances / 2)
+            {
+                error = "Upload failed: Model contains too much prims smaller than minimum size to ignore";
+                return false;
+            }
+
             if (meshcostdata.physics_cost <= meshcostdata.model_streaming_cost)
                 meshcostdata.resource_cost = meshcostdata.model_streaming_cost;
             else
-- 
cgit v1.1